diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c
index 8dc3ca8e72..ac1d7dc069 100644
--- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c
+++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.45.1. By combining all the individual C code files into this
+** version 3.47.2. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -18,7 +18,7 @@
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
-** e876e51a0ed5c5b3126f52e532044363a014 with changes in files:
+** 2aabe05e2e8cae4847a802ee2daddc1d7413 with changes in files:
**
** .fossil-settings/empty-dirs
** .fossil-settings/ignore-glob
@@ -28,13 +28,10 @@
** README.md
** configure
** configure.ac
-** doc/compile-for-windows.md
** doc/jsonb.md
-** doc/testrunner.md
** doc/trusted-schema.md
** doc/vdbesort-memory.md
** doc/wal-lock.md
-** ext/fts5/fts5_tokenize.c
** ext/jni/README.md
** ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java
** ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java
@@ -42,9 +39,9 @@
** ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java
** ext/jni/src/org/sqlite/jni/capi/ValueHolder.java
** ext/wasm/GNUmakefile
-** ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api
-** ext/wasm/api/sqlite3-api-glue.js
-** ext/wasm/api/sqlite3-api-oo1.js
+** ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core
+** ext/wasm/api/sqlite3-api-glue.c-pp.js
+** ext/wasm/api/sqlite3-api-oo1.c-pp.js
** ext/wasm/fiddle.make
** ext/wasm/fiddle/fiddle-worker.js
** ext/wasm/fiddle/fiddle.js
@@ -89,14 +86,12 @@
** src/wherecode.c
** test/all.test
** test/json/README.md
-** test/permutations.test
** test/rowvaluevtab.test
** tool/mkkeywordhash.c
** tool/mksqlite3c-noext.tcl
** tool/mksqlite3c.tcl
** tool/mksqlite3h.tcl
** tool/mksqlite3internalh.tcl
-** manifest.uuid
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
@@ -340,10 +335,13 @@
/*
** Macro to disable warnings about missing "break" at the end of a "case".
*/
-#if GCC_VERSION>=7000000
-# define deliberate_fall_through __attribute__((fallthrough));
-#else
-# define deliberate_fall_through
+#if defined(__has_attribute)
+# if __has_attribute(fallthrough)
+# define deliberate_fall_through __attribute__((fallthrough));
+# endif
+#endif
+#if !defined(deliberate_fall_through)
+# define deliberate_fall_through
#endif
/*
@@ -546,9 +544,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.45.1"
-#define SQLITE_VERSION_NUMBER 3045001
-#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257ccalt1"
+#define SQLITE_VERSION "3.47.2"
+#define SQLITE_VERSION_NUMBER 3047002
+#define SQLITE_SOURCE_ID "2024-12-07 20:39:59 2aabe05e2e8cae4847a802ee2daddc1d7413d8fc560254d93ee3e72c1468alt1"
#define LIBSQL_VERSION "0.2.3"
@@ -824,6 +822,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
**
The application must not modify the SQL statement text passed into
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
+** The application must not dereference the arrays or string pointers
+** passed as the 3rd and 4th callback parameters after it returns.
**
*/
SQLITE_API int sqlite3_exec(
@@ -1054,6 +1054,13 @@ SQLITE_API int sqlite3_exec(
** filesystem supports doing multiple write operations atomically when those
** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
+**
+** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read
+** from the database file in amounts that are not a multiple of the
+** page size and that do not begin at a page boundary. Without this
+** property, SQLite is careful to only do full-page reads and write
+** on aligned pages, with the one exception that it will do a sub-page
+** read of the first page to access the database header.
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -1070,6 +1077,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
+#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000
/*
** CAPI3REF: File Locking Levels
@@ -1166,16 +1174,16 @@ struct sqlite3_file {
**
** xLock() upgrades the database file lock. In other words, xLock() moves the
** database file lock in the direction NONE toward EXCLUSIVE. The argument to
-** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
+** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
** SQLITE_LOCK_NONE. If the database file lock is already at or above the
** requested lock, then the call to xLock() is a no-op.
** xUnlock() downgrades the database file lock to either SHARED or NONE.
-* If the lock is already at or below the requested lock state, then the call
+** If the lock is already at or below the requested lock state, then the call
** to xUnlock() is a no-op.
** The xCheckReservedLock() method checks whether any database connection,
** either in this process or in some other process, is holding a RESERVED,
-** PENDING, or EXCLUSIVE lock on the file. It returns true
-** if such a lock exists and false otherwise.
+** PENDING, or EXCLUSIVE lock on the file. It returns, via its output
+** pointer parameter, true if such a lock exists and false otherwise.
**
** The xFileControl() method is a generic interface that allows custom
** VFS implementations to directly control an open file using the
@@ -1216,6 +1224,7 @@ struct sqlite3_file {
** [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
** [SQLITE_IOCAP_IMMUTABLE]
** [SQLITE_IOCAP_BATCH_ATOMIC]
+** [SQLITE_IOCAP_SUBPAGE_READ]
**
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -2565,6 +2574,22 @@ struct sqlite3_mem_methods {
** configuration setting is never used, then the default maximum is determined
** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that
** compile-time option is not set, then the default maximum is 1073741824.
+**
+** [[SQLITE_CONFIG_ROWID_IN_VIEW]]
+** SQLITE_CONFIG_ROWID_IN_VIEW
+** The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability
+** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is
+** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability
+** defaults to on. This configuration option queries the current setting or
+** changes the setting to off or on. The argument is a pointer to an integer.
+** If that integer initially holds a value of 1, then the ability for VIEWs to
+** have ROWIDs is activated. If the integer initially holds zero, then the
+** ability is deactivated. Any other initial value for the integer leaves the
+** setting unchanged. After changes, if any, the integer is written with
+** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite
+** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and
+** recommended case) then the integer is always filled with zero, regardless
+** if its initial value.
**
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2596,6 +2621,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
+#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -3710,8 +3736,8 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
-** CAPI3REF: Tracing And Profiling Functions
-** METHOD: sqlite3
+** CAPI3REF: Deprecated Tracing And Profiling Functions
+** DEPRECATED
**
** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
** instead of the routines described here.
@@ -3975,8 +4001,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** [[OPEN_EXRESCODE]] ^([SQLITE_OPEN_EXRESCODE]
** The database connection comes up in "extended result code mode".
-** In other words, the database behaves has if
-** [sqlite3_extended_result_codes(db,1)] where called on the database
+** In other words, the database behaves as if
+** [sqlite3_extended_result_codes(db,1)] were called on the database
** connection as soon as the connection is created. In addition to setting
** the extended result code mode, this flag also causes [sqlite3_open_v2()]
** to return an extended result code.
@@ -4661,13 +4687,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** and sqlite3_prepare16_v3() use UTF-16.
**
** ^If the nByte argument is negative, then zSql is read up to the
-** first zero terminator. ^If nByte is positive, then it is the
-** number of bytes read from zSql. ^If nByte is zero, then no prepared
+** first zero terminator. ^If nByte is positive, then it is the maximum
+** number of bytes read from zSql. When nByte is positive, zSql is read
+** up to the first zero terminator or until the nByte bytes have been read,
+** whichever comes first. ^If nByte is zero, then no prepared
** statement is generated.
** If the caller knows that the supplied string is nul-terminated, then
** there is a small performance advantage to passing an nByte parameter that
** is the number of bytes in the input string including
** the nul-terminator.
+** Note that nByte measure the length of the input in bytes, not
+** characters, even for the UTF-16 interfaces.
**
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
** past the end of the first SQL statement in zSql. These routines only
@@ -6040,7 +6070,7 @@ SQLITE_API int sqlite3_create_window_function(
** This flag instructs SQLite to omit some corner-case optimizations that
** might disrupt the operation of the [sqlite3_value_subtype()] function,
** causing it to return zero rather than the correct subtype().
-** SQL functions that invokes [sqlite3_value_subtype()] should have this
+** All SQL functions that invoke [sqlite3_value_subtype()] should have this
** property. If the SQLITE_SUBTYPE property is omitted, then the return
** value from [sqlite3_value_subtype()] might sometimes be zero even though
** a non-zero subtype was specified by the function argument expression.
@@ -6056,6 +6086,15 @@ SQLITE_API int sqlite3_create_window_function(
** [sqlite3_result_subtype()] should avoid setting this property, as the
** purpose of this property is to disable certain optimizations that are
** incompatible with subtypes.
+**
+** [[SQLITE_SELFORDER1]] SQLITE_SELFORDER1
+** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
+** that internally orders the values provided to the first argument. The
+** ordered-set aggregate SQL notation with a single ORDER BY term can be
+** used to invoke this function. If the ordered-set aggregate notation is
+** used on a function that lacks this flag, then an error is raised. Note
+** that the ordered-set aggregate syntax is only available if SQLite is
+** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
**
**
*/
@@ -6064,6 +6103,7 @@ SQLITE_API int sqlite3_create_window_function(
#define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000
#define SQLITE_RESULT_SUBTYPE 0x001000000
+#define SQLITE_SELFORDER1 0x002000000
/*
** CAPI3REF: Deprecated Functions
@@ -6261,7 +6301,7 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*);
** one SQL function to another. Use the [sqlite3_result_subtype()]
** routine to set the subtype for the return value of an SQL function.
**
-** Every [application-defined SQL function] that invoke this interface
+** Every [application-defined SQL function] that invokes this interface
** should include the [SQLITE_SUBTYPE] property in the text
** encoding argument when the function is [sqlite3_create_function|registered].
** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype()
@@ -7328,6 +7368,12 @@ SQLITE_API int sqlite3_autovacuum_pages(
** The exceptions defined in this paragraph might change in a future
** release of SQLite.
**
+** Whether the update hook is invoked before or after the
+** corresponding change is currently unspecified and may differ
+** depending on the type of change. Do not rely on the order of the
+** hook call with regards to the final result of the operation which
+** triggers the hook.
+**
** 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
@@ -7867,9 +7913,11 @@ struct sqlite3_module {
** will be returned by the strategy.
**
** The xBestIndex method may optionally populate the idxFlags field with a
-** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
-** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
-** assumes that the strategy may visit at most one row.
+** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
+** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
+** output to show the idxNum has hex instead of as decimal. Another flag is
+** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
+** return at most one row.
**
** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
** SQLite also assumes that if a call to the xUpdate() method is made as
@@ -7933,7 +7981,9 @@ struct sqlite3_index_info {
** [sqlite3_index_info].idxFlags field to some combination of
** these bits.
*/
-#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
+#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */
+#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */
+ /* in EXPLAIN QUERY PLAN */
/*
** CAPI3REF: Virtual Table Constraint Operator Codes
@@ -8792,6 +8842,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
+#define SQLITE_TESTCTRL_GETOPT 16
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -8811,7 +8862,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_TRACEFLAGS 31
#define SQLITE_TESTCTRL_TUNE 32
#define SQLITE_TESTCTRL_LOGEST 33
-#define SQLITE_TESTCTRL_USELONGDOUBLE 34
+#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */
#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */
/*
@@ -8825,7 +8876,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
** The sqlite3_keyword_count() interface returns the number of distinct
** keywords understood by SQLite.
**
-** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
+** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and
** makes *Z point to that keyword expressed as UTF8 and writes the number
** of bytes in the keyword into *L. The string that *Z points to is not
** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
@@ -9803,6 +9854,16 @@ typedef struct sqlite3_backup sqlite3_backup;
** APIs are not strictly speaking threadsafe. If they are invoked at the
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
+**
+** Alternatives To Using The Backup API
+**
+** Other techniques for safely creating a consistent backup of an SQLite
+** database include:
+**
+**
+** - The [VACUUM INTO] command.
+**
- The [sqlite3_rsync] utility program.
+**
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
@@ -10420,24 +10481,45 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
**
** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
** that the query planner does not need the rows returned in any particular
-** order, as long as rows with the same values in all "aOrderBy" columns
-** are adjacent.)^ ^(Furthermore, only a single row for each particular
-** combination of values in the columns identified by the "aOrderBy" field
-** needs to be returned.)^ ^It is always ok for two or more rows with the same
-** values in all "aOrderBy" columns to be returned, as long as all such rows
-** are adjacent. ^The virtual table may, if it chooses, omit extra rows
-** that have the same value for all columns identified by "aOrderBy".
-** ^However omitting the extra rows is optional.
+** order, as long as rows with the same values in all columns identified
+** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows
+** contain the same values for all columns identified by "colUsed", all but
+** one such row may optionally be omitted from the result.)^
+** The virtual table is not required to omit rows that are duplicates
+** over the "colUsed" columns, but if the virtual table can do that without
+** too much extra effort, it could potentially help the query to run faster.
** This mode is used for a DISTINCT query.
**
-** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
-** that the query planner needs only distinct rows but it does need the
-** rows to be sorted.)^ ^The virtual table implementation is free to omit
-** rows that are identical in all aOrderBy columns, if it wants to, but
-** it is not required to omit any rows. This mode is used for queries
+** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the
+** virtual table must return rows in the order defined by "aOrderBy" as
+** if the sqlite3_vtab_distinct() interface had returned 0. However if
+** two or more rows in the result have the same values for all columns
+** identified by "colUsed", then all but one such row may optionally be
+** omitted.)^ Like when the return value is 2, the virtual table
+** is not required to omit rows that are duplicates over the "colUsed"
+** columns, but if the virtual table can do that without
+** too much extra effort, it could potentially help the query to run faster.
+** This mode is used for queries
** that have both DISTINCT and ORDER BY clauses.
**
**
+**
The following table summarizes the conditions under which the
+** virtual table is allowed to set the "orderByConsumed" flag based on
+** the value returned by sqlite3_vtab_distinct(). This table is a
+** restatement of the previous four paragraphs:
+**
+**
+**
+** | sqlite3_vtab_distinct() return value
+** | Rows are returned in aOrderBy order
+** | Rows with the same value in all aOrderBy columns are adjacent
+** | Duplicates over all colUsed columns may be omitted
+** |
| 0 | yes | yes | no
+** |
| 1 | no | yes | no
+** |
| 2 | no | yes | yes
+** |
| 3 | yes | yes | yes
+** |
+**
** ^For the purposes of comparing virtual table output values to see if the
** values are same value for sorting purposes, two NULL values are considered
** to be the same. In other words, the comparison operator is "IS"
@@ -11050,6 +11132,14 @@ typedef struct sqlite3_snapshot {
** If there is not already a read-transaction open on schema S when
** this function is called, one is opened automatically.
**
+** If a read-transaction is opened by this function, then it is guaranteed
+** that the returned snapshot object may not be invalidated by a database
+** writer or checkpointer until after the read-transaction is closed. This
+** is not guaranteed if a read-transaction is already open when this
+** function is called. In that case, any subsequent write or checkpoint
+** operation on the database may invalidate the returned snapshot handle,
+** even while the read-transaction remains open.
+**
** The following must be true for this function to succeed. If any of
** the following statements are false when sqlite3_snapshot_get() is
** called, SQLITE_ERROR is returned. The final value of *P is undefined
@@ -12552,6 +12642,30 @@ SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const c
*/
SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+/*
+** CAPI3REF: Add A Single Change To A Changegroup
+** METHOD: sqlite3_changegroup
+**
+** This function adds the single change currently indicated by the iterator
+** passed as the second argument to the changegroup object. The rules for
+** adding the change are just as described for [sqlite3changegroup_add()].
+**
+** If the change is successfully added to the changegroup, SQLITE_OK is
+** returned. Otherwise, an SQLite error code is returned.
+**
+** The iterator must point to a valid entry when this function is called.
+** If it does not, SQLITE_ERROR is returned and no change is added to the
+** changegroup. Additionally, the iterator must not have been opened with
+** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also
+** returned.
+*/
+SQLITE_API int sqlite3changegroup_add_change(
+ sqlite3_changegroup*,
+ sqlite3_changeset_iter*
+);
+
+
+
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
** METHOD: sqlite3_changegroup
@@ -13356,8 +13470,8 @@ struct Fts5PhraseIter {
** EXTENSION API FUNCTIONS
**
** xUserData(pFts):
-** Return a copy of the context pointer the extension function was
-** registered with.
+** Return a copy of the pUserData pointer passed to the xCreateFunction()
+** API when the extension function was registered.
**
** xColumnTotalSize(pFts, iCol, pnToken):
** If parameter iCol is less than zero, set output variable *pnToken
@@ -13539,6 +13653,10 @@ struct Fts5PhraseIter {
** (i.e. if it is a contentless table), then this API always iterates
** through an empty set (all calls to xPhraseFirst() set iCol to -1).
**
+** In all cases, matches are visited in (column ASC, offset ASC) order.
+** i.e. all those in column 0, sorted by offset, followed by those in
+** column 1, etc.
+**
** xPhraseNext()
** See xPhraseFirst above.
**
@@ -13605,9 +13723,32 @@ struct Fts5PhraseIter {
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
+**
+** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
+** If parameter iCol is less than zero, or greater than or equal to the
+** number of columns in the table, SQLITE_RANGE is returned.
+**
+** Otherwise, this function attempts to retrieve the locale associated
+** with column iCol of the current row. Usually, there is no associated
+** locale, and output parameters (*pzLocale) and (*pnLocale) are set
+** to NULL and 0, respectively. However, if the fts5_locale() function
+** was used to associate a locale with the value when it was inserted
+** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
+** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
+** is set to the size in bytes of the buffer, not including the
+** nul-terminator.
+**
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an
+** SQLite error code is returned. The final value of the output parameters
+** is undefined in this case.
+**
+** xTokenize_v2:
+** Tokenize text using the tokenizer belonging to the FTS5 table. This
+** API is the same as the xTokenize() API, except that it allows a tokenizer
+** locale to be specified.
*/
struct Fts5ExtensionApi {
- int iVersion; /* Currently always set to 3 */
+ int iVersion; /* Currently always set to 4 */
void *(*xUserData)(Fts5Context*);
@@ -13649,6 +13790,15 @@ struct Fts5ExtensionApi {
const char **ppToken, int *pnToken
);
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
+
+ /* Below this point are iVersion>=4 only */
+ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xTokenize_v2)(Fts5Context*,
+ const char *pText, int nText, /* Text to tokenize */
+ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
};
/*
@@ -13669,7 +13819,7 @@ struct Fts5ExtensionApi {
** A tokenizer instance is required to actually tokenize text.
**
** The first argument passed to this function is a copy of the (void*)
-** pointer provided by the application when the fts5_tokenizer object
+** pointer provided by the application when the fts5_tokenizer_v2 object
** was registered with FTS5 (the third argument to xCreateTokenizer()).
** The second and third arguments are an array of nul-terminated strings
** containing the tokenizer arguments, if any, specified following the
@@ -13693,7 +13843,7 @@ struct Fts5ExtensionApi {
** argument passed to this function is a pointer to an Fts5Tokenizer object
** returned by an earlier call to xCreate().
**
-** The second argument indicates the reason that FTS5 is requesting
+** The third argument indicates the reason that FTS5 is requesting
** tokenization of the supplied text. This is always one of the following
** four values:
**
@@ -13717,6 +13867,13 @@ struct Fts5ExtensionApi {
** on a columnsize=0 database.
**
**
+** The sixth and seventh arguments passed to xTokenize() - pLocale and
+** nLocale - are a pointer to a buffer containing the locale to use for
+** tokenization (e.g. "en_US") and its size in bytes, respectively. The
+** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
+** which case nLocale is always 0) to indicate that the tokenizer should
+** use its default locale.
+**
** For each token in the input string, the supplied callback xToken() must
** be invoked. The first argument to it should be a copy of the pointer
** passed as the second argument to xTokenize(). The third and fourth
@@ -13740,6 +13897,30 @@ struct Fts5ExtensionApi {
** may abandon the tokenization and return any error code other than
** SQLITE_OK or SQLITE_DONE.
**
+** If the tokenizer is registered using an fts5_tokenizer_v2 object,
+** then the xTokenize() method has two additional arguments - pLocale
+** and nLocale. These specify the locale that the tokenizer should use
+** for the current request. If pLocale and nLocale are both 0, then the
+** tokenizer should use its default locale. Otherwise, pLocale points to
+** an nLocale byte buffer containing the name of the locale to use as utf-8
+** text. pLocale is not nul-terminated.
+**
+** FTS5_TOKENIZER
+**
+** There is also an fts5_tokenizer object. This is an older, deprecated,
+** version of fts5_tokenizer_v2. It is similar except that:
+**
+**
+** - There is no "iVersion" field, and
+**
- The xTokenize() method does not take a locale argument.
+**
+**
+** Legacy fts5_tokenizer tokenizers must be registered using the
+** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
+**
+** Tokenizer implementations registered using either API may be retrieved
+** using both xFindTokenizer() and xFindTokenizer_v2().
+**
** SYNONYM SUPPORT
**
** Custom tokenizers may also support synonyms. Consider a case in which a
@@ -13848,6 +14029,33 @@ struct Fts5ExtensionApi {
** inefficient.
*/
typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
+struct fts5_tokenizer_v2 {
+ int iVersion; /* Currently always 2 */
+
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
+ int (*xTokenize)(Fts5Tokenizer*,
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ const char *pText, int nText,
+ const char *pLocale, int nLocale,
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/*
+** New code should use the fts5_tokenizer_v2 type to define tokenizer
+** implementations. The following type is included for legacy applications
+** that still use it.
+*/
typedef struct fts5_tokenizer fts5_tokenizer;
struct fts5_tokenizer {
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
@@ -13867,6 +14075,7 @@ struct fts5_tokenizer {
);
};
+
/* Flags that may be passed as the third argument to xTokenize() */
#define FTS5_TOKENIZE_QUERY 0x0001
#define FTS5_TOKENIZE_PREFIX 0x0002
@@ -13886,7 +14095,7 @@ struct fts5_tokenizer {
*/
typedef struct fts5_api fts5_api;
struct fts5_api {
- int iVersion; /* Currently always set to 2 */
+ int iVersion; /* Currently always set to 3 */
/* Create a new tokenizer */
int (*xCreateTokenizer)(
@@ -13913,6 +14122,25 @@ struct fts5_api {
fts5_extension_function xFunction,
void (*xDestroy)(void*)
);
+
+ /* APIs below this point are only available if iVersion>=3 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer_v2)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pUserData,
+ fts5_tokenizer_v2 *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer_v2)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppUserData,
+ fts5_tokenizer_v2 **ppTokenizer
+ );
};
/*
@@ -14911,6 +15139,8 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *);
# define SQLITE_OMIT_ALTERTABLE
#endif
+#define SQLITE_DIGIT_SEPARATOR '_'
+
/*
** Return true (non-zero) if the input is an integer that is too large
** to fit in 32-bits. This macro is used inside of various testcase()
@@ -15080,134 +15310,134 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_OR 47
#define TK_AND 48
#define TK_IS 49
-#define TK_MATCH 50
-#define TK_LIKE_KW 51
-#define TK_BETWEEN 52
-#define TK_IN 53
-#define TK_ISNULL 54
-#define TK_NOTNULL 55
-#define TK_NE 56
-#define TK_EQ 57
-#define TK_GT 58
-#define TK_LE 59
-#define TK_LT 60
-#define TK_GE 61
-#define TK_ESCAPE 62
-#define TK_ID 63
-#define TK_COLUMNKW 64
-#define TK_DO 65
-#define TK_FOR 66
-#define TK_IGNORE 67
-#define TK_INITIALLY 68
-#define TK_INSTEAD 69
-#define TK_NO 70
-#define TK_KEY 71
-#define TK_OF 72
-#define TK_OFFSET 73
-#define TK_PRAGMA 74
-#define TK_RAISE 75
-#define TK_RECURSIVE 76
-#define TK_REPLACE 77
-#define TK_RESTRICT 78
-#define TK_ROW 79
-#define TK_ROWS 80
-#define TK_TRIGGER 81
-#define TK_VACUUM 82
-#define TK_VIEW 83
-#define TK_VIRTUAL 84
-#define TK_WITH 85
-#define TK_NULLS 86
-#define TK_FIRST 87
-#define TK_LAST 88
-#define TK_CURRENT 89
-#define TK_FOLLOWING 90
-#define TK_PARTITION 91
-#define TK_PRECEDING 92
-#define TK_RANGE 93
-#define TK_UNBOUNDED 94
-#define TK_EXCLUDE 95
-#define TK_GROUPS 96
-#define TK_OTHERS 97
-#define TK_TIES 98
-#define TK_GENERATED 99
-#define TK_ALWAYS 100
-#define TK_MATERIALIZED 101
-#define TK_REINDEX 102
-#define TK_RENAME 103
-#define TK_CTIME_KW 104
-#define TK_ANY 105
-#define TK_BITAND 106
-#define TK_BITOR 107
-#define TK_LSHIFT 108
-#define TK_RSHIFT 109
-#define TK_PLUS 110
-#define TK_MINUS 111
-#define TK_STAR 112
-#define TK_SLASH 113
-#define TK_REM 114
-#define TK_CONCAT 115
-#define TK_PTR 116
-#define TK_COLLATE 117
-#define TK_BITNOT 118
-#define TK_ON 119
-#define TK_INDEXED 120
-#define TK_STRING 121
-#define TK_JOIN_KW 122
-#define TK_CONSTRAINT 123
-#define TK_DEFAULT 124
-#define TK_NULL 125
-#define TK_PRIMARY 126
-#define TK_UNIQUE 127
-#define TK_CHECK 128
-#define TK_REFERENCES 129
-#define TK_AUTOINCR 130
-#define TK_INSERT 131
-#define TK_DELETE 132
-#define TK_UPDATE 133
-#define TK_SET 134
-#define TK_DEFERRABLE 135
-#define TK_FOREIGN 136
-#define TK_DROP 137
-#define TK_BLOB 138
-#define TK_UNION 139
-#define TK_ALL 140
-#define TK_EXCEPT 141
-#define TK_INTERSECT 142
-#define TK_SELECT 143
-#define TK_VALUES 144
-#define TK_DISTINCT 145
-#define TK_DOT 146
-#define TK_FROM 147
-#define TK_JOIN 148
-#define TK_USING 149
-#define TK_ORDER 150
-#define TK_GROUP 151
-#define TK_HAVING 152
-#define TK_LIMIT 153
-#define TK_WHERE 154
-#define TK_RETURNING 155
-#define TK_INTO 156
-#define TK_NOTHING 157
-#define TK_FLOAT 158
-#define TK_INTEGER 159
-#define TK_VARIABLE 160
-#define TK_CASE 161
-#define TK_WHEN 162
-#define TK_THEN 163
-#define TK_ELSE 164
-#define TK_INDEX 165
-#define TK_ALTER 166
-#define TK_ADD 167
-#define TK_WINDOW 168
-#define TK_OVER 169
-#define TK_FILTER 170
-#define TK_COLUMN 171
-#define TK_AGG_FUNCTION 172
-#define TK_AGG_COLUMN 173
-#define TK_TRUEFALSE 174
-#define TK_ISNOT 175
-#define TK_UMINUS 176
-#define TK_UPLUS 177
+#define TK_ISNOT 50
+#define TK_MATCH 51
+#define TK_LIKE_KW 52
+#define TK_BETWEEN 53
+#define TK_IN 54
+#define TK_ISNULL 55
+#define TK_NOTNULL 56
+#define TK_NE 57
+#define TK_EQ 58
+#define TK_GT 59
+#define TK_LE 60
+#define TK_LT 61
+#define TK_GE 62
+#define TK_ESCAPE 63
+#define TK_ID 64
+#define TK_COLUMNKW 65
+#define TK_DO 66
+#define TK_FOR 67
+#define TK_IGNORE 68
+#define TK_INITIALLY 69
+#define TK_INSTEAD 70
+#define TK_NO 71
+#define TK_KEY 72
+#define TK_OF 73
+#define TK_OFFSET 74
+#define TK_PRAGMA 75
+#define TK_RAISE 76
+#define TK_RECURSIVE 77
+#define TK_REPLACE 78
+#define TK_RESTRICT 79
+#define TK_ROW 80
+#define TK_ROWS 81
+#define TK_TRIGGER 82
+#define TK_VACUUM 83
+#define TK_VIEW 84
+#define TK_VIRTUAL 85
+#define TK_WITH 86
+#define TK_NULLS 87
+#define TK_FIRST 88
+#define TK_LAST 89
+#define TK_CURRENT 90
+#define TK_FOLLOWING 91
+#define TK_PARTITION 92
+#define TK_PRECEDING 93
+#define TK_RANGE 94
+#define TK_UNBOUNDED 95
+#define TK_EXCLUDE 96
+#define TK_GROUPS 97
+#define TK_OTHERS 98
+#define TK_TIES 99
+#define TK_GENERATED 100
+#define TK_ALWAYS 101
+#define TK_MATERIALIZED 102
+#define TK_REINDEX 103
+#define TK_RENAME 104
+#define TK_CTIME_KW 105
+#define TK_ANY 106
+#define TK_BITAND 107
+#define TK_BITOR 108
+#define TK_LSHIFT 109
+#define TK_RSHIFT 110
+#define TK_PLUS 111
+#define TK_MINUS 112
+#define TK_STAR 113
+#define TK_SLASH 114
+#define TK_REM 115
+#define TK_CONCAT 116
+#define TK_PTR 117
+#define TK_COLLATE 118
+#define TK_BITNOT 119
+#define TK_ON 120
+#define TK_INDEXED 121
+#define TK_STRING 122
+#define TK_JOIN_KW 123
+#define TK_CONSTRAINT 124
+#define TK_DEFAULT 125
+#define TK_NULL 126
+#define TK_PRIMARY 127
+#define TK_UNIQUE 128
+#define TK_CHECK 129
+#define TK_REFERENCES 130
+#define TK_AUTOINCR 131
+#define TK_INSERT 132
+#define TK_DELETE 133
+#define TK_UPDATE 134
+#define TK_SET 135
+#define TK_DEFERRABLE 136
+#define TK_FOREIGN 137
+#define TK_DROP 138
+#define TK_BLOB 139
+#define TK_UNION 140
+#define TK_ALL 141
+#define TK_EXCEPT 142
+#define TK_INTERSECT 143
+#define TK_SELECT 144
+#define TK_VALUES 145
+#define TK_DISTINCT 146
+#define TK_DOT 147
+#define TK_FROM 148
+#define TK_JOIN 149
+#define TK_USING 150
+#define TK_ORDER 151
+#define TK_GROUP 152
+#define TK_HAVING 153
+#define TK_LIMIT 154
+#define TK_WHERE 155
+#define TK_RETURNING 156
+#define TK_INTO 157
+#define TK_NOTHING 158
+#define TK_FLOAT 159
+#define TK_INTEGER 160
+#define TK_VARIABLE 161
+#define TK_CASE 162
+#define TK_WHEN 163
+#define TK_THEN 164
+#define TK_ELSE 165
+#define TK_INDEX 166
+#define TK_ALTER 167
+#define TK_ADD 168
+#define TK_WINDOW 169
+#define TK_OVER 170
+#define TK_FILTER 171
+#define TK_COLUMN 172
+#define TK_AGG_FUNCTION 173
+#define TK_AGG_COLUMN 174
+#define TK_TRUEFALSE 175
+#define TK_UPLUS 176
+#define TK_UMINUS 177
#define TK_TRUTH 178
#define TK_REGISTER 179
#define TK_VECTOR 180
@@ -15216,8 +15446,9 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_ASTERISK 183
#define TK_SPAN 184
#define TK_ERROR 185
-#define TK_SPACE 186
-#define TK_ILLEGAL 187
+#define TK_QNUMBER 186
+#define TK_SPACE 187
+#define TK_ILLEGAL 188
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -15226,6 +15457,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#include
#include
#include
+#include
/*
** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY.
@@ -15246,7 +15478,8 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite_int64
# define float sqlite_int64
-# define LONGDOUBLE_TYPE sqlite_int64
+# define fabs(X) ((X)<0?-(X):(X))
+# define sqlite3IsOverflow(X) 0
# ifndef SQLITE_BIG_DBL
# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
# endif
@@ -15421,9 +15654,6 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
# define INT8_TYPE signed char
# endif
#endif
-#ifndef LONGDOUBLE_TYPE
-# define LONGDOUBLE_TYPE long double
-#endif
typedef sqlite_int64 i64; /* 8-byte signed integer */
typedef sqlite_uint64 u64; /* 8-byte unsigned integer */
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
@@ -15479,7 +15709,7 @@ typedef INT16_TYPE LogEst;
# define SQLITE_PTRSIZE __SIZEOF_POINTER__
# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(_M_ARM) || defined(__arm__) || defined(__x86) || \
- (defined(__APPLE__) && defined(__POWERPC__)) || \
+ (defined(__APPLE__) && defined(__ppc__)) || \
(defined(__TOS_AIX__) && !defined(__64BIT__))
# define SQLITE_PTRSIZE 4
# else
@@ -15716,6 +15946,7 @@ SQLITE_PRIVATE u32 sqlite3TreeTrace;
** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing
** 0x00020000 Transform DISTINCT into GROUP BY
** 0x00040000 SELECT tree dump after all code has been generated
+** 0x00080000 NOT NULL strength reduction
*/
/*
@@ -15746,7 +15977,7 @@ SQLITE_PRIVATE u32 sqlite3WhereTrace;
** 0x00000010 Display sqlite3_index_info xBestIndex calls
** 0x00000020 Range an equality scan metrics
** 0x00000040 IN operator decisions
-** 0x00000080 WhereLoop cost adjustements
+** 0x00000080 WhereLoop cost adjustments
** 0x00000100
** 0x00000200 Covering index decisions
** 0x00000400 OR optimization
@@ -15922,6 +16153,7 @@ typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;
+typedef struct Subquery Subquery;
typedef struct SrcItem SrcItem;
typedef struct SrcList SrcList;
typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
@@ -16819,6 +17051,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursor(
);
SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void);
SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(Btree*,BtCursor*);
+#endif
SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
@@ -16910,6 +17145,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck(
sqlite3 *db, /* Database connection that is running the check */
Btree *p, /* The btree to be checked */
Pgno *aRoot, /* An array of root pages numbers for individual trees */
+ sqlite3_value *aCnt, /* OUT: entry counts for each btree in aRoot[] */
int nRoot, /* Number of entries in aRoot[] */
int mxErr, /* Stop reporting errors after this many */
int *pnErr, /* OUT: Write number of errors seen to this variable */
@@ -17036,6 +17272,19 @@ typedef struct Vdbe Vdbe;
*/
typedef struct sqlite3_value Mem;
typedef struct SubProgram SubProgram;
+typedef struct SubrtnSig SubrtnSig;
+
+/*
+** A signature for a reusable subroutine that materializes the RHS of
+** an IN operator.
+*/
+struct SubrtnSig {
+ int selId; /* SELECT-id for the SELECT statement on the RHS */
+ char *zAff; /* Affinity of the overall IN expression */
+ int iTable; /* Ephemeral table generated by the subroutine */
+ int iAddr; /* Subroutine entry address */
+ int regReturn; /* Register used to hold return address */
+};
/*
** A single instruction of the virtual machine has an opcode
@@ -17064,6 +17313,7 @@ struct VdbeOp {
u32 *ai; /* Used when p4type is P4_INTARRAY */
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
Table *pTab; /* Used when p4type is P4_TABLE */
+ SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */
#ifdef SQLITE_ENABLE_CURSOR_HINTS
Expr *pExpr; /* Used when p4type is P4_EXPR */
#endif
@@ -17131,6 +17381,7 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */
+#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */
/* Error message codes for OP_Halt */
#define P5_ConstraintNotNull 1
@@ -17180,12 +17431,12 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Vacuum 5
#define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */
#define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */
-#define OP_Init 8 /* jump, synopsis: Start at P2 */
+#define OP_Init 8 /* jump0, synopsis: Start at P2 */
#define OP_Goto 9 /* jump */
#define OP_Gosub 10 /* jump */
-#define OP_InitCoroutine 11 /* jump */
-#define OP_Yield 12 /* jump */
-#define OP_MustBeInt 13 /* jump */
+#define OP_InitCoroutine 11 /* jump0 */
+#define OP_Yield 12 /* jump0 */
+#define OP_MustBeInt 13 /* jump0 */
#define OP_Jump 14 /* jump */
#define OP_Once 15 /* jump */
#define OP_If 16 /* jump */
@@ -17193,22 +17444,22 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */
#define OP_IfNullRow 19 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
#define OP_Not 20 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
-#define OP_SeekLT 21 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekLE 22 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekGT 24 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekLT 21 /* jump0, synopsis: key=r[P3@P4] */
+#define OP_SeekLE 22 /* jump0, synopsis: key=r[P3@P4] */
+#define OP_SeekGE 23 /* jump0, synopsis: key=r[P3@P4] */
+#define OP_SeekGT 24 /* jump0, synopsis: key=r[P3@P4] */
#define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */
#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */
#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */
#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */
#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */
+#define OP_SeekRowid 30 /* jump0, synopsis: intkey=r[P3] */
#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */
-#define OP_Last 32 /* jump */
-#define OP_IfSmaller 33 /* jump */
+#define OP_Last 32 /* jump0 */
+#define OP_IfSizeBetween 33 /* jump */
#define OP_SorterSort 34 /* jump */
#define OP_Sort 35 /* jump */
-#define OP_Rewind 36 /* jump */
+#define OP_Rewind 36 /* jump0 */
#define OP_SorterNext 37 /* jump */
#define OP_Prev 38 /* jump */
#define OP_Next 39 /* jump */
@@ -17218,7 +17469,7 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IdxGE 43 /* jump, synopsis: key=r[P3@P4] */
#define OP_RowSetRead 44 /* jump, synopsis: r[P3]=rowset(P1) */
#define OP_RowSetTest 45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 46 /* jump */
+#define OP_Program 46 /* jump0 */
#define OP_Or 47 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
#define OP_And 48 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
#define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
@@ -17226,16 +17477,16 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IfNotZero 51 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
#define OP_DecrJumpZero 52 /* jump, synopsis: if (--r[P1])==0 goto P2 */
#define OP_IncrVacuum 53 /* jump */
-#define OP_IsNull 54 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull 55 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 56 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
-#define OP_Eq 57 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
-#define OP_Gt 58 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
-#define OP_Le 59 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
-#define OP_Lt 60 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */
-#define OP_ElseEq 62 /* jump, same as TK_ESCAPE */
-#define OP_VNext 63 /* jump */
+#define OP_VNext 54 /* jump */
+#define OP_IsNull 55 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 56 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 57 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+#define OP_Eq 58 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
+#define OP_Gt 59 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
+#define OP_Le 60 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
+#define OP_Lt 61 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */
+#define OP_ElseEq 63 /* jump, same as TK_ESCAPE */
#define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */
#define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */
#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
@@ -17250,7 +17501,7 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
#define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
#define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1) */
#define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
#define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
#define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */
@@ -17278,23 +17529,23 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_OpenRead 103 /* synopsis: root=P2 iDb=P3 */
#define OP_OpenWrite 104 /* synopsis: root=P2 iDb=P3 */
#define OP_OpenDup 105
-#define OP_BitAnd 106 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 107 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 108 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
-#define OP_Add 110 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 111 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 112 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 113 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 114 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 115 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */
+#define OP_OpenAutoindex 106 /* synopsis: nColumn=P2 */
+#define OP_BitAnd 107 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 108 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 109 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
+#define OP_Add 111 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 112 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 113 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 114 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 115 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 116 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
#define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */
-#define OP_BitNot 118 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
-#define OP_SorterOpen 119
+#define OP_SorterOpen 118
+#define OP_BitNot 119 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
#define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
-#define OP_String8 121 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_OpenPseudo 122 /* synopsis: P3 columns in r[P2] */
+#define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */
+#define OP_String8 122 /* same as TK_STRING, synopsis: r[P2]='P4' */
#define OP_Close 123
#define OP_ColumnsUsed 124
#define OP_SeekScan 125 /* synopsis: Scan-ahead up to P1 rows */
@@ -17330,8 +17581,8 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_DropIndex 155
#define OP_DropTrigger 156
#define OP_IntegrityCk 157
-#define OP_Real 158 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_RowSetAdd 159 /* synopsis: rowset(P1)=r[P2] */
+#define OP_RowSetAdd 158 /* synopsis: rowset(P1)=r[P2] */
+#define OP_Real 159 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
#define OP_Param 160
#define OP_FkCounter 161 /* synopsis: fkctr[P1]+=P2 */
#define OP_MemMax 162 /* synopsis: r[P1]=max(r[P1],r[P2]) */
@@ -17378,27 +17629,28 @@ typedef struct VdbeOpList VdbeOpList;
#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
#define OPFLG_OUT3 0x20 /* out3: P3 is an output */
#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */
+#define OPFLG_JUMP0 0x80 /* jump0: P2 might be zero */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\
-/* 8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\
-/* 16 */ 0x03, 0x03, 0x01, 0x01, 0x12, 0x49, 0x49, 0x49,\
-/* 24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\
-/* 32 */ 0x41, 0x01, 0x41, 0x41, 0x41, 0x01, 0x41, 0x41,\
-/* 40 */ 0x41, 0x41, 0x41, 0x41, 0x23, 0x0b, 0x01, 0x26,\
-/* 48 */ 0x26, 0x01, 0x03, 0x03, 0x03, 0x01, 0x03, 0x03,\
-/* 56 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x01, 0x41,\
+/* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\
+/* 16 */ 0x03, 0x03, 0x01, 0x01, 0x12, 0xc9, 0xc9, 0xc9,\
+/* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\
+/* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\
+/* 40 */ 0x41, 0x41, 0x41, 0x41, 0x23, 0x0b, 0x81, 0x26,\
+/* 48 */ 0x26, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41, 0x03,\
+/* 56 */ 0x03, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x01,\
/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\
/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
/* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\
/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x40, 0x40,\
-/* 104 */ 0x00, 0x40, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
-/* 112 */ 0x26, 0x26, 0x26, 0x26, 0x40, 0x40, 0x12, 0x00,\
-/* 120 */ 0x00, 0x10, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10,\
+/* 104 */ 0x00, 0x40, 0x40, 0x26, 0x26, 0x26, 0x26, 0x26,\
+/* 112 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x40, 0x00, 0x12,\
+/* 120 */ 0x00, 0x00, 0x10, 0x40, 0x00, 0x40, 0x40, 0x10,\
/* 128 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 136 */ 0x40, 0x00, 0x50, 0x00, 0x40, 0x04, 0x04, 0x00,\
/* 144 */ 0x40, 0x50, 0x40, 0x10, 0x00, 0x00, 0x10, 0x00,\
-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06,\
+/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10,\
/* 160 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 176 */ 0x40, 0x10, 0x50, 0x00, 0x40, 0x00, 0x10, 0x10,\
@@ -17546,6 +17798,8 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*);
+SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val);
+
SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*);
@@ -18152,6 +18406,10 @@ struct FuncDefHash {
};
#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
+#if defined(SQLITE_USER_AUTHENTICATION)
+# warning "The SQLITE_USER_AUTHENTICATION extension is deprecated. \
+ See ext/userauth/user-auth.txt for details."
+#endif
#ifdef SQLITE_USER_AUTHENTICATION
/*
** Information held in the "sqlite3" database connection object and used
@@ -18474,7 +18732,7 @@ struct sqlite3 {
#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */
#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */
/* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */
-#define SQLITE_PushDown 0x00001000 /* The push-down optimization */
+#define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */
#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */
#define SQLITE_SkipScan 0x00004000 /* Skip-scans */
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
@@ -18492,6 +18750,7 @@ struct sqlite3 {
#define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */
#define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */
#define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */
+#define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
/*
@@ -19047,8 +19306,7 @@ struct Table {
#define TF_HasStored 0x00000040 /* Has one or more STORED columns */
#define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */
#define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */
-#define TF_StatsUsed 0x00000100 /* Query planner decisions affected by
- ** Index.aiRowLogEst[] values */
+#define TF_MaybeReanalyze 0x00000100 /* Maybe run ANALYZE on this table */
#define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */
#define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */
#define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */
@@ -19108,6 +19366,15 @@ struct Table {
#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
+/* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is
+** available. By default, this macro is false
+*/
+#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
+# define ViewCanHaveRowid 0
+#else
+# define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0)
+#endif
+
/*
** Each foreign key constraint is an instance of the following structure.
**
@@ -19485,9 +19752,15 @@ struct AggInfo {
** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg.
** The assert()s that are part of this macro verify that constraint.
*/
+#ifndef NDEBUG
#define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I))
#define AggInfoFuncReg(A,I) \
(assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I))
+#else
+#define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I))
+#define AggInfoFuncReg(A,I) \
+ ((A)->iFirstReg+(A)->nColumn+(I))
+#endif
/*
** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
@@ -19668,7 +19941,7 @@ struct Expr {
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
#define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */
- /* 0x80000000 // Available */
+#define EP_SubtArg 0x80000000 /* Is argument to SQLITE_SUBTYPE function */
/* The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes.
@@ -19839,6 +20112,16 @@ struct IdList {
#define EU4_IDX 1 /* Uses IdList.a.u4.idx */
#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */
+/*
+** Details of the implementation of a subquery.
+*/
+struct Subquery {
+ Select *pSelect; /* A SELECT statement used in place of a table name */
+ int addrFillSub; /* Address of subroutine to initialize a subquery */
+ int regReturn; /* Register holding return address of addrFillSub */
+ int regResult; /* Registers holding results of a co-routine */
+};
+
/*
** The SrcItem object represents a single term in the FROM clause of a query.
** The SrcList object is mostly an array of SrcItems.
@@ -19851,27 +20134,40 @@ struct IdList {
** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used.
**
-** Union member validity:
+** Aggressive use of "union" helps keep the size of the object small. This
+** has been shown to boost performance, in addition to saving memory.
+** Access to union elements is gated by the following rules which should
+** always be checked, either by an if-statement or by an assert().
+**
+** Field Only access if this is true
+** --------------- -----------------------------------
+** u1.zIndexedBy fg.isIndexedBy
+** u1.pFuncArg fg.isTabFunc
+** u1.nRow !fg.isTabFunc && !fg.isIndexedBy
+**
+** u2.pIBIndex fg.isIndexedBy
+** u2.pCteUse fg.isCte
**
-** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc
-** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy
-** u2.pIBIndex fg.isIndexedBy && !fg.isCte
-** u2.pCteUse fg.isCte && !fg.isIndexedBy
+** u3.pOn !fg.isUsing
+** u3.pUsing fg.isUsing
+**
+** u4.zDatabase !fg.fixedSchema && !fg.isSubquery
+** u4.pSchema fg.fixedSchema
+** u4.pSubq fg.isSubquery
+**
+** See also the sqlite3SrcListDelete() routine for assert() statements that
+** check invariants on the fields of this object, especially the flags
+** inside the fg struct.
*/
struct SrcItem {
- Schema *pSchema; /* Schema to which this item is fixed */
- char *zDatabase; /* Name of database holding this table */
char *zName; /* Name of the table */
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
- Table *pTab; /* An SQL table corresponding to zName */
- Select *pSelect; /* A SELECT statement used in place of a table name */
- int addrFillSub; /* Address of subroutine to manifest a subquery */
- int regReturn; /* Register holding return address of addrFillSub */
- int regResult; /* Registers holding results of a co-routine */
+ Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */
struct {
u8 jointype; /* Type of join between this table and the previous */
unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
+ unsigned isSubquery :1; /* True if this term is a subquery */
unsigned isTabFunc :1; /* True if table-valued-function syntax */
unsigned isCorrelated :1; /* True if sub-query is correlated */
unsigned isMaterialized:1; /* This is a materialized view */
@@ -19884,21 +20180,30 @@ struct SrcItem {
unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */
unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
+ unsigned rowidUsed :1; /* The ROWID of this table is referenced */
+ unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */
+ unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */
} fg;
int iCursor; /* The VDBE cursor number used to access this table */
- union {
- Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
- IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
- } u3;
Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */
union {
char *zIndexedBy; /* Identifier from "INDEXED BY " clause */
ExprList *pFuncArg; /* Arguments to table-valued-function */
+ u32 nRow; /* Number of rows in a VALUES clause */
} u1;
union {
Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */
} u2;
+ union {
+ Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
+ IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
+ } u3;
+ union {
+ Schema *pSchema; /* Schema to which this item is fixed */
+ char *zDatabase; /* Name of database holding this table */
+ Subquery *pSubq; /* Description of a subquery */
+ } u4;
};
/*
@@ -19958,7 +20263,7 @@ struct SrcList {
#define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
#define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */
- /* 0x2000 not currently used */
+#define WHERE_KEEP_ALL_JOINS 0x2000 /* Do not do the omit-noop-join opt */
#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
/* 0x8000 not currently used */
@@ -20030,13 +20335,14 @@ struct NameContext {
#define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */
#define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */
#define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */
-#define NC_Complex 0x002000 /* True if a function or subquery seen */
+/* 0x002000 // available for reuse */
#define NC_AllowWin 0x004000 /* Window functions are allowed here */
#define NC_HasWin 0x008000 /* One or more window functions seen */
#define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */
#define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */
#define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */
#define NC_NoSelect 0x080000 /* Do not descend into sub-selects */
+#define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */
#define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */
/*
@@ -20060,6 +20366,7 @@ struct Upsert {
Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */
Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */
u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */
+ u8 isDup; /* True if 2nd or later with same pUpsertIdx */
/* Above this point is the parse tree for the ON CONFLICT clauses.
** The next group of fields stores intermediate data. */
void *pToFree; /* Free memory when deleting the Upsert object */
@@ -20149,14 +20456,17 @@ struct Select {
#define SF_View 0x0200000 /* SELECT statement is a view */
#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */
#define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */
-#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */
+#define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */
#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
+#define SF_Correlated 0x20000000 /* True if references the outer context */
-/* True if S exists and has SF_NestedFrom */
-#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
+/* True if SrcItem X is a subquery that has SF_NestedFrom */
+#define IsNestedFrom(X) \
+ ((X)->fg.isSubquery && \
+ ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0)
/*
** The results of a SELECT can be distributed in several ways, as defined
@@ -20186,7 +20496,11 @@ struct Select {
** SRT_Set The result must be a single column. Store each
** row of result as the key in table pDest->iSDParm.
** Apply the affinity pDest->affSdst before storing
-** results. Used to implement "IN (SELECT ...)".
+** results. if pDest->iSDParm2 is positive, then it is
+** a register holding a Bloom filter for the IN operator
+** that should be populated in addition to the
+** pDest->iSDParm table. This SRT is used to
+** implement "IN (SELECT ...)".
**
** SRT_EphemTab Create an temporary table pDest->iSDParm and store
** the result there. The cursor is left open after
@@ -20393,6 +20707,8 @@ struct Parse {
u8 disableLookaside; /* Number of times lookaside has been disabled */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */
+ u8 bHasWith; /* True if statement contains WITH */
+ u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
#endif
@@ -20688,7 +21004,7 @@ struct Returning {
};
/*
-** An objected used to accumulate the text of a string where we
+** An object used to accumulate the text of a string where we
** do not necessarily know how big the string will be in the end.
*/
struct sqlite3_str {
@@ -20702,7 +21018,7 @@ struct sqlite3_str {
};
#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */
#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
-#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
+#define SQLITE_PRINTF_MALLOCED 0x04 /* True if zText is allocated space */
#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
@@ -20780,7 +21096,6 @@ struct Sqlite3Config {
u8 bUseCis; /* Use covering indices for full-scans */
u8 bSmallMalloc; /* Avoid large memory allocations if true */
u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */
- u8 bUseLongDouble; /* Make use of long double */
#ifdef SQLITE_DEBUG
u8 bJsonSelfcheck; /* Double-check JSON parsing */
#endif
@@ -20830,6 +21145,11 @@ struct Sqlite3Config {
#endif
#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
+#endif
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW
+ ** feature is disabled. 0 if rowids can
+ ** occur in views. */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
@@ -21067,6 +21387,9 @@ struct Window {
** due to the SQLITE_SUBTYPE flag */
};
+SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow);
+SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal);
+
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*);
SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window*);
@@ -21147,15 +21470,6 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define SQLITE_ENABLE_FTS3 1
#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
-#endif
-
/*
** The following macros mimic the standard library functions toupper(),
** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
@@ -21286,10 +21600,13 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
# define EXP754 (((u64)0x7ff)<<52)
# define MAN754 ((((u64)1)<<52)-1)
# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
+# define IsOvfl(X) (((X)&EXP754)==EXP754)
SQLITE_PRIVATE int sqlite3IsNaN(double);
+SQLITE_PRIVATE int sqlite3IsOverflow(double);
#else
-# define IsNaN(X) 0
-# define sqlite3IsNaN(X) 0
+# define IsNaN(X) 0
+# define sqlite3IsNaN(X) 0
+# define sqlite3IsOVerflow(X) 0
#endif
/*
@@ -21381,6 +21698,7 @@ SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
SQLITE_PRIVATE void sqlite3Dequote(char*);
SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*);
SQLITE_PRIVATE void sqlite3DequoteToken(Token*);
+SQLITE_PRIVATE void sqlite3DequoteNumber(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*);
@@ -21411,7 +21729,7 @@ SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*)
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*);
-SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*);
+SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
@@ -21530,6 +21848,9 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
+SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*);
+SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*);
+SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, OnOrUsing*);
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
@@ -21579,6 +21900,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
+SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg);
SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int);
@@ -21634,16 +21956,14 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*);
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*);
SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
+SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
-SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
-SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int);
+SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
#endif
-SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*);
+SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
@@ -21774,7 +22094,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*);
SQLITE_PRIVATE int sqlite3Atoi(const char*);
#ifndef SQLITE_OMIT_UTF16
-SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
+SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar);
#endif
SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
@@ -21827,7 +22147,9 @@ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*);
SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int);
+#if !defined(SQLITE_OMIT_BLOB_LITERAL)
SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
+#endif
SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
@@ -22139,7 +22461,7 @@ SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8);
SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*);
SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
-SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
+SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*);
SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*);
SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*);
@@ -22529,6 +22851,9 @@ static const char * const sqlite3azCompileOpt[] = {
"ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN),
# endif
#endif
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ "ALLOW_ROWID_IN_VIEW",
+#endif
#ifdef SQLITE_ALLOW_URI_AUTHORITY
"ALLOW_URI_AUTHORITY",
#endif
@@ -22756,6 +23081,9 @@ static const char * const sqlite3azCompileOpt[] = {
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
"ENABLE_OFFSET_SQL_FUNC",
#endif
+#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
+ "ENABLE_ORDERED_SET_AGGREGATES",
+#endif
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
"ENABLE_OVERSIZE_CELL_CHECK",
#endif
@@ -23503,7 +23831,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
0, /* bSmallMalloc */
1, /* bExtraSchemaChecks */
- sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */
#ifdef SQLITE_DEBUG
0, /* bJsonSelfcheck */
#endif
@@ -23548,6 +23875,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
+#endif
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */
#endif
0, /* bLocaltimeFault */
0, /* xAltLocaltime */
@@ -24240,6 +24570,7 @@ struct PreUpdate {
Mem *aNew; /* Array of new.* values */
Table *pTab; /* Schema object being updated */
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
+ sqlite3_value **apDflt; /* Array of default values, if required */
};
/*
@@ -24904,13 +25235,14 @@ struct DateTime {
int tz; /* Timezone offset in minutes */
double s; /* Seconds */
char validJD; /* True (1) if iJD is valid */
- char rawS; /* Raw numeric value stored in s */
char validYMD; /* True (1) if Y,M,D are valid */
char validHMS; /* True (1) if h,m,s are valid */
- char validTZ; /* True (1) if tz is valid */
- char tzSet; /* Timezone was set explicitly */
- char isError; /* An overflow has occurred */
- char useSubsec; /* Display subsecond precision */
+ char nFloor; /* Days to implement "floor" */
+ unsigned rawS : 1; /* Raw numeric value stored in s */
+ unsigned isError : 1; /* An overflow has occurred */
+ unsigned useSubsec : 1; /* Display subsecond precision */
+ unsigned isUtc : 1; /* Time is known to be UTC */
+ unsigned isLocal : 1; /* Time is known to be localtime */
};
@@ -25008,6 +25340,8 @@ static int parseTimezone(const char *zDate, DateTime *p){
sgn = +1;
}else if( c=='Z' || c=='z' ){
zDate++;
+ p->isLocal = 0;
+ p->isUtc = 1;
goto zulu_time;
}else{
return c!=0;
@@ -25020,7 +25354,6 @@ static int parseTimezone(const char *zDate, DateTime *p){
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite3Isspace(*zDate) ){ zDate++; }
- p->tzSet = 1;
return *zDate!=0;
}
@@ -25064,7 +25397,6 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
p->m = m;
p->s = s + ms;
if( parseTimezone(zDate, p) ) return 1;
- p->validTZ = (p->tz!=0)?1:0;
return 0;
}
@@ -25103,23 +25435,48 @@ static void computeJD(DateTime *p){
Y--;
M += 12;
}
- A = Y/100;
- B = 2 - A + (A/4);
+ A = (Y+4800)/100;
+ B = 38 - A + (A/4);
X1 = 36525*(Y+4716)/100;
X2 = 306001*(M+1)/10000;
p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
p->validJD = 1;
if( p->validHMS ){
p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5);
- if( p->validTZ ){
+ if( p->tz ){
p->iJD -= p->tz*60000;
p->validYMD = 0;
p->validHMS = 0;
- p->validTZ = 0;
+ p->tz = 0;
+ p->isUtc = 1;
+ p->isLocal = 0;
}
}
}
+/*
+** Given the YYYY-MM-DD information current in p, determine if there
+** is day-of-month overflow and set nFloor to the number of days that
+** would need to be subtracted from the date in order to bring the
+** date back to the end of the month.
+*/
+static void computeFloor(DateTime *p){
+ assert( p->validYMD || p->isError );
+ assert( p->D>=0 && p->D<=31 );
+ assert( p->M>=0 && p->M<=12 );
+ if( p->D<=28 ){
+ p->nFloor = 0;
+ }else if( (1<M) & 0x15aa ){
+ p->nFloor = 0;
+ }else if( p->M!=2 ){
+ p->nFloor = (p->D==31);
+ }else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){
+ p->nFloor = p->D - 28;
+ }else{
+ p->nFloor = p->D - 29;
+ }
+}
+
/*
** Parse dates of the form
**
@@ -25158,12 +25515,16 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){
p->Y = neg ? -Y : Y;
p->M = M;
p->D = D;
- if( p->validTZ ){
+ computeFloor(p);
+ if( p->tz ){
computeJD(p);
}
return 0;
}
+
+static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */
+
/*
** Set the time to the current time reported by the VFS.
**
@@ -25173,6 +25534,9 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
p->iJD = sqlite3StmtCurrentTime(context);
if( p->iJD>0 ){
p->validJD = 1;
+ p->isUtc = 1;
+ p->isLocal = 0;
+ clearYMD_HMS_TZ(p);
return 0;
}else{
return 1;
@@ -25256,7 +25620,7 @@ static int validJulianDay(sqlite3_int64 iJD){
** Compute the Year, Month, and Day from the julian day number.
*/
static void computeYMD(DateTime *p){
- int Z, A, B, C, D, E, X1;
+ int Z, alpha, A, B, C, D, E, X1;
if( p->validYMD ) return;
if( !p->validJD ){
p->Y = 2000;
@@ -25267,8 +25631,8 @@ static void computeYMD(DateTime *p){
return;
}else{
Z = (int)((p->iJD + 43200000)/86400000);
- A = (int)((Z - 1867216.25)/36524.25);
- A = Z + 1 + A - (A/4);
+ alpha = (int)((Z + 32044.75)/36524.25) - 52;
+ A = Z + 1 + alpha - ((alpha+100)/4) + 25;
B = A + 1524;
C = (int)((B - 122.1)/365.25);
D = (36525*(C&32767))/100;
@@ -25311,7 +25675,7 @@ static void computeYMD_HMS(DateTime *p){
static void clearYMD_HMS_TZ(DateTime *p){
p->validYMD = 0;
p->validHMS = 0;
- p->validTZ = 0;
+ p->tz = 0;
}
#ifndef SQLITE_OMIT_LOCALTIME
@@ -25443,7 +25807,7 @@ static int toLocaltime(
p->validHMS = 1;
p->validJD = 0;
p->rawS = 0;
- p->validTZ = 0;
+ p->tz = 0;
p->isError = 0;
return SQLITE_OK;
}
@@ -25463,12 +25827,12 @@ static const struct {
float rLimit; /* Maximum NNN value for this transform */
float rXform; /* Constant used for this transform */
} aXformType[] = {
- { 6, "second", 4.6427e+14, 1.0 },
- { 6, "minute", 7.7379e+12, 60.0 },
- { 4, "hour", 1.2897e+11, 3600.0 },
- { 3, "day", 5373485.0, 86400.0 },
- { 5, "month", 176546.0, 2592000.0 },
- { 4, "year", 14713.0, 31536000.0 },
+ /* 0 */ { 6, "second", 4.6427e+14, 1.0 },
+ /* 1 */ { 6, "minute", 7.7379e+12, 60.0 },
+ /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 },
+ /* 3 */ { 3, "day", 5373485.0, 86400.0 },
+ /* 4 */ { 5, "month", 176546.0, 2592000.0 },
+ /* 5 */ { 4, "year", 14713.0, 31536000.0 },
};
/*
@@ -25500,14 +25864,20 @@ static void autoAdjustDate(DateTime *p){
** NNN.NNNN seconds
** NNN months
** NNN years
+** +/-YYYY-MM-DD HH:MM:SS.SSS
+** ceiling
+** floor
** start of month
** start of year
** start of week
** start of day
** weekday N
** unixepoch
+** auto
** localtime
** utc
+** subsec
+** subsecond
**
** Return 0 on success and 1 if there is any kind of error. If the error
** is in a system call (i.e. localtime()), then an error message is written
@@ -25538,6 +25908,37 @@ static int parseModifier(
}
break;
}
+ case 'c': {
+ /*
+ ** ceiling
+ **
+ ** Resolve day-of-month overflow by rolling forward into the next
+ ** month. As this is the default action, this modifier is really
+ ** a no-op that is only included for symmetry. See "floor".
+ */
+ if( sqlite3_stricmp(z, "ceiling")==0 ){
+ computeJD(p);
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ p->nFloor = 0;
+ }
+ break;
+ }
+ case 'f': {
+ /*
+ ** floor
+ **
+ ** Resolve day-of-month overflow by rolling back to the end of the
+ ** previous month.
+ */
+ if( sqlite3_stricmp(z, "floor")==0 ){
+ computeJD(p);
+ p->iJD -= p->nFloor*86400000;
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ }
+ break;
+ }
case 'j': {
/*
** julianday
@@ -25564,7 +25965,9 @@ static int parseModifier(
** show local time.
*/
if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
- rc = toLocaltime(p, pCtx);
+ rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx);
+ p->isUtc = 0;
+ p->isLocal = 1;
}
break;
}
@@ -25589,7 +25992,7 @@ static int parseModifier(
}
#ifndef SQLITE_OMIT_LOCALTIME
else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
- if( p->tzSet==0 ){
+ if( p->isUtc==0 ){
i64 iOrigJD; /* Original localtime */
i64 iGuess; /* Guess at the corresponding utc time */
int cnt = 0; /* Safety to prevent infinite loop */
@@ -25612,7 +26015,8 @@ static int parseModifier(
memset(p, 0, sizeof(*p));
p->iJD = iGuess;
p->validJD = 1;
- p->tzSet = 1;
+ p->isUtc = 1;
+ p->isLocal = 0;
}
rc = SQLITE_OK;
}
@@ -25632,7 +26036,7 @@ static int parseModifier(
&& r>=0.0 && r<7.0 && (n=(int)r)==r ){
sqlite3_int64 Z;
computeYMD_HMS(p);
- p->validTZ = 0;
+ p->tz = 0;
p->validJD = 0;
computeJD(p);
Z = ((p->iJD + 129600000)/86400000) % 7;
@@ -25672,7 +26076,7 @@ static int parseModifier(
p->h = p->m = 0;
p->s = 0.0;
p->rawS = 0;
- p->validTZ = 0;
+ p->tz = 0;
p->validJD = 0;
if( sqlite3_stricmp(z,"month")==0 ){
p->D = 1;
@@ -25743,6 +26147,7 @@ static int parseModifier(
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
p->Y += x;
p->M -= x*12;
+ computeFloor(p);
computeJD(p);
p->validHMS = 0;
p->validYMD = 0;
@@ -25789,11 +26194,12 @@ static int parseModifier(
z += n;
while( sqlite3Isspace(*z) ) z++;
n = sqlite3Strlen30(z);
- if( n>10 || n<3 ) break;
+ if( n<3 || n>10 ) break;
if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
computeJD(p);
assert( rc==1 );
rRounder = r<0 ? -0.5 : +0.5;
+ p->nFloor = 0;
for(i=0; iM += (int)r;
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
p->Y += x;
p->M -= x*12;
+ computeFloor(p);
p->validJD = 0;
r -= (int)r;
break;
}
case 5: { /* Special processing to add years */
int y = (int)r;
- assert( strcmp(aXformType[i].zName,"year")==0 );
+ assert( strcmp(aXformType[5].zName,"year")==0 );
computeYMD_HMS(p);
+ assert( p->M>=0 && p->M<=12 );
p->Y += y;
+ computeFloor(p);
p->validJD = 0;
r -= (int)r;
break;
@@ -26069,22 +26478,83 @@ static void dateFunc(
}
}
+/*
+** Compute the number of days after the most recent January 1.
+**
+** In other words, compute the zero-based day number for the
+** current year:
+**
+** Jan01 = 0, Jan02 = 1, ..., Jan31 = 30, Feb01 = 31, ...
+** Dec31 = 364 or 365.
+*/
+static int daysAfterJan01(DateTime *pDate){
+ DateTime jan01 = *pDate;
+ assert( jan01.validYMD );
+ assert( jan01.validHMS );
+ assert( pDate->validJD );
+ jan01.validJD = 0;
+ jan01.M = 1;
+ jan01.D = 1;
+ computeJD(&jan01);
+ return (int)((pDate->iJD-jan01.iJD+43200000)/86400000);
+}
+
+/*
+** Return the number of days after the most recent Monday.
+**
+** In other words, return the day of the week according
+** to this code:
+**
+** 0=Monday, 1=Tuesday, 2=Wednesday, ..., 6=Sunday.
+*/
+static int daysAfterMonday(DateTime *pDate){
+ assert( pDate->validJD );
+ return (int)((pDate->iJD+43200000)/86400000) % 7;
+}
+
+/*
+** Return the number of days after the most recent Sunday.
+**
+** In other words, return the day of the week according
+** to this code:
+**
+** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday
+*/
+static int daysAfterSunday(DateTime *pDate){
+ assert( pDate->validJD );
+ return (int)((pDate->iJD+129600000)/86400000) % 7;
+}
+
/*
** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
**
** Return a string described by FORMAT. Conversions as follows:
**
-** %d day of month
+** %d day of month 01-31
+** %e day of month 1-31
** %f ** fractional seconds SS.SSS
+** %F ISO date. YYYY-MM-DD
+** %G ISO year corresponding to %V 0000-9999.
+** %g 2-digit ISO year corresponding to %V 00-99
** %H hour 00-24
-** %j day of year 000-366
+** %k hour 0-24 (leading zero converted to space)
+** %I hour 01-12
+** %j day of year 001-366
** %J ** julian day number
+** %l hour 1-12 (leading zero converted to space)
** %m month 01-12
** %M minute 00-59
+** %p "am" or "pm"
+** %P "AM" or "PM"
+** %R time as HH:MM
** %s seconds since 1970-01-01
** %S seconds 00-59
-** %w day of week 0-6 Sunday==0
-** %W week of year 00-53
+** %T time as HH:MM:SS
+** %u day of week 1-7 Monday==1, Sunday==7
+** %w day of week 0-6 Sunday==0, Monday==1
+** %U week of year 00-53 (First Sunday is start of week 01)
+** %V week of year 01-53 (First week containing Thursday is week 01)
+** %W week of year 00-53 (First Monday is start of week 01)
** %Y year 0000-9999
** %% %
*/
@@ -26121,7 +26591,7 @@ static void strftimeFunc(
sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D);
break;
}
- case 'f': {
+ case 'f': { /* Fractional seconds. (Non-standard) */
double s = x.s;
if( s>59.999 ) s = 59.999;
sqlite3_str_appendf(&sRes, "%06.3f", s);
@@ -26131,6 +26601,21 @@ static void strftimeFunc(
sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D);
break;
}
+ case 'G': /* Fall thru */
+ case 'g': {
+ DateTime y = x;
+ assert( y.validJD );
+ /* Move y so that it is the Thursday in the same week as x */
+ y.iJD += (3 - daysAfterMonday(&x))*86400000;
+ y.validYMD = 0;
+ computeYMD(&y);
+ if( cf=='g' ){
+ sqlite3_str_appendf(&sRes, "%02d", y.Y%100);
+ }else{
+ sqlite3_str_appendf(&sRes, "%04d", y.Y);
+ }
+ break;
+ }
case 'H':
case 'k': {
sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h);
@@ -26144,25 +26629,11 @@ static void strftimeFunc(
sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h);
break;
}
- case 'W': /* Fall thru */
- case 'j': {
- int nDay; /* Number of days since 1st day of year */
- DateTime y = x;
- y.validJD = 0;
- y.M = 1;
- y.D = 1;
- computeJD(&y);
- nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
- if( cf=='W' ){
- int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
- wd = (int)(((x.iJD+43200000)/86400000)%7);
- sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7);
- }else{
- sqlite3_str_appendf(&sRes,"%03d",nDay+1);
- }
+ case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */
+ sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1);
break;
}
- case 'J': {
+ case 'J': { /* Julian day number. (Non-standard) */
sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0);
break;
}
@@ -26205,13 +26676,33 @@ static void strftimeFunc(
sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s);
break;
}
- case 'u': /* Fall thru */
- case 'w': {
- char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
+ case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */
+ case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */
+ char c = (char)daysAfterSunday(&x) + '0';
if( c=='0' && cf=='u' ) c = '7';
sqlite3_str_appendchar(&sRes, 1, c);
break;
}
+ case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */
+ sqlite3_str_appendf(&sRes,"%02d",
+ (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7);
+ break;
+ }
+ case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */
+ DateTime y = x;
+ /* Adjust y so that is the Thursday in the same week as x */
+ assert( y.validJD );
+ y.iJD += (3 - daysAfterMonday(&x))*86400000;
+ y.validYMD = 0;
+ computeYMD(&y);
+ sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1);
+ break;
+ }
+ case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */
+ sqlite3_str_appendf(&sRes,"%02d",
+ (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7);
+ break;
+ }
case 'Y': {
sqlite3_str_appendf(&sRes,"%04d",x.Y);
break;
@@ -26358,9 +26849,7 @@ static void timediffFunc(
d1.iJD = d2.iJD - d1.iJD;
d1.iJD += (u64)1486995408 * (u64)100000;
}
- d1.validYMD = 0;
- d1.validHMS = 0;
- d1.validTZ = 0;
+ clearYMD_HMS_TZ(&d1);
computeYMD_HMS(&d1);
sqlite3StrAccumInit(&sRes, 0, 0, 0, 100);
sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f",
@@ -26429,6 +26918,36 @@ static void currentTimeFunc(
}
#endif
+#if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG)
+/*
+** datedebug(...)
+**
+** This routine returns JSON that describes the internal DateTime object.
+** Used for debugging and testing only. Subject to change.
+*/
+static void datedebugFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ DateTime x;
+ if( isDate(context, argc, argv, &x)==0 ){
+ char *zJson;
+ zJson = sqlite3_mprintf(
+ "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d,"
+ "s:%.3f,validJD:%d,validYMS:%d,validHMS:%d,"
+ "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d,"
+ "isUtc:%d,isLocal:%d}",
+ x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz,
+ x.s, x.validJD, x.validYMD, x.validHMS,
+ x.nFloor, x.rawS, x.isError, x.useSubsec,
+ x.isUtc, x.isLocal);
+ sqlite3_result_text(context, zJson, -1, sqlite3_free);
+ }
+}
+#endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */
+
+
/*
** This function registered all of the above C functions as SQL
** functions. This should be the only routine in this file with
@@ -26444,6 +26963,9 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
PURE_DATE(timediff, 2, 0, 0, timediffFunc ),
+#ifdef SQLITE_DEBUG
+ PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ),
+#endif
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
@@ -29512,16 +30034,29 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
+**
+** Because these routines raise false-positive alerts in TSAN, disable
+** them (make them always return 1) when compiling with TSAN.
*/
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
+# if defined(__has_feature)
+# if __has_feature(thread_sanitizer)
+ p = 0;
+# endif
+# endif
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
+# if defined(__has_feature)
+# if __has_feature(thread_sanitizer)
+ p = 0;
+# endif
+# endif
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
-#endif
+#endif /* NDEBUG */
#endif /* !defined(SQLITE_MUTEX_OMIT) */
@@ -30859,6 +31394,24 @@ static void sqlite3MallocAlarm(int nByte){
sqlite3_mutex_enter(mem0.mutex);
}
+#ifdef SQLITE_DEBUG
+/*
+** This routine is called whenever an out-of-memory condition is seen,
+** It's only purpose to to serve as a breakpoint for gdb or similar
+** code debuggers when working on out-of-memory conditions, for example
+** caused by PRAGMA hard_heap_limit=N.
+*/
+static SQLITE_NOINLINE void test_oom_breakpoint(u64 n){
+ static u64 nOomFault = 0;
+ nOomFault += n;
+ /* The assert() is never reached in a human lifetime. It is here mostly
+ ** to prevent code optimizers from optimizing out this function. */
+ assert( (nOomFault>>32) < 0xffffffff );
+}
+#else
+# define test_oom_breakpoint(X) /* No-op for production builds */
+#endif
+
/*
** Do a memory allocation with statistics and alarms. Assume the
** lock is already held.
@@ -30885,6 +31438,7 @@ static void mallocWithAlarm(int n, void **pp){
if( mem0.hardLimit ){
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.hardLimit - nFull ){
+ test_oom_breakpoint(1);
*pp = 0;
return;
}
@@ -31173,6 +31727,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
sqlite3MallocAlarm(nDiff);
if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){
sqlite3_mutex_leave(mem0.mutex);
+ test_oom_breakpoint(1);
return 0;
}
}
@@ -32039,6 +32594,7 @@ SQLITE_API void sqlite3_str_vappendf(
if( xtype==etFLOAT ){
iRound = -precision;
}else if( xtype==etGENERIC ){
+ if( precision==0 ) precision = 1;
iRound = precision;
}else{
iRound = precision+1;
@@ -32074,13 +32630,14 @@ SQLITE_API void sqlite3_str_vappendf(
}
exp = s.iDP-1;
- if( xtype==etGENERIC && precision>0 ) precision--;
/*
** If the field type is etGENERIC, then convert to either etEXP
** or etFLOAT, as appropriate.
*/
if( xtype==etGENERIC ){
+ assert( precision>0 );
+ precision--;
flag_rtz = !flag_alternateform;
if( exp<-4 || exp>precision ){
xtype = etEXP;
@@ -32387,18 +32944,25 @@ SQLITE_API void sqlite3_str_vappendf(
if( pItem->zAlias && !flag_altform2 ){
sqlite3_str_appendall(pAccum, pItem->zAlias);
}else if( pItem->zName ){
- if( pItem->zDatabase ){
- sqlite3_str_appendall(pAccum, pItem->zDatabase);
+ if( pItem->fg.fixedSchema==0
+ && pItem->fg.isSubquery==0
+ && pItem->u4.zDatabase!=0
+ ){
+ sqlite3_str_appendall(pAccum, pItem->u4.zDatabase);
sqlite3_str_append(pAccum, ".", 1);
}
sqlite3_str_appendall(pAccum, pItem->zName);
}else if( pItem->zAlias ){
sqlite3_str_appendall(pAccum, pItem->zAlias);
- }else{
- Select *pSel = pItem->pSelect;
+ }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */
+ Select *pSel = pItem->u4.pSubq->pSelect;
assert( pSel!=0 );
if( pSel->selFlags & SF_NestedFrom ){
sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId);
+ }else if( pSel->selFlags & SF_MultiValue ){
+ assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy );
+ sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE",
+ pItem->u1.nRow);
}else{
sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId);
}
@@ -32470,6 +33034,7 @@ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExp
pExpr = pExpr->pLeft;
}
if( pExpr==0 ) return;
+ if( ExprHasProperty(pExpr, EP_FromDDL) ) return;
db->errByteOffset = pExpr->w.iOfst;
}
@@ -33174,9 +33739,11 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
x.printfFlags |= SQLITE_PRINTF_INTERNAL;
sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
- if( pItem->pTab ){
- sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
- pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
+ if( pItem->pSTab ){
+ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s",
+ pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab,
+ pItem->colUsed,
+ pItem->fg.rowidUsed ? "+rowid" : "");
}
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
@@ -33205,23 +33772,30 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine");
if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte");
if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom");
+ if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema");
+ if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema");
+ if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery");
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, inSrc-1);
n = 0;
- if( pItem->pSelect ) n++;
+ if( pItem->fg.isSubquery ) n++;
if( pItem->fg.isTabFunc ) n++;
if( pItem->fg.isUsing ) n++;
if( pItem->fg.isUsing ){
sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
}
- if( pItem->pSelect ){
- if( pItem->pTab ){
- Table *pTab = pItem->pTab;
+ if( pItem->fg.isSubquery ){
+ assert( n==1 );
+ if( pItem->pSTab ){
+ Table *pTab = pItem->pSTab;
sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
}
- assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
- sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0);
+ assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
+ sqlite3TreeViewPush(&pView, 0);
+ sqlite3TreeViewLine(pView, "SUBQUERY");
+ sqlite3TreeViewPop(&pView);
+ sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0);
}
if( pItem->fg.isTabFunc ){
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
@@ -33263,7 +33837,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
n = 1000;
}else{
n = 0;
- if( p->pSrc && p->pSrc->nSrc ) n++;
+ if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++;
if( p->pWhere ) n++;
if( p->pGroupBy ) n++;
if( p->pHaving ) n++;
@@ -33289,7 +33863,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
sqlite3TreeViewPop(&pView);
}
#endif
- if( p->pSrc && p->pSrc->nSrc ){
+ if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){
sqlite3TreeViewPush(&pView, (n--)>0);
sqlite3TreeViewLine(pView, "FROM");
sqlite3TreeViewSrcList(pView, p->pSrc);
@@ -33325,7 +33899,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
if( p->pLimit->pRight ){
- sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+ sqlite3TreeViewItem(pView, "OFFSET", 0);
sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
sqlite3TreeViewPop(&pView);
}
@@ -33797,7 +34371,8 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
case OE_Ignore: zType = "ignore"; break;
}
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
+ sqlite3TreeViewLine(pView, "RAISE %s", zType);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
break;
}
#endif
@@ -33877,9 +34452,10 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; inExpr; i++){
int j = pList->a[i].u.x.iOrderByCol;
+ u8 sortFlags = pList->a[i].fg.sortFlags;
char *zName = pList->a[i].zEName;
int moreToFollow = inExpr - 1;
- if( j || zName ){
+ if( j || zName || sortFlags ){
sqlite3TreeViewPush(&pView, moreToFollow);
moreToFollow = 0;
sqlite3TreeViewLine(pView, 0);
@@ -33900,13 +34476,18 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
}
}
if( j ){
- fprintf(stdout, "iOrderByCol=%d", j);
+ fprintf(stdout, "iOrderByCol=%d ", j);
+ }
+ if( sortFlags & KEYINFO_ORDER_DESC ){
+ fprintf(stdout, "DESC ");
+ }else if( sortFlags & KEYINFO_ORDER_BIGNULL ){
+ fprintf(stdout, "NULLS-LAST");
}
fprintf(stdout, "\n");
fflush(stdout);
}
sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
- if( j || zName ){
+ if( j || zName || sortFlags ){
sqlite3TreeViewPop(&pView);
}
}
@@ -34869,7 +35450,7 @@ static const unsigned char sqlite3Utf8Trans1[] = {
c = *(zIn++); \
if( c>=0xc0 ){ \
c = sqlite3Utf8Trans1[c-0xc0]; \
- while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
+ while( zIn=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
+ if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
n++;
}
return (int)(z-(unsigned char const *)zIn)
@@ -35370,6 +35953,19 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
+#ifndef SQLITE_OMIT_FLOATING_POINT
+/*
+** Return true if the floating point value is NaN or +Inf or -Inf.
+*/
+SQLITE_PRIVATE int sqlite3IsOverflow(double x){
+ int rc; /* The value return */
+ u64 y;
+ memcpy(&y,&x,sizeof(y));
+ rc = IsOvfl(y);
+ return rc;
+}
+#endif /* SQLITE_OMIT_FLOATING_POINT */
+
/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
@@ -35613,6 +36209,44 @@ SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
sqlite3Dequote(p->u.zToken);
}
+/*
+** Expression p is a QNUMBER (quoted number). Dequote the value in p->u.zToken
+** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those
+** that contain '_' characters that must be removed before further processing.
+*/
+SQLITE_PRIVATE void sqlite3DequoteNumber(Parse *pParse, Expr *p){
+ assert( p!=0 || pParse->db->mallocFailed );
+ if( p ){
+ const char *pIn = p->u.zToken;
+ char *pOut = p->u.zToken;
+ int bHex = (pIn[0]=='0' && (pIn[1]=='x' || pIn[1]=='X'));
+ int iValue;
+ assert( p->op==TK_QNUMBER );
+ p->op = TK_INTEGER;
+ do {
+ if( *pIn!=SQLITE_DIGIT_SEPARATOR ){
+ *pOut++ = *pIn;
+ if( *pIn=='e' || *pIn=='E' || *pIn=='.' ) p->op = TK_FLOAT;
+ }else{
+ if( (bHex==0 && (!sqlite3Isdigit(pIn[-1]) || !sqlite3Isdigit(pIn[1])))
+ || (bHex==1 && (!sqlite3Isxdigit(pIn[-1]) || !sqlite3Isxdigit(pIn[1])))
+ ){
+ sqlite3ErrorMsg(pParse, "unrecognized token: \"%s\"", p->u.zToken);
+ }
+ }
+ }while( *pIn++ );
+ if( bHex ) p->op = TK_INTEGER;
+
+ /* tag-20240227-a: If after dequoting, the number is an integer that
+ ** fits in 32 bits, then it must be converted into EP_IntValue. Other
+ ** parts of the code expect this. See also tag-20240227-b. */
+ if( p->op==TK_INTEGER && sqlite3GetInt32(p->u.zToken, &iValue) ){
+ p->u.iValue = iValue;
+ p->flags |= EP_IntValue;
+ }
+ }
+}
+
/*
** If the input token p is quoted, try to adjust the token to remove
** the quotes. This is not always possible:
@@ -35790,6 +36424,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
int eValid = 1; /* True exponent is either not used or is well-formed */
int nDigit = 0; /* Number of digits processed */
int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
+ u64 s2; /* round-tripped significand */
+ double rr[2];
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
@@ -35892,7 +36528,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
e = (e*esign) + d;
/* Try to adjust the exponent to make it smaller */
- while( e>0 && s<(LARGEST_UINT64/10) ){
+ while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){
s *= 10;
e--;
}
@@ -35901,65 +36537,46 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
e++;
}
- if( e==0 ){
- *pResult = s;
- }else if( sqlite3Config.bUseLongDouble ){
- LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s;
- if( e>0 ){
- while( e>=100 ){ e-=100; r *= 1.0e+100L; }
- while( e>=10 ){ e-=10; r *= 1.0e+10L; }
- while( e>=1 ){ e-=1; r *= 1.0e+01L; }
- }else{
- while( e<=-100 ){ e+=100; r *= 1.0e-100L; }
- while( e<=-10 ){ e+=10; r *= 1.0e-10L; }
- while( e<=-1 ){ e+=1; r *= 1.0e-01L; }
- }
- assert( r>=0.0 );
- if( r>+1.7976931348623157081452742373e+308L ){
-#ifdef INFINITY
- *pResult = +INFINITY;
-#else
- *pResult = 1.0e308*10.0;
-#endif
- }else{
- *pResult = (double)r;
- }
- }else{
- double rr[2];
- u64 s2;
- rr[0] = (double)s;
+ rr[0] = (double)s;
+ assert( sizeof(s2)==sizeof(rr[0]) );
+ memcpy(&s2, &rr[0], sizeof(s2));
+ if( s2<=0x43efffffffffffffLL ){
s2 = (u64)rr[0];
rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
- if( e>0 ){
- while( e>=100 ){
- e -= 100;
- dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
- }
- while( e>=10 ){
- e -= 10;
- dekkerMul2(rr, 1.0e+10, 0.0);
- }
- while( e>=1 ){
- e -= 1;
- dekkerMul2(rr, 1.0e+01, 0.0);
- }
- }else{
- while( e<=-100 ){
- e += 100;
- dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117);
- }
- while( e<=-10 ){
- e += 10;
- dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
- }
- while( e<=-1 ){
- e += 1;
- dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
- }
+ }else{
+ rr[1] = 0.0;
+ }
+ assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */
+
+ if( e>0 ){
+ while( e>=100 ){
+ e -= 100;
+ dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
+ }
+ while( e>=10 ){
+ e -= 10;
+ dekkerMul2(rr, 1.0e+10, 0.0);
+ }
+ while( e>=1 ){
+ e -= 1;
+ dekkerMul2(rr, 1.0e+01, 0.0);
+ }
+ }else{
+ while( e<=-100 ){
+ e += 100;
+ dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117);
+ }
+ while( e<=-10 ){
+ e += 10;
+ dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
+ }
+ while( e<=-1 ){
+ e += 1;
+ dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
}
- *pResult = rr[0]+rr[1];
- if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300;
}
+ *pResult = rr[0]+rr[1];
+ if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300;
if( sign<0 ) *pResult = -*pResult;
assert( !sqlite3IsNaN(*pResult) );
@@ -36263,10 +36880,13 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){
** Decode a floating-point value into an approximate decimal
** representation.
**
-** Round the decimal representation to n significant digits if
-** n is positive. Or round to -n signficant digits after the
-** decimal point if n is negative. No rounding is performed if
-** n is zero.
+** If iRound<=0 then round to -iRound significant digits to the
+** the left of the decimal point, or to a maximum of mxRound total
+** significant digits.
+**
+** If iRound>0 round to min(iRound,mxRound) significant digits total.
+**
+** mxRound must be positive.
**
** The significant digits of the decimal representation are
** stored in p->z[] which is a often (but not always) a pointer
@@ -36277,8 +36897,11 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou
int i;
u64 v;
int e, exp = 0;
+ double rr[2];
+
p->isSpecial = 0;
p->z = p->zBuf;
+ assert( mxRound>0 );
/* Convert negative numbers to positive. Deal with Infinity, 0.0, and
** NaN. */
@@ -36305,62 +36928,45 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou
/* Multiply r by powers of ten until it lands somewhere in between
** 1.0e+19 and 1.0e+17.
+ **
+ ** Use Dekker-style double-double computation to increase the
+ ** precision.
+ **
+ ** The error terms on constants like 1.0e+100 computed using the
+ ** decimal extension, for example as follows:
+ **
+ ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100)));
*/
- if( sqlite3Config.bUseLongDouble ){
- LONGDOUBLE_TYPE rr = r;
- if( rr>=1.0e+19 ){
- while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; }
- while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; }
- while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; }
- }else{
- while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; }
- while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; }
- while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; }
+ rr[0] = r;
+ rr[1] = 0.0;
+ if( rr[0]>9.223372036854774784e+18 ){
+ while( rr[0]>9.223372036854774784e+118 ){
+ exp += 100;
+ dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117);
+ }
+ while( rr[0]>9.223372036854774784e+28 ){
+ exp += 10;
+ dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
+ }
+ while( rr[0]>9.223372036854774784e+18 ){
+ exp += 1;
+ dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
}
- v = (u64)rr;
}else{
- /* If high-precision floating point is not available using "long double",
- ** then use Dekker-style double-double computation to increase the
- ** precision.
- **
- ** The error terms on constants like 1.0e+100 computed using the
- ** decimal extension, for example as follows:
- **
- ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100)));
- */
- double rr[2];
- rr[0] = r;
- rr[1] = 0.0;
- if( rr[0]>9.223372036854774784e+18 ){
- while( rr[0]>9.223372036854774784e+118 ){
- exp += 100;
- dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117);
- }
- while( rr[0]>9.223372036854774784e+28 ){
- exp += 10;
- dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
- }
- while( rr[0]>9.223372036854774784e+18 ){
- exp += 1;
- dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
- }
- }else{
- while( rr[0]<9.223372036854774784e-83 ){
- exp -= 100;
- dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
- }
- while( rr[0]<9.223372036854774784e+07 ){
- exp -= 10;
- dekkerMul2(rr, 1.0e+10, 0.0);
- }
- while( rr[0]<9.22337203685477478e+17 ){
- exp -= 1;
- dekkerMul2(rr, 1.0e+01, 0.0);
- }
+ while( rr[0]<9.223372036854774784e-83 ){
+ exp -= 100;
+ dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
+ }
+ while( rr[0]<9.223372036854774784e+07 ){
+ exp -= 10;
+ dekkerMul2(rr, 1.0e+10, 0.0);
+ }
+ while( rr[0]<9.22337203685477478e+17 ){
+ exp -= 1;
+ dekkerMul2(rr, 1.0e+01, 0.0);
}
- v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1];
}
-
+ v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1];
/* Extract significant digits. */
i = sizeof(p->zBuf)-1;
@@ -36371,7 +36977,7 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou
assert( p->n>0 );
assert( p->nzBuf) );
p->iDP = p->n + exp;
- if( iRound<0 ){
+ if( iRound<=0 ){
iRound = p->iDP - iRound;
if( iRound==0 && p->zBuf[i+1]>='5' ){
iRound = 1;
@@ -37131,104 +37737,6 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam
return 0;
}
-/*
-** High-resolution hardware timer used for debugging and testing only.
-*/
-#if defined(VDBE_PROFILE) \
- || defined(SQLITE_PERFORMANCE_TRACE) \
- || defined(SQLITE_ENABLE_STMT_SCANSTATUS)
-/************** Include hwtime.h in the middle of util.c *********************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 and x86_64 class CPUs.
-*/
-#ifndef SQLITE_HWTIME_H
-#define SQLITE_HWTIME_H
-
-/*
-** The following routine only works on Pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if !defined(__STRICT_ANSI__) && \
- (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
-#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- /*
- ** asm() is needed for hardware timing support. Without asm(),
- ** disable the sqlite3Hwtime() routine.
- **
- ** sqlite3Hwtime() is only used for some obscure debugging
- ** and analysis configurations, not in any deliverable, so this
- ** should not be a great loss.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(SQLITE_HWTIME_H) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in util.c ***********************/
-#endif
-
/************** End of util.c ************************************************/
/************** Begin file hash.c ********************************************/
/*
@@ -37549,7 +38057,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"),
/* 31 */ "NotExists" OpHelp("intkey=r[P3]"),
/* 32 */ "Last" OpHelp(""),
- /* 33 */ "IfSmaller" OpHelp(""),
+ /* 33 */ "IfSizeBetween" OpHelp(""),
/* 34 */ "SorterSort" OpHelp(""),
/* 35 */ "Sort" OpHelp(""),
/* 36 */ "Rewind" OpHelp(""),
@@ -37570,16 +38078,16 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 51 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
/* 52 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
/* 53 */ "IncrVacuum" OpHelp(""),
- /* 54 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
- /* 55 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 56 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
- /* 57 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
- /* 58 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
- /* 59 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
- /* 60 */ "Lt" OpHelp("IF r[P3]=r[P1]"),
- /* 62 */ "ElseEq" OpHelp(""),
- /* 63 */ "VNext" OpHelp(""),
+ /* 54 */ "VNext" OpHelp(""),
+ /* 55 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 56 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 57 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
+ /* 58 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
+ /* 59 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
+ /* 60 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
+ /* 61 */ "Lt" OpHelp("IF r[P3]=r[P1]"),
+ /* 63 */ "ElseEq" OpHelp(""),
/* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"),
/* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
/* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
@@ -37594,7 +38102,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
/* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
/* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1)"),
/* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
/* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
/* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"),
@@ -37622,23 +38130,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 103 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
/* 104 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
/* 105 */ "OpenDup" OpHelp(""),
- /* 106 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 107 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 108 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
- /* 110 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 111 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 112 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 113 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 114 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 115 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 106 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 107 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 108 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 109 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
+ /* 111 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 112 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 113 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 114 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 115 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 116 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
/* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"),
- /* 118 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
- /* 119 */ "SorterOpen" OpHelp(""),
+ /* 118 */ "SorterOpen" OpHelp(""),
+ /* 119 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
/* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
- /* 121 */ "String8" OpHelp("r[P2]='P4'"),
- /* 122 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 122 */ "String8" OpHelp("r[P2]='P4'"),
/* 123 */ "Close" OpHelp(""),
/* 124 */ "ColumnsUsed" OpHelp(""),
/* 125 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
@@ -37674,8 +38182,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 155 */ "DropIndex" OpHelp(""),
/* 156 */ "DropTrigger" OpHelp(""),
/* 157 */ "IntegrityCk" OpHelp(""),
- /* 158 */ "Real" OpHelp("r[P2]=P4"),
- /* 159 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 158 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 159 */ "Real" OpHelp("r[P2]=P4"),
/* 160 */ "Param" OpHelp(""),
/* 161 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
/* 162 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
@@ -39023,7 +39531,7 @@ static pid_t randomnessPid = 0;
#define UNIXFILE_EXCL 0x01 /* Connections from one process only */
#define UNIXFILE_RDONLY 0x02 /* Connection is read only */
#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
-#ifndef SQLITE_DISABLE_DIRSYNC
+#if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX)
# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */
#else
# define UNIXFILE_DIRSYNC 0x00
@@ -39996,8 +40504,12 @@ static int unixLogErrorAtLine(
** available, the error message will often be an empty string. Not a
** huge problem. Incorrectly concluding that the GNU version is available
** could lead to a segfault though.
+ **
+ ** Forum post 3f13857fa4062301 reports that the Android SDK may use
+ ** int-type return, depending on its version.
*/
-#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
+#if (defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)) \
+ && !defined(ANDROID) && !defined(__ANDROID__)
zErr =
# endif
strerror_r(iErrno, aErr, sizeof(aErr)-1);
@@ -40976,26 +41488,22 @@ static int nolockClose(sqlite3_file *id) {
/*
** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-**
-** In dotfile locking, either a lock exists or it does not. So in this
-** variation of CheckReservedLock(), *pResOut is set to true if any lock
-** is held on the file and false if the file is unlocked.
+** file by this or any other process. If the caller holds a SHARED
+** or greater lock when it is called, then it is assumed that no other
+** client may hold RESERVED. Or, if the caller holds no lock, then it
+** is assumed another client holds RESERVED if the lock-file exists.
*/
static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
- int rc = SQLITE_OK;
- int reserved = 0;
unixFile *pFile = (unixFile*)id;
-
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
- assert( pFile );
- reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
- OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
- *pResOut = reserved;
- return rc;
+ if( pFile->eFileLock>=SHARED_LOCK ){
+ *pResOut = 0;
+ }else{
+ *pResOut = osAccess((const char*)pFile->lockingContext, 0)==0;
+ }
+ OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut));
+ return SQLITE_OK;
}
/*
@@ -41165,54 +41673,33 @@ static int robust_flock(int fd, int op){
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
*/
static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
+#ifdef SQLITE_DEBUG
unixFile *pFile = (unixFile*)id;
+#else
+ UNUSED_PARAMETER(id);
+#endif
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( pFile );
+ assert( pFile->eFileLock<=SHARED_LOCK );
- /* Check if a thread in this process holds such a lock */
- if( pFile->eFileLock>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it. */
- if( !reserved ){
- /* attempt to get the lock */
- int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB);
- if( !lrc ){
- /* got the lock, unlock it */
- lrc = robust_flock(pFile->h, LOCK_UN);
- if ( lrc ) {
- int tErrno = errno;
- /* unlock failed with an error */
- lrc = SQLITE_IOERR_UNLOCK;
- storeLastErrno(pFile, tErrno);
- rc = lrc;
- }
- } else {
- int tErrno = errno;
- reserved = 1;
- /* someone else might have it reserved */
- lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(lrc) ){
- storeLastErrno(pFile, tErrno);
- rc = lrc;
- }
- }
- }
- OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
+ /* The flock VFS only ever takes exclusive locks (see function flockLock).
+ ** Therefore, if this connection is holding any lock at all, no other
+ ** connection may be holding a RESERVED lock. So set *pResOut to 0
+ ** in this case.
+ **
+ ** Or, this connection may be holding no lock. In that case, set *pResOut to
+ ** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the
+ ** db in order to roll the hot journal back. If there is another connection
+ ** holding a lock, that attempt will fail and an SQLITE_BUSY returned to
+ ** the user. With other VFS, we try to avoid this, in order to allow a reader
+ ** to proceed while a writer is preparing its transaction. But that won't
+ ** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is
+ ** not a problem in this case. */
+ *pResOut = 0;
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & 0xff) == SQLITE_IOERR ){
- rc = SQLITE_OK;
- reserved=1;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- *pResOut = reserved;
- return rc;
+ return SQLITE_OK;
}
/*
@@ -42850,6 +43337,7 @@ static void setDeviceCharacteristics(unixFile *pFd){
if( pFd->ctrlFlags & UNIXFILE_PSOW ){
pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
}
+ pFd->deviceCharacteristics |= SQLITE_IOCAP_SUBPAGE_READ;
pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
}
@@ -42900,7 +43388,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
/* full bitset of atomics from max sector size and smaller */
- ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
+ (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) |
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
@@ -42908,7 +43396,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
/* full bitset of atomics from max sector size and smaller */
- ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
+ (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) |
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
@@ -45095,12 +45583,19 @@ static int unixOpen(
rc = SQLITE_READONLY_DIRECTORY;
}else if( errno!=EISDIR && isReadWrite ){
/* Failed to open the file for read/write access. Try read-only. */
+ UnixUnusedFd *pReadonly = 0;
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
openFlags &= ~(O_RDWR|O_CREAT);
flags |= SQLITE_OPEN_READONLY;
openFlags |= O_RDONLY;
isReadonly = 1;
- fd = robust_open(zName, openFlags, openMode);
+ pReadonly = findReusableFd(zName, flags);
+ if( pReadonly ){
+ fd = pReadonly->fd;
+ sqlite3_free(pReadonly);
+ }else{
+ fd = robust_open(zName, openFlags, openMode);
+ }
}
}
if( fd<0 ){
@@ -50643,7 +51138,7 @@ static int winSectorSize(sqlite3_file *id){
*/
static int winDeviceCharacteristics(sqlite3_file *id){
winFile *p = (winFile*)id;
- return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
+ return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_SUBPAGE_READ |
((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
}
@@ -52031,7 +52526,7 @@ static int winOpen(
int rc = SQLITE_OK; /* Function Return Code */
#if !defined(NDEBUG) || SQLITE_OS_WINCE
- int eType = flags&0xFFFFFF00; /* Type of file to open */
+ int eType = flags&0x0FFF00; /* Type of file to open */
#endif
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
@@ -53996,6 +54491,14 @@ SQLITE_API unsigned char *sqlite3_serialize(
pOut = 0;
}else{
sz = sqlite3_column_int64(pStmt, 0)*szPage;
+ if( sz==0 ){
+ sqlite3_reset(pStmt);
+ sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0);
+ rc = sqlite3_step(pStmt);
+ if( rc==SQLITE_ROW ){
+ sz = sqlite3_column_int64(pStmt, 0)*szPage;
+ }
+ }
if( piSize ) *piSize = sz;
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
pOut = 0;
@@ -55054,6 +55557,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
pPgHdr->pData = pPage->pBuf;
pPgHdr->pExtra = (void *)&pPgHdr[1];
memset(pPgHdr->pExtra, 0, 8);
+ assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) );
pPgHdr->pCache = pCache;
pPgHdr->pgno = pgno;
pPgHdr->flags = PGHDR_CLEAN;
@@ -55800,7 +56304,8 @@ static int pcache1InitBulk(PCache1 *pCache){
do{
PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
pX->page.pBuf = zBulk;
- pX->page.pExtra = &pX[1];
+ pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX));
+ assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) );
pX->isBulkLocal = 1;
pX->isAnchor = 0;
pX->pNext = pCache->pFree;
@@ -55937,7 +56442,8 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
if( pPg==0 ) return 0;
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
p->page.pBuf = pPg;
- p->page.pExtra = &p[1];
+ p->page.pExtra = (u8*)p + ROUND8(sizeof(*p));
+ assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) );
p->isBulkLocal = 0;
p->isAnchor = 0;
p->pLruPrev = 0; /* Initializing this saves a valgrind error */
@@ -58377,19 +58883,27 @@ static const unsigned char aJournalMagic[] = {
** Return true if page pgno can be read directly from the database file
** by the b-tree layer. This is the case if:
**
-** * the database file is open,
-** * there are no dirty pages in the cache, and
-** * the desired page is not currently in the wal file.
+** (1) the database file is open
+** (2) the VFS for the database is able to do unaligned sub-page reads
+** (3) there are no dirty pages in the cache, and
+** (4) the desired page is not currently in the wal file.
*/
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
- if( pPager->fd->pMethods==0 ) return 0;
- if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
+ assert( pPager!=0 );
+ assert( pPager->fd!=0 );
+ if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */
+ assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
+ if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
+ & SQLITE_IOCAP_SUBPAGE_READ)==0 ){
+ return 0; /* Case (2) */
+ }
+ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */
if( pPager->hasCodec ) return 0;
#ifndef SQLITE_OMIT_WAL
if( pagerUseWal(pPager) ){
u32 iRead = 0;
(void)pPager->wal->methods.xFindFrame(pPager->wal->pData, pgno, &iRead);
- return iRead==0;
+ return iRead==0; /* Condition (4) */
}
#endif
return 1;
@@ -61636,6 +62150,7 @@ static int pagerAcquireMapPage(
return SQLITE_NOMEM_BKPT;
}
p->pExtra = (void *)&p[1];
+ assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) );
p->flags = PGHDR_MMAP;
p->nRef = 1;
p->pPager = pPager;
@@ -64689,7 +65204,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
** This will be either the rollback journal or the WAL file.
*/
SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
-#if SQLITE_OMIT_WAL
+#ifdef SQLITE_OMIT_WAL
return pPager->jfd;
#else
return pagerUseWal(pPager) ? pPager->wal->methods.xFile(pPager->wal->pData) : pPager->jfd;
@@ -65599,7 +66114,7 @@ SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){
** 28: Checksum-2 (second part of checksum for first 24 bytes of header).
**
** Immediately following the wal-header are zero or more frames. Each
-** frame consists of a 24-byte frame-header followed by a bytes
+** frame consists of a 24-byte frame-header followed by bytes
** of page data. The frame-header is six big-endian 32-bit unsigned
** integer values, as follows:
**
@@ -68422,7 +68937,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){
SEH_INJECT_FAULT;
if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
- && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
+ && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0)
#endif
){
/* The WAL has been completely backfilled (or it is empty).
@@ -69891,7 +70406,20 @@ static void sqlite3WalSnapshotOpen(
Wal *pWal,
sqlite3_snapshot *pSnapshot
){
- pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
+ if( pSnapshot && ((WalIndexHdr*)pSnapshot)->iVersion==0 ){
+ /* iVersion==0 means that this is a call to sqlite3_snapshot_get(). In
+ ** this case set the bGetSnapshot flag so that if the call to
+ ** sqlite3_snapshot_get() is about to read transaction on this wal
+ ** file, it does not take read-lock 0 if the wal file has been completely
+ ** checkpointed. Taking read-lock 0 would work, but then it would be
+ ** possible for a subsequent writer to destroy the snapshot even while
+ ** this connection is holding its read-transaction open. This is contrary
+ ** to user expectations, so we avoid it by not taking read-lock 0. */
+ pWal->bGetSnapshot = 1;
+ }else{
+ pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
+ pWal->bGetSnapshot = 0;
+ }
}
/*
@@ -70953,6 +71481,7 @@ struct IntegrityCk {
StrAccum errMsg; /* Accumulate the error message text here */
u32 *heap; /* Min-heap used for analyzing cell coverage */
sqlite3 *db; /* Database connection running the check */
+ i64 nRow; /* Number of rows visited in current tree */
};
/*
@@ -71427,8 +71956,47 @@ int corruptPageError(int lineno, MemPage *p){
# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno)
#endif
+/* Default value for SHARED_LOCK_TRACE macro if shared-cache is disabled
+** or if the lock tracking is disabled. This is always the value for
+** release builds.
+*/
+#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) /*no-op*/
+
#ifndef SQLITE_OMIT_SHARED_CACHE
+#if 0
+/* ^---- Change to 1 and recompile to enable shared-lock tracing
+** for debugging purposes.
+**
+** Print all shared-cache locks on a BtShared. Debugging use only.
+*/
+static void sharedLockTrace(
+ BtShared *pBt,
+ const char *zMsg,
+ int iRoot,
+ int eLockType
+){
+ BtLock *pLock;
+ if( iRoot>0 ){
+ printf("%s-%p %u%s:", zMsg, pBt, iRoot, eLockType==READ_LOCK?"R":"W");
+ }else{
+ printf("%s-%p:", zMsg, pBt);
+ }
+ for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){
+ printf(" %p/%u%s", pLock->pBtree, pLock->iTable,
+ pLock->eLock==READ_LOCK ? "R" : "W");
+ while( pLock->pNext && pLock->pBtree==pLock->pNext->pBtree ){
+ pLock = pLock->pNext;
+ printf(",%u%s", pLock->iTable, pLock->eLock==READ_LOCK ? "R" : "W");
+ }
+ }
+ printf("\n");
+ fflush(stdout);
+}
+#undef SHARED_LOCK_TRACE
+#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) sharedLockTrace(X,MSG,TAB,TYPE)
+#endif /* Shared-lock tracing */
+
#ifdef SQLITE_DEBUG
/*
**** This function is only used as part of an assert() statement. ***
@@ -71505,6 +72073,8 @@ static int hasSharedCacheTableLock(
iTab = iRoot;
}
+ SHARED_LOCK_TRACE(pBtree->pBt,"hasLock",iRoot,eLockType);
+
/* Search for the required lock. Either a write-lock on root-page iTab, a
** write-lock on the schema table, or (if the client is reading) a
** read-lock on iTab will suffice. Return 1 if any of these are found. */
@@ -71638,6 +72208,8 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
BtLock *pLock = 0;
BtLock *pIter;
+ SHARED_LOCK_TRACE(pBt,"setLock", iTable, eLock);
+
assert( sqlite3BtreeHoldsMutex(p) );
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
assert( p->db!=0 );
@@ -71705,6 +72277,8 @@ static void clearAllSharedCacheTableLocks(Btree *p){
assert( p->sharable || 0==*ppIter );
assert( p->inTrans>0 );
+ SHARED_LOCK_TRACE(pBt, "clearAllLocks", 0, 0);
+
while( *ppIter ){
BtLock *pLock = *ppIter;
assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree );
@@ -71743,6 +72317,9 @@ static void clearAllSharedCacheTableLocks(Btree *p){
*/
static void downgradeAllSharedCacheTableLocks(Btree *p){
BtShared *pBt = p->pBt;
+
+ SHARED_LOCK_TRACE(pBt, "downgradeLocks", 0, 0);
+
if( pBt->pWriter==p ){
BtLock *pLock;
pBt->pWriter = 0;
@@ -75975,6 +76552,25 @@ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){
return ROUND8(sizeof(BtCursor));
}
+#ifdef SQLITE_DEBUG
+/*
+** Return true if and only if the Btree object will be automatically
+** closed with the BtCursor closes. This is used within assert() statements
+** only.
+*/
+SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(
+ Btree *pBtree, /* the btree object */
+ BtCursor *pCur /* Corresponding cursor */
+){
+ BtShared *pBt = pBtree->pBt;
+ if( (pBt->openFlags & BTREE_SINGLE)==0 ) return 0;
+ if( pBt->pCursor!=pCur ) return 0;
+ if( pCur->pNext!=0 ) return 0;
+ if( pCur->pBtree!=pBtree ) return 0;
+ return 1;
+}
+#endif
+
/*
** Initialize memory that will be converted into a BtCursor object.
**
@@ -76357,9 +76953,12 @@ static int accessPayload(
if( pCur->aOverflow==0
|| nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow)
){
- Pgno *aNew = (Pgno*)sqlite3Realloc(
- pCur->aOverflow, nOvfl*2*sizeof(Pgno)
- );
+ Pgno *aNew;
+ if( sqlite3FaultSim(413) ){
+ aNew = 0;
+ }else{
+ aNew = (Pgno*)sqlite3Realloc(pCur->aOverflow, nOvfl*2*sizeof(Pgno));
+ }
if( aNew==0 ){
return SQLITE_NOMEM_BKPT;
}else{
@@ -76369,6 +76968,12 @@ static int accessPayload(
memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
pCur->curFlags |= BTCF_ValidOvfl;
}else{
+ /* Sanity check the validity of the overflow page cache */
+ assert( pCur->aOverflow[0]==nextPage
+ || pCur->aOverflow[0]==0
+ || CORRUPT_DB );
+ assert( pCur->aOverflow[0]!=0 || pCur->aOverflow[offset/ovflSize]==0 );
+
/* If the overflow page-list cache has been allocated and the
** entry for the first required overflow page is valid, skip
** directly to it.
@@ -76850,6 +77455,23 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
return rc;
}
+#ifdef SQLITE_DEBUG
+/* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that
+** this flags are true for a consistent database.
+**
+** This routine is is called from within assert() statements only.
+** It is an internal verification routine and does not appear in production
+** builds.
+*/
+static int cursorIsAtLastEntry(BtCursor *pCur){
+ int ii;
+ for(ii=0; iiiPage; ii++){
+ if( pCur->aiIdx[ii]!=pCur->apPage[ii]->nCell ) return 0;
+ }
+ return pCur->ix==pCur->pPage->nCell-1 && pCur->pPage->leaf!=0;
+}
+#endif
+
/* Move the cursor to the last entry in the table. Return SQLITE_OK
** on success. Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
@@ -76878,18 +77500,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
/* If the cursor already points to the last entry, this is a no-op. */
if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){
-#ifdef SQLITE_DEBUG
- /* This block serves to assert() that the cursor really does point
- ** to the last entry in the b-tree. */
- int ii;
- for(ii=0; iiiPage; ii++){
- assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
- }
- assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB );
- testcase( pCur->ix!=pCur->pPage->nCell-1 );
- /* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */
- assert( pCur->pPage->leaf );
-#endif
+ assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB );
*pRes = 0;
return SQLITE_OK;
}
@@ -76942,6 +77553,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
}
if( pCur->info.nKeycurFlags & BTCF_AtLast)!=0 ){
+ assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB );
*pRes = -1;
return SQLITE_OK;
}
@@ -77202,7 +77814,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
&& indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
&& pIdxKey->errCode==SQLITE_OK
){
- pCur->curFlags &= ~BTCF_ValidOvfl;
+ pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast);
if( !pCur->pPage->isInit ){
return SQLITE_CORRUPT_BKPT;
}
@@ -77408,10 +78020,10 @@ SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
assert( cursorOwnsBtShared(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- /* Currently this interface is only called by the OP_IfSmaller
- ** opcode, and it that case the cursor will always be valid and
- ** will always point to a leaf node. */
- if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
+ /* Currently this interface is only called by the OP_IfSizeBetween
+ ** opcode and the OP_Count opcode with P3=1. In either case,
+ ** the cursor will always be valid unless the btree is empty. */
+ if( pCur->eState!=CURSOR_VALID ) return 0;
if( NEVER(pCur->pPage->leaf==0) ) return -1;
n = pCur->pPage->nCell;
@@ -78233,7 +78845,10 @@ static int fillInCell(
n = nHeader + nPayload;
testcase( n==3 );
testcase( n==4 );
- if( n<4 ) n = 4;
+ if( n<4 ){
+ n = 4;
+ pPayload[nPayload] = 0;
+ }
*pnSize = n;
assert( nSrc<=nPayload );
testcase( nSrc(u32)usableSize ){ j = 0; }
memcpy(&pTmp[j], &aData[j], usableSize - j);
- for(k=0; ALWAYS(kixNx[k]<=i; k++){}
+ assert( pCArray->ixNx[NB*2-1]>i );
+ for(k=0; pCArray->ixNx[k]<=i; k++){}
pSrcEnd = pCArray->apEnd[k];
pData = pEnd;
@@ -78860,7 +79476,8 @@ static int pageInsertArray(
u8 *pEnd; /* Maximum extent of cell data */
assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */
if( iEnd<=iFirst ) return 0;
- for(k=0; ALWAYS(kixNx[k]<=i ; k++){}
+ assert( pCArray->ixNx[NB*2-1]>i );
+ for(k=0; pCArray->ixNx[k]<=i ; k++){}
pEnd = pCArray->apEnd[k];
while( 1 /*Exit by break*/ ){
int sz, rc;
@@ -79145,6 +79762,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
b.szCell = &szCell;
b.apEnd[0] = pPage->aDataEnd;
b.ixNx[0] = 2;
+ b.ixNx[NB*2-1] = 0x7fffffff;
rc = rebuildPage(&b, 0, 1, pNew);
if( NEVER(rc) ){
releasePage(pNew);
@@ -79380,7 +79998,9 @@ static int balance_nonroot(
CellArray b; /* Parsed information on cells being balanced */
memset(abDone, 0, sizeof(abDone));
- memset(&b, 0, sizeof(b));
+ assert( sizeof(b) - sizeof(b.ixNx) == offsetof(CellArray,ixNx) );
+ memset(&b, 0, sizeof(b)-sizeof(b.ixNx[0]));
+ b.ixNx[NB*2-1] = 0x7fffffff;
pBt = pParent->pBt;
assert( sqlite3_mutex_held(pBt->mutex) );
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
@@ -79539,7 +80159,7 @@ static int balance_nonroot(
** table-interior, index-leaf, or index-interior).
*/
if( pOld->aData[0]!=apOld[0]->aData[0] ){
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_PAGE(pOld);
goto balance_cleanup;
}
@@ -79563,7 +80183,7 @@ static int balance_nonroot(
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
if( pOld->nOverflow>0 ){
if( NEVER(limitaiOvfl[0]) ){
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_PAGE(pOld);
goto balance_cleanup;
}
limit = pOld->aiOvfl[0];
@@ -79971,7 +80591,8 @@ static int balance_nonroot(
iOvflSpace += sz;
assert( sz<=pBt->maxLocal+23 );
assert( iOvflSpace <= (int)pBt->pageSize );
- for(k=0; ALWAYS(kj );
+ for(k=0; b.ixNx[k]<=j; k++){}
pSrcEnd = b.apEnd[k];
if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){
rc = SQLITE_CORRUPT_BKPT;
@@ -80206,7 +80827,7 @@ static int anotherValidCursor(BtCursor *pCur){
&& pOther->eState==CURSOR_VALID
&& pOther->pPage==pCur->pPage
){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pCur->pPage);
}
}
return SQLITE_OK;
@@ -80266,7 +80887,7 @@ static int balance(BtCursor *pCur){
/* The page being written is not a root page, and there is currently
** more than one reference to it. This only happens if the page is one
** of its own ancestor pages. Corruption. */
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_PAGE(pPage);
}else{
MemPage * const pParent = pCur->apPage[iPage-1];
int const iIdx = pCur->aiIdx[iPage-1];
@@ -80430,7 +81051,7 @@ static SQLITE_NOINLINE int btreeOverwriteOverflowCell(
rc = btreeGetPage(pBt, ovflPgno, &pPage, 0);
if( rc ) return rc;
if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_PAGE(pPage);
}else{
if( iOffset+ovflPageSize<(u32)nTotal ){
ovflPgno = get4byte(pPage->aData);
@@ -80458,7 +81079,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd
|| pCur->info.pPayload < pPage->aData + pPage->cellOffset
){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pPage);
}
if( pCur->info.nLocal==nTotal ){
/* The entire cell is local */
@@ -80539,7 +81160,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** Which can only happen if the SQLITE_NoSchemaError flag was set when
** the schema was loaded. This cannot be asserted though, as a user might
** set the flag, load the schema, and then unset the flag. */
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot);
}
}
@@ -80662,7 +81283,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
if( pPage->nFree<0 ){
if( NEVER(pCur->eState>CURSOR_INVALID) ){
/* ^^^^^--- due to the moveToRoot() call above */
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_PAGE(pPage);
}else{
rc = btreeComputeFreeSpace(pPage);
}
@@ -80679,7 +81300,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
if( flags & BTREE_PREFORMAT ){
rc = SQLITE_OK;
szNew = p->pBt->nPreformatSize;
- if( szNew<4 ) szNew = 4;
+ if( szNew<4 ){
+ szNew = 4;
+ newCell[3] = 0;
+ }
if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){
CellInfo info;
pPage->xParseCell(pPage, newCell, &info);
@@ -80701,7 +81325,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
CellInfo info;
assert( idx>=0 );
if( idx>=pPage->nCell ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pPage);
}
rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ){
@@ -80728,10 +81352,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */
assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
if( oldCell < pPage->aData+pPage->hdrOffset+10 ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pPage);
}
if( oldCell+szNew > pPage->aDataEnd ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pPage);
}
memcpy(oldCell, newCell, szNew);
return SQLITE_OK;
@@ -80741,7 +81365,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
}else if( loc<0 && pPage->nCell>0 ){
assert( pPage->leaf );
idx = ++pCur->ix;
- pCur->curFlags &= ~BTCF_ValidNKey;
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
}else{
assert( pPage->leaf );
}
@@ -80771,7 +81395,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
*/
if( pPage->nOverflow ){
assert( rc==SQLITE_OK );
- pCur->curFlags &= ~(BTCF_ValidNKey);
+ pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
rc = balance(pCur);
/* Must make sure nOverflow is reset to zero even if the balance()
@@ -80833,7 +81457,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64
nIn = pSrc->info.nLocal;
aIn = pSrc->info.pPayload;
if( aIn+nIn>pSrc->pPage->aDataEnd ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pSrc->pPage);
}
nRem = pSrc->info.nPayload;
if( nIn==nRem && nInpPage->maxLocal ){
@@ -80858,7 +81482,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64
if( nRem>nIn ){
if( aIn+nIn+4>pSrc->pPage->aDataEnd ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pSrc->pPage);
}
ovflIn = get4byte(&pSrc->info.pPayload[nIn]);
}
@@ -80954,7 +81578,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID );
if( rc || pCur->eState!=CURSOR_VALID ) return rc;
}else{
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot);
}
}
assert( pCur->eState==CURSOR_VALID );
@@ -80963,14 +81587,14 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
iCellIdx = pCur->ix;
pPage = pCur->pPage;
if( pPage->nCell<=iCellIdx ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pPage);
}
pCell = findCell(pPage, iCellIdx);
if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pPage);
}
if( pCell<&pPage->aCellIdx[pPage->nCell] ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PAGE(pPage);
}
/* If the BTREE_SAVEPOSITION bit is on, then the cursor position must
@@ -81061,7 +81685,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
n = pCur->pPage->pgno;
}
pCell = findCell(pLeaf, pLeaf->nCell-1);
- if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
+ if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_PAGE(pLeaf);
nCell = pLeaf->xCellSize(pLeaf, pCell);
assert( MX_CELL_SIZE(pBt) >= nCell );
pTmp = pBt->pTmpSpace;
@@ -81177,7 +81801,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){
*/
sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
if( pgnoRoot>btreePagecount(pBt) ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PGNO(pgnoRoot);
}
pgnoRoot++;
@@ -81225,7 +81849,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){
}
rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_PGNO(pgnoRoot);
}
if( rc!=SQLITE_OK ){
releasePage(pRoot);
@@ -81315,14 +81939,14 @@ static int clearDatabasePage(
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PGNO(pgno);
}
rc = getAndInitPage(pBt, pgno, &pPage, 0);
if( rc ) return rc;
if( (pBt->openFlags & BTREE_SINGLE)==0
&& sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1))
){
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_PAGE(pPage);
goto cleardatabasepage_out;
}
hdr = pPage->hdrOffset;
@@ -81426,7 +82050,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
assert( p->inTrans==TRANS_WRITE );
assert( iTable>=2 );
if( iTable>btreePagecount(pBt) ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_PGNO(iTable);
}
rc = sqlite3BtreeClearTable(p, iTable, 0);
@@ -82023,6 +82647,9 @@ static int checkTreePage(
** number of cells on the page. */
nCell = get2byte(&data[hdr+3]);
assert( pPage->nCell==nCell );
+ if( pPage->leaf || pPage->intKey==0 ){
+ pCheck->nRow += nCell;
+ }
/* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
** immediately follows the b-tree page header. */
@@ -82134,6 +82761,7 @@ static int checkTreePage(
btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
}
}
+ assert( heap!=0 );
/* Add the freeblocks to the min-heap
**
** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
@@ -82233,6 +82861,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck(
sqlite3 *db, /* Database connection that is running the check */
Btree *p, /* The btree to be checked */
Pgno *aRoot, /* An array of root pages numbers for individual trees */
+ Mem *aCnt, /* Memory cells to write counts for each tree to */
int nRoot, /* Number of entries in aRoot[] */
int mxErr, /* Stop reporting errors after this many */
int *pnErr, /* OUT: Write number of errors seen to this variable */
@@ -82246,7 +82875,9 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck(
int bPartial = 0; /* True if not checking all btrees */
int bCkFreelist = 1; /* True to scan the freelist */
VVA_ONLY( int nRef );
+
assert( nRoot>0 );
+ assert( aCnt!=0 );
/* aRoot[0]==0 means this is a partial check */
if( aRoot[0]==0 ){
@@ -82319,15 +82950,18 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck(
testcase( pBt->db->flags & SQLITE_CellSizeCk );
pBt->db->flags &= ~(u64)SQLITE_CellSizeCk;
for(i=0; (int)iautoVacuum && aRoot[i]>1 && !bPartial ){
- checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
- }
+ if( pBt->autoVacuum && aRoot[i]>1 && !bPartial ){
+ checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
+ }
#endif
- sCheck.v0 = aRoot[i];
- checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64);
+ sCheck.v0 = aRoot[i];
+ checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64);
+ }
+ sqlite3MemSetArrayInt64(aCnt, i, sCheck.nRow);
}
pBt->db->flags = savedDbFlags;
@@ -84382,6 +85016,13 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
}
}
+/*
+** Set the iIdx'th entry of array aMem[] to contain integer value val.
+*/
+SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val){
+ sqlite3VdbeMemSetInt64(&aMem[iIdx], val);
+}
+
/* A no-op destructor */
SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
@@ -84966,7 +85607,8 @@ static int valueFromFunction(
goto value_from_function_out;
}
for(i=0; ia[i].pExpr, enc, aff, &apVal[i]);
+ rc = sqlite3Stat4ValueFromExpr(pCtx->pParse, pList->a[i].pExpr, aff,
+ &apVal[i]);
if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;
}
}
@@ -85070,14 +85712,20 @@ static int valueFromExpr(
}
/* Handle negative integers in a single step. This is needed in the
- ** case when the value is -9223372036854775808.
- */
- if( op==TK_UMINUS
- && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){
- pExpr = pExpr->pLeft;
- op = pExpr->op;
- negInt = -1;
- zNeg = "-";
+ ** case when the value is -9223372036854775808. Except - do not do this
+ ** for hexadecimal literals. */
+ if( op==TK_UMINUS ){
+ Expr *pLeft = pExpr->pLeft;
+ if( (pLeft->op==TK_INTEGER || pLeft->op==TK_FLOAT) ){
+ if( ExprHasProperty(pLeft, EP_IntValue)
+ || pLeft->u.zToken[0]!='0' || (pLeft->u.zToken[1] & ~0x20)!='X'
+ ){
+ pExpr = pLeft;
+ op = pExpr->op;
+ negInt = -1;
+ zNeg = "-";
+ }
+ }
}
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
@@ -85086,12 +85734,26 @@ static int valueFromExpr(
if( ExprHasProperty(pExpr, EP_IntValue) ){
sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
}else{
- zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
- if( zVal==0 ) goto no_mem;
- sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
+ i64 iVal;
+ if( op==TK_INTEGER && 0==sqlite3DecOrHexToI64(pExpr->u.zToken, &iVal) ){
+ sqlite3VdbeMemSetInt64(pVal, iVal*negInt);
+ }else{
+ zVal = sqlite3MPrintf(db, "%s%s", zNeg, 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_BLOB ){
- sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
+ if( affinity==SQLITE_AFF_BLOB ){
+ if( op==TK_FLOAT ){
+ assert( pVal && pVal->z && pVal->flags==(MEM_Str|MEM_Term) );
+ sqlite3AtoF(pVal->z, &pVal->u.r, pVal->n, SQLITE_UTF8);
+ pVal->flags = MEM_Real;
+ }else if( op==TK_INTEGER ){
+ /* This case is required by -9223372036854775808 and other strings
+ ** that look like integers but cannot be handled by the
+ ** sqlite3DecOrHexToI64() call above. */
+ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
+ }
}else{
sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
}
@@ -85361,17 +86023,17 @@ SQLITE_PRIVATE int sqlite3Stat4Column(
sqlite3_value **ppVal /* OUT: Extracted value */
){
u32 t = 0; /* a column type code */
- int nHdr; /* Size of the header in the record */
- int iHdr; /* Next unread header byte */
- int iField; /* Next unread data byte */
- int szField = 0; /* Size of the current data field */
+ u32 nHdr; /* Size of the header in the record */
+ u32 iHdr; /* Next unread header byte */
+ i64 iField; /* Next unread data byte */
+ u32 szField = 0; /* Size of the current data field */
int i; /* Column index */
u8 *a = (u8*)pRec; /* Typecast byte array */
Mem *pMem = *ppVal; /* Write result into this Mem object */
assert( iCol>0 );
iHdr = getVarint32(a, nHdr);
- if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT;
+ if( nHdr>(u32)nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT;
iField = nHdr;
for(i=0; i<=iCol; i++){
iHdr += getVarint32(&a[iHdr], t);
@@ -86869,6 +87531,15 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
assert( aLabel!=0 ); /* True because of tag-20230419-1 */
pOp->p2 = aLabel[ADDR(pOp->p2)];
}
+
+ /* OPFLG_JUMP opcodes never have P2==0, though OPFLG_JUMP0 opcodes
+ ** might */
+ assert( pOp->p2>0
+ || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP0)!=0 );
+
+ /* Jumps never go off the end of the bytecode array */
+ assert( pOp->p2nOp
+ || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)==0 );
break;
}
}
@@ -87334,6 +88005,12 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4);
break;
}
+ case P4_SUBRTNSIG: {
+ SubrtnSig *pSig = (SubrtnSig*)p4;
+ sqlite3DbFree(db, pSig->zAff);
+ sqlite3DbFree(db, pSig);
+ break;
+ }
}
}
@@ -87913,6 +88590,11 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
zP4 = pOp->p4.pTab->zName;
break;
}
+ case P4_SUBRTNSIG: {
+ SubrtnSig *pSig = pOp->p4.pSubrtnSig;
+ sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff);
+ break;
+ }
default: {
zP4 = pOp->p4.z;
}
@@ -89298,7 +89980,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
/* Check for immediate foreign key violations. */
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
- sqlite3VdbeCheckFk(p, 0);
+ (void)sqlite3VdbeCheckFk(p, 0);
}
/* If the auto-commit flag is set and this is the only active writer
@@ -90013,6 +90695,23 @@ static void serialGet(
pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
}
}
+static int serialGet7(
+ const unsigned char *buf, /* Buffer to deserialize from */
+ Mem *pMem /* Memory cell to write value into */
+){
+ u64 x = FOUR_BYTE_UINT(buf);
+ u32 y = FOUR_BYTE_UINT(buf+4);
+ x = (x<<32) + y;
+ assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
+ swapMixedEndianFloat(x);
+ memcpy(&pMem->u.r, &x, sizeof(x));
+ if( IsNaN(x) ){
+ pMem->flags = MEM_Null;
+ return 1;
+ }
+ pMem->flags = MEM_Real;
+ return 0;
+}
SQLITE_PRIVATE void sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
@@ -90428,7 +91127,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem
** We must use separate SQLITE_NOINLINE functions here, since otherwise
** optimizer code movement causes gcov to become very confused.
*/
-#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
static int SQLITE_NOINLINE doubleLt(double a, double b){ return ar );
- testcase( x==r );
- return (xr);
}else{
i64 y;
- double s;
if( r<-9223372036854775808.0 ) return +1;
if( r>=9223372036854775808.0 ) return -1;
y = (i64)r;
if( iy ) return +1;
- s = (double)i;
- testcase( doubleLt(s,r) );
- testcase( doubleLt(r,s) );
- testcase( doubleEq(r,s) );
- return (sr);
+ testcase( doubleLt(((double)i),r) );
+ testcase( doubleLt(r,((double)i)) );
+ testcase( doubleEq(r,((double)i)) );
+ return (((double)i)r);
}
}
@@ -90692,7 +91382,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
}else if( serial_type==0 ){
rc = -1;
}else if( serial_type==7 ){
- sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
+ serialGet7(&aKey1[d1], &mem1);
rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r);
}else{
i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
@@ -90717,14 +91407,18 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
}else if( serial_type==0 ){
rc = -1;
}else{
- sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
if( serial_type==7 ){
- if( mem1.u.ru.r ){
+ if( serialGet7(&aKey1[d1], &mem1) ){
+ rc = -1; /* mem1 is a NaN */
+ }else if( mem1.u.ru.r ){
rc = -1;
}else if( mem1.u.r>pRhs->u.r ){
rc = +1;
+ }else{
+ assert( rc==0 );
}
}else{
+ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r);
}
}
@@ -90794,7 +91488,14 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
/* RHS is null */
else{
serial_type = aKey1[idx1];
- rc = (serial_type!=0 && serial_type!=10);
+ if( serial_type==0
+ || serial_type==10
+ || (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0)
+ ){
+ assert( rc==0 );
+ }else{
+ rc = 1;
+ }
}
if( rc!=0 ){
@@ -91254,7 +91955,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
assert( iVar>0 );
if( v ){
Mem *pMem = &v->aVar[iVar-1];
- assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
+ assert( (v->db->flags & SQLITE_EnableQPSG)==0
+ || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 );
if( 0==(pMem->flags & MEM_Null) ){
sqlite3_value *pRet = sqlite3ValueNew(v->db);
if( pRet ){
@@ -91274,7 +91976,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
*/
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
assert( iVar>0 );
- assert( (v->db->flags & SQLITE_EnableQPSG)==0 );
+ assert( (v->db->flags & SQLITE_EnableQPSG)==0
+ || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 );
if( iVar>=32 ){
v->expmask |= 0x80000000;
}else{
@@ -91448,6 +92151,13 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
}
sqlite3DbNNFreeNN(db, preupdate.aNew);
}
+ if( preupdate.apDflt ){
+ int i;
+ for(i=0; inCol; i++){
+ sqlite3ValueFree(preupdate.apDflt[i]);
+ }
+ sqlite3DbFree(db, preupdate.apDflt);
+ }
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -93094,6 +93804,17 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
+**
+** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK,
+** that means all of the the following will be true:
+**
+** p!=0
+** p->pVar!=0
+** i>0
+** i<=p->nVar
+**
+** An assert() is normally added after vdbeUnbind() to help static analyzers
+** realize this.
*/
static int vdbeUnbind(Vdbe *p, unsigned int i){
Mem *pVar;
@@ -93151,6 +93872,7 @@ static int bindText(
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
if( zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
@@ -93200,6 +93922,7 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
sqlite3_mutex_leave(p->db->mutex);
}
@@ -93213,6 +93936,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
sqlite3_mutex_leave(p->db->mutex);
}
@@ -93223,6 +93947,7 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3_mutex_leave(p->db->mutex);
}
return rc;
@@ -93238,6 +93963,7 @@ SQLITE_API int sqlite3_bind_pointer(
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
sqlite3_mutex_leave(p->db->mutex);
}else if( xDestructor ){
@@ -93319,6 +94045,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
#ifndef SQLITE_OMIT_INCRBLOB
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
#else
@@ -93681,7 +94408,30 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa
if( iIdx==p->pTab->iPKey ){
sqlite3VdbeMemSetInt64(pMem, p->iKey1);
}else if( iIdx>=p->pUnpacked->nField ){
- *ppValue = (sqlite3_value *)columnNullValue();
+ /* This occurs when the table has been extended using ALTER TABLE
+ ** ADD COLUMN. The value to return is the default value of the column. */
+ Column *pCol = &p->pTab->aCol[iIdx];
+ if( pCol->iDflt>0 ){
+ if( p->apDflt==0 ){
+ int nByte = sizeof(sqlite3_value*)*p->pTab->nCol;
+ p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte);
+ if( p->apDflt==0 ) goto preupdate_old_out;
+ }
+ if( p->apDflt[iIdx]==0 ){
+ sqlite3_value *pVal = 0;
+ Expr *pDflt;
+ assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) );
+ pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
+ rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal);
+ if( rc==SQLITE_OK && pVal==0 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }
+ p->apDflt[iIdx] = pVal;
+ }
+ *ppValue = p->apDflt[iIdx];
+ }else{
+ *ppValue = (sqlite3_value *)columnNullValue();
+ }
}else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
if( pMem->flags & (MEM_Int|MEM_IntReal) ){
testcase( pMem->flags & MEM_Int );
@@ -93880,7 +94630,6 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2(
}
if( flags & SQLITE_SCANSTAT_COMPLEX ){
idx = iScan;
- pScan = &p->aScan[idx];
}else{
/* If the COMPLEX flag is clear, then this function must ignore any
** ScanStatus structures with ScanStatus.addrLoop set to 0. */
@@ -93893,6 +94642,8 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2(
}
}
if( idx>=p->nScan ) return 1;
+ assert( pScan==0 || pScan==&p->aScan[idx] );
+ pScan = &p->aScan[idx];
switch( iScanStatusOp ){
case SQLITE_SCANSTAT_NLOOP: {
@@ -94239,6 +94990,104 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
/* #include "vectorIndexInt.h" */
#endif
+/*
+** High-resolution hardware timer used for debugging and testing only.
+*/
+#if defined(VDBE_PROFILE) \
+ || defined(SQLITE_PERFORMANCE_TRACE) \
+ || defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+/************** Include hwtime.h in the middle of vdbe.c *********************/
+/************** Begin file hwtime.h ******************************************/
+/*
+** 2008 May 27
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains inline asm code for retrieving "high-performance"
+** counters for x86 and x86_64 class CPUs.
+*/
+#ifndef SQLITE_HWTIME_H
+#define SQLITE_HWTIME_H
+
+/*
+** The following routine only works on Pentium-class (or newer) processors.
+** It uses the RDTSC opcode to read the cycle count value out of the
+** processor and returns that value. This can be used for high-res
+** profiling.
+*/
+#if !defined(__STRICT_ANSI__) && \
+ (defined(__GNUC__) || defined(_MSC_VER)) && \
+ (defined(i386) || defined(__i386__) || defined(_M_IX86))
+
+ #if defined(__GNUC__)
+
+ __inline__ sqlite_uint64 sqlite3Hwtime(void){
+ unsigned int lo, hi;
+ __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+ return (sqlite_uint64)hi << 32 | lo;
+ }
+
+ #elif defined(_MSC_VER)
+
+ __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
+ __asm {
+ rdtsc
+ ret ; return value at EDX:EAX
+ }
+ }
+
+ #endif
+
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
+
+ __inline__ sqlite_uint64 sqlite3Hwtime(void){
+ unsigned int lo, hi;
+ __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+ return (sqlite_uint64)hi << 32 | lo;
+ }
+
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
+
+ __inline__ sqlite_uint64 sqlite3Hwtime(void){
+ unsigned long long retval;
+ unsigned long junk;
+ __asm__ __volatile__ ("\n\
+ 1: mftbu %1\n\
+ mftb %L0\n\
+ mftbu %0\n\
+ cmpw %0,%1\n\
+ bne 1b"
+ : "=r" (retval), "=r" (junk));
+ return retval;
+ }
+
+#else
+
+ /*
+ ** asm() is needed for hardware timing support. Without asm(),
+ ** disable the sqlite3Hwtime() routine.
+ **
+ ** sqlite3Hwtime() is only used for some obscure debugging
+ ** and analysis configurations, not in any deliverable, so this
+ ** should not be a great loss.
+ */
+SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
+
+#endif
+
+#endif /* !defined(SQLITE_HWTIME_H) */
+
+/************** End of hwtime.h **********************************************/
+/************** Continuing where we left off in vdbe.c ***********************/
+#endif
+
/*
** Invoke this macro on memory cells just prior to changing the
** value of the cell. This macro verifies that shallow copies are
@@ -95370,7 +96219,7 @@ case OP_Return: { /* in1 */
**
** See also: EndCoroutine
*/
-case OP_InitCoroutine: { /* jump */
+case OP_InitCoroutine: { /* jump0 */
assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
assert( pOp->p2>=0 && pOp->p2nOp );
assert( pOp->p3>=0 && pOp->p3nOp );
@@ -95393,7 +96242,9 @@ case OP_InitCoroutine: { /* jump */
**
** The instruction at the address in register P1 is a Yield.
** Jump to the P2 parameter of that Yield.
-** After the jump, register P1 becomes undefined.
+** After the jump, the value register P1 is left with a value
+** such that subsequent OP_Yields go back to the this same
+** OP_EndCoroutine instruction.
**
** See also: InitCoroutine
*/
@@ -95405,8 +96256,8 @@ case OP_EndCoroutine: { /* in1 */
pCaller = &aOp[pIn1->u.i];
assert( pCaller->opcode==OP_Yield );
assert( pCaller->p2>=0 && pCaller->p2nOp );
+ pIn1->u.i = (int)(pOp - p->aOp) - 1;
pOp = &aOp[pCaller->p2 - 1];
- pIn1->flags = MEM_Undefined;
break;
}
@@ -95423,7 +96274,7 @@ case OP_EndCoroutine: { /* in1 */
**
** See also: InitCoroutine
*/
-case OP_Yield: { /* in1, jump */
+case OP_Yield: { /* in1, jump0 */
int pcDest;
pIn1 = &aMem[pOp->p1];
assert( VdbeMemDynamic(pIn1)==0 );
@@ -95453,7 +96304,7 @@ case OP_HaltIfNull: { /* in3 */
/* no break */ deliberate_fall_through
}
-/* Opcode: Halt P1 P2 * P4 P5
+/* Opcode: Halt P1 P2 P3 P4 P5
**
** Exit immediately. All open cursors, etc are closed
** automatically.
@@ -95466,18 +96317,22 @@ case OP_HaltIfNull: { /* in3 */
** then back out all changes that have occurred during this execution of the
** VDBE, but do not rollback the transaction.
**
-** If P4 is not null then it is an error message string.
+** If P3 is not zero and P4 is NULL, then P3 is a register that holds the
+** text of an error message.
+**
+** If P3 is zero and P4 is not null then the error message string is held
+** in P4.
**
-** P5 is a value between 0 and 4, inclusive, that modifies the P4 string.
+** P5 is a value between 1 and 4, inclusive, then the P4 error message
+** string is modified as follows:
**
-** 0: (no change)
** 1: NOT NULL constraint failed: P4
** 2: UNIQUE constraint failed: P4
** 3: CHECK constraint failed: P4
** 4: FOREIGN KEY constraint failed: P4
**
-** If P5 is not zero and P4 is NULL, then everything after the ":" is
-** omitted.
+** If P3 is zero and P5 is not zero and P4 is NULL, then everything after
+** the ":" is omitted.
**
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program. So a jump past the last instruction of the program
@@ -95490,6 +96345,9 @@ case OP_Halt: {
#ifdef SQLITE_DEBUG
if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
#endif
+ assert( pOp->p4type==P4_NOTUSED
+ || pOp->p4type==P4_STATIC
+ || pOp->p4type==P4_DYNAMIC );
/* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates
** something is wrong with the code generator. Raise an assertion in order
@@ -95520,7 +96378,12 @@ case OP_Halt: {
p->errorAction = (u8)pOp->p2;
assert( pOp->p5<=4 );
if( p->rc ){
- if( pOp->p5 ){
+ if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){
+ const char *zErr;
+ assert( pOp->p3<=(p->nMem + 1 - p->nCursor) );
+ zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8);
+ sqlite3VdbeError(p, "%s", zErr);
+ }else if( pOp->p5 ){
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
"FOREIGN KEY" };
testcase( pOp->p5==1 );
@@ -95753,19 +96616,15 @@ case OP_Blob: { /* out2 */
break;
}
-/* Opcode: Variable P1 P2 * P4 *
-** Synopsis: r[P2]=parameter(P1,P4)
+/* Opcode: Variable P1 P2 * * *
+** Synopsis: r[P2]=parameter(P1)
**
** Transfer the values of bound parameter P1 into register P2
-**
-** If the parameter is named, then its name appears in P4.
-** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
- assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
@@ -96286,7 +97145,7 @@ case OP_AddImm: { /* in1 */
** without data loss, then jump immediately to P2, or if P2==0
** raise an SQLITE_MISMATCH exception.
*/
-case OP_MustBeInt: { /* jump, in1 */
+case OP_MustBeInt: { /* jump0, in1 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_Int)==0 ){
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
@@ -96327,7 +97186,7 @@ case OP_RealAffinity: { /* in1 */
}
#endif
-#ifndef SQLITE_OMIT_CAST
+#if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE)
/* Opcode: Cast P1 P2 * * *
** Synopsis: affinity(r[P1])
**
@@ -96542,7 +97401,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}
}
}else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){
- if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
+ if( (flags1 & MEM_Str)!=0 ){
+ pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
+ }else if( (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_Real );
testcase( pIn1->flags & MEM_IntReal );
@@ -96551,7 +97412,9 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
}
- if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
+ if( (flags3 & MEM_Str)!=0 ){
+ pIn3->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
+ }else if( (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_Real );
testcase( pIn3->flags & MEM_IntReal );
@@ -97895,11 +98758,16 @@ case OP_MakeRecord: {
switch( len ){
default: zPayload[7] = (u8)(v&0xff); v >>= 8;
zPayload[6] = (u8)(v&0xff); v >>= 8;
+ /* no break */ deliberate_fall_through
case 6: zPayload[5] = (u8)(v&0xff); v >>= 8;
zPayload[4] = (u8)(v&0xff); v >>= 8;
+ /* no break */ deliberate_fall_through
case 4: zPayload[3] = (u8)(v&0xff); v >>= 8;
+ /* no break */ deliberate_fall_through
case 3: zPayload[2] = (u8)(v&0xff); v >>= 8;
+ /* no break */ deliberate_fall_through
case 2: zPayload[1] = (u8)(v&0xff); v >>= 8;
+ /* no break */ deliberate_fall_through
case 1: zPayload[0] = (u8)(v&0xff);
}
zPayload += len;
@@ -98602,23 +99470,23 @@ case OP_OpenWrite:
if( pDb->pSchema->file_format < p->minWriteFileFormat ){
p->minWriteFileFormat = pDb->pSchema->file_format;
}
+ if( pOp->p5 & OPFLAG_P2ISREG ){
+ assert( p2>0 );
+ assert( p2<=(u32)(p->nMem+1 - p->nCursor) );
+ pIn2 = &aMem[p2];
+ assert( memIsValid(pIn2) );
+ assert( (pIn2->flags & MEM_Int)!=0 );
+ sqlite3VdbeMemIntegerify(pIn2);
+ p2 = (int)pIn2->u.i;
+ /* The p2 value always comes from a prior OP_CreateBtree opcode and
+ ** that opcode will always set the p2 value to 2 or more or else fail.
+ ** If there were a failure, the prepared statement would have halted
+ ** before reaching this instruction. */
+ assert( p2>=2 );
+ }
}else{
wrFlag = 0;
- }
- if( pOp->p5 & OPFLAG_P2ISREG ){
- assert( p2>0 );
- assert( p2<=(u32)(p->nMem+1 - p->nCursor) );
- assert( pOp->opcode==OP_OpenWrite );
- pIn2 = &aMem[p2];
- assert( memIsValid(pIn2) );
- assert( (pIn2->flags & MEM_Int)!=0 );
- sqlite3VdbeMemIntegerify(pIn2);
- p2 = (int)pIn2->u.i;
- /* The p2 value always comes from a prior OP_CreateBtree opcode and
- ** that opcode will always set the p2 value to 2 or more or else fail.
- ** If there were a failure, the prepared statement would have halted
- ** before reaching this instruction. */
- assert( p2>=2 );
+ assert( (pOp->p5 & OPFLAG_P2ISREG)==0 );
}
if( pOp->p4type==P4_KEYINFO ){
pKeyInfo = pOp->p4.pKeyInfo;
@@ -98797,7 +99665,10 @@ case OP_OpenEphemeral: { /* ncycle */
}
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
if( rc ){
+ assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) );
sqlite3BtreeClose(pCx->ub.pBtx);
+ }else{
+ assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) );
}
}
}
@@ -98863,7 +99734,8 @@ case OP_SequenceTest: {
** is the only cursor opcode that works with a pseudo-table.
**
** P3 is the number of fields in the records that will be stored by
-** the pseudo-table.
+** the pseudo-table. If P2 is 0 or negative then the pseudo-cursor
+** will return NULL for every column.
*/
case OP_OpenPseudo: {
VdbeCursor *pCx;
@@ -99006,10 +99878,10 @@ case OP_ColumnsUsed: {
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
-case OP_SeekLT: /* jump, in3, group, ncycle */
-case OP_SeekLE: /* jump, in3, group, ncycle */
-case OP_SeekGE: /* jump, in3, group, ncycle */
-case OP_SeekGT: { /* jump, in3, group, ncycle */
+case OP_SeekLT: /* jump0, in3, group, ncycle */
+case OP_SeekLE: /* jump0, in3, group, ncycle */
+case OP_SeekGE: /* jump0, in3, group, ncycle */
+case OP_SeekGT: { /* jump0, in3, group, ncycle */
int res; /* Comparison result */
int oc; /* Opcode */
VdbeCursor *pC; /* The cursor to seek */
@@ -99575,6 +100447,7 @@ case OP_Found: { /* jump, in3, ncycle */
r.pKeyInfo = pC->pKeyInfo;
r.default_rc = 0;
#ifdef SQLITE_DEBUG
+ (void)sqlite3FaultSim(50); /* For use by --counter in TH3 */
for(ii=0; iip1>=0 && pOp->p1nCursor );
+ assert( pOp->p4type==P4_INT32 );
+ assert( pOp->p3>=-1 && pOp->p3<=640*2 );
+ assert( pOp->p4.i>=-1 && pOp->p4.i<=640*2 );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
pCrsr = pC->uc.pCursor;
assert( pCrsr );
rc = sqlite3BtreeFirst(pCrsr, &res);
if( rc ) goto abort_due_to_error;
- if( res==0 ){
+ if( res!=0 ){
+ sz = -1; /* -Infinity encoding */
+ }else{
sz = sqlite3BtreeRowCountEst(pCrsr);
- if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)p3 ) res = 1;
+ assert( sz>0 );
+ sz = sqlite3LogEst((u64)sz);
}
+ res = sz>=pOp->p3 && sz<=pOp->p4.i;
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
break;
@@ -100593,7 +101476,7 @@ case OP_Sort: { /* jump ncycle */
** from the beginning toward the end. In other words, the cursor is
** configured to use Next, not Prev.
*/
-case OP_Rewind: { /* jump, ncycle */
+case OP_Rewind: { /* jump0, ncycle */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
@@ -101295,11 +102178,18 @@ case OP_CreateBtree: { /* out2 */
break;
}
-/* Opcode: SqlExec * * * P4 *
+/* Opcode: SqlExec P1 P2 * P4 *
**
** Run the SQL statement or statements specified in the P4 string.
-** Disable Auth and Trace callbacks while those statements are running if
-** P1 is true.
+**
+** The P1 parameter is a bitmask of options:
+**
+** 0x0001 Disable Auth and Trace callbacks while the statements
+** in P4 are running.
+**
+** 0x0002 Set db->nAnalysisLimit to P2 while the statements in
+** P4 are running.
+**
*/
case OP_SqlExec: {
char *zErr;
@@ -101307,6 +102197,7 @@ case OP_SqlExec: {
sqlite3_xauth xAuth;
#endif
u8 mTrace;
+ int savedAnalysisLimit;
sqlite3VdbeIncrWriteCounter(p, 0);
db->nSqlExec++;
@@ -101315,18 +102206,23 @@ case OP_SqlExec: {
xAuth = db->xAuth;
#endif
mTrace = db->mTrace;
- if( pOp->p1 ){
+ savedAnalysisLimit = db->nAnalysisLimit;
+ if( pOp->p1 & 0x0001 ){
#ifndef SQLITE_OMIT_AUTHORIZATION
db->xAuth = 0;
#endif
db->mTrace = 0;
}
+ if( pOp->p1 & 0x0002 ){
+ db->nAnalysisLimit = pOp->p2;
+ }
rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr);
db->nSqlExec--;
#ifndef SQLITE_OMIT_AUTHORIZATION
db->xAuth = xAuth;
#endif
db->mTrace = mTrace;
+ db->nAnalysisLimit = savedAnalysisLimit;
if( zErr || rc ){
sqlite3VdbeError(p, "%s", zErr);
sqlite3_free(zErr);
@@ -101478,11 +102374,11 @@ case OP_DropTrigger: {
/* Opcode: IntegrityCk P1 P2 P3 P4 P5
**
** Do an analysis of the currently open database. Store in
-** register P1 the text of an error message describing any problems.
-** If no problems are found, store a NULL in register P1.
+** register (P1+1) the text of an error message describing any problems.
+** If no problems are found, store a NULL in register (P1+1).
**
-** The register P3 contains one less than the maximum number of allowed errors.
-** At most reg(P3) errors will be reported.
+** The register (P1) contains one less than the maximum number of allowed
+** errors. At most reg(P1) errors will be reported.
** In other words, the analysis stops as soon as reg(P1) errors are
** seen. Reg(P1) is updated with the number of errors remaining.
**
@@ -101502,19 +102398,21 @@ case OP_IntegrityCk: {
Mem *pnErr; /* Register keeping track of errors remaining */
assert( p->bIsReader );
+ assert( pOp->p4type==P4_INTARRAY );
nRoot = pOp->p2;
aRoot = pOp->p4.ai;
assert( nRoot>0 );
+ assert( aRoot!=0 );
assert( aRoot[0]==(Pgno)nRoot );
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
- pnErr = &aMem[pOp->p3];
+ assert( pOp->p1>0 && (pOp->p1+1)<=(p->nMem+1 - p->nCursor) );
+ pnErr = &aMem[pOp->p1];
assert( (pnErr->flags & MEM_Int)!=0 );
assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
- pIn1 = &aMem[pOp->p1];
+ pIn1 = &aMem[pOp->p1+1];
assert( pOp->p5nDb );
assert( DbMaskTest(p->btreeMask, pOp->p5) );
- rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
- (int)pnErr->u.i+1, &nErr, &z);
+ rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1],
+ &aMem[pOp->p3], nRoot, (int)pnErr->u.i+1, &nErr, &z);
sqlite3VdbeMemSetNull(pIn1);
if( nErr==0 ){
assert( z==0 );
@@ -101641,7 +102539,9 @@ case OP_RowSetTest: { /* jump, in1, in3 */
** P1 contains the address of the memory cell that contains the first memory
** cell in an array of values used as arguments to the sub-program. P2
** contains the address to jump to if the sub-program throws an IGNORE
-** exception using the RAISE() function. Register P3 contains the address
+** exception using the RAISE() function. P2 might be zero, if there is
+** no possibility that an IGNORE exception will be raised.
+** Register P3 contains the address
** of a memory cell in this (the parent) VM that is used to allocate the
** memory required by the sub-vdbe at runtime.
**
@@ -101649,7 +102549,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
**
** If P5 is non-zero, then recursive program invocation is enabled.
*/
-case OP_Program: { /* jump */
+case OP_Program: { /* jump0 */
int nMem; /* Number of memory registers for sub-program */
int nByte; /* Bytes of runtime space required for sub-program */
Mem *pRt; /* Register to allocate runtime space */
@@ -102014,18 +102914,29 @@ case OP_AggInverse:
case OP_AggStep: {
int n;
sqlite3_context *pCtx;
+ u64 nAlloc;
assert( pOp->p4type==P4_FUNCDEF );
n = pOp->p5;
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
assert( pOp->p3p2 || pOp->p3>=pOp->p2+n );
- pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) +
- (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*)));
+
+ /* Allocate space for (a) the context object and (n-1) extra pointers
+ ** to append to the sqlite3_context.argv[1] array, and (b) a memory
+ ** cell in which to store the accumulation. Be careful that the memory
+ ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits.
+ **
+ ** Note: We could avoid this by using a regular memory cell from aMem[] for
+ ** the accumulator, instead of allocating one here. */
+ nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) );
+ pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem));
if( pCtx==0 ) goto no_mem;
- pCtx->pMem = 0;
- pCtx->pOut = (Mem*)&(pCtx->argv[n]);
+ pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc);
+ assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) );
+
sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null);
+ pCtx->pMem = 0;
pCtx->pFunc = pOp->p4.pFunc;
pCtx->iOp = (int)(pOp - aOp);
pCtx->pVdbe = p;
@@ -103238,7 +104149,7 @@ case OP_Filter: { /* jump */
** error is encountered.
*/
case OP_Trace:
-case OP_Init: { /* jump */
+case OP_Init: { /* jump0 */
int i;
#ifndef SQLITE_OMIT_TRACE
char *zTrace;
@@ -103399,14 +104310,29 @@ case OP_ReleaseReg: {
/* Opcode: Noop * * * * *
**
-** Do nothing. This instruction is often useful as a jump
-** destination.
+** Do nothing. Continue downward to the next opcode.
*/
-/*
-** The magic Explain opcode are only inserted when explain==2 (which
-** is to say when the EXPLAIN QUERY PLAN syntax is used.)
-** This opcode records information from the optimizer. It is the
-** the same as a no-op. This opcodesnever appears in a real VM program.
+/* Opcode: Explain P1 P2 P3 P4 *
+**
+** This is the same as OP_Noop during normal query execution. The
+** purpose of this opcode is to hold information about the query
+** plan for the purpose of EXPLAIN QUERY PLAN output.
+**
+** The P4 value is human-readable text that describes the query plan
+** element. Something like "SCAN t1" or "SEARCH t2 USING INDEX t2x1".
+**
+** The P1 value is the ID of the current element and P2 is the parent
+** element for the case of nested query plan elements. If P2 is zero
+** then this element is a top-level element.
+**
+** For loop elements, P3 is the estimated code of each invocation of this
+** element.
+**
+** As with all opcodes, the meanings of the parameters for OP_Explain
+** are subject to change from one release to the next. Applications
+** should not attempt to interpret or use any of the information
+** contained in the OP_Explain opcode. The information provided by this
+** opcode is intended for testing and debugging use only.
*/
default: { /* This is really OP_Noop, OP_Explain */
assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain );
@@ -103733,6 +104659,11 @@ SQLITE_API int sqlite3_blob_open(
pTab = 0;
sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
}
+ if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){
+ pTab = 0;
+ sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s",
+ zTable);
+ }
#ifndef SQLITE_OMIT_VIEW
if( pTab && IsView(pTab) ){
pTab = 0;
@@ -104640,13 +105571,14 @@ static int vdbePmaReadBlob(
while( nRem>0 ){
int rc; /* vdbePmaReadBlob() return code */
int nCopy; /* Number of bytes to copy */
- u8 *aNext; /* Pointer to buffer to copy data from */
+ u8 *aNext = 0; /* Pointer to buffer to copy data from */
nCopy = nRem;
if( nRem>p->nBuffer ) nCopy = p->nBuffer;
rc = vdbePmaReadBlob(p, nCopy, &aNext);
if( rc!=SQLITE_OK ) return rc;
assert( aNext!=p->aAlloc );
+ assert( aNext!=0 );
memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
nRem -= nCopy;
}
@@ -107139,10 +108071,10 @@ static int bytecodevtabColumn(
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
case 9: /* nexec */
- sqlite3_result_int(ctx, pOp->nExec);
+ sqlite3_result_int64(ctx, pOp->nExec);
break;
case 10: /* ncycle */
- sqlite3_result_int(ctx, pOp->nCycle);
+ sqlite3_result_int64(ctx, pOp->nCycle);
break;
#else
case 9: /* nexec */
@@ -107916,7 +108848,9 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
pSrc = p->pSrc;
if( ALWAYS(pSrc) ){
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
+ if( pItem->fg.isSubquery
+ && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect)
+ ){
return WRC_Abort;
}
if( pItem->fg.isTabFunc
@@ -108086,6 +109020,8 @@ static void resolveAlias(
assert( iCol>=0 && iColnExpr );
pOrig = pEList->a[iCol].pExpr;
assert( pOrig!=0 );
+ assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
+ if( pExpr->pAggInfo ) return;
db = pParse->db;
pDup = sqlite3ExprDup(db, pOrig, 0);
if( db->mallocFailed ){
@@ -108220,7 +109156,7 @@ static void extendFJMatch(
if( pNew ){
pNew->iTable = pMatch->iCursor;
pNew->iColumn = iColumn;
- pNew->y.pTab = pMatch->pTab;
+ pNew->y.pTab = pMatch->pSTab;
assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 );
ExprSetProperty(pNew, EP_CanBeNull);
*ppList = sqlite3ExprListAppend(pParse, *ppList, pNew);
@@ -108233,7 +109169,7 @@ static void extendFJMatch(
static SQLITE_NOINLINE int isValidSchemaTableName(
const char *zTab, /* Name as it appears in the SQL */
Table *pTab, /* The schema table we are trying to match */
- Schema *pSchema /* non-NULL if a database qualifier is present */
+ const char *zDb /* non-NULL if a database qualifier is present */
){
const char *zLegacy;
assert( pTab!=0 );
@@ -108244,7 +109180,7 @@ static SQLITE_NOINLINE int isValidSchemaTableName(
if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
return 1;
}
- if( pSchema==0 ) return 0;
+ if( zDb==0 ) return 0;
if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1;
if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1;
}else{
@@ -108284,7 +109220,7 @@ static int lookupName(
Parse *pParse, /* The parsing context */
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. */
+ const Expr *pRight, /* 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 */
){
@@ -108301,6 +109237,7 @@ static int lookupName(
Table *pTab = 0; /* Table holding the row */
Column *pCol; /* A column of pTab */
ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */
+ const char *zCol = pRight->u.zToken;
assert( pNC ); /* the name context cannot be NULL. */
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
@@ -108350,10 +109287,10 @@ static int lookupName(
if( pSrcList ){
for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){
u8 hCol;
- pTab = pItem->pTab;
+ pTab = pItem->pSTab;
assert( pTab!=0 && pTab->zName!=0 );
assert( pTab->nCol>0 || pParse->nErr );
- assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
+ assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem));
if( pItem->fg.isNestedFrom ){
/* In this case, pItem is a subquery that has been formed from a
** parenthesized subset of the FROM clause terms. Example:
@@ -108362,8 +109299,12 @@ static int lookupName(
** This pItem -------------^
*/
int hit = 0;
- assert( pItem->pSelect!=0 );
- pEList = pItem->pSelect->pEList;
+ Select *pSel;
+ assert( pItem->fg.isSubquery );
+ assert( pItem->u4.pSubq!=0 );
+ pSel = pItem->u4.pSubq->pSelect;
+ assert( pSel!=0 );
+ pEList = pSel->pEList;
assert( pEList!=0 );
assert( pEList->nExpr==pTab->nCol );
for(j=0; jnExpr; j++){
@@ -108426,7 +109367,7 @@ static int lookupName(
}
}else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){
if( pTab->tnum!=1 ) continue;
- if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue;
+ if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue;
}
assert( ExprUseYTab(pExpr) );
if( IN_RENAME_OBJECT && pItem->zAlias ){
@@ -108473,14 +109414,43 @@ static int lookupName(
}
}
if( 0==cnt && VisibleRowid(pTab) ){
+ /* pTab is a potential ROWID match. Keep track of it and match
+ ** the ROWID later if that seems appropriate. (Search for "cntTab"
+ ** to find related code.) Only allow a ROWID match if there is
+ ** a single ROWID match candidate.
+ */
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ /* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match
+ ** if there is a single VIEW candidate or if there is a single
+ ** non-VIEW candidate plus multiple VIEW candidates. In other
+ ** words non-VIEW candidate terms take precedence over VIEWs.
+ */
+ if( cntTab==0
+ || (cntTab==1
+ && pMatch!=0
+ && ALWAYS(pMatch->pSTab!=0)
+ && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0
+ && (pTab->tabFlags & TF_Ephemeral)==0)
+ ){
+ cntTab = 1;
+ pMatch = pItem;
+ }else{
+ cntTab++;
+ }
+#else
+ /* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is
+ ** simpler since we require exactly one candidate, which will
+ ** always be a non-VIEW
+ */
cntTab++;
pMatch = pItem;
+#endif
}
}
if( pMatch ){
pExpr->iTable = pMatch->iCursor;
assert( ExprUseYTab(pExpr) );
- pExpr->y.pTab = pMatch->pTab;
+ pExpr->y.pTab = pMatch->pSTab;
if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
@@ -108503,7 +109473,8 @@ static int lookupName(
if( pParse->bReturning ){
if( (pNC->ncFlags & NC_UBaseReg)!=0
&& ALWAYS(zTab==0
- || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0)
+ || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0
+ || isValidSchemaTableName(zTab, pParse->pTriggerTab, 0))
){
pExpr->iTable = op!=TK_DELETE;
pTab = pParse->pTriggerTab;
@@ -108521,7 +109492,7 @@ static int lookupName(
if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){
Upsert *pUpsert = pNC->uNC.pUpsert;
if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
- pTab = pUpsert->pUpsertSrc->a[0].pTab;
+ pTab = pUpsert->pUpsertSrc->a[0].pSTab;
pExpr->iTable = EXCLUDED_TABLE_NUMBER;
}
}
@@ -108600,13 +109571,18 @@ static int lookupName(
** Perhaps the name is a reference to the ROWID
*/
if( cnt==0
- && cntTab==1
+ && cntTab>=1
&& pMatch
&& (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
&& sqlite3IsRowid(zCol)
- && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom)
+ && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom)
){
- cnt = 1;
+ cnt = cntTab;
+#if SQLITE_ALLOW_ROWID_IN_VIEW+0==2
+ if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){
+ eNewExprOp = TK_NULL;
+ }
+#endif
if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1;
pExpr->affExpr = SQLITE_AFF_INTEGER;
}
@@ -108760,6 +109736,10 @@ static int lookupName(
sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
}else if( zTab ){
sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
+ }else if( cnt==0 && ExprHasProperty(pRight,EP_DblQuoted) ){
+ sqlite3ErrorMsg(pParse, "%s: \"%s\" - should this be a"
+ " string literal in single-quotes?",
+ zErr, zCol);
}else{
sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
}
@@ -108793,8 +109773,12 @@ static int lookupName(
** If a generated column is referenced, set bits for every column
** of the table.
*/
- if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){
- pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
+ if( pMatch ){
+ if( pExpr->iColumn>=0 ){
+ pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
+ }else{
+ pMatch->fg.rowidUsed = 1;
+ }
}
pExpr->op = eNewExprOp;
@@ -108832,7 +109816,7 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
SrcItem *pItem = &pSrc->a[iSrc];
Table *pTab;
assert( ExprUseYTab(p) );
- pTab = p->y.pTab = pItem->pTab;
+ pTab = p->y.pTab = pItem->pSTab;
p->iTable = pItem->iCursor;
if( p->y.pTab->iPKey==iCol ){
p->iColumn = -1;
@@ -108951,7 +109935,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pItem = pSrcList->a;
pExpr->op = TK_COLUMN;
assert( ExprUseYTab(pExpr) );
- pExpr->y.pTab = pItem->pTab;
+ pExpr->y.pTab = pItem->pSTab;
pExpr->iTable = pItem->iCursor;
pExpr->iColumn--;
pExpr->affExpr = SQLITE_AFF_INTEGER;
@@ -108971,6 +109955,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
** resolved. This prevents "column" from being counted as having been
** referenced, which might prevent a SELECT from being erroneously
** marked as correlated.
+ **
+ ** 2024-03-28: Beware of aggregates. A bare column of aggregated table
+ ** can still evaluate to NULL even though it is marked as NOT NULL.
+ ** Example:
+ **
+ ** CREATE TABLE t1(a INT NOT NULL);
+ ** SELECT a, a IS NULL, a IS NOT NULL, count(*) FROM t1;
+ **
+ ** The "a IS NULL" and "a IS NOT NULL" expressions cannot be optimized
+ ** here because at the time this case is hit, we do not yet know whether
+ ** or not t1 is being aggregated. We have to assume the worst and omit
+ ** the optimization. The only time it is safe to apply this optimization
+ ** is within the WHERE clause.
*/
case TK_NOTNULL:
case TK_ISNULL: {
@@ -108981,19 +109978,36 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
anRef[i] = p->nRef;
}
sqlite3WalkExpr(pWalker, pExpr->pLeft);
- if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
- testcase( ExprHasProperty(pExpr, EP_OuterON) );
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- pExpr->u.iValue = (pExpr->op==TK_NOTNULL);
- pExpr->flags |= EP_IntValue;
- pExpr->op = TK_INTEGER;
+ if( IN_RENAME_OBJECT ) return WRC_Prune;
+ if( sqlite3ExprCanBeNull(pExpr->pLeft) ){
+ /* The expression can be NULL. So the optimization does not apply */
+ return WRC_Prune;
+ }
- for(i=0, p=pNC; p && ipNext, i++){
- p->nRef = anRef[i];
+ for(i=0, p=pNC; p; p=p->pNext, i++){
+ if( (p->ncFlags & NC_Where)==0 ){
+ return WRC_Prune; /* Not in a WHERE clause. Unsafe to optimize. */
}
- sqlite3ExprDelete(pParse->db, pExpr->pLeft);
- pExpr->pLeft = 0;
}
+ testcase( ExprHasProperty(pExpr, EP_OuterON) );
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+#if TREETRACE_ENABLED
+ if( sqlite3TreeTrace & 0x80000 ){
+ sqlite3DebugPrintf(
+ "NOT NULL strength reduction converts the following to %d:\n",
+ pExpr->op==TK_NOTNULL
+ );
+ sqlite3ShowExpr(pExpr);
+ }
+#endif /* TREETRACE_ENABLED */
+ pExpr->u.iValue = (pExpr->op==TK_NOTNULL);
+ pExpr->flags |= EP_IntValue;
+ pExpr->op = TK_INTEGER;
+ for(i=0, p=pNC; p && ipNext, i++){
+ p->nRef = anRef[i];
+ }
+ sqlite3ExprDelete(pParse->db, pExpr->pLeft);
+ pExpr->pLeft = 0;
return WRC_Prune;
}
@@ -109007,7 +110021,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
*/
case TK_ID:
case TK_DOT: {
- const char *zColumn;
const char *zTable;
const char *zDb;
Expr *pRight;
@@ -109016,7 +110029,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
zDb = 0;
zTable = 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- zColumn = pExpr->u.zToken;
+ pRight = pExpr;
}else{
Expr *pLeft = pExpr->pLeft;
testcase( pNC->ncFlags & NC_IdxExpr );
@@ -109035,21 +110048,20 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) );
zTable = pLeft->u.zToken;
- zColumn = pRight->u.zToken;
assert( ExprUseYTab(pExpr) );
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
}
}
- return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
+ return lookupName(pParse, zDb, zTable, pRight, pNC, pExpr);
}
/* Resolve function names
*/
case TK_FUNCTION: {
- ExprList *pList = pExpr->x.pList; /* The argument list */
- int n = pList ? pList->nExpr : 0; /* Number of arguments */
+ ExprList *pList; /* The argument list */
+ int n; /* Number of arguments */
int no_such_func = 0; /* True if no such function exists */
int wrong_num_args = 0; /* True if wrong number of arguments */
int is_agg = 0; /* True if is an aggregate function */
@@ -109062,6 +110074,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif
assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER );
+ pList = pExpr->x.pList;
+ n = pList ? pList->nExpr : 0;
zId = pExpr->u.zToken;
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
if( pDef==0 ){
@@ -109110,6 +110124,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
}
#endif
+
+ /* If the function may call sqlite3_value_subtype(), then set the
+ ** EP_SubtArg flag on all of its argument expressions. This prevents
+ ** where.c from replacing the expression with a value read from an
+ ** index on the same expression, which will not have the correct
+ ** subtype. Also set the flag if the function expression itself is
+ ** an EP_SubtArg expression. In this case subtypes are required as
+ ** the function may return a value with a subtype back to its
+ ** caller using sqlite3_result_value(). */
+ if( (pDef->funcFlags & SQLITE_SUBTYPE)
+ || ExprHasProperty(pExpr, EP_SubtArg)
+ ){
+ int ii;
+ for(ii=0; iia[ii].pExpr, EP_SubtArg);
+ }
+ }
+
if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
/* For the purposes of the EP_ConstFunc flag, date and time
** functions and other functions that change slowly are considered
@@ -109218,11 +110250,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif
}
}
-#ifndef SQLITE_OMIT_WINDOWFUNC
- else if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ else if( ExprHasProperty(pExpr, EP_WinFunc) || pExpr->pLeft ){
is_agg = 1;
}
-#endif
sqlite3WalkExprList(pWalker, pList);
if( is_agg ){
if( pExpr->pLeft ){
@@ -109231,9 +110261,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList);
}
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( pWin ){
+ if( pWin && pParse->nErr==0 ){
Select *pSel = pNC->pWinSelect;
- assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) );
+ assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin );
if( IN_RENAME_OBJECT==0 ){
sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
if( pParse->db->mallocFailed ) break;
@@ -109292,6 +110322,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
testcase( pNC->ncFlags & NC_PartIdx );
testcase( pNC->ncFlags & NC_IdxExpr );
testcase( pNC->ncFlags & NC_GenCol );
+ assert( pExpr->x.pSelect );
if( pNC->ncFlags & NC_SelfRef ){
notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr);
}else{
@@ -109300,6 +110331,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
+ pExpr->x.pSelect->selFlags |= SF_Correlated;
}
pNC->ncFlags |= NC_Subquery;
}
@@ -109438,7 +110470,7 @@ static int resolveOrderByTermToExprList(
int rc; /* Return code from subprocedures */
u8 savedSuppErr; /* Saved value of db->suppressErr */
- assert( sqlite3ExprIsInteger(pE, &i)==0 );
+ assert( sqlite3ExprIsInteger(pE, &i, 0)==0 );
pEList = pSelect->pEList;
/* Resolve all names in the ORDER BY term expression
@@ -109537,7 +110569,7 @@ static int resolveCompoundOrderBy(
if( pItem->fg.done ) continue;
pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
if( NEVER(pE==0) ) continue;
- if( sqlite3ExprIsInteger(pE, &iCol) ){
+ if( sqlite3ExprIsInteger(pE, &iCol, 0) ){
if( iCol<=0 || iCol>pEList->nExpr ){
resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE);
return 1;
@@ -109722,7 +110754,7 @@ static int resolveOrderGroupBy(
continue;
}
}
- if( sqlite3ExprIsInteger(pE2, &iCol) ){
+ if( sqlite3ExprIsInteger(pE2, &iCol, 0) ){
/* The ORDER BY term is an integer constant. Again, set the column
** number so that sqlite3ResolveOrderGroupBy() will convert the
** order-by term to a copy of the result-set expression */
@@ -109813,7 +110845,11 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** moves the pOrderBy down to the sub-query. It will be moved back
** after the names have been resolved. */
if( p->selFlags & SF_Converted ){
- Select *pSub = p->pSrc->a[0].pSelect;
+ Select *pSub;
+ assert( p->pSrc->a[0].fg.isSubquery );
+ assert( p->pSrc->a[0].u4.pSubq!=0 );
+ pSub = p->pSrc->a[0].u4.pSubq->pSelect;
+ assert( pSub!=0 );
assert( p->pSrc->nSrc==1 && p->pOrderBy );
assert( pSub->pPrior && pSub->pOrderBy==0 );
pSub->pOrderBy = p->pOrderBy;
@@ -109825,12 +110861,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
if( pOuterNC ) pOuterNC->nNestedSelect++;
for(i=0; ipSrc->nSrc; i++){
SrcItem *pItem = &p->pSrc->a[i];
- if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
+ assert( pItem->zName!=0
+ || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/
+ if( pItem->fg.isSubquery
+ && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0
+ ){
int nRef = pOuterNC ? pOuterNC->nRef : 0;
const char *zSavedContext = pParse->zAuthContext;
if( pItem->zName ) pParse->zAuthContext = pItem->zName;
- sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
+ sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC);
pParse->zAuthContext = zSavedContext;
if( pParse->nErr ) return WRC_Abort;
assert( db->mallocFailed==0 );
@@ -109893,7 +110933,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
}
+ sNC.ncFlags |= NC_Where;
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
+ sNC.ncFlags &= ~NC_Where;
/* Resolve names in table-valued-function arguments */
for(i=0; ipSrc->nSrc; i++){
@@ -109930,7 +110972,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** These integers will be replaced by copies of the corresponding result
** set expressions by the call to resolveOrderGroupBy() below. */
if( p->selFlags & SF_Converted ){
- Select *pSub = p->pSrc->a[0].pSelect;
+ Select *pSub;
+ assert( p->pSrc->a[0].fg.isSubquery );
+ pSub = p->pSrc->a[0].u4.pSubq->pSelect;
+ assert( pSub!=0 );
p->pOrderBy = pSub->pOrderBy;
pSub->pOrderBy = 0;
}
@@ -110084,6 +111129,9 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
** Resolve all names for all expression in an expression list. This is
** just like sqlite3ResolveExprNames() except that it works for an expression
** list rather than a single expression.
+**
+** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a
+** failure.
*/
SQLITE_PRIVATE int sqlite3ResolveExprListNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
@@ -110092,7 +111140,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
int i;
int savedHasAgg = 0;
Walker w;
- if( pList==0 ) return WRC_Continue;
+ if( pList==0 ) return SQLITE_OK;
w.pParse = pNC->pParse;
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
@@ -110106,7 +111154,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
#if SQLITE_MAX_EXPR_DEPTH>0
w.pParse->nHeight += pExpr->nHeight;
if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
- return WRC_Abort;
+ return SQLITE_ERROR;
}
#endif
sqlite3WalkExprNN(&w, pExpr);
@@ -110123,10 +111171,10 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg);
}
- if( w.pParse->nErr>0 ) return WRC_Abort;
+ if( w.pParse->nErr>0 ) return SQLITE_ERROR;
}
pNC->ncFlags |= savedHasAgg;
- return WRC_Continue;
+ return SQLITE_OK;
}
/*
@@ -110194,7 +111242,7 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference(
if( pTab ){
sSrc.nSrc = 1;
sSrc.a[0].zName = pTab->zName;
- sSrc.a[0].pTab = pTab;
+ sSrc.a[0].pSTab = pTab;
sSrc.a[0].iCursor = -1;
if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){
/* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP
@@ -110299,7 +111347,9 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
op = pExpr->op;
continue;
}
- if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break;
+ if( op!=TK_REGISTER ) break;
+ op = pExpr->op2;
+ if( NEVER( op==TK_REGISTER ) ) break;
}
return pExpr->affExpr;
}
@@ -110432,9 +111482,10 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
- }else{
- assert( pExpr->op==TK_COLLATE );
+ }else if( pExpr->op==TK_COLLATE ){
pExpr = pExpr->pLeft;
+ }else{
+ break;
}
}
return pExpr;
@@ -111128,11 +112179,12 @@ SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){
** 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
+** Special case (tag-20240227-a): 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.
+** See also tag-20240227-b.
*/
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */
@@ -111148,7 +112200,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
if( pToken ){
if( op!=TK_INTEGER || pToken->z==0
|| sqlite3GetInt32(pToken->z, &iValue)==0 ){
- nExtra = pToken->n+1;
+ nExtra = pToken->n+1; /* tag-20240227-a */
assert( iValue>=0 );
}
}
@@ -111580,6 +112632,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
assert( db!=0 );
+exprDeleteRestart:
assert( !ExprUseUValue(p) || p->u.iValue>=0 );
assert( !ExprUseYWin(p) || !ExprUseYSub(p) );
assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed );
@@ -111595,7 +112648,6 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 );
- if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
if( p->pRight ){
assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3ExprDeleteNN(db, p->pRight);
@@ -111610,6 +112662,19 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
}
#endif
}
+ if( p->pLeft && p->op!=TK_SELECT_COLUMN ){
+ Expr *pLeft = p->pLeft;
+ if( !ExprHasProperty(p, EP_Static)
+ && !ExprHasProperty(pLeft, EP_Static)
+ ){
+ /* Avoid unnecessary recursion on unary operators */
+ sqlite3DbNNFreeNN(db, p);
+ p = pLeft;
+ goto exprDeleteRestart;
+ }else{
+ sqlite3ExprDeleteNN(db, pLeft);
+ }
+ }
}
if( !ExprHasProperty(p, EP_Static) ){
sqlite3DbNNFreeNN(db, p);
@@ -111642,11 +112707,11 @@ SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
**
** The pExpr might be deleted immediately on an OOM error.
**
-** The deferred delete is (currently) implemented by adding the
-** pExpr to the pParse->pConstExpr list with a register number of 0.
+** Return 0 if the delete was successfully deferred. Return non-zero
+** if the delete happened immediately because of an OOM.
*/
-SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
- sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr);
+SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
+ return 0==sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr);
}
/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
@@ -112074,30 +113139,46 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla
SrcItem *pNewItem = &pNew->a[i];
const SrcItem *pOldItem = &p->a[i];
Table *pTab;
- pNewItem->pSchema = pOldItem->pSchema;
- pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
+ pNewItem->fg = pOldItem->fg;
+ if( pOldItem->fg.isSubquery ){
+ Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery));
+ if( pNewSubq==0 ){
+ assert( db->mallocFailed );
+ pNewItem->fg.isSubquery = 0;
+ }else{
+ memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq));
+ pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags);
+ if( pNewSubq->pSelect==0 ){
+ sqlite3DbFree(db, pNewSubq);
+ pNewSubq = 0;
+ pNewItem->fg.isSubquery = 0;
+ }
+ }
+ pNewItem->u4.pSubq = pNewSubq;
+ }else if( pOldItem->fg.fixedSchema ){
+ pNewItem->u4.pSchema = pOldItem->u4.pSchema;
+ }else{
+ pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase);
+ }
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
- pNewItem->fg = pOldItem->fg;
pNewItem->iCursor = pOldItem->iCursor;
- pNewItem->addrFillSub = pOldItem->addrFillSub;
- pNewItem->regReturn = pOldItem->regReturn;
if( pNewItem->fg.isIndexedBy ){
pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
+ }else if( pNewItem->fg.isTabFunc ){
+ pNewItem->u1.pFuncArg =
+ sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
+ }else{
+ pNewItem->u1.nRow = pOldItem->u1.nRow;
}
pNewItem->u2 = pOldItem->u2;
if( pNewItem->fg.isCte ){
pNewItem->u2.pCteUse->nUse++;
}
- if( pNewItem->fg.isTabFunc ){
- pNewItem->u1.pFuncArg =
- sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags);
- }
- pTab = pNewItem->pTab = pOldItem->pTab;
+ pTab = pNewItem->pSTab = pOldItem->pSTab;
if( pTab ){
pTab->nTabRef++;
}
- pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
if( pOldItem->fg.isUsing ){
assert( pNewItem->fg.isUsing );
pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
@@ -112171,7 +113252,6 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla
pp = &pNew->pPrior;
pNext = pNew;
}
-
return pRet;
}
#else
@@ -112558,6 +113638,54 @@ SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
return pExpr;
}
+/*
+** pExpr is a TK_FUNCTION node. Try to determine whether or not the
+** function is a constant function. A function is constant if all of
+** the following are true:
+**
+** (1) It is a scalar function (not an aggregate or window function)
+** (2) It has either the SQLITE_FUNC_CONSTANT or SQLITE_FUNC_SLOCHNG
+** property.
+** (3) All of its arguments are constants
+**
+** This routine sets pWalker->eCode to 0 if pExpr is not a constant.
+** It makes no changes to pWalker->eCode if pExpr is constant. In
+** every case, it returns WRC_Abort.
+**
+** Called as a service subroutine from exprNodeIsConstant().
+*/
+static SQLITE_NOINLINE int exprNodeIsConstantFunction(
+ Walker *pWalker,
+ Expr *pExpr
+){
+ int n; /* Number of arguments */
+ ExprList *pList; /* List of arguments */
+ FuncDef *pDef; /* The function */
+ sqlite3 *db; /* The database */
+
+ assert( pExpr->op==TK_FUNCTION );
+ if( ExprHasProperty(pExpr, EP_TokenOnly)
+ || (pList = pExpr->x.pList)==0
+ ){;
+ n = 0;
+ }else{
+ n = pList->nExpr;
+ sqlite3WalkExprList(pWalker, pList);
+ if( pWalker->eCode==0 ) return WRC_Abort;
+ }
+ db = pWalker->pParse->db;
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
+ if( pDef==0
+ || pDef->xFinalize!=0
+ || (pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
+ || ExprHasProperty(pExpr, EP_WinFunc)
+ ){
+ pWalker->eCode = 0;
+ return WRC_Abort;
+ }
+ return WRC_Prune;
+}
+
/*
** These routines are Walker callbacks used to check expressions to
@@ -112586,6 +113714,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
** malformed schema error.
*/
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
+ assert( pWalker->eCode>0 );
/* If pWalker->eCode is 2 then any term of the expression that comes from
** the ON or USING clauses of an outer join disqualifies the expression
@@ -112605,6 +113734,8 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
){
if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL);
return WRC_Continue;
+ }else if( pWalker->pParse ){
+ return exprNodeIsConstantFunction(pWalker, pExpr);
}else{
pWalker->eCode = 0;
return WRC_Abort;
@@ -112633,9 +113764,11 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
case TK_IF_NULL_ROW:
case TK_REGISTER:
case TK_DOT:
+ case TK_RAISE:
testcase( pExpr->op==TK_REGISTER );
testcase( pExpr->op==TK_IF_NULL_ROW );
testcase( pExpr->op==TK_DOT );
+ testcase( pExpr->op==TK_RAISE );
pWalker->eCode = 0;
return WRC_Abort;
case TK_VARIABLE:
@@ -112657,15 +113790,15 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
return WRC_Continue;
}
}
-static int exprIsConst(Expr *p, int initFlag, int iCur){
+static int exprIsConst(Parse *pParse, Expr *p, int initFlag){
Walker w;
w.eCode = initFlag;
+ w.pParse = pParse;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
- w.u.iCur = iCur;
sqlite3WalkExpr(&w, p);
return w.eCode;
}
@@ -112677,9 +113810,15 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
+**
+** The pParse parameter may be NULL. But if it is NULL, there is no way
+** to determine if function calls are constant or not, and hence all
+** function calls will be considered to be non-constant. If pParse is
+** not NULL, then a function call might be constant, depending on the
+** function and on its parameters.
*/
-SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
- return exprIsConst(p, 1, 0);
+SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse *pParse, Expr *p){
+ return exprIsConst(pParse, p, 1);
}
/*
@@ -112695,8 +113834,24 @@ SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
** can be added to the pParse->pConstExpr list and evaluated once when
** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce().
*/
-SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
- return exprIsConst(p, 2, 0);
+static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){
+ return exprIsConst(pParse, p, 2);
+}
+
+/*
+** This routine examines sub-SELECT statements as an expression is being
+** walked as part of sqlite3ExprIsTableConstant(). Sub-SELECTs are considered
+** constant as long as they are uncorrelated - meaning that they do not
+** contain any terms from outer contexts.
+*/
+static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){
+ assert( pSelect!=0 );
+ assert( pWalker->eCode==3 || pWalker->eCode==0 );
+ if( (pSelect->selFlags & SF_Correlated)!=0 ){
+ pWalker->eCode = 0;
+ return WRC_Abort;
+ }
+ return WRC_Prune;
}
/*
@@ -112704,9 +113859,26 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
** for any single row of the table with cursor iCur. In other words, the
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
+**
+** Consider uncorrelated subqueries to be constants if the bAllowSubq
+** parameter is true.
*/
-SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
- return exprIsConst(p, 3, iCur);
+static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){
+ Walker w;
+ w.eCode = 3;
+ w.pParse = 0;
+ w.xExprCallback = exprNodeIsConstant;
+ if( bAllowSubq ){
+ w.xSelectCallback = exprSelectWalkTableConstant;
+ }else{
+ w.xSelectCallback = sqlite3SelectWalkFail;
+#ifdef SQLITE_DEBUG
+ w.xSelectCallback2 = sqlite3SelectWalkAssert2;
+#endif
+ }
+ w.u.iCur = iCur;
+ sqlite3WalkExpr(&w, p);
+ return w.eCode;
}
/*
@@ -112724,7 +113896,10 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
**
** (1) pExpr cannot refer to any table other than pSrc->iCursor.
**
-** (2) pExpr cannot use subqueries or non-deterministic functions.
+** (2a) pExpr cannot use subqueries unless the bAllowSubq parameter is
+** true and the subquery is non-correlated
+**
+** (2b) pExpr cannot use non-deterministic functions.
**
** (3) pSrc cannot be part of the left operand for a RIGHT JOIN.
** (Is there some way to relax this constraint?)
@@ -112753,7 +113928,8 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(
Expr *pExpr, /* The constraint */
const SrcList *pSrcList, /* Complete FROM clause */
- int iSrc /* Which element of pSrcList to use */
+ int iSrc, /* Which element of pSrcList to use */
+ int bAllowSubq /* Allow non-correlated subqueries */
){
const SrcItem *pSrc = &pSrcList->a[iSrc];
if( pSrc->fg.jointype & JT_LTORJ ){
@@ -112778,7 +113954,8 @@ SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(
}
}
}
- return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
+ /* Rules (1), (2a), and (2b) handled by the following: */
+ return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor, bAllowSubq);
}
@@ -112863,7 +114040,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprLi
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
assert( isInit==0 || isInit==1 );
- return exprIsConst(p, 4+isInit, 0);
+ return exprIsConst(0, p, 4+isInit);
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
@@ -112889,8 +114066,12 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue. If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
+**
+** If the pParse pointer is provided, then allow the expression p to be
+** a parameter (TK_VARIABLE) that is bound to an integer.
+** But if pParse is NULL, then p must be a pure integer literal.
*/
-SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){
+SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse){
int rc = 0;
if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */
@@ -112905,18 +114086,38 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){
}
switch( p->op ){
case TK_UPLUS: {
- rc = sqlite3ExprIsInteger(p->pLeft, pValue);
+ rc = sqlite3ExprIsInteger(p->pLeft, pValue, 0);
break;
}
case TK_UMINUS: {
int v = 0;
- if( sqlite3ExprIsInteger(p->pLeft, &v) ){
+ if( sqlite3ExprIsInteger(p->pLeft, &v, 0) ){
assert( ((unsigned int)v)!=0x80000000 );
*pValue = -v;
rc = 1;
}
break;
}
+ case TK_VARIABLE: {
+ sqlite3_value *pVal;
+ if( pParse==0 ) break;
+ if( NEVER(pParse->pVdbe==0) ) break;
+ if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) break;
+ sqlite3VdbeSetVarmask(pParse->pVdbe, p->iColumn);
+ pVal = sqlite3VdbeGetBoundValue(pParse->pReprepare, p->iColumn,
+ SQLITE_AFF_BLOB);
+ if( pVal ){
+ if( sqlite3_value_type(pVal)==SQLITE_INTEGER ){
+ sqlite3_int64 vv = sqlite3_value_int64(pVal);
+ if( vv == (vv & 0x7fffffff) ){ /* non-negative numbers only */
+ *pValue = (int)vv;
+ rc = 1;
+ }
+ }
+ sqlite3ValueFree(pVal);
+ }
+ break;
+ }
default: break;
}
return rc;
@@ -112953,9 +114154,12 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
return 0;
case TK_COLUMN:
assert( ExprUseYTab(p) );
- return ExprHasProperty(p, EP_CanBeNull) ||
- NEVER(p->y.pTab==0) || /* Reference to column of index on expr */
- (p->iColumn>=0
+ return ExprHasProperty(p, EP_CanBeNull)
+ || NEVER(p->y.pTab==0) /* Reference to column of index on expr */
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ || (p->iColumn==XN_ROWID && IsView(p->y.pTab))
+#endif
+ || (p->iColumn>=0
&& p->y.pTab->aCol!=0 /* Possible due to prior error */
&& ALWAYS(p->iColumny.pTab->nCol)
&& p->y.pTab->aCol[p->iColumn].notNull==0);
@@ -113067,8 +114271,8 @@ static Select *isCandidateForInOpt(const Expr *pX){
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 is not a subquery or view */
- pTab = pSrc->a[0].pTab;
+ if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */
+ pTab = pSrc->a[0].pSTab;
assert( pTab!=0 );
assert( !IsView(pTab) ); /* FROM clause is not a view */
if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
@@ -113108,13 +114312,13 @@ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){
** The argument is an IN operator with a list (not a subquery) on the
** right-hand side. Return TRUE if that list is constant.
*/
-static int sqlite3InRhsIsConstant(Expr *pIn){
+static int sqlite3InRhsIsConstant(Parse *pParse, Expr *pIn){
Expr *pLHS;
int res;
assert( !ExprHasProperty(pIn, EP_xIsSelect) );
pLHS = pIn->pLeft;
pIn->pLeft = 0;
- res = sqlite3ExprIsConstant(pIn);
+ res = sqlite3ExprIsConstant(pParse, pIn);
pIn->pLeft = pLHS;
return res;
}
@@ -113251,7 +114455,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
- pTab = p->pSrc->a[0].pTab;
+ pTab = p->pSrc->a[0].pSTab;
/* Code an OP_Transaction and OP_TableLock for . */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -113383,7 +114587,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
if( eType==0
&& (inFlags & IN_INDEX_NOOP_OK)
&& ExprUseXList(pX)
- && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
+ && (!sqlite3InRhsIsConstant(pParse,pX) || pX->x.pList->nExpr<=2)
){
pParse->nTab--; /* Back out the allocation of the unused cursor */
iTab = -1; /* Cursor is not allocated */
@@ -113491,6 +114695,49 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
}
}
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
+** Scan all previously generated bytecode looking for an OP_BeginSubrtn
+** that is compatible with pExpr. If found, add the y.sub values
+** to pExpr and return true. If not found, return false.
+*/
+static int findCompatibleInRhsSubrtn(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* IN operator with RHS that we want to reuse */
+ SubrtnSig *pNewSig /* Signature for the IN operator */
+){
+ VdbeOp *pOp, *pEnd;
+ SubrtnSig *pSig;
+ Vdbe *v;
+
+ if( pNewSig==0 ) return 0;
+ if( (pParse->mSubrtnSig & (1<<(pNewSig->selId&7)))==0 ) return 0;
+ assert( pExpr->op==TK_IN );
+ assert( !ExprUseYSub(pExpr) );
+ assert( ExprUseXSelect(pExpr) );
+ assert( pExpr->x.pSelect!=0 );
+ assert( (pExpr->x.pSelect->selFlags & SF_All)==0 );
+ v = pParse->pVdbe;
+ assert( v!=0 );
+ pOp = sqlite3VdbeGetOp(v, 1);
+ pEnd = sqlite3VdbeGetLastOp(v);
+ for(; pOpp4type!=P4_SUBRTNSIG ) continue;
+ assert( pOp->opcode==OP_BeginSubrtn );
+ pSig = pOp->p4.pSubrtnSig;
+ assert( pSig!=0 );
+ if( pNewSig->selId!=pSig->selId ) continue;
+ if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue;
+ pExpr->y.sub.iAddr = pSig->iAddr;
+ pExpr->y.sub.regReturn = pSig->regReturn;
+ pExpr->iTable = pSig->iTable;
+ ExprSetProperty(pExpr, EP_Subrtn);
+ return 1;
+ }
+ return 0;
+}
+#endif /* SQLITE_OMIT_SUBQUERY */
+
#ifndef SQLITE_OMIT_SUBQUERY
/*
** Generate code that will construct an ephemeral table containing all terms
@@ -113540,11 +114787,28 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
** and reuse it many names.
*/
if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){
- /* Reuse of the RHS is allowed */
- /* If this routine has already been coded, but the previous code
- ** might not have been invoked yet, so invoke it now as a subroutine.
+ /* Reuse of the RHS is allowed
+ **
+ ** Compute a signature for the RHS of the IN operator to facility
+ ** finding and reusing prior instances of the same IN operator.
+ */
+ SubrtnSig *pSig = 0;
+ assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 );
+ if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){
+ pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0]));
+ if( pSig ){
+ pSig->selId = pExpr->x.pSelect->selId;
+ pSig->zAff = exprINAffinity(pParse, pExpr);
+ }
+ }
+
+ /* Check to see if there is a prior materialization of the RHS of
+ ** this IN operator. If there is, then make use of that prior
+ ** materialization rather than recomputing it.
*/
- if( ExprHasProperty(pExpr, EP_Subrtn) ){
+ if( ExprHasProperty(pExpr, EP_Subrtn)
+ || findCompatibleInRhsSubrtn(pParse, pExpr, pSig)
+ ){
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
if( ExprUseXSelect(pExpr) ){
ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
@@ -113556,6 +114820,10 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
assert( iTab!=pExpr->iTable );
sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
sqlite3VdbeJumpHere(v, addrOnce);
+ if( pSig ){
+ sqlite3DbFree(pParse->db, pSig->zAff);
+ sqlite3DbFree(pParse->db, pSig);
+ }
return;
}
@@ -113566,7 +114834,13 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;
-
+ if( pSig ){
+ pSig->iAddr = pExpr->y.sub.iAddr;
+ pSig->regReturn = pExpr->y.sub.regReturn;
+ pSig->iTable = iTab;
+ pParse->mSubrtnSig = 1 << (pSig->selId&7);
+ sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG);
+ }
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
@@ -113607,15 +114881,30 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
SelectDest dest;
int i;
int rc;
+ int addrBloom = 0;
sqlite3SelectDestInit(&dest, SRT_Set, iTab);
dest.zAffSdst = exprINAffinity(pParse, pExpr);
pSelect->iLimit = 0;
+ if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){
+ int regBloom = ++pParse->nMem;
+ addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom);
+ VdbeComment((v, "Bloom filter"));
+ dest.iSDParm2 = regBloom;
+ }
testcase( pSelect->selFlags & SF_Distinct );
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
pCopy = sqlite3SelectDup(pParse->db, pSelect, 0);
rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest);
sqlite3SelectDelete(pParse->db, pCopy);
sqlite3DbFree(pParse->db, dest.zAffSdst);
+ if( addrBloom ){
+ sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2;
+ if( dest.iSDParm2==0 ){
+ sqlite3VdbeChangeToNoop(v, addrBloom);
+ }else{
+ sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2;
+ }
+ }
if( rc ){
sqlite3KeyInfoUnref(pKeyInfo);
return;
@@ -113666,7 +114955,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
** this code only executes once. Because for a non-constant
** expression we need to rerun this code each time.
*/
- if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
+ if( addrOnce && !sqlite3ExprIsConstant(pParse, pE2) ){
sqlite3VdbeChangeToNoop(v, addrOnce-1);
sqlite3VdbeChangeToNoop(v, addrOnce);
ExprClearProperty(pExpr, EP_Subrtn);
@@ -113913,9 +115202,7 @@ static void sqlite3ExprCodeIN(
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
zAff = exprINAffinity(pParse, pExpr);
nVector = sqlite3ExprVectorSize(pExpr->pLeft);
- aiMap = (int*)sqlite3DbMallocZero(
- pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
- );
+ aiMap = (int*)sqlite3DbMallocZero(pParse->db, nVector*sizeof(int));
if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
/* Attempt to compute the RHS. After this step, if anything other than
@@ -114058,6 +115345,15 @@ static void sqlite3ExprCodeIN(
sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
if( destIfFalse==destIfNull ){
/* Combine Step 3 and Step 5 into a single opcode */
+ if( ExprHasProperty(pExpr, EP_Subrtn) ){
+ const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr);
+ assert( pOp->opcode==OP_Once || pParse->nErr );
+ if( pOp->opcode==OP_Once && pOp->p3>0 ){
+ assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) );
+ sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse,
+ rLhs, nVector); VdbeCoverage(v);
+ }
+ }
sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse,
rLhs, nVector); VdbeCoverage(v);
goto sqlite3ExprCodeIN_finished;
@@ -114340,13 +115636,17 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n
** register iReg. The caller must ensure that iReg already contains
** the correct value for the expression.
*/
-static void exprToRegister(Expr *pExpr, int iReg){
+SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg){
Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
if( NEVER(p==0) ) return;
- p->op2 = p->op;
- p->op = TK_REGISTER;
- p->iTable = iReg;
- ExprClearProperty(p, EP_Skip);
+ if( p->op==TK_REGISTER ){
+ assert( p->iTable==iReg );
+ }else{
+ p->op2 = p->op;
+ p->op = TK_REGISTER;
+ p->iTable = iReg;
+ ExprClearProperty(p, EP_Skip);
+ }
}
/*
@@ -114516,6 +115816,59 @@ static int exprCodeInlineFunction(
return target;
}
+/*
+** Expression Node callback for sqlite3ExprCanReturnSubtype().
+**
+** Only a function call is able to return a subtype. So if the node
+** is not a function call, return WRC_Prune immediately.
+**
+** A function call is able to return a subtype if it has the
+** SQLITE_RESULT_SUBTYPE property.
+**
+** Assume that every function is able to pass-through a subtype from
+** one of its argument (using sqlite3_result_value()). Most functions
+** are not this way, but we don't have a mechanism to distinguish those
+** that are from those that are not, so assume they all work this way.
+** That means that if one of its arguments is another function and that
+** other function is able to return a subtype, then this function is
+** able to return a subtype.
+*/
+static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){
+ int n;
+ FuncDef *pDef;
+ sqlite3 *db;
+ if( pExpr->op!=TK_FUNCTION ){
+ return WRC_Prune;
+ }
+ assert( ExprUseXList(pExpr) );
+ db = pWalker->pParse->db;
+ n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0;
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
+ if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){
+ pWalker->eCode = 1;
+ return WRC_Prune;
+ }
+ return WRC_Continue;
+}
+
+/*
+** Return TRUE if expression pExpr is able to return a subtype.
+**
+** A TRUE return does not guarantee that a subtype will be returned.
+** It only indicates that a subtype return is possible. False positives
+** are acceptable as they only disable an optimization. False negatives,
+** on the other hand, can lead to incorrect answers.
+*/
+static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.pParse = pParse;
+ w.xExprCallback = exprNodeCanReturnSubtype;
+ sqlite3WalkExpr(&w, pExpr);
+ return w.eCode;
+}
+
+
/*
** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr.
** If it is, then resolve the expression by reading from the index and
@@ -114548,6 +115901,17 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
continue;
}
+
+ /* Functions that might set a subtype should not be replaced by the
+ ** value taken from an expression index if they are themselves an
+ ** argument to another scalar function or aggregate.
+ ** https://sqlite.org/forum/forumpost/68d284c86b082c3e */
+ if( ExprHasProperty(pExpr, EP_SubtArg)
+ && sqlite3ExprCanReturnSubtype(pParse, pExpr)
+ ){
+ continue;
+ }
+
v = pParse->pVdbe;
assert( v!=0 );
if( p->bMaybeNullRow ){
@@ -114830,12 +116194,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( pExpr->u.zToken!=0 );
assert( pExpr->u.zToken[0]!=0 );
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
- if( pExpr->u.zToken[1]!=0 ){
- const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
- assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) );
- pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
- sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
- }
return target;
}
case TK_REGISTER: {
@@ -115009,7 +116367,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
#endif
- if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
+ if( ConstFactorOk(pParse)
+ && sqlite3ExprIsConstantNotJoin(pParse,pExpr)
+ ){
/* SQL functions can be expensive. So try to avoid running them
** multiple times if we know they always give the same result */
return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
@@ -115040,7 +116400,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
for(i=0; ia[i].pExpr) ){
+ if( i<32 && sqlite3ExprIsConstant(pParse, pFarg->a[i].pExpr) ){
testcase( i==31 );
constMask |= MASKBIT32(i);
}
@@ -115182,8 +116542,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( !ExprHasProperty(pExpr, EP_Collate) ){
/* A TK_COLLATE Expr node without the EP_Collate tag is a so-called
** "SOFT-COLLATE" that is added to constraints that are pushed down
- ** from outer queries into sub-queries by the push-down optimization.
- ** Clear subtypes as subtypes may not cross a subquery boundary.
+ ** from outer queries into sub-queries by the WHERE-clause push-down
+ ** optimization. Clear subtypes as subtypes may not cross a subquery
+ ** boundary.
*/
assert( pExpr->pLeft );
sqlite3ExprCode(pParse, pExpr->pLeft, target);
@@ -115352,7 +116713,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
break;
}
testcase( pX->op==TK_COLUMN );
- exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
+ sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
testcase( regFree1==0 );
memset(&opCompare, 0, sizeof(opCompare));
opCompare.op = TK_EQ;
@@ -115406,15 +116767,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
assert( !ExprHasProperty(pExpr, EP_IntValue) );
if( pExpr->affExpr==OE_Ignore ){
- sqlite3VdbeAddOp4(
- v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
+ sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore);
VdbeCoverage(v);
}else{
- sqlite3HaltConstraint(pParse,
+ r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
+ sqlite3VdbeAddOp3(v, OP_Halt,
pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
- pExpr->affExpr, pExpr->u.zToken, 0, 0);
+ pExpr->affExpr, r1);
}
-
break;
}
#endif
@@ -115507,7 +116867,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
if( ConstFactorOk(pParse)
&& ALWAYS(pExpr!=0)
&& pExpr->op!=TK_REGISTER
- && sqlite3ExprIsConstantNotJoin(pExpr)
+ && sqlite3ExprIsConstantNotJoin(pParse, pExpr)
){
*pReg = 0;
r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
@@ -115571,7 +116931,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
** might choose to code the expression at initialization time.
*/
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
- if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
+ if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){
sqlite3ExprCodeRunJustOnce(pParse, pExpr, target);
}else{
sqlite3ExprCodeCopy(pParse, pExpr, target);
@@ -115630,7 +116990,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
}
}else if( (flags & SQLITE_ECEL_FACTOR)!=0
- && sqlite3ExprIsConstantNotJoin(pExpr)
+ && sqlite3ExprIsConstantNotJoin(pParse,pExpr)
){
sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i);
}else{
@@ -115703,7 +117063,7 @@ static void exprCodeBetween(
compRight.op = TK_LE;
compRight.pLeft = pDel;
compRight.pRight = pExpr->x.pList->a[1].pExpr;
- exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
+ sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
if( xJump ){
xJump(pParse, &exprAnd, dest, jumpIfNull);
}else{
@@ -116781,9 +118141,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
&& pAggInfo->aCol[iAgg].pCExpr==pExpr
){
pExpr = sqlite3ExprDup(db, pExpr, 0);
- if( pExpr ){
+ if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){
pAggInfo->aCol[iAgg].pCExpr = pExpr;
- sqlite3ExprDeferredDelete(pParse, pExpr);
}
}
}else{
@@ -116792,9 +118151,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
&& pAggInfo->aFunc[iAgg].pFExpr==pExpr
){
pExpr = sqlite3ExprDup(db, pExpr, 0);
- if( pExpr ){
+ if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){
pAggInfo->aFunc[iAgg].pFExpr = pExpr;
- sqlite3ExprDeferredDelete(pParse, pExpr);
}
}
}
@@ -118647,7 +120005,7 @@ static int renameResolveTrigger(Parse *pParse){
/* ALWAYS() because if the table of the trigger does not exist, the
** error would have been hit before this point */
if( ALWAYS(pParse->pTriggerTab) ){
- rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
+ rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0;
}
/* Resolve symbols in WHEN clause */
@@ -118693,8 +120051,9 @@ static int renameResolveTrigger(Parse *pParse){
int i;
for(i=0; ipFrom->nSrc && rc==SQLITE_OK; i++){
SrcItem *p = &pStep->pFrom->a[i];
- if( p->pSelect ){
- sqlite3SelectPrep(pParse, p->pSelect, 0);
+ if( p->fg.isSubquery ){
+ assert( p->u4.pSubq!=0 );
+ sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0);
}
}
}
@@ -118762,8 +120121,12 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){
}
if( pStep->pFrom ){
int i;
- for(i=0; ipFrom->nSrc; i++){
- sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect);
+ SrcList *pFrom = pStep->pFrom;
+ for(i=0; inSrc; i++){
+ if( pFrom->a[i].fg.isSubquery ){
+ assert( pFrom->a[i].u4.pSubq!=0 );
+ sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect);
+ }
}
}
}
@@ -119186,7 +120549,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
}
for(i=0; inSrc; i++){
SrcItem *pItem = &pSrc->a[i];
- if( pItem->pTab==p->pTab ){
+ if( pItem->pSTab==p->pTab ){
renameTokenFind(pWalker->pParse, p, pItem->zName);
}
}
@@ -119765,7 +121128,12 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T
if( i==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regOut);
}else{
+ char aff = pTab->aCol[i].affinity;
+ if( aff==SQLITE_AFF_REAL ){
+ pTab->aCol[i].affinity = SQLITE_AFF_NUMERIC;
+ }
sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut);
+ pTab->aCol[i].affinity = aff;
}
nField++;
}
@@ -120686,7 +122054,7 @@ static void statGet(
if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1;
sqlite3_str_appendf(&sStat, " %llu", iVal);
#ifdef SQLITE_ENABLE_STAT4
- assert( p->current.anEq[i] );
+ assert( p->current.anEq[i] || p->nRow==0 );
#endif
}
sqlite3ResultStrAccum(context, &sStat);
@@ -120871,7 +122239,7 @@ static void analyzeOneTable(
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int nCol; /* Number of columns in pIdx. "N" */
- int addrRewind; /* Address of "OP_Rewind iIdxCur" */
+ int addrGotoEnd; /* Address of "OP_Rewind iIdxCur" */
int addrNextRow; /* Address of "next_row:" */
const char *zIdxName; /* Name of the index */
int nColTest; /* Number of columns to test for changes */
@@ -120895,9 +122263,14 @@ static void analyzeOneTable(
/*
** Pseudo-code for loop that calls stat_push():
**
- ** Rewind csr
- ** if eof(csr) goto end_of_scan;
** regChng = 0
+ ** Rewind csr
+ ** if eof(csr){
+ ** stat_init() with count = 0;
+ ** goto end_of_scan;
+ ** }
+ ** count()
+ ** stat_init()
** goto chng_addr_0;
**
** next_row:
@@ -120936,41 +122309,36 @@ static void analyzeOneTable(
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
- /* Invoke the stat_init() function. The arguments are:
+ /* Implementation of the following:
**
+ ** regChng = 0
+ ** Rewind csr
+ ** if eof(csr){
+ ** stat_init() with count = 0;
+ ** goto end_of_scan;
+ ** }
+ ** count()
+ ** stat_init()
+ ** goto chng_addr_0;
+ */
+ assert( regTemp2==regStat+4 );
+ sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
+
+ /* Arguments to stat_init():
** (1) the number of columns in the index including the rowid
** (or for a WITHOUT ROWID table, the number of PK columns),
** (2) the number of columns in the key without the rowid/pk
- ** (3) estimated number of rows in the index,
- */
+ ** (3) estimated number of rows in the index. */
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
assert( regRowid==regStat+2 );
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
-#ifdef SQLITE_ENABLE_STAT4
- if( OptimizationEnabled(db, SQLITE_Stat4) ){
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
- addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
- VdbeCoverage(v);
- }else
-#endif
- {
- addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
- }
- assert( regTemp2==regStat+4 );
- sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
+ sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp,
+ OptimizationDisabled(db, SQLITE_Stat4));
sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
&statInitFuncdef, 0);
+ addrGotoEnd = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ VdbeCoverage(v);
- /* Implementation of the following:
- **
- ** Rewind csr
- ** if eof(csr) goto end_of_scan;
- ** regChng = 0
- ** goto next_push_0;
- **
- */
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
addrNextRow = sqlite3VdbeCurrentAddr(v);
@@ -121077,6 +122445,12 @@ static void analyzeOneTable(
}
/* Add the entry to the stat1 table. */
+ if( pIdx->pPartIdxWhere ){
+ /* Partial indexes might get a zero-entry in sqlite_stat1. But
+ ** an empty table is omitted from sqlite_stat1. */
+ sqlite3VdbeJumpHere(v, addrGotoEnd);
+ addrGotoEnd = 0;
+ }
callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
assert( "BBB"[0]==SQLITE_AFF_TEXT );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
@@ -121100,6 +122474,13 @@ static void analyzeOneTable(
int addrIsNull;
u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+ /* No STAT4 data is generated if the number of rows is zero */
+ if( addrGotoEnd==0 ){
+ sqlite3VdbeAddOp2(v, OP_Cast, regStat1, SQLITE_AFF_INTEGER);
+ addrGotoEnd = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
+ VdbeCoverage(v);
+ }
+
if( doOnce ){
int mxCol = nCol;
Index *pX;
@@ -121152,7 +122533,7 @@ static void analyzeOneTable(
#endif /* SQLITE_ENABLE_STAT4 */
/* End of analysis */
- sqlite3VdbeJumpHere(v, addrRewind);
+ if( addrGotoEnd ) sqlite3VdbeJumpHere(v, addrGotoEnd);
}
@@ -121598,12 +122979,13 @@ static int loadStatTbl(
while( sqlite3_step(pStmt)==SQLITE_ROW ){
int nIdxCol = 1; /* Number of columns in stat4 records */
- char *zIndex; /* Index name */
- Index *pIdx; /* Pointer to the index object */
- int nSample; /* Number of samples */
- int nByte; /* Bytes of space required */
- int i; /* Bytes of space required */
- tRowcnt *pSpace;
+ char *zIndex; /* Index name */
+ Index *pIdx; /* Pointer to the index object */
+ int nSample; /* Number of samples */
+ i64 nByte; /* Bytes of space required */
+ i64 i; /* Bytes of space required */
+ tRowcnt *pSpace; /* Available allocated memory space */
+ u8 *pPtr; /* Available memory as a u8 for easier manipulation */
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
@@ -121623,7 +123005,7 @@ static int loadStatTbl(
}
pIdx->nSampleCol = nIdxCol;
pIdx->mxSample = nSample;
- nByte = sizeof(IndexSample) * nSample;
+ nByte = ROUND8(sizeof(IndexSample) * nSample);
nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
@@ -121632,7 +123014,10 @@ static int loadStatTbl(
sqlite3_finalize(pStmt);
return SQLITE_NOMEM_BKPT;
}
- pSpace = (tRowcnt*)&pIdx->aSample[nSample];
+ pPtr = (u8*)pIdx->aSample;
+ pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0]));
+ pSpace = (tRowcnt*)pPtr;
+ assert( EIGHT_BYTE_ALIGNMENT( pSpace ) );
pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
pIdx->pTable->tabFlags |= TF_HasStat4;
for(i=0; ia; inSrc; i++, pItem++){
- if( pFix->bTemp==0 ){
- if( pItem->zDatabase ){
- if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
+ if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){
+ if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){
+ if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
- pFix->zType, pFix->pName, pItem->zDatabase);
+ pFix->zType, pFix->pName, pItem->u4.zDatabase);
return WRC_Abort;
}
- sqlite3DbFree(db, pItem->zDatabase);
- pItem->zDatabase = 0;
+ sqlite3DbFree(db, pItem->u4.zDatabase);
pItem->fg.notCte = 1;
+ pItem->fg.hadSchema = 1;
}
- pItem->pSchema = pFix->pSchema;
+ pItem->u4.pSchema = pFix->pSchema;
pItem->fg.fromDDL = 1;
+ pItem->fg.fixedSchema = 1;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
if( pList->a[i].fg.isUsing==0
@@ -122641,7 +124027,7 @@ SQLITE_PRIVATE void sqlite3AuthRead(
assert( pTabList );
for(iSrc=0; iSrcnSrc; iSrc++){
if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
- pTab = pTabList->a[iSrc].pTab;
+ pTab = pTabList->a[iSrc].pSTab;
break;
}
}
@@ -122939,7 +124325,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
}
sqlite3VdbeAddOp0(v, OP_Halt);
-#if SQLITE_USER_AUTHENTICATION
+#if SQLITE_USER_AUTHENTICATION && !defined(SQLITE_OMIT_SHARED_CACHE)
if( pParse->nTableLock>0 && db->init.busy==0 ){
sqlite3UserAuthInit(db);
if( db->auth.authLevelpSchema==0 || p->zDatabase==0 );
- if( p->pSchema ){
- int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
+ if( p->fg.fixedSchema ){
+ int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema);
zDb = pParse->db->aDb[iDb].zDbSName;
}else{
- zDb = p->zDatabase;
+ assert( !p->fg.isSubquery );
+ zDb = p->u4.zDatabase;
}
return sqlite3LocateTable(pParse, flags, p->zName, zDb);
}
@@ -125587,20 +126973,20 @@ SQLITE_PRIVATE void sqlite3EndTable(
int regRowid; /* Rowid of the next row to insert */
int addrInsLoop; /* Top of the loop for inserting rows */
Table *pSelTab; /* A table that describes the SELECT results */
+ int iCsr; /* Write cursor on the new table */
if( IN_SPECIAL_PARSE ){
pParse->rc = SQLITE_ERROR;
pParse->nErr++;
return;
}
+ iCsr = pParse->nTab++;
regYield = ++pParse->nMem;
regRec = ++pParse->nMem;
regRowid = ++pParse->nMem;
- assert(pParse->nTab==1);
sqlite3MayAbort(pParse);
- sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
+ sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->regRoot, iDb);
sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
- pParse->nTab = 2;
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
if( pParse->nErr ) return;
@@ -125621,11 +127007,11 @@ SQLITE_PRIVATE void sqlite3EndTable(
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
sqlite3TableAffinity(v, p, 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iCsr, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iCsr, regRec, regRowid);
sqlite3VdbeGoto(v, addrInsLoop);
sqlite3VdbeJumpHere(v, addrInsLoop);
- sqlite3VdbeAddOp1(v, OP_Close, 1);
+ sqlite3VdbeAddOp1(v, OP_Close, iCsr);
}
/* Compute the complete text of the CREATE statement */
@@ -125682,13 +127068,10 @@ SQLITE_PRIVATE void sqlite3EndTable(
/* Test for cycles in generated columns and illegal expressions
** in CHECK constraints and in DEFAULT clauses. */
if( p->tabFlags & TF_HasGenerated ){
- sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0,
+ sqlite3VdbeAddOp4(v, OP_SqlExec, 0x0001, 0, 0,
sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"",
db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC);
}
- sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0,
- sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)",
- db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC);
}
/* Add the table to the in-memory representation of the database.
@@ -125765,9 +127148,12 @@ SQLITE_PRIVATE void sqlite3CreateView(
** on a view, even though views do not have rowids. The following flag
** setting fixes this problem. But the fix can be disabled by compiling
** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that
- ** depend upon the old buggy behavior. */
-#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
- p->tabFlags |= TF_NoVisibleRowid;
+ ** depend upon the old buggy behavior. The ability can also be toggled
+ ** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */
+#else
+ p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */
#endif
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
@@ -125823,8 +127209,9 @@ SQLITE_PRIVATE void sqlite3CreateView(
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
/*
** The Table structure pTable is really a VIEW. Fill in the names of
-** the columns of the view in the pTable structure. Return the number
-** of errors. If an error is seen leave an error message in pParse->zErrMsg.
+** the columns of the view in the pTable structure. Return non-zero if
+** there are errors. If an error is seen an error message is left
+** in pParse->zErrMsg.
*/
static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
Table *pSelTab; /* A fake table from which we get the result set */
@@ -125947,7 +127334,7 @@ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
sqlite3DeleteColumnNames(db, pTable);
}
#endif /* SQLITE_OMIT_VIEW */
- return nErr;
+ return nErr + pParse->nErr;
}
SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
assert( pTable!=0 );
@@ -126269,6 +127656,8 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
}
assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
+ assert( pName->a[0].fg.fixedSchema==0 );
+ assert( pName->a[0].fg.isSubquery==0 );
if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
if( noErr ) db->suppressErr++;
assert( isView==0 || isView==LOCATE_VIEW );
@@ -126277,7 +127666,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
if( pTab==0 ){
if( noErr ){
- sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
+ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase);
sqlite3ForceNotReadOnly(pParse);
}
goto exit_drop_table;
@@ -127407,15 +128796,17 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists
}
assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */
assert( pName->nSrc==1 );
+ assert( pName->a[0].fg.fixedSchema==0 );
+ assert( pName->a[0].fg.isSubquery==0 );
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_drop_index;
}
- pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
+ pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase);
if( pIndex==0 ){
if( !ifExists ){
sqlite3ErrorMsg(pParse, "no such index: %S", pName->a);
}else{
- sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
+ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase);
sqlite3ForceNotReadOnly(pParse);
}
pParse->checkSchema = 1;
@@ -127728,12 +129119,14 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
if( pDatabase && pDatabase->z==0 ){
pDatabase = 0;
}
+ assert( pItem->fg.fixedSchema==0 );
+ assert( pItem->fg.isSubquery==0 );
if( pDatabase ){
pItem->zName = sqlite3NameFromToken(db, pDatabase);
- pItem->zDatabase = sqlite3NameFromToken(db, pTable);
+ pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable);
}else{
pItem->zName = sqlite3NameFromToken(db, pTable);
- pItem->zDatabase = 0;
+ pItem->u4.zDatabase = 0;
}
return pList;
}
@@ -127749,13 +129142,40 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
for(i=0, pItem=pList->a; inSrc; i++, pItem++){
if( pItem->iCursor>=0 ) continue;
pItem->iCursor = pParse->nTab++;
- if( pItem->pSelect ){
- sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
+ if( pItem->fg.isSubquery ){
+ assert( pItem->u4.pSubq!=0 );
+ assert( pItem->u4.pSubq->pSelect!=0 );
+ assert( pItem->u4.pSubq->pSelect->pSrc!=0 );
+ sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc);
}
}
}
}
+/*
+** Delete a Subquery object and its substructure.
+*/
+SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){
+ assert( pSubq!=0 && pSubq->pSelect!=0 );
+ sqlite3SelectDelete(db, pSubq->pSelect);
+ sqlite3DbFree(db, pSubq);
+}
+
+/*
+** Remove a Subquery from a SrcItem. Return the associated Select object.
+** The returned Select becomes the responsibility of the caller.
+*/
+SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){
+ Select *pSel;
+ assert( pItem!=0 );
+ assert( pItem->fg.isSubquery );
+ pSel = pItem->u4.pSubq->pSelect;
+ sqlite3DbFree(db, pItem->u4.pSubq);
+ pItem->u4.pSubq = 0;
+ pItem->fg.isSubquery = 0;
+ return pSel;
+}
+
/*
** Delete an entire SrcList including all its substructure.
*/
@@ -127765,13 +129185,24 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
assert( db!=0 );
if( pList==0 ) return;
for(pItem=pList->a, i=0; inSrc; i++, pItem++){
- if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase);
+
+ /* Check invariants on SrcItem */
+ assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc );
+ assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy );
+ assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery );
+ assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 &&
+ pItem->u4.pSubq->pSelect!=0) );
+
if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName);
if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias);
+ if( pItem->fg.isSubquery ){
+ sqlite3SubqueryDelete(db, pItem->u4.pSubq);
+ }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){
+ sqlite3DbNNFreeNN(db, pItem->u4.zDatabase);
+ }
if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy);
if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
- sqlite3DeleteTable(db, pItem->pTab);
- if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
+ sqlite3DeleteTable(db, pItem->pSTab);
if( pItem->fg.isUsing ){
sqlite3IdListDelete(db, pItem->u3.pUsing);
}else if( pItem->u3.pOn ){
@@ -127781,6 +129212,54 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
sqlite3DbNNFreeNN(db, pList);
}
+/*
+** Attach a Subquery object to pItem->uv.pSubq. Set the
+** pSelect value but leave all the other values initialized
+** to zero.
+**
+** A copy of the Select object is made if dupSelect is true, and the
+** SrcItem takes responsibility for deleting the copy. If dupSelect is
+** false, ownership of the Select passes to the SrcItem. Either way,
+** the SrcItem will take responsibility for deleting the Select.
+**
+** When dupSelect is zero, that means the Select might get deleted right
+** away if there is an OOM error. Beware.
+**
+** Return non-zero on success. Return zero on an OOM error.
+*/
+SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(
+ Parse *pParse, /* Parsing context */
+ SrcItem *pItem, /* Item to which the subquery is to be attached */
+ Select *pSelect, /* The subquery SELECT. Must be non-NULL */
+ int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/
+){
+ Subquery *p;
+ assert( pSelect!=0 );
+ assert( pItem->fg.isSubquery==0 );
+ if( pItem->fg.fixedSchema ){
+ pItem->u4.pSchema = 0;
+ pItem->fg.fixedSchema = 0;
+ }else if( pItem->u4.zDatabase!=0 ){
+ sqlite3DbFree(pParse->db, pItem->u4.zDatabase);
+ pItem->u4.zDatabase = 0;
+ }
+ if( dupSelect ){
+ pSelect = sqlite3SelectDup(pParse->db, pSelect, 0);
+ if( pSelect==0 ) return 0;
+ }
+ p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery));
+ if( p==0 ){
+ sqlite3SelectDelete(pParse->db, pSelect);
+ return 0;
+ }
+ pItem->fg.isSubquery = 1;
+ p->pSelect = pSelect;
+ assert( offsetof(Subquery, pSelect)==0 );
+ memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect));
+ return 1;
+}
+
+
/*
** This routine is called by the parser to add a new term to the
** end of a growing FROM clause. The "p" parameter is the part of
@@ -127830,10 +129309,12 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
if( pAlias->n ){
pItem->zAlias = sqlite3NameFromToken(db, pAlias);
}
+ assert( pSubquery==0 || pDatabase==0 );
if( pSubquery ){
- pItem->pSelect = pSubquery;
- if( pSubquery->selFlags & SF_NestedFrom ){
- pItem->fg.isNestedFrom = 1;
+ if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){
+ if( pSubquery->selFlags & SF_NestedFrom ){
+ pItem->fg.isNestedFrom = 1;
+ }
}
}
assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 );
@@ -129265,8 +130746,8 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
**
** The following fields are initialized appropriate in pSrc:
**
-** pSrc->a[0].pTab Pointer to the Table object
-** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one
+** pSrc->a[0].spTab Pointer to the Table object
+** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one
**
*/
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
@@ -129274,8 +130755,8 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
Table *pTab;
assert( pItem && pSrc->nSrc>=1 );
pTab = sqlite3LocateTableItem(pParse, 0, pItem);
- if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab);
- pItem->pTab = pTab;
+ if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab);
+ pItem->pSTab = pTab;
pItem->fg.notCte = 1;
if( pTab ){
pTab->nTabRef++;
@@ -129316,6 +130797,7 @@ SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *
** is for a top-level SQL statement.
*/
static int vtabIsReadOnly(Parse *pParse, Table *pTab){
+ assert( IsVirtual(pTab) );
if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){
return 1;
}
@@ -129397,7 +130879,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
- pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
+ assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 );
+ pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
assert( pFrom->a[0].fg.isUsing==0 );
assert( pFrom->a[0].u3.pOn==0 );
}
@@ -129459,7 +130942,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
** );
*/
- pTab = pSrc->a[0].pTab;
+ pTab = pSrc->a[0].pSTab;
if( HasRowid(pTab) ){
pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
pEList = sqlite3ExprListAppend(
@@ -129492,9 +130975,9 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */
- pSrc->a[0].pTab = 0;
+ pSrc->a[0].pSTab = 0;
pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
- pSrc->a[0].pTab = pTab;
+ pSrc->a[0].pSTab = pTab;
if( pSrc->a[0].fg.isIndexedBy ){
assert( pSrc->a[0].fg.isCte==0 );
pSrc->a[0].u2.pIBIndex = 0;
@@ -131377,13 +132860,13 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){
double r1, r2;
const char *zVal;
r1 = sqlite3_value_double(pValue);
- sqlite3_str_appendf(pStr, "%!.15g", r1);
+ sqlite3_str_appendf(pStr, "%!0.15g", r1);
zVal = sqlite3_str_value(pStr);
if( zVal ){
sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8);
if( r1!=r2 ){
sqlite3_str_reset(pStr);
- sqlite3_str_appendf(pStr, "%!.20e", r1);
+ sqlite3_str_appendf(pStr, "%!0.20e", r1);
}
}
break;
@@ -131685,7 +133168,7 @@ static void replaceFunc(
}
if( zPattern[0]==0 ){
assert( sqlite3_value_type(argv[1])!=SQLITE_NULL );
- sqlite3_result_value(context, argv[0]);
+ sqlite3_result_text(context, (const char*)zStr, nStr, SQLITE_TRANSIENT);
return;
}
nPattern = sqlite3_value_bytes(argv[1]);
@@ -132168,7 +133651,7 @@ static void sumFinalize(sqlite3_context *context){
if( p->approx ){
if( p->ovrfl ){
sqlite3_result_error(context,"integer overflow",-1);
- }else if( !sqlite3IsNaN(p->rErr) ){
+ }else if( !sqlite3IsOverflow(p->rErr) ){
sqlite3_result_double(context, p->rSum+p->rErr);
}else{
sqlite3_result_double(context, p->rSum);
@@ -132185,7 +133668,7 @@ static void avgFinalize(sqlite3_context *context){
double r;
if( p->approx ){
r = p->rSum;
- if( !sqlite3IsNaN(p->rErr) ) r += p->rErr;
+ if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr;
}else{
r = (double)(p->iSum);
}
@@ -132199,7 +133682,7 @@ static void totalFinalize(sqlite3_context *context){
if( p ){
if( p->approx ){
r = p->rSum;
- if( !sqlite3IsNaN(p->rErr) ) r += p->rErr;
+ if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr;
}else{
r = (double)(p->iSum);
}
@@ -132325,7 +133808,11 @@ static void minMaxFinalize(sqlite3_context *context){
** group_concat(EXPR, ?SEPARATOR?)
** string_agg(EXPR, SEPARATOR)
**
-** The SEPARATOR goes before the EXPR string. This is tragic. The
+** Content is accumulated in GroupConcatCtx.str with the SEPARATOR
+** coming before the EXPR value, except for the first entry which
+** omits the SEPARATOR.
+**
+** It is tragic that the SEPARATOR goes before the EXPR string. The
** groupConcatInverse() implementation would have been easier if the
** SEPARATOR were appended after EXPR. And the order is undocumented,
** so we could change it, in theory. But the old behavior has been
@@ -132429,7 +133916,7 @@ static void groupConcatInverse(
/* pGCC is always non-NULL since groupConcatStep() will have always
** run first to initialize it */
if( ALWAYS(pGCC) ){
- int nVS;
+ int nVS; /* Number of characters to remove */
/* Must call sqlite3_value_text() to convert the argument into text prior
** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
(void)sqlite3_value_text(argv[0]);
@@ -132482,6 +133969,8 @@ static void groupConcatValue(sqlite3_context *context){
sqlite3_result_error_toobig(context);
}else if( pAccum->accError==SQLITE_NOMEM ){
sqlite3_result_error_nomem(context);
+ }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){
+ sqlite3_result_text(context, "", 1, SQLITE_STATIC);
}else{
const char *zText = sqlite3_str_value(pAccum);
sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT);
@@ -132936,7 +134425,13 @@ int libsql_try_initialize_wasm_func_table(sqlite3 *db) {
** Implementation of fpdecode(x,y,z) function.
**
** x is a real number that is to be decoded. y is the precision.
-** z is the maximum real precision.
+** z is the maximum real precision. Return a string that shows the
+** results of the sqlite3FpDecode() function.
+**
+** Used for testing and debugging only, specifically testing and debugging
+** of the sqlite3FpDecode() function. This SQL function does not appear
+** in production builds. This function is not an API and is subject to
+** modification or removal in future versions of SQLite.
*/
static void fpdecodeFunc(
sqlite3_context *context,
@@ -132952,6 +134447,7 @@ static void fpdecodeFunc(
x = sqlite3_value_double(argv[0]);
y = sqlite3_value_int(argv[1]);
z = sqlite3_value_int(argv[2]);
+ if( z<=0 ) z = 1;
sqlite3FpDecode(&s, x, y, z);
if( s.isSpecial==2 ){
sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN");
@@ -132962,6 +134458,82 @@ static void fpdecodeFunc(
}
#endif /* SQLITE_DEBUG */
+#ifdef SQLITE_DEBUG
+/*
+** Implementation of parseuri(uri,flags) function.
+**
+** Required Arguments:
+** "uri" The URI to parse.
+** "flags" Bitmask of flags, as if to sqlite3_open_v2().
+**
+** Additional arguments beyond the first two make calls to
+** sqlite3_uri_key() for integers and sqlite3_uri_parameter for
+** anything else.
+**
+** The result is a string showing the results of calling sqlite3ParseUri().
+**
+** Used for testing and debugging only, specifically testing and debugging
+** of the sqlite3ParseUri() function. This SQL function does not appear
+** in production builds. This function is not an API and is subject to
+** modification or removal in future versions of SQLite.
+*/
+static void parseuriFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ sqlite3_str *pResult;
+ const char *zVfs;
+ const char *zUri;
+ unsigned int flgs;
+ int rc;
+ sqlite3_vfs *pVfs = 0;
+ char *zFile = 0;
+ char *zErr = 0;
+
+ if( argc<2 ) return;
+ pVfs = sqlite3_vfs_find(0);
+ assert( pVfs );
+ zVfs = pVfs->zName;
+ zUri = (const char*)sqlite3_value_text(argv[0]);
+ if( zUri==0 ) return;
+ flgs = (unsigned int)sqlite3_value_int(argv[1]);
+ rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr);
+ pResult = sqlite3_str_new(0);
+ if( pResult ){
+ int i;
+ sqlite3_str_appendf(pResult, "rc=%d", rc);
+ sqlite3_str_appendf(pResult, ", flags=0x%x", flgs);
+ sqlite3_str_appendf(pResult, ", vfs=%Q", pVfs ? pVfs->zName: 0);
+ sqlite3_str_appendf(pResult, ", err=%Q", zErr);
+ sqlite3_str_appendf(pResult, ", file=%Q", zFile);
+ if( zFile ){
+ const char *z = zFile;
+ z += sqlite3Strlen30(z)+1;
+ while( z[0] ){
+ sqlite3_str_appendf(pResult, ", %Q", z);
+ z += sqlite3Strlen30(z)+1;
+ }
+ for(i=2; ia;
- pItem->pTab = pFKey->pFrom;
+ pItem->pSTab = pFKey->pFrom;
pItem->zName = pFKey->pFrom->zName;
- pItem->pTab->nTabRef++;
+ pItem->pSTab->nTabRef++;
pItem->iCursor = pParse->nTab++;
if( regNew!=0 ){
@@ -134496,7 +136070,8 @@ static Trigger *fkActionTrigger(
SrcList *pSrc;
Expr *pRaise;
- pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
+ pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"),
+ pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0);
if( pRaise ){
pRaise->affExpr = OE_Abort;
}
@@ -134504,7 +136079,8 @@ static Trigger *fkActionTrigger(
if( pSrc ){
assert( pSrc->nSrc==1 );
pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom);
- pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
+ assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 );
+ pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
}
pSelect = sqlite3SelectNew(pParse,
sqlite3ExprListAppend(pParse, 0, pRaise),
@@ -135230,6 +136806,210 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
# define autoIncStep(A,B,C)
#endif /* SQLITE_OMIT_AUTOINCREMENT */
+/*
+** If argument pVal is a Select object returned by an sqlite3MultiValues()
+** that was able to use the co-routine optimization, finish coding the
+** co-routine.
+*/
+SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){
+ if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){
+ SrcItem *pItem = &pVal->pSrc->a[0];
+ assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr );
+ if( pItem->fg.isSubquery ){
+ sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn);
+ sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1);
+ }
+ }
+}
+
+/*
+** Return true if all expressions in the expression-list passed as the
+** only argument are constant.
+*/
+static int exprListIsConstant(Parse *pParse, ExprList *pRow){
+ int ii;
+ for(ii=0; iinExpr; ii++){
+ if( 0==sqlite3ExprIsConstant(pParse, pRow->a[ii].pExpr) ) return 0;
+ }
+ return 1;
+}
+
+/*
+** Return true if all expressions in the expression-list passed as the
+** only argument are both constant and have no affinity.
+*/
+static int exprListIsNoAffinity(Parse *pParse, ExprList *pRow){
+ int ii;
+ if( exprListIsConstant(pParse,pRow)==0 ) return 0;
+ for(ii=0; iinExpr; ii++){
+ Expr *pExpr = pRow->a[ii].pExpr;
+ assert( pExpr->op!=TK_RAISE );
+ assert( pExpr->affExpr==0 );
+ if( 0!=sqlite3ExprAffinity(pExpr) ) return 0;
+ }
+ return 1;
+
+}
+
+/*
+** This function is called by the parser for the second and subsequent
+** rows of a multi-row VALUES clause. Argument pLeft is the part of
+** the VALUES clause already parsed, argument pRow is the vector of values
+** for the new row. The Select object returned represents the complete
+** VALUES clause, including the new row.
+**
+** There are two ways in which this may be achieved - by incremental
+** coding of a co-routine (the "co-routine" method) or by returning a
+** Select object equivalent to the following (the "UNION ALL" method):
+**
+** "pLeft UNION ALL SELECT pRow"
+**
+** If the VALUES clause contains a lot of rows, this compound Select
+** object may consume a lot of memory.
+**
+** When the co-routine method is used, each row that will be returned
+** by the VALUES clause is coded into part of a co-routine as it is
+** passed to this function. The returned Select object is equivalent to:
+**
+** SELECT * FROM (
+** Select object to read co-routine
+** )
+**
+** The co-routine method is used in most cases. Exceptions are:
+**
+** a) If the current statement has a WITH clause. This is to avoid
+** statements like:
+**
+** WITH cte AS ( VALUES('x'), ('y') ... )
+** SELECT * FROM cte AS a, cte AS b;
+**
+** This will not work, as the co-routine uses a hard-coded register
+** for its OP_Yield instructions, and so it is not possible for two
+** cursors to iterate through it concurrently.
+**
+** b) The schema is currently being parsed (i.e. the VALUES clause is part
+** of a schema item like a VIEW or TRIGGER). In this case there is no VM
+** being generated when parsing is taking place, and so generating
+** a co-routine is not possible.
+**
+** c) There are non-constant expressions in the VALUES clause (e.g.
+** the VALUES clause is part of a correlated sub-query).
+**
+** d) One or more of the values in the first row of the VALUES clause
+** has an affinity (i.e. is a CAST expression). This causes problems
+** because the complex rules SQLite uses (see function
+** sqlite3SubqueryColumnTypes() in select.c) to determine the effective
+** affinity of such a column for all rows require access to all values in
+** the column simultaneously.
+*/
+SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){
+
+ if( pParse->bHasWith /* condition (a) above */
+ || pParse->db->init.busy /* condition (b) above */
+ || exprListIsConstant(pParse,pRow)==0 /* condition (c) above */
+ || (pLeft->pSrc->nSrc==0 &&
+ exprListIsNoAffinity(pParse,pLeft->pEList)==0) /* condition (d) above */
+ || IN_SPECIAL_PARSE
+ ){
+ /* The co-routine method cannot be used. Fall back to UNION ALL. */
+ Select *pSelect = 0;
+ int f = SF_Values | SF_MultiValue;
+ if( pLeft->pSrc->nSrc ){
+ sqlite3MultiValuesEnd(pParse, pLeft);
+ f = SF_Values;
+ }else if( pLeft->pPrior ){
+ /* In this case set the SF_MultiValue flag only if it was set on pLeft */
+ f = (f & pLeft->selFlags);
+ }
+ pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0);
+ pLeft->selFlags &= ~SF_MultiValue;
+ if( pSelect ){
+ pSelect->op = TK_ALL;
+ pSelect->pPrior = pLeft;
+ pLeft = pSelect;
+ }
+ }else{
+ SrcItem *p = 0; /* SrcItem that reads from co-routine */
+
+ if( pLeft->pSrc->nSrc==0 ){
+ /* Co-routine has not yet been started and the special Select object
+ ** that accesses the co-routine has not yet been created. This block
+ ** does both those things. */
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ Select *pRet = sqlite3SelectNew(pParse, 0, 0, 0, 0, 0, 0, 0, 0);
+
+ /* Ensure the database schema has been read. This is to ensure we have
+ ** the correct text encoding. */
+ if( (pParse->db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ){
+ sqlite3ReadSchema(pParse);
+ }
+
+ if( pRet ){
+ SelectDest dest;
+ Subquery *pSubq;
+ pRet->pSrc->nSrc = 1;
+ pRet->pPrior = pLeft->pPrior;
+ pRet->op = pLeft->op;
+ if( pRet->pPrior ) pRet->selFlags |= SF_Values;
+ pLeft->pPrior = 0;
+ pLeft->op = TK_SELECT;
+ assert( pLeft->pNext==0 );
+ assert( pRet->pNext==0 );
+ p = &pRet->pSrc->a[0];
+ p->fg.viaCoroutine = 1;
+ p->iCursor = -1;
+ assert( !p->fg.isIndexedBy && !p->fg.isTabFunc );
+ p->u1.nRow = 2;
+ if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){
+ pSubq = p->u4.pSubq;
+ pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1;
+ pSubq->regReturn = ++pParse->nMem;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine,
+ pSubq->regReturn, 0, pSubq->addrFillSub);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn);
+
+ /* Allocate registers for the output of the co-routine. Do so so
+ ** that there are two unused registers immediately before those
+ ** used by the co-routine. This allows the code in sqlite3Insert()
+ ** to use these registers directly, instead of copying the output
+ ** of the co-routine to a separate array for processing. */
+ dest.iSdst = pParse->nMem + 3;
+ dest.nSdst = pLeft->pEList->nExpr;
+ pParse->nMem += 2 + dest.nSdst;
+
+ pLeft->selFlags |= SF_MultiValue;
+ sqlite3Select(pParse, pLeft, &dest);
+ pSubq->regResult = dest.iSdst;
+ assert( pParse->nErr || dest.iSdst>0 );
+ }
+ pLeft = pRet;
+ }
+ }else{
+ p = &pLeft->pSrc->a[0];
+ assert( !p->fg.isTabFunc && !p->fg.isIndexedBy );
+ p->u1.nRow++;
+ }
+
+ if( pParse->nErr==0 ){
+ Subquery *pSubq;
+ assert( p!=0 );
+ assert( p->fg.isSubquery );
+ pSubq = p->u4.pSubq;
+ assert( pSubq!=0 );
+ assert( pSubq->pSelect!=0 );
+ assert( pSubq->pSelect->pEList!=0 );
+ if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){
+ sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect);
+ }else{
+ sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0);
+ sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn);
+ }
+ }
+ sqlite3ExprListDelete(pParse->db, pRow);
+ }
+
+ return pLeft;
+}
/* Forward declaration */
static int xferOptimization(
@@ -135569,25 +137349,45 @@ SQLITE_PRIVATE void sqlite3Insert(
if( pSelect ){
/* Data is coming from a SELECT or from a multi-row VALUES clause.
** Generate a co-routine to run the SELECT. */
- int regYield; /* Register holding co-routine entry-point */
- int addrTop; /* Top of the co-routine */
int rc; /* Result code */
- regYield = ++pParse->nMem;
- addrTop = sqlite3VdbeCurrentAddr(v) + 1;
- sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
- sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
- dest.iSdst = bIdListInOrder ? regData : 0;
- dest.nSdst = pTab->nCol;
- rc = sqlite3Select(pParse, pSelect, &dest);
- regFromSelect = dest.iSdst;
- assert( db->pParse==pParse );
- if( rc || pParse->nErr ) goto insert_cleanup;
- assert( db->mallocFailed==0 );
- sqlite3VdbeEndCoroutine(v, regYield);
- sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
- assert( pSelect->pEList );
- nColumn = pSelect->pEList->nExpr;
+ if( pSelect->pSrc->nSrc==1
+ && pSelect->pSrc->a[0].fg.viaCoroutine
+ && pSelect->pPrior==0
+ ){
+ SrcItem *pItem = &pSelect->pSrc->a[0];
+ Subquery *pSubq;
+ assert( pItem->fg.isSubquery );
+ pSubq = pItem->u4.pSubq;
+ dest.iSDParm = pSubq->regReturn;
+ regFromSelect = pSubq->regResult;
+ assert( pSubq->pSelect!=0 );
+ assert( pSubq->pSelect->pEList!=0 );
+ nColumn = pSubq->pSelect->pEList->nExpr;
+ ExplainQueryPlan((pParse, 0, "SCAN %S", pItem));
+ if( bIdListInOrder && nColumn==pTab->nCol ){
+ regData = regFromSelect;
+ regRowid = regData - 1;
+ regIns = regRowid - (IsVirtual(pTab) ? 1 : 0);
+ }
+ }else{
+ int addrTop; /* Top of the co-routine */
+ int regYield = ++pParse->nMem;
+ addrTop = sqlite3VdbeCurrentAddr(v) + 1;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+ dest.iSdst = bIdListInOrder ? regData : 0;
+ dest.nSdst = pTab->nCol;
+ rc = sqlite3Select(pParse, pSelect, &dest);
+ regFromSelect = dest.iSdst;
+ assert( db->pParse==pParse );
+ if( rc || pParse->nErr ) goto insert_cleanup;
+ assert( db->mallocFailed==0 );
+ sqlite3VdbeEndCoroutine(v, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
+ assert( pSelect->pEList );
+ nColumn = pSelect->pEList->nExpr;
+ }
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
@@ -135742,7 +137542,7 @@ SQLITE_PRIVATE void sqlite3Insert(
pNx->iDataCur = iDataCur;
pNx->iIdxCur = iIdxCur;
if( pNx->pUpsertTarget ){
- if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){
+ if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){
goto insert_cleanup;
}
}
@@ -137512,7 +139312,7 @@ static int xferOptimization(
if( pSelect->pSrc->nSrc!=1 ){
return 0; /* FROM clause must have exactly one term */
}
- if( pSelect->pSrc->a[0].pSelect ){
+ if( pSelect->pSrc->a[0].fg.isSubquery ){
return 0; /* FROM clause cannot contain a subquery */
}
if( pSelect->pWhere ){
@@ -137663,7 +139463,10 @@ static int xferOptimization(
}
}
#ifndef SQLITE_OMIT_CHECK
- if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
+ if( pDest->pCheck
+ && (db->mDbFlags & DBFLAG_Vacuum)==0
+ && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1)
+ ){
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
}
#endif
@@ -140365,6 +142168,34 @@ static const PragmaName aPragmaName[] = {
/************** End of pragma.h **********************************************/
/************** Continuing where we left off in pragma.c *********************/
+/*
+** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands
+** will be run with an analysis_limit set to the lessor of the value of
+** the following macro or to the actual analysis_limit if it is non-zero,
+** in order to prevent PRAGMA optimize from running for too long.
+**
+** The value of 2000 is chosen emperically so that the worst-case run-time
+** for PRAGMA optimize does not exceed 100 milliseconds against a variety
+** of test databases on a RaspberryPI-4 compiled using -Os and without
+** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of
+** this paragraph, "worst-case" means that ANALYZE ends up being
+** run on every table in the database. The worst case typically only
+** happens if PRAGMA optimize is run on a database file for which ANALYZE
+** has not been previously run and the 0x10000 flag is included so that
+** all tables are analyzed. The usual case for PRAGMA optimize is that
+** no ANALYZE commands will be run at all, or if any ANALYZE happens it
+** will be against a single table, so that expected timing for PRAGMA
+** optimize on a PI-4 is more like 1 millisecond or less with the 0x10000
+** flag or less than 100 microseconds without the 0x10000 flag.
+**
+** An analysis limit of 2000 is almost always sufficient for the query
+** planner to fully characterize an index. The additional accuracy from
+** a larger analysis is not usually helpful.
+*/
+#ifndef SQLITE_DEFAULT_OPTIMIZE_LIMIT
+# define SQLITE_DEFAULT_OPTIMIZE_LIMIT 2000
+#endif
+
/*
** Interpret the given string as a safety level. Return 0 for OFF,
** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or
@@ -142019,7 +143850,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Set the maximum error count */
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
if( zRight ){
- if( sqlite3GetInt32(zRight, &mxErr) ){
+ if( sqlite3GetInt32(pValue->z, &mxErr) ){
if( mxErr<=0 ){
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
}
@@ -142036,7 +143867,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
Hash *pTbls; /* Set of all tables in the schema */
int *aRoot; /* Array of root page numbers of all btrees */
int cnt = 0; /* Number of entries in aRoot[] */
- int mxIdx = 0; /* Maximum number of indexes for any table */
if( OMIT_TEMPDB && i==1 ) continue;
if( iDb>=0 && i!=iDb ) continue;
@@ -142058,7 +143888,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( pObjTab && pObjTab!=pTab ) continue;
if( HasRowid(pTab) ) cnt++;
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
- if( nIdx>mxIdx ) mxIdx = nIdx;
}
if( cnt==0 ) continue;
if( pObjTab ) cnt++;
@@ -142078,11 +143907,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
aRoot[0] = cnt;
/* Make sure sufficient number of registers have been allocated */
- sqlite3TouchRegister(pParse, 8+mxIdx);
+ sqlite3TouchRegister(pParse, 8+cnt);
+ sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt);
sqlite3ClearTempRegCache(pParse);
/* Do the b-tree integrity checks */
- sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
+ sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY);
sqlite3VdbeChangeP5(v, (u8)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
@@ -142092,6 +143922,36 @@ SQLITE_PRIVATE void sqlite3Pragma(
integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, addr);
+ /* Check that the indexes all have the right number of rows */
+ cnt = pObjTab ? 1 : 0;
+ sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
+ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+ int iTab = 0;
+ Table *pTab = sqliteHashData(x);
+ Index *pIdx;
+ if( pObjTab && pObjTab!=pTab ) continue;
+ if( HasRowid(pTab) ){
+ iTab = cnt++;
+ }else{
+ iTab = cnt;
+ for(pIdx=pTab->pIndex; ALWAYS(pIdx); pIdx=pIdx->pNext){
+ if( IsPrimaryKeyIndex(pIdx) ) break;
+ iTab++;
+ }
+ }
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->pPartIdxWhere==0 ){
+ addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+cnt, 0, 8+iTab);
+ VdbeCoverageNeverNull(v);
+ sqlite3VdbeLoadString(v, 4, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
+ integrityCheckResultRow(v);
+ sqlite3VdbeJumpHere(v, addr);
+ }
+ cnt++;
+ }
+ }
+
/* Make sure all the indices are constructed correctly.
*/
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
@@ -142106,31 +143966,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
int mxCol; /* Maximum non-virtual column number */
if( pObjTab && pObjTab!=pTab ) continue;
- if( !IsOrdinaryTable(pTab) ){
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3_vtab *pVTab;
- int a1;
- if( !IsVirtual(pTab) ) continue;
- if( pTab->nCol<=0 ){
- const char *zMod = pTab->u.vtab.azArg[0];
- if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
- }
- sqlite3ViewGetColumnNames(pParse, pTab);
- if( pTab->u.vtab.p==0 ) continue;
- pVTab = pTab->u.vtab.p->pVtab;
- if( NEVER(pVTab==0) ) continue;
- if( NEVER(pVTab->pModule==0) ) continue;
- if( pVTab->pModule->iVersion<4 ) continue;
- if( pVTab->pModule->xIntegrity==0 ) continue;
- sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
- pTab->nTabRef++;
- sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF);
- a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
- integrityCheckResultRow(v);
- sqlite3VdbeJumpHere(v, a1);
-#endif
- continue;
- }
+ if( !IsOrdinaryTable(pTab) ) continue;
if( isQuick || HasRowid(pTab) ){
pPk = 0;
r2 = 0;
@@ -142265,6 +144101,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** is REAL, we have to load the actual data using OP_Column
** to reliably determine if the value is a NULL. */
sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3);
+ sqlite3ColumnDefault(v, pTab, j, 3);
jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk);
VdbeCoverage(v);
}
@@ -142457,6 +144294,38 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ /* Second pass to invoke the xIntegrity method on all virtual
+ ** tables.
+ */
+ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
+ Table *pTab = sqliteHashData(x);
+ sqlite3_vtab *pVTab;
+ int a1;
+ if( pObjTab && pObjTab!=pTab ) continue;
+ if( IsOrdinaryTable(pTab) ) continue;
+ if( !IsVirtual(pTab) ) continue;
+ if( pTab->nCol<=0 ){
+ const char *zMod = pTab->u.vtab.azArg[0];
+ if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue;
+ }
+ sqlite3ViewGetColumnNames(pParse, pTab);
+ if( pTab->u.vtab.p==0 ) continue;
+ pVTab = pTab->u.vtab.p->pVtab;
+ if( NEVER(pVTab==0) ) continue;
+ if( NEVER(pVTab->pModule==0) ) continue;
+ if( pVTab->pModule->iVersion<4 ) continue;
+ if( pVTab->pModule->xIntegrity==0 ) continue;
+ sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick);
+ pTab->nTabRef++;
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF);
+ a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v);
+ integrityCheckResultRow(v);
+ sqlite3VdbeJumpHere(v, a1);
+ continue;
+ }
+#endif
}
{
static const int iLn = VDBE_OFFSET_LINENO(2);
@@ -142720,44 +144589,63 @@ SQLITE_PRIVATE void sqlite3Pragma(
**
** The optional argument is a bitmask of optimizations to perform:
**
- ** 0x0001 Debugging mode. Do not actually perform any optimizations
- ** but instead return one line of text for each optimization
- ** that would have been done. Off by default.
+ ** 0x00001 Debugging mode. Do not actually perform any optimizations
+ ** but instead return one line of text for each optimization
+ ** that would have been done. Off by default.
**
- ** 0x0002 Run ANALYZE on tables that might benefit. On by default.
- ** See below for additional information.
+ ** 0x00002 Run ANALYZE on tables that might benefit. On by default.
+ ** See below for additional information.
**
- ** 0x0004 (Not yet implemented) Record usage and performance
- ** information from the current session in the
- ** database file so that it will be available to "optimize"
- ** pragmas run by future database connections.
+ ** 0x00010 Run all ANALYZE operations using an analysis_limit that
+ ** is the lessor of the current analysis_limit and the
+ ** SQLITE_DEFAULT_OPTIMIZE_LIMIT compile-time option.
+ ** The default value of SQLITE_DEFAULT_OPTIMIZE_LIMIT is
+ ** currently (2024-02-19) set to 2000, which is such that
+ ** the worst case run-time for PRAGMA optimize on a 100MB
+ ** database will usually be less than 100 milliseconds on
+ ** a RaspberryPI-4 class machine. On by default.
**
- ** 0x0008 (Not yet implemented) Create indexes that might have
- ** been helpful to recent queries
+ ** 0x10000 Look at tables to see if they need to be reanalyzed
+ ** due to growth or shrinkage even if they have not been
+ ** queried during the current connection. Off by default.
**
- ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all
- ** of the optimizations listed above except Debug Mode, including new
- ** optimizations that have not yet been invented. If new optimizations are
- ** ever added that should be off by default, those off-by-default
- ** optimizations will have bitmasks of 0x10000 or larger.
+ ** The default MASK is and always shall be 0x0fffe. In the current
+ ** implementation, the default mask only covers the 0x00002 optimization,
+ ** though additional optimizations that are covered by 0x0fffe might be
+ ** added in the future. Optimizations that are off by default and must
+ ** be explicitly requested have masks of 0x10000 or greater.
**
** DETERMINATION OF WHEN TO RUN ANALYZE
**
** In the current implementation, a table is analyzed if only if all of
** the following are true:
**
- ** (1) MASK bit 0x02 is set.
+ ** (1) MASK bit 0x00002 is set.
+ **
+ ** (2) The table is an ordinary table, not a virtual table or view.
+ **
+ ** (3) The table name does not begin with "sqlite_".
**
- ** (2) The query planner used sqlite_stat1-style statistics for one or
- ** more indexes of the table at some point during the lifetime of
- ** the current connection.
+ ** (4) One or more of the following is true:
+ ** (4a) The 0x10000 MASK bit is set.
+ ** (4b) One or more indexes on the table lacks an entry
+ ** in the sqlite_stat1 table.
+ ** (4c) The query planner used sqlite_stat1-style statistics for one
+ ** or more indexes of the table at some point during the lifetime
+ ** of the current connection.
**
- ** (3) One or more indexes of the table are currently unanalyzed OR
- ** the number of rows in the table has increased by 25 times or more
- ** since the last time ANALYZE was run.
+ ** (5) One or more of the following is true:
+ ** (5a) One or more indexes on the table lacks an entry
+ ** in the sqlite_stat1 table. (Same as 4a)
+ ** (5b) The number of rows in the table has increased or decreased by
+ ** 10-fold. In other words, the current size of the table is
+ ** 10 times larger than the size in sqlite_stat1 or else the
+ ** current size is less than 1/10th the size in sqlite_stat1.
**
** The rules for when tables are analyzed are likely to change in
- ** future releases.
+ ** future releases. Future versions of SQLite might accept a string
+ ** literal argument to this pragma that contains a mnemonic description
+ ** of the options rather than a bitmap.
*/
case PragTyp_OPTIMIZE: {
int iDbLast; /* Loop termination point for the schema loop */
@@ -142769,6 +144657,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
LogEst szThreshold; /* Size threshold above which reanalysis needed */
char *zSubSql; /* SQL statement for the OP_SqlExec opcode */
u32 opMask; /* Mask of operations to perform */
+ int nLimit; /* Analysis limit to use */
+ int nCheck = 0; /* Number of tables to be optimized */
+ int nBtree = 0; /* Number of btrees to scan */
+ int nIndex; /* Number of indexes on the current table */
if( zRight ){
opMask = (u32)sqlite3Atoi(zRight);
@@ -142776,6 +144668,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
}else{
opMask = 0xfffe;
}
+ if( (opMask & 0x10)==0 ){
+ nLimit = 0;
+ }else if( db->nAnalysisLimit>0
+ && db->nAnalysisLimitnTab++;
for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
if( iDb==1 ) continue;
@@ -142784,23 +144684,61 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
pTab = (Table*)sqliteHashData(k);
- /* If table pTab has not been used in a way that would benefit from
- ** having analysis statistics during the current session, then skip it.
- ** This also has the effect of skipping virtual tables and views */
- if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;
+ /* This only works for ordinary tables */
+ if( !IsOrdinaryTable(pTab) ) continue;
+
+ /* Do not scan system tables */
+ if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ) continue;
- /* Reanalyze if the table is 25 times larger than the last analysis */
- szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
+ /* Find the size of the table as last recorded in sqlite_stat1.
+ ** If any index is unanalyzed, then the threshold is -1 to
+ ** indicate a new, unanalyzed index
+ */
+ szThreshold = pTab->nRowLogEst;
+ nIndex = 0;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ nIndex++;
if( !pIdx->hasStat1 ){
- szThreshold = 0; /* Always analyze if any index lacks statistics */
- break;
+ szThreshold = -1; /* Always analyze if any index lacks statistics */
}
}
- if( szThreshold ){
- sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
- sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur,
- sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold);
+
+ /* If table pTab has not been used in a way that would benefit from
+ ** having analysis statistics during the current session, then skip it,
+ ** unless the 0x10000 MASK bit is set. */
+ if( (pTab->tabFlags & TF_MaybeReanalyze)!=0 ){
+ /* Check for size change if stat1 has been used for a query */
+ }else if( opMask & 0x10000 ){
+ /* Check for size change if 0x10000 is set */
+ }else if( pTab->pIndex!=0 && szThreshold<0 ){
+ /* Do analysis if unanalyzed indexes exists */
+ }else{
+ /* Otherwise, we can skip this table */
+ continue;
+ }
+
+ nCheck++;
+ if( nCheck==2 ){
+ /* If ANALYZE might be invoked two or more times, hold a write
+ ** transaction for efficiency */
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ }
+ nBtree += nIndex+1;
+
+ /* Reanalyze if the table is 10 times larger or smaller than
+ ** the last analysis. Unconditional reanalysis if there are
+ ** unanalyzed indexes. */
+ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
+ if( szThreshold>=0 ){
+ const LogEst iRange = 33; /* 10x size change */
+ sqlite3VdbeAddOp4Int(v, OP_IfSizeBetween, iTabCur,
+ sqlite3VdbeCurrentAddr(v)+2+(opMask&1),
+ szThreshold>=iRange ? szThreshold-iRange : -1,
+ szThreshold+iRange);
+ VdbeCoverage(v);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Rewind, iTabCur,
+ sqlite3VdbeCurrentAddr(v)+2+(opMask&1));
VdbeCoverage(v);
}
zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"",
@@ -142810,11 +144748,27 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC);
sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1);
}else{
- sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC);
+ sqlite3VdbeAddOp4(v, OP_SqlExec, nLimit ? 0x02 : 00, nLimit, 0,
+ zSubSql, P4_DYNAMIC);
}
}
}
sqlite3VdbeAddOp0(v, OP_Expire);
+
+ /* In a schema with a large number of tables and indexes, scale back
+ ** the analysis_limit to avoid excess run-time in the worst case.
+ */
+ if( !db->mallocFailed && nLimit>0 && nBtree>100 ){
+ int iAddr, iEnd;
+ VdbeOp *aOp;
+ nLimit = 100*nLimit/nBtree;
+ if( nLimit<100 ) nLimit = 100;
+ aOp = sqlite3VdbeGetOp(v, 0);
+ iEnd = sqlite3VdbeCurrentAddr(v);
+ for(iAddr=0; iAddrnConstraint; i++, pConstraint++){
- if( pConstraint->usable==0 ) continue;
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( pConstraint->iColumn < pTab->iHidden ) continue;
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( pConstraint->usable==0 ) return SQLITE_CONSTRAINT;
j = pConstraint->iColumn - pTab->iHidden;
assert( j < 2 );
seen[j] = i+1;
@@ -143093,12 +145047,13 @@ static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
j = seen[0]-1;
pIdxInfo->aConstraintUsage[j].argvIndex = 1;
pIdxInfo->aConstraintUsage[j].omit = 1;
- if( seen[1]==0 ) return SQLITE_OK;
pIdxInfo->estimatedCost = (double)20;
pIdxInfo->estimatedRows = 20;
- j = seen[1]-1;
- pIdxInfo->aConstraintUsage[j].argvIndex = 2;
- pIdxInfo->aConstraintUsage[j].omit = 1;
+ if( seen[1] ){
+ j = seen[1]-1;
+ pIdxInfo->aConstraintUsage[j].argvIndex = 2;
+ pIdxInfo->aConstraintUsage[j].omit = 1;
+ }
return SQLITE_OK;
}
@@ -143118,6 +145073,7 @@ static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){
int i;
sqlite3_finalize(pCsr->pPragma);
pCsr->pPragma = 0;
+ pCsr->iRowid = 0;
for(i=0; iazArg); i++){
sqlite3_free(pCsr->azArg[i]);
pCsr->azArg[i] = 0;
@@ -143918,7 +145874,13 @@ SQLITE_PRIVATE void *sqlite3ParserAddCleanup(
void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */
void *pPtr /* Pointer to object to be cleaned up */
){
- ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup));
+ ParseCleanup *pCleanup;
+ if( sqlite3FaultSim(300) ){
+ pCleanup = 0;
+ sqlite3OomFault(pParse->db);
+ }else{
+ pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup));
+ }
if( pCleanup ){
pCleanup->pNext = pParse->pCleanup;
pParse->pCleanup = pCleanup;
@@ -144286,12 +146248,24 @@ static int sqlite3Prepare16(
if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
return SQLITE_MISUSE_BKPT;
}
+
+ /* Make sure nBytes is non-negative and correct. It should be the
+ ** number of bytes until the end of the input buffer or until the first
+ ** U+0000 character. If the input nBytes is odd, convert it into
+ ** an even number. If the input nBytes is negative, then the input
+ ** must be terminated by at least one U+0000 character */
if( nBytes>=0 ){
int sz;
const char *z = (const char*)zSql;
for(sz=0; szmutex);
zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
if( zSql8 ){
@@ -144305,7 +146279,7 @@ static int sqlite3Prepare16(
** the same number of characters into the UTF-16 string.
*/
int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8));
- *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
+ *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, nBytes, chars_parsed);
}
sqlite3DbFree(db, zSql8);
rc = sqlite3ApiExit(db, rc);
@@ -144699,11 +146673,13 @@ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){
*/
SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
assert( pItem!=0 );
- assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
+ assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
if( pItem->fg.isNestedFrom ){
ExprList *pResults;
- assert( pItem->pSelect!=0 );
- pResults = pItem->pSelect->pEList;
+ assert( pItem->fg.isSubquery );
+ assert( pItem->u4.pSubq!=0 );
+ assert( pItem->u4.pSubq->pSelect!=0 );
+ pResults = pItem->u4.pSubq->pSelect->pEList;
assert( pResults!=0 );
assert( iCol>=0 && iColnExpr );
pResults->a[iCol].fg.bUsed = 1;
@@ -144737,9 +146713,9 @@ static int tableAndColumnIndex(
assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
for(i=iStart; i<=iEnd; i++){
- iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol);
+ iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol);
if( iCol>=0
- && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
+ && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0)
){
if( piTab ){
sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol);
@@ -144868,10 +146844,10 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){
pLeft = &pSrc->a[0];
pRight = &pLeft[1];
for(i=0; inSrc-1; i++, pRight++, pLeft++){
- Table *pRightTab = pRight->pTab;
+ Table *pRightTab = pRight->pSTab;
u32 joinType;
- if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
+ if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue;
joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON;
/* If this is a NATURAL join, synthesize an appropriate USING clause
@@ -145744,12 +147720,18 @@ static void selectInnerLoop(
** case the order does matter */
pushOntoSorter(
pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
+ pDest->iSDParm2 = 0; /* Signal that any Bloom filter is unpopulated */
}else{
int r1 = sqlite3GetTempReg(pParse);
assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol,
r1, pDest->zAffSdst, nResultCol);
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
+ if( pDest->iSDParm2 ){
+ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0,
+ regResult, nResultCol);
+ ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER"));
+ }
sqlite3ReleaseTempReg(pParse, r1);
}
break;
@@ -146050,9 +148032,16 @@ static void generateSortTail(
int addrExplain; /* Address of OP_Explain instruction */
#endif
- ExplainQueryPlan2(addrExplain, (pParse, 0,
- "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"")
- );
+ nKey = pOrderBy->nExpr - pSort->nOBSat;
+ if( pSort->nOBSat==0 || nKey==1 ){
+ ExplainQueryPlan2(addrExplain, (pParse, 0,
+ "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat?"LAST TERM OF ":""
+ ));
+ }else{
+ ExplainQueryPlan2(addrExplain, (pParse, 0,
+ "USE TEMP B-TREE FOR LAST %d TERMS OF ORDER BY", nKey
+ ));
+ }
sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd);
sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush);
@@ -146090,7 +148079,6 @@ static void generateSortTail(
regRow = sqlite3GetTempRange(pParse, nColumn);
}
}
- nKey = pOrderBy->nExpr - pSort->nOBSat;
if( pSort->sortFlags & SORTFLAG_UseSorter ){
int regSortOut = ++pParse->nMem;
iSortTab = pParse->nTab++;
@@ -146295,8 +148283,12 @@ static const char *columnTypeImpl(
SrcList *pTabList = pNC->pSrcList;
for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
if( jnSrc ){
- pTab = pTabList->a[j].pTab;
- pS = pTabList->a[j].pSelect;
+ pTab = pTabList->a[j].pSTab;
+ if( pTabList->a[j].fg.isSubquery ){
+ pS = pTabList->a[j].u4.pSubq->pSelect;
+ }else{
+ pS = 0;
+ }
}else{
pNC = pNC->pNext;
}
@@ -146330,11 +148322,7 @@ static const char *columnTypeImpl(
** data for the result-set column of the sub-select.
*/
if( iColpEList->nExpr
-#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
- && iCol>=0
-#else
- && ALWAYS(iCol>=0)
-#endif
+ && (!ViewCanHaveRowid || iCol>=0)
){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
@@ -146699,8 +148687,7 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(
NameContext sNC;
assert( pSelect!=0 );
- testcase( (pSelect->selFlags & SF_Resolved)==0 );
- assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT );
+ assert( (pSelect->selFlags & SF_Resolved)!=0 );
assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 );
assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB );
if( db->mallocFailed || IN_RENAME_OBJECT ) return;
@@ -146711,17 +148698,22 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(
for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){
const char *zType;
i64 n;
+ int m = 0;
+ Select *pS2 = pSelect;
pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT);
p = a[i].pExpr;
/* pCol->szEst = ... // Column size est for SELECT tables never used */
pCol->affinity = sqlite3ExprAffinity(p);
+ while( pCol->affinity<=SQLITE_AFF_NONE && pS2->pNext!=0 ){
+ m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr);
+ pS2 = pS2->pNext;
+ pCol->affinity = sqlite3ExprAffinity(pS2->pEList->a[i].pExpr);
+ }
if( pCol->affinity<=SQLITE_AFF_NONE ){
pCol->affinity = aff;
}
- if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){
- int m = 0;
- Select *pS2;
- for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){
+ if( pCol->affinity>=SQLITE_AFF_TEXT && (pS2->pNext || pS2!=pSelect) ){
+ for(pS2=pS2->pNext; pS2; pS2=pS2->pNext){
m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr);
}
if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){
@@ -146751,12 +148743,12 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(
}
}
if( zType ){
- i64 m = sqlite3Strlen30(zType);
+ const i64 k = sqlite3Strlen30(zType);
n = sqlite3Strlen30(pCol->zCnName);
- pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
+ pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2);
pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
if( pCol->zCnName ){
- memcpy(&pCol->zCnName[n+1], zType, m+1);
+ memcpy(&pCol->zCnName[n+1], zType, k+1);
pCol->colFlags |= COLFLAG_HASTYPE;
}
}
@@ -146863,7 +148855,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
- if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){
+ if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse) ){
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
@@ -147343,7 +149335,7 @@ static int multiSelect(
p->pPrior = pPrior;
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
if( p->pLimit
- && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit)
+ && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse)
&& nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
){
p->nSelectRow = sqlite3LogEst((u64)nLimit);
@@ -147687,6 +149679,11 @@ static int generateOutputSubroutine(
r1, pDest->zAffSdst, pIn->nSdst);
sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
pIn->iSdst, pIn->nSdst);
+ if( pDest->iSDParm2>0 ){
+ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0,
+ pIn->iSdst, pIn->nSdst);
+ ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER"));
+ }
sqlite3ReleaseTempReg(pParse, r1);
break;
}
@@ -148265,32 +150262,32 @@ static Expr *substExpr(
if( pSubst->isOuterJoin ){
ExprSetProperty(pNew, EP_CanBeNull);
}
- if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){
- sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
- pExpr->flags & (EP_OuterON|EP_InnerON));
- }
- sqlite3ExprDelete(db, pExpr);
- pExpr = pNew;
- if( pExpr->op==TK_TRUEFALSE ){
- pExpr->u.iValue = sqlite3ExprTruthValue(pExpr);
- pExpr->op = TK_INTEGER;
- ExprSetProperty(pExpr, EP_IntValue);
+ if( pNew->op==TK_TRUEFALSE ){
+ pNew->u.iValue = sqlite3ExprTruthValue(pNew);
+ pNew->op = TK_INTEGER;
+ ExprSetProperty(pNew, EP_IntValue);
}
/* Ensure that the expression now has an implicit collation sequence,
** just as it did when it was a column of a view or sub-query. */
{
- CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr);
+ CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pNew);
CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse,
pSubst->pCList->a[iColumn].pExpr
);
- if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){
- pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr,
+ if( pNat!=pColl || (pNew->op!=TK_COLUMN && pNew->op!=TK_COLLATE) ){
+ pNew = sqlite3ExprAddCollateString(pSubst->pParse, pNew,
(pColl ? pColl->zName : "BINARY")
);
}
}
- ExprClearProperty(pExpr, EP_Collate);
+ ExprClearProperty(pNew, EP_Collate);
+ if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){
+ sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
+ pExpr->flags & (EP_OuterON|EP_InnerON));
+ }
+ sqlite3ExprDelete(db, pExpr);
+ pExpr = pNew;
}
}
}else{
@@ -148343,7 +150340,9 @@ static void substSelect(
pSrc = p->pSrc;
assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- substSelect(pSubst, pItem->pSelect, 1);
+ if( pItem->fg.isSubquery ){
+ substSelect(pSubst, pItem->u4.pSubq->pSelect, 1);
+ }
if( pItem->fg.isTabFunc ){
substExprList(pSubst, pItem->u1.pFuncArg);
}
@@ -148374,7 +150373,7 @@ static void recomputeColumnsUsed(
SrcItem *pSrcItem /* Which FROM clause item to recompute */
){
Walker w;
- if( NEVER(pSrcItem->pTab==0) ) return;
+ if( NEVER(pSrcItem->pSTab==0) ) return;
memset(&w, 0, sizeof(w));
w.xExprCallback = recomputeColumnsUsedExpr;
w.xSelectCallback = sqlite3SelectWalkNoop;
@@ -148414,8 +150413,10 @@ static void srclistRenumberCursors(
aCsrMap[pItem->iCursor+1] = pParse->nTab++;
}
pItem->iCursor = aCsrMap[pItem->iCursor+1];
- for(p=pItem->pSelect; p; p=p->pPrior){
- srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
+ if( pItem->fg.isSubquery ){
+ for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){
+ srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1);
+ }
}
}
}
@@ -148726,7 +150727,8 @@ static int flattenSubquery(
assert( pSrc && iFrom>=0 && iFromnSrc );
pSubitem = &pSrc->a[iFrom];
iParent = pSubitem->iCursor;
- pSub = pSubitem->pSelect;
+ assert( pSubitem->fg.isSubquery );
+ pSub = pSubitem->u4.pSubq->pSelect;
assert( pSub!=0 );
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -148779,7 +150781,7 @@ static int flattenSubquery(
*/
if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
if( pSubSrc->nSrc>1 /* (3a) */
- || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */
+ || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */
|| (p->selFlags & SF_Distinct)!=0 /* (3d) */
|| (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */
){
@@ -148865,14 +150867,18 @@ static int flattenSubquery(
pParse->zAuthContext = zSavedAuthContext;
/* Delete the transient structures associated with the subquery */
- pSub1 = pSubitem->pSelect;
- sqlite3DbFree(db, pSubitem->zDatabase);
+
+ if( ALWAYS(pSubitem->fg.isSubquery) ){
+ pSub1 = sqlite3SubqueryDetach(db, pSubitem);
+ }else{
+ pSub1 = 0;
+ }
+ assert( pSubitem->fg.isSubquery==0 );
+ assert( pSubitem->fg.fixedSchema==0 );
sqlite3DbFree(db, pSubitem->zName);
sqlite3DbFree(db, pSubitem->zAlias);
- pSubitem->zDatabase = 0;
pSubitem->zName = 0;
pSubitem->zAlias = 0;
- pSubitem->pSelect = 0;
assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 );
/* If the sub-query is a compound SELECT statement, then (by restrictions
@@ -148913,8 +150919,8 @@ static int flattenSubquery(
ExprList *pOrderBy = p->pOrderBy;
Expr *pLimit = p->pLimit;
Select *pPrior = p->pPrior;
- Table *pItemTab = pSubitem->pTab;
- pSubitem->pTab = 0;
+ Table *pItemTab = pSubitem->pSTab;
+ pSubitem->pSTab = 0;
p->pOrderBy = 0;
p->pPrior = 0;
p->pLimit = 0;
@@ -148922,7 +150928,7 @@ static int flattenSubquery(
p->pLimit = pLimit;
p->pOrderBy = pOrderBy;
p->op = TK_ALL;
- pSubitem->pTab = pItemTab;
+ pSubitem->pSTab = pItemTab;
if( pNew==0 ){
p->pPrior = pPrior;
}else{
@@ -148937,11 +150943,14 @@ static int flattenSubquery(
TREETRACE(0x4,pParse,p,("compound-subquery flattener"
" creates %u as peer\n",pNew->selId));
}
- assert( pSubitem->pSelect==0 );
+ assert( pSubitem->fg.isSubquery==0 );
}
sqlite3DbFree(db, aCsrMap);
if( db->mallocFailed ){
- pSubitem->pSelect = pSub1;
+ assert( pSubitem->fg.fixedSchema==0 );
+ assert( pSubitem->fg.isSubquery==0 );
+ assert( pSubitem->u4.zDatabase==0 );
+ sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0);
return 1;
}
@@ -148952,8 +150961,8 @@ static int flattenSubquery(
**
** pSubitem->pTab is always non-NULL by test restrictions and tests above.
*/
- if( ALWAYS(pSubitem->pTab!=0) ){
- Table *pTabToDel = pSubitem->pTab;
+ if( ALWAYS(pSubitem->pSTab!=0) ){
+ Table *pTabToDel = pSubitem->pSTab;
if( pTabToDel->nTabRef==1 ){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel);
@@ -148961,7 +150970,7 @@ static int flattenSubquery(
}else{
pTabToDel->nTabRef--;
}
- pSubitem->pTab = 0;
+ pSubitem->pSTab = 0;
}
/* The following loop runs once for each term in a compound-subquery
@@ -149017,8 +151026,11 @@ static int flattenSubquery(
*/
for(i=0; ia[i+iFrom];
- if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
assert( pItem->fg.isTabFunc==0 );
+ assert( pItem->fg.isSubquery
+ || pItem->fg.fixedSchema
+ || pItem->u4.zDatabase==0 );
+ if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
*pItem = pSubSrc->a[i];
pItem->fg.jointype |= ltorj;
iNewParent = pSubSrc->a[i].iCursor;
@@ -149153,7 +151165,7 @@ static void constInsert(
){
int i;
assert( pColumn->op==TK_COLUMN );
- assert( sqlite3ExprIsConstant(pValue) );
+ assert( sqlite3ExprIsConstant(pConst->pParse, pValue) );
if( ExprHasProperty(pColumn, EP_FixedCol) ) return;
if( sqlite3ExprAffinity(pValue)!=0 ) return;
@@ -149211,10 +151223,10 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
pLeft = pExpr->pLeft;
assert( pRight!=0 );
assert( pLeft!=0 );
- if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){
+ if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pLeft) ){
constInsert(pConst,pRight,pLeft,pExpr);
}
- if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){
+ if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pRight) ){
constInsert(pConst,pLeft,pRight,pExpr);
}
}
@@ -149435,6 +151447,19 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
** The hope is that the terms added to the inner query will make it more
** efficient.
**
+** NAME AMBIGUITY
+**
+** This optimization is called the "WHERE-clause push-down optimization"
+** or sometimes the "predicate push-down optimization".
+**
+** Do not confuse this optimization with another unrelated optimization
+** with a similar name: The "MySQL push-down optimization" causes WHERE
+** clause terms that can be evaluated using only the index and without
+** reference to the table are run first, so that if they are false,
+** unnecessary table seeks are avoided.
+**
+** RULES
+**
** Do not attempt this optimization if:
**
** (1) (** This restriction was removed on 2017-09-29. We used to
@@ -149500,15 +151525,19 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING
** clause and the subquery.
**
-** Without this restriction, the push-down optimization might move
-** the ON/USING filter expression from the left side of a RIGHT JOIN
-** over to the right side, which leads to incorrect answers. See
-** also restriction (6) in sqlite3ExprIsSingleTableConstraint().
+** Without this restriction, the WHERE-clause push-down optimization
+** might move the ON/USING filter expression from the left side of a
+** RIGHT JOIN over to the right side, which leads to incorrect answers.
+** See also restriction (6) in sqlite3ExprIsSingleTableConstraint().
**
** (10) The inner query is not the right-hand table of a RIGHT JOIN.
**
** (11) The subquery is not a VALUES clause
**
+** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This
+** case only comes up if SQLite is compiled using
+** SQLITE_ALLOW_ROWID_IN_VIEW.
+**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
*/
@@ -149619,7 +151648,19 @@ static int pushDownWhereTerms(
}
#endif
- if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ if( ViewCanHaveRowid && (pWhere->op==TK_ISNULL || pWhere->op==TK_NOTNULL) ){
+ Expr *pLeft = pWhere->pLeft;
+ if( ALWAYS(pLeft)
+ && pLeft->op==TK_COLUMN
+ && pLeft->iColumn < 0
+ ){
+ return 0; /* Restriction (12) */
+ }
+ }
+#endif
+
+ if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){
nChng++;
pSubq->selFlags |= SF_PushDown;
while( pSubq ){
@@ -149673,10 +151714,10 @@ static int disableUnusedSubqueryResultColumns(SrcItem *pItem){
if( pItem->fg.isCorrelated || pItem->fg.isCte ){
return 0;
}
- assert( pItem->pTab!=0 );
- pTab = pItem->pTab;
- assert( pItem->pSelect!=0 );
- pSub = pItem->pSelect;
+ assert( pItem->pSTab!=0 );
+ pTab = pItem->pSTab;
+ assert( pItem->fg.isSubquery );
+ pSub = pItem->u4.pSubq->pSelect;
assert( pSub->pEList->nExpr==pTab->nCol );
for(pX=pSub; pX; pX=pX->pPrior){
if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){
@@ -149805,13 +151846,13 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
if( p->pWhere
|| p->pEList->nExpr!=1
|| p->pSrc->nSrc!=1
- || p->pSrc->a[0].pSelect
+ || p->pSrc->a[0].fg.isSubquery
|| pAggInfo->nFunc!=1
|| p->pHaving
){
return 0;
}
- pTab = p->pSrc->a[0].pTab;
+ pTab = p->pSrc->a[0].pSTab;
assert( pTab!=0 );
assert( !IsView(pTab) );
if( !IsOrdinaryTable(pTab) ) return 0;
@@ -149836,7 +151877,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
** pFrom->pIndex and return SQLITE_OK.
*/
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){
- Table *pTab = pFrom->pTab;
+ Table *pTab = pFrom->pSTab;
char *zIndexedBy = pFrom->u1.zIndexedBy;
Index *pIdx;
assert( pTab!=0 );
@@ -149913,7 +151954,11 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
if( pNew==0 ) return WRC_Abort;
memset(&dummy, 0, sizeof(dummy));
pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0);
- if( pNewSrc==0 ) return WRC_Abort;
+ assert( pNewSrc!=0 || pParse->nErr );
+ if( pParse->nErr ){
+ sqlite3SrcListDelete(db, pNewSrc);
+ return WRC_Abort;
+ }
*pNew = *p;
p->pSrc = pNewSrc;
p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0));
@@ -149968,7 +152013,7 @@ static struct Cte *searchWith(
){
const char *zName = pItem->zName;
With *p;
- assert( pItem->zDatabase==0 );
+ assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 );
assert( zName!=0 );
for(p=pWith; p; p=p->pOuter){
int i;
@@ -150038,7 +152083,7 @@ static int resolveFromTermToCte(
Cte *pCte; /* Matched CTE (or NULL if no match) */
With *pWith; /* The matching WITH */
- assert( pFrom->pTab==0 );
+ assert( pFrom->pSTab==0 );
if( pParse->pWith==0 ){
/* There are no WITH clauses in the stack. No match is possible */
return 0;
@@ -150048,7 +152093,8 @@ static int resolveFromTermToCte(
** go no further. */
return 0;
}
- if( pFrom->zDatabase!=0 ){
+ assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 );
+ if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){
/* The FROM term contains a schema qualifier (ex: main.t1) and so
** it cannot possibly be a CTE reference. */
return 0;
@@ -150084,7 +152130,7 @@ static int resolveFromTermToCte(
}
if( cannotBeFunction(pParse, pFrom) ) return 2;
- assert( pFrom->pTab==0 );
+ assert( pFrom->pSTab==0 );
pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return 2;
pCteUse = pCte->pUse;
@@ -150098,26 +152144,29 @@ static int resolveFromTermToCte(
}
pCteUse->eM10d = pCte->eM10d;
}
- pFrom->pTab = pTab;
+ pFrom->pSTab = pTab;
pTab->nTabRef = 1;
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
pTab->iPKey = -1;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
- pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
+ sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1);
if( db->mallocFailed ) return 2;
- pFrom->pSelect->selFlags |= SF_CopyCte;
- assert( pFrom->pSelect );
+ assert( pFrom->fg.isSubquery && pFrom->u4.pSubq );
+ pSel = pFrom->u4.pSubq->pSelect;
+ assert( pSel!=0 );
+ pSel->selFlags |= SF_CopyCte;
if( pFrom->fg.isIndexedBy ){
sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy);
return 2;
}
+ assert( !pFrom->fg.isIndexedBy );
pFrom->fg.isCte = 1;
pFrom->u2.pCteUse = pCteUse;
pCteUse->nUse++;
/* Check if this is a recursive CTE. */
- pRecTerm = pSel = pFrom->pSelect;
+ pRecTerm = pSel;
bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
while( bMayRecursive && pRecTerm->op==pSel->op ){
int i;
@@ -150125,11 +152174,13 @@ static int resolveFromTermToCte(
assert( pRecTerm->pPrior!=0 );
for(i=0; inSrc; i++){
SrcItem *pItem = &pSrc->a[i];
- if( pItem->zDatabase==0
- && pItem->zName!=0
+ if( pItem->zName!=0
+ && !pItem->fg.hadSchema
+ && ALWAYS( !pItem->fg.isSubquery )
+ && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0)
&& 0==sqlite3StrICmp(pItem->zName, pCte->zName)
){
- pItem->pTab = pTab;
+ pItem->pSTab = pTab;
pTab->nTabRef++;
pItem->fg.isRecursive = 1;
if( pRecTerm->selFlags & SF_Recursive ){
@@ -150231,11 +152282,14 @@ SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){
** SQLITE_NOMEM.
*/
SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
- Select *pSel = pFrom->pSelect;
+ Select *pSel;
Table *pTab;
+ assert( pFrom->fg.isSubquery );
+ assert( pFrom->u4.pSubq!=0 );
+ pSel = pFrom->u4.pSubq->pSelect;
assert( pSel );
- pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
+ pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table));
if( pTab==0 ) return SQLITE_NOMEM;
pTab->nTabRef = 1;
if( pFrom->zAlias ){
@@ -150246,12 +152300,14 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
while( pSel->pPrior ){ pSel = pSel->pPrior; }
sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
pTab->iPKey = -1;
+ pTab->eTabType = TABTYP_VIEW;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
/* The usual case - do not allow ROWID on a subquery */
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
#else
- pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */
+ /* Legacy compatibility mode */
+ pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid;
#endif
return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
}
@@ -150353,33 +152409,35 @@ static int selectExpander(Walker *pWalker, Select *p){
*/
for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){
Table *pTab;
- assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
- if( pFrom->pTab ) continue;
+ assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 );
+ if( pFrom->pSTab ) continue;
assert( pFrom->fg.isRecursive==0 );
if( pFrom->zName==0 ){
#ifndef SQLITE_OMIT_SUBQUERY
- Select *pSel = pFrom->pSelect;
+ Select *pSel;
+ assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 );
+ pSel = pFrom->u4.pSubq->pSelect;
/* A sub-query in the FROM clause of a SELECT */
assert( pSel!=0 );
- assert( pFrom->pTab==0 );
+ assert( pFrom->pSTab==0 );
if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort;
#endif
#ifndef SQLITE_OMIT_CTE
}else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){
if( rc>1 ) return WRC_Abort;
- pTab = pFrom->pTab;
+ pTab = pFrom->pSTab;
assert( pTab!=0 );
#endif
}else{
/* An ordinary table or view name in the FROM clause */
- assert( pFrom->pTab==0 );
- pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
+ assert( pFrom->pSTab==0 );
+ pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
if( pTab==0 ) return WRC_Abort;
if( pTab->nTabRef>=0xffff ){
sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
pTab->zName);
- pFrom->pTab = 0;
+ pFrom->pSTab = 0;
return WRC_Abort;
}
pTab->nTabRef++;
@@ -150391,7 +152449,7 @@ static int selectExpander(Walker *pWalker, Select *p){
i16 nCol;
u8 eCodeOrig = pWalker->eCode;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
- assert( pFrom->pSelect==0 );
+ assert( pFrom->fg.isSubquery==0 );
if( IsView(pTab) ){
if( (db->flags & SQLITE_EnableView)==0
&& pTab->pSchema!=db->aDb[1].pSchema
@@ -150399,7 +152457,7 @@ static int selectExpander(Walker *pWalker, Select *p){
sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
pTab->zName);
}
- pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0);
+ sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( ALWAYS(IsVirtual(pTab))
@@ -150415,7 +152473,9 @@ static int selectExpander(Walker *pWalker, Select *p){
nCol = pTab->nCol;
pTab->nCol = -1;
pWalker->eCode = 1; /* Turn on Select.selId renumbering */
- sqlite3WalkSelect(pWalker, pFrom->pSelect);
+ if( pFrom->fg.isSubquery ){
+ sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect);
+ }
pWalker->eCode = eCodeOrig;
pTab->nCol = nCol;
}
@@ -150502,7 +152562,7 @@ static int selectExpander(Walker *pWalker, Select *p){
}
for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){
int nAdd; /* Number of cols including rowid */
- Table *pTab = pFrom->pTab; /* Table for this data source */
+ Table *pTab = pFrom->pSTab; /* Table for this data source */
ExprList *pNestedFrom; /* Result-set of a nested FROM clause */
char *zTabName; /* AS name for this data source */
const char *zSchemaName = 0; /* Schema name for this data source */
@@ -150513,13 +152573,14 @@ static int selectExpander(Walker *pWalker, Select *p){
zTabName = pTab->zName;
}
if( db->mallocFailed ) break;
- assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) );
+ assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) );
if( pFrom->fg.isNestedFrom ){
- assert( pFrom->pSelect!=0 );
- pNestedFrom = pFrom->pSelect->pEList;
+ assert( pFrom->fg.isSubquery && pFrom->u4.pSubq );
+ assert( pFrom->u4.pSubq->pSelect!=0 );
+ pNestedFrom = pFrom->u4.pSubq->pSelect->pEList;
assert( pNestedFrom!=0 );
assert( pNestedFrom->nExpr==pTab->nCol );
- assert( VisibleRowid(pTab)==0 );
+ assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid );
}else{
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
continue;
@@ -150551,7 +152612,8 @@ static int selectExpander(Walker *pWalker, Select *p){
pUsing = 0;
}
- nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom));
+ nAdd = pTab->nCol;
+ if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++;
for(j=0; ja[pNew->nExpr-1];
assert( pX->zEName==0 );
if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
- if( pNestedFrom ){
+ if( pNestedFrom && (!ViewCanHaveRowid || jnExpr) ){
+ assert( jnExpr );
pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName);
testcase( pX->zEName==0 );
}else{
@@ -150750,18 +152813,15 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
if( p->selFlags & SF_HasTypeInfo ) return;
p->selFlags |= SF_HasTypeInfo;
pParse = pWalker->pParse;
- testcase( (p->selFlags & SF_Resolved)==0 );
- assert( (p->selFlags & SF_Resolved) || IN_RENAME_OBJECT );
+ assert( (p->selFlags & SF_Resolved) );
pTabList = p->pSrc;
for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){
- Table *pTab = pFrom->pTab;
+ Table *pTab = pFrom->pSTab;
assert( pTab!=0 );
- if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
+ if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){
/* A sub-query in the FROM clause of a SELECT */
- Select *pSel = pFrom->pSelect;
- if( pSel ){
- sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
- }
+ Select *pSel = pFrom->u4.pSubq->pSelect;
+ sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
}
}
}
@@ -150821,6 +152881,8 @@ SQLITE_PRIVATE void sqlite3SelectPrep(
*/
static void printAggInfo(AggInfo *pAggInfo){
int ii;
+ sqlite3DebugPrintf("AggInfo %d/%p:\n",
+ pAggInfo->selId, pAggInfo);
for(ii=0; iinColumn; ii++){
struct AggInfo_col *pCol = &pAggInfo->aCol[ii];
sqlite3DebugPrintf(
@@ -151073,6 +153135,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){
ExprList *pList;
assert( ExprUseXList(pF->pFExpr) );
+ if( pParse->nErr ) return;
pList = pF->pFExpr->x.pList;
if( pF->iOBTab>=0 ){
/* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs
@@ -151282,6 +153345,7 @@ static void updateAccumulator(
if( addrNext ){
sqlite3VdbeResolveLabel(v, addrNext);
}
+ if( pParse->nErr ) return;
}
if( regHit==0 && pAggInfo->nAccumulator ){
regHit = regAcc;
@@ -151291,6 +153355,7 @@ static void updateAccumulator(
}
for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){
sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i));
+ if( pParse->nErr ) return;
}
pAggInfo->directMode = 0;
@@ -151406,25 +153471,28 @@ static SrcItem *isSelfJoinView(
int iFirst, int iEnd /* Range of FROM-clause entries to search. */
){
SrcItem *pItem;
- assert( pThis->pSelect!=0 );
- if( pThis->pSelect->selFlags & SF_PushDown ) return 0;
+ Select *pSel;
+ assert( pThis->fg.isSubquery );
+ pSel = pThis->u4.pSubq->pSelect;
+ assert( pSel!=0 );
+ if( pSel->selFlags & SF_PushDown ) return 0;
while( iFirsta[iFirst++];
- if( pItem->pSelect==0 ) continue;
+ if( !pItem->fg.isSubquery ) continue;
if( pItem->fg.viaCoroutine ) continue;
if( pItem->zName==0 ) continue;
- assert( pItem->pTab!=0 );
- assert( pThis->pTab!=0 );
- if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
+ assert( pItem->pSTab!=0 );
+ assert( pThis->pSTab!=0 );
+ if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue;
if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
- pS1 = pItem->pSelect;
- if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
+ pS1 = pItem->u4.pSubq->pSelect;
+ if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){
/* The query flattener left two different CTE tables with identical
** names in the same FROM clause. */
continue;
}
- if( pItem->pSelect->selFlags & SF_PushDown ){
+ if( pS1->selFlags & SF_PushDown ){
/* The view was modified by some other optimization such as
** pushDownWhereTerms() */
continue;
@@ -151468,6 +153536,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
Expr *pExpr;
Expr *pCount;
sqlite3 *db;
+ SrcItem *pFrom;
if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
if( p->pWhere ) return 0;
@@ -151482,8 +153551,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */
- pSub = p->pSrc->a[0].pSelect;
- if( pSub==0 ) return 0; /* The FROM is a subquery */
+ pFrom = p->pSrc->a;
+ if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */
+ pSub = pFrom->u4.pSubq->pSelect;
if( pSub->pPrior==0 ) return 0; /* Must be a compound */
if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */
do{
@@ -151492,7 +153562,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
if( pSub->pLimit ) return 0; /* No LIMIT clause */
if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
assert( pSub->pHaving==0 ); /* Due to the previous */
- pSub = pSub->pPrior; /* Repeat over compound */
+ pSub = pSub->pPrior; /* Repeat over compound */
}while( pSub );
/* If we reach this point then it is OK to perform the transformation */
@@ -151500,8 +153570,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
db = pParse->db;
pCount = pExpr;
pExpr = 0;
- pSub = p->pSrc->a[0].pSelect;
- p->pSrc->a[0].pSelect = 0;
+ pSub = sqlite3SubqueryDetach(db, pFrom);
sqlite3SrcListDelete(db, p->pSrc);
p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc));
while( pSub ){
@@ -151546,12 +153615,12 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
for(i=0; inSrc; i++){
SrcItem *p1 = &pSrc->a[i];
if( p1==p0 ) continue;
- if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
+ if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
return 1;
}
- if( p1->pSelect
- && (p1->pSelect->selFlags & SF_NestedFrom)!=0
- && sameSrcAlias(p0, p1->pSelect->pSrc)
+ if( p1->fg.isSubquery
+ && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0
+ && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc)
){
return 1;
}
@@ -151616,13 +153685,13 @@ static int fromClauseTermCanBeCoroutine(
if( i==0 ) break;
i--;
pItem--;
- if( pItem->pSelect!=0 ) return 0; /* (1c-i) */
+ if( pItem->fg.isSubquery ) return 0; /* (1c-i) */
}
return 1;
}
/*
-** Generate code for the SELECT statement given in the p argument.
+** Generate byte-code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
** See comments in sqliteInt.h for further information.
@@ -151633,6 +153702,40 @@ static int fromClauseTermCanBeCoroutine(
**
** This routine does NOT free the Select structure passed in. The
** calling function needs to do that.
+**
+** This is a long function. The following is an outline of the processing
+** steps, with tags referencing various milestones:
+**
+** * Resolve names and similar preparation tag-select-0100
+** * Scan of the FROM clause tag-select-0200
+** + OUTER JOIN strength reduction tag-select-0220
+** + Sub-query ORDER BY removal tag-select-0230
+** + Query flattening tag-select-0240
+** * Separate subroutine for compound-SELECT tag-select-0300
+** * WHERE-clause constant propagation tag-select-0330
+** * Count()-of-VIEW optimization tag-select-0350
+** * Scan of the FROM clause again tag-select-0400
+** + Authorize unreferenced tables tag-select-0410
+** + Predicate push-down optimization tag-select-0420
+** + Omit unused subquery columns optimization tag-select-0440
+** + Generate code to implement subqueries tag-select-0480
+** - Co-routines tag-select-0482
+** - Reuse previously computed CTE tag-select-0484
+** - REuse previously computed VIEW tag-select-0486
+** - Materialize a VIEW or CTE tag-select-0488
+** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500
+** * Set up for ORDER BY tag-select-0600
+** * Create output table tag-select-0630
+** * Prepare registers for LIMIT tag-select-0650
+** * Setup for DISTINCT tag-select-0680
+** * Generate code for non-aggregate and non-GROUP BY tag-select-0700
+** * Generate code for aggregate and/or GROUP BY tag-select-0800
+** + GROUP BY queries tag-select-0810
+** + non-GROUP BY queries tag-select-0820
+** - Special case of count() w/o GROUP BY tag-select-0821
+** - General case of non-GROUP BY aggregates tag-select-0822
+** * Sort results, as needed tag-select-0900
+** * Internal self-checks tag-select-1000
*/
SQLITE_PRIVATE int sqlite3Select(
Parse *pParse, /* The parser context */
@@ -151676,6 +153779,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
#endif
+ /* tag-select-0100 */
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
@@ -151727,7 +153831,7 @@ SQLITE_PRIVATE int sqlite3Select(
if( sameSrcAlias(p0, p->pSrc) ){
sqlite3ErrorMsg(pParse,
"target object/alias may not appear in FROM clause: %s",
- p0->zAlias ? p0->zAlias : p0->pTab->zName
+ p0->zAlias ? p0->zAlias : p0->pSTab->zName
);
goto select_end;
}
@@ -151762,12 +153866,13 @@ SQLITE_PRIVATE int sqlite3Select(
/* Try to do various optimizations (flattening subqueries, and strength
** reduction of join operators) in the FROM clause up into the main query
+ ** tag-select-0200
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
for(i=0; !p->pPrior && inSrc; i++){
SrcItem *pItem = &pTabList->a[i];
- Select *pSub = pItem->pSelect;
- Table *pTab = pItem->pTab;
+ Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0;
+ Table *pTab = pItem->pSTab;
/* The expander should have already created transient Table objects
** even for FROM clause elements such as subqueries that do not correspond
@@ -151784,6 +153889,7 @@ SQLITE_PRIVATE int sqlite3Select(
** way that the i-th table cannot be the NULL row of a join, then
** perform the appropriate simplification. This is called
** "OUTER JOIN strength reduction" in the SQLite documentation.
+ ** tag-select-0220
*/
if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0
&& sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor,
@@ -151854,7 +153960,8 @@ SQLITE_PRIVATE int sqlite3Select(
if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
assert( pSub->pGroupBy==0 );
- /* If a FROM-clause subquery has an ORDER BY clause that is not
+ /* tag-select-0230:
+ ** If a FROM-clause subquery has an ORDER BY clause that is not
** really doing anything, then delete it now so that it does not
** interfere with query flattening. See the discussion at
** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a
@@ -151873,13 +153980,16 @@ SQLITE_PRIVATE int sqlite3Select(
** (a) The outer query has a different ORDER BY clause
** (b) The subquery is part of a join
** See forum post 062d576715d277c8
+ ** (6) The subquery is not a recursive CTE. ORDER BY has a different
+ ** meaning for recursive CTEs and this optimization does not
+ ** apply.
**
** Also retain the ORDER BY if the OmitOrderBy optimization is disabled.
*/
if( pSub->pOrderBy!=0
&& (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */
&& pSub->pLimit==0 /* Condition (1) */
- && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */
+ && (pSub->selFlags & (SF_OrderByReqd|SF_Recursive))==0 /* (2) and (6) */
&& (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */
&& OptimizationEnabled(db, SQLITE_OmitOrderBy)
){
@@ -151917,6 +154027,7 @@ SQLITE_PRIVATE int sqlite3Select(
continue;
}
+ /* tag-select-0240 */
if( flattenSubquery(pParse, p, i, isAgg) ){
if( pParse->nErr ) goto select_end;
/* This subquery can be absorbed into its parent. */
@@ -151932,7 +154043,7 @@ SQLITE_PRIVATE int sqlite3Select(
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/* Handle compound SELECT statements using the separate multiSelect()
- ** procedure.
+ ** procedure. tag-select-0300
*/
if( p->pPrior ){
rc = multiSelect(pParse, p, pDest);
@@ -151948,9 +154059,9 @@ SQLITE_PRIVATE int sqlite3Select(
#endif
/* Do the WHERE-clause constant propagation optimization if this is
- ** a join. No need to speed time on this operation for non-join queries
+ ** a join. No need to spend time on this operation for non-join queries
** as the equivalent optimization will be handled by query planner in
- ** sqlite3WhereBegin().
+ ** sqlite3WhereBegin(). tag-select-0330
*/
if( p->pWhere!=0
&& p->pWhere->op==TK_AND
@@ -151967,6 +154078,7 @@ SQLITE_PRIVATE int sqlite3Select(
TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n"));
}
+ /* tag-select-0350 */
if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
&& countOfViewOptimization(pParse, p)
){
@@ -151974,20 +154086,26 @@ SQLITE_PRIVATE int sqlite3Select(
pTabList = p->pSrc;
}
- /* For each term in the FROM clause, do two things:
- ** (1) Authorized unreferenced tables
- ** (2) Generate code for all sub-queries
+ /* Loop over all terms in the FROM clause and do two things for each term:
+ **
+ ** (1) Authorize unreferenced tables
+ ** (2) Generate code for all sub-queries
+ **
+ ** tag-select-0400
*/
for(i=0; inSrc; i++){
SrcItem *pItem = &pTabList->a[i];
SrcItem *pPrior;
SelectDest dest;
+ Subquery *pSubq;
Select *pSub;
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
const char *zSavedAuthContext;
#endif
- /* Issue SQLITE_READ authorizations with a fake column name for any
+ /* Authorized unreferenced tables. tag-select-0410
+ **
+ ** Issue SQLITE_READ authorizations with a fake column name for any
** tables that are referenced but from which no values are extracted.
** Examples of where these kinds of null SQLITE_READ authorizations
** would occur:
@@ -152004,17 +154122,28 @@ SQLITE_PRIVATE int sqlite3Select(
** string for the fake column name seems safer.
*/
if( pItem->colUsed==0 && pItem->zName!=0 ){
- sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
+ const char *zDb;
+ if( pItem->fg.fixedSchema ){
+ int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema);
+ zDb = db->aDb[iDb].zDbSName;
+ }else if( pItem->fg.isSubquery ){
+ zDb = 0;
+ }else{
+ zDb = pItem->u4.zDatabase;
+ }
+ sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb);
}
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/* Generate code for all sub-queries in the FROM clause
*/
- pSub = pItem->pSelect;
- if( pSub==0 ) continue;
+ if( pItem->fg.isSubquery==0 ) continue;
+ pSubq = pItem->u4.pSubq;
+ assert( pSubq!=0 );
+ pSub = pSubq->pSelect;
/* The code for a subquery should only be generated once. */
- assert( pItem->addrFillSub==0 );
+ if( pSubq->addrFillSub!=0 ) continue;
/* Increment Parse.nHeight by the height of the largest expression
** tree referred to by this, the parent select. The child select
@@ -152027,6 +154156,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Make copies of constant WHERE-clause terms in the outer query down
** inside the subquery. This can help the subquery to run more efficiently.
+ ** This is the "predicate push-down optimization". tag-select-0420
*/
if( OptimizationEnabled(db, SQLITE_PushDown)
&& (pItem->fg.isCte==0
@@ -152040,13 +154170,14 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3TreeViewSelect(0, p, 0);
}
#endif
- assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 );
+ assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 );
}else{
- TREETRACE(0x4000,pParse,p,("Push-down not possible\n"));
+ TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n"));
}
/* Convert unused result columns of the subquery into simple NULL
** expressions, to avoid unneeded searching and computation.
+ ** tag-select-0440
*/
if( OptimizationEnabled(db, SQLITE_NullUnusedCols)
&& disableUnusedSubqueryResultColumns(pItem)
@@ -152064,32 +154195,33 @@ SQLITE_PRIVATE int sqlite3Select(
zSavedAuthContext = pParse->zAuthContext;
pParse->zAuthContext = pItem->zName;
- /* Generate code to implement the subquery
+ /* Generate byte-code to implement the subquery tag-select-0480
*/
if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){
/* Implement a co-routine that will return a single row of the result
- ** set on each invocation.
+ ** set on each invocation. tag-select-0482
*/
int addrTop = sqlite3VdbeCurrentAddr(v)+1;
- pItem->regReturn = ++pParse->nMem;
- sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
+ pSubq->regReturn = ++pParse->nMem;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop);
VdbeComment((v, "%!S", pItem));
- pItem->addrFillSub = addrTop;
- sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
+ pSubq->addrFillSub = addrTop;
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn);
ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem));
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = pSub->nSelectRow;
+ pItem->pSTab->nRowLogEst = pSub->nSelectRow;
pItem->fg.viaCoroutine = 1;
- pItem->regResult = dest.iSdst;
- sqlite3VdbeEndCoroutine(v, pItem->regReturn);
+ pSubq->regResult = dest.iSdst;
+ sqlite3VdbeEndCoroutine(v, pSubq->regReturn);
+ VdbeComment((v, "end %!S", pItem));
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){
/* This is a CTE for which materialization code has already been
** generated. Invoke the subroutine to compute the materialization,
- ** the make the pItem->iCursor be a copy of the ephemeral table that
- ** holds the result of the materialization. */
+ ** then make the pItem->iCursor be a copy of the ephemeral table that
+ ** holds the result of the materialization. tag-select-0484 */
CteUse *pCteUse = pItem->u2.pCteUse;
sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e);
if( pItem->iCursor!=pCteUse->iCur ){
@@ -152099,25 +154231,30 @@ SQLITE_PRIVATE int sqlite3Select(
pSub->nSelectRow = pCteUse->nRowEst;
}else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){
/* This view has already been materialized by a prior entry in
- ** this same FROM clause. Reuse it. */
- if( pPrior->addrFillSub ){
- sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub);
+ ** this same FROM clause. Reuse it. tag-select-0486 */
+ Subquery *pPriorSubq;
+ assert( pPrior->fg.isSubquery );
+ pPriorSubq = pPrior->u4.pSubq;
+ assert( pPriorSubq!=0 );
+ if( pPriorSubq->addrFillSub ){
+ sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn,
+ pPriorSubq->addrFillSub);
}
sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor);
- pSub->nSelectRow = pPrior->pSelect->nSelectRow;
+ pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow;
}else{
/* Materialize the view. If the view is not correlated, generate a
** subroutine to do the materialization so that subsequent uses of
- ** the same view can reuse the materialization. */
+ ** the same view can reuse the materialization. tag-select-0488 */
int topAddr;
int onceAddr = 0;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
int addrExplain;
#endif
- pItem->regReturn = ++pParse->nMem;
+ pSubq->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
- pItem->addrFillSub = topAddr+1;
+ pSubq->addrFillSub = topAddr+1;
pItem->fg.isMaterialized = 1;
if( pItem->fg.isCorrelated==0 ){
/* If the subquery is not correlated and if we are not inside of
@@ -152132,17 +154269,17 @@ SQLITE_PRIVATE int sqlite3Select(
ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem));
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = pSub->nSelectRow;
+ pItem->pSTab->nRowLogEst = pSub->nSelectRow;
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
- sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1);
+ sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1);
VdbeComment((v, "end %!S", pItem));
sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
sqlite3VdbeJumpHere(v, topAddr);
sqlite3ClearTempRegCache(pParse);
if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
CteUse *pCteUse = pItem->u2.pCteUse;
- pCteUse->addrM9e = pItem->addrFillSub;
- pCteUse->regRtn = pItem->regReturn;
+ pCteUse->addrM9e = pSubq->addrFillSub;
+ pCteUse->regRtn = pSubq->regReturn;
pCteUse->iCur = pItem->iCursor;
pCteUse->nRowEst = pSub->nSelectRow;
}
@@ -152168,7 +154305,9 @@ SQLITE_PRIVATE int sqlite3Select(
}
#endif
- /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
+ /* tag-select-0500
+ **
+ ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and
** if the select-list is the same as the ORDER BY list, then this query
** can be rewritten as a GROUP BY. In other words, this:
**
@@ -152185,12 +154324,18 @@ SQLITE_PRIVATE int sqlite3Select(
*/
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
&& sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0
+ && OptimizationEnabled(db, SQLITE_GroupByOrder)
#ifndef SQLITE_OMIT_WINDOWFUNC
&& p->pWin==0
#endif
){
p->selFlags &= ~SF_Distinct;
pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0);
+ if( pGroupBy ){
+ for(i=0; inExpr; i++){
+ pGroupBy->a[i].u.x.iOrderByCol = i+1;
+ }
+ }
p->selFlags |= SF_Aggregate;
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
** the sDistinct.isTnct is still set. Hence, isTnct represents the
@@ -152212,7 +154357,7 @@ SQLITE_PRIVATE int sqlite3Select(
** If that is the case, then the OP_OpenEphemeral instruction will be
** changed to an OP_Noop once we figure out that the sorting index is
** not needed. The sSort.addrSortIndex variable is used to facilitate
- ** that change.
+ ** that change. tag-select-0600
*/
if( sSort.pOrderBy ){
KeyInfo *pKeyInfo;
@@ -152229,6 +154374,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
/* If the output is destined for a temporary table, open that table.
+ ** tag-select-0630
*/
if( pDest->eDest==SRT_EphemTab ){
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
@@ -152246,7 +154392,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
}
- /* Set the limiter.
+ /* Set the limiter. tag-select-0650
*/
iEnd = sqlite3VdbeMakeLabel(pParse);
if( (p->selFlags & SF_FixedLimit)==0 ){
@@ -152258,7 +154404,7 @@ SQLITE_PRIVATE int sqlite3Select(
sSort.sortFlags |= SORTFLAG_UseSorter;
}
- /* Open an ephemeral index to use for the distinct set.
+ /* Open an ephemeral index to use for the distinct set. tag-select-0680
*/
if( p->selFlags & SF_Distinct ){
sDistinct.tabTnct = pParse->nTab++;
@@ -152273,7 +154419,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
if( !isAgg && pGroupBy==0 ){
- /* No aggregate functions and no GROUP BY clause */
+ /* No aggregate functions and no GROUP BY clause. tag-select-0700 */
u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0)
| (p->selFlags & SF_FixedLimit);
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -152346,8 +154492,8 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3WhereEnd(pWInfo);
}
}else{
- /* This case when there exist aggregate functions or a GROUP BY clause
- ** or both */
+ /* This case is for when there exist aggregate functions or a GROUP BY
+ ** clause or both. tag-select-0800 */
NameContext sNC; /* Name context for processing aggregate information */
int iAMem; /* First Mem address for storing current GROUP BY */
int iBMem; /* First Mem address for previous GROUP BY */
@@ -152466,7 +154612,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Processing for aggregates with GROUP BY is very different and
- ** much more complex than aggregates without a GROUP BY.
+ ** much more complex than aggregates without a GROUP BY. tag-select-0810
*/
if( pGroupBy ){
KeyInfo *pKeyInfo; /* Keying information for the group by clause */
@@ -152653,12 +154799,25 @@ SQLITE_PRIVATE int sqlite3Select(
sortOut, sortPTab);
}
for(j=0; jnExpr; j++){
+ int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol;
+
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
}else{
pAggInfo->directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
+
+ if( iOrderByCol ){
+ Expr *pX = p->pEList->a[iOrderByCol-1].pExpr;
+ Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX);
+ if( ALWAYS(pBase!=0)
+ && pBase->op!=TK_AGG_COLUMN
+ && pBase->op!=TK_REGISTER
+ ){
+ sqlite3ExprToRegister(pX, iAMem+j);
+ }
+ }
}
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
@@ -152674,9 +154833,9 @@ SQLITE_PRIVATE int sqlite3Select(
** and resets the aggregate accumulator registers in preparation
** for the next GROUP BY batch.
*/
- sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output one row"));
+ sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v);
VdbeComment((v, "check abort flag"));
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
@@ -152750,9 +154909,12 @@ SQLITE_PRIVATE int sqlite3Select(
}
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
+ /* Aggregate functions without GROUP BY. tag-select-0820 */
Table *pTab;
if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){
- /* If isSimpleCount() returns a pointer to a Table structure, then
+ /* tag-select-0821
+ **
+ ** If isSimpleCount() returns a pointer to a Table structure, then
** the SQL statement is of the form:
**
** SELECT count(*) FROM
@@ -152812,6 +154974,8 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
explainSimpleCount(pParse, pTab, pBest);
}else{
+ /* The general case of an aggregate query without GROUP BY
+ ** tag-select-0822 */
int regAcc = 0; /* "populate accumulators" flag */
ExprList *pDistinct = 0;
u16 distFlag = 0;
@@ -152900,7 +155064,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
/* If there is an ORDER BY clause, then we need to sort the results
- ** and send them to the callback one by one.
+ ** and send them to the callback one by one. tag-select-0900
*/
if( sSort.pOrderBy ){
assert( p->pEList==pEList );
@@ -152923,7 +155087,14 @@ SQLITE_PRIVATE int sqlite3Select(
assert( db->mallocFailed==0 || pParse->nErr!=0 );
sqlite3ExprListDelete(db, pMinMaxOrderBy);
#ifdef SQLITE_DEBUG
+ /* Internal self-checks. tag-select-1000 */
if( pAggInfo && !db->mallocFailed ){
+#if TREETRACE_ENABLED
+ if( sqlite3TreeTrace & 0x20 ){
+ TREETRACE(0x20,pParse,p,("Finished with AggInfo\n"));
+ printAggInfo(pAggInfo);
+ }
+#endif
for(i=0; inColumn; i++){
Expr *pExpr = pAggInfo->aCol[i].pCExpr;
if( pExpr==0 ) continue;
@@ -153306,8 +155477,10 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
** name on pTableName if we are reparsing out of the schema table
*/
if( db->init.busy && iDb!=1 ){
- sqlite3DbFree(db, pTableName->a[0].zDatabase);
- pTableName->a[0].zDatabase = 0;
+ assert( pTableName->a[0].fg.fixedSchema==0 );
+ assert( pTableName->a[0].fg.isSubquery==0 );
+ sqlite3DbFree(db, pTableName->a[0].u4.zDatabase);
+ pTableName->a[0].u4.zDatabase = 0;
}
/* If the trigger name was unqualified, and the table is a temp table,
@@ -153785,7 +155958,8 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr)
}
assert( pName->nSrc==1 );
- zDb = pName->a[0].zDatabase;
+ assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 );
+ zDb = pName->a[0].u4.zDatabase;
zName = pName->a[0].zName;
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; inDb; i++){
@@ -154022,7 +156196,9 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(
Schema *pSchema = pStep->pTrig->pSchema;
pSrc->a[0].zName = zName;
if( pSchema!=db->aDb[1].pSchema ){
- pSrc->a[0].pSchema = pSchema;
+ assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 );
+ pSrc->a[0].u4.pSchema = pSchema;
+ pSrc->a[0].fg.fixedSchema = 1;
}
if( pStep->pFrom ){
SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
@@ -154105,6 +156281,72 @@ static ExprList *sqlite3ExpandReturning(
return pNew;
}
+/* If the Expr node is a subquery or an EXISTS operator or an IN operator that
+** uses a subquery, and if the subquery is SF_Correlated, then mark the
+** expression as EP_VarSelect.
+*/
+static int sqlite3ReturningSubqueryVarSelect(Walker *NotUsed, Expr *pExpr){
+ UNUSED_PARAMETER(NotUsed);
+ if( ExprUseXSelect(pExpr)
+ && (pExpr->x.pSelect->selFlags & SF_Correlated)!=0
+ ){
+ testcase( ExprHasProperty(pExpr, EP_VarSelect) );
+ ExprSetProperty(pExpr, EP_VarSelect);
+ }
+ return WRC_Continue;
+}
+
+
+/*
+** If the SELECT references the table pWalker->u.pTab, then do two things:
+**
+** (1) Mark the SELECT as as SF_Correlated.
+** (2) Set pWalker->eCode to non-zero so that the caller will know
+** that (1) has happened.
+*/
+static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){
+ int i;
+ SrcList *pSrc;
+ assert( pSelect!=0 );
+ pSrc = pSelect->pSrc;
+ assert( pSrc!=0 );
+ for(i=0; inSrc; i++){
+ if( pSrc->a[i].pSTab==pWalker->u.pTab ){
+ testcase( pSelect->selFlags & SF_Correlated );
+ pSelect->selFlags |= SF_Correlated;
+ pWalker->eCode = 1;
+ break;
+ }
+ }
+ return WRC_Continue;
+}
+
+/*
+** Scan the expression list that is the argument to RETURNING looking
+** for subqueries that depend on the table which is being modified in the
+** statement that is hosting the RETURNING clause (pTab). Mark all such
+** subqueries as SF_Correlated. If the subqueries are part of an
+** expression, mark the expression as EP_VarSelect.
+**
+** https://sqlite.org/forum/forumpost/2c83569ce8945d39
+*/
+static void sqlite3ProcessReturningSubqueries(
+ ExprList *pEList,
+ Table *pTab
+){
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.xExprCallback = sqlite3ExprWalkNoop;
+ w.xSelectCallback = sqlite3ReturningSubqueryCorrelated;
+ w.u.pTab = pTab;
+ sqlite3WalkExprList(&w, pEList);
+ if( w.eCode ){
+ w.xExprCallback = sqlite3ReturningSubqueryVarSelect;
+ w.xSelectCallback = sqlite3SelectWalkNoop;
+ sqlite3WalkExprList(&w, pEList);
+ }
+}
+
/*
** Generate code for the RETURNING trigger. Unlike other triggers
** that invoke a subprogram in the bytecode, the code for RETURNING
@@ -154140,7 +156382,8 @@ static void codeReturningTrigger(
sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
sSelect.pSrc = &sFrom;
sFrom.nSrc = 1;
- sFrom.a[0].pTab = pTab;
+ sFrom.a[0].pSTab = pTab;
+ sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */
sFrom.a[0].iCursor = -1;
sqlite3SelectPrep(pParse, &sSelect, 0);
if( pParse->nErr==0 ){
@@ -154167,6 +156410,7 @@ static void codeReturningTrigger(
int i;
int nCol = pNew->nExpr;
int reg = pParse->nMem+1;
+ sqlite3ProcessReturningSubqueries(pNew, pTab);
pParse->nMem += nCol+2;
pReturning->iRetReg = reg;
for(i=0; idb;
- Table *pTab = pTabList->a[0].pTab;
+ Table *pTab = pTabList->a[0].pSTab;
SrcList *pSrc;
Expr *pWhere2;
int eDest;
@@ -154873,8 +157117,8 @@ static void updateFromSelect(
if( pSrc ){
assert( pSrc->a[0].fg.notCte );
pSrc->a[0].iCursor = -1;
- pSrc->a[0].pTab->nTabRef--;
- pSrc->a[0].pTab = 0;
+ pSrc->a[0].pSTab->nTabRef--;
+ pSrc->a[0].pSTab = 0;
}
if( pPk ){
for(i=0; inKeyCol; i++){
@@ -155568,6 +157812,9 @@ SQLITE_PRIVATE void sqlite3Update(
}
}
if( chngRowid==0 && pPk==0 ){
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid);
+#endif
sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
}
}
@@ -156105,7 +158352,8 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertNew(
SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
Parse *pParse, /* The parsing context */
SrcList *pTabList, /* Table into which we are inserting */
- Upsert *pUpsert /* The ON CONFLICT clauses */
+ Upsert *pUpsert, /* The ON CONFLICT clauses */
+ Upsert *pAll /* Complete list of all ON CONFLICT clauses */
){
Table *pTab; /* That table into which we are inserting */
int rc; /* Result code */
@@ -156118,7 +158366,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
int nClause = 0; /* Counter of ON CONFLICT clauses */
assert( pTabList->nSrc==1 );
- assert( pTabList->a[0].pTab!=0 );
+ assert( pTabList->a[0].pSTab!=0 );
assert( pUpsert!=0 );
assert( pUpsert->pUpsertTarget!=0 );
@@ -156137,7 +158385,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
if( rc ) return rc;
/* Check to see if the conflict target matches the rowid. */
- pTab = pTabList->a[0].pTab;
+ pTab = pTabList->a[0].pSTab;
pTarget = pUpsert->pUpsertTarget;
iCursor = pTabList->a[0].iCursor;
if( HasRowid(pTab)
@@ -156208,6 +158456,14 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(
continue;
}
pUpsert->pUpsertIdx = pIdx;
+ if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){
+ /* Really this should be an error. The isDup ON CONFLICT clause will
+ ** never fire. But this problem was not discovered until three years
+ ** after multi-CONFLICT upsert was added, and so we silently ignore
+ ** the problem to prevent breaking applications that might actually
+ ** have redundant ON CONFLICT clauses. */
+ pUpsert->isDup = 1;
+ }
break;
}
if( pUpsert->pUpsertIdx==0 ){
@@ -156234,9 +158490,13 @@ SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){
Upsert *pNext;
if( NEVER(pUpsert==0) ) return 0;
pNext = pUpsert->pNextUpsert;
- if( pNext==0 ) return 1;
- if( pNext->pUpsertTarget==0 ) return 1;
- if( pNext->pUpsertIdx==0 ) return 1;
+ while( 1 /*exit-by-return*/ ){
+ if( pNext==0 ) return 1;
+ if( pNext->pUpsertTarget==0 ) return 1;
+ if( pNext->pUpsertIdx==0 ) return 1;
+ if( !pNext->isDup ) return 0;
+ pNext = pNext->pNextUpsert;
+ }
return 0;
}
@@ -156500,6 +158760,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
const char *zDbMain; /* Schema name of database to vacuum */
const char *zOut; /* Name of output file */
u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */
+ u64 iRandom; /* Random value used for zDbVacuum[] */
+ char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */
+
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
@@ -156540,27 +158803,29 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
pMain = db->aDb[iDb].pBt;
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
- /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
+ /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma
** can be set to 'off' for this file, as it is not recovered if a crash
** occurs anyway. The integrity of the database is maintained by a
** (possibly synchronous) transaction opened on the main database before
** sqlite3BtreeCopyFile() is called.
**
** An optimization would be to use a non-journaled pager.
- ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
+ ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but
** that actually made the VACUUM run slower. Very little journalling
** actually occurs when doing a vacuum since the vacuum_db is initially
** empty. Only the journal header is written. Apparently it takes more
** time to parse and run the PRAGMA to turn journalling off than it does
** to write the journal header file.
*/
+ sqlite3_randomness(sizeof(iRandom),&iRandom);
+ sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom);
nDb = db->nDb;
- rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
+ rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum);
db->openFlags = saved_openFlags;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
assert( (db->nDb-1)==nDb );
pDb = &db->aDb[nDb];
- assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
+ assert( strcmp(pDb->zDbSName,zDbVacuum)==0 );
pTemp = pDb->pBt;
if( pOut ){
sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
@@ -156658,11 +158923,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
** the contents to the temporary database.
*/
rc = execSqlF(db, pzErrMsg,
- "SELECT'INSERT INTO vacuum_db.'||quote(name)"
+ "SELECT'INSERT INTO %s.'||quote(name)"
"||' SELECT*FROM\"%w\".'||quote(name)"
- "FROM vacuum_db.sqlite_schema "
+ "FROM %s.sqlite_schema "
"WHERE type='table'AND coalesce(rootpage,1)>0",
- zDbMain
+ zDbVacuum, zDbMain, zDbVacuum
);
#endif
assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
@@ -156675,11 +158940,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
** from the schema table.
*/
rc = execSqlF(db, pzErrMsg,
- "INSERT INTO vacuum_db.sqlite_schema"
+ "INSERT INTO %s.sqlite_schema"
" SELECT*FROM \"%w\".sqlite_schema"
" WHERE type IN('view','trigger')"
" OR(type='table'AND rootpage=0)",
- zDbMain
+ zDbVacuum, zDbMain
);
if( rc ) goto end_of_vacuum;
@@ -157387,6 +159652,8 @@ static int vtabCallConstructor(
db->pVtabCtx = &sCtx;
pTab->nTabRef++;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
+ assert( pTab!=0 );
+ assert( pTab->nTabRef>1 || rc!=SQLITE_OK );
sqlite3DeleteTable(db, pTab);
db->pVtabCtx = sCtx.pPrior;
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
@@ -157409,7 +159676,7 @@ static int vtabCallConstructor(
pVTable->nRef = 1;
if( sCtx.bDeclared==0 ){
const char *zFormat = "vtable constructor did not declare schema: %s";
- *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
+ *pzErr = sqlite3MPrintf(db, zFormat, zModuleName);
sqlite3VtabUnlock(pVTable);
rc = SQLITE_ERROR;
}else{
@@ -157587,12 +159854,30 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
Table *pTab;
Parse sParse;
int initBusy;
+ int i;
+ const unsigned char *z;
+ static const u8 aKeyword[] = { TK_CREATE, TK_TABLE, 0 };
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
+
+ /* Verify that the first two keywords in the CREATE TABLE statement
+ ** really are "CREATE" and "TABLE". If this is not the case, then
+ ** sqlite3_declare_vtab() is being misused.
+ */
+ z = (const unsigned char*)zCreateTable;
+ for(i=0; aKeyword[i]; i++){
+ int tokenType = 0;
+ do{ z += sqlite3GetToken(z, &tokenType); }while( tokenType==TK_SPACE );
+ if( tokenType!=aKeyword[i] ){
+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, "syntax error");
+ return SQLITE_ERROR;
+ }
+ }
+
sqlite3_mutex_enter(db->mutex);
pCtx = db->pVtabCtx;
if( !pCtx || pCtx->bDeclared ){
@@ -157600,6 +159885,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE_BKPT;
}
+
pTab = pCtx->pTab;
assert( IsVirtual(pTab) );
@@ -157613,16 +159899,16 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
initBusy = db->init.busy;
db->init.busy = 0;
sParse.nQueryLoop = 1;
- if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable)
- && ALWAYS(sParse.pNewTable!=0)
- && ALWAYS(!db->mallocFailed)
- && IsOrdinaryTable(sParse.pNewTable)
- ){
+ if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) ){
+ assert( sParse.pNewTable!=0 );
+ assert( !db->mallocFailed );
+ assert( IsOrdinaryTable(sParse.pNewTable) );
assert( sParse.zErrMsg==0 );
if( !pTab->aCol ){
Table *pNew = sParse.pNewTable;
Index *pIdx;
pTab->aCol = pNew->aCol;
+ assert( IsOrdinaryTable(pNew) );
sqlite3ExprListDelete(db, pNew->u.tab.pDfltList);
pTab->nNVCol = pTab->nCol = pNew->nCol;
pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
@@ -158297,11 +160583,13 @@ struct WhereLoop {
u16 nTop; /* Size of TOP vector */
u16 nDistinctCol; /* Index columns used to sort for DISTINCT */
Index *pIndex; /* Index used, or NULL */
+ ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */
} btree;
struct { /* Information for virtual tables */
int idxNum; /* Index number */
u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
u32 bOmitOffset : 1; /* True to let virtual table handle offset */
+ u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */
i8 isOrdered; /* True if satisfies ORDER BY */
u16 omitMask; /* Terms that may be omitted */
char *idxStr; /* Index identifier string */
@@ -158314,6 +160602,8 @@ struct WhereLoop {
/**** whereLoopXfer() copies fields above ***********************/
# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
u16 nLSlot; /* Number of slots allocated for aLTerm[] */
+ LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not
+ ** initialized unless pWInfo->nOutStarDelta>0 */
WhereTerm **aLTerm; /* WhereTerms used */
WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */
@@ -158636,6 +160926,7 @@ struct WhereInfo {
unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */
unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */
unsigned sorted :1; /* True if really sorted (not just grouped) */
+ LogEst nOutStarDelta; /* Artifical nOut reduction for star-query */
LogEst nRowOut; /* Estimated number of output rows */
int iTop; /* The very beginning of the WHERE loop */
int iEndWhere; /* End of the WHERE clause itself */
@@ -158787,7 +161078,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */
- /* 0x02000000 -- available for reuse */
+#define WHERE_COROUTINE 0x02000000 /* Implemented by co-routine.
+ ** NB: False-negatives are possible */
#define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */
#endif /* !defined(SQLITE_WHEREINT_H) */
@@ -158932,7 +161224,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
assert( pLoop->u.btree.pIndex!=0 );
pIdx = pLoop->u.btree.pIndex;
assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
- if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
+ if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){
if( isSearch ){
zFmt = "PRIMARY KEY";
}
@@ -158975,7 +161267,9 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
- sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
+ sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX ");
+ sqlite3_str_appendf(&str,
+ pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s",
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
}
#endif
@@ -158993,7 +161287,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
zMsg = sqlite3StrAccumFinish(&str);
sqlite3ExplainBreakpoint("",zMsg);
ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
- pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
+ pParse->addrExplain, pLoop->rRun,
+ zMsg, P4_DYNAMIC);
}
return ret;
}
@@ -159028,7 +161323,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter(
sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem);
pLoop = pLevel->pWLoop;
if( pLoop->wsFlags & WHERE_IPK ){
- const Table *pTab = pItem->pTab;
+ const Table *pTab = pItem->pSTab;
if( pTab->iPKey>=0 ){
sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName);
}else{
@@ -159091,7 +161386,9 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur);
}
}else{
- int addr = pSrclist->a[pLvl->iFrom].addrFillSub;
+ int addr;
+ assert( pSrclist->a[pLvl->iFrom].fg.isSubquery );
+ addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub;
VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1);
assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine );
assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr );
@@ -159235,6 +161532,39 @@ static void updateRangeAffinityStr(
}
}
+/*
+** The pOrderBy->a[].u.x.iOrderByCol values might be incorrect because
+** columns might have been rearranged in the result set. This routine
+** fixes them up.
+**
+** pEList is the new result set. The pEList->a[].u.x.iOrderByCol values
+** contain the *old* locations of each expression. This is a temporary
+** use of u.x.iOrderByCol, not its intended use. The caller must reset
+** u.x.iOrderByCol back to zero for all entries in pEList before the
+** caller returns.
+**
+** This routine changes pOrderBy->a[].u.x.iOrderByCol values from
+** pEList->a[N].u.x.iOrderByCol into N+1. (The "+1" is because of the 1-based
+** indexing used by iOrderByCol.) Or if no match, iOrderByCol is set to zero.
+*/
+static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){
+ int i, j;
+ if( pOrderBy==0 ) return;
+ for(i=0; inExpr; i++){
+ int t = pOrderBy->a[i].u.x.iOrderByCol;
+ if( t==0 ) continue;
+ for(j=0; jnExpr; j++){
+ if( pEList->a[j].u.x.iOrderByCol==t ){
+ pOrderBy->a[i].u.x.iOrderByCol = j+1;
+ break;
+ }
+ }
+ if( j>=pEList->nExpr ){
+ pOrderBy->a[i].u.x.iOrderByCol = 0;
+ }
+ }
+}
+
/*
** pX is an expression of the form: (vector) IN (SELECT ...)
@@ -159298,6 +161628,7 @@ static Expr *removeUnindexableInClauseTerms(
if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
pOrigRhs->a[iField].pExpr = 0;
+ if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1;
if( pOrigLhs ){
assert( pOrigLhs->a[iField].pExpr!=0 );
pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr);
@@ -159311,6 +161642,7 @@ static Expr *removeUnindexableInClauseTerms(
pNew->pLeft->x.pList = pLhs;
}
pSelect->pEList = pRhs;
+ pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */
if( pLhs && pLhs->nExpr==1 ){
/* Take care here not to generate a TK_VECTOR containing only a
** single value. Since the parser never creates such a vector, some
@@ -159320,18 +161652,16 @@ static Expr *removeUnindexableInClauseTerms(
sqlite3ExprDelete(db, pNew->pLeft);
pNew->pLeft = p;
}
- if( pSelect->pOrderBy ){
- /* If the SELECT statement has an ORDER BY clause, zero the
- ** iOrderByCol variables. These are set to non-zero when an
- ** ORDER BY term exactly matches one of the terms of the
- ** result-set. Since the result-set of the SELECT statement may
- ** have been modified or reordered, these variables are no longer
- ** set correctly. Since setting them is just an optimization,
- ** it's easiest just to zero them here. */
- ExprList *pOrderBy = pSelect->pOrderBy;
- for(i=0; inExpr; i++){
- pOrderBy->a[i].u.x.iOrderByCol = 0;
- }
+
+ /* If either the ORDER BY clause or the GROUP BY clause contains
+ ** references to result-set columns, those references might now be
+ ** obsolete. So fix them up.
+ */
+ assert( pRhs!=0 || db->mallocFailed );
+ if( pRhs ){
+ adjustOrderByCol(pSelect->pOrderBy, pRhs);
+ adjustOrderByCol(pSelect->pGroupBy, pRhs);
+ for(i=0; inExpr; i++) pRhs->a[i].u.x.iOrderByCol = 0;
}
#if 0
@@ -159346,6 +161676,147 @@ static Expr *removeUnindexableInClauseTerms(
}
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
+** Generate code for a single X IN (....) term of the WHERE clause.
+**
+** This is a special-case of codeEqualityTerm() that works for IN operators
+** only. It is broken out into a subroutine because this case is
+** uncommon and by splitting it off into a subroutine, the common case
+** runs faster.
+**
+** The current value for the constraint is left in register iTarget.
+** This routine sets up a loop that will iterate over all values of X.
+*/
+static SQLITE_NOINLINE void codeINTerm(
+ Parse *pParse, /* The parsing context */
+ WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
+ WhereLevel *pLevel, /* The level of the FROM clause we are working on */
+ int iEq, /* Index of the equality term within this level */
+ int bRev, /* True for reverse-order IN operations */
+ int iTarget /* Attempt to leave results in this register */
+){
+ Expr *pX = pTerm->pExpr;
+ int eType = IN_INDEX_NOOP;
+ int iTab;
+ struct InLoop *pIn;
+ WhereLoop *pLoop = pLevel->pWLoop;
+ Vdbe *v = pParse->pVdbe;
+ int i;
+ int nEq = 0;
+ int *aiMap = 0;
+
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
+ && pLoop->u.btree.pIndex!=0
+ && pLoop->u.btree.pIndex->aSortOrder[iEq]
+ ){
+ testcase( iEq==0 );
+ testcase( bRev );
+ bRev = !bRev;
+ }
+ assert( pX->op==TK_IN );
+
+ for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
+ disableTerm(pLevel, pTerm);
+ return;
+ }
+ }
+ for(i=iEq;inLTerm; i++){
+ assert( pLoop->aLTerm[i]!=0 );
+ if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
+ }
+
+ iTab = 0;
+ if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
+ }else{
+ Expr *pExpr = pTerm->pExpr;
+ if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){
+ sqlite3 *db = pParse->db;
+ pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
+ if( !db->mallocFailed ){
+ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab);
+ pExpr->iTable = iTab;
+ }
+ sqlite3ExprDelete(db, pX);
+ }else{
+ int n = sqlite3ExprVectorSize(pX->pLeft);
+ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n));
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
+ }
+ pX = pExpr;
+ }
+
+ if( eType==IN_INDEX_INDEX_DESC ){
+ testcase( bRev );
+ bRev = !bRev;
+ }
+ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
+ VdbeCoverageIf(v, bRev);
+ VdbeCoverageIf(v, !bRev);
+
+ assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
+ pLoop->wsFlags |= WHERE_IN_ABLE;
+ if( pLevel->u.in.nIn==0 ){
+ pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
+ }
+ if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
+ pLoop->wsFlags |= WHERE_IN_EARLYOUT;
+ }
+
+ i = pLevel->u.in.nIn;
+ pLevel->u.in.nIn += nEq;
+ pLevel->u.in.aInLoop =
+ sqlite3WhereRealloc(pTerm->pWC->pWInfo,
+ pLevel->u.in.aInLoop,
+ sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
+ pIn = pLevel->u.in.aInLoop;
+ if( pIn ){
+ int iMap = 0; /* Index in aiMap[] */
+ pIn += i;
+ for(i=iEq;inLTerm; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
+ int iOut = iTarget + i - iEq;
+ if( eType==IN_INDEX_ROWID ){
+ pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
+ }else{
+ int iCol = aiMap ? aiMap[iMap++] : 0;
+ pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
+ }
+ sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
+ if( i==iEq ){
+ pIn->iCur = iTab;
+ pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
+ if( iEq>0 ){
+ pIn->iBase = iTarget - i;
+ pIn->nPrefix = i;
+ }else{
+ pIn->nPrefix = 0;
+ }
+ }else{
+ pIn->eEndLoopOp = OP_Noop;
+ }
+ pIn++;
+ }
+ }
+ testcase( iEq>0
+ && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
+ && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 );
+ if( iEq>0
+ && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0
+ ){
+ sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq);
+ }
+ }else{
+ pLevel->u.in.nIn = 0;
+ }
+ sqlite3DbFree(pParse->db, aiMap);
+}
+#endif
+
+
/*
** Generate code for a single equality term of the WHERE clause. An equality
** term can be either X=expr or X IN (...). pTerm is the term to be
@@ -159370,7 +161841,6 @@ static int codeEqualityTerm(
int iTarget /* Attempt to leave results in this register */
){
Expr *pX = pTerm->pExpr;
- Vdbe *v = pParse->pVdbe;
int iReg; /* Register holding results */
assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
@@ -159379,125 +161849,12 @@ static int codeEqualityTerm(
iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
}else if( pX->op==TK_ISNULL ){
iReg = iTarget;
- sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_Null, 0, iReg);
#ifndef SQLITE_OMIT_SUBQUERY
}else{
- int eType = IN_INDEX_NOOP;
- int iTab;
- struct InLoop *pIn;
- WhereLoop *pLoop = pLevel->pWLoop;
- int i;
- int nEq = 0;
- int *aiMap = 0;
-
- if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
- && pLoop->u.btree.pIndex!=0
- && pLoop->u.btree.pIndex->aSortOrder[iEq]
- ){
- testcase( iEq==0 );
- testcase( bRev );
- bRev = !bRev;
- }
assert( pX->op==TK_IN );
iReg = iTarget;
-
- for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
- disableTerm(pLevel, pTerm);
- return iTarget;
- }
- }
- for(i=iEq;inLTerm; i++){
- assert( pLoop->aLTerm[i]!=0 );
- if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
- }
-
- iTab = 0;
- if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){
- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
- }else{
- Expr *pExpr = pTerm->pExpr;
- if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){
- sqlite3 *db = pParse->db;
- pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
- if( !db->mallocFailed ){
- aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab);
- pExpr->iTable = iTab;
- }
- sqlite3ExprDelete(db, pX);
- }else{
- int n = sqlite3ExprVectorSize(pX->pLeft);
- aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n));
- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
- }
- pX = pExpr;
- }
-
- if( eType==IN_INDEX_INDEX_DESC ){
- testcase( bRev );
- bRev = !bRev;
- }
- sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
- VdbeCoverageIf(v, bRev);
- VdbeCoverageIf(v, !bRev);
-
- assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
- pLoop->wsFlags |= WHERE_IN_ABLE;
- if( pLevel->u.in.nIn==0 ){
- pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
- }
- if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
- pLoop->wsFlags |= WHERE_IN_EARLYOUT;
- }
-
- i = pLevel->u.in.nIn;
- pLevel->u.in.nIn += nEq;
- pLevel->u.in.aInLoop =
- sqlite3WhereRealloc(pTerm->pWC->pWInfo,
- pLevel->u.in.aInLoop,
- sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
- pIn = pLevel->u.in.aInLoop;
- if( pIn ){
- int iMap = 0; /* Index in aiMap[] */
- pIn += i;
- for(i=iEq;inLTerm; i++){
- if( pLoop->aLTerm[i]->pExpr==pX ){
- int iOut = iReg + i - iEq;
- if( eType==IN_INDEX_ROWID ){
- pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
- }else{
- int iCol = aiMap ? aiMap[iMap++] : 0;
- pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
- }
- sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
- if( i==iEq ){
- pIn->iCur = iTab;
- pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
- if( iEq>0 ){
- pIn->iBase = iReg - i;
- pIn->nPrefix = i;
- }else{
- pIn->nPrefix = 0;
- }
- }else{
- pIn->eEndLoopOp = OP_Noop;
- }
- pIn++;
- }
- }
- testcase( iEq>0
- && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0
- && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 );
- if( iEq>0
- && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0
- ){
- sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq);
- }
- }else{
- pLevel->u.in.nIn = 0;
- }
- sqlite3DbFree(pParse->db, aiMap);
+ codeINTerm(pParse, pTerm, pLevel, iEq, bRev, iTarget);
#endif
}
@@ -160112,6 +162469,27 @@ static SQLITE_NOINLINE void filterPullDown(
}
}
+/*
+** Loop pLoop is a WHERE_INDEXED level that uses at least one IN(...)
+** operator. Return true if level pLoop is guaranteed to visit only one
+** row for each key generated for the index.
+*/
+static int whereLoopIsOneRow(WhereLoop *pLoop){
+ if( pLoop->u.btree.pIndex->onError
+ && pLoop->nSkip==0
+ && pLoop->u.btree.nEq==pLoop->u.btree.pIndex->nKeyCol
+ ){
+ int ii;
+ for(ii=0; iiu.btree.nEq; ii++){
+ if( pLoop->aLTerm[ii]->eOperator & (WO_IS|WO_ISNULL) ){
+ return 0;
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
@@ -160148,7 +162526,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
iCur = pTabItem->iCursor;
pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
bRev = (pWInfo->revMask>>iLevel)&1;
- VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
+ VdbeModuleComment((v, "Begin WHERE-loop%d: %s",
+ iLevel, pTabItem->pSTab->zName));
#if WHERETRACE_ENABLED /* 0x4001 */
if( sqlite3WhereTrace & 0x1 ){
sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n",
@@ -160190,7 +162569,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
pLevel->iLeftJoin = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
- VdbeComment((v, "init LEFT JOIN no-match flag"));
+ VdbeComment((v, "init LEFT JOIN match flag"));
}
/* Compute a safe address to jump to if we discover that the table for
@@ -160203,11 +162582,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
/* Special case of a FROM clause subquery implemented as a co-routine */
if( pTabItem->fg.viaCoroutine ){
- int regYield = pTabItem->regReturn;
- sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
+ int regYield;
+ Subquery *pSubq;
+ assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 );
+ pSubq = pTabItem->u4.pSubq;
+ regYield = pSubq->regReturn;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub);
pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
VdbeCoverage(v);
- VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
+ VdbeComment((v, "next row of %s", pTabItem->pSTab->zName));
pLevel->op = OP_Goto;
}else
@@ -160861,7 +163244,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
/* Record the instruction used to terminate the loop. */
- if( pLoop->wsFlags & WHERE_ONEROW ){
+ if( (pLoop->wsFlags & WHERE_ONEROW)
+ || (pLevel->u.in.nIn && regBignull==0 && whereLoopIsOneRow(pLoop))
+ ){
pLevel->op = OP_Noop;
}else if( bRev ){
pLevel->op = OP_Prev;
@@ -160936,7 +163321,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int untestedTerms = 0; /* Some terms not completely tested */
int ii; /* Loop counter */
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
- Table *pTab = pTabItem->pTab;
+ Table *pTab = pTabItem->pSTab;
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
@@ -161251,6 +163636,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** iLoop==3: Code all remaining expressions.
**
** An effort is made to skip unnecessary iterations of the loop.
+ **
+ ** This optimization of causing simple query restrictions to occur before
+ ** more complex one is call the "push-down" optimization in MySQL. Here
+ ** in SQLite, the name is "MySQL push-down", since there is also another
+ ** totally unrelated optimization called "WHERE-clause push-down".
+ ** Sometimes the qualifier is omitted, resulting in an ambiguity, so beware.
*/
iLoop = (pIdx ? 1 : 2);
do{
@@ -161389,7 +163780,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** least once. This is accomplished by storing the PK for the row in
** both the iMatch index and the regBloom Bloom filter.
*/
- pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab;
+ pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab;
if( HasRowid(pTab) ){
r = sqlite3GetTempRange(pParse, 2);
sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1);
@@ -161496,12 +163887,25 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
Bitmask mAll = 0;
int k;
- ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName));
+ ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName));
sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn,
pRJ->regReturn);
for(k=0; ka[k].pWLoop->iTab == pWInfo->a[k].iFrom );
+ pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom];
mAll |= pWInfo->a[k].pWLoop->maskSelf;
+ if( pRight->fg.viaCoroutine ){
+ Subquery *pSubq;
+ assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 );
+ pSubq = pRight->u4.pSubq;
+ assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 );
+ sqlite3VdbeAddOp3(
+ v, OP_Null, 0, pSubq->regResult,
+ pSubq->regResult + pSubq->pSelect->pEList->nExpr-1
+ );
+ }
sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
iIdxCur = pWInfo->a[k].iIdxCur;
if( iIdxCur ){
@@ -161537,7 +163941,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
int nPk;
int jmp;
int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
- Table *pTab = pTabItem->pTab;
+ Table *pTab = pTabItem->pSTab;
if( HasRowid(pTab) ){
sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
nPk = 1;
@@ -161670,7 +164074,12 @@ static int allowedOp(int op){
assert( TK_LT>TK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS;
+ assert( TK_INTK_GE ) return 0;
+ if( op>=TK_EQ ) return 1;
+ return op==TK_IN || op==TK_ISNULL || op==TK_IS;
}
/*
@@ -161703,15 +164112,16 @@ static u16 exprCommute(Parse *pParse, Expr *pExpr){
static u16 operatorMask(int op){
u16 c;
assert( allowedOp(op) );
- if( op==TK_IN ){
+ if( op>=TK_EQ ){
+ assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
+ c = (u16)(WO_EQ<<(op-TK_EQ));
+ }else if( op==TK_IN ){
c = WO_IN;
}else if( op==TK_ISNULL ){
c = WO_ISNULL;
- }else if( op==TK_IS ){
- c = WO_IS;
}else{
- assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
- c = (u16)(WO_EQ<<(op-TK_EQ));
+ assert( op==TK_IS );
+ c = WO_IS;
}
assert( op!=TK_ISNULL || c==WO_ISNULL );
assert( op!=TK_IN || c==WO_IN );
@@ -161782,12 +164192,26 @@ static int isLikeOrGlob(
z = (u8*)pRight->u.zToken;
}
if( z ){
-
- /* Count the number of prefix characters prior to the first wildcard */
+ /* Count the number of prefix bytes prior to the first wildcard.
+ ** or U+fffd character. If the underlying database has a UTF16LE
+ ** encoding, then only consider ASCII characters. Note that the
+ ** encoding of z[] is UTF8 - we are dealing with only UTF8 here in
+ ** this code, but the database engine itself might be processing
+ ** content using a different encoding. */
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
- if( c==wc[3] && z[cnt]!=0 ) cnt++;
+ if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){
+ cnt++;
+ }else if( c>=0x80 ){
+ const u8 *z2 = z+cnt-1;
+ if( sqlite3Utf8Read(&z2)==0xfffd || ENC(db)==SQLITE_UTF16LE ){
+ cnt--;
+ break;
+ }else{
+ cnt = (int)(z2-z);
+ }
+ }
}
/* The optimization is possible only if (1) the pattern does not begin
@@ -161798,11 +164222,11 @@ static int isLikeOrGlob(
** range search. The third is because the caller assumes that the pattern
** consists of at least one character after all escapes have been
** removed. */
- if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){
+ if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && ALWAYS(255!=(u8)z[cnt-1]) ){
Expr *pPrefix;
/* A "complete" match if the pattern ends with "*" or "%" */
- *pisComplete = c==wc[0] && z[cnt+1]==0;
+ *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE;
/* Get the pattern prefix. Remove all escapes from the prefix. */
pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
@@ -161998,6 +164422,13 @@ static int isAuxiliaryVtabOperator(
}
}
}
+ }else if( pExpr->op>=TK_EQ ){
+ /* Comparison operators are a common case. Save a few comparisons for
+ ** that common case by terminating early. */
+ assert( TK_NE < TK_EQ );
+ assert( TK_ISNOT < TK_EQ );
+ assert( TK_NOTNULL < TK_EQ );
+ return 0;
}else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
int res = 0;
Expr *pLeft = pExpr->pLeft;
@@ -162514,7 +164945,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
if( ALWAYS(pSrc!=0) ){
int i;
for(i=0; inSrc; i++){
- mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
+ if( pSrc->a[i].fg.isSubquery ){
+ mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect);
+ }
if( pSrc->a[i].fg.isUsing==0 ){
mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn);
}
@@ -162552,13 +164985,13 @@ static SQLITE_NOINLINE int exprMightBeIndexed2(
int iCur;
do{
iCur = pFrom->a[j].iCursor;
- for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->aColExpr==0 ) continue;
for(i=0; inKeyCol; i++){
if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
assert( pIdx->bHasExpr );
if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0
- && pExpr->op!=TK_STRING
+ && !sqlite3ExprIsConstant(0,pIdx->aColExpr->a[i].pExpr)
){
aiCurCol[0] = iCur;
aiCurCol[1] = XN_EXPR;
@@ -162596,7 +165029,7 @@ static int exprMightBeIndexed(
for(i=0; inSrc; i++){
Index *pIdx;
- for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->aColExpr ){
return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i);
}
@@ -163139,7 +165572,7 @@ static void whereAddLimitExpr(
Expr *pNew;
int iVal = 0;
- if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){
+ if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){
Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0);
if( pVal==0 ) return;
ExprSetProperty(pVal, EP_IntValue);
@@ -163184,7 +165617,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec
assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */
if( p->pGroupBy==0
&& (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */
- && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */
+ && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */
){
ExprList *pOrderBy = p->pOrderBy;
int iCsr = p->pSrc->a[0].iCursor;
@@ -163207,6 +165640,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec
continue;
}
if( pWC->a[ii].leftCursor!=iCsr ) return;
+ if( pWC->a[ii].prereqRight!=0 ) return;
}
/* Check condition (5). Return early if it is not met. */
@@ -163221,12 +165655,14 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec
/* All conditions are met. Add the terms to the where-clause object. */
assert( p->pLimit->op==TK_LIMIT );
- whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft,
- iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT);
- if( p->iOffset>0 ){
+ if( p->iOffset!=0 && (p->selFlags & SF_Compound)==0 ){
whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight,
iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET);
}
+ if( p->iOffset==0 || (p->selFlags & SF_Compound)==0 ){
+ whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft,
+ iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT);
+ }
}
}
@@ -163402,7 +165838,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
Expr *pColRef;
Expr *pTerm;
if( pItem->fg.isTabFunc==0 ) return;
- pTab = pItem->pTab;
+ pTab = pItem->pSTab;
assert( pTab!=0 );
pArgs = pItem->u1.pFuncArg;
if( pArgs==0 ) return;
@@ -163744,6 +166180,42 @@ static Expr *whereRightSubexprIsColumn(Expr *p){
return 0;
}
+/*
+** Term pTerm is guaranteed to be a WO_IN term. It may be a component term
+** of a vector IN expression of the form "(x, y, ...) IN (SELECT ...)".
+** This function checks to see if the term is compatible with an index
+** column with affinity idxaff (one of the SQLITE_AFF_XYZ values). If so,
+** it returns a pointer to the name of the collation sequence (e.g. "BINARY"
+** or "NOCASE") used by the comparison in pTerm. If it is not compatible
+** with affinity idxaff, NULL is returned.
+*/
+static SQLITE_NOINLINE const char *indexInAffinityOk(
+ Parse *pParse,
+ WhereTerm *pTerm,
+ u8 idxaff
+){
+ Expr *pX = pTerm->pExpr;
+ Expr inexpr;
+
+ assert( pTerm->eOperator & WO_IN );
+
+ if( sqlite3ExprIsVector(pX->pLeft) ){
+ int iField = pTerm->u.x.iField - 1;
+ inexpr.flags = 0;
+ inexpr.op = TK_EQ;
+ inexpr.pLeft = pX->pLeft->x.pList->a[iField].pExpr;
+ assert( ExprUseXSelect(pX) );
+ inexpr.pRight = pX->x.pSelect->pEList->a[iField].pExpr;
+ pX = &inexpr;
+ }
+
+ if( sqlite3IndexAffinityOk(pX, idxaff) ){
+ CollSeq *pRet = sqlite3ExprCompareCollSeq(pParse, pX);
+ return pRet ? pRet->zName : sqlite3StrBINARY;
+ }
+ return 0;
+}
+
/*
** Advance to the next WhereTerm that matches according to the criteria
** established when the pScan object was initialized by whereScanInit().
@@ -163794,16 +166266,24 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
if( (pTerm->eOperator & pScan->opMask)!=0 ){
/* Verify the affinity and collating sequence match */
if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){
- CollSeq *pColl;
+ const char *zCollName;
Parse *pParse = pWC->pWInfo->pParse;
pX = pTerm->pExpr;
- if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
- continue;
+
+ if( (pTerm->eOperator & WO_IN) ){
+ zCollName = indexInAffinityOk(pParse, pTerm, pScan->idxaff);
+ if( !zCollName ) continue;
+ }else{
+ CollSeq *pColl;
+ if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
+ continue;
+ }
+ assert(pX->pLeft);
+ pColl = sqlite3ExprCompareCollSeq(pParse, pX);
+ zCollName = pColl ? pColl->zName : sqlite3StrBINARY;
}
- assert(pX->pLeft);
- pColl = sqlite3ExprCompareCollSeq(pParse, pX);
- if( pColl==0 ) pColl = pParse->db->pDfltColl;
- if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
+
+ if( sqlite3StrICmp(zCollName, pScan->zCollName) ){
continue;
}
}
@@ -164042,7 +166522,7 @@ static int isDistinctRedundant(
** clause is redundant. */
if( pTabList->nSrc!=1 ) return 0;
iBase = pTabList->a[0].iCursor;
- pTab = pTabList->a[0].pTab;
+ pTab = pTabList->a[0].pSTab;
/* If any of the expressions is an IPK column on table iBase, then return
** true. Note: The (p->iTable==iBase) part of this test may be false if the
@@ -164117,6 +166597,12 @@ static void translateColumnToCopy(
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
int iEnd = sqlite3VdbeCurrentAddr(v);
if( pParse->db->mallocFailed ) return;
+#ifdef SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("CHECKING for column-to-copy on cursor %d for %d..%d\n",
+ iTabCur, iStart, iEnd);
+ }
+#endif
for(; iStartp1!=iTabCur ) continue;
if( pOp->opcode==OP_Column ){
@@ -164155,9 +166641,13 @@ static void translateColumnToCopy(
** are no-ops.
*/
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED)
-static void whereTraceIndexInfoInputs(sqlite3_index_info *p){
+static void whereTraceIndexInfoInputs(
+ sqlite3_index_info *p, /* The IndexInfo object */
+ Table *pTab /* The TABLE that is the virtual table */
+){
int i;
if( (sqlite3WhereTrace & 0x10)==0 ) return;
+ sqlite3DebugPrintf("sqlite3_index_info inputs for %s:\n", pTab->zName);
for(i=0; inConstraint; i++){
sqlite3DebugPrintf(
" constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n",
@@ -164175,9 +166665,13 @@ static void whereTraceIndexInfoInputs(sqlite3_index_info *p){
p->aOrderBy[i].desc);
}
}
-static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){
+static void whereTraceIndexInfoOutputs(
+ sqlite3_index_info *p, /* The IndexInfo object */
+ Table *pTab /* The TABLE that is the virtual table */
+){
int i;
if( (sqlite3WhereTrace & 0x10)==0 ) return;
+ sqlite3DebugPrintf("sqlite3_index_info outputs for %s:\n", pTab->zName);
for(i=0; inConstraint; i++){
sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n",
i,
@@ -164191,8 +166685,8 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){
sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows);
}
#else
-#define whereTraceIndexInfoInputs(A)
-#define whereTraceIndexInfoOutputs(A)
+#define whereTraceIndexInfoInputs(A,B)
+#define whereTraceIndexInfoOutputs(A,B)
#endif
/*
@@ -164230,6 +166724,40 @@ static int constraintCompatibleWithOuterJoin(
return 1;
}
+#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+/*
+** Return true if column iCol of table pTab seem like it might be a
+** good column to use as part of a query-time index.
+**
+** Current algorithm (subject to improvement!):
+**
+** 1. If iCol is already the left-most column of some other index,
+** then return false.
+**
+** 2. If iCol is part of an existing index that has an aiRowLogEst of
+** more than 20, then return false.
+**
+** 3. If no disqualifying conditions above are found, return true.
+*/
+static SQLITE_NOINLINE int columnIsGoodIndexCandidate(
+ const Table *pTab,
+ int iCol
+){
+ const Index *pIdx;
+ for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){
+ int j;
+ for(j=0; jnKeyCol; j++){
+ if( pIdx->aiColumn[j]==iCol ){
+ if( j==0 ) return 0;
+ if( pIdx->hasStat1 && pIdx->aiRowLogEst[j+1]>20 ) return 0;
+ break;
+ }
+ }
+ }
+ return 1;
+}
+#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
+
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -164244,6 +166772,8 @@ static int termCanDriveIndex(
const Bitmask notReady /* Tables in outer loops of the join */
){
char aff;
+ int leftCol;
+
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
@@ -164254,11 +166784,12 @@ static int termCanDriveIndex(
}
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
- if( pTerm->u.x.leftColumn<0 ) return 0;
- aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
+ leftCol = pTerm->u.x.leftColumn;
+ if( leftCol<0 ) return 0;
+ aff = pSrc->pSTab->aCol[leftCol].affinity;
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
testcase( pTerm->pExpr->op==TK_IS );
- return 1;
+ return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol);
}
#endif
@@ -164366,7 +166897,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
nKeyCol = 0;
pTabList = pWC->pWInfo->pTabList;
pSrc = &pTabList->a[pLevel->iFrom];
- pTable = pSrc->pTab;
+ pTable = pSrc->pSTab;
pWCEnd = &pWC->a[pWC->nTerm];
pLoop = pLevel->pWLoop;
idxCols = 0;
@@ -164376,7 +166907,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
** WHERE clause (or the ON clause of a LEFT join) that constrain which
** rows of the target table (pSrc) that can be used. */
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
- && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom)
+ && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom, 0)
){
pPartial = sqlite3ExprAnd(pParse, pPartial,
sqlite3ExprDup(pParse->db, pExpr, 0));
@@ -164418,7 +166949,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
** if they go out of sync.
*/
if( IsView(pTable) ){
- extraCols = ALLBITS;
+ extraCols = ALLBITS & ~idxCols;
}else{
extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
}
@@ -164508,12 +167039,17 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
/* Fill the automatic index with content */
assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] );
if( pSrc->fg.viaCoroutine ){
- int regYield = pSrc->regReturn;
+ int regYield;
+ Subquery *pSubq;
+ assert( pSrc->fg.isSubquery );
+ pSubq = pSrc->u4.pSubq;
+ assert( pSubq!=0 );
+ regYield = pSubq->regReturn;
addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
- sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub);
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub);
addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
VdbeCoverage(v);
- VdbeComment((v, "next row of %s", pSrc->pTab->zName));
+ VdbeComment((v, "next row of %s", pSrc->pSTab->zName));
}else{
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
}
@@ -164535,11 +167071,12 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
if( pSrc->fg.viaCoroutine ){
+ assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 );
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
testcase( pParse->db->mallocFailed );
assert( pLevel->iIdxCur>0 );
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
- pSrc->regResult, pLevel->iIdxCur);
+ pSrc->u4.pSubq->regResult, pLevel->iIdxCur);
sqlite3VdbeGoto(v, addrTop);
pSrc->fg.viaCoroutine = 0;
}else{
@@ -164630,7 +167167,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
iSrc = pLevel->iFrom;
pItem = &pTabList->a[iSrc];
assert( pItem!=0 );
- pTab = pItem->pTab;
+ pTab = pItem->pSTab;
assert( pTab!=0 );
sz = sqlite3LogEstToInt(pTab->nRowLogEst);
if( sz<10000 ){
@@ -164645,7 +167182,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
for(pTerm=pWInfo->sWC.a; pTermpExpr;
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
- && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc)
+ && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc, 0)
){
sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
}
@@ -164661,7 +167198,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
int r1 = sqlite3GetTempRange(pParse, n);
int jj;
for(jj=0; jjpTable==pItem->pTab );
+ assert( pIdx->pTable==pItem->pSTab );
sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj);
}
sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n);
@@ -164699,6 +167236,20 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Return term iTerm of the WhereClause passed as the first argument. Terms
+** are numbered from 0 upwards, starting with the terms in pWC->a[], then
+** those in pWC->pOuter->a[] (if any), and so on.
+*/
+static WhereTerm *termFromWhereClause(WhereClause *pWC, int iTerm){
+ WhereClause *p;
+ for(p=pWC; p; p=p->pOuter){
+ if( iTermnTerm ) return &p->a[iTerm];
+ iTerm -= p->nTerm;
+ }
+ return 0;
+}
+
/*
** Allocate and populate an sqlite3_index_info structure. It is the
** responsibility of the caller to eventually release the structure
@@ -164725,9 +167276,10 @@ static sqlite3_index_info *allocateIndexInfo(
const Table *pTab;
int eDistinct = 0;
ExprList *pOrderBy = pWInfo->pOrderBy;
+ WhereClause *p;
assert( pSrc!=0 );
- pTab = pSrc->pTab;
+ pTab = pSrc->pSTab;
assert( pTab!=0 );
assert( IsVirtual(pTab) );
@@ -164735,28 +167287,30 @@ static sqlite3_index_info *allocateIndexInfo(
** Mark each term with the TERM_OK flag. Set nTerm to the number of
** terms found.
*/
- for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){
- pTerm->wtFlags &= ~TERM_OK;
- if( pTerm->leftCursor != pSrc->iCursor ) continue;
- if( pTerm->prereqRight & mUnusable ) continue;
- assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
- testcase( pTerm->eOperator & WO_IN );
- testcase( pTerm->eOperator & WO_ISNULL );
- testcase( pTerm->eOperator & WO_IS );
- testcase( pTerm->eOperator & WO_ALL );
- if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
- if( pTerm->wtFlags & TERM_VNULL ) continue;
+ for(p=pWC, nTerm=0; p; p=p->pOuter){
+ for(i=0, pTerm=p->a; inTerm; i++, pTerm++){
+ pTerm->wtFlags &= ~TERM_OK;
+ if( pTerm->leftCursor != pSrc->iCursor ) continue;
+ if( pTerm->prereqRight & mUnusable ) continue;
+ assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
+ testcase( pTerm->eOperator & WO_IN );
+ testcase( pTerm->eOperator & WO_ISNULL );
+ testcase( pTerm->eOperator & WO_IS );
+ testcase( pTerm->eOperator & WO_ALL );
+ if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
+ if( pTerm->wtFlags & TERM_VNULL ) continue;
- assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
- assert( pTerm->u.x.leftColumn>=XN_ROWID );
- assert( pTerm->u.x.leftColumnnCol );
- if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
- && !constraintCompatibleWithOuterJoin(pTerm,pSrc)
- ){
- continue;
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
+ assert( pTerm->u.x.leftColumn>=XN_ROWID );
+ assert( pTerm->u.x.leftColumnnCol );
+ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0
+ && !constraintCompatibleWithOuterJoin(pTerm,pSrc)
+ ){
+ continue;
+ }
+ nTerm++;
+ pTerm->wtFlags |= TERM_OK;
}
- nTerm++;
- pTerm->wtFlags |= TERM_OK;
}
/* If the ORDER BY clause contains only columns in the current
@@ -164771,7 +167325,7 @@ static sqlite3_index_info *allocateIndexInfo(
Expr *pE2;
/* Skip over constant terms in the ORDER BY clause */
- if( sqlite3ExprIsConstant(pExpr) ){
+ if( sqlite3ExprIsConstant(0, pExpr) ){
continue;
}
@@ -164806,7 +167360,7 @@ static sqlite3_index_info *allocateIndexInfo(
}
if( i==n ){
nOrderBy = n;
- if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){
+ if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) && !pSrc->fg.rowidUsed ){
eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0);
}else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){
eDistinct = 1;
@@ -164831,59 +167385,75 @@ static sqlite3_index_info *allocateIndexInfo(
pIdxInfo->aConstraint = pIdxCons;
pIdxInfo->aOrderBy = pIdxOrderBy;
pIdxInfo->aConstraintUsage = pUsage;
+ pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
+ if( HasRowid(pTab)==0 ){
+ /* Ensure that all bits associated with PK columns are set. This is to
+ ** ensure they are available for cases like RIGHT joins or OR loops. */
+ Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab);
+ assert( pPk!=0 );
+ for(i=0; inKeyCol; i++){
+ int iCol = pPk->aiColumn[i];
+ assert( iCol>=0 );
+ if( iCol>=BMS-1 ) iCol = BMS-1;
+ pIdxInfo->colUsed |= MASKBIT(iCol);
+ }
+ }
pHidden->pWC = pWC;
pHidden->pParse = pParse;
pHidden->eDistinct = eDistinct;
pHidden->mIn = 0;
- for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){
- u16 op;
- if( (pTerm->wtFlags & TERM_OK)==0 ) continue;
- pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
- pIdxCons[j].iTermOffset = i;
- op = pTerm->eOperator & WO_ALL;
- if( op==WO_IN ){
- if( (pTerm->wtFlags & TERM_SLICE)==0 ){
- pHidden->mIn |= SMASKBIT32(j);
- }
- op = WO_EQ;
- }
- if( op==WO_AUX ){
- pIdxCons[j].op = pTerm->eMatchOp;
- }else if( op & (WO_ISNULL|WO_IS) ){
- if( op==WO_ISNULL ){
- pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
+ for(p=pWC, i=j=0; p; p=p->pOuter){
+ int nLast = i+p->nTerm;;
+ for(pTerm=p->a; iwtFlags & TERM_OK)==0 ) continue;
+ pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
+ pIdxCons[j].iTermOffset = i;
+ op = pTerm->eOperator & WO_ALL;
+ if( op==WO_IN ){
+ if( (pTerm->wtFlags & TERM_SLICE)==0 ){
+ pHidden->mIn |= SMASKBIT32(j);
+ }
+ op = WO_EQ;
+ }
+ if( op==WO_AUX ){
+ pIdxCons[j].op = pTerm->eMatchOp;
+ }else if( op & (WO_ISNULL|WO_IS) ){
+ if( op==WO_ISNULL ){
+ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
+ }else{
+ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS;
+ }
}else{
- pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS;
- }
- }else{
- pIdxCons[j].op = (u8)op;
- /* The direct assignment in the previous line is possible only because
- ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
- ** following asserts verify this fact. */
- assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
- assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
- assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
- assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
- assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
- assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) );
-
- if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
- && sqlite3ExprIsVector(pTerm->pExpr->pRight)
- ){
- testcase( j!=i );
- if( j<16 ) mNoOmit |= (1 << j);
- if( op==WO_LT ) pIdxCons[j].op = WO_LE;
- if( op==WO_GT ) pIdxCons[j].op = WO_GE;
+ pIdxCons[j].op = (u8)op;
+ /* The direct assignment in the previous line is possible only because
+ ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
+ ** following asserts verify this fact. */
+ assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
+ assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
+ assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
+ assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
+ assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
+ assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) );
+
+ if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
+ && sqlite3ExprIsVector(pTerm->pExpr->pRight)
+ ){
+ testcase( j!=i );
+ if( j<16 ) mNoOmit |= (1 << j);
+ if( op==WO_LT ) pIdxCons[j].op = WO_LE;
+ if( op==WO_GT ) pIdxCons[j].op = WO_GE;
+ }
}
- }
- j++;
+ j++;
+ }
}
assert( j==nTerm );
pIdxInfo->nConstraint = j;
for(i=j=0; ia[i].pExpr;
- if( sqlite3ExprIsConstant(pExpr) ) continue;
+ if( sqlite3ExprIsConstant(0, pExpr) ) continue;
assert( pExpr->op==TK_COLUMN
|| (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN
&& pExpr->iColumn==pExpr->pLeft->iColumn) );
@@ -164897,6 +167467,17 @@ static sqlite3_index_info *allocateIndexInfo(
return pIdxInfo;
}
+/*
+** Free and zero the sqlite3_index_info.idxStr value if needed.
+*/
+static void freeIdxStr(sqlite3_index_info *pIdxInfo){
+ if( pIdxInfo->needToFreeIdxStr ){
+ sqlite3_free(pIdxInfo->idxStr);
+ pIdxInfo->idxStr = 0;
+ pIdxInfo->needToFreeIdxStr = 0;
+ }
+}
+
/*
** Free an sqlite3_index_info structure allocated by allocateIndexInfo()
** and possibly modified by xBestIndex methods.
@@ -164912,6 +167493,7 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){
sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */
pHidden->aRhs[i] = 0;
}
+ freeIdxStr(pIdxInfo);
sqlite3DbFree(db, pIdxInfo);
}
@@ -164932,14 +167514,16 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){
** that this is required.
*/
static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
- sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
int rc;
+ sqlite3_vtab *pVtab;
- whereTraceIndexInfoInputs(p);
+ assert( IsVirtual(pTab) );
+ pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
+ whereTraceIndexInfoInputs(p, pTab);
pParse->db->nSchemaLock++;
rc = pVtab->pModule->xBestIndex(pVtab, p);
pParse->db->nSchemaLock--;
- whereTraceIndexInfoOutputs(p);
+ whereTraceIndexInfoOutputs(p, pTab);
if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
if( rc==SQLITE_NOMEM ){
@@ -165705,7 +168289,7 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause
WhereInfo *pWInfo = pWC->pWInfo;
int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
- Table *pTab = pItem->pTab;
+ Table *pTab = pItem->pSTab;
Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
@@ -165877,7 +168461,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
** and Y has additional constraints that might speed the search that X lacks
** but the cost of running X is not more than the cost of running Y.
**
-** In other words, return true if the cost relationwship between X and Y
+** In other words, return true if the cost relationship between X and Y
** is inverted and needs to be adjusted.
**
** Case 1:
@@ -166263,7 +168847,7 @@ static void whereLoopOutputAdjust(
Expr *pRight = pTerm->pExpr->pRight;
int k = 0;
testcase( pTerm->pExpr->op==TK_IS );
- if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
+ if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){
k = 10;
}else{
k = 20;
@@ -166417,7 +169001,9 @@ static int whereLoopAddBtreeIndex(
}
if( pProbe->bUnordered || pProbe->bLowQual || pProbe->idxIsVector ){
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
- if( pProbe->bLowQual ) opMask &= ~(WO_EQ|WO_IN|WO_IS);
+ if( pProbe->bLowQual && pSrc->fg.isIndexedBy==0 ){
+ opMask &= ~(WO_EQ|WO_IN|WO_IS);
+ }
if( pProbe->idxIsVector ) opMask = 0;
}
@@ -166559,7 +169145,7 @@ static int whereLoopAddBtreeIndex(
|| (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
){
if( iCol==XN_ROWID || pProbe->uniqNotNull
- || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ)
+ || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ))
){
pNew->wsFlags |= WHERE_ONEROW;
}else{
@@ -166685,11 +169271,14 @@ static int whereLoopAddBtreeIndex(
}
}
- /* Set rCostIdx to the cost of visiting selected rows in index. Add
- ** it to pNew->rRun, which is currently set to the cost of the index
- ** seek only. Then, if this is a non-covering index, add the cost of
- ** visiting the rows in the main table. */
- assert( pSrc->pTab->szTabRow>0 );
+ /* Set rCostIdx to the estimated cost of visiting selected rows in the
+ ** index. The estimate is the sum of two values:
+ ** 1. The cost of doing one search-by-key to find the first matching
+ ** entry
+ ** 2. Stepping forward in the index pNew->nOut times to find all
+ ** additional matching entries.
+ */
+ assert( pSrc->pSTab->szTabRow>0 );
if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
/* The pProbe->szIdxRow is low for an IPK table since the interior
** pages are small. Thus szIdxRow gives a good estimate of seek cost.
@@ -166697,9 +169286,17 @@ static int whereLoopAddBtreeIndex(
** under-estimate the scanning cost. */
rCostIdx = pNew->nOut + 16;
}else{
- rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
+ rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow;
}
- pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
+ rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx);
+
+ /* Estimate the cost of running the loop. If all data is coming
+ ** from the index, then this is just the cost of doing the index
+ ** lookup and scan. But if some data is coming out of the main table,
+ ** we also have to add in the cost of doing pNew->nOut searches to
+ ** locate the row in the main table that corresponds to the index entry.
+ */
+ pNew->rRun = rCostIdx;
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
}
@@ -166805,7 +169402,9 @@ static int indexMightHelpWithOrderBy(
for(ii=0; iinExpr; ii++){
Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr);
if( NEVER(pExpr==0) ) continue;
- if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
+ if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN)
+ && pExpr->iTable==iCursor
+ ){
if( pExpr->iColumn<0 ) return 1;
for(jj=0; jjnKeyCol; jj++){
if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
@@ -167065,7 +169664,7 @@ static void wherePartIdxExpr(
u8 aff;
if( pLeft->op!=TK_COLUMN ) return;
- if( !sqlite3ExprIsConstant(pRight) ) return;
+ if( !sqlite3ExprIsConstant(0, pRight) ) return;
if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return;
if( pLeft->iColumn<0 ) return;
aff = pIdx->pTable->aCol[pLeft->iColumn].affinity;
@@ -167155,9 +169754,9 @@ static int whereLoopAddBtree(
pWInfo = pBuilder->pWInfo;
pTabList = pWInfo->pTabList;
pSrc = pTabList->a + pNew->iTab;
- pTab = pSrc->pTab;
+ pTab = pSrc->pSTab;
pWC = pBuilder->pWC;
- assert( !IsVirtual(pSrc->pTab) );
+ assert( !IsVirtual(pSrc->pSTab) );
if( pSrc->fg.isIndexedBy ){
assert( pSrc->fg.isCte==0 );
@@ -167182,7 +169781,7 @@ static int whereLoopAddBtree(
sPk.idxType = SQLITE_IDXTYPE_IPK;
aiRowEstPk[0] = pTab->nRowLogEst;
aiRowEstPk[1] = 0;
- pFirst = pSrc->pTab->pIndex;
+ pFirst = pSrc->pSTab->pIndex;
if( pSrc->fg.notIndexed==0 ){
/* The real indices of the table are only considered if the
** NOT INDEXED qualifier is omitted from the FROM clause */
@@ -167275,6 +169874,7 @@ static int whereLoopAddBtree(
pNew->prereq = mPrereq;
pNew->nOut = rSize;
pNew->u.btree.pIndex = pProbe;
+ pNew->u.btree.pOrderBy = 0;
b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
/* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
@@ -167304,6 +169904,10 @@ static int whereLoopAddBtree(
#endif
ApplyCostMultiplier(pNew->rRun, pTab->costMult);
whereLoopOutputAdjust(pWC, pNew, rSize);
+ if( pSrc->fg.isSubquery ){
+ if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE;
+ pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy;
+ }
rc = whereLoopInsert(pBuilder, pNew);
pNew->nOut = rSize;
if( rc ) break;
@@ -167341,7 +169945,9 @@ static int whereLoopAddBtree(
" according to whereIsCoveringIndex()\n", pProbe->zName));
}
}
- }else if( m==0 ){
+ }else if( m==0
+ && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
+ ){
WHERETRACE(0x200,
("-> %s a covering index according to bitmasks\n",
pProbe->zName, m==0 ? "is" : "is not"));
@@ -167417,7 +170023,7 @@ static int whereLoopAddBtree(
** unique index is used (making the index functionally non-unique)
** then the sqlite_stat1 data becomes important for scoring the
** plan */
- pTab->tabFlags |= TF_StatsUsed;
+ pTab->tabFlags |= TF_MaybeReanalyze;
}
#ifdef SQLITE_ENABLE_STAT4
sqlite3Stat4ProbeFree(pBuilder->pRec);
@@ -167439,6 +170045,21 @@ static int isLimitTerm(WhereTerm *pTerm){
&& pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET;
}
+/*
+** Return true if the first nCons constraints in the pUsage array are
+** marked as in-use (have argvIndex>0). False otherwise.
+*/
+static int allConstraintsUsed(
+ struct sqlite3_index_constraint_usage *aUsage,
+ int nCons
+){
+ int ii;
+ for(ii=0; iipNew->iTab. This
@@ -167489,7 +170110,7 @@ static int whereLoopAddVirtualOne(
** arguments mUsable and mExclude. */
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
for(i=0; ia[pIdxCons->iTermOffset];
+ WhereTerm *pTerm = termFromWhereClause(pWC, pIdxCons->iTermOffset);
pIdxCons->usable = 0;
if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight
&& (pTerm->eOperator & mExclude)==0
@@ -167508,11 +170129,10 @@ static int whereLoopAddVirtualOne(
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
pIdxInfo->estimatedRows = 25;
pIdxInfo->idxFlags = 0;
- pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
pHidden->mHandleIn = 0;
/* Invoke the virtual table xBestIndex() method */
- rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
+ rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo);
if( rc ){
if( rc==SQLITE_CONSTRAINT ){
/* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
@@ -167520,6 +170140,7 @@ static int whereLoopAddVirtualOne(
** Make no entries in the loop table.
*/
WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n"));
+ freeIdxStr(pIdxInfo);
return SQLITE_OK;
}
return rc;
@@ -167537,18 +170158,17 @@ static int whereLoopAddVirtualOne(
int j = pIdxCons->iTermOffset;
if( iTerm>=nConstraint
|| j<0
- || j>=pWC->nTerm
+ || (pTerm = termFromWhereClause(pWC, j))==0
|| pNew->aLTerm[iTerm]!=0
|| pIdxCons->usable==0
){
- sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
- testcase( pIdxInfo->needToFreeIdxStr );
+ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName);
+ freeIdxStr(pIdxInfo);
return SQLITE_ERROR;
}
testcase( iTerm==nConstraint-1 );
testcase( j==0 );
testcase( j==pWC->nTerm-1 );
- pTerm = &pWC->a[j];
pNew->prereq |= pTerm->prereqRight;
assert( iTermnLSlot );
pNew->aLTerm[iTerm] = pTerm;
@@ -167579,18 +170199,21 @@ static int whereLoopAddVirtualOne(
*pbIn = 1; assert( (mExclude & WO_IN)==0 );
}
+ /* Unless pbRetryLimit is non-NULL, there should be no LIMIT/OFFSET
+ ** terms. And if there are any, they should follow all other terms. */
assert( pbRetryLimit || !isLimitTerm(pTerm) );
- if( isLimitTerm(pTerm) && *pbIn ){
+ assert( !isLimitTerm(pTerm) || i>=nConstraint-2 );
+ assert( !isLimitTerm(pTerm) || i==nConstraint-1 || isLimitTerm(pTerm+1) );
+
+ if( isLimitTerm(pTerm) && (*pbIn || !allConstraintsUsed(pUsage, i)) ){
/* If there is an IN(...) term handled as an == (separate call to
** xFilter for each value on the RHS of the IN) and a LIMIT or
- ** OFFSET term handled as well, the plan is unusable. Set output
- ** variable *pbRetryLimit to true to tell the caller to retry with
- ** LIMIT and OFFSET disabled. */
- if( pIdxInfo->needToFreeIdxStr ){
- sqlite3_free(pIdxInfo->idxStr);
- pIdxInfo->idxStr = 0;
- pIdxInfo->needToFreeIdxStr = 0;
- }
+ ** OFFSET term handled as well, the plan is unusable. Similarly,
+ ** if there is a LIMIT/OFFSET and there are other unused terms,
+ ** the plan cannot be used. In these cases set variable *pbRetryLimit
+ ** to true to tell the caller to retry with LIMIT and OFFSET
+ ** disabled. */
+ freeIdxStr(pIdxInfo);
*pbRetryLimit = 1;
return SQLITE_OK;
}
@@ -167602,8 +170225,8 @@ static int whereLoopAddVirtualOne(
if( pNew->aLTerm[i]==0 ){
/* The non-zero argvIdx values must be contiguous. Raise an
** error if they are not */
- sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
- testcase( pIdxInfo->needToFreeIdxStr );
+ sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName);
+ freeIdxStr(pIdxInfo);
return SQLITE_ERROR;
}
}
@@ -167614,6 +170237,7 @@ static int whereLoopAddVirtualOne(
pNew->u.vtab.idxStr = pIdxInfo->idxStr;
pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
pIdxInfo->nOrderBy : 0);
+ pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0;
pNew->rSetup = 0;
pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
@@ -167658,7 +170282,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int
if( iCons>=0 && iConsnConstraint ){
CollSeq *pC = 0;
int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset;
- Expr *pX = pHidden->pWC->a[iTerm].pExpr;
+ Expr *pX = termFromWhereClause(pHidden->pWC, iTerm)->pExpr;
if( pX->pLeft ){
pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX);
}
@@ -167704,7 +170328,9 @@ SQLITE_API int sqlite3_vtab_rhs_value(
rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */
}else{
if( pH->aRhs[iCons]==0 ){
- WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset];
+ WhereTerm *pTerm = termFromWhereClause(
+ pH->pWC, pIdxInfo->aConstraint[iCons].iTermOffset
+ );
rc = sqlite3ValueFromExpr(
pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db),
SQLITE_AFF_BLOB, &pH->aRhs[iCons]
@@ -167802,7 +170428,7 @@ static int whereLoopAddVirtual(
pWC = pBuilder->pWC;
pNew = pBuilder->pNew;
pSrc = &pWInfo->pTabList->a[pNew->iTab];
- assert( IsVirtual(pSrc->pTab) );
+ assert( IsVirtual(pSrc->pSTab) );
p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit);
if( p==0 ) return SQLITE_NOMEM_BKPT;
pNew->rSetup = 0;
@@ -167816,7 +170442,7 @@ static int whereLoopAddVirtual(
}
/* First call xBestIndex() with all constraints usable. */
- WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
+ WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName));
WHERETRACE(0x800, (" VirtualOne: all usable\n"));
rc = whereLoopAddVirtualOne(
pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
@@ -167860,9 +170486,8 @@ static int whereLoopAddVirtual(
Bitmask mNext = ALLBITS;
assert( mNext>0 );
for(i=0; ia[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq
- );
+ int iTerm = p->aConstraint[i].iTermOffset;
+ Bitmask mThis = termFromWhereClause(pWC, iTerm)->prereqRight & ~mPrereq;
if( mThis>mPrev && mThisneedToFreeIdxStr ) sqlite3_free(p->idxStr);
freeIndexInfo(pParse->db, p);
- WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
+ WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc));
return rc;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -167972,7 +170596,7 @@ static int whereLoopAddOr(
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pItem->pTab) ){
+ if( IsVirtual(pItem->pSTab) ){
rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
}else
#endif
@@ -168086,7 +170710,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
mPrereq = 0;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pItem->pTab) ){
+ if( IsVirtual(pItem->pSTab) ){
SrcItem *p;
for(p=&pItem[1]; pfg.jointype & (JT_OUTER|JT_CROSS)) ){
@@ -168118,6 +170742,97 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
return rc;
}
+/* Implementation of the order-by-subquery optimization:
+**
+** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really
+** a subquery or CTE that has an ORDER BY clause. See if any of the terms
+** in the subquery ORDER BY clause will satisfy pOrderBy from the outer
+** query. Mark off all satisfied terms (by setting bits in *pOBSat) and
+** return TRUE if they do. If not, return false.
+**
+** Example:
+**
+** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b));
+** CREATE TABLE t2(x,y);
+** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y)
+** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b;
+**
+** The CTE named "t3" comes out in the natural order of "p", so the first
+** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3"
+** and sorting only needs to occur on the second term "b".
+**
+** Limitations:
+**
+** (1) The optimization is not applied if the outer ORDER BY contains
+** a COLLATE clause. The optimization might be applied if the
+** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as
+** long as the subquery ORDER BY does the same. But if the
+** outer ORDER BY uses COLLATE, even a redundant COLLATE, the
+** optimization is bypassed.
+**
+** (2) The subquery ORDER BY terms must exactly match subquery result
+** columns, including any COLLATE annotations. This routine relies
+** on iOrderByCol to do matching between order by terms and result
+** columns, and iOrderByCol will not be set if the result column
+** and ORDER BY collations differ.
+**
+** (3) The subquery and outer ORDER BY can be in opposite directions as
+** long as the subquery is materialized. If the subquery is
+** implemented as a co-routine, the sort orders must be in the same
+** direction because there is no way to run a co-routine backwards.
+*/
+static SQLITE_NOINLINE int wherePathMatchSubqueryOB(
+ WhereInfo *pWInfo, /* The WHERE clause */
+ WhereLoop *pLoop, /* The nested loop term that is a subquery */
+ int iLoop, /* Which level of the nested loop. 0==outermost */
+ int iCur, /* Cursor used by the this loop */
+ ExprList *pOrderBy, /* The ORDER BY clause on the whole query */
+ Bitmask *pRevMask, /* When loops need to go in reverse order */
+ Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */
+){
+ int iOB; /* Index into pOrderBy->a[] */
+ int jSub; /* Index into pSubOB->a[] */
+ u8 rev = 0; /* True if iOB and jSub sort in opposite directions */
+ u8 revIdx = 0; /* Sort direction for jSub */
+ Expr *pOBExpr; /* Current term of outer ORDER BY */
+ ExprList *pSubOB; /* Complete ORDER BY on the subquery */
+
+ pSubOB = pLoop->u.btree.pOrderBy;
+ assert( pSubOB!=0 );
+ for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){}
+ for(jSub=0; jSubnExpr && iOBnExpr; jSub++, iOB++){
+ if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break;
+ pOBExpr = pOrderBy->a[iOB].pExpr;
+ if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break;
+ if( pOBExpr->iTable!=iCur ) break;
+ if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break;
+ if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
+ u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */
+ u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */
+ if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){
+ break;
+ }
+ revIdx = sfSub & KEYINFO_ORDER_DESC;
+ if( jSub>0 ){
+ if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){
+ break;
+ }
+ }else{
+ rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC);
+ if( rev ){
+ if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){
+ /* Cannot run a co-routine in reverse order */
+ break;
+ }
+ *pRevMask |= MASKBIT(iLoop);
+ }
+ }
+ }
+ *pOBSat |= MASKBIT(iOB);
+ }
+ return jSub>0;
+}
+
/*
** Examine a WherePath (with the addition of the extra WhereLoop of the 6th
** parameters) to see if it outputs rows in the requested ORDER BY
@@ -168263,6 +170978,16 @@ static i8 wherePathSatisfiesOrderBy(
if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
if( pLoop->wsFlags & WHERE_IPK ){
+ if( pLoop->u.btree.pOrderBy
+ && OptimizationEnabled(db, SQLITE_OrderBySubq)
+ && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur,
+ pOrderBy,pRevMask, &obSat)
+ ){
+ nColumn = 0;
+ isOrderDistinct = 0;
+ }else{
+ nColumn = 1;
+ }
pIndex = 0;
nKeyCol = 0;
nColumn = 1;
@@ -168275,7 +171000,7 @@ static i8 wherePathSatisfiesOrderBy(
assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
|| !HasRowid(pIndex->pTable));
/* All relevant terms of the index must also be non-NULL in order
- ** for isOrderDistinct to be true. So the isOrderDistint value
+ ** for isOrderDistinct to be true. So the isOrderDistinct value
** computed here might be a false positive. Corrections will be
** made at tag-20210426-1 below */
isOrderDistinct = IsUniqueIndex(pIndex)
@@ -168360,7 +171085,7 @@ static i8 wherePathSatisfiesOrderBy(
}
/* Find the ORDER BY term that corresponds to the j-th column
- ** of the index and mark that ORDER BY term off
+ ** of the index and mark that ORDER BY term having been satisfied.
*/
isMatch = 0;
for(i=0; bOnce && ia[i].pExpr;
mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p);
- if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue;
+ if( mTerm==0 && !sqlite3ExprIsConstant(0,p) ) continue;
if( (mTerm&~orderDistinctMask)==0 ){
obSat |= MASKBIT(i);
}
@@ -168567,6 +171292,83 @@ static LogEst whereSortingCost(
return rSortCost;
}
+/*
+** Compute the maximum number of paths in the solver algorithm, for
+** queries that have three or more terms in the FROM clause. Queries with
+** two or fewer FROM clause terms are handled by the caller.
+**
+** Query planning is NP-hard. We must limit the number of paths at
+** each step of the solver search algorithm to avoid exponential behavior.
+**
+** The value returned is a tuning parameter. Currently the value is:
+**
+** 18 for star queries
+** 12 otherwise
+**
+** For the purposes of SQLite, a star-query is defined as a query
+** with a large central table that is joined against four or more
+** smaller tables. The central table is called the "fact" table.
+** The smaller tables that get joined are "dimension tables".
+**
+** SIDE EFFECT: (and really the whole point of this subroutine)
+**
+** If pWInfo describes a star-query, then the cost on WhereLoops for the
+** fact table is reduced. This heuristic helps keep fact tables in
+** outer loops. Without this heuristic, paths with fact tables in outer
+** loops tend to get pruned by the mxChoice limit on the number of paths,
+** resulting in poor query plans. The total amount of heuristic cost
+** adjustment is stored in pWInfo->nOutStarDelta and the cost adjustment
+** for each WhereLoop is stored in its rStarDelta field.
+*/
+static int computeMxChoice(WhereInfo *pWInfo, LogEst nRowEst){
+ int nLoop = pWInfo->nLevel; /* Number of terms in the join */
+ if( nRowEst==0 && nLoop>=5 ){
+ /* Check to see if we are dealing with a star schema and if so, reduce
+ ** the cost of fact tables relative to dimension tables, as a heuristic
+ ** to help keep the fact tables in outer loops.
+ */
+ int iLoop; /* Counter over join terms */
+ Bitmask m; /* Bitmask for current loop */
+ assert( pWInfo->nOutStarDelta==0 );
+ for(iLoop=0, m=1; iLooppLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
+ if( (pWLoop->prereq & m)!=0 && (pWLoop->maskSelf & mSeen)==0 ){
+ nDep++;
+ mSeen |= pWLoop->maskSelf;
+ }
+ }
+ if( nDep<=3 ) continue;
+ rDelta = 15*(nDep-3);
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ SrcItem *pItem = pWInfo->pTabList->a + iLoop;
+ sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n",
+ pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName,
+ nDep, rDelta);
+ }
+#endif
+ if( pWInfo->nOutStarDelta==0 ){
+ for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
+ pWLoop->rStarDelta = 0;
+ }
+ }
+ pWInfo->nOutStarDelta += rDelta;
+ for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
+ if( pWLoop->maskSelf==m ){
+ pWLoop->rRun -= rDelta;
+ pWLoop->nOut -= rDelta;
+ pWLoop->rStarDelta = rDelta;
+ }
+ }
+ }
+ }
+ return pWInfo->nOutStarDelta>0 ? 18 : 12;
+}
+
/*
** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
** attempts to find the lowest cost path that visits each WhereLoop
@@ -168602,13 +171404,25 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pParse = pWInfo->pParse;
nLoop = pWInfo->nLevel;
- /* TUNING: For simple queries, only the best path is tracked.
- ** For 2-way joins, the 5 best paths are followed.
- ** For joins of 3 or more tables, track the 10 best paths */
- mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10);
- assert( nLoop<=pWInfo->pTabList->nSrc );
WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n",
nRowEst, pParse->nQueryLoop));
+ /* TUNING: mxChoice is the maximum number of possible paths to preserve
+ ** at each step. Based on the number of loops in the FROM clause:
+ **
+ ** nLoop mxChoice
+ ** ----- --------
+ ** 1 1 // the most common case
+ ** 2 5
+ ** 3+ 12 or 18 // see computeMxChoice()
+ */
+ if( nLoop<=1 ){
+ mxChoice = 1;
+ }else if( nLoop==2 ){
+ mxChoice = 5;
+ }else{
+ mxChoice = computeMxChoice(pWInfo, nRowEst);
+ }
+ assert( nLoop<=pWInfo->pTabList->nSrc );
/* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this
** case the purpose of this call is to estimate the number of rows returned
@@ -168691,7 +171505,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
/* At this point, pWLoop is a candidate to be the next loop.
** Compute its cost */
- rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
+ rUnsorted = pWLoop->rRun + pFrom->nRow;
+ if( pWLoop->rSetup ){
+ rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup, rUnsorted);
+ }
rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted);
nOut = pFrom->nRow + pWLoop->nOut;
maskNew = pFrom->maskLoop | pWLoop->maskSelf;
@@ -168736,6 +171553,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range
** of legal values for isOrdered, -1..64.
*/
+ testcase( nTo==0 );
for(jj=0, pTo=aTo; jjmaskLoop==maskNew
&& ((pTo->isOrdered^isOrdered)&0x80)==0
@@ -168852,16 +171670,28 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
#ifdef WHERETRACE_ENABLED /* >=2 */
if( sqlite3WhereTrace & 0x02 ){
+ LogEst rMin, rFloor = 0;
+ int nDone = 0;
sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
- for(ii=0, pTo=aTo; iirCost, pTo->nRow,
- pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?');
- if( pTo->isOrdered>0 ){
- sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
- }else{
- sqlite3DebugPrintf("\n");
+ while( nDonerCost>rFloor && pTo->rCostrCost;
+ }
+ for(ii=0, pTo=aTo; iirCost==rMin ){
+ sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
+ wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+ pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?');
+ if( pTo->isOrdered>0 ){
+ sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
+ }else{
+ sqlite3DebugPrintf("\n");
+ }
+ nDone++;
+ }
}
+ rFloor = rMin;
}
}
#endif
@@ -168911,10 +171741,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
- if( pWInfo->pSelect->pOrderBy
- && pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){
- pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr;
- }
+ /* vvv--- See check-in [12ad822d9b827777] on 2023-03-16 ---vvv */
+ assert( pWInfo->pSelect->pOrderBy==0
+ || pWInfo->nOBSat <= pWInfo->pSelect->pOrderBy->nExpr );
}else{
pWInfo->revMask = pFrom->revLoop;
if( pWInfo->nOBSat<=0 ){
@@ -168957,14 +171786,90 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
}
}
-
- pWInfo->nRowOut = pFrom->nRow;
+ pWInfo->nRowOut = pFrom->nRow + pWInfo->nOutStarDelta;
/* Free temporary memory and return success */
sqlite3StackFreeNN(pParse->db, pSpace);
return SQLITE_OK;
}
+/*
+** This routine implements a heuristic designed to improve query planning.
+** This routine is called in between the first and second call to
+** wherePathSolver(). Hence the name "Interstage" "Heuristic".
+**
+** The first call to wherePathSolver() (hereafter just "solver()") computes
+** the best path without regard to the order of the outputs. The second call
+** to the solver() builds upon the first call to try to find an alternative
+** path that satisfies the ORDER BY clause.
+**
+** This routine looks at the results of the first solver() run, and for
+** every FROM clause term in the resulting query plan that uses an equality
+** constraint against an index, disable other WhereLoops for that same
+** FROM clause term that would try to do a full-table scan. This prevents
+** an index search from being converted into a full-table scan in order to
+** satisfy an ORDER BY clause, since even though we might get slightly better
+** performance using the full-scan without sorting if the output size
+** estimates are very precise, we might also get severe performance
+** degradation using the full-scan if the output size estimate is too large.
+** It is better to err on the side of caution.
+**
+** Except, if the first solver() call generated a full-table scan in an outer
+** loop then stop this analysis at the first full-scan, since the second
+** solver() run might try to swap that full-scan for another in order to
+** get the output into the correct order. In other words, we allow a
+** rewrite like this:
+**
+** First Solver() Second Solver()
+** |-- SCAN t1 |-- SCAN t2
+** |-- SEARCH t2 `-- SEARCH t1
+** `-- SORT USING B-TREE
+**
+** The purpose of this routine is to disallow rewrites such as:
+**
+** First Solver() Second Solver()
+** |-- SEARCH t1 |-- SCAN t2 <--- bad!
+** |-- SEARCH t2 `-- SEARCH t1
+** `-- SORT USING B-TREE
+**
+** See test cases in test/whereN.test for the real-world query that
+** originally provoked this heuristic.
+*/
+static SQLITE_NOINLINE void whereInterstageHeuristic(WhereInfo *pWInfo){
+ int i;
+#ifdef WHERETRACE_ENABLED
+ int once = 0;
+#endif
+ for(i=0; inLevel; i++){
+ WhereLoop *p = pWInfo->a[i].pWLoop;
+ if( p==0 ) break;
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ) continue;
+ if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){
+ u8 iTab = p->iTab;
+ WhereLoop *pLoop;
+ for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){
+ if( pLoop->iTab!=iTab ) continue;
+ if( (pLoop->wsFlags & (WHERE_CONSTRAINT|WHERE_AUTO_INDEX))!=0 ){
+ /* Auto-index and index-constrained loops allowed to remain */
+ continue;
+ }
+#ifdef WHERETRACE_ENABLED
+ if( sqlite3WhereTrace & 0x80 ){
+ if( once==0 ){
+ sqlite3DebugPrintf("Loops disabled by interstage heuristic:\n");
+ once = 1;
+ }
+ sqlite3WhereLoopPrint(pLoop, &pWInfo->sWC);
+ }
+#endif /* WHERETRACE_ENABLED */
+ pLoop->prereq = ALLBITS; /* Prevent 2nd solver() from using this one */
+ }
+ }else{
+ break;
+ }
+ }
+}
+
/*
** Most queries use only a single table (they are not joins) and have
** simple == constraints against indexed fields. This routine attempts
@@ -168992,7 +171897,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
assert( pWInfo->pTabList->nSrc>=1 );
pItem = pWInfo->pTabList->a;
- pTab = pItem->pTab;
+ pTab = pItem->pSTab;
if( IsVirtual(pTab) ) return 0;
if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){
testcase( pItem->fg.isIndexedBy );
@@ -169133,6 +172038,10 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
** the right-most table of a subquery that was flattened into the
** main query and that subquery was the right-hand operand of an
** inner join that held an ON or USING clause.
+** 6) The ORDER BY clause has 63 or fewer terms
+** 7) The omit-noop-join optimization is enabled.
+**
+** Items (1), (6), and (7) are checked by the caller.
**
** For example, given:
**
@@ -169178,6 +172087,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
WhereTerm *pTerm, *pEnd;
SrcItem *pItem;
WhereLoop *pLoop;
+ Bitmask m1;
pLoop = pWInfo->a[i].pWLoop;
pItem = &pWInfo->pTabList->a[pLoop->iTab];
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue;
@@ -169204,7 +172114,10 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
}
}
if( pTerm drop loop %c not used\n", pLoop->cId));
+ WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId));
+ m1 = MASKBIT(i)-1;
+ testcase( ((pWInfo->revMask>>1) & ~m1)!=0 );
+ pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1);
notReady &= ~pLoop->maskSelf;
for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){
@@ -169251,9 +172164,9 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(
WhereLoop *pLoop = pWInfo->a[i].pWLoop;
const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ);
SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab];
- Table *pTab = pItem->pTab;
+ Table *pTab = pItem->pSTab;
if( (pTab->tabFlags & TF_HasStat1)==0 ) break;
- pTab->tabFlags |= TF_StatsUsed;
+ pTab->tabFlags |= TF_MaybeReanalyze;
if( i>=1
&& (pLoop->wsFlags & reqFlags)==reqFlags
/* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */
@@ -169271,6 +172184,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(
}
}
nSearch += pLoop->nOut;
+ if( pWInfo->nOutStarDelta ) nSearch += pLoop->rStarDelta;
}
}
@@ -169299,34 +172213,14 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
for(i=0; inColumn; i++){
Expr *pExpr;
int j = pIdx->aiColumn[i];
- int bMaybeNullRow;
if( j==XN_EXPR ){
pExpr = pIdx->aColExpr->a[i].pExpr;
- testcase( pTabItem->fg.jointype & JT_LEFT );
- testcase( pTabItem->fg.jointype & JT_RIGHT );
- testcase( pTabItem->fg.jointype & JT_LTORJ );
- bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0;
}else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){
pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]);
- bMaybeNullRow = 0;
}else{
continue;
}
- if( sqlite3ExprIsConstant(pExpr) ) continue;
- if( pExpr->op==TK_FUNCTION ){
- /* Functions that might set a subtype should not be replaced by the
- ** value taken from an expression index since the index omits the
- ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */
- int n;
- FuncDef *pDef;
- sqlite3 *db = pParse->db;
- assert( ExprUseXList(pExpr) );
- n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0;
- pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
- if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){
- continue;
- }
- }
+ if( sqlite3ExprIsConstant(0,pExpr) ) continue;
p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr));
if( p==0 ) break;
p->pIENext = pParse->pIdxEpr;
@@ -169340,7 +172234,7 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
p->iDataCur = pTabItem->iCursor;
p->iIdxCur = iIdxCur;
p->iIdxCol = i;
- p->bMaybeNullRow = bMaybeNullRow;
+ p->bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0;
if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){
p->aff = pIdx->zColAff[i];
}
@@ -169369,8 +172263,8 @@ static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){
SrcItem *pItem = &pWInfo->pTabList->a[ii];
if( !pItem->fg.isCte
|| pItem->u2.pCteUse->eM10d!=M10d_Yes
- || NEVER(pItem->pSelect==0)
- || pItem->pSelect->pOrderBy==0
+ || NEVER(pItem->fg.isSubquery==0)
+ || pItem->u4.pSubq->pSelect->pOrderBy==0
){
pWInfo->revMask |= MASKBIT(ii);
}
@@ -169508,6 +172402,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( pOrderBy && pOrderBy->nExpr>=BMS ){
pOrderBy = 0;
wctrlFlags &= ~WHERE_WANT_DISTINCT;
+ wctrlFlags |= WHERE_KEEP_ALL_JOINS; /* Disable omit-noop-join opt */
}
/* The number of tables in the FROM clause is limited by the number of
@@ -169590,7 +172485,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
){
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}
- ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
+ if( ALWAYS(pWInfo->pSelect)
+ && (pWInfo->pSelect->selFlags & SF_MultiValue)==0
+ ){
+ ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
+ }
}else{
/* Assign a bit from the bitmask to every term in the FROM clause.
**
@@ -169743,7 +172642,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
wherePathSolver(pWInfo, 0);
if( db->mallocFailed ) goto whereBeginError;
if( pWInfo->pOrderBy ){
- wherePathSolver(pWInfo, pWInfo->nRowOut+1);
+ whereInterstageHeuristic(pWInfo);
+ wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1);
if( db->mallocFailed ) goto whereBeginError;
}
@@ -169803,10 +172703,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** in-line sqlite3WhereCodeOneLoopStart() for performance reasons.
*/
notReady = ~(Bitmask)0;
- if( pWInfo->nLevel>=2
- && pResultSet!=0 /* these two combine to guarantee */
- && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */
- && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
+ if( pWInfo->nLevel>=2 /* Must be a join, or this opt8n is pointless */
+ && pResultSet!=0 /* Condition (1) */
+ && 0==(wctrlFlags & (WHERE_AGG_DISTINCT|WHERE_KEEP_ALL_JOINS)) /* (1),(6) */
+ && OptimizationEnabled(db, SQLITE_OmitNoopJoin) /* (7) */
){
notReady = whereOmitNoopJoin(pWInfo, notReady);
nTabList = pWInfo->nLevel;
@@ -169854,15 +172754,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
- assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) );
+ assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) );
if( bOnerow || (
0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
- && !IsVirtual(pTabList->a[0].pTab)
+ && !IsVirtual(pTabList->a[0].pSTab)
&& (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
&& OptimizationEnabled(db, SQLITE_OnePass)
)){
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
- if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
+ if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){
if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
bFordelete = OPFLAG_FORDELETE;
}
@@ -169880,7 +172780,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
SrcItem *pTabItem;
pTabItem = &pTabList->a[pLevel->iFrom];
- pTab = pTabItem->pTab;
+ pTab = pTabItem->pSTab;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pLoop = pLevel->pWLoop;
if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){
@@ -169951,7 +172851,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
iIndexCur = pLevel->iTabCur;
op = 0;
}else if( pWInfo->eOnePass!=ONEPASS_OFF ){
- Index *pJ = pTabItem->pTab->pIndex;
+ Index *pJ = pTabItem->pSTab->pIndex;
iIndexCur = iAuxArg;
assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
while( ALWAYS(pJ) && pJ!=pIx ){
@@ -170018,7 +172918,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom);
pRJ->regReturn = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn);
- assert( pTab==pTabItem->pTab );
+ assert( pTab==pTabItem->pSTab );
if( HasRowid(pTab) ){
KeyInfo *pInfo;
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1);
@@ -170057,13 +172957,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
wsFlags = pLevel->pWLoop->wsFlags;
pSrc = &pTabList->a[pLevel->iFrom];
if( pSrc->fg.isMaterialized ){
- if( pSrc->fg.isCorrelated ){
- sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
+ Subquery *pSubq;
+ int iOnce = 0;
+ assert( pSrc->fg.isSubquery );
+ pSubq = pSrc->u4.pSubq;
+ if( pSrc->fg.isCorrelated==0 ){
+ iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}else{
- int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
- sqlite3VdbeJumpHere(v, iOnce);
+ iOnce = 0;
}
+ sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub);
+ VdbeComment((v, "materialize %!S", pSrc));
+ if( iOnce ) sqlite3VdbeJumpHere(v, iOnce);
}
assert( pTabList == pWInfo->pTabList );
if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
@@ -170126,26 +173031,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
#endif
-#ifdef SQLITE_DEBUG
-/*
-** Return true if cursor iCur is opened by instruction k of the
-** bytecode. Used inside of assert() only.
-*/
-static int cursorIsOpen(Vdbe *v, int iCur, int k){
- while( k>=0 ){
- VdbeOp *pOp = sqlite3VdbeGetOp(v,k--);
- if( pOp->p1!=iCur ) continue;
- if( pOp->opcode==OP_Close ) return 0;
- if( pOp->opcode==OP_OpenRead ) return 1;
- if( pOp->opcode==OP_OpenWrite ) return 1;
- if( pOp->opcode==OP_OpenDup ) return 1;
- if( pOp->opcode==OP_OpenAutoindex ) return 1;
- if( pOp->opcode==OP_OpenEphemeral ) return 1;
- }
- return 0;
-}
-#endif /* SQLITE_DEBUG */
-
/*
** Generate the end of the WHERE loop. See comments on
** sqlite3WhereBegin() for additional information.
@@ -170292,7 +173177,16 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
if( (ws & WHERE_IDX_ONLY)==0 ){
- assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
+ SrcItem *pSrc = &pTabList->a[pLevel->iFrom];
+ assert( pLevel->iTabCur==pSrc->iCursor );
+ if( pSrc->fg.viaCoroutine ){
+ int m, n;
+ assert( pSrc->fg.isSubquery );
+ n = pSrc->u4.pSubq->regResult;
+ assert( pSrc->pSTab!=0 );
+ m = pSrc->pSTab->nCol;
+ sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1);
+ }
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
}
if( (ws & WHERE_INDEXED)
@@ -170314,7 +173208,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeJumpHere(v, addr);
}
VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
- pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
+ pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName));
}
assert( pWInfo->nLevel<=pTabList->nSrc );
@@ -170323,7 +173217,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
VdbeOp *pOp, *pLastOp;
Index *pIdx = 0;
SrcItem *pTabItem = &pTabList->a[pLevel->iFrom];
- Table *pTab = pTabItem->pTab;
+ Table *pTab = pTabItem->pSTab;
assert( pTab!=0 );
pLoop = pLevel->pWLoop;
@@ -170342,8 +173236,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
*/
if( pTabItem->fg.viaCoroutine ){
testcase( pParse->db->mallocFailed );
+ assert( pTabItem->fg.isSubquery );
+ assert( pTabItem->u4.pSubq->regResult>=0 );
translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
- pTabItem->regResult, 0);
+ pTabItem->u4.pSubq->regResult, 0);
continue;
}
@@ -170436,16 +173332,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
** reference. Verify that this is harmless - that the
** table being referenced really is open.
*/
-#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
- || cursorIsOpen(v,pOp->p1,k)
- || pOp->opcode==OP_Offset
- );
-#else
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
- || cursorIsOpen(v,pOp->p1,k)
- );
-#endif
+ if( pLoop->wsFlags & WHERE_IDX_ONLY ){
+ sqlite3ErrorMsg(pParse, "internal query planner error");
+ pParse->rc = SQLITE_INTERNAL;
+ }
}
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
@@ -171391,7 +174281,7 @@ static ExprList *exprListAppendList(
int iDummy;
Expr *pSub;
pSub = sqlite3ExprSkipCollateAndLikely(pDup);
- if( sqlite3ExprIsInteger(pSub, &iDummy) ){
+ if( sqlite3ExprIsInteger(pSub, &iDummy, 0) ){
pSub->op = TK_NULL;
pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
pSub->u.zToken = 0;
@@ -171559,9 +174449,10 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside
** of sqlite3DbMallocRawNN() called from
** sqlite3SrcListAppend() */
- if( p->pSrc ){
+ if( p->pSrc==0 ){
+ sqlite3SelectDelete(db, pSub);
+ }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){
Table *pTab2;
- p->pSrc->a[0].pSelect = pSub;
p->pSrc->a[0].fg.isCorrelated = 1;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
pSub->selFlags |= SF_Expanded|SF_OrderByReqd;
@@ -171575,7 +174466,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
}else{
memcpy(pTab, pTab2, sizeof(Table));
pTab->tabFlags |= TF_Ephemeral;
- p->pSrc->a[0].pTab = pTab;
+ p->pSrc->a[0].pSTab = pTab;
pTab = pTab2;
memset(&w, 0, sizeof(w));
w.xExprCallback = sqlite3WindowExtraAggFuncDepth;
@@ -171583,8 +174474,6 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
sqlite3WalkSelect(&w, pSub);
}
- }else{
- sqlite3SelectDelete(db, pSub);
}
if( db->mallocFailed ) rc = SQLITE_NOMEM;
@@ -171646,7 +174535,7 @@ SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){
** variable values in the expression tree.
*/
static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
- if( 0==sqlite3ExprIsConstant(pExpr) ){
+ if( 0==sqlite3ExprIsConstant(0,pExpr) ){
if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr);
sqlite3ExprDelete(pParse->db, pExpr);
pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
@@ -171871,10 +174760,15 @@ SQLITE_PRIVATE int sqlite3WindowCompare(
** and initialize registers and cursors used by sqlite3WindowCodeStep().
*/
SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
- int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr;
- Window *pMWin = pSelect->pWin;
Window *pWin;
- Vdbe *v = sqlite3GetVdbe(pParse);
+ int nEphExpr;
+ Window *pMWin;
+ Vdbe *v;
+
+ assert( pSelect->pSrc->a[0].fg.isSubquery );
+ nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr;
+ pMWin = pSelect->pWin;
+ v = sqlite3GetVdbe(pParse);
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr);
sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
@@ -173271,7 +176165,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
Vdbe *v = sqlite3GetVdbe(pParse);
int csrWrite; /* Cursor used to write to eph. table */
int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */
- int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */
+ int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */
int iInput; /* To iterate through sub cols */
int addrNe; /* Address of OP_Ne */
int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */
@@ -173716,9 +176610,9 @@ static void updateDeleteLimitError(
break;
}
}
- if( (p->selFlags & SF_MultiValue)==0 &&
- (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
- cnt>mxSelect
+ if( (p->selFlags & (SF_MultiValue|SF_Values))==0
+ && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0
+ && cnt>mxSelect
){
sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
}
@@ -173738,6 +176632,14 @@ static void updateDeleteLimitError(
return pSelect;
}
+ /* Memory allocator for parser stack resizing. This is a thin wrapper around
+ ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
+ ** testing.
+ */
+ static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){
+ return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
+ }
+
/* Construct a new Expr object from a single token */
static Expr *tokenExpr(Parse *pParse, int op, Token t){
@@ -173864,134 +176766,134 @@ static void updateDeleteLimitError(
#define TK_OR 47
#define TK_AND 48
#define TK_IS 49
-#define TK_MATCH 50
-#define TK_LIKE_KW 51
-#define TK_BETWEEN 52
-#define TK_IN 53
-#define TK_ISNULL 54
-#define TK_NOTNULL 55
-#define TK_NE 56
-#define TK_EQ 57
-#define TK_GT 58
-#define TK_LE 59
-#define TK_LT 60
-#define TK_GE 61
-#define TK_ESCAPE 62
-#define TK_ID 63
-#define TK_COLUMNKW 64
-#define TK_DO 65
-#define TK_FOR 66
-#define TK_IGNORE 67
-#define TK_INITIALLY 68
-#define TK_INSTEAD 69
-#define TK_NO 70
-#define TK_KEY 71
-#define TK_OF 72
-#define TK_OFFSET 73
-#define TK_PRAGMA 74
-#define TK_RAISE 75
-#define TK_RECURSIVE 76
-#define TK_REPLACE 77
-#define TK_RESTRICT 78
-#define TK_ROW 79
-#define TK_ROWS 80
-#define TK_TRIGGER 81
-#define TK_VACUUM 82
-#define TK_VIEW 83
-#define TK_VIRTUAL 84
-#define TK_WITH 85
-#define TK_NULLS 86
-#define TK_FIRST 87
-#define TK_LAST 88
-#define TK_CURRENT 89
-#define TK_FOLLOWING 90
-#define TK_PARTITION 91
-#define TK_PRECEDING 92
-#define TK_RANGE 93
-#define TK_UNBOUNDED 94
-#define TK_EXCLUDE 95
-#define TK_GROUPS 96
-#define TK_OTHERS 97
-#define TK_TIES 98
-#define TK_GENERATED 99
-#define TK_ALWAYS 100
-#define TK_MATERIALIZED 101
-#define TK_REINDEX 102
-#define TK_RENAME 103
-#define TK_CTIME_KW 104
-#define TK_ANY 105
-#define TK_BITAND 106
-#define TK_BITOR 107
-#define TK_LSHIFT 108
-#define TK_RSHIFT 109
-#define TK_PLUS 110
-#define TK_MINUS 111
-#define TK_STAR 112
-#define TK_SLASH 113
-#define TK_REM 114
-#define TK_CONCAT 115
-#define TK_PTR 116
-#define TK_COLLATE 117
-#define TK_BITNOT 118
-#define TK_ON 119
-#define TK_INDEXED 120
-#define TK_STRING 121
-#define TK_JOIN_KW 122
-#define TK_CONSTRAINT 123
-#define TK_DEFAULT 124
-#define TK_NULL 125
-#define TK_PRIMARY 126
-#define TK_UNIQUE 127
-#define TK_CHECK 128
-#define TK_REFERENCES 129
-#define TK_AUTOINCR 130
-#define TK_INSERT 131
-#define TK_DELETE 132
-#define TK_UPDATE 133
-#define TK_SET 134
-#define TK_DEFERRABLE 135
-#define TK_FOREIGN 136
-#define TK_DROP 137
-#define TK_BLOB 138
-#define TK_UNION 139
-#define TK_ALL 140
-#define TK_EXCEPT 141
-#define TK_INTERSECT 142
-#define TK_SELECT 143
-#define TK_VALUES 144
-#define TK_DISTINCT 145
-#define TK_DOT 146
-#define TK_FROM 147
-#define TK_JOIN 148
-#define TK_USING 149
-#define TK_ORDER 150
-#define TK_GROUP 151
-#define TK_HAVING 152
-#define TK_LIMIT 153
-#define TK_WHERE 154
-#define TK_RETURNING 155
-#define TK_INTO 156
-#define TK_NOTHING 157
-#define TK_FLOAT 158
-#define TK_INTEGER 159
-#define TK_VARIABLE 160
-#define TK_CASE 161
-#define TK_WHEN 162
-#define TK_THEN 163
-#define TK_ELSE 164
-#define TK_INDEX 165
-#define TK_ALTER 166
-#define TK_ADD 167
-#define TK_WINDOW 168
-#define TK_OVER 169
-#define TK_FILTER 170
-#define TK_COLUMN 171
-#define TK_AGG_FUNCTION 172
-#define TK_AGG_COLUMN 173
-#define TK_TRUEFALSE 174
-#define TK_ISNOT 175
-#define TK_UMINUS 176
-#define TK_UPLUS 177
+#define TK_ISNOT 50
+#define TK_MATCH 51
+#define TK_LIKE_KW 52
+#define TK_BETWEEN 53
+#define TK_IN 54
+#define TK_ISNULL 55
+#define TK_NOTNULL 56
+#define TK_NE 57
+#define TK_EQ 58
+#define TK_GT 59
+#define TK_LE 60
+#define TK_LT 61
+#define TK_GE 62
+#define TK_ESCAPE 63
+#define TK_ID 64
+#define TK_COLUMNKW 65
+#define TK_DO 66
+#define TK_FOR 67
+#define TK_IGNORE 68
+#define TK_INITIALLY 69
+#define TK_INSTEAD 70
+#define TK_NO 71
+#define TK_KEY 72
+#define TK_OF 73
+#define TK_OFFSET 74
+#define TK_PRAGMA 75
+#define TK_RAISE 76
+#define TK_RECURSIVE 77
+#define TK_REPLACE 78
+#define TK_RESTRICT 79
+#define TK_ROW 80
+#define TK_ROWS 81
+#define TK_TRIGGER 82
+#define TK_VACUUM 83
+#define TK_VIEW 84
+#define TK_VIRTUAL 85
+#define TK_WITH 86
+#define TK_NULLS 87
+#define TK_FIRST 88
+#define TK_LAST 89
+#define TK_CURRENT 90
+#define TK_FOLLOWING 91
+#define TK_PARTITION 92
+#define TK_PRECEDING 93
+#define TK_RANGE 94
+#define TK_UNBOUNDED 95
+#define TK_EXCLUDE 96
+#define TK_GROUPS 97
+#define TK_OTHERS 98
+#define TK_TIES 99
+#define TK_GENERATED 100
+#define TK_ALWAYS 101
+#define TK_MATERIALIZED 102
+#define TK_REINDEX 103
+#define TK_RENAME 104
+#define TK_CTIME_KW 105
+#define TK_ANY 106
+#define TK_BITAND 107
+#define TK_BITOR 108
+#define TK_LSHIFT 109
+#define TK_RSHIFT 110
+#define TK_PLUS 111
+#define TK_MINUS 112
+#define TK_STAR 113
+#define TK_SLASH 114
+#define TK_REM 115
+#define TK_CONCAT 116
+#define TK_PTR 117
+#define TK_COLLATE 118
+#define TK_BITNOT 119
+#define TK_ON 120
+#define TK_INDEXED 121
+#define TK_STRING 122
+#define TK_JOIN_KW 123
+#define TK_CONSTRAINT 124
+#define TK_DEFAULT 125
+#define TK_NULL 126
+#define TK_PRIMARY 127
+#define TK_UNIQUE 128
+#define TK_CHECK 129
+#define TK_REFERENCES 130
+#define TK_AUTOINCR 131
+#define TK_INSERT 132
+#define TK_DELETE 133
+#define TK_UPDATE 134
+#define TK_SET 135
+#define TK_DEFERRABLE 136
+#define TK_FOREIGN 137
+#define TK_DROP 138
+#define TK_BLOB 139
+#define TK_UNION 140
+#define TK_ALL 141
+#define TK_EXCEPT 142
+#define TK_INTERSECT 143
+#define TK_SELECT 144
+#define TK_VALUES 145
+#define TK_DISTINCT 146
+#define TK_DOT 147
+#define TK_FROM 148
+#define TK_JOIN 149
+#define TK_USING 150
+#define TK_ORDER 151
+#define TK_GROUP 152
+#define TK_HAVING 153
+#define TK_LIMIT 154
+#define TK_WHERE 155
+#define TK_RETURNING 156
+#define TK_INTO 157
+#define TK_NOTHING 158
+#define TK_FLOAT 159
+#define TK_INTEGER 160
+#define TK_VARIABLE 161
+#define TK_CASE 162
+#define TK_WHEN 163
+#define TK_THEN 164
+#define TK_ELSE 165
+#define TK_INDEX 166
+#define TK_ALTER 167
+#define TK_ADD 168
+#define TK_WINDOW 169
+#define TK_OVER 170
+#define TK_FILTER 171
+#define TK_COLUMN 172
+#define TK_AGG_FUNCTION 173
+#define TK_AGG_COLUMN 174
+#define TK_TRUEFALSE 175
+#define TK_UPLUS 176
+#define TK_UMINUS 177
#define TK_TRUTH 178
#define TK_REGISTER 179
#define TK_VECTOR 180
@@ -174000,8 +176902,9 @@ static void updateDeleteLimitError(
#define TK_ASTERISK 183
#define TK_SPAN 184
#define TK_ERROR 185
-#define TK_SPACE 186
-#define TK_ILLEGAL 187
+#define TK_QNUMBER 186
+#define TK_SPACE 187
+#define TK_ILLEGAL 188
#endif
/**************** End token definitions ***************************************/
@@ -174042,6 +176945,9 @@ static void updateDeleteLimitError(
** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser
** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser
** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context
+** YYREALLOC Name of the realloc() function to use
+** YYFREE Name of the free() function to use
+** YYDYNSTACK True if stack space should be extended on heap
** YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
** YYNSTATE the combined number of states.
@@ -174055,37 +176961,39 @@ static void updateDeleteLimitError(
** YY_NO_ACTION The yy_action[] code for no-op
** YY_MIN_REDUCE Minimum value for reduce actions
** YY_MAX_REDUCE Maximum value for reduce actions
+** YY_MIN_DSTRCTR Minimum symbol value that has a destructor
+** YY_MAX_DSTRCTR Maximum symbol value that has a destructor
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned short int
-#define YYNOCODE 323
+#define YYNOCODE 326
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 105
+#define YYWILDCARD 106
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- u32 yy9;
- struct TrigEvent yy28;
- With* yy125;
- IdList* yy204;
- struct FrameBound yy205;
- TriggerStep* yy319;
- const char* yy342;
- Cte* yy361;
- ExprList* yy402;
- Upsert* yy403;
- OnOrUsing yy421;
- u8 yy444;
- struct {int value; int mask;} yy481;
- Window* yy483;
- int yy502;
- SrcList* yy563;
- Expr* yy590;
- Select* yy637;
+ Expr* yy66;
+ ExprList* yy70;
+ struct TrigEvent yy158;
+ Upsert* yy186;
+ u32 yy191;
+ TriggerStep* yy243;
+ Window* yy255;
+ int yy320;
+ IdList* yy332;
+ u8 yy390;
+ const char* yy400;
+ struct FrameBound yy417;
+ Cte* yy487;
+ OnOrUsing yy497;
+ With* yy523;
+ struct {int value; int mask;} yy571;
+ SrcList* yy595;
+ Select* yy599;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -174095,24 +177003,29 @@ typedef union {
#define sqlite3ParserARG_PARAM
#define sqlite3ParserARG_FETCH
#define sqlite3ParserARG_STORE
+#define YYREALLOC parserStackRealloc
+#define YYFREE sqlite3_free
+#define YYDYNSTACK 1
#define sqlite3ParserCTX_SDECL Parse *pParse;
#define sqlite3ParserCTX_PDECL ,Parse *pParse
#define sqlite3ParserCTX_PARAM ,pParse
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
#define YYFALLBACK 1
-#define YYNSTATE 597
-#define YYNRULE 413
-#define YYNRULE_WITH_ACTION 348
-#define YYNTOKEN 188
-#define YY_MAX_SHIFT 596
-#define YY_MIN_SHIFTREDUCE 861
-#define YY_MAX_SHIFTREDUCE 1273
-#define YY_ERROR_ACTION 1274
-#define YY_ACCEPT_ACTION 1275
-#define YY_NO_ACTION 1276
-#define YY_MIN_REDUCE 1277
-#define YY_MAX_REDUCE 1689
+#define YYNSTATE 601
+#define YYNRULE 417
+#define YYNRULE_WITH_ACTION 352
+#define YYNTOKEN 189
+#define YY_MAX_SHIFT 600
+#define YY_MIN_SHIFTREDUCE 868
+#define YY_MAX_SHIFTREDUCE 1284
+#define YY_ERROR_ACTION 1285
+#define YY_ACCEPT_ACTION 1286
+#define YY_NO_ACTION 1287
+#define YY_MIN_REDUCE 1288
+#define YY_MAX_REDUCE 1704
+#define YY_MIN_DSTRCTR 208
+#define YY_MAX_DSTRCTR 323
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
@@ -174128,6 +177041,22 @@ typedef union {
# define yytestcase(X)
#endif
+/* Macro to determine if stack space has the ability to grow using
+** heap memory.
+*/
+#if YYSTACKDEPTH<=0 || YYDYNSTACK
+# define YYGROWABLESTACK 1
+#else
+# define YYGROWABLESTACK 0
+#endif
+
+/* Guarantee a minimum number of initial stack slots.
+*/
+#if YYSTACKDEPTH<=0
+# undef YYSTACKDEPTH
+# define YYSTACKDEPTH 2 /* Need a minimum stack size */
+#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
@@ -174179,628 +177108,652 @@ typedef union {
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (2119)
+#define YY_ACTTAB_COUNT (2224)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 119, 116, 235, 590, 1350, 590, 1329, 565, 590, 493,
- /* 10 */ 397, 590, 393, 590, 1350, 590, 119, 116, 235, 590,
- /* 20 */ 424, 544, 1567, 584, 584, 584, 42, 42, 42, 42,
- /* 30 */ 390, 13, 13, 1002, 72, 72, 72, 72, 42, 42,
- /* 40 */ 1312, 1003, 71, 71, 16, 16, 436, 126, 127, 81,
- /* 50 */ 1248, 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125,
- /* 60 */ 125, 125, 424, 1303, 1275, 1, 1, 596, 2, 1279,
- /* 70 */ 1303, 572, 1315, 572, 327, 1300, 144, 1355, 1355, 546,
- /* 80 */ 592, 571, 592, 1366, 302, 119, 116, 235, 545, 126,
- /* 90 */ 127, 81, 1248, 1248, 1082, 1085, 1072, 1072, 124, 124,
- /* 100 */ 125, 125, 125, 125, 396, 1314, 123, 123, 123, 123,
- /* 110 */ 122, 122, 121, 121, 121, 120, 117, 461, 295, 295,
- /* 120 */ 391, 566, 566, 295, 295, 1607, 389, 1609, 101, 388,
- /* 130 */ 1190, 587, 1195, 424, 1195, 433, 587, 1607, 559, 102,
- /* 140 */ 268, 232, 493, 1190, 145, 246, 1190, 461, 123, 123,
- /* 150 */ 123, 123, 122, 122, 121, 121, 121, 120, 117, 461,
- /* 160 */ 126, 127, 81, 1248, 1248, 1082, 1085, 1072, 1072, 124,
- /* 170 */ 124, 125, 125, 125, 125, 119, 116, 235, 465, 121,
- /* 180 */ 121, 121, 120, 117, 461, 588, 128, 957, 957, 290,
- /* 190 */ 123, 123, 123, 123, 122, 122, 121, 121, 121, 120,
- /* 200 */ 117, 461, 326, 581, 337, 261, 1126, 424, 526, 523,
- /* 210 */ 522, 125, 125, 125, 125, 118, 195, 305, 521, 123,
- /* 220 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117,
- /* 230 */ 461, 9, 911, 271, 126, 127, 81, 1248, 1248, 1082,
- /* 240 */ 1085, 1072, 1072, 124, 124, 125, 125, 125, 125, 424,
- /* 250 */ 119, 116, 235, 1602, 84, 1652, 1224, 6, 83, 123,
- /* 260 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117,
- /* 270 */ 461, 1244, 335, 472, 484, 353, 126, 127, 81, 1248,
- /* 280 */ 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125, 125,
- /* 290 */ 125, 472, 471, 123, 123, 123, 123, 122, 122, 121,
- /* 300 */ 121, 121, 120, 117, 461, 122, 122, 121, 121, 121,
- /* 310 */ 120, 117, 461, 1224, 1225, 1224, 493, 1190, 230, 537,
- /* 320 */ 424, 125, 125, 125, 125, 1224, 484, 353, 555, 1244,
- /* 330 */ 1190, 281, 280, 1190, 386, 123, 123, 123, 123, 122,
- /* 340 */ 122, 121, 121, 121, 120, 117, 461, 126, 127, 81,
- /* 350 */ 1248, 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125,
- /* 360 */ 125, 125, 1128, 1531, 1224, 472, 1128, 1224, 433, 123,
- /* 370 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117,
- /* 380 */ 461, 1190, 1224, 1225, 1224, 261, 1224, 554, 526, 523,
- /* 390 */ 522, 308, 562, 513, 1190, 495, 590, 1190, 521, 147,
- /* 400 */ 508, 1069, 1069, 1083, 1086, 214, 123, 123, 123, 123,
- /* 410 */ 122, 122, 121, 121, 121, 120, 117, 461, 422, 134,
- /* 420 */ 134, 1224, 1225, 1224, 1224, 1225, 1224, 1353, 1353, 424,
- /* 430 */ 879, 476, 988, 369, 196, 214, 1224, 212, 427, 214,
- /* 440 */ 313, 421, 313, 1224, 1225, 1224, 1595, 401, 410, 149,
- /* 450 */ 424, 553, 416, 358, 527, 220, 126, 127, 81, 1248,
- /* 460 */ 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125, 125,
- /* 470 */ 125, 424, 297, 33, 1224, 904, 1073, 126, 127, 81,
- /* 480 */ 1248, 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125,
- /* 490 */ 125, 125, 482, 1224, 1225, 1224, 568, 466, 126, 127,
- /* 500 */ 81, 1248, 1248, 1082, 1085, 1072, 1072, 124, 124, 125,
- /* 510 */ 125, 125, 125, 1224, 150, 123, 123, 123, 123, 122,
- /* 520 */ 122, 121, 121, 121, 120, 117, 461, 1224, 234, 590,
- /* 530 */ 384, 1224, 1225, 1224, 228, 1104, 123, 123, 123, 123,
- /* 540 */ 122, 122, 121, 121, 121, 120, 117, 461, 866, 867,
- /* 550 */ 868, 869, 72, 72, 988, 1623, 413, 123, 123, 123,
- /* 560 */ 123, 122, 122, 121, 121, 121, 120, 117, 461, 443,
- /* 570 */ 1224, 1225, 1224, 1521, 458, 457, 589, 590, 424, 1683,
- /* 580 */ 408, 179, 897, 1253, 1224, 1225, 1224, 1224, 1255, 572,
- /* 590 */ 1646, 295, 295, 458, 457, 1640, 1254, 450, 1322, 424,
- /* 600 */ 136, 136, 474, 1208, 587, 126, 127, 81, 1248, 1248,
- /* 610 */ 1082, 1085, 1072, 1072, 124, 124, 125, 125, 125, 125,
- /* 620 */ 424, 491, 1256, 1256, 1060, 499, 126, 127, 81, 1248,
- /* 630 */ 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125, 125,
- /* 640 */ 125, 1256, 1256, 5, 1224, 1225, 1224, 126, 127, 81,
- /* 650 */ 1248, 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125,
- /* 660 */ 125, 125, 99, 433, 123, 123, 123, 123, 122, 122,
- /* 670 */ 121, 121, 121, 120, 117, 461, 101, 900, 265, 1224,
- /* 680 */ 86, 590, 1536, 1224, 513, 123, 123, 123, 123, 122,
- /* 690 */ 122, 121, 121, 121, 120, 117, 461, 538, 538, 590,
- /* 700 */ 1536, 1538, 6, 387, 13, 13, 123, 123, 123, 123,
- /* 710 */ 122, 122, 121, 121, 121, 120, 117, 461, 1059, 441,
- /* 720 */ 1600, 590, 56, 56, 6, 304, 590, 424, 968, 1566,
- /* 730 */ 1190, 1043, 213, 565, 900, 1048, 1224, 1225, 1224, 1047,
- /* 740 */ 1224, 1225, 1224, 1190, 57, 57, 1190, 429, 424, 15,
- /* 750 */ 15, 499, 1047, 145, 126, 127, 81, 1248, 1248, 1082,
- /* 760 */ 1085, 1072, 1072, 124, 124, 125, 125, 125, 125, 424,
- /* 770 */ 590, 550, 1047, 1049, 1536, 126, 127, 81, 1248, 1248,
- /* 780 */ 1082, 1085, 1072, 1072, 124, 124, 125, 125, 125, 125,
- /* 790 */ 233, 3, 473, 72, 72, 1224, 126, 127, 81, 1248,
- /* 800 */ 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125, 125,
- /* 810 */ 125, 326, 581, 123, 123, 123, 123, 122, 122, 121,
- /* 820 */ 121, 121, 120, 117, 461, 1224, 590, 120, 117, 461,
- /* 830 */ 551, 1224, 493, 367, 123, 123, 123, 123, 122, 122,
- /* 840 */ 121, 121, 121, 120, 117, 461, 1224, 590, 1596, 72,
- /* 850 */ 72, 350, 1224, 1225, 1224, 123, 123, 123, 123, 122,
- /* 860 */ 122, 121, 121, 121, 120, 117, 461, 459, 459, 459,
- /* 870 */ 13, 13, 179, 1171, 1681, 1601, 1681, 1059, 590, 6,
- /* 880 */ 990, 395, 1224, 1225, 1224, 444, 322, 424, 1224, 1225,
- /* 890 */ 1224, 105, 215, 152, 1048, 203, 214, 362, 1047, 365,
- /* 900 */ 1577, 44, 44, 1224, 1225, 1224, 1579, 310, 424, 411,
- /* 910 */ 989, 1047, 108, 469, 126, 127, 81, 1248, 1248, 1082,
- /* 920 */ 1085, 1072, 1072, 124, 124, 125, 125, 125, 125, 424,
- /* 930 */ 1599, 1047, 1049, 892, 6, 126, 127, 81, 1248, 1248,
- /* 940 */ 1082, 1085, 1072, 1072, 124, 124, 125, 125, 125, 125,
- /* 950 */ 1171, 1682, 499, 1682, 12, 1169, 126, 115, 81, 1248,
- /* 960 */ 1248, 1082, 1085, 1072, 1072, 124, 124, 125, 125, 125,
- /* 970 */ 125, 1458, 428, 123, 123, 123, 123, 122, 122, 121,
- /* 980 */ 121, 121, 120, 117, 461, 590, 1391, 321, 563, 563,
- /* 990 */ 1575, 892, 300, 6, 123, 123, 123, 123, 122, 122,
- /* 1000 */ 121, 121, 121, 120, 117, 461, 590, 1474, 72, 72,
- /* 1010 */ 547, 590, 326, 581, 343, 123, 123, 123, 123, 122,
- /* 1020 */ 122, 121, 121, 121, 120, 117, 461, 295, 295, 13,
- /* 1030 */ 13, 561, 1169, 500, 13, 13, 424, 1458, 214, 590,
- /* 1040 */ 587, 438, 341, 114, 312, 323, 382, 1620, 1038, 449,
- /* 1050 */ 560, 467, 311, 386, 130, 505, 145, 424, 590, 1201,
- /* 1060 */ 501, 590, 58, 58, 127, 81, 1248, 1248, 1082, 1085,
- /* 1070 */ 1072, 1072, 124, 124, 125, 125, 125, 125, 339, 1598,
- /* 1080 */ 342, 72, 72, 6, 13, 13, 81, 1248, 1248, 1082,
- /* 1090 */ 1085, 1072, 1072, 124, 124, 125, 125, 125, 125, 206,
- /* 1100 */ 12, 155, 351, 1626, 596, 2, 1279, 439, 330, 98,
- /* 1110 */ 548, 327, 1201, 144, 326, 581, 112, 582, 456, 4,
- /* 1120 */ 1366, 331, 123, 123, 123, 123, 122, 122, 121, 121,
- /* 1130 */ 121, 120, 117, 461, 585, 1038, 518, 590, 386, 549,
- /* 1140 */ 590, 420, 419, 123, 123, 123, 123, 122, 122, 121,
- /* 1150 */ 121, 121, 120, 117, 461, 295, 295, 309, 98, 462,
- /* 1160 */ 13, 13, 340, 13, 13, 1594, 265, 568, 587, 112,
- /* 1170 */ 582, 579, 4, 590, 209, 207, 407, 1269, 567, 483,
- /* 1180 */ 590, 145, 246, 334, 573, 590, 158, 585, 549, 351,
- /* 1190 */ 479, 338, 295, 295, 1458, 920, 72, 72, 1370, 386,
- /* 1200 */ 1059, 8, 590, 45, 45, 587, 110, 110, 59, 59,
- /* 1210 */ 587, 1147, 462, 539, 111, 465, 462, 591, 462, 295,
- /* 1220 */ 295, 1047, 590, 513, 579, 52, 52, 1148, 530, 1131,
- /* 1230 */ 1131, 510, 587, 572, 1047, 429, 921, 1361, 557, 326,
- /* 1240 */ 581, 574, 1149, 556, 1403, 72, 72, 154, 295, 295,
- /* 1250 */ 1594, 372, 513, 1059, 1047, 1049, 1050, 28, 1270, 110,
- /* 1260 */ 110, 587, 540, 1402, 440, 940, 384, 111, 1530, 462,
- /* 1270 */ 591, 462, 295, 295, 1047, 941, 112, 582, 1298, 4,
- /* 1280 */ 541, 292, 460, 988, 513, 587, 478, 1047, 1625, 1212,
- /* 1290 */ 464, 386, 446, 286, 585, 1365, 1473, 1362, 575, 405,
- /* 1300 */ 405, 404, 283, 402, 1472, 453, 876, 1047, 1049, 1050,
- /* 1310 */ 28, 1594, 17, 295, 295, 295, 295, 590, 547, 462,
- /* 1320 */ 240, 1147, 333, 1458, 590, 534, 587, 513, 587, 1358,
- /* 1330 */ 332, 579, 590, 295, 295, 382, 1620, 1148, 1583, 156,
- /* 1340 */ 60, 60, 1458, 382, 1620, 557, 587, 61, 61, 477,
- /* 1350 */ 558, 489, 1149, 963, 434, 62, 62, 475, 962, 421,
- /* 1360 */ 1059, 475, 242, 407, 1170, 590, 110, 110, 590, 344,
- /* 1370 */ 172, 228, 360, 143, 111, 578, 462, 591, 462, 234,
- /* 1380 */ 1651, 1047, 929, 112, 582, 1555, 4, 222, 63, 63,
- /* 1390 */ 241, 46, 46, 502, 1047, 303, 1212, 464, 590, 303,
- /* 1400 */ 286, 585, 299, 1594, 1389, 988, 405, 405, 404, 283,
- /* 1410 */ 402, 590, 509, 876, 1047, 1049, 1050, 28, 548, 1304,
- /* 1420 */ 430, 47, 47, 1554, 590, 423, 462, 240, 1227, 333,
- /* 1430 */ 1458, 326, 581, 286, 48, 48, 329, 332, 579, 405,
- /* 1440 */ 405, 404, 283, 402, 503, 1270, 876, 50, 50, 497,
- /* 1450 */ 112, 582, 557, 4, 470, 583, 430, 556, 326, 581,
- /* 1460 */ 240, 1243, 333, 289, 289, 468, 590, 1059, 585, 242,
- /* 1470 */ 332, 590, 486, 110, 110, 590, 587, 172, 431, 180,
- /* 1480 */ 143, 111, 421, 462, 591, 462, 1227, 243, 1047, 51,
- /* 1490 */ 51, 590, 223, 462, 64, 64, 590, 241, 65, 65,
- /* 1500 */ 454, 1047, 242, 296, 296, 579, 264, 263, 262, 1002,
- /* 1510 */ 172, 239, 590, 143, 66, 66, 587, 1003, 490, 14,
- /* 1520 */ 14, 1047, 1049, 1050, 28, 271, 112, 582, 421, 4,
- /* 1530 */ 241, 109, 423, 107, 1059, 67, 67, 325, 326, 581,
- /* 1540 */ 110, 110, 967, 590, 585, 294, 232, 421, 111, 498,
- /* 1550 */ 462, 591, 462, 590, 485, 1047, 87, 219, 1166, 1264,
- /* 1560 */ 409, 470, 590, 1244, 907, 423, 132, 132, 1047, 462,
- /* 1570 */ 31, 326, 581, 590, 963, 590, 133, 133, 348, 962,
- /* 1580 */ 356, 579, 223, 590, 162, 68, 68, 506, 1047, 1049,
- /* 1590 */ 1050, 28, 919, 918, 470, 590, 53, 53, 69, 69,
- /* 1600 */ 926, 927, 80, 582, 32, 4, 70, 70, 245, 448,
- /* 1610 */ 1059, 590, 507, 590, 373, 1399, 110, 110, 54, 54,
- /* 1620 */ 585, 1244, 907, 595, 111, 1279, 462, 591, 462, 590,
- /* 1630 */ 327, 1047, 144, 947, 165, 165, 166, 166, 590, 1366,
- /* 1640 */ 153, 361, 39, 364, 1047, 462, 349, 590, 101, 590,
- /* 1650 */ 948, 570, 77, 77, 366, 543, 487, 579, 519, 590,
- /* 1660 */ 267, 55, 55, 368, 1047, 1049, 1050, 28, 1125, 1125,
- /* 1670 */ 73, 73, 135, 135, 295, 295, 1124, 1124, 112, 582,
- /* 1680 */ 306, 4, 74, 74, 380, 590, 1059, 587, 529, 1040,
- /* 1690 */ 1346, 270, 110, 110, 379, 492, 585, 270, 1333, 590,
- /* 1700 */ 111, 246, 462, 591, 462, 1330, 445, 1047, 163, 163,
- /* 1710 */ 535, 1332, 279, 298, 381, 532, 376, 531, 266, 1113,
- /* 1720 */ 1047, 462, 137, 137, 372, 1331, 590, 569, 494, 590,
- /* 1730 */ 270, 590, 375, 579, 465, 590, 1175, 590, 1005, 1006,
- /* 1740 */ 1047, 1049, 1050, 28, 385, 1412, 354, 590, 101, 131,
- /* 1750 */ 131, 1457, 164, 164, 157, 157, 205, 1385, 141, 141,
- /* 1760 */ 140, 140, 1059, 590, 960, 590, 114, 1397, 110, 110,
- /* 1770 */ 138, 138, 1051, 370, 590, 101, 111, 1113, 462, 591,
- /* 1780 */ 462, 1614, 590, 1047, 576, 577, 139, 139, 76, 76,
- /* 1790 */ 161, 590, 101, 1109, 1462, 267, 1047, 78, 78, 590,
- /* 1800 */ 993, 890, 270, 151, 1311, 75, 75, 961, 1302, 114,
- /* 1810 */ 1301, 1289, 1288, 406, 43, 43, 1047, 1049, 1050, 28,
- /* 1820 */ 1290, 1633, 49, 49, 514, 217, 1382, 11, 287, 238,
- /* 1830 */ 1051, 318, 319, 320, 1439, 225, 1444, 346, 301, 1449,
- /* 1840 */ 1432, 347, 496, 307, 352, 229, 1448, 1394, 1329, 524,
- /* 1850 */ 414, 378, 1527, 1526, 210, 400, 211, 224, 1636, 1395,
- /* 1860 */ 580, 1393, 1392, 1264, 182, 274, 1574, 236, 1261, 1572,
- /* 1870 */ 432, 86, 221, 193, 1532, 186, 1445, 82, 36, 177,
- /* 1880 */ 480, 85, 188, 189, 247, 190, 191, 481, 517, 249,
- /* 1890 */ 99, 1453, 197, 198, 37, 504, 412, 488, 1451, 415,
- /* 1900 */ 355, 1519, 1450, 253, 255, 92, 512, 202, 288, 257,
- /* 1910 */ 515, 363, 258, 417, 1291, 259, 533, 1349, 1340, 1348,
- /* 1920 */ 1347, 447, 1543, 94, 911, 359, 230, 1650, 451, 1318,
- /* 1930 */ 1649, 452, 272, 273, 455, 1319, 418, 377, 1417, 316,
- /* 1940 */ 1416, 1317, 1648, 317, 129, 542, 1375, 383, 1339, 1619,
- /* 1950 */ 568, 10, 106, 1506, 394, 100, 324, 552, 1605, 35,
- /* 1960 */ 1604, 593, 1218, 285, 282, 284, 594, 1286, 1280, 425,
- /* 1970 */ 167, 426, 181, 168, 1559, 1560, 392, 216, 1374, 148,
- /* 1980 */ 398, 399, 226, 862, 463, 169, 1558, 314, 218, 170,
- /* 1990 */ 1557, 328, 183, 184, 237, 227, 79, 146, 1123, 1121,
- /* 2000 */ 336, 185, 173, 1243, 187, 943, 345, 244, 248, 1137,
- /* 2010 */ 192, 174, 175, 88, 435, 89, 194, 90, 91, 176,
- /* 2020 */ 251, 1140, 437, 250, 1136, 159, 270, 18, 252, 357,
- /* 2030 */ 442, 254, 1258, 511, 1129, 199, 256, 200, 38, 878,
- /* 2040 */ 379, 516, 260, 520, 525, 201, 528, 93, 19, 909,
- /* 2050 */ 371, 20, 374, 95, 178, 160, 96, 536, 40, 922,
- /* 2060 */ 1206, 1088, 315, 1177, 97, 1176, 231, 291, 21, 293,
- /* 2070 */ 997, 204, 991, 114, 1196, 1200, 269, 22, 23, 1181,
- /* 2080 */ 24, 7, 25, 1194, 1192, 1199, 26, 34, 564, 27,
- /* 2090 */ 103, 208, 101, 1102, 104, 1089, 1087, 1091, 1146, 1092,
- /* 2100 */ 1145, 275, 276, 29, 41, 277, 1052, 891, 113, 30,
- /* 2110 */ 586, 956, 278, 1641, 171, 142, 403, 1214, 1213,
+ /* 0 */ 130, 127, 238, 594, 1366, 1366, 292, 435, 6, 1286,
+ /* 10 */ 1, 1, 600, 2, 1290, 392, 130, 127, 238, 329,
+ /* 20 */ 426, 154, 1641, 600, 2, 1290, 51, 51, 1377, 502,
+ /* 30 */ 329, 548, 154, 1011, 1323, 184, 409, 1280, 1580, 1377,
+ /* 40 */ 498, 1012, 393, 873, 874, 875, 876, 137, 138, 91,
+ /* 50 */ 1326, 1259, 1259, 1091, 1094, 1081, 1081, 135, 135, 136,
+ /* 60 */ 136, 136, 136, 297, 297, 157, 297, 297, 130, 127,
+ /* 70 */ 238, 130, 127, 238, 297, 297, 591, 339, 580, 591,
+ /* 80 */ 1314, 580, 594, 213, 271, 235, 302, 591, 486, 580,
+ /* 90 */ 311, 249, 1311, 136, 136, 136, 136, 129, 130, 127,
+ /* 100 */ 238, 399, 249, 395, 564, 51, 51, 134, 134, 134,
+ /* 110 */ 134, 133, 133, 132, 132, 132, 131, 128, 464, 1281,
+ /* 120 */ 184, 297, 297, 563, 468, 297, 297, 1623, 426, 390,
+ /* 130 */ 306, 568, 1211, 1616, 591, 468, 580, 7, 591, 1235,
+ /* 140 */ 580, 134, 134, 134, 134, 133, 133, 132, 132, 132,
+ /* 150 */ 131, 128, 464, 541, 541, 137, 138, 91, 7, 1259,
+ /* 160 */ 1259, 1091, 1094, 1081, 1081, 135, 135, 136, 136, 136,
+ /* 170 */ 136, 134, 134, 134, 134, 133, 133, 132, 132, 132,
+ /* 180 */ 131, 128, 464, 328, 585, 1211, 461, 460, 594, 132,
+ /* 190 */ 132, 132, 131, 128, 464, 1264, 1235, 1236, 1235, 1205,
+ /* 200 */ 1266, 1205, 136, 136, 136, 136, 1621, 391, 1265, 283,
+ /* 210 */ 282, 51, 51, 475, 1200, 134, 134, 134, 134, 133,
+ /* 220 */ 133, 132, 132, 132, 131, 128, 464, 1200, 1235, 1047,
+ /* 230 */ 1200, 475, 474, 242, 1267, 1267, 426, 44, 566, 566,
+ /* 240 */ 907, 1137, 112, 7, 516, 1137, 1235, 569, 569, 369,
+ /* 250 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
+ /* 260 */ 128, 464, 1235, 137, 138, 91, 218, 1259, 1259, 1091,
+ /* 270 */ 1094, 1081, 1081, 135, 135, 136, 136, 136, 136, 412,
+ /* 280 */ 511, 1068, 1275, 353, 594, 1235, 1236, 1235, 264, 1579,
+ /* 290 */ 139, 529, 526, 525, 594, 328, 585, 907, 1057, 1235,
+ /* 300 */ 496, 524, 1056, 1235, 1236, 1235, 475, 19, 19, 233,
+ /* 310 */ 540, 426, 1621, 562, 364, 1056, 367, 81, 81, 1235,
+ /* 320 */ 1236, 1235, 438, 134, 134, 134, 134, 133, 133, 132,
+ /* 330 */ 132, 132, 131, 128, 464, 1056, 1058, 200, 137, 138,
+ /* 340 */ 91, 464, 1259, 1259, 1091, 1094, 1081, 1081, 135, 135,
+ /* 350 */ 136, 136, 136, 136, 426, 96, 1235, 1236, 1235, 94,
+ /* 360 */ 487, 355, 1219, 93, 133, 133, 132, 132, 132, 131,
+ /* 370 */ 128, 464, 328, 585, 1047, 44, 304, 496, 1235, 1325,
+ /* 380 */ 398, 137, 138, 91, 426, 1259, 1259, 1091, 1094, 1081,
+ /* 390 */ 1081, 135, 135, 136, 136, 136, 136, 1235, 134, 134,
+ /* 400 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 464,
+ /* 410 */ 45, 137, 138, 91, 476, 1259, 1259, 1091, 1094, 1081,
+ /* 420 */ 1081, 135, 135, 136, 136, 136, 136, 450, 353, 482,
+ /* 430 */ 340, 1667, 375, 328, 585, 1235, 1236, 1235, 588, 588,
+ /* 440 */ 588, 134, 134, 134, 134, 133, 133, 132, 132, 132,
+ /* 450 */ 131, 128, 464, 307, 1235, 1236, 1235, 1235, 1364, 1364,
+ /* 460 */ 516, 594, 426, 594, 461, 460, 371, 131, 128, 464,
+ /* 470 */ 46, 134, 134, 134, 134, 133, 133, 132, 132, 132,
+ /* 480 */ 131, 128, 464, 301, 82, 82, 82, 82, 231, 137,
+ /* 490 */ 138, 91, 1372, 1259, 1259, 1091, 1094, 1081, 1081, 135,
+ /* 500 */ 135, 136, 136, 136, 136, 429, 264, 532, 492, 529,
+ /* 510 */ 526, 525, 1267, 1267, 1235, 1236, 1235, 331, 1614, 524,
+ /* 520 */ 223, 575, 7, 554, 594, 447, 201, 297, 297, 1637,
+ /* 530 */ 549, 281, 300, 383, 535, 378, 534, 269, 1698, 410,
+ /* 540 */ 591, 426, 580, 374, 225, 530, 471, 82, 82, 134,
+ /* 550 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128,
+ /* 560 */ 464, 1235, 426, 547, 496, 469, 911, 1235, 137, 138,
+ /* 570 */ 91, 593, 1259, 1259, 1091, 1094, 1081, 1081, 135, 135,
+ /* 580 */ 136, 136, 136, 136, 324, 477, 22, 22, 1068, 137,
+ /* 590 */ 138, 91, 594, 1259, 1259, 1091, 1094, 1081, 1081, 135,
+ /* 600 */ 135, 136, 136, 136, 136, 1057, 1315, 432, 44, 1056,
+ /* 610 */ 977, 1078, 1078, 1092, 1095, 145, 145, 109, 1235, 1236,
+ /* 620 */ 1235, 594, 1056, 594, 1235, 1236, 1235, 415, 134, 134,
+ /* 630 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 464,
+ /* 640 */ 310, 594, 1056, 1058, 82, 82, 82, 82, 345, 134,
+ /* 650 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128,
+ /* 660 */ 464, 537, 297, 297, 19, 19, 328, 585, 1314, 1219,
+ /* 670 */ 426, 1200, 496, 389, 904, 591, 343, 580, 596, 443,
+ /* 680 */ 596, 575, 558, 575, 1200, 1235, 1082, 1200, 1661, 972,
+ /* 690 */ 574, 426, 452, 494, 971, 1218, 1333, 137, 138, 91,
+ /* 700 */ 1344, 1259, 1259, 1091, 1094, 1081, 1081, 135, 135, 136,
+ /* 710 */ 136, 136, 136, 341, 40, 344, 6, 1235, 137, 138,
+ /* 720 */ 91, 553, 1259, 1259, 1091, 1094, 1081, 1081, 135, 135,
+ /* 730 */ 136, 136, 136, 136, 1200, 587, 432, 111, 291, 291,
+ /* 740 */ 1381, 557, 1235, 1236, 1235, 565, 435, 1200, 312, 594,
+ /* 750 */ 1200, 591, 591, 580, 580, 1235, 386, 134, 134, 134,
+ /* 760 */ 134, 133, 133, 132, 132, 132, 131, 128, 464, 5,
+ /* 770 */ 999, 1309, 82, 82, 1235, 1236, 1235, 594, 134, 134,
+ /* 780 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 464,
+ /* 790 */ 1180, 1696, 1200, 1696, 594, 445, 503, 342, 516, 426,
+ /* 800 */ 19, 19, 236, 1069, 556, 1200, 297, 297, 1200, 325,
+ /* 810 */ 1235, 1607, 1235, 1236, 1235, 446, 216, 147, 147, 591,
+ /* 820 */ 426, 580, 594, 1666, 1052, 936, 137, 138, 91, 1607,
+ /* 830 */ 1259, 1259, 1091, 1094, 1081, 1081, 135, 135, 136, 136,
+ /* 840 */ 136, 136, 594, 1543, 1235, 82, 82, 137, 138, 91,
+ /* 850 */ 1402, 1259, 1259, 1091, 1094, 1081, 1081, 135, 135, 136,
+ /* 860 */ 136, 136, 136, 298, 298, 19, 19, 1235, 1236, 1235,
+ /* 870 */ 218, 1180, 1697, 1178, 1697, 568, 591, 48, 580, 397,
+ /* 880 */ 314, 594, 458, 413, 544, 218, 134, 134, 134, 134,
+ /* 890 */ 133, 133, 132, 132, 132, 131, 128, 464, 470, 594,
+ /* 900 */ 578, 1235, 1236, 1235, 82, 82, 1487, 134, 134, 134,
+ /* 910 */ 134, 133, 133, 132, 132, 132, 131, 128, 464, 297,
+ /* 920 */ 297, 1549, 19, 19, 1609, 125, 388, 435, 426, 998,
+ /* 930 */ 218, 1590, 591, 3, 580, 297, 297, 451, 403, 1549,
+ /* 940 */ 1551, 459, 1608, 418, 388, 1607, 384, 1634, 591, 426,
+ /* 950 */ 580, 997, 1592, 1155, 1178, 137, 138, 91, 1607, 1259,
+ /* 960 */ 1259, 1091, 1094, 1081, 1081, 135, 135, 136, 136, 136,
+ /* 970 */ 136, 594, 337, 472, 1235, 594, 137, 138, 91, 430,
+ /* 980 */ 1259, 1259, 1091, 1094, 1081, 1081, 135, 135, 136, 136,
+ /* 990 */ 136, 136, 1610, 50, 19, 19, 1156, 217, 19, 19,
+ /* 1000 */ 1361, 294, 1340, 997, 1238, 594, 47, 1135, 1607, 570,
+ /* 1010 */ 1361, 594, 1157, 210, 1549, 134, 134, 134, 134, 133,
+ /* 1020 */ 133, 132, 132, 132, 131, 128, 464, 1158, 82, 82,
+ /* 1030 */ 550, 1235, 1236, 1235, 19, 19, 134, 134, 134, 134,
+ /* 1040 */ 133, 133, 132, 132, 132, 131, 128, 464, 237, 211,
+ /* 1050 */ 571, 947, 594, 462, 462, 462, 49, 426, 1608, 516,
+ /* 1060 */ 388, 948, 1238, 508, 1544, 463, 218, 592, 504, 964,
+ /* 1070 */ 964, 1608, 115, 388, 997, 66, 66, 521, 426, 424,
+ /* 1080 */ 1140, 1140, 513, 219, 137, 138, 91, 516, 1259, 1259,
+ /* 1090 */ 1091, 1094, 1081, 1081, 135, 135, 136, 136, 136, 136,
+ /* 1100 */ 237, 315, 502, 315, 1373, 137, 138, 91, 268, 1259,
+ /* 1110 */ 1259, 1091, 1094, 1081, 1081, 135, 135, 136, 136, 136,
+ /* 1120 */ 136, 1608, 1343, 388, 571, 1471, 997, 1156, 487, 355,
+ /* 1130 */ 108, 551, 1369, 409, 1179, 267, 266, 265, 10, 594,
+ /* 1140 */ 274, 1471, 158, 1157, 134, 134, 134, 134, 133, 133,
+ /* 1150 */ 132, 132, 132, 131, 128, 464, 927, 594, 1158, 1486,
+ /* 1160 */ 552, 594, 67, 67, 594, 134, 134, 134, 134, 133,
+ /* 1170 */ 133, 132, 132, 132, 131, 128, 464, 431, 141, 1255,
+ /* 1180 */ 21, 21, 582, 1588, 53, 53, 426, 68, 68, 1471,
+ /* 1190 */ 533, 1471, 268, 374, 1471, 332, 440, 1471, 928, 384,
+ /* 1200 */ 1634, 119, 333, 352, 231, 516, 594, 426, 502, 594,
+ /* 1210 */ 336, 1485, 441, 137, 138, 91, 1281, 1259, 1259, 1091,
+ /* 1220 */ 1094, 1081, 1081, 135, 135, 136, 136, 136, 136, 54,
+ /* 1230 */ 54, 386, 69, 69, 137, 126, 91, 1255, 1259, 1259,
+ /* 1240 */ 1091, 1094, 1081, 1081, 135, 135, 136, 136, 136, 136,
+ /* 1250 */ 362, 384, 1634, 1615, 448, 1404, 323, 7, 97, 222,
+ /* 1260 */ 442, 431, 505, 594, 1416, 512, 422, 421, 456, 594,
+ /* 1270 */ 455, 433, 185, 134, 134, 134, 134, 133, 133, 132,
+ /* 1280 */ 132, 132, 131, 128, 464, 1613, 70, 70, 594, 7,
+ /* 1290 */ 594, 550, 71, 71, 134, 134, 134, 134, 133, 133,
+ /* 1300 */ 132, 132, 132, 131, 128, 464, 594, 479, 594, 313,
+ /* 1310 */ 594, 72, 72, 73, 73, 426, 480, 594, 423, 274,
+ /* 1320 */ 1612, 478, 160, 972, 7, 478, 226, 423, 971, 55,
+ /* 1330 */ 55, 56, 56, 57, 57, 305, 426, 594, 1342, 305,
+ /* 1340 */ 59, 59, 1415, 138, 91, 500, 1259, 1259, 1091, 1094,
+ /* 1350 */ 1081, 1081, 135, 135, 136, 136, 136, 136, 1255, 886,
+ /* 1360 */ 60, 60, 594, 899, 594, 91, 594, 1259, 1259, 1091,
+ /* 1370 */ 1094, 1081, 1081, 135, 135, 136, 136, 136, 136, 120,
+ /* 1380 */ 489, 117, 360, 493, 327, 74, 74, 75, 75, 76,
+ /* 1390 */ 76, 423, 551, 23, 423, 423, 123, 586, 481, 4,
+ /* 1400 */ 296, 235, 134, 134, 134, 134, 133, 133, 132, 132,
+ /* 1410 */ 132, 131, 128, 464, 589, 594, 1255, 111, 594, 38,
+ /* 1420 */ 594, 899, 485, 134, 134, 134, 134, 133, 133, 132,
+ /* 1430 */ 132, 132, 131, 128, 464, 594, 436, 594, 20, 20,
+ /* 1440 */ 465, 77, 77, 143, 143, 594, 501, 594, 1011, 161,
+ /* 1450 */ 108, 16, 583, 914, 39, 1254, 1012, 382, 144, 144,
+ /* 1460 */ 78, 78, 44, 1376, 1175, 1113, 411, 381, 62, 62,
+ /* 1470 */ 79, 79, 246, 123, 586, 166, 4, 594, 926, 925,
+ /* 1480 */ 552, 1068, 1122, 351, 594, 111, 594, 121, 121, 1596,
+ /* 1490 */ 594, 589, 488, 346, 1049, 122, 273, 465, 595, 465,
+ /* 1500 */ 63, 63, 1056, 1534, 594, 1568, 9, 80, 80, 64,
+ /* 1510 */ 64, 914, 1567, 170, 170, 1056, 350, 465, 933, 934,
+ /* 1520 */ 328, 585, 918, 495, 1060, 273, 490, 171, 171, 583,
+ /* 1530 */ 594, 497, 594, 273, 954, 1056, 1058, 1059, 35, 506,
+ /* 1540 */ 1122, 123, 586, 560, 4, 594, 358, 594, 559, 299,
+ /* 1550 */ 308, 955, 546, 87, 87, 65, 65, 594, 1068, 589,
+ /* 1560 */ 594, 509, 1219, 594, 121, 121, 594, 1628, 83, 83,
+ /* 1570 */ 146, 146, 122, 209, 465, 595, 465, 226, 510, 1056,
+ /* 1580 */ 84, 84, 1060, 168, 168, 465, 148, 148, 408, 142,
+ /* 1590 */ 142, 356, 1056, 111, 248, 1412, 522, 583, 270, 372,
+ /* 1600 */ 594, 111, 538, 363, 594, 165, 594, 111, 1118, 12,
+ /* 1610 */ 270, 560, 1056, 1058, 1059, 35, 561, 576, 123, 586,
+ /* 1620 */ 366, 4, 594, 169, 169, 594, 1068, 162, 162, 82,
+ /* 1630 */ 82, 594, 121, 121, 1184, 594, 589, 1014, 1015, 1219,
+ /* 1640 */ 122, 368, 465, 595, 465, 152, 152, 1056, 151, 151,
+ /* 1650 */ 1134, 1134, 297, 297, 149, 149, 1133, 1133, 150, 150,
+ /* 1660 */ 1056, 370, 465, 594, 1357, 591, 575, 580, 594, 1341,
+ /* 1670 */ 1002, 594, 273, 1655, 583, 577, 897, 970, 159, 125,
+ /* 1680 */ 1056, 1058, 1059, 35, 377, 387, 86, 86, 560, 594,
+ /* 1690 */ 1425, 88, 88, 559, 85, 85, 967, 1470, 125, 594,
+ /* 1700 */ 969, 1398, 125, 1068, 517, 1410, 1475, 1219, 581, 121,
+ /* 1710 */ 121, 1322, 52, 52, 1313, 1312, 1300, 122, 1395, 465,
+ /* 1720 */ 595, 465, 58, 58, 1056, 1299, 1301, 1648, 289, 167,
+ /* 1730 */ 228, 1457, 348, 320, 241, 321, 322, 1056, 1640, 1223,
+ /* 1740 */ 467, 1452, 499, 288, 303, 123, 586, 354, 4, 407,
+ /* 1750 */ 407, 406, 285, 404, 1445, 349, 883, 1056, 1058, 1059,
+ /* 1760 */ 35, 1462, 1461, 589, 527, 309, 416, 232, 1340, 380,
+ /* 1770 */ 243, 1540, 335, 1539, 1407, 1275, 402, 1408, 214, 584,
+ /* 1780 */ 334, 187, 1651, 227, 1219, 277, 1406, 1405, 215, 465,
+ /* 1790 */ 1587, 1585, 239, 1272, 434, 1545, 92, 96, 224, 198,
+ /* 1800 */ 191, 583, 182, 95, 483, 193, 194, 250, 1458, 594,
+ /* 1810 */ 195, 196, 13, 245, 484, 520, 252, 109, 414, 1464,
+ /* 1820 */ 542, 177, 123, 586, 43, 4, 491, 14, 1463, 1466,
+ /* 1830 */ 1068, 202, 61, 61, 203, 417, 121, 121, 976, 1532,
+ /* 1840 */ 589, 244, 507, 357, 122, 102, 465, 595, 465, 1556,
+ /* 1850 */ 256, 1056, 258, 515, 361, 297, 297, 207, 290, 260,
+ /* 1860 */ 518, 365, 261, 262, 1056, 1302, 465, 536, 591, 543,
+ /* 1870 */ 580, 104, 1360, 419, 449, 1351, 425, 1359, 583, 1665,
+ /* 1880 */ 1358, 918, 328, 585, 1056, 1058, 1059, 35, 1330, 420,
+ /* 1890 */ 233, 1664, 1329, 379, 453, 1328, 1350, 1663, 1633, 90,
+ /* 1900 */ 586, 454, 4, 545, 318, 473, 319, 1068, 385, 275,
+ /* 1910 */ 276, 1219, 1619, 121, 121, 457, 140, 589, 1618, 571,
+ /* 1920 */ 11, 122, 396, 465, 595, 465, 116, 394, 1056, 326,
+ /* 1930 */ 110, 599, 1386, 1290, 1385, 401, 555, 1430, 329, 1429,
+ /* 1940 */ 154, 1056, 220, 465, 400, 42, 597, 1377, 573, 1229,
+ /* 1950 */ 284, 287, 1519, 598, 286, 583, 1297, 1291, 1572, 172,
+ /* 1960 */ 173, 1056, 1058, 1059, 35, 869, 466, 221, 1573, 156,
+ /* 1970 */ 174, 1571, 316, 188, 330, 1570, 175, 189, 240, 1132,
+ /* 1980 */ 1130, 89, 297, 297, 1068, 186, 427, 229, 1219, 230,
+ /* 1990 */ 121, 121, 155, 190, 338, 591, 428, 580, 122, 178,
+ /* 2000 */ 465, 595, 465, 1223, 467, 1056, 1254, 288, 247, 192,
+ /* 2010 */ 249, 950, 251, 407, 407, 406, 285, 404, 1056, 1146,
+ /* 2020 */ 883, 347, 288, 197, 179, 572, 180, 439, 407, 407,
+ /* 2030 */ 406, 285, 404, 437, 243, 883, 335, 199, 1056, 1058,
+ /* 2040 */ 1059, 35, 98, 468, 334, 99, 181, 100, 1149, 243,
+ /* 2050 */ 101, 335, 253, 254, 1145, 163, 273, 123, 586, 334,
+ /* 2060 */ 4, 24, 255, 514, 359, 1219, 444, 257, 1138, 204,
+ /* 2070 */ 259, 1269, 205, 15, 519, 589, 885, 245, 263, 381,
+ /* 2080 */ 206, 523, 103, 25, 26, 177, 373, 528, 43, 916,
+ /* 2090 */ 376, 105, 245, 929, 531, 317, 164, 183, 539, 107,
+ /* 2100 */ 177, 465, 27, 43, 106, 244, 1216, 1097, 1186, 17,
+ /* 2110 */ 1185, 234, 293, 583, 295, 1006, 272, 208, 1000, 125,
+ /* 2120 */ 244, 28, 1202, 29, 1206, 30, 1204, 31, 32, 8,
+ /* 2130 */ 1209, 1210, 1191, 41, 567, 33, 34, 212, 111, 1111,
+ /* 2140 */ 425, 1098, 1068, 1096, 1100, 113, 328, 585, 121, 121,
+ /* 2150 */ 579, 114, 118, 1154, 278, 425, 122, 1101, 465, 595,
+ /* 2160 */ 465, 328, 585, 1056, 36, 18, 590, 1061, 898, 473,
+ /* 2170 */ 124, 37, 963, 279, 280, 1656, 1056, 176, 153, 405,
+ /* 2180 */ 1225, 1224, 1287, 1287, 473, 1287, 1287, 1287, 1287, 1287,
+ /* 2190 */ 1287, 1287, 1287, 1287, 1287, 1287, 1056, 1058, 1059, 35,
+ /* 2200 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
+ /* 2210 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
+ /* 2220 */ 1287, 1287, 1287, 1219,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 277, 278, 279, 196, 226, 196, 228, 196, 196, 196,
- /* 10 */ 252, 196, 254, 196, 236, 196, 277, 278, 279, 196,
- /* 20 */ 20, 196, 299, 213, 214, 215, 219, 220, 219, 220,
- /* 30 */ 222, 219, 220, 33, 219, 220, 219, 220, 219, 220,
- /* 40 */ 219, 41, 219, 220, 219, 220, 234, 47, 48, 49,
- /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- /* 60 */ 60, 61, 20, 196, 188, 189, 190, 191, 192, 193,
- /* 70 */ 196, 256, 219, 256, 198, 208, 200, 238, 239, 264,
- /* 80 */ 206, 264, 208, 207, 271, 277, 278, 279, 207, 47,
- /* 90 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 100 */ 58, 59, 60, 61, 281, 219, 106, 107, 108, 109,
- /* 110 */ 110, 111, 112, 113, 114, 115, 116, 117, 242, 243,
- /* 120 */ 222, 310, 311, 242, 243, 318, 319, 318, 26, 320,
- /* 130 */ 80, 255, 90, 20, 92, 196, 255, 318, 319, 26,
- /* 140 */ 259, 260, 196, 93, 85, 269, 96, 117, 106, 107,
- /* 150 */ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
- /* 160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 170 */ 57, 58, 59, 60, 61, 277, 278, 279, 302, 112,
- /* 180 */ 113, 114, 115, 116, 117, 139, 73, 141, 142, 216,
- /* 190 */ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
- /* 200 */ 116, 117, 143, 144, 265, 123, 12, 20, 126, 127,
- /* 210 */ 128, 58, 59, 60, 61, 62, 23, 271, 136, 106,
- /* 220 */ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
- /* 230 */ 117, 23, 130, 25, 47, 48, 49, 50, 51, 52,
- /* 240 */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 20,
- /* 250 */ 277, 278, 279, 313, 25, 233, 63, 317, 71, 106,
- /* 260 */ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
- /* 270 */ 117, 63, 196, 196, 132, 133, 47, 48, 49, 50,
- /* 280 */ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- /* 290 */ 61, 214, 215, 106, 107, 108, 109, 110, 111, 112,
- /* 300 */ 113, 114, 115, 116, 117, 110, 111, 112, 113, 114,
- /* 310 */ 115, 116, 117, 120, 121, 122, 196, 80, 169, 170,
- /* 320 */ 20, 58, 59, 60, 61, 63, 132, 133, 91, 121,
- /* 330 */ 93, 27, 28, 96, 196, 106, 107, 108, 109, 110,
- /* 340 */ 111, 112, 113, 114, 115, 116, 117, 47, 48, 49,
- /* 350 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- /* 360 */ 60, 61, 31, 287, 63, 288, 35, 63, 196, 106,
- /* 370 */ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
- /* 380 */ 117, 80, 120, 121, 122, 123, 63, 150, 126, 127,
- /* 390 */ 128, 271, 91, 196, 93, 196, 196, 96, 136, 76,
- /* 400 */ 69, 50, 51, 52, 53, 196, 106, 107, 108, 109,
- /* 410 */ 110, 111, 112, 113, 114, 115, 116, 117, 209, 219,
- /* 420 */ 220, 120, 121, 122, 120, 121, 122, 238, 239, 20,
- /* 430 */ 22, 247, 26, 24, 23, 196, 63, 265, 241, 196,
- /* 440 */ 231, 257, 233, 120, 121, 122, 308, 204, 209, 76,
- /* 450 */ 20, 150, 209, 45, 24, 155, 47, 48, 49, 50,
- /* 460 */ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- /* 470 */ 61, 20, 23, 23, 63, 24, 125, 47, 48, 49,
- /* 480 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- /* 490 */ 60, 61, 84, 120, 121, 122, 150, 300, 47, 48,
- /* 500 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
- /* 510 */ 59, 60, 61, 63, 168, 106, 107, 108, 109, 110,
- /* 520 */ 111, 112, 113, 114, 115, 116, 117, 63, 122, 196,
- /* 530 */ 196, 120, 121, 122, 26, 127, 106, 107, 108, 109,
- /* 540 */ 110, 111, 112, 113, 114, 115, 116, 117, 7, 8,
- /* 550 */ 9, 10, 219, 220, 148, 196, 207, 106, 107, 108,
- /* 560 */ 109, 110, 111, 112, 113, 114, 115, 116, 117, 235,
- /* 570 */ 120, 121, 122, 165, 110, 111, 196, 196, 20, 305,
- /* 580 */ 306, 196, 24, 119, 120, 121, 122, 63, 124, 256,
- /* 590 */ 218, 242, 243, 110, 111, 146, 132, 264, 226, 20,
- /* 600 */ 219, 220, 272, 24, 255, 47, 48, 49, 50, 51,
- /* 610 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- /* 620 */ 20, 272, 158, 159, 24, 196, 47, 48, 49, 50,
- /* 630 */ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- /* 640 */ 61, 158, 159, 23, 120, 121, 122, 47, 48, 49,
- /* 650 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
- /* 660 */ 60, 61, 154, 196, 106, 107, 108, 109, 110, 111,
- /* 670 */ 112, 113, 114, 115, 116, 117, 26, 63, 50, 63,
- /* 680 */ 156, 196, 196, 63, 196, 106, 107, 108, 109, 110,
- /* 690 */ 111, 112, 113, 114, 115, 116, 117, 312, 313, 196,
- /* 700 */ 214, 215, 317, 196, 219, 220, 106, 107, 108, 109,
- /* 710 */ 110, 111, 112, 113, 114, 115, 116, 117, 104, 234,
- /* 720 */ 313, 196, 219, 220, 317, 296, 196, 20, 112, 241,
- /* 730 */ 80, 24, 265, 196, 120, 121, 120, 121, 122, 125,
- /* 740 */ 120, 121, 122, 93, 219, 220, 96, 119, 20, 219,
- /* 750 */ 220, 196, 138, 85, 47, 48, 49, 50, 51, 52,
- /* 760 */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 20,
- /* 770 */ 196, 196, 158, 159, 288, 47, 48, 49, 50, 51,
- /* 780 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- /* 790 */ 196, 23, 124, 219, 220, 63, 47, 48, 49, 50,
- /* 800 */ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- /* 810 */ 61, 143, 144, 106, 107, 108, 109, 110, 111, 112,
- /* 820 */ 113, 114, 115, 116, 117, 63, 196, 115, 116, 117,
- /* 830 */ 256, 63, 196, 17, 106, 107, 108, 109, 110, 111,
- /* 840 */ 112, 113, 114, 115, 116, 117, 63, 196, 311, 219,
- /* 850 */ 220, 296, 120, 121, 122, 106, 107, 108, 109, 110,
- /* 860 */ 111, 112, 113, 114, 115, 116, 117, 213, 214, 215,
- /* 870 */ 219, 220, 196, 23, 24, 313, 26, 104, 196, 317,
- /* 880 */ 148, 196, 120, 121, 122, 234, 256, 20, 120, 121,
- /* 890 */ 122, 163, 25, 23, 121, 26, 196, 81, 125, 83,
- /* 900 */ 196, 219, 220, 120, 121, 122, 196, 271, 20, 209,
- /* 910 */ 148, 138, 163, 196, 47, 48, 49, 50, 51, 52,
- /* 920 */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 20,
- /* 930 */ 313, 158, 159, 63, 317, 47, 48, 49, 50, 51,
- /* 940 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
- /* 950 */ 23, 24, 196, 26, 216, 105, 47, 48, 49, 50,
- /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
- /* 970 */ 61, 196, 201, 106, 107, 108, 109, 110, 111, 112,
- /* 980 */ 113, 114, 115, 116, 117, 196, 262, 263, 312, 313,
- /* 990 */ 196, 121, 207, 317, 106, 107, 108, 109, 110, 111,
- /* 1000 */ 112, 113, 114, 115, 116, 117, 196, 276, 219, 220,
- /* 1010 */ 20, 196, 143, 144, 17, 106, 107, 108, 109, 110,
- /* 1020 */ 111, 112, 113, 114, 115, 116, 117, 242, 243, 219,
- /* 1030 */ 220, 70, 105, 295, 219, 220, 20, 196, 196, 196,
- /* 1040 */ 255, 266, 45, 26, 234, 256, 315, 316, 77, 234,
- /* 1050 */ 89, 209, 296, 196, 23, 284, 85, 20, 196, 98,
- /* 1060 */ 289, 196, 219, 220, 48, 49, 50, 51, 52, 53,
- /* 1070 */ 54, 55, 56, 57, 58, 59, 60, 61, 81, 313,
- /* 1080 */ 83, 219, 220, 317, 219, 220, 49, 50, 51, 52,
- /* 1090 */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 234,
- /* 1100 */ 216, 244, 131, 190, 191, 192, 193, 266, 196, 119,
- /* 1110 */ 120, 198, 151, 200, 143, 144, 20, 21, 256, 23,
- /* 1120 */ 207, 196, 106, 107, 108, 109, 110, 111, 112, 113,
- /* 1130 */ 114, 115, 116, 117, 38, 77, 20, 196, 196, 149,
- /* 1140 */ 196, 110, 111, 106, 107, 108, 109, 110, 111, 112,
- /* 1150 */ 113, 114, 115, 116, 117, 242, 243, 207, 119, 63,
- /* 1160 */ 219, 220, 165, 219, 220, 308, 50, 150, 255, 20,
- /* 1170 */ 21, 75, 23, 196, 290, 234, 23, 24, 234, 295,
- /* 1180 */ 196, 85, 269, 196, 207, 196, 244, 38, 149, 131,
- /* 1190 */ 132, 133, 242, 243, 196, 37, 219, 220, 243, 196,
- /* 1200 */ 104, 52, 196, 219, 220, 255, 110, 111, 219, 220,
- /* 1210 */ 255, 13, 63, 207, 118, 302, 120, 121, 122, 242,
- /* 1220 */ 243, 125, 196, 196, 75, 219, 220, 29, 70, 131,
- /* 1230 */ 132, 133, 255, 256, 138, 119, 78, 207, 89, 143,
- /* 1240 */ 144, 264, 44, 94, 196, 219, 220, 244, 242, 243,
- /* 1250 */ 308, 135, 196, 104, 158, 159, 160, 161, 105, 110,
- /* 1260 */ 111, 255, 256, 196, 266, 67, 196, 118, 241, 120,
- /* 1270 */ 121, 122, 242, 243, 125, 77, 20, 21, 207, 23,
- /* 1280 */ 207, 24, 256, 26, 196, 255, 196, 138, 0, 1,
- /* 1290 */ 2, 196, 134, 5, 38, 196, 276, 241, 207, 11,
- /* 1300 */ 12, 13, 14, 15, 276, 235, 18, 158, 159, 160,
- /* 1310 */ 161, 308, 23, 242, 243, 242, 243, 196, 20, 63,
- /* 1320 */ 32, 13, 34, 196, 196, 112, 255, 196, 255, 241,
- /* 1330 */ 42, 75, 196, 242, 243, 315, 316, 29, 196, 244,
- /* 1340 */ 219, 220, 196, 315, 316, 89, 255, 219, 220, 247,
- /* 1350 */ 94, 119, 44, 140, 65, 219, 220, 263, 145, 257,
- /* 1360 */ 104, 267, 74, 23, 24, 196, 110, 111, 196, 196,
- /* 1370 */ 82, 26, 241, 85, 118, 67, 120, 121, 122, 122,
- /* 1380 */ 24, 125, 26, 20, 21, 196, 23, 155, 219, 220,
- /* 1390 */ 102, 219, 220, 266, 138, 263, 1, 2, 196, 267,
- /* 1400 */ 5, 38, 103, 308, 261, 148, 11, 12, 13, 14,
- /* 1410 */ 15, 196, 266, 18, 158, 159, 160, 161, 120, 211,
- /* 1420 */ 212, 219, 220, 196, 196, 137, 63, 32, 63, 34,
- /* 1430 */ 196, 143, 144, 5, 219, 220, 137, 42, 75, 11,
- /* 1440 */ 12, 13, 14, 15, 196, 105, 18, 219, 220, 20,
- /* 1450 */ 20, 21, 89, 23, 166, 211, 212, 94, 143, 144,
- /* 1460 */ 32, 26, 34, 242, 243, 166, 196, 104, 38, 74,
- /* 1470 */ 42, 196, 247, 110, 111, 196, 255, 82, 303, 304,
- /* 1480 */ 85, 118, 257, 120, 121, 122, 121, 25, 125, 219,
- /* 1490 */ 220, 196, 147, 63, 219, 220, 196, 102, 219, 220,
- /* 1500 */ 266, 138, 74, 242, 243, 75, 131, 132, 133, 33,
- /* 1510 */ 82, 16, 196, 85, 219, 220, 255, 41, 247, 219,
- /* 1520 */ 220, 158, 159, 160, 161, 25, 20, 21, 257, 23,
- /* 1530 */ 102, 162, 137, 164, 104, 219, 220, 247, 143, 144,
- /* 1540 */ 110, 111, 112, 196, 38, 259, 260, 257, 118, 120,
- /* 1550 */ 120, 121, 122, 196, 133, 125, 154, 155, 24, 64,
- /* 1560 */ 26, 166, 196, 63, 63, 137, 219, 220, 138, 63,
- /* 1570 */ 23, 143, 144, 196, 140, 196, 219, 220, 157, 145,
- /* 1580 */ 196, 75, 147, 196, 24, 219, 220, 196, 158, 159,
- /* 1590 */ 160, 161, 124, 125, 166, 196, 219, 220, 219, 220,
- /* 1600 */ 7, 8, 20, 21, 57, 23, 219, 220, 146, 20,
- /* 1610 */ 104, 196, 196, 196, 25, 196, 110, 111, 219, 220,
- /* 1620 */ 38, 121, 121, 191, 118, 193, 120, 121, 122, 196,
- /* 1630 */ 198, 125, 200, 121, 219, 220, 219, 220, 196, 207,
- /* 1640 */ 23, 196, 25, 196, 138, 63, 24, 196, 26, 196,
- /* 1650 */ 138, 145, 219, 220, 196, 20, 133, 75, 24, 196,
- /* 1660 */ 26, 219, 220, 196, 158, 159, 160, 161, 158, 159,
- /* 1670 */ 219, 220, 219, 220, 242, 243, 158, 159, 20, 21,
- /* 1680 */ 157, 23, 219, 220, 125, 196, 104, 255, 99, 24,
- /* 1690 */ 196, 26, 110, 111, 135, 24, 38, 26, 229, 196,
- /* 1700 */ 118, 269, 120, 121, 122, 196, 117, 125, 219, 220,
- /* 1710 */ 150, 229, 123, 124, 125, 126, 127, 128, 129, 63,
- /* 1720 */ 138, 63, 219, 220, 135, 229, 196, 145, 24, 196,
- /* 1730 */ 26, 196, 196, 75, 302, 196, 101, 196, 87, 88,
- /* 1740 */ 158, 159, 160, 161, 196, 196, 24, 196, 26, 219,
- /* 1750 */ 220, 196, 219, 220, 219, 220, 258, 196, 219, 220,
- /* 1760 */ 219, 220, 104, 196, 24, 196, 26, 196, 110, 111,
- /* 1770 */ 219, 220, 63, 24, 196, 26, 118, 121, 120, 121,
- /* 1780 */ 122, 322, 196, 125, 196, 239, 219, 220, 219, 220,
- /* 1790 */ 24, 196, 26, 24, 196, 26, 138, 219, 220, 196,
- /* 1800 */ 24, 24, 26, 26, 196, 219, 220, 24, 196, 26,
- /* 1810 */ 196, 196, 196, 194, 219, 220, 158, 159, 160, 161,
- /* 1820 */ 196, 196, 219, 220, 292, 245, 258, 246, 291, 301,
- /* 1830 */ 121, 258, 258, 258, 270, 217, 274, 297, 248, 274,
- /* 1840 */ 270, 249, 297, 249, 248, 232, 274, 262, 228, 223,
- /* 1850 */ 274, 222, 222, 222, 252, 248, 252, 246, 199, 262,
- /* 1860 */ 283, 262, 262, 64, 301, 146, 203, 301, 40, 203,
- /* 1870 */ 203, 156, 155, 23, 287, 237, 275, 298, 273, 47,
- /* 1880 */ 19, 298, 240, 240, 240, 240, 240, 203, 19, 202,
- /* 1890 */ 154, 237, 237, 149, 273, 285, 249, 249, 275, 249,
- /* 1900 */ 203, 249, 275, 202, 202, 162, 66, 23, 203, 202,
- /* 1910 */ 224, 203, 202, 224, 203, 202, 119, 221, 230, 221,
- /* 1920 */ 221, 68, 294, 23, 130, 293, 169, 227, 25, 223,
- /* 1930 */ 227, 117, 203, 95, 86, 221, 224, 221, 268, 286,
- /* 1940 */ 268, 221, 221, 286, 153, 309, 253, 224, 230, 316,
- /* 1950 */ 150, 23, 162, 280, 203, 152, 282, 151, 321, 26,
- /* 1960 */ 321, 205, 14, 6, 197, 197, 195, 195, 195, 307,
- /* 1970 */ 210, 307, 304, 210, 216, 216, 252, 251, 253, 225,
- /* 1980 */ 250, 249, 217, 4, 3, 210, 216, 225, 23, 210,
- /* 1990 */ 216, 167, 16, 64, 16, 217, 216, 17, 24, 24,
- /* 2000 */ 144, 156, 134, 26, 147, 21, 17, 25, 149, 1,
- /* 2010 */ 147, 134, 134, 57, 65, 57, 156, 57, 57, 134,
- /* 2020 */ 146, 120, 39, 36, 1, 5, 26, 23, 119, 165,
- /* 2030 */ 25, 46, 79, 43, 72, 72, 146, 119, 25, 21,
- /* 2040 */ 135, 20, 129, 71, 71, 23, 100, 23, 23, 63,
- /* 2050 */ 24, 23, 25, 23, 39, 24, 154, 23, 23, 30,
- /* 2060 */ 24, 24, 71, 24, 26, 101, 146, 24, 36, 24,
- /* 2070 */ 120, 23, 148, 26, 79, 79, 36, 36, 36, 24,
- /* 2080 */ 36, 48, 36, 90, 92, 97, 36, 23, 25, 36,
- /* 2090 */ 147, 26, 26, 24, 147, 24, 24, 24, 24, 12,
- /* 2100 */ 24, 26, 23, 23, 23, 146, 24, 24, 23, 23,
- /* 2110 */ 26, 140, 146, 146, 26, 24, 16, 1, 1, 323,
- /* 2120 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2130 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2140 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2150 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2160 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2170 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2180 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2190 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2200 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2210 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2220 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2230 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2240 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2250 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2260 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2270 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2280 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2290 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- /* 2300 */ 323, 323, 323, 323, 323, 323, 323,
+ /* 0 */ 279, 280, 281, 197, 239, 240, 217, 197, 217, 189,
+ /* 10 */ 190, 191, 192, 193, 194, 223, 279, 280, 281, 199,
+ /* 20 */ 20, 201, 191, 192, 193, 194, 220, 221, 208, 197,
+ /* 30 */ 199, 208, 201, 33, 220, 197, 23, 24, 301, 208,
+ /* 40 */ 197, 41, 223, 7, 8, 9, 10, 47, 48, 49,
+ /* 50 */ 220, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ /* 60 */ 60, 61, 62, 243, 244, 26, 243, 244, 279, 280,
+ /* 70 */ 281, 279, 280, 281, 243, 244, 256, 267, 258, 256,
+ /* 80 */ 197, 258, 197, 292, 261, 262, 208, 256, 297, 258,
+ /* 90 */ 208, 271, 209, 59, 60, 61, 62, 63, 279, 280,
+ /* 100 */ 281, 253, 271, 255, 71, 220, 221, 107, 108, 109,
+ /* 110 */ 110, 111, 112, 113, 114, 115, 116, 117, 118, 106,
+ /* 120 */ 197, 243, 244, 90, 304, 243, 244, 321, 20, 323,
+ /* 130 */ 298, 197, 99, 316, 256, 304, 258, 320, 256, 64,
+ /* 140 */ 258, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+ /* 150 */ 116, 117, 118, 315, 316, 47, 48, 49, 320, 51,
+ /* 160 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ /* 170 */ 62, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+ /* 180 */ 116, 117, 118, 144, 145, 152, 111, 112, 197, 113,
+ /* 190 */ 114, 115, 116, 117, 118, 120, 121, 122, 123, 91,
+ /* 200 */ 125, 93, 59, 60, 61, 62, 321, 322, 133, 27,
+ /* 210 */ 28, 220, 221, 197, 81, 107, 108, 109, 110, 111,
+ /* 220 */ 112, 113, 114, 115, 116, 117, 118, 94, 64, 78,
+ /* 230 */ 97, 215, 216, 16, 159, 160, 20, 86, 315, 316,
+ /* 240 */ 64, 31, 26, 320, 197, 35, 64, 313, 314, 17,
+ /* 250 */ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
+ /* 260 */ 117, 118, 64, 47, 48, 49, 197, 51, 52, 53,
+ /* 270 */ 54, 55, 56, 57, 58, 59, 60, 61, 62, 210,
+ /* 280 */ 70, 105, 65, 132, 197, 121, 122, 123, 124, 242,
+ /* 290 */ 74, 127, 128, 129, 197, 144, 145, 121, 122, 64,
+ /* 300 */ 197, 137, 126, 121, 122, 123, 290, 220, 221, 170,
+ /* 310 */ 171, 20, 321, 322, 82, 139, 84, 220, 221, 121,
+ /* 320 */ 122, 123, 235, 107, 108, 109, 110, 111, 112, 113,
+ /* 330 */ 114, 115, 116, 117, 118, 159, 160, 23, 47, 48,
+ /* 340 */ 49, 118, 51, 52, 53, 54, 55, 56, 57, 58,
+ /* 350 */ 59, 60, 61, 62, 20, 157, 121, 122, 123, 25,
+ /* 360 */ 133, 134, 186, 72, 111, 112, 113, 114, 115, 116,
+ /* 370 */ 117, 118, 144, 145, 78, 86, 273, 197, 64, 220,
+ /* 380 */ 283, 47, 48, 49, 20, 51, 52, 53, 54, 55,
+ /* 390 */ 56, 57, 58, 59, 60, 61, 62, 64, 107, 108,
+ /* 400 */ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
+ /* 410 */ 77, 47, 48, 49, 125, 51, 52, 53, 54, 55,
+ /* 420 */ 56, 57, 58, 59, 60, 61, 62, 20, 132, 133,
+ /* 430 */ 134, 234, 25, 144, 145, 121, 122, 123, 214, 215,
+ /* 440 */ 216, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+ /* 450 */ 116, 117, 118, 273, 121, 122, 123, 64, 239, 240,
+ /* 460 */ 197, 197, 20, 197, 111, 112, 24, 116, 117, 118,
+ /* 470 */ 77, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+ /* 480 */ 116, 117, 118, 104, 220, 221, 220, 221, 26, 47,
+ /* 490 */ 48, 49, 208, 51, 52, 53, 54, 55, 56, 57,
+ /* 500 */ 58, 59, 60, 61, 62, 242, 124, 100, 120, 127,
+ /* 510 */ 128, 129, 159, 160, 121, 122, 123, 138, 316, 137,
+ /* 520 */ 156, 257, 320, 257, 197, 118, 23, 243, 244, 197,
+ /* 530 */ 266, 124, 125, 126, 127, 128, 129, 130, 307, 308,
+ /* 540 */ 256, 20, 258, 136, 156, 24, 167, 220, 221, 107,
+ /* 550 */ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+ /* 560 */ 118, 64, 20, 197, 197, 302, 24, 64, 47, 48,
+ /* 570 */ 49, 197, 51, 52, 53, 54, 55, 56, 57, 58,
+ /* 580 */ 59, 60, 61, 62, 257, 274, 220, 221, 105, 47,
+ /* 590 */ 48, 49, 197, 51, 52, 53, 54, 55, 56, 57,
+ /* 600 */ 58, 59, 60, 61, 62, 122, 212, 213, 86, 126,
+ /* 610 */ 113, 51, 52, 53, 54, 220, 221, 155, 121, 122,
+ /* 620 */ 123, 197, 139, 197, 121, 122, 123, 208, 107, 108,
+ /* 630 */ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
+ /* 640 */ 273, 197, 159, 160, 220, 221, 220, 221, 17, 107,
+ /* 650 */ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+ /* 660 */ 118, 113, 243, 244, 220, 221, 144, 145, 197, 186,
+ /* 670 */ 20, 81, 197, 197, 24, 256, 45, 258, 207, 235,
+ /* 680 */ 209, 257, 92, 257, 94, 64, 126, 97, 219, 141,
+ /* 690 */ 266, 20, 266, 274, 146, 24, 227, 47, 48, 49,
+ /* 700 */ 230, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ /* 710 */ 60, 61, 62, 82, 23, 84, 217, 64, 47, 48,
+ /* 720 */ 49, 197, 51, 52, 53, 54, 55, 56, 57, 58,
+ /* 730 */ 59, 60, 61, 62, 81, 212, 213, 26, 243, 244,
+ /* 740 */ 244, 151, 121, 122, 123, 92, 197, 94, 273, 197,
+ /* 750 */ 97, 256, 256, 258, 258, 64, 197, 107, 108, 109,
+ /* 760 */ 110, 111, 112, 113, 114, 115, 116, 117, 118, 23,
+ /* 770 */ 149, 208, 220, 221, 121, 122, 123, 197, 107, 108,
+ /* 780 */ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
+ /* 790 */ 23, 24, 81, 26, 197, 236, 297, 166, 197, 20,
+ /* 800 */ 220, 221, 197, 24, 151, 94, 243, 244, 97, 257,
+ /* 810 */ 64, 197, 121, 122, 123, 235, 267, 220, 221, 256,
+ /* 820 */ 20, 258, 197, 24, 24, 26, 47, 48, 49, 197,
+ /* 830 */ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ /* 840 */ 61, 62, 197, 242, 64, 220, 221, 47, 48, 49,
+ /* 850 */ 263, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ /* 860 */ 60, 61, 62, 243, 244, 220, 221, 121, 122, 123,
+ /* 870 */ 197, 23, 24, 106, 26, 197, 256, 245, 258, 197,
+ /* 880 */ 235, 197, 257, 210, 208, 197, 107, 108, 109, 110,
+ /* 890 */ 111, 112, 113, 114, 115, 116, 117, 118, 210, 197,
+ /* 900 */ 208, 121, 122, 123, 220, 221, 278, 107, 108, 109,
+ /* 910 */ 110, 111, 112, 113, 114, 115, 116, 117, 118, 243,
+ /* 920 */ 244, 197, 220, 221, 310, 26, 312, 197, 20, 149,
+ /* 930 */ 197, 197, 256, 23, 258, 243, 244, 235, 205, 215,
+ /* 940 */ 216, 257, 310, 210, 312, 197, 318, 319, 256, 20,
+ /* 950 */ 258, 26, 197, 24, 106, 47, 48, 49, 197, 51,
+ /* 960 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ /* 970 */ 62, 197, 197, 197, 64, 197, 47, 48, 49, 202,
+ /* 980 */ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ /* 990 */ 61, 62, 314, 245, 220, 221, 13, 267, 220, 221,
+ /* 1000 */ 227, 24, 229, 26, 64, 197, 245, 12, 197, 235,
+ /* 1010 */ 237, 197, 29, 235, 290, 107, 108, 109, 110, 111,
+ /* 1020 */ 112, 113, 114, 115, 116, 117, 118, 44, 220, 221,
+ /* 1030 */ 20, 121, 122, 123, 220, 221, 107, 108, 109, 110,
+ /* 1040 */ 111, 112, 113, 114, 115, 116, 117, 118, 123, 235,
+ /* 1050 */ 151, 68, 197, 214, 215, 216, 245, 20, 310, 197,
+ /* 1060 */ 312, 78, 122, 286, 289, 257, 197, 140, 291, 142,
+ /* 1070 */ 143, 310, 164, 312, 149, 220, 221, 20, 20, 210,
+ /* 1080 */ 132, 133, 134, 25, 47, 48, 49, 197, 51, 52,
+ /* 1090 */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ /* 1100 */ 123, 232, 197, 234, 242, 47, 48, 49, 51, 51,
+ /* 1110 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ /* 1120 */ 62, 310, 230, 312, 151, 197, 149, 13, 133, 134,
+ /* 1130 */ 120, 121, 242, 23, 24, 132, 133, 134, 23, 197,
+ /* 1140 */ 25, 197, 169, 29, 107, 108, 109, 110, 111, 112,
+ /* 1150 */ 113, 114, 115, 116, 117, 118, 37, 197, 44, 278,
+ /* 1160 */ 150, 197, 220, 221, 197, 107, 108, 109, 110, 111,
+ /* 1170 */ 112, 113, 114, 115, 116, 117, 118, 120, 23, 64,
+ /* 1180 */ 220, 221, 68, 197, 220, 221, 20, 220, 221, 197,
+ /* 1190 */ 71, 197, 51, 136, 197, 197, 268, 197, 79, 318,
+ /* 1200 */ 319, 164, 197, 298, 26, 197, 197, 20, 197, 197,
+ /* 1210 */ 197, 278, 268, 47, 48, 49, 106, 51, 52, 53,
+ /* 1220 */ 54, 55, 56, 57, 58, 59, 60, 61, 62, 220,
+ /* 1230 */ 221, 197, 220, 221, 47, 48, 49, 122, 51, 52,
+ /* 1240 */ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ /* 1250 */ 242, 318, 319, 316, 135, 264, 265, 320, 155, 156,
+ /* 1260 */ 268, 120, 268, 197, 197, 268, 111, 112, 268, 197,
+ /* 1270 */ 236, 305, 306, 107, 108, 109, 110, 111, 112, 113,
+ /* 1280 */ 114, 115, 116, 117, 118, 316, 220, 221, 197, 320,
+ /* 1290 */ 197, 20, 220, 221, 107, 108, 109, 110, 111, 112,
+ /* 1300 */ 113, 114, 115, 116, 117, 118, 197, 248, 197, 298,
+ /* 1310 */ 197, 220, 221, 220, 221, 20, 248, 197, 259, 25,
+ /* 1320 */ 316, 265, 23, 141, 320, 269, 148, 259, 146, 220,
+ /* 1330 */ 221, 220, 221, 220, 221, 265, 20, 197, 230, 269,
+ /* 1340 */ 220, 221, 197, 48, 49, 20, 51, 52, 53, 54,
+ /* 1350 */ 55, 56, 57, 58, 59, 60, 61, 62, 64, 22,
+ /* 1360 */ 220, 221, 197, 64, 197, 49, 197, 51, 52, 53,
+ /* 1370 */ 54, 55, 56, 57, 58, 59, 60, 61, 62, 163,
+ /* 1380 */ 248, 165, 45, 248, 248, 220, 221, 220, 221, 220,
+ /* 1390 */ 221, 259, 121, 23, 259, 259, 20, 21, 197, 23,
+ /* 1400 */ 261, 262, 107, 108, 109, 110, 111, 112, 113, 114,
+ /* 1410 */ 115, 116, 117, 118, 38, 197, 122, 26, 197, 23,
+ /* 1420 */ 197, 122, 85, 107, 108, 109, 110, 111, 112, 113,
+ /* 1430 */ 114, 115, 116, 117, 118, 197, 66, 197, 220, 221,
+ /* 1440 */ 64, 220, 221, 220, 221, 197, 121, 197, 33, 23,
+ /* 1450 */ 120, 25, 76, 64, 58, 26, 41, 126, 220, 221,
+ /* 1460 */ 220, 221, 86, 197, 24, 128, 26, 136, 220, 221,
+ /* 1470 */ 220, 221, 25, 20, 21, 24, 23, 197, 125, 126,
+ /* 1480 */ 150, 105, 64, 24, 197, 26, 197, 111, 112, 197,
+ /* 1490 */ 197, 38, 134, 197, 24, 119, 26, 121, 122, 123,
+ /* 1500 */ 220, 221, 126, 166, 197, 197, 53, 220, 221, 220,
+ /* 1510 */ 221, 122, 197, 220, 221, 139, 158, 64, 7, 8,
+ /* 1520 */ 144, 145, 131, 24, 64, 26, 134, 220, 221, 76,
+ /* 1530 */ 197, 24, 197, 26, 122, 159, 160, 161, 162, 197,
+ /* 1540 */ 122, 20, 21, 90, 23, 197, 197, 197, 95, 23,
+ /* 1550 */ 158, 139, 20, 220, 221, 220, 221, 197, 105, 38,
+ /* 1560 */ 197, 197, 186, 197, 111, 112, 197, 325, 220, 221,
+ /* 1570 */ 220, 221, 119, 260, 121, 122, 123, 148, 197, 126,
+ /* 1580 */ 220, 221, 122, 220, 221, 64, 220, 221, 195, 220,
+ /* 1590 */ 221, 24, 139, 26, 147, 197, 24, 76, 26, 24,
+ /* 1600 */ 197, 26, 151, 197, 197, 24, 197, 26, 24, 247,
+ /* 1610 */ 26, 90, 159, 160, 161, 162, 95, 208, 20, 21,
+ /* 1620 */ 197, 23, 197, 220, 221, 197, 105, 220, 221, 220,
+ /* 1630 */ 221, 197, 111, 112, 102, 197, 38, 88, 89, 186,
+ /* 1640 */ 119, 197, 121, 122, 123, 220, 221, 126, 220, 221,
+ /* 1650 */ 159, 160, 243, 244, 220, 221, 159, 160, 220, 221,
+ /* 1660 */ 139, 197, 64, 197, 197, 256, 257, 258, 197, 197,
+ /* 1670 */ 24, 197, 26, 147, 76, 266, 24, 24, 26, 26,
+ /* 1680 */ 159, 160, 161, 162, 197, 197, 220, 221, 90, 197,
+ /* 1690 */ 197, 220, 221, 95, 220, 221, 24, 197, 26, 197,
+ /* 1700 */ 24, 197, 26, 105, 294, 197, 197, 186, 240, 111,
+ /* 1710 */ 112, 197, 220, 221, 197, 197, 197, 119, 260, 121,
+ /* 1720 */ 122, 123, 220, 221, 126, 197, 197, 197, 293, 246,
+ /* 1730 */ 218, 276, 299, 260, 303, 260, 260, 139, 0, 1,
+ /* 1740 */ 2, 272, 299, 5, 249, 20, 21, 249, 23, 11,
+ /* 1750 */ 12, 13, 14, 15, 272, 250, 18, 159, 160, 161,
+ /* 1760 */ 162, 276, 276, 38, 224, 250, 276, 233, 229, 223,
+ /* 1770 */ 32, 223, 34, 223, 264, 65, 249, 264, 253, 285,
+ /* 1780 */ 42, 303, 200, 247, 186, 147, 264, 264, 253, 64,
+ /* 1790 */ 204, 204, 303, 40, 204, 289, 300, 157, 156, 23,
+ /* 1800 */ 238, 76, 47, 300, 19, 241, 241, 241, 277, 197,
+ /* 1810 */ 241, 241, 275, 75, 204, 19, 203, 155, 250, 277,
+ /* 1820 */ 208, 83, 20, 21, 86, 23, 250, 275, 277, 238,
+ /* 1830 */ 105, 238, 220, 221, 150, 250, 111, 112, 113, 250,
+ /* 1840 */ 38, 103, 287, 204, 119, 163, 121, 122, 123, 296,
+ /* 1850 */ 203, 126, 203, 67, 295, 243, 244, 23, 204, 203,
+ /* 1860 */ 225, 204, 203, 203, 139, 204, 64, 120, 256, 257,
+ /* 1870 */ 258, 23, 222, 225, 69, 231, 138, 222, 76, 228,
+ /* 1880 */ 222, 131, 144, 145, 159, 160, 161, 162, 222, 225,
+ /* 1890 */ 170, 228, 224, 222, 25, 222, 231, 222, 319, 20,
+ /* 1900 */ 21, 118, 23, 311, 288, 167, 288, 105, 225, 204,
+ /* 1910 */ 96, 186, 324, 111, 112, 87, 154, 38, 324, 151,
+ /* 1920 */ 23, 119, 204, 121, 122, 123, 163, 253, 126, 284,
+ /* 1930 */ 153, 192, 254, 194, 254, 250, 152, 270, 199, 270,
+ /* 1940 */ 201, 139, 252, 64, 251, 26, 206, 208, 146, 14,
+ /* 1950 */ 198, 6, 282, 196, 198, 76, 196, 196, 217, 211,
+ /* 1960 */ 211, 159, 160, 161, 162, 4, 3, 23, 217, 226,
+ /* 1970 */ 211, 217, 226, 16, 168, 217, 211, 65, 16, 24,
+ /* 1980 */ 24, 217, 243, 244, 105, 306, 309, 218, 186, 218,
+ /* 1990 */ 111, 112, 17, 157, 145, 256, 309, 258, 119, 135,
+ /* 2000 */ 121, 122, 123, 1, 2, 126, 26, 5, 25, 148,
+ /* 2010 */ 271, 21, 150, 11, 12, 13, 14, 15, 139, 1,
+ /* 2020 */ 18, 17, 5, 148, 135, 146, 135, 39, 11, 12,
+ /* 2030 */ 13, 14, 15, 66, 32, 18, 34, 157, 159, 160,
+ /* 2040 */ 161, 162, 58, 304, 42, 58, 135, 58, 121, 32,
+ /* 2050 */ 58, 34, 36, 147, 1, 5, 26, 20, 21, 42,
+ /* 2060 */ 23, 23, 120, 43, 166, 186, 25, 46, 73, 73,
+ /* 2070 */ 147, 80, 120, 25, 20, 38, 21, 75, 130, 136,
+ /* 2080 */ 23, 72, 23, 23, 23, 83, 24, 72, 86, 64,
+ /* 2090 */ 25, 23, 75, 30, 101, 72, 24, 39, 23, 26,
+ /* 2100 */ 83, 64, 36, 86, 155, 103, 24, 24, 24, 23,
+ /* 2110 */ 102, 147, 24, 76, 24, 121, 36, 23, 149, 26,
+ /* 2120 */ 103, 36, 93, 36, 80, 36, 91, 36, 36, 48,
+ /* 2130 */ 98, 80, 24, 23, 25, 36, 23, 26, 26, 24,
+ /* 2140 */ 138, 24, 105, 24, 24, 148, 144, 145, 111, 112,
+ /* 2150 */ 26, 148, 26, 24, 23, 138, 119, 12, 121, 122,
+ /* 2160 */ 123, 144, 145, 126, 23, 23, 26, 24, 24, 167,
+ /* 2170 */ 23, 23, 141, 147, 147, 147, 139, 26, 24, 16,
+ /* 2180 */ 1, 1, 326, 326, 167, 326, 326, 326, 326, 326,
+ /* 2190 */ 326, 326, 326, 326, 326, 326, 159, 160, 161, 162,
+ /* 2200 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2210 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2220 */ 326, 326, 326, 186, 326, 326, 326, 326, 326, 326,
+ /* 2230 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2240 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2250 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2260 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2270 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2280 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2290 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2300 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2310 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2320 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2330 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2340 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2350 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2360 */ 326, 326, 326, 326, 326, 326, 326, 326, 326, 326,
+ /* 2370 */ 326, 189, 189, 189, 189, 189, 189, 189, 189, 189,
+ /* 2380 */ 189, 189, 189, 189, 189, 189, 189, 189, 189, 189,
+ /* 2390 */ 189, 189, 189, 189, 189, 189, 189, 189, 189, 189,
+ /* 2400 */ 189, 189, 189, 189, 189, 189, 189, 189, 189, 189,
+ /* 2410 */ 189, 189, 189,
};
-#define YY_SHIFT_COUNT (596)
+#define YY_SHIFT_COUNT (600)
#define YY_SHIFT_MIN (0)
-#define YY_SHIFT_MAX (2117)
+#define YY_SHIFT_MAX (2180)
static const unsigned short int yy_shift_ofst[] = {
- /* 0 */ 1395, 1288, 1428, 1096, 1096, 59, 1149, 1256, 1363, 1658,
- /* 10 */ 1658, 1658, 971, 0, 0, 187, 888, 1658, 1658, 1658,
- /* 20 */ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- /* 30 */ 1658, 464, 464, 301, 301, 262, 668, 59, 59, 59,
- /* 40 */ 59, 59, 42, 113, 229, 300, 409, 430, 451, 558,
- /* 50 */ 579, 600, 707, 728, 749, 867, 888, 888, 888, 888,
- /* 60 */ 888, 888, 888, 888, 888, 888, 888, 888, 888, 888,
- /* 70 */ 888, 888, 888, 888, 909, 888, 1016, 1037, 1037, 1430,
- /* 80 */ 1506, 1582, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- /* 90 */ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- /* 100 */ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- /* 110 */ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- /* 120 */ 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- /* 130 */ 1658, 153, 263, 263, 263, 263, 263, 263, 263, 84,
- /* 140 */ 195, 67, 304, 323, 408, 373, 783, 783, 1116, 783,
- /* 150 */ 783, 483, 483, 783, 869, 869, 869, 712, 869, 142,
- /* 160 */ 149, 149, 149, 30, 30, 2119, 2119, 1589, 1589, 1589,
- /* 170 */ 1589, 304, 524, 193, 193, 193, 193, 1198, 1198, 237,
- /* 180 */ 850, 927, 783, 783, 783, 783, 783, 783, 783, 783,
- /* 190 */ 783, 783, 783, 783, 783, 783, 783, 783, 783, 783,
- /* 200 */ 783, 783, 783, 783, 783, 990, 650, 650, 783, 194,
- /* 210 */ 50, 50, 1298, 1298, 1365, 1365, 346, 1315, 2119, 2119,
- /* 220 */ 2119, 2119, 2119, 2119, 2119, 614, 773, 773, 411, 82,
- /* 230 */ 450, 616, 620, 732, 762, 768, 783, 783, 783, 783,
- /* 240 */ 783, 783, 783, 783, 783, 783, 1058, 783, 783, 783,
- /* 250 */ 783, 783, 783, 783, 783, 783, 783, 783, 783, 783,
- /* 260 */ 783, 783, 1158, 1158, 1158, 783, 783, 783, 1257, 783,
- /* 270 */ 783, 783, 208, 961, 783, 783, 1308, 783, 783, 783,
- /* 280 */ 783, 783, 783, 783, 783, 783, 541, 1098, 331, 46,
- /* 290 */ 1500, 1500, 1500, 1500, 406, 46, 46, 1213, 1031, 1495,
- /* 300 */ 1232, 1402, 1345, 1402, 1429, 508, 1232, 1232, 508, 1232,
- /* 310 */ 1345, 1429, 102, 1356, 628, 1476, 1476, 1476, 1039, 1039,
- /* 320 */ 1039, 1039, 1017, 1017, 1369, 1435, 1434, 1617, 1799, 1799,
- /* 330 */ 1719, 1719, 1828, 1828, 1719, 1715, 1717, 1850, 1832, 1861,
- /* 340 */ 1861, 1861, 1861, 1861, 1719, 1869, 1736, 1717, 1717, 1736,
- /* 350 */ 1850, 1832, 1736, 1832, 1736, 1744, 1719, 1869, 1869, 1743,
- /* 360 */ 1840, 1719, 1869, 1884, 1719, 1869, 1719, 1869, 1884, 1797,
- /* 370 */ 1797, 1797, 1853, 1900, 1900, 1884, 1797, 1794, 1797, 1853,
- /* 380 */ 1797, 1797, 1757, 1903, 1814, 1814, 1884, 1719, 1838, 1838,
- /* 390 */ 1848, 1848, 1791, 1800, 1928, 1719, 1790, 1791, 1803, 1806,
- /* 400 */ 1736, 1933, 1948, 1948, 1957, 1957, 1957, 2119, 2119, 2119,
- /* 410 */ 2119, 2119, 2119, 2119, 2119, 2119, 2119, 2119, 2119, 2119,
- /* 420 */ 2119, 2119, 2119, 997, 351, 1153, 1340, 1299, 816, 1375,
- /* 430 */ 870, 1534, 1547, 1462, 1421, 1523, 1622, 1289, 1665, 1671,
- /* 440 */ 1704, 1722, 1512, 1634, 1749, 1501, 1468, 1593, 1559, 1766,
- /* 450 */ 1560, 1635, 1656, 1769, 1776, 1651, 1740, 1510, 1518, 1777,
- /* 460 */ 1783, 1709, 449, 1979, 1981, 1965, 1824, 1976, 1929, 1978,
- /* 470 */ 1980, 1974, 1975, 1856, 1845, 1868, 1977, 1977, 1982, 1857,
- /* 480 */ 1984, 1859, 1989, 2008, 1863, 1877, 1977, 1878, 1949, 1983,
- /* 490 */ 1977, 1860, 1956, 1958, 1960, 1961, 1885, 1901, 1987, 1874,
- /* 500 */ 2023, 2020, 2000, 2004, 1909, 1864, 2005, 1985, 1962, 2000,
- /* 510 */ 1963, 1953, 1990, 1890, 1918, 2013, 2018, 2021, 1905, 1913,
- /* 520 */ 2022, 1972, 2024, 2025, 2026, 2028, 1973, 1986, 2027, 1946,
- /* 530 */ 2029, 2030, 1991, 2015, 2031, 2032, 1902, 2034, 2036, 2037,
- /* 540 */ 2038, 2039, 2035, 1964, 1920, 2043, 2045, 1950, 2040, 2048,
- /* 550 */ 1924, 2047, 2041, 2042, 2044, 2046, 1992, 1995, 1993, 2033,
- /* 560 */ 1996, 1988, 2050, 2055, 2064, 2063, 2065, 2066, 2053, 1943,
- /* 570 */ 1947, 2069, 2047, 2071, 2072, 2073, 2074, 2075, 2076, 2079,
- /* 580 */ 2087, 2080, 2081, 2082, 2083, 2085, 2086, 2084, 1971, 1959,
- /* 590 */ 1966, 1967, 2088, 2091, 2100, 2116, 2117,
+ /* 0 */ 2002, 1738, 2017, 1376, 1376, 522, 151, 1453, 1521, 1598,
+ /* 10 */ 2037, 2037, 2037, 289, 522, 522, 522, 522, 522, 0,
+ /* 20 */ 0, 291, 1166, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
+ /* 30 */ 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 75, 75,
+ /* 40 */ 653, 653, 164, 333, 393, 235, 235, 39, 39, 39,
+ /* 50 */ 39, 108, 216, 334, 364, 442, 521, 542, 650, 671,
+ /* 60 */ 779, 800, 908, 929, 1037, 1058, 1166, 1166, 1166, 1166,
+ /* 70 */ 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1166,
+ /* 80 */ 1166, 1166, 1166, 1166, 1187, 1166, 1295, 1316, 1316, 1725,
+ /* 90 */ 1802, 1879, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
+ /* 100 */ 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
+ /* 110 */ 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
+ /* 120 */ 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
+ /* 130 */ 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
+ /* 140 */ 2037, 2037, 34, 143, 143, 143, 143, 143, 143, 143,
+ /* 150 */ 64, 253, 76, 182, 1337, 235, 1057, 235, 235, 353,
+ /* 160 */ 353, 235, 351, 227, 139, 139, 139, 228, 223, 223,
+ /* 170 */ 2224, 2224, 407, 407, 407, 407, 182, 198, 314, 314,
+ /* 180 */ 314, 314, 983, 983, 590, 767, 848, 235, 235, 235,
+ /* 190 */ 235, 235, 235, 235, 235, 235, 235, 235, 235, 235,
+ /* 200 */ 235, 235, 235, 235, 235, 235, 235, 235, 235, 1010,
+ /* 210 */ 711, 711, 235, 995, 133, 133, 1271, 1271, 940, 940,
+ /* 220 */ 973, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 176, 483,
+ /* 230 */ 483, 503, 382, 691, 497, 746, 621, 780, 910, 235,
+ /* 240 */ 235, 235, 235, 235, 235, 235, 235, 235, 235, 296,
+ /* 250 */ 235, 235, 235, 235, 235, 235, 235, 235, 235, 235,
+ /* 260 */ 235, 235, 235, 235, 235, 1119, 1119, 1119, 235, 235,
+ /* 270 */ 235, 977, 235, 235, 235, 1115, 33, 235, 1114, 235,
+ /* 280 */ 235, 235, 235, 235, 235, 235, 235, 235, 36, 948,
+ /* 290 */ 210, 927, 1294, 1294, 1294, 1294, 925, 927, 927, 548,
+ /* 300 */ 1155, 217, 388, 1103, 1178, 1103, 1325, 462, 388, 388,
+ /* 310 */ 462, 388, 1178, 1325, 1391, 799, 1141, 1415, 1415, 1415,
+ /* 320 */ 1330, 1330, 1330, 1330, 899, 899, 1216, 1429, 1182, 1426,
+ /* 330 */ 1710, 1710, 1638, 1638, 1753, 1753, 1638, 1640, 1642, 1776,
+ /* 340 */ 1755, 1785, 1785, 1785, 1785, 1785, 1638, 1796, 1662, 1642,
+ /* 350 */ 1642, 1662, 1776, 1755, 1662, 1755, 1662, 1684, 1638, 1796,
+ /* 360 */ 1796, 1682, 1786, 1638, 1796, 1834, 1638, 1796, 1638, 1796,
+ /* 370 */ 1834, 1747, 1747, 1747, 1805, 1848, 1848, 1834, 1747, 1750,
+ /* 380 */ 1747, 1805, 1747, 1747, 1720, 1869, 1783, 1783, 1834, 1638,
+ /* 390 */ 1814, 1814, 1828, 1828, 1762, 1768, 1897, 1638, 1763, 1762,
+ /* 400 */ 1777, 1784, 1662, 1919, 1935, 1935, 1945, 1945, 1945, 2224,
+ /* 410 */ 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224, 2224,
+ /* 420 */ 2224, 2224, 2224, 2224, 2224, 631, 560, 13, 1110, 379,
+ /* 430 */ 232, 1003, 1299, 1440, 1396, 1447, 1358, 1392, 1459, 1370,
+ /* 440 */ 1470, 1499, 1507, 1567, 1412, 1572, 1575, 1389, 1353, 1511,
+ /* 450 */ 1331, 1581, 1451, 1532, 1418, 1584, 1646, 1549, 1653, 1672,
+ /* 460 */ 1491, 1497, 1652, 1676, 1460, 1526, 1961, 1963, 1944, 1806,
+ /* 470 */ 1957, 1912, 1962, 1975, 1955, 1956, 1849, 1836, 1864, 1980,
+ /* 480 */ 1980, 1983, 1861, 1990, 1862, 2004, 2018, 1875, 1889, 1980,
+ /* 490 */ 1891, 1967, 1988, 1980, 1880, 1984, 1987, 1989, 1992, 1911,
+ /* 500 */ 1927, 2016, 1906, 2053, 2050, 2030, 2038, 1942, 1898, 2041,
+ /* 510 */ 2021, 1995, 2030, 1996, 1991, 2020, 1923, 1952, 2048, 2055,
+ /* 520 */ 2054, 1943, 1948, 2057, 2009, 2059, 2060, 2062, 2061, 2015,
+ /* 530 */ 2025, 2065, 1993, 2063, 2068, 2023, 2058, 2072, 2066, 1949,
+ /* 540 */ 2075, 2082, 2083, 2073, 2084, 2086, 2008, 1964, 2088, 2090,
+ /* 550 */ 1994, 2080, 2094, 1969, 2093, 2085, 2087, 2089, 2091, 2029,
+ /* 560 */ 2044, 2035, 2081, 2051, 2032, 2092, 2108, 2110, 2109, 2111,
+ /* 570 */ 2112, 2099, 1997, 2003, 2115, 2093, 2117, 2119, 2120, 2113,
+ /* 580 */ 2124, 2126, 2129, 2131, 2145, 2141, 2142, 2143, 2144, 2147,
+ /* 590 */ 2148, 2140, 2031, 2026, 2027, 2028, 2151, 2154, 2163, 2179,
+ /* 600 */ 2180,
};
-#define YY_REDUCE_COUNT (422)
-#define YY_REDUCE_MIN (-277)
-#define YY_REDUCE_MAX (1780)
+#define YY_REDUCE_COUNT (424)
+#define YY_REDUCE_MIN (-279)
+#define YY_REDUCE_MAX (1771)
static const short yy_reduce_ofst[] = {
- /* 0 */ -124, 913, 1432, 977, 1006, -119, -193, -191, -181, -185,
- /* 10 */ -183, 333, 349, -192, -102, -277, -27, -188, 485, 651,
- /* 20 */ 810, 815, 574, 865, 941, 630, 789, 944, -177, 862,
- /* 30 */ 1026, 77, 486, 385, 676, 209, 785, 950, 1030, 1071,
- /* 40 */ 1073, 1091, -261, -261, -261, -261, -261, -261, -261, -261,
- /* 50 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261,
- /* 60 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261,
- /* 70 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -175,
- /* 80 */ 200, 381, 503, 525, 530, 682, 843, 984, 989, 1121,
- /* 90 */ 1128, 1136, 1169, 1172, 1202, 1215, 1228, 1270, 1275, 1279,
- /* 100 */ 1295, 1300, 1316, 1347, 1357, 1366, 1377, 1379, 1387, 1399,
- /* 110 */ 1415, 1417, 1433, 1442, 1451, 1453, 1463, 1489, 1503, 1530,
- /* 120 */ 1533, 1535, 1539, 1541, 1551, 1567, 1569, 1578, 1586, 1595,
- /* 130 */ 1603, -261, -261, -261, -261, -261, -261, -261, -261, -261,
- /* 140 */ -261, -261, -126, 857, 771, 942, 197, 1003, -222, 1095,
- /* 150 */ -189, -190, 654, 243, 1221, 1261, 1221, -261, 1261, 884,
- /* 160 */ 731, 1020, 1028, -261, -261, -261, -261, 372, 372, 372,
- /* 170 */ 372, -133, 76, -187, -54, 120, 636, -161, 189, -60,
- /* 180 */ 274, 274, 239, 700, 842, -61, 172, 467, 488, 1027,
- /* 190 */ 1056, 1088, 429, 775, 555, 841, 998, 756, 1127, 1146,
- /* 200 */ 1131, 334, 1070, 138, 1234, 724, 407, 562, 537, 738,
- /* 210 */ 617, 766, 1094, 1132, 1208, 1244, -242, 955, 1175, 184,
- /* 220 */ 1102, 1225, 1271, 1286, 1290, -179, -147, -114, 199, 22,
- /* 230 */ 359, 380, 507, 575, 594, 685, 704, 710, 717, 794,
- /* 240 */ 912, 925, 987, 1048, 1067, 1090, 330, 1099, 1142, 1173,
- /* 250 */ 1189, 1227, 1248, 1384, 1391, 1416, 1419, 1445, 1447, 1458,
- /* 260 */ 1467, 1494, 1469, 1482, 1496, 1509, 1536, 1548, 1143, 1549,
- /* 270 */ 1555, 1561, 1498, 1459, 1571, 1588, 1546, 1598, 380, 1608,
- /* 280 */ 1612, 1614, 1615, 1616, 1624, 1625, 1619, 1532, 1537, 1580,
- /* 290 */ 1568, 1573, 1574, 1575, 1143, 1580, 1580, 1581, 1618, 1528,
- /* 300 */ 1562, 1564, 1590, 1570, 1540, 1592, 1565, 1572, 1594, 1576,
- /* 310 */ 1596, 1545, 1626, 1613, 1620, 1629, 1630, 1631, 1585, 1597,
- /* 320 */ 1599, 1600, 1602, 1604, 1577, 1607, 1611, 1659, 1563, 1566,
- /* 330 */ 1663, 1666, 1579, 1583, 1667, 1587, 1601, 1605, 1638, 1642,
- /* 340 */ 1643, 1644, 1645, 1646, 1684, 1687, 1647, 1623, 1627, 1648,
- /* 350 */ 1621, 1654, 1650, 1655, 1652, 1610, 1697, 1701, 1702, 1628,
- /* 360 */ 1632, 1705, 1707, 1686, 1708, 1710, 1711, 1713, 1689, 1696,
- /* 370 */ 1698, 1699, 1688, 1700, 1703, 1712, 1714, 1706, 1716, 1718,
- /* 380 */ 1720, 1721, 1633, 1636, 1653, 1657, 1723, 1729, 1637, 1639,
- /* 390 */ 1670, 1672, 1693, 1724, 1673, 1751, 1674, 1725, 1726, 1730,
- /* 400 */ 1732, 1756, 1767, 1768, 1771, 1772, 1773, 1662, 1664, 1668,
- /* 410 */ 1760, 1763, 1758, 1759, 1770, 1774, 1775, 1754, 1762, 1765,
- /* 420 */ 1778, 1780, 1779,
+ /* 0 */ -180, -169, 1739, 1409, 1612, -177, 419, -115, -194, -9,
+ /* 10 */ 264, 424, 426, -122, -118, 284, 563, 676, 692, -208,
+ /* 20 */ -181, -263, -211, 87, 444, 580, 645, 702, 266, 778,
+ /* 30 */ 814, 327, 552, 774, 625, 97, 684, 808, 16, 724,
+ /* 40 */ -162, -77, 869, 632, 748, 761, 811, 495, 620, 495,
+ /* 50 */ 620, -279, -279, -279, -279, -279, -279, -279, -279, -279,
+ /* 60 */ -279, -279, -279, -279, -279, -279, -279, -279, -279, -279,
+ /* 70 */ -279, -279, -279, -279, -279, -279, -279, -279, -279, -279,
+ /* 80 */ -279, -279, -279, -279, -279, -279, -279, -279, -279, 366,
+ /* 90 */ 395, 597, 855, 942, 960, 964, 967, 1009, 1012, 1066,
+ /* 100 */ 1072, 1091, 1093, 1109, 1111, 1113, 1120, 1140, 1165, 1167,
+ /* 110 */ 1169, 1218, 1221, 1223, 1238, 1240, 1248, 1250, 1280, 1287,
+ /* 120 */ 1289, 1293, 1307, 1333, 1335, 1348, 1350, 1360, 1363, 1366,
+ /* 130 */ 1369, 1403, 1407, 1425, 1428, 1434, 1438, 1466, 1471, 1474,
+ /* 140 */ 1492, 1502, -279, -279, -279, -279, -279, -279, -279, -279,
+ /* 150 */ -279, -279, -279, 471, 777, 263, 773, 614, -66, 224,
+ /* 160 */ 839, 733, -279, -209, 628, 881, 933, 496, -279, -279,
+ /* 170 */ -279, -279, 469, 469, 469, 469, -117, 775, 103, 180,
+ /* 180 */ 367, 475, -235, 219, -183, 231, 231, 69, 673, 688,
+ /* 190 */ -190, 549, 730, 47, 601, 862, 890, -168, 928, 905,
+ /* 200 */ 944, 992, 1011, 994, 997, 1008, 559, 1034, 1000, 991,
+ /* 210 */ 202, 937, 678, 499, 969, 1004, 1056, 1070, 394, 523,
+ /* 220 */ -152, 966, 1059, 1068, 1132, 1135, 1139, 1136, -186, -170,
+ /* 230 */ 159, -157, 197, 332, 374, 476, 524, 605, 682, 734,
+ /* 240 */ 755, 776, 986, 998, 1005, 1013, 1067, 1145, 1201, 311,
+ /* 250 */ 1266, 1292, 1296, 1308, 1315, 1342, 1349, 1364, 1381, 1398,
+ /* 260 */ 1406, 1423, 1444, 1464, 1467, 470, 892, 1108, 1472, 1487,
+ /* 270 */ 1488, 587, 1493, 1500, 1504, 1313, 1242, 1508, 1468, 1509,
+ /* 280 */ 374, 1514, 1517, 1518, 1519, 1528, 1529, 1530, 1393, 1410,
+ /* 290 */ 1435, 1483, 1458, 1473, 1475, 1476, 587, 1483, 1483, 1362,
+ /* 300 */ 1512, 1431, 1455, 1469, 1495, 1482, 1433, 1505, 1485, 1486,
+ /* 310 */ 1515, 1490, 1498, 1443, 1540, 1534, 1539, 1546, 1548, 1550,
+ /* 320 */ 1510, 1513, 1522, 1523, 1525, 1535, 1494, 1527, 1536, 1582,
+ /* 330 */ 1478, 1489, 1586, 1587, 1496, 1503, 1590, 1506, 1531, 1537,
+ /* 340 */ 1562, 1564, 1565, 1566, 1569, 1570, 1610, 1613, 1568, 1542,
+ /* 350 */ 1551, 1576, 1552, 1591, 1585, 1593, 1589, 1555, 1639, 1647,
+ /* 360 */ 1649, 1553, 1559, 1654, 1656, 1635, 1657, 1659, 1661, 1660,
+ /* 370 */ 1648, 1650, 1655, 1658, 1644, 1651, 1663, 1664, 1666, 1668,
+ /* 380 */ 1671, 1665, 1673, 1675, 1579, 1592, 1616, 1618, 1683, 1705,
+ /* 390 */ 1588, 1594, 1667, 1669, 1678, 1674, 1670, 1718, 1645, 1680,
+ /* 400 */ 1690, 1693, 1685, 1740, 1752, 1756, 1757, 1760, 1761, 1677,
+ /* 410 */ 1687, 1679, 1748, 1749, 1741, 1751, 1754, 1758, 1759, 1743,
+ /* 420 */ 1746, 1769, 1771, 1764, 1765,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1687, 1687, 1687, 1514, 1274, 1390, 1274, 1274, 1274, 1514,
- /* 10 */ 1514, 1514, 1274, 1420, 1420, 1569, 1309, 1274, 1274, 1274,
- /* 20 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1513, 1274,
- /* 30 */ 1274, 1274, 1274, 1603, 1603, 1274, 1274, 1274, 1274, 1274,
- /* 40 */ 1274, 1274, 1274, 1429, 1274, 1436, 1274, 1274, 1274, 1274,
- /* 50 */ 1274, 1515, 1516, 1274, 1274, 1274, 1568, 1570, 1533, 1443,
- /* 60 */ 1442, 1441, 1440, 1551, 1408, 1434, 1427, 1431, 1510, 1511,
- /* 70 */ 1509, 1665, 1516, 1515, 1274, 1430, 1478, 1494, 1477, 1274,
- /* 80 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 90 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 100 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 110 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 120 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 130 */ 1274, 1486, 1493, 1492, 1491, 1500, 1490, 1487, 1480, 1479,
- /* 140 */ 1481, 1482, 1299, 1274, 1296, 1274, 1274, 1274, 1351, 1274,
- /* 150 */ 1274, 1274, 1274, 1274, 1589, 1588, 1274, 1483, 1274, 1309,
- /* 160 */ 1471, 1470, 1469, 1497, 1484, 1496, 1495, 1576, 1580, 1639,
- /* 170 */ 1638, 1274, 1534, 1274, 1274, 1274, 1274, 1274, 1274, 1603,
- /* 180 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 190 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 200 */ 1274, 1274, 1274, 1274, 1274, 1410, 1603, 1603, 1274, 1309,
- /* 210 */ 1603, 1603, 1411, 1411, 1305, 1305, 1414, 1274, 1584, 1381,
- /* 220 */ 1381, 1381, 1381, 1390, 1381, 1274, 1274, 1274, 1274, 1274,
- /* 230 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 240 */ 1573, 1571, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 250 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 260 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 270 */ 1274, 1274, 1386, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 280 */ 1274, 1274, 1274, 1274, 1274, 1632, 1281, 1274, 1546, 1368,
- /* 290 */ 1386, 1386, 1386, 1386, 1388, 1369, 1367, 1380, 1310, 1679,
- /* 300 */ 1446, 1435, 1387, 1435, 1676, 1433, 1446, 1446, 1433, 1446,
- /* 310 */ 1387, 1676, 1326, 1654, 1321, 1420, 1420, 1420, 1410, 1410,
- /* 320 */ 1410, 1410, 1414, 1414, 1512, 1387, 1380, 1274, 1679, 1679,
- /* 330 */ 1396, 1396, 1678, 1678, 1396, 1534, 1662, 1455, 1354, 1360,
- /* 340 */ 1360, 1360, 1360, 1360, 1396, 1293, 1433, 1662, 1662, 1433,
- /* 350 */ 1455, 1354, 1433, 1354, 1433, 1523, 1396, 1293, 1293, 1550,
- /* 360 */ 1673, 1396, 1293, 1524, 1396, 1293, 1396, 1293, 1524, 1352,
- /* 370 */ 1352, 1352, 1341, 1274, 1274, 1524, 1352, 1326, 1352, 1341,
- /* 380 */ 1352, 1352, 1621, 1274, 1528, 1528, 1524, 1396, 1613, 1613,
- /* 390 */ 1423, 1423, 1428, 1414, 1517, 1396, 1274, 1428, 1426, 1424,
- /* 400 */ 1433, 1344, 1635, 1635, 1631, 1631, 1631, 1684, 1684, 1584,
- /* 410 */ 1647, 1647, 1309, 1309, 1309, 1309, 1647, 1328, 1328, 1310,
- /* 420 */ 1310, 1309, 1647, 1274, 1274, 1274, 1274, 1578, 1274, 1274,
- /* 430 */ 1642, 1274, 1535, 1400, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 440 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 450 */ 1274, 1590, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 460 */ 1274, 1274, 1460, 1274, 1277, 1581, 1274, 1274, 1274, 1274,
- /* 470 */ 1274, 1274, 1274, 1274, 1274, 1274, 1437, 1438, 1401, 1274,
- /* 480 */ 1274, 1274, 1274, 1274, 1274, 1274, 1452, 1274, 1274, 1274,
- /* 490 */ 1447, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1675,
- /* 500 */ 1274, 1274, 1522, 1274, 1274, 1274, 1274, 1274, 1274, 1549,
- /* 510 */ 1548, 1274, 1274, 1398, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 520 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1324, 1274, 1274,
- /* 530 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 540 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 550 */ 1274, 1425, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 560 */ 1274, 1274, 1274, 1274, 1274, 1274, 1618, 1415, 1274, 1274,
- /* 570 */ 1274, 1274, 1666, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 580 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1658, 1371, 1461,
- /* 590 */ 1274, 1464, 1297, 1274, 1287, 1274, 1274,
+ /* 0 */ 1702, 1702, 1702, 1527, 1285, 1403, 1285, 1285, 1285, 1285,
+ /* 10 */ 1527, 1527, 1527, 1285, 1285, 1285, 1285, 1285, 1285, 1433,
+ /* 20 */ 1433, 1582, 1320, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 30 */ 1285, 1285, 1285, 1285, 1285, 1526, 1285, 1285, 1285, 1285,
+ /* 40 */ 1617, 1617, 1285, 1285, 1285, 1285, 1285, 1602, 1601, 1285,
+ /* 50 */ 1285, 1285, 1442, 1285, 1449, 1285, 1285, 1285, 1285, 1285,
+ /* 60 */ 1528, 1529, 1285, 1285, 1285, 1285, 1581, 1583, 1546, 1456,
+ /* 70 */ 1455, 1454, 1453, 1564, 1421, 1447, 1440, 1444, 1523, 1524,
+ /* 80 */ 1522, 1680, 1529, 1528, 1285, 1443, 1491, 1507, 1490, 1285,
+ /* 90 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 100 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 110 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 120 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 130 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 140 */ 1285, 1285, 1499, 1506, 1505, 1504, 1513, 1503, 1500, 1493,
+ /* 150 */ 1492, 1494, 1495, 1310, 1307, 1285, 1362, 1285, 1285, 1285,
+ /* 160 */ 1285, 1285, 1496, 1320, 1484, 1483, 1482, 1285, 1510, 1497,
+ /* 170 */ 1509, 1508, 1589, 1593, 1654, 1653, 1285, 1547, 1285, 1285,
+ /* 180 */ 1285, 1285, 1285, 1285, 1617, 1285, 1285, 1285, 1285, 1285,
+ /* 190 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 200 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1423,
+ /* 210 */ 1617, 1617, 1285, 1320, 1617, 1617, 1424, 1424, 1316, 1316,
+ /* 220 */ 1427, 1597, 1394, 1394, 1394, 1394, 1403, 1394, 1285, 1285,
+ /* 230 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 240 */ 1285, 1285, 1285, 1586, 1584, 1285, 1285, 1285, 1285, 1285,
+ /* 250 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 260 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 270 */ 1285, 1285, 1285, 1285, 1285, 1399, 1285, 1285, 1285, 1285,
+ /* 280 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1647, 1292, 1285,
+ /* 290 */ 1559, 1379, 1399, 1399, 1399, 1399, 1401, 1380, 1378, 1393,
+ /* 300 */ 1321, 1694, 1459, 1448, 1400, 1448, 1691, 1446, 1459, 1459,
+ /* 310 */ 1446, 1459, 1400, 1691, 1337, 1669, 1332, 1433, 1433, 1433,
+ /* 320 */ 1423, 1423, 1423, 1423, 1427, 1427, 1525, 1400, 1393, 1285,
+ /* 330 */ 1694, 1694, 1409, 1409, 1693, 1693, 1409, 1547, 1677, 1468,
+ /* 340 */ 1365, 1371, 1371, 1371, 1371, 1371, 1409, 1304, 1446, 1677,
+ /* 350 */ 1677, 1446, 1468, 1365, 1446, 1365, 1446, 1536, 1409, 1304,
+ /* 360 */ 1304, 1563, 1688, 1409, 1304, 1537, 1409, 1304, 1409, 1304,
+ /* 370 */ 1537, 1363, 1363, 1363, 1352, 1285, 1285, 1537, 1363, 1337,
+ /* 380 */ 1363, 1352, 1363, 1363, 1635, 1285, 1541, 1541, 1537, 1409,
+ /* 390 */ 1627, 1627, 1436, 1436, 1441, 1427, 1530, 1409, 1285, 1441,
+ /* 400 */ 1439, 1437, 1446, 1355, 1650, 1650, 1646, 1646, 1646, 1699,
+ /* 410 */ 1699, 1597, 1662, 1662, 1320, 1320, 1320, 1320, 1662, 1339,
+ /* 420 */ 1339, 1321, 1321, 1320, 1662, 1285, 1285, 1285, 1285, 1591,
+ /* 430 */ 1285, 1285, 1657, 1285, 1548, 1413, 1285, 1285, 1285, 1285,
+ /* 440 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 450 */ 1285, 1285, 1285, 1603, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 460 */ 1285, 1285, 1285, 1285, 1285, 1473, 1285, 1288, 1594, 1285,
+ /* 470 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1450,
+ /* 480 */ 1451, 1414, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1465,
+ /* 490 */ 1285, 1285, 1285, 1460, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 500 */ 1285, 1285, 1690, 1285, 1285, 1535, 1285, 1285, 1285, 1285,
+ /* 510 */ 1285, 1285, 1562, 1561, 1285, 1285, 1411, 1285, 1285, 1285,
+ /* 520 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 530 */ 1335, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 540 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 550 */ 1285, 1285, 1285, 1285, 1438, 1285, 1285, 1285, 1285, 1285,
+ /* 560 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1632,
+ /* 570 */ 1428, 1285, 1285, 1285, 1285, 1681, 1285, 1285, 1285, 1285,
+ /* 580 */ 1388, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ /* 590 */ 1285, 1673, 1382, 1474, 1285, 1477, 1308, 1285, 1298, 1285,
+ /* 600 */ 1285,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -174822,56 +177775,57 @@ static const YYACTIONTYPE yy_default[] = {
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 63, /* EXPLAIN => ID */
- 63, /* QUERY => ID */
- 63, /* PLAN => ID */
- 63, /* BEGIN => ID */
+ 64, /* EXPLAIN => ID */
+ 64, /* QUERY => ID */
+ 64, /* PLAN => ID */
+ 64, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 63, /* DEFERRED => ID */
- 63, /* IMMEDIATE => ID */
- 63, /* EXCLUSIVE => ID */
- 63, /* READONLY => ID */
+ 64, /* DEFERRED => ID */
+ 64, /* IMMEDIATE => ID */
+ 64, /* EXCLUSIVE => ID */
+ 64, /* READONLY => ID */
0, /* COMMIT => nothing */
- 63, /* END => ID */
- 63, /* ROLLBACK => ID */
- 63, /* SAVEPOINT => ID */
- 63, /* RELEASE => ID */
+ 64, /* END => ID */
+ 64, /* ROLLBACK => ID */
+ 64, /* SAVEPOINT => ID */
+ 64, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 63, /* IF => ID */
+ 64, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 63, /* TEMP => ID */
+ 64, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
0, /* COMMA => nothing */
- 63, /* WITHOUT => ID */
- 63, /* RANDOM => ID */
- 63, /* ABORT => ID */
- 63, /* ACTION => ID */
- 63, /* AFTER => ID */
- 63, /* ANALYZE => ID */
- 63, /* ASC => ID */
- 63, /* ATTACH => ID */
- 63, /* BEFORE => ID */
- 63, /* BY => ID */
- 63, /* CASCADE => ID */
- 63, /* CAST => ID */
- 63, /* CONFLICT => ID */
- 63, /* DATABASE => ID */
- 63, /* DESC => ID */
- 63, /* DETACH => ID */
- 63, /* EACH => ID */
- 63, /* FAIL => ID */
- 63, /* FUNCTION => ID */
- 63, /* LANGUAGE => ID */
+ 64, /* WITHOUT => ID */
+ 64, /* RANDOM => ID */
+ 64, /* ABORT => ID */
+ 64, /* ACTION => ID */
+ 64, /* AFTER => ID */
+ 64, /* ANALYZE => ID */
+ 64, /* ASC => ID */
+ 64, /* ATTACH => ID */
+ 64, /* BEFORE => ID */
+ 64, /* BY => ID */
+ 64, /* CASCADE => ID */
+ 64, /* CAST => ID */
+ 64, /* CONFLICT => ID */
+ 64, /* DATABASE => ID */
+ 64, /* DESC => ID */
+ 64, /* DETACH => ID */
+ 64, /* EACH => ID */
+ 64, /* FAIL => ID */
+ 64, /* FUNCTION => ID */
+ 64, /* LANGUAGE => ID */
0, /* OR => nothing */
0, /* AND => nothing */
0, /* IS => nothing */
- 63, /* MATCH => ID */
- 63, /* LIKE_KW => ID */
+ 0, /* ISNOT => nothing */
+ 64, /* MATCH => ID */
+ 64, /* LIKE_KW => ID */
0, /* BETWEEN => nothing */
0, /* IN => nothing */
0, /* ISNULL => nothing */
@@ -174884,47 +177838,47 @@ static const YYCODETYPE yyFallback[] = {
0, /* GE => nothing */
0, /* ESCAPE => nothing */
0, /* ID => nothing */
- 63, /* COLUMNKW => ID */
- 63, /* DO => ID */
- 63, /* FOR => ID */
- 63, /* IGNORE => ID */
- 63, /* INITIALLY => ID */
- 63, /* INSTEAD => ID */
- 63, /* NO => ID */
- 63, /* KEY => ID */
- 63, /* OF => ID */
- 63, /* OFFSET => ID */
- 63, /* PRAGMA => ID */
- 63, /* RAISE => ID */
- 63, /* RECURSIVE => ID */
- 63, /* REPLACE => ID */
- 63, /* RESTRICT => ID */
- 63, /* ROW => ID */
- 63, /* ROWS => ID */
- 63, /* TRIGGER => ID */
- 63, /* VACUUM => ID */
- 63, /* VIEW => ID */
- 63, /* VIRTUAL => ID */
- 63, /* WITH => ID */
- 63, /* NULLS => ID */
- 63, /* FIRST => ID */
- 63, /* LAST => ID */
- 63, /* CURRENT => ID */
- 63, /* FOLLOWING => ID */
- 63, /* PARTITION => ID */
- 63, /* PRECEDING => ID */
- 63, /* RANGE => ID */
- 63, /* UNBOUNDED => ID */
- 63, /* EXCLUDE => ID */
- 63, /* GROUPS => ID */
- 63, /* OTHERS => ID */
- 63, /* TIES => ID */
- 63, /* GENERATED => ID */
- 63, /* ALWAYS => ID */
- 63, /* MATERIALIZED => ID */
- 63, /* REINDEX => ID */
- 63, /* RENAME => ID */
- 63, /* CTIME_KW => ID */
+ 64, /* COLUMNKW => ID */
+ 64, /* DO => ID */
+ 64, /* FOR => ID */
+ 64, /* IGNORE => ID */
+ 64, /* INITIALLY => ID */
+ 64, /* INSTEAD => ID */
+ 64, /* NO => ID */
+ 64, /* KEY => ID */
+ 64, /* OF => ID */
+ 64, /* OFFSET => ID */
+ 64, /* PRAGMA => ID */
+ 64, /* RAISE => ID */
+ 64, /* RECURSIVE => ID */
+ 64, /* REPLACE => ID */
+ 64, /* RESTRICT => ID */
+ 64, /* ROW => ID */
+ 64, /* ROWS => ID */
+ 64, /* TRIGGER => ID */
+ 64, /* VACUUM => ID */
+ 64, /* VIEW => ID */
+ 64, /* VIRTUAL => ID */
+ 64, /* WITH => ID */
+ 64, /* NULLS => ID */
+ 64, /* FIRST => ID */
+ 64, /* LAST => ID */
+ 64, /* CURRENT => ID */
+ 64, /* FOLLOWING => ID */
+ 64, /* PARTITION => ID */
+ 64, /* PRECEDING => ID */
+ 64, /* RANGE => ID */
+ 64, /* UNBOUNDED => ID */
+ 64, /* EXCLUDE => ID */
+ 64, /* GROUPS => ID */
+ 64, /* OTHERS => ID */
+ 64, /* TIES => ID */
+ 64, /* GENERATED => ID */
+ 64, /* ALWAYS => ID */
+ 64, /* MATERIALIZED => ID */
+ 64, /* REINDEX => ID */
+ 64, /* RENAME => ID */
+ 64, /* CTIME_KW => ID */
0, /* ANY => nothing */
0, /* BITAND => nothing */
0, /* BITOR => nothing */
@@ -174995,9 +177949,8 @@ static const YYCODETYPE yyFallback[] = {
0, /* AGG_FUNCTION => nothing */
0, /* AGG_COLUMN => nothing */
0, /* TRUEFALSE => nothing */
- 0, /* ISNOT => nothing */
- 0, /* UMINUS => nothing */
0, /* UPLUS => nothing */
+ 0, /* UMINUS => nothing */
0, /* TRUTH => nothing */
0, /* REGISTER => nothing */
0, /* VECTOR => nothing */
@@ -175006,6 +177959,7 @@ static const YYCODETYPE yyFallback[] = {
0, /* ASTERISK => nothing */
0, /* SPAN => nothing */
0, /* ERROR => nothing */
+ 0, /* QNUMBER => nothing */
0, /* SPACE => nothing */
0, /* ILLEGAL => nothing */
};
@@ -175048,14 +178002,9 @@ struct yyParser {
#endif
sqlite3ParserARG_SDECL /* A place to hold %extra_argument */
sqlite3ParserCTX_SDECL /* A place to hold %extra_context */
-#if YYSTACKDEPTH<=0
- int yystksz; /* Current side of the stack */
- yyStackEntry *yystack; /* The parser's stack */
- yyStackEntry yystk0; /* First stack entry */
-#else
- yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
- yyStackEntry *yystackEnd; /* Last entry in the stack */
-#endif
+ yyStackEntry *yystackEnd; /* Last entry in the stack */
+ yyStackEntry *yystack; /* The parser stack */
+ yyStackEntry yystk0[YYSTACKDEPTH]; /* Initial stack space */
};
typedef struct yyParser yyParser;
@@ -175146,134 +178095,134 @@ static const char *const yyTokenName[] = {
/* 47 */ "OR",
/* 48 */ "AND",
/* 49 */ "IS",
- /* 50 */ "MATCH",
- /* 51 */ "LIKE_KW",
- /* 52 */ "BETWEEN",
- /* 53 */ "IN",
- /* 54 */ "ISNULL",
- /* 55 */ "NOTNULL",
- /* 56 */ "NE",
- /* 57 */ "EQ",
- /* 58 */ "GT",
- /* 59 */ "LE",
- /* 60 */ "LT",
- /* 61 */ "GE",
- /* 62 */ "ESCAPE",
- /* 63 */ "ID",
- /* 64 */ "COLUMNKW",
- /* 65 */ "DO",
- /* 66 */ "FOR",
- /* 67 */ "IGNORE",
- /* 68 */ "INITIALLY",
- /* 69 */ "INSTEAD",
- /* 70 */ "NO",
- /* 71 */ "KEY",
- /* 72 */ "OF",
- /* 73 */ "OFFSET",
- /* 74 */ "PRAGMA",
- /* 75 */ "RAISE",
- /* 76 */ "RECURSIVE",
- /* 77 */ "REPLACE",
- /* 78 */ "RESTRICT",
- /* 79 */ "ROW",
- /* 80 */ "ROWS",
- /* 81 */ "TRIGGER",
- /* 82 */ "VACUUM",
- /* 83 */ "VIEW",
- /* 84 */ "VIRTUAL",
- /* 85 */ "WITH",
- /* 86 */ "NULLS",
- /* 87 */ "FIRST",
- /* 88 */ "LAST",
- /* 89 */ "CURRENT",
- /* 90 */ "FOLLOWING",
- /* 91 */ "PARTITION",
- /* 92 */ "PRECEDING",
- /* 93 */ "RANGE",
- /* 94 */ "UNBOUNDED",
- /* 95 */ "EXCLUDE",
- /* 96 */ "GROUPS",
- /* 97 */ "OTHERS",
- /* 98 */ "TIES",
- /* 99 */ "GENERATED",
- /* 100 */ "ALWAYS",
- /* 101 */ "MATERIALIZED",
- /* 102 */ "REINDEX",
- /* 103 */ "RENAME",
- /* 104 */ "CTIME_KW",
- /* 105 */ "ANY",
- /* 106 */ "BITAND",
- /* 107 */ "BITOR",
- /* 108 */ "LSHIFT",
- /* 109 */ "RSHIFT",
- /* 110 */ "PLUS",
- /* 111 */ "MINUS",
- /* 112 */ "STAR",
- /* 113 */ "SLASH",
- /* 114 */ "REM",
- /* 115 */ "CONCAT",
- /* 116 */ "PTR",
- /* 117 */ "COLLATE",
- /* 118 */ "BITNOT",
- /* 119 */ "ON",
- /* 120 */ "INDEXED",
- /* 121 */ "STRING",
- /* 122 */ "JOIN_KW",
- /* 123 */ "CONSTRAINT",
- /* 124 */ "DEFAULT",
- /* 125 */ "NULL",
- /* 126 */ "PRIMARY",
- /* 127 */ "UNIQUE",
- /* 128 */ "CHECK",
- /* 129 */ "REFERENCES",
- /* 130 */ "AUTOINCR",
- /* 131 */ "INSERT",
- /* 132 */ "DELETE",
- /* 133 */ "UPDATE",
- /* 134 */ "SET",
- /* 135 */ "DEFERRABLE",
- /* 136 */ "FOREIGN",
- /* 137 */ "DROP",
- /* 138 */ "BLOB",
- /* 139 */ "UNION",
- /* 140 */ "ALL",
- /* 141 */ "EXCEPT",
- /* 142 */ "INTERSECT",
- /* 143 */ "SELECT",
- /* 144 */ "VALUES",
- /* 145 */ "DISTINCT",
- /* 146 */ "DOT",
- /* 147 */ "FROM",
- /* 148 */ "JOIN",
- /* 149 */ "USING",
- /* 150 */ "ORDER",
- /* 151 */ "GROUP",
- /* 152 */ "HAVING",
- /* 153 */ "LIMIT",
- /* 154 */ "WHERE",
- /* 155 */ "RETURNING",
- /* 156 */ "INTO",
- /* 157 */ "NOTHING",
- /* 158 */ "FLOAT",
- /* 159 */ "INTEGER",
- /* 160 */ "VARIABLE",
- /* 161 */ "CASE",
- /* 162 */ "WHEN",
- /* 163 */ "THEN",
- /* 164 */ "ELSE",
- /* 165 */ "INDEX",
- /* 166 */ "ALTER",
- /* 167 */ "ADD",
- /* 168 */ "WINDOW",
- /* 169 */ "OVER",
- /* 170 */ "FILTER",
- /* 171 */ "COLUMN",
- /* 172 */ "AGG_FUNCTION",
- /* 173 */ "AGG_COLUMN",
- /* 174 */ "TRUEFALSE",
- /* 175 */ "ISNOT",
- /* 176 */ "UMINUS",
- /* 177 */ "UPLUS",
+ /* 50 */ "ISNOT",
+ /* 51 */ "MATCH",
+ /* 52 */ "LIKE_KW",
+ /* 53 */ "BETWEEN",
+ /* 54 */ "IN",
+ /* 55 */ "ISNULL",
+ /* 56 */ "NOTNULL",
+ /* 57 */ "NE",
+ /* 58 */ "EQ",
+ /* 59 */ "GT",
+ /* 60 */ "LE",
+ /* 61 */ "LT",
+ /* 62 */ "GE",
+ /* 63 */ "ESCAPE",
+ /* 64 */ "ID",
+ /* 65 */ "COLUMNKW",
+ /* 66 */ "DO",
+ /* 67 */ "FOR",
+ /* 68 */ "IGNORE",
+ /* 69 */ "INITIALLY",
+ /* 70 */ "INSTEAD",
+ /* 71 */ "NO",
+ /* 72 */ "KEY",
+ /* 73 */ "OF",
+ /* 74 */ "OFFSET",
+ /* 75 */ "PRAGMA",
+ /* 76 */ "RAISE",
+ /* 77 */ "RECURSIVE",
+ /* 78 */ "REPLACE",
+ /* 79 */ "RESTRICT",
+ /* 80 */ "ROW",
+ /* 81 */ "ROWS",
+ /* 82 */ "TRIGGER",
+ /* 83 */ "VACUUM",
+ /* 84 */ "VIEW",
+ /* 85 */ "VIRTUAL",
+ /* 86 */ "WITH",
+ /* 87 */ "NULLS",
+ /* 88 */ "FIRST",
+ /* 89 */ "LAST",
+ /* 90 */ "CURRENT",
+ /* 91 */ "FOLLOWING",
+ /* 92 */ "PARTITION",
+ /* 93 */ "PRECEDING",
+ /* 94 */ "RANGE",
+ /* 95 */ "UNBOUNDED",
+ /* 96 */ "EXCLUDE",
+ /* 97 */ "GROUPS",
+ /* 98 */ "OTHERS",
+ /* 99 */ "TIES",
+ /* 100 */ "GENERATED",
+ /* 101 */ "ALWAYS",
+ /* 102 */ "MATERIALIZED",
+ /* 103 */ "REINDEX",
+ /* 104 */ "RENAME",
+ /* 105 */ "CTIME_KW",
+ /* 106 */ "ANY",
+ /* 107 */ "BITAND",
+ /* 108 */ "BITOR",
+ /* 109 */ "LSHIFT",
+ /* 110 */ "RSHIFT",
+ /* 111 */ "PLUS",
+ /* 112 */ "MINUS",
+ /* 113 */ "STAR",
+ /* 114 */ "SLASH",
+ /* 115 */ "REM",
+ /* 116 */ "CONCAT",
+ /* 117 */ "PTR",
+ /* 118 */ "COLLATE",
+ /* 119 */ "BITNOT",
+ /* 120 */ "ON",
+ /* 121 */ "INDEXED",
+ /* 122 */ "STRING",
+ /* 123 */ "JOIN_KW",
+ /* 124 */ "CONSTRAINT",
+ /* 125 */ "DEFAULT",
+ /* 126 */ "NULL",
+ /* 127 */ "PRIMARY",
+ /* 128 */ "UNIQUE",
+ /* 129 */ "CHECK",
+ /* 130 */ "REFERENCES",
+ /* 131 */ "AUTOINCR",
+ /* 132 */ "INSERT",
+ /* 133 */ "DELETE",
+ /* 134 */ "UPDATE",
+ /* 135 */ "SET",
+ /* 136 */ "DEFERRABLE",
+ /* 137 */ "FOREIGN",
+ /* 138 */ "DROP",
+ /* 139 */ "BLOB",
+ /* 140 */ "UNION",
+ /* 141 */ "ALL",
+ /* 142 */ "EXCEPT",
+ /* 143 */ "INTERSECT",
+ /* 144 */ "SELECT",
+ /* 145 */ "VALUES",
+ /* 146 */ "DISTINCT",
+ /* 147 */ "DOT",
+ /* 148 */ "FROM",
+ /* 149 */ "JOIN",
+ /* 150 */ "USING",
+ /* 151 */ "ORDER",
+ /* 152 */ "GROUP",
+ /* 153 */ "HAVING",
+ /* 154 */ "LIMIT",
+ /* 155 */ "WHERE",
+ /* 156 */ "RETURNING",
+ /* 157 */ "INTO",
+ /* 158 */ "NOTHING",
+ /* 159 */ "FLOAT",
+ /* 160 */ "INTEGER",
+ /* 161 */ "VARIABLE",
+ /* 162 */ "CASE",
+ /* 163 */ "WHEN",
+ /* 164 */ "THEN",
+ /* 165 */ "ELSE",
+ /* 166 */ "INDEX",
+ /* 167 */ "ALTER",
+ /* 168 */ "ADD",
+ /* 169 */ "WINDOW",
+ /* 170 */ "OVER",
+ /* 171 */ "FILTER",
+ /* 172 */ "COLUMN",
+ /* 173 */ "AGG_FUNCTION",
+ /* 174 */ "AGG_COLUMN",
+ /* 175 */ "TRUEFALSE",
+ /* 176 */ "UPLUS",
+ /* 177 */ "UMINUS",
/* 178 */ "TRUTH",
/* 179 */ "REGISTER",
/* 180 */ "VECTOR",
@@ -175282,143 +178231,146 @@ static const char *const yyTokenName[] = {
/* 183 */ "ASTERISK",
/* 184 */ "SPAN",
/* 185 */ "ERROR",
- /* 186 */ "SPACE",
- /* 187 */ "ILLEGAL",
- /* 188 */ "input",
- /* 189 */ "cmdlist",
- /* 190 */ "ecmd",
- /* 191 */ "cmdx",
- /* 192 */ "explain",
- /* 193 */ "cmd",
- /* 194 */ "transtype",
- /* 195 */ "trans_opt",
- /* 196 */ "nm",
- /* 197 */ "savepoint_opt",
- /* 198 */ "create_table",
- /* 199 */ "create_table_args",
- /* 200 */ "createkw",
- /* 201 */ "temp",
- /* 202 */ "ifnotexists",
- /* 203 */ "dbnm",
- /* 204 */ "columnlist",
- /* 205 */ "conslist_opt",
- /* 206 */ "table_option_set",
- /* 207 */ "select",
- /* 208 */ "table_option",
- /* 209 */ "columnname",
- /* 210 */ "carglist",
- /* 211 */ "typetoken",
- /* 212 */ "typename",
- /* 213 */ "signed",
- /* 214 */ "plus_num",
- /* 215 */ "minus_num",
- /* 216 */ "scanpt",
- /* 217 */ "scantok",
- /* 218 */ "ccons",
- /* 219 */ "term",
- /* 220 */ "expr",
- /* 221 */ "onconf",
- /* 222 */ "sortorder",
- /* 223 */ "autoinc",
- /* 224 */ "eidlist_opt",
- /* 225 */ "refargs",
- /* 226 */ "defer_subclause",
- /* 227 */ "generated",
- /* 228 */ "refarg",
- /* 229 */ "refact",
- /* 230 */ "init_deferred_pred_opt",
- /* 231 */ "conslist",
- /* 232 */ "tconscomma",
- /* 233 */ "tcons",
- /* 234 */ "sortlist",
- /* 235 */ "eidlist",
- /* 236 */ "defer_subclause_opt",
- /* 237 */ "orconf",
- /* 238 */ "resolvetype",
- /* 239 */ "raisetype",
- /* 240 */ "ifexists",
- /* 241 */ "fullname",
- /* 242 */ "selectnowith",
- /* 243 */ "oneselect",
- /* 244 */ "wqlist",
- /* 245 */ "multiselect_op",
- /* 246 */ "distinct",
- /* 247 */ "selcollist",
- /* 248 */ "from",
- /* 249 */ "where_opt",
- /* 250 */ "groupby_opt",
- /* 251 */ "having_opt",
- /* 252 */ "orderby_opt",
- /* 253 */ "limit_opt",
- /* 254 */ "window_clause",
- /* 255 */ "values",
- /* 256 */ "nexprlist",
- /* 257 */ "sclp",
- /* 258 */ "as",
- /* 259 */ "seltablist",
- /* 260 */ "stl_prefix",
- /* 261 */ "joinop",
- /* 262 */ "on_using",
- /* 263 */ "indexed_by",
- /* 264 */ "exprlist",
- /* 265 */ "xfullname",
- /* 266 */ "idlist",
- /* 267 */ "indexed_opt",
- /* 268 */ "nulls",
- /* 269 */ "with",
- /* 270 */ "where_opt_ret",
- /* 271 */ "setlist",
- /* 272 */ "insert_cmd",
- /* 273 */ "idlist_opt",
- /* 274 */ "upsert",
- /* 275 */ "returning",
- /* 276 */ "filter_over",
- /* 277 */ "likeop",
- /* 278 */ "between_op",
- /* 279 */ "in_op",
- /* 280 */ "paren_exprlist",
- /* 281 */ "case_operand",
- /* 282 */ "case_exprlist",
- /* 283 */ "case_else",
- /* 284 */ "uniqueflag",
- /* 285 */ "indextype",
- /* 286 */ "collate",
- /* 287 */ "vinto",
- /* 288 */ "nmnum",
- /* 289 */ "trigger_decl",
- /* 290 */ "trigger_cmd_list",
- /* 291 */ "trigger_time",
- /* 292 */ "trigger_event",
- /* 293 */ "foreach_clause",
- /* 294 */ "when_clause",
- /* 295 */ "trigger_cmd",
- /* 296 */ "trnm",
- /* 297 */ "tridxby",
- /* 298 */ "database_kw_opt",
- /* 299 */ "key_opt",
- /* 300 */ "add_column_fullname",
- /* 301 */ "kwcolumn_opt",
- /* 302 */ "create_vtab",
- /* 303 */ "vtabarglist",
- /* 304 */ "vtabarg",
- /* 305 */ "vtabargtoken",
- /* 306 */ "lp",
- /* 307 */ "anylist",
- /* 308 */ "wqitem",
- /* 309 */ "wqas",
- /* 310 */ "windowdefn_list",
- /* 311 */ "windowdefn",
- /* 312 */ "window",
- /* 313 */ "frame_opt",
- /* 314 */ "part_opt",
- /* 315 */ "filter_clause",
- /* 316 */ "over_clause",
- /* 317 */ "range_or_rows",
- /* 318 */ "frame_bound",
- /* 319 */ "frame_bound_s",
- /* 320 */ "frame_bound_e",
- /* 321 */ "frame_exclude_opt",
- /* 322 */ "frame_exclude",
+ /* 186 */ "QNUMBER",
+ /* 187 */ "SPACE",
+ /* 188 */ "ILLEGAL",
+ /* 189 */ "input",
+ /* 190 */ "cmdlist",
+ /* 191 */ "ecmd",
+ /* 192 */ "cmdx",
+ /* 193 */ "explain",
+ /* 194 */ "cmd",
+ /* 195 */ "transtype",
+ /* 196 */ "trans_opt",
+ /* 197 */ "nm",
+ /* 198 */ "savepoint_opt",
+ /* 199 */ "create_table",
+ /* 200 */ "create_table_args",
+ /* 201 */ "createkw",
+ /* 202 */ "temp",
+ /* 203 */ "ifnotexists",
+ /* 204 */ "dbnm",
+ /* 205 */ "columnlist",
+ /* 206 */ "conslist_opt",
+ /* 207 */ "table_option_set",
+ /* 208 */ "select",
+ /* 209 */ "table_option",
+ /* 210 */ "columnname",
+ /* 211 */ "carglist",
+ /* 212 */ "typetoken",
+ /* 213 */ "typename",
+ /* 214 */ "signed",
+ /* 215 */ "plus_num",
+ /* 216 */ "minus_num",
+ /* 217 */ "scanpt",
+ /* 218 */ "scantok",
+ /* 219 */ "ccons",
+ /* 220 */ "term",
+ /* 221 */ "expr",
+ /* 222 */ "onconf",
+ /* 223 */ "sortorder",
+ /* 224 */ "autoinc",
+ /* 225 */ "eidlist_opt",
+ /* 226 */ "refargs",
+ /* 227 */ "defer_subclause",
+ /* 228 */ "generated",
+ /* 229 */ "refarg",
+ /* 230 */ "refact",
+ /* 231 */ "init_deferred_pred_opt",
+ /* 232 */ "conslist",
+ /* 233 */ "tconscomma",
+ /* 234 */ "tcons",
+ /* 235 */ "sortlist",
+ /* 236 */ "eidlist",
+ /* 237 */ "defer_subclause_opt",
+ /* 238 */ "orconf",
+ /* 239 */ "resolvetype",
+ /* 240 */ "raisetype",
+ /* 241 */ "ifexists",
+ /* 242 */ "fullname",
+ /* 243 */ "selectnowith",
+ /* 244 */ "oneselect",
+ /* 245 */ "wqlist",
+ /* 246 */ "multiselect_op",
+ /* 247 */ "distinct",
+ /* 248 */ "selcollist",
+ /* 249 */ "from",
+ /* 250 */ "where_opt",
+ /* 251 */ "groupby_opt",
+ /* 252 */ "having_opt",
+ /* 253 */ "orderby_opt",
+ /* 254 */ "limit_opt",
+ /* 255 */ "window_clause",
+ /* 256 */ "values",
+ /* 257 */ "nexprlist",
+ /* 258 */ "mvalues",
+ /* 259 */ "sclp",
+ /* 260 */ "as",
+ /* 261 */ "seltablist",
+ /* 262 */ "stl_prefix",
+ /* 263 */ "joinop",
+ /* 264 */ "on_using",
+ /* 265 */ "indexed_by",
+ /* 266 */ "exprlist",
+ /* 267 */ "xfullname",
+ /* 268 */ "idlist",
+ /* 269 */ "indexed_opt",
+ /* 270 */ "nulls",
+ /* 271 */ "with",
+ /* 272 */ "where_opt_ret",
+ /* 273 */ "setlist",
+ /* 274 */ "insert_cmd",
+ /* 275 */ "idlist_opt",
+ /* 276 */ "upsert",
+ /* 277 */ "returning",
+ /* 278 */ "filter_over",
+ /* 279 */ "likeop",
+ /* 280 */ "between_op",
+ /* 281 */ "in_op",
+ /* 282 */ "paren_exprlist",
+ /* 283 */ "case_operand",
+ /* 284 */ "case_exprlist",
+ /* 285 */ "case_else",
+ /* 286 */ "uniqueflag",
+ /* 287 */ "indextype",
+ /* 288 */ "collate",
+ /* 289 */ "vinto",
+ /* 290 */ "nmnum",
+ /* 291 */ "trigger_decl",
+ /* 292 */ "trigger_cmd_list",
+ /* 293 */ "trigger_time",
+ /* 294 */ "trigger_event",
+ /* 295 */ "foreach_clause",
+ /* 296 */ "when_clause",
+ /* 297 */ "trigger_cmd",
+ /* 298 */ "trnm",
+ /* 299 */ "tridxby",
+ /* 300 */ "database_kw_opt",
+ /* 301 */ "key_opt",
+ /* 302 */ "add_column_fullname",
+ /* 303 */ "kwcolumn_opt",
+ /* 304 */ "create_vtab",
+ /* 305 */ "vtabarglist",
+ /* 306 */ "vtabarg",
+ /* 307 */ "vtabargtoken",
+ /* 308 */ "lp",
+ /* 309 */ "anylist",
+ /* 310 */ "wqitem",
+ /* 311 */ "wqas",
+ /* 312 */ "withnm",
+ /* 313 */ "windowdefn_list",
+ /* 314 */ "windowdefn",
+ /* 315 */ "window",
+ /* 316 */ "frame_opt",
+ /* 317 */ "part_opt",
+ /* 318 */ "filter_clause",
+ /* 319 */ "over_clause",
+ /* 320 */ "range_or_rows",
+ /* 321 */ "frame_bound",
+ /* 322 */ "frame_bound_s",
+ /* 323 */ "frame_bound_e",
+ /* 324 */ "frame_exclude_opt",
+ /* 325 */ "frame_exclude",
};
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
@@ -175526,354 +178478,366 @@ static const char *const yyRuleName[] = {
/* 97 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
/* 98 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
/* 99 */ "values ::= VALUES LP nexprlist RP",
- /* 100 */ "values ::= values COMMA LP nexprlist RP",
- /* 101 */ "distinct ::= DISTINCT",
- /* 102 */ "distinct ::= ALL",
- /* 103 */ "distinct ::=",
- /* 104 */ "sclp ::=",
- /* 105 */ "selcollist ::= sclp scanpt expr scanpt as",
- /* 106 */ "selcollist ::= sclp scanpt STAR",
- /* 107 */ "selcollist ::= sclp scanpt nm DOT STAR",
- /* 108 */ "as ::= AS nm",
- /* 109 */ "as ::=",
- /* 110 */ "from ::=",
- /* 111 */ "from ::= FROM seltablist",
- /* 112 */ "stl_prefix ::= seltablist joinop",
- /* 113 */ "stl_prefix ::=",
- /* 114 */ "seltablist ::= stl_prefix nm dbnm as on_using",
- /* 115 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using",
- /* 116 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using",
- /* 117 */ "seltablist ::= stl_prefix LP select RP as on_using",
- /* 118 */ "seltablist ::= stl_prefix LP seltablist RP as on_using",
- /* 119 */ "dbnm ::=",
- /* 120 */ "dbnm ::= DOT nm",
- /* 121 */ "fullname ::= nm",
- /* 122 */ "fullname ::= nm DOT nm",
- /* 123 */ "xfullname ::= nm",
- /* 124 */ "xfullname ::= nm DOT nm",
- /* 125 */ "xfullname ::= nm DOT nm AS nm",
- /* 126 */ "xfullname ::= nm AS nm",
- /* 127 */ "joinop ::= COMMA|JOIN",
- /* 128 */ "joinop ::= JOIN_KW JOIN",
- /* 129 */ "joinop ::= JOIN_KW nm JOIN",
- /* 130 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 131 */ "on_using ::= ON expr",
- /* 132 */ "on_using ::= USING LP idlist RP",
- /* 133 */ "on_using ::=",
- /* 134 */ "indexed_opt ::=",
- /* 135 */ "indexed_by ::= INDEXED BY nm",
- /* 136 */ "indexed_by ::= NOT INDEXED",
- /* 137 */ "orderby_opt ::=",
- /* 138 */ "orderby_opt ::= ORDER BY sortlist",
- /* 139 */ "sortlist ::= sortlist COMMA expr sortorder nulls",
- /* 140 */ "sortlist ::= expr sortorder nulls",
- /* 141 */ "sortorder ::= ASC",
- /* 142 */ "sortorder ::= DESC",
- /* 143 */ "sortorder ::=",
- /* 144 */ "nulls ::= NULLS FIRST",
- /* 145 */ "nulls ::= NULLS LAST",
- /* 146 */ "nulls ::=",
- /* 147 */ "groupby_opt ::=",
- /* 148 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 149 */ "having_opt ::=",
- /* 150 */ "having_opt ::= HAVING expr",
- /* 151 */ "limit_opt ::=",
- /* 152 */ "limit_opt ::= LIMIT expr",
- /* 153 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 154 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 155 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret",
- /* 156 */ "where_opt ::=",
- /* 157 */ "where_opt ::= WHERE expr",
- /* 158 */ "where_opt_ret ::=",
- /* 159 */ "where_opt_ret ::= WHERE expr",
- /* 160 */ "where_opt_ret ::= RETURNING selcollist",
- /* 161 */ "where_opt_ret ::= WHERE expr RETURNING selcollist",
- /* 162 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret",
- /* 163 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 164 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
- /* 165 */ "setlist ::= nm EQ expr",
- /* 166 */ "setlist ::= LP idlist RP EQ expr",
- /* 167 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
- /* 168 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning",
- /* 169 */ "upsert ::=",
- /* 170 */ "upsert ::= RETURNING selcollist",
- /* 171 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert",
- /* 172 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert",
- /* 173 */ "upsert ::= ON CONFLICT DO NOTHING returning",
- /* 174 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning",
- /* 175 */ "returning ::= RETURNING selcollist",
- /* 176 */ "insert_cmd ::= INSERT orconf",
- /* 177 */ "insert_cmd ::= REPLACE",
- /* 178 */ "idlist_opt ::=",
- /* 179 */ "idlist_opt ::= LP idlist RP",
- /* 180 */ "idlist ::= idlist COMMA nm",
- /* 181 */ "idlist ::= nm",
- /* 182 */ "expr ::= LP expr RP",
- /* 183 */ "expr ::= ID|INDEXED|JOIN_KW",
- /* 184 */ "expr ::= nm DOT nm",
- /* 185 */ "expr ::= nm DOT nm DOT nm",
- /* 186 */ "term ::= NULL|FLOAT|BLOB",
- /* 187 */ "term ::= STRING",
- /* 188 */ "term ::= INTEGER",
- /* 189 */ "expr ::= VARIABLE",
- /* 190 */ "expr ::= expr COLLATE ID|STRING",
- /* 191 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP",
- /* 193 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP",
- /* 194 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP",
- /* 195 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over",
- /* 196 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over",
- /* 197 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over",
- /* 198 */ "term ::= CTIME_KW",
- /* 199 */ "expr ::= LP nexprlist COMMA expr RP",
- /* 200 */ "expr ::= expr AND expr",
- /* 201 */ "expr ::= expr OR expr",
- /* 202 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 203 */ "expr ::= expr EQ|NE expr",
- /* 204 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 205 */ "expr ::= expr PLUS|MINUS expr",
- /* 206 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 207 */ "expr ::= expr CONCAT expr",
- /* 208 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 209 */ "expr ::= expr likeop expr",
- /* 210 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 211 */ "expr ::= expr ISNULL|NOTNULL",
- /* 212 */ "expr ::= expr NOT NULL",
- /* 213 */ "expr ::= expr IS expr",
- /* 214 */ "expr ::= expr IS NOT expr",
- /* 215 */ "expr ::= expr IS NOT DISTINCT FROM expr",
- /* 216 */ "expr ::= expr IS DISTINCT FROM expr",
- /* 217 */ "expr ::= NOT expr",
- /* 218 */ "expr ::= BITNOT expr",
- /* 219 */ "expr ::= PLUS|MINUS expr",
- /* 220 */ "expr ::= expr PTR expr",
- /* 221 */ "between_op ::= BETWEEN",
- /* 222 */ "between_op ::= NOT BETWEEN",
- /* 223 */ "expr ::= expr between_op expr AND expr",
- /* 224 */ "in_op ::= IN",
- /* 225 */ "in_op ::= NOT IN",
- /* 226 */ "expr ::= expr in_op LP exprlist RP",
- /* 227 */ "expr ::= LP select RP",
- /* 228 */ "expr ::= expr in_op LP select RP",
- /* 229 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 230 */ "expr ::= EXISTS LP select RP",
- /* 231 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 232 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 233 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 234 */ "case_else ::= ELSE expr",
- /* 235 */ "case_else ::=",
- /* 236 */ "case_operand ::=",
- /* 237 */ "exprlist ::=",
- /* 238 */ "nexprlist ::= nexprlist COMMA expr",
- /* 239 */ "nexprlist ::= expr",
- /* 240 */ "paren_exprlist ::=",
- /* 241 */ "paren_exprlist ::= LP exprlist RP",
- /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm indextype ON nm LP sortlist RP where_opt",
- /* 243 */ "uniqueflag ::= UNIQUE",
- /* 244 */ "uniqueflag ::=",
- /* 245 */ "indextype ::= USING idlist",
- /* 246 */ "indextype ::=",
- /* 247 */ "eidlist_opt ::=",
- /* 248 */ "eidlist_opt ::= LP eidlist RP",
- /* 249 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 250 */ "eidlist ::= nm collate sortorder",
- /* 251 */ "collate ::=",
- /* 252 */ "collate ::= COLLATE ID|STRING",
- /* 253 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 254 */ "cmd ::= VACUUM vinto",
- /* 255 */ "cmd ::= VACUUM nm vinto",
- /* 256 */ "vinto ::= INTO expr",
- /* 257 */ "vinto ::=",
- /* 258 */ "cmd ::= PRAGMA nm dbnm",
- /* 259 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 260 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 261 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 262 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 263 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 264 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 265 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 266 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 267 */ "trigger_time ::= BEFORE|AFTER",
- /* 268 */ "trigger_time ::= INSTEAD OF",
- /* 269 */ "trigger_time ::=",
- /* 270 */ "trigger_event ::= DELETE|INSERT",
- /* 271 */ "trigger_event ::= UPDATE",
- /* 272 */ "trigger_event ::= UPDATE OF idlist",
- /* 273 */ "when_clause ::=",
- /* 274 */ "when_clause ::= WHEN expr",
- /* 275 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 276 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 277 */ "trnm ::= nm DOT nm",
- /* 278 */ "tridxby ::= INDEXED BY nm",
- /* 279 */ "tridxby ::= NOT INDEXED",
- /* 280 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
- /* 281 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
- /* 282 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
- /* 283 */ "trigger_cmd ::= scanpt select scanpt",
- /* 284 */ "expr ::= RAISE LP IGNORE RP",
- /* 285 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 286 */ "raisetype ::= ROLLBACK",
- /* 287 */ "raisetype ::= ABORT",
- /* 288 */ "raisetype ::= FAIL",
- /* 289 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 290 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 291 */ "cmd ::= DETACH database_kw_opt expr",
- /* 292 */ "key_opt ::=",
- /* 293 */ "key_opt ::= KEY expr",
- /* 294 */ "cmd ::= REINDEX",
- /* 295 */ "cmd ::= REINDEX nm dbnm",
- /* 296 */ "cmd ::= ANALYZE",
- /* 297 */ "cmd ::= ANALYZE nm dbnm",
- /* 298 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 299 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 300 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
- /* 301 */ "add_column_fullname ::= fullname",
- /* 302 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
- /* 303 */ "cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist",
- /* 304 */ "cmd ::= create_vtab",
- /* 305 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 306 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 307 */ "vtabarg ::=",
- /* 308 */ "vtabargtoken ::= ANY",
- /* 309 */ "vtabargtoken ::= lp anylist RP",
- /* 310 */ "lp ::= LP",
- /* 311 */ "with ::= WITH wqlist",
- /* 312 */ "with ::= WITH RECURSIVE wqlist",
- /* 313 */ "wqas ::= AS",
- /* 314 */ "wqas ::= AS MATERIALIZED",
- /* 315 */ "wqas ::= AS NOT MATERIALIZED",
- /* 316 */ "wqitem ::= nm eidlist_opt wqas LP select RP",
- /* 317 */ "wqlist ::= wqitem",
- /* 318 */ "wqlist ::= wqlist COMMA wqitem",
- /* 319 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
- /* 320 */ "windowdefn ::= nm AS LP window RP",
- /* 321 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
- /* 322 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
- /* 323 */ "window ::= ORDER BY sortlist frame_opt",
- /* 324 */ "window ::= nm ORDER BY sortlist frame_opt",
- /* 325 */ "window ::= nm frame_opt",
- /* 326 */ "frame_opt ::=",
- /* 327 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
- /* 328 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
- /* 329 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
- /* 330 */ "frame_bound_s ::= frame_bound",
- /* 331 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
- /* 332 */ "frame_bound_e ::= frame_bound",
- /* 333 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
- /* 334 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
- /* 335 */ "frame_bound ::= CURRENT ROW",
- /* 336 */ "frame_exclude_opt ::=",
- /* 337 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
- /* 338 */ "frame_exclude ::= NO OTHERS",
- /* 339 */ "frame_exclude ::= CURRENT ROW",
- /* 340 */ "frame_exclude ::= GROUP|TIES",
- /* 341 */ "window_clause ::= WINDOW windowdefn_list",
- /* 342 */ "filter_over ::= filter_clause over_clause",
- /* 343 */ "filter_over ::= over_clause",
- /* 344 */ "filter_over ::= filter_clause",
- /* 345 */ "over_clause ::= OVER LP window RP",
- /* 346 */ "over_clause ::= OVER nm",
- /* 347 */ "filter_clause ::= FILTER LP WHERE expr RP",
- /* 348 */ "input ::= cmdlist",
- /* 349 */ "cmdlist ::= cmdlist ecmd",
- /* 350 */ "cmdlist ::= ecmd",
- /* 351 */ "ecmd ::= SEMI",
- /* 352 */ "ecmd ::= cmdx SEMI",
- /* 353 */ "ecmd ::= explain cmdx SEMI",
- /* 354 */ "trans_opt ::=",
- /* 355 */ "trans_opt ::= TRANSACTION",
- /* 356 */ "trans_opt ::= TRANSACTION nm",
- /* 357 */ "savepoint_opt ::= SAVEPOINT",
- /* 358 */ "savepoint_opt ::=",
- /* 359 */ "cmd ::= create_table create_table_args",
- /* 360 */ "table_option_set ::= table_option",
- /* 361 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 362 */ "columnlist ::= columnname carglist",
- /* 363 */ "nm ::= ID|INDEXED|JOIN_KW",
- /* 364 */ "nm ::= STRING",
- /* 365 */ "typetoken ::= typename",
- /* 366 */ "typename ::= ID|STRING",
- /* 367 */ "signed ::= plus_num",
- /* 368 */ "signed ::= minus_num",
- /* 369 */ "carglist ::= carglist ccons",
- /* 370 */ "carglist ::=",
- /* 371 */ "ccons ::= NULL onconf",
- /* 372 */ "ccons ::= GENERATED ALWAYS AS generated",
- /* 373 */ "ccons ::= AS generated",
- /* 374 */ "conslist_opt ::= COMMA conslist",
- /* 375 */ "conslist ::= conslist tconscomma tcons",
- /* 376 */ "conslist ::= tcons",
- /* 377 */ "tconscomma ::=",
- /* 378 */ "defer_subclause_opt ::= defer_subclause",
- /* 379 */ "resolvetype ::= raisetype",
- /* 380 */ "selectnowith ::= oneselect",
- /* 381 */ "oneselect ::= values",
- /* 382 */ "sclp ::= selcollist COMMA",
- /* 383 */ "as ::= ID|STRING",
- /* 384 */ "indexed_opt ::= indexed_by",
- /* 385 */ "returning ::=",
- /* 386 */ "expr ::= term",
- /* 387 */ "likeop ::= LIKE_KW|MATCH",
- /* 388 */ "case_operand ::= expr",
- /* 389 */ "exprlist ::= nexprlist",
- /* 390 */ "nmnum ::= plus_num",
- /* 391 */ "nmnum ::= nm",
- /* 392 */ "nmnum ::= ON",
- /* 393 */ "nmnum ::= DELETE",
- /* 394 */ "nmnum ::= DEFAULT",
- /* 395 */ "plus_num ::= INTEGER|FLOAT",
- /* 396 */ "foreach_clause ::=",
- /* 397 */ "foreach_clause ::= FOR EACH ROW",
- /* 398 */ "trnm ::= nm",
- /* 399 */ "tridxby ::=",
- /* 400 */ "database_kw_opt ::= DATABASE",
- /* 401 */ "database_kw_opt ::=",
- /* 402 */ "kwcolumn_opt ::=",
- /* 403 */ "kwcolumn_opt ::= COLUMNKW",
- /* 404 */ "vtabarglist ::= vtabarg",
- /* 405 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 406 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 407 */ "anylist ::=",
- /* 408 */ "anylist ::= anylist LP anylist RP",
- /* 409 */ "anylist ::= anylist ANY",
- /* 410 */ "with ::=",
- /* 411 */ "windowdefn_list ::= windowdefn",
- /* 412 */ "window ::= frame_opt",
+ /* 100 */ "oneselect ::= mvalues",
+ /* 101 */ "mvalues ::= values COMMA LP nexprlist RP",
+ /* 102 */ "mvalues ::= mvalues COMMA LP nexprlist RP",
+ /* 103 */ "distinct ::= DISTINCT",
+ /* 104 */ "distinct ::= ALL",
+ /* 105 */ "distinct ::=",
+ /* 106 */ "sclp ::=",
+ /* 107 */ "selcollist ::= sclp scanpt expr scanpt as",
+ /* 108 */ "selcollist ::= sclp scanpt STAR",
+ /* 109 */ "selcollist ::= sclp scanpt nm DOT STAR",
+ /* 110 */ "as ::= AS nm",
+ /* 111 */ "as ::=",
+ /* 112 */ "from ::=",
+ /* 113 */ "from ::= FROM seltablist",
+ /* 114 */ "stl_prefix ::= seltablist joinop",
+ /* 115 */ "stl_prefix ::=",
+ /* 116 */ "seltablist ::= stl_prefix nm dbnm as on_using",
+ /* 117 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using",
+ /* 118 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using",
+ /* 119 */ "seltablist ::= stl_prefix LP select RP as on_using",
+ /* 120 */ "seltablist ::= stl_prefix LP seltablist RP as on_using",
+ /* 121 */ "dbnm ::=",
+ /* 122 */ "dbnm ::= DOT nm",
+ /* 123 */ "fullname ::= nm",
+ /* 124 */ "fullname ::= nm DOT nm",
+ /* 125 */ "xfullname ::= nm",
+ /* 126 */ "xfullname ::= nm DOT nm",
+ /* 127 */ "xfullname ::= nm DOT nm AS nm",
+ /* 128 */ "xfullname ::= nm AS nm",
+ /* 129 */ "joinop ::= COMMA|JOIN",
+ /* 130 */ "joinop ::= JOIN_KW JOIN",
+ /* 131 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 132 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 133 */ "on_using ::= ON expr",
+ /* 134 */ "on_using ::= USING LP idlist RP",
+ /* 135 */ "on_using ::=",
+ /* 136 */ "indexed_opt ::=",
+ /* 137 */ "indexed_by ::= INDEXED BY nm",
+ /* 138 */ "indexed_by ::= NOT INDEXED",
+ /* 139 */ "orderby_opt ::=",
+ /* 140 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 141 */ "sortlist ::= sortlist COMMA expr sortorder nulls",
+ /* 142 */ "sortlist ::= expr sortorder nulls",
+ /* 143 */ "sortorder ::= ASC",
+ /* 144 */ "sortorder ::= DESC",
+ /* 145 */ "sortorder ::=",
+ /* 146 */ "nulls ::= NULLS FIRST",
+ /* 147 */ "nulls ::= NULLS LAST",
+ /* 148 */ "nulls ::=",
+ /* 149 */ "groupby_opt ::=",
+ /* 150 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 151 */ "having_opt ::=",
+ /* 152 */ "having_opt ::= HAVING expr",
+ /* 153 */ "limit_opt ::=",
+ /* 154 */ "limit_opt ::= LIMIT expr",
+ /* 155 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 156 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 157 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret",
+ /* 158 */ "where_opt ::=",
+ /* 159 */ "where_opt ::= WHERE expr",
+ /* 160 */ "where_opt_ret ::=",
+ /* 161 */ "where_opt_ret ::= WHERE expr",
+ /* 162 */ "where_opt_ret ::= RETURNING selcollist",
+ /* 163 */ "where_opt_ret ::= WHERE expr RETURNING selcollist",
+ /* 164 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret",
+ /* 165 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 166 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+ /* 167 */ "setlist ::= nm EQ expr",
+ /* 168 */ "setlist ::= LP idlist RP EQ expr",
+ /* 169 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
+ /* 170 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning",
+ /* 171 */ "upsert ::=",
+ /* 172 */ "upsert ::= RETURNING selcollist",
+ /* 173 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert",
+ /* 174 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert",
+ /* 175 */ "upsert ::= ON CONFLICT DO NOTHING returning",
+ /* 176 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning",
+ /* 177 */ "returning ::= RETURNING selcollist",
+ /* 178 */ "insert_cmd ::= INSERT orconf",
+ /* 179 */ "insert_cmd ::= REPLACE",
+ /* 180 */ "idlist_opt ::=",
+ /* 181 */ "idlist_opt ::= LP idlist RP",
+ /* 182 */ "idlist ::= idlist COMMA nm",
+ /* 183 */ "idlist ::= nm",
+ /* 184 */ "expr ::= LP expr RP",
+ /* 185 */ "expr ::= ID|INDEXED|JOIN_KW",
+ /* 186 */ "expr ::= nm DOT nm",
+ /* 187 */ "expr ::= nm DOT nm DOT nm",
+ /* 188 */ "term ::= NULL|FLOAT|BLOB",
+ /* 189 */ "term ::= STRING",
+ /* 190 */ "term ::= INTEGER",
+ /* 191 */ "expr ::= VARIABLE",
+ /* 192 */ "expr ::= expr COLLATE ID|STRING",
+ /* 193 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 194 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP",
+ /* 195 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP",
+ /* 196 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP",
+ /* 197 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over",
+ /* 198 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over",
+ /* 199 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over",
+ /* 200 */ "term ::= CTIME_KW",
+ /* 201 */ "expr ::= LP nexprlist COMMA expr RP",
+ /* 202 */ "expr ::= expr AND expr",
+ /* 203 */ "expr ::= expr OR expr",
+ /* 204 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 205 */ "expr ::= expr EQ|NE expr",
+ /* 206 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 207 */ "expr ::= expr PLUS|MINUS expr",
+ /* 208 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 209 */ "expr ::= expr CONCAT expr",
+ /* 210 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 211 */ "expr ::= expr likeop expr",
+ /* 212 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 213 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 214 */ "expr ::= expr NOT NULL",
+ /* 215 */ "expr ::= expr IS expr",
+ /* 216 */ "expr ::= expr IS NOT expr",
+ /* 217 */ "expr ::= expr IS NOT DISTINCT FROM expr",
+ /* 218 */ "expr ::= expr IS DISTINCT FROM expr",
+ /* 219 */ "expr ::= NOT expr",
+ /* 220 */ "expr ::= BITNOT expr",
+ /* 221 */ "expr ::= PLUS|MINUS expr",
+ /* 222 */ "expr ::= expr PTR expr",
+ /* 223 */ "between_op ::= BETWEEN",
+ /* 224 */ "between_op ::= NOT BETWEEN",
+ /* 225 */ "expr ::= expr between_op expr AND expr",
+ /* 226 */ "in_op ::= IN",
+ /* 227 */ "in_op ::= NOT IN",
+ /* 228 */ "expr ::= expr in_op LP exprlist RP",
+ /* 229 */ "expr ::= LP select RP",
+ /* 230 */ "expr ::= expr in_op LP select RP",
+ /* 231 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 232 */ "expr ::= EXISTS LP select RP",
+ /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 235 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 236 */ "case_else ::= ELSE expr",
+ /* 237 */ "case_else ::=",
+ /* 238 */ "case_operand ::=",
+ /* 239 */ "exprlist ::=",
+ /* 240 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 241 */ "nexprlist ::= expr",
+ /* 242 */ "paren_exprlist ::=",
+ /* 243 */ "paren_exprlist ::= LP exprlist RP",
+ /* 244 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm indextype ON nm LP sortlist RP where_opt",
+ /* 245 */ "uniqueflag ::= UNIQUE",
+ /* 246 */ "uniqueflag ::=",
+ /* 247 */ "indextype ::= USING idlist",
+ /* 248 */ "indextype ::=",
+ /* 249 */ "eidlist_opt ::=",
+ /* 250 */ "eidlist_opt ::= LP eidlist RP",
+ /* 251 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 252 */ "eidlist ::= nm collate sortorder",
+ /* 253 */ "collate ::=",
+ /* 254 */ "collate ::= COLLATE ID|STRING",
+ /* 255 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 256 */ "cmd ::= VACUUM vinto",
+ /* 257 */ "cmd ::= VACUUM nm vinto",
+ /* 258 */ "vinto ::= INTO expr",
+ /* 259 */ "vinto ::=",
+ /* 260 */ "cmd ::= PRAGMA nm dbnm",
+ /* 261 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 262 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 263 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 264 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 265 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 266 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 267 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 268 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 269 */ "trigger_time ::= BEFORE|AFTER",
+ /* 270 */ "trigger_time ::= INSTEAD OF",
+ /* 271 */ "trigger_time ::=",
+ /* 272 */ "trigger_event ::= DELETE|INSERT",
+ /* 273 */ "trigger_event ::= UPDATE",
+ /* 274 */ "trigger_event ::= UPDATE OF idlist",
+ /* 275 */ "when_clause ::=",
+ /* 276 */ "when_clause ::= WHEN expr",
+ /* 277 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 278 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 279 */ "trnm ::= nm DOT nm",
+ /* 280 */ "tridxby ::= INDEXED BY nm",
+ /* 281 */ "tridxby ::= NOT INDEXED",
+ /* 282 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
+ /* 283 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
+ /* 284 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+ /* 285 */ "trigger_cmd ::= scanpt select scanpt",
+ /* 286 */ "expr ::= RAISE LP IGNORE RP",
+ /* 287 */ "expr ::= RAISE LP raisetype COMMA expr RP",
+ /* 288 */ "raisetype ::= ROLLBACK",
+ /* 289 */ "raisetype ::= ABORT",
+ /* 290 */ "raisetype ::= FAIL",
+ /* 291 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 292 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 293 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 294 */ "key_opt ::=",
+ /* 295 */ "key_opt ::= KEY expr",
+ /* 296 */ "cmd ::= REINDEX",
+ /* 297 */ "cmd ::= REINDEX nm dbnm",
+ /* 298 */ "cmd ::= ANALYZE",
+ /* 299 */ "cmd ::= ANALYZE nm dbnm",
+ /* 300 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 301 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 302 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
+ /* 303 */ "add_column_fullname ::= fullname",
+ /* 304 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
+ /* 305 */ "cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist",
+ /* 306 */ "cmd ::= create_vtab",
+ /* 307 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 308 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 309 */ "vtabarg ::=",
+ /* 310 */ "vtabargtoken ::= ANY",
+ /* 311 */ "vtabargtoken ::= lp anylist RP",
+ /* 312 */ "lp ::= LP",
+ /* 313 */ "with ::= WITH wqlist",
+ /* 314 */ "with ::= WITH RECURSIVE wqlist",
+ /* 315 */ "wqas ::= AS",
+ /* 316 */ "wqas ::= AS MATERIALIZED",
+ /* 317 */ "wqas ::= AS NOT MATERIALIZED",
+ /* 318 */ "wqitem ::= withnm eidlist_opt wqas LP select RP",
+ /* 319 */ "withnm ::= nm",
+ /* 320 */ "wqlist ::= wqitem",
+ /* 321 */ "wqlist ::= wqlist COMMA wqitem",
+ /* 322 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
+ /* 323 */ "windowdefn ::= nm AS LP window RP",
+ /* 324 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 325 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 326 */ "window ::= ORDER BY sortlist frame_opt",
+ /* 327 */ "window ::= nm ORDER BY sortlist frame_opt",
+ /* 328 */ "window ::= nm frame_opt",
+ /* 329 */ "frame_opt ::=",
+ /* 330 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
+ /* 331 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
+ /* 332 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
+ /* 333 */ "frame_bound_s ::= frame_bound",
+ /* 334 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
+ /* 335 */ "frame_bound_e ::= frame_bound",
+ /* 336 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
+ /* 337 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
+ /* 338 */ "frame_bound ::= CURRENT ROW",
+ /* 339 */ "frame_exclude_opt ::=",
+ /* 340 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
+ /* 341 */ "frame_exclude ::= NO OTHERS",
+ /* 342 */ "frame_exclude ::= CURRENT ROW",
+ /* 343 */ "frame_exclude ::= GROUP|TIES",
+ /* 344 */ "window_clause ::= WINDOW windowdefn_list",
+ /* 345 */ "filter_over ::= filter_clause over_clause",
+ /* 346 */ "filter_over ::= over_clause",
+ /* 347 */ "filter_over ::= filter_clause",
+ /* 348 */ "over_clause ::= OVER LP window RP",
+ /* 349 */ "over_clause ::= OVER nm",
+ /* 350 */ "filter_clause ::= FILTER LP WHERE expr RP",
+ /* 351 */ "term ::= QNUMBER",
+ /* 352 */ "input ::= cmdlist",
+ /* 353 */ "cmdlist ::= cmdlist ecmd",
+ /* 354 */ "cmdlist ::= ecmd",
+ /* 355 */ "ecmd ::= SEMI",
+ /* 356 */ "ecmd ::= cmdx SEMI",
+ /* 357 */ "ecmd ::= explain cmdx SEMI",
+ /* 358 */ "trans_opt ::=",
+ /* 359 */ "trans_opt ::= TRANSACTION",
+ /* 360 */ "trans_opt ::= TRANSACTION nm",
+ /* 361 */ "savepoint_opt ::= SAVEPOINT",
+ /* 362 */ "savepoint_opt ::=",
+ /* 363 */ "cmd ::= create_table create_table_args",
+ /* 364 */ "table_option_set ::= table_option",
+ /* 365 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 366 */ "columnlist ::= columnname carglist",
+ /* 367 */ "nm ::= ID|INDEXED|JOIN_KW",
+ /* 368 */ "nm ::= STRING",
+ /* 369 */ "typetoken ::= typename",
+ /* 370 */ "typename ::= ID|STRING",
+ /* 371 */ "signed ::= plus_num",
+ /* 372 */ "signed ::= minus_num",
+ /* 373 */ "carglist ::= carglist ccons",
+ /* 374 */ "carglist ::=",
+ /* 375 */ "ccons ::= NULL onconf",
+ /* 376 */ "ccons ::= GENERATED ALWAYS AS generated",
+ /* 377 */ "ccons ::= AS generated",
+ /* 378 */ "conslist_opt ::= COMMA conslist",
+ /* 379 */ "conslist ::= conslist tconscomma tcons",
+ /* 380 */ "conslist ::= tcons",
+ /* 381 */ "tconscomma ::=",
+ /* 382 */ "defer_subclause_opt ::= defer_subclause",
+ /* 383 */ "resolvetype ::= raisetype",
+ /* 384 */ "selectnowith ::= oneselect",
+ /* 385 */ "oneselect ::= values",
+ /* 386 */ "sclp ::= selcollist COMMA",
+ /* 387 */ "as ::= ID|STRING",
+ /* 388 */ "indexed_opt ::= indexed_by",
+ /* 389 */ "returning ::=",
+ /* 390 */ "expr ::= term",
+ /* 391 */ "likeop ::= LIKE_KW|MATCH",
+ /* 392 */ "case_operand ::= expr",
+ /* 393 */ "exprlist ::= nexprlist",
+ /* 394 */ "nmnum ::= plus_num",
+ /* 395 */ "nmnum ::= nm",
+ /* 396 */ "nmnum ::= ON",
+ /* 397 */ "nmnum ::= DELETE",
+ /* 398 */ "nmnum ::= DEFAULT",
+ /* 399 */ "plus_num ::= INTEGER|FLOAT",
+ /* 400 */ "foreach_clause ::=",
+ /* 401 */ "foreach_clause ::= FOR EACH ROW",
+ /* 402 */ "trnm ::= nm",
+ /* 403 */ "tridxby ::=",
+ /* 404 */ "database_kw_opt ::= DATABASE",
+ /* 405 */ "database_kw_opt ::=",
+ /* 406 */ "kwcolumn_opt ::=",
+ /* 407 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 408 */ "vtabarglist ::= vtabarg",
+ /* 409 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 410 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 411 */ "anylist ::=",
+ /* 412 */ "anylist ::= anylist LP anylist RP",
+ /* 413 */ "anylist ::= anylist ANY",
+ /* 414 */ "with ::=",
+ /* 415 */ "windowdefn_list ::= windowdefn",
+ /* 416 */ "window ::= frame_opt",
};
#endif /* NDEBUG */
-#if YYSTACKDEPTH<=0
+#if YYGROWABLESTACK
/*
** Try to increase the size of the parser stack. Return the number
** of errors. Return 0 on success.
*/
static int yyGrowStack(yyParser *p){
+ int oldSize = 1 + (int)(p->yystackEnd - p->yystack);
int newSize;
int idx;
yyStackEntry *pNew;
- newSize = p->yystksz*2 + 100;
- idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
- if( p->yystack==&p->yystk0 ){
- pNew = malloc(newSize*sizeof(pNew[0]));
- if( pNew ) pNew[0] = p->yystk0;
+ newSize = oldSize*2 + 100;
+ idx = (int)(p->yytos - p->yystack);
+ if( p->yystack==p->yystk0 ){
+ pNew = YYREALLOC(0, newSize*sizeof(pNew[0]));
+ if( pNew==0 ) return 1;
+ memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
}else{
- pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
+ pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]));
+ if( pNew==0 ) return 1;
}
- if( pNew ){
- p->yystack = pNew;
- p->yytos = &p->yystack[idx];
+ p->yystack = pNew;
+ p->yytos = &p->yystack[idx];
#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
- yyTracePrompt, p->yystksz, newSize);
- }
-#endif
- p->yystksz = newSize;
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
+ yyTracePrompt, oldSize, newSize);
}
- return pNew==0;
+#endif
+ p->yystackEnd = &p->yystack[newSize-1];
+ return 0;
}
+#endif /* YYGROWABLESTACK */
+
+#if !YYGROWABLESTACK
+/* For builds that do no have a growable stack, yyGrowStack always
+** returns an error.
+*/
+# define yyGrowStack(X) 1
#endif
/* Datatype of the argument to the memory allocated passed as the
@@ -175893,24 +178857,14 @@ SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL)
#ifdef YYTRACKMAXSTACKDEPTH
yypParser->yyhwm = 0;
#endif
-#if YYSTACKDEPTH<=0
- yypParser->yytos = NULL;
- yypParser->yystack = NULL;
- yypParser->yystksz = 0;
- if( yyGrowStack(yypParser) ){
- yypParser->yystack = &yypParser->yystk0;
- yypParser->yystksz = 1;
- }
-#endif
+ yypParser->yystack = yypParser->yystk0;
+ yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
#ifndef YYNOERRORRECOVERY
yypParser->yyerrcnt = -1;
#endif
yypParser->yytos = yypParser->yystack;
yypParser->yystack[0].stateno = 0;
yypParser->yystack[0].major = 0;
-#if YYSTACKDEPTH>0
- yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
-#endif
}
#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
@@ -175964,97 +178918,98 @@ static void yy_destructor(
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
- case 207: /* select */
- case 242: /* selectnowith */
- case 243: /* oneselect */
- case 255: /* values */
+ case 208: /* select */
+ case 243: /* selectnowith */
+ case 244: /* oneselect */
+ case 256: /* values */
+ case 258: /* mvalues */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy637));
+sqlite3SelectDelete(pParse->db, (yypminor->yy599));
}
break;
- case 219: /* term */
- case 220: /* expr */
- case 249: /* where_opt */
- case 251: /* having_opt */
- case 270: /* where_opt_ret */
- case 281: /* case_operand */
- case 283: /* case_else */
- case 287: /* vinto */
- case 294: /* when_clause */
- case 299: /* key_opt */
- case 315: /* filter_clause */
+ case 220: /* term */
+ case 221: /* expr */
+ case 250: /* where_opt */
+ case 252: /* having_opt */
+ case 272: /* where_opt_ret */
+ case 283: /* case_operand */
+ case 285: /* case_else */
+ case 289: /* vinto */
+ case 296: /* when_clause */
+ case 301: /* key_opt */
+ case 318: /* filter_clause */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy590));
+sqlite3ExprDelete(pParse->db, (yypminor->yy66));
}
break;
- case 224: /* eidlist_opt */
- case 234: /* sortlist */
- case 235: /* eidlist */
- case 247: /* selcollist */
- case 250: /* groupby_opt */
- case 252: /* orderby_opt */
- case 256: /* nexprlist */
- case 257: /* sclp */
- case 264: /* exprlist */
- case 271: /* setlist */
- case 280: /* paren_exprlist */
- case 282: /* case_exprlist */
- case 314: /* part_opt */
+ case 225: /* eidlist_opt */
+ case 235: /* sortlist */
+ case 236: /* eidlist */
+ case 248: /* selcollist */
+ case 251: /* groupby_opt */
+ case 253: /* orderby_opt */
+ case 257: /* nexprlist */
+ case 259: /* sclp */
+ case 266: /* exprlist */
+ case 273: /* setlist */
+ case 282: /* paren_exprlist */
+ case 284: /* case_exprlist */
+ case 317: /* part_opt */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy402));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy70));
}
break;
- case 241: /* fullname */
- case 248: /* from */
- case 259: /* seltablist */
- case 260: /* stl_prefix */
- case 265: /* xfullname */
+ case 242: /* fullname */
+ case 249: /* from */
+ case 261: /* seltablist */
+ case 262: /* stl_prefix */
+ case 267: /* xfullname */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy563));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy595));
}
break;
- case 244: /* wqlist */
+ case 245: /* wqlist */
{
-sqlite3WithDelete(pParse->db, (yypminor->yy125));
+sqlite3WithDelete(pParse->db, (yypminor->yy523));
}
break;
- case 254: /* window_clause */
- case 310: /* windowdefn_list */
+ case 255: /* window_clause */
+ case 313: /* windowdefn_list */
{
-sqlite3WindowListDelete(pParse->db, (yypminor->yy483));
+sqlite3WindowListDelete(pParse->db, (yypminor->yy255));
}
break;
- case 266: /* idlist */
- case 273: /* idlist_opt */
+ case 268: /* idlist */
+ case 275: /* idlist_opt */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy204));
+sqlite3IdListDelete(pParse->db, (yypminor->yy332));
}
break;
- case 276: /* filter_over */
- case 311: /* windowdefn */
- case 312: /* window */
- case 313: /* frame_opt */
- case 316: /* over_clause */
+ case 278: /* filter_over */
+ case 314: /* windowdefn */
+ case 315: /* window */
+ case 316: /* frame_opt */
+ case 319: /* over_clause */
{
-sqlite3WindowDelete(pParse->db, (yypminor->yy483));
+sqlite3WindowDelete(pParse->db, (yypminor->yy255));
}
break;
- case 290: /* trigger_cmd_list */
- case 295: /* trigger_cmd */
+ case 292: /* trigger_cmd_list */
+ case 297: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy319));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy243));
}
break;
- case 292: /* trigger_event */
+ case 294: /* trigger_event */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy28).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy158).b);
}
break;
- case 318: /* frame_bound */
- case 319: /* frame_bound_s */
- case 320: /* frame_bound_e */
+ case 321: /* frame_bound */
+ case 322: /* frame_bound_s */
+ case 323: /* frame_bound_e */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy205).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy417).pExpr);
}
break;
/********* End destructor definitions *****************************************/
@@ -176088,9 +179043,26 @@ static void yy_pop_parser_stack(yyParser *pParser){
*/
SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){
yyParser *pParser = (yyParser*)p;
- while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
-#if YYSTACKDEPTH<=0
- if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
+
+ /* In-lined version of calling yy_pop_parser_stack() for each
+ ** element left in the stack */
+ yyStackEntry *yytos = pParser->yytos;
+ while( yytos>pParser->yystack ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sPopping %s\n",
+ yyTracePrompt,
+ yyTokenName[yytos->major]);
+ }
+#endif
+ if( yytos->major>=YY_MIN_DSTRCTR ){
+ yy_destructor(pParser, yytos->major, &yytos->minor);
+ }
+ yytos--;
+ }
+
+#if YYGROWABLESTACK
+ if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack);
#endif
}
@@ -176273,7 +179245,7 @@ static void yyStackOverflow(yyParser *yypParser){
** stack every overflows */
/******** Begin %stack_overflow code ******************************************/
- sqlite3ErrorMsg(pParse, "parser stack overflow");
+ sqlite3OomFault(pParse->db);
/******** End %stack_overflow code ********************************************/
sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */
sqlite3ParserCTX_STORE
@@ -176317,25 +179289,19 @@ static void yy_shift(
assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
}
#endif
-#if YYSTACKDEPTH>0
- if( yypParser->yytos>yypParser->yystackEnd ){
- yypParser->yytos--;
- yyStackOverflow(yypParser);
- return;
- }
-#else
- if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
+ yytos = yypParser->yytos;
+ if( yytos>yypParser->yystackEnd ){
if( yyGrowStack(yypParser) ){
yypParser->yytos--;
yyStackOverflow(yypParser);
return;
}
+ yytos = yypParser->yytos;
+ assert( yytos <= yypParser->yystackEnd );
}
-#endif
if( yyNewState > YY_MAX_SHIFT ){
yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
}
- yytos = yypParser->yytos;
yytos->stateno = yyNewState;
yytos->major = yyMajor;
yytos->minor.yy0 = yyMinor;
@@ -176345,419 +179311,423 @@ static void yy_shift(
/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
** of that rule */
static const YYCODETYPE yyRuleInfoLhs[] = {
- 192, /* (0) explain ::= EXPLAIN */
- 192, /* (1) explain ::= EXPLAIN QUERY PLAN */
- 191, /* (2) cmdx ::= cmd */
- 193, /* (3) cmd ::= BEGIN transtype trans_opt */
- 194, /* (4) transtype ::= */
- 194, /* (5) transtype ::= DEFERRED */
- 194, /* (6) transtype ::= IMMEDIATE */
- 194, /* (7) transtype ::= EXCLUSIVE */
- 194, /* (8) transtype ::= READONLY */
- 193, /* (9) cmd ::= COMMIT|END trans_opt */
- 193, /* (10) cmd ::= ROLLBACK trans_opt */
- 193, /* (11) cmd ::= SAVEPOINT nm */
- 193, /* (12) cmd ::= RELEASE savepoint_opt nm */
- 193, /* (13) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
- 198, /* (14) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
- 200, /* (15) createkw ::= CREATE */
- 202, /* (16) ifnotexists ::= */
- 202, /* (17) ifnotexists ::= IF NOT EXISTS */
- 201, /* (18) temp ::= TEMP */
- 201, /* (19) temp ::= */
- 199, /* (20) create_table_args ::= LP columnlist conslist_opt RP table_option_set */
- 199, /* (21) create_table_args ::= AS select */
- 206, /* (22) table_option_set ::= */
- 206, /* (23) table_option_set ::= table_option_set COMMA table_option */
- 208, /* (24) table_option ::= WITHOUT nm */
- 208, /* (25) table_option ::= RANDOM nm */
- 208, /* (26) table_option ::= nm */
- 209, /* (27) columnname ::= nm typetoken */
- 211, /* (28) typetoken ::= */
- 211, /* (29) typetoken ::= typename LP signed RP */
- 211, /* (30) typetoken ::= typename LP signed COMMA signed RP */
- 212, /* (31) typename ::= typename ID|STRING */
- 216, /* (32) scanpt ::= */
- 217, /* (33) scantok ::= */
- 218, /* (34) ccons ::= CONSTRAINT nm */
- 218, /* (35) ccons ::= DEFAULT scantok term */
- 218, /* (36) ccons ::= DEFAULT LP expr RP */
- 218, /* (37) ccons ::= DEFAULT PLUS scantok term */
- 218, /* (38) ccons ::= DEFAULT MINUS scantok term */
- 218, /* (39) ccons ::= DEFAULT scantok ID|INDEXED */
- 218, /* (40) ccons ::= NOT NULL onconf */
- 218, /* (41) ccons ::= PRIMARY KEY sortorder onconf autoinc */
- 218, /* (42) ccons ::= UNIQUE onconf */
- 218, /* (43) ccons ::= CHECK LP expr RP */
- 218, /* (44) ccons ::= REFERENCES nm eidlist_opt refargs */
- 218, /* (45) ccons ::= defer_subclause */
- 218, /* (46) ccons ::= COLLATE ID|STRING */
- 227, /* (47) generated ::= LP expr RP */
- 227, /* (48) generated ::= LP expr RP ID */
- 223, /* (49) autoinc ::= */
- 223, /* (50) autoinc ::= AUTOINCR */
- 225, /* (51) refargs ::= */
- 225, /* (52) refargs ::= refargs refarg */
- 228, /* (53) refarg ::= MATCH nm */
- 228, /* (54) refarg ::= ON INSERT refact */
- 228, /* (55) refarg ::= ON DELETE refact */
- 228, /* (56) refarg ::= ON UPDATE refact */
- 229, /* (57) refact ::= SET NULL */
- 229, /* (58) refact ::= SET DEFAULT */
- 229, /* (59) refact ::= CASCADE */
- 229, /* (60) refact ::= RESTRICT */
- 229, /* (61) refact ::= NO ACTION */
- 226, /* (62) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- 226, /* (63) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- 230, /* (64) init_deferred_pred_opt ::= */
- 230, /* (65) init_deferred_pred_opt ::= INITIALLY DEFERRED */
- 230, /* (66) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
- 205, /* (67) conslist_opt ::= */
- 232, /* (68) tconscomma ::= COMMA */
- 233, /* (69) tcons ::= CONSTRAINT nm */
- 233, /* (70) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
- 233, /* (71) tcons ::= UNIQUE LP sortlist RP onconf */
- 233, /* (72) tcons ::= CHECK LP expr RP onconf */
- 233, /* (73) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
- 236, /* (74) defer_subclause_opt ::= */
- 221, /* (75) onconf ::= */
- 221, /* (76) onconf ::= ON CONFLICT resolvetype */
- 237, /* (77) orconf ::= */
- 237, /* (78) orconf ::= OR resolvetype */
- 238, /* (79) resolvetype ::= IGNORE */
- 238, /* (80) resolvetype ::= REPLACE */
- 193, /* (81) cmd ::= DROP TABLE ifexists fullname */
- 240, /* (82) ifexists ::= IF EXISTS */
- 240, /* (83) ifexists ::= */
- 193, /* (84) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
- 193, /* (85) cmd ::= DROP VIEW ifexists fullname */
- 193, /* (86) cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS STRING */
- 193, /* (87) cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS BLOB */
- 193, /* (88) cmd ::= DROP FUNCTION ifexists nm */
- 193, /* (89) cmd ::= select */
- 207, /* (90) select ::= WITH wqlist selectnowith */
- 207, /* (91) select ::= WITH RECURSIVE wqlist selectnowith */
- 207, /* (92) select ::= selectnowith */
- 242, /* (93) selectnowith ::= selectnowith multiselect_op oneselect */
- 245, /* (94) multiselect_op ::= UNION */
- 245, /* (95) multiselect_op ::= UNION ALL */
- 245, /* (96) multiselect_op ::= EXCEPT|INTERSECT */
- 243, /* (97) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
- 243, /* (98) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
- 255, /* (99) values ::= VALUES LP nexprlist RP */
- 255, /* (100) values ::= values COMMA LP nexprlist RP */
- 246, /* (101) distinct ::= DISTINCT */
- 246, /* (102) distinct ::= ALL */
- 246, /* (103) distinct ::= */
- 257, /* (104) sclp ::= */
- 247, /* (105) selcollist ::= sclp scanpt expr scanpt as */
- 247, /* (106) selcollist ::= sclp scanpt STAR */
- 247, /* (107) selcollist ::= sclp scanpt nm DOT STAR */
- 258, /* (108) as ::= AS nm */
- 258, /* (109) as ::= */
- 248, /* (110) from ::= */
- 248, /* (111) from ::= FROM seltablist */
- 260, /* (112) stl_prefix ::= seltablist joinop */
- 260, /* (113) stl_prefix ::= */
- 259, /* (114) seltablist ::= stl_prefix nm dbnm as on_using */
- 259, /* (115) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
- 259, /* (116) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
- 259, /* (117) seltablist ::= stl_prefix LP select RP as on_using */
- 259, /* (118) seltablist ::= stl_prefix LP seltablist RP as on_using */
- 203, /* (119) dbnm ::= */
- 203, /* (120) dbnm ::= DOT nm */
- 241, /* (121) fullname ::= nm */
- 241, /* (122) fullname ::= nm DOT nm */
- 265, /* (123) xfullname ::= nm */
- 265, /* (124) xfullname ::= nm DOT nm */
- 265, /* (125) xfullname ::= nm DOT nm AS nm */
- 265, /* (126) xfullname ::= nm AS nm */
- 261, /* (127) joinop ::= COMMA|JOIN */
- 261, /* (128) joinop ::= JOIN_KW JOIN */
- 261, /* (129) joinop ::= JOIN_KW nm JOIN */
- 261, /* (130) joinop ::= JOIN_KW nm nm JOIN */
- 262, /* (131) on_using ::= ON expr */
- 262, /* (132) on_using ::= USING LP idlist RP */
- 262, /* (133) on_using ::= */
- 267, /* (134) indexed_opt ::= */
- 263, /* (135) indexed_by ::= INDEXED BY nm */
- 263, /* (136) indexed_by ::= NOT INDEXED */
- 252, /* (137) orderby_opt ::= */
- 252, /* (138) orderby_opt ::= ORDER BY sortlist */
- 234, /* (139) sortlist ::= sortlist COMMA expr sortorder nulls */
- 234, /* (140) sortlist ::= expr sortorder nulls */
- 222, /* (141) sortorder ::= ASC */
- 222, /* (142) sortorder ::= DESC */
- 222, /* (143) sortorder ::= */
- 268, /* (144) nulls ::= NULLS FIRST */
- 268, /* (145) nulls ::= NULLS LAST */
- 268, /* (146) nulls ::= */
- 250, /* (147) groupby_opt ::= */
- 250, /* (148) groupby_opt ::= GROUP BY nexprlist */
- 251, /* (149) having_opt ::= */
- 251, /* (150) having_opt ::= HAVING expr */
- 253, /* (151) limit_opt ::= */
- 253, /* (152) limit_opt ::= LIMIT expr */
- 253, /* (153) limit_opt ::= LIMIT expr OFFSET expr */
- 253, /* (154) limit_opt ::= LIMIT expr COMMA expr */
- 193, /* (155) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
- 249, /* (156) where_opt ::= */
- 249, /* (157) where_opt ::= WHERE expr */
- 270, /* (158) where_opt_ret ::= */
- 270, /* (159) where_opt_ret ::= WHERE expr */
- 270, /* (160) where_opt_ret ::= RETURNING selcollist */
- 270, /* (161) where_opt_ret ::= WHERE expr RETURNING selcollist */
- 193, /* (162) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
- 271, /* (163) setlist ::= setlist COMMA nm EQ expr */
- 271, /* (164) setlist ::= setlist COMMA LP idlist RP EQ expr */
- 271, /* (165) setlist ::= nm EQ expr */
- 271, /* (166) setlist ::= LP idlist RP EQ expr */
- 193, /* (167) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
- 193, /* (168) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
- 274, /* (169) upsert ::= */
- 274, /* (170) upsert ::= RETURNING selcollist */
- 274, /* (171) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
- 274, /* (172) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
- 274, /* (173) upsert ::= ON CONFLICT DO NOTHING returning */
- 274, /* (174) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
- 275, /* (175) returning ::= RETURNING selcollist */
- 272, /* (176) insert_cmd ::= INSERT orconf */
- 272, /* (177) insert_cmd ::= REPLACE */
- 273, /* (178) idlist_opt ::= */
- 273, /* (179) idlist_opt ::= LP idlist RP */
- 266, /* (180) idlist ::= idlist COMMA nm */
- 266, /* (181) idlist ::= nm */
- 220, /* (182) expr ::= LP expr RP */
- 220, /* (183) expr ::= ID|INDEXED|JOIN_KW */
- 220, /* (184) expr ::= nm DOT nm */
- 220, /* (185) expr ::= nm DOT nm DOT nm */
- 219, /* (186) term ::= NULL|FLOAT|BLOB */
- 219, /* (187) term ::= STRING */
- 219, /* (188) term ::= INTEGER */
- 220, /* (189) expr ::= VARIABLE */
- 220, /* (190) expr ::= expr COLLATE ID|STRING */
- 220, /* (191) expr ::= CAST LP expr AS typetoken RP */
- 220, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
- 220, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
- 220, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
- 220, /* (195) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
- 220, /* (196) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
- 220, /* (197) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
- 219, /* (198) term ::= CTIME_KW */
- 220, /* (199) expr ::= LP nexprlist COMMA expr RP */
- 220, /* (200) expr ::= expr AND expr */
- 220, /* (201) expr ::= expr OR expr */
- 220, /* (202) expr ::= expr LT|GT|GE|LE expr */
- 220, /* (203) expr ::= expr EQ|NE expr */
- 220, /* (204) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- 220, /* (205) expr ::= expr PLUS|MINUS expr */
- 220, /* (206) expr ::= expr STAR|SLASH|REM expr */
- 220, /* (207) expr ::= expr CONCAT expr */
- 277, /* (208) likeop ::= NOT LIKE_KW|MATCH */
- 220, /* (209) expr ::= expr likeop expr */
- 220, /* (210) expr ::= expr likeop expr ESCAPE expr */
- 220, /* (211) expr ::= expr ISNULL|NOTNULL */
- 220, /* (212) expr ::= expr NOT NULL */
- 220, /* (213) expr ::= expr IS expr */
- 220, /* (214) expr ::= expr IS NOT expr */
- 220, /* (215) expr ::= expr IS NOT DISTINCT FROM expr */
- 220, /* (216) expr ::= expr IS DISTINCT FROM expr */
- 220, /* (217) expr ::= NOT expr */
- 220, /* (218) expr ::= BITNOT expr */
- 220, /* (219) expr ::= PLUS|MINUS expr */
- 220, /* (220) expr ::= expr PTR expr */
- 278, /* (221) between_op ::= BETWEEN */
- 278, /* (222) between_op ::= NOT BETWEEN */
- 220, /* (223) expr ::= expr between_op expr AND expr */
- 279, /* (224) in_op ::= IN */
- 279, /* (225) in_op ::= NOT IN */
- 220, /* (226) expr ::= expr in_op LP exprlist RP */
- 220, /* (227) expr ::= LP select RP */
- 220, /* (228) expr ::= expr in_op LP select RP */
- 220, /* (229) expr ::= expr in_op nm dbnm paren_exprlist */
- 220, /* (230) expr ::= EXISTS LP select RP */
- 220, /* (231) expr ::= CASE case_operand case_exprlist case_else END */
- 282, /* (232) case_exprlist ::= case_exprlist WHEN expr THEN expr */
- 282, /* (233) case_exprlist ::= WHEN expr THEN expr */
- 283, /* (234) case_else ::= ELSE expr */
- 283, /* (235) case_else ::= */
- 281, /* (236) case_operand ::= */
- 264, /* (237) exprlist ::= */
- 256, /* (238) nexprlist ::= nexprlist COMMA expr */
- 256, /* (239) nexprlist ::= expr */
- 280, /* (240) paren_exprlist ::= */
- 280, /* (241) paren_exprlist ::= LP exprlist RP */
- 193, /* (242) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm indextype ON nm LP sortlist RP where_opt */
- 284, /* (243) uniqueflag ::= UNIQUE */
- 284, /* (244) uniqueflag ::= */
- 285, /* (245) indextype ::= USING idlist */
- 285, /* (246) indextype ::= */
- 224, /* (247) eidlist_opt ::= */
- 224, /* (248) eidlist_opt ::= LP eidlist RP */
- 235, /* (249) eidlist ::= eidlist COMMA nm collate sortorder */
- 235, /* (250) eidlist ::= nm collate sortorder */
- 286, /* (251) collate ::= */
- 286, /* (252) collate ::= COLLATE ID|STRING */
- 193, /* (253) cmd ::= DROP INDEX ifexists fullname */
- 193, /* (254) cmd ::= VACUUM vinto */
- 193, /* (255) cmd ::= VACUUM nm vinto */
- 287, /* (256) vinto ::= INTO expr */
- 287, /* (257) vinto ::= */
- 193, /* (258) cmd ::= PRAGMA nm dbnm */
- 193, /* (259) cmd ::= PRAGMA nm dbnm EQ nmnum */
- 193, /* (260) cmd ::= PRAGMA nm dbnm LP nmnum RP */
- 193, /* (261) cmd ::= PRAGMA nm dbnm EQ minus_num */
- 193, /* (262) cmd ::= PRAGMA nm dbnm LP minus_num RP */
- 214, /* (263) plus_num ::= PLUS INTEGER|FLOAT */
- 215, /* (264) minus_num ::= MINUS INTEGER|FLOAT */
- 193, /* (265) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
- 289, /* (266) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
- 291, /* (267) trigger_time ::= BEFORE|AFTER */
- 291, /* (268) trigger_time ::= INSTEAD OF */
- 291, /* (269) trigger_time ::= */
- 292, /* (270) trigger_event ::= DELETE|INSERT */
- 292, /* (271) trigger_event ::= UPDATE */
- 292, /* (272) trigger_event ::= UPDATE OF idlist */
- 294, /* (273) when_clause ::= */
- 294, /* (274) when_clause ::= WHEN expr */
- 290, /* (275) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
- 290, /* (276) trigger_cmd_list ::= trigger_cmd SEMI */
- 296, /* (277) trnm ::= nm DOT nm */
- 297, /* (278) tridxby ::= INDEXED BY nm */
- 297, /* (279) tridxby ::= NOT INDEXED */
- 295, /* (280) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
- 295, /* (281) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
- 295, /* (282) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
- 295, /* (283) trigger_cmd ::= scanpt select scanpt */
- 220, /* (284) expr ::= RAISE LP IGNORE RP */
- 220, /* (285) expr ::= RAISE LP raisetype COMMA nm RP */
- 239, /* (286) raisetype ::= ROLLBACK */
- 239, /* (287) raisetype ::= ABORT */
- 239, /* (288) raisetype ::= FAIL */
- 193, /* (289) cmd ::= DROP TRIGGER ifexists fullname */
- 193, /* (290) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
- 193, /* (291) cmd ::= DETACH database_kw_opt expr */
- 299, /* (292) key_opt ::= */
- 299, /* (293) key_opt ::= KEY expr */
- 193, /* (294) cmd ::= REINDEX */
- 193, /* (295) cmd ::= REINDEX nm dbnm */
- 193, /* (296) cmd ::= ANALYZE */
- 193, /* (297) cmd ::= ANALYZE nm dbnm */
- 193, /* (298) cmd ::= ALTER TABLE fullname RENAME TO nm */
- 193, /* (299) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
- 193, /* (300) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
- 300, /* (301) add_column_fullname ::= fullname */
- 193, /* (302) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
- 193, /* (303) cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */
- 193, /* (304) cmd ::= create_vtab */
- 193, /* (305) cmd ::= create_vtab LP vtabarglist RP */
- 302, /* (306) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
- 304, /* (307) vtabarg ::= */
- 305, /* (308) vtabargtoken ::= ANY */
- 305, /* (309) vtabargtoken ::= lp anylist RP */
- 306, /* (310) lp ::= LP */
- 269, /* (311) with ::= WITH wqlist */
- 269, /* (312) with ::= WITH RECURSIVE wqlist */
- 309, /* (313) wqas ::= AS */
- 309, /* (314) wqas ::= AS MATERIALIZED */
- 309, /* (315) wqas ::= AS NOT MATERIALIZED */
- 308, /* (316) wqitem ::= nm eidlist_opt wqas LP select RP */
- 244, /* (317) wqlist ::= wqitem */
- 244, /* (318) wqlist ::= wqlist COMMA wqitem */
- 310, /* (319) windowdefn_list ::= windowdefn_list COMMA windowdefn */
- 311, /* (320) windowdefn ::= nm AS LP window RP */
- 312, /* (321) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
- 312, /* (322) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
- 312, /* (323) window ::= ORDER BY sortlist frame_opt */
- 312, /* (324) window ::= nm ORDER BY sortlist frame_opt */
- 312, /* (325) window ::= nm frame_opt */
- 313, /* (326) frame_opt ::= */
- 313, /* (327) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
- 313, /* (328) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
- 317, /* (329) range_or_rows ::= RANGE|ROWS|GROUPS */
- 319, /* (330) frame_bound_s ::= frame_bound */
- 319, /* (331) frame_bound_s ::= UNBOUNDED PRECEDING */
- 320, /* (332) frame_bound_e ::= frame_bound */
- 320, /* (333) frame_bound_e ::= UNBOUNDED FOLLOWING */
- 318, /* (334) frame_bound ::= expr PRECEDING|FOLLOWING */
- 318, /* (335) frame_bound ::= CURRENT ROW */
- 321, /* (336) frame_exclude_opt ::= */
- 321, /* (337) frame_exclude_opt ::= EXCLUDE frame_exclude */
- 322, /* (338) frame_exclude ::= NO OTHERS */
- 322, /* (339) frame_exclude ::= CURRENT ROW */
- 322, /* (340) frame_exclude ::= GROUP|TIES */
- 254, /* (341) window_clause ::= WINDOW windowdefn_list */
- 276, /* (342) filter_over ::= filter_clause over_clause */
- 276, /* (343) filter_over ::= over_clause */
- 276, /* (344) filter_over ::= filter_clause */
- 316, /* (345) over_clause ::= OVER LP window RP */
- 316, /* (346) over_clause ::= OVER nm */
- 315, /* (347) filter_clause ::= FILTER LP WHERE expr RP */
- 188, /* (348) input ::= cmdlist */
- 189, /* (349) cmdlist ::= cmdlist ecmd */
- 189, /* (350) cmdlist ::= ecmd */
- 190, /* (351) ecmd ::= SEMI */
- 190, /* (352) ecmd ::= cmdx SEMI */
- 190, /* (353) ecmd ::= explain cmdx SEMI */
- 195, /* (354) trans_opt ::= */
- 195, /* (355) trans_opt ::= TRANSACTION */
- 195, /* (356) trans_opt ::= TRANSACTION nm */
- 197, /* (357) savepoint_opt ::= SAVEPOINT */
- 197, /* (358) savepoint_opt ::= */
- 193, /* (359) cmd ::= create_table create_table_args */
- 206, /* (360) table_option_set ::= table_option */
- 204, /* (361) columnlist ::= columnlist COMMA columnname carglist */
- 204, /* (362) columnlist ::= columnname carglist */
- 196, /* (363) nm ::= ID|INDEXED|JOIN_KW */
- 196, /* (364) nm ::= STRING */
- 211, /* (365) typetoken ::= typename */
- 212, /* (366) typename ::= ID|STRING */
- 213, /* (367) signed ::= plus_num */
- 213, /* (368) signed ::= minus_num */
- 210, /* (369) carglist ::= carglist ccons */
- 210, /* (370) carglist ::= */
- 218, /* (371) ccons ::= NULL onconf */
- 218, /* (372) ccons ::= GENERATED ALWAYS AS generated */
- 218, /* (373) ccons ::= AS generated */
- 205, /* (374) conslist_opt ::= COMMA conslist */
- 231, /* (375) conslist ::= conslist tconscomma tcons */
- 231, /* (376) conslist ::= tcons */
- 232, /* (377) tconscomma ::= */
- 236, /* (378) defer_subclause_opt ::= defer_subclause */
- 238, /* (379) resolvetype ::= raisetype */
- 242, /* (380) selectnowith ::= oneselect */
- 243, /* (381) oneselect ::= values */
- 257, /* (382) sclp ::= selcollist COMMA */
- 258, /* (383) as ::= ID|STRING */
- 267, /* (384) indexed_opt ::= indexed_by */
- 275, /* (385) returning ::= */
- 220, /* (386) expr ::= term */
- 277, /* (387) likeop ::= LIKE_KW|MATCH */
- 281, /* (388) case_operand ::= expr */
- 264, /* (389) exprlist ::= nexprlist */
- 288, /* (390) nmnum ::= plus_num */
- 288, /* (391) nmnum ::= nm */
- 288, /* (392) nmnum ::= ON */
- 288, /* (393) nmnum ::= DELETE */
- 288, /* (394) nmnum ::= DEFAULT */
- 214, /* (395) plus_num ::= INTEGER|FLOAT */
- 293, /* (396) foreach_clause ::= */
- 293, /* (397) foreach_clause ::= FOR EACH ROW */
- 296, /* (398) trnm ::= nm */
- 297, /* (399) tridxby ::= */
- 298, /* (400) database_kw_opt ::= DATABASE */
- 298, /* (401) database_kw_opt ::= */
- 301, /* (402) kwcolumn_opt ::= */
- 301, /* (403) kwcolumn_opt ::= COLUMNKW */
- 303, /* (404) vtabarglist ::= vtabarg */
- 303, /* (405) vtabarglist ::= vtabarglist COMMA vtabarg */
- 304, /* (406) vtabarg ::= vtabarg vtabargtoken */
- 307, /* (407) anylist ::= */
- 307, /* (408) anylist ::= anylist LP anylist RP */
- 307, /* (409) anylist ::= anylist ANY */
- 269, /* (410) with ::= */
- 310, /* (411) windowdefn_list ::= windowdefn */
- 312, /* (412) window ::= frame_opt */
+ 193, /* (0) explain ::= EXPLAIN */
+ 193, /* (1) explain ::= EXPLAIN QUERY PLAN */
+ 192, /* (2) cmdx ::= cmd */
+ 194, /* (3) cmd ::= BEGIN transtype trans_opt */
+ 195, /* (4) transtype ::= */
+ 195, /* (5) transtype ::= DEFERRED */
+ 195, /* (6) transtype ::= IMMEDIATE */
+ 195, /* (7) transtype ::= EXCLUSIVE */
+ 195, /* (8) transtype ::= READONLY */
+ 194, /* (9) cmd ::= COMMIT|END trans_opt */
+ 194, /* (10) cmd ::= ROLLBACK trans_opt */
+ 194, /* (11) cmd ::= SAVEPOINT nm */
+ 194, /* (12) cmd ::= RELEASE savepoint_opt nm */
+ 194, /* (13) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ 199, /* (14) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ 201, /* (15) createkw ::= CREATE */
+ 203, /* (16) ifnotexists ::= */
+ 203, /* (17) ifnotexists ::= IF NOT EXISTS */
+ 202, /* (18) temp ::= TEMP */
+ 202, /* (19) temp ::= */
+ 200, /* (20) create_table_args ::= LP columnlist conslist_opt RP table_option_set */
+ 200, /* (21) create_table_args ::= AS select */
+ 207, /* (22) table_option_set ::= */
+ 207, /* (23) table_option_set ::= table_option_set COMMA table_option */
+ 209, /* (24) table_option ::= WITHOUT nm */
+ 209, /* (25) table_option ::= RANDOM nm */
+ 209, /* (26) table_option ::= nm */
+ 210, /* (27) columnname ::= nm typetoken */
+ 212, /* (28) typetoken ::= */
+ 212, /* (29) typetoken ::= typename LP signed RP */
+ 212, /* (30) typetoken ::= typename LP signed COMMA signed RP */
+ 213, /* (31) typename ::= typename ID|STRING */
+ 217, /* (32) scanpt ::= */
+ 218, /* (33) scantok ::= */
+ 219, /* (34) ccons ::= CONSTRAINT nm */
+ 219, /* (35) ccons ::= DEFAULT scantok term */
+ 219, /* (36) ccons ::= DEFAULT LP expr RP */
+ 219, /* (37) ccons ::= DEFAULT PLUS scantok term */
+ 219, /* (38) ccons ::= DEFAULT MINUS scantok term */
+ 219, /* (39) ccons ::= DEFAULT scantok ID|INDEXED */
+ 219, /* (40) ccons ::= NOT NULL onconf */
+ 219, /* (41) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ 219, /* (42) ccons ::= UNIQUE onconf */
+ 219, /* (43) ccons ::= CHECK LP expr RP */
+ 219, /* (44) ccons ::= REFERENCES nm eidlist_opt refargs */
+ 219, /* (45) ccons ::= defer_subclause */
+ 219, /* (46) ccons ::= COLLATE ID|STRING */
+ 228, /* (47) generated ::= LP expr RP */
+ 228, /* (48) generated ::= LP expr RP ID */
+ 224, /* (49) autoinc ::= */
+ 224, /* (50) autoinc ::= AUTOINCR */
+ 226, /* (51) refargs ::= */
+ 226, /* (52) refargs ::= refargs refarg */
+ 229, /* (53) refarg ::= MATCH nm */
+ 229, /* (54) refarg ::= ON INSERT refact */
+ 229, /* (55) refarg ::= ON DELETE refact */
+ 229, /* (56) refarg ::= ON UPDATE refact */
+ 230, /* (57) refact ::= SET NULL */
+ 230, /* (58) refact ::= SET DEFAULT */
+ 230, /* (59) refact ::= CASCADE */
+ 230, /* (60) refact ::= RESTRICT */
+ 230, /* (61) refact ::= NO ACTION */
+ 227, /* (62) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ 227, /* (63) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ 231, /* (64) init_deferred_pred_opt ::= */
+ 231, /* (65) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ 231, /* (66) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ 206, /* (67) conslist_opt ::= */
+ 233, /* (68) tconscomma ::= COMMA */
+ 234, /* (69) tcons ::= CONSTRAINT nm */
+ 234, /* (70) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ 234, /* (71) tcons ::= UNIQUE LP sortlist RP onconf */
+ 234, /* (72) tcons ::= CHECK LP expr RP onconf */
+ 234, /* (73) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ 237, /* (74) defer_subclause_opt ::= */
+ 222, /* (75) onconf ::= */
+ 222, /* (76) onconf ::= ON CONFLICT resolvetype */
+ 238, /* (77) orconf ::= */
+ 238, /* (78) orconf ::= OR resolvetype */
+ 239, /* (79) resolvetype ::= IGNORE */
+ 239, /* (80) resolvetype ::= REPLACE */
+ 194, /* (81) cmd ::= DROP TABLE ifexists fullname */
+ 241, /* (82) ifexists ::= IF EXISTS */
+ 241, /* (83) ifexists ::= */
+ 194, /* (84) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ 194, /* (85) cmd ::= DROP VIEW ifexists fullname */
+ 194, /* (86) cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS STRING */
+ 194, /* (87) cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS BLOB */
+ 194, /* (88) cmd ::= DROP FUNCTION ifexists nm */
+ 194, /* (89) cmd ::= select */
+ 208, /* (90) select ::= WITH wqlist selectnowith */
+ 208, /* (91) select ::= WITH RECURSIVE wqlist selectnowith */
+ 208, /* (92) select ::= selectnowith */
+ 243, /* (93) selectnowith ::= selectnowith multiselect_op oneselect */
+ 246, /* (94) multiselect_op ::= UNION */
+ 246, /* (95) multiselect_op ::= UNION ALL */
+ 246, /* (96) multiselect_op ::= EXCEPT|INTERSECT */
+ 244, /* (97) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ 244, /* (98) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ 256, /* (99) values ::= VALUES LP nexprlist RP */
+ 244, /* (100) oneselect ::= mvalues */
+ 258, /* (101) mvalues ::= values COMMA LP nexprlist RP */
+ 258, /* (102) mvalues ::= mvalues COMMA LP nexprlist RP */
+ 247, /* (103) distinct ::= DISTINCT */
+ 247, /* (104) distinct ::= ALL */
+ 247, /* (105) distinct ::= */
+ 259, /* (106) sclp ::= */
+ 248, /* (107) selcollist ::= sclp scanpt expr scanpt as */
+ 248, /* (108) selcollist ::= sclp scanpt STAR */
+ 248, /* (109) selcollist ::= sclp scanpt nm DOT STAR */
+ 260, /* (110) as ::= AS nm */
+ 260, /* (111) as ::= */
+ 249, /* (112) from ::= */
+ 249, /* (113) from ::= FROM seltablist */
+ 262, /* (114) stl_prefix ::= seltablist joinop */
+ 262, /* (115) stl_prefix ::= */
+ 261, /* (116) seltablist ::= stl_prefix nm dbnm as on_using */
+ 261, /* (117) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
+ 261, /* (118) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
+ 261, /* (119) seltablist ::= stl_prefix LP select RP as on_using */
+ 261, /* (120) seltablist ::= stl_prefix LP seltablist RP as on_using */
+ 204, /* (121) dbnm ::= */
+ 204, /* (122) dbnm ::= DOT nm */
+ 242, /* (123) fullname ::= nm */
+ 242, /* (124) fullname ::= nm DOT nm */
+ 267, /* (125) xfullname ::= nm */
+ 267, /* (126) xfullname ::= nm DOT nm */
+ 267, /* (127) xfullname ::= nm DOT nm AS nm */
+ 267, /* (128) xfullname ::= nm AS nm */
+ 263, /* (129) joinop ::= COMMA|JOIN */
+ 263, /* (130) joinop ::= JOIN_KW JOIN */
+ 263, /* (131) joinop ::= JOIN_KW nm JOIN */
+ 263, /* (132) joinop ::= JOIN_KW nm nm JOIN */
+ 264, /* (133) on_using ::= ON expr */
+ 264, /* (134) on_using ::= USING LP idlist RP */
+ 264, /* (135) on_using ::= */
+ 269, /* (136) indexed_opt ::= */
+ 265, /* (137) indexed_by ::= INDEXED BY nm */
+ 265, /* (138) indexed_by ::= NOT INDEXED */
+ 253, /* (139) orderby_opt ::= */
+ 253, /* (140) orderby_opt ::= ORDER BY sortlist */
+ 235, /* (141) sortlist ::= sortlist COMMA expr sortorder nulls */
+ 235, /* (142) sortlist ::= expr sortorder nulls */
+ 223, /* (143) sortorder ::= ASC */
+ 223, /* (144) sortorder ::= DESC */
+ 223, /* (145) sortorder ::= */
+ 270, /* (146) nulls ::= NULLS FIRST */
+ 270, /* (147) nulls ::= NULLS LAST */
+ 270, /* (148) nulls ::= */
+ 251, /* (149) groupby_opt ::= */
+ 251, /* (150) groupby_opt ::= GROUP BY nexprlist */
+ 252, /* (151) having_opt ::= */
+ 252, /* (152) having_opt ::= HAVING expr */
+ 254, /* (153) limit_opt ::= */
+ 254, /* (154) limit_opt ::= LIMIT expr */
+ 254, /* (155) limit_opt ::= LIMIT expr OFFSET expr */
+ 254, /* (156) limit_opt ::= LIMIT expr COMMA expr */
+ 194, /* (157) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
+ 250, /* (158) where_opt ::= */
+ 250, /* (159) where_opt ::= WHERE expr */
+ 272, /* (160) where_opt_ret ::= */
+ 272, /* (161) where_opt_ret ::= WHERE expr */
+ 272, /* (162) where_opt_ret ::= RETURNING selcollist */
+ 272, /* (163) where_opt_ret ::= WHERE expr RETURNING selcollist */
+ 194, /* (164) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
+ 273, /* (165) setlist ::= setlist COMMA nm EQ expr */
+ 273, /* (166) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ 273, /* (167) setlist ::= nm EQ expr */
+ 273, /* (168) setlist ::= LP idlist RP EQ expr */
+ 194, /* (169) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ 194, /* (170) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
+ 276, /* (171) upsert ::= */
+ 276, /* (172) upsert ::= RETURNING selcollist */
+ 276, /* (173) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
+ 276, /* (174) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
+ 276, /* (175) upsert ::= ON CONFLICT DO NOTHING returning */
+ 276, /* (176) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
+ 277, /* (177) returning ::= RETURNING selcollist */
+ 274, /* (178) insert_cmd ::= INSERT orconf */
+ 274, /* (179) insert_cmd ::= REPLACE */
+ 275, /* (180) idlist_opt ::= */
+ 275, /* (181) idlist_opt ::= LP idlist RP */
+ 268, /* (182) idlist ::= idlist COMMA nm */
+ 268, /* (183) idlist ::= nm */
+ 221, /* (184) expr ::= LP expr RP */
+ 221, /* (185) expr ::= ID|INDEXED|JOIN_KW */
+ 221, /* (186) expr ::= nm DOT nm */
+ 221, /* (187) expr ::= nm DOT nm DOT nm */
+ 220, /* (188) term ::= NULL|FLOAT|BLOB */
+ 220, /* (189) term ::= STRING */
+ 220, /* (190) term ::= INTEGER */
+ 221, /* (191) expr ::= VARIABLE */
+ 221, /* (192) expr ::= expr COLLATE ID|STRING */
+ 221, /* (193) expr ::= CAST LP expr AS typetoken RP */
+ 221, /* (194) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
+ 221, /* (195) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
+ 221, /* (196) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
+ 221, /* (197) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
+ 221, /* (198) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
+ 221, /* (199) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
+ 220, /* (200) term ::= CTIME_KW */
+ 221, /* (201) expr ::= LP nexprlist COMMA expr RP */
+ 221, /* (202) expr ::= expr AND expr */
+ 221, /* (203) expr ::= expr OR expr */
+ 221, /* (204) expr ::= expr LT|GT|GE|LE expr */
+ 221, /* (205) expr ::= expr EQ|NE expr */
+ 221, /* (206) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ 221, /* (207) expr ::= expr PLUS|MINUS expr */
+ 221, /* (208) expr ::= expr STAR|SLASH|REM expr */
+ 221, /* (209) expr ::= expr CONCAT expr */
+ 279, /* (210) likeop ::= NOT LIKE_KW|MATCH */
+ 221, /* (211) expr ::= expr likeop expr */
+ 221, /* (212) expr ::= expr likeop expr ESCAPE expr */
+ 221, /* (213) expr ::= expr ISNULL|NOTNULL */
+ 221, /* (214) expr ::= expr NOT NULL */
+ 221, /* (215) expr ::= expr IS expr */
+ 221, /* (216) expr ::= expr IS NOT expr */
+ 221, /* (217) expr ::= expr IS NOT DISTINCT FROM expr */
+ 221, /* (218) expr ::= expr IS DISTINCT FROM expr */
+ 221, /* (219) expr ::= NOT expr */
+ 221, /* (220) expr ::= BITNOT expr */
+ 221, /* (221) expr ::= PLUS|MINUS expr */
+ 221, /* (222) expr ::= expr PTR expr */
+ 280, /* (223) between_op ::= BETWEEN */
+ 280, /* (224) between_op ::= NOT BETWEEN */
+ 221, /* (225) expr ::= expr between_op expr AND expr */
+ 281, /* (226) in_op ::= IN */
+ 281, /* (227) in_op ::= NOT IN */
+ 221, /* (228) expr ::= expr in_op LP exprlist RP */
+ 221, /* (229) expr ::= LP select RP */
+ 221, /* (230) expr ::= expr in_op LP select RP */
+ 221, /* (231) expr ::= expr in_op nm dbnm paren_exprlist */
+ 221, /* (232) expr ::= EXISTS LP select RP */
+ 221, /* (233) expr ::= CASE case_operand case_exprlist case_else END */
+ 284, /* (234) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ 284, /* (235) case_exprlist ::= WHEN expr THEN expr */
+ 285, /* (236) case_else ::= ELSE expr */
+ 285, /* (237) case_else ::= */
+ 283, /* (238) case_operand ::= */
+ 266, /* (239) exprlist ::= */
+ 257, /* (240) nexprlist ::= nexprlist COMMA expr */
+ 257, /* (241) nexprlist ::= expr */
+ 282, /* (242) paren_exprlist ::= */
+ 282, /* (243) paren_exprlist ::= LP exprlist RP */
+ 194, /* (244) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm indextype ON nm LP sortlist RP where_opt */
+ 286, /* (245) uniqueflag ::= UNIQUE */
+ 286, /* (246) uniqueflag ::= */
+ 287, /* (247) indextype ::= USING idlist */
+ 287, /* (248) indextype ::= */
+ 225, /* (249) eidlist_opt ::= */
+ 225, /* (250) eidlist_opt ::= LP eidlist RP */
+ 236, /* (251) eidlist ::= eidlist COMMA nm collate sortorder */
+ 236, /* (252) eidlist ::= nm collate sortorder */
+ 288, /* (253) collate ::= */
+ 288, /* (254) collate ::= COLLATE ID|STRING */
+ 194, /* (255) cmd ::= DROP INDEX ifexists fullname */
+ 194, /* (256) cmd ::= VACUUM vinto */
+ 194, /* (257) cmd ::= VACUUM nm vinto */
+ 289, /* (258) vinto ::= INTO expr */
+ 289, /* (259) vinto ::= */
+ 194, /* (260) cmd ::= PRAGMA nm dbnm */
+ 194, /* (261) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ 194, /* (262) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ 194, /* (263) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ 194, /* (264) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ 215, /* (265) plus_num ::= PLUS INTEGER|FLOAT */
+ 216, /* (266) minus_num ::= MINUS INTEGER|FLOAT */
+ 194, /* (267) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ 291, /* (268) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ 293, /* (269) trigger_time ::= BEFORE|AFTER */
+ 293, /* (270) trigger_time ::= INSTEAD OF */
+ 293, /* (271) trigger_time ::= */
+ 294, /* (272) trigger_event ::= DELETE|INSERT */
+ 294, /* (273) trigger_event ::= UPDATE */
+ 294, /* (274) trigger_event ::= UPDATE OF idlist */
+ 296, /* (275) when_clause ::= */
+ 296, /* (276) when_clause ::= WHEN expr */
+ 292, /* (277) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ 292, /* (278) trigger_cmd_list ::= trigger_cmd SEMI */
+ 298, /* (279) trnm ::= nm DOT nm */
+ 299, /* (280) tridxby ::= INDEXED BY nm */
+ 299, /* (281) tridxby ::= NOT INDEXED */
+ 297, /* (282) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+ 297, /* (283) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ 297, /* (284) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ 297, /* (285) trigger_cmd ::= scanpt select scanpt */
+ 221, /* (286) expr ::= RAISE LP IGNORE RP */
+ 221, /* (287) expr ::= RAISE LP raisetype COMMA expr RP */
+ 240, /* (288) raisetype ::= ROLLBACK */
+ 240, /* (289) raisetype ::= ABORT */
+ 240, /* (290) raisetype ::= FAIL */
+ 194, /* (291) cmd ::= DROP TRIGGER ifexists fullname */
+ 194, /* (292) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ 194, /* (293) cmd ::= DETACH database_kw_opt expr */
+ 301, /* (294) key_opt ::= */
+ 301, /* (295) key_opt ::= KEY expr */
+ 194, /* (296) cmd ::= REINDEX */
+ 194, /* (297) cmd ::= REINDEX nm dbnm */
+ 194, /* (298) cmd ::= ANALYZE */
+ 194, /* (299) cmd ::= ANALYZE nm dbnm */
+ 194, /* (300) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ 194, /* (301) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ 194, /* (302) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+ 302, /* (303) add_column_fullname ::= fullname */
+ 194, /* (304) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ 194, /* (305) cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */
+ 194, /* (306) cmd ::= create_vtab */
+ 194, /* (307) cmd ::= create_vtab LP vtabarglist RP */
+ 304, /* (308) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 306, /* (309) vtabarg ::= */
+ 307, /* (310) vtabargtoken ::= ANY */
+ 307, /* (311) vtabargtoken ::= lp anylist RP */
+ 308, /* (312) lp ::= LP */
+ 271, /* (313) with ::= WITH wqlist */
+ 271, /* (314) with ::= WITH RECURSIVE wqlist */
+ 311, /* (315) wqas ::= AS */
+ 311, /* (316) wqas ::= AS MATERIALIZED */
+ 311, /* (317) wqas ::= AS NOT MATERIALIZED */
+ 310, /* (318) wqitem ::= withnm eidlist_opt wqas LP select RP */
+ 312, /* (319) withnm ::= nm */
+ 245, /* (320) wqlist ::= wqitem */
+ 245, /* (321) wqlist ::= wqlist COMMA wqitem */
+ 313, /* (322) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ 314, /* (323) windowdefn ::= nm AS LP window RP */
+ 315, /* (324) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ 315, /* (325) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ 315, /* (326) window ::= ORDER BY sortlist frame_opt */
+ 315, /* (327) window ::= nm ORDER BY sortlist frame_opt */
+ 315, /* (328) window ::= nm frame_opt */
+ 316, /* (329) frame_opt ::= */
+ 316, /* (330) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ 316, /* (331) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ 320, /* (332) range_or_rows ::= RANGE|ROWS|GROUPS */
+ 322, /* (333) frame_bound_s ::= frame_bound */
+ 322, /* (334) frame_bound_s ::= UNBOUNDED PRECEDING */
+ 323, /* (335) frame_bound_e ::= frame_bound */
+ 323, /* (336) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ 321, /* (337) frame_bound ::= expr PRECEDING|FOLLOWING */
+ 321, /* (338) frame_bound ::= CURRENT ROW */
+ 324, /* (339) frame_exclude_opt ::= */
+ 324, /* (340) frame_exclude_opt ::= EXCLUDE frame_exclude */
+ 325, /* (341) frame_exclude ::= NO OTHERS */
+ 325, /* (342) frame_exclude ::= CURRENT ROW */
+ 325, /* (343) frame_exclude ::= GROUP|TIES */
+ 255, /* (344) window_clause ::= WINDOW windowdefn_list */
+ 278, /* (345) filter_over ::= filter_clause over_clause */
+ 278, /* (346) filter_over ::= over_clause */
+ 278, /* (347) filter_over ::= filter_clause */
+ 319, /* (348) over_clause ::= OVER LP window RP */
+ 319, /* (349) over_clause ::= OVER nm */
+ 318, /* (350) filter_clause ::= FILTER LP WHERE expr RP */
+ 220, /* (351) term ::= QNUMBER */
+ 189, /* (352) input ::= cmdlist */
+ 190, /* (353) cmdlist ::= cmdlist ecmd */
+ 190, /* (354) cmdlist ::= ecmd */
+ 191, /* (355) ecmd ::= SEMI */
+ 191, /* (356) ecmd ::= cmdx SEMI */
+ 191, /* (357) ecmd ::= explain cmdx SEMI */
+ 196, /* (358) trans_opt ::= */
+ 196, /* (359) trans_opt ::= TRANSACTION */
+ 196, /* (360) trans_opt ::= TRANSACTION nm */
+ 198, /* (361) savepoint_opt ::= SAVEPOINT */
+ 198, /* (362) savepoint_opt ::= */
+ 194, /* (363) cmd ::= create_table create_table_args */
+ 207, /* (364) table_option_set ::= table_option */
+ 205, /* (365) columnlist ::= columnlist COMMA columnname carglist */
+ 205, /* (366) columnlist ::= columnname carglist */
+ 197, /* (367) nm ::= ID|INDEXED|JOIN_KW */
+ 197, /* (368) nm ::= STRING */
+ 212, /* (369) typetoken ::= typename */
+ 213, /* (370) typename ::= ID|STRING */
+ 214, /* (371) signed ::= plus_num */
+ 214, /* (372) signed ::= minus_num */
+ 211, /* (373) carglist ::= carglist ccons */
+ 211, /* (374) carglist ::= */
+ 219, /* (375) ccons ::= NULL onconf */
+ 219, /* (376) ccons ::= GENERATED ALWAYS AS generated */
+ 219, /* (377) ccons ::= AS generated */
+ 206, /* (378) conslist_opt ::= COMMA conslist */
+ 232, /* (379) conslist ::= conslist tconscomma tcons */
+ 232, /* (380) conslist ::= tcons */
+ 233, /* (381) tconscomma ::= */
+ 237, /* (382) defer_subclause_opt ::= defer_subclause */
+ 239, /* (383) resolvetype ::= raisetype */
+ 243, /* (384) selectnowith ::= oneselect */
+ 244, /* (385) oneselect ::= values */
+ 259, /* (386) sclp ::= selcollist COMMA */
+ 260, /* (387) as ::= ID|STRING */
+ 269, /* (388) indexed_opt ::= indexed_by */
+ 277, /* (389) returning ::= */
+ 221, /* (390) expr ::= term */
+ 279, /* (391) likeop ::= LIKE_KW|MATCH */
+ 283, /* (392) case_operand ::= expr */
+ 266, /* (393) exprlist ::= nexprlist */
+ 290, /* (394) nmnum ::= plus_num */
+ 290, /* (395) nmnum ::= nm */
+ 290, /* (396) nmnum ::= ON */
+ 290, /* (397) nmnum ::= DELETE */
+ 290, /* (398) nmnum ::= DEFAULT */
+ 215, /* (399) plus_num ::= INTEGER|FLOAT */
+ 295, /* (400) foreach_clause ::= */
+ 295, /* (401) foreach_clause ::= FOR EACH ROW */
+ 298, /* (402) trnm ::= nm */
+ 299, /* (403) tridxby ::= */
+ 300, /* (404) database_kw_opt ::= DATABASE */
+ 300, /* (405) database_kw_opt ::= */
+ 303, /* (406) kwcolumn_opt ::= */
+ 303, /* (407) kwcolumn_opt ::= COLUMNKW */
+ 305, /* (408) vtabarglist ::= vtabarg */
+ 305, /* (409) vtabarglist ::= vtabarglist COMMA vtabarg */
+ 306, /* (410) vtabarg ::= vtabarg vtabargtoken */
+ 309, /* (411) anylist ::= */
+ 309, /* (412) anylist ::= anylist LP anylist RP */
+ 309, /* (413) anylist ::= anylist ANY */
+ 271, /* (414) with ::= */
+ 313, /* (415) windowdefn_list ::= windowdefn */
+ 315, /* (416) window ::= frame_opt */
};
/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
@@ -176863,319 +179833,323 @@ static const signed char yyRuleInfoNRhs[] = {
-9, /* (97) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
-10, /* (98) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
-4, /* (99) values ::= VALUES LP nexprlist RP */
- -5, /* (100) values ::= values COMMA LP nexprlist RP */
- -1, /* (101) distinct ::= DISTINCT */
- -1, /* (102) distinct ::= ALL */
- 0, /* (103) distinct ::= */
- 0, /* (104) sclp ::= */
- -5, /* (105) selcollist ::= sclp scanpt expr scanpt as */
- -3, /* (106) selcollist ::= sclp scanpt STAR */
- -5, /* (107) selcollist ::= sclp scanpt nm DOT STAR */
- -2, /* (108) as ::= AS nm */
- 0, /* (109) as ::= */
- 0, /* (110) from ::= */
- -2, /* (111) from ::= FROM seltablist */
- -2, /* (112) stl_prefix ::= seltablist joinop */
- 0, /* (113) stl_prefix ::= */
- -5, /* (114) seltablist ::= stl_prefix nm dbnm as on_using */
- -6, /* (115) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
- -8, /* (116) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
- -6, /* (117) seltablist ::= stl_prefix LP select RP as on_using */
- -6, /* (118) seltablist ::= stl_prefix LP seltablist RP as on_using */
- 0, /* (119) dbnm ::= */
- -2, /* (120) dbnm ::= DOT nm */
- -1, /* (121) fullname ::= nm */
- -3, /* (122) fullname ::= nm DOT nm */
- -1, /* (123) xfullname ::= nm */
- -3, /* (124) xfullname ::= nm DOT nm */
- -5, /* (125) xfullname ::= nm DOT nm AS nm */
- -3, /* (126) xfullname ::= nm AS nm */
- -1, /* (127) joinop ::= COMMA|JOIN */
- -2, /* (128) joinop ::= JOIN_KW JOIN */
- -3, /* (129) joinop ::= JOIN_KW nm JOIN */
- -4, /* (130) joinop ::= JOIN_KW nm nm JOIN */
- -2, /* (131) on_using ::= ON expr */
- -4, /* (132) on_using ::= USING LP idlist RP */
- 0, /* (133) on_using ::= */
- 0, /* (134) indexed_opt ::= */
- -3, /* (135) indexed_by ::= INDEXED BY nm */
- -2, /* (136) indexed_by ::= NOT INDEXED */
- 0, /* (137) orderby_opt ::= */
- -3, /* (138) orderby_opt ::= ORDER BY sortlist */
- -5, /* (139) sortlist ::= sortlist COMMA expr sortorder nulls */
- -3, /* (140) sortlist ::= expr sortorder nulls */
- -1, /* (141) sortorder ::= ASC */
- -1, /* (142) sortorder ::= DESC */
- 0, /* (143) sortorder ::= */
- -2, /* (144) nulls ::= NULLS FIRST */
- -2, /* (145) nulls ::= NULLS LAST */
- 0, /* (146) nulls ::= */
- 0, /* (147) groupby_opt ::= */
- -3, /* (148) groupby_opt ::= GROUP BY nexprlist */
- 0, /* (149) having_opt ::= */
- -2, /* (150) having_opt ::= HAVING expr */
- 0, /* (151) limit_opt ::= */
- -2, /* (152) limit_opt ::= LIMIT expr */
- -4, /* (153) limit_opt ::= LIMIT expr OFFSET expr */
- -4, /* (154) limit_opt ::= LIMIT expr COMMA expr */
- -6, /* (155) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
- 0, /* (156) where_opt ::= */
- -2, /* (157) where_opt ::= WHERE expr */
- 0, /* (158) where_opt_ret ::= */
- -2, /* (159) where_opt_ret ::= WHERE expr */
- -2, /* (160) where_opt_ret ::= RETURNING selcollist */
- -4, /* (161) where_opt_ret ::= WHERE expr RETURNING selcollist */
- -9, /* (162) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
- -5, /* (163) setlist ::= setlist COMMA nm EQ expr */
- -7, /* (164) setlist ::= setlist COMMA LP idlist RP EQ expr */
- -3, /* (165) setlist ::= nm EQ expr */
- -5, /* (166) setlist ::= LP idlist RP EQ expr */
- -7, /* (167) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
- -8, /* (168) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
- 0, /* (169) upsert ::= */
- -2, /* (170) upsert ::= RETURNING selcollist */
- -12, /* (171) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
- -9, /* (172) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
- -5, /* (173) upsert ::= ON CONFLICT DO NOTHING returning */
- -8, /* (174) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
- -2, /* (175) returning ::= RETURNING selcollist */
- -2, /* (176) insert_cmd ::= INSERT orconf */
- -1, /* (177) insert_cmd ::= REPLACE */
- 0, /* (178) idlist_opt ::= */
- -3, /* (179) idlist_opt ::= LP idlist RP */
- -3, /* (180) idlist ::= idlist COMMA nm */
- -1, /* (181) idlist ::= nm */
- -3, /* (182) expr ::= LP expr RP */
- -1, /* (183) expr ::= ID|INDEXED|JOIN_KW */
- -3, /* (184) expr ::= nm DOT nm */
- -5, /* (185) expr ::= nm DOT nm DOT nm */
- -1, /* (186) term ::= NULL|FLOAT|BLOB */
- -1, /* (187) term ::= STRING */
- -1, /* (188) term ::= INTEGER */
- -1, /* (189) expr ::= VARIABLE */
- -3, /* (190) expr ::= expr COLLATE ID|STRING */
- -6, /* (191) expr ::= CAST LP expr AS typetoken RP */
- -5, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
- -8, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
- -4, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
- -6, /* (195) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
- -9, /* (196) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
- -5, /* (197) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
- -1, /* (198) term ::= CTIME_KW */
- -5, /* (199) expr ::= LP nexprlist COMMA expr RP */
- -3, /* (200) expr ::= expr AND expr */
- -3, /* (201) expr ::= expr OR expr */
- -3, /* (202) expr ::= expr LT|GT|GE|LE expr */
- -3, /* (203) expr ::= expr EQ|NE expr */
- -3, /* (204) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- -3, /* (205) expr ::= expr PLUS|MINUS expr */
- -3, /* (206) expr ::= expr STAR|SLASH|REM expr */
- -3, /* (207) expr ::= expr CONCAT expr */
- -2, /* (208) likeop ::= NOT LIKE_KW|MATCH */
- -3, /* (209) expr ::= expr likeop expr */
- -5, /* (210) expr ::= expr likeop expr ESCAPE expr */
- -2, /* (211) expr ::= expr ISNULL|NOTNULL */
- -3, /* (212) expr ::= expr NOT NULL */
- -3, /* (213) expr ::= expr IS expr */
- -4, /* (214) expr ::= expr IS NOT expr */
- -6, /* (215) expr ::= expr IS NOT DISTINCT FROM expr */
- -5, /* (216) expr ::= expr IS DISTINCT FROM expr */
- -2, /* (217) expr ::= NOT expr */
- -2, /* (218) expr ::= BITNOT expr */
- -2, /* (219) expr ::= PLUS|MINUS expr */
- -3, /* (220) expr ::= expr PTR expr */
- -1, /* (221) between_op ::= BETWEEN */
- -2, /* (222) between_op ::= NOT BETWEEN */
- -5, /* (223) expr ::= expr between_op expr AND expr */
- -1, /* (224) in_op ::= IN */
- -2, /* (225) in_op ::= NOT IN */
- -5, /* (226) expr ::= expr in_op LP exprlist RP */
- -3, /* (227) expr ::= LP select RP */
- -5, /* (228) expr ::= expr in_op LP select RP */
- -5, /* (229) expr ::= expr in_op nm dbnm paren_exprlist */
- -4, /* (230) expr ::= EXISTS LP select RP */
- -5, /* (231) expr ::= CASE case_operand case_exprlist case_else END */
- -5, /* (232) case_exprlist ::= case_exprlist WHEN expr THEN expr */
- -4, /* (233) case_exprlist ::= WHEN expr THEN expr */
- -2, /* (234) case_else ::= ELSE expr */
- 0, /* (235) case_else ::= */
- 0, /* (236) case_operand ::= */
- 0, /* (237) exprlist ::= */
- -3, /* (238) nexprlist ::= nexprlist COMMA expr */
- -1, /* (239) nexprlist ::= expr */
- 0, /* (240) paren_exprlist ::= */
- -3, /* (241) paren_exprlist ::= LP exprlist RP */
- -13, /* (242) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm indextype ON nm LP sortlist RP where_opt */
- -1, /* (243) uniqueflag ::= UNIQUE */
- 0, /* (244) uniqueflag ::= */
- -2, /* (245) indextype ::= USING idlist */
- 0, /* (246) indextype ::= */
- 0, /* (247) eidlist_opt ::= */
- -3, /* (248) eidlist_opt ::= LP eidlist RP */
- -5, /* (249) eidlist ::= eidlist COMMA nm collate sortorder */
- -3, /* (250) eidlist ::= nm collate sortorder */
- 0, /* (251) collate ::= */
- -2, /* (252) collate ::= COLLATE ID|STRING */
- -4, /* (253) cmd ::= DROP INDEX ifexists fullname */
- -2, /* (254) cmd ::= VACUUM vinto */
- -3, /* (255) cmd ::= VACUUM nm vinto */
- -2, /* (256) vinto ::= INTO expr */
- 0, /* (257) vinto ::= */
- -3, /* (258) cmd ::= PRAGMA nm dbnm */
- -5, /* (259) cmd ::= PRAGMA nm dbnm EQ nmnum */
- -6, /* (260) cmd ::= PRAGMA nm dbnm LP nmnum RP */
- -5, /* (261) cmd ::= PRAGMA nm dbnm EQ minus_num */
- -6, /* (262) cmd ::= PRAGMA nm dbnm LP minus_num RP */
- -2, /* (263) plus_num ::= PLUS INTEGER|FLOAT */
- -2, /* (264) minus_num ::= MINUS INTEGER|FLOAT */
- -5, /* (265) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
- -11, /* (266) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
- -1, /* (267) trigger_time ::= BEFORE|AFTER */
- -2, /* (268) trigger_time ::= INSTEAD OF */
- 0, /* (269) trigger_time ::= */
- -1, /* (270) trigger_event ::= DELETE|INSERT */
- -1, /* (271) trigger_event ::= UPDATE */
- -3, /* (272) trigger_event ::= UPDATE OF idlist */
- 0, /* (273) when_clause ::= */
- -2, /* (274) when_clause ::= WHEN expr */
- -3, /* (275) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
- -2, /* (276) trigger_cmd_list ::= trigger_cmd SEMI */
- -3, /* (277) trnm ::= nm DOT nm */
- -3, /* (278) tridxby ::= INDEXED BY nm */
- -2, /* (279) tridxby ::= NOT INDEXED */
- -9, /* (280) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
- -8, /* (281) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
- -6, /* (282) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
- -3, /* (283) trigger_cmd ::= scanpt select scanpt */
- -4, /* (284) expr ::= RAISE LP IGNORE RP */
- -6, /* (285) expr ::= RAISE LP raisetype COMMA nm RP */
- -1, /* (286) raisetype ::= ROLLBACK */
- -1, /* (287) raisetype ::= ABORT */
- -1, /* (288) raisetype ::= FAIL */
- -4, /* (289) cmd ::= DROP TRIGGER ifexists fullname */
- -6, /* (290) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
- -3, /* (291) cmd ::= DETACH database_kw_opt expr */
- 0, /* (292) key_opt ::= */
- -2, /* (293) key_opt ::= KEY expr */
- -1, /* (294) cmd ::= REINDEX */
- -3, /* (295) cmd ::= REINDEX nm dbnm */
- -1, /* (296) cmd ::= ANALYZE */
- -3, /* (297) cmd ::= ANALYZE nm dbnm */
- -6, /* (298) cmd ::= ALTER TABLE fullname RENAME TO nm */
- -7, /* (299) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
- -6, /* (300) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
- -1, /* (301) add_column_fullname ::= fullname */
- -8, /* (302) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
- -9, /* (303) cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */
- -1, /* (304) cmd ::= create_vtab */
- -4, /* (305) cmd ::= create_vtab LP vtabarglist RP */
- -8, /* (306) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
- 0, /* (307) vtabarg ::= */
- -1, /* (308) vtabargtoken ::= ANY */
- -3, /* (309) vtabargtoken ::= lp anylist RP */
- -1, /* (310) lp ::= LP */
- -2, /* (311) with ::= WITH wqlist */
- -3, /* (312) with ::= WITH RECURSIVE wqlist */
- -1, /* (313) wqas ::= AS */
- -2, /* (314) wqas ::= AS MATERIALIZED */
- -3, /* (315) wqas ::= AS NOT MATERIALIZED */
- -6, /* (316) wqitem ::= nm eidlist_opt wqas LP select RP */
- -1, /* (317) wqlist ::= wqitem */
- -3, /* (318) wqlist ::= wqlist COMMA wqitem */
- -3, /* (319) windowdefn_list ::= windowdefn_list COMMA windowdefn */
- -5, /* (320) windowdefn ::= nm AS LP window RP */
- -5, /* (321) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
- -6, /* (322) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
- -4, /* (323) window ::= ORDER BY sortlist frame_opt */
- -5, /* (324) window ::= nm ORDER BY sortlist frame_opt */
- -2, /* (325) window ::= nm frame_opt */
- 0, /* (326) frame_opt ::= */
- -3, /* (327) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
- -6, /* (328) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
- -1, /* (329) range_or_rows ::= RANGE|ROWS|GROUPS */
- -1, /* (330) frame_bound_s ::= frame_bound */
- -2, /* (331) frame_bound_s ::= UNBOUNDED PRECEDING */
- -1, /* (332) frame_bound_e ::= frame_bound */
- -2, /* (333) frame_bound_e ::= UNBOUNDED FOLLOWING */
- -2, /* (334) frame_bound ::= expr PRECEDING|FOLLOWING */
- -2, /* (335) frame_bound ::= CURRENT ROW */
- 0, /* (336) frame_exclude_opt ::= */
- -2, /* (337) frame_exclude_opt ::= EXCLUDE frame_exclude */
- -2, /* (338) frame_exclude ::= NO OTHERS */
- -2, /* (339) frame_exclude ::= CURRENT ROW */
- -1, /* (340) frame_exclude ::= GROUP|TIES */
- -2, /* (341) window_clause ::= WINDOW windowdefn_list */
- -2, /* (342) filter_over ::= filter_clause over_clause */
- -1, /* (343) filter_over ::= over_clause */
- -1, /* (344) filter_over ::= filter_clause */
- -4, /* (345) over_clause ::= OVER LP window RP */
- -2, /* (346) over_clause ::= OVER nm */
- -5, /* (347) filter_clause ::= FILTER LP WHERE expr RP */
- -1, /* (348) input ::= cmdlist */
- -2, /* (349) cmdlist ::= cmdlist ecmd */
- -1, /* (350) cmdlist ::= ecmd */
- -1, /* (351) ecmd ::= SEMI */
- -2, /* (352) ecmd ::= cmdx SEMI */
- -3, /* (353) ecmd ::= explain cmdx SEMI */
- 0, /* (354) trans_opt ::= */
- -1, /* (355) trans_opt ::= TRANSACTION */
- -2, /* (356) trans_opt ::= TRANSACTION nm */
- -1, /* (357) savepoint_opt ::= SAVEPOINT */
- 0, /* (358) savepoint_opt ::= */
- -2, /* (359) cmd ::= create_table create_table_args */
- -1, /* (360) table_option_set ::= table_option */
- -4, /* (361) columnlist ::= columnlist COMMA columnname carglist */
- -2, /* (362) columnlist ::= columnname carglist */
- -1, /* (363) nm ::= ID|INDEXED|JOIN_KW */
- -1, /* (364) nm ::= STRING */
- -1, /* (365) typetoken ::= typename */
- -1, /* (366) typename ::= ID|STRING */
- -1, /* (367) signed ::= plus_num */
- -1, /* (368) signed ::= minus_num */
- -2, /* (369) carglist ::= carglist ccons */
- 0, /* (370) carglist ::= */
- -2, /* (371) ccons ::= NULL onconf */
- -4, /* (372) ccons ::= GENERATED ALWAYS AS generated */
- -2, /* (373) ccons ::= AS generated */
- -2, /* (374) conslist_opt ::= COMMA conslist */
- -3, /* (375) conslist ::= conslist tconscomma tcons */
- -1, /* (376) conslist ::= tcons */
- 0, /* (377) tconscomma ::= */
- -1, /* (378) defer_subclause_opt ::= defer_subclause */
- -1, /* (379) resolvetype ::= raisetype */
- -1, /* (380) selectnowith ::= oneselect */
- -1, /* (381) oneselect ::= values */
- -2, /* (382) sclp ::= selcollist COMMA */
- -1, /* (383) as ::= ID|STRING */
- -1, /* (384) indexed_opt ::= indexed_by */
- 0, /* (385) returning ::= */
- -1, /* (386) expr ::= term */
- -1, /* (387) likeop ::= LIKE_KW|MATCH */
- -1, /* (388) case_operand ::= expr */
- -1, /* (389) exprlist ::= nexprlist */
- -1, /* (390) nmnum ::= plus_num */
- -1, /* (391) nmnum ::= nm */
- -1, /* (392) nmnum ::= ON */
- -1, /* (393) nmnum ::= DELETE */
- -1, /* (394) nmnum ::= DEFAULT */
- -1, /* (395) plus_num ::= INTEGER|FLOAT */
- 0, /* (396) foreach_clause ::= */
- -3, /* (397) foreach_clause ::= FOR EACH ROW */
- -1, /* (398) trnm ::= nm */
- 0, /* (399) tridxby ::= */
- -1, /* (400) database_kw_opt ::= DATABASE */
- 0, /* (401) database_kw_opt ::= */
- 0, /* (402) kwcolumn_opt ::= */
- -1, /* (403) kwcolumn_opt ::= COLUMNKW */
- -1, /* (404) vtabarglist ::= vtabarg */
- -3, /* (405) vtabarglist ::= vtabarglist COMMA vtabarg */
- -2, /* (406) vtabarg ::= vtabarg vtabargtoken */
- 0, /* (407) anylist ::= */
- -4, /* (408) anylist ::= anylist LP anylist RP */
- -2, /* (409) anylist ::= anylist ANY */
- 0, /* (410) with ::= */
- -1, /* (411) windowdefn_list ::= windowdefn */
- -1, /* (412) window ::= frame_opt */
+ -1, /* (100) oneselect ::= mvalues */
+ -5, /* (101) mvalues ::= values COMMA LP nexprlist RP */
+ -5, /* (102) mvalues ::= mvalues COMMA LP nexprlist RP */
+ -1, /* (103) distinct ::= DISTINCT */
+ -1, /* (104) distinct ::= ALL */
+ 0, /* (105) distinct ::= */
+ 0, /* (106) sclp ::= */
+ -5, /* (107) selcollist ::= sclp scanpt expr scanpt as */
+ -3, /* (108) selcollist ::= sclp scanpt STAR */
+ -5, /* (109) selcollist ::= sclp scanpt nm DOT STAR */
+ -2, /* (110) as ::= AS nm */
+ 0, /* (111) as ::= */
+ 0, /* (112) from ::= */
+ -2, /* (113) from ::= FROM seltablist */
+ -2, /* (114) stl_prefix ::= seltablist joinop */
+ 0, /* (115) stl_prefix ::= */
+ -5, /* (116) seltablist ::= stl_prefix nm dbnm as on_using */
+ -6, /* (117) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
+ -8, /* (118) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
+ -6, /* (119) seltablist ::= stl_prefix LP select RP as on_using */
+ -6, /* (120) seltablist ::= stl_prefix LP seltablist RP as on_using */
+ 0, /* (121) dbnm ::= */
+ -2, /* (122) dbnm ::= DOT nm */
+ -1, /* (123) fullname ::= nm */
+ -3, /* (124) fullname ::= nm DOT nm */
+ -1, /* (125) xfullname ::= nm */
+ -3, /* (126) xfullname ::= nm DOT nm */
+ -5, /* (127) xfullname ::= nm DOT nm AS nm */
+ -3, /* (128) xfullname ::= nm AS nm */
+ -1, /* (129) joinop ::= COMMA|JOIN */
+ -2, /* (130) joinop ::= JOIN_KW JOIN */
+ -3, /* (131) joinop ::= JOIN_KW nm JOIN */
+ -4, /* (132) joinop ::= JOIN_KW nm nm JOIN */
+ -2, /* (133) on_using ::= ON expr */
+ -4, /* (134) on_using ::= USING LP idlist RP */
+ 0, /* (135) on_using ::= */
+ 0, /* (136) indexed_opt ::= */
+ -3, /* (137) indexed_by ::= INDEXED BY nm */
+ -2, /* (138) indexed_by ::= NOT INDEXED */
+ 0, /* (139) orderby_opt ::= */
+ -3, /* (140) orderby_opt ::= ORDER BY sortlist */
+ -5, /* (141) sortlist ::= sortlist COMMA expr sortorder nulls */
+ -3, /* (142) sortlist ::= expr sortorder nulls */
+ -1, /* (143) sortorder ::= ASC */
+ -1, /* (144) sortorder ::= DESC */
+ 0, /* (145) sortorder ::= */
+ -2, /* (146) nulls ::= NULLS FIRST */
+ -2, /* (147) nulls ::= NULLS LAST */
+ 0, /* (148) nulls ::= */
+ 0, /* (149) groupby_opt ::= */
+ -3, /* (150) groupby_opt ::= GROUP BY nexprlist */
+ 0, /* (151) having_opt ::= */
+ -2, /* (152) having_opt ::= HAVING expr */
+ 0, /* (153) limit_opt ::= */
+ -2, /* (154) limit_opt ::= LIMIT expr */
+ -4, /* (155) limit_opt ::= LIMIT expr OFFSET expr */
+ -4, /* (156) limit_opt ::= LIMIT expr COMMA expr */
+ -6, /* (157) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
+ 0, /* (158) where_opt ::= */
+ -2, /* (159) where_opt ::= WHERE expr */
+ 0, /* (160) where_opt_ret ::= */
+ -2, /* (161) where_opt_ret ::= WHERE expr */
+ -2, /* (162) where_opt_ret ::= RETURNING selcollist */
+ -4, /* (163) where_opt_ret ::= WHERE expr RETURNING selcollist */
+ -9, /* (164) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
+ -5, /* (165) setlist ::= setlist COMMA nm EQ expr */
+ -7, /* (166) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ -3, /* (167) setlist ::= nm EQ expr */
+ -5, /* (168) setlist ::= LP idlist RP EQ expr */
+ -7, /* (169) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ -8, /* (170) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
+ 0, /* (171) upsert ::= */
+ -2, /* (172) upsert ::= RETURNING selcollist */
+ -12, /* (173) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
+ -9, /* (174) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
+ -5, /* (175) upsert ::= ON CONFLICT DO NOTHING returning */
+ -8, /* (176) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
+ -2, /* (177) returning ::= RETURNING selcollist */
+ -2, /* (178) insert_cmd ::= INSERT orconf */
+ -1, /* (179) insert_cmd ::= REPLACE */
+ 0, /* (180) idlist_opt ::= */
+ -3, /* (181) idlist_opt ::= LP idlist RP */
+ -3, /* (182) idlist ::= idlist COMMA nm */
+ -1, /* (183) idlist ::= nm */
+ -3, /* (184) expr ::= LP expr RP */
+ -1, /* (185) expr ::= ID|INDEXED|JOIN_KW */
+ -3, /* (186) expr ::= nm DOT nm */
+ -5, /* (187) expr ::= nm DOT nm DOT nm */
+ -1, /* (188) term ::= NULL|FLOAT|BLOB */
+ -1, /* (189) term ::= STRING */
+ -1, /* (190) term ::= INTEGER */
+ -1, /* (191) expr ::= VARIABLE */
+ -3, /* (192) expr ::= expr COLLATE ID|STRING */
+ -6, /* (193) expr ::= CAST LP expr AS typetoken RP */
+ -5, /* (194) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
+ -8, /* (195) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
+ -4, /* (196) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
+ -6, /* (197) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
+ -9, /* (198) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
+ -5, /* (199) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
+ -1, /* (200) term ::= CTIME_KW */
+ -5, /* (201) expr ::= LP nexprlist COMMA expr RP */
+ -3, /* (202) expr ::= expr AND expr */
+ -3, /* (203) expr ::= expr OR expr */
+ -3, /* (204) expr ::= expr LT|GT|GE|LE expr */
+ -3, /* (205) expr ::= expr EQ|NE expr */
+ -3, /* (206) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ -3, /* (207) expr ::= expr PLUS|MINUS expr */
+ -3, /* (208) expr ::= expr STAR|SLASH|REM expr */
+ -3, /* (209) expr ::= expr CONCAT expr */
+ -2, /* (210) likeop ::= NOT LIKE_KW|MATCH */
+ -3, /* (211) expr ::= expr likeop expr */
+ -5, /* (212) expr ::= expr likeop expr ESCAPE expr */
+ -2, /* (213) expr ::= expr ISNULL|NOTNULL */
+ -3, /* (214) expr ::= expr NOT NULL */
+ -3, /* (215) expr ::= expr IS expr */
+ -4, /* (216) expr ::= expr IS NOT expr */
+ -6, /* (217) expr ::= expr IS NOT DISTINCT FROM expr */
+ -5, /* (218) expr ::= expr IS DISTINCT FROM expr */
+ -2, /* (219) expr ::= NOT expr */
+ -2, /* (220) expr ::= BITNOT expr */
+ -2, /* (221) expr ::= PLUS|MINUS expr */
+ -3, /* (222) expr ::= expr PTR expr */
+ -1, /* (223) between_op ::= BETWEEN */
+ -2, /* (224) between_op ::= NOT BETWEEN */
+ -5, /* (225) expr ::= expr between_op expr AND expr */
+ -1, /* (226) in_op ::= IN */
+ -2, /* (227) in_op ::= NOT IN */
+ -5, /* (228) expr ::= expr in_op LP exprlist RP */
+ -3, /* (229) expr ::= LP select RP */
+ -5, /* (230) expr ::= expr in_op LP select RP */
+ -5, /* (231) expr ::= expr in_op nm dbnm paren_exprlist */
+ -4, /* (232) expr ::= EXISTS LP select RP */
+ -5, /* (233) expr ::= CASE case_operand case_exprlist case_else END */
+ -5, /* (234) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ -4, /* (235) case_exprlist ::= WHEN expr THEN expr */
+ -2, /* (236) case_else ::= ELSE expr */
+ 0, /* (237) case_else ::= */
+ 0, /* (238) case_operand ::= */
+ 0, /* (239) exprlist ::= */
+ -3, /* (240) nexprlist ::= nexprlist COMMA expr */
+ -1, /* (241) nexprlist ::= expr */
+ 0, /* (242) paren_exprlist ::= */
+ -3, /* (243) paren_exprlist ::= LP exprlist RP */
+ -13, /* (244) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm indextype ON nm LP sortlist RP where_opt */
+ -1, /* (245) uniqueflag ::= UNIQUE */
+ 0, /* (246) uniqueflag ::= */
+ -2, /* (247) indextype ::= USING idlist */
+ 0, /* (248) indextype ::= */
+ 0, /* (249) eidlist_opt ::= */
+ -3, /* (250) eidlist_opt ::= LP eidlist RP */
+ -5, /* (251) eidlist ::= eidlist COMMA nm collate sortorder */
+ -3, /* (252) eidlist ::= nm collate sortorder */
+ 0, /* (253) collate ::= */
+ -2, /* (254) collate ::= COLLATE ID|STRING */
+ -4, /* (255) cmd ::= DROP INDEX ifexists fullname */
+ -2, /* (256) cmd ::= VACUUM vinto */
+ -3, /* (257) cmd ::= VACUUM nm vinto */
+ -2, /* (258) vinto ::= INTO expr */
+ 0, /* (259) vinto ::= */
+ -3, /* (260) cmd ::= PRAGMA nm dbnm */
+ -5, /* (261) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ -6, /* (262) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ -5, /* (263) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ -6, /* (264) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ -2, /* (265) plus_num ::= PLUS INTEGER|FLOAT */
+ -2, /* (266) minus_num ::= MINUS INTEGER|FLOAT */
+ -5, /* (267) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ -11, /* (268) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ -1, /* (269) trigger_time ::= BEFORE|AFTER */
+ -2, /* (270) trigger_time ::= INSTEAD OF */
+ 0, /* (271) trigger_time ::= */
+ -1, /* (272) trigger_event ::= DELETE|INSERT */
+ -1, /* (273) trigger_event ::= UPDATE */
+ -3, /* (274) trigger_event ::= UPDATE OF idlist */
+ 0, /* (275) when_clause ::= */
+ -2, /* (276) when_clause ::= WHEN expr */
+ -3, /* (277) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ -2, /* (278) trigger_cmd_list ::= trigger_cmd SEMI */
+ -3, /* (279) trnm ::= nm DOT nm */
+ -3, /* (280) tridxby ::= INDEXED BY nm */
+ -2, /* (281) tridxby ::= NOT INDEXED */
+ -9, /* (282) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+ -8, /* (283) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ -6, /* (284) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ -3, /* (285) trigger_cmd ::= scanpt select scanpt */
+ -4, /* (286) expr ::= RAISE LP IGNORE RP */
+ -6, /* (287) expr ::= RAISE LP raisetype COMMA expr RP */
+ -1, /* (288) raisetype ::= ROLLBACK */
+ -1, /* (289) raisetype ::= ABORT */
+ -1, /* (290) raisetype ::= FAIL */
+ -4, /* (291) cmd ::= DROP TRIGGER ifexists fullname */
+ -6, /* (292) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ -3, /* (293) cmd ::= DETACH database_kw_opt expr */
+ 0, /* (294) key_opt ::= */
+ -2, /* (295) key_opt ::= KEY expr */
+ -1, /* (296) cmd ::= REINDEX */
+ -3, /* (297) cmd ::= REINDEX nm dbnm */
+ -1, /* (298) cmd ::= ANALYZE */
+ -3, /* (299) cmd ::= ANALYZE nm dbnm */
+ -6, /* (300) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ -7, /* (301) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ -6, /* (302) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+ -1, /* (303) add_column_fullname ::= fullname */
+ -8, /* (304) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ -9, /* (305) cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */
+ -1, /* (306) cmd ::= create_vtab */
+ -4, /* (307) cmd ::= create_vtab LP vtabarglist RP */
+ -8, /* (308) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 0, /* (309) vtabarg ::= */
+ -1, /* (310) vtabargtoken ::= ANY */
+ -3, /* (311) vtabargtoken ::= lp anylist RP */
+ -1, /* (312) lp ::= LP */
+ -2, /* (313) with ::= WITH wqlist */
+ -3, /* (314) with ::= WITH RECURSIVE wqlist */
+ -1, /* (315) wqas ::= AS */
+ -2, /* (316) wqas ::= AS MATERIALIZED */
+ -3, /* (317) wqas ::= AS NOT MATERIALIZED */
+ -6, /* (318) wqitem ::= withnm eidlist_opt wqas LP select RP */
+ -1, /* (319) withnm ::= nm */
+ -1, /* (320) wqlist ::= wqitem */
+ -3, /* (321) wqlist ::= wqlist COMMA wqitem */
+ -3, /* (322) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ -5, /* (323) windowdefn ::= nm AS LP window RP */
+ -5, /* (324) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ -6, /* (325) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ -4, /* (326) window ::= ORDER BY sortlist frame_opt */
+ -5, /* (327) window ::= nm ORDER BY sortlist frame_opt */
+ -2, /* (328) window ::= nm frame_opt */
+ 0, /* (329) frame_opt ::= */
+ -3, /* (330) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ -6, /* (331) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ -1, /* (332) range_or_rows ::= RANGE|ROWS|GROUPS */
+ -1, /* (333) frame_bound_s ::= frame_bound */
+ -2, /* (334) frame_bound_s ::= UNBOUNDED PRECEDING */
+ -1, /* (335) frame_bound_e ::= frame_bound */
+ -2, /* (336) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ -2, /* (337) frame_bound ::= expr PRECEDING|FOLLOWING */
+ -2, /* (338) frame_bound ::= CURRENT ROW */
+ 0, /* (339) frame_exclude_opt ::= */
+ -2, /* (340) frame_exclude_opt ::= EXCLUDE frame_exclude */
+ -2, /* (341) frame_exclude ::= NO OTHERS */
+ -2, /* (342) frame_exclude ::= CURRENT ROW */
+ -1, /* (343) frame_exclude ::= GROUP|TIES */
+ -2, /* (344) window_clause ::= WINDOW windowdefn_list */
+ -2, /* (345) filter_over ::= filter_clause over_clause */
+ -1, /* (346) filter_over ::= over_clause */
+ -1, /* (347) filter_over ::= filter_clause */
+ -4, /* (348) over_clause ::= OVER LP window RP */
+ -2, /* (349) over_clause ::= OVER nm */
+ -5, /* (350) filter_clause ::= FILTER LP WHERE expr RP */
+ -1, /* (351) term ::= QNUMBER */
+ -1, /* (352) input ::= cmdlist */
+ -2, /* (353) cmdlist ::= cmdlist ecmd */
+ -1, /* (354) cmdlist ::= ecmd */
+ -1, /* (355) ecmd ::= SEMI */
+ -2, /* (356) ecmd ::= cmdx SEMI */
+ -3, /* (357) ecmd ::= explain cmdx SEMI */
+ 0, /* (358) trans_opt ::= */
+ -1, /* (359) trans_opt ::= TRANSACTION */
+ -2, /* (360) trans_opt ::= TRANSACTION nm */
+ -1, /* (361) savepoint_opt ::= SAVEPOINT */
+ 0, /* (362) savepoint_opt ::= */
+ -2, /* (363) cmd ::= create_table create_table_args */
+ -1, /* (364) table_option_set ::= table_option */
+ -4, /* (365) columnlist ::= columnlist COMMA columnname carglist */
+ -2, /* (366) columnlist ::= columnname carglist */
+ -1, /* (367) nm ::= ID|INDEXED|JOIN_KW */
+ -1, /* (368) nm ::= STRING */
+ -1, /* (369) typetoken ::= typename */
+ -1, /* (370) typename ::= ID|STRING */
+ -1, /* (371) signed ::= plus_num */
+ -1, /* (372) signed ::= minus_num */
+ -2, /* (373) carglist ::= carglist ccons */
+ 0, /* (374) carglist ::= */
+ -2, /* (375) ccons ::= NULL onconf */
+ -4, /* (376) ccons ::= GENERATED ALWAYS AS generated */
+ -2, /* (377) ccons ::= AS generated */
+ -2, /* (378) conslist_opt ::= COMMA conslist */
+ -3, /* (379) conslist ::= conslist tconscomma tcons */
+ -1, /* (380) conslist ::= tcons */
+ 0, /* (381) tconscomma ::= */
+ -1, /* (382) defer_subclause_opt ::= defer_subclause */
+ -1, /* (383) resolvetype ::= raisetype */
+ -1, /* (384) selectnowith ::= oneselect */
+ -1, /* (385) oneselect ::= values */
+ -2, /* (386) sclp ::= selcollist COMMA */
+ -1, /* (387) as ::= ID|STRING */
+ -1, /* (388) indexed_opt ::= indexed_by */
+ 0, /* (389) returning ::= */
+ -1, /* (390) expr ::= term */
+ -1, /* (391) likeop ::= LIKE_KW|MATCH */
+ -1, /* (392) case_operand ::= expr */
+ -1, /* (393) exprlist ::= nexprlist */
+ -1, /* (394) nmnum ::= plus_num */
+ -1, /* (395) nmnum ::= nm */
+ -1, /* (396) nmnum ::= ON */
+ -1, /* (397) nmnum ::= DELETE */
+ -1, /* (398) nmnum ::= DEFAULT */
+ -1, /* (399) plus_num ::= INTEGER|FLOAT */
+ 0, /* (400) foreach_clause ::= */
+ -3, /* (401) foreach_clause ::= FOR EACH ROW */
+ -1, /* (402) trnm ::= nm */
+ 0, /* (403) tridxby ::= */
+ -1, /* (404) database_kw_opt ::= DATABASE */
+ 0, /* (405) database_kw_opt ::= */
+ 0, /* (406) kwcolumn_opt ::= */
+ -1, /* (407) kwcolumn_opt ::= COLUMNKW */
+ -1, /* (408) vtabarglist ::= vtabarg */
+ -3, /* (409) vtabarglist ::= vtabarglist COMMA vtabarg */
+ -2, /* (410) vtabarg ::= vtabarg vtabargtoken */
+ 0, /* (411) anylist ::= */
+ -4, /* (412) anylist ::= anylist LP anylist RP */
+ -2, /* (413) anylist ::= anylist ANY */
+ 0, /* (414) with ::= */
+ -1, /* (415) windowdefn_list ::= windowdefn */
+ -1, /* (416) window ::= frame_opt */
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -177227,19 +180201,19 @@ static YYACTIONTYPE yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy502);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy320);}
break;
case 4: /* transtype ::= */
-{yymsp[1].minor.yy502 = TK_DEFERRED;}
+{yymsp[1].minor.yy320 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
- case 329: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==329);
-{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/}
+ case 332: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==332);
+{yymsp[0].minor.yy320 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* transtype ::= READONLY */
-{yymsp[0].minor.yy502 = TK_DEFERRED; /*yymsp[0].minor.yy502-overwrites-X*/}
+{yymsp[0].minor.yy320 = TK_DEFERRED; /*yymsp[0].minor.yy320-overwrites-X*/}
break;
case 9: /* cmd ::= COMMIT|END trans_opt */
case 10: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==10);
@@ -177262,7 +180236,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 14: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy502,0,0,yymsp[-2].minor.yy502);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy320,0,0,yymsp[-2].minor.yy320);
}
break;
case 15: /* createkw ::= CREATE */
@@ -177274,40 +180248,40 @@ static YYACTIONTYPE yy_reduce(
case 64: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==64);
case 74: /* defer_subclause_opt ::= */ yytestcase(yyruleno==74);
case 83: /* ifexists ::= */ yytestcase(yyruleno==83);
- case 103: /* distinct ::= */ yytestcase(yyruleno==103);
- case 251: /* collate ::= */ yytestcase(yyruleno==251);
-{yymsp[1].minor.yy502 = 0;}
+ case 105: /* distinct ::= */ yytestcase(yyruleno==105);
+ case 253: /* collate ::= */ yytestcase(yyruleno==253);
+{yymsp[1].minor.yy320 = 0;}
break;
case 17: /* ifnotexists ::= IF NOT EXISTS */
-{yymsp[-2].minor.yy502 = 1;}
+{yymsp[-2].minor.yy320 = 1;}
break;
case 18: /* temp ::= TEMP */
-{yymsp[0].minor.yy502 = pParse->db->init.busy==0;}
+{yymsp[0].minor.yy320 = pParse->db->init.busy==0;}
break;
case 20: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */
{
- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy9,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy191,0);
}
break;
case 21: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy637);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy637);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy599);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy599);
}
break;
case 22: /* table_option_set ::= */
-{yymsp[1].minor.yy9 = 0;}
+{yymsp[1].minor.yy191 = 0;}
break;
case 23: /* table_option_set ::= table_option_set COMMA table_option */
-{yylhsminor.yy9 = yymsp[-2].minor.yy9|yymsp[0].minor.yy9;}
- yymsp[-2].minor.yy9 = yylhsminor.yy9;
+{yylhsminor.yy191 = yymsp[-2].minor.yy191|yymsp[0].minor.yy191;}
+ yymsp[-2].minor.yy191 = yylhsminor.yy191;
break;
case 24: /* table_option ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yymsp[-1].minor.yy9 = TF_WithoutRowid | TF_NoVisibleRowid;
+ yymsp[-1].minor.yy191 = TF_WithoutRowid | TF_NoVisibleRowid;
}else{
- yymsp[-1].minor.yy9 = 0;
+ yymsp[-1].minor.yy191 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -177315,9 +180289,9 @@ static YYACTIONTYPE yy_reduce(
case 25: /* table_option ::= RANDOM nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yymsp[-1].minor.yy9 = TF_RandomRowid;
+ yymsp[-1].minor.yy191 = TF_RandomRowid;
}else{
- yymsp[-1].minor.yy9 = 0;
+ yymsp[-1].minor.yy191 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -177325,20 +180299,20 @@ static YYACTIONTYPE yy_reduce(
case 26: /* table_option ::= nm */
{
if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){
- yylhsminor.yy9 = TF_Strict;
+ yylhsminor.yy191 = TF_Strict;
}else{
- yylhsminor.yy9 = 0;
+ yylhsminor.yy191 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
- yymsp[0].minor.yy9 = yylhsminor.yy9;
+ yymsp[0].minor.yy191 = yylhsminor.yy191;
break;
case 27: /* columnname ::= nm typetoken */
{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);}
break;
case 28: /* typetoken ::= */
case 67: /* conslist_opt ::= */ yytestcase(yyruleno==67);
- case 109: /* as ::= */ yytestcase(yyruleno==109);
+ case 111: /* as ::= */ yytestcase(yyruleno==111);
{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
break;
case 29: /* typetoken ::= typename LP signed RP */
@@ -177357,7 +180331,7 @@ static YYACTIONTYPE yy_reduce(
case 32: /* scanpt ::= */
{
assert( yyLookahead!=YYNOCODE );
- yymsp[1].minor.yy342 = yyLookaheadToken.z;
+ yymsp[1].minor.yy400 = yyLookaheadToken.z;
}
break;
case 33: /* scantok ::= */
@@ -177371,17 +180345,17 @@ static YYACTIONTYPE yy_reduce(
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
case 35: /* ccons ::= DEFAULT scantok term */
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy66,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
case 36: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy590,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy66,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
break;
case 37: /* ccons ::= DEFAULT PLUS scantok term */
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy66,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
case 38: /* ccons ::= DEFAULT MINUS scantok term */
{
- Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy590, 0);
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy66, 0);
sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
}
break;
@@ -177396,166 +180370,166 @@ static YYACTIONTYPE yy_reduce(
}
break;
case 40: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy502);}
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy320);}
break;
case 41: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy502,yymsp[0].minor.yy502,yymsp[-2].minor.yy502);}
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy320,yymsp[0].minor.yy320,yymsp[-2].minor.yy320);}
break;
case 42: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy502,0,0,0,0,
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy320,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE,0);}
break;
case 43: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy590,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy66,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
break;
case 44: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy402,yymsp[0].minor.yy502);}
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy70,yymsp[0].minor.yy320);}
break;
case 45: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy502);}
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy320);}
break;
case 46: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
case 47: /* generated ::= LP expr RP */
-{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy590,0);}
+{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy66,0);}
break;
case 48: /* generated ::= LP expr RP ID */
-{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy590,&yymsp[0].minor.yy0);}
+{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy66,&yymsp[0].minor.yy0);}
break;
case 50: /* autoinc ::= AUTOINCR */
-{yymsp[0].minor.yy502 = 1;}
+{yymsp[0].minor.yy320 = 1;}
break;
case 51: /* refargs ::= */
-{ yymsp[1].minor.yy502 = OE_None*0x0101; /* EV: R-19803-45884 */}
+{ yymsp[1].minor.yy320 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
case 52: /* refargs ::= refargs refarg */
-{ yymsp[-1].minor.yy502 = (yymsp[-1].minor.yy502 & ~yymsp[0].minor.yy481.mask) | yymsp[0].minor.yy481.value; }
+{ yymsp[-1].minor.yy320 = (yymsp[-1].minor.yy320 & ~yymsp[0].minor.yy571.mask) | yymsp[0].minor.yy571.value; }
break;
case 53: /* refarg ::= MATCH nm */
-{ yymsp[-1].minor.yy481.value = 0; yymsp[-1].minor.yy481.mask = 0x000000; }
+{ yymsp[-1].minor.yy571.value = 0; yymsp[-1].minor.yy571.mask = 0x000000; }
break;
case 54: /* refarg ::= ON INSERT refact */
-{ yymsp[-2].minor.yy481.value = 0; yymsp[-2].minor.yy481.mask = 0x000000; }
+{ yymsp[-2].minor.yy571.value = 0; yymsp[-2].minor.yy571.mask = 0x000000; }
break;
case 55: /* refarg ::= ON DELETE refact */
-{ yymsp[-2].minor.yy481.value = yymsp[0].minor.yy502; yymsp[-2].minor.yy481.mask = 0x0000ff; }
+{ yymsp[-2].minor.yy571.value = yymsp[0].minor.yy320; yymsp[-2].minor.yy571.mask = 0x0000ff; }
break;
case 56: /* refarg ::= ON UPDATE refact */
-{ yymsp[-2].minor.yy481.value = yymsp[0].minor.yy502<<8; yymsp[-2].minor.yy481.mask = 0x00ff00; }
+{ yymsp[-2].minor.yy571.value = yymsp[0].minor.yy320<<8; yymsp[-2].minor.yy571.mask = 0x00ff00; }
break;
case 57: /* refact ::= SET NULL */
-{ yymsp[-1].minor.yy502 = OE_SetNull; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy320 = OE_SetNull; /* EV: R-33326-45252 */}
break;
case 58: /* refact ::= SET DEFAULT */
-{ yymsp[-1].minor.yy502 = OE_SetDflt; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy320 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
case 59: /* refact ::= CASCADE */
-{ yymsp[0].minor.yy502 = OE_Cascade; /* EV: R-33326-45252 */}
+{ yymsp[0].minor.yy320 = OE_Cascade; /* EV: R-33326-45252 */}
break;
case 60: /* refact ::= RESTRICT */
-{ yymsp[0].minor.yy502 = OE_Restrict; /* EV: R-33326-45252 */}
+{ yymsp[0].minor.yy320 = OE_Restrict; /* EV: R-33326-45252 */}
break;
case 61: /* refact ::= NO ACTION */
-{ yymsp[-1].minor.yy502 = OE_None; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy320 = OE_None; /* EV: R-33326-45252 */}
break;
case 62: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-{yymsp[-2].minor.yy502 = 0;}
+{yymsp[-2].minor.yy320 = 0;}
break;
case 63: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 78: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==78);
- case 176: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==176);
-{yymsp[-1].minor.yy502 = yymsp[0].minor.yy502;}
+ case 178: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==178);
+{yymsp[-1].minor.yy320 = yymsp[0].minor.yy320;}
break;
case 65: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
case 82: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==82);
- case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
- case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
- case 252: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==252);
-{yymsp[-1].minor.yy502 = 1;}
+ case 224: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==224);
+ case 227: /* in_op ::= NOT IN */ yytestcase(yyruleno==227);
+ case 254: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==254);
+{yymsp[-1].minor.yy320 = 1;}
break;
case 66: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
-{yymsp[-1].minor.yy502 = 0;}
+{yymsp[-1].minor.yy320 = 0;}
break;
case 68: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
case 70: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy402,yymsp[0].minor.yy502,yymsp[-2].minor.yy502,0);}
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy70,yymsp[0].minor.yy320,yymsp[-2].minor.yy320,0);}
break;
case 71: /* tcons ::= UNIQUE LP sortlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy402,yymsp[0].minor.yy502,0,0,0,0,
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy70,yymsp[0].minor.yy320,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE,0);}
break;
case 72: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy590,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy66,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
break;
case 73: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy402, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy402, yymsp[-1].minor.yy502);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy502);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy70, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy70, yymsp[-1].minor.yy320);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy320);
}
break;
case 75: /* onconf ::= */
case 77: /* orconf ::= */ yytestcase(yyruleno==77);
-{yymsp[1].minor.yy502 = OE_Default;}
+{yymsp[1].minor.yy320 = OE_Default;}
break;
case 76: /* onconf ::= ON CONFLICT resolvetype */
-{yymsp[-2].minor.yy502 = yymsp[0].minor.yy502;}
+{yymsp[-2].minor.yy320 = yymsp[0].minor.yy320;}
break;
case 79: /* resolvetype ::= IGNORE */
-{yymsp[0].minor.yy502 = OE_Ignore;}
+{yymsp[0].minor.yy320 = OE_Ignore;}
break;
case 80: /* resolvetype ::= REPLACE */
- case 177: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==177);
-{yymsp[0].minor.yy502 = OE_Replace;}
+ case 179: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==179);
+{yymsp[0].minor.yy320 = OE_Replace;}
break;
case 81: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy563, 0, yymsp[-1].minor.yy502);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy595, 0, yymsp[-1].minor.yy320);
}
break;
case 84: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
{
- sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy402, yymsp[0].minor.yy637, yymsp[-7].minor.yy502, yymsp[-5].minor.yy502);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy70, yymsp[0].minor.yy599, yymsp[-7].minor.yy320, yymsp[-5].minor.yy320);
}
break;
case 85: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy563, 1, yymsp[-1].minor.yy502);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy595, 1, yymsp[-1].minor.yy320);
}
break;
case 86: /* cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS STRING */
{
- libsql_create_function(pParse, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, 0, yymsp[-5].minor.yy502);
+ libsql_create_function(pParse, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, 0, yymsp[-5].minor.yy320);
}
break;
case 87: /* cmd ::= createkw FUNCTION ifnotexists nm LANGUAGE nm AS BLOB */
{
- libsql_create_function(pParse, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, 1, yymsp[-5].minor.yy502);
+ libsql_create_function(pParse, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, 1, yymsp[-5].minor.yy320);
}
break;
case 88: /* cmd ::= DROP FUNCTION ifexists nm */
{
- libsql_drop_function(pParse, &yymsp[0].minor.yy0, yymsp[-1].minor.yy502);
+ libsql_drop_function(pParse, &yymsp[0].minor.yy0, yymsp[-1].minor.yy320);
}
break;
case 89: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy637, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy637);
+ sqlite3Select(pParse, yymsp[0].minor.yy599, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy599);
}
break;
case 90: /* select ::= WITH wqlist selectnowith */
-{yymsp[-2].minor.yy637 = attachWithToSelect(pParse,yymsp[0].minor.yy637,yymsp[-1].minor.yy125);}
+{yymsp[-2].minor.yy599 = attachWithToSelect(pParse,yymsp[0].minor.yy599,yymsp[-1].minor.yy523);}
break;
case 91: /* select ::= WITH RECURSIVE wqlist selectnowith */
-{yymsp[-3].minor.yy637 = attachWithToSelect(pParse,yymsp[0].minor.yy637,yymsp[-1].minor.yy125);}
+{yymsp[-3].minor.yy599 = attachWithToSelect(pParse,yymsp[0].minor.yy599,yymsp[-1].minor.yy523);}
break;
case 92: /* select ::= selectnowith */
{
- Select *p = yymsp[0].minor.yy637;
+ Select *p = yymsp[0].minor.yy599;
if( p ){
parserDoubleLinkSelect(pParse, p);
}
@@ -177563,8 +180537,8 @@ static YYACTIONTYPE yy_reduce(
break;
case 93: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
- Select *pRhs = yymsp[0].minor.yy637;
- Select *pLhs = yymsp[-2].minor.yy637;
+ Select *pRhs = yymsp[0].minor.yy599;
+ Select *pLhs = yymsp[-2].minor.yy599;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
@@ -177574,153 +180548,160 @@ static YYACTIONTYPE yy_reduce(
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
- pRhs->op = (u8)yymsp[-1].minor.yy502;
+ pRhs->op = (u8)yymsp[-1].minor.yy320;
pRhs->pPrior = pLhs;
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
pRhs->selFlags &= ~SF_MultiValue;
- if( yymsp[-1].minor.yy502!=TK_ALL ) pParse->hasCompound = 1;
+ if( yymsp[-1].minor.yy320!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, pLhs);
}
- yymsp[-2].minor.yy637 = pRhs;
+ yymsp[-2].minor.yy599 = pRhs;
}
break;
case 94: /* multiselect_op ::= UNION */
case 96: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==96);
-{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-OP*/}
+{yymsp[0].minor.yy320 = yymsp[0].major; /*A-overwrites-OP*/}
break;
case 95: /* multiselect_op ::= UNION ALL */
-{yymsp[-1].minor.yy502 = TK_ALL;}
+{yymsp[-1].minor.yy320 = TK_ALL;}
break;
case 97: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
- yymsp[-8].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy402,yymsp[-5].minor.yy563,yymsp[-4].minor.yy590,yymsp[-3].minor.yy402,yymsp[-2].minor.yy590,yymsp[-1].minor.yy402,yymsp[-7].minor.yy502,yymsp[0].minor.yy590);
+ yymsp[-8].minor.yy599 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy70,yymsp[-5].minor.yy595,yymsp[-4].minor.yy66,yymsp[-3].minor.yy70,yymsp[-2].minor.yy66,yymsp[-1].minor.yy70,yymsp[-7].minor.yy320,yymsp[0].minor.yy66);
}
break;
case 98: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
{
- yymsp[-9].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy402,yymsp[-6].minor.yy563,yymsp[-5].minor.yy590,yymsp[-4].minor.yy402,yymsp[-3].minor.yy590,yymsp[-1].minor.yy402,yymsp[-8].minor.yy502,yymsp[0].minor.yy590);
- if( yymsp[-9].minor.yy637 ){
- yymsp[-9].minor.yy637->pWinDefn = yymsp[-2].minor.yy483;
+ yymsp[-9].minor.yy599 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy70,yymsp[-6].minor.yy595,yymsp[-5].minor.yy66,yymsp[-4].minor.yy70,yymsp[-3].minor.yy66,yymsp[-1].minor.yy70,yymsp[-8].minor.yy320,yymsp[0].minor.yy66);
+ if( yymsp[-9].minor.yy599 ){
+ yymsp[-9].minor.yy599->pWinDefn = yymsp[-2].minor.yy255;
}else{
- sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy483);
+ sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy255);
}
}
break;
case 99: /* values ::= VALUES LP nexprlist RP */
{
- yymsp[-3].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy402,0,0,0,0,0,SF_Values,0);
+ yymsp[-3].minor.yy599 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy70,0,0,0,0,0,SF_Values,0);
}
break;
- case 100: /* values ::= values COMMA LP nexprlist RP */
+ case 100: /* oneselect ::= mvalues */
{
- Select *pRight, *pLeft = yymsp[-4].minor.yy637;
- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy402,0,0,0,0,0,SF_Values|SF_MultiValue,0);
- if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
- if( pRight ){
- pRight->op = TK_ALL;
- pRight->pPrior = pLeft;
- yymsp[-4].minor.yy637 = pRight;
- }else{
- yymsp[-4].minor.yy637 = pLeft;
- }
+ sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy599);
}
break;
- case 101: /* distinct ::= DISTINCT */
-{yymsp[0].minor.yy502 = SF_Distinct;}
+ case 101: /* mvalues ::= values COMMA LP nexprlist RP */
+ case 102: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==102);
+{
+ yymsp[-4].minor.yy599 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy599, yymsp[-1].minor.yy70);
+}
+ break;
+ case 103: /* distinct ::= DISTINCT */
+{yymsp[0].minor.yy320 = SF_Distinct;}
break;
- case 102: /* distinct ::= ALL */
-{yymsp[0].minor.yy502 = SF_All;}
+ case 104: /* distinct ::= ALL */
+{yymsp[0].minor.yy320 = SF_All;}
break;
- case 104: /* sclp ::= */
- case 137: /* orderby_opt ::= */ yytestcase(yyruleno==137);
- case 147: /* groupby_opt ::= */ yytestcase(yyruleno==147);
- case 237: /* exprlist ::= */ yytestcase(yyruleno==237);
- case 240: /* paren_exprlist ::= */ yytestcase(yyruleno==240);
- case 247: /* eidlist_opt ::= */ yytestcase(yyruleno==247);
-{yymsp[1].minor.yy402 = 0;}
+ case 106: /* sclp ::= */
+ case 139: /* orderby_opt ::= */ yytestcase(yyruleno==139);
+ case 149: /* groupby_opt ::= */ yytestcase(yyruleno==149);
+ case 239: /* exprlist ::= */ yytestcase(yyruleno==239);
+ case 242: /* paren_exprlist ::= */ yytestcase(yyruleno==242);
+ case 249: /* eidlist_opt ::= */ yytestcase(yyruleno==249);
+{yymsp[1].minor.yy70 = 0;}
break;
- case 105: /* selcollist ::= sclp scanpt expr scanpt as */
+ case 107: /* selcollist ::= sclp scanpt expr scanpt as */
{
- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy402, yymsp[-2].minor.yy590);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy402, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy402,yymsp[-3].minor.yy342,yymsp[-1].minor.yy342);
+ yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy66);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy70, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy70,yymsp[-3].minor.yy400,yymsp[-1].minor.yy400);
}
break;
- case 106: /* selcollist ::= sclp scanpt STAR */
+ case 108: /* selcollist ::= sclp scanpt STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
- yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy402, p);
+ yymsp[-2].minor.yy70 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy70, p);
}
break;
- case 107: /* selcollist ::= sclp scanpt nm DOT STAR */
+ case 109: /* selcollist ::= sclp scanpt nm DOT STAR */
{
Expr *pRight, *pLeft, *pDot;
pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, pDot);
+ yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy70, pDot);
}
break;
- case 108: /* as ::= AS nm */
- case 120: /* dbnm ::= DOT nm */ yytestcase(yyruleno==120);
- case 263: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==263);
- case 264: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==264);
+ case 110: /* as ::= AS nm */
+ case 122: /* dbnm ::= DOT nm */ yytestcase(yyruleno==122);
+ case 265: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==265);
+ case 266: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==266);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 110: /* from ::= */
- case 113: /* stl_prefix ::= */ yytestcase(yyruleno==113);
-{yymsp[1].minor.yy563 = 0;}
+ case 112: /* from ::= */
+ case 115: /* stl_prefix ::= */ yytestcase(yyruleno==115);
+{yymsp[1].minor.yy595 = 0;}
break;
- case 111: /* from ::= FROM seltablist */
+ case 113: /* from ::= FROM seltablist */
{
- yymsp[-1].minor.yy563 = yymsp[0].minor.yy563;
- sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy563);
+ yymsp[-1].minor.yy595 = yymsp[0].minor.yy595;
+ sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy595);
}
break;
- case 112: /* stl_prefix ::= seltablist joinop */
+ case 114: /* stl_prefix ::= seltablist joinop */
{
- if( ALWAYS(yymsp[-1].minor.yy563 && yymsp[-1].minor.yy563->nSrc>0) ) yymsp[-1].minor.yy563->a[yymsp[-1].minor.yy563->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy502;
+ if( ALWAYS(yymsp[-1].minor.yy595 && yymsp[-1].minor.yy595->nSrc>0) ) yymsp[-1].minor.yy595->a[yymsp[-1].minor.yy595->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy320;
}
break;
- case 114: /* seltablist ::= stl_prefix nm dbnm as on_using */
+ case 116: /* seltablist ::= stl_prefix nm dbnm as on_using */
{
- yymsp[-4].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy563,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421);
+ yymsp[-4].minor.yy595 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy595,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy497);
}
break;
- case 115: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
+ case 117: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
{
- yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy421);
- sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy563, &yymsp[-1].minor.yy0);
+ yymsp[-5].minor.yy595 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy595,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy497);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy595, &yymsp[-1].minor.yy0);
}
break;
- case 116: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
+ case 118: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
{
- yymsp[-7].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy563,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421);
- sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy563, yymsp[-3].minor.yy402);
+ yymsp[-7].minor.yy595 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy595,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy497);
+ sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy595, yymsp[-3].minor.yy70);
}
break;
- case 117: /* seltablist ::= stl_prefix LP select RP as on_using */
+ case 119: /* seltablist ::= stl_prefix LP select RP as on_using */
{
- yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy637,&yymsp[0].minor.yy421);
+ yymsp[-5].minor.yy595 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy595,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy599,&yymsp[0].minor.yy497);
}
break;
- case 118: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
+ case 120: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
{
- if( yymsp[-5].minor.yy563==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy421.pOn==0 && yymsp[0].minor.yy421.pUsing==0 ){
- yymsp[-5].minor.yy563 = yymsp[-3].minor.yy563;
- }else if( ALWAYS(yymsp[-3].minor.yy563!=0) && yymsp[-3].minor.yy563->nSrc==1 ){
- yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421);
- if( yymsp[-5].minor.yy563 ){
- SrcItem *pNew = &yymsp[-5].minor.yy563->a[yymsp[-5].minor.yy563->nSrc-1];
- SrcItem *pOld = yymsp[-3].minor.yy563->a;
+ if( yymsp[-5].minor.yy595==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy497.pOn==0 && yymsp[0].minor.yy497.pUsing==0 ){
+ yymsp[-5].minor.yy595 = yymsp[-3].minor.yy595;
+ }else if( ALWAYS(yymsp[-3].minor.yy595!=0) && yymsp[-3].minor.yy595->nSrc==1 ){
+ yymsp[-5].minor.yy595 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy595,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy497);
+ if( yymsp[-5].minor.yy595 ){
+ SrcItem *pNew = &yymsp[-5].minor.yy595->a[yymsp[-5].minor.yy595->nSrc-1];
+ SrcItem *pOld = yymsp[-3].minor.yy595->a;
+ assert( pOld->fg.fixedSchema==0 );
pNew->zName = pOld->zName;
- pNew->zDatabase = pOld->zDatabase;
- pNew->pSelect = pOld->pSelect;
- if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){
- pNew->fg.isNestedFrom = 1;
+ assert( pOld->fg.fixedSchema==0 );
+ if( pOld->fg.isSubquery ){
+ pNew->fg.isSubquery = 1;
+ pNew->u4.pSubq = pOld->u4.pSubq;
+ pOld->u4.pSubq = 0;
+ pOld->fg.isSubquery = 0;
+ assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 );
+ if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){
+ pNew->fg.isNestedFrom = 1;
+ }
+ }else{
+ pNew->u4.zDatabase = pOld->u4.zDatabase;
+ pOld->u4.zDatabase = 0;
}
if( pOld->fg.isTabFunc ){
pNew->u1.pFuncArg = pOld->u1.pFuncArg;
@@ -177728,157 +180709,156 @@ static YYACTIONTYPE yy_reduce(
pOld->fg.isTabFunc = 0;
pNew->fg.isTabFunc = 1;
}
- pOld->zName = pOld->zDatabase = 0;
- pOld->pSelect = 0;
+ pOld->zName = 0;
}
- sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy563);
+ sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy595);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy563);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy563,0,0,0,0,SF_NestedFrom,0);
- yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy421);
+ sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy595);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy595,0,0,0,0,SF_NestedFrom,0);
+ yymsp[-5].minor.yy595 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy595,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy497);
}
}
break;
- case 119: /* dbnm ::= */
- case 134: /* indexed_opt ::= */ yytestcase(yyruleno==134);
+ case 121: /* dbnm ::= */
+ case 136: /* indexed_opt ::= */ yytestcase(yyruleno==136);
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
break;
- case 121: /* fullname ::= nm */
+ case 123: /* fullname ::= nm */
{
- yylhsminor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
- if( IN_RENAME_OBJECT && yylhsminor.yy563 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy563->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy595 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy595 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy595->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[0].minor.yy563 = yylhsminor.yy563;
+ yymsp[0].minor.yy595 = yylhsminor.yy595;
break;
- case 122: /* fullname ::= nm DOT nm */
+ case 124: /* fullname ::= nm DOT nm */
{
- yylhsminor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
- if( IN_RENAME_OBJECT && yylhsminor.yy563 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy563->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy595 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy595 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy595->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[-2].minor.yy563 = yylhsminor.yy563;
+ yymsp[-2].minor.yy595 = yylhsminor.yy595;
break;
- case 123: /* xfullname ::= nm */
-{yymsp[0].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+ case 125: /* xfullname ::= nm */
+{yymsp[0].minor.yy595 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
break;
- case 124: /* xfullname ::= nm DOT nm */
-{yymsp[-2].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 126: /* xfullname ::= nm DOT nm */
+{yymsp[-2].minor.yy595 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 125: /* xfullname ::= nm DOT nm AS nm */
+ case 127: /* xfullname ::= nm DOT nm AS nm */
{
- yymsp[-4].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
- if( yymsp[-4].minor.yy563 ) yymsp[-4].minor.yy563->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-4].minor.yy595 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
+ if( yymsp[-4].minor.yy595 ) yymsp[-4].minor.yy595->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
- case 126: /* xfullname ::= nm AS nm */
+ case 128: /* xfullname ::= nm AS nm */
{
- yymsp[-2].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
- if( yymsp[-2].minor.yy563 ) yymsp[-2].minor.yy563->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-2].minor.yy595 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
+ if( yymsp[-2].minor.yy595 ) yymsp[-2].minor.yy595->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
- case 127: /* joinop ::= COMMA|JOIN */
-{ yymsp[0].minor.yy502 = JT_INNER; }
+ case 129: /* joinop ::= COMMA|JOIN */
+{ yymsp[0].minor.yy320 = JT_INNER; }
break;
- case 128: /* joinop ::= JOIN_KW JOIN */
-{yymsp[-1].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
+ case 130: /* joinop ::= JOIN_KW JOIN */
+{yymsp[-1].minor.yy320 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
break;
- case 129: /* joinop ::= JOIN_KW nm JOIN */
-{yymsp[-2].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
+ case 131: /* joinop ::= JOIN_KW nm JOIN */
+{yymsp[-2].minor.yy320 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
break;
- case 130: /* joinop ::= JOIN_KW nm nm JOIN */
-{yymsp[-3].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+ case 132: /* joinop ::= JOIN_KW nm nm JOIN */
+{yymsp[-3].minor.yy320 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
break;
- case 131: /* on_using ::= ON expr */
-{yymsp[-1].minor.yy421.pOn = yymsp[0].minor.yy590; yymsp[-1].minor.yy421.pUsing = 0;}
+ case 133: /* on_using ::= ON expr */
+{yymsp[-1].minor.yy497.pOn = yymsp[0].minor.yy66; yymsp[-1].minor.yy497.pUsing = 0;}
break;
- case 132: /* on_using ::= USING LP idlist RP */
-{yymsp[-3].minor.yy421.pOn = 0; yymsp[-3].minor.yy421.pUsing = yymsp[-1].minor.yy204;}
+ case 134: /* on_using ::= USING LP idlist RP */
+{yymsp[-3].minor.yy497.pOn = 0; yymsp[-3].minor.yy497.pUsing = yymsp[-1].minor.yy332;}
break;
- case 133: /* on_using ::= */
- case 246: /* indextype ::= */ yytestcase(yyruleno==246);
-{yymsp[1].minor.yy421.pOn = 0; yymsp[1].minor.yy421.pUsing = 0;}
+ case 135: /* on_using ::= */
+ case 248: /* indextype ::= */ yytestcase(yyruleno==248);
+{yymsp[1].minor.yy497.pOn = 0; yymsp[1].minor.yy497.pUsing = 0;}
break;
- case 135: /* indexed_by ::= INDEXED BY nm */
+ case 137: /* indexed_by ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 136: /* indexed_by ::= NOT INDEXED */
+ case 138: /* indexed_by ::= NOT INDEXED */
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
- case 138: /* orderby_opt ::= ORDER BY sortlist */
- case 148: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==148);
-{yymsp[-2].minor.yy402 = yymsp[0].minor.yy402;}
+ case 140: /* orderby_opt ::= ORDER BY sortlist */
+ case 150: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==150);
+{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;}
break;
- case 139: /* sortlist ::= sortlist COMMA expr sortorder nulls */
+ case 141: /* sortlist ::= sortlist COMMA expr sortorder nulls */
{
- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402,yymsp[-2].minor.yy590);
- sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy402,yymsp[-1].minor.yy502,yymsp[0].minor.yy502);
+ yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy70,yymsp[-2].minor.yy66);
+ sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy70,yymsp[-1].minor.yy320,yymsp[0].minor.yy320);
}
break;
- case 140: /* sortlist ::= expr sortorder nulls */
+ case 142: /* sortlist ::= expr sortorder nulls */
{
- yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy590); /*A-overwrites-Y*/
- sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy402,yymsp[-1].minor.yy502,yymsp[0].minor.yy502);
+ yymsp[-2].minor.yy70 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy66); /*A-overwrites-Y*/
+ sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy70,yymsp[-1].minor.yy320,yymsp[0].minor.yy320);
}
break;
- case 141: /* sortorder ::= ASC */
-{yymsp[0].minor.yy502 = SQLITE_SO_ASC;}
+ case 143: /* sortorder ::= ASC */
+{yymsp[0].minor.yy320 = SQLITE_SO_ASC;}
break;
- case 142: /* sortorder ::= DESC */
-{yymsp[0].minor.yy502 = SQLITE_SO_DESC;}
+ case 144: /* sortorder ::= DESC */
+{yymsp[0].minor.yy320 = SQLITE_SO_DESC;}
break;
- case 143: /* sortorder ::= */
- case 146: /* nulls ::= */ yytestcase(yyruleno==146);
-{yymsp[1].minor.yy502 = SQLITE_SO_UNDEFINED;}
+ case 145: /* sortorder ::= */
+ case 148: /* nulls ::= */ yytestcase(yyruleno==148);
+{yymsp[1].minor.yy320 = SQLITE_SO_UNDEFINED;}
break;
- case 144: /* nulls ::= NULLS FIRST */
-{yymsp[-1].minor.yy502 = SQLITE_SO_ASC;}
+ case 146: /* nulls ::= NULLS FIRST */
+{yymsp[-1].minor.yy320 = SQLITE_SO_ASC;}
break;
- case 145: /* nulls ::= NULLS LAST */
-{yymsp[-1].minor.yy502 = SQLITE_SO_DESC;}
+ case 147: /* nulls ::= NULLS LAST */
+{yymsp[-1].minor.yy320 = SQLITE_SO_DESC;}
break;
- case 149: /* having_opt ::= */
- case 151: /* limit_opt ::= */ yytestcase(yyruleno==151);
- case 156: /* where_opt ::= */ yytestcase(yyruleno==156);
- case 158: /* where_opt_ret ::= */ yytestcase(yyruleno==158);
- case 235: /* case_else ::= */ yytestcase(yyruleno==235);
- case 236: /* case_operand ::= */ yytestcase(yyruleno==236);
- case 257: /* vinto ::= */ yytestcase(yyruleno==257);
-{yymsp[1].minor.yy590 = 0;}
+ case 151: /* having_opt ::= */
+ case 153: /* limit_opt ::= */ yytestcase(yyruleno==153);
+ case 158: /* where_opt ::= */ yytestcase(yyruleno==158);
+ case 160: /* where_opt_ret ::= */ yytestcase(yyruleno==160);
+ case 237: /* case_else ::= */ yytestcase(yyruleno==237);
+ case 238: /* case_operand ::= */ yytestcase(yyruleno==238);
+ case 259: /* vinto ::= */ yytestcase(yyruleno==259);
+{yymsp[1].minor.yy66 = 0;}
break;
- case 150: /* having_opt ::= HAVING expr */
- case 157: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==157);
- case 159: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==159);
- case 234: /* case_else ::= ELSE expr */ yytestcase(yyruleno==234);
- case 256: /* vinto ::= INTO expr */ yytestcase(yyruleno==256);
-{yymsp[-1].minor.yy590 = yymsp[0].minor.yy590;}
+ case 152: /* having_opt ::= HAVING expr */
+ case 159: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==159);
+ case 161: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==161);
+ case 236: /* case_else ::= ELSE expr */ yytestcase(yyruleno==236);
+ case 258: /* vinto ::= INTO expr */ yytestcase(yyruleno==258);
+{yymsp[-1].minor.yy66 = yymsp[0].minor.yy66;}
break;
- case 152: /* limit_opt ::= LIMIT expr */
-{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy590,0);}
+ case 154: /* limit_opt ::= LIMIT expr */
+{yymsp[-1].minor.yy66 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy66,0);}
break;
- case 153: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);}
+ case 155: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yymsp[-3].minor.yy66 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy66,yymsp[0].minor.yy66);}
break;
- case 154: /* limit_opt ::= LIMIT expr COMMA expr */
-{yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy590,yymsp[-2].minor.yy590);}
+ case 156: /* limit_opt ::= LIMIT expr COMMA expr */
+{yymsp[-3].minor.yy66 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy66,yymsp[-2].minor.yy66);}
break;
- case 155: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
+ case 157: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy563, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy563,yymsp[0].minor.yy590,0,0);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy595, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy595,yymsp[0].minor.yy66,0,0);
}
break;
- case 160: /* where_opt_ret ::= RETURNING selcollist */
-{sqlite3AddReturning(pParse,yymsp[0].minor.yy402); yymsp[-1].minor.yy590 = 0;}
+ case 162: /* where_opt_ret ::= RETURNING selcollist */
+{sqlite3AddReturning(pParse,yymsp[0].minor.yy70); yymsp[-1].minor.yy66 = 0;}
break;
- case 161: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
-{sqlite3AddReturning(pParse,yymsp[0].minor.yy402); yymsp[-3].minor.yy590 = yymsp[-2].minor.yy590;}
+ case 163: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
+{sqlite3AddReturning(pParse,yymsp[0].minor.yy70); yymsp[-3].minor.yy66 = yymsp[-2].minor.yy66;}
break;
- case 162: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
+ case 164: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy563, &yymsp[-4].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy402,"set list");
- if( yymsp[-1].minor.yy563 ){
- SrcList *pFromClause = yymsp[-1].minor.yy563;
+ sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy595, &yymsp[-4].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy70,"set list");
+ if( yymsp[-1].minor.yy595 ){
+ SrcList *pFromClause = yymsp[-1].minor.yy595;
if( pFromClause->nSrc>1 ){
Select *pSubquery;
Token as;
@@ -177887,92 +180867,92 @@ static YYACTIONTYPE yy_reduce(
as.z = 0;
pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
}
- yymsp[-5].minor.yy563 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy563, pFromClause);
+ yymsp[-5].minor.yy595 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy595, pFromClause);
}
- sqlite3Update(pParse,yymsp[-5].minor.yy563,yymsp[-2].minor.yy402,yymsp[0].minor.yy590,yymsp[-6].minor.yy502,0,0,0);
+ sqlite3Update(pParse,yymsp[-5].minor.yy595,yymsp[-2].minor.yy70,yymsp[0].minor.yy66,yymsp[-6].minor.yy320,0,0,0);
}
break;
- case 163: /* setlist ::= setlist COMMA nm EQ expr */
+ case 165: /* setlist ::= setlist COMMA nm EQ expr */
{
- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy402, yymsp[0].minor.yy590);
- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, 1);
+ yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy70, yymsp[0].minor.yy66);
+ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy70, &yymsp[-2].minor.yy0, 1);
}
break;
- case 164: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+ case 166: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
{
- yymsp[-6].minor.yy402 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy402, yymsp[-3].minor.yy204, yymsp[0].minor.yy590);
+ yymsp[-6].minor.yy70 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy70, yymsp[-3].minor.yy332, yymsp[0].minor.yy66);
}
break;
- case 165: /* setlist ::= nm EQ expr */
+ case 167: /* setlist ::= nm EQ expr */
{
- yylhsminor.yy402 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy590);
- sqlite3ExprListSetName(pParse, yylhsminor.yy402, &yymsp[-2].minor.yy0, 1);
+ yylhsminor.yy70 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy66);
+ sqlite3ExprListSetName(pParse, yylhsminor.yy70, &yymsp[-2].minor.yy0, 1);
}
- yymsp[-2].minor.yy402 = yylhsminor.yy402;
+ yymsp[-2].minor.yy70 = yylhsminor.yy70;
break;
- case 166: /* setlist ::= LP idlist RP EQ expr */
+ case 168: /* setlist ::= LP idlist RP EQ expr */
{
- yymsp[-4].minor.yy402 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy204, yymsp[0].minor.yy590);
+ yymsp[-4].minor.yy70 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy332, yymsp[0].minor.yy66);
}
break;
- case 167: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ case 169: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
{
- sqlite3Insert(pParse, yymsp[-3].minor.yy563, yymsp[-1].minor.yy637, yymsp[-2].minor.yy204, yymsp[-5].minor.yy502, yymsp[0].minor.yy403);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy595, yymsp[-1].minor.yy599, yymsp[-2].minor.yy332, yymsp[-5].minor.yy320, yymsp[0].minor.yy186);
}
break;
- case 168: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
+ case 170: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
{
- sqlite3Insert(pParse, yymsp[-4].minor.yy563, 0, yymsp[-3].minor.yy204, yymsp[-6].minor.yy502, 0);
+ sqlite3Insert(pParse, yymsp[-4].minor.yy595, 0, yymsp[-3].minor.yy332, yymsp[-6].minor.yy320, 0);
}
break;
- case 169: /* upsert ::= */
-{ yymsp[1].minor.yy403 = 0; }
+ case 171: /* upsert ::= */
+{ yymsp[1].minor.yy186 = 0; }
break;
- case 170: /* upsert ::= RETURNING selcollist */
-{ yymsp[-1].minor.yy403 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy402); }
+ case 172: /* upsert ::= RETURNING selcollist */
+{ yymsp[-1].minor.yy186 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy70); }
break;
- case 171: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
-{ yymsp[-11].minor.yy403 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy402,yymsp[-6].minor.yy590,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590,yymsp[0].minor.yy403);}
+ case 173: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
+{ yymsp[-11].minor.yy186 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy70,yymsp[-6].minor.yy66,yymsp[-2].minor.yy70,yymsp[-1].minor.yy66,yymsp[0].minor.yy186);}
break;
- case 172: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
-{ yymsp[-8].minor.yy403 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy402,yymsp[-3].minor.yy590,0,0,yymsp[0].minor.yy403); }
+ case 174: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
+{ yymsp[-8].minor.yy186 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy70,yymsp[-3].minor.yy66,0,0,yymsp[0].minor.yy186); }
break;
- case 173: /* upsert ::= ON CONFLICT DO NOTHING returning */
-{ yymsp[-4].minor.yy403 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
+ case 175: /* upsert ::= ON CONFLICT DO NOTHING returning */
+{ yymsp[-4].minor.yy186 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
break;
- case 174: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
-{ yymsp[-7].minor.yy403 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590,0);}
+ case 176: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
+{ yymsp[-7].minor.yy186 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy70,yymsp[-1].minor.yy66,0);}
break;
- case 175: /* returning ::= RETURNING selcollist */
-{sqlite3AddReturning(pParse,yymsp[0].minor.yy402);}
+ case 177: /* returning ::= RETURNING selcollist */
+{sqlite3AddReturning(pParse,yymsp[0].minor.yy70);}
break;
- case 178: /* idlist_opt ::= */
-{yymsp[1].minor.yy204 = 0;}
+ case 180: /* idlist_opt ::= */
+{yymsp[1].minor.yy332 = 0;}
break;
- case 179: /* idlist_opt ::= LP idlist RP */
-{yymsp[-2].minor.yy204 = yymsp[-1].minor.yy204;}
+ case 181: /* idlist_opt ::= LP idlist RP */
+{yymsp[-2].minor.yy332 = yymsp[-1].minor.yy332;}
break;
- case 180: /* idlist ::= idlist COMMA nm */
-{yymsp[-2].minor.yy204 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy204,&yymsp[0].minor.yy0);}
+ case 182: /* idlist ::= idlist COMMA nm */
+{yymsp[-2].minor.yy332 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy332,&yymsp[0].minor.yy0);}
break;
- case 181: /* idlist ::= nm */
-{yymsp[0].minor.yy204 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+ case 183: /* idlist ::= nm */
+{yymsp[0].minor.yy332 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
- case 182: /* expr ::= LP expr RP */
-{yymsp[-2].minor.yy590 = yymsp[-1].minor.yy590;}
+ case 184: /* expr ::= LP expr RP */
+{yymsp[-2].minor.yy66 = yymsp[-1].minor.yy66;}
break;
- case 183: /* expr ::= ID|INDEXED|JOIN_KW */
-{yymsp[0].minor.yy590=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 185: /* expr ::= ID|INDEXED|JOIN_KW */
+{yymsp[0].minor.yy66=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 184: /* expr ::= nm DOT nm */
+ case 186: /* expr ::= nm DOT nm */
{
Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
- yylhsminor.yy590 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ yylhsminor.yy66 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
- yymsp[-2].minor.yy590 = yylhsminor.yy590;
+ yymsp[-2].minor.yy66 = yylhsminor.yy66;
break;
- case 185: /* expr ::= nm DOT nm DOT nm */
+ case 187: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
@@ -177981,27 +180961,27 @@ static YYACTIONTYPE yy_reduce(
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, 0, temp1);
}
- yylhsminor.yy590 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ yylhsminor.yy66 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
- yymsp[-4].minor.yy590 = yylhsminor.yy590;
+ yymsp[-4].minor.yy66 = yylhsminor.yy66;
break;
- case 186: /* term ::= NULL|FLOAT|BLOB */
- case 187: /* term ::= STRING */ yytestcase(yyruleno==187);
-{yymsp[0].minor.yy590=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 188: /* term ::= NULL|FLOAT|BLOB */
+ case 189: /* term ::= STRING */ yytestcase(yyruleno==189);
+{yymsp[0].minor.yy66=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 188: /* term ::= INTEGER */
+ case 190: /* term ::= INTEGER */
{
- yylhsminor.yy590 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
- if( yylhsminor.yy590 ) yylhsminor.yy590->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
+ yylhsminor.yy66 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+ if( yylhsminor.yy66 ) yylhsminor.yy66->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
}
- yymsp[0].minor.yy590 = yylhsminor.yy590;
+ yymsp[0].minor.yy66 = yylhsminor.yy66;
break;
- case 189: /* expr ::= VARIABLE */
+ case 191: /* expr ::= VARIABLE */
{
if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
u32 n = yymsp[0].minor.yy0.n;
- yymsp[0].minor.yy590 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy590, n);
+ yymsp[0].minor.yy66 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy66, n);
}else{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
@@ -178010,194 +180990,203 @@ static YYACTIONTYPE yy_reduce(
assert( t.n>=2 );
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
- yymsp[0].minor.yy590 = 0;
+ yymsp[0].minor.yy66 = 0;
}else{
- yymsp[0].minor.yy590 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
- if( yymsp[0].minor.yy590 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy590->iTable);
+ yymsp[0].minor.yy66 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+ if( yymsp[0].minor.yy66 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy66->iTable);
}
}
}
break;
- case 190: /* expr ::= expr COLLATE ID|STRING */
+ case 192: /* expr ::= expr COLLATE ID|STRING */
{
- yymsp[-2].minor.yy590 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy590, &yymsp[0].minor.yy0, 1);
+ yymsp[-2].minor.yy66 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy66, &yymsp[0].minor.yy0, 1);
}
break;
- case 191: /* expr ::= CAST LP expr AS typetoken RP */
+ case 193: /* expr ::= CAST LP expr AS typetoken RP */
{
- yymsp[-5].minor.yy590 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy590, yymsp[-3].minor.yy590, 0);
+ yymsp[-5].minor.yy66 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy66, yymsp[-3].minor.yy66, 0);
}
break;
- case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
+ case 194: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
{
- yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy502);
+ yylhsminor.yy66 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy70, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy320);
}
- yymsp[-4].minor.yy590 = yylhsminor.yy590;
+ yymsp[-4].minor.yy66 = yylhsminor.yy66;
break;
- case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
+ case 195: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
{
- yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy402, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy502);
- sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy590, yymsp[-1].minor.yy402);
+ yylhsminor.yy66 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy70, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy320);
+ sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy66, yymsp[-1].minor.yy70);
}
- yymsp[-7].minor.yy590 = yylhsminor.yy590;
+ yymsp[-7].minor.yy66 = yylhsminor.yy66;
break;
- case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
+ case 196: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
{
- yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
+ yylhsminor.yy66 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
- yymsp[-3].minor.yy590 = yylhsminor.yy590;
+ yymsp[-3].minor.yy66 = yylhsminor.yy66;
break;
- case 195: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
+ case 197: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
{
- yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy402, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy502);
- sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483);
+ yylhsminor.yy66 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy70, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy320);
+ sqlite3WindowAttach(pParse, yylhsminor.yy66, yymsp[0].minor.yy255);
}
- yymsp[-5].minor.yy590 = yylhsminor.yy590;
+ yymsp[-5].minor.yy66 = yylhsminor.yy66;
break;
- case 196: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
+ case 198: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
{
- yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy402, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy502);
- sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483);
- sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy590, yymsp[-2].minor.yy402);
+ yylhsminor.yy66 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy70, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy320);
+ sqlite3WindowAttach(pParse, yylhsminor.yy66, yymsp[0].minor.yy255);
+ sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy66, yymsp[-2].minor.yy70);
}
- yymsp[-8].minor.yy590 = yylhsminor.yy590;
+ yymsp[-8].minor.yy66 = yylhsminor.yy66;
break;
- case 197: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
+ case 199: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
{
- yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
- sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483);
+ yylhsminor.yy66 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
+ sqlite3WindowAttach(pParse, yylhsminor.yy66, yymsp[0].minor.yy255);
}
- yymsp[-4].minor.yy590 = yylhsminor.yy590;
+ yymsp[-4].minor.yy66 = yylhsminor.yy66;
break;
- case 198: /* term ::= CTIME_KW */
+ case 200: /* term ::= CTIME_KW */
{
- yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
+ yylhsminor.yy66 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
}
- yymsp[0].minor.yy590 = yylhsminor.yy590;
+ yymsp[0].minor.yy66 = yylhsminor.yy66;
break;
- case 199: /* expr ::= LP nexprlist COMMA expr RP */
+ case 201: /* expr ::= LP nexprlist COMMA expr RP */
{
- ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy402, yymsp[-1].minor.yy590);
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
- if( yymsp[-4].minor.yy590 ){
- yymsp[-4].minor.yy590->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy70, yymsp[-1].minor.yy66);
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( yymsp[-4].minor.yy66 ){
+ yymsp[-4].minor.yy66->x.pList = pList;
if( ALWAYS(pList->nExpr) ){
- yymsp[-4].minor.yy590->flags |= pList->a[0].pExpr->flags & EP_Propagate;
+ yymsp[-4].minor.yy66->flags |= pList->a[0].pExpr->flags & EP_Propagate;
}
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
break;
- case 200: /* expr ::= expr AND expr */
-{yymsp[-2].minor.yy590=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);}
+ case 202: /* expr ::= expr AND expr */
+{yymsp[-2].minor.yy66=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy66,yymsp[0].minor.yy66);}
break;
- case 201: /* expr ::= expr OR expr */
- case 202: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==202);
- case 203: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==203);
- case 204: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==204);
- case 205: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==205);
- case 206: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==206);
- case 207: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==207);
-{yymsp[-2].minor.yy590=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);}
+ case 203: /* expr ::= expr OR expr */
+ case 204: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==204);
+ case 205: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==205);
+ case 206: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==206);
+ case 207: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==207);
+ case 208: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==208);
+ case 209: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==209);
+{yymsp[-2].minor.yy66=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy66,yymsp[0].minor.yy66);}
break;
- case 208: /* likeop ::= NOT LIKE_KW|MATCH */
+ case 210: /* likeop ::= NOT LIKE_KW|MATCH */
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
break;
- case 209: /* expr ::= expr likeop expr */
+ case 211: /* expr ::= expr likeop expr */
{
ExprList *pList;
int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
yymsp[-1].minor.yy0.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy590);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy590);
- yymsp[-2].minor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
- if( bNot ) yymsp[-2].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy590, 0);
- if( yymsp[-2].minor.yy590 ) yymsp[-2].minor.yy590->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy66);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy66);
+ yymsp[-2].minor.yy66 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+ if( bNot ) yymsp[-2].minor.yy66 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy66, 0);
+ if( yymsp[-2].minor.yy66 ) yymsp[-2].minor.yy66->flags |= EP_InfixFunc;
}
break;
- case 210: /* expr ::= expr likeop expr ESCAPE expr */
+ case 212: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
yymsp[-3].minor.yy0.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy590);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy590);
- yymsp[-4].minor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
- if( bNot ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
- if( yymsp[-4].minor.yy590 ) yymsp[-4].minor.yy590->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy66);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy66);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy66);
+ yymsp[-4].minor.yy66 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
+ if( bNot ) yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy66, 0);
+ if( yymsp[-4].minor.yy66 ) yymsp[-4].minor.yy66->flags |= EP_InfixFunc;
}
break;
- case 211: /* expr ::= expr ISNULL|NOTNULL */
-{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy590,0);}
+ case 213: /* expr ::= expr ISNULL|NOTNULL */
+{yymsp[-1].minor.yy66 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy66,0);}
break;
- case 212: /* expr ::= expr NOT NULL */
-{yymsp[-2].minor.yy590 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy590,0);}
+ case 214: /* expr ::= expr NOT NULL */
+{yymsp[-2].minor.yy66 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy66,0);}
break;
- case 213: /* expr ::= expr IS expr */
+ case 215: /* expr ::= expr IS expr */
{
- yymsp[-2].minor.yy590 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-2].minor.yy590, TK_ISNULL);
+ yymsp[-2].minor.yy66 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy66,yymsp[0].minor.yy66);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy66, yymsp[-2].minor.yy66, TK_ISNULL);
}
break;
- case 214: /* expr ::= expr IS NOT expr */
+ case 216: /* expr ::= expr IS NOT expr */
{
- yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy590,yymsp[0].minor.yy590);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-3].minor.yy590, TK_NOTNULL);
+ yymsp[-3].minor.yy66 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy66,yymsp[0].minor.yy66);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy66, yymsp[-3].minor.yy66, TK_NOTNULL);
}
break;
- case 215: /* expr ::= expr IS NOT DISTINCT FROM expr */
+ case 217: /* expr ::= expr IS NOT DISTINCT FROM expr */
{
- yymsp[-5].minor.yy590 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy590,yymsp[0].minor.yy590);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-5].minor.yy590, TK_ISNULL);
+ yymsp[-5].minor.yy66 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy66,yymsp[0].minor.yy66);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy66, yymsp[-5].minor.yy66, TK_ISNULL);
}
break;
- case 216: /* expr ::= expr IS DISTINCT FROM expr */
+ case 218: /* expr ::= expr IS DISTINCT FROM expr */
{
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy590,yymsp[0].minor.yy590);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-4].minor.yy590, TK_NOTNULL);
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy66,yymsp[0].minor.yy66);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy66, yymsp[-4].minor.yy66, TK_NOTNULL);
}
break;
- case 217: /* expr ::= NOT expr */
- case 218: /* expr ::= BITNOT expr */ yytestcase(yyruleno==218);
-{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy590, 0);/*A-overwrites-B*/}
+ case 219: /* expr ::= NOT expr */
+ case 220: /* expr ::= BITNOT expr */ yytestcase(yyruleno==220);
+{yymsp[-1].minor.yy66 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy66, 0);/*A-overwrites-B*/}
break;
- case 219: /* expr ::= PLUS|MINUS expr */
+ case 221: /* expr ::= PLUS|MINUS expr */
{
- yymsp[-1].minor.yy590 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy590, 0);
- /*A-overwrites-B*/
+ Expr *p = yymsp[0].minor.yy66;
+ u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS);
+ assert( TK_UPLUS>TK_PLUS );
+ assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) );
+ if( p && p->op==TK_UPLUS ){
+ p->op = op;
+ yymsp[-1].minor.yy66 = p;
+ }else{
+ yymsp[-1].minor.yy66 = sqlite3PExpr(pParse, op, p, 0);
+ /*A-overwrites-B*/
+ }
}
break;
- case 220: /* expr ::= expr PTR expr */
+ case 222: /* expr ::= expr PTR expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy590);
- pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy590);
- yylhsminor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+ ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy66);
+ pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy66);
+ yylhsminor.yy66 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
}
- yymsp[-2].minor.yy590 = yylhsminor.yy590;
+ yymsp[-2].minor.yy66 = yylhsminor.yy66;
break;
- case 221: /* between_op ::= BETWEEN */
- case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
-{yymsp[0].minor.yy502 = 0;}
+ case 223: /* between_op ::= BETWEEN */
+ case 226: /* in_op ::= IN */ yytestcase(yyruleno==226);
+{yymsp[0].minor.yy320 = 0;}
break;
- case 223: /* expr ::= expr between_op expr AND expr */
+ case 225: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy590);
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy590, 0);
- if( yymsp[-4].minor.yy590 ){
- yymsp[-4].minor.yy590->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy66);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy66);
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy66, 0);
+ if( yymsp[-4].minor.yy66 ){
+ yymsp[-4].minor.yy66->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
+ if( yymsp[-3].minor.yy320 ) yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy66, 0);
}
break;
- case 226: /* expr ::= expr in_op LP exprlist RP */
+ case 228: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy402==0 ){
+ if( yymsp[-1].minor.yy70==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -178206,212 +181195,212 @@ static YYACTIONTYPE yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590);
- yymsp[-4].minor.yy590 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false");
- if( yymsp[-4].minor.yy590 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy590);
+ sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy66);
+ yymsp[-4].minor.yy66 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy320 ? "true" : "false");
+ if( yymsp[-4].minor.yy66 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy66);
}else{
- Expr *pRHS = yymsp[-1].minor.yy402->a[0].pExpr;
- if( yymsp[-1].minor.yy402->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy590->op!=TK_VECTOR ){
- yymsp[-1].minor.yy402->a[0].pExpr = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402);
+ Expr *pRHS = yymsp[-1].minor.yy70->a[0].pExpr;
+ if( yymsp[-1].minor.yy70->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy66->op!=TK_VECTOR ){
+ yymsp[-1].minor.yy70->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy70);
pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy590, pRHS);
- }else if( yymsp[-1].minor.yy402->nExpr==1 && pRHS->op==TK_SELECT ){
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pRHS->x.pSelect);
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy66, pRHS);
+ }else if( yymsp[-1].minor.yy70->nExpr==1 && pRHS->op==TK_SELECT ){
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy66, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy66, pRHS->x.pSelect);
pRHS->x.pSelect = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy70);
}else{
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0);
- if( yymsp[-4].minor.yy590==0 ){
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402);
- }else if( yymsp[-4].minor.yy590->pLeft->op==TK_VECTOR ){
- int nExpr = yymsp[-4].minor.yy590->pLeft->x.pList->nExpr;
- Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy402);
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy66, 0);
+ if( yymsp[-4].minor.yy66==0 ){
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy70);
+ }else if( yymsp[-4].minor.yy66->pLeft->op==TK_VECTOR ){
+ int nExpr = yymsp[-4].minor.yy66->pLeft->x.pList->nExpr;
+ Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy70);
if( pSelectRHS ){
parserDoubleLinkSelect(pParse, pSelectRHS);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pSelectRHS);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy66, pSelectRHS);
}
}else{
- yymsp[-4].minor.yy590->x.pList = yymsp[-1].minor.yy402;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy590);
+ yymsp[-4].minor.yy66->x.pList = yymsp[-1].minor.yy70;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy66);
}
}
- if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
+ if( yymsp[-3].minor.yy320 ) yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy66, 0);
}
}
break;
- case 227: /* expr ::= LP select RP */
+ case 229: /* expr ::= LP select RP */
{
- yymsp[-2].minor.yy590 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy590, yymsp[-1].minor.yy637);
+ yymsp[-2].minor.yy66 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy66, yymsp[-1].minor.yy599);
}
break;
- case 228: /* expr ::= expr in_op LP select RP */
+ case 230: /* expr ::= expr in_op LP select RP */
{
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, yymsp[-1].minor.yy637);
- if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy66, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy66, yymsp[-1].minor.yy599);
+ if( yymsp[-3].minor.yy320 ) yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy66, 0);
}
break;
- case 229: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ case 231: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
- if( yymsp[0].minor.yy402 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy402);
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pSelect);
- if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
+ if( yymsp[0].minor.yy70 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy70);
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy66, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy66, pSelect);
+ if( yymsp[-3].minor.yy320 ) yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy66, 0);
}
break;
- case 230: /* expr ::= EXISTS LP select RP */
+ case 232: /* expr ::= EXISTS LP select RP */
{
Expr *p;
- p = yymsp[-3].minor.yy590 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy637);
+ p = yymsp[-3].minor.yy66 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy599);
}
break;
- case 231: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 233: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy590, 0);
- if( yymsp[-4].minor.yy590 ){
- yymsp[-4].minor.yy590->x.pList = yymsp[-1].minor.yy590 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590) : yymsp[-2].minor.yy402;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy590);
+ yymsp[-4].minor.yy66 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy66, 0);
+ if( yymsp[-4].minor.yy66 ){
+ yymsp[-4].minor.yy66->x.pList = yymsp[-1].minor.yy66 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy70,yymsp[-1].minor.yy66) : yymsp[-2].minor.yy70;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy66);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy402);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy70);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy66);
}
}
break;
- case 232: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 234: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[-2].minor.yy590);
- yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[0].minor.yy590);
+ yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy70, yymsp[-2].minor.yy66);
+ yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy70, yymsp[0].minor.yy66);
}
break;
- case 233: /* case_exprlist ::= WHEN expr THEN expr */
+ case 235: /* case_exprlist ::= WHEN expr THEN expr */
{
- yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590);
- yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy402, yymsp[0].minor.yy590);
+ yymsp[-3].minor.yy70 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy66);
+ yymsp[-3].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy70, yymsp[0].minor.yy66);
}
break;
- case 238: /* nexprlist ::= nexprlist COMMA expr */
-{yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[0].minor.yy590);}
+ case 240: /* nexprlist ::= nexprlist COMMA expr */
+{yymsp[-2].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy70,yymsp[0].minor.yy66);}
break;
- case 239: /* nexprlist ::= expr */
-{yymsp[0].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy590); /*A-overwrites-Y*/}
+ case 241: /* nexprlist ::= expr */
+{yymsp[0].minor.yy70 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy66); /*A-overwrites-Y*/}
break;
- case 241: /* paren_exprlist ::= LP exprlist RP */
- case 248: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==248);
-{yymsp[-2].minor.yy402 = yymsp[-1].minor.yy402;}
+ case 243: /* paren_exprlist ::= LP exprlist RP */
+ case 250: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==250);
+{yymsp[-2].minor.yy70 = yymsp[-1].minor.yy70;}
break;
- case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm indextype ON nm LP sortlist RP where_opt */
+ case 244: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm indextype ON nm LP sortlist RP where_opt */
{
u8 idxType = SQLITE_IDXTYPE_APPDEF;
sqlite3CreateIndex(pParse, &yymsp[-8].minor.yy0, &yymsp[-7].minor.yy0,
- sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy402, yymsp[-11].minor.yy502,
- &yymsp[-12].minor.yy0, yymsp[0].minor.yy590, SQLITE_SO_ASC, yymsp[-9].minor.yy502, idxType, yymsp[-6].minor.yy421.pUsing);
+ sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy70, yymsp[-11].minor.yy320,
+ &yymsp[-12].minor.yy0, yymsp[0].minor.yy66, SQLITE_SO_ASC, yymsp[-9].minor.yy320, idxType, yymsp[-6].minor.yy497.pUsing);
if( IN_RENAME_OBJECT && pParse->pNewIndex ){
sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
}
}
break;
- case 243: /* uniqueflag ::= UNIQUE */
- case 287: /* raisetype ::= ABORT */ yytestcase(yyruleno==287);
-{yymsp[0].minor.yy502 = OE_Abort;}
+ case 245: /* uniqueflag ::= UNIQUE */
+ case 289: /* raisetype ::= ABORT */ yytestcase(yyruleno==289);
+{yymsp[0].minor.yy320 = OE_Abort;}
break;
- case 244: /* uniqueflag ::= */
-{yymsp[1].minor.yy502 = OE_None;}
+ case 246: /* uniqueflag ::= */
+{yymsp[1].minor.yy320 = OE_None;}
break;
- case 245: /* indextype ::= USING idlist */
-{yymsp[-1].minor.yy421.pOn = 0; yymsp[-1].minor.yy421.pUsing = yymsp[0].minor.yy204;}
+ case 247: /* indextype ::= USING idlist */
+{yymsp[-1].minor.yy497.pOn = 0; yymsp[-1].minor.yy497.pUsing = yymsp[0].minor.yy332;}
break;
- case 249: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ case 251: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
- yymsp[-4].minor.yy402 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502);
+ yymsp[-4].minor.yy70 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy70, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy320, yymsp[0].minor.yy320);
}
break;
- case 250: /* eidlist ::= nm collate sortorder */
+ case 252: /* eidlist ::= nm collate sortorder */
{
- yymsp[-2].minor.yy402 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502); /*A-overwrites-Y*/
+ yymsp[-2].minor.yy70 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy320, yymsp[0].minor.yy320); /*A-overwrites-Y*/
}
break;
- case 253: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy563, yymsp[-1].minor.yy502);}
+ case 255: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy595, yymsp[-1].minor.yy320);}
break;
- case 254: /* cmd ::= VACUUM vinto */
-{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy590);}
+ case 256: /* cmd ::= VACUUM vinto */
+{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy66);}
break;
- case 255: /* cmd ::= VACUUM nm vinto */
-{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy590);}
+ case 257: /* cmd ::= VACUUM nm vinto */
+{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy66);}
break;
- case 258: /* cmd ::= PRAGMA nm dbnm */
+ case 260: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 259: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 261: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 260: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 262: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 261: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 263: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 262: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 264: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
- case 265: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 267: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy319, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy243, &all);
}
break;
- case 266: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 268: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy502, yymsp[-4].minor.yy28.a, yymsp[-4].minor.yy28.b, yymsp[-2].minor.yy563, yymsp[0].minor.yy590, yymsp[-10].minor.yy502, yymsp[-8].minor.yy502);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy320, yymsp[-4].minor.yy158.a, yymsp[-4].minor.yy158.b, yymsp[-2].minor.yy595, yymsp[0].minor.yy66, yymsp[-10].minor.yy320, yymsp[-8].minor.yy320);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 267: /* trigger_time ::= BEFORE|AFTER */
-{ yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/ }
+ case 269: /* trigger_time ::= BEFORE|AFTER */
+{ yymsp[0].minor.yy320 = yymsp[0].major; /*A-overwrites-X*/ }
break;
- case 268: /* trigger_time ::= INSTEAD OF */
-{ yymsp[-1].minor.yy502 = TK_INSTEAD;}
+ case 270: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy320 = TK_INSTEAD;}
break;
- case 269: /* trigger_time ::= */
-{ yymsp[1].minor.yy502 = TK_BEFORE; }
+ case 271: /* trigger_time ::= */
+{ yymsp[1].minor.yy320 = TK_BEFORE; }
break;
- case 270: /* trigger_event ::= DELETE|INSERT */
- case 271: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==271);
-{yymsp[0].minor.yy28.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy28.b = 0;}
+ case 272: /* trigger_event ::= DELETE|INSERT */
+ case 273: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==273);
+{yymsp[0].minor.yy158.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy158.b = 0;}
break;
- case 272: /* trigger_event ::= UPDATE OF idlist */
-{yymsp[-2].minor.yy28.a = TK_UPDATE; yymsp[-2].minor.yy28.b = yymsp[0].minor.yy204;}
+ case 274: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy158.a = TK_UPDATE; yymsp[-2].minor.yy158.b = yymsp[0].minor.yy332;}
break;
- case 273: /* when_clause ::= */
- case 292: /* key_opt ::= */ yytestcase(yyruleno==292);
-{ yymsp[1].minor.yy590 = 0; }
+ case 275: /* when_clause ::= */
+ case 294: /* key_opt ::= */ yytestcase(yyruleno==294);
+{ yymsp[1].minor.yy66 = 0; }
break;
- case 274: /* when_clause ::= WHEN expr */
- case 293: /* key_opt ::= KEY expr */ yytestcase(yyruleno==293);
-{ yymsp[-1].minor.yy590 = yymsp[0].minor.yy590; }
+ case 276: /* when_clause ::= WHEN expr */
+ case 295: /* key_opt ::= KEY expr */ yytestcase(yyruleno==295);
+{ yymsp[-1].minor.yy66 = yymsp[0].minor.yy66; }
break;
- case 275: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 277: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
- assert( yymsp[-2].minor.yy319!=0 );
- yymsp[-2].minor.yy319->pLast->pNext = yymsp[-1].minor.yy319;
- yymsp[-2].minor.yy319->pLast = yymsp[-1].minor.yy319;
+ assert( yymsp[-2].minor.yy243!=0 );
+ yymsp[-2].minor.yy243->pLast->pNext = yymsp[-1].minor.yy243;
+ yymsp[-2].minor.yy243->pLast = yymsp[-1].minor.yy243;
}
break;
- case 276: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 278: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy319!=0 );
- yymsp[-1].minor.yy319->pLast = yymsp[-1].minor.yy319;
+ assert( yymsp[-1].minor.yy243!=0 );
+ yymsp[-1].minor.yy243->pLast = yymsp[-1].minor.yy243;
}
break;
- case 277: /* trnm ::= nm DOT nm */
+ case 279: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -178419,373 +181408,383 @@ static YYACTIONTYPE yy_reduce(
"statements within triggers");
}
break;
- case 278: /* tridxby ::= INDEXED BY nm */
+ case 280: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 279: /* tridxby ::= NOT INDEXED */
+ case 281: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 280: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
-{yylhsminor.yy319 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy563, yymsp[-3].minor.yy402, yymsp[-1].minor.yy590, yymsp[-7].minor.yy502, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy342);}
- yymsp[-8].minor.yy319 = yylhsminor.yy319;
+ case 282: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+{yylhsminor.yy243 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy595, yymsp[-3].minor.yy70, yymsp[-1].minor.yy66, yymsp[-7].minor.yy320, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy400);}
+ yymsp[-8].minor.yy243 = yylhsminor.yy243;
break;
- case 281: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ case 283: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
{
- yylhsminor.yy319 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy204,yymsp[-2].minor.yy637,yymsp[-6].minor.yy502,yymsp[-1].minor.yy403,yymsp[-7].minor.yy342,yymsp[0].minor.yy342);/*yylhsminor.yy319-overwrites-yymsp[-6].minor.yy502*/
+ yylhsminor.yy243 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy332,yymsp[-2].minor.yy599,yymsp[-6].minor.yy320,yymsp[-1].minor.yy186,yymsp[-7].minor.yy400,yymsp[0].minor.yy400);/*yylhsminor.yy243-overwrites-yymsp[-6].minor.yy320*/
}
- yymsp[-7].minor.yy319 = yylhsminor.yy319;
+ yymsp[-7].minor.yy243 = yylhsminor.yy243;
break;
- case 282: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
-{yylhsminor.yy319 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy590, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy342);}
- yymsp[-5].minor.yy319 = yylhsminor.yy319;
+ case 284: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+{yylhsminor.yy243 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy66, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy400);}
+ yymsp[-5].minor.yy243 = yylhsminor.yy243;
break;
- case 283: /* trigger_cmd ::= scanpt select scanpt */
-{yylhsminor.yy319 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy637, yymsp[-2].minor.yy342, yymsp[0].minor.yy342); /*yylhsminor.yy319-overwrites-yymsp[-1].minor.yy637*/}
- yymsp[-2].minor.yy319 = yylhsminor.yy319;
+ case 285: /* trigger_cmd ::= scanpt select scanpt */
+{yylhsminor.yy243 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy599, yymsp[-2].minor.yy400, yymsp[0].minor.yy400); /*yylhsminor.yy243-overwrites-yymsp[-1].minor.yy599*/}
+ yymsp[-2].minor.yy243 = yylhsminor.yy243;
break;
- case 284: /* expr ::= RAISE LP IGNORE RP */
+ case 286: /* expr ::= RAISE LP IGNORE RP */
{
- yymsp[-3].minor.yy590 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
- if( yymsp[-3].minor.yy590 ){
- yymsp[-3].minor.yy590->affExpr = OE_Ignore;
+ yymsp[-3].minor.yy66 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
+ if( yymsp[-3].minor.yy66 ){
+ yymsp[-3].minor.yy66->affExpr = OE_Ignore;
}
}
break;
- case 285: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 287: /* expr ::= RAISE LP raisetype COMMA expr RP */
{
- yymsp[-5].minor.yy590 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
- if( yymsp[-5].minor.yy590 ) {
- yymsp[-5].minor.yy590->affExpr = (char)yymsp[-3].minor.yy502;
+ yymsp[-5].minor.yy66 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy66, 0);
+ if( yymsp[-5].minor.yy66 ) {
+ yymsp[-5].minor.yy66->affExpr = (char)yymsp[-3].minor.yy320;
}
}
break;
- case 286: /* raisetype ::= ROLLBACK */
-{yymsp[0].minor.yy502 = OE_Rollback;}
+ case 288: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy320 = OE_Rollback;}
break;
- case 288: /* raisetype ::= FAIL */
-{yymsp[0].minor.yy502 = OE_Fail;}
+ case 290: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy320 = OE_Fail;}
break;
- case 289: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 291: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy563,yymsp[-1].minor.yy502);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy595,yymsp[-1].minor.yy320);
}
break;
- case 290: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 292: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy590, yymsp[-1].minor.yy590, yymsp[0].minor.yy590);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy66, yymsp[-1].minor.yy66, yymsp[0].minor.yy66);
}
break;
- case 291: /* cmd ::= DETACH database_kw_opt expr */
+ case 293: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy590);
+ sqlite3Detach(pParse, yymsp[0].minor.yy66);
}
break;
- case 294: /* cmd ::= REINDEX */
+ case 296: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 295: /* cmd ::= REINDEX nm dbnm */
+ case 297: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 296: /* cmd ::= ANALYZE */
+ case 298: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 297: /* cmd ::= ANALYZE nm dbnm */
+ case 299: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 298: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 300: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy563,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy595,&yymsp[0].minor.yy0);
}
break;
- case 299: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 301: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
break;
- case 300: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+ case 302: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
{
- sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy563, &yymsp[0].minor.yy0);
+ sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy595, &yymsp[0].minor.yy0);
}
break;
- case 301: /* add_column_fullname ::= fullname */
+ case 303: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy563);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy595);
}
break;
- case 302: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ case 304: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
- sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy563, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
+ sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy595, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 303: /* cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */
+ case 305: /* cmd ::= ALTER TABLE fullname ALTER COLUMNKW columnname TO columnname carglist */
{
int definitionLength = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
- libsqlAlterAlterColumn(pParse, yymsp[-6].minor.yy563, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, definitionLength);
+ libsqlAlterAlterColumn(pParse, yymsp[-6].minor.yy595, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, definitionLength);
}
break;
- case 304: /* cmd ::= create_vtab */
+ case 306: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 305: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 307: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 306: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 308: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
- sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy502);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy320);
}
break;
- case 307: /* vtabarg ::= */
+ case 309: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 308: /* vtabargtoken ::= ANY */
- case 309: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==309);
- case 310: /* lp ::= LP */ yytestcase(yyruleno==310);
+ case 310: /* vtabargtoken ::= ANY */
+ case 311: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==311);
+ case 312: /* lp ::= LP */ yytestcase(yyruleno==312);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 311: /* with ::= WITH wqlist */
- case 312: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==312);
-{ sqlite3WithPush(pParse, yymsp[0].minor.yy125, 1); }
+ case 313: /* with ::= WITH wqlist */
+ case 314: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==314);
+{ sqlite3WithPush(pParse, yymsp[0].minor.yy523, 1); }
break;
- case 313: /* wqas ::= AS */
-{yymsp[0].minor.yy444 = M10d_Any;}
+ case 315: /* wqas ::= AS */
+{yymsp[0].minor.yy390 = M10d_Any;}
break;
- case 314: /* wqas ::= AS MATERIALIZED */
-{yymsp[-1].minor.yy444 = M10d_Yes;}
+ case 316: /* wqas ::= AS MATERIALIZED */
+{yymsp[-1].minor.yy390 = M10d_Yes;}
break;
- case 315: /* wqas ::= AS NOT MATERIALIZED */
-{yymsp[-2].minor.yy444 = M10d_No;}
+ case 317: /* wqas ::= AS NOT MATERIALIZED */
+{yymsp[-2].minor.yy390 = M10d_No;}
break;
- case 316: /* wqitem ::= nm eidlist_opt wqas LP select RP */
+ case 318: /* wqitem ::= withnm eidlist_opt wqas LP select RP */
{
- yymsp[-5].minor.yy361 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy402, yymsp[-1].minor.yy637, yymsp[-3].minor.yy444); /*A-overwrites-X*/
+ yymsp[-5].minor.yy487 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy70, yymsp[-1].minor.yy599, yymsp[-3].minor.yy390); /*A-overwrites-X*/
}
break;
- case 317: /* wqlist ::= wqitem */
+ case 319: /* withnm ::= nm */
+{pParse->bHasWith = 1;}
+ break;
+ case 320: /* wqlist ::= wqitem */
{
- yymsp[0].minor.yy125 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy361); /*A-overwrites-X*/
+ yymsp[0].minor.yy523 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy487); /*A-overwrites-X*/
}
break;
- case 318: /* wqlist ::= wqlist COMMA wqitem */
+ case 321: /* wqlist ::= wqlist COMMA wqitem */
{
- yymsp[-2].minor.yy125 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy125, yymsp[0].minor.yy361);
+ yymsp[-2].minor.yy523 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy523, yymsp[0].minor.yy487);
}
break;
- case 319: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ case 322: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
- assert( yymsp[0].minor.yy483!=0 );
- sqlite3WindowChain(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy483);
- yymsp[0].minor.yy483->pNextWin = yymsp[-2].minor.yy483;
- yylhsminor.yy483 = yymsp[0].minor.yy483;
+ assert( yymsp[0].minor.yy255!=0 );
+ sqlite3WindowChain(pParse, yymsp[0].minor.yy255, yymsp[-2].minor.yy255);
+ yymsp[0].minor.yy255->pNextWin = yymsp[-2].minor.yy255;
+ yylhsminor.yy255 = yymsp[0].minor.yy255;
}
- yymsp[-2].minor.yy483 = yylhsminor.yy483;
+ yymsp[-2].minor.yy255 = yylhsminor.yy255;
break;
- case 320: /* windowdefn ::= nm AS LP window RP */
+ case 323: /* windowdefn ::= nm AS LP window RP */
{
- if( ALWAYS(yymsp[-1].minor.yy483) ){
- yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
+ if( ALWAYS(yymsp[-1].minor.yy255) ){
+ yymsp[-1].minor.yy255->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
}
- yylhsminor.yy483 = yymsp[-1].minor.yy483;
+ yylhsminor.yy255 = yymsp[-1].minor.yy255;
}
- yymsp[-4].minor.yy483 = yylhsminor.yy483;
+ yymsp[-4].minor.yy255 = yylhsminor.yy255;
break;
- case 321: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ case 324: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
{
- yymsp[-4].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, 0);
+ yymsp[-4].minor.yy255 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy255, yymsp[-2].minor.yy70, yymsp[-1].minor.yy70, 0);
}
break;
- case 322: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ case 325: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
{
- yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, &yymsp[-5].minor.yy0);
+ yylhsminor.yy255 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy255, yymsp[-2].minor.yy70, yymsp[-1].minor.yy70, &yymsp[-5].minor.yy0);
}
- yymsp[-5].minor.yy483 = yylhsminor.yy483;
+ yymsp[-5].minor.yy255 = yylhsminor.yy255;
break;
- case 323: /* window ::= ORDER BY sortlist frame_opt */
+ case 326: /* window ::= ORDER BY sortlist frame_opt */
{
- yymsp[-3].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, 0);
+ yymsp[-3].minor.yy255 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy255, 0, yymsp[-1].minor.yy70, 0);
}
break;
- case 324: /* window ::= nm ORDER BY sortlist frame_opt */
+ case 327: /* window ::= nm ORDER BY sortlist frame_opt */
{
- yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0);
+ yylhsminor.yy255 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy255, 0, yymsp[-1].minor.yy70, &yymsp[-4].minor.yy0);
}
- yymsp[-4].minor.yy483 = yylhsminor.yy483;
+ yymsp[-4].minor.yy255 = yylhsminor.yy255;
break;
- case 325: /* window ::= nm frame_opt */
+ case 328: /* window ::= nm frame_opt */
{
- yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, 0, &yymsp[-1].minor.yy0);
+ yylhsminor.yy255 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy255, 0, 0, &yymsp[-1].minor.yy0);
}
- yymsp[-1].minor.yy483 = yylhsminor.yy483;
+ yymsp[-1].minor.yy255 = yylhsminor.yy255;
break;
- case 326: /* frame_opt ::= */
+ case 329: /* frame_opt ::= */
{
- yymsp[1].minor.yy483 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
+ yymsp[1].minor.yy255 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
break;
- case 327: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ case 330: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
{
- yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy502, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy444);
+ yylhsminor.yy255 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy320, yymsp[-1].minor.yy417.eType, yymsp[-1].minor.yy417.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy390);
}
- yymsp[-2].minor.yy483 = yylhsminor.yy483;
+ yymsp[-2].minor.yy255 = yylhsminor.yy255;
break;
- case 328: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ case 331: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
{
- yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy502, yymsp[-3].minor.yy205.eType, yymsp[-3].minor.yy205.pExpr, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, yymsp[0].minor.yy444);
+ yylhsminor.yy255 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy320, yymsp[-3].minor.yy417.eType, yymsp[-3].minor.yy417.pExpr, yymsp[-1].minor.yy417.eType, yymsp[-1].minor.yy417.pExpr, yymsp[0].minor.yy390);
}
- yymsp[-5].minor.yy483 = yylhsminor.yy483;
+ yymsp[-5].minor.yy255 = yylhsminor.yy255;
break;
- case 330: /* frame_bound_s ::= frame_bound */
- case 332: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==332);
-{yylhsminor.yy205 = yymsp[0].minor.yy205;}
- yymsp[0].minor.yy205 = yylhsminor.yy205;
+ case 333: /* frame_bound_s ::= frame_bound */
+ case 335: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==335);
+{yylhsminor.yy417 = yymsp[0].minor.yy417;}
+ yymsp[0].minor.yy417 = yylhsminor.yy417;
break;
- case 331: /* frame_bound_s ::= UNBOUNDED PRECEDING */
- case 333: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==333);
- case 335: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==335);
-{yylhsminor.yy205.eType = yymsp[-1].major; yylhsminor.yy205.pExpr = 0;}
- yymsp[-1].minor.yy205 = yylhsminor.yy205;
+ case 334: /* frame_bound_s ::= UNBOUNDED PRECEDING */
+ case 336: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==336);
+ case 338: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==338);
+{yylhsminor.yy417.eType = yymsp[-1].major; yylhsminor.yy417.pExpr = 0;}
+ yymsp[-1].minor.yy417 = yylhsminor.yy417;
break;
- case 334: /* frame_bound ::= expr PRECEDING|FOLLOWING */
-{yylhsminor.yy205.eType = yymsp[0].major; yylhsminor.yy205.pExpr = yymsp[-1].minor.yy590;}
- yymsp[-1].minor.yy205 = yylhsminor.yy205;
+ case 337: /* frame_bound ::= expr PRECEDING|FOLLOWING */
+{yylhsminor.yy417.eType = yymsp[0].major; yylhsminor.yy417.pExpr = yymsp[-1].minor.yy66;}
+ yymsp[-1].minor.yy417 = yylhsminor.yy417;
break;
- case 336: /* frame_exclude_opt ::= */
-{yymsp[1].minor.yy444 = 0;}
+ case 339: /* frame_exclude_opt ::= */
+{yymsp[1].minor.yy390 = 0;}
break;
- case 337: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
-{yymsp[-1].minor.yy444 = yymsp[0].minor.yy444;}
+ case 340: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
+{yymsp[-1].minor.yy390 = yymsp[0].minor.yy390;}
break;
- case 338: /* frame_exclude ::= NO OTHERS */
- case 339: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==339);
-{yymsp[-1].minor.yy444 = yymsp[-1].major; /*A-overwrites-X*/}
+ case 341: /* frame_exclude ::= NO OTHERS */
+ case 342: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==342);
+{yymsp[-1].minor.yy390 = yymsp[-1].major; /*A-overwrites-X*/}
break;
- case 340: /* frame_exclude ::= GROUP|TIES */
-{yymsp[0].minor.yy444 = yymsp[0].major; /*A-overwrites-X*/}
+ case 343: /* frame_exclude ::= GROUP|TIES */
+{yymsp[0].minor.yy390 = yymsp[0].major; /*A-overwrites-X*/}
break;
- case 341: /* window_clause ::= WINDOW windowdefn_list */
-{ yymsp[-1].minor.yy483 = yymsp[0].minor.yy483; }
+ case 344: /* window_clause ::= WINDOW windowdefn_list */
+{ yymsp[-1].minor.yy255 = yymsp[0].minor.yy255; }
break;
- case 342: /* filter_over ::= filter_clause over_clause */
+ case 345: /* filter_over ::= filter_clause over_clause */
{
- if( yymsp[0].minor.yy483 ){
- yymsp[0].minor.yy483->pFilter = yymsp[-1].minor.yy590;
+ if( yymsp[0].minor.yy255 ){
+ yymsp[0].minor.yy255->pFilter = yymsp[-1].minor.yy66;
}else{
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy66);
}
- yylhsminor.yy483 = yymsp[0].minor.yy483;
+ yylhsminor.yy255 = yymsp[0].minor.yy255;
}
- yymsp[-1].minor.yy483 = yylhsminor.yy483;
+ yymsp[-1].minor.yy255 = yylhsminor.yy255;
break;
- case 343: /* filter_over ::= over_clause */
+ case 346: /* filter_over ::= over_clause */
{
- yylhsminor.yy483 = yymsp[0].minor.yy483;
+ yylhsminor.yy255 = yymsp[0].minor.yy255;
}
- yymsp[0].minor.yy483 = yylhsminor.yy483;
+ yymsp[0].minor.yy255 = yylhsminor.yy255;
break;
- case 344: /* filter_over ::= filter_clause */
+ case 347: /* filter_over ::= filter_clause */
{
- yylhsminor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( yylhsminor.yy483 ){
- yylhsminor.yy483->eFrmType = TK_FILTER;
- yylhsminor.yy483->pFilter = yymsp[0].minor.yy590;
+ yylhsminor.yy255 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( yylhsminor.yy255 ){
+ yylhsminor.yy255->eFrmType = TK_FILTER;
+ yylhsminor.yy255->pFilter = yymsp[0].minor.yy66;
}else{
- sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy590);
+ sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy66);
}
}
- yymsp[0].minor.yy483 = yylhsminor.yy483;
+ yymsp[0].minor.yy255 = yylhsminor.yy255;
break;
- case 345: /* over_clause ::= OVER LP window RP */
+ case 348: /* over_clause ::= OVER LP window RP */
{
- yymsp[-3].minor.yy483 = yymsp[-1].minor.yy483;
- assert( yymsp[-3].minor.yy483!=0 );
+ yymsp[-3].minor.yy255 = yymsp[-1].minor.yy255;
+ assert( yymsp[-3].minor.yy255!=0 );
}
break;
- case 346: /* over_clause ::= OVER nm */
+ case 349: /* over_clause ::= OVER nm */
{
- yymsp[-1].minor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( yymsp[-1].minor.yy483 ){
- yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
+ yymsp[-1].minor.yy255 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( yymsp[-1].minor.yy255 ){
+ yymsp[-1].minor.yy255->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
}
}
break;
- case 347: /* filter_clause ::= FILTER LP WHERE expr RP */
-{ yymsp[-4].minor.yy590 = yymsp[-1].minor.yy590; }
+ case 350: /* filter_clause ::= FILTER LP WHERE expr RP */
+{ yymsp[-4].minor.yy66 = yymsp[-1].minor.yy66; }
+ break;
+ case 351: /* term ::= QNUMBER */
+{
+ yylhsminor.yy66=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0);
+ sqlite3DequoteNumber(pParse, yylhsminor.yy66);
+}
+ yymsp[0].minor.yy66 = yylhsminor.yy66;
break;
default:
- /* (348) input ::= cmdlist */ yytestcase(yyruleno==348);
- /* (349) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==349);
- /* (350) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=350);
- /* (351) ecmd ::= SEMI */ yytestcase(yyruleno==351);
- /* (352) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==352);
- /* (353) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=353);
- /* (354) trans_opt ::= */ yytestcase(yyruleno==354);
- /* (355) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==355);
- /* (356) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==356);
- /* (357) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==357);
- /* (358) savepoint_opt ::= */ yytestcase(yyruleno==358);
- /* (359) cmd ::= create_table create_table_args */ yytestcase(yyruleno==359);
- /* (360) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=360);
- /* (361) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==361);
- /* (362) columnlist ::= columnname carglist */ yytestcase(yyruleno==362);
- /* (363) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==363);
- /* (364) nm ::= STRING */ yytestcase(yyruleno==364);
- /* (365) typetoken ::= typename */ yytestcase(yyruleno==365);
- /* (366) typename ::= ID|STRING */ yytestcase(yyruleno==366);
- /* (367) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=367);
- /* (368) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=368);
- /* (369) carglist ::= carglist ccons */ yytestcase(yyruleno==369);
- /* (370) carglist ::= */ yytestcase(yyruleno==370);
- /* (371) ccons ::= NULL onconf */ yytestcase(yyruleno==371);
- /* (372) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==372);
- /* (373) ccons ::= AS generated */ yytestcase(yyruleno==373);
- /* (374) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==374);
- /* (375) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==375);
- /* (376) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=376);
- /* (377) tconscomma ::= */ yytestcase(yyruleno==377);
- /* (378) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=378);
- /* (379) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=379);
- /* (380) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=380);
- /* (381) oneselect ::= values */ yytestcase(yyruleno==381);
- /* (382) sclp ::= selcollist COMMA */ yytestcase(yyruleno==382);
- /* (383) as ::= ID|STRING */ yytestcase(yyruleno==383);
- /* (384) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=384);
- /* (385) returning ::= */ yytestcase(yyruleno==385);
- /* (386) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=386);
- /* (387) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==387);
- /* (388) case_operand ::= expr */ yytestcase(yyruleno==388);
- /* (389) exprlist ::= nexprlist */ yytestcase(yyruleno==389);
- /* (390) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=390);
- /* (391) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=391);
- /* (392) nmnum ::= ON */ yytestcase(yyruleno==392);
- /* (393) nmnum ::= DELETE */ yytestcase(yyruleno==393);
- /* (394) nmnum ::= DEFAULT */ yytestcase(yyruleno==394);
- /* (395) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==395);
- /* (396) foreach_clause ::= */ yytestcase(yyruleno==396);
- /* (397) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==397);
- /* (398) trnm ::= nm */ yytestcase(yyruleno==398);
- /* (399) tridxby ::= */ yytestcase(yyruleno==399);
- /* (400) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==400);
- /* (401) database_kw_opt ::= */ yytestcase(yyruleno==401);
- /* (402) kwcolumn_opt ::= */ yytestcase(yyruleno==402);
- /* (403) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==403);
- /* (404) vtabarglist ::= vtabarg */ yytestcase(yyruleno==404);
- /* (405) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==405);
- /* (406) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==406);
- /* (407) anylist ::= */ yytestcase(yyruleno==407);
- /* (408) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==408);
- /* (409) anylist ::= anylist ANY */ yytestcase(yyruleno==409);
- /* (410) with ::= */ yytestcase(yyruleno==410);
- /* (411) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=411);
- /* (412) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=412);
+ /* (352) input ::= cmdlist */ yytestcase(yyruleno==352);
+ /* (353) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==353);
+ /* (354) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=354);
+ /* (355) ecmd ::= SEMI */ yytestcase(yyruleno==355);
+ /* (356) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==356);
+ /* (357) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=357);
+ /* (358) trans_opt ::= */ yytestcase(yyruleno==358);
+ /* (359) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==359);
+ /* (360) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==360);
+ /* (361) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==361);
+ /* (362) savepoint_opt ::= */ yytestcase(yyruleno==362);
+ /* (363) cmd ::= create_table create_table_args */ yytestcase(yyruleno==363);
+ /* (364) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=364);
+ /* (365) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==365);
+ /* (366) columnlist ::= columnname carglist */ yytestcase(yyruleno==366);
+ /* (367) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==367);
+ /* (368) nm ::= STRING */ yytestcase(yyruleno==368);
+ /* (369) typetoken ::= typename */ yytestcase(yyruleno==369);
+ /* (370) typename ::= ID|STRING */ yytestcase(yyruleno==370);
+ /* (371) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=371);
+ /* (372) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=372);
+ /* (373) carglist ::= carglist ccons */ yytestcase(yyruleno==373);
+ /* (374) carglist ::= */ yytestcase(yyruleno==374);
+ /* (375) ccons ::= NULL onconf */ yytestcase(yyruleno==375);
+ /* (376) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==376);
+ /* (377) ccons ::= AS generated */ yytestcase(yyruleno==377);
+ /* (378) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==378);
+ /* (379) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==379);
+ /* (380) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=380);
+ /* (381) tconscomma ::= */ yytestcase(yyruleno==381);
+ /* (382) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=382);
+ /* (383) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=383);
+ /* (384) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=384);
+ /* (385) oneselect ::= values */ yytestcase(yyruleno==385);
+ /* (386) sclp ::= selcollist COMMA */ yytestcase(yyruleno==386);
+ /* (387) as ::= ID|STRING */ yytestcase(yyruleno==387);
+ /* (388) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=388);
+ /* (389) returning ::= */ yytestcase(yyruleno==389);
+ /* (390) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=390);
+ /* (391) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==391);
+ /* (392) case_operand ::= expr */ yytestcase(yyruleno==392);
+ /* (393) exprlist ::= nexprlist */ yytestcase(yyruleno==393);
+ /* (394) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=394);
+ /* (395) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=395);
+ /* (396) nmnum ::= ON */ yytestcase(yyruleno==396);
+ /* (397) nmnum ::= DELETE */ yytestcase(yyruleno==397);
+ /* (398) nmnum ::= DEFAULT */ yytestcase(yyruleno==398);
+ /* (399) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==399);
+ /* (400) foreach_clause ::= */ yytestcase(yyruleno==400);
+ /* (401) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==401);
+ /* (402) trnm ::= nm */ yytestcase(yyruleno==402);
+ /* (403) tridxby ::= */ yytestcase(yyruleno==403);
+ /* (404) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==404);
+ /* (405) database_kw_opt ::= */ yytestcase(yyruleno==405);
+ /* (406) kwcolumn_opt ::= */ yytestcase(yyruleno==406);
+ /* (407) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==407);
+ /* (408) vtabarglist ::= vtabarg */ yytestcase(yyruleno==408);
+ /* (409) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==409);
+ /* (410) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==410);
+ /* (411) anylist ::= */ yytestcase(yyruleno==411);
+ /* (412) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==412);
+ /* (413) anylist ::= anylist ANY */ yytestcase(yyruleno==413);
+ /* (414) with ::= */ yytestcase(yyruleno==414);
+ /* (415) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=415);
+ /* (416) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=416);
break;
/********** End reduce actions ************************************************/
};
@@ -178972,19 +181971,12 @@ SQLITE_PRIVATE void sqlite3Parser(
(int)(yypParser->yytos - yypParser->yystack));
}
#endif
-#if YYSTACKDEPTH>0
if( yypParser->yytos>=yypParser->yystackEnd ){
- yyStackOverflow(yypParser);
- break;
- }
-#else
- if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
if( yyGrowStack(yypParser) ){
yyStackOverflow(yypParser);
break;
}
}
-#endif
}
yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM);
}else if( yyact <= YY_MAX_SHIFTREDUCE ){
@@ -180062,27 +183054,58 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_INTEGER;
#ifndef SQLITE_OMIT_HEX_INTEGER
if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){
- for(i=3; sqlite3Isxdigit(z[i]); i++){}
- return i;
- }
+ for(i=3; 1; i++){
+ if( sqlite3Isxdigit(z[i])==0 ){
+ if( z[i]==SQLITE_DIGIT_SEPARATOR ){
+ *tokenType = TK_QNUMBER;
+ }else{
+ break;
+ }
+ }
+ }
+ }else
#endif
- for(i=0; sqlite3Isdigit(z[i]); i++){}
+ {
+ for(i=0; 1; i++){
+ if( sqlite3Isdigit(z[i])==0 ){
+ if( z[i]==SQLITE_DIGIT_SEPARATOR ){
+ *tokenType = TK_QNUMBER;
+ }else{
+ break;
+ }
+ }
+ }
#ifndef SQLITE_OMIT_FLOATING_POINT
- if( z[i]=='.' ){
- i++;
- while( sqlite3Isdigit(z[i]) ){ i++; }
- *tokenType = TK_FLOAT;
- }
- if( (z[i]=='e' || z[i]=='E') &&
- ( sqlite3Isdigit(z[i+1])
- || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2]))
- )
- ){
- i += 2;
- while( sqlite3Isdigit(z[i]) ){ i++; }
- *tokenType = TK_FLOAT;
- }
+ if( z[i]=='.' ){
+ if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT;
+ for(i++; 1; i++){
+ if( sqlite3Isdigit(z[i])==0 ){
+ if( z[i]==SQLITE_DIGIT_SEPARATOR ){
+ *tokenType = TK_QNUMBER;
+ }else{
+ break;
+ }
+ }
+ }
+ }
+ if( (z[i]=='e' || z[i]=='E') &&
+ ( sqlite3Isdigit(z[i+1])
+ || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2]))
+ )
+ ){
+ if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT;
+ for(i+=2; 1; i++){
+ if( sqlite3Isdigit(z[i])==0 ){
+ if( z[i]==SQLITE_DIGIT_SEPARATOR ){
+ *tokenType = TK_QNUMBER;
+ }else{
+ break;
+ }
+ }
+ }
+ }
#endif
+ }
while( IdChar(z[i]) ){
*tokenType = TK_ILLEGAL;
i++;
@@ -180247,10 +183270,13 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
if( tokenType>=TK_WINDOW ){
assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
|| tokenType==TK_ILLEGAL || tokenType==TK_WINDOW
+ || tokenType==TK_QNUMBER
);
#else
if( tokenType>=TK_SPACE ){
- assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
+ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL
+ || tokenType==TK_QNUMBER
+ );
#endif /* SQLITE_OMIT_WINDOWFUNC */
if( AtomicLoad(&db->u1.isInterrupted) ){
pParse->rc = SQLITE_INTERRUPT;
@@ -180283,7 +183309,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
assert( n==6 );
tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
#endif /* SQLITE_OMIT_WINDOWFUNC */
- }else{
+ }else if( tokenType!=TK_QNUMBER ){
Token x;
x.z = zSql;
x.n = n;
@@ -181037,32 +184063,6 @@ SQLITE_API char *sqlite3_temp_directory = 0;
*/
SQLITE_API char *sqlite3_data_directory = 0;
-/*
-** Determine whether or not high-precision (long double) floating point
-** math works correctly on CPU currently running.
-*/
-static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){
- if( sizeof(LONGDOUBLE_TYPE)<=8 ){
- /* If the size of "long double" is not more than 8, then
- ** high-precision math is not possible. */
- return 0;
- }else{
- /* Just because sizeof(long double)>8 does not mean that the underlying
- ** hardware actually supports high-precision floating point. For example,
- ** clearing the 0x100 bit in the floating-point control word on Intel
- ** processors will make long double work like double, even though long
- ** double takes up more space. The only way to determine if long double
- ** actually works is to run an experiment. */
- LONGDOUBLE_TYPE a, b, c;
- rc++;
- a = 1.0+rc*0.1;
- b = 1.0e+18+rc*25.0;
- c = a+b;
- return b!=c;
- }
-}
-
-
/*
** Initialize SQLite.
**
@@ -181257,13 +184257,6 @@ SQLITE_API int sqlite3_initialize(void){
rc = SQLITE_EXTRA_INIT(0);
}
#endif
-
- /* Experimentally determine if high-precision floating point is
- ** available. */
-#ifndef SQLITE_OMIT_WSD
- sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc);
-#endif
-
return rc;
}
@@ -181643,6 +184636,18 @@ SQLITE_API int sqlite3_config(int op, ...){
}
#endif /* SQLITE_OMIT_DESERIALIZE */
+ case SQLITE_CONFIG_ROWID_IN_VIEW: {
+ int *pVal = va_arg(ap,int*);
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ if( 0==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = TF_NoVisibleRowid;
+ if( 1==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = 0;
+ *pVal = (sqlite3GlobalConfig.mNoVisibleRowid==0);
+#else
+ *pVal = 0;
+#endif
+ break;
+ }
+
default: {
rc = SQLITE_ERROR;
break;
@@ -182804,7 +185809,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
- SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE);
+ SQLITE_SUBTYPE|SQLITE_INNOCUOUS|
+ SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1);
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
/* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
@@ -184558,6 +187564,7 @@ static int openDatabase(
if( ((1<<(flags&7)) & 0x46)==0 ){
rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */
}else{
+ if( zFilename==0 ) zFilename = ":memory:";
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
}
if( rc!=SQLITE_OK ){
@@ -185529,6 +188536,18 @@ SQLITE_API int sqlite3_test_control(int op, ...){
break;
}
+ /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N)
+ **
+ ** Write the current optimization settings into *N. A zero bit means that
+ ** the optimization is on, and a 1 bit means that the optimization is off.
+ */
+ case SQLITE_TESTCTRL_GETOPT: {
+ sqlite3 *db = va_arg(ap, sqlite3*);
+ int *pN = va_arg(ap, int*);
+ *pN = db->dbOptFlags;
+ break;
+ }
+
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
**
** If parameter onoff is 1, subsequent calls to localtime() fail.
@@ -185760,24 +188779,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){
break;
}
-#if !defined(SQLITE_OMIT_WSD)
- /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X);
- **
- ** X<0 Make no changes to the bUseLongDouble. Just report value.
- ** X==0 Disable bUseLongDouble
- ** X==1 Enable bUseLongDouble
- ** X>=2 Set bUseLongDouble to its default value for this platform
- */
- case SQLITE_TESTCTRL_USELONGDOUBLE: {
- int b = va_arg(ap, int);
- if( b>=2 ) b = hasHighPrecisionDouble(b);
- if( b>=0 ) sqlite3Config.bUseLongDouble = b>0;
- rc = sqlite3Config.bUseLongDouble!=0;
- break;
- }
-#endif
-
-
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
/* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue)
**
@@ -186085,7 +189086,11 @@ SQLITE_API int sqlite3_snapshot_get(
if( iDb==0 || iDb>1 ){
Btree *pBt = db->aDb[iDb].pBt;
if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){
+ Pager *pPager = sqlite3BtreePager(pBt);
+ i64 dummy = 0;
+ sqlite3PagerSnapshotOpen(pPager, (sqlite3_snapshot*)&dummy);
rc = sqlite3BtreeBeginTrans(pBt, 0, 0);
+ sqlite3PagerSnapshotOpen(pPager, 0);
if( rc==SQLITE_OK ){
rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
}
@@ -189875,10 +192880,15 @@ static int fts3PoslistPhraseMerge(
if( *p1==POS_COLUMN ){
p1++;
p1 += fts3GetVarint32(p1, &iCol1);
+ /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN
+ ** entry, so this is actually end-of-doclist. */
+ if( iCol1==0 ) return 0;
}
if( *p2==POS_COLUMN ){
p2++;
p2 += fts3GetVarint32(p2, &iCol2);
+ /* As above, iCol2==0 indicates corruption. */
+ if( iCol2==0 ) return 0;
}
while( 1 ){
@@ -191545,22 +194555,24 @@ static int fts3IntegrityMethod(
char **pzErr /* Write error message here */
){
Fts3Table *p = (Fts3Table*)pVtab;
- int rc;
+ int rc = SQLITE_OK;
int bOk = 0;
UNUSED_PARAMETER(isQuick);
rc = sqlite3Fts3IntegrityCheck(p, &bOk);
- assert( rc!=SQLITE_CORRUPT_VTAB || bOk==0 );
- if( rc!=SQLITE_OK && rc!=SQLITE_CORRUPT_VTAB ){
+ assert( rc!=SQLITE_CORRUPT_VTAB );
+ if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){
*pzErr = sqlite3_mprintf("unable to validate the inverted index for"
" FTS%d table %s.%s: %s",
p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc));
- }else if( bOk==0 ){
+ if( *pzErr ) rc = SQLITE_OK;
+ }else if( rc==SQLITE_OK && bOk==0 ){
*pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s",
p->bFts4 ? 4 : 3, zSchema, zTabname);
+ if( *pzErr==0 ) rc = SQLITE_NOMEM;
}
sqlite3Fts3SegmentsClose(p);
- return SQLITE_OK;
+ return rc;
}
@@ -193047,7 +196059,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
- aTmp = sqlite3_malloc64(nTmp*2);
+ aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX);
if( !aTmp ){
*pRc = SQLITE_NOMEM;
res = 0;
@@ -194600,10 +197612,11 @@ static int getNextString(
Fts3PhraseToken *pToken;
p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken));
- if( !p ) goto no_mem;
-
zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte);
- if( !zTemp ) goto no_mem;
+ if( !zTemp || !p ){
+ rc = SQLITE_NOMEM;
+ goto getnextstring_out;
+ }
assert( nToken==ii );
pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii];
@@ -194618,9 +197631,6 @@ static int getNextString(
nToken = ii+1;
}
}
-
- pModule->xClose(pCursor);
- pCursor = 0;
}
if( rc==SQLITE_DONE ){
@@ -194628,7 +197638,10 @@ static int getNextString(
char *zBuf = 0;
p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp);
- if( !p ) goto no_mem;
+ if( !p ){
+ rc = SQLITE_NOMEM;
+ goto getnextstring_out;
+ }
memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p);
p->eType = FTSQUERY_PHRASE;
p->pPhrase = (Fts3Phrase *)&p[1];
@@ -194636,11 +197649,9 @@ static int getNextString(
p->pPhrase->nToken = nToken;
zBuf = (char *)&p->pPhrase->aToken[nToken];
+ assert( nTemp==0 || zTemp );
if( zTemp ){
memcpy(zBuf, zTemp, nTemp);
- sqlite3_free(zTemp);
- }else{
- assert( nTemp==0 );
}
for(jj=0; jjpPhrase->nToken; jj++){
@@ -194650,17 +197661,17 @@ static int getNextString(
rc = SQLITE_OK;
}
- *ppExpr = p;
- return rc;
-no_mem:
-
+ getnextstring_out:
if( pCursor ){
pModule->xClose(pCursor);
}
sqlite3_free(zTemp);
- sqlite3_free(p);
- *ppExpr = 0;
- return SQLITE_NOMEM;
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(p);
+ p = 0;
+ }
+ *ppExpr = p;
+ return rc;
}
/*
@@ -196854,11 +199865,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
#ifdef SQLITE_TEST
-#if defined(INCLUDE_SQLITE_TCL_H)
-# include "sqlite_tcl.h"
-#else
-# include "tcl.h"
-#endif
+#include "tclsqlite.h"
/* #include */
/*
@@ -203222,7 +206229,12 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){
sqlite3_finalize(pStmt);
}
- *pbOk = (rc==SQLITE_OK && cksum1==cksum2);
+ if( rc==SQLITE_CORRUPT_VTAB ){
+ rc = SQLITE_OK;
+ *pbOk = 0;
+ }else{
+ *pbOk = (rc==SQLITE_OK && cksum1==cksum2);
+ }
return rc;
}
@@ -204080,6 +207092,7 @@ static int fts3SnippetNextCandidate(SnippetIter *pIter){
return 1;
}
+ assert( pIter->nSnippet>=0 );
pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1;
for(i=0; inPhrase; i++){
SnippetPhrase *pPhrase = &pIter->aPhrase[i];
@@ -204128,7 +207141,7 @@ static void fts3SnippetDetails(
}
mCover |= mPhrase;
- for(j=0; jnToken; j++){
+ for(j=0; jnToken && jnSnippet; j++){
mHighlight |= (mPos>>j);
}
@@ -206789,7 +209802,6 @@ static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
}
}
-
/* Append formatted text (not to exceed N bytes) to the JsonString.
*/
static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
@@ -206847,6 +209859,40 @@ static void jsonAppendSeparator(JsonString *p){
jsonAppendChar(p, ',');
}
+/* c is a control character. Append the canonical JSON representation
+** of that control character to p.
+**
+** This routine assumes that the output buffer has already been enlarged
+** sufficiently to hold the worst-case encoding plus a nul terminator.
+*/
+static void jsonAppendControlChar(JsonString *p, u8 c){
+ static const char aSpecial[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ assert( sizeof(aSpecial)==32 );
+ assert( aSpecial['\b']=='b' );
+ assert( aSpecial['\f']=='f' );
+ assert( aSpecial['\n']=='n' );
+ assert( aSpecial['\r']=='r' );
+ assert( aSpecial['\t']=='t' );
+ assert( c>=0 && cnUsed+7 <= p->nAlloc );
+ if( aSpecial[c] ){
+ p->zBuf[p->nUsed] = '\\';
+ p->zBuf[p->nUsed+1] = aSpecial[c];
+ p->nUsed += 2;
+ }else{
+ p->zBuf[p->nUsed] = '\\';
+ p->zBuf[p->nUsed+1] = 'u';
+ p->zBuf[p->nUsed+2] = '0';
+ p->zBuf[p->nUsed+3] = '0';
+ p->zBuf[p->nUsed+4] = "0123456789abcdef"[c>>4];
+ p->zBuf[p->nUsed+5] = "0123456789abcdef"[c&0xf];
+ p->nUsed += 6;
+ }
+}
+
/* Append the N-byte string in zIn to the end of the JsonString string
** under construction. Enclose the string in double-quotes ("...") and
** escape any double-quotes or backslash characters contained within the
@@ -206906,35 +209952,14 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
}
c = z[0];
if( c=='"' || c=='\\' ){
- json_simple_escape:
if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return;
p->zBuf[p->nUsed++] = '\\';
p->zBuf[p->nUsed++] = c;
}else if( c=='\'' ){
p->zBuf[p->nUsed++] = c;
}else{
- static const char aSpecial[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- assert( sizeof(aSpecial)==32 );
- assert( aSpecial['\b']=='b' );
- assert( aSpecial['\f']=='f' );
- assert( aSpecial['\n']=='n' );
- assert( aSpecial['\r']=='r' );
- assert( aSpecial['\t']=='t' );
- assert( c>=0 && cnUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return;
- p->zBuf[p->nUsed++] = '\\';
- p->zBuf[p->nUsed++] = 'u';
- p->zBuf[p->nUsed++] = '0';
- p->zBuf[p->nUsed++] = '0';
- p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4];
- p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf];
+ jsonAppendControlChar(p, c);
}
z++;
N--;
@@ -207635,7 +210660,10 @@ static u32 jsonbValidityCheck(
if( !jsonIsOk[z[j]] && z[j]!='\'' ){
if( z[j]=='"' ){
if( x==JSONB_TEXTJ ) return j+1;
- }else if( z[j]!='\\' || j+1>=k ){
+ }else if( z[j]<=0x1f ){
+ /* Control characters in JSON5 string literals are ok */
+ if( x==JSONB_TEXTJ ) return j+1;
+ }else if( NEVER(z[j]!='\\') || j+1>=k ){
return j+1;
}else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){
j++;
@@ -207833,6 +210861,7 @@ static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){
case '[': {
/* Parse array */
iThis = pParse->nBlob;
+ assert( i<=(u32)pParse->nJson );
jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0);
iStart = pParse->nBlob;
if( pParse->oom ) return -1;
@@ -207929,9 +210958,14 @@ static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){
return -1;
}
}else if( c<=0x1f ){
- /* Control characters are not allowed in strings */
- pParse->iErr = j;
- return -1;
+ if( c==0 ){
+ pParse->iErr = j;
+ return -1;
+ }
+ /* Control characters are not allowed in canonical JSON string
+ ** literals, but are allowed in JSON5 string literals. */
+ opcode = JSONB_TEXT5;
+ pParse->hasNonstd = 1;
}else if( c=='"' ){
opcode = JSONB_TEXT5;
}
@@ -208147,6 +211181,7 @@ static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){
return i+4;
}
/* fall-through into the default case that checks for NaN */
+ /* no break */ deliberate_fall_through
}
default: {
u32 k;
@@ -208231,6 +211266,10 @@ static void jsonReturnStringAsBlob(JsonString *pStr){
JsonParse px;
memset(&px, 0, sizeof(px));
jsonStringTerminate(pStr);
+ if( pStr->eErr ){
+ sqlite3_result_error_nomem(pStr->pCtx);
+ return;
+ }
px.zJson = pStr->zBuf;
px.nJson = pStr->nUsed;
px.db = sqlite3_context_db_handle(pStr->pCtx);
@@ -208411,7 +211450,7 @@ static u32 jsonTranslateBlobToText(
zIn = (const char*)&pParse->aBlob[i+n];
jsonAppendChar(pOut, '"');
while( sz2>0 ){
- for(k=0; k0 ){
jsonAppendRawNZ(pOut, zIn, k);
if( k>=sz2 ){
@@ -208426,6 +211465,13 @@ static u32 jsonTranslateBlobToText(
sz2--;
continue;
}
+ if( zIn[0]<=0x1f ){
+ if( pOut->nUsed+7>pOut->nAlloc && jsonStringGrow(pOut,7) ) break;
+ jsonAppendControlChar(pOut, zIn[0]);
+ zIn++;
+ sz2--;
+ continue;
+ }
assert( zIn[0]=='\\' );
assert( sz2>=1 );
if( sz2<2 ){
@@ -208528,6 +211574,112 @@ static u32 jsonTranslateBlobToText(
return i+n+sz;
}
+/* Context for recursion of json_pretty()
+*/
+typedef struct JsonPretty JsonPretty;
+struct JsonPretty {
+ JsonParse *pParse; /* The BLOB being rendered */
+ JsonString *pOut; /* Generate pretty output into this string */
+ const char *zIndent; /* Use this text for indentation */
+ u32 szIndent; /* Bytes in zIndent[] */
+ u32 nIndent; /* Current level of indentation */
+};
+
+/* Append indentation to the pretty JSON under construction */
+static void jsonPrettyIndent(JsonPretty *pPretty){
+ u32 jj;
+ for(jj=0; jjnIndent; jj++){
+ jsonAppendRaw(pPretty->pOut, pPretty->zIndent, pPretty->szIndent);
+ }
+}
+
+/*
+** Translate the binary JSONB representation of JSON beginning at
+** pParse->aBlob[i] into a JSON text string. Append the JSON
+** text onto the end of pOut. Return the index in pParse->aBlob[]
+** of the first byte past the end of the element that is translated.
+**
+** This is a variant of jsonTranslateBlobToText() that "pretty-prints"
+** the output. Extra whitespace is inserted to make the JSON easier
+** for humans to read.
+**
+** If an error is detected in the BLOB input, the pOut->eErr flag
+** might get set to JSTRING_MALFORMED. But not all BLOB input errors
+** are detected. So a malformed JSONB input might either result
+** in an error, or in incorrect JSON.
+**
+** The pOut->eErr JSTRING_OOM flag is set on a OOM.
+*/
+static u32 jsonTranslateBlobToPrettyText(
+ JsonPretty *pPretty, /* Pretty-printing context */
+ u32 i /* Start rendering at this index */
+){
+ u32 sz, n, j, iEnd;
+ const JsonParse *pParse = pPretty->pParse;
+ JsonString *pOut = pPretty->pOut;
+ n = jsonbPayloadSize(pParse, i, &sz);
+ if( n==0 ){
+ pOut->eErr |= JSTRING_MALFORMED;
+ return pParse->nBlob+1;
+ }
+ switch( pParse->aBlob[i] & 0x0f ){
+ case JSONB_ARRAY: {
+ j = i+n;
+ iEnd = j+sz;
+ jsonAppendChar(pOut, '[');
+ if( jnIndent++;
+ while( pOut->eErr==0 ){
+ jsonPrettyIndent(pPretty);
+ j = jsonTranslateBlobToPrettyText(pPretty, j);
+ if( j>=iEnd ) break;
+ jsonAppendRawNZ(pOut, ",\n", 2);
+ }
+ jsonAppendChar(pOut, '\n');
+ pPretty->nIndent--;
+ jsonPrettyIndent(pPretty);
+ }
+ jsonAppendChar(pOut, ']');
+ i = iEnd;
+ break;
+ }
+ case JSONB_OBJECT: {
+ j = i+n;
+ iEnd = j+sz;
+ jsonAppendChar(pOut, '{');
+ if( jnIndent++;
+ while( pOut->eErr==0 ){
+ jsonPrettyIndent(pPretty);
+ j = jsonTranslateBlobToText(pParse, j, pOut);
+ if( j>iEnd ){
+ pOut->eErr |= JSTRING_MALFORMED;
+ break;
+ }
+ jsonAppendRawNZ(pOut, ": ", 2);
+ j = jsonTranslateBlobToPrettyText(pPretty, j);
+ if( j>=iEnd ) break;
+ jsonAppendRawNZ(pOut, ",\n", 2);
+ }
+ jsonAppendChar(pOut, '\n');
+ pPretty->nIndent--;
+ jsonPrettyIndent(pPretty);
+ }
+ jsonAppendChar(pOut, '}');
+ i = iEnd;
+ break;
+ }
+ default: {
+ i = jsonTranslateBlobToText(pParse, i, pOut);
+ break;
+ }
+ }
+ return i;
+}
+
+
/* Return true if the input pJson
**
** For performance reasons, this routine does not do a detailed check of the
@@ -208934,7 +212086,9 @@ static u32 jsonLookupStep(
zPath++;
if( zPath[0]=='"' ){
zKey = zPath + 1;
- for(i=1; zPath[i] && zPath[i]!='"'; i++){}
+ for(i=1; zPath[i] && zPath[i]!='"'; i++){
+ if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++;
+ }
nKey = i-1;
if( zPath[i] ){
i++;
@@ -209556,8 +212710,9 @@ static JsonParse *jsonParseFuncArg(
}
p->zJson = (char*)sqlite3_value_text(pArg);
p->nJson = sqlite3_value_bytes(pArg);
+ if( db->mallocFailed ) goto json_pfa_oom;
if( p->nJson==0 ) goto json_pfa_malformed;
- if( NEVER(p->zJson==0) ) goto json_pfa_oom;
+ assert( p->zJson!=0 );
if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){
if( flgs & JSON_KEEPERROR ){
p->nErr = 1;
@@ -209723,10 +212878,10 @@ static void jsonDebugPrintBlob(
if( sz==0 && x<=JSONB_FALSE ){
sqlite3_str_append(pOut, "\n", 1);
}else{
- u32 i;
+ u32 j;
sqlite3_str_appendall(pOut, ": \"");
- for(i=iStart+n; iaBlob[i];
+ for(j=iStart+n; jaBlob[j];
if( c<0x20 || c>=0x7f ) c = '.';
sqlite3_str_append(pOut, (char*)&c, 1);
}
@@ -209777,11 +212932,12 @@ static void jsonParseFunc(
if( p==0 ) return;
if( argc==1 ){
jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out);
- sqlite3_result_text64(ctx, out.zText, out.nChar, SQLITE_DYNAMIC, SQLITE_UTF8);
+ sqlite3_result_text64(ctx,out.zText,out.nChar,SQLITE_TRANSIENT,SQLITE_UTF8);
}else{
jsonShowParse(p);
}
jsonParseFree(p);
+ sqlite3_str_reset(&out);
}
#endif /* SQLITE_DEBUG */
@@ -209880,13 +213036,6 @@ static void jsonArrayLengthFunc(
jsonParseFree(p);
}
-/* True if the string is all digits */
-static int jsonAllDigits(const char *z, int n){
- int i;
- for(i=0; i $[NUMBER] // PG compatible
** LABEL ==> $.LABEL // PG compatible
** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
+ **
+ ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from
+ ** the right of the array. Hence for negative NUMBER:
+ **
+ ** NUMBER ==> $[#NUMBER] // PG compatible
*/
jsonStringInit(&jx, ctx);
- if( jsonAllDigits(zPath, nPath) ){
+ if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){
jsonAppendRawNZ(&jx, "[", 1);
+ if( zPath[0]=='-' ) jsonAppendRawNZ(&jx,"#",1);
jsonAppendRaw(&jx, zPath, nPath);
jsonAppendRawNZ(&jx, "]", 2);
}else if( jsonAllAlphanum(zPath, nPath) ){
@@ -210445,6 +213600,40 @@ static void jsonTypeFunc(
jsonParseFree(p);
}
+/*
+** json_pretty(JSON)
+** json_pretty(JSON, INDENT)
+**
+** Return text that is a pretty-printed rendering of the input JSON.
+** If the argument is not valid JSON, return NULL.
+**
+** The INDENT argument is text that is used for indentation. If omitted,
+** it defaults to four spaces (the same as PostgreSQL).
+*/
+static void jsonPrettyFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonString s; /* The output string */
+ JsonPretty x; /* Pretty printing context */
+
+ memset(&x, 0, sizeof(x));
+ x.pParse = jsonParseFuncArg(ctx, argv[0], 0);
+ if( x.pParse==0 ) return;
+ x.pOut = &s;
+ jsonStringInit(&s, ctx);
+ if( argc==1 || (x.zIndent = (const char*)sqlite3_value_text(argv[1]))==0 ){
+ x.zIndent = " ";
+ x.szIndent = 4;
+ }else{
+ x.szIndent = (u32)strlen(x.zIndent);
+ }
+ jsonTranslateBlobToPrettyText(&x, 0);
+ jsonReturnString(&s, 0, 0);
+ jsonParseFree(x.pParse);
+}
+
/*
** json_valid(JSON)
** json_valid(JSON, FLAGS)
@@ -211134,6 +214323,9 @@ static int jsonEachColumn(
case JEACH_VALUE: {
u32 i = jsonSkipLabel(p);
jsonReturnFromBlob(&p->sParse, i, ctx, 1);
+ if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
+ sqlite3_result_subtype(ctx, JSON_SUBTYPE);
+ }
break;
}
case JEACH_TYPE: {
@@ -211180,9 +214372,9 @@ static int jsonEachColumn(
case JEACH_JSON: {
if( p->sParse.zJson==0 ){
sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob,
- SQLITE_STATIC);
+ SQLITE_TRANSIENT);
}else{
- sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC);
+ sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT);
}
break;
}
@@ -211456,6 +214648,8 @@ SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){
JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc),
JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc),
JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc),
+ JFUNCTION(json_pretty, 1,1,0, 0,0,0, jsonPrettyFunc),
+ JFUNCTION(json_pretty, 2,1,0, 0,0,0, jsonPrettyFunc),
JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc),
JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc),
JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc),
@@ -217699,11 +220893,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
** Clear the Rtree.pNodeBlob object
*/
static void nodeBlobReset(Rtree *pRtree){
- if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
- sqlite3_blob *pBlob = pRtree->pNodeBlob;
- pRtree->pNodeBlob = 0;
- sqlite3_blob_close(pBlob);
- }
+ sqlite3_blob *pBlob = pRtree->pNodeBlob;
+ pRtree->pNodeBlob = 0;
+ sqlite3_blob_close(pBlob);
}
/*
@@ -217747,7 +220939,6 @@ static int nodeAcquire(
&pRtree->pNodeBlob);
}
if( rc ){
- nodeBlobReset(pRtree);
*ppNode = 0;
/* If unable to open an sqlite3_blob on the desired row, that can only
** be because the shadow tables hold erroneous data. */
@@ -217807,6 +220998,7 @@ static int nodeAcquire(
}
*ppNode = pNode;
}else{
+ nodeBlobReset(pRtree);
if( pNode ){
pRtree->nNodeRef--;
sqlite3_free(pNode);
@@ -217951,6 +221143,7 @@ static void nodeGetCoord(
int iCoord, /* Which coordinate to extract */
RtreeCoord *pCoord /* OUT: Space to write result to */
){
+ assert( iCellzData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord);
}
@@ -218140,7 +221333,9 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){
sqlite3_finalize(pCsr->pReadAux);
sqlite3_free(pCsr);
pRtree->nCursor--;
- nodeBlobReset(pRtree);
+ if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){
+ nodeBlobReset(pRtree);
+ }
return SQLITE_OK;
}
@@ -218725,7 +221920,11 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
int rc = SQLITE_OK;
RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
if( rc==SQLITE_OK && ALWAYS(p) ){
- *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell);
+ if( p->iCell>=NCELL(pNode) ){
+ rc = SQLITE_ABORT;
+ }else{
+ *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell);
+ }
}
return rc;
}
@@ -218743,6 +221942,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
if( rc ) return rc;
if( NEVER(p==0) ) return SQLITE_OK;
+ if( p->iCell>=NCELL(pNode) ) return SQLITE_ABORT;
if( i==0 ){
sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
}else if( i<=pRtree->nDim2 ){
@@ -218840,6 +222040,8 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
return SQLITE_OK;
}
+SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double);
+
/*
** Rtree virtual table module xFilter method.
*/
@@ -218869,7 +222071,8 @@ static int rtreeFilter(
i64 iNode = 0;
int eType = sqlite3_value_numeric_type(argv[0]);
if( eType==SQLITE_INTEGER
- || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid)
+ || (eType==SQLITE_FLOAT
+ && 0==sqlite3IntFloatCompare(iRowid,sqlite3_value_double(argv[0])))
){
rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
}else{
@@ -220225,7 +223428,7 @@ static int rtreeUpdate(
static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
Rtree *pRtree = (Rtree *)pVtab;
assert( pRtree->inWrTrans==0 );
- pRtree->inWrTrans++;
+ pRtree->inWrTrans = 1;
return SQLITE_OK;
}
@@ -220239,6 +223442,9 @@ static int rtreeEndTransaction(sqlite3_vtab *pVtab){
nodeBlobReset(pRtree);
return SQLITE_OK;
}
+static int rtreeRollback(sqlite3_vtab *pVtab){
+ return rtreeEndTransaction(pVtab);
+}
/*
** The xRename method for rtree module virtual tables.
@@ -220357,7 +223563,7 @@ static sqlite3_module rtreeModule = {
rtreeBeginTransaction, /* xBegin - begin transaction */
rtreeEndTransaction, /* xSync - sync transaction */
rtreeEndTransaction, /* xCommit - commit transaction */
- rtreeEndTransaction, /* xRollback - rollback transaction */
+ rtreeRollback, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
rtreeRename, /* xRename - rename the table */
rtreeSavepoint, /* xSavepoint */
@@ -223776,7 +226982,7 @@ static void icuLoadCollation(
UCollator *pUCollator; /* ICU library collation object */
int rc; /* Return code from sqlite3_create_collation_x() */
- assert(nArg==2);
+ assert(nArg==2 || nArg==3);
(void)nArg; /* Unused parameter */
zLocale = (const char *)sqlite3_value_text(apArg[0]);
zName = (const char *)sqlite3_value_text(apArg[1]);
@@ -223791,7 +226997,39 @@ static void icuLoadCollation(
return;
}
assert(p);
-
+ if(nArg==3){
+ const char *zOption = (const char*)sqlite3_value_text(apArg[2]);
+ static const struct {
+ const char *zName;
+ UColAttributeValue val;
+ } aStrength[] = {
+ { "PRIMARY", UCOL_PRIMARY },
+ { "SECONDARY", UCOL_SECONDARY },
+ { "TERTIARY", UCOL_TERTIARY },
+ { "DEFAULT", UCOL_DEFAULT_STRENGTH },
+ { "QUARTERNARY", UCOL_QUATERNARY },
+ { "IDENTICAL", UCOL_IDENTICAL },
+ };
+ unsigned int i;
+ for(i=0; i=sizeof(aStrength)/sizeof(aStrength[0]) ){
+ sqlite3_str *pStr = sqlite3_str_new(sqlite3_context_db_handle(p));
+ sqlite3_str_appendf(pStr,
+ "unknown collation strength \"%s\" - should be one of:",
+ zOption);
+ for(i=0; ipTblIter, &p->zErrmsg);
pIter->zTbl = 0;
+ pIter->zDataTbl = 0;
}else{
pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1);
@@ -227031,13 +230294,13 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
else if( c==')' ){
nParen--;
if( nParen==0 ){
- int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
+ int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
i++;
break;
}
}else if( c==',' && nParen==1 ){
- int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
+ int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
}else if( c=='"' || c=='\'' || c=='`' ){
@@ -227727,6 +230990,8 @@ static void rbuFileSuffix3(const char *zBase, char *z){
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
}
+#else
+ UNUSED_PARAMETER2(zBase,z);
#endif
}
@@ -227744,7 +231009,7 @@ static i64 rbuShmChecksum(sqlite3rbu *p){
u32 volatile *ptr;
p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr);
if( p->rc==SQLITE_OK ){
- iRet = ((i64)ptr[10] << 32) + ptr[11];
+ iRet = (i64)(((u64)ptr[10] << 32) + ptr[11]);
}
}
return iRet;
@@ -228311,7 +231576,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
"(%d, %Q), "
"(%d, %Q), "
"(%d, %d), "
- "(%d, %d), "
+ "(%d, %lld), "
"(%d, %lld), "
"(%d, %lld), "
"(%d, %lld), "
@@ -228669,6 +231934,7 @@ static void rbuIndexCntFunc(
sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
assert( nVal==1 );
+ UNUSED_PARAMETER(nVal);
rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
@@ -228944,7 +232210,7 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
){
if( zTarget==0 ){ return rbuMisuseError(); }
if( zState ){
- int n = strlen(zState);
+ size_t n = strlen(zState);
if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
return rbuMisuseError();
}
@@ -229161,6 +232427,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
*/
static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){
int rc = SQLITE_OK;
+ UNUSED_PARAMETER(pArg);
#if defined(_WIN32_WCE)
{
LPWSTR zWideOld;
@@ -230065,6 +233332,9 @@ static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
** No-op.
*/
static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
+ UNUSED_PARAMETER(pVfs);
+ UNUSED_PARAMETER(a);
+ UNUSED_PARAMETER(b);
return 0;
}
@@ -230463,6 +233733,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
pIdxInfo->orderByConsumed = 1;
pIdxInfo->idxNum |= 0x08;
}
+ pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX;
return SQLITE_OK;
}
@@ -231120,7 +234391,13 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
**
** The data field of sqlite_dbpage table can be updated. The new
** value must be a BLOB which is the correct page size, otherwise the
-** update fails. Rows may not be deleted or inserted.
+** update fails. INSERT operations also work, and operate as if they
+** where REPLACE. The size of the database can be extended by INSERT-ing
+** new pages on the end.
+**
+** Rows may not be deleted. However, doing an INSERT to page number N
+** with NULL page data causes the N-th page and all subsequent pages to be
+** deleted and the database to be truncated.
*/
/* #include "sqliteInt.h" ** Requires access to internal data structures ** */
@@ -231143,6 +234420,8 @@ struct DbpageCursor {
struct DbpageTable {
sqlite3_vtab base; /* Base class. Must be first */
sqlite3 *db; /* The database */
+ int iDbTrunc; /* Database to truncate */
+ Pgno pgnoTrunc; /* Size to truncate to */
};
/* Columns */
@@ -231151,7 +234430,6 @@ struct DbpageTable {
#define DBPAGE_COLUMN_SCHEMA 2
-
/*
** Connect to or create a dbpagevfs virtual table.
*/
@@ -231413,11 +234691,11 @@ static int dbpageUpdate(
DbPage *pDbPage = 0;
int rc = SQLITE_OK;
char *zErr = 0;
- const char *zSchema;
int iDb;
Btree *pBt;
Pager *pPager;
int szPage;
+ int isInsert;
(void)pRowid;
if( pTab->db->flags & SQLITE_Defensive ){
@@ -231428,21 +234706,29 @@ static int dbpageUpdate(
zErr = "cannot delete";
goto update_fail;
}
- pgno = sqlite3_value_int(argv[0]);
- if( sqlite3_value_type(argv[0])==SQLITE_NULL
- || (Pgno)sqlite3_value_int(argv[1])!=pgno
- ){
- zErr = "cannot insert";
- goto update_fail;
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+ pgno = (Pgno)sqlite3_value_int(argv[2]);
+ isInsert = 1;
+ }else{
+ pgno = sqlite3_value_int(argv[0]);
+ if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
+ zErr = "cannot insert";
+ goto update_fail;
+ }
+ isInsert = 0;
}
- zSchema = (const char*)sqlite3_value_text(argv[4]);
- iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1;
- if( NEVER(iDb<0) ){
- zErr = "no such schema";
- goto update_fail;
+ if( sqlite3_value_type(argv[4])==SQLITE_NULL ){
+ iDb = 0;
+ }else{
+ const char *zSchema = (const char*)sqlite3_value_text(argv[4]);
+ iDb = sqlite3FindDbName(pTab->db, zSchema);
+ if( iDb<0 ){
+ zErr = "no such schema";
+ goto update_fail;
+ }
}
pBt = pTab->db->aDb[iDb].pBt;
- if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){
+ if( pgno<1 || NEVER(pBt==0) ){
zErr = "bad page number";
goto update_fail;
}
@@ -231450,18 +234736,25 @@ static int dbpageUpdate(
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
|| sqlite3_value_bytes(argv[3])!=szPage
){
- zErr = "bad page value";
- goto update_fail;
+ if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){
+ /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and
+ ** all subsequent pages to be deleted. */
+ pTab->iDbTrunc = iDb;
+ pgno--;
+ pTab->pgnoTrunc = pgno;
+ }else{
+ zErr = "bad page value";
+ goto update_fail;
+ }
}
pPager = sqlite3BtreePager(pBt);
rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
if( rc==SQLITE_OK ){
const void *pData = sqlite3_value_blob(argv[3]);
- assert( pData!=0 || pTab->db->mallocFailed );
- if( pData
- && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK
- ){
- memcpy(sqlite3PagerGetData(pDbPage), pData, szPage);
+ if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
+ unsigned char *aPage = sqlite3PagerGetData(pDbPage);
+ memcpy(aPage, pData, szPage);
+ pTab->pgnoTrunc = 0;
}
}
sqlite3PagerUnref(pDbPage);
@@ -231485,9 +234778,31 @@ static int dbpageBegin(sqlite3_vtab *pVtab){
Btree *pBt = db->aDb[i].pBt;
if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0);
}
+ pTab->pgnoTrunc = 0;
+ return SQLITE_OK;
+}
+
+/* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT
+*/
+static int dbpageSync(sqlite3_vtab *pVtab){
+ DbpageTable *pTab = (DbpageTable *)pVtab;
+ if( pTab->pgnoTrunc>0 ){
+ Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt;
+ Pager *pPager = sqlite3BtreePager(pBt);
+ sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc);
+ }
+ pTab->pgnoTrunc = 0;
return SQLITE_OK;
}
+/* Cancel any pending truncate.
+*/
+static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){
+ DbpageTable *pTab = (DbpageTable *)pVtab;
+ pTab->pgnoTrunc = 0;
+ (void)notUsed1;
+ return SQLITE_OK;
+}
/*
** Invoke this routine to register the "dbpage" virtual table module
@@ -231509,14 +234824,14 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
dbpageRowid, /* xRowid - read data */
dbpageUpdate, /* xUpdate */
dbpageBegin, /* xBegin */
- 0, /* xSync */
+ dbpageSync, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
- 0, /* xRollbackTo */
+ dbpageRollbackTo, /* xRollbackTo */
0, /* xShadowName */
0 /* xIntegrity */
};
@@ -231604,6 +234919,10 @@ struct SessionBuffer {
** input data. Input data may be supplied either as a single large buffer
** (e.g. sqlite3changeset_start()) or using a stream function (e.g.
** sqlite3changeset_start_strm()).
+**
+** bNoDiscard:
+** If true, then the only time data is discarded is as a result of explicit
+** sessionDiscardData() calls. Not within every sessionInputBuffer() call.
*/
struct SessionInput {
int bNoDiscard; /* If true, do not discard in InputBuffer() */
@@ -233287,16 +236606,19 @@ static void sessionPreupdateOneChange(
for(i=0; i<(pTab->nCol-pTab->bRowid); i++){
sqlite3_value *p = 0;
if( op!=SQLITE_INSERT ){
- TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
- assert( trc==SQLITE_OK );
+ /* This may fail if the column has a non-NULL default and was added
+ ** using ALTER TABLE ADD COLUMN after this record was created. */
+ rc = pSession->hook.xOld(pSession->hook.pCtx, i, &p);
}else if( pTab->abPK[i] ){
TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p);
assert( trc==SQLITE_OK );
}
- /* This may fail if SQLite value p contains a utf-16 string that must
- ** be converted to utf-8 and an OOM error occurs while doing so. */
- rc = sessionSerializeValue(0, p, &nByte);
+ if( rc==SQLITE_OK ){
+ /* This may fail if SQLite value p contains a utf-16 string that must
+ ** be converted to utf-8 and an OOM error occurs while doing so. */
+ rc = sessionSerializeValue(0, p, &nByte);
+ }
if( rc!=SQLITE_OK ) goto error_out;
}
if( pTab->bRowid ){
@@ -235215,14 +238537,14 @@ static int sessionChangesetNextOne(
p->rc = sessionInputBuffer(&p->in, 2);
if( p->rc!=SQLITE_OK ) return p->rc;
+ sessionDiscardData(&p->in);
+ p->in.iCurrent = p->in.iNext;
+
/* If the iterator is already at the end of the changeset, return DONE. */
if( p->in.iNext>=p->in.nData ){
return SQLITE_DONE;
}
- sessionDiscardData(&p->in);
- p->in.iCurrent = p->in.iNext;
-
op = p->in.aData[p->in.iNext++];
while( op=='T' || op=='P' ){
if( pbNew ) *pbNew = 1;
@@ -236654,15 +239976,21 @@ static int sessionChangesetApply(
int nTab = 0; /* Result of sqlite3Strlen30(zTab) */
SessionApplyCtx sApply; /* changeset_apply() context object */
int bPatchset;
+ u64 savedFlag = db->flags & SQLITE_FkNoAction;
assert( xConflict!=0 );
+ sqlite3_mutex_enter(sqlite3_db_mutex(db));
+ if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){
+ db->flags |= ((u64)SQLITE_FkNoAction);
+ db->aDb[0].pSchema->schema_cookie -= 32;
+ }
+
pIter->in.bNoDiscard = 1;
memset(&sApply, 0, sizeof(sApply));
sApply.bRebase = (ppRebase && pnRebase);
sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP);
- sqlite3_mutex_enter(sqlite3_db_mutex(db));
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
}
@@ -236824,6 +240152,12 @@ static int sessionChangesetApply(
sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
sqlite3_free((char*)sApply.constraints.aBuf);
sqlite3_free((char*)sApply.rebase.aBuf);
+
+ if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){
+ assert( db->flags & SQLITE_FkNoAction );
+ db->flags &= ~((u64)SQLITE_FkNoAction);
+ db->aDb[0].pSchema->schema_cookie -= 32;
+ }
sqlite3_mutex_leave(sqlite3_db_mutex(db));
return rc;
}
@@ -236852,12 +240186,6 @@ SQLITE_API int sqlite3changeset_apply_v2(
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1);
- u64 savedFlag = db->flags & SQLITE_FkNoAction;
-
- if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){
- db->flags |= ((u64)SQLITE_FkNoAction);
- db->aDb[0].pSchema->schema_cookie -= 32;
- }
if( rc==SQLITE_OK ){
rc = sessionChangesetApply(
@@ -236865,11 +240193,6 @@ SQLITE_API int sqlite3changeset_apply_v2(
);
}
- if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){
- assert( db->flags & SQLITE_FkNoAction );
- db->flags &= ~((u64)SQLITE_FkNoAction);
- db->aDb[0].pSchema->schema_cookie -= 32;
- }
return rc;
}
@@ -236957,6 +240280,7 @@ struct sqlite3_changegroup {
int rc; /* Error code */
int bPatch; /* True to accumulate patchsets */
SessionTable *pList; /* List of tables in current patch */
+ SessionBuffer rec;
sqlite3 *db; /* Configured by changegroup_schema() */
char *zDb; /* Configured by changegroup_schema() */
@@ -237189,6 +240513,9 @@ static int sessionChangesetExtendRecord(
sessionAppendBlob(pOut, aRec, nRec, &rc);
if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){
rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt);
+ if( rc==SQLITE_OK && SQLITE_ROW!=sqlite3_step(pTab->pDfltStmt) ){
+ rc = sqlite3_errcode(pGrp->db);
+ }
}
for(ii=nCol; rc==SQLITE_OK && iinCol; ii++){
int eType = sqlite3_column_type(pTab->pDfltStmt, ii);
@@ -237205,6 +240532,7 @@ static int sessionChangesetExtendRecord(
}
if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){
sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal);
+ pOut->nBuf += 8;
}
break;
}
@@ -237255,108 +240583,130 @@ static int sessionChangesetExtendRecord(
}
/*
-** Add all changes in the changeset traversed by the iterator passed as
-** the first argument to the changegroup hash tables.
+** Locate or create a SessionTable object that may be used to add the
+** change currently pointed to by iterator pIter to changegroup pGrp.
+** If successful, set output variable (*ppTab) to point to the table
+** object and return SQLITE_OK. Otherwise, if some error occurs, return
+** an SQLite error code and leave (*ppTab) set to NULL.
*/
-static int sessionChangesetToHash(
- sqlite3_changeset_iter *pIter, /* Iterator to read from */
- sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */
- int bRebase /* True if hash table is for rebasing */
+static int sessionChangesetFindTable(
+ sqlite3_changegroup *pGrp,
+ const char *zTab,
+ sqlite3_changeset_iter *pIter,
+ SessionTable **ppTab
){
- u8 *aRec;
- int nRec;
int rc = SQLITE_OK;
SessionTable *pTab = 0;
- SessionBuffer rec = {0, 0, 0};
-
- while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){
- const char *zNew;
- int nCol;
- int op;
- int iHash;
- int bIndirect;
- SessionChange *pChange;
- SessionChange *pExist = 0;
- SessionChange **pp;
-
- /* Ensure that only changesets, or only patchsets, but not a mixture
- ** of both, are being combined. It is an error to try to combine a
- ** changeset and a patchset. */
- if( pGrp->pList==0 ){
- pGrp->bPatch = pIter->bPatchset;
- }else if( pIter->bPatchset!=pGrp->bPatch ){
- rc = SQLITE_ERROR;
- break;
- }
+ int nTab = (int)strlen(zTab);
+ u8 *abPK = 0;
+ int nCol = 0;
- sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect);
- if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){
- /* Search the list for a matching table */
- int nNew = (int)strlen(zNew);
- u8 *abPK;
+ *ppTab = 0;
+ sqlite3changeset_pk(pIter, &abPK, &nCol);
- sqlite3changeset_pk(pIter, &abPK, 0);
- for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){
- if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break;
- }
- if( !pTab ){
- SessionTable **ppTab;
+ /* Search the list for an existing table */
+ for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){
+ if( 0==sqlite3_strnicmp(pTab->zName, zTab, nTab+1) ) break;
+ }
- pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1);
- if( !pTab ){
- rc = SQLITE_NOMEM;
- break;
- }
- memset(pTab, 0, sizeof(SessionTable));
- pTab->nCol = nCol;
- pTab->abPK = (u8*)&pTab[1];
- memcpy(pTab->abPK, abPK, nCol);
- pTab->zName = (char*)&pTab->abPK[nCol];
- memcpy(pTab->zName, zNew, nNew+1);
-
- if( pGrp->db ){
- pTab->nCol = 0;
- rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb);
- if( rc ){
- assert( pTab->azCol==0 );
- sqlite3_free(pTab);
- break;
- }
- }
+ /* If one was not found above, create a new table now */
+ if( !pTab ){
+ SessionTable **ppNew;
- /* The new object must be linked on to the end of the list, not
- ** simply added to the start of it. This is to ensure that the
- ** tables within the output of sqlite3changegroup_output() are in
- ** the right order. */
- for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext);
- *ppTab = pTab;
- }
+ pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nTab+1);
+ if( !pTab ){
+ return SQLITE_NOMEM;
+ }
+ memset(pTab, 0, sizeof(SessionTable));
+ pTab->nCol = nCol;
+ pTab->abPK = (u8*)&pTab[1];
+ memcpy(pTab->abPK, abPK, nCol);
+ pTab->zName = (char*)&pTab->abPK[nCol];
+ memcpy(pTab->zName, zTab, nTab+1);
- if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){
- rc = SQLITE_SCHEMA;
- break;
+ if( pGrp->db ){
+ pTab->nCol = 0;
+ rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb);
+ if( rc ){
+ assert( pTab->azCol==0 );
+ sqlite3_free(pTab);
+ return rc;
}
}
- if( nColnCol ){
- assert( pGrp->db );
- rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec);
- if( rc ) break;
- aRec = rec.aBuf;
- nRec = rec.nBuf;
- }
+ /* The new object must be linked on to the end of the list, not
+ ** simply added to the start of it. This is to ensure that the
+ ** tables within the output of sqlite3changegroup_output() are in
+ ** the right order. */
+ for(ppNew=&pGrp->pList; *ppNew; ppNew=&(*ppNew)->pNext);
+ *ppNew = pTab;
+ }
- if( sessionGrowHash(0, pIter->bPatchset, pTab) ){
- rc = SQLITE_NOMEM;
- break;
- }
+ /* Check that the table is compatible. */
+ if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){
+ rc = SQLITE_SCHEMA;
+ }
+
+ *ppTab = pTab;
+ return rc;
+}
+
+/*
+** Add the change currently indicated by iterator pIter to the hash table
+** belonging to changegroup pGrp.
+*/
+static int sessionOneChangeToHash(
+ sqlite3_changegroup *pGrp,
+ sqlite3_changeset_iter *pIter,
+ int bRebase
+){
+ int rc = SQLITE_OK;
+ int nCol = 0;
+ int op = 0;
+ int iHash = 0;
+ int bIndirect = 0;
+ SessionChange *pChange = 0;
+ SessionChange *pExist = 0;
+ SessionChange **pp = 0;
+ SessionTable *pTab = 0;
+ u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2];
+ int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2;
+
+ assert( nRec>0 );
+
+ /* Ensure that only changesets, or only patchsets, but not a mixture
+ ** of both, are being combined. It is an error to try to combine a
+ ** changeset and a patchset. */
+ if( pGrp->pList==0 ){
+ pGrp->bPatch = pIter->bPatchset;
+ }else if( pIter->bPatchset!=pGrp->bPatch ){
+ rc = SQLITE_ERROR;
+ }
+
+ if( rc==SQLITE_OK ){
+ const char *zTab = 0;
+ sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect);
+ rc = sessionChangesetFindTable(pGrp, zTab, pIter, &pTab);
+ }
+
+ if( rc==SQLITE_OK && nColnCol ){
+ SessionBuffer *pBuf = &pGrp->rec;
+ rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, pBuf);
+ aRec = pBuf->aBuf;
+ nRec = pBuf->nBuf;
+ assert( pGrp->db );
+ }
+
+ if( rc==SQLITE_OK && sessionGrowHash(0, pIter->bPatchset, pTab) ){
+ rc = SQLITE_NOMEM;
+ }
+
+ if( rc==SQLITE_OK ){
+ /* Search for existing entry. If found, remove it from the hash table.
+ ** Code below may link it back in. */
iHash = sessionChangeHash(
pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange
);
-
- /* Search for existing entry. If found, remove it from the hash table.
- ** Code below may link it back in.
- */
for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){
int bPkOnly1 = 0;
int bPkOnly2 = 0;
@@ -237371,19 +240721,42 @@ static int sessionChangesetToHash(
break;
}
}
+ }
+ if( rc==SQLITE_OK ){
rc = sessionChangeMerge(pTab, bRebase,
pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
);
- if( rc ) break;
- if( pChange ){
- pChange->pNext = pTab->apChange[iHash];
- pTab->apChange[iHash] = pChange;
- pTab->nEntry++;
- }
+ }
+ if( rc==SQLITE_OK && pChange ){
+ pChange->pNext = pTab->apChange[iHash];
+ pTab->apChange[iHash] = pChange;
+ pTab->nEntry++;
+ }
+
+ if( rc==SQLITE_OK ) rc = pIter->rc;
+ return rc;
+}
+
+/*
+** Add all changes in the changeset traversed by the iterator passed as
+** the first argument to the changegroup hash tables.
+*/
+static int sessionChangesetToHash(
+ sqlite3_changeset_iter *pIter, /* Iterator to read from */
+ sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */
+ int bRebase /* True if hash table is for rebasing */
+){
+ u8 *aRec;
+ int nRec;
+ int rc = SQLITE_OK;
+
+ pIter->in.bNoDiscard = 1;
+ while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){
+ rc = sessionOneChangeToHash(pGrp, pIter, bRebase);
+ if( rc!=SQLITE_OK ) break;
}
- sqlite3_free(rec.aBuf);
if( rc==SQLITE_OK ) rc = pIter->rc;
return rc;
}
@@ -237511,6 +240884,23 @@ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void
return rc;
}
+/*
+** Add a single change to a changeset-group.
+*/
+SQLITE_API int sqlite3changegroup_add_change(
+ sqlite3_changegroup *pGrp,
+ sqlite3_changeset_iter *pIter
+){
+ if( pIter->in.iCurrent==pIter->in.iNext
+ || pIter->rc!=SQLITE_OK
+ || pIter->bInvert
+ ){
+ /* Iterator does not point to any valid entry or is an INVERT iterator. */
+ return SQLITE_ERROR;
+ }
+ return sessionOneChangeToHash(pGrp, pIter, 0);
+}
+
/*
** Obtain a buffer containing a changeset representing the concatenation
** of all changesets added to the group so far.
@@ -237560,6 +240950,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
if( pGrp ){
sqlite3_free(pGrp->zDb);
sessionDeleteTable(0, pGrp->pList);
+ sqlite3_free(pGrp->rec.aBuf);
sqlite3_free(pGrp);
}
}
@@ -237961,6 +241352,7 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){
if( p ){
sessionDeleteTable(0, p->grp.pList);
+ sqlite3_free(p->grp.rec.aBuf);
sqlite3_free(p);
}
}
@@ -237991,7 +241383,27 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){
/************** End of sqlite3session.c **************************************/
/************** Begin file fts5.c ********************************************/
-
+/*
+** This, the "fts5.c" source file, is a composite file that is itself
+** assembled from the following files:
+**
+** fts5.h
+** fts5Int.h
+** fts5parse.h <--- Generated from fts5parse.y by Lemon
+** fts5parse.c <--- Generated from fts5parse.y by Lemon
+** fts5_aux.c
+** fts5_buffer.c
+** fts5_config.c
+** fts5_expr.c
+** fts5_hash.c
+** fts5_index.c
+** fts5_main.c
+** fts5_storage.c
+** fts5_tokenize.c
+** fts5_unicode2.c
+** fts5_varint.c
+** fts5_vocab.c
+*/
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5)
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
@@ -238001,6 +241413,12 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){
# undef NDEBUG
#endif
+#ifdef HAVE_STDINT_H
+/* #include */
+#endif
+#ifdef HAVE_INTTYPES_H
+/* #include */
+#endif
/*
** 2014 May 31
**
@@ -238058,8 +241476,8 @@ struct Fts5PhraseIter {
** EXTENSION API FUNCTIONS
**
** xUserData(pFts):
-** Return a copy of the context pointer the extension function was
-** registered with.
+** Return a copy of the pUserData pointer passed to the xCreateFunction()
+** API when the extension function was registered.
**
** xColumnTotalSize(pFts, iCol, pnToken):
** If parameter iCol is less than zero, set output variable *pnToken
@@ -238241,6 +241659,10 @@ struct Fts5PhraseIter {
** (i.e. if it is a contentless table), then this API always iterates
** through an empty set (all calls to xPhraseFirst() set iCol to -1).
**
+** In all cases, matches are visited in (column ASC, offset ASC) order.
+** i.e. all those in column 0, sorted by offset, followed by those in
+** column 1, etc.
+**
** xPhraseNext()
** See xPhraseFirst above.
**
@@ -238307,9 +241729,32 @@ struct Fts5PhraseIter {
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
+**
+** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
+** If parameter iCol is less than zero, or greater than or equal to the
+** number of columns in the table, SQLITE_RANGE is returned.
+**
+** Otherwise, this function attempts to retrieve the locale associated
+** with column iCol of the current row. Usually, there is no associated
+** locale, and output parameters (*pzLocale) and (*pnLocale) are set
+** to NULL and 0, respectively. However, if the fts5_locale() function
+** was used to associate a locale with the value when it was inserted
+** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
+** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
+** is set to the size in bytes of the buffer, not including the
+** nul-terminator.
+**
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an
+** SQLite error code is returned. The final value of the output parameters
+** is undefined in this case.
+**
+** xTokenize_v2:
+** Tokenize text using the tokenizer belonging to the FTS5 table. This
+** API is the same as the xTokenize() API, except that it allows a tokenizer
+** locale to be specified.
*/
struct Fts5ExtensionApi {
- int iVersion; /* Currently always set to 3 */
+ int iVersion; /* Currently always set to 4 */
void *(*xUserData)(Fts5Context*);
@@ -238351,6 +241796,15 @@ struct Fts5ExtensionApi {
const char **ppToken, int *pnToken
);
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
+
+ /* Below this point are iVersion>=4 only */
+ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xTokenize_v2)(Fts5Context*,
+ const char *pText, int nText, /* Text to tokenize */
+ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
};
/*
@@ -238371,7 +241825,7 @@ struct Fts5ExtensionApi {
** A tokenizer instance is required to actually tokenize text.
**
** The first argument passed to this function is a copy of the (void*)
-** pointer provided by the application when the fts5_tokenizer object
+** pointer provided by the application when the fts5_tokenizer_v2 object
** was registered with FTS5 (the third argument to xCreateTokenizer()).
** The second and third arguments are an array of nul-terminated strings
** containing the tokenizer arguments, if any, specified following the
@@ -238395,7 +241849,7 @@ struct Fts5ExtensionApi {
** argument passed to this function is a pointer to an Fts5Tokenizer object
** returned by an earlier call to xCreate().
**
-** The second argument indicates the reason that FTS5 is requesting
+** The third argument indicates the reason that FTS5 is requesting
** tokenization of the supplied text. This is always one of the following
** four values:
**
@@ -238419,6 +241873,13 @@ struct Fts5ExtensionApi {
** on a columnsize=0 database.
**
**
+** The sixth and seventh arguments passed to xTokenize() - pLocale and
+** nLocale - are a pointer to a buffer containing the locale to use for
+** tokenization (e.g. "en_US") and its size in bytes, respectively. The
+** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
+** which case nLocale is always 0) to indicate that the tokenizer should
+** use its default locale.
+**
** For each token in the input string, the supplied callback xToken() must
** be invoked. The first argument to it should be a copy of the pointer
** passed as the second argument to xTokenize(). The third and fourth
@@ -238442,6 +241903,30 @@ struct Fts5ExtensionApi {
** may abandon the tokenization and return any error code other than
** SQLITE_OK or SQLITE_DONE.
**
+** If the tokenizer is registered using an fts5_tokenizer_v2 object,
+** then the xTokenize() method has two additional arguments - pLocale
+** and nLocale. These specify the locale that the tokenizer should use
+** for the current request. If pLocale and nLocale are both 0, then the
+** tokenizer should use its default locale. Otherwise, pLocale points to
+** an nLocale byte buffer containing the name of the locale to use as utf-8
+** text. pLocale is not nul-terminated.
+**
+** FTS5_TOKENIZER
+**
+** There is also an fts5_tokenizer object. This is an older, deprecated,
+** version of fts5_tokenizer_v2. It is similar except that:
+**
+**
+** - There is no "iVersion" field, and
+**
- The xTokenize() method does not take a locale argument.
+**
+**
+** Legacy fts5_tokenizer tokenizers must be registered using the
+** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
+**
+** Tokenizer implementations registered using either API may be retrieved
+** using both xFindTokenizer() and xFindTokenizer_v2().
+**
** SYNONYM SUPPORT
**
** Custom tokenizers may also support synonyms. Consider a case in which a
@@ -238550,6 +242035,33 @@ struct Fts5ExtensionApi {
** inefficient.
*/
typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
+struct fts5_tokenizer_v2 {
+ int iVersion; /* Currently always 2 */
+
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
+ int (*xTokenize)(Fts5Tokenizer*,
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ const char *pText, int nText,
+ const char *pLocale, int nLocale,
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/*
+** New code should use the fts5_tokenizer_v2 type to define tokenizer
+** implementations. The following type is included for legacy applications
+** that still use it.
+*/
typedef struct fts5_tokenizer fts5_tokenizer;
struct fts5_tokenizer {
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
@@ -238569,6 +242081,7 @@ struct fts5_tokenizer {
);
};
+
/* Flags that may be passed as the third argument to xTokenize() */
#define FTS5_TOKENIZE_QUERY 0x0001
#define FTS5_TOKENIZE_PREFIX 0x0002
@@ -238588,7 +242101,7 @@ struct fts5_tokenizer {
*/
typedef struct fts5_api fts5_api;
struct fts5_api {
- int iVersion; /* Currently always set to 2 */
+ int iVersion; /* Currently always set to 3 */
/* Create a new tokenizer */
int (*xCreateTokenizer)(
@@ -238615,6 +242128,25 @@ struct fts5_api {
fts5_extension_function xFunction,
void (*xDestroy)(void*)
);
+
+ /* APIs below this point are only available if iVersion>=3 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer_v2)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pUserData,
+ fts5_tokenizer_v2 *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer_v2)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppUserData,
+ fts5_tokenizer_v2 **ppTokenizer
+ );
};
/*
@@ -238688,6 +242220,22 @@ typedef sqlite3_uint64 u64;
# define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
# define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
+/* The uptr type is an unsigned integer large enough to hold a pointer
+*/
+#if defined(HAVE_STDINT_H)
+ typedef uintptr_t uptr;
+#elif SQLITE_PTRSIZE==4
+ typedef u32 uptr;
+#else
+ typedef u64 uptr;
+#endif
+
+#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
+# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0)
+#else
+# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0)
+#endif
+
#endif
/* Truncate very long tokens to this many bytes. Hard limit is
@@ -238771,6 +242319,18 @@ struct Fts5Colset {
*/
typedef struct Fts5Config Fts5Config;
+typedef struct Fts5TokenizerConfig Fts5TokenizerConfig;
+
+struct Fts5TokenizerConfig {
+ Fts5Tokenizer *pTok;
+ fts5_tokenizer_v2 *pApi2;
+ fts5_tokenizer *pApi1;
+ const char **azArg;
+ int nArg;
+ int ePattern; /* FTS_PATTERN_XXX constant */
+ const char *pLocale; /* Current locale to use */
+ int nLocale; /* Size of pLocale in bytes */
+};
/*
** An instance of the following structure encodes all information that can
@@ -238810,9 +242370,12 @@ typedef struct Fts5Config Fts5Config;
**
** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex);
**
+** bLocale:
+** Set to true if locale=1 was specified when the table was created.
*/
struct Fts5Config {
sqlite3 *db; /* Database handle */
+ Fts5Global *pGlobal; /* Global fts5 object for handle db */
char *zDb; /* Database holding FTS index (e.g. "main") */
char *zName; /* Name of FTS index */
int nCol; /* Number of columns */
@@ -238822,16 +242385,17 @@ struct Fts5Config {
int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */
int eContent; /* An FTS5_CONTENT value */
int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */
+ int bContentlessUnindexed; /* "contentless_unindexed=" option (dflt=0) */
char *zContent; /* content table */
char *zContentRowid; /* "content_rowid=" option value */
int bColumnsize; /* "columnsize=" option value (dflt==1) */
int bTokendata; /* "tokendata=" option value (dflt==0) */
+ int bLocale; /* "locale=" option value (dflt==0) */
int eDetail; /* FTS5_DETAIL_XXX value */
char *zContentExprlist;
- Fts5Tokenizer *pTok;
- fts5_tokenizer *pTokApi;
+ Fts5TokenizerConfig t;
int bLock; /* True when table is preparing statement */
- int ePattern; /* FTS_PATTERN_XXX constant */
+
/* Values loaded from the %_config table */
int iVersion; /* fts5 file format 'version' */
@@ -238860,9 +242424,10 @@ struct Fts5Config {
#define FTS5_CURRENT_VERSION 4
#define FTS5_CURRENT_VERSION_SECUREDELETE 5
-#define FTS5_CONTENT_NORMAL 0
-#define FTS5_CONTENT_NONE 1
-#define FTS5_CONTENT_EXTERNAL 2
+#define FTS5_CONTENT_NORMAL 0
+#define FTS5_CONTENT_NONE 1
+#define FTS5_CONTENT_EXTERNAL 2
+#define FTS5_CONTENT_UNINDEXED 3
#define FTS5_DETAIL_FULL 0
#define FTS5_DETAIL_NONE 1
@@ -238897,6 +242462,8 @@ static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, i
static int sqlite3Fts5ConfigParseRank(const char*, char**, char**);
+static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...);
+
/*
** End of interface to code in fts5_config.c.
**************************************************************************/
@@ -238941,7 +242508,7 @@ static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...);
static void sqlite3Fts5Put32(u8*, int);
static int sqlite3Fts5Get32(const u8*);
-#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
+#define FTS5_POS2COLUMN(iPos) (int)((iPos >> 32) & 0x7FFFFFFF)
#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF)
typedef struct Fts5PoslistReader Fts5PoslistReader;
@@ -239226,18 +242793,20 @@ struct Fts5Table {
Fts5Index *pIndex; /* Full-text index */
};
-static int sqlite3Fts5GetTokenizer(
- Fts5Global*,
- const char **azArg,
- int nArg,
- Fts5Config*,
- char **pzErr
-);
+static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig);
static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
static int sqlite3Fts5FlushToDisk(Fts5Table*);
+static void sqlite3Fts5ClearLocale(Fts5Config *pConfig);
+static void sqlite3Fts5SetLocale(Fts5Config *pConfig, const char *pLoc, int nLoc);
+
+static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal);
+static int sqlite3Fts5DecodeLocaleValue(sqlite3_value *pVal,
+ const char **ppText, int *pnText, const char **ppLoc, int *pnLoc
+);
+
/*
** End of interface to code in fts5.c.
**************************************************************************/
@@ -239317,8 +242886,8 @@ static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
static int sqlite3Fts5DropAll(Fts5Config*);
static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
-static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**);
-static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
+static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**, int);
+static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, int, sqlite3_value**, i64*);
static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg);
@@ -239343,6 +242912,9 @@ static int sqlite3Fts5StorageOptimize(Fts5Storage *p);
static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge);
static int sqlite3Fts5StorageReset(Fts5Storage *p);
+static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage*);
+static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel);
+
/*
** End of interface to code in fts5_storage.c.
**************************************************************************/
@@ -239495,6 +243067,7 @@ static int sqlite3Fts5TokenizerPattern(
int (*xCreate)(void*, const char**, int, Fts5Tokenizer**),
Fts5Tokenizer *pTok
);
+static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig*);
/*
** End of interface to code in fts5_tokenizer.c.
**************************************************************************/
@@ -239655,6 +243228,9 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*);
** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser
** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser
** sqlite3Fts5ParserCTX_* As sqlite3Fts5ParserARG_ except for %extra_context
+** fts5YYREALLOC Name of the realloc() function to use
+** fts5YYFREE Name of the free() function to use
+** fts5YYDYNSTACK True if stack space should be extended on heap
** fts5YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
** fts5YYNSTATE the combined number of states.
@@ -239668,6 +243244,8 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*);
** fts5YY_NO_ACTION The fts5yy_action[] code for no-op
** fts5YY_MIN_REDUCE Minimum value for reduce actions
** fts5YY_MAX_REDUCE Maximum value for reduce actions
+** fts5YY_MIN_DSTRCTR Minimum symbol value that has a destructor
+** fts5YY_MAX_DSTRCTR Maximum symbol value that has a destructor
*/
#ifndef INTERFACE
# define INTERFACE 1
@@ -239694,6 +243272,9 @@ typedef union {
#define sqlite3Fts5ParserARG_PARAM ,pParse
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse;
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse;
+#define fts5YYREALLOC realloc
+#define fts5YYFREE free
+#define fts5YYDYNSTACK 0
#define sqlite3Fts5ParserCTX_SDECL
#define sqlite3Fts5ParserCTX_PDECL
#define sqlite3Fts5ParserCTX_PARAM
@@ -239711,6 +243292,8 @@ typedef union {
#define fts5YY_NO_ACTION 82
#define fts5YY_MIN_REDUCE 83
#define fts5YY_MAX_REDUCE 110
+#define fts5YY_MIN_DSTRCTR 16
+#define fts5YY_MAX_DSTRCTR 24
/************* End control #defines *******************************************/
#define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0])))
@@ -239726,6 +243309,22 @@ typedef union {
# define fts5yytestcase(X)
#endif
+/* Macro to determine if stack space has the ability to grow using
+** heap memory.
+*/
+#if fts5YYSTACKDEPTH<=0 || fts5YYDYNSTACK
+# define fts5YYGROWABLESTACK 1
+#else
+# define fts5YYGROWABLESTACK 0
+#endif
+
+/* Guarantee a minimum number of initial stack slots.
+*/
+#if fts5YYSTACKDEPTH<=0
+# undef fts5YYSTACKDEPTH
+# define fts5YYSTACKDEPTH 2 /* Need a minimum stack size */
+#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
@@ -239886,14 +243485,9 @@ struct fts5yyParser {
#endif
sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */
sqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */
-#if fts5YYSTACKDEPTH<=0
- int fts5yystksz; /* Current side of the stack */
- fts5yyStackEntry *fts5yystack; /* The parser's stack */
- fts5yyStackEntry fts5yystk0; /* First stack entry */
-#else
- fts5yyStackEntry fts5yystack[fts5YYSTACKDEPTH]; /* The parser's stack */
- fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
-#endif
+ fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
+ fts5yyStackEntry *fts5yystack; /* The parser stack */
+ fts5yyStackEntry fts5yystk0[fts5YYSTACKDEPTH]; /* Initial stack space */
};
typedef struct fts5yyParser fts5yyParser;
@@ -240000,37 +243594,45 @@ static const char *const fts5yyRuleName[] = {
#endif /* NDEBUG */
-#if fts5YYSTACKDEPTH<=0
+#if fts5YYGROWABLESTACK
/*
** Try to increase the size of the parser stack. Return the number
** of errors. Return 0 on success.
*/
static int fts5yyGrowStack(fts5yyParser *p){
+ int oldSize = 1 + (int)(p->fts5yystackEnd - p->fts5yystack);
int newSize;
int idx;
fts5yyStackEntry *pNew;
- newSize = p->fts5yystksz*2 + 100;
- idx = p->fts5yytos ? (int)(p->fts5yytos - p->fts5yystack) : 0;
- if( p->fts5yystack==&p->fts5yystk0 ){
- pNew = malloc(newSize*sizeof(pNew[0]));
- if( pNew ) pNew[0] = p->fts5yystk0;
+ newSize = oldSize*2 + 100;
+ idx = (int)(p->fts5yytos - p->fts5yystack);
+ if( p->fts5yystack==p->fts5yystk0 ){
+ pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0]));
+ if( pNew==0 ) return 1;
+ memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0]));
}else{
- pNew = realloc(p->fts5yystack, newSize*sizeof(pNew[0]));
+ pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0]));
+ if( pNew==0 ) return 1;
}
- if( pNew ){
- p->fts5yystack = pNew;
- p->fts5yytos = &p->fts5yystack[idx];
+ p->fts5yystack = pNew;
+ p->fts5yytos = &p->fts5yystack[idx];
#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n",
- fts5yyTracePrompt, p->fts5yystksz, newSize);
- }
-#endif
- p->fts5yystksz = newSize;
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n",
+ fts5yyTracePrompt, oldSize, newSize);
}
- return pNew==0;
+#endif
+ p->fts5yystackEnd = &p->fts5yystack[newSize-1];
+ return 0;
}
+#endif /* fts5YYGROWABLESTACK */
+
+#if !fts5YYGROWABLESTACK
+/* For builds that do no have a growable stack, fts5yyGrowStack always
+** returns an error.
+*/
+# define fts5yyGrowStack(X) 1
#endif
/* Datatype of the argument to the memory allocated passed as the
@@ -240050,24 +243652,14 @@ static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PD
#ifdef fts5YYTRACKMAXSTACKDEPTH
fts5yypParser->fts5yyhwm = 0;
#endif
-#if fts5YYSTACKDEPTH<=0
- fts5yypParser->fts5yytos = NULL;
- fts5yypParser->fts5yystack = NULL;
- fts5yypParser->fts5yystksz = 0;
- if( fts5yyGrowStack(fts5yypParser) ){
- fts5yypParser->fts5yystack = &fts5yypParser->fts5yystk0;
- fts5yypParser->fts5yystksz = 1;
- }
-#endif
+ fts5yypParser->fts5yystack = fts5yypParser->fts5yystk0;
+ fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1];
#ifndef fts5YYNOERRORRECOVERY
fts5yypParser->fts5yyerrcnt = -1;
#endif
fts5yypParser->fts5yytos = fts5yypParser->fts5yystack;
fts5yypParser->fts5yystack[0].stateno = 0;
fts5yypParser->fts5yystack[0].major = 0;
-#if fts5YYSTACKDEPTH>0
- fts5yypParser->fts5yystackEnd = &fts5yypParser->fts5yystack[fts5YYSTACKDEPTH-1];
-#endif
}
#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
@@ -240181,9 +243773,26 @@ static void fts5yy_pop_parser_stack(fts5yyParser *pParser){
*/
static void sqlite3Fts5ParserFinalize(void *p){
fts5yyParser *pParser = (fts5yyParser*)p;
- while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser);
-#if fts5YYSTACKDEPTH<=0
- if( pParser->fts5yystack!=&pParser->fts5yystk0 ) free(pParser->fts5yystack);
+
+ /* In-lined version of calling fts5yy_pop_parser_stack() for each
+ ** element left in the stack */
+ fts5yyStackEntry *fts5yytos = pParser->fts5yytos;
+ while( fts5yytos>pParser->fts5yystack ){
+#ifndef NDEBUG
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE,"%sPopping %s\n",
+ fts5yyTracePrompt,
+ fts5yyTokenName[fts5yytos->major]);
+ }
+#endif
+ if( fts5yytos->major>=fts5YY_MIN_DSTRCTR ){
+ fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor);
+ }
+ fts5yytos--;
+ }
+
+#if fts5YYGROWABLESTACK
+ if( pParser->fts5yystack!=pParser->fts5yystk0 ) fts5YYFREE(pParser->fts5yystack);
#endif
}
@@ -240410,25 +244019,19 @@ static void fts5yy_shift(
assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack) );
}
#endif
-#if fts5YYSTACKDEPTH>0
- if( fts5yypParser->fts5yytos>fts5yypParser->fts5yystackEnd ){
- fts5yypParser->fts5yytos--;
- fts5yyStackOverflow(fts5yypParser);
- return;
- }
-#else
- if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz] ){
+ fts5yytos = fts5yypParser->fts5yytos;
+ if( fts5yytos>fts5yypParser->fts5yystackEnd ){
if( fts5yyGrowStack(fts5yypParser) ){
fts5yypParser->fts5yytos--;
fts5yyStackOverflow(fts5yypParser);
return;
}
+ fts5yytos = fts5yypParser->fts5yytos;
+ assert( fts5yytos <= fts5yypParser->fts5yystackEnd );
}
-#endif
if( fts5yyNewState > fts5YY_MAX_SHIFT ){
fts5yyNewState += fts5YY_MIN_REDUCE - fts5YY_MIN_SHIFTREDUCE;
}
- fts5yytos = fts5yypParser->fts5yytos;
fts5yytos->stateno = fts5yyNewState;
fts5yytos->major = fts5yyMajor;
fts5yytos->minor.fts5yy0 = fts5yyMinor;
@@ -240865,19 +244468,12 @@ static void sqlite3Fts5Parser(
(int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack));
}
#endif
-#if fts5YYSTACKDEPTH>0
if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){
- fts5yyStackOverflow(fts5yypParser);
- break;
- }
-#else
- if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){
if( fts5yyGrowStack(fts5yypParser) ){
fts5yyStackOverflow(fts5yypParser);
break;
}
}
-#endif
}
fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyruleno,fts5yymajor,fts5yyminor sqlite3Fts5ParserCTX_PARAM);
}else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
@@ -241249,6 +244845,7 @@ static int fts5HighlightCb(
return rc;
}
+
/*
** Implementation of highlight() function.
*/
@@ -241279,12 +244876,19 @@ static void fts5HighlightFunction(
sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
rc = SQLITE_OK;
}else if( ctx.zIn ){
+ const char *pLoc = 0; /* Locale of column iCol */
+ int nLoc = 0; /* Size of pLoc in bytes */
if( rc==SQLITE_OK ){
rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter);
}
if( rc==SQLITE_OK ){
- rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
+ rc = pApi->xColumnLocale(pFts, iCol, &pLoc, &nLoc);
+ }
+ if( rc==SQLITE_OK ){
+ rc = pApi->xTokenize_v2(
+ pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx, fts5HighlightCb
+ );
}
if( ctx.bOpen ){
fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1);
@@ -241481,6 +245085,8 @@ static void fts5SnippetFunction(
memset(&sFinder, 0, sizeof(Fts5SFinder));
for(i=0; ixColumnText(pFts, i, &sFinder.zDoc, &nDoc);
if( rc!=SQLITE_OK ) break;
- rc = pApi->xTokenize(pFts,
- sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb
+ rc = pApi->xColumnLocale(pFts, i, &pLoc, &nLoc);
+ if( rc!=SQLITE_OK ) break;
+ rc = pApi->xTokenize_v2(pFts,
+ sFinder.zDoc, nDoc, pLoc, nLoc, (void*)&sFinder, fts5SentenceFinderCb
);
if( rc!=SQLITE_OK ) break;
rc = pApi->xColumnSize(pFts, i, &nDocsize);
@@ -241547,6 +245155,9 @@ static void fts5SnippetFunction(
rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
}
if( ctx.zIn ){
+ const char *pLoc = 0; /* Locale of column iBestCol */
+ int nLoc = 0; /* Bytes in pLoc */
+
if( rc==SQLITE_OK ){
rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
}
@@ -241565,7 +245176,12 @@ static void fts5SnippetFunction(
}
if( rc==SQLITE_OK ){
- rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
+ rc = pApi->xColumnLocale(pFts, iBestCol, &pLoc, &nLoc);
+ }
+ if( rc==SQLITE_OK ){
+ rc = pApi->xTokenize_v2(
+ pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx,fts5HighlightCb
+ );
}
if( ctx.bOpen ){
fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1);
@@ -241749,6 +245365,53 @@ static void fts5Bm25Function(
}
}
+/*
+** Implementation of fts5_get_locale() function.
+*/
+static void fts5GetLocaleFunction(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ sqlite3_context *pCtx, /* Context for returning result/error */
+ int nVal, /* Number of values in apVal[] array */
+ sqlite3_value **apVal /* Array of trailing arguments */
+){
+ int iCol = 0;
+ int eType = 0;
+ int rc = SQLITE_OK;
+ const char *zLocale = 0;
+ int nLocale = 0;
+
+ /* xColumnLocale() must be available */
+ assert( pApi->iVersion>=4 );
+
+ if( nVal!=1 ){
+ const char *z = "wrong number of arguments to function fts5_get_locale()";
+ sqlite3_result_error(pCtx, z, -1);
+ return;
+ }
+
+ eType = sqlite3_value_numeric_type(apVal[0]);
+ if( eType!=SQLITE_INTEGER ){
+ const char *z = "non-integer argument passed to function fts5_get_locale()";
+ sqlite3_result_error(pCtx, z, -1);
+ return;
+ }
+
+ iCol = sqlite3_value_int(apVal[0]);
+ if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){
+ sqlite3_result_error_code(pCtx, SQLITE_RANGE);
+ return;
+ }
+
+ rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale);
+ if( rc!=SQLITE_OK ){
+ sqlite3_result_error_code(pCtx, rc);
+ return;
+ }
+
+ sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT);
+}
+
static int sqlite3Fts5AuxInit(fts5_api *pApi){
struct Builtin {
const char *zFunc; /* Function name (nul-terminated) */
@@ -241756,9 +245419,10 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){
fts5_extension_function xFunc;/* Callback function */
void (*xDestroy)(void*); /* Destructor function */
} aBuiltin [] = {
- { "snippet", 0, fts5SnippetFunction, 0 },
- { "highlight", 0, fts5HighlightFunction, 0 },
- { "bm25", 0, fts5Bm25Function, 0 },
+ { "snippet", 0, fts5SnippetFunction, 0 },
+ { "highlight", 0, fts5HighlightFunction, 0 },
+ { "bm25", 0, fts5Bm25Function, 0 },
+ { "fts5_get_locale", 0, fts5GetLocaleFunction, 0 },
};
int rc = SQLITE_OK; /* Return code */
int i; /* To iterate through builtin functions */
@@ -242423,7 +246087,6 @@ static int fts5ConfigSetEnum(
** eventually free any such error message using sqlite3_free().
*/
static int fts5ConfigParseSpecial(
- Fts5Global *pGlobal,
Fts5Config *pConfig, /* Configuration object to update */
const char *zCmd, /* Special command to parse */
const char *zArg, /* Argument to parse */
@@ -242431,6 +246094,7 @@ static int fts5ConfigParseSpecial(
){
int rc = SQLITE_OK;
int nCmd = (int)strlen(zCmd);
+
if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){
const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES;
const char *p;
@@ -242487,12 +246151,11 @@ static int fts5ConfigParseSpecial(
if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){
const char *p = (const char*)zArg;
sqlite3_int64 nArg = strlen(zArg) + 1;
- char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg);
- char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2);
- char *pSpace = pDel;
+ char **azArg = sqlite3Fts5MallocZero(&rc, (sizeof(char*) + 2) * nArg);
- if( azArg && pSpace ){
- if( pConfig->pTok ){
+ if( azArg ){
+ char *pSpace = (char*)&azArg[nArg];
+ if( pConfig->t.azArg ){
*pzErr = sqlite3_mprintf("multiple tokenize=... directives");
rc = SQLITE_ERROR;
}else{
@@ -242515,16 +246178,14 @@ static int fts5ConfigParseSpecial(
*pzErr = sqlite3_mprintf("parse error in tokenize directive");
rc = SQLITE_ERROR;
}else{
- rc = sqlite3Fts5GetTokenizer(pGlobal,
- (const char**)azArg, (int)nArg, pConfig,
- pzErr
- );
+ pConfig->t.azArg = (const char**)azArg;
+ pConfig->t.nArg = nArg;
+ azArg = 0;
}
}
}
-
sqlite3_free(azArg);
- sqlite3_free(pDel);
+
return rc;
}
@@ -242553,6 +246214,16 @@ static int fts5ConfigParseSpecial(
return rc;
}
+ if( sqlite3_strnicmp("contentless_unindexed", zCmd, nCmd)==0 ){
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
+ *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive");
+ rc = SQLITE_ERROR;
+ }else{
+ pConfig->bContentlessUnindexed = (zArg[0]=='1');
+ }
+ return rc;
+ }
+
if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){
if( pConfig->zContentRowid ){
*pzErr = sqlite3_mprintf("multiple content_rowid=... directives");
@@ -242573,6 +246244,16 @@ static int fts5ConfigParseSpecial(
return rc;
}
+ if( sqlite3_strnicmp("locale", zCmd, nCmd)==0 ){
+ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){
+ *pzErr = sqlite3_mprintf("malformed locale=... directive");
+ rc = SQLITE_ERROR;
+ }else{
+ pConfig->bLocale = (zArg[0]=='1');
+ }
+ return rc;
+ }
+
if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){
const Fts5Enum aDetail[] = {
{ "none", FTS5_DETAIL_NONE },
@@ -242601,16 +246282,6 @@ static int fts5ConfigParseSpecial(
return SQLITE_ERROR;
}
-/*
-** Allocate an instance of the default tokenizer ("simple") at
-** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error
-** code if an error occurs.
-*/
-static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){
- assert( pConfig->pTok==0 && pConfig->pTokApi==0 );
- return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0);
-}
-
/*
** Gobble up the first bareword or quoted word from the input buffer zIn.
** Return a pointer to the character immediately following the last in
@@ -242670,7 +246341,8 @@ static int fts5ConfigParseColumn(
Fts5Config *p,
char *zCol,
char *zArg,
- char **pzErr
+ char **pzErr,
+ int *pbUnindexed
){
int rc = SQLITE_OK;
if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME)
@@ -242681,6 +246353,7 @@ static int fts5ConfigParseColumn(
}else if( zArg ){
if( 0==sqlite3_stricmp(zArg, "unindexed") ){
p->abUnindexed[p->nCol] = 1;
+ *pbUnindexed = 1;
}else{
*pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg);
rc = SQLITE_ERROR;
@@ -242701,11 +246374,26 @@ static int fts5ConfigMakeExprlist(Fts5Config *p){
sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid);
if( p->eContent!=FTS5_CONTENT_NONE ){
+ assert( p->eContent==FTS5_CONTENT_EXTERNAL
+ || p->eContent==FTS5_CONTENT_NORMAL
+ || p->eContent==FTS5_CONTENT_UNINDEXED
+ );
for(i=0; inCol; i++){
if( p->eContent==FTS5_CONTENT_EXTERNAL ){
sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]);
- }else{
+ }else if( p->eContent==FTS5_CONTENT_NORMAL || p->abUnindexed[i] ){
sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i);
+ }else{
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL");
+ }
+ }
+ }
+ if( p->eContent==FTS5_CONTENT_NORMAL && p->bLocale ){
+ for(i=0; inCol; i++){
+ if( p->abUnindexed[i]==0 ){
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.l%d", i);
+ }else{
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL");
}
}
}
@@ -242739,10 +246427,12 @@ static int sqlite3Fts5ConfigParse(
Fts5Config *pRet; /* New object to return */
int i;
sqlite3_int64 nByte;
+ int bUnindexed = 0; /* True if there are one or more UNINDEXED */
*ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config));
if( pRet==0 ) return SQLITE_NOMEM;
memset(pRet, 0, sizeof(Fts5Config));
+ pRet->pGlobal = pGlobal;
pRet->db = db;
pRet->iCookie = -1;
@@ -242791,13 +246481,13 @@ static int sqlite3Fts5ConfigParse(
rc = SQLITE_ERROR;
}else{
if( bOption ){
- rc = fts5ConfigParseSpecial(pGlobal, pRet,
+ rc = fts5ConfigParseSpecial(pRet,
ALWAYS(zOne)?zOne:"",
zTwo?zTwo:"",
pzErr
);
}else{
- rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
+ rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr, &bUnindexed);
zOne = 0;
}
}
@@ -242829,11 +246519,17 @@ static int sqlite3Fts5ConfigParse(
rc = SQLITE_ERROR;
}
- /* If a tokenizer= option was successfully parsed, the tokenizer has
- ** already been allocated. Otherwise, allocate an instance of the default
- ** tokenizer (unicode61) now. */
- if( rc==SQLITE_OK && pRet->pTok==0 ){
- rc = fts5ConfigDefaultTokenizer(pGlobal, pRet);
+ /* We only allow contentless_unindexed=1 if the table is actually a
+ ** contentless one.
+ */
+ if( rc==SQLITE_OK
+ && pRet->bContentlessUnindexed
+ && pRet->eContent!=FTS5_CONTENT_NONE
+ ){
+ *pzErr = sqlite3_mprintf(
+ "contentless_unindexed=1 requires a contentless table"
+ );
+ rc = SQLITE_ERROR;
}
/* If no zContent option was specified, fill in the default values. */
@@ -242844,6 +246540,9 @@ static int sqlite3Fts5ConfigParse(
);
if( pRet->eContent==FTS5_CONTENT_NORMAL ){
zTail = "content";
+ }else if( bUnindexed && pRet->bContentlessUnindexed ){
+ pRet->eContent = FTS5_CONTENT_UNINDEXED;
+ zTail = "content";
}else if( pRet->bColumnsize ){
zTail = "docsize";
}
@@ -242877,9 +246576,14 @@ static int sqlite3Fts5ConfigParse(
static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){
if( pConfig ){
int i;
- if( pConfig->pTok ){
- pConfig->pTokApi->xDelete(pConfig->pTok);
+ if( pConfig->t.pTok ){
+ if( pConfig->t.pApi1 ){
+ pConfig->t.pApi1->xDelete(pConfig->t.pTok);
+ }else{
+ pConfig->t.pApi2->xDelete(pConfig->t.pTok);
+ }
}
+ sqlite3_free((char*)pConfig->t.azArg);
sqlite3_free(pConfig->zDb);
sqlite3_free(pConfig->zName);
for(i=0; inCol; i++){
@@ -242954,10 +246658,24 @@ static int sqlite3Fts5Tokenize(
void *pCtx, /* Context passed to xToken() */
int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
){
- if( pText==0 ) return SQLITE_OK;
- return pConfig->pTokApi->xTokenize(
- pConfig->pTok, pCtx, flags, pText, nText, xToken
- );
+ int rc = SQLITE_OK;
+ if( pText ){
+ if( pConfig->t.pTok==0 ){
+ rc = sqlite3Fts5LoadTokenizer(pConfig);
+ }
+ if( rc==SQLITE_OK ){
+ if( pConfig->t.pApi1 ){
+ rc = pConfig->t.pApi1->xTokenize(
+ pConfig->t.pTok, pCtx, flags, pText, nText, xToken
+ );
+ }else{
+ rc = pConfig->t.pApi2->xTokenize(pConfig->t.pTok, pCtx, flags,
+ pText, nText, pConfig->t.pLocale, pConfig->t.nLocale, xToken
+ );
+ }
+ }
+ }
+ return rc;
}
/*
@@ -243211,13 +246929,10 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
&& iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE
){
rc = SQLITE_ERROR;
- if( pConfig->pzErrmsg ){
- assert( 0==*pConfig->pzErrmsg );
- *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format "
- "(found %d, expected %d or %d) - run 'rebuild'",
- iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE
- );
- }
+ sqlite3Fts5ConfigErrmsg(pConfig, "invalid fts5 file format "
+ "(found %d, expected %d or %d) - run 'rebuild'",
+ iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE
+ );
}else{
pConfig->iVersion = iVersion;
}
@@ -243228,6 +246943,29 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
return rc;
}
+/*
+** Set (*pConfig->pzErrmsg) to point to an sqlite3_malloc()ed buffer
+** containing the error message created using printf() style formatting
+** string zFmt and its trailing arguments.
+*/
+static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){
+ va_list ap; /* ... printf arguments */
+ char *zMsg = 0;
+
+ va_start(ap, zFmt);
+ zMsg = sqlite3_vmprintf(zFmt, ap);
+ if( pConfig->pzErrmsg ){
+ assert( *pConfig->pzErrmsg==0 );
+ *pConfig->pzErrmsg = zMsg;
+ }else{
+ sqlite3_free(zMsg);
+ }
+
+ va_end(ap);
+}
+
+
+
/*
** 2014 May 31
**
@@ -243284,7 +247022,7 @@ struct Fts5Expr {
/*
** eType:
-** Expression node type. Always one of:
+** Expression node type. Usually one of:
**
** FTS5_AND (nChild, apChild valid)
** FTS5_OR (nChild, apChild valid)
@@ -243292,6 +247030,10 @@ struct Fts5Expr {
** FTS5_STRING (pNear valid)
** FTS5_TERM (pNear valid)
**
+** An expression node with eType==0 may also exist. It always matches zero
+** rows. This is created when a phrase containing no tokens is parsed.
+** e.g. "".
+**
** iHeight:
** Distance from this node to furthest leaf. This is always 0 for nodes
** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one
@@ -243512,11 +247254,12 @@ static int sqlite3Fts5ExprNew(
}while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
sqlite3Fts5ParserFree(pEngine, fts5ParseFree);
+ assert( sParse.pExpr || sParse.rc!=SQLITE_OK );
assert_expr_depth_ok(sParse.rc, sParse.pExpr);
/* If the LHS of the MATCH expression was a user column, apply the
** implicit column-filter. */
- if( iColnCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
+ if( sParse.rc==SQLITE_OK && iColnCol ){
int n = sizeof(Fts5Colset);
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
if( pColset ){
@@ -243533,15 +247276,7 @@ static int sqlite3Fts5ExprNew(
sParse.rc = SQLITE_NOMEM;
sqlite3Fts5ParseNodeFree(sParse.pExpr);
}else{
- if( !sParse.pExpr ){
- const int nByte = sizeof(Fts5ExprNode);
- pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte);
- if( pNew->pRoot ){
- pNew->pRoot->bEof = 1;
- }
- }else{
- pNew->pRoot = sParse.pExpr;
- }
+ pNew->pRoot = sParse.pExpr;
pNew->pIndex = 0;
pNew->pConfig = pConfig;
pNew->apExprPhrase = sParse.apPhrase;
@@ -243554,7 +247289,11 @@ static int sqlite3Fts5ExprNew(
}
sqlite3_free(sParse.apPhrase);
- *pzErr = sParse.zErr;
+ if( 0==*pzErr ){
+ *pzErr = sParse.zErr;
+ }else{
+ sqlite3_free(sParse.zErr);
+ }
return sParse.rc;
}
@@ -244355,7 +248094,7 @@ static int fts5ExprNodeTest_STRING(
}
}else{
Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
- if( pIter->iRowid==iLast || pIter->bEof ) continue;
+ if( pIter->iRowid==iLast ) continue;
bMatch = 0;
if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
return rc;
@@ -244877,9 +248616,6 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset(
Fts5ExprNearset *pRet = 0;
if( pParse->rc==SQLITE_OK ){
- if( pPhrase==0 ){
- return pNear;
- }
if( pNear==0 ){
sqlite3_int64 nByte;
nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
@@ -245101,6 +248837,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
}else if( sCtx.pPhrase->nTerm ){
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
}
+ assert( pParse->apPhrase!=0 );
pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
}
@@ -245120,7 +248857,7 @@ static int sqlite3Fts5ExprClonePhrase(
Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */
Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */
- if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){
+ if( !pExpr || iPhrase<0 || iPhrase>=pExpr->nPhrase ){
rc = SQLITE_RANGE;
}else{
pOrig = pExpr->apExprPhrase[iPhrase];
@@ -245488,6 +249225,9 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
}
}
+/*
+** Add pSub as a child of p.
+*/
static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
int ii = p->nChild;
if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
@@ -245632,19 +249372,23 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
"fts5: %s queries are not supported (detail!=full)",
pNear->nPhrase==1 ? "phrase": "NEAR"
);
- sqlite3_free(pRet);
+ sqlite3Fts5ParseNodeFree(pRet);
pRet = 0;
+ pNear = 0;
+ assert( pLeft==0 && pRight==0 );
}
}
}else{
+ assert( pNear==0 );
fts5ExprAddChildren(pRet, pLeft);
fts5ExprAddChildren(pRet, pRight);
+ pLeft = pRight = 0;
if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){
sqlite3Fts5ParseError(pParse,
"fts5 expression tree is too large (maximum depth %d)",
SQLITE_FTS5_MAX_EXPR_DEPTH
);
- sqlite3_free(pRet);
+ sqlite3Fts5ParseNodeFree(pRet);
pRet = 0;
}
}
@@ -245682,6 +249426,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
assert( pRight->eType==FTS5_STRING
|| pRight->eType==FTS5_TERM
|| pRight->eType==FTS5_EOF
+ || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd)
);
if( pLeft->eType==FTS5_AND ){
@@ -245695,6 +249440,8 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd(
);
if( pRight->eType==FTS5_EOF ){
+ assert( pParse->apPhrase!=0 );
+ assert( pParse->nPhrase>0 );
assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] );
sqlite3Fts5ParseNodeFree(pRight);
pRet = pLeft;
@@ -246327,6 +250074,7 @@ static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){
pNode->iRowid = iRowid;
pNode->bEof = 0;
switch( pNode->eType ){
+ case 0:
case FTS5_TERM:
case FTS5_STRING:
return (pNode->pNear->apPhrase[0]->poslist.n>0);
@@ -247910,11 +251658,12 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
int nByte = sqlite3_blob_bytes(p->pReader);
- sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING;
+ int szData = (sizeof(Fts5Data) + 7) & ~7;
+ sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING;
pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
if( pRet ){
pRet->nn = nByte;
- aOut = pRet->p = (u8*)&pRet[1];
+ aOut = pRet->p = (u8*)pRet + szData;
}else{
rc = SQLITE_NOMEM;
}
@@ -247937,6 +251686,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
}
assert( (pRet==0)==(p->rc!=SQLITE_OK) );
+ assert( pRet==0 || EIGHT_BYTE_ALIGNMENT( pRet->p ) );
return pRet;
}
@@ -249262,7 +253012,7 @@ static void fts5SegIterNext_None(
if( iOffiEndofDoclist ){
/* Next entry is on the current page */
- i64 iDelta;
+ u64 iDelta;
iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta);
pIter->iLeafOffset = iOff;
pIter->iRowid += iDelta;
@@ -251966,6 +255716,11 @@ static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){
nBest = nPercent;
}
}
+
+ /* If pLvl is already the input level to an ongoing merge, look no
+ ** further for a merge candidate. The caller should be allowed to
+ ** continue merging from pLvl first. */
+ if( pLvl->nMerge ) break;
}
}
return iRet;
@@ -253916,23 +257671,26 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){
static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){
int ii;
Fts5TokenDataIter *pT = pIter->pTokenDataIter;
+ Fts5Index *pIndex = pIter->pIndex;
for(ii=0; iinIter; ii++){
Fts5Iter *p = pT->apIter[ii];
if( p->base.bEof==0
&& (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowidpIndex, p, bFrom, iFrom);
+ fts5MultiIterNext(pIndex, p, bFrom, iFrom);
while( bFrom && p->base.bEof==0
&& p->base.iRowidpIndex->rc==SQLITE_OK
+ && pIndex->rc==SQLITE_OK
){
- fts5MultiIterNext(p->pIndex, p, 0, 0);
+ fts5MultiIterNext(pIndex, p, 0, 0);
}
}
}
- fts5IterSetOutputsTokendata(pIter);
+ if( pIndex->rc==SQLITE_OK ){
+ fts5IterSetOutputsTokendata(pIter);
+ }
}
/*
@@ -255887,7 +259645,7 @@ static int fts5structConnectMethod(
/*
** We must have a single struct=? constraint that will be passed through
-** into the xFilter method. If there is no valid stmt=? constraint,
+** into the xFilter method. If there is no valid struct=? constraint,
** then return an SQLITE_CONSTRAINT error.
*/
static int fts5structBestIndexMethod(
@@ -256229,8 +259987,17 @@ struct Fts5Global {
Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
Fts5Cursor *pCsr; /* First in list of all open cursors */
+ u32 aLocaleHdr[4];
};
+/*
+** Size of header on fts5_locale() values. And macro to access a buffer
+** containing a copy of the header from an Fts5Config pointer.
+*/
+#define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr ))
+#define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
+
+
/*
** Each auxiliary function registered with the FTS5 module is represented
** by an object of the following type. All such objects are stored as part
@@ -256249,11 +260016,28 @@ struct Fts5Auxiliary {
** Each tokenizer module registered with the FTS5 module is represented
** by an object of the following type. All such objects are stored as part
** of the Fts5Global.pTok list.
+**
+** bV2Native:
+** True if the tokenizer was registered using xCreateTokenizer_v2(), false
+** for xCreateTokenizer(). If this variable is true, then x2 is populated
+** with the routines as supplied by the caller and x1 contains synthesized
+** wrapper routines. In this case the user-data pointer passed to
+** x1.xCreate should be a pointer to the Fts5TokenizerModule structure,
+** not a copy of pUserData.
+**
+** Of course, if bV2Native is false, then x1 contains the real routines and
+** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule
+** object should be passed to x2.xCreate.
+**
+** The synthesized wrapper routines are necessary for xFindTokenizer(_v2)
+** calls.
*/
struct Fts5TokenizerModule {
char *zName; /* Name of tokenizer */
void *pUserData; /* User pointer passed to xCreate() */
- fts5_tokenizer x; /* Tokenizer functions */
+ int bV2Native; /* True if v2 native tokenizer */
+ fts5_tokenizer x1; /* Tokenizer functions */
+ fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
void (*xDestroy)(void*); /* Destructor function */
Fts5TokenizerModule *pNext; /* Next registered tokenizer module */
};
@@ -256341,7 +260125,7 @@ struct Fts5Cursor {
Fts5Auxiliary *pAux; /* Currently executing extension function */
Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
- /* Cache used by auxiliary functions xInst() and xInstCount() */
+ /* Cache used by auxiliary API functions xInst() and xInstCount() */
Fts5PoslistReader *aInstIter; /* One for each phrase */
int nInstAlloc; /* Size of aInst[] array (entries / 3) */
int nInstCount; /* Number of phrase instances */
@@ -256452,10 +260236,16 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){
#endif
/*
-** Return true if pTab is a contentless table.
+** Return true if pTab is a contentless table. If parameter bIncludeUnindexed
+** is true, this includes contentless tables that store UNINDEXED columns
+** only.
*/
-static int fts5IsContentless(Fts5FullTable *pTab){
- return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE;
+static int fts5IsContentless(Fts5FullTable *pTab, int bIncludeUnindexed){
+ int eContent = pTab->p.pConfig->eContent;
+ return (
+ eContent==FTS5_CONTENT_NONE
+ || (bIncludeUnindexed && eContent==FTS5_CONTENT_UNINDEXED)
+ );
}
/*
@@ -256523,8 +260313,12 @@ static int fts5InitVtab(
assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 );
}
if( rc==SQLITE_OK ){
+ pConfig->pzErrmsg = pzErr;
pTab->p.pConfig = pConfig;
pTab->pGlobal = pGlobal;
+ if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){
+ rc = sqlite3Fts5LoadTokenizer(pConfig);
+ }
}
/* Open the index sub-system */
@@ -256546,11 +260340,7 @@ static int fts5InitVtab(
/* Load the initial configuration */
if( rc==SQLITE_OK ){
- assert( pConfig->pzErrmsg==0 );
- pConfig->pzErrmsg = pzErr;
- rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
- sqlite3Fts5IndexRollback(pTab->p.pIndex);
- pConfig->pzErrmsg = 0;
+ rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1);
}
if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){
@@ -256560,6 +260350,7 @@ static int fts5InitVtab(
rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
}
+ if( pConfig ) pConfig->pzErrmsg = 0;
if( rc!=SQLITE_OK ){
fts5FreeVtab(pTab);
pTab = 0;
@@ -256627,10 +260418,10 @@ static int fts5UsePatternMatch(
){
assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB );
assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE );
- if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){
+ if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){
return 1;
}
- if( pConfig->ePattern==FTS5_PATTERN_LIKE
+ if( pConfig->t.ePattern==FTS5_PATTERN_LIKE
&& (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB)
){
return 1;
@@ -256677,10 +260468,10 @@ static int fts5UsePatternMatch(
** This function ensures that there is at most one "r" or "=". And that if
** there exists an "=" then there is no "<" or ">".
**
-** Costs are assigned as follows:
+** If an unusable MATCH operator is present in the WHERE clause, then
+** SQLITE_CONSTRAINT is returned.
**
-** a) If an unusable MATCH operator is present in the WHERE clause, the
-** cost is unconditionally set to 1e50 (a really big number).
+** Costs are assigned as follows:
**
** a) If a MATCH operator is present, the cost depends on the other
** constraints also present. As follows:
@@ -256713,7 +260504,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
int bSeenEq = 0;
int bSeenGt = 0;
int bSeenLt = 0;
- int bSeenMatch = 0;
+ int nSeenMatch = 0;
int bSeenRank = 0;
@@ -256744,18 +260535,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
/* A MATCH operator or equivalent */
if( p->usable==0 || iCol<0 ){
/* As there exists an unusable MATCH constraint this is an
- ** unusable plan. Set a prohibitively high cost. */
- pInfo->estimatedCost = 1e50;
- assert( iIdxStr < pInfo->nConstraint*6 + 1 );
- idxStr[iIdxStr] = 0;
- return SQLITE_OK;
+ ** unusable plan. Return SQLITE_CONSTRAINT. */
+ return SQLITE_CONSTRAINT;
}else{
if( iCol==nCol+1 ){
if( bSeenRank ) continue;
idxStr[iIdxStr++] = 'r';
bSeenRank = 1;
- }else if( iCol>=0 ){
- bSeenMatch = 1;
+ }else{
+ nSeenMatch++;
idxStr[iIdxStr++] = 'M';
sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol);
idxStr += strlen(&idxStr[iIdxStr]);
@@ -256772,6 +260560,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
idxStr += strlen(&idxStr[iIdxStr]);
pInfo->aConstraintUsage[i].argvIndex = ++iCons;
assert( idxStr[iIdxStr]=='\0' );
+ nSeenMatch++;
}else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){
idxStr[iIdxStr++] = '=';
bSeenEq = 1;
@@ -256808,7 +260597,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
*/
if( pInfo->nOrderBy==1 ){
int iSort = pInfo->aOrderBy[0].iColumn;
- if( iSort==(pConfig->nCol+1) && bSeenMatch ){
+ if( iSort==(pConfig->nCol+1) && nSeenMatch>0 ){
idxFlags |= FTS5_BI_ORDER_RANK;
}else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){
idxFlags |= FTS5_BI_ORDER_ROWID;
@@ -256823,14 +260612,17 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
/* Calculate the estimated cost based on the flags set in idxFlags. */
if( bSeenEq ){
- pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0;
- if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
+ pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0;
+ if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo);
}else if( bSeenLt && bSeenGt ){
- pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0;
+ pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0;
}else if( bSeenLt || bSeenGt ){
- pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0;
+ pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0;
}else{
- pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0;
+ pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0;
+ }
+ for(i=1; iestimatedCost *= 0.4;
}
pInfo->idxNum = idxFlags;
@@ -257106,6 +260898,7 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
}
}else{
rc = SQLITE_OK;
+ CsrFlagSet(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
}
break;
}
@@ -257135,7 +260928,7 @@ static int fts5PrepareStatement(
rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
SQLITE_PREPARE_PERSISTENT, &pRet, 0);
if( rc!=SQLITE_OK ){
- *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db));
+ sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db));
}
sqlite3_free(zSql);
}
@@ -257359,6 +261152,145 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){
return iDefault;
}
+/*
+** Set the error message on the virtual table passed as the first argument.
+*/
+static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){
+ va_list ap; /* ... printf arguments */
+ va_start(ap, zFormat);
+ sqlite3_free(p->p.base.zErrMsg);
+ p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
+ va_end(ap);
+}
+
+/*
+** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale
+** specified by pLocale/nLocale. The buffer indicated by pLocale must remain
+** valid until after the final call to sqlite3Fts5Tokenize() that will use
+** the locale.
+*/
+static void sqlite3Fts5SetLocale(
+ Fts5Config *pConfig,
+ const char *zLocale,
+ int nLocale
+){
+ Fts5TokenizerConfig *pT = &pConfig->t;
+ pT->pLocale = zLocale;
+ pT->nLocale = nLocale;
+}
+
+/*
+** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale().
+*/
+static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
+ sqlite3Fts5SetLocale(pConfig, 0, 0);
+}
+
+/*
+** Return true if the value passed as the only argument is an
+** fts5_locale() value.
+*/
+static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){
+ int ret = 0;
+ if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
+ /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case.
+ ** If the blob was created using zeroblob(), then sqlite3_value_blob()
+ ** may call malloc(). If this malloc() fails, then the values returned
+ ** by both value_blob() and value_bytes() will be 0. If value_bytes() were
+ ** called first, then the NULL pointer returned by value_blob() might
+ ** be dereferenced. */
+ const u8 *pBlob = sqlite3_value_blob(pVal);
+ int nBlob = sqlite3_value_bytes(pVal);
+ if( nBlob>FTS5_LOCALE_HDR_SIZE
+ && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE)
+ ){
+ ret = 1;
+ }
+ }
+ return ret;
+}
+
+/*
+** Value pVal is guaranteed to be an fts5_locale() value, according to
+** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale
+** from the value and returns them separately.
+**
+** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set
+** to point to buffers containing the text and locale, as utf-8,
+** respectively. In this case output parameters (*pnText) and (*pnLoc) are
+** set to the sizes in bytes of these two buffers.
+**
+** Or, if an error occurs, then an SQLite error code is returned. The final
+** value of the four output parameters is undefined in this case.
+*/
+static int sqlite3Fts5DecodeLocaleValue(
+ sqlite3_value *pVal,
+ const char **ppText,
+ int *pnText,
+ const char **ppLoc,
+ int *pnLoc
+){
+ const char *p = sqlite3_value_blob(pVal);
+ int n = sqlite3_value_bytes(pVal);
+ int nLoc = 0;
+
+ assert( sqlite3_value_type(pVal)==SQLITE_BLOB );
+ assert( n>FTS5_LOCALE_HDR_SIZE );
+
+ for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){
+ if( nLoc==(n-1) ){
+ return SQLITE_MISMATCH;
+ }
+ }
+ *ppLoc = &p[FTS5_LOCALE_HDR_SIZE];
+ *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE;
+
+ *ppText = &p[nLoc+1];
+ *pnText = n - nLoc - 1;
+ return SQLITE_OK;
+}
+
+/*
+** Argument pVal is the text of a full-text search expression. It may or
+** may not have been wrapped by fts5_locale(). This function extracts
+** the text of the expression, and sets output variable (*pzText) to
+** point to a nul-terminated buffer containing the expression.
+**
+** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called
+** to set the tokenizer to use the specified locale.
+**
+** If output variable (*pbFreeAndReset) is set to true, then the caller
+** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer
+** locale, and (b) call sqlite3_free() to free (*pzText).
+*/
+static int fts5ExtractExprText(
+ Fts5Config *pConfig, /* Fts5 configuration */
+ sqlite3_value *pVal, /* Value to extract expression text from */
+ char **pzText, /* OUT: nul-terminated buffer of text */
+ int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */
+){
+ int rc = SQLITE_OK;
+
+ if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
+ const char *pText = 0;
+ int nText = 0;
+ const char *pLoc = 0;
+ int nLoc = 0;
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
+ *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText);
+ if( rc==SQLITE_OK ){
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
+ }
+ *pbFreeAndReset = 1;
+ }else{
+ *pzText = (char*)sqlite3_value_text(pVal);
+ *pbFreeAndReset = 0;
+ }
+
+ return rc;
+}
+
+
/*
** This is the xFilter interface for the virtual table. See
** the virtual table xFilter method documentation for additional
@@ -257393,13 +261325,7 @@ static int fts5FilterMethod(
int iIdxStr = 0;
Fts5Expr *pExpr = 0;
- if( pConfig->bLock ){
- pTab->p.base.zErrMsg = sqlite3_mprintf(
- "recursively defined fts5 content table"
- );
- return SQLITE_ERROR;
- }
-
+ assert( pConfig->bLock==0 );
if( pCsr->ePlan ){
fts5FreeCursorComponents(pCsr);
memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
@@ -257423,8 +261349,14 @@ static int fts5FilterMethod(
pRank = apVal[i];
break;
case 'M': {
- const char *zText = (const char*)sqlite3_value_text(apVal[i]);
+ char *zText = 0;
+ int bFreeAndReset = 0;
+ int bInternal = 0;
+
+ rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset);
+ if( rc!=SQLITE_OK ) goto filter_out;
if( zText==0 ) zText = "";
+
iCol = 0;
do{
iCol = iCol*10 + (idxStr[iIdxStr]-'0');
@@ -257436,7 +261368,7 @@ static int fts5FilterMethod(
** indicates that the MATCH expression is not a full text query,
** but a request for an internal parameter. */
rc = fts5SpecialMatch(pTab, pCsr, &zText[1]);
- goto filter_out;
+ bInternal = 1;
}else{
char **pzErr = &pTab->p.base.zErrMsg;
rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr);
@@ -257444,9 +261376,15 @@ static int fts5FilterMethod(
rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr);
pExpr = 0;
}
- if( rc!=SQLITE_OK ) goto filter_out;
}
+ if( bFreeAndReset ){
+ sqlite3_free(zText);
+ sqlite3Fts5ClearLocale(pConfig);
+ }
+
+ if( bInternal || rc!=SQLITE_OK ) goto filter_out;
+
break;
}
case 'L':
@@ -257534,9 +261472,7 @@ static int fts5FilterMethod(
}
}
}else if( pConfig->zContent==0 ){
- *pConfig->pzErrmsg = sqlite3_mprintf(
- "%s: table does not support scanning", pConfig->zName
- );
+ fts5SetVtabError(pTab,"%s: table does not support scanning",pConfig->zName);
rc = SQLITE_ERROR;
}else{
/* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup
@@ -257579,9 +261515,13 @@ static i64 fts5CursorRowid(Fts5Cursor *pCsr){
assert( pCsr->ePlan==FTS5_PLAN_MATCH
|| pCsr->ePlan==FTS5_PLAN_SORTED_MATCH
|| pCsr->ePlan==FTS5_PLAN_SOURCE
+ || pCsr->ePlan==FTS5_PLAN_SCAN
+ || pCsr->ePlan==FTS5_PLAN_ROWID
);
if( pCsr->pSorter ){
return pCsr->pSorter->iRowid;
+ }else if( pCsr->ePlan>=FTS5_PLAN_SCAN ){
+ return sqlite3_column_int64(pCsr->pStmt, 0);
}else{
return sqlite3Fts5ExprRowid(pCsr->pExpr);
}
@@ -257598,25 +261538,16 @@ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
int ePlan = pCsr->ePlan;
assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 );
- switch( ePlan ){
- case FTS5_PLAN_SPECIAL:
- *pRowid = 0;
- break;
-
- case FTS5_PLAN_SOURCE:
- case FTS5_PLAN_MATCH:
- case FTS5_PLAN_SORTED_MATCH:
- *pRowid = fts5CursorRowid(pCsr);
- break;
-
- default:
- *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
- break;
+ if( ePlan==FTS5_PLAN_SPECIAL ){
+ *pRowid = 0;
+ }else{
+ *pRowid = fts5CursorRowid(pCsr);
}
return SQLITE_OK;
}
+
/*
** If the cursor requires seeking (bSeekRequired flag is set), seek it.
** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise.
@@ -257653,8 +261584,13 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
rc = sqlite3_reset(pCsr->pStmt);
if( rc==SQLITE_OK ){
rc = FTS5_CORRUPT;
+ fts5SetVtabError((Fts5FullTable*)pTab,
+ "fts5: missing row %lld from content table %s",
+ fts5CursorRowid(pCsr),
+ pTab->pConfig->zContent
+ );
}else if( pTab->pConfig->pzErrmsg ){
- *pTab->pConfig->pzErrmsg = sqlite3_mprintf(
+ fts5SetVtabError((Fts5FullTable*)pTab,
"%s", sqlite3_errmsg(pTab->pConfig->db)
);
}
@@ -257663,14 +261599,6 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){
return rc;
}
-static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){
- va_list ap; /* ... printf arguments */
- va_start(ap, zFormat);
- assert( p->p.base.zErrMsg==0 );
- p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap);
- va_end(ap);
-}
-
/*
** This function is called to handle an FTS INSERT command. In other words,
** an INSERT statement of the form:
@@ -257708,7 +261636,7 @@ static int fts5SpecialInsert(
}
bLoadConfig = 1;
}else if( 0==sqlite3_stricmp("rebuild", zCmd) ){
- if( pConfig->eContent==FTS5_CONTENT_NONE ){
+ if( fts5IsContentless(pTab, 1) ){
fts5SetVtabError(pTab,
"'rebuild' may not be used with a contentless fts5 table"
);
@@ -257764,7 +261692,7 @@ static int fts5SpecialDelete(
int eType1 = sqlite3_value_type(apVal[1]);
if( eType1==SQLITE_INTEGER ){
sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]);
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0);
}
return rc;
}
@@ -257777,7 +261705,7 @@ static void fts5StorageInsert(
){
int rc = *pRc;
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid);
+ rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, 0, apVal, piRowid);
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid);
@@ -257785,6 +261713,67 @@ static void fts5StorageInsert(
*pRc = rc;
}
+/*
+**
+** This function is called when the user attempts an UPDATE on a contentless
+** table. Parameter bRowidModified is true if the UPDATE statement modifies
+** the rowid value. Parameter apVal[] contains the new values for each user
+** defined column of the fts5 table. pConfig is the configuration object of the
+** table being updated (guaranteed to be contentless). The contentless_delete=1
+** and contentless_unindexed=1 options may or may not be set.
+**
+** This function returns SQLITE_OK if the UPDATE can go ahead, or an SQLite
+** error code if it cannot. In this case an error message is also loaded into
+** pConfig. Output parameter (*pbContent) is set to true if the caller should
+** update the %_content table only - not the FTS index or any other shadow
+** table. This occurs when an UPDATE modifies only UNINDEXED columns of the
+** table.
+**
+** An UPDATE may proceed if:
+**
+** * The only columns modified are UNINDEXED columns, or
+**
+** * The contentless_delete=1 option was specified and all of the indexed
+** columns (not a subset) have been modified.
+*/
+static int fts5ContentlessUpdate(
+ Fts5Config *pConfig,
+ sqlite3_value **apVal,
+ int bRowidModified,
+ int *pbContent
+){
+ int ii;
+ int bSeenIndex = 0; /* Have seen modified indexed column */
+ int bSeenIndexNC = 0; /* Have seen unmodified indexed column */
+ int rc = SQLITE_OK;
+
+ for(ii=0; iinCol; ii++){
+ if( pConfig->abUnindexed[ii]==0 ){
+ if( sqlite3_value_nochange(apVal[ii]) ){
+ bSeenIndexNC++;
+ }else{
+ bSeenIndex++;
+ }
+ }
+ }
+
+ if( bSeenIndex==0 && bRowidModified==0 ){
+ *pbContent = 1;
+ }else{
+ if( bSeenIndexNC || pConfig->bContentlessDelete==0 ){
+ rc = SQLITE_ERROR;
+ sqlite3Fts5ConfigErrmsg(pConfig,
+ (pConfig->bContentlessDelete ?
+ "%s a subset of columns on fts5 contentless-delete table: %s" :
+ "%s contentless fts5 table: %s")
+ , "cannot UPDATE", pConfig->zName
+ );
+ }
+ }
+
+ return rc;
+}
+
/*
** This function is the implementation of the xUpdate callback used by
** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
@@ -257846,6 +261835,7 @@ static int fts5UpdateMethod(
rc = SQLITE_ERROR;
}else{
rc = fts5SpecialDelete(pTab, apVal);
+ bUpdateOrDelete = 1;
}
}else{
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
@@ -257870,41 +261860,46 @@ static int fts5UpdateMethod(
assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
assert( nArg!=1 || eType0==SQLITE_INTEGER );
- /* Filter out attempts to run UPDATE or DELETE on contentless tables.
- ** This is not suported. Except - they are both supported if the CREATE
- ** VIRTUAL TABLE statement contained "contentless_delete=1". */
- if( eType0==SQLITE_INTEGER
- && pConfig->eContent==FTS5_CONTENT_NONE
- && pConfig->bContentlessDelete==0
- ){
- pTab->p.base.zErrMsg = sqlite3_mprintf(
- "cannot %s contentless fts5 table: %s",
- (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
- );
- rc = SQLITE_ERROR;
- }
-
/* DELETE */
- else if( nArg==1 ){
- i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
- bUpdateOrDelete = 1;
+ if( nArg==1 ){
+ /* It is only possible to DELETE from a contentless table if the
+ ** contentless_delete=1 flag is set. */
+ if( fts5IsContentless(pTab, 1) && pConfig->bContentlessDelete==0 ){
+ fts5SetVtabError(pTab,
+ "cannot DELETE from contentless fts5 table: %s", pConfig->zName
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0);
+ bUpdateOrDelete = 1;
+ }
}
/* INSERT or UPDATE */
else{
int eType1 = sqlite3_value_numeric_type(apVal[1]);
- if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){
- rc = SQLITE_MISMATCH;
+ /* It is an error to write an fts5_locale() value to a table without
+ ** the locale=1 option. */
+ if( pConfig->bLocale==0 ){
+ int ii;
+ for(ii=0; iinCol; ii++){
+ sqlite3_value *pVal = apVal[ii+2];
+ if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
+ fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
+ rc = SQLITE_MISMATCH;
+ goto update_out;
+ }
+ }
}
- else if( eType0!=SQLITE_INTEGER ){
+ if( eType0!=SQLITE_INTEGER ){
/* An INSERT statement. If the conflict-mode is REPLACE, first remove
** the current entry (if any). */
if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
+ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0);
bUpdateOrDelete = 1;
}
fts5StorageInsert(&rc, pTab, apVal, pRowid);
@@ -257912,30 +261907,57 @@ static int fts5UpdateMethod(
/* UPDATE */
else{
+ Fts5Storage *pStorage = pTab->pStorage;
i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */
i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */
- if( eType1==SQLITE_INTEGER && iOld!=iNew ){
+ int bContent = 0; /* Content only update */
+
+ /* If this is a contentless table (including contentless_unindexed=1
+ ** tables), check if the UPDATE may proceed. */
+ if( fts5IsContentless(pTab, 1) ){
+ rc = fts5ContentlessUpdate(pConfig, &apVal[2], iOld!=iNew, &bContent);
+ if( rc!=SQLITE_OK ) goto update_out;
+ }
+
+ if( eType1!=SQLITE_INTEGER ){
+ rc = SQLITE_MISMATCH;
+ }else if( iOld!=iNew ){
+ assert( bContent==0 );
if( eConflict==SQLITE_REPLACE ){
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+ rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1);
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
+ rc = sqlite3Fts5StorageDelete(pStorage, iNew, 0, 0);
}
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}else{
- rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
+ rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld);
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+ rc = sqlite3Fts5StorageContentInsert(pStorage, 0, apVal, pRowid);
}
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid);
+ rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 0);
}
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageIndexInsert(pStorage, apVal, *pRowid);
+ }
+ }
+ }else if( bContent ){
+ /* This occurs when an UPDATE on a contentless table affects *only*
+ ** UNINDEXED columns. This is a no-op for contentless_unindexed=0
+ ** tables, or a write to the %_content table only for =1 tables. */
+ assert( fts5IsContentless(pTab, 1) );
+ rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid);
}
}else{
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+ rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1);
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
bUpdateOrDelete = 1;
+ sqlite3Fts5StorageReleaseDeleteRow(pStorage);
}
+
}
}
@@ -257952,6 +261974,7 @@ static int fts5UpdateMethod(
}
}
+ update_out:
pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
@@ -257973,9 +261996,11 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
** Implementation of xBegin() method.
*/
static int fts5BeginMethod(sqlite3_vtab *pVtab){
- fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
- fts5NewTransaction((Fts5FullTable*)pVtab);
- return SQLITE_OK;
+ int rc = fts5NewTransaction((Fts5FullTable*)pVtab);
+ if( rc==SQLITE_OK ){
+ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0);
+ }
+ return rc;
}
/*
@@ -258029,17 +262054,40 @@ static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){
return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow);
}
-static int fts5ApiTokenize(
+/*
+** Implementation of xTokenize_v2() API.
+*/
+static int fts5ApiTokenize_v2(
Fts5Context *pCtx,
const char *pText, int nText,
+ const char *pLoc, int nLoc,
void *pUserData,
int (*xToken)(void*, int, const char*, int, int, int)
){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
- return sqlite3Fts5Tokenize(
- pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
+ int rc = SQLITE_OK;
+
+ sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc);
+ rc = sqlite3Fts5Tokenize(pTab->pConfig,
+ FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
);
+ sqlite3Fts5SetLocale(pTab->pConfig, 0, 0);
+
+ return rc;
+}
+
+/*
+** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0
+** passed as the locale.
+*/
+static int fts5ApiTokenize(
+ Fts5Context *pCtx,
+ const char *pText, int nText,
+ void *pUserData,
+ int (*xToken)(void*, int, const char*, int, int, int)
+){
+ return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken);
}
static int fts5ApiPhraseCount(Fts5Context *pCtx){
@@ -258052,6 +262100,49 @@ static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
}
+/*
+** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This
+** function extracts the text value of column iCol of the current row.
+** Additionally, if there is an associated locale, it invokes
+** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller
+** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point
+** after this function returns.
+**
+** If successful, (*ppText) is set to point to a buffer containing the text
+** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that
+** buffer in bytes. It is not guaranteed to be nul-terminated. If an error
+** occurs, an SQLite error code is returned. The final values of the two
+** output parameters are undefined in this case.
+*/
+static int fts5TextFromStmt(
+ Fts5Config *pConfig,
+ sqlite3_stmt *pStmt,
+ int iCol,
+ const char **ppText,
+ int *pnText
+){
+ sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1);
+ const char *pLoc = 0;
+ int nLoc = 0;
+ int rc = SQLITE_OK;
+
+ if( pConfig->bLocale
+ && pConfig->eContent==FTS5_CONTENT_EXTERNAL
+ && sqlite3Fts5IsLocaleValue(pConfig, pVal)
+ ){
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc);
+ }else{
+ *ppText = (const char*)sqlite3_value_text(pVal);
+ *pnText = sqlite3_value_bytes(pVal);
+ if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol);
+ nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol);
+ }
+ }
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
+ return rc;
+}
+
static int fts5ApiColumnText(
Fts5Context *pCtx,
int iCol,
@@ -258061,28 +262152,35 @@ static int fts5ApiColumnText(
int rc = SQLITE_OK;
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
+
+ assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
if( iCol<0 || iCol>=pTab->pConfig->nCol ){
rc = SQLITE_RANGE;
- }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab))
- || pCsr->ePlan==FTS5_PLAN_SPECIAL
- ){
+ }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab), 0) ){
*pz = 0;
*pn = 0;
}else{
rc = fts5SeekCursor(pCsr, 0);
if( rc==SQLITE_OK ){
- *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1);
- *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
+ rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn);
+ sqlite3Fts5ClearLocale(pTab->pConfig);
}
}
return rc;
}
+/*
+** This is called by various API functions - xInst, xPhraseFirst,
+** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase
+** of the current row. This function works for both detail=full tables (in
+** which case the position-list was read from the fts index) or for other
+** detail= modes if the row content is available.
+*/
static int fts5CsrPoslist(
- Fts5Cursor *pCsr,
- int iPhrase,
- const u8 **pa,
- int *pn
+ Fts5Cursor *pCsr, /* Fts5 cursor object */
+ int iPhrase, /* Phrase to find position list for */
+ const u8 **pa, /* OUT: Pointer to position list buffer */
+ int *pn /* OUT: Size of (*pa) in bytes */
){
Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
int rc = SQLITE_OK;
@@ -258090,20 +262188,32 @@ static int fts5CsrPoslist(
if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){
rc = SQLITE_RANGE;
+ }else if( pConfig->eDetail!=FTS5_DETAIL_FULL
+ && fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1)
+ ){
+ *pa = 0;
+ *pn = 0;
+ return SQLITE_OK;
}else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){
if( pConfig->eDetail!=FTS5_DETAIL_FULL ){
Fts5PoslistPopulator *aPopulator;
int i;
+
aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive);
if( aPopulator==0 ) rc = SQLITE_NOMEM;
+ if( rc==SQLITE_OK ){
+ rc = fts5SeekCursor(pCsr, 0);
+ }
for(i=0; inCol && rc==SQLITE_OK; i++){
- int n; const char *z;
- rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n);
+ const char *z = 0;
+ int n = 0;
+ rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n);
if( rc==SQLITE_OK ){
rc = sqlite3Fts5ExprPopulatePoslists(
pConfig, pCsr->pExpr, aPopulator, i, z, n
);
}
+ sqlite3Fts5ClearLocale(pConfig);
}
sqlite3_free(aPopulator);
@@ -258128,7 +262238,6 @@ static int fts5CsrPoslist(
*pn = 0;
}
-
return rc;
}
@@ -258197,7 +262306,8 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){
aInst[0] = iBest;
aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos);
aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos);
- if( aInst[1]<0 || aInst[1]>=nCol ){
+ assert( aInst[1]>=0 );
+ if( aInst[1]>=nCol ){
rc = FTS5_CORRUPT;
break;
}
@@ -258275,7 +262385,7 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
if( pConfig->bColumnsize ){
i64 iRowid = fts5CursorRowid(pCsr);
rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize);
- }else if( pConfig->zContent==0 ){
+ }else if( !pConfig->zContent || pConfig->eContent==FTS5_CONTENT_UNINDEXED ){
int i;
for(i=0; inCol; i++){
if( pConfig->abUnindexed[i]==0 ){
@@ -258284,17 +262394,19 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
}
}else{
int i;
+ rc = fts5SeekCursor(pCsr, 0);
for(i=0; rc==SQLITE_OK && inCol; i++){
if( pConfig->abUnindexed[i]==0 ){
- const char *z; int n;
- void *p = (void*)(&pCsr->aColumnSize[i]);
+ const char *z = 0;
+ int n = 0;
pCsr->aColumnSize[i] = 0;
- rc = fts5ApiColumnText(pCtx, i, &z, &n);
+ rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n);
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5Tokenize(
- pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb
+ rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX,
+ z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb
);
}
+ sqlite3Fts5ClearLocale(pConfig);
}
}
}
@@ -258374,11 +262486,10 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){
}
static void fts5ApiPhraseNext(
- Fts5Context *pUnused,
+ Fts5Context *pCtx,
Fts5PhraseIter *pIter,
int *piCol, int *piOff
){
- UNUSED_PARAM(pUnused);
if( pIter->a>=pIter->b ){
*piCol = -1;
*piOff = -1;
@@ -258386,8 +262497,12 @@ static void fts5ApiPhraseNext(
int iVal;
pIter->a += fts5GetVarint32(pIter->a, iVal);
if( iVal==1 ){
+ /* Avoid returning a (*piCol) value that is too large for the table,
+ ** even if the position-list is corrupt. The caller might not be
+ ** expecting it. */
+ int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol;
pIter->a += fts5GetVarint32(pIter->a, iVal);
- *piCol = iVal;
+ *piCol = (iVal>=nCol ? nCol-1 : iVal);
*piOff = 0;
pIter->a += fts5GetVarint32(pIter->a, iVal);
}
@@ -258537,8 +262652,48 @@ static int fts5ApiQueryPhrase(Fts5Context*, int, void*,
int(*)(const Fts5ExtensionApi*, Fts5Context*, void*)
);
+/*
+** The xColumnLocale() API.
+*/
+static int fts5ApiColumnLocale(
+ Fts5Context *pCtx,
+ int iCol,
+ const char **pzLocale,
+ int *pnLocale
+){
+ int rc = SQLITE_OK;
+ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
+ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig;
+
+ *pzLocale = 0;
+ *pnLocale = 0;
+
+ assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
+ if( iCol<0 || iCol>=pConfig->nCol ){
+ rc = SQLITE_RANGE;
+ }else if(
+ pConfig->abUnindexed[iCol]==0
+ && 0==fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1)
+ && pConfig->bLocale
+ ){
+ rc = fts5SeekCursor(pCsr, 0);
+ if( rc==SQLITE_OK ){
+ const char *zDummy = 0;
+ int nDummy = 0;
+ rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy);
+ if( rc==SQLITE_OK ){
+ *pzLocale = pConfig->t.pLocale;
+ *pnLocale = pConfig->t.nLocale;
+ }
+ sqlite3Fts5ClearLocale(pConfig);
+ }
+ }
+
+ return rc;
+}
+
static const Fts5ExtensionApi sFts5Api = {
- 3, /* iVersion */
+ 4, /* iVersion */
fts5ApiUserData,
fts5ApiColumnCount,
fts5ApiRowCount,
@@ -258559,7 +262714,9 @@ static const Fts5ExtensionApi sFts5Api = {
fts5ApiPhraseFirstColumn,
fts5ApiPhraseNextColumn,
fts5ApiQueryToken,
- fts5ApiInstToken
+ fts5ApiInstToken,
+ fts5ApiColumnLocale,
+ fts5ApiTokenize_v2
};
/*
@@ -258610,6 +262767,7 @@ static void fts5ApiInvoke(
sqlite3_value **argv
){
assert( pCsr->pAux==0 );
+ assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL );
pCsr->pAux = pAux;
pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv);
pCsr->pAux = 0;
@@ -258623,6 +262781,21 @@ static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){
return pCsr;
}
+/*
+** Parameter zFmt is a printf() style formatting string. This function
+** formats it using the trailing arguments and returns the result as
+** an error message to the context passed as the first argument.
+*/
+static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){
+ char *zErr = 0;
+ va_list ap;
+ va_start(ap, zFmt);
+ zErr = sqlite3_vmprintf(zFmt, ap);
+ sqlite3_result_error(pCtx, zErr, -1);
+ sqlite3_free(zErr);
+ va_end(ap);
+}
+
static void fts5ApiCallback(
sqlite3_context *context,
int argc,
@@ -258638,12 +262811,13 @@ static void fts5ApiCallback(
iCsrId = sqlite3_value_int64(argv[0]);
pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId);
- if( pCsr==0 || pCsr->ePlan==0 ){
- char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
+ if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){
+ fts5ResultError(context, "no such cursor: %lld", iCsrId);
}else{
+ sqlite3_vtab *pTab = pCsr->base.pVtab;
fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]);
+ sqlite3_free(pTab->zErrMsg);
+ pTab->zErrMsg = 0;
}
}
@@ -258761,8 +262935,8 @@ static int fts5ColumnMethod(
** auxiliary function. */
sqlite3_result_int64(pCtx, pCsr->iCsrId);
}else if( iCol==pConfig->nCol+1 ){
-
/* The value of the "rank" column. */
+
if( pCsr->ePlan==FTS5_PLAN_SOURCE ){
fts5PoslistBlob(pCtx, pCsr);
}else if(
@@ -258773,20 +262947,32 @@ static int fts5ColumnMethod(
fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg);
}
}
- }else if( !fts5IsContentless(pTab) ){
- pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
- rc = fts5SeekCursor(pCsr, 1);
- if( rc==SQLITE_OK ){
- sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
+ }else{
+ if( !sqlite3_vtab_nochange(pCtx) && pConfig->eContent!=FTS5_CONTENT_NONE ){
+ pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
+ rc = fts5SeekCursor(pCsr, 1);
+ if( rc==SQLITE_OK ){
+ sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
+ if( pConfig->bLocale
+ && pConfig->eContent==FTS5_CONTENT_EXTERNAL
+ && sqlite3Fts5IsLocaleValue(pConfig, pVal)
+ ){
+ const char *z = 0;
+ int n = 0;
+ rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT);
+ }
+ sqlite3Fts5ClearLocale(pConfig);
+ }else{
+ sqlite3_result_value(pCtx, pVal);
+ }
+ }
+
+ pConfig->pzErrmsg = 0;
}
- pConfig->pzErrmsg = 0;
- }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){
- char *zErr = sqlite3_mprintf("cannot UPDATE a subset of "
- "columns on fts5 contentless-delete table: %s", pConfig->zName
- );
- sqlite3_result_error(pCtx, zErr, -1);
- sqlite3_free(zErr);
}
+
return rc;
}
@@ -258926,47 +263112,210 @@ static int fts5CreateAux(
}
/*
-** Register a new tokenizer. This is the implementation of the
-** fts5_api.xCreateTokenizer() method.
+** This function is used by xCreateTokenizer_v2() and xCreateTokenizer().
+** It allocates and partially populates a new Fts5TokenizerModule object.
+** The new object is already linked into the Fts5Global context before
+** returning.
+**
+** If successful, SQLITE_OK is returned and a pointer to the new
+** Fts5TokenizerModule object returned via output parameter (*ppNew). All
+** that is required is for the caller to fill in the methods in
+** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native
+** as appropriate.
+**
+** If an error occurs, an SQLite error code is returned and the final value
+** of (*ppNew) undefined.
*/
-static int fts5CreateTokenizer(
- fts5_api *pApi, /* Global context (one per db handle) */
+static int fts5NewTokenizerModule(
+ Fts5Global *pGlobal, /* Global context (one per db handle) */
const char *zName, /* Name of new function */
void *pUserData, /* User data for aux. function */
- fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
- void(*xDestroy)(void*) /* Destructor for pUserData */
+ void(*xDestroy)(void*), /* Destructor for pUserData */
+ Fts5TokenizerModule **ppNew
){
- Fts5Global *pGlobal = (Fts5Global*)pApi;
- Fts5TokenizerModule *pNew;
- sqlite3_int64 nName; /* Size of zName and its \0 terminator */
- sqlite3_int64 nByte; /* Bytes of space to allocate */
int rc = SQLITE_OK;
+ Fts5TokenizerModule *pNew;
+ sqlite3_int64 nName; /* Size of zName and its \0 terminator */
+ sqlite3_int64 nByte; /* Bytes of space to allocate */
nName = strlen(zName) + 1;
nByte = sizeof(Fts5TokenizerModule) + nName;
- pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte);
+ *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte);
if( pNew ){
- memset(pNew, 0, (size_t)nByte);
pNew->zName = (char*)&pNew[1];
memcpy(pNew->zName, zName, nName);
pNew->pUserData = pUserData;
- pNew->x = *pTokenizer;
pNew->xDestroy = xDestroy;
pNew->pNext = pGlobal->pTok;
pGlobal->pTok = pNew;
if( pNew->pNext==0 ){
pGlobal->pDfltTok = pNew;
}
+ }
+
+ return rc;
+}
+
+/*
+** An instance of this type is used as the Fts5Tokenizer object for
+** wrapper tokenizers - those that provide access to a v1 tokenizer via
+** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer
+** via the fts5_tokenizer API.
+*/
+typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
+struct Fts5VtoVTokenizer {
+ int bV2Native; /* True if v2 native tokenizer */
+ fts5_tokenizer x1; /* Tokenizer functions */
+ fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
+ Fts5Tokenizer *pReal;
+};
+
+/*
+** Create a wrapper tokenizer. The context argument pCtx points to the
+** Fts5TokenizerModule object.
+*/
+static int fts5VtoVCreate(
+ void *pCtx,
+ const char **azArg,
+ int nArg,
+ Fts5Tokenizer **ppOut
+){
+ Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx;
+ Fts5VtoVTokenizer *pNew = 0;
+ int rc = SQLITE_OK;
+
+ pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
+ if( rc==SQLITE_OK ){
+ pNew->x1 = pMod->x1;
+ pNew->x2 = pMod->x2;
+ pNew->bV2Native = pMod->bV2Native;
+ if( pMod->bV2Native ){
+ rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
+ }else{
+ rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
+ }
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(pNew);
+ pNew = 0;
+ }
+ }
+
+ *ppOut = (Fts5Tokenizer*)pNew;
+ return rc;
+}
+
+/*
+** Delete an Fts5VtoVTokenizer wrapper tokenizer.
+*/
+static void fts5VtoVDelete(Fts5Tokenizer *pTok){
+ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
+ if( p ){
+ if( p->bV2Native ){
+ p->x2.xDelete(p->pReal);
+ }else{
+ p->x1.xDelete(p->pReal);
+ }
+ sqlite3_free(p);
+ }
+}
+
+
+/*
+** xTokenizer method for a wrapper tokenizer that offers the v1 interface
+** (no support for locales).
+*/
+static int fts5V1toV2Tokenize(
+ Fts5Tokenizer *pTok,
+ void *pCtx, int flags,
+ const char *pText, int nText,
+ int (*xToken)(void*, int, const char*, int, int, int)
+){
+ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
+ assert( p->bV2Native );
+ return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
+}
+
+/*
+** xTokenizer method for a wrapper tokenizer that offers the v2 interface
+** (with locale support).
+*/
+static int fts5V2toV1Tokenize(
+ Fts5Tokenizer *pTok,
+ void *pCtx, int flags,
+ const char *pText, int nText,
+ const char *pLocale, int nLocale,
+ int (*xToken)(void*, int, const char*, int, int, int)
+){
+ Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
+ assert( p->bV2Native==0 );
+ UNUSED_PARAM2(pLocale,nLocale);
+ return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
+}
+
+/*
+** Register a new tokenizer. This is the implementation of the
+** fts5_api.xCreateTokenizer_v2() method.
+*/
+static int fts5CreateTokenizer_v2(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of new function */
+ void *pUserData, /* User data for aux. function */
+ fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */
+ void(*xDestroy)(void*) /* Destructor for pUserData */
+){
+ Fts5Global *pGlobal = (Fts5Global*)pApi;
+ int rc = SQLITE_OK;
+
+ if( pTokenizer->iVersion>2 ){
+ rc = SQLITE_ERROR;
}else{
- rc = SQLITE_NOMEM;
+ Fts5TokenizerModule *pNew = 0;
+ rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew);
+ if( pNew ){
+ pNew->x2 = *pTokenizer;
+ pNew->bV2Native = 1;
+ pNew->x1.xCreate = fts5VtoVCreate;
+ pNew->x1.xTokenize = fts5V1toV2Tokenize;
+ pNew->x1.xDelete = fts5VtoVDelete;
+ }
}
return rc;
}
+/*
+** The fts5_api.xCreateTokenizer() method.
+*/
+static int fts5CreateTokenizer(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of new function */
+ void *pUserData, /* User data for aux. function */
+ fts5_tokenizer *pTokenizer, /* Tokenizer implementation */
+ void(*xDestroy)(void*) /* Destructor for pUserData */
+){
+ Fts5TokenizerModule *pNew = 0;
+ int rc = SQLITE_OK;
+
+ rc = fts5NewTokenizerModule(
+ (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew
+ );
+ if( pNew ){
+ pNew->x1 = *pTokenizer;
+ pNew->x2.xCreate = fts5VtoVCreate;
+ pNew->x2.xTokenize = fts5V2toV1Tokenize;
+ pNew->x2.xDelete = fts5VtoVDelete;
+ }
+ return rc;
+}
+
+/*
+** Search the global context passed as the first argument for a tokenizer
+** module named zName. If found, return a pointer to the Fts5TokenizerModule
+** object. Otherwise, return NULL.
+*/
static Fts5TokenizerModule *fts5LocateTokenizer(
- Fts5Global *pGlobal,
- const char *zName
+ Fts5Global *pGlobal, /* Global (one per db handle) object */
+ const char *zName /* Name of tokenizer module to find */
){
Fts5TokenizerModule *pMod = 0;
@@ -258981,6 +263330,36 @@ static Fts5TokenizerModule *fts5LocateTokenizer(
return pMod;
}
+/*
+** Find a tokenizer. This is the implementation of the
+** fts5_api.xFindTokenizer_v2() method.
+*/
+static int fts5FindTokenizer_v2(
+ fts5_api *pApi, /* Global context (one per db handle) */
+ const char *zName, /* Name of tokenizer */
+ void **ppUserData,
+ fts5_tokenizer_v2 **ppTokenizer /* Populate this object */
+){
+ int rc = SQLITE_OK;
+ Fts5TokenizerModule *pMod;
+
+ pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
+ if( pMod ){
+ if( pMod->bV2Native ){
+ *ppUserData = pMod->pUserData;
+ }else{
+ *ppUserData = (void*)pMod;
+ }
+ *ppTokenizer = &pMod->x2;
+ }else{
+ *ppTokenizer = 0;
+ *ppUserData = 0;
+ rc = SQLITE_ERROR;
+ }
+
+ return rc;
+}
+
/*
** Find a tokenizer. This is the implementation of the
** fts5_api.xFindTokenizer() method.
@@ -258996,53 +263375,75 @@ static int fts5FindTokenizer(
pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName);
if( pMod ){
- *pTokenizer = pMod->x;
- *ppUserData = pMod->pUserData;
+ if( pMod->bV2Native==0 ){
+ *ppUserData = pMod->pUserData;
+ }else{
+ *ppUserData = (void*)pMod;
+ }
+ *pTokenizer = pMod->x1;
}else{
- memset(pTokenizer, 0, sizeof(fts5_tokenizer));
+ memset(pTokenizer, 0, sizeof(*pTokenizer));
+ *ppUserData = 0;
rc = SQLITE_ERROR;
}
return rc;
}
-static int sqlite3Fts5GetTokenizer(
- Fts5Global *pGlobal,
- const char **azArg,
- int nArg,
- Fts5Config *pConfig,
- char **pzErr
-){
- Fts5TokenizerModule *pMod;
+/*
+** Attempt to instantiate the tokenizer.
+*/
+static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){
+ const char **azArg = pConfig->t.azArg;
+ const int nArg = pConfig->t.nArg;
+ Fts5TokenizerModule *pMod = 0;
int rc = SQLITE_OK;
- pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]);
+ pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]);
if( pMod==0 ){
assert( nArg>0 );
rc = SQLITE_ERROR;
- *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]);
+ sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]);
}else{
- rc = pMod->x.xCreate(
- pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok
+ int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0;
+ if( pMod->bV2Native ){
+ xCreate = pMod->x2.xCreate;
+ pConfig->t.pApi2 = &pMod->x2;
+ }else{
+ pConfig->t.pApi1 = &pMod->x1;
+ xCreate = pMod->x1.xCreate;
+ }
+
+ rc = xCreate(pMod->pUserData,
+ (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok
);
- pConfig->pTokApi = &pMod->x;
+
if( rc!=SQLITE_OK ){
- if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor");
- }else{
- pConfig->ePattern = sqlite3Fts5TokenizerPattern(
- pMod->x.xCreate, pConfig->pTok
+ if( rc!=SQLITE_NOMEM ){
+ sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor");
+ }
+ }else if( pMod->bV2Native==0 ){
+ pConfig->t.ePattern = sqlite3Fts5TokenizerPattern(
+ pMod->x1.xCreate, pConfig->t.pTok
);
}
}
if( rc!=SQLITE_OK ){
- pConfig->pTokApi = 0;
- pConfig->pTok = 0;
+ pConfig->t.pApi1 = 0;
+ pConfig->t.pApi2 = 0;
+ pConfig->t.pTok = 0;
}
return rc;
}
+
+/*
+** xDestroy callback passed to sqlite3_create_module(). This is invoked
+** when the db handle is being closed. Free memory associated with
+** tokenizers and aux functions registered with this db handle.
+*/
static void fts5ModuleDestroy(void *pCtx){
Fts5TokenizerModule *pTok, *pNextTok;
Fts5Auxiliary *pAux, *pNextAux;
@@ -259063,6 +263464,10 @@ static void fts5ModuleDestroy(void *pCtx){
sqlite3_free(pGlobal);
}
+/*
+** Implementation of the fts5() function used by clients to obtain the
+** API pointer.
+*/
static void fts5Fts5Func(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
@@ -259086,7 +263491,68 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2024-12-07 20:39:59 2aabe05e2e8cae4847a802ee2daddc1d7413d8fc560254d93ee3e72c14685b6c", -1, SQLITE_TRANSIENT);
+}
+
+/*
+** Implementation of fts5_locale(LOCALE, TEXT) function.
+**
+** If parameter LOCALE is NULL, or a zero-length string, then a copy of
+** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
+** text, and the value returned is a blob consisting of:
+**
+** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER).
+** * The LOCALE, as utf-8 text, followed by
+** * 0x00, followed by
+** * The TEXT, as utf-8 text.
+**
+** There is no final nul-terminator following the TEXT value.
+*/
+static void fts5LocaleFunc(
+ sqlite3_context *pCtx, /* Function call context */
+ int nArg, /* Number of args */
+ sqlite3_value **apArg /* Function arguments */
+){
+ const char *zLocale = 0;
+ int nLocale = 0;
+ const char *zText = 0;
+ int nText = 0;
+
+ assert( nArg==2 );
+ UNUSED_PARAM(nArg);
+
+ zLocale = (const char*)sqlite3_value_text(apArg[0]);
+ nLocale = sqlite3_value_bytes(apArg[0]);
+
+ zText = (const char*)sqlite3_value_text(apArg[1]);
+ nText = sqlite3_value_bytes(apArg[1]);
+
+ if( zLocale==0 || zLocale[0]=='\0' ){
+ sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
+ }else{
+ Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx);
+ u8 *pBlob = 0;
+ u8 *pCsr = 0;
+ int nBlob = 0;
+
+ nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText;
+ pBlob = (u8*)sqlite3_malloc(nBlob);
+ if( pBlob==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ return;
+ }
+
+ pCsr = pBlob;
+ memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE);
+ pCsr += FTS5_LOCALE_HDR_SIZE;
+ memcpy(pCsr, zLocale, nLocale);
+ pCsr += nLocale;
+ (*pCsr++) = 0x00;
+ if( zText ) memcpy(pCsr, zText, nText);
+ assert( &pCsr[nText]==&pBlob[nBlob] );
+
+ sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
+ }
}
/*
@@ -259121,18 +263587,25 @@ static int fts5IntegrityMethod(
assert( pzErr!=0 && *pzErr==0 );
UNUSED_PARAM(isQuick);
+ assert( pTab->p.pConfig->pzErrmsg==0 );
+ pTab->p.pConfig->pzErrmsg = pzErr;
rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0);
- if( (rc&0xff)==SQLITE_CORRUPT ){
- *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
- zSchema, zTabname);
- }else if( rc!=SQLITE_OK ){
- *pzErr = sqlite3_mprintf("unable to validate the inverted index for"
- " FTS5 table %s.%s: %s",
- zSchema, zTabname, sqlite3_errstr(rc));
+ if( *pzErr==0 && rc!=SQLITE_OK ){
+ if( (rc&0xff)==SQLITE_CORRUPT ){
+ *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s",
+ zSchema, zTabname);
+ rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM;
+ }else{
+ *pzErr = sqlite3_mprintf("unable to validate the inverted index for"
+ " FTS5 table %s.%s: %s",
+ zSchema, zTabname, sqlite3_errstr(rc));
+ }
}
+
sqlite3Fts5IndexCloseReader(pTab->p.pIndex);
+ pTab->p.pConfig->pzErrmsg = 0;
- return SQLITE_OK;
+ return rc;
}
static int fts5Init(sqlite3 *db){
@@ -259174,10 +263647,22 @@ static int fts5Init(sqlite3 *db){
void *p = (void*)pGlobal;
memset(pGlobal, 0, sizeof(Fts5Global));
pGlobal->db = db;
- pGlobal->api.iVersion = 2;
+ pGlobal->api.iVersion = 3;
pGlobal->api.xCreateFunction = fts5CreateAux;
pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
pGlobal->api.xFindTokenizer = fts5FindTokenizer;
+ pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2;
+ pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2;
+
+ /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector.
+ ** The constants below were generated randomly. */
+ sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr);
+ pGlobal->aLocaleHdr[0] ^= 0xF924976D;
+ pGlobal->aLocaleHdr[1] ^= 0x16596E13;
+ pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA;
+ pGlobal->aLocaleHdr[3] ^= 0x9B03A67F;
+ assert( sizeof(pGlobal->aLocaleHdr)==16 );
+
rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
@@ -259196,6 +263681,13 @@ static int fts5Init(sqlite3 *db){
p, fts5SourceIdFunc, 0, 0
);
}
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(
+ db, "fts5_locale", 2,
+ SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE,
+ p, fts5LocaleFunc, 0, 0
+ );
+ }
}
/* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
@@ -259270,13 +263762,40 @@ SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){
/* #include "fts5Int.h" */
+/*
+** pSavedRow:
+** SQL statement FTS5_STMT_LOOKUP2 is a copy of FTS5_STMT_LOOKUP, it
+** does a by-rowid lookup to retrieve a single row from the %_content
+** table or equivalent external-content table/view.
+**
+** However, FTS5_STMT_LOOKUP2 is only used when retrieving the original
+** values for a row being UPDATEd. In that case, the SQL statement is
+** not reset and pSavedRow is set to point at it. This is so that the
+** insert operation that follows the delete may access the original
+** row values for any new values for which sqlite3_value_nochange() returns
+** true. i.e. if the user executes:
+**
+** CREATE VIRTUAL TABLE ft USING fts5(a, b, c, locale=1);
+** ...
+** UPDATE fts SET a=?, b=? WHERE rowid=?;
+**
+** then the value passed to the xUpdate() method of this table as the
+** new.c value is an sqlite3_value_nochange() value. So in this case it
+** must be read from the saved row stored in Fts5Storage.pSavedRow.
+**
+** This is necessary - using sqlite3_value_nochange() instead of just having
+** SQLite pass the original value back via xUpdate() - so as not to discard
+** any locale information associated with such values.
+**
+*/
struct Fts5Storage {
Fts5Config *pConfig;
Fts5Index *pIndex;
int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */
i64 nTotalRow; /* Total number of rows in FTS table */
i64 *aTotalSize; /* Total sizes of each column */
- sqlite3_stmt *aStmt[11];
+ sqlite3_stmt *pSavedRow;
+ sqlite3_stmt *aStmt[12];
};
@@ -259290,14 +263809,15 @@ struct Fts5Storage {
# error "FTS5_STMT_LOOKUP mismatch"
#endif
-#define FTS5_STMT_INSERT_CONTENT 3
-#define FTS5_STMT_REPLACE_CONTENT 4
-#define FTS5_STMT_DELETE_CONTENT 5
-#define FTS5_STMT_REPLACE_DOCSIZE 6
-#define FTS5_STMT_DELETE_DOCSIZE 7
-#define FTS5_STMT_LOOKUP_DOCSIZE 8
-#define FTS5_STMT_REPLACE_CONFIG 9
-#define FTS5_STMT_SCAN 10
+#define FTS5_STMT_LOOKUP2 3
+#define FTS5_STMT_INSERT_CONTENT 4
+#define FTS5_STMT_REPLACE_CONTENT 5
+#define FTS5_STMT_DELETE_CONTENT 6
+#define FTS5_STMT_REPLACE_DOCSIZE 7
+#define FTS5_STMT_DELETE_DOCSIZE 8
+#define FTS5_STMT_LOOKUP_DOCSIZE 9
+#define FTS5_STMT_REPLACE_CONFIG 10
+#define FTS5_STMT_SCAN 11
/*
** Prepare the two insert statements - Fts5Storage.pInsertContent and
@@ -259327,6 +263847,7 @@ static int fts5StorageGetStmt(
"SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC",
"SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC",
"SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */
+ "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP2 */
"INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */
"REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */
@@ -259342,6 +263863,8 @@ static int fts5StorageGetStmt(
Fts5Config *pC = p->pConfig;
char *zSql = 0;
+ assert( ArraySize(azStmt)==ArraySize(p->aStmt) );
+
switch( eStmt ){
case FTS5_STMT_SCAN:
zSql = sqlite3_mprintf(azStmt[eStmt],
@@ -259358,6 +263881,7 @@ static int fts5StorageGetStmt(
break;
case FTS5_STMT_LOOKUP:
+ case FTS5_STMT_LOOKUP2:
zSql = sqlite3_mprintf(azStmt[eStmt],
pC->zContentExprlist, pC->zContent, pC->zContentRowid
);
@@ -259365,20 +263889,35 @@ static int fts5StorageGetStmt(
case FTS5_STMT_INSERT_CONTENT:
case FTS5_STMT_REPLACE_CONTENT: {
- int nCol = pC->nCol + 1;
- char *zBind;
+ char *zBind = 0;
int i;
- zBind = sqlite3_malloc64(1 + nCol*2);
- if( zBind ){
- for(i=0; ieContent==FTS5_CONTENT_NORMAL
+ || pC->eContent==FTS5_CONTENT_UNINDEXED
+ );
+
+ /* Add bindings for the "c*" columns - those that store the actual
+ ** table content. If eContent==NORMAL, then there is one binding
+ ** for each column. Or, if eContent==UNINDEXED, then there are only
+ ** bindings for the UNINDEXED columns. */
+ for(i=0; rc==SQLITE_OK && i<(pC->nCol+1); i++){
+ if( !i || pC->eContent==FTS5_CONTENT_NORMAL || pC->abUnindexed[i-1] ){
+ zBind = sqlite3Fts5Mprintf(&rc, "%z%s?%d", zBind, zBind?",":"",i+1);
}
- zBind[i*2-1] = '\0';
- zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
- sqlite3_free(zBind);
}
+
+ /* Add bindings for any "l*" columns. Only non-UNINDEXED columns
+ ** require these. */
+ if( pC->bLocale && pC->eContent==FTS5_CONTENT_NORMAL ){
+ for(i=0; rc==SQLITE_OK && inCol; i++){
+ if( pC->abUnindexed[i]==0 ){
+ zBind = sqlite3Fts5Mprintf(&rc, "%z,?%d", zBind, pC->nCol+i+2);
+ }
+ }
+ }
+
+ zSql = sqlite3Fts5Mprintf(&rc, azStmt[eStmt], pC->zDb, pC->zName,zBind);
+ sqlite3_free(zBind);
break;
}
@@ -259404,7 +263943,7 @@ static int fts5StorageGetStmt(
rc = SQLITE_NOMEM;
}else{
int f = SQLITE_PREPARE_PERSISTENT;
- if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
+ if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB;
p->pConfig->bLock++;
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
p->pConfig->bLock--;
@@ -259564,9 +264103,11 @@ static int sqlite3Fts5StorageOpen(
p->pIndex = pIndex;
if( bCreate ){
- if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL
+ || pConfig->eContent==FTS5_CONTENT_UNINDEXED
+ ){
int nDefn = 32 + pConfig->nCol*10;
- char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10);
+ char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20);
if( zDefn==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -259575,8 +264116,20 @@ static int sqlite3Fts5StorageOpen(
sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
iOff = (int)strlen(zDefn);
for(i=0; inCol; i++){
- sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
- iOff += (int)strlen(&zDefn[iOff]);
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL
+ || pConfig->abUnindexed[i]
+ ){
+ sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
+ iOff += (int)strlen(&zDefn[iOff]);
+ }
+ }
+ if( pConfig->bLocale ){
+ for(i=0; inCol; i++){
+ if( pConfig->abUnindexed[i]==0 ){
+ sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i);
+ iOff += (int)strlen(&zDefn[iOff]);
+ }
+ }
}
rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
}
@@ -259653,15 +264206,49 @@ static int fts5StorageInsertCallback(
return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
}
+/*
+** This function is used as part of an UPDATE statement that modifies the
+** rowid of a row. In that case, this function is called first to set
+** Fts5Storage.pSavedRow to point to a statement that may be used to
+** access the original values of the row being deleted - iDel.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+** It is not considered an error if row iDel does not exist. In this case
+** pSavedRow is not set and SQLITE_OK returned.
+*/
+static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel){
+ int rc = SQLITE_OK;
+ sqlite3_stmt *pSeek = 0;
+
+ assert( p->pSavedRow==0 );
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+1, &pSeek, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_int64(pSeek, 1, iDel);
+ if( sqlite3_step(pSeek)!=SQLITE_ROW ){
+ rc = sqlite3_reset(pSeek);
+ }else{
+ p->pSavedRow = pSeek;
+ }
+ }
+
+ return rc;
+}
+
/*
** If a row with rowid iDel is present in the %_content table, add the
** delete-markers to the FTS index necessary to delete it. Do not actually
** remove the %_content row at this time though.
+**
+** If parameter bSaveRow is true, then Fts5Storage.pSavedRow is left
+** pointing to a statement (FTS5_STMT_LOOKUP2) that may be used to access
+** the original values of the row being deleted. This is used by UPDATE
+** statements.
*/
static int fts5StorageDeleteFromIndex(
Fts5Storage *p,
i64 iDel,
- sqlite3_value **apVal
+ sqlite3_value **apVal,
+ int bSaveRow /* True to set pSavedRow */
){
Fts5Config *pConfig = p->pConfig;
sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */
@@ -259670,12 +264257,21 @@ static int fts5StorageDeleteFromIndex(
int iCol;
Fts5InsertCtx ctx;
+ assert( bSaveRow==0 || apVal==0 );
+ assert( bSaveRow==0 || bSaveRow==1 );
+ assert( FTS5_STMT_LOOKUP2==FTS5_STMT_LOOKUP+1 );
+
if( apVal==0 ){
- rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0);
- if( rc!=SQLITE_OK ) return rc;
- sqlite3_bind_int64(pSeek, 1, iDel);
- if( sqlite3_step(pSeek)!=SQLITE_ROW ){
- return sqlite3_reset(pSeek);
+ if( p->pSavedRow && bSaveRow ){
+ pSeek = p->pSavedRow;
+ p->pSavedRow = 0;
+ }else{
+ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+bSaveRow, &pSeek, 0);
+ if( rc!=SQLITE_OK ) return rc;
+ sqlite3_bind_int64(pSeek, 1, iDel);
+ if( sqlite3_step(pSeek)!=SQLITE_ROW ){
+ return sqlite3_reset(pSeek);
+ }
}
}
@@ -259683,26 +264279,42 @@ static int fts5StorageDeleteFromIndex(
ctx.iCol = -1;
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
if( pConfig->abUnindexed[iCol-1]==0 ){
- const char *zText;
- int nText;
+ sqlite3_value *pVal = 0;
+ const char *pText = 0;
+ int nText = 0;
+ const char *pLoc = 0;
+ int nLoc = 0;
+
assert( pSeek==0 || apVal==0 );
assert( pSeek!=0 || apVal!=0 );
if( pSeek ){
- zText = (const char*)sqlite3_column_text(pSeek, iCol);
- nText = sqlite3_column_bytes(pSeek, iCol);
- }else if( ALWAYS(apVal) ){
- zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
- nText = sqlite3_value_bytes(apVal[iCol-1]);
+ pVal = sqlite3_column_value(pSeek, iCol);
}else{
- continue;
+ pVal = apVal[iCol-1];
}
- ctx.szCol = 0;
- rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
- zText, nText, (void*)&ctx, fts5StorageInsertCallback
- );
- p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
- if( p->aTotalSize[iCol-1]<0 ){
- rc = FTS5_CORRUPT;
+
+ if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
+ }else{
+ pText = (const char*)sqlite3_value_text(pVal);
+ nText = sqlite3_value_bytes(pVal);
+ if( pConfig->bLocale && pSeek ){
+ pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol);
+ nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
+ ctx.szCol = 0;
+ rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
+ pText, nText, (void*)&ctx, fts5StorageInsertCallback
+ );
+ p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
+ if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){
+ rc = FTS5_CORRUPT;
+ }
+ sqlite3Fts5ClearLocale(pConfig);
}
}
}
@@ -259712,11 +264324,29 @@ static int fts5StorageDeleteFromIndex(
p->nTotalRow--;
}
- rc2 = sqlite3_reset(pSeek);
- if( rc==SQLITE_OK ) rc = rc2;
+ if( rc==SQLITE_OK && bSaveRow ){
+ assert( p->pSavedRow==0 );
+ p->pSavedRow = pSeek;
+ }else{
+ rc2 = sqlite3_reset(pSeek);
+ if( rc==SQLITE_OK ) rc = rc2;
+ }
return rc;
}
+/*
+** Reset any saved statement pSavedRow. Zero pSavedRow as well. This
+** should be called by the xUpdate() method of the fts5 table before
+** returning from any operation that may have set Fts5Storage.pSavedRow.
+*/
+static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){
+ assert( pStorage->pSavedRow==0
+ || pStorage->pSavedRow==pStorage->aStmt[FTS5_STMT_LOOKUP2]
+ );
+ sqlite3_reset(pStorage->pSavedRow);
+ pStorage->pSavedRow = 0;
+}
+
/*
** This function is called to process a DELETE on a contentless_delete=1
** table. It adds the tombstone required to delete the entry with rowid
@@ -259729,7 +264359,9 @@ static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){
int rc = SQLITE_OK;
assert( p->pConfig->bContentlessDelete );
- assert( p->pConfig->eContent==FTS5_CONTENT_NONE );
+ assert( p->pConfig->eContent==FTS5_CONTENT_NONE
+ || p->pConfig->eContent==FTS5_CONTENT_UNINDEXED
+ );
/* Look up the origin of the document in the %_docsize table. Store
** this in stack variable iOrigin. */
@@ -259773,12 +264405,12 @@ static int fts5StorageInsertDocsize(
rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin);
sqlite3_bind_int64(pReplace, 3, iOrigin);
}
- if( rc==SQLITE_OK ){
- sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
- sqlite3_step(pReplace);
- rc = sqlite3_reset(pReplace);
- sqlite3_bind_null(pReplace, 2);
- }
+ }
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
+ sqlite3_step(pReplace);
+ rc = sqlite3_reset(pReplace);
+ sqlite3_bind_null(pReplace, 2);
}
}
return rc;
@@ -259832,7 +264464,12 @@ static int fts5StorageSaveTotals(Fts5Storage *p){
/*
** Remove a row from the FTS table.
*/
-static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){
+static int sqlite3Fts5StorageDelete(
+ Fts5Storage *p, /* Storage object */
+ i64 iDel, /* Rowid to delete from table */
+ sqlite3_value **apVal, /* Optional - values to remove from index */
+ int bSaveRow /* If true, set pSavedRow for deleted row */
+){
Fts5Config *pConfig = p->pConfig;
int rc;
sqlite3_stmt *pDel = 0;
@@ -259848,8 +264485,14 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap
if( rc==SQLITE_OK ){
if( p->pConfig->bContentlessDelete ){
rc = fts5StorageContentlessDelete(p, iDel);
+ if( rc==SQLITE_OK
+ && bSaveRow
+ && p->pConfig->eContent==FTS5_CONTENT_UNINDEXED
+ ){
+ rc = sqlite3Fts5StorageFindDeleteRow(p, iDel);
+ }
}else{
- rc = fts5StorageDeleteFromIndex(p, iDel, apVal);
+ rc = fts5StorageDeleteFromIndex(p, iDel, apVal, bSaveRow);
}
}
@@ -259864,7 +264507,9 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap
}
/* Delete the %_content record */
- if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL
+ || pConfig->eContent==FTS5_CONTENT_UNINDEXED
+ ){
if( rc==SQLITE_OK ){
rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0);
}
@@ -259896,8 +264541,13 @@ static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){
);
if( rc==SQLITE_OK && pConfig->bColumnsize ){
rc = fts5ExecPrintf(pConfig->db, 0,
- "DELETE FROM %Q.'%q_docsize';",
- pConfig->zDb, pConfig->zName
+ "DELETE FROM %Q.'%q_docsize';", pConfig->zDb, pConfig->zName
+ );
+ }
+
+ if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_UNINDEXED ){
+ rc = fts5ExecPrintf(pConfig->db, 0,
+ "DELETE FROM %Q.'%q_content';", pConfig->zDb, pConfig->zName
);
}
@@ -259938,14 +264588,36 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){
ctx.szCol = 0;
if( pConfig->abUnindexed[ctx.iCol]==0 ){
- const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1);
- int nText = sqlite3_column_bytes(pScan, ctx.iCol+1);
- rc = sqlite3Fts5Tokenize(pConfig,
- FTS5_TOKENIZE_DOCUMENT,
- zText, nText,
- (void*)&ctx,
- fts5StorageInsertCallback
- );
+ int nText = 0; /* Size of pText in bytes */
+ const char *pText = 0; /* Pointer to buffer containing text value */
+ int nLoc = 0; /* Size of pLoc in bytes */
+ const char *pLoc = 0; /* Pointer to buffer containing text value */
+
+ sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1);
+ if( pConfig->eContent==FTS5_CONTENT_EXTERNAL
+ && sqlite3Fts5IsLocaleValue(pConfig, pVal)
+ ){
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
+ }else{
+ pText = (const char*)sqlite3_value_text(pVal);
+ nText = sqlite3_value_bytes(pVal);
+ if( pConfig->bLocale ){
+ int iCol = ctx.iCol + 1 + pConfig->nCol;
+ pLoc = (const char*)sqlite3_column_text(pScan, iCol);
+ nLoc = sqlite3_column_bytes(pScan, iCol);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
+ pText, nText,
+ (void*)&ctx,
+ fts5StorageInsertCallback
+ );
+ sqlite3Fts5ClearLocale(pConfig);
+ }
}
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
@@ -260011,6 +264683,7 @@ static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){
*/
static int sqlite3Fts5StorageContentInsert(
Fts5Storage *p,
+ int bReplace, /* True to use REPLACE instead of INSERT */
sqlite3_value **apVal,
i64 *piRowid
){
@@ -260018,7 +264691,9 @@ static int sqlite3Fts5StorageContentInsert(
int rc = SQLITE_OK;
/* Insert the new row into the %_content table. */
- if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
+ if( pConfig->eContent!=FTS5_CONTENT_NORMAL
+ && pConfig->eContent!=FTS5_CONTENT_UNINDEXED
+ ){
if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
*piRowid = sqlite3_value_int64(apVal[1]);
}else{
@@ -260027,9 +264702,52 @@ static int sqlite3Fts5StorageContentInsert(
}else{
sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
int i; /* Counter variable */
- rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
- for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
- rc = sqlite3_bind_value(pInsert, i, apVal[i]);
+
+ assert( FTS5_STMT_INSERT_CONTENT+1==FTS5_STMT_REPLACE_CONTENT );
+ assert( bReplace==0 || bReplace==1 );
+ rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT+bReplace, &pInsert, 0);
+ if( pInsert ) sqlite3_clear_bindings(pInsert);
+
+ /* Bind the rowid value */
+ sqlite3_bind_value(pInsert, 1, apVal[1]);
+
+ /* Loop through values for user-defined columns. i=2 is the leftmost
+ ** user-defined column. As is column 1 of pSavedRow. */
+ for(i=2; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
+ int bUnindexed = pConfig->abUnindexed[i-2];
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL || bUnindexed ){
+ sqlite3_value *pVal = apVal[i];
+
+ if( sqlite3_value_nochange(pVal) && p->pSavedRow ){
+ /* This is an UPDATE statement, and user-defined column (i-2) was not
+ ** modified. Retrieve the value from Fts5Storage.pSavedRow. */
+ pVal = sqlite3_column_value(p->pSavedRow, i-1);
+ if( pConfig->bLocale && bUnindexed==0 ){
+ sqlite3_bind_value(pInsert, pConfig->nCol + i,
+ sqlite3_column_value(p->pSavedRow, pConfig->nCol + i - 1)
+ );
+ }
+ }else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
+ const char *pText = 0;
+ const char *pLoc = 0;
+ int nText = 0;
+ int nLoc = 0;
+ assert( pConfig->bLocale );
+
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT);
+ if( bUnindexed==0 ){
+ int iLoc = pConfig->nCol + i;
+ sqlite3_bind_text(pInsert, iLoc, pLoc, nLoc, SQLITE_TRANSIENT);
+ }
+ }
+
+ continue;
+ }
+
+ rc = sqlite3_bind_value(pInsert, i, pVal);
+ }
}
if( rc==SQLITE_OK ){
sqlite3_step(pInsert);
@@ -260064,14 +264782,38 @@ static int sqlite3Fts5StorageIndexInsert(
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){
ctx.szCol = 0;
if( pConfig->abUnindexed[ctx.iCol]==0 ){
- const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]);
- int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]);
- rc = sqlite3Fts5Tokenize(pConfig,
- FTS5_TOKENIZE_DOCUMENT,
- zText, nText,
- (void*)&ctx,
- fts5StorageInsertCallback
- );
+ int nText = 0; /* Size of pText in bytes */
+ const char *pText = 0; /* Pointer to buffer containing text value */
+ int nLoc = 0; /* Size of pText in bytes */
+ const char *pLoc = 0; /* Pointer to buffer containing text value */
+
+ sqlite3_value *pVal = apVal[ctx.iCol+2];
+ if( p->pSavedRow && sqlite3_value_nochange(pVal) ){
+ pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1);
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){
+ int iCol = ctx.iCol + 1 + pConfig->nCol;
+ pLoc = (const char*)sqlite3_column_text(p->pSavedRow, iCol);
+ nLoc = sqlite3_column_bytes(p->pSavedRow, iCol);
+ }
+ }else{
+ pVal = apVal[ctx.iCol+2];
+ }
+
+ if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
+ }else{
+ pText = (const char*)sqlite3_value_text(pVal);
+ nText = sqlite3_value_bytes(pVal);
+ }
+
+ if( rc==SQLITE_OK ){
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx,
+ fts5StorageInsertCallback
+ );
+ sqlite3Fts5ClearLocale(pConfig);
+ }
}
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
@@ -260235,29 +264977,61 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
}
for(i=0; rc==SQLITE_OK && inCol; i++){
- if( pConfig->abUnindexed[i] ) continue;
- ctx.iCol = i;
- ctx.szCol = 0;
- if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
- rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
- }
- if( rc==SQLITE_OK ){
- const char *zText = (const char*)sqlite3_column_text(pScan, i+1);
- int nText = sqlite3_column_bytes(pScan, i+1);
- rc = sqlite3Fts5Tokenize(pConfig,
- FTS5_TOKENIZE_DOCUMENT,
- zText, nText,
- (void*)&ctx,
- fts5StorageIntegrityCallback
- );
- }
- if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
- rc = FTS5_CORRUPT;
- }
- aTotalSize[i] += ctx.szCol;
- if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
- sqlite3Fts5TermsetFree(ctx.pTermset);
- ctx.pTermset = 0;
+ if( pConfig->abUnindexed[i]==0 ){
+ const char *pText = 0;
+ int nText = 0;
+ const char *pLoc = 0;
+ int nLoc = 0;
+ sqlite3_value *pVal = sqlite3_column_value(pScan, i+1);
+
+ if( pConfig->eContent==FTS5_CONTENT_EXTERNAL
+ && sqlite3Fts5IsLocaleValue(pConfig, pVal)
+ ){
+ rc = sqlite3Fts5DecodeLocaleValue(
+ pVal, &pText, &nText, &pLoc, &nLoc
+ );
+ }else{
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){
+ int iCol = i + 1 + pConfig->nCol;
+ pLoc = (const char*)sqlite3_column_text(pScan, iCol);
+ nLoc = sqlite3_column_bytes(pScan, iCol);
+ }
+ pText = (const char*)sqlite3_value_text(pVal);
+ nText = sqlite3_value_bytes(pVal);
+ }
+
+ ctx.iCol = i;
+ ctx.szCol = 0;
+
+ if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
+ rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
+ }
+
+ if( rc==SQLITE_OK ){
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
+ rc = sqlite3Fts5Tokenize(pConfig,
+ FTS5_TOKENIZE_DOCUMENT,
+ pText, nText,
+ (void*)&ctx,
+ fts5StorageIntegrityCallback
+ );
+ sqlite3Fts5ClearLocale(pConfig);
+ }
+
+ /* If this is not a columnsize=0 database, check that the number
+ ** of tokens in the value matches the aColSize[] value read from
+ ** the %_docsize table. */
+ if( rc==SQLITE_OK
+ && pConfig->bColumnsize
+ && ctx.szCol!=aColSize[i]
+ ){
+ rc = FTS5_CORRUPT;
+ }
+ aTotalSize[i] += ctx.szCol;
+ if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
+ sqlite3Fts5TermsetFree(ctx.pTermset);
+ ctx.pTermset = 0;
+ }
}
}
sqlite3Fts5TermsetFree(ctx.pTermset);
@@ -260683,7 +265457,7 @@ static const unsigned char sqlite3Utf8Trans1[] = {
c = *(zIn++); \
if( c>=0xc0 ){ \
c = sqlite3Utf8Trans1[c-0xc0]; \
- while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
+ while( zInpTokenizer ){
- p->tokenizer.xDelete(p->pTokenizer);
+ p->tokenizer_v2.xDelete(p->pTokenizer);
}
sqlite3_free(p);
}
@@ -261071,6 +265843,7 @@ static int fts5PorterCreate(
PorterTokenizer *pRet;
void *pUserdata = 0;
const char *zBase = "unicode61";
+ fts5_tokenizer_v2 *pV2 = 0;
if( nArg>0 ){
zBase = azArg[0];
@@ -261079,14 +265852,15 @@ static int fts5PorterCreate(
pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer));
if( pRet ){
memset(pRet, 0, sizeof(PorterTokenizer));
- rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer);
+ rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2);
}else{
rc = SQLITE_NOMEM;
}
if( rc==SQLITE_OK ){
int nArg2 = (nArg>0 ? nArg-1 : 0);
- const char **azArg2 = (nArg2 ? &azArg[1] : 0);
- rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer);
+ const char **az2 = (nArg2 ? &azArg[1] : 0);
+ memcpy(&pRet->tokenizer_v2, pV2, sizeof(fts5_tokenizer_v2));
+ rc = pRet->tokenizer_v2.xCreate(pUserdata, az2, nArg2, &pRet->pTokenizer);
}
if( rc!=SQLITE_OK ){
@@ -261737,6 +266511,7 @@ static int fts5PorterTokenize(
void *pCtx,
int flags,
const char *pText, int nText,
+ const char *pLoc, int nLoc,
int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
){
PorterTokenizer *p = (PorterTokenizer*)pTokenizer;
@@ -261744,8 +266519,8 @@ static int fts5PorterTokenize(
sCtx.xToken = xToken;
sCtx.pCtx = pCtx;
sCtx.aBuf = p->aBuf;
- return p->tokenizer.xTokenize(
- p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb
+ return p->tokenizer_v2.xTokenize(
+ p->pTokenizer, (void*)&sCtx, flags, pText, nText, pLoc, nLoc, fts5PorterCb
);
}
@@ -261776,18 +266551,18 @@ static int fts5TriCreate(
){
int rc = SQLITE_OK;
TrigramTokenizer *pNew = 0;
-
+ UNUSED_PARAM(pUnused);
if( nArg%2 ){
rc = SQLITE_ERROR;
}else{
+ int i;
pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
- UNUSED_PARAM(pUnused);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
- int i;
pNew->bFold = 1;
pNew->iFoldParam = 0;
+
for(i=0; rc==SQLITE_OK && iazArg[] is the trigram
+** tokenizer. This tokenizer needs to be loaded before xBestIndex is
+** called for the first time in order to correctly handle LIKE/GLOB.
+*/
+static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig *p){
+ return (p->nArg>=1 && 0==sqlite3_stricmp(p->azArg[0], "trigram"));
+}
+
+
/*
** Register all built-in tokenizers with FTS5.
*/
@@ -261929,7 +266714,6 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
} aBuiltin[] = {
{ "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
{ "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
- { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
{ "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
};
@@ -261944,7 +266728,20 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
0
);
}
-
+ if( rc==SQLITE_OK ){
+ fts5_tokenizer_v2 sPorter = {
+ 2,
+ fts5PorterCreate,
+ fts5PorterDelete,
+ fts5PorterTokenize
+ };
+ rc = pApi->xCreateTokenizer_v2(pApi,
+ "porter",
+ (void*)pApi,
+ &sPorter,
+ 0
+ );
+ }
return rc;
}
@@ -262314,6 +267111,9 @@ static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
default: return 1; }
break;
+
+ default:
+ return 1;
}
return 0;
}
@@ -263138,6 +267938,7 @@ struct Fts5VocabCursor {
int nLeTerm; /* Size of zLeTerm in bytes */
char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */
+ int colUsed; /* Copy of sqlite3_index_info.colUsed */
/* These are used by 'col' tables only */
int iCol;
@@ -263164,9 +267965,11 @@ struct Fts5VocabCursor {
/*
** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
*/
-#define FTS5_VOCAB_TERM_EQ 0x01
-#define FTS5_VOCAB_TERM_GE 0x02
-#define FTS5_VOCAB_TERM_LE 0x04
+#define FTS5_VOCAB_TERM_EQ 0x0100
+#define FTS5_VOCAB_TERM_GE 0x0200
+#define FTS5_VOCAB_TERM_LE 0x0400
+
+#define FTS5_VOCAB_COLUSED_MASK 0xFF
/*
@@ -263343,11 +268146,13 @@ static int fts5VocabBestIndexMethod(
int iTermEq = -1;
int iTermGe = -1;
int iTermLe = -1;
- int idxNum = 0;
+ int idxNum = (int)pInfo->colUsed;
int nArg = 0;
UNUSED_PARAM(pUnused);
+ assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed );
+
for(i=0; inConstraint; i++){
struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
if( p->usable==0 ) continue;
@@ -263439,7 +268244,7 @@ static int fts5VocabOpenMethod(
if( rc==SQLITE_OK ){
pVTab->zErrMsg = sqlite3_mprintf(
"no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl
- );
+ );
rc = SQLITE_ERROR;
}
}else{
@@ -263599,9 +268404,19 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
switch( pTab->eType ){
case FTS5_VOCAB_ROW:
- if( eDetail==FTS5_DETAIL_FULL ){
- while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
- pCsr->aCnt[0]++;
+ /* Do not bother counting the number of instances if the "cnt"
+ ** column is not being read (according to colUsed). */
+ if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){
+ while( iPosaCnt[] */
+ pCsr->aCnt[0]++;
+ }
}
}
pCsr->aDoc[0]++;
@@ -263699,6 +268514,7 @@ static int fts5VocabFilterMethod(
if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
+ pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK);
if( pEq ){
zTerm = (const char *)sqlite3_value_text(pEq);
@@ -263866,7 +268682,7 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){
}
-
+/* Here ends the fts5.c composite file. */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
/************** End of fts5.c ************************************************/
diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h
index be068ebe3f..8619eecfa4 100644
--- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h
+++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sqlite3.h
@@ -149,9 +149,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.45.1"
-#define SQLITE_VERSION_NUMBER 3045001
-#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257ccalt1"
+#define SQLITE_VERSION "3.47.2"
+#define SQLITE_VERSION_NUMBER 3047002
+#define SQLITE_SOURCE_ID "2024-12-07 20:39:59 2aabe05e2e8cae4847a802ee2daddc1d7413d8fc560254d93ee3e72c1468alt1"
#define LIBSQL_VERSION "0.2.3"
@@ -427,6 +427,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
** The application must not modify the SQL statement text passed into
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
+** The application must not dereference the arrays or string pointers
+** passed as the 3rd and 4th callback parameters after it returns.
**
*/
SQLITE_API int sqlite3_exec(
@@ -657,6 +659,13 @@ SQLITE_API int sqlite3_exec(
** filesystem supports doing multiple write operations atomically when those
** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
+**
+** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read
+** from the database file in amounts that are not a multiple of the
+** page size and that do not begin at a page boundary. Without this
+** property, SQLite is careful to only do full-page reads and write
+** on aligned pages, with the one exception that it will do a sub-page
+** read of the first page to access the database header.
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -673,6 +682,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
+#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000
/*
** CAPI3REF: File Locking Levels
@@ -769,16 +779,16 @@ struct sqlite3_file {
**
** xLock() upgrades the database file lock. In other words, xLock() moves the
** database file lock in the direction NONE toward EXCLUSIVE. The argument to
-** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
+** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
** SQLITE_LOCK_NONE. If the database file lock is already at or above the
** requested lock, then the call to xLock() is a no-op.
** xUnlock() downgrades the database file lock to either SHARED or NONE.
-* If the lock is already at or below the requested lock state, then the call
+** If the lock is already at or below the requested lock state, then the call
** to xUnlock() is a no-op.
** The xCheckReservedLock() method checks whether any database connection,
** either in this process or in some other process, is holding a RESERVED,
-** PENDING, or EXCLUSIVE lock on the file. It returns true
-** if such a lock exists and false otherwise.
+** PENDING, or EXCLUSIVE lock on the file. It returns, via its output
+** pointer parameter, true if such a lock exists and false otherwise.
**
** The xFileControl() method is a generic interface that allows custom
** VFS implementations to directly control an open file using the
@@ -819,6 +829,7 @@ struct sqlite3_file {
** [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
** [SQLITE_IOCAP_IMMUTABLE]
** [SQLITE_IOCAP_BATCH_ATOMIC]
+** [SQLITE_IOCAP_SUBPAGE_READ]
**
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -2168,6 +2179,22 @@ struct sqlite3_mem_methods {
** configuration setting is never used, then the default maximum is determined
** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that
** compile-time option is not set, then the default maximum is 1073741824.
+**
+** [[SQLITE_CONFIG_ROWID_IN_VIEW]]
+** SQLITE_CONFIG_ROWID_IN_VIEW
+** The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability
+** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is
+** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability
+** defaults to on. This configuration option queries the current setting or
+** changes the setting to off or on. The argument is a pointer to an integer.
+** If that integer initially holds a value of 1, then the ability for VIEWs to
+** have ROWIDs is activated. If the integer initially holds zero, then the
+** ability is deactivated. Any other initial value for the integer leaves the
+** setting unchanged. After changes, if any, the integer is written with
+** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite
+** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and
+** recommended case) then the integer is always filled with zero, regardless
+** if its initial value.
**
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2199,6 +2226,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
+#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -3313,8 +3341,8 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
-** CAPI3REF: Tracing And Profiling Functions
-** METHOD: sqlite3
+** CAPI3REF: Deprecated Tracing And Profiling Functions
+** DEPRECATED
**
** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
** instead of the routines described here.
@@ -3578,8 +3606,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** [[OPEN_EXRESCODE]] ^([SQLITE_OPEN_EXRESCODE]
** The database connection comes up in "extended result code mode".
-** In other words, the database behaves has if
-** [sqlite3_extended_result_codes(db,1)] where called on the database
+** In other words, the database behaves as if
+** [sqlite3_extended_result_codes(db,1)] were called on the database
** connection as soon as the connection is created. In addition to setting
** the extended result code mode, this flag also causes [sqlite3_open_v2()]
** to return an extended result code.
@@ -4264,13 +4292,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** and sqlite3_prepare16_v3() use UTF-16.
**
** ^If the nByte argument is negative, then zSql is read up to the
-** first zero terminator. ^If nByte is positive, then it is the
-** number of bytes read from zSql. ^If nByte is zero, then no prepared
+** first zero terminator. ^If nByte is positive, then it is the maximum
+** number of bytes read from zSql. When nByte is positive, zSql is read
+** up to the first zero terminator or until the nByte bytes have been read,
+** whichever comes first. ^If nByte is zero, then no prepared
** statement is generated.
** If the caller knows that the supplied string is nul-terminated, then
** there is a small performance advantage to passing an nByte parameter that
** is the number of bytes in the input string including
** the nul-terminator.
+** Note that nByte measure the length of the input in bytes, not
+** characters, even for the UTF-16 interfaces.
**
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
** past the end of the first SQL statement in zSql. These routines only
@@ -5643,7 +5675,7 @@ SQLITE_API int sqlite3_create_window_function(
** This flag instructs SQLite to omit some corner-case optimizations that
** might disrupt the operation of the [sqlite3_value_subtype()] function,
** causing it to return zero rather than the correct subtype().
-** SQL functions that invokes [sqlite3_value_subtype()] should have this
+** All SQL functions that invoke [sqlite3_value_subtype()] should have this
** property. If the SQLITE_SUBTYPE property is omitted, then the return
** value from [sqlite3_value_subtype()] might sometimes be zero even though
** a non-zero subtype was specified by the function argument expression.
@@ -5659,6 +5691,15 @@ SQLITE_API int sqlite3_create_window_function(
** [sqlite3_result_subtype()] should avoid setting this property, as the
** purpose of this property is to disable certain optimizations that are
** incompatible with subtypes.
+**
+** [[SQLITE_SELFORDER1]] SQLITE_SELFORDER1
+** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
+** that internally orders the values provided to the first argument. The
+** ordered-set aggregate SQL notation with a single ORDER BY term can be
+** used to invoke this function. If the ordered-set aggregate notation is
+** used on a function that lacks this flag, then an error is raised. Note
+** that the ordered-set aggregate syntax is only available if SQLite is
+** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
**
**
*/
@@ -5667,6 +5708,7 @@ SQLITE_API int sqlite3_create_window_function(
#define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000
#define SQLITE_RESULT_SUBTYPE 0x001000000
+#define SQLITE_SELFORDER1 0x002000000
/*
** CAPI3REF: Deprecated Functions
@@ -5864,7 +5906,7 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*);
** one SQL function to another. Use the [sqlite3_result_subtype()]
** routine to set the subtype for the return value of an SQL function.
**
-** Every [application-defined SQL function] that invoke this interface
+** Every [application-defined SQL function] that invokes this interface
** should include the [SQLITE_SUBTYPE] property in the text
** encoding argument when the function is [sqlite3_create_function|registered].
** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype()
@@ -6931,6 +6973,12 @@ SQLITE_API int sqlite3_autovacuum_pages(
** The exceptions defined in this paragraph might change in a future
** release of SQLite.
**
+** Whether the update hook is invoked before or after the
+** corresponding change is currently unspecified and may differ
+** depending on the type of change. Do not rely on the order of the
+** hook call with regards to the final result of the operation which
+** triggers the hook.
+**
** 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
@@ -7470,9 +7518,11 @@ struct sqlite3_module {
** will be returned by the strategy.
**
** The xBestIndex method may optionally populate the idxFlags field with a
-** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
-** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
-** assumes that the strategy may visit at most one row.
+** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
+** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
+** output to show the idxNum has hex instead of as decimal. Another flag is
+** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
+** return at most one row.
**
** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
** SQLite also assumes that if a call to the xUpdate() method is made as
@@ -7536,7 +7586,9 @@ struct sqlite3_index_info {
** [sqlite3_index_info].idxFlags field to some combination of
** these bits.
*/
-#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
+#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */
+#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */
+ /* in EXPLAIN QUERY PLAN */
/*
** CAPI3REF: Virtual Table Constraint Operator Codes
@@ -8395,6 +8447,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
+#define SQLITE_TESTCTRL_GETOPT 16
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -8414,7 +8467,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_TRACEFLAGS 31
#define SQLITE_TESTCTRL_TUNE 32
#define SQLITE_TESTCTRL_LOGEST 33
-#define SQLITE_TESTCTRL_USELONGDOUBLE 34
+#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */
#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */
/*
@@ -8428,7 +8481,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
** The sqlite3_keyword_count() interface returns the number of distinct
** keywords understood by SQLite.
**
-** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
+** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and
** makes *Z point to that keyword expressed as UTF8 and writes the number
** of bytes in the keyword into *L. The string that *Z points to is not
** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
@@ -9406,6 +9459,16 @@ typedef struct sqlite3_backup sqlite3_backup;
** APIs are not strictly speaking threadsafe. If they are invoked at the
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
+**
+** Alternatives To Using The Backup API
+**
+** Other techniques for safely creating a consistent backup of an SQLite
+** database include:
+**
+**
+** - The [VACUUM INTO] command.
+**
- The [sqlite3_rsync] utility program.
+**
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
@@ -10023,24 +10086,45 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
**
** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
** that the query planner does not need the rows returned in any particular
-** order, as long as rows with the same values in all "aOrderBy" columns
-** are adjacent.)^ ^(Furthermore, only a single row for each particular
-** combination of values in the columns identified by the "aOrderBy" field
-** needs to be returned.)^ ^It is always ok for two or more rows with the same
-** values in all "aOrderBy" columns to be returned, as long as all such rows
-** are adjacent. ^The virtual table may, if it chooses, omit extra rows
-** that have the same value for all columns identified by "aOrderBy".
-** ^However omitting the extra rows is optional.
+** order, as long as rows with the same values in all columns identified
+** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows
+** contain the same values for all columns identified by "colUsed", all but
+** one such row may optionally be omitted from the result.)^
+** The virtual table is not required to omit rows that are duplicates
+** over the "colUsed" columns, but if the virtual table can do that without
+** too much extra effort, it could potentially help the query to run faster.
** This mode is used for a DISTINCT query.
**
-** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
-** that the query planner needs only distinct rows but it does need the
-** rows to be sorted.)^ ^The virtual table implementation is free to omit
-** rows that are identical in all aOrderBy columns, if it wants to, but
-** it is not required to omit any rows. This mode is used for queries
+** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the
+** virtual table must return rows in the order defined by "aOrderBy" as
+** if the sqlite3_vtab_distinct() interface had returned 0. However if
+** two or more rows in the result have the same values for all columns
+** identified by "colUsed", then all but one such row may optionally be
+** omitted.)^ Like when the return value is 2, the virtual table
+** is not required to omit rows that are duplicates over the "colUsed"
+** columns, but if the virtual table can do that without
+** too much extra effort, it could potentially help the query to run faster.
+** This mode is used for queries
** that have both DISTINCT and ORDER BY clauses.
**
**
+**
The following table summarizes the conditions under which the
+** virtual table is allowed to set the "orderByConsumed" flag based on
+** the value returned by sqlite3_vtab_distinct(). This table is a
+** restatement of the previous four paragraphs:
+**
+**
+**
+** | sqlite3_vtab_distinct() return value
+** | Rows are returned in aOrderBy order
+** | Rows with the same value in all aOrderBy columns are adjacent
+** | Duplicates over all colUsed columns may be omitted
+** |
| 0 | yes | yes | no
+** |
| 1 | no | yes | no
+** |
| 2 | no | yes | yes
+** |
| 3 | yes | yes | yes
+** |
+**
** ^For the purposes of comparing virtual table output values to see if the
** values are same value for sorting purposes, two NULL values are considered
** to be the same. In other words, the comparison operator is "IS"
@@ -10653,6 +10737,14 @@ typedef struct sqlite3_snapshot {
** If there is not already a read-transaction open on schema S when
** this function is called, one is opened automatically.
**
+** If a read-transaction is opened by this function, then it is guaranteed
+** that the returned snapshot object may not be invalidated by a database
+** writer or checkpointer until after the read-transaction is closed. This
+** is not guaranteed if a read-transaction is already open when this
+** function is called. In that case, any subsequent write or checkpoint
+** operation on the database may invalidate the returned snapshot handle,
+** even while the read-transaction remains open.
+**
** The following must be true for this function to succeed. If any of
** the following statements are false when sqlite3_snapshot_get() is
** called, SQLITE_ERROR is returned. The final value of *P is undefined
@@ -12155,6 +12247,30 @@ SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const c
*/
SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+/*
+** CAPI3REF: Add A Single Change To A Changegroup
+** METHOD: sqlite3_changegroup
+**
+** This function adds the single change currently indicated by the iterator
+** passed as the second argument to the changegroup object. The rules for
+** adding the change are just as described for [sqlite3changegroup_add()].
+**
+** If the change is successfully added to the changegroup, SQLITE_OK is
+** returned. Otherwise, an SQLite error code is returned.
+**
+** The iterator must point to a valid entry when this function is called.
+** If it does not, SQLITE_ERROR is returned and no change is added to the
+** changegroup. Additionally, the iterator must not have been opened with
+** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also
+** returned.
+*/
+SQLITE_API int sqlite3changegroup_add_change(
+ sqlite3_changegroup*,
+ sqlite3_changeset_iter*
+);
+
+
+
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
** METHOD: sqlite3_changegroup
@@ -12959,8 +13075,8 @@ struct Fts5PhraseIter {
** EXTENSION API FUNCTIONS
**
** xUserData(pFts):
-** Return a copy of the context pointer the extension function was
-** registered with.
+** Return a copy of the pUserData pointer passed to the xCreateFunction()
+** API when the extension function was registered.
**
** xColumnTotalSize(pFts, iCol, pnToken):
** If parameter iCol is less than zero, set output variable *pnToken
@@ -13142,6 +13258,10 @@ struct Fts5PhraseIter {
** (i.e. if it is a contentless table), then this API always iterates
** through an empty set (all calls to xPhraseFirst() set iCol to -1).
**
+** In all cases, matches are visited in (column ASC, offset ASC) order.
+** i.e. all those in column 0, sorted by offset, followed by those in
+** column 1, etc.
+**
** xPhraseNext()
** See xPhraseFirst above.
**
@@ -13208,9 +13328,32 @@ struct Fts5PhraseIter {
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
+**
+** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
+** If parameter iCol is less than zero, or greater than or equal to the
+** number of columns in the table, SQLITE_RANGE is returned.
+**
+** Otherwise, this function attempts to retrieve the locale associated
+** with column iCol of the current row. Usually, there is no associated
+** locale, and output parameters (*pzLocale) and (*pnLocale) are set
+** to NULL and 0, respectively. However, if the fts5_locale() function
+** was used to associate a locale with the value when it was inserted
+** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
+** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
+** is set to the size in bytes of the buffer, not including the
+** nul-terminator.
+**
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an
+** SQLite error code is returned. The final value of the output parameters
+** is undefined in this case.
+**
+** xTokenize_v2:
+** Tokenize text using the tokenizer belonging to the FTS5 table. This
+** API is the same as the xTokenize() API, except that it allows a tokenizer
+** locale to be specified.
*/
struct Fts5ExtensionApi {
- int iVersion; /* Currently always set to 3 */
+ int iVersion; /* Currently always set to 4 */
void *(*xUserData)(Fts5Context*);
@@ -13252,6 +13395,15 @@ struct Fts5ExtensionApi {
const char **ppToken, int *pnToken
);
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
+
+ /* Below this point are iVersion>=4 only */
+ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xTokenize_v2)(Fts5Context*,
+ const char *pText, int nText, /* Text to tokenize */
+ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
};
/*
@@ -13272,7 +13424,7 @@ struct Fts5ExtensionApi {
** A tokenizer instance is required to actually tokenize text.
**
** The first argument passed to this function is a copy of the (void*)
-** pointer provided by the application when the fts5_tokenizer object
+** pointer provided by the application when the fts5_tokenizer_v2 object
** was registered with FTS5 (the third argument to xCreateTokenizer()).
** The second and third arguments are an array of nul-terminated strings
** containing the tokenizer arguments, if any, specified following the
@@ -13296,7 +13448,7 @@ struct Fts5ExtensionApi {
** argument passed to this function is a pointer to an Fts5Tokenizer object
** returned by an earlier call to xCreate().
**
-** The second argument indicates the reason that FTS5 is requesting
+** The third argument indicates the reason that FTS5 is requesting
** tokenization of the supplied text. This is always one of the following
** four values:
**
@@ -13320,6 +13472,13 @@ struct Fts5ExtensionApi {
** on a columnsize=0 database.
**
**
+** The sixth and seventh arguments passed to xTokenize() - pLocale and
+** nLocale - are a pointer to a buffer containing the locale to use for
+** tokenization (e.g. "en_US") and its size in bytes, respectively. The
+** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
+** which case nLocale is always 0) to indicate that the tokenizer should
+** use its default locale.
+**
** For each token in the input string, the supplied callback xToken() must
** be invoked. The first argument to it should be a copy of the pointer
** passed as the second argument to xTokenize(). The third and fourth
@@ -13343,6 +13502,30 @@ struct Fts5ExtensionApi {
** may abandon the tokenization and return any error code other than
** SQLITE_OK or SQLITE_DONE.
**
+** If the tokenizer is registered using an fts5_tokenizer_v2 object,
+** then the xTokenize() method has two additional arguments - pLocale
+** and nLocale. These specify the locale that the tokenizer should use
+** for the current request. If pLocale and nLocale are both 0, then the
+** tokenizer should use its default locale. Otherwise, pLocale points to
+** an nLocale byte buffer containing the name of the locale to use as utf-8
+** text. pLocale is not nul-terminated.
+**
+** FTS5_TOKENIZER
+**
+** There is also an fts5_tokenizer object. This is an older, deprecated,
+** version of fts5_tokenizer_v2. It is similar except that:
+**
+**
+** - There is no "iVersion" field, and
+**
- The xTokenize() method does not take a locale argument.
+**
+**
+** Legacy fts5_tokenizer tokenizers must be registered using the
+** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
+**
+** Tokenizer implementations registered using either API may be retrieved
+** using both xFindTokenizer() and xFindTokenizer_v2().
+**
** SYNONYM SUPPORT
**
** Custom tokenizers may also support synonyms. Consider a case in which a
@@ -13451,6 +13634,33 @@ struct Fts5ExtensionApi {
** inefficient.
*/
typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
+struct fts5_tokenizer_v2 {
+ int iVersion; /* Currently always 2 */
+
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
+ int (*xTokenize)(Fts5Tokenizer*,
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ const char *pText, int nText,
+ const char *pLocale, int nLocale,
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/*
+** New code should use the fts5_tokenizer_v2 type to define tokenizer
+** implementations. The following type is included for legacy applications
+** that still use it.
+*/
typedef struct fts5_tokenizer fts5_tokenizer;
struct fts5_tokenizer {
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
@@ -13470,6 +13680,7 @@ struct fts5_tokenizer {
);
};
+
/* Flags that may be passed as the third argument to xTokenize() */
#define FTS5_TOKENIZE_QUERY 0x0001
#define FTS5_TOKENIZE_PREFIX 0x0002
@@ -13489,7 +13700,7 @@ struct fts5_tokenizer {
*/
typedef struct fts5_api fts5_api;
struct fts5_api {
- int iVersion; /* Currently always set to 2 */
+ int iVersion; /* Currently always set to 3 */
/* Create a new tokenizer */
int (*xCreateTokenizer)(
@@ -13516,6 +13727,25 @@ struct fts5_api {
fts5_extension_function xFunction,
void (*xDestroy)(void*)
);
+
+ /* APIs below this point are only available if iVersion>=3 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer_v2)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pUserData,
+ fts5_tokenizer_v2 *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer_v2)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppUserData,
+ fts5_tokenizer_v2 **ppTokenizer
+ );
};
/*
diff --git a/libsql-ffi/bundled/bindings/bindgen.rs b/libsql-ffi/bundled/bindings/bindgen.rs
index 343361ba38..253ad00974 100644
--- a/libsql-ffi/bundled/bindings/bindgen.rs
+++ b/libsql-ffi/bundled/bindings/bindgen.rs
@@ -23,11 +23,10 @@ extern "C" {
) -> ::std::os::raw::c_int;
}
-pub const __GNUC_VA_LIST: i32 = 1;
-pub const SQLITE_VERSION: &[u8; 7] = b"3.45.1\0";
-pub const SQLITE_VERSION_NUMBER: i32 = 3045001;
+pub const SQLITE_VERSION: &[u8; 7] = b"3.47.2\0";
+pub const SQLITE_VERSION_NUMBER: i32 = 3047002;
pub const SQLITE_SOURCE_ID: &[u8; 85] =
- b"2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257ccalt1\0";
+ b"2024-12-07 20:39:59 2aabe05e2e8cae4847a802ee2daddc1d7413d8fc560254d93ee3e72c1468alt1\0";
pub const LIBSQL_VERSION: &[u8; 6] = b"0.2.3\0";
pub const SQLITE_OK: i32 = 0;
pub const SQLITE_ERROR: i32 = 1;
@@ -175,6 +174,7 @@ pub const SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN: i32 = 2048;
pub const SQLITE_IOCAP_POWERSAFE_OVERWRITE: i32 = 4096;
pub const SQLITE_IOCAP_IMMUTABLE: i32 = 8192;
pub const SQLITE_IOCAP_BATCH_ATOMIC: i32 = 16384;
+pub const SQLITE_IOCAP_SUBPAGE_READ: i32 = 32768;
pub const SQLITE_LOCK_NONE: i32 = 0;
pub const SQLITE_LOCK_SHARED: i32 = 1;
pub const SQLITE_LOCK_RESERVED: i32 = 2;
@@ -264,6 +264,7 @@ pub const SQLITE_CONFIG_STMTJRNL_SPILL: i32 = 26;
pub const SQLITE_CONFIG_SMALL_MALLOC: i32 = 27;
pub const SQLITE_CONFIG_SORTERREF_SIZE: i32 = 28;
pub const SQLITE_CONFIG_MEMDB_MAXSIZE: i32 = 29;
+pub const SQLITE_CONFIG_ROWID_IN_VIEW: i32 = 30;
pub const SQLITE_DBCONFIG_MAINDBNAME: i32 = 1000;
pub const SQLITE_DBCONFIG_LOOKASIDE: i32 = 1001;
pub const SQLITE_DBCONFIG_ENABLE_FKEY: i32 = 1002;
@@ -357,12 +358,14 @@ pub const SQLITE_DIRECTONLY: i32 = 524288;
pub const SQLITE_SUBTYPE: i32 = 1048576;
pub const SQLITE_INNOCUOUS: i32 = 2097152;
pub const SQLITE_RESULT_SUBTYPE: i32 = 16777216;
+pub const SQLITE_SELFORDER1: i32 = 33554432;
pub const SQLITE_WIN32_DATA_DIRECTORY_TYPE: i32 = 1;
pub const SQLITE_WIN32_TEMP_DIRECTORY_TYPE: i32 = 2;
pub const SQLITE_TXN_NONE: i32 = 0;
pub const SQLITE_TXN_READ: i32 = 1;
pub const SQLITE_TXN_WRITE: i32 = 2;
pub const SQLITE_INDEX_SCAN_UNIQUE: i32 = 1;
+pub const SQLITE_INDEX_SCAN_HEX: i32 = 2;
pub const SQLITE_INDEX_CONSTRAINT_EQ: i32 = 2;
pub const SQLITE_INDEX_CONSTRAINT_GT: i32 = 4;
pub const SQLITE_INDEX_CONSTRAINT_LE: i32 = 8;
@@ -412,6 +415,7 @@ pub const SQLITE_TESTCTRL_RESERVE: i32 = 14;
pub const SQLITE_TESTCTRL_JSON_SELFCHECK: i32 = 14;
pub const SQLITE_TESTCTRL_OPTIMIZATIONS: i32 = 15;
pub const SQLITE_TESTCTRL_ISKEYWORD: i32 = 16;
+pub const SQLITE_TESTCTRL_GETOPT: i32 = 16;
pub const SQLITE_TESTCTRL_SCRATCHMALLOC: i32 = 17;
pub const SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: i32 = 17;
pub const SQLITE_TESTCTRL_LOCALTIME_FAULT: i32 = 18;
@@ -502,8 +506,6 @@ pub const FTS5_TOKENIZE_DOCUMENT: i32 = 4;
pub const FTS5_TOKENIZE_AUX: i32 = 8;
pub const FTS5_TOKEN_COLOCATED: i32 = 1;
pub const WAL_SAVEPOINT_NDATA: i32 = 4;
-pub type va_list = __builtin_va_list;
-pub type __gnuc_va_list = __builtin_va_list;
extern "C" {
pub static sqlite3_version: [::std::os::raw::c_char; 0usize];
}
@@ -937,12 +939,6 @@ extern "C" {
pub fn sqlite3_mprintf(arg1: *const ::std::os::raw::c_char, ...)
-> *mut ::std::os::raw::c_char;
}
-extern "C" {
- pub fn sqlite3_vmprintf(
- arg1: *const ::std::os::raw::c_char,
- arg2: *mut __va_list_tag,
- ) -> *mut ::std::os::raw::c_char;
-}
extern "C" {
pub fn sqlite3_snprintf(
arg1: ::std::os::raw::c_int,
@@ -951,14 +947,6 @@ extern "C" {
...
) -> *mut ::std::os::raw::c_char;
}
-extern "C" {
- pub fn sqlite3_vsnprintf(
- arg1: ::std::os::raw::c_int,
- arg2: *mut ::std::os::raw::c_char,
- arg3: *const ::std::os::raw::c_char,
- arg4: *mut __va_list_tag,
- ) -> *mut ::std::os::raw::c_char;
-}
extern "C" {
pub fn sqlite3_malloc(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_void;
}
@@ -2502,13 +2490,6 @@ extern "C" {
extern "C" {
pub fn sqlite3_str_appendf(arg1: *mut sqlite3_str, zFormat: *const ::std::os::raw::c_char, ...);
}
-extern "C" {
- pub fn sqlite3_str_vappendf(
- arg1: *mut sqlite3_str,
- zFormat: *const ::std::os::raw::c_char,
- arg2: *mut __va_list_tag,
- );
-}
extern "C" {
pub fn sqlite3_str_append(
arg1: *mut sqlite3_str,
@@ -3188,6 +3169,34 @@ pub struct Fts5ExtensionApi {
arg3: *mut ::std::os::raw::c_int,
) -> ::std::os::raw::c_int,
>,
+ pub xColumnLocale: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut Fts5Context,
+ iCol: ::std::os::raw::c_int,
+ pz: *mut *const ::std::os::raw::c_char,
+ pn: *mut ::std::os::raw::c_int,
+ ) -> ::std::os::raw::c_int,
+ >,
+ pub xTokenize_v2: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut Fts5Context,
+ pText: *const ::std::os::raw::c_char,
+ nText: ::std::os::raw::c_int,
+ pLocale: *const ::std::os::raw::c_char,
+ nLocale: ::std::os::raw::c_int,
+ pCtx: *mut ::std::os::raw::c_void,
+ xToken: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut ::std::os::raw::c_void,
+ arg2: ::std::os::raw::c_int,
+ arg3: *const ::std::os::raw::c_char,
+ arg4: ::std::os::raw::c_int,
+ arg5: ::std::os::raw::c_int,
+ arg6: ::std::os::raw::c_int,
+ ) -> ::std::os::raw::c_int,
+ >,
+ ) -> ::std::os::raw::c_int,
+ >,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@@ -3196,6 +3205,41 @@ pub struct Fts5Tokenizer {
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
+pub struct fts5_tokenizer_v2 {
+ pub iVersion: ::std::os::raw::c_int,
+ pub xCreate: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut ::std::os::raw::c_void,
+ azArg: *mut *const ::std::os::raw::c_char,
+ nArg: ::std::os::raw::c_int,
+ ppOut: *mut *mut Fts5Tokenizer,
+ ) -> ::std::os::raw::c_int,
+ >,
+ pub xDelete: ::std::option::Option,
+ pub xTokenize: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut Fts5Tokenizer,
+ pCtx: *mut ::std::os::raw::c_void,
+ flags: ::std::os::raw::c_int,
+ pText: *const ::std::os::raw::c_char,
+ nText: ::std::os::raw::c_int,
+ pLocale: *const ::std::os::raw::c_char,
+ nLocale: ::std::os::raw::c_int,
+ xToken: ::std::option::Option<
+ unsafe extern "C" fn(
+ pCtx: *mut ::std::os::raw::c_void,
+ tflags: ::std::os::raw::c_int,
+ pToken: *const ::std::os::raw::c_char,
+ nToken: ::std::os::raw::c_int,
+ iStart: ::std::os::raw::c_int,
+ iEnd: ::std::os::raw::c_int,
+ ) -> ::std::os::raw::c_int,
+ >,
+ ) -> ::std::os::raw::c_int,
+ >,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
pub struct fts5_tokenizer {
pub xCreate: ::std::option::Option<
unsafe extern "C" fn(
@@ -3256,6 +3300,23 @@ pub struct fts5_api {
xDestroy: ::std::option::Option,
) -> ::std::os::raw::c_int,
>,
+ pub xCreateTokenizer_v2: ::std::option::Option<
+ unsafe extern "C" fn(
+ pApi: *mut fts5_api,
+ zName: *const ::std::os::raw::c_char,
+ pUserData: *mut ::std::os::raw::c_void,
+ pTokenizer: *mut fts5_tokenizer_v2,
+ xDestroy: ::std::option::Option,
+ ) -> ::std::os::raw::c_int,
+ >,
+ pub xFindTokenizer_v2: ::std::option::Option<
+ unsafe extern "C" fn(
+ pApi: *mut fts5_api,
+ zName: *const ::std::os::raw::c_char,
+ ppUserData: *mut *mut ::std::os::raw::c_void,
+ ppTokenizer: *mut *mut fts5_tokenizer_v2,
+ ) -> ::std::os::raw::c_int,
+ >,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@@ -3574,12 +3635,3 @@ extern "C" {
extern "C" {
pub static sqlite3_wal_manager: libsql_wal_manager;
}
-pub type __builtin_va_list = [__va_list_tag; 1usize];
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct __va_list_tag {
- pub gp_offset: ::std::os::raw::c_uint,
- pub fp_offset: ::std::os::raw::c_uint,
- pub overflow_arg_area: *mut ::std::os::raw::c_void,
- pub reg_save_area: *mut ::std::os::raw::c_void,
-}
diff --git a/libsql-ffi/bundled/bindings/session_bindgen.rs b/libsql-ffi/bundled/bindings/session_bindgen.rs
index f2621f1d43..6bd4abcda6 100644
--- a/libsql-ffi/bundled/bindings/session_bindgen.rs
+++ b/libsql-ffi/bundled/bindings/session_bindgen.rs
@@ -23,10 +23,10 @@ extern "C" {
) -> ::std::os::raw::c_int;
}
-pub const SQLITE_VERSION: &[u8; 7] = b"3.45.1\0";
-pub const SQLITE_VERSION_NUMBER: i32 = 3045001;
+pub const SQLITE_VERSION: &[u8; 7] = b"3.47.2\0";
+pub const SQLITE_VERSION_NUMBER: i32 = 3047002;
pub const SQLITE_SOURCE_ID: &[u8; 85] =
- b"2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257ccalt1\0";
+ b"2024-12-07 20:39:59 2aabe05e2e8cae4847a802ee2daddc1d7413d8fc560254d93ee3e72c1468alt1\0";
pub const LIBSQL_VERSION: &[u8; 6] = b"0.2.3\0";
pub const SQLITE_OK: i32 = 0;
pub const SQLITE_ERROR: i32 = 1;
@@ -174,6 +174,7 @@ pub const SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN: i32 = 2048;
pub const SQLITE_IOCAP_POWERSAFE_OVERWRITE: i32 = 4096;
pub const SQLITE_IOCAP_IMMUTABLE: i32 = 8192;
pub const SQLITE_IOCAP_BATCH_ATOMIC: i32 = 16384;
+pub const SQLITE_IOCAP_SUBPAGE_READ: i32 = 32768;
pub const SQLITE_LOCK_NONE: i32 = 0;
pub const SQLITE_LOCK_SHARED: i32 = 1;
pub const SQLITE_LOCK_RESERVED: i32 = 2;
@@ -263,6 +264,7 @@ pub const SQLITE_CONFIG_STMTJRNL_SPILL: i32 = 26;
pub const SQLITE_CONFIG_SMALL_MALLOC: i32 = 27;
pub const SQLITE_CONFIG_SORTERREF_SIZE: i32 = 28;
pub const SQLITE_CONFIG_MEMDB_MAXSIZE: i32 = 29;
+pub const SQLITE_CONFIG_ROWID_IN_VIEW: i32 = 30;
pub const SQLITE_DBCONFIG_MAINDBNAME: i32 = 1000;
pub const SQLITE_DBCONFIG_LOOKASIDE: i32 = 1001;
pub const SQLITE_DBCONFIG_ENABLE_FKEY: i32 = 1002;
@@ -356,12 +358,14 @@ pub const SQLITE_DIRECTONLY: i32 = 524288;
pub const SQLITE_SUBTYPE: i32 = 1048576;
pub const SQLITE_INNOCUOUS: i32 = 2097152;
pub const SQLITE_RESULT_SUBTYPE: i32 = 16777216;
+pub const SQLITE_SELFORDER1: i32 = 33554432;
pub const SQLITE_WIN32_DATA_DIRECTORY_TYPE: i32 = 1;
pub const SQLITE_WIN32_TEMP_DIRECTORY_TYPE: i32 = 2;
pub const SQLITE_TXN_NONE: i32 = 0;
pub const SQLITE_TXN_READ: i32 = 1;
pub const SQLITE_TXN_WRITE: i32 = 2;
pub const SQLITE_INDEX_SCAN_UNIQUE: i32 = 1;
+pub const SQLITE_INDEX_SCAN_HEX: i32 = 2;
pub const SQLITE_INDEX_CONSTRAINT_EQ: i32 = 2;
pub const SQLITE_INDEX_CONSTRAINT_GT: i32 = 4;
pub const SQLITE_INDEX_CONSTRAINT_LE: i32 = 8;
@@ -411,6 +415,7 @@ pub const SQLITE_TESTCTRL_RESERVE: i32 = 14;
pub const SQLITE_TESTCTRL_JSON_SELFCHECK: i32 = 14;
pub const SQLITE_TESTCTRL_OPTIMIZATIONS: i32 = 15;
pub const SQLITE_TESTCTRL_ISKEYWORD: i32 = 16;
+pub const SQLITE_TESTCTRL_GETOPT: i32 = 16;
pub const SQLITE_TESTCTRL_SCRATCHMALLOC: i32 = 17;
pub const SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: i32 = 17;
pub const SQLITE_TESTCTRL_LOCALTIME_FAULT: i32 = 18;
@@ -518,8 +523,6 @@ pub const FTS5_TOKENIZE_DOCUMENT: i32 = 4;
pub const FTS5_TOKENIZE_AUX: i32 = 8;
pub const FTS5_TOKEN_COLOCATED: i32 = 1;
pub const WAL_SAVEPOINT_NDATA: i32 = 4;
-pub type __gnuc_va_list = __builtin_va_list;
-pub type va_list = __builtin_va_list;
extern "C" {
pub static sqlite3_version: [::std::os::raw::c_char; 0usize];
}
@@ -953,12 +956,6 @@ extern "C" {
pub fn sqlite3_mprintf(arg1: *const ::std::os::raw::c_char, ...)
-> *mut ::std::os::raw::c_char;
}
-extern "C" {
- pub fn sqlite3_vmprintf(
- arg1: *const ::std::os::raw::c_char,
- arg2: va_list,
- ) -> *mut ::std::os::raw::c_char;
-}
extern "C" {
pub fn sqlite3_snprintf(
arg1: ::std::os::raw::c_int,
@@ -967,14 +964,6 @@ extern "C" {
...
) -> *mut ::std::os::raw::c_char;
}
-extern "C" {
- pub fn sqlite3_vsnprintf(
- arg1: ::std::os::raw::c_int,
- arg2: *mut ::std::os::raw::c_char,
- arg3: *const ::std::os::raw::c_char,
- arg4: va_list,
- ) -> *mut ::std::os::raw::c_char;
-}
extern "C" {
pub fn sqlite3_malloc(arg1: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_void;
}
@@ -2518,13 +2507,6 @@ extern "C" {
extern "C" {
pub fn sqlite3_str_appendf(arg1: *mut sqlite3_str, zFormat: *const ::std::os::raw::c_char, ...);
}
-extern "C" {
- pub fn sqlite3_str_vappendf(
- arg1: *mut sqlite3_str,
- zFormat: *const ::std::os::raw::c_char,
- arg2: va_list,
- );
-}
extern "C" {
pub fn sqlite3_str_append(
arg1: *mut sqlite3_str,
@@ -3227,6 +3209,12 @@ extern "C" {
pData: *mut ::std::os::raw::c_void,
) -> ::std::os::raw::c_int;
}
+extern "C" {
+ pub fn sqlite3changegroup_add_change(
+ arg1: *mut sqlite3_changegroup,
+ arg2: *mut sqlite3_changeset_iter,
+ ) -> ::std::os::raw::c_int;
+}
extern "C" {
pub fn sqlite3changegroup_output(
arg1: *mut sqlite3_changegroup,
@@ -3699,6 +3687,34 @@ pub struct Fts5ExtensionApi {
arg3: *mut ::std::os::raw::c_int,
) -> ::std::os::raw::c_int,
>,
+ pub xColumnLocale: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut Fts5Context,
+ iCol: ::std::os::raw::c_int,
+ pz: *mut *const ::std::os::raw::c_char,
+ pn: *mut ::std::os::raw::c_int,
+ ) -> ::std::os::raw::c_int,
+ >,
+ pub xTokenize_v2: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut Fts5Context,
+ pText: *const ::std::os::raw::c_char,
+ nText: ::std::os::raw::c_int,
+ pLocale: *const ::std::os::raw::c_char,
+ nLocale: ::std::os::raw::c_int,
+ pCtx: *mut ::std::os::raw::c_void,
+ xToken: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut ::std::os::raw::c_void,
+ arg2: ::std::os::raw::c_int,
+ arg3: *const ::std::os::raw::c_char,
+ arg4: ::std::os::raw::c_int,
+ arg5: ::std::os::raw::c_int,
+ arg6: ::std::os::raw::c_int,
+ ) -> ::std::os::raw::c_int,
+ >,
+ ) -> ::std::os::raw::c_int,
+ >,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@@ -3707,6 +3723,41 @@ pub struct Fts5Tokenizer {
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
+pub struct fts5_tokenizer_v2 {
+ pub iVersion: ::std::os::raw::c_int,
+ pub xCreate: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut ::std::os::raw::c_void,
+ azArg: *mut *const ::std::os::raw::c_char,
+ nArg: ::std::os::raw::c_int,
+ ppOut: *mut *mut Fts5Tokenizer,
+ ) -> ::std::os::raw::c_int,
+ >,
+ pub xDelete: ::std::option::Option,
+ pub xTokenize: ::std::option::Option<
+ unsafe extern "C" fn(
+ arg1: *mut Fts5Tokenizer,
+ pCtx: *mut ::std::os::raw::c_void,
+ flags: ::std::os::raw::c_int,
+ pText: *const ::std::os::raw::c_char,
+ nText: ::std::os::raw::c_int,
+ pLocale: *const ::std::os::raw::c_char,
+ nLocale: ::std::os::raw::c_int,
+ xToken: ::std::option::Option<
+ unsafe extern "C" fn(
+ pCtx: *mut ::std::os::raw::c_void,
+ tflags: ::std::os::raw::c_int,
+ pToken: *const ::std::os::raw::c_char,
+ nToken: ::std::os::raw::c_int,
+ iStart: ::std::os::raw::c_int,
+ iEnd: ::std::os::raw::c_int,
+ ) -> ::std::os::raw::c_int,
+ >,
+ ) -> ::std::os::raw::c_int,
+ >,
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
pub struct fts5_tokenizer {
pub xCreate: ::std::option::Option<
unsafe extern "C" fn(
@@ -3767,6 +3818,23 @@ pub struct fts5_api {
xDestroy: ::std::option::Option,
) -> ::std::os::raw::c_int,
>,
+ pub xCreateTokenizer_v2: ::std::option::Option<
+ unsafe extern "C" fn(
+ pApi: *mut fts5_api,
+ zName: *const ::std::os::raw::c_char,
+ pUserData: *mut ::std::os::raw::c_void,
+ pTokenizer: *mut fts5_tokenizer_v2,
+ xDestroy: ::std::option::Option,
+ ) -> ::std::os::raw::c_int,
+ >,
+ pub xFindTokenizer_v2: ::std::option::Option<
+ unsafe extern "C" fn(
+ pApi: *mut fts5_api,
+ zName: *const ::std::os::raw::c_char,
+ ppUserData: *mut *mut ::std::os::raw::c_void,
+ ppTokenizer: *mut *mut fts5_tokenizer_v2,
+ ) -> ::std::os::raw::c_int,
+ >,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@@ -4085,4 +4153,3 @@ extern "C" {
extern "C" {
pub static sqlite3_wal_manager: libsql_wal_manager;
}
-pub type __builtin_va_list = *mut ::std::os::raw::c_char;
diff --git a/libsql-ffi/bundled/src/sqlite3.c b/libsql-ffi/bundled/src/sqlite3.c
index 8dc3ca8e72..ac1d7dc069 100644
--- a/libsql-ffi/bundled/src/sqlite3.c
+++ b/libsql-ffi/bundled/src/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.45.1. By combining all the individual C code files into this
+** version 3.47.2. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -18,7 +18,7 @@
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
-** e876e51a0ed5c5b3126f52e532044363a014 with changes in files:
+** 2aabe05e2e8cae4847a802ee2daddc1d7413 with changes in files:
**
** .fossil-settings/empty-dirs
** .fossil-settings/ignore-glob
@@ -28,13 +28,10 @@
** README.md
** configure
** configure.ac
-** doc/compile-for-windows.md
** doc/jsonb.md
-** doc/testrunner.md
** doc/trusted-schema.md
** doc/vdbesort-memory.md
** doc/wal-lock.md
-** ext/fts5/fts5_tokenize.c
** ext/jni/README.md
** ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java
** ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java
@@ -42,9 +39,9 @@
** ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java
** ext/jni/src/org/sqlite/jni/capi/ValueHolder.java
** ext/wasm/GNUmakefile
-** ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api
-** ext/wasm/api/sqlite3-api-glue.js
-** ext/wasm/api/sqlite3-api-oo1.js
+** ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core
+** ext/wasm/api/sqlite3-api-glue.c-pp.js
+** ext/wasm/api/sqlite3-api-oo1.c-pp.js
** ext/wasm/fiddle.make
** ext/wasm/fiddle/fiddle-worker.js
** ext/wasm/fiddle/fiddle.js
@@ -89,14 +86,12 @@
** src/wherecode.c
** test/all.test
** test/json/README.md
-** test/permutations.test
** test/rowvaluevtab.test
** tool/mkkeywordhash.c
** tool/mksqlite3c-noext.tcl
** tool/mksqlite3c.tcl
** tool/mksqlite3h.tcl
** tool/mksqlite3internalh.tcl
-** manifest.uuid
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
@@ -340,10 +335,13 @@
/*
** Macro to disable warnings about missing "break" at the end of a "case".
*/
-#if GCC_VERSION>=7000000
-# define deliberate_fall_through __attribute__((fallthrough));
-#else
-# define deliberate_fall_through
+#if defined(__has_attribute)
+# if __has_attribute(fallthrough)
+# define deliberate_fall_through __attribute__((fallthrough));
+# endif
+#endif
+#if !defined(deliberate_fall_through)
+# define deliberate_fall_through
#endif
/*
@@ -546,9 +544,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.45.1"
-#define SQLITE_VERSION_NUMBER 3045001
-#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257ccalt1"
+#define SQLITE_VERSION "3.47.2"
+#define SQLITE_VERSION_NUMBER 3047002
+#define SQLITE_SOURCE_ID "2024-12-07 20:39:59 2aabe05e2e8cae4847a802ee2daddc1d7413d8fc560254d93ee3e72c1468alt1"
#define LIBSQL_VERSION "0.2.3"
@@ -824,6 +822,8 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
** The application must not modify the SQL statement text passed into
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
+** The application must not dereference the arrays or string pointers
+** passed as the 3rd and 4th callback parameters after it returns.
**
*/
SQLITE_API int sqlite3_exec(
@@ -1054,6 +1054,13 @@ SQLITE_API int sqlite3_exec(
** filesystem supports doing multiple write operations atomically when those
** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
+**
+** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read
+** from the database file in amounts that are not a multiple of the
+** page size and that do not begin at a page boundary. Without this
+** property, SQLite is careful to only do full-page reads and write
+** on aligned pages, with the one exception that it will do a sub-page
+** read of the first page to access the database header.
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -1070,6 +1077,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
+#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000
/*
** CAPI3REF: File Locking Levels
@@ -1166,16 +1174,16 @@ struct sqlite3_file {
**
** xLock() upgrades the database file lock. In other words, xLock() moves the
** database file lock in the direction NONE toward EXCLUSIVE. The argument to
-** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
+** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
** SQLITE_LOCK_NONE. If the database file lock is already at or above the
** requested lock, then the call to xLock() is a no-op.
** xUnlock() downgrades the database file lock to either SHARED or NONE.
-* If the lock is already at or below the requested lock state, then the call
+** If the lock is already at or below the requested lock state, then the call
** to xUnlock() is a no-op.
** The xCheckReservedLock() method checks whether any database connection,
** either in this process or in some other process, is holding a RESERVED,
-** PENDING, or EXCLUSIVE lock on the file. It returns true
-** if such a lock exists and false otherwise.
+** PENDING, or EXCLUSIVE lock on the file. It returns, via its output
+** pointer parameter, true if such a lock exists and false otherwise.
**
** The xFileControl() method is a generic interface that allows custom
** VFS implementations to directly control an open file using the
@@ -1216,6 +1224,7 @@ struct sqlite3_file {
** [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
** [SQLITE_IOCAP_IMMUTABLE]
** [SQLITE_IOCAP_BATCH_ATOMIC]
+** [SQLITE_IOCAP_SUBPAGE_READ]
**
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -2565,6 +2574,22 @@ struct sqlite3_mem_methods {
** configuration setting is never used, then the default maximum is determined
** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that
** compile-time option is not set, then the default maximum is 1073741824.
+**
+** [[SQLITE_CONFIG_ROWID_IN_VIEW]]
+** SQLITE_CONFIG_ROWID_IN_VIEW
+** The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability
+** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is
+** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability
+** defaults to on. This configuration option queries the current setting or
+** changes the setting to off or on. The argument is a pointer to an integer.
+** If that integer initially holds a value of 1, then the ability for VIEWs to
+** have ROWIDs is activated. If the integer initially holds zero, then the
+** ability is deactivated. Any other initial value for the integer leaves the
+** setting unchanged. After changes, if any, the integer is written with
+** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite
+** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and
+** recommended case) then the integer is always filled with zero, regardless
+** if its initial value.
**
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2596,6 +2621,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
+#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -3710,8 +3736,8 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
-** CAPI3REF: Tracing And Profiling Functions
-** METHOD: sqlite3
+** CAPI3REF: Deprecated Tracing And Profiling Functions
+** DEPRECATED
**
** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
** instead of the routines described here.
@@ -3975,8 +4001,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** [[OPEN_EXRESCODE]] ^([SQLITE_OPEN_EXRESCODE]
** The database connection comes up in "extended result code mode".
-** In other words, the database behaves has if
-** [sqlite3_extended_result_codes(db,1)] where called on the database
+** In other words, the database behaves as if
+** [sqlite3_extended_result_codes(db,1)] were called on the database
** connection as soon as the connection is created. In addition to setting
** the extended result code mode, this flag also causes [sqlite3_open_v2()]
** to return an extended result code.
@@ -4661,13 +4687,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** and sqlite3_prepare16_v3() use UTF-16.
**
** ^If the nByte argument is negative, then zSql is read up to the
-** first zero terminator. ^If nByte is positive, then it is the
-** number of bytes read from zSql. ^If nByte is zero, then no prepared
+** first zero terminator. ^If nByte is positive, then it is the maximum
+** number of bytes read from zSql. When nByte is positive, zSql is read
+** up to the first zero terminator or until the nByte bytes have been read,
+** whichever comes first. ^If nByte is zero, then no prepared
** statement is generated.
** If the caller knows that the supplied string is nul-terminated, then
** there is a small performance advantage to passing an nByte parameter that
** is the number of bytes in the input string including
** the nul-terminator.
+** Note that nByte measure the length of the input in bytes, not
+** characters, even for the UTF-16 interfaces.
**
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
** past the end of the first SQL statement in zSql. These routines only
@@ -6040,7 +6070,7 @@ SQLITE_API int sqlite3_create_window_function(
** This flag instructs SQLite to omit some corner-case optimizations that
** might disrupt the operation of the [sqlite3_value_subtype()] function,
** causing it to return zero rather than the correct subtype().
-** SQL functions that invokes [sqlite3_value_subtype()] should have this
+** All SQL functions that invoke [sqlite3_value_subtype()] should have this
** property. If the SQLITE_SUBTYPE property is omitted, then the return
** value from [sqlite3_value_subtype()] might sometimes be zero even though
** a non-zero subtype was specified by the function argument expression.
@@ -6056,6 +6086,15 @@ SQLITE_API int sqlite3_create_window_function(
** [sqlite3_result_subtype()] should avoid setting this property, as the
** purpose of this property is to disable certain optimizations that are
** incompatible with subtypes.
+**
+** [[SQLITE_SELFORDER1]] SQLITE_SELFORDER1
+** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate
+** that internally orders the values provided to the first argument. The
+** ordered-set aggregate SQL notation with a single ORDER BY term can be
+** used to invoke this function. If the ordered-set aggregate notation is
+** used on a function that lacks this flag, then an error is raised. Note
+** that the ordered-set aggregate syntax is only available if SQLite is
+** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option.
**
**
*/
@@ -6064,6 +6103,7 @@ SQLITE_API int sqlite3_create_window_function(
#define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000
#define SQLITE_RESULT_SUBTYPE 0x001000000
+#define SQLITE_SELFORDER1 0x002000000
/*
** CAPI3REF: Deprecated Functions
@@ -6261,7 +6301,7 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*);
** one SQL function to another. Use the [sqlite3_result_subtype()]
** routine to set the subtype for the return value of an SQL function.
**
-** Every [application-defined SQL function] that invoke this interface
+** Every [application-defined SQL function] that invokes this interface
** should include the [SQLITE_SUBTYPE] property in the text
** encoding argument when the function is [sqlite3_create_function|registered].
** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype()
@@ -7328,6 +7368,12 @@ SQLITE_API int sqlite3_autovacuum_pages(
** The exceptions defined in this paragraph might change in a future
** release of SQLite.
**
+** Whether the update hook is invoked before or after the
+** corresponding change is currently unspecified and may differ
+** depending on the type of change. Do not rely on the order of the
+** hook call with regards to the final result of the operation which
+** triggers the hook.
+**
** 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
@@ -7867,9 +7913,11 @@ struct sqlite3_module {
** will be returned by the strategy.
**
** The xBestIndex method may optionally populate the idxFlags field with a
-** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
-** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
-** assumes that the strategy may visit at most one row.
+** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
+** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
+** output to show the idxNum has hex instead of as decimal. Another flag is
+** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
+** return at most one row.
**
** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
** SQLite also assumes that if a call to the xUpdate() method is made as
@@ -7933,7 +7981,9 @@ struct sqlite3_index_info {
** [sqlite3_index_info].idxFlags field to some combination of
** these bits.
*/
-#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
+#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */
+#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */
+ /* in EXPLAIN QUERY PLAN */
/*
** CAPI3REF: Virtual Table Constraint Operator Codes
@@ -8792,6 +8842,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
+#define SQLITE_TESTCTRL_GETOPT 16
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
@@ -8811,7 +8862,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_TRACEFLAGS 31
#define SQLITE_TESTCTRL_TUNE 32
#define SQLITE_TESTCTRL_LOGEST 33
-#define SQLITE_TESTCTRL_USELONGDOUBLE 34
+#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */
#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */
/*
@@ -8825,7 +8876,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
** The sqlite3_keyword_count() interface returns the number of distinct
** keywords understood by SQLite.
**
-** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
+** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and
** makes *Z point to that keyword expressed as UTF8 and writes the number
** of bytes in the keyword into *L. The string that *Z points to is not
** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
@@ -9803,6 +9854,16 @@ typedef struct sqlite3_backup sqlite3_backup;
** APIs are not strictly speaking threadsafe. If they are invoked at the
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
+**
+** Alternatives To Using The Backup API
+**
+** Other techniques for safely creating a consistent backup of an SQLite
+** database include:
+**
+**
+** - The [VACUUM INTO] command.
+**
- The [sqlite3_rsync] utility program.
+**
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
@@ -10420,24 +10481,45 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
**
** ^(If the sqlite3_vtab_distinct() interface returns 2, that means
** that the query planner does not need the rows returned in any particular
-** order, as long as rows with the same values in all "aOrderBy" columns
-** are adjacent.)^ ^(Furthermore, only a single row for each particular
-** combination of values in the columns identified by the "aOrderBy" field
-** needs to be returned.)^ ^It is always ok for two or more rows with the same
-** values in all "aOrderBy" columns to be returned, as long as all such rows
-** are adjacent. ^The virtual table may, if it chooses, omit extra rows
-** that have the same value for all columns identified by "aOrderBy".
-** ^However omitting the extra rows is optional.
+** order, as long as rows with the same values in all columns identified
+** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows
+** contain the same values for all columns identified by "colUsed", all but
+** one such row may optionally be omitted from the result.)^
+** The virtual table is not required to omit rows that are duplicates
+** over the "colUsed" columns, but if the virtual table can do that without
+** too much extra effort, it could potentially help the query to run faster.
** This mode is used for a DISTINCT query.
**
-** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
-** that the query planner needs only distinct rows but it does need the
-** rows to be sorted.)^ ^The virtual table implementation is free to omit
-** rows that are identical in all aOrderBy columns, if it wants to, but
-** it is not required to omit any rows. This mode is used for queries
+** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the
+** virtual table must return rows in the order defined by "aOrderBy" as
+** if the sqlite3_vtab_distinct() interface had returned 0. However if
+** two or more rows in the result have the same values for all columns
+** identified by "colUsed", then all but one such row may optionally be
+** omitted.)^ Like when the return value is 2, the virtual table
+** is not required to omit rows that are duplicates over the "colUsed"
+** columns, but if the virtual table can do that without
+** too much extra effort, it could potentially help the query to run faster.
+** This mode is used for queries
** that have both DISTINCT and ORDER BY clauses.
**
**
+**
The following table summarizes the conditions under which the
+** virtual table is allowed to set the "orderByConsumed" flag based on
+** the value returned by sqlite3_vtab_distinct(). This table is a
+** restatement of the previous four paragraphs:
+**
+**
+**
+** | sqlite3_vtab_distinct() return value
+** | Rows are returned in aOrderBy order
+** | Rows with the same value in all aOrderBy columns are adjacent
+** | Duplicates over all colUsed columns may be omitted
+** |
| 0 | yes | yes | no
+** |
| 1 | no | yes | no
+** |
| 2 | no | yes | yes
+** |
| 3 | yes | yes | yes
+** |
+**
** ^For the purposes of comparing virtual table output values to see if the
** values are same value for sorting purposes, two NULL values are considered
** to be the same. In other words, the comparison operator is "IS"
@@ -11050,6 +11132,14 @@ typedef struct sqlite3_snapshot {
** If there is not already a read-transaction open on schema S when
** this function is called, one is opened automatically.
**
+** If a read-transaction is opened by this function, then it is guaranteed
+** that the returned snapshot object may not be invalidated by a database
+** writer or checkpointer until after the read-transaction is closed. This
+** is not guaranteed if a read-transaction is already open when this
+** function is called. In that case, any subsequent write or checkpoint
+** operation on the database may invalidate the returned snapshot handle,
+** even while the read-transaction remains open.
+**
** The following must be true for this function to succeed. If any of
** the following statements are false when sqlite3_snapshot_get() is
** called, SQLITE_ERROR is returned. The final value of *P is undefined
@@ -12552,6 +12642,30 @@ SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const c
*/
SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
+/*
+** CAPI3REF: Add A Single Change To A Changegroup
+** METHOD: sqlite3_changegroup
+**
+** This function adds the single change currently indicated by the iterator
+** passed as the second argument to the changegroup object. The rules for
+** adding the change are just as described for [sqlite3changegroup_add()].
+**
+** If the change is successfully added to the changegroup, SQLITE_OK is
+** returned. Otherwise, an SQLite error code is returned.
+**
+** The iterator must point to a valid entry when this function is called.
+** If it does not, SQLITE_ERROR is returned and no change is added to the
+** changegroup. Additionally, the iterator must not have been opened with
+** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also
+** returned.
+*/
+SQLITE_API int sqlite3changegroup_add_change(
+ sqlite3_changegroup*,
+ sqlite3_changeset_iter*
+);
+
+
+
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
** METHOD: sqlite3_changegroup
@@ -13356,8 +13470,8 @@ struct Fts5PhraseIter {
** EXTENSION API FUNCTIONS
**
** xUserData(pFts):
-** Return a copy of the context pointer the extension function was
-** registered with.
+** Return a copy of the pUserData pointer passed to the xCreateFunction()
+** API when the extension function was registered.
**
** xColumnTotalSize(pFts, iCol, pnToken):
** If parameter iCol is less than zero, set output variable *pnToken
@@ -13539,6 +13653,10 @@ struct Fts5PhraseIter {
** (i.e. if it is a contentless table), then this API always iterates
** through an empty set (all calls to xPhraseFirst() set iCol to -1).
**
+** In all cases, matches are visited in (column ASC, offset ASC) order.
+** i.e. all those in column 0, sorted by offset, followed by those in
+** column 1, etc.
+**
** xPhraseNext()
** See xPhraseFirst above.
**
@@ -13605,9 +13723,32 @@ struct Fts5PhraseIter {
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
+**
+** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale)
+** If parameter iCol is less than zero, or greater than or equal to the
+** number of columns in the table, SQLITE_RANGE is returned.
+**
+** Otherwise, this function attempts to retrieve the locale associated
+** with column iCol of the current row. Usually, there is no associated
+** locale, and output parameters (*pzLocale) and (*pnLocale) are set
+** to NULL and 0, respectively. However, if the fts5_locale() function
+** was used to associate a locale with the value when it was inserted
+** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated
+** buffer containing the name of the locale in utf-8 encoding. (*pnLocale)
+** is set to the size in bytes of the buffer, not including the
+** nul-terminator.
+**
+** If successful, SQLITE_OK is returned. Or, if an error occurs, an
+** SQLite error code is returned. The final value of the output parameters
+** is undefined in this case.
+**
+** xTokenize_v2:
+** Tokenize text using the tokenizer belonging to the FTS5 table. This
+** API is the same as the xTokenize() API, except that it allows a tokenizer
+** locale to be specified.
*/
struct Fts5ExtensionApi {
- int iVersion; /* Currently always set to 3 */
+ int iVersion; /* Currently always set to 4 */
void *(*xUserData)(Fts5Context*);
@@ -13649,6 +13790,15 @@ struct Fts5ExtensionApi {
const char **ppToken, int *pnToken
);
int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*);
+
+ /* Below this point are iVersion>=4 only */
+ int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
+ int (*xTokenize_v2)(Fts5Context*,
+ const char *pText, int nText, /* Text to tokenize */
+ const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
+ void *pCtx, /* Context passed to xToken() */
+ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
+ );
};
/*
@@ -13669,7 +13819,7 @@ struct Fts5ExtensionApi {
** A tokenizer instance is required to actually tokenize text.
**
** The first argument passed to this function is a copy of the (void*)
-** pointer provided by the application when the fts5_tokenizer object
+** pointer provided by the application when the fts5_tokenizer_v2 object
** was registered with FTS5 (the third argument to xCreateTokenizer()).
** The second and third arguments are an array of nul-terminated strings
** containing the tokenizer arguments, if any, specified following the
@@ -13693,7 +13843,7 @@ struct Fts5ExtensionApi {
** argument passed to this function is a pointer to an Fts5Tokenizer object
** returned by an earlier call to xCreate().
**
-** The second argument indicates the reason that FTS5 is requesting
+** The third argument indicates the reason that FTS5 is requesting
** tokenization of the supplied text. This is always one of the following
** four values:
**
@@ -13717,6 +13867,13 @@ struct Fts5ExtensionApi {
** on a columnsize=0 database.
**
**
+** The sixth and seventh arguments passed to xTokenize() - pLocale and
+** nLocale - are a pointer to a buffer containing the locale to use for
+** tokenization (e.g. "en_US") and its size in bytes, respectively. The
+** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in
+** which case nLocale is always 0) to indicate that the tokenizer should
+** use its default locale.
+**
** For each token in the input string, the supplied callback xToken() must
** be invoked. The first argument to it should be a copy of the pointer
** passed as the second argument to xTokenize(). The third and fourth
@@ -13740,6 +13897,30 @@ struct Fts5ExtensionApi {
** may abandon the tokenization and return any error code other than
** SQLITE_OK or SQLITE_DONE.
**
+** If the tokenizer is registered using an fts5_tokenizer_v2 object,
+** then the xTokenize() method has two additional arguments - pLocale
+** and nLocale. These specify the locale that the tokenizer should use
+** for the current request. If pLocale and nLocale are both 0, then the
+** tokenizer should use its default locale. Otherwise, pLocale points to
+** an nLocale byte buffer containing the name of the locale to use as utf-8
+** text. pLocale is not nul-terminated.
+**
+** FTS5_TOKENIZER
+**
+** There is also an fts5_tokenizer object. This is an older, deprecated,
+** version of fts5_tokenizer_v2. It is similar except that:
+**
+**
+** - There is no "iVersion" field, and
+**
- The xTokenize() method does not take a locale argument.
+**
+**
+** Legacy fts5_tokenizer tokenizers must be registered using the
+** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
+**
+** Tokenizer implementations registered using either API may be retrieved
+** using both xFindTokenizer() and xFindTokenizer_v2().
+**
** SYNONYM SUPPORT
**
** Custom tokenizers may also support synonyms. Consider a case in which a
@@ -13848,6 +14029,33 @@ struct Fts5ExtensionApi {
** inefficient.
*/
typedef struct Fts5Tokenizer Fts5Tokenizer;
+typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2;
+struct fts5_tokenizer_v2 {
+ int iVersion; /* Currently always 2 */
+
+ int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
+ void (*xDelete)(Fts5Tokenizer*);
+ int (*xTokenize)(Fts5Tokenizer*,
+ void *pCtx,
+ int flags, /* Mask of FTS5_TOKENIZE_* flags */
+ const char *pText, int nText,
+ const char *pLocale, int nLocale,
+ int (*xToken)(
+ void *pCtx, /* Copy of 2nd argument to xTokenize() */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Pointer to buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStart, /* Byte offset of token within input text */
+ int iEnd /* Byte offset of end of token within input text */
+ )
+ );
+};
+
+/*
+** New code should use the fts5_tokenizer_v2 type to define tokenizer
+** implementations. The following type is included for legacy applications
+** that still use it.
+*/
typedef struct fts5_tokenizer fts5_tokenizer;
struct fts5_tokenizer {
int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut);
@@ -13867,6 +14075,7 @@ struct fts5_tokenizer {
);
};
+
/* Flags that may be passed as the third argument to xTokenize() */
#define FTS5_TOKENIZE_QUERY 0x0001
#define FTS5_TOKENIZE_PREFIX 0x0002
@@ -13886,7 +14095,7 @@ struct fts5_tokenizer {
*/
typedef struct fts5_api fts5_api;
struct fts5_api {
- int iVersion; /* Currently always set to 2 */
+ int iVersion; /* Currently always set to 3 */
/* Create a new tokenizer */
int (*xCreateTokenizer)(
@@ -13913,6 +14122,25 @@ struct fts5_api {
fts5_extension_function xFunction,
void (*xDestroy)(void*)
);
+
+ /* APIs below this point are only available if iVersion>=3 */
+
+ /* Create a new tokenizer */
+ int (*xCreateTokenizer_v2)(
+ fts5_api *pApi,
+ const char *zName,
+ void *pUserData,
+ fts5_tokenizer_v2 *pTokenizer,
+ void (*xDestroy)(void*)
+ );
+
+ /* Find an existing tokenizer */
+ int (*xFindTokenizer_v2)(
+ fts5_api *pApi,
+ const char *zName,
+ void **ppUserData,
+ fts5_tokenizer_v2 **ppTokenizer
+ );
};
/*
@@ -14911,6 +15139,8 @@ SQLITE_API void libsql_wasm_engine_free(libsql_wasm_engine_t *);
# define SQLITE_OMIT_ALTERTABLE
#endif
+#define SQLITE_DIGIT_SEPARATOR '_'
+
/*
** Return true (non-zero) if the input is an integer that is too large
** to fit in 32-bits. This macro is used inside of various testcase()
@@ -15080,134 +15310,134 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_OR 47
#define TK_AND 48
#define TK_IS 49
-#define TK_MATCH 50
-#define TK_LIKE_KW 51
-#define TK_BETWEEN 52
-#define TK_IN 53
-#define TK_ISNULL 54
-#define TK_NOTNULL 55
-#define TK_NE 56
-#define TK_EQ 57
-#define TK_GT 58
-#define TK_LE 59
-#define TK_LT 60
-#define TK_GE 61
-#define TK_ESCAPE 62
-#define TK_ID 63
-#define TK_COLUMNKW 64
-#define TK_DO 65
-#define TK_FOR 66
-#define TK_IGNORE 67
-#define TK_INITIALLY 68
-#define TK_INSTEAD 69
-#define TK_NO 70
-#define TK_KEY 71
-#define TK_OF 72
-#define TK_OFFSET 73
-#define TK_PRAGMA 74
-#define TK_RAISE 75
-#define TK_RECURSIVE 76
-#define TK_REPLACE 77
-#define TK_RESTRICT 78
-#define TK_ROW 79
-#define TK_ROWS 80
-#define TK_TRIGGER 81
-#define TK_VACUUM 82
-#define TK_VIEW 83
-#define TK_VIRTUAL 84
-#define TK_WITH 85
-#define TK_NULLS 86
-#define TK_FIRST 87
-#define TK_LAST 88
-#define TK_CURRENT 89
-#define TK_FOLLOWING 90
-#define TK_PARTITION 91
-#define TK_PRECEDING 92
-#define TK_RANGE 93
-#define TK_UNBOUNDED 94
-#define TK_EXCLUDE 95
-#define TK_GROUPS 96
-#define TK_OTHERS 97
-#define TK_TIES 98
-#define TK_GENERATED 99
-#define TK_ALWAYS 100
-#define TK_MATERIALIZED 101
-#define TK_REINDEX 102
-#define TK_RENAME 103
-#define TK_CTIME_KW 104
-#define TK_ANY 105
-#define TK_BITAND 106
-#define TK_BITOR 107
-#define TK_LSHIFT 108
-#define TK_RSHIFT 109
-#define TK_PLUS 110
-#define TK_MINUS 111
-#define TK_STAR 112
-#define TK_SLASH 113
-#define TK_REM 114
-#define TK_CONCAT 115
-#define TK_PTR 116
-#define TK_COLLATE 117
-#define TK_BITNOT 118
-#define TK_ON 119
-#define TK_INDEXED 120
-#define TK_STRING 121
-#define TK_JOIN_KW 122
-#define TK_CONSTRAINT 123
-#define TK_DEFAULT 124
-#define TK_NULL 125
-#define TK_PRIMARY 126
-#define TK_UNIQUE 127
-#define TK_CHECK 128
-#define TK_REFERENCES 129
-#define TK_AUTOINCR 130
-#define TK_INSERT 131
-#define TK_DELETE 132
-#define TK_UPDATE 133
-#define TK_SET 134
-#define TK_DEFERRABLE 135
-#define TK_FOREIGN 136
-#define TK_DROP 137
-#define TK_BLOB 138
-#define TK_UNION 139
-#define TK_ALL 140
-#define TK_EXCEPT 141
-#define TK_INTERSECT 142
-#define TK_SELECT 143
-#define TK_VALUES 144
-#define TK_DISTINCT 145
-#define TK_DOT 146
-#define TK_FROM 147
-#define TK_JOIN 148
-#define TK_USING 149
-#define TK_ORDER 150
-#define TK_GROUP 151
-#define TK_HAVING 152
-#define TK_LIMIT 153
-#define TK_WHERE 154
-#define TK_RETURNING 155
-#define TK_INTO 156
-#define TK_NOTHING 157
-#define TK_FLOAT 158
-#define TK_INTEGER 159
-#define TK_VARIABLE 160
-#define TK_CASE 161
-#define TK_WHEN 162
-#define TK_THEN 163
-#define TK_ELSE 164
-#define TK_INDEX 165
-#define TK_ALTER 166
-#define TK_ADD 167
-#define TK_WINDOW 168
-#define TK_OVER 169
-#define TK_FILTER 170
-#define TK_COLUMN 171
-#define TK_AGG_FUNCTION 172
-#define TK_AGG_COLUMN 173
-#define TK_TRUEFALSE 174
-#define TK_ISNOT 175
-#define TK_UMINUS 176
-#define TK_UPLUS 177
+#define TK_ISNOT 50
+#define TK_MATCH 51
+#define TK_LIKE_KW 52
+#define TK_BETWEEN 53
+#define TK_IN 54
+#define TK_ISNULL 55
+#define TK_NOTNULL 56
+#define TK_NE 57
+#define TK_EQ 58
+#define TK_GT 59
+#define TK_LE 60
+#define TK_LT 61
+#define TK_GE 62
+#define TK_ESCAPE 63
+#define TK_ID 64
+#define TK_COLUMNKW 65
+#define TK_DO 66
+#define TK_FOR 67
+#define TK_IGNORE 68
+#define TK_INITIALLY 69
+#define TK_INSTEAD 70
+#define TK_NO 71
+#define TK_KEY 72
+#define TK_OF 73
+#define TK_OFFSET 74
+#define TK_PRAGMA 75
+#define TK_RAISE 76
+#define TK_RECURSIVE 77
+#define TK_REPLACE 78
+#define TK_RESTRICT 79
+#define TK_ROW 80
+#define TK_ROWS 81
+#define TK_TRIGGER 82
+#define TK_VACUUM 83
+#define TK_VIEW 84
+#define TK_VIRTUAL 85
+#define TK_WITH 86
+#define TK_NULLS 87
+#define TK_FIRST 88
+#define TK_LAST 89
+#define TK_CURRENT 90
+#define TK_FOLLOWING 91
+#define TK_PARTITION 92
+#define TK_PRECEDING 93
+#define TK_RANGE 94
+#define TK_UNBOUNDED 95
+#define TK_EXCLUDE 96
+#define TK_GROUPS 97
+#define TK_OTHERS 98
+#define TK_TIES 99
+#define TK_GENERATED 100
+#define TK_ALWAYS 101
+#define TK_MATERIALIZED 102
+#define TK_REINDEX 103
+#define TK_RENAME 104
+#define TK_CTIME_KW 105
+#define TK_ANY 106
+#define TK_BITAND 107
+#define TK_BITOR 108
+#define TK_LSHIFT 109
+#define TK_RSHIFT 110
+#define TK_PLUS 111
+#define TK_MINUS 112
+#define TK_STAR 113
+#define TK_SLASH 114
+#define TK_REM 115
+#define TK_CONCAT 116
+#define TK_PTR 117
+#define TK_COLLATE 118
+#define TK_BITNOT 119
+#define TK_ON 120
+#define TK_INDEXED 121
+#define TK_STRING 122
+#define TK_JOIN_KW 123
+#define TK_CONSTRAINT 124
+#define TK_DEFAULT 125
+#define TK_NULL 126
+#define TK_PRIMARY 127
+#define TK_UNIQUE 128
+#define TK_CHECK 129
+#define TK_REFERENCES 130
+#define TK_AUTOINCR 131
+#define TK_INSERT 132
+#define TK_DELETE 133
+#define TK_UPDATE 134
+#define TK_SET 135
+#define TK_DEFERRABLE 136
+#define TK_FOREIGN 137
+#define TK_DROP 138
+#define TK_BLOB 139
+#define TK_UNION 140
+#define TK_ALL 141
+#define TK_EXCEPT 142
+#define TK_INTERSECT 143
+#define TK_SELECT 144
+#define TK_VALUES 145
+#define TK_DISTINCT 146
+#define TK_DOT 147
+#define TK_FROM 148
+#define TK_JOIN 149
+#define TK_USING 150
+#define TK_ORDER 151
+#define TK_GROUP 152
+#define TK_HAVING 153
+#define TK_LIMIT 154
+#define TK_WHERE 155
+#define TK_RETURNING 156
+#define TK_INTO 157
+#define TK_NOTHING 158
+#define TK_FLOAT 159
+#define TK_INTEGER 160
+#define TK_VARIABLE 161
+#define TK_CASE 162
+#define TK_WHEN 163
+#define TK_THEN 164
+#define TK_ELSE 165
+#define TK_INDEX 166
+#define TK_ALTER 167
+#define TK_ADD 168
+#define TK_WINDOW 169
+#define TK_OVER 170
+#define TK_FILTER 171
+#define TK_COLUMN 172
+#define TK_AGG_FUNCTION 173
+#define TK_AGG_COLUMN 174
+#define TK_TRUEFALSE 175
+#define TK_UPLUS 176
+#define TK_UMINUS 177
#define TK_TRUTH 178
#define TK_REGISTER 179
#define TK_VECTOR 180
@@ -15216,8 +15446,9 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_ASTERISK 183
#define TK_SPAN 184
#define TK_ERROR 185
-#define TK_SPACE 186
-#define TK_ILLEGAL 187
+#define TK_QNUMBER 186
+#define TK_SPACE 187
+#define TK_ILLEGAL 188
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -15226,6 +15457,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#include
#include
#include
+#include
/*
** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY.
@@ -15246,7 +15478,8 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#ifdef SQLITE_OMIT_FLOATING_POINT
# define double sqlite_int64
# define float sqlite_int64
-# define LONGDOUBLE_TYPE sqlite_int64
+# define fabs(X) ((X)<0?-(X):(X))
+# define sqlite3IsOverflow(X) 0
# ifndef SQLITE_BIG_DBL
# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
# endif
@@ -15421,9 +15654,6 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
# define INT8_TYPE signed char
# endif
#endif
-#ifndef LONGDOUBLE_TYPE
-# define LONGDOUBLE_TYPE long double
-#endif
typedef sqlite_int64 i64; /* 8-byte signed integer */
typedef sqlite_uint64 u64; /* 8-byte unsigned integer */
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
@@ -15479,7 +15709,7 @@ typedef INT16_TYPE LogEst;
# define SQLITE_PTRSIZE __SIZEOF_POINTER__
# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(_M_ARM) || defined(__arm__) || defined(__x86) || \
- (defined(__APPLE__) && defined(__POWERPC__)) || \
+ (defined(__APPLE__) && defined(__ppc__)) || \
(defined(__TOS_AIX__) && !defined(__64BIT__))
# define SQLITE_PTRSIZE 4
# else
@@ -15716,6 +15946,7 @@ SQLITE_PRIVATE u32 sqlite3TreeTrace;
** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing
** 0x00020000 Transform DISTINCT into GROUP BY
** 0x00040000 SELECT tree dump after all code has been generated
+** 0x00080000 NOT NULL strength reduction
*/
/*
@@ -15746,7 +15977,7 @@ SQLITE_PRIVATE u32 sqlite3WhereTrace;
** 0x00000010 Display sqlite3_index_info xBestIndex calls
** 0x00000020 Range an equality scan metrics
** 0x00000040 IN operator decisions
-** 0x00000080 WhereLoop cost adjustements
+** 0x00000080 WhereLoop cost adjustments
** 0x00000100
** 0x00000200 Covering index decisions
** 0x00000400 OR optimization
@@ -15922,6 +16153,7 @@ typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SQLiteThread SQLiteThread;
typedef struct SelectDest SelectDest;
+typedef struct Subquery Subquery;
typedef struct SrcItem SrcItem;
typedef struct SrcList SrcList;
typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
@@ -16819,6 +17051,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursor(
);
SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void);
SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(Btree*,BtCursor*);
+#endif
SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
@@ -16910,6 +17145,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck(
sqlite3 *db, /* Database connection that is running the check */
Btree *p, /* The btree to be checked */
Pgno *aRoot, /* An array of root pages numbers for individual trees */
+ sqlite3_value *aCnt, /* OUT: entry counts for each btree in aRoot[] */
int nRoot, /* Number of entries in aRoot[] */
int mxErr, /* Stop reporting errors after this many */
int *pnErr, /* OUT: Write number of errors seen to this variable */
@@ -17036,6 +17272,19 @@ typedef struct Vdbe Vdbe;
*/
typedef struct sqlite3_value Mem;
typedef struct SubProgram SubProgram;
+typedef struct SubrtnSig SubrtnSig;
+
+/*
+** A signature for a reusable subroutine that materializes the RHS of
+** an IN operator.
+*/
+struct SubrtnSig {
+ int selId; /* SELECT-id for the SELECT statement on the RHS */
+ char *zAff; /* Affinity of the overall IN expression */
+ int iTable; /* Ephemeral table generated by the subroutine */
+ int iAddr; /* Subroutine entry address */
+ int regReturn; /* Register used to hold return address */
+};
/*
** A single instruction of the virtual machine has an opcode
@@ -17064,6 +17313,7 @@ struct VdbeOp {
u32 *ai; /* Used when p4type is P4_INTARRAY */
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
Table *pTab; /* Used when p4type is P4_TABLE */
+ SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */
#ifdef SQLITE_ENABLE_CURSOR_HINTS
Expr *pExpr; /* Used when p4type is P4_EXPR */
#endif
@@ -17131,6 +17381,7 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */
#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */
#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */
+#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */
/* Error message codes for OP_Halt */
#define P5_ConstraintNotNull 1
@@ -17180,12 +17431,12 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Vacuum 5
#define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */
#define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */
-#define OP_Init 8 /* jump, synopsis: Start at P2 */
+#define OP_Init 8 /* jump0, synopsis: Start at P2 */
#define OP_Goto 9 /* jump */
#define OP_Gosub 10 /* jump */
-#define OP_InitCoroutine 11 /* jump */
-#define OP_Yield 12 /* jump */
-#define OP_MustBeInt 13 /* jump */
+#define OP_InitCoroutine 11 /* jump0 */
+#define OP_Yield 12 /* jump0 */
+#define OP_MustBeInt 13 /* jump0 */
#define OP_Jump 14 /* jump */
#define OP_Once 15 /* jump */
#define OP_If 16 /* jump */
@@ -17193,22 +17444,22 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */
#define OP_IfNullRow 19 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
#define OP_Not 20 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
-#define OP_SeekLT 21 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekLE 22 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekGT 24 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekLT 21 /* jump0, synopsis: key=r[P3@P4] */
+#define OP_SeekLE 22 /* jump0, synopsis: key=r[P3@P4] */
+#define OP_SeekGE 23 /* jump0, synopsis: key=r[P3@P4] */
+#define OP_SeekGT 24 /* jump0, synopsis: key=r[P3@P4] */
#define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */
#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */
#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */
#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */
#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */
+#define OP_SeekRowid 30 /* jump0, synopsis: intkey=r[P3] */
#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */
-#define OP_Last 32 /* jump */
-#define OP_IfSmaller 33 /* jump */
+#define OP_Last 32 /* jump0 */
+#define OP_IfSizeBetween 33 /* jump */
#define OP_SorterSort 34 /* jump */
#define OP_Sort 35 /* jump */
-#define OP_Rewind 36 /* jump */
+#define OP_Rewind 36 /* jump0 */
#define OP_SorterNext 37 /* jump */
#define OP_Prev 38 /* jump */
#define OP_Next 39 /* jump */
@@ -17218,7 +17469,7 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IdxGE 43 /* jump, synopsis: key=r[P3@P4] */
#define OP_RowSetRead 44 /* jump, synopsis: r[P3]=rowset(P1) */
#define OP_RowSetTest 45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 46 /* jump */
+#define OP_Program 46 /* jump0 */
#define OP_Or 47 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
#define OP_And 48 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
#define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
@@ -17226,16 +17477,16 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IfNotZero 51 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
#define OP_DecrJumpZero 52 /* jump, synopsis: if (--r[P1])==0 goto P2 */
#define OP_IncrVacuum 53 /* jump */
-#define OP_IsNull 54 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull 55 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 56 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
-#define OP_Eq 57 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
-#define OP_Gt 58 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
-#define OP_Le 59 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
-#define OP_Lt 60 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */
-#define OP_ElseEq 62 /* jump, same as TK_ESCAPE */
-#define OP_VNext 63 /* jump */
+#define OP_VNext 54 /* jump */
+#define OP_IsNull 55 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 56 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 57 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+#define OP_Eq 58 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
+#define OP_Gt 59 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
+#define OP_Le 60 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
+#define OP_Lt 61 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */
+#define OP_ElseEq 63 /* jump, same as TK_ESCAPE */
#define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */
#define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */
#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
@@ -17250,7 +17501,7 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Null 75 /* synopsis: r[P2..P3]=NULL */
#define OP_SoftNull 76 /* synopsis: r[P1]=NULL */
#define OP_Blob 77 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Variable 78 /* synopsis: r[P2]=parameter(P1) */
#define OP_Move 79 /* synopsis: r[P2@P3]=r[P1@P3] */
#define OP_Copy 80 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
#define OP_SCopy 81 /* synopsis: r[P2]=r[P1] */
@@ -17278,23 +17529,23 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_OpenRead 103 /* synopsis: root=P2 iDb=P3 */
#define OP_OpenWrite 104 /* synopsis: root=P2 iDb=P3 */
#define OP_OpenDup 105
-#define OP_BitAnd 106 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 107 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 108 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
-#define OP_Add 110 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 111 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 112 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 113 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 114 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 115 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */
+#define OP_OpenAutoindex 106 /* synopsis: nColumn=P2 */
+#define OP_BitAnd 107 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 108 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 109 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
+#define OP_Add 111 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 112 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 113 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 114 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 115 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 116 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
#define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */
-#define OP_BitNot 118 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
-#define OP_SorterOpen 119
+#define OP_SorterOpen 118
+#define OP_BitNot 119 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
#define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
-#define OP_String8 121 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_OpenPseudo 122 /* synopsis: P3 columns in r[P2] */
+#define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */
+#define OP_String8 122 /* same as TK_STRING, synopsis: r[P2]='P4' */
#define OP_Close 123
#define OP_ColumnsUsed 124
#define OP_SeekScan 125 /* synopsis: Scan-ahead up to P1 rows */
@@ -17330,8 +17581,8 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_DropIndex 155
#define OP_DropTrigger 156
#define OP_IntegrityCk 157
-#define OP_Real 158 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_RowSetAdd 159 /* synopsis: rowset(P1)=r[P2] */
+#define OP_RowSetAdd 158 /* synopsis: rowset(P1)=r[P2] */
+#define OP_Real 159 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
#define OP_Param 160
#define OP_FkCounter 161 /* synopsis: fkctr[P1]+=P2 */
#define OP_MemMax 162 /* synopsis: r[P1]=max(r[P1],r[P2]) */
@@ -17378,27 +17629,28 @@ typedef struct VdbeOpList VdbeOpList;
#define OPFLG_OUT2 0x10 /* out2: P2 is an output */
#define OPFLG_OUT3 0x20 /* out3: P3 is an output */
#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */
+#define OPFLG_JUMP0 0x80 /* jump0: P2 might be zero */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\
-/* 8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\
-/* 16 */ 0x03, 0x03, 0x01, 0x01, 0x12, 0x49, 0x49, 0x49,\
-/* 24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\
-/* 32 */ 0x41, 0x01, 0x41, 0x41, 0x41, 0x01, 0x41, 0x41,\
-/* 40 */ 0x41, 0x41, 0x41, 0x41, 0x23, 0x0b, 0x01, 0x26,\
-/* 48 */ 0x26, 0x01, 0x03, 0x03, 0x03, 0x01, 0x03, 0x03,\
-/* 56 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x01, 0x41,\
+/* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\
+/* 16 */ 0x03, 0x03, 0x01, 0x01, 0x12, 0xc9, 0xc9, 0xc9,\
+/* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\
+/* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\
+/* 40 */ 0x41, 0x41, 0x41, 0x41, 0x23, 0x0b, 0x81, 0x26,\
+/* 48 */ 0x26, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41, 0x03,\
+/* 56 */ 0x03, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x01,\
/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\
/* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
/* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\
/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x40, 0x40,\
-/* 104 */ 0x00, 0x40, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
-/* 112 */ 0x26, 0x26, 0x26, 0x26, 0x40, 0x40, 0x12, 0x00,\
-/* 120 */ 0x00, 0x10, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10,\
+/* 104 */ 0x00, 0x40, 0x40, 0x26, 0x26, 0x26, 0x26, 0x26,\
+/* 112 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x40, 0x00, 0x12,\
+/* 120 */ 0x00, 0x00, 0x10, 0x40, 0x00, 0x40, 0x40, 0x10,\
/* 128 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 136 */ 0x40, 0x00, 0x50, 0x00, 0x40, 0x04, 0x04, 0x00,\
/* 144 */ 0x40, 0x50, 0x40, 0x10, 0x00, 0x00, 0x10, 0x00,\
-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x06,\
+/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10,\
/* 160 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 176 */ 0x40, 0x10, 0x50, 0x00, 0x40, 0x00, 0x10, 0x10,\
@@ -17546,6 +17798,8 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*);
+SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val);
+
SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*);
@@ -18152,6 +18406,10 @@ struct FuncDefHash {
};
#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
+#if defined(SQLITE_USER_AUTHENTICATION)
+# warning "The SQLITE_USER_AUTHENTICATION extension is deprecated. \
+ See ext/userauth/user-auth.txt for details."
+#endif
#ifdef SQLITE_USER_AUTHENTICATION
/*
** Information held in the "sqlite3" database connection object and used
@@ -18474,7 +18732,7 @@ struct sqlite3 {
#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */
#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */
/* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */
-#define SQLITE_PushDown 0x00001000 /* The push-down optimization */
+#define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */
#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */
#define SQLITE_SkipScan 0x00004000 /* Skip-scans */
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
@@ -18492,6 +18750,7 @@ struct sqlite3 {
#define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */
#define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */
#define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */
+#define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
/*
@@ -19047,8 +19306,7 @@ struct Table {
#define TF_HasStored 0x00000040 /* Has one or more STORED columns */
#define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */
#define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */
-#define TF_StatsUsed 0x00000100 /* Query planner decisions affected by
- ** Index.aiRowLogEst[] values */
+#define TF_MaybeReanalyze 0x00000100 /* Maybe run ANALYZE on this table */
#define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */
#define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */
#define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */
@@ -19108,6 +19366,15 @@ struct Table {
#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
+/* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is
+** available. By default, this macro is false
+*/
+#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
+# define ViewCanHaveRowid 0
+#else
+# define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0)
+#endif
+
/*
** Each foreign key constraint is an instance of the following structure.
**
@@ -19485,9 +19752,15 @@ struct AggInfo {
** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg.
** The assert()s that are part of this macro verify that constraint.
*/
+#ifndef NDEBUG
#define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I))
#define AggInfoFuncReg(A,I) \
(assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I))
+#else
+#define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I))
+#define AggInfoFuncReg(A,I) \
+ ((A)->iFirstReg+(A)->nColumn+(I))
+#endif
/*
** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
@@ -19668,7 +19941,7 @@ struct Expr {
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
#define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */
- /* 0x80000000 // Available */
+#define EP_SubtArg 0x80000000 /* Is argument to SQLITE_SUBTYPE function */
/* The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes.
@@ -19839,6 +20112,16 @@ struct IdList {
#define EU4_IDX 1 /* Uses IdList.a.u4.idx */
#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */
+/*
+** Details of the implementation of a subquery.
+*/
+struct Subquery {
+ Select *pSelect; /* A SELECT statement used in place of a table name */
+ int addrFillSub; /* Address of subroutine to initialize a subquery */
+ int regReturn; /* Register holding return address of addrFillSub */
+ int regResult; /* Registers holding results of a co-routine */
+};
+
/*
** The SrcItem object represents a single term in the FROM clause of a query.
** The SrcList object is mostly an array of SrcItems.
@@ -19851,27 +20134,40 @@ struct IdList {
** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used.
**
-** Union member validity:
+** Aggressive use of "union" helps keep the size of the object small. This
+** has been shown to boost performance, in addition to saving memory.
+** Access to union elements is gated by the following rules which should
+** always be checked, either by an if-statement or by an assert().
+**
+** Field Only access if this is true
+** --------------- -----------------------------------
+** u1.zIndexedBy fg.isIndexedBy
+** u1.pFuncArg fg.isTabFunc
+** u1.nRow !fg.isTabFunc && !fg.isIndexedBy
+**
+** u2.pIBIndex fg.isIndexedBy
+** u2.pCteUse fg.isCte
**
-** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc
-** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy
-** u2.pIBIndex fg.isIndexedBy && !fg.isCte
-** u2.pCteUse fg.isCte && !fg.isIndexedBy
+** u3.pOn !fg.isUsing
+** u3.pUsing fg.isUsing
+**
+** u4.zDatabase !fg.fixedSchema && !fg.isSubquery
+** u4.pSchema fg.fixedSchema
+** u4.pSubq fg.isSubquery
+**
+** See also the sqlite3SrcListDelete() routine for assert() statements that
+** check invariants on the fields of this object, especially the flags
+** inside the fg struct.
*/
struct SrcItem {
- Schema *pSchema; /* Schema to which this item is fixed */
- char *zDatabase; /* Name of database holding this table */
char *zName; /* Name of the table */
char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
- Table *pTab; /* An SQL table corresponding to zName */
- Select *pSelect; /* A SELECT statement used in place of a table name */
- int addrFillSub; /* Address of subroutine to manifest a subquery */
- int regReturn; /* Register holding return address of addrFillSub */
- int regResult; /* Registers holding results of a co-routine */
+ Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */
struct {
u8 jointype; /* Type of join between this table and the previous */
unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */
+ unsigned isSubquery :1; /* True if this term is a subquery */
unsigned isTabFunc :1; /* True if table-valued-function syntax */
unsigned isCorrelated :1; /* True if sub-query is correlated */
unsigned isMaterialized:1; /* This is a materialized view */
@@ -19884,21 +20180,30 @@ struct SrcItem {
unsigned isOn :1; /* u3.pOn was once valid and non-NULL */
unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */
unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */
+ unsigned rowidUsed :1; /* The ROWID of this table is referenced */
+ unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */
+ unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */
} fg;
int iCursor; /* The VDBE cursor number used to access this table */
- union {
- Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
- IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
- } u3;
Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */
union {
char *zIndexedBy; /* Identifier from "INDEXED BY " clause */
ExprList *pFuncArg; /* Arguments to table-valued-function */
+ u32 nRow; /* Number of rows in a VALUES clause */
} u1;
union {
Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */
} u2;
+ union {
+ Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
+ IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
+ } u3;
+ union {
+ Schema *pSchema; /* Schema to which this item is fixed */
+ char *zDatabase; /* Name of database holding this table */
+ Subquery *pSubq; /* Description of a subquery */
+ } u4;
};
/*
@@ -19958,7 +20263,7 @@ struct SrcList {
#define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
#define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */
- /* 0x2000 not currently used */
+#define WHERE_KEEP_ALL_JOINS 0x2000 /* Do not do the omit-noop-join opt */
#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
/* 0x8000 not currently used */
@@ -20030,13 +20335,14 @@ struct NameContext {
#define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */
#define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */
#define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */
-#define NC_Complex 0x002000 /* True if a function or subquery seen */
+/* 0x002000 // available for reuse */
#define NC_AllowWin 0x004000 /* Window functions are allowed here */
#define NC_HasWin 0x008000 /* One or more window functions seen */
#define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */
#define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */
#define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */
#define NC_NoSelect 0x080000 /* Do not descend into sub-selects */
+#define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */
#define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */
/*
@@ -20060,6 +20366,7 @@ struct Upsert {
Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */
Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */
u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */
+ u8 isDup; /* True if 2nd or later with same pUpsertIdx */
/* Above this point is the parse tree for the ON CONFLICT clauses.
** The next group of fields stores intermediate data. */
void *pToFree; /* Free memory when deleting the Upsert object */
@@ -20149,14 +20456,17 @@ struct Select {
#define SF_View 0x0200000 /* SELECT statement is a view */
#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */
#define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */
-#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */
+#define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */
#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */
#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */
#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */
#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */
+#define SF_Correlated 0x20000000 /* True if references the outer context */
-/* True if S exists and has SF_NestedFrom */
-#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
+/* True if SrcItem X is a subquery that has SF_NestedFrom */
+#define IsNestedFrom(X) \
+ ((X)->fg.isSubquery && \
+ ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0)
/*
** The results of a SELECT can be distributed in several ways, as defined
@@ -20186,7 +20496,11 @@ struct Select {
** SRT_Set The result must be a single column. Store each
** row of result as the key in table pDest->iSDParm.
** Apply the affinity pDest->affSdst before storing
-** results. Used to implement "IN (SELECT ...)".
+** results. if pDest->iSDParm2 is positive, then it is
+** a register holding a Bloom filter for the IN operator
+** that should be populated in addition to the
+** pDest->iSDParm table. This SRT is used to
+** implement "IN (SELECT ...)".
**
** SRT_EphemTab Create an temporary table pDest->iSDParm and store
** the result there. The cursor is left open after
@@ -20393,6 +20707,8 @@ struct Parse {
u8 disableLookaside; /* Number of times lookaside has been disabled */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */
+ u8 bHasWith; /* True if statement contains WITH */
+ u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
#endif
@@ -20688,7 +21004,7 @@ struct Returning {
};
/*
-** An objected used to accumulate the text of a string where we
+** An object used to accumulate the text of a string where we
** do not necessarily know how big the string will be in the end.
*/
struct sqlite3_str {
@@ -20702,7 +21018,7 @@ struct sqlite3_str {
};
#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */
#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */
-#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */
+#define SQLITE_PRINTF_MALLOCED 0x04 /* True if zText is allocated space */
#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
@@ -20780,7 +21096,6 @@ struct Sqlite3Config {
u8 bUseCis; /* Use covering indices for full-scans */
u8 bSmallMalloc; /* Avoid large memory allocations if true */
u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */
- u8 bUseLongDouble; /* Make use of long double */
#ifdef SQLITE_DEBUG
u8 bJsonSelfcheck; /* Double-check JSON parsing */
#endif
@@ -20830,6 +21145,11 @@ struct Sqlite3Config {
#endif
#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
+#endif
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW
+ ** feature is disabled. 0 if rowids can
+ ** occur in views. */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
@@ -21067,6 +21387,9 @@ struct Window {
** due to the SQLITE_SUBTYPE flag */
};
+SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow);
+SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal);
+
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*);
SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window*);
@@ -21147,15 +21470,6 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define SQLITE_ENABLE_FTS3 1
#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
-#endif
-
/*
** The following macros mimic the standard library functions toupper(),
** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
@@ -21286,10 +21600,13 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
# define EXP754 (((u64)0x7ff)<<52)
# define MAN754 ((((u64)1)<<52)-1)
# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
+# define IsOvfl(X) (((X)&EXP754)==EXP754)
SQLITE_PRIVATE int sqlite3IsNaN(double);
+SQLITE_PRIVATE int sqlite3IsOverflow(double);
#else
-# define IsNaN(X) 0
-# define sqlite3IsNaN(X) 0
+# define IsNaN(X) 0
+# define sqlite3IsNaN(X) 0
+# define sqlite3IsOVerflow(X) 0
#endif
/*
@@ -21381,6 +21698,7 @@ SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
SQLITE_PRIVATE void sqlite3Dequote(char*);
SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*);
SQLITE_PRIVATE void sqlite3DequoteToken(Token*);
+SQLITE_PRIVATE void sqlite3DequoteNumber(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*);
@@ -21411,7 +21729,7 @@ SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*)
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*);
-SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*);
+SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
@@ -21530,6 +21848,9 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
+SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*);
+SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*);
+SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, OnOrUsing*);
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
@@ -21579,6 +21900,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
+SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg);
SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int);
@@ -21634,16 +21956,14 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*);
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*);
SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
+SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
-SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
-SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int);
+SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
#endif
-SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*);
+SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
@@ -21774,7 +22094,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*);
SQLITE_PRIVATE int sqlite3Atoi(const char*);
#ifndef SQLITE_OMIT_UTF16
-SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
+SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar);
#endif
SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
@@ -21827,7 +22147,9 @@ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*);
SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int);
+#if !defined(SQLITE_OMIT_BLOB_LITERAL)
SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
+#endif
SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
@@ -22139,7 +22461,7 @@ SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8);
SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*);
SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
-SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
+SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*);
SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*);
SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*);
@@ -22529,6 +22851,9 @@ static const char * const sqlite3azCompileOpt[] = {
"ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN),
# endif
#endif
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ "ALLOW_ROWID_IN_VIEW",
+#endif
#ifdef SQLITE_ALLOW_URI_AUTHORITY
"ALLOW_URI_AUTHORITY",
#endif
@@ -22756,6 +23081,9 @@ static const char * const sqlite3azCompileOpt[] = {
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
"ENABLE_OFFSET_SQL_FUNC",
#endif
+#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES
+ "ENABLE_ORDERED_SET_AGGREGATES",
+#endif
#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
"ENABLE_OVERSIZE_CELL_CHECK",
#endif
@@ -23503,7 +23831,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
0, /* bSmallMalloc */
1, /* bExtraSchemaChecks */
- sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */
#ifdef SQLITE_DEBUG
0, /* bJsonSelfcheck */
#endif
@@ -23548,6 +23875,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
+#endif
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */
#endif
0, /* bLocaltimeFault */
0, /* xAltLocaltime */
@@ -24240,6 +24570,7 @@ struct PreUpdate {
Mem *aNew; /* Array of new.* values */
Table *pTab; /* Schema object being updated */
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
+ sqlite3_value **apDflt; /* Array of default values, if required */
};
/*
@@ -24904,13 +25235,14 @@ struct DateTime {
int tz; /* Timezone offset in minutes */
double s; /* Seconds */
char validJD; /* True (1) if iJD is valid */
- char rawS; /* Raw numeric value stored in s */
char validYMD; /* True (1) if Y,M,D are valid */
char validHMS; /* True (1) if h,m,s are valid */
- char validTZ; /* True (1) if tz is valid */
- char tzSet; /* Timezone was set explicitly */
- char isError; /* An overflow has occurred */
- char useSubsec; /* Display subsecond precision */
+ char nFloor; /* Days to implement "floor" */
+ unsigned rawS : 1; /* Raw numeric value stored in s */
+ unsigned isError : 1; /* An overflow has occurred */
+ unsigned useSubsec : 1; /* Display subsecond precision */
+ unsigned isUtc : 1; /* Time is known to be UTC */
+ unsigned isLocal : 1; /* Time is known to be localtime */
};
@@ -25008,6 +25340,8 @@ static int parseTimezone(const char *zDate, DateTime *p){
sgn = +1;
}else if( c=='Z' || c=='z' ){
zDate++;
+ p->isLocal = 0;
+ p->isUtc = 1;
goto zulu_time;
}else{
return c!=0;
@@ -25020,7 +25354,6 @@ static int parseTimezone(const char *zDate, DateTime *p){
p->tz = sgn*(nMn + nHr*60);
zulu_time:
while( sqlite3Isspace(*zDate) ){ zDate++; }
- p->tzSet = 1;
return *zDate!=0;
}
@@ -25064,7 +25397,6 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
p->m = m;
p->s = s + ms;
if( parseTimezone(zDate, p) ) return 1;
- p->validTZ = (p->tz!=0)?1:0;
return 0;
}
@@ -25103,23 +25435,48 @@ static void computeJD(DateTime *p){
Y--;
M += 12;
}
- A = Y/100;
- B = 2 - A + (A/4);
+ A = (Y+4800)/100;
+ B = 38 - A + (A/4);
X1 = 36525*(Y+4716)/100;
X2 = 306001*(M+1)/10000;
p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
p->validJD = 1;
if( p->validHMS ){
p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5);
- if( p->validTZ ){
+ if( p->tz ){
p->iJD -= p->tz*60000;
p->validYMD = 0;
p->validHMS = 0;
- p->validTZ = 0;
+ p->tz = 0;
+ p->isUtc = 1;
+ p->isLocal = 0;
}
}
}
+/*
+** Given the YYYY-MM-DD information current in p, determine if there
+** is day-of-month overflow and set nFloor to the number of days that
+** would need to be subtracted from the date in order to bring the
+** date back to the end of the month.
+*/
+static void computeFloor(DateTime *p){
+ assert( p->validYMD || p->isError );
+ assert( p->D>=0 && p->D<=31 );
+ assert( p->M>=0 && p->M<=12 );
+ if( p->D<=28 ){
+ p->nFloor = 0;
+ }else if( (1<M) & 0x15aa ){
+ p->nFloor = 0;
+ }else if( p->M!=2 ){
+ p->nFloor = (p->D==31);
+ }else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){
+ p->nFloor = p->D - 28;
+ }else{
+ p->nFloor = p->D - 29;
+ }
+}
+
/*
** Parse dates of the form
**
@@ -25158,12 +25515,16 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){
p->Y = neg ? -Y : Y;
p->M = M;
p->D = D;
- if( p->validTZ ){
+ computeFloor(p);
+ if( p->tz ){
computeJD(p);
}
return 0;
}
+
+static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */
+
/*
** Set the time to the current time reported by the VFS.
**
@@ -25173,6 +25534,9 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
p->iJD = sqlite3StmtCurrentTime(context);
if( p->iJD>0 ){
p->validJD = 1;
+ p->isUtc = 1;
+ p->isLocal = 0;
+ clearYMD_HMS_TZ(p);
return 0;
}else{
return 1;
@@ -25256,7 +25620,7 @@ static int validJulianDay(sqlite3_int64 iJD){
** Compute the Year, Month, and Day from the julian day number.
*/
static void computeYMD(DateTime *p){
- int Z, A, B, C, D, E, X1;
+ int Z, alpha, A, B, C, D, E, X1;
if( p->validYMD ) return;
if( !p->validJD ){
p->Y = 2000;
@@ -25267,8 +25631,8 @@ static void computeYMD(DateTime *p){
return;
}else{
Z = (int)((p->iJD + 43200000)/86400000);
- A = (int)((Z - 1867216.25)/36524.25);
- A = Z + 1 + A - (A/4);
+ alpha = (int)((Z + 32044.75)/36524.25) - 52;
+ A = Z + 1 + alpha - ((alpha+100)/4) + 25;
B = A + 1524;
C = (int)((B - 122.1)/365.25);
D = (36525*(C&32767))/100;
@@ -25311,7 +25675,7 @@ static void computeYMD_HMS(DateTime *p){
static void clearYMD_HMS_TZ(DateTime *p){
p->validYMD = 0;
p->validHMS = 0;
- p->validTZ = 0;
+ p->tz = 0;
}
#ifndef SQLITE_OMIT_LOCALTIME
@@ -25443,7 +25807,7 @@ static int toLocaltime(
p->validHMS = 1;
p->validJD = 0;
p->rawS = 0;
- p->validTZ = 0;
+ p->tz = 0;
p->isError = 0;
return SQLITE_OK;
}
@@ -25463,12 +25827,12 @@ static const struct {
float rLimit; /* Maximum NNN value for this transform */
float rXform; /* Constant used for this transform */
} aXformType[] = {
- { 6, "second", 4.6427e+14, 1.0 },
- { 6, "minute", 7.7379e+12, 60.0 },
- { 4, "hour", 1.2897e+11, 3600.0 },
- { 3, "day", 5373485.0, 86400.0 },
- { 5, "month", 176546.0, 2592000.0 },
- { 4, "year", 14713.0, 31536000.0 },
+ /* 0 */ { 6, "second", 4.6427e+14, 1.0 },
+ /* 1 */ { 6, "minute", 7.7379e+12, 60.0 },
+ /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 },
+ /* 3 */ { 3, "day", 5373485.0, 86400.0 },
+ /* 4 */ { 5, "month", 176546.0, 2592000.0 },
+ /* 5 */ { 4, "year", 14713.0, 31536000.0 },
};
/*
@@ -25500,14 +25864,20 @@ static void autoAdjustDate(DateTime *p){
** NNN.NNNN seconds
** NNN months
** NNN years
+** +/-YYYY-MM-DD HH:MM:SS.SSS
+** ceiling
+** floor
** start of month
** start of year
** start of week
** start of day
** weekday N
** unixepoch
+** auto
** localtime
** utc
+** subsec
+** subsecond
**
** Return 0 on success and 1 if there is any kind of error. If the error
** is in a system call (i.e. localtime()), then an error message is written
@@ -25538,6 +25908,37 @@ static int parseModifier(
}
break;
}
+ case 'c': {
+ /*
+ ** ceiling
+ **
+ ** Resolve day-of-month overflow by rolling forward into the next
+ ** month. As this is the default action, this modifier is really
+ ** a no-op that is only included for symmetry. See "floor".
+ */
+ if( sqlite3_stricmp(z, "ceiling")==0 ){
+ computeJD(p);
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ p->nFloor = 0;
+ }
+ break;
+ }
+ case 'f': {
+ /*
+ ** floor
+ **
+ ** Resolve day-of-month overflow by rolling back to the end of the
+ ** previous month.
+ */
+ if( sqlite3_stricmp(z, "floor")==0 ){
+ computeJD(p);
+ p->iJD -= p->nFloor*86400000;
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ }
+ break;
+ }
case 'j': {
/*
** julianday
@@ -25564,7 +25965,9 @@ static int parseModifier(
** show local time.
*/
if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){
- rc = toLocaltime(p, pCtx);
+ rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx);
+ p->isUtc = 0;
+ p->isLocal = 1;
}
break;
}
@@ -25589,7 +25992,7 @@ static int parseModifier(
}
#ifndef SQLITE_OMIT_LOCALTIME
else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){
- if( p->tzSet==0 ){
+ if( p->isUtc==0 ){
i64 iOrigJD; /* Original localtime */
i64 iGuess; /* Guess at the corresponding utc time */
int cnt = 0; /* Safety to prevent infinite loop */
@@ -25612,7 +26015,8 @@ static int parseModifier(
memset(p, 0, sizeof(*p));
p->iJD = iGuess;
p->validJD = 1;
- p->tzSet = 1;
+ p->isUtc = 1;
+ p->isLocal = 0;
}
rc = SQLITE_OK;
}
@@ -25632,7 +26036,7 @@ static int parseModifier(
&& r>=0.0 && r<7.0 && (n=(int)r)==r ){
sqlite3_int64 Z;
computeYMD_HMS(p);
- p->validTZ = 0;
+ p->tz = 0;
p->validJD = 0;
computeJD(p);
Z = ((p->iJD + 129600000)/86400000) % 7;
@@ -25672,7 +26076,7 @@ static int parseModifier(
p->h = p->m = 0;
p->s = 0.0;
p->rawS = 0;
- p->validTZ = 0;
+ p->tz = 0;
p->validJD = 0;
if( sqlite3_stricmp(z,"month")==0 ){
p->D = 1;
@@ -25743,6 +26147,7 @@ static int parseModifier(
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
p->Y += x;
p->M -= x*12;
+ computeFloor(p);
computeJD(p);
p->validHMS = 0;
p->validYMD = 0;
@@ -25789,11 +26194,12 @@ static int parseModifier(
z += n;
while( sqlite3Isspace(*z) ) z++;
n = sqlite3Strlen30(z);
- if( n>10 || n<3 ) break;
+ if( n<3 || n>10 ) break;
if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
computeJD(p);
assert( rc==1 );
rRounder = r<0 ? -0.5 : +0.5;
+ p->nFloor = 0;
for(i=0; iM += (int)r;
x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
p->Y += x;
p->M -= x*12;
+ computeFloor(p);
p->validJD = 0;
r -= (int)r;
break;
}
case 5: { /* Special processing to add years */
int y = (int)r;
- assert( strcmp(aXformType[i].zName,"year")==0 );
+ assert( strcmp(aXformType[5].zName,"year")==0 );
computeYMD_HMS(p);
+ assert( p->M>=0 && p->M<=12 );
p->Y += y;
+ computeFloor(p);
p->validJD = 0;
r -= (int)r;
break;
@@ -26069,22 +26478,83 @@ static void dateFunc(
}
}
+/*
+** Compute the number of days after the most recent January 1.
+**
+** In other words, compute the zero-based day number for the
+** current year:
+**
+** Jan01 = 0, Jan02 = 1, ..., Jan31 = 30, Feb01 = 31, ...
+** Dec31 = 364 or 365.
+*/
+static int daysAfterJan01(DateTime *pDate){
+ DateTime jan01 = *pDate;
+ assert( jan01.validYMD );
+ assert( jan01.validHMS );
+ assert( pDate->validJD );
+ jan01.validJD = 0;
+ jan01.M = 1;
+ jan01.D = 1;
+ computeJD(&jan01);
+ return (int)((pDate->iJD-jan01.iJD+43200000)/86400000);
+}
+
+/*
+** Return the number of days after the most recent Monday.
+**
+** In other words, return the day of the week according
+** to this code:
+**
+** 0=Monday, 1=Tuesday, 2=Wednesday, ..., 6=Sunday.
+*/
+static int daysAfterMonday(DateTime *pDate){
+ assert( pDate->validJD );
+ return (int)((pDate->iJD+43200000)/86400000) % 7;
+}
+
+/*
+** Return the number of days after the most recent Sunday.
+**
+** In other words, return the day of the week according
+** to this code:
+**
+** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday
+*/
+static int daysAfterSunday(DateTime *pDate){
+ assert( pDate->validJD );
+ return (int)((pDate->iJD+129600000)/86400000) % 7;
+}
+
/*
** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
**
** Return a string described by FORMAT. Conversions as follows:
**
-** %d day of month
+** %d day of month 01-31
+** %e day of month 1-31
** %f ** fractional seconds SS.SSS
+** %F ISO date. YYYY-MM-DD
+** %G ISO year corresponding to %V 0000-9999.
+** %g 2-digit ISO year corresponding to %V 00-99
** %H hour 00-24
-** %j day of year 000-366
+** %k hour 0-24 (leading zero converted to space)
+** %I hour 01-12
+** %j day of year 001-366
** %J ** julian day number
+** %l hour 1-12 (leading zero converted to space)
** %m month 01-12
** %M minute 00-59
+** %p "am" or "pm"
+** %P "AM" or "PM"
+** %R time as HH:MM
** %s seconds since 1970-01-01
** %S seconds 00-59
-** %w day of week 0-6 Sunday==0
-** %W week of year 00-53
+** %T time as HH:MM:SS
+** %u day of week 1-7 Monday==1, Sunday==7
+** %w day of week 0-6 Sunday==0, Monday==1
+** %U week of year 00-53 (First Sunday is start of week 01)
+** %V week of year 01-53 (First week containing Thursday is week 01)
+** %W week of year 00-53 (First Monday is start of week 01)
** %Y year 0000-9999
** %% %
*/
@@ -26121,7 +26591,7 @@ static void strftimeFunc(
sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D);
break;
}
- case 'f': {
+ case 'f': { /* Fractional seconds. (Non-standard) */
double s = x.s;
if( s>59.999 ) s = 59.999;
sqlite3_str_appendf(&sRes, "%06.3f", s);
@@ -26131,6 +26601,21 @@ static void strftimeFunc(
sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D);
break;
}
+ case 'G': /* Fall thru */
+ case 'g': {
+ DateTime y = x;
+ assert( y.validJD );
+ /* Move y so that it is the Thursday in the same week as x */
+ y.iJD += (3 - daysAfterMonday(&x))*86400000;
+ y.validYMD = 0;
+ computeYMD(&y);
+ if( cf=='g' ){
+ sqlite3_str_appendf(&sRes, "%02d", y.Y%100);
+ }else{
+ sqlite3_str_appendf(&sRes, "%04d", y.Y);
+ }
+ break;
+ }
case 'H':
case 'k': {
sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h);
@@ -26144,25 +26629,11 @@ static void strftimeFunc(
sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h);
break;
}
- case 'W': /* Fall thru */
- case 'j': {
- int nDay; /* Number of days since 1st day of year */
- DateTime y = x;
- y.validJD = 0;
- y.M = 1;
- y.D = 1;
- computeJD(&y);
- nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
- if( cf=='W' ){
- int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
- wd = (int)(((x.iJD+43200000)/86400000)%7);
- sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7);
- }else{
- sqlite3_str_appendf(&sRes,"%03d",nDay+1);
- }
+ case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */
+ sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1);
break;
}
- case 'J': {
+ case 'J': { /* Julian day number. (Non-standard) */
sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0);
break;
}
@@ -26205,13 +26676,33 @@ static void strftimeFunc(
sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s);
break;
}
- case 'u': /* Fall thru */
- case 'w': {
- char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
+ case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */
+ case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */
+ char c = (char)daysAfterSunday(&x) + '0';
if( c=='0' && cf=='u' ) c = '7';
sqlite3_str_appendchar(&sRes, 1, c);
break;
}
+ case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */
+ sqlite3_str_appendf(&sRes,"%02d",
+ (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7);
+ break;
+ }
+ case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */
+ DateTime y = x;
+ /* Adjust y so that is the Thursday in the same week as x */
+ assert( y.validJD );
+ y.iJD += (3 - daysAfterMonday(&x))*86400000;
+ y.validYMD = 0;
+ computeYMD(&y);
+ sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1);
+ break;
+ }
+ case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */
+ sqlite3_str_appendf(&sRes,"%02d",
+ (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7);
+ break;
+ }
case 'Y': {
sqlite3_str_appendf(&sRes,"%04d",x.Y);
break;
@@ -26358,9 +26849,7 @@ static void timediffFunc(
d1.iJD = d2.iJD - d1.iJD;
d1.iJD += (u64)1486995408 * (u64)100000;
}
- d1.validYMD = 0;
- d1.validHMS = 0;
- d1.validTZ = 0;
+ clearYMD_HMS_TZ(&d1);
computeYMD_HMS(&d1);
sqlite3StrAccumInit(&sRes, 0, 0, 0, 100);
sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f",
@@ -26429,6 +26918,36 @@ static void currentTimeFunc(
}
#endif
+#if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG)
+/*
+** datedebug(...)
+**
+** This routine returns JSON that describes the internal DateTime object.
+** Used for debugging and testing only. Subject to change.
+*/
+static void datedebugFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ DateTime x;
+ if( isDate(context, argc, argv, &x)==0 ){
+ char *zJson;
+ zJson = sqlite3_mprintf(
+ "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d,"
+ "s:%.3f,validJD:%d,validYMS:%d,validHMS:%d,"
+ "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d,"
+ "isUtc:%d,isLocal:%d}",
+ x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz,
+ x.s, x.validJD, x.validYMD, x.validHMS,
+ x.nFloor, x.rawS, x.isError, x.useSubsec,
+ x.isUtc, x.isLocal);
+ sqlite3_result_text(context, zJson, -1, sqlite3_free);
+ }
+}
+#endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */
+
+
/*
** This function registered all of the above C functions as SQL
** functions. This should be the only routine in this file with
@@ -26444,6 +26963,9 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
PURE_DATE(timediff, 2, 0, 0, timediffFunc ),
+#ifdef SQLITE_DEBUG
+ PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ),
+#endif
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
DFUNCTION(current_date, 0, 0, 0, cdateFunc ),
@@ -29512,16 +30034,29 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
+**
+** Because these routines raise false-positive alerts in TSAN, disable
+** them (make them always return 1) when compiling with TSAN.
*/
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
+# if defined(__has_feature)
+# if __has_feature(thread_sanitizer)
+ p = 0;
+# endif
+# endif
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
+# if defined(__has_feature)
+# if __has_feature(thread_sanitizer)
+ p = 0;
+# endif
+# endif
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
-#endif
+#endif /* NDEBUG */
#endif /* !defined(SQLITE_MUTEX_OMIT) */
@@ -30859,6 +31394,24 @@ static void sqlite3MallocAlarm(int nByte){
sqlite3_mutex_enter(mem0.mutex);
}
+#ifdef SQLITE_DEBUG
+/*
+** This routine is called whenever an out-of-memory condition is seen,
+** It's only purpose to to serve as a breakpoint for gdb or similar
+** code debuggers when working on out-of-memory conditions, for example
+** caused by PRAGMA hard_heap_limit=N.
+*/
+static SQLITE_NOINLINE void test_oom_breakpoint(u64 n){
+ static u64 nOomFault = 0;
+ nOomFault += n;
+ /* The assert() is never reached in a human lifetime. It is here mostly
+ ** to prevent code optimizers from optimizing out this function. */
+ assert( (nOomFault>>32) < 0xffffffff );
+}
+#else
+# define test_oom_breakpoint(X) /* No-op for production builds */
+#endif
+
/*
** Do a memory allocation with statistics and alarms. Assume the
** lock is already held.
@@ -30885,6 +31438,7 @@ static void mallocWithAlarm(int n, void **pp){
if( mem0.hardLimit ){
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.hardLimit - nFull ){
+ test_oom_breakpoint(1);
*pp = 0;
return;
}
@@ -31173,6 +31727,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
sqlite3MallocAlarm(nDiff);
if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){
sqlite3_mutex_leave(mem0.mutex);
+ test_oom_breakpoint(1);
return 0;
}
}
@@ -32039,6 +32594,7 @@ SQLITE_API void sqlite3_str_vappendf(
if( xtype==etFLOAT ){
iRound = -precision;
}else if( xtype==etGENERIC ){
+ if( precision==0 ) precision = 1;
iRound = precision;
}else{
iRound = precision+1;
@@ -32074,13 +32630,14 @@ SQLITE_API void sqlite3_str_vappendf(
}
exp = s.iDP-1;
- if( xtype==etGENERIC && precision>0 ) precision--;
/*
** If the field type is etGENERIC, then convert to either etEXP
** or etFLOAT, as appropriate.
*/
if( xtype==etGENERIC ){
+ assert( precision>0 );
+ precision--;
flag_rtz = !flag_alternateform;
if( exp<-4 || exp>precision ){
xtype = etEXP;
@@ -32387,18 +32944,25 @@ SQLITE_API void sqlite3_str_vappendf(
if( pItem->zAlias && !flag_altform2 ){
sqlite3_str_appendall(pAccum, pItem->zAlias);
}else if( pItem->zName ){
- if( pItem->zDatabase ){
- sqlite3_str_appendall(pAccum, pItem->zDatabase);
+ if( pItem->fg.fixedSchema==0
+ && pItem->fg.isSubquery==0
+ && pItem->u4.zDatabase!=0
+ ){
+ sqlite3_str_appendall(pAccum, pItem->u4.zDatabase);
sqlite3_str_append(pAccum, ".", 1);
}
sqlite3_str_appendall(pAccum, pItem->zName);
}else if( pItem->zAlias ){
sqlite3_str_appendall(pAccum, pItem->zAlias);
- }else{
- Select *pSel = pItem->pSelect;
+ }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */
+ Select *pSel = pItem->u4.pSubq->pSelect;
assert( pSel!=0 );
if( pSel->selFlags & SF_NestedFrom ){
sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId);
+ }else if( pSel->selFlags & SF_MultiValue ){
+ assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy );
+ sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE",
+ pItem->u1.nRow);
}else{
sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId);
}
@@ -32470,6 +33034,7 @@ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExp
pExpr = pExpr->pLeft;
}
if( pExpr==0 ) return;
+ if( ExprHasProperty(pExpr, EP_FromDDL) ) return;
db->errByteOffset = pExpr->w.iOfst;
}
@@ -33174,9 +33739,11 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
x.printfFlags |= SQLITE_PRINTF_INTERNAL;
sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
- if( pItem->pTab ){
- sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
- pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
+ if( pItem->pSTab ){
+ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s",
+ pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab,
+ pItem->colUsed,
+ pItem->fg.rowidUsed ? "+rowid" : "");
}
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
@@ -33205,23 +33772,30 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine");
if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte");
if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom");
+ if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema");
+ if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema");
+ if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery");
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, inSrc-1);
n = 0;
- if( pItem->pSelect ) n++;
+ if( pItem->fg.isSubquery ) n++;
if( pItem->fg.isTabFunc ) n++;
if( pItem->fg.isUsing ) n++;
if( pItem->fg.isUsing ){
sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
}
- if( pItem->pSelect ){
- if( pItem->pTab ){
- Table *pTab = pItem->pTab;
+ if( pItem->fg.isSubquery ){
+ assert( n==1 );
+ if( pItem->pSTab ){
+ Table *pTab = pItem->pSTab;
sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
}
- assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
- sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0);
+ assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
+ sqlite3TreeViewPush(&pView, 0);
+ sqlite3TreeViewLine(pView, "SUBQUERY");
+ sqlite3TreeViewPop(&pView);
+ sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0);
}
if( pItem->fg.isTabFunc ){
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
@@ -33263,7 +33837,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
n = 1000;
}else{
n = 0;
- if( p->pSrc && p->pSrc->nSrc ) n++;
+ if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++;
if( p->pWhere ) n++;
if( p->pGroupBy ) n++;
if( p->pHaving ) n++;
@@ -33289,7 +33863,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
sqlite3TreeViewPop(&pView);
}
#endif
- if( p->pSrc && p->pSrc->nSrc ){
+ if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){
sqlite3TreeViewPush(&pView, (n--)>0);
sqlite3TreeViewLine(pView, "FROM");
sqlite3TreeViewSrcList(pView, p->pSrc);
@@ -33325,7 +33899,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
if( p->pLimit->pRight ){
- sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+ sqlite3TreeViewItem(pView, "OFFSET", 0);
sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
sqlite3TreeViewPop(&pView);
}
@@ -33797,7 +34371,8 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
case OE_Ignore: zType = "ignore"; break;
}
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
+ sqlite3TreeViewLine(pView, "RAISE %s", zType);
+ sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
break;
}
#endif
@@ -33877,9 +34452,10 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; inExpr; i++){
int j = pList->a[i].u.x.iOrderByCol;
+ u8 sortFlags = pList->a[i].fg.sortFlags;
char *zName = pList->a[i].zEName;
int moreToFollow = inExpr - 1;
- if( j || zName ){
+ if( j || zName || sortFlags ){
sqlite3TreeViewPush(&pView, moreToFollow);
moreToFollow = 0;
sqlite3TreeViewLine(pView, 0);
@@ -33900,13 +34476,18 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
}
}
if( j ){
- fprintf(stdout, "iOrderByCol=%d", j);
+ fprintf(stdout, "iOrderByCol=%d ", j);
+ }
+ if( sortFlags & KEYINFO_ORDER_DESC ){
+ fprintf(stdout, "DESC ");
+ }else if( sortFlags & KEYINFO_ORDER_BIGNULL ){
+ fprintf(stdout, "NULLS-LAST");
}
fprintf(stdout, "\n");
fflush(stdout);
}
sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
- if( j || zName ){
+ if( j || zName || sortFlags ){
sqlite3TreeViewPop(&pView);
}
}
@@ -34869,7 +35450,7 @@ static const unsigned char sqlite3Utf8Trans1[] = {
c = *(zIn++); \
if( c>=0xc0 ){ \
c = sqlite3Utf8Trans1[c-0xc0]; \
- while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
+ while( zIn=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
+ if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
n++;
}
return (int)(z-(unsigned char const *)zIn)
@@ -35370,6 +35953,19 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
+#ifndef SQLITE_OMIT_FLOATING_POINT
+/*
+** Return true if the floating point value is NaN or +Inf or -Inf.
+*/
+SQLITE_PRIVATE int sqlite3IsOverflow(double x){
+ int rc; /* The value return */
+ u64 y;
+ memcpy(&y,&x,sizeof(y));
+ rc = IsOvfl(y);
+ return rc;
+}
+#endif /* SQLITE_OMIT_FLOATING_POINT */
+
/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
@@ -35613,6 +36209,44 @@ SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
sqlite3Dequote(p->u.zToken);
}
+/*
+** Expression p is a QNUMBER (quoted number). Dequote the value in p->u.zToken
+** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those
+** that contain '_' characters that must be removed before further processing.
+*/
+SQLITE_PRIVATE void sqlite3DequoteNumber(Parse *pParse, Expr *p){
+ assert( p!=0 || pParse->db->mallocFailed );
+ if( p ){
+ const char *pIn = p->u.zToken;
+ char *pOut = p->u.zToken;
+ int bHex = (pIn[0]=='0' && (pIn[1]=='x' || pIn[1]=='X'));
+ int iValue;
+ assert( p->op==TK_QNUMBER );
+ p->op = TK_INTEGER;
+ do {
+ if( *pIn!=SQLITE_DIGIT_SEPARATOR ){
+ *pOut++ = *pIn;
+ if( *pIn=='e' || *pIn=='E' || *pIn=='.' ) p->op = TK_FLOAT;
+ }else{
+ if( (bHex==0 && (!sqlite3Isdigit(pIn[-1]) || !sqlite3Isdigit(pIn[1])))
+ || (bHex==1 && (!sqlite3Isxdigit(pIn[-1]) || !sqlite3Isxdigit(pIn[1])))
+ ){
+ sqlite3ErrorMsg(pParse, "unrecognized token: \"%s\"", p->u.zToken);
+ }
+ }
+ }while( *pIn++ );
+ if( bHex ) p->op = TK_INTEGER;
+
+ /* tag-20240227-a: If after dequoting, the number is an integer that
+ ** fits in 32 bits, then it must be converted into EP_IntValue. Other
+ ** parts of the code expect this. See also tag-20240227-b. */
+ if( p->op==TK_INTEGER && sqlite3GetInt32(p->u.zToken, &iValue) ){
+ p->u.iValue = iValue;
+ p->flags |= EP_IntValue;
+ }
+ }
+}
+
/*
** If the input token p is quoted, try to adjust the token to remove
** the quotes. This is not always possible:
@@ -35790,6 +36424,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
int eValid = 1; /* True exponent is either not used or is well-formed */
int nDigit = 0; /* Number of digits processed */
int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
+ u64 s2; /* round-tripped significand */
+ double rr[2];
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
@@ -35892,7 +36528,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
e = (e*esign) + d;
/* Try to adjust the exponent to make it smaller */
- while( e>0 && s<(LARGEST_UINT64/10) ){
+ while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){
s *= 10;
e--;
}
@@ -35901,65 +36537,46 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
e++;
}
- if( e==0 ){
- *pResult = s;
- }else if( sqlite3Config.bUseLongDouble ){
- LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s;
- if( e>0 ){
- while( e>=100 ){ e-=100; r *= 1.0e+100L; }
- while( e>=10 ){ e-=10; r *= 1.0e+10L; }
- while( e>=1 ){ e-=1; r *= 1.0e+01L; }
- }else{
- while( e<=-100 ){ e+=100; r *= 1.0e-100L; }
- while( e<=-10 ){ e+=10; r *= 1.0e-10L; }
- while( e<=-1 ){ e+=1; r *= 1.0e-01L; }
- }
- assert( r>=0.0 );
- if( r>+1.7976931348623157081452742373e+308L ){
-#ifdef INFINITY
- *pResult = +INFINITY;
-#else
- *pResult = 1.0e308*10.0;
-#endif
- }else{
- *pResult = (double)r;
- }
- }else{
- double rr[2];
- u64 s2;
- rr[0] = (double)s;
+ rr[0] = (double)s;
+ assert( sizeof(s2)==sizeof(rr[0]) );
+ memcpy(&s2, &rr[0], sizeof(s2));
+ if( s2<=0x43efffffffffffffLL ){
s2 = (u64)rr[0];
rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
- if( e>0 ){
- while( e>=100 ){
- e -= 100;
- dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
- }
- while( e>=10 ){
- e -= 10;
- dekkerMul2(rr, 1.0e+10, 0.0);
- }
- while( e>=1 ){
- e -= 1;
- dekkerMul2(rr, 1.0e+01, 0.0);
- }
- }else{
- while( e<=-100 ){
- e += 100;
- dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117);
- }
- while( e<=-10 ){
- e += 10;
- dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
- }
- while( e<=-1 ){
- e += 1;
- dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
- }
+ }else{
+ rr[1] = 0.0;
+ }
+ assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */
+
+ if( e>0 ){
+ while( e>=100 ){
+ e -= 100;
+ dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
+ }
+ while( e>=10 ){
+ e -= 10;
+ dekkerMul2(rr, 1.0e+10, 0.0);
+ }
+ while( e>=1 ){
+ e -= 1;
+ dekkerMul2(rr, 1.0e+01, 0.0);
+ }
+ }else{
+ while( e<=-100 ){
+ e += 100;
+ dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117);
+ }
+ while( e<=-10 ){
+ e += 10;
+ dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
+ }
+ while( e<=-1 ){
+ e += 1;
+ dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
}
- *pResult = rr[0]+rr[1];
- if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300;
}
+ *pResult = rr[0]+rr[1];
+ if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300;
if( sign<0 ) *pResult = -*pResult;
assert( !sqlite3IsNaN(*pResult) );
@@ -36263,10 +36880,13 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){
** Decode a floating-point value into an approximate decimal
** representation.
**
-** Round the decimal representation to n significant digits if
-** n is positive. Or round to -n signficant digits after the
-** decimal point if n is negative. No rounding is performed if
-** n is zero.
+** If iRound<=0 then round to -iRound significant digits to the
+** the left of the decimal point, or to a maximum of mxRound total
+** significant digits.
+**
+** If iRound>0 round to min(iRound,mxRound) significant digits total.
+**
+** mxRound must be positive.
**
** The significant digits of the decimal representation are
** stored in p->z[] which is a often (but not always) a pointer
@@ -36277,8 +36897,11 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou
int i;
u64 v;
int e, exp = 0;
+ double rr[2];
+
p->isSpecial = 0;
p->z = p->zBuf;
+ assert( mxRound>0 );
/* Convert negative numbers to positive. Deal with Infinity, 0.0, and
** NaN. */
@@ -36305,62 +36928,45 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou
/* Multiply r by powers of ten until it lands somewhere in between
** 1.0e+19 and 1.0e+17.
+ **
+ ** Use Dekker-style double-double computation to increase the
+ ** precision.
+ **
+ ** The error terms on constants like 1.0e+100 computed using the
+ ** decimal extension, for example as follows:
+ **
+ ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100)));
*/
- if( sqlite3Config.bUseLongDouble ){
- LONGDOUBLE_TYPE rr = r;
- if( rr>=1.0e+19 ){
- while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; }
- while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; }
- while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; }
- }else{
- while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; }
- while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; }
- while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; }
+ rr[0] = r;
+ rr[1] = 0.0;
+ if( rr[0]>9.223372036854774784e+18 ){
+ while( rr[0]>9.223372036854774784e+118 ){
+ exp += 100;
+ dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117);
+ }
+ while( rr[0]>9.223372036854774784e+28 ){
+ exp += 10;
+ dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
+ }
+ while( rr[0]>9.223372036854774784e+18 ){
+ exp += 1;
+ dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
}
- v = (u64)rr;
}else{
- /* If high-precision floating point is not available using "long double",
- ** then use Dekker-style double-double computation to increase the
- ** precision.
- **
- ** The error terms on constants like 1.0e+100 computed using the
- ** decimal extension, for example as follows:
- **
- ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100)));
- */
- double rr[2];
- rr[0] = r;
- rr[1] = 0.0;
- if( rr[0]>9.223372036854774784e+18 ){
- while( rr[0]>9.223372036854774784e+118 ){
- exp += 100;
- dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117);
- }
- while( rr[0]>9.223372036854774784e+28 ){
- exp += 10;
- dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27);
- }
- while( rr[0]>9.223372036854774784e+18 ){
- exp += 1;
- dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18);
- }
- }else{
- while( rr[0]<9.223372036854774784e-83 ){
- exp -= 100;
- dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
- }
- while( rr[0]<9.223372036854774784e+07 ){
- exp -= 10;
- dekkerMul2(rr, 1.0e+10, 0.0);
- }
- while( rr[0]<9.22337203685477478e+17 ){
- exp -= 1;
- dekkerMul2(rr, 1.0e+01, 0.0);
- }
+ while( rr[0]<9.223372036854774784e-83 ){
+ exp -= 100;
+ dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83);
+ }
+ while( rr[0]<9.223372036854774784e+07 ){
+ exp -= 10;
+ dekkerMul2(rr, 1.0e+10, 0.0);
+ }
+ while( rr[0]<9.22337203685477478e+17 ){
+ exp -= 1;
+ dekkerMul2(rr, 1.0e+01, 0.0);
}
- v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1];
}
-
+ v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1];
/* Extract significant digits. */
i = sizeof(p->zBuf)-1;
@@ -36371,7 +36977,7 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou
assert( p->n>0 );
assert( p->nzBuf) );
p->iDP = p->n + exp;
- if( iRound<0 ){
+ if( iRound<=0 ){
iRound = p->iDP - iRound;
if( iRound==0 && p->zBuf[i+1]>='5' ){
iRound = 1;
@@ -37131,104 +37737,6 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam
return 0;
}
-/*
-** High-resolution hardware timer used for debugging and testing only.
-*/
-#if defined(VDBE_PROFILE) \
- || defined(SQLITE_PERFORMANCE_TRACE) \
- || defined(SQLITE_ENABLE_STMT_SCANSTATUS)
-/************** Include hwtime.h in the middle of util.c *********************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 and x86_64 class CPUs.
-*/
-#ifndef SQLITE_HWTIME_H
-#define SQLITE_HWTIME_H
-
-/*
-** The following routine only works on Pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if !defined(__STRICT_ANSI__) && \
- (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
-#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- /*
- ** asm() is needed for hardware timing support. Without asm(),
- ** disable the sqlite3Hwtime() routine.
- **
- ** sqlite3Hwtime() is only used for some obscure debugging
- ** and analysis configurations, not in any deliverable, so this
- ** should not be a great loss.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(SQLITE_HWTIME_H) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in util.c ***********************/
-#endif
-
/************** End of util.c ************************************************/
/************** Begin file hash.c ********************************************/
/*
@@ -37549,7 +38057,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"),
/* 31 */ "NotExists" OpHelp("intkey=r[P3]"),
/* 32 */ "Last" OpHelp(""),
- /* 33 */ "IfSmaller" OpHelp(""),
+ /* 33 */ "IfSizeBetween" OpHelp(""),
/* 34 */ "SorterSort" OpHelp(""),
/* 35 */ "Sort" OpHelp(""),
/* 36 */ "Rewind" OpHelp(""),
@@ -37570,16 +38078,16 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 51 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
/* 52 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
/* 53 */ "IncrVacuum" OpHelp(""),
- /* 54 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
- /* 55 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 56 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
- /* 57 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
- /* 58 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
- /* 59 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
- /* 60 */ "Lt" OpHelp("IF r[P3]=r[P1]"),
- /* 62 */ "ElseEq" OpHelp(""),
- /* 63 */ "VNext" OpHelp(""),
+ /* 54 */ "VNext" OpHelp(""),
+ /* 55 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 56 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 57 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
+ /* 58 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
+ /* 59 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
+ /* 60 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
+ /* 61 */ "Lt" OpHelp("IF r[P3]=r[P1]"),
+ /* 63 */ "ElseEq" OpHelp(""),
/* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"),
/* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
/* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
@@ -37594,7 +38102,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 75 */ "Null" OpHelp("r[P2..P3]=NULL"),
/* 76 */ "SoftNull" OpHelp("r[P1]=NULL"),
/* 77 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 78 */ "Variable" OpHelp("r[P2]=parameter(P1)"),
/* 79 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
/* 80 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
/* 81 */ "SCopy" OpHelp("r[P2]=r[P1]"),
@@ -37622,23 +38130,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 103 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
/* 104 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
/* 105 */ "OpenDup" OpHelp(""),
- /* 106 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 107 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 108 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
- /* 110 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 111 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 112 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 113 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 114 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 115 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 106 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 107 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 108 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 109 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
+ /* 111 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 112 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 113 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 114 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 115 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 116 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
/* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"),
- /* 118 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
- /* 119 */ "SorterOpen" OpHelp(""),
+ /* 118 */ "SorterOpen" OpHelp(""),
+ /* 119 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
/* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
- /* 121 */ "String8" OpHelp("r[P2]='P4'"),
- /* 122 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 122 */ "String8" OpHelp("r[P2]='P4'"),
/* 123 */ "Close" OpHelp(""),
/* 124 */ "ColumnsUsed" OpHelp(""),
/* 125 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
@@ -37674,8 +38182,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 155 */ "DropIndex" OpHelp(""),
/* 156 */ "DropTrigger" OpHelp(""),
/* 157 */ "IntegrityCk" OpHelp(""),
- /* 158 */ "Real" OpHelp("r[P2]=P4"),
- /* 159 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 158 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 159 */ "Real" OpHelp("r[P2]=P4"),
/* 160 */ "Param" OpHelp(""),
/* 161 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
/* 162 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
@@ -39023,7 +39531,7 @@ static pid_t randomnessPid = 0;
#define UNIXFILE_EXCL 0x01 /* Connections from one process only */
#define UNIXFILE_RDONLY 0x02 /* Connection is read only */
#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
-#ifndef SQLITE_DISABLE_DIRSYNC
+#if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX)
# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */
#else
# define UNIXFILE_DIRSYNC 0x00
@@ -39996,8 +40504,12 @@ static int unixLogErrorAtLine(
** available, the error message will often be an empty string. Not a
** huge problem. Incorrectly concluding that the GNU version is available
** could lead to a segfault though.
+ **
+ ** Forum post 3f13857fa4062301 reports that the Android SDK may use
+ ** int-type return, depending on its version.
*/
-#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
+#if (defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)) \
+ && !defined(ANDROID) && !defined(__ANDROID__)
zErr =
# endif
strerror_r(iErrno, aErr, sizeof(aErr)-1);
@@ -40976,26 +41488,22 @@ static int nolockClose(sqlite3_file *id) {
/*
** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-**
-** In dotfile locking, either a lock exists or it does not. So in this
-** variation of CheckReservedLock(), *pResOut is set to true if any lock
-** is held on the file and false if the file is unlocked.
+** file by this or any other process. If the caller holds a SHARED
+** or greater lock when it is called, then it is assumed that no other
+** client may hold RESERVED. Or, if the caller holds no lock, then it
+** is assumed another client holds RESERVED if the lock-file exists.
*/
static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
- int rc = SQLITE_OK;
- int reserved = 0;
unixFile *pFile = (unixFile*)id;
-
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
- assert( pFile );
- reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
- OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
- *pResOut = reserved;
- return rc;
+ if( pFile->eFileLock>=SHARED_LOCK ){
+ *pResOut = 0;
+ }else{
+ *pResOut = osAccess((const char*)pFile->lockingContext, 0)==0;
+ }
+ OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut));
+ return SQLITE_OK;
}
/*
@@ -41165,54 +41673,33 @@ static int robust_flock(int fd, int op){
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
*/
static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
+#ifdef SQLITE_DEBUG
unixFile *pFile = (unixFile*)id;
+#else
+ UNUSED_PARAMETER(id);
+#endif
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( pFile );
+ assert( pFile->eFileLock<=SHARED_LOCK );
- /* Check if a thread in this process holds such a lock */
- if( pFile->eFileLock>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it. */
- if( !reserved ){
- /* attempt to get the lock */
- int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB);
- if( !lrc ){
- /* got the lock, unlock it */
- lrc = robust_flock(pFile->h, LOCK_UN);
- if ( lrc ) {
- int tErrno = errno;
- /* unlock failed with an error */
- lrc = SQLITE_IOERR_UNLOCK;
- storeLastErrno(pFile, tErrno);
- rc = lrc;
- }
- } else {
- int tErrno = errno;
- reserved = 1;
- /* someone else might have it reserved */
- lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(lrc) ){
- storeLastErrno(pFile, tErrno);
- rc = lrc;
- }
- }
- }
- OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
+ /* The flock VFS only ever takes exclusive locks (see function flockLock).
+ ** Therefore, if this connection is holding any lock at all, no other
+ ** connection may be holding a RESERVED lock. So set *pResOut to 0
+ ** in this case.
+ **
+ ** Or, this connection may be holding no lock. In that case, set *pResOut to
+ ** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the
+ ** db in order to roll the hot journal back. If there is another connection
+ ** holding a lock, that attempt will fail and an SQLITE_BUSY returned to
+ ** the user. With other VFS, we try to avoid this, in order to allow a reader
+ ** to proceed while a writer is preparing its transaction. But that won't
+ ** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is
+ ** not a problem in this case. */
+ *pResOut = 0;
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & 0xff) == SQLITE_IOERR ){
- rc = SQLITE_OK;
- reserved=1;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- *pResOut = reserved;
- return rc;
+ return SQLITE_OK;
}
/*
@@ -42850,6 +43337,7 @@ static void setDeviceCharacteristics(unixFile *pFd){
if( pFd->ctrlFlags & UNIXFILE_PSOW ){
pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
}
+ pFd->deviceCharacteristics |= SQLITE_IOCAP_SUBPAGE_READ;
pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
}
@@ -42900,7 +43388,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
/* full bitset of atomics from max sector size and smaller */
- ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
+ (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) |
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
@@ -42908,7 +43396,7 @@ static void setDeviceCharacteristics(unixFile *pFile){
pFile->sectorSize = fsInfo.f_bsize;
pFile->deviceCharacteristics =
/* full bitset of atomics from max sector size and smaller */
- ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
+ (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) |
SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
** so it is ordered */
0;
@@ -45095,12 +45583,19 @@ static int unixOpen(
rc = SQLITE_READONLY_DIRECTORY;
}else if( errno!=EISDIR && isReadWrite ){
/* Failed to open the file for read/write access. Try read-only. */
+ UnixUnusedFd *pReadonly = 0;
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
openFlags &= ~(O_RDWR|O_CREAT);
flags |= SQLITE_OPEN_READONLY;
openFlags |= O_RDONLY;
isReadonly = 1;
- fd = robust_open(zName, openFlags, openMode);
+ pReadonly = findReusableFd(zName, flags);
+ if( pReadonly ){
+ fd = pReadonly->fd;
+ sqlite3_free(pReadonly);
+ }else{
+ fd = robust_open(zName, openFlags, openMode);
+ }
}
}
if( fd<0 ){
@@ -50643,7 +51138,7 @@ static int winSectorSize(sqlite3_file *id){
*/
static int winDeviceCharacteristics(sqlite3_file *id){
winFile *p = (winFile*)id;
- return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
+ return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_SUBPAGE_READ |
((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
}
@@ -52031,7 +52526,7 @@ static int winOpen(
int rc = SQLITE_OK; /* Function Return Code */
#if !defined(NDEBUG) || SQLITE_OS_WINCE
- int eType = flags&0xFFFFFF00; /* Type of file to open */
+ int eType = flags&0x0FFF00; /* Type of file to open */
#endif
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
@@ -53996,6 +54491,14 @@ SQLITE_API unsigned char *sqlite3_serialize(
pOut = 0;
}else{
sz = sqlite3_column_int64(pStmt, 0)*szPage;
+ if( sz==0 ){
+ sqlite3_reset(pStmt);
+ sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0);
+ rc = sqlite3_step(pStmt);
+ if( rc==SQLITE_ROW ){
+ sz = sqlite3_column_int64(pStmt, 0)*szPage;
+ }
+ }
if( piSize ) *piSize = sz;
if( mFlags & SQLITE_SERIALIZE_NOCOPY ){
pOut = 0;
@@ -55054,6 +55557,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
pPgHdr->pData = pPage->pBuf;
pPgHdr->pExtra = (void *)&pPgHdr[1];
memset(pPgHdr->pExtra, 0, 8);
+ assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) );
pPgHdr->pCache = pCache;
pPgHdr->pgno = pgno;
pPgHdr->flags = PGHDR_CLEAN;
@@ -55800,7 +56304,8 @@ static int pcache1InitBulk(PCache1 *pCache){
do{
PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage];
pX->page.pBuf = zBulk;
- pX->page.pExtra = &pX[1];
+ pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX));
+ assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) );
pX->isBulkLocal = 1;
pX->isAnchor = 0;
pX->pNext = pCache->pFree;
@@ -55937,7 +56442,8 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
if( pPg==0 ) return 0;
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
p->page.pBuf = pPg;
- p->page.pExtra = &p[1];
+ p->page.pExtra = (u8*)p + ROUND8(sizeof(*p));
+ assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) );
p->isBulkLocal = 0;
p->isAnchor = 0;
p->pLruPrev = 0; /* Initializing this saves a valgrind error */
@@ -58377,19 +58883,27 @@ static const unsigned char aJournalMagic[] = {
** Return true if page pgno can be read directly from the database file
** by the b-tree layer. This is the case if:
**
-** * the database file is open,
-** * there are no dirty pages in the cache, and
-** * the desired page is not currently in the wal file.
+** (1) the database file is open
+** (2) the VFS for the database is able to do unaligned sub-page reads
+** (3) there are no dirty pages in the cache, and
+** (4) the desired page is not currently in the wal file.
*/
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
- if( pPager->fd->pMethods==0 ) return 0;
- if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
+ assert( pPager!=0 );
+ assert( pPager->fd!=0 );
+ if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */
+ assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
+ if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
+ & SQLITE_IOCAP_SUBPAGE_READ)==0 ){
+ return 0; /* Case (2) */
+ }
+ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */
if( pPager->hasCodec ) return 0;
#ifndef SQLITE_OMIT_WAL
if( pagerUseWal(pPager) ){
u32 iRead = 0;
(void)pPager->wal->methods.xFindFrame(pPager->wal->pData, pgno, &iRead);
- return iRead==0;
+ return iRead==0; /* Condition (4) */
}
#endif
return 1;
@@ -61636,6 +62150,7 @@ static int pagerAcquireMapPage(
return SQLITE_NOMEM_BKPT;
}
p->pExtra = (void *)&p[1];
+ assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) );
p->flags = PGHDR_MMAP;
p->nRef = 1;
p->pPager = pPager;
@@ -64689,7 +65204,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
** This will be either the rollback journal or the WAL file.
*/
SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
-#if SQLITE_OMIT_WAL
+#ifdef SQLITE_OMIT_WAL
return pPager->jfd;
#else
return pagerUseWal(pPager) ? pPager->wal->methods.xFile(pPager->wal->pData) : pPager->jfd;
@@ -65599,7 +66114,7 @@ SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){
** 28: Checksum-2 (second part of checksum for first 24 bytes of header).
**
** Immediately following the wal-header are zero or more frames. Each
-** frame consists of a 24-byte frame-header followed by a bytes
+** frame consists of a 24-byte frame-header followed by bytes
** of page data. The frame-header is six big-endian 32-bit unsigned
** integer values, as follows:
**
@@ -68422,7 +68937,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){
SEH_INJECT_FAULT;
if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
- && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
+ && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0)
#endif
){
/* The WAL has been completely backfilled (or it is empty).
@@ -69891,7 +70406,20 @@ static void sqlite3WalSnapshotOpen(
Wal *pWal,
sqlite3_snapshot *pSnapshot
){
- pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
+ if( pSnapshot && ((WalIndexHdr*)pSnapshot)->iVersion==0 ){
+ /* iVersion==0 means that this is a call to sqlite3_snapshot_get(). In
+ ** this case set the bGetSnapshot flag so that if the call to
+ ** sqlite3_snapshot_get() is about to read transaction on this wal
+ ** file, it does not take read-lock 0 if the wal file has been completely
+ ** checkpointed. Taking read-lock 0 would work, but then it would be
+ ** possible for a subsequent writer to destroy the snapshot even while
+ ** this connection is holding its read-transaction open. This is contrary
+ ** to user expectations, so we avoid it by not taking read-lock 0. */
+ pWal->bGetSnapshot = 1;
+ }else{
+ pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
+ pWal->bGetSnapshot = 0;
+ }
}
/*
@@ -70953,6 +71481,7 @@ struct IntegrityCk {
StrAccum errMsg; /* Accumulate the error message text here */
u32 *heap; /* Min-heap used for analyzing cell coverage */
sqlite3 *db; /* Database connection running the check */
+ i64 nRow; /* Number of rows visited in current tree */
};
/*
@@ -71427,8 +71956,47 @@ int corruptPageError(int lineno, MemPage *p){
# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno)
#endif
+/* Default value for SHARED_LOCK_TRACE macro if shared-cache is disabled
+** or if the lock tracking is disabled. This is always the value for
+** release builds.
+*/
+#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) /*no-op*/
+
#ifndef SQLITE_OMIT_SHARED_CACHE
+#if 0
+/* ^---- Change to 1 and recompile to enable shared-lock tracing
+** for debugging purposes.
+**
+** Print all shared-cache locks on a BtShared. Debugging use only.
+*/
+static void sharedLockTrace(
+ BtShared *pBt,
+ const char *zMsg,
+ int iRoot,
+ int eLockType
+){
+ BtLock *pLock;
+ if( iRoot>0 ){
+ printf("%s-%p %u%s:", zMsg, pBt, iRoot, eLockType==READ_LOCK?"R":"W");
+ }else{
+ printf("%s-%p:", zMsg, pBt);
+ }
+ for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){
+ printf(" %p/%u%s", pLock->pBtree, pLock->iTable,
+ pLock->eLock==READ_LOCK ? "R" : "W");
+ while( pLock->pNext && pLock->pBtree==pLock->pNext->pBtree ){
+ pLock = pLock->pNext;
+ printf(",%u%s", pLock->iTable, pLock->eLock==READ_LOCK ? "R" : "W");
+ }
+ }
+ printf("\n");
+ fflush(stdout);
+}
+#undef SHARED_LOCK_TRACE
+#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) sharedLockTrace(X,MSG,TAB,TYPE)
+#endif /* Shared-lock tracing */
+
#ifdef SQLITE_DEBUG
/*
**** This function is only used as part of an assert() statement. ***
@@ -71505,6 +72073,8 @@ static int hasSharedCacheTableLock(
iTab = iRoot;
}
+ SHARED_LOCK_TRACE(pBtree->pBt,"hasLock",iRoot,eLockType);
+
/* Search for the required lock. Either a write-lock on root-page iTab, a
** write-lock on the schema table, or (if the client is reading) a
** read-lock on iTab will suffice. Return 1 if any of these are found. */
@@ -71638,6 +72208,8 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
BtLock *pLock = 0;
BtLock *pIter;
+ SHARED_LOCK_TRACE(pBt,"setLock", iTable, eLock);
+
assert( sqlite3BtreeHoldsMutex(p) );
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
assert( p->db!=0 );
@@ -71705,6 +72277,8 @@ static void clearAllSharedCacheTableLocks(Btree *p){
assert( p->sharable || 0==*ppIter );
assert( p->inTrans>0 );
+ SHARED_LOCK_TRACE(pBt, "clearAllLocks", 0, 0);
+
while( *ppIter ){
BtLock *pLock = *ppIter;
assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree );
@@ -71743,6 +72317,9 @@ static void clearAllSharedCacheTableLocks(Btree *p){
*/
static void downgradeAllSharedCacheTableLocks(Btree *p){
BtShared *pBt = p->pBt;
+
+ SHARED_LOCK_TRACE(pBt, "downgradeLocks", 0, 0);
+
if( pBt->pWriter==p ){
BtLock *pLock;
pBt->pWriter = 0;
@@ -75975,6 +76552,25 @@ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){
return ROUND8(sizeof(BtCursor));
}
+#ifdef SQLITE_DEBUG
+/*
+** Return true if and only if the Btree object will be automatically
+** closed with the BtCursor closes. This is used within assert() statements
+** only.
+*/
+SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(
+ Btree *pBtree, /* the btree object */
+ BtCursor *pCur /* Corresponding cursor */
+){
+ BtShared *pBt = pBtree->pBt;
+ if( (pBt->openFlags & BTREE_SINGLE)==0 ) return 0;
+ if( pBt->pCursor!=pCur ) return 0;
+ if( pCur->pNext!=0 ) return 0;
+ if( pCur->pBtree!=pBtree ) return 0;
+ return 1;
+}
+#endif
+
/*
** Initialize memory that will be converted into a BtCursor object.
**
@@ -76357,9 +76953,12 @@ static int accessPayload(
if( pCur->aOverflow==0
|| nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow)
){
- Pgno *aNew = (Pgno*)sqlite3Realloc(
- pCur->aOverflow, nOvfl*2*sizeof(Pgno)
- );
+ Pgno *aNew;
+ if( sqlite3FaultSim(413) ){
+ aNew = 0;
+ }else{
+ aNew = (Pgno*)sqlite3Realloc(pCur->aOverflow, nOvfl*2*sizeof(Pgno));
+ }
if( aNew==0 ){
return SQLITE_NOMEM_BKPT;
}else{
@@ -76369,6 +76968,12 @@ static int accessPayload(
memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
pCur->curFlags |= BTCF_ValidOvfl;
}else{
+ /* Sanity check the validity of the overflow page cache */
+ assert( pCur->aOverflow[0]==nextPage
+ || pCur->aOverflow[0]==0
+ || CORRUPT_DB );
+ assert( pCur->aOverflow[0]!=0 || pCur->aOverflow[offset/ovflSize]==0 );
+
/* If the overflow page-list cache has been allocated and the
** entry for the first required overflow page is valid, skip
** directly to it.
@@ -76850,6 +77455,23 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
return rc;
}
+#ifdef SQLITE_DEBUG
+/* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that
+** this flags are true for a consistent database.
+**
+** This routine is is called from within assert() statements only.
+** It is an internal verification routine and does not appear in production
+** builds.
+*/
+static int cursorIsAtLastEntry(BtCursor *pCur){
+ int ii;
+ for(ii=0; iiiPage; ii++){
+ if( pCur->aiIdx[ii]!=pCur->apPage[ii]->nCell ) return 0;
+ }
+ return pCur->ix==pCur->pPage->nCell-1 && pCur->pPage->leaf!=0;
+}
+#endif
+
/* Move the cursor to the last entry in the table. Return SQLITE_OK
** on success. Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
@@ -76878,18 +77500,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
/* If the cursor already points to the last entry, this is a no-op. */
if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){
-#ifdef SQLITE_DEBUG
- /* This block serves to assert() that the cursor really does point
- ** to the last entry in the b-tree. */
- int ii;
- for(ii=0; iiiPage; ii++){
- assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
- }
- assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB );
- testcase( pCur->ix!=pCur->pPage->nCell-1 );
- /* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */
- assert( pCur->pPage->leaf );
-#endif
+ assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB );
*pRes = 0;
return SQLITE_OK;
}
@@ -76942,6 +77553,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
}
if( pCur->info.nKeycurFlags & BTCF_AtLast)!=0 ){
+ assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB );
*pRes = -1;
return SQLITE_OK;
}
@@ -77202,7 +77814,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
&& indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
&& pIdxKey->errCode==SQLITE_OK
){
- pCur->curFlags &= ~BTCF_ValidOvfl;
+ pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast);
if( !pCur->pPage->isInit ){
return SQLITE_CORRUPT_BKPT;
}
@@ -77408,10 +78020,10 @@ SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
assert( cursorOwnsBtShared(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- /* Currently this interface is only called by the OP_IfSmaller
- ** opcode, and it that case the cursor will always be valid and
- ** will always point to a leaf node. */
- if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
+ /* Currently this interface is only called by the OP_IfSizeBetween
+ ** opcode and the OP_Count opcode with P3=1. In either case,
+ ** the cursor will always be valid unless the btree is empty. */
+ if( pCur->eState!=CURSOR_VALID ) return 0;
if( NEVER(pCur->pPage->leaf==0) ) return -1;
n = pCur->pPage->nCell;
@@ -78233,7 +78845,10 @@ static int fillInCell(
n = nHeader + nPayload;
testcase( n==3 );
testcase( n==4 );
- if( n<4 ) n = 4;
+ if( n<4 ){
+ n = 4;
+ pPayload[nPayload] = 0;
+ }
*pnSize = n;
assert( nSrc<=nPayload );
testcase( nSrc(u32)usableSize ){ j = 0; }
memcpy(&pTmp[j], &aData[j], usableSize - j);
- for(k=0; ALWAYS(kixNx[k]<=i; k++){}
+ assert( pCArray->ixNx[NB*2-1]>i );
+ for(k=0; pCArray->ixNx[k]<=i; k++){}
pSrcEnd = pCArray->apEnd[k];
pData = pEnd;
@@ -78860,7 +79476,8 @@ static int pageInsertArray(
u8 *pEnd; /* Maximum extent of cell data */
assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */
if( iEnd<=iFirst ) return 0;
- for(k=0; ALWAYS(kixNx[k]<=i ; k++){}
+ assert( pCArray->ixNx[NB*2-1]>i );
+ for(k=0; pCArray->ixNx[k]<=i ; k++){}
pEnd = pCArray->apEnd[k];
while( 1 /*Exit by break*/ ){
int sz, rc;
@@ -79145,6 +79762,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
b.szCell = &szCell;
b.apEnd[0] = pPage->aDataEnd;
b.ixNx[0] = 2;
+ b.ixNx[NB*2-1] = 0x7fffffff;
rc = rebuildPage(&b, 0, 1, pNew);
if( NEVER(rc) ){
releasePage(pNew);
@@ -79380,7 +79998,9 @@ static int balance_nonroot(
CellArray b; /* Parsed information on cells being balanced */
memset(abDone, 0, sizeof(abDone));
- memset(&b, 0, sizeof(b));
+ assert( sizeof(b) - sizeof(b.ixNx) == offsetof(CellArray,ixNx) );
+ memset(&b, 0, sizeof(b)-sizeof(b.ixNx[0]));
+ b.ixNx[NB*2-1] = 0x7fffffff;
pBt = pParent->pBt;
assert( sqlite3_mutex_held(pBt->mutex) );
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
@@ -79539,7 +80159,7 @@ static int balance_nonroot(
** table-interior, index-leaf, or index-interior).
*/
if( pOld->aData[0]!=apOld[0]->aData[0] ){
- rc = SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_PAGE(pOld);
goto balance_cleanup;
}
@@ -79563,7 +80183,7 @@ static int balance_nonroot(
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
if( pOld->nOverflow>0 ){
if( NEVER(limit