From f74a67eca9d71cda0690b260b8afad96ecb8925d Mon Sep 17 00:00:00 2001
From: tomHastik <57239190+ha100@users.noreply.github.com>
Date: Mon, 28 Oct 2024 09:29:31 +0100
Subject: [PATCH] Updated sqlite-vec to 0.1.3 & sqlite-amalgamation-3450300
(#5)
---
README.md | 2 +-
Sources/CSQLiteVec/extinit.c | 4 +-
Sources/CSQLiteVec/include/sqlite-vec.h | 22 +-
Sources/CSQLiteVec/include/sqlite3.h | 284 +-
Sources/CSQLiteVec/sqlite-vec.c | 23 +-
Sources/CSQLiteVec/sqlite3.c | 15526 ++++++++++++++--------
deps.sh | 12 +-
7 files changed, 10293 insertions(+), 5580 deletions(-)
diff --git a/README.md b/README.md
index 9360e20..41b3edf 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ The [Swift Package Manager](https://www.swift.org/documentation/package-manager/
```swift
dependencies: [
- .package(url: "https://github.com/jkrukowski/SQLiteVec", from: "0.0.8")
+ .package(url: "https://github.com/jkrukowski/SQLiteVec", from: "0.0.9")
]
```
diff --git a/Sources/CSQLiteVec/extinit.c b/Sources/CSQLiteVec/extinit.c
index 9a390fb..db4927c 100644
--- a/Sources/CSQLiteVec/extinit.c
+++ b/Sources/CSQLiteVec/extinit.c
@@ -5,7 +5,5 @@
#include "sqlite-vec.h"
int core_vec_init() {
- int rc = sqlite3_auto_extension((void (*)())sqlite3_vec_init);
- if (rc != SQLITE_OK) return rc;
- return sqlite3_auto_extension((void (*)())sqlite3_vec_fs_read_init);
+ return sqlite3_auto_extension((void *)sqlite3_vec_init);
}
diff --git a/Sources/CSQLiteVec/include/sqlite-vec.h b/Sources/CSQLiteVec/include/sqlite-vec.h
index e45fa69..5d9f0d7 100644
--- a/Sources/CSQLiteVec/include/sqlite-vec.h
+++ b/Sources/CSQLiteVec/include/sqlite-vec.h
@@ -1,7 +1,11 @@
#ifndef SQLITE_VEC_H
#define SQLITE_VEC_H
+#ifndef SQLITE_CORE
#include "sqlite3ext.h"
+#else
+#include "sqlite3.h"
+#endif
#ifdef SQLITE_VEC_STATIC
#define SQLITE_VEC_API
@@ -13,27 +17,17 @@
#endif
#endif
-#define SQLITE_VEC_VERSION "v0.1.2"
-#define SQLITE_VEC_DATE "2024-09-13T16:15:25Z+0000"
-#define SQLITE_VEC_SOURCE "2998a24462b125cb09cd466d54b34f4eabf6f075"
+#define SQLITE_VEC_VERSION "v0.1.3"
+#define SQLITE_VEC_DATE "2024-09-26T07:27:42Z+0000"
+#define SQLITE_VEC_SOURCE "496560cf9ac4b358ea43793e591f376c02c16b90"
#ifdef __cplusplus
extern "C" {
#endif
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-int sqlite3_vec_init(sqlite3 *db, char **pzErrMsg,
+SQLITE_VEC_API int sqlite3_vec_init(sqlite3 *db, char **pzErrMsg,
const sqlite3_api_routines *pApi);
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-int sqlite3_vec_fs_read_init(sqlite3 *db, char **pzErrMsg,
- const sqlite3_api_routines *pApi);
-
-
#ifdef __cplusplus
} /* end of the 'extern "C"' block */
#endif
diff --git a/Sources/CSQLiteVec/include/sqlite3.h b/Sources/CSQLiteVec/include/sqlite3.h
index 2618b37..eaffd1e 100644
--- a/Sources/CSQLiteVec/include/sqlite3.h
+++ b/Sources/CSQLiteVec/include/sqlite3.h
@@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.45.3"
-#define SQLITE_VERSION_NUMBER 3045003
-#define SQLITE_SOURCE_ID "2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355"
+#define SQLITE_VERSION "3.47.0"
+#define SQLITE_VERSION_NUMBER 3047000
+#define SQLITE_SOURCE_ID "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -764,16 +764,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
@@ -3305,8 +3305,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.
@@ -3570,8 +3570,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.
@@ -4222,13 +4222,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
@@ -5599,7 +5603,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.
@@ -5615,6 +5619,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.
**
**
*/
@@ -5623,6 +5636,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
@@ -5820,7 +5834,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()
@@ -6887,6 +6901,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
@@ -7421,9 +7441,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
@@ -7487,7 +7509,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
@@ -8324,6 +8348,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
@@ -8343,7 +8368,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 */
/*
@@ -8357,7 +8382,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
@@ -9319,6 +9344,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 */
@@ -9936,24 +9971,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"
@@ -10497,6 +10553,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
@@ -10805,8 +10869,6 @@ SQLITE_API int sqlite3_deserialize(
#if defined(__wasi__)
# undef SQLITE_WASI
# define SQLITE_WASI 1
-# undef SQLITE_OMIT_WAL
-# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */
# ifndef SQLITE_OMIT_LOAD_EXTENSION
# define SQLITE_OMIT_LOAD_EXTENSION
# endif
@@ -11998,6 +12060,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
@@ -12802,8 +12888,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
@@ -12985,6 +13071,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.
**
@@ -13051,9 +13141,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*);
@@ -13095,6 +13208,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 */
+ );
};
/*
@@ -13115,7 +13237,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
@@ -13139,7 +13261,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:
**
@@ -13163,6 +13285,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
@@ -13186,6 +13315,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
@@ -13294,6 +13447,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);
@@ -13313,6 +13493,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
@@ -13332,7 +13513,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)(
@@ -13359,6 +13540,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/Sources/CSQLiteVec/sqlite-vec.c b/Sources/CSQLiteVec/sqlite-vec.c
index e4db66e..211aaff 100644
--- a/Sources/CSQLiteVec/sqlite-vec.c
+++ b/Sources/CSQLiteVec/sqlite-vec.c
@@ -15,8 +15,12 @@
#include
#endif
+#ifndef SQLITE_CORE
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
+#else
+#include "sqlite3.h"
+#endif
#ifndef UINT32_TYPE
#ifdef HAVE_UINT32_T
@@ -105,9 +109,11 @@ typedef size_t usize;
#define min(a, b) (((a) <= (b)) ? (a) : (b))
enum VectorElementType {
+ // clang-format off
SQLITE_VEC_ELEMENT_TYPE_FLOAT32 = 223 + 0,
- SQLITE_VEC_ELEMENT_TYPE_BIT = 223 + 1,
- SQLITE_VEC_ELEMENT_TYPE_INT8 = 223 + 2,
+ SQLITE_VEC_ELEMENT_TYPE_BIT = 223 + 1,
+ SQLITE_VEC_ELEMENT_TYPE_INT8 = 223 + 2,
+ // clang-format on
};
#ifdef SQLITE_VEC_ENABLE_AVX
@@ -6976,7 +6982,9 @@ static sqlite3_module vec_static_blob_entriesModule = {
SQLITE_VEC_API int sqlite3_vec_init(sqlite3 *db, char **pzErrMsg,
const sqlite3_api_routines *pApi) {
+#ifndef SQLITE_CORE
SQLITE_EXTENSION_INIT2(pApi);
+#endif
int rc = SQLITE_OK;
#define DEFAULT_FLAGS (SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC)
@@ -7030,7 +7038,6 @@ SQLITE_VEC_API int sqlite3_vec_init(sqlite3 *db, char **pzErrMsg,
// clang-format off
{"vec0", &vec0Module, NULL, NULL},
{"vec_each", &vec_eachModule, NULL, NULL},
- {"vec_npy_each", &vec_npy_eachModule, NULL, NULL},
// clang-format on
};
@@ -7058,13 +7065,19 @@ SQLITE_VEC_API int sqlite3_vec_init(sqlite3 *db, char **pzErrMsg,
}
#ifndef SQLITE_VEC_OMIT_FS
-SQLITE_VEC_API int sqlite3_vec_fs_read_init(sqlite3 *db, char **pzErrMsg,
+SQLITE_VEC_API int sqlite3_vec_numpy_init(sqlite3 *db, char **pzErrMsg,
const sqlite3_api_routines *pApi) {
UNUSED_PARAMETER(pzErrMsg);
+#ifndef SQLITE_CORE
SQLITE_EXTENSION_INIT2(pApi);
+#endif
int rc = SQLITE_OK;
rc = sqlite3_create_function_v2(db, "vec_npy_file", 1, SQLITE_RESULT_SUBTYPE,
NULL, vec_npy_file, NULL, NULL, NULL);
+ if(rc != SQLITE_OK) {
+ return rc;
+ }
+ rc = sqlite3_create_module_v2(db, "vec_npy_each", &vec_npy_eachModule, NULL, NULL);
return rc;
}
#endif
@@ -7073,7 +7086,9 @@ SQLITE_VEC_API int
sqlite3_vec_static_blobs_init(sqlite3 *db, char **pzErrMsg,
const sqlite3_api_routines *pApi) {
UNUSED_PARAMETER(pzErrMsg);
+#ifndef SQLITE_CORE
SQLITE_EXTENSION_INIT2(pApi);
+#endif
int rc = SQLITE_OK;
vec_static_blob_data *static_blob_data;
diff --git a/Sources/CSQLiteVec/sqlite3.c b/Sources/CSQLiteVec/sqlite3.c
index 08c593e..2886d04 100644
--- a/Sources/CSQLiteVec/sqlite3.c
+++ b/Sources/CSQLiteVec/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.45.3. By combining all the individual C code files into this
+** version 3.47.0. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -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
-** 8653b758870e6ef0c98d46b3ace27849054a.
+** 03a9703e27c44437c39363d0baf82db4ebc9.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
@@ -256,10 +256,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
/*
@@ -459,9 +462,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.45.3"
-#define SQLITE_VERSION_NUMBER 3045003
-#define SQLITE_SOURCE_ID "2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355"
+#define SQLITE_VERSION "3.47.0"
+#define SQLITE_VERSION_NUMBER 3047000
+#define SQLITE_SOURCE_ID "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1077,16 +1080,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
@@ -3618,8 +3621,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.
@@ -3883,8 +3886,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.
@@ -4535,13 +4538,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
@@ -5912,7 +5919,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.
@@ -5928,6 +5935,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.
**
**
*/
@@ -5936,6 +5952,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
@@ -6133,7 +6150,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()
@@ -7200,6 +7217,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
@@ -7734,9 +7757,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
@@ -7800,7 +7825,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
@@ -8637,6 +8664,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
@@ -8656,7 +8684,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 */
/*
@@ -8670,7 +8698,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
@@ -9632,6 +9660,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 */
@@ -10249,24 +10287,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"
@@ -10810,6 +10869,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
@@ -11118,8 +11185,6 @@ SQLITE_API int sqlite3_deserialize(
#if defined(__wasi__)
# undef SQLITE_WASI
# define SQLITE_WASI 1
-# undef SQLITE_OMIT_WAL
-# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */
# ifndef SQLITE_OMIT_LOAD_EXTENSION
# define SQLITE_OMIT_LOAD_EXTENSION
# endif
@@ -12311,6 +12376,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
@@ -13115,8 +13204,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
@@ -13298,6 +13387,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.
**
@@ -13364,9 +13457,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*);
@@ -13408,6 +13524,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 */
+ );
};
/*
@@ -13428,7 +13553,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
@@ -13452,7 +13577,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:
**
@@ -13476,6 +13601,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
@@ -13499,6 +13631,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
@@ -13607,6 +13763,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);
@@ -13626,6 +13809,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
@@ -13645,7 +13829,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)(
@@ -13672,6 +13856,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
+ );
};
/*
@@ -14314,6 +14517,8 @@ struct fts5_api {
# 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()
@@ -14479,135 +14684,135 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_OR 43
#define TK_AND 44
#define TK_IS 45
-#define TK_MATCH 46
-#define TK_LIKE_KW 47
-#define TK_BETWEEN 48
-#define TK_IN 49
-#define TK_ISNULL 50
-#define TK_NOTNULL 51
-#define TK_NE 52
-#define TK_EQ 53
-#define TK_GT 54
-#define TK_LE 55
-#define TK_LT 56
-#define TK_GE 57
-#define TK_ESCAPE 58
-#define TK_ID 59
-#define TK_COLUMNKW 60
-#define TK_DO 61
-#define TK_FOR 62
-#define TK_IGNORE 63
-#define TK_INITIALLY 64
-#define TK_INSTEAD 65
-#define TK_NO 66
-#define TK_KEY 67
-#define TK_OF 68
-#define TK_OFFSET 69
-#define TK_PRAGMA 70
-#define TK_RAISE 71
-#define TK_RECURSIVE 72
-#define TK_REPLACE 73
-#define TK_RESTRICT 74
-#define TK_ROW 75
-#define TK_ROWS 76
-#define TK_TRIGGER 77
-#define TK_VACUUM 78
-#define TK_VIEW 79
-#define TK_VIRTUAL 80
-#define TK_WITH 81
-#define TK_NULLS 82
-#define TK_FIRST 83
-#define TK_LAST 84
-#define TK_CURRENT 85
-#define TK_FOLLOWING 86
-#define TK_PARTITION 87
-#define TK_PRECEDING 88
-#define TK_RANGE 89
-#define TK_UNBOUNDED 90
-#define TK_EXCLUDE 91
-#define TK_GROUPS 92
-#define TK_OTHERS 93
-#define TK_TIES 94
-#define TK_GENERATED 95
-#define TK_ALWAYS 96
-#define TK_MATERIALIZED 97
-#define TK_REINDEX 98
-#define TK_RENAME 99
-#define TK_CTIME_KW 100
-#define TK_ANY 101
-#define TK_BITAND 102
-#define TK_BITOR 103
-#define TK_LSHIFT 104
-#define TK_RSHIFT 105
-#define TK_PLUS 106
-#define TK_MINUS 107
-#define TK_STAR 108
-#define TK_SLASH 109
-#define TK_REM 110
-#define TK_CONCAT 111
-#define TK_PTR 112
-#define TK_COLLATE 113
-#define TK_BITNOT 114
-#define TK_ON 115
-#define TK_INDEXED 116
-#define TK_STRING 117
-#define TK_JOIN_KW 118
-#define TK_CONSTRAINT 119
-#define TK_DEFAULT 120
-#define TK_NULL 121
-#define TK_PRIMARY 122
-#define TK_UNIQUE 123
-#define TK_CHECK 124
-#define TK_REFERENCES 125
-#define TK_AUTOINCR 126
-#define TK_INSERT 127
-#define TK_DELETE 128
-#define TK_UPDATE 129
-#define TK_SET 130
-#define TK_DEFERRABLE 131
-#define TK_FOREIGN 132
-#define TK_DROP 133
-#define TK_UNION 134
-#define TK_ALL 135
-#define TK_EXCEPT 136
-#define TK_INTERSECT 137
-#define TK_SELECT 138
-#define TK_VALUES 139
-#define TK_DISTINCT 140
-#define TK_DOT 141
-#define TK_FROM 142
-#define TK_JOIN 143
-#define TK_USING 144
-#define TK_ORDER 145
-#define TK_GROUP 146
-#define TK_HAVING 147
-#define TK_LIMIT 148
-#define TK_WHERE 149
-#define TK_RETURNING 150
-#define TK_INTO 151
-#define TK_NOTHING 152
-#define TK_FLOAT 153
-#define TK_BLOB 154
-#define TK_INTEGER 155
-#define TK_VARIABLE 156
-#define TK_CASE 157
-#define TK_WHEN 158
-#define TK_THEN 159
-#define TK_ELSE 160
-#define TK_INDEX 161
-#define TK_ALTER 162
-#define TK_ADD 163
-#define TK_WINDOW 164
-#define TK_OVER 165
-#define TK_FILTER 166
-#define TK_COLUMN 167
-#define TK_AGG_FUNCTION 168
-#define TK_AGG_COLUMN 169
-#define TK_TRUEFALSE 170
-#define TK_ISNOT 171
+#define TK_ISNOT 46
+#define TK_MATCH 47
+#define TK_LIKE_KW 48
+#define TK_BETWEEN 49
+#define TK_IN 50
+#define TK_ISNULL 51
+#define TK_NOTNULL 52
+#define TK_NE 53
+#define TK_EQ 54
+#define TK_GT 55
+#define TK_LE 56
+#define TK_LT 57
+#define TK_GE 58
+#define TK_ESCAPE 59
+#define TK_ID 60
+#define TK_COLUMNKW 61
+#define TK_DO 62
+#define TK_FOR 63
+#define TK_IGNORE 64
+#define TK_INITIALLY 65
+#define TK_INSTEAD 66
+#define TK_NO 67
+#define TK_KEY 68
+#define TK_OF 69
+#define TK_OFFSET 70
+#define TK_PRAGMA 71
+#define TK_RAISE 72
+#define TK_RECURSIVE 73
+#define TK_REPLACE 74
+#define TK_RESTRICT 75
+#define TK_ROW 76
+#define TK_ROWS 77
+#define TK_TRIGGER 78
+#define TK_VACUUM 79
+#define TK_VIEW 80
+#define TK_VIRTUAL 81
+#define TK_WITH 82
+#define TK_NULLS 83
+#define TK_FIRST 84
+#define TK_LAST 85
+#define TK_CURRENT 86
+#define TK_FOLLOWING 87
+#define TK_PARTITION 88
+#define TK_PRECEDING 89
+#define TK_RANGE 90
+#define TK_UNBOUNDED 91
+#define TK_EXCLUDE 92
+#define TK_GROUPS 93
+#define TK_OTHERS 94
+#define TK_TIES 95
+#define TK_GENERATED 96
+#define TK_ALWAYS 97
+#define TK_MATERIALIZED 98
+#define TK_REINDEX 99
+#define TK_RENAME 100
+#define TK_CTIME_KW 101
+#define TK_ANY 102
+#define TK_BITAND 103
+#define TK_BITOR 104
+#define TK_LSHIFT 105
+#define TK_RSHIFT 106
+#define TK_PLUS 107
+#define TK_MINUS 108
+#define TK_STAR 109
+#define TK_SLASH 110
+#define TK_REM 111
+#define TK_CONCAT 112
+#define TK_PTR 113
+#define TK_COLLATE 114
+#define TK_BITNOT 115
+#define TK_ON 116
+#define TK_INDEXED 117
+#define TK_STRING 118
+#define TK_JOIN_KW 119
+#define TK_CONSTRAINT 120
+#define TK_DEFAULT 121
+#define TK_NULL 122
+#define TK_PRIMARY 123
+#define TK_UNIQUE 124
+#define TK_CHECK 125
+#define TK_REFERENCES 126
+#define TK_AUTOINCR 127
+#define TK_INSERT 128
+#define TK_DELETE 129
+#define TK_UPDATE 130
+#define TK_SET 131
+#define TK_DEFERRABLE 132
+#define TK_FOREIGN 133
+#define TK_DROP 134
+#define TK_UNION 135
+#define TK_ALL 136
+#define TK_EXCEPT 137
+#define TK_INTERSECT 138
+#define TK_SELECT 139
+#define TK_VALUES 140
+#define TK_DISTINCT 141
+#define TK_DOT 142
+#define TK_FROM 143
+#define TK_JOIN 144
+#define TK_USING 145
+#define TK_ORDER 146
+#define TK_GROUP 147
+#define TK_HAVING 148
+#define TK_LIMIT 149
+#define TK_WHERE 150
+#define TK_RETURNING 151
+#define TK_INTO 152
+#define TK_NOTHING 153
+#define TK_FLOAT 154
+#define TK_BLOB 155
+#define TK_INTEGER 156
+#define TK_VARIABLE 157
+#define TK_CASE 158
+#define TK_WHEN 159
+#define TK_THEN 160
+#define TK_ELSE 161
+#define TK_INDEX 162
+#define TK_ALTER 163
+#define TK_ADD 164
+#define TK_WINDOW 165
+#define TK_OVER 166
+#define TK_FILTER 167
+#define TK_COLUMN 168
+#define TK_AGG_FUNCTION 169
+#define TK_AGG_COLUMN 170
+#define TK_TRUEFALSE 171
#define TK_FUNCTION 172
-#define TK_UMINUS 173
-#define TK_UPLUS 174
+#define TK_UPLUS 173
+#define TK_UMINUS 174
#define TK_TRUTH 175
#define TK_REGISTER 176
#define TK_VECTOR 177
@@ -14616,8 +14821,9 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_ASTERISK 180
#define TK_SPAN 181
#define TK_ERROR 182
-#define TK_SPACE 183
-#define TK_ILLEGAL 184
+#define TK_QNUMBER 183
+#define TK_SPACE 184
+#define TK_ILLEGAL 185
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -14626,6 +14832,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#include
#include
#include
+#include
/*
** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY.
@@ -14646,7 +14853,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
@@ -14821,9 +15029,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 */
@@ -14879,7 +15084,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
@@ -15147,7 +15352,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
@@ -15323,6 +15528,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 */
@@ -16205,6 +16411,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
@@ -16296,6 +16505,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 */
@@ -16422,6 +16632,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
@@ -16450,6 +16673,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
@@ -16517,6 +16741,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
@@ -16566,12 +16791,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 */
@@ -16579,22 +16804,22 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */
#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
#define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
-#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 */
@@ -16606,18 +16831,18 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */
#define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */
#define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 48 /* jump */
+#define OP_Program 48 /* jump0 */
#define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
-#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
-#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
-#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
-#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
-#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */
-#define OP_ElseEq 58 /* jump, same as TK_ESCAPE */
-#define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfPos 50 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+#define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
+#define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
+#define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
+#define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */
+#define OP_ElseEq 59 /* jump, same as TK_ESCAPE */
#define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
#define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */
#define OP_IncrVacuum 62 /* jump */
@@ -16636,7 +16861,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] */
@@ -16660,23 +16885,23 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_ReadCookie 99
#define OP_SetCookie 100
#define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */
-#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
-#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenRead 102 /* synopsis: root=P2 iDb=P3 */
+#define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
+#define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
#define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */
-#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
-#define OP_OpenDup 115
+#define OP_OpenDup 114
+#define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */
-#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */
+#define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */
#define OP_SorterOpen 119
#define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
#define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */
@@ -16711,8 +16936,8 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_LoadAnalysis 150
#define OP_DropTable 151
#define OP_DropIndex 152
-#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_DropTrigger 154
+#define OP_DropTrigger 153
+#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
#define OP_IntegrityCk 155
#define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */
#define OP_Param 157
@@ -16760,27 +16985,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, 0x12, 0x01, 0x49, 0x49, 0x49,\
-/* 24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\
-/* 32 */ 0x41, 0x01, 0x41, 0x41, 0x41, 0x01, 0x41, 0x41,\
+/* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\
+/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 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, 0x26, 0x26, 0x41, 0x23, 0x0b,\
-/* 48 */ 0x01, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
-/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\
+/* 48 */ 0x81, 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\
+/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x41,\
/* 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, 0x40, 0x26, 0x26,\
+/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, 0x26,\
/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
-/* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\
+/* 112 */ 0x26, 0x00, 0x40, 0x12, 0x40, 0x40, 0x10, 0x00,\
/* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\
/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\
/* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\
/* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
-/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
+/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04,\
/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\
/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\
@@ -16927,6 +17153,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*);
@@ -17514,6 +17742,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
@@ -17817,7 +18049,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 */
@@ -17835,6 +18067,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 */
/*
@@ -18390,8 +18623,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 */
@@ -18823,9 +19055,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.
@@ -19006,7 +19244,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.
@@ -19177,6 +19415,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.
@@ -19189,27 +19437,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 */
@@ -19222,21 +19483,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;
};
/*
@@ -19296,7 +19566,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 */
@@ -19368,7 +19638,7 @@ 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 */
@@ -19489,14 +19759,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
@@ -19526,7 +19799,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
@@ -19733,6 +20010,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
@@ -20028,7 +20307,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 {
@@ -20042,7 +20321,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)
@@ -20120,7 +20399,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
@@ -20412,6 +20690,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*);
@@ -20492,15 +20773,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
@@ -20729,6 +21001,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*);
@@ -20759,7 +21032,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*);
@@ -20878,6 +21151,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 *);
@@ -20927,6 +21203,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);
@@ -20982,16 +21259,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*);
@@ -21119,7 +21394,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**);
@@ -21172,7 +21447,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 **);
@@ -22103,6 +22380,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
@@ -22850,7 +23130,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
@@ -23573,6 +23852,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 */
};
/*
@@ -24219,13 +24499,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 */
};
@@ -24323,6 +24604,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;
@@ -24335,7 +24618,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;
}
@@ -24379,7 +24661,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;
}
@@ -24418,23 +24699,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
**
@@ -24473,12 +24779,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.
**
@@ -24488,6 +24798,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;
@@ -24571,7 +24884,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;
@@ -24582,8 +24895,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;
@@ -24626,7 +24939,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
@@ -24758,7 +25071,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;
}
@@ -24778,12 +25091,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 },
};
/*
@@ -24815,14 +25128,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
@@ -24853,6 +25172,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
@@ -24879,7 +25229,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;
}
@@ -24904,7 +25256,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 */
@@ -24927,7 +25279,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;
}
@@ -24947,7 +25300,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;
@@ -24987,7 +25340,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;
@@ -25058,6 +25411,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;
@@ -25104,11 +25458,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;
@@ -25384,22 +25742,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
** %% %
*/
@@ -25436,7 +25855,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);
@@ -25446,6 +25865,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);
@@ -25459,25 +25893,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;
}
@@ -25520,13 +25940,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;
@@ -25673,9 +26113,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",
@@ -25744,6 +26182,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
@@ -25759,6 +26227,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 ),
@@ -28827,16 +29298,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) */
@@ -30174,6 +30658,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.
@@ -30200,6 +30702,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;
}
@@ -30488,6 +30991,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;
}
}
@@ -31390,13 +31894,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;
@@ -31703,18 +32208,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);
}
@@ -32490,9 +33002,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");
@@ -32521,23 +33035,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:");
@@ -32579,7 +33100,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++;
@@ -32605,7 +33126,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);
@@ -32641,7 +33162,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);
}
@@ -33113,7 +33634,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
@@ -33193,9 +33715,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);
@@ -33216,13 +33739,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);
}
}
@@ -34185,7 +34713,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)
@@ -34942,6 +35472,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:
@@ -35119,6 +35687,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 */
+ double rr[2];
+ u64 s2;
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
@@ -35230,68 +35800,41 @@ 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;
+ rr[0] = (double)s;
+ s2 = (u64)rr[0];
+#if defined(_MSC_VER) && _MSC_VER<1700
+ if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
#endif
- }else{
- *pResult = (double)r;
+ 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{
- double rr[2];
- u64 s2;
- rr[0] = (double)s;
- s2 = (u64)rr[0];
-#if defined(_MSC_VER) && _MSC_VER<1700
- if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
-#endif
- 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);
- }
+ 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) );
@@ -35595,10 +36138,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
@@ -35609,8 +36155,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. */
@@ -35637,62 +36186,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;
@@ -36463,104 +36995,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 ********************************************/
/*
@@ -36881,7 +37315,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(""),
@@ -36898,16 +37332,16 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
/* 48 */ "Program" OpHelp(""),
/* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
- /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
- /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
- /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
- /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
- /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
- /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"),
- /* 58 */ "ElseEq" OpHelp(""),
- /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 50 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
+ /* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
+ /* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
+ /* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
+ /* 57 */ "Lt" OpHelp("IF r[P3]=r[P1]"),
+ /* 59 */ "ElseEq" OpHelp(""),
/* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
/* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
/* 62 */ "IncrVacuum" OpHelp(""),
@@ -36926,7 +37360,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]"),
@@ -36950,23 +37384,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 99 */ "ReadCookie" OpHelp(""),
/* 100 */ "SetCookie" OpHelp(""),
/* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
- /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
- /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 102 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
+ /* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
/* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
- /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
- /* 115 */ "OpenDup" OpHelp(""),
+ /* 114 */ "OpenDup" OpHelp(""),
+ /* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
/* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"),
- /* 117 */ "String8" OpHelp("r[P2]='P4'"),
- /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 118 */ "String8" OpHelp("r[P2]='P4'"),
/* 119 */ "SorterOpen" OpHelp(""),
/* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
/* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
@@ -37001,8 +37435,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 150 */ "LoadAnalysis" OpHelp(""),
/* 151 */ "DropTable" OpHelp(""),
/* 152 */ "DropIndex" OpHelp(""),
- /* 153 */ "Real" OpHelp("r[P2]=P4"),
- /* 154 */ "DropTrigger" OpHelp(""),
+ /* 153 */ "DropTrigger" OpHelp(""),
+ /* 154 */ "Real" OpHelp("r[P2]=P4"),
/* 155 */ "IntegrityCk" OpHelp(""),
/* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
/* 157 */ "Param" OpHelp(""),
@@ -38351,7 +38785,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
@@ -39324,8 +39758,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);
@@ -40304,26 +40742,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;
}
/*
@@ -40493,54 +40927,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;
}
/*
@@ -42012,7 +42425,7 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){
/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);
-#ifndef SQLITE_OMIT_WAL
+#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
static int unixFcntlExternalReader(unixFile*, int*);
#endif
@@ -42139,7 +42552,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
case SQLITE_FCNTL_EXTERNAL_READER: {
-#ifndef SQLITE_OMIT_WAL
+#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
#else
*(int*)pArg = 0;
@@ -42228,7 +42641,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;
@@ -42236,7 +42649,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;
@@ -42312,7 +42725,7 @@ static int unixGetpagesize(void){
#endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */
-#ifndef SQLITE_OMIT_WAL
+#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
/*
** Object used to represent an shared memory buffer.
@@ -44423,12 +44836,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 ){
@@ -54390,6 +54810,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;
@@ -55136,7 +55557,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;
@@ -55273,7 +55695,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 */
@@ -60832,6 +61255,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;
@@ -64615,7 +65039,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:
**
@@ -65112,6 +65536,7 @@ struct Wal {
#endif
#ifdef SQLITE_ENABLE_SNAPSHOT
WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
+ int bGetSnapshot; /* Transaction opened for sqlite3_get_snapshot() */
#endif
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
sqlite3 *db;
@@ -67004,7 +67429,7 @@ static int walHandleException(Wal *pWal){
/*
** Assert that the Wal.lockMask mask, which indicates the locks held
-** by the connenction, is consistent with the Wal.readLock, Wal.writeLock
+** by the connection, is consistent with the Wal.readLock, Wal.writeLock
** and Wal.ckptLock variables. To be used as:
**
** assert( walAssertLockmask(pWal) );
@@ -67668,7 +68093,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).
@@ -69068,7 +69493,20 @@ SQLITE_PRIVATE 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;
+ }
}
/*
@@ -69879,6 +70317,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 */
};
/*
@@ -70353,8 +70792,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. ***
@@ -70431,6 +70909,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. */
@@ -70564,6 +71044,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 );
@@ -70631,6 +71113,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 );
@@ -70669,6 +71153,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;
@@ -74900,6 +75387,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.
**
@@ -75282,9 +75788,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{
@@ -75294,6 +75803,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.
@@ -75775,6 +76290,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.
@@ -75803,18 +76335,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;
}
@@ -75867,6 +76388,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto(
}
if( pCur->info.nKeycurFlags & BTCF_AtLast)!=0 ){
+ assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB );
*pRes = -1;
return SQLITE_OK;
}
@@ -76127,7 +76649,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;
}
@@ -76333,10 +76855,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;
@@ -77705,7 +78227,8 @@ static int rebuildPage(
if( j>(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;
@@ -77788,7 +78311,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;
@@ -78073,6 +78597,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);
@@ -78308,7 +78833,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) );
@@ -78467,7 +78994,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;
}
@@ -78491,7 +79018,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];
@@ -78899,7 +79426,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;
@@ -79134,7 +79662,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;
@@ -79194,7 +79722,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];
@@ -79358,7 +79886,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);
@@ -79386,7 +79914,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 */
@@ -79467,7 +79995,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);
}
}
@@ -79590,7 +80118,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);
}
@@ -79632,7 +80160,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 ){
@@ -79659,10 +80187,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;
@@ -79764,7 +80292,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 ){
@@ -79789,7 +80317,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]);
}
@@ -79885,7 +80413,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 );
@@ -79894,14 +80422,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
@@ -79992,7 +80520,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;
@@ -80108,7 +80636,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++;
@@ -80156,7 +80684,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);
@@ -80246,14 +80774,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;
@@ -80357,7 +80885,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);
@@ -80951,6 +81479,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. */
@@ -81062,6 +81593,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
@@ -81161,6 +81693,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 */
@@ -81174,7 +81707,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 ){
@@ -81247,15 +81782,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;
@@ -83310,6 +83848,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); }
@@ -83894,7 +84439,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;
}
}
@@ -83998,14 +84544,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 ){
@@ -84014,12 +84566,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);
}
@@ -84289,17 +84855,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);
@@ -85334,6 +85900,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;
}
}
@@ -85799,6 +86374,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;
+ }
}
}
@@ -86378,6 +86959,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;
}
@@ -87741,7 +88327,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
@@ -88887,7 +89473,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);
}
}
@@ -89724,7 +90301,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 ){
@@ -89744,7 +90322,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{
@@ -89918,6 +90497,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 */
@@ -91546,6 +92132,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;
@@ -91603,6 +92200,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);
@@ -91652,6 +92250,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);
}
@@ -91665,6 +92264,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);
}
@@ -91675,6 +92275,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;
@@ -91690,6 +92291,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 ){
@@ -91771,6 +92373,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
@@ -92130,7 +92733,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 );
@@ -92329,7 +92955,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. */
@@ -92342,6 +92967,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: {
@@ -92682,6 +93309,104 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */
+/*
+** 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
@@ -93790,7 +94515,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 );
@@ -93813,7 +94538,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
*/
@@ -93825,8 +94552,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;
}
@@ -93843,7 +94570,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 );
@@ -93873,7 +94600,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.
@@ -93886,18 +94613,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
@@ -93910,6 +94641,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
@@ -93940,7 +94674,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 );
@@ -94173,19 +94912,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;
@@ -94706,7 +95441,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);
@@ -94747,7 +95482,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])
**
@@ -96319,11 +97054,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;
@@ -96982,23 +97722,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;
@@ -97176,7 +97916,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) );
}
}
}
@@ -97242,7 +97985,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;
@@ -97385,10 +98129,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 */
@@ -97953,6 +98697,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;
@@ -98922,7 +99677,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;
@@ -99569,11 +100324,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;
@@ -99581,6 +100343,7 @@ case OP_SqlExec: {
sqlite3_xauth xAuth;
#endif
u8 mTrace;
+ int savedAnalysisLimit;
sqlite3VdbeIncrWriteCounter(p, 0);
db->nSqlExec++;
@@ -99589,18 +100352,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);
@@ -99752,11 +100520,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.
**
@@ -99776,19 +100544,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 );
@@ -99915,7 +100685,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.
**
@@ -99923,7 +100695,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 */
@@ -100288,18 +101060,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;
@@ -101472,7 +102255,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;
@@ -101633,14 +102416,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 );
@@ -101967,6 +102765,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;
@@ -102874,13 +103677,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;
}
@@ -105373,10 +106177,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 */
@@ -106150,7 +106954,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
@@ -106456,7 +107262,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);
@@ -106469,7 +107275,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 );
@@ -106480,7 +107286,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{
@@ -106520,7 +107326,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 */
){
@@ -106537,6 +107343,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 */
@@ -106586,10 +107393,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:
@@ -106598,8 +107405,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++){
@@ -106662,7 +107473,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 ){
@@ -106722,9 +107533,9 @@ static int lookupName(
*/
if( cntTab==0
|| (cntTab==1
- && ALWAYS(pMatch!=0)
- && ALWAYS(pMatch->pTab!=0)
- && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0
+ && pMatch!=0
+ && ALWAYS(pMatch->pSTab!=0)
+ && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0
&& (pTab->tabFlags & TF_Ephemeral)==0)
){
cntTab = 1;
@@ -106745,7 +107556,7 @@ static int lookupName(
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);
}
@@ -106768,7 +107579,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;
@@ -106786,7 +107598,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;
}
}
@@ -106869,9 +107681,14 @@ static int lookupName(
&& 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 = 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;
}
@@ -107025,6 +107842,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);
}
@@ -107058,8 +107879,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;
@@ -107097,7 +107922,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;
@@ -107216,7 +108041,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;
@@ -107302,7 +108127,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;
@@ -107311,7 +108135,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 );
@@ -107330,21 +108154,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 */
@@ -107357,6 +108180,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 ){
@@ -107405,6 +108230,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
@@ -107513,11 +108356,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 ){
@@ -107526,9 +108367,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;
@@ -107587,6 +108428,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{
@@ -107595,6 +108437,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;
}
@@ -107733,7 +108576,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
@@ -107832,7 +108675,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;
@@ -108017,7 +108860,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 */
@@ -108108,7 +108951,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;
@@ -108120,12 +108967,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 );
@@ -108227,7 +109078,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;
}
@@ -108381,6 +109235,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. */
@@ -108389,7 +109246,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;
@@ -108403,7 +109260,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);
@@ -108420,10 +109277,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;
}
/*
@@ -108491,7 +109348,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
@@ -108596,7 +109453,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;
}
@@ -109426,11 +110285,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() */
@@ -109446,7 +110306,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 );
}
}
@@ -109878,6 +110738,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 );
@@ -109893,7 +110754,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);
@@ -109908,6 +110768,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);
@@ -109940,11 +110813,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
@@ -110372,30 +111245,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);
@@ -110469,7 +111358,6 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla
pp = &pNew->pPrior;
pNext = pNew;
}
-
return pRet;
}
#else
@@ -110856,6 +111744,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
@@ -110884,6 +111820,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
@@ -110903,6 +111840,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;
@@ -110931,9 +111870,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:
@@ -110955,15 +111896,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;
}
@@ -110975,9 +111916,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);
}
/*
@@ -110993,8 +111940,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;
}
/*
@@ -111002,9 +111965,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;
}
/*
@@ -111022,7 +112002,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?)
@@ -111051,7 +112034,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 ){
@@ -111076,7 +112060,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);
}
@@ -111161,7 +112146,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
@@ -111187,8 +112172,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 */
@@ -111203,18 +112192,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;
@@ -111368,8 +112377,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 */
@@ -111409,13 +112418,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;
}
@@ -111552,7 +112561,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);
@@ -111684,7 +112693,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 */
@@ -111792,6 +112801,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
@@ -111841,11 +112893,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",
@@ -111857,6 +112926,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;
}
@@ -111867,7 +112940,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);
}
@@ -111908,15 +112987,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;
@@ -111967,7 +113061,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);
@@ -112214,9 +113308,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
@@ -112359,6 +113451,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;
@@ -112641,13 +113742,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);
+ }
}
/*
@@ -112817,6 +113922,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
@@ -112849,6 +114007,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 ){
@@ -113131,12 +114300,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: {
@@ -113310,7 +114473,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);
@@ -113341,7 +114506,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);
}
@@ -113483,8 +114648,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);
@@ -113653,7 +114819,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;
@@ -113707,15 +114873,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
@@ -113808,7 +114973,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);
@@ -113872,7 +115037,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);
@@ -113931,7 +115096,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{
@@ -114004,7 +115169,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{
@@ -115082,9 +116247,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{
@@ -115093,9 +116257,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);
}
}
}
@@ -116854,7 +118017,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 */
@@ -116900,8 +118063,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);
}
}
}
@@ -116969,8 +118133,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);
+ }
}
}
}
@@ -117217,7 +118385,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);
}
}
@@ -117796,7 +118964,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++;
}
@@ -118715,7 +119888,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);
@@ -118900,7 +120073,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 */
@@ -118924,9 +120097,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:
@@ -118965,41 +120143,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);
@@ -119106,6 +120279,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);
@@ -119129,6 +120308,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;
@@ -119181,7 +120367,7 @@ static void analyzeOneTable(
#endif /* SQLITE_ENABLE_STAT4 */
/* End of analysis */
- sqlite3VdbeJumpHere(v, addrRewind);
+ if( addrGotoEnd ) sqlite3VdbeJumpHere(v, addrGotoEnd);
}
@@ -119627,12 +120813,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;
@@ -119652,7 +120839,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[] */
@@ -119661,7 +120848,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
@@ -120635,7 +121826,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;
}
}
@@ -120930,7 +122121,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);
}
@@ -123569,20 +124760,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;
@@ -123603,11 +124794,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 */
@@ -123664,13 +124855,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.
@@ -123808,8 +124996,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 */
@@ -123932,7 +125121,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 );
@@ -124230,6 +125419,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 );
@@ -124238,7 +125429,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;
@@ -125329,15 +126520,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;
@@ -125634,12 +126827,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;
}
@@ -125655,13 +126850,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.
*/
@@ -125671,13 +126893,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 ){
@@ -125687,6 +126920,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
@@ -125736,10 +127017,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 );
@@ -127017,8 +128300,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){
@@ -127026,8 +128309,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++;
@@ -127068,6 +128351,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;
}
@@ -127149,7 +128433,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 );
}
@@ -127211,7 +128496,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(
@@ -127244,9 +128529,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;
@@ -130073,7 +131358,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
@@ -130177,7 +131466,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]);
@@ -130230,6 +131519,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);
@@ -130553,7 +131844,13 @@ static void signFunc(
** 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,
@@ -130569,6 +131866,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");
@@ -130579,6 +131877,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 ){
@@ -132110,7 +133486,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;
}
@@ -132118,7 +133495,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),
@@ -132844,6 +134222,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(
@@ -133180,25 +134762,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
@@ -135094,7 +136696,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 ){
@@ -137923,6 +139525,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
@@ -139568,7 +141198,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;
}
@@ -139585,7 +141215,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;
@@ -139607,7 +141236,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++;
@@ -139627,11 +141255,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,
@@ -139641,6 +141270,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)){
@@ -139964,21 +141623,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
- if( !isQuick ){
- sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- if( pPk==pIdx ) continue;
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
- addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
- sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
- sqlite3VdbeLoadString(v, 4, pIdx->zName);
- sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
- integrityCheckResultRow(v);
- sqlite3VdbeJumpHere(v, addr);
- }
- if( pPk ){
- sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol);
- }
+ if( pPk ){
+ assert( !isQuick );
+ sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol);
}
}
@@ -140276,44 +141923,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.
**
- ** (2) The query planner used sqlite_stat1-style statistics for one or
- ** more indexes of the table at some point during the lifetime of
- ** the current connection.
+ ** (3) The table name does not begin with "sqlite_".
**
- ** (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.
+ ** (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.
+ **
+ ** (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 */
@@ -140325,6 +141991,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);
@@ -140332,6 +142002,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;
@@ -140340,23 +142018,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\"",
@@ -140366,11 +142082,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;
@@ -140649,16 +142381,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 ){
- pIdxInfo->estimatedCost = (double)1000;
- pIdxInfo->estimatedRows = 1000;
- 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;
}
@@ -140678,6 +142407,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;
@@ -141478,7 +143208,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;
@@ -141846,12 +143582,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 ){
@@ -141865,7 +143613,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);
@@ -142259,11 +144007,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;
@@ -142297,9 +144047,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);
@@ -142428,10 +144178,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
@@ -143304,12 +145054,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;
@@ -143600,9 +145356,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);
@@ -143640,7 +145403,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++;
@@ -143845,8 +145607,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;
}
@@ -144245,8 +146011,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;
@@ -144257,17 +146022,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 ){
@@ -144297,12 +146067,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;
}
}
@@ -144409,7 +146179,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 ){
@@ -144889,7 +146659,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);
@@ -145233,6 +147003,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;
}
@@ -145889,7 +147664,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);
}
@@ -145920,7 +147697,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;
@@ -145960,8 +147737,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);
+ }
}
}
}
@@ -146272,7 +148051,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
@@ -146325,7 +148105,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) */
){
@@ -146411,14 +148191,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
@@ -146459,8 +148243,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;
@@ -146468,7 +148252,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{
@@ -146483,11 +148267,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;
}
@@ -146498,8 +148285,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);
@@ -146507,7 +148294,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
@@ -146563,8 +148350,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;
@@ -146699,7 +148489,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;
@@ -146757,10 +148547,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);
}
}
@@ -146981,6 +148771,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
@@ -147046,10 +148849,10 @@ 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.
**
@@ -147181,7 +148984,7 @@ static int pushDownWhereTerms(
}
#endif
- if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){
+ if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){
nChng++;
pSubq->selFlags |= SF_PushDown;
while( pSubq ){
@@ -147235,10 +149038,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 ){
@@ -147367,13 +149170,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;
@@ -147398,7 +149201,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 );
@@ -147475,7 +149278,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));
@@ -147530,7 +149337,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;
@@ -147600,7 +149407,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;
@@ -147610,7 +149417,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;
@@ -147646,7 +149454,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;
@@ -147660,26 +149468,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;
@@ -147687,11 +149498,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 ){
@@ -147793,11 +149606,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 ){
@@ -147917,33 +149733,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++;
@@ -147955,7 +149773,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
@@ -147963,7 +149781,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))
@@ -147979,7 +149797,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;
}
@@ -148066,7 +149886,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 */
@@ -148077,10 +149897,11 @@ 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 || ViewCanHaveRowid );
@@ -148316,18 +150137,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);
}
}
}
@@ -148387,6 +150205,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(
@@ -148639,6 +150459,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
@@ -148848,6 +150669,7 @@ static void updateAccumulator(
if( addrNext ){
sqlite3VdbeResolveLabel(v, addrNext);
}
+ if( pParse->nErr ) return;
}
if( regHit==0 && pAggInfo->nAccumulator ){
regHit = regAcc;
@@ -148857,6 +150679,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;
@@ -148972,25 +150795,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;
@@ -149034,6 +150860,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;
@@ -149048,8 +150875,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{
@@ -149058,7 +150886,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 */
@@ -149066,8 +150894,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 ){
@@ -149112,12 +150939,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;
}
@@ -149182,13 +151009,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.
@@ -149199,6 +151026,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 */
@@ -149242,6 +151103,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 );
@@ -149293,7 +151155,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;
}
@@ -149328,12 +151190,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
@@ -149350,6 +151213,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,
@@ -149420,7 +151284,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
@@ -149439,13 +151304,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)
){
@@ -149483,6 +151351,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. */
@@ -149498,7 +151367,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);
@@ -149514,9 +151383,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
@@ -149533,6 +151402,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)
){
@@ -149540,20 +151410,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:
@@ -149570,17 +151446,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
@@ -149593,6 +151480,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
@@ -149606,13 +151494,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)
@@ -149630,32 +151519,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 ){
@@ -149665,25 +151555,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
@@ -149698,17 +151593,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;
}
@@ -149734,7 +151629,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:
**
@@ -149751,12 +151648,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
@@ -149778,7 +151681,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;
@@ -149795,6 +151698,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);
@@ -149812,7 +151716,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
}
- /* Set the limiter.
+ /* Set the limiter. tag-select-0650
*/
iEnd = sqlite3VdbeMakeLabel(pParse);
if( (p->selFlags & SF_FixedLimit)==0 ){
@@ -149824,7 +151728,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++;
@@ -149839,7 +151743,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
@@ -149912,8 +151816,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 */
@@ -150032,7 +151936,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 */
@@ -150219,12 +152123,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);
@@ -150240,9 +152157,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);
@@ -150316,9 +152233,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
@@ -150377,6 +152297,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;
@@ -150465,7 +152387,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 );
@@ -150488,7 +152410,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;
@@ -150871,8 +152800,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,
@@ -151350,7 +153281,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++){
@@ -151587,7 +153519,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);
@@ -151670,6 +153604,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
@@ -151705,7 +153705,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 ){
@@ -151732,6 +153733,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;
@@ -152438,8 +154440,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++){
@@ -153687,7 +155689,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 );
@@ -153706,7 +155708,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)
@@ -154077,6 +156079,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");
@@ -154117,27 +156122,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));
@@ -154214,11 +156221,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
);
assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
db->mDbFlags &= ~DBFLAG_Vacuum;
@@ -154230,11 +156237,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;
@@ -154942,6 +156949,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);
@@ -154964,7 +156973,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{
@@ -155142,12 +157151,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 ){
@@ -155155,6 +157182,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) );
@@ -155168,16 +157196,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);
@@ -155852,11 +157880,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 */
@@ -155869,6 +157899,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 */
@@ -156191,6 +158223,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 */
@@ -156342,7 +158375,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) */
@@ -156487,7 +158521,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";
}
@@ -156530,7 +158564,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
@@ -156548,7 +158584,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;
}
@@ -156583,7 +158620,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{
@@ -156646,7 +158683,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 );
@@ -156790,6 +158829,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 ...)
@@ -156853,6 +158925,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);
@@ -156875,18 +158948,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
@@ -156901,6 +158972,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
@@ -156925,7 +159137,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 );
@@ -156934,125 +159145,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
}
@@ -157667,6 +159765,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.
@@ -157703,7 +159822,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",
@@ -157745,7 +159865,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
@@ -157758,11 +159878,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
@@ -158414,7 +160538,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;
@@ -158489,7 +160615,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 );
@@ -158804,6 +160930,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{
@@ -158942,7 +161074,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);
@@ -159049,12 +161181,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 ){
@@ -159090,7 +161235,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;
@@ -159223,7 +161368,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;
}
/*
@@ -159256,15 +161406,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 );
@@ -159335,12 +161486,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
@@ -159351,11 +161516,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);
@@ -159551,6 +161716,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;
@@ -160067,7 +162239,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);
}
@@ -160105,13 +162279,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;
@@ -160149,7 +162323,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);
}
@@ -160692,7 +162866,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);
@@ -160737,7 +162911,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;
@@ -160760,6 +162934,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. */
@@ -160774,12 +162949,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);
+ }
}
}
@@ -160955,7 +163132,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;
@@ -161297,6 +163474,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().
@@ -161347,16 +163560,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;
}
}
@@ -161595,7 +163816,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
@@ -161670,6 +163891,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 ){
@@ -161708,9 +163935,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",
@@ -161728,9 +163959,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,
@@ -161744,8 +163979,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
/*
@@ -161783,6 +164018,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
@@ -161797,6 +164066,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 );
@@ -161807,11 +164078,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
@@ -161919,7 +164191,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;
@@ -161929,7 +164201,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));
@@ -161971,7 +164243,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));
}
@@ -162061,12 +164333,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);
}
@@ -162088,11 +164365,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{
@@ -162183,7 +164461,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 ){
@@ -162198,7 +164476,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);
}
@@ -162214,7 +164492,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);
@@ -162252,6 +164530,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
@@ -162278,9 +164570,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) );
@@ -162288,28 +164581,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
@@ -162324,7 +164619,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;
}
@@ -162359,7 +164654,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;
@@ -162384,59 +164679,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;
- }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;
+ 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 = (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) );
@@ -162450,6 +164761,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.
@@ -162465,6 +164787,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);
}
@@ -162485,14 +164808,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 ){
@@ -163258,7 +165583,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);
@@ -163430,7 +165755,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:
@@ -163816,7 +166141,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;
@@ -163970,7 +166295,9 @@ static int whereLoopAddBtreeIndex(
}
if( pProbe->bUnordered || pProbe->bLowQual ){
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);
+ }
}
assert( pNew->u.btree.nEqnColumn );
@@ -164111,7 +166438,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{
@@ -164237,11 +166564,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.
@@ -164249,9 +166579,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);
}
@@ -164357,7 +166695,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;
@@ -164614,7 +166954,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;
@@ -164704,9 +167044,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 );
@@ -164731,7 +167071,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 */
@@ -164821,6 +167161,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 */
@@ -164850,6 +167191,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;
@@ -164887,7 +167232,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"));
@@ -164963,7 +167310,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);
@@ -164985,6 +167332,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
@@ -165035,7 +167397,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
@@ -165054,11 +167416,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
@@ -165066,6 +167427,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;
@@ -165083,18 +167445,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;
@@ -165125,18 +167486,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;
}
@@ -165148,8 +167512,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;
}
}
@@ -165160,6 +167524,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);
@@ -165204,7 +167569,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);
}
@@ -165250,7 +167615,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]
@@ -165348,7 +167715,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;
@@ -165362,7 +167729,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
@@ -165406,9 +167773,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 */
@@ -165518,7 +167883,7 @@ static int whereLoopAddOr(
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pItem->pTab) ){
+ if( IsVirtual(pItem->pSTab) ){
rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
}else
#endif
@@ -165632,7 +167997,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)) ){
@@ -165664,6 +168029,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
@@ -165809,9 +168265,18 @@ 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;
}else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
return 0;
}else{
@@ -165821,7 +168286,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)
@@ -165906,7 +168371,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);
}
@@ -166113,6 +168578,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
@@ -166148,13 +168690,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
@@ -166237,7 +168791,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;
@@ -166282,6 +168839,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
@@ -166398,16 +168956,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
@@ -166457,10 +169027,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 ){
@@ -166503,14 +169072,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
@@ -166538,7 +169183,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 );
@@ -166679,6 +169324,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:
**
@@ -166724,6 +169373,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;
@@ -166750,7 +169400,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 ){
@@ -166797,9 +169450,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 */
@@ -166817,6 +169470,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(
}
}
nSearch += pLoop->nOut;
+ if( pWInfo->nOutStarDelta ) nSearch += pLoop->rStarDelta;
}
}
@@ -166852,21 +169506,7 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
}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;
@@ -166909,8 +169549,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);
}
@@ -167048,6 +169688,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
@@ -167130,7 +169771,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.
**
@@ -167283,7 +169928,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;
}
@@ -167343,10 +169989,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;
@@ -167394,15 +170040,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;
}
@@ -167420,7 +170066,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) ){
@@ -167491,7 +170137,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 ){
@@ -167558,7 +170204,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);
@@ -167597,13 +170243,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 ){
@@ -167666,26 +170317,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.
@@ -167832,7 +170463,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)
@@ -167854,7 +170494,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 );
@@ -167863,7 +170503,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;
@@ -167882,8 +170522,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;
}
@@ -167976,16 +170618,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;
@@ -168931,7 +171567,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;
@@ -169099,9 +171735,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;
@@ -169115,7 +171752,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;
@@ -169123,8 +171760,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;
@@ -169186,7 +171821,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);
@@ -169411,10 +172046,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);
@@ -170811,7 +173451,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: */
@@ -171256,9 +173896,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");
}
@@ -171278,6 +173918,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){
@@ -171400,135 +174048,135 @@ static void updateDeleteLimitError(
#define TK_OR 43
#define TK_AND 44
#define TK_IS 45
-#define TK_MATCH 46
-#define TK_LIKE_KW 47
-#define TK_BETWEEN 48
-#define TK_IN 49
-#define TK_ISNULL 50
-#define TK_NOTNULL 51
-#define TK_NE 52
-#define TK_EQ 53
-#define TK_GT 54
-#define TK_LE 55
-#define TK_LT 56
-#define TK_GE 57
-#define TK_ESCAPE 58
-#define TK_ID 59
-#define TK_COLUMNKW 60
-#define TK_DO 61
-#define TK_FOR 62
-#define TK_IGNORE 63
-#define TK_INITIALLY 64
-#define TK_INSTEAD 65
-#define TK_NO 66
-#define TK_KEY 67
-#define TK_OF 68
-#define TK_OFFSET 69
-#define TK_PRAGMA 70
-#define TK_RAISE 71
-#define TK_RECURSIVE 72
-#define TK_REPLACE 73
-#define TK_RESTRICT 74
-#define TK_ROW 75
-#define TK_ROWS 76
-#define TK_TRIGGER 77
-#define TK_VACUUM 78
-#define TK_VIEW 79
-#define TK_VIRTUAL 80
-#define TK_WITH 81
-#define TK_NULLS 82
-#define TK_FIRST 83
-#define TK_LAST 84
-#define TK_CURRENT 85
-#define TK_FOLLOWING 86
-#define TK_PARTITION 87
-#define TK_PRECEDING 88
-#define TK_RANGE 89
-#define TK_UNBOUNDED 90
-#define TK_EXCLUDE 91
-#define TK_GROUPS 92
-#define TK_OTHERS 93
-#define TK_TIES 94
-#define TK_GENERATED 95
-#define TK_ALWAYS 96
-#define TK_MATERIALIZED 97
-#define TK_REINDEX 98
-#define TK_RENAME 99
-#define TK_CTIME_KW 100
-#define TK_ANY 101
-#define TK_BITAND 102
-#define TK_BITOR 103
-#define TK_LSHIFT 104
-#define TK_RSHIFT 105
-#define TK_PLUS 106
-#define TK_MINUS 107
-#define TK_STAR 108
-#define TK_SLASH 109
-#define TK_REM 110
-#define TK_CONCAT 111
-#define TK_PTR 112
-#define TK_COLLATE 113
-#define TK_BITNOT 114
-#define TK_ON 115
-#define TK_INDEXED 116
-#define TK_STRING 117
-#define TK_JOIN_KW 118
-#define TK_CONSTRAINT 119
-#define TK_DEFAULT 120
-#define TK_NULL 121
-#define TK_PRIMARY 122
-#define TK_UNIQUE 123
-#define TK_CHECK 124
-#define TK_REFERENCES 125
-#define TK_AUTOINCR 126
-#define TK_INSERT 127
-#define TK_DELETE 128
-#define TK_UPDATE 129
-#define TK_SET 130
-#define TK_DEFERRABLE 131
-#define TK_FOREIGN 132
-#define TK_DROP 133
-#define TK_UNION 134
-#define TK_ALL 135
-#define TK_EXCEPT 136
-#define TK_INTERSECT 137
-#define TK_SELECT 138
-#define TK_VALUES 139
-#define TK_DISTINCT 140
-#define TK_DOT 141
-#define TK_FROM 142
-#define TK_JOIN 143
-#define TK_USING 144
-#define TK_ORDER 145
-#define TK_GROUP 146
-#define TK_HAVING 147
-#define TK_LIMIT 148
-#define TK_WHERE 149
-#define TK_RETURNING 150
-#define TK_INTO 151
-#define TK_NOTHING 152
-#define TK_FLOAT 153
-#define TK_BLOB 154
-#define TK_INTEGER 155
-#define TK_VARIABLE 156
-#define TK_CASE 157
-#define TK_WHEN 158
-#define TK_THEN 159
-#define TK_ELSE 160
-#define TK_INDEX 161
-#define TK_ALTER 162
-#define TK_ADD 163
-#define TK_WINDOW 164
-#define TK_OVER 165
-#define TK_FILTER 166
-#define TK_COLUMN 167
-#define TK_AGG_FUNCTION 168
-#define TK_AGG_COLUMN 169
-#define TK_TRUEFALSE 170
-#define TK_ISNOT 171
+#define TK_ISNOT 46
+#define TK_MATCH 47
+#define TK_LIKE_KW 48
+#define TK_BETWEEN 49
+#define TK_IN 50
+#define TK_ISNULL 51
+#define TK_NOTNULL 52
+#define TK_NE 53
+#define TK_EQ 54
+#define TK_GT 55
+#define TK_LE 56
+#define TK_LT 57
+#define TK_GE 58
+#define TK_ESCAPE 59
+#define TK_ID 60
+#define TK_COLUMNKW 61
+#define TK_DO 62
+#define TK_FOR 63
+#define TK_IGNORE 64
+#define TK_INITIALLY 65
+#define TK_INSTEAD 66
+#define TK_NO 67
+#define TK_KEY 68
+#define TK_OF 69
+#define TK_OFFSET 70
+#define TK_PRAGMA 71
+#define TK_RAISE 72
+#define TK_RECURSIVE 73
+#define TK_REPLACE 74
+#define TK_RESTRICT 75
+#define TK_ROW 76
+#define TK_ROWS 77
+#define TK_TRIGGER 78
+#define TK_VACUUM 79
+#define TK_VIEW 80
+#define TK_VIRTUAL 81
+#define TK_WITH 82
+#define TK_NULLS 83
+#define TK_FIRST 84
+#define TK_LAST 85
+#define TK_CURRENT 86
+#define TK_FOLLOWING 87
+#define TK_PARTITION 88
+#define TK_PRECEDING 89
+#define TK_RANGE 90
+#define TK_UNBOUNDED 91
+#define TK_EXCLUDE 92
+#define TK_GROUPS 93
+#define TK_OTHERS 94
+#define TK_TIES 95
+#define TK_GENERATED 96
+#define TK_ALWAYS 97
+#define TK_MATERIALIZED 98
+#define TK_REINDEX 99
+#define TK_RENAME 100
+#define TK_CTIME_KW 101
+#define TK_ANY 102
+#define TK_BITAND 103
+#define TK_BITOR 104
+#define TK_LSHIFT 105
+#define TK_RSHIFT 106
+#define TK_PLUS 107
+#define TK_MINUS 108
+#define TK_STAR 109
+#define TK_SLASH 110
+#define TK_REM 111
+#define TK_CONCAT 112
+#define TK_PTR 113
+#define TK_COLLATE 114
+#define TK_BITNOT 115
+#define TK_ON 116
+#define TK_INDEXED 117
+#define TK_STRING 118
+#define TK_JOIN_KW 119
+#define TK_CONSTRAINT 120
+#define TK_DEFAULT 121
+#define TK_NULL 122
+#define TK_PRIMARY 123
+#define TK_UNIQUE 124
+#define TK_CHECK 125
+#define TK_REFERENCES 126
+#define TK_AUTOINCR 127
+#define TK_INSERT 128
+#define TK_DELETE 129
+#define TK_UPDATE 130
+#define TK_SET 131
+#define TK_DEFERRABLE 132
+#define TK_FOREIGN 133
+#define TK_DROP 134
+#define TK_UNION 135
+#define TK_ALL 136
+#define TK_EXCEPT 137
+#define TK_INTERSECT 138
+#define TK_SELECT 139
+#define TK_VALUES 140
+#define TK_DISTINCT 141
+#define TK_DOT 142
+#define TK_FROM 143
+#define TK_JOIN 144
+#define TK_USING 145
+#define TK_ORDER 146
+#define TK_GROUP 147
+#define TK_HAVING 148
+#define TK_LIMIT 149
+#define TK_WHERE 150
+#define TK_RETURNING 151
+#define TK_INTO 152
+#define TK_NOTHING 153
+#define TK_FLOAT 154
+#define TK_BLOB 155
+#define TK_INTEGER 156
+#define TK_VARIABLE 157
+#define TK_CASE 158
+#define TK_WHEN 159
+#define TK_THEN 160
+#define TK_ELSE 161
+#define TK_INDEX 162
+#define TK_ALTER 163
+#define TK_ADD 164
+#define TK_WINDOW 165
+#define TK_OVER 166
+#define TK_FILTER 167
+#define TK_COLUMN 168
+#define TK_AGG_FUNCTION 169
+#define TK_AGG_COLUMN 170
+#define TK_TRUEFALSE 171
#define TK_FUNCTION 172
-#define TK_UMINUS 173
-#define TK_UPLUS 174
+#define TK_UPLUS 173
+#define TK_UMINUS 174
#define TK_TRUTH 175
#define TK_REGISTER 176
#define TK_VECTOR 177
@@ -171537,8 +174185,9 @@ static void updateDeleteLimitError(
#define TK_ASTERISK 180
#define TK_SPAN 181
#define TK_ERROR 182
-#define TK_SPACE 183
-#define TK_ILLEGAL 184
+#define TK_QNUMBER 183
+#define TK_SPACE 184
+#define TK_ILLEGAL 185
#endif
/**************** End token definitions ***************************************/
@@ -171579,6 +174228,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.
@@ -171592,37 +174244,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 319
+#define YYNOCODE 322
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 101
+#define YYWILDCARD 102
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- TriggerStep* yy33;
- Window* yy41;
- Select* yy47;
- SrcList* yy131;
- struct TrigEvent yy180;
- struct {int value; int mask;} yy231;
- IdList* yy254;
- u32 yy285;
- ExprList* yy322;
- Cte* yy385;
- int yy394;
- Upsert* yy444;
- u8 yy516;
- With* yy521;
- const char* yy522;
- Expr* yy528;
- OnOrUsing yy561;
- struct FrameBound yy595;
+ ExprList* yy14;
+ With* yy59;
+ Cte* yy67;
+ Upsert* yy122;
+ IdList* yy132;
+ int yy144;
+ const char* yy168;
+ SrcList* yy203;
+ Window* yy211;
+ OnOrUsing yy269;
+ struct TrigEvent yy286;
+ struct {int value; int mask;} yy383;
+ u32 yy391;
+ TriggerStep* yy427;
+ Expr* yy454;
+ u8 yy462;
+ struct FrameBound yy509;
+ Select* yy555;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -171632,24 +174286,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 579
-#define YYNRULE 405
-#define YYNRULE_WITH_ACTION 340
-#define YYNTOKEN 185
-#define YY_MAX_SHIFT 578
-#define YY_MIN_SHIFTREDUCE 838
-#define YY_MAX_SHIFTREDUCE 1242
-#define YY_ERROR_ACTION 1243
-#define YY_ACCEPT_ACTION 1244
-#define YY_NO_ACTION 1245
-#define YY_MIN_REDUCE 1246
-#define YY_MAX_REDUCE 1650
+#define YYNSTATE 583
+#define YYNRULE 409
+#define YYNRULE_WITH_ACTION 344
+#define YYNTOKEN 186
+#define YY_MAX_SHIFT 582
+#define YY_MIN_SHIFTREDUCE 845
+#define YY_MAX_SHIFTREDUCE 1253
+#define YY_ERROR_ACTION 1254
+#define YY_ACCEPT_ACTION 1255
+#define YY_NO_ACTION 1256
+#define YY_MIN_REDUCE 1257
+#define YY_MAX_REDUCE 1665
+#define YY_MIN_DSTRCTR 205
+#define YY_MAX_DSTRCTR 319
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
@@ -171665,6 +174324,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
@@ -171716,619 +174391,643 @@ typedef union {
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (2100)
+#define YY_ACTTAB_COUNT (2207)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 572, 210, 572, 119, 116, 231, 572, 119, 116, 231,
- /* 10 */ 572, 1317, 379, 1296, 410, 566, 566, 566, 572, 411,
- /* 20 */ 380, 1317, 1279, 42, 42, 42, 42, 210, 1529, 72,
- /* 30 */ 72, 974, 421, 42, 42, 495, 305, 281, 305, 975,
- /* 40 */ 399, 72, 72, 126, 127, 81, 1217, 1217, 1054, 1057,
- /* 50 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 480, 411,
- /* 60 */ 1244, 1, 1, 578, 2, 1248, 554, 119, 116, 231,
- /* 70 */ 319, 484, 147, 484, 528, 119, 116, 231, 533, 1330,
- /* 80 */ 419, 527, 143, 126, 127, 81, 1217, 1217, 1054, 1057,
- /* 90 */ 1044, 1044, 124, 124, 125, 125, 125, 125, 119, 116,
- /* 100 */ 231, 329, 123, 123, 123, 123, 122, 122, 121, 121,
- /* 110 */ 121, 120, 117, 448, 286, 286, 286, 286, 446, 446,
- /* 120 */ 446, 1568, 378, 1570, 1193, 377, 1164, 569, 1164, 569,
- /* 130 */ 411, 1568, 541, 261, 228, 448, 102, 146, 453, 318,
- /* 140 */ 563, 242, 123, 123, 123, 123, 122, 122, 121, 121,
- /* 150 */ 121, 120, 117, 448, 126, 127, 81, 1217, 1217, 1054,
- /* 160 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 143,
- /* 170 */ 296, 1193, 341, 452, 121, 121, 121, 120, 117, 448,
- /* 180 */ 128, 1193, 1194, 1193, 149, 445, 444, 572, 120, 117,
- /* 190 */ 448, 125, 125, 125, 125, 118, 123, 123, 123, 123,
- /* 200 */ 122, 122, 121, 121, 121, 120, 117, 448, 458, 114,
- /* 210 */ 13, 13, 550, 123, 123, 123, 123, 122, 122, 121,
- /* 220 */ 121, 121, 120, 117, 448, 424, 318, 563, 1193, 1194,
- /* 230 */ 1193, 150, 1225, 411, 1225, 125, 125, 125, 125, 123,
- /* 240 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117,
- /* 250 */ 448, 469, 344, 1041, 1041, 1055, 1058, 126, 127, 81,
- /* 260 */ 1217, 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125,
- /* 270 */ 125, 125, 1282, 526, 224, 1193, 572, 411, 226, 519,
- /* 280 */ 177, 83, 84, 123, 123, 123, 123, 122, 122, 121,
- /* 290 */ 121, 121, 120, 117, 448, 1010, 16, 16, 1193, 134,
- /* 300 */ 134, 126, 127, 81, 1217, 1217, 1054, 1057, 1044, 1044,
- /* 310 */ 124, 124, 125, 125, 125, 125, 123, 123, 123, 123,
- /* 320 */ 122, 122, 121, 121, 121, 120, 117, 448, 1045, 550,
- /* 330 */ 1193, 375, 1193, 1194, 1193, 254, 1438, 401, 508, 505,
- /* 340 */ 504, 112, 564, 570, 4, 929, 929, 435, 503, 342,
- /* 350 */ 464, 330, 362, 396, 1238, 1193, 1194, 1193, 567, 572,
- /* 360 */ 123, 123, 123, 123, 122, 122, 121, 121, 121, 120,
- /* 370 */ 117, 448, 286, 286, 371, 1581, 1607, 445, 444, 155,
- /* 380 */ 411, 449, 72, 72, 1289, 569, 1222, 1193, 1194, 1193,
- /* 390 */ 86, 1224, 273, 561, 547, 520, 520, 572, 99, 1223,
- /* 400 */ 6, 1281, 476, 143, 126, 127, 81, 1217, 1217, 1054,
- /* 410 */ 1057, 1044, 1044, 124, 124, 125, 125, 125, 125, 554,
- /* 420 */ 13, 13, 1031, 511, 1225, 1193, 1225, 553, 110, 110,
- /* 430 */ 224, 572, 1239, 177, 572, 429, 111, 199, 449, 573,
- /* 440 */ 449, 432, 1555, 1019, 327, 555, 1193, 272, 289, 370,
- /* 450 */ 514, 365, 513, 259, 72, 72, 547, 72, 72, 361,
- /* 460 */ 318, 563, 1613, 123, 123, 123, 123, 122, 122, 121,
- /* 470 */ 121, 121, 120, 117, 448, 1019, 1019, 1021, 1022, 28,
- /* 480 */ 286, 286, 1193, 1194, 1193, 1159, 572, 1612, 411, 904,
- /* 490 */ 192, 554, 358, 569, 554, 940, 537, 521, 1159, 437,
- /* 500 */ 415, 1159, 556, 1193, 1194, 1193, 572, 548, 548, 52,
- /* 510 */ 52, 216, 126, 127, 81, 1217, 1217, 1054, 1057, 1044,
- /* 520 */ 1044, 124, 124, 125, 125, 125, 125, 1193, 478, 136,
- /* 530 */ 136, 411, 286, 286, 1493, 509, 122, 122, 121, 121,
- /* 540 */ 121, 120, 117, 448, 1010, 569, 522, 219, 545, 545,
- /* 550 */ 318, 563, 143, 6, 536, 126, 127, 81, 1217, 1217,
- /* 560 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125,
- /* 570 */ 1557, 123, 123, 123, 123, 122, 122, 121, 121, 121,
- /* 580 */ 120, 117, 448, 489, 1193, 1194, 1193, 486, 283, 1270,
- /* 590 */ 960, 254, 1193, 375, 508, 505, 504, 1193, 342, 574,
- /* 600 */ 1193, 574, 411, 294, 503, 960, 879, 193, 484, 318,
- /* 610 */ 563, 386, 292, 382, 123, 123, 123, 123, 122, 122,
- /* 620 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217,
- /* 630 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125,
- /* 640 */ 125, 411, 396, 1139, 1193, 872, 101, 286, 286, 1193,
- /* 650 */ 1194, 1193, 375, 1096, 1193, 1194, 1193, 1193, 1194, 1193,
- /* 660 */ 569, 459, 33, 375, 235, 126, 127, 81, 1217, 1217,
- /* 670 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125,
- /* 680 */ 1437, 962, 572, 230, 961, 123, 123, 123, 123, 122,
- /* 690 */ 122, 121, 121, 121, 120, 117, 448, 1159, 230, 1193,
- /* 700 */ 158, 1193, 1194, 1193, 1556, 13, 13, 303, 960, 1233,
- /* 710 */ 1159, 154, 411, 1159, 375, 1584, 1177, 5, 371, 1581,
- /* 720 */ 431, 1239, 3, 960, 123, 123, 123, 123, 122, 122,
- /* 730 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217,
- /* 740 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125,
- /* 750 */ 125, 411, 210, 571, 1193, 1032, 1193, 1194, 1193, 1193,
- /* 760 */ 390, 855, 156, 1555, 376, 404, 1101, 1101, 492, 572,
- /* 770 */ 469, 344, 1322, 1322, 1555, 126, 127, 81, 1217, 1217,
- /* 780 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125,
- /* 790 */ 130, 572, 13, 13, 532, 123, 123, 123, 123, 122,
- /* 800 */ 122, 121, 121, 121, 120, 117, 448, 304, 572, 457,
- /* 810 */ 229, 1193, 1194, 1193, 13, 13, 1193, 1194, 1193, 1300,
- /* 820 */ 467, 1270, 411, 1320, 1320, 1555, 1015, 457, 456, 436,
- /* 830 */ 301, 72, 72, 1268, 123, 123, 123, 123, 122, 122,
- /* 840 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217,
- /* 850 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125,
- /* 860 */ 125, 411, 384, 1076, 1159, 286, 286, 421, 314, 280,
- /* 870 */ 280, 287, 287, 461, 408, 407, 1539, 1159, 569, 572,
- /* 880 */ 1159, 1196, 569, 409, 569, 126, 127, 81, 1217, 1217,
- /* 890 */ 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125, 125,
- /* 900 */ 457, 1485, 13, 13, 1541, 123, 123, 123, 123, 122,
- /* 910 */ 122, 121, 121, 121, 120, 117, 448, 202, 572, 462,
- /* 920 */ 1587, 578, 2, 1248, 843, 844, 845, 1563, 319, 409,
- /* 930 */ 147, 6, 411, 257, 256, 255, 208, 1330, 9, 1196,
- /* 940 */ 264, 72, 72, 1436, 123, 123, 123, 123, 122, 122,
- /* 950 */ 121, 121, 121, 120, 117, 448, 126, 127, 81, 1217,
- /* 960 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125,
- /* 970 */ 125, 572, 286, 286, 572, 1213, 411, 577, 315, 1248,
- /* 980 */ 421, 371, 1581, 356, 319, 569, 147, 495, 529, 1644,
- /* 990 */ 397, 935, 495, 1330, 71, 71, 934, 72, 72, 242,
- /* 1000 */ 1328, 105, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124,
- /* 1010 */ 124, 125, 125, 125, 125, 123, 123, 123, 123, 122,
- /* 1020 */ 122, 121, 121, 121, 120, 117, 448, 1117, 286, 286,
- /* 1030 */ 1422, 452, 1528, 1213, 443, 286, 286, 1492, 1355, 313,
- /* 1040 */ 478, 569, 1118, 454, 351, 495, 354, 1266, 569, 209,
- /* 1050 */ 572, 418, 179, 572, 1031, 242, 385, 1119, 523, 123,
- /* 1060 */ 123, 123, 123, 122, 122, 121, 121, 121, 120, 117,
- /* 1070 */ 448, 1020, 108, 72, 72, 1019, 13, 13, 915, 572,
- /* 1080 */ 1498, 572, 286, 286, 98, 530, 1537, 452, 916, 1334,
- /* 1090 */ 1329, 203, 411, 286, 286, 569, 152, 211, 1498, 1500,
- /* 1100 */ 426, 569, 56, 56, 57, 57, 569, 1019, 1019, 1021,
- /* 1110 */ 447, 572, 411, 531, 12, 297, 126, 127, 81, 1217,
- /* 1120 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125,
- /* 1130 */ 125, 572, 411, 867, 15, 15, 126, 127, 81, 1217,
- /* 1140 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125,
- /* 1150 */ 125, 373, 529, 264, 44, 44, 126, 115, 81, 1217,
- /* 1160 */ 1217, 1054, 1057, 1044, 1044, 124, 124, 125, 125, 125,
- /* 1170 */ 125, 1498, 478, 1271, 417, 123, 123, 123, 123, 122,
- /* 1180 */ 122, 121, 121, 121, 120, 117, 448, 205, 1213, 495,
- /* 1190 */ 430, 867, 468, 322, 495, 123, 123, 123, 123, 122,
- /* 1200 */ 122, 121, 121, 121, 120, 117, 448, 572, 557, 1140,
- /* 1210 */ 1642, 1422, 1642, 543, 572, 123, 123, 123, 123, 122,
- /* 1220 */ 122, 121, 121, 121, 120, 117, 448, 572, 1422, 572,
- /* 1230 */ 13, 13, 542, 323, 1325, 411, 334, 58, 58, 349,
- /* 1240 */ 1422, 1170, 326, 286, 286, 549, 1213, 300, 895, 530,
- /* 1250 */ 45, 45, 59, 59, 1140, 1643, 569, 1643, 565, 417,
- /* 1260 */ 127, 81, 1217, 1217, 1054, 1057, 1044, 1044, 124, 124,
- /* 1270 */ 125, 125, 125, 125, 1367, 373, 500, 290, 1193, 512,
- /* 1280 */ 1366, 427, 394, 394, 393, 275, 391, 896, 1138, 852,
- /* 1290 */ 478, 258, 1422, 1170, 463, 1159, 12, 331, 428, 333,
- /* 1300 */ 1117, 460, 236, 258, 325, 460, 544, 1544, 1159, 1098,
- /* 1310 */ 491, 1159, 324, 1098, 440, 1118, 335, 516, 123, 123,
- /* 1320 */ 123, 123, 122, 122, 121, 121, 121, 120, 117, 448,
- /* 1330 */ 1119, 318, 563, 1138, 572, 1193, 1194, 1193, 112, 564,
- /* 1340 */ 201, 4, 238, 433, 935, 490, 285, 228, 1517, 934,
- /* 1350 */ 170, 560, 572, 142, 1516, 567, 572, 60, 60, 572,
- /* 1360 */ 416, 572, 441, 572, 535, 302, 875, 8, 487, 572,
- /* 1370 */ 237, 572, 416, 572, 485, 61, 61, 572, 449, 62,
- /* 1380 */ 62, 332, 63, 63, 46, 46, 47, 47, 361, 572,
- /* 1390 */ 561, 572, 48, 48, 50, 50, 51, 51, 572, 295,
- /* 1400 */ 64, 64, 482, 295, 539, 412, 471, 1031, 572, 538,
- /* 1410 */ 318, 563, 65, 65, 66, 66, 409, 475, 572, 1031,
- /* 1420 */ 572, 14, 14, 875, 1020, 110, 110, 409, 1019, 572,
- /* 1430 */ 474, 67, 67, 111, 455, 449, 573, 449, 98, 317,
- /* 1440 */ 1019, 132, 132, 133, 133, 572, 1561, 572, 974, 409,
- /* 1450 */ 6, 1562, 68, 68, 1560, 6, 975, 572, 6, 1559,
- /* 1460 */ 1019, 1019, 1021, 6, 346, 218, 101, 531, 53, 53,
- /* 1470 */ 69, 69, 1019, 1019, 1021, 1022, 28, 1586, 1181, 451,
- /* 1480 */ 70, 70, 290, 87, 215, 31, 1363, 394, 394, 393,
- /* 1490 */ 275, 391, 350, 109, 852, 107, 572, 112, 564, 483,
- /* 1500 */ 4, 1212, 572, 239, 153, 572, 39, 236, 1299, 325,
- /* 1510 */ 112, 564, 1298, 4, 567, 572, 32, 324, 572, 54,
- /* 1520 */ 54, 572, 1135, 353, 398, 165, 165, 567, 166, 166,
- /* 1530 */ 572, 291, 355, 572, 17, 357, 572, 449, 77, 77,
- /* 1540 */ 1313, 55, 55, 1297, 73, 73, 572, 238, 470, 561,
- /* 1550 */ 449, 472, 364, 135, 135, 170, 74, 74, 142, 163,
- /* 1560 */ 163, 374, 561, 539, 572, 321, 572, 886, 540, 137,
- /* 1570 */ 137, 339, 1353, 422, 298, 237, 539, 572, 1031, 572,
- /* 1580 */ 340, 538, 101, 369, 110, 110, 162, 131, 131, 164,
- /* 1590 */ 164, 1031, 111, 368, 449, 573, 449, 110, 110, 1019,
- /* 1600 */ 157, 157, 141, 141, 572, 111, 572, 449, 573, 449,
- /* 1610 */ 412, 288, 1019, 572, 882, 318, 563, 572, 219, 572,
- /* 1620 */ 241, 1012, 477, 263, 263, 894, 893, 140, 140, 138,
- /* 1630 */ 138, 1019, 1019, 1021, 1022, 28, 139, 139, 525, 455,
- /* 1640 */ 76, 76, 78, 78, 1019, 1019, 1021, 1022, 28, 1181,
- /* 1650 */ 451, 572, 1083, 290, 112, 564, 1575, 4, 394, 394,
- /* 1660 */ 393, 275, 391, 572, 1023, 852, 572, 479, 345, 263,
- /* 1670 */ 101, 567, 882, 1376, 75, 75, 1421, 501, 236, 260,
- /* 1680 */ 325, 112, 564, 359, 4, 101, 43, 43, 324, 49,
- /* 1690 */ 49, 901, 902, 161, 449, 101, 977, 978, 567, 1079,
- /* 1700 */ 1349, 260, 965, 932, 263, 114, 561, 1095, 517, 1095,
- /* 1710 */ 1083, 1094, 865, 1094, 151, 933, 1144, 114, 238, 1361,
- /* 1720 */ 558, 449, 1023, 559, 1426, 1278, 170, 1269, 1257, 142,
- /* 1730 */ 1601, 1256, 1258, 561, 1594, 1031, 496, 278, 213, 1346,
- /* 1740 */ 310, 110, 110, 939, 311, 312, 237, 11, 234, 111,
- /* 1750 */ 221, 449, 573, 449, 293, 395, 1019, 1408, 337, 1403,
- /* 1760 */ 1396, 338, 1031, 299, 343, 1413, 1412, 481, 110, 110,
- /* 1770 */ 506, 402, 225, 1296, 206, 367, 111, 1358, 449, 573,
- /* 1780 */ 449, 412, 1359, 1019, 1489, 1488, 318, 563, 1019, 1019,
- /* 1790 */ 1021, 1022, 28, 562, 207, 220, 80, 564, 389, 4,
- /* 1800 */ 1597, 1357, 552, 1356, 1233, 181, 267, 232, 1536, 1534,
- /* 1810 */ 455, 1230, 420, 567, 82, 1019, 1019, 1021, 1022, 28,
- /* 1820 */ 86, 217, 85, 1494, 190, 175, 183, 465, 185, 466,
- /* 1830 */ 36, 1409, 186, 187, 188, 499, 449, 244, 37, 99,
- /* 1840 */ 400, 1415, 1414, 488, 1417, 194, 473, 403, 561, 1483,
- /* 1850 */ 248, 92, 1505, 494, 198, 279, 112, 564, 250, 4,
- /* 1860 */ 348, 497, 405, 352, 1259, 251, 252, 515, 1316, 434,
- /* 1870 */ 1315, 1314, 94, 567, 1307, 886, 1306, 1031, 226, 406,
- /* 1880 */ 1611, 1610, 438, 110, 110, 1580, 1286, 524, 439, 308,
- /* 1890 */ 266, 111, 1285, 449, 573, 449, 449, 309, 1019, 366,
- /* 1900 */ 1284, 1609, 265, 1566, 1565, 442, 372, 1381, 561, 129,
- /* 1910 */ 550, 1380, 10, 1470, 383, 106, 316, 551, 100, 35,
- /* 1920 */ 534, 575, 212, 1339, 381, 387, 1187, 1338, 274, 276,
- /* 1930 */ 1019, 1019, 1021, 1022, 28, 277, 413, 1031, 576, 1254,
- /* 1940 */ 388, 1521, 1249, 110, 110, 167, 1522, 168, 148, 1520,
- /* 1950 */ 1519, 111, 306, 449, 573, 449, 222, 223, 1019, 839,
- /* 1960 */ 169, 79, 450, 214, 414, 233, 320, 145, 1093, 1091,
- /* 1970 */ 328, 182, 171, 1212, 918, 184, 240, 336, 243, 1107,
- /* 1980 */ 189, 172, 173, 423, 425, 88, 180, 191, 89, 90,
- /* 1990 */ 1019, 1019, 1021, 1022, 28, 91, 174, 1110, 245, 1106,
- /* 2000 */ 246, 159, 18, 247, 347, 1099, 263, 195, 1227, 493,
- /* 2010 */ 249, 196, 38, 854, 498, 368, 253, 360, 897, 197,
- /* 2020 */ 502, 93, 19, 20, 507, 884, 363, 510, 95, 307,
- /* 2030 */ 160, 96, 518, 97, 1175, 1060, 1146, 40, 21, 227,
- /* 2040 */ 176, 1145, 282, 284, 969, 200, 963, 114, 262, 1165,
- /* 2050 */ 22, 23, 24, 1161, 1169, 25, 1163, 1150, 34, 26,
- /* 2060 */ 1168, 546, 27, 204, 101, 103, 104, 1074, 7, 1061,
- /* 2070 */ 1059, 1063, 1116, 1064, 1115, 268, 269, 29, 41, 270,
- /* 2080 */ 1024, 866, 113, 30, 568, 392, 1183, 144, 178, 1182,
- /* 2090 */ 271, 928, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1602,
+ /* 0 */ 130, 127, 234, 282, 282, 1328, 576, 1307, 460, 289,
+ /* 10 */ 289, 576, 1622, 381, 576, 1328, 573, 576, 562, 413,
+ /* 20 */ 1300, 1542, 573, 481, 562, 524, 460, 459, 558, 82,
+ /* 30 */ 82, 983, 294, 375, 51, 51, 498, 61, 61, 984,
+ /* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063,
+ /* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413,
+ /* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130,
+ /* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290,
+ /* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063,
+ /* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296,
+ /* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132,
+ /* 110 */ 132, 132, 131, 128, 451, 44, 1050, 1050, 1064, 1067,
+ /* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174,
+ /* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 498, 1341,
+ /* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132,
+ /* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 1105, 1228,
+ /* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136,
+ /* 170 */ 136, 1204, 320, 567, 288, 288, 283, 288, 288, 523,
+ /* 180 */ 523, 1250, 139, 1541, 7, 214, 503, 573, 1169, 562,
+ /* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 401, 547,
+ /* 200 */ 487, 1169, 245, 1568, 1169, 245, 133, 133, 132, 132,
+ /* 210 */ 132, 131, 128, 451, 261, 134, 134, 134, 134, 133,
+ /* 220 */ 133, 132, 132, 132, 131, 128, 451, 451, 1204, 1205,
+ /* 230 */ 1204, 130, 127, 234, 455, 413, 182, 455, 130, 127,
+ /* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132,
+ /* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 576, 137,
+ /* 260 */ 138, 91, 261, 1228, 1228, 1063, 1066, 1053, 1053, 135,
+ /* 270 */ 135, 136, 136, 136, 136, 44, 472, 346, 1204, 472,
+ /* 280 */ 346, 51, 51, 418, 93, 157, 134, 134, 134, 134,
+ /* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 166, 363,
+ /* 300 */ 298, 134, 134, 134, 134, 133, 133, 132, 132, 132,
+ /* 310 */ 131, 128, 451, 1293, 461, 1570, 423, 377, 275, 134,
+ /* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128,
+ /* 330 */ 451, 418, 320, 567, 1292, 1204, 1205, 1204, 257, 413,
+ /* 340 */ 483, 511, 508, 507, 94, 132, 132, 132, 131, 128,
+ /* 350 */ 451, 506, 1204, 548, 548, 388, 576, 384, 7, 413,
+ /* 360 */ 550, 229, 522, 137, 138, 91, 530, 1228, 1228, 1063,
+ /* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 51,
+ /* 380 */ 51, 1582, 380, 137, 138, 91, 331, 1228, 1228, 1063,
+ /* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 320,
+ /* 400 */ 567, 288, 288, 320, 567, 1602, 582, 2, 1259, 1204,
+ /* 410 */ 1205, 1204, 1628, 321, 573, 155, 562, 576, 1511, 264,
+ /* 420 */ 231, 520, 1341, 134, 134, 134, 134, 133, 133, 132,
+ /* 430 */ 132, 132, 131, 128, 451, 519, 1511, 1513, 1333, 1333,
+ /* 440 */ 82, 82, 498, 134, 134, 134, 134, 133, 133, 132,
+ /* 450 */ 132, 132, 131, 128, 451, 1435, 257, 288, 288, 511,
+ /* 460 */ 508, 507, 944, 1568, 413, 1019, 1204, 943, 360, 506,
+ /* 470 */ 573, 1598, 562, 44, 575, 551, 551, 557, 1107, 1582,
+ /* 480 */ 544, 576, 1107, 40, 417, 245, 531, 1505, 137, 138,
+ /* 490 */ 91, 219, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135,
+ /* 500 */ 136, 136, 136, 136, 81, 81, 1281, 1204, 413, 553,
+ /* 510 */ 1511, 48, 512, 448, 447, 493, 578, 455, 578, 344,
+ /* 520 */ 45, 1204, 1233, 1204, 1205, 1204, 428, 1235, 158, 882,
+ /* 530 */ 320, 567, 137, 138, 91, 1234, 1228, 1228, 1063, 1066,
+ /* 540 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 134, 134,
+ /* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451,
+ /* 560 */ 1236, 576, 1236, 329, 1204, 1205, 1204, 387, 492, 403,
+ /* 570 */ 1040, 382, 489, 123, 568, 1569, 4, 377, 1204, 1205,
+ /* 580 */ 1204, 570, 570, 570, 82, 82, 882, 1029, 1331, 1331,
+ /* 590 */ 571, 1028, 134, 134, 134, 134, 133, 133, 132, 132,
+ /* 600 */ 132, 131, 128, 451, 288, 288, 1281, 1204, 576, 423,
+ /* 610 */ 576, 1568, 413, 423, 452, 378, 886, 573, 1279, 562,
+ /* 620 */ 46, 557, 532, 1028, 1028, 1030, 565, 130, 127, 234,
+ /* 630 */ 556, 82, 82, 82, 82, 479, 137, 138, 91, 462,
+ /* 640 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136,
+ /* 650 */ 136, 136, 1188, 487, 1506, 1040, 413, 6, 1204, 50,
+ /* 660 */ 879, 121, 121, 948, 1204, 1205, 1204, 358, 557, 122,
+ /* 670 */ 316, 452, 577, 452, 535, 1204, 1028, 439, 303, 212,
+ /* 680 */ 137, 138, 91, 213, 1228, 1228, 1063, 1066, 1053, 1053,
+ /* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134,
+ /* 700 */ 133, 133, 132, 132, 132, 131, 128, 451, 1028, 1028,
+ /* 710 */ 1030, 1031, 35, 288, 288, 1204, 1205, 1204, 1040, 1339,
+ /* 720 */ 533, 123, 568, 1569, 4, 377, 573, 1019, 562, 353,
+ /* 730 */ 1277, 356, 1204, 1205, 1204, 1029, 488, 1188, 571, 1028,
+ /* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
+ /* 750 */ 128, 451, 576, 343, 288, 288, 449, 449, 449, 971,
+ /* 760 */ 413, 1627, 452, 911, 1187, 288, 288, 573, 464, 562,
+ /* 770 */ 238, 1028, 1028, 1030, 565, 82, 82, 498, 573, 411,
+ /* 780 */ 562, 344, 467, 332, 137, 138, 91, 197, 1228, 1228,
+ /* 790 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136,
+ /* 800 */ 1188, 528, 1169, 1040, 413, 1110, 1110, 495, 1041, 121,
+ /* 810 */ 121, 1204, 317, 540, 862, 1169, 1244, 122, 1169, 452,
+ /* 820 */ 577, 452, 1340, 198, 1028, 1204, 481, 526, 137, 138,
+ /* 830 */ 91, 560, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135,
+ /* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133,
+ /* 850 */ 132, 132, 132, 131, 128, 451, 1028, 1028, 1030, 1031,
+ /* 860 */ 35, 1204, 288, 288, 1204, 477, 288, 288, 1204, 1205,
+ /* 870 */ 1204, 539, 481, 437, 470, 573, 1451, 562, 364, 573,
+ /* 880 */ 1153, 562, 1204, 1205, 1204, 1188, 5, 576, 134, 134,
+ /* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451,
+ /* 900 */ 221, 214, 302, 96, 1149, 1657, 232, 1657, 413, 392,
+ /* 910 */ 19, 19, 1024, 949, 406, 373, 1595, 1085, 1204, 1205,
+ /* 920 */ 1204, 1204, 1205, 1204, 1204, 426, 1149, 1658, 413, 1658,
+ /* 930 */ 1659, 399, 137, 138, 91, 3, 1228, 1228, 1063, 1066,
+ /* 940 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 304, 1311,
+ /* 950 */ 514, 1204, 137, 138, 91, 1498, 1228, 1228, 1063, 1066,
+ /* 960 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 434, 131,
+ /* 970 */ 128, 451, 375, 1204, 274, 291, 372, 517, 367, 516,
+ /* 980 */ 262, 1204, 1205, 1204, 1147, 227, 363, 448, 447, 1435,
+ /* 990 */ 1568, 1310, 134, 134, 134, 134, 133, 133, 132, 132,
+ /* 1000 */ 132, 131, 128, 451, 1568, 576, 1147, 487, 1204, 1205,
+ /* 1010 */ 1204, 442, 134, 134, 134, 134, 133, 133, 132, 132,
+ /* 1020 */ 132, 131, 128, 451, 386, 576, 485, 576, 19, 19,
+ /* 1030 */ 1204, 1205, 1204, 1345, 1236, 970, 1236, 574, 47, 936,
+ /* 1040 */ 936, 473, 413, 431, 1552, 573, 1125, 562, 19, 19,
+ /* 1050 */ 19, 19, 49, 336, 850, 851, 852, 111, 1368, 315,
+ /* 1060 */ 429, 576, 413, 433, 341, 306, 137, 138, 91, 115,
+ /* 1070 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136,
+ /* 1080 */ 136, 136, 576, 1309, 82, 82, 137, 138, 91, 529,
+ /* 1090 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136,
+ /* 1100 */ 136, 136, 1569, 222, 377, 19, 19, 305, 1126, 1169,
+ /* 1110 */ 398, 1148, 22, 22, 498, 333, 1569, 335, 377, 576,
+ /* 1120 */ 438, 445, 1169, 1127, 486, 1169, 134, 134, 134, 134,
+ /* 1130 */ 133, 133, 132, 132, 132, 131, 128, 451, 1128, 576,
+ /* 1140 */ 902, 576, 145, 145, 6, 576, 134, 134, 134, 134,
+ /* 1150 */ 133, 133, 132, 132, 132, 131, 128, 451, 214, 1336,
+ /* 1160 */ 922, 576, 19, 19, 19, 19, 1282, 419, 19, 19,
+ /* 1170 */ 923, 412, 515, 141, 576, 1169, 413, 206, 465, 207,
+ /* 1180 */ 903, 215, 1575, 552, 147, 147, 7, 227, 1169, 411,
+ /* 1190 */ 1250, 1169, 120, 307, 117, 307, 413, 66, 66, 334,
+ /* 1200 */ 137, 138, 91, 119, 1228, 1228, 1063, 1066, 1053, 1053,
+ /* 1210 */ 135, 135, 136, 136, 136, 136, 413, 285, 209, 969,
+ /* 1220 */ 137, 138, 91, 471, 1228, 1228, 1063, 1066, 1053, 1053,
+ /* 1230 */ 135, 135, 136, 136, 136, 136, 435, 10, 1450, 267,
+ /* 1240 */ 137, 126, 91, 1435, 1228, 1228, 1063, 1066, 1053, 1053,
+ /* 1250 */ 135, 135, 136, 136, 136, 136, 1435, 1435, 410, 409,
+ /* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
+ /* 1270 */ 128, 451, 576, 969, 576, 1224, 498, 373, 1595, 1554,
+ /* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
+ /* 1290 */ 128, 451, 532, 457, 576, 82, 82, 82, 82, 111,
+ /* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
+ /* 1310 */ 128, 451, 109, 233, 430, 1576, 546, 67, 67, 7,
+ /* 1320 */ 413, 351, 550, 1550, 260, 259, 258, 494, 443, 569,
+ /* 1330 */ 419, 983, 446, 1224, 450, 545, 1207, 576, 969, 984,
+ /* 1340 */ 413, 475, 1449, 1574, 1180, 138, 91, 7, 1228, 1228,
+ /* 1350 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136,
+ /* 1360 */ 21, 21, 267, 576, 300, 1126, 91, 233, 1228, 1228,
+ /* 1370 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136,
+ /* 1380 */ 1127, 373, 1595, 161, 1573, 16, 53, 53, 7, 108,
+ /* 1390 */ 533, 38, 969, 125, 1207, 1128, 1180, 576, 1224, 123,
+ /* 1400 */ 568, 893, 4, 324, 134, 134, 134, 134, 133, 133,
+ /* 1410 */ 132, 132, 132, 131, 128, 451, 571, 564, 534, 576,
+ /* 1420 */ 68, 68, 576, 39, 134, 134, 134, 134, 133, 133,
+ /* 1430 */ 132, 132, 132, 131, 128, 451, 576, 160, 1571, 1223,
+ /* 1440 */ 452, 576, 54, 54, 576, 69, 69, 576, 1366, 576,
+ /* 1450 */ 420, 184, 565, 463, 297, 576, 1224, 463, 297, 70,
+ /* 1460 */ 70, 576, 44, 474, 71, 71, 576, 72, 72, 576,
+ /* 1470 */ 73, 73, 55, 55, 411, 874, 242, 576, 56, 56,
+ /* 1480 */ 576, 1040, 576, 478, 57, 57, 576, 121, 121, 59,
+ /* 1490 */ 59, 23, 60, 60, 411, 122, 319, 452, 577, 452,
+ /* 1500 */ 74, 74, 1028, 75, 75, 76, 76, 411, 290, 20,
+ /* 1510 */ 20, 108, 287, 231, 553, 123, 568, 325, 4, 320,
+ /* 1520 */ 567, 97, 218, 944, 1144, 328, 400, 576, 943, 576,
+ /* 1530 */ 1380, 424, 571, 874, 1028, 1028, 1030, 1031, 35, 293,
+ /* 1540 */ 534, 576, 1104, 576, 1104, 9, 576, 342, 576, 111,
+ /* 1550 */ 77, 77, 143, 143, 576, 205, 452, 222, 1379, 889,
+ /* 1560 */ 576, 901, 900, 1188, 144, 144, 78, 78, 565, 62,
+ /* 1570 */ 62, 79, 79, 323, 1021, 576, 266, 63, 63, 908,
+ /* 1580 */ 909, 1589, 542, 80, 80, 576, 371, 541, 123, 568,
+ /* 1590 */ 480, 4, 266, 482, 244, 266, 370, 1040, 64, 64,
+ /* 1600 */ 576, 466, 576, 121, 121, 571, 1557, 576, 170, 170,
+ /* 1610 */ 576, 122, 576, 452, 577, 452, 576, 889, 1028, 576,
+ /* 1620 */ 165, 576, 111, 171, 171, 87, 87, 337, 1616, 452,
+ /* 1630 */ 65, 65, 1530, 83, 83, 146, 146, 986, 987, 84,
+ /* 1640 */ 84, 565, 168, 168, 148, 148, 1092, 347, 1032, 111,
+ /* 1650 */ 1028, 1028, 1030, 1031, 35, 542, 1103, 576, 1103, 576,
+ /* 1660 */ 543, 123, 568, 504, 4, 263, 576, 361, 1529, 111,
+ /* 1670 */ 1040, 1088, 576, 263, 576, 490, 121, 121, 571, 1188,
+ /* 1680 */ 142, 142, 169, 169, 122, 576, 452, 577, 452, 162,
+ /* 1690 */ 162, 1028, 576, 563, 576, 152, 152, 151, 151, 348,
+ /* 1700 */ 1376, 974, 452, 266, 1092, 942, 1032, 125, 149, 149,
+ /* 1710 */ 939, 576, 125, 576, 565, 150, 150, 86, 86, 872,
+ /* 1720 */ 352, 159, 576, 1028, 1028, 1030, 1031, 35, 542, 941,
+ /* 1730 */ 576, 125, 355, 541, 88, 88, 85, 85, 357, 359,
+ /* 1740 */ 1324, 1308, 366, 1040, 376, 52, 52, 499, 1389, 121,
+ /* 1750 */ 121, 1434, 1188, 58, 58, 1362, 1374, 122, 1439, 452,
+ /* 1760 */ 577, 452, 1289, 167, 1028, 1280, 280, 1268, 1267, 1269,
+ /* 1770 */ 1609, 1359, 312, 313, 12, 314, 397, 1421, 224, 1416,
+ /* 1780 */ 295, 237, 1409, 339, 340, 1426, 301, 345, 484, 228,
+ /* 1790 */ 1371, 1307, 1372, 1370, 1425, 404, 1028, 1028, 1030, 1031,
+ /* 1800 */ 35, 1601, 1192, 454, 509, 369, 292, 1502, 210, 1501,
+ /* 1810 */ 1369, 396, 396, 395, 277, 393, 211, 566, 859, 1612,
+ /* 1820 */ 1244, 123, 568, 391, 4, 1188, 223, 270, 1549, 1547,
+ /* 1830 */ 1241, 239, 186, 327, 422, 96, 195, 220, 571, 235,
+ /* 1840 */ 180, 326, 188, 468, 190, 1507, 191, 192, 92, 193,
+ /* 1850 */ 469, 95, 1422, 13, 502, 247, 1430, 109, 199, 402,
+ /* 1860 */ 476, 405, 452, 1496, 1428, 1427, 14, 491, 251, 102,
+ /* 1870 */ 497, 1518, 241, 281, 565, 253, 203, 354, 500, 254,
+ /* 1880 */ 175, 1270, 407, 43, 350, 518, 1327, 436, 255, 1326,
+ /* 1890 */ 1325, 1318, 104, 893, 1626, 229, 408, 440, 1625, 441,
+ /* 1900 */ 240, 310, 1296, 1040, 311, 1317, 527, 1594, 1297, 121,
+ /* 1910 */ 121, 368, 1295, 1624, 268, 269, 1580, 122, 1579, 452,
+ /* 1920 */ 577, 452, 374, 444, 1028, 1394, 1393, 140, 553, 90,
+ /* 1930 */ 568, 11, 4, 1483, 383, 414, 385, 110, 116, 216,
+ /* 1940 */ 320, 567, 1350, 555, 42, 318, 571, 537, 1349, 389,
+ /* 1950 */ 390, 579, 1198, 276, 279, 278, 1028, 1028, 1030, 1031,
+ /* 1960 */ 35, 580, 415, 1265, 458, 1260, 416, 185, 1534, 172,
+ /* 1970 */ 452, 1535, 173, 156, 308, 846, 1533, 1532, 453, 217,
+ /* 1980 */ 225, 89, 565, 174, 322, 1188, 226, 236, 1102, 154,
+ /* 1990 */ 1100, 330, 176, 187, 1223, 189, 925, 338, 243, 1116,
+ /* 2000 */ 246, 194, 177, 178, 425, 427, 98, 99, 196, 100,
+ /* 2010 */ 101, 1040, 179, 1119, 248, 1115, 249, 121, 121, 24,
+ /* 2020 */ 163, 250, 349, 1108, 266, 122, 1238, 452, 577, 452,
+ /* 2030 */ 1192, 454, 1028, 200, 292, 496, 252, 201, 861, 396,
+ /* 2040 */ 396, 395, 277, 393, 15, 501, 859, 370, 292, 256,
+ /* 2050 */ 202, 554, 505, 396, 396, 395, 277, 393, 103, 239,
+ /* 2060 */ 859, 327, 25, 26, 1028, 1028, 1030, 1031, 35, 326,
+ /* 2070 */ 362, 510, 891, 239, 365, 327, 513, 904, 105, 309,
+ /* 2080 */ 164, 181, 27, 326, 106, 521, 107, 1185, 1069, 1155,
+ /* 2090 */ 17, 1154, 284, 1188, 286, 978, 265, 204, 125, 1171,
+ /* 2100 */ 241, 230, 972, 1175, 28, 1160, 29, 1179, 175, 1173,
+ /* 2110 */ 30, 43, 31, 1178, 241, 32, 41, 549, 8, 33,
+ /* 2120 */ 208, 111, 175, 1083, 1070, 43, 113, 1068, 240, 114,
+ /* 2130 */ 1072, 34, 1073, 561, 1124, 118, 271, 36, 18, 1194,
+ /* 2140 */ 1033, 873, 240, 935, 124, 37, 272, 273, 1617, 572,
+ /* 2150 */ 183, 153, 394, 1193, 1256, 1256, 1256, 1256, 1256, 1256,
+ /* 2160 */ 1256, 1256, 1256, 414, 1256, 1256, 1256, 1256, 320, 567,
+ /* 2170 */ 1256, 1256, 1256, 1256, 1256, 1256, 1256, 414, 1256, 1256,
+ /* 2180 */ 1256, 1256, 320, 567, 1256, 1256, 1256, 1256, 1256, 1256,
+ /* 2190 */ 1256, 1256, 458, 1256, 1256, 1256, 1256, 1256, 1256, 1256,
+ /* 2200 */ 1256, 1256, 1256, 1256, 1256, 1256, 458,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276,
- /* 10 */ 193, 223, 219, 225, 206, 210, 211, 212, 193, 19,
- /* 20 */ 219, 233, 216, 216, 217, 216, 217, 193, 295, 216,
- /* 30 */ 217, 31, 193, 216, 217, 193, 228, 213, 230, 39,
- /* 40 */ 206, 216, 217, 43, 44, 45, 46, 47, 48, 49,
- /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19,
- /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276,
- /* 70 */ 195, 193, 197, 193, 261, 274, 275, 276, 253, 204,
- /* 80 */ 238, 204, 81, 43, 44, 45, 46, 47, 48, 49,
- /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 274, 275,
- /* 100 */ 276, 262, 102, 103, 104, 105, 106, 107, 108, 109,
- /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211,
- /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252,
- /* 130 */ 19, 314, 315, 256, 257, 113, 25, 72, 296, 138,
- /* 140 */ 139, 266, 102, 103, 104, 105, 106, 107, 108, 109,
- /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48,
- /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81,
- /* 170 */ 292, 59, 292, 298, 108, 109, 110, 111, 112, 113,
- /* 180 */ 69, 116, 117, 118, 72, 106, 107, 193, 111, 112,
- /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105,
- /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 25,
- /* 210 */ 216, 217, 145, 102, 103, 104, 105, 106, 107, 108,
- /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117,
- /* 230 */ 118, 164, 153, 19, 155, 54, 55, 56, 57, 102,
- /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
- /* 250 */ 113, 128, 129, 46, 47, 48, 49, 43, 44, 45,
- /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 270 */ 56, 57, 216, 193, 25, 59, 193, 19, 165, 166,
- /* 280 */ 193, 67, 24, 102, 103, 104, 105, 106, 107, 108,
- /* 290 */ 109, 110, 111, 112, 113, 73, 216, 217, 59, 216,
- /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105,
- /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 145,
- /* 330 */ 59, 193, 116, 117, 118, 119, 273, 204, 122, 123,
- /* 340 */ 124, 19, 20, 134, 22, 136, 137, 19, 132, 127,
- /* 350 */ 128, 129, 24, 22, 23, 116, 117, 118, 36, 193,
- /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
- /* 370 */ 112, 113, 239, 240, 311, 312, 215, 106, 107, 241,
- /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118,
- /* 390 */ 151, 120, 26, 71, 193, 308, 309, 193, 149, 128,
- /* 400 */ 313, 216, 269, 81, 43, 44, 45, 46, 47, 48,
- /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 253,
- /* 420 */ 216, 217, 100, 95, 153, 59, 155, 261, 106, 107,
- /* 430 */ 25, 193, 101, 193, 193, 231, 114, 25, 116, 117,
- /* 440 */ 118, 113, 304, 121, 193, 204, 59, 119, 120, 121,
- /* 450 */ 122, 123, 124, 125, 216, 217, 193, 216, 217, 131,
- /* 460 */ 138, 139, 230, 102, 103, 104, 105, 106, 107, 108,
- /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157,
- /* 480 */ 239, 240, 116, 117, 118, 76, 193, 23, 19, 25,
- /* 490 */ 22, 253, 23, 252, 253, 108, 87, 204, 89, 261,
- /* 500 */ 198, 92, 261, 116, 117, 118, 193, 306, 307, 216,
- /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 520 */ 51, 52, 53, 54, 55, 56, 57, 59, 193, 216,
- /* 530 */ 217, 19, 239, 240, 283, 23, 106, 107, 108, 109,
- /* 540 */ 110, 111, 112, 113, 73, 252, 253, 142, 308, 309,
- /* 550 */ 138, 139, 81, 313, 145, 43, 44, 45, 46, 47,
- /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 570 */ 307, 102, 103, 104, 105, 106, 107, 108, 109, 110,
- /* 580 */ 111, 112, 113, 281, 116, 117, 118, 285, 23, 193,
- /* 590 */ 25, 119, 59, 193, 122, 123, 124, 59, 127, 203,
- /* 600 */ 59, 205, 19, 268, 132, 25, 23, 22, 193, 138,
- /* 610 */ 139, 249, 204, 251, 102, 103, 104, 105, 106, 107,
- /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
- /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 640 */ 57, 19, 22, 23, 59, 23, 25, 239, 240, 116,
- /* 650 */ 117, 118, 193, 11, 116, 117, 118, 116, 117, 118,
- /* 660 */ 252, 269, 22, 193, 15, 43, 44, 45, 46, 47,
- /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 680 */ 273, 143, 193, 118, 143, 102, 103, 104, 105, 106,
- /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59,
- /* 700 */ 241, 116, 117, 118, 304, 216, 217, 292, 143, 60,
- /* 710 */ 89, 241, 19, 92, 193, 193, 23, 22, 311, 312,
- /* 720 */ 231, 101, 22, 143, 102, 103, 104, 105, 106, 107,
- /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
- /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 750 */ 57, 19, 193, 193, 59, 23, 116, 117, 118, 59,
- /* 760 */ 201, 21, 241, 304, 193, 206, 127, 128, 129, 193,
- /* 770 */ 128, 129, 235, 236, 304, 43, 44, 45, 46, 47,
- /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 790 */ 22, 193, 216, 217, 193, 102, 103, 104, 105, 106,
- /* 800 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 193,
- /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 226,
- /* 820 */ 80, 193, 19, 235, 236, 304, 23, 211, 212, 231,
- /* 830 */ 204, 216, 217, 205, 102, 103, 104, 105, 106, 107,
- /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
- /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 860 */ 57, 19, 193, 123, 76, 239, 240, 193, 253, 239,
- /* 870 */ 240, 239, 240, 244, 106, 107, 193, 89, 252, 193,
- /* 880 */ 92, 59, 252, 254, 252, 43, 44, 45, 46, 47,
- /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 900 */ 284, 161, 216, 217, 193, 102, 103, 104, 105, 106,
- /* 910 */ 107, 108, 109, 110, 111, 112, 113, 231, 193, 244,
- /* 920 */ 187, 188, 189, 190, 7, 8, 9, 309, 195, 254,
- /* 930 */ 197, 313, 19, 127, 128, 129, 262, 204, 22, 117,
- /* 940 */ 24, 216, 217, 273, 102, 103, 104, 105, 106, 107,
- /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46,
- /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 970 */ 57, 193, 239, 240, 193, 59, 19, 188, 253, 190,
- /* 980 */ 193, 311, 312, 16, 195, 252, 197, 193, 19, 301,
- /* 990 */ 302, 135, 193, 204, 216, 217, 140, 216, 217, 266,
- /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106,
- /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240,
- /* 1030 */ 193, 298, 238, 117, 253, 239, 240, 238, 259, 260,
- /* 1040 */ 193, 252, 27, 193, 77, 193, 79, 204, 252, 262,
- /* 1050 */ 193, 299, 300, 193, 100, 266, 278, 42, 204, 102,
- /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
- /* 1070 */ 113, 117, 159, 216, 217, 121, 216, 217, 63, 193,
- /* 1080 */ 193, 193, 239, 240, 115, 116, 193, 298, 73, 240,
- /* 1090 */ 238, 231, 19, 239, 240, 252, 22, 24, 211, 212,
- /* 1100 */ 263, 252, 216, 217, 216, 217, 252, 153, 154, 155,
- /* 1110 */ 253, 193, 19, 144, 213, 268, 43, 44, 45, 46,
- /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 1130 */ 57, 193, 19, 59, 216, 217, 43, 44, 45, 46,
- /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 1150 */ 57, 193, 19, 24, 216, 217, 43, 44, 45, 46,
- /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 1170 */ 57, 284, 193, 208, 209, 102, 103, 104, 105, 106,
- /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 286, 59, 193,
- /* 1190 */ 232, 117, 291, 193, 193, 102, 103, 104, 105, 106,
- /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 193, 204, 22,
- /* 1210 */ 23, 193, 25, 66, 193, 102, 103, 104, 105, 106,
- /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 193, 193, 193,
- /* 1230 */ 216, 217, 85, 193, 238, 19, 16, 216, 217, 238,
- /* 1240 */ 193, 94, 193, 239, 240, 231, 117, 268, 35, 116,
- /* 1250 */ 216, 217, 216, 217, 22, 23, 252, 25, 208, 209,
- /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 1270 */ 54, 55, 56, 57, 193, 193, 19, 5, 59, 66,
- /* 1280 */ 193, 263, 10, 11, 12, 13, 14, 74, 101, 17,
- /* 1290 */ 193, 46, 193, 146, 193, 76, 213, 77, 263, 79,
- /* 1300 */ 12, 260, 30, 46, 32, 264, 87, 193, 89, 29,
- /* 1310 */ 263, 92, 40, 33, 232, 27, 193, 108, 102, 103,
- /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
- /* 1330 */ 42, 138, 139, 101, 193, 116, 117, 118, 19, 20,
- /* 1340 */ 255, 22, 70, 130, 135, 65, 256, 257, 193, 140,
- /* 1350 */ 78, 63, 193, 81, 193, 36, 193, 216, 217, 193,
- /* 1360 */ 115, 193, 263, 193, 145, 268, 59, 48, 193, 193,
- /* 1370 */ 98, 193, 115, 193, 291, 216, 217, 193, 59, 216,
- /* 1380 */ 217, 161, 216, 217, 216, 217, 216, 217, 131, 193,
- /* 1390 */ 71, 193, 216, 217, 216, 217, 216, 217, 193, 260,
- /* 1400 */ 216, 217, 19, 264, 85, 133, 244, 100, 193, 90,
- /* 1410 */ 138, 139, 216, 217, 216, 217, 254, 244, 193, 100,
- /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 254, 121, 193,
- /* 1430 */ 115, 216, 217, 114, 162, 116, 117, 118, 115, 244,
- /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 193, 31, 254,
- /* 1450 */ 313, 309, 216, 217, 309, 313, 39, 193, 313, 309,
- /* 1460 */ 153, 154, 155, 313, 193, 150, 25, 144, 216, 217,
- /* 1470 */ 216, 217, 153, 154, 155, 156, 157, 0, 1, 2,
- /* 1480 */ 216, 217, 5, 149, 150, 22, 193, 10, 11, 12,
- /* 1490 */ 13, 14, 193, 158, 17, 160, 193, 19, 20, 116,
- /* 1500 */ 22, 25, 193, 24, 22, 193, 24, 30, 226, 32,
- /* 1510 */ 19, 20, 226, 22, 36, 193, 53, 40, 193, 216,
- /* 1520 */ 217, 193, 23, 193, 25, 216, 217, 36, 216, 217,
- /* 1530 */ 193, 99, 193, 193, 22, 193, 193, 59, 216, 217,
- /* 1540 */ 193, 216, 217, 193, 216, 217, 193, 70, 129, 71,
- /* 1550 */ 59, 129, 193, 216, 217, 78, 216, 217, 81, 216,
- /* 1560 */ 217, 193, 71, 85, 193, 133, 193, 126, 90, 216,
- /* 1570 */ 217, 152, 258, 61, 152, 98, 85, 193, 100, 193,
- /* 1580 */ 23, 90, 25, 121, 106, 107, 23, 216, 217, 216,
- /* 1590 */ 217, 100, 114, 131, 116, 117, 118, 106, 107, 121,
- /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118,
- /* 1610 */ 133, 22, 121, 193, 59, 138, 139, 193, 142, 193,
- /* 1620 */ 141, 23, 23, 25, 25, 120, 121, 216, 217, 216,
- /* 1630 */ 217, 153, 154, 155, 156, 157, 216, 217, 19, 162,
- /* 1640 */ 216, 217, 216, 217, 153, 154, 155, 156, 157, 1,
- /* 1650 */ 2, 193, 59, 5, 19, 20, 318, 22, 10, 11,
- /* 1660 */ 12, 13, 14, 193, 59, 17, 193, 23, 23, 25,
- /* 1670 */ 25, 36, 117, 193, 216, 217, 193, 23, 30, 25,
- /* 1680 */ 32, 19, 20, 23, 22, 25, 216, 217, 40, 216,
- /* 1690 */ 217, 7, 8, 23, 59, 25, 83, 84, 36, 23,
- /* 1700 */ 193, 25, 23, 23, 25, 25, 71, 153, 145, 155,
- /* 1710 */ 117, 153, 23, 155, 25, 23, 97, 25, 70, 193,
- /* 1720 */ 193, 59, 117, 236, 193, 193, 78, 193, 193, 81,
- /* 1730 */ 141, 193, 193, 71, 193, 100, 288, 287, 242, 255,
- /* 1740 */ 255, 106, 107, 108, 255, 255, 98, 243, 297, 114,
- /* 1750 */ 214, 116, 117, 118, 245, 191, 121, 271, 293, 267,
- /* 1760 */ 267, 246, 100, 246, 245, 271, 271, 293, 106, 107,
- /* 1770 */ 220, 271, 229, 225, 249, 219, 114, 259, 116, 117,
- /* 1780 */ 118, 133, 259, 121, 219, 219, 138, 139, 153, 154,
- /* 1790 */ 155, 156, 157, 280, 249, 243, 19, 20, 245, 22,
- /* 1800 */ 196, 259, 140, 259, 60, 297, 141, 297, 200, 200,
- /* 1810 */ 162, 38, 200, 36, 294, 153, 154, 155, 156, 157,
- /* 1820 */ 151, 150, 294, 283, 22, 43, 234, 18, 237, 200,
- /* 1830 */ 270, 272, 237, 237, 237, 18, 59, 199, 270, 149,
- /* 1840 */ 246, 272, 272, 200, 234, 234, 246, 246, 71, 246,
- /* 1850 */ 199, 158, 290, 62, 22, 200, 19, 20, 199, 22,
- /* 1860 */ 289, 221, 221, 200, 200, 199, 199, 115, 218, 64,
- /* 1870 */ 218, 218, 22, 36, 227, 126, 227, 100, 165, 221,
- /* 1880 */ 224, 224, 24, 106, 107, 312, 218, 305, 113, 282,
- /* 1890 */ 91, 114, 220, 116, 117, 118, 59, 282, 121, 218,
- /* 1900 */ 218, 218, 200, 317, 317, 82, 221, 265, 71, 148,
- /* 1910 */ 145, 265, 22, 277, 200, 158, 279, 140, 147, 25,
- /* 1920 */ 146, 202, 248, 250, 249, 247, 13, 250, 194, 194,
- /* 1930 */ 153, 154, 155, 156, 157, 6, 303, 100, 192, 192,
- /* 1940 */ 246, 213, 192, 106, 107, 207, 213, 207, 222, 213,
- /* 1950 */ 213, 114, 222, 116, 117, 118, 214, 214, 121, 4,
- /* 1960 */ 207, 213, 3, 22, 303, 15, 163, 16, 23, 23,
- /* 1970 */ 139, 151, 130, 25, 20, 142, 24, 16, 144, 1,
- /* 1980 */ 142, 130, 130, 61, 37, 53, 300, 151, 53, 53,
- /* 1990 */ 153, 154, 155, 156, 157, 53, 130, 116, 34, 1,
- /* 2000 */ 141, 5, 22, 115, 161, 68, 25, 68, 75, 41,
- /* 2010 */ 141, 115, 24, 20, 19, 131, 125, 23, 28, 22,
- /* 2020 */ 67, 22, 22, 22, 67, 59, 24, 96, 22, 67,
- /* 2030 */ 23, 149, 22, 25, 23, 23, 23, 22, 34, 141,
- /* 2040 */ 37, 97, 23, 23, 116, 22, 143, 25, 34, 75,
- /* 2050 */ 34, 34, 34, 88, 75, 34, 86, 23, 22, 34,
- /* 2060 */ 93, 24, 34, 25, 25, 142, 142, 23, 44, 23,
- /* 2070 */ 23, 23, 23, 11, 23, 25, 22, 22, 22, 141,
- /* 2080 */ 23, 23, 22, 22, 25, 15, 1, 23, 25, 1,
- /* 2090 */ 141, 135, 319, 319, 319, 319, 319, 319, 319, 141,
- /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2150 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2160 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2170 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2180 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319,
- /* 2280 */ 319, 319, 319, 319, 319,
+ /* 0 */ 276, 277, 278, 240, 241, 224, 194, 226, 194, 240,
+ /* 10 */ 241, 194, 216, 220, 194, 234, 253, 194, 255, 19,
+ /* 20 */ 224, 297, 253, 194, 255, 205, 212, 213, 205, 217,
+ /* 30 */ 218, 31, 205, 194, 217, 218, 194, 217, 218, 39,
+ /* 40 */ 217, 218, 312, 43, 44, 45, 316, 47, 48, 49,
+ /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19,
+ /* 60 */ 240, 241, 194, 240, 241, 194, 254, 240, 241, 276,
+ /* 70 */ 277, 278, 233, 253, 254, 255, 253, 254, 255, 217,
+ /* 80 */ 253, 239, 255, 43, 44, 45, 263, 47, 48, 49,
+ /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 270,
+ /* 100 */ 286, 22, 23, 103, 104, 105, 106, 107, 108, 109,
+ /* 110 */ 110, 111, 112, 113, 114, 82, 47, 48, 49, 50,
+ /* 120 */ 186, 187, 188, 189, 190, 191, 189, 87, 191, 89,
+ /* 130 */ 196, 19, 198, 196, 317, 198, 319, 25, 194, 205,
+ /* 140 */ 298, 270, 205, 103, 104, 105, 106, 107, 108, 109,
+ /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 11, 47,
+ /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ /* 170 */ 58, 60, 139, 140, 240, 241, 214, 240, 241, 311,
+ /* 180 */ 312, 102, 70, 239, 316, 194, 19, 253, 77, 255,
+ /* 190 */ 253, 122, 255, 55, 56, 57, 58, 59, 207, 88,
+ /* 200 */ 194, 90, 268, 194, 93, 268, 107, 108, 109, 110,
+ /* 210 */ 111, 112, 113, 114, 47, 103, 104, 105, 106, 107,
+ /* 220 */ 108, 109, 110, 111, 112, 113, 114, 114, 117, 118,
+ /* 230 */ 119, 276, 277, 278, 300, 19, 194, 300, 276, 277,
+ /* 240 */ 278, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ /* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 194, 43,
+ /* 260 */ 44, 45, 47, 47, 48, 49, 50, 51, 52, 53,
+ /* 270 */ 54, 55, 56, 57, 58, 82, 129, 130, 60, 129,
+ /* 280 */ 130, 217, 218, 116, 68, 25, 103, 104, 105, 106,
+ /* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 23, 132,
+ /* 300 */ 294, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ /* 310 */ 112, 113, 114, 217, 121, 306, 194, 308, 26, 103,
+ /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
+ /* 330 */ 114, 116, 139, 140, 217, 117, 118, 119, 120, 19,
+ /* 340 */ 194, 123, 124, 125, 24, 109, 110, 111, 112, 113,
+ /* 350 */ 114, 133, 60, 311, 312, 250, 194, 252, 316, 19,
+ /* 360 */ 194, 166, 167, 43, 44, 45, 205, 47, 48, 49,
+ /* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 217,
+ /* 380 */ 218, 317, 318, 43, 44, 45, 264, 47, 48, 49,
+ /* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 139,
+ /* 400 */ 140, 240, 241, 139, 140, 188, 189, 190, 191, 117,
+ /* 410 */ 118, 119, 231, 196, 253, 198, 255, 194, 194, 258,
+ /* 420 */ 259, 146, 205, 103, 104, 105, 106, 107, 108, 109,
+ /* 430 */ 110, 111, 112, 113, 114, 109, 212, 213, 236, 237,
+ /* 440 */ 217, 218, 194, 103, 104, 105, 106, 107, 108, 109,
+ /* 450 */ 110, 111, 112, 113, 114, 194, 120, 240, 241, 123,
+ /* 460 */ 124, 125, 136, 194, 19, 74, 60, 141, 23, 133,
+ /* 470 */ 253, 194, 255, 82, 194, 309, 310, 254, 29, 317,
+ /* 480 */ 318, 194, 33, 22, 199, 268, 263, 239, 43, 44,
+ /* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54,
+ /* 500 */ 55, 56, 57, 58, 217, 218, 194, 60, 19, 146,
+ /* 510 */ 286, 242, 23, 107, 108, 66, 204, 300, 206, 128,
+ /* 520 */ 73, 60, 116, 117, 118, 119, 265, 121, 165, 60,
+ /* 530 */ 139, 140, 43, 44, 45, 129, 47, 48, 49, 50,
+ /* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104,
+ /* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ /* 560 */ 154, 194, 156, 194, 117, 118, 119, 280, 283, 205,
+ /* 570 */ 101, 220, 287, 19, 20, 306, 22, 308, 117, 118,
+ /* 580 */ 119, 211, 212, 213, 217, 218, 117, 118, 236, 237,
+ /* 590 */ 36, 122, 103, 104, 105, 106, 107, 108, 109, 110,
+ /* 600 */ 111, 112, 113, 114, 240, 241, 194, 60, 194, 194,
+ /* 610 */ 194, 194, 19, 194, 60, 194, 23, 253, 206, 255,
+ /* 620 */ 73, 254, 19, 154, 155, 156, 72, 276, 277, 278,
+ /* 630 */ 263, 217, 218, 217, 218, 271, 43, 44, 45, 271,
+ /* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 650 */ 57, 58, 183, 194, 285, 101, 19, 214, 60, 242,
+ /* 660 */ 23, 107, 108, 109, 117, 118, 119, 16, 254, 115,
+ /* 670 */ 254, 117, 118, 119, 194, 60, 122, 263, 205, 264,
+ /* 680 */ 43, 44, 45, 264, 47, 48, 49, 50, 51, 52,
+ /* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106,
+ /* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155,
+ /* 710 */ 156, 157, 158, 240, 241, 117, 118, 119, 101, 205,
+ /* 720 */ 117, 19, 20, 306, 22, 308, 253, 74, 255, 78,
+ /* 730 */ 205, 80, 117, 118, 119, 118, 293, 183, 36, 122,
+ /* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ /* 750 */ 113, 114, 194, 294, 240, 241, 211, 212, 213, 144,
+ /* 760 */ 19, 23, 60, 25, 23, 240, 241, 253, 245, 255,
+ /* 770 */ 15, 154, 155, 156, 72, 217, 218, 194, 253, 256,
+ /* 780 */ 255, 128, 129, 130, 43, 44, 45, 22, 47, 48,
+ /* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ /* 800 */ 183, 19, 77, 101, 19, 128, 129, 130, 23, 107,
+ /* 810 */ 108, 60, 254, 88, 21, 90, 61, 115, 93, 117,
+ /* 820 */ 118, 119, 239, 22, 122, 60, 194, 205, 43, 44,
+ /* 830 */ 45, 205, 47, 48, 49, 50, 51, 52, 53, 54,
+ /* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108,
+ /* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157,
+ /* 860 */ 158, 60, 240, 241, 60, 116, 240, 241, 117, 118,
+ /* 870 */ 119, 146, 194, 19, 81, 253, 275, 255, 24, 253,
+ /* 880 */ 98, 255, 117, 118, 119, 183, 22, 194, 103, 104,
+ /* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ /* 900 */ 151, 194, 270, 152, 22, 23, 194, 25, 19, 202,
+ /* 910 */ 217, 218, 23, 109, 207, 314, 315, 124, 117, 118,
+ /* 920 */ 119, 117, 118, 119, 60, 232, 22, 23, 19, 25,
+ /* 930 */ 303, 304, 43, 44, 45, 22, 47, 48, 49, 50,
+ /* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 270, 227,
+ /* 950 */ 96, 60, 43, 44, 45, 162, 47, 48, 49, 50,
+ /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 112,
+ /* 970 */ 113, 114, 194, 60, 120, 121, 122, 123, 124, 125,
+ /* 980 */ 126, 117, 118, 119, 102, 25, 132, 107, 108, 194,
+ /* 990 */ 194, 227, 103, 104, 105, 106, 107, 108, 109, 110,
+ /* 1000 */ 111, 112, 113, 114, 194, 194, 102, 194, 117, 118,
+ /* 1010 */ 119, 233, 103, 104, 105, 106, 107, 108, 109, 110,
+ /* 1020 */ 111, 112, 113, 114, 194, 194, 19, 194, 217, 218,
+ /* 1030 */ 117, 118, 119, 241, 154, 144, 156, 135, 242, 137,
+ /* 1040 */ 138, 130, 19, 232, 194, 253, 23, 255, 217, 218,
+ /* 1050 */ 217, 218, 242, 16, 7, 8, 9, 25, 261, 262,
+ /* 1060 */ 265, 194, 19, 232, 153, 232, 43, 44, 45, 160,
+ /* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 1080 */ 57, 58, 194, 227, 217, 218, 43, 44, 45, 194,
+ /* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 1100 */ 57, 58, 306, 143, 308, 217, 218, 294, 12, 77,
+ /* 1110 */ 22, 23, 217, 218, 194, 78, 306, 80, 308, 194,
+ /* 1120 */ 232, 254, 90, 27, 117, 93, 103, 104, 105, 106,
+ /* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 194,
+ /* 1140 */ 35, 194, 217, 218, 214, 194, 103, 104, 105, 106,
+ /* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 194, 239,
+ /* 1160 */ 64, 194, 217, 218, 217, 218, 209, 210, 217, 218,
+ /* 1170 */ 74, 207, 67, 22, 194, 77, 19, 232, 245, 232,
+ /* 1180 */ 75, 24, 312, 232, 217, 218, 316, 25, 90, 256,
+ /* 1190 */ 102, 93, 159, 229, 161, 231, 19, 217, 218, 162,
+ /* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52,
+ /* 1210 */ 53, 54, 55, 56, 57, 58, 19, 23, 288, 25,
+ /* 1220 */ 43, 44, 45, 293, 47, 48, 49, 50, 51, 52,
+ /* 1230 */ 53, 54, 55, 56, 57, 58, 131, 22, 275, 24,
+ /* 1240 */ 43, 44, 45, 194, 47, 48, 49, 50, 51, 52,
+ /* 1250 */ 53, 54, 55, 56, 57, 58, 194, 194, 107, 108,
+ /* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ /* 1270 */ 113, 114, 194, 25, 194, 60, 194, 314, 315, 194,
+ /* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ /* 1290 */ 113, 114, 19, 194, 194, 217, 218, 217, 218, 25,
+ /* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ /* 1310 */ 113, 114, 150, 119, 265, 312, 67, 217, 218, 316,
+ /* 1320 */ 19, 239, 194, 194, 128, 129, 130, 265, 265, 209,
+ /* 1330 */ 210, 31, 254, 118, 254, 86, 60, 194, 144, 39,
+ /* 1340 */ 19, 130, 275, 312, 95, 44, 45, 316, 47, 48,
+ /* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ /* 1360 */ 217, 218, 24, 194, 153, 12, 45, 119, 47, 48,
+ /* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
+ /* 1380 */ 27, 314, 315, 22, 312, 24, 217, 218, 316, 116,
+ /* 1390 */ 117, 22, 144, 25, 118, 42, 147, 194, 60, 19,
+ /* 1400 */ 20, 127, 22, 194, 103, 104, 105, 106, 107, 108,
+ /* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 194,
+ /* 1420 */ 217, 218, 194, 54, 103, 104, 105, 106, 107, 108,
+ /* 1430 */ 109, 110, 111, 112, 113, 114, 194, 22, 310, 25,
+ /* 1440 */ 60, 194, 217, 218, 194, 217, 218, 194, 260, 194,
+ /* 1450 */ 301, 302, 72, 262, 262, 194, 118, 266, 266, 217,
+ /* 1460 */ 218, 194, 82, 245, 217, 218, 194, 217, 218, 194,
+ /* 1470 */ 217, 218, 217, 218, 256, 60, 24, 194, 217, 218,
+ /* 1480 */ 194, 101, 194, 245, 217, 218, 194, 107, 108, 217,
+ /* 1490 */ 218, 22, 217, 218, 256, 115, 245, 117, 118, 119,
+ /* 1500 */ 217, 218, 122, 217, 218, 217, 218, 256, 22, 217,
+ /* 1510 */ 218, 116, 258, 259, 146, 19, 20, 194, 22, 139,
+ /* 1520 */ 140, 150, 151, 136, 23, 194, 25, 194, 141, 194,
+ /* 1530 */ 194, 62, 36, 118, 154, 155, 156, 157, 158, 100,
+ /* 1540 */ 145, 194, 154, 194, 156, 49, 194, 23, 194, 25,
+ /* 1550 */ 217, 218, 217, 218, 194, 257, 60, 143, 194, 60,
+ /* 1560 */ 194, 121, 122, 183, 217, 218, 217, 218, 72, 217,
+ /* 1570 */ 218, 217, 218, 134, 23, 194, 25, 217, 218, 7,
+ /* 1580 */ 8, 321, 86, 217, 218, 194, 122, 91, 19, 20,
+ /* 1590 */ 23, 22, 25, 23, 142, 25, 132, 101, 217, 218,
+ /* 1600 */ 194, 194, 194, 107, 108, 36, 194, 194, 217, 218,
+ /* 1610 */ 194, 115, 194, 117, 118, 119, 194, 118, 122, 194,
+ /* 1620 */ 23, 194, 25, 217, 218, 217, 218, 194, 142, 60,
+ /* 1630 */ 217, 218, 194, 217, 218, 217, 218, 84, 85, 217,
+ /* 1640 */ 218, 72, 217, 218, 217, 218, 60, 23, 60, 25,
+ /* 1650 */ 154, 155, 156, 157, 158, 86, 154, 194, 156, 194,
+ /* 1660 */ 91, 19, 20, 23, 22, 25, 194, 23, 194, 25,
+ /* 1670 */ 101, 23, 194, 25, 194, 194, 107, 108, 36, 183,
+ /* 1680 */ 217, 218, 217, 218, 115, 194, 117, 118, 119, 217,
+ /* 1690 */ 218, 122, 194, 237, 194, 217, 218, 217, 218, 194,
+ /* 1700 */ 194, 23, 60, 25, 118, 23, 118, 25, 217, 218,
+ /* 1710 */ 23, 194, 25, 194, 72, 217, 218, 217, 218, 23,
+ /* 1720 */ 194, 25, 194, 154, 155, 156, 157, 158, 86, 23,
+ /* 1730 */ 194, 25, 194, 91, 217, 218, 217, 218, 194, 194,
+ /* 1740 */ 194, 194, 194, 101, 194, 217, 218, 290, 194, 107,
+ /* 1750 */ 108, 194, 183, 217, 218, 194, 194, 115, 194, 117,
+ /* 1760 */ 118, 119, 194, 243, 122, 194, 289, 194, 194, 194,
+ /* 1770 */ 194, 257, 257, 257, 244, 257, 192, 273, 215, 269,
+ /* 1780 */ 246, 299, 269, 295, 247, 273, 247, 246, 295, 230,
+ /* 1790 */ 261, 226, 261, 261, 273, 273, 154, 155, 156, 157,
+ /* 1800 */ 158, 0, 1, 2, 221, 220, 5, 220, 250, 220,
+ /* 1810 */ 261, 10, 11, 12, 13, 14, 250, 282, 17, 197,
+ /* 1820 */ 61, 19, 20, 246, 22, 183, 244, 142, 201, 201,
+ /* 1830 */ 38, 30, 299, 32, 201, 152, 22, 151, 36, 299,
+ /* 1840 */ 43, 40, 235, 18, 238, 285, 238, 238, 296, 238,
+ /* 1850 */ 201, 296, 274, 272, 18, 200, 235, 150, 235, 247,
+ /* 1860 */ 247, 247, 60, 247, 274, 274, 272, 201, 200, 159,
+ /* 1870 */ 63, 292, 71, 201, 72, 200, 22, 201, 222, 200,
+ /* 1880 */ 79, 201, 222, 82, 291, 116, 219, 65, 200, 219,
+ /* 1890 */ 219, 228, 22, 127, 225, 166, 222, 24, 225, 114,
+ /* 1900 */ 99, 284, 221, 101, 284, 228, 307, 315, 219, 107,
+ /* 1910 */ 108, 219, 219, 219, 201, 92, 320, 115, 320, 117,
+ /* 1920 */ 118, 119, 222, 83, 122, 267, 267, 149, 146, 19,
+ /* 1930 */ 20, 22, 22, 279, 250, 134, 201, 148, 159, 249,
+ /* 1940 */ 139, 140, 251, 141, 25, 281, 36, 147, 251, 248,
+ /* 1950 */ 247, 203, 13, 195, 6, 195, 154, 155, 156, 157,
+ /* 1960 */ 158, 193, 305, 193, 163, 193, 305, 302, 214, 208,
+ /* 1970 */ 60, 214, 208, 223, 223, 4, 214, 214, 3, 22,
+ /* 1980 */ 215, 214, 72, 208, 164, 183, 215, 15, 23, 16,
+ /* 1990 */ 23, 140, 131, 152, 25, 143, 20, 16, 24, 1,
+ /* 2000 */ 145, 143, 131, 131, 62, 37, 54, 54, 152, 54,
+ /* 2010 */ 54, 101, 131, 117, 34, 1, 142, 107, 108, 22,
+ /* 2020 */ 5, 116, 162, 69, 25, 115, 76, 117, 118, 119,
+ /* 2030 */ 1, 2, 122, 69, 5, 41, 142, 116, 20, 10,
+ /* 2040 */ 11, 12, 13, 14, 24, 19, 17, 132, 5, 126,
+ /* 2050 */ 22, 141, 68, 10, 11, 12, 13, 14, 22, 30,
+ /* 2060 */ 17, 32, 22, 22, 154, 155, 156, 157, 158, 40,
+ /* 2070 */ 23, 68, 60, 30, 24, 32, 97, 28, 22, 68,
+ /* 2080 */ 23, 37, 34, 40, 150, 22, 25, 23, 23, 23,
+ /* 2090 */ 22, 98, 23, 183, 23, 117, 34, 22, 25, 89,
+ /* 2100 */ 71, 142, 144, 76, 34, 23, 34, 76, 79, 87,
+ /* 2110 */ 34, 82, 34, 94, 71, 34, 22, 24, 44, 34,
+ /* 2120 */ 25, 25, 79, 23, 23, 82, 143, 23, 99, 143,
+ /* 2130 */ 23, 22, 11, 25, 23, 25, 22, 22, 22, 1,
+ /* 2140 */ 23, 23, 99, 136, 22, 22, 142, 142, 142, 25,
+ /* 2150 */ 25, 23, 15, 1, 322, 322, 322, 322, 322, 322,
+ /* 2160 */ 322, 322, 322, 134, 322, 322, 322, 322, 139, 140,
+ /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 134, 322, 322,
+ /* 2180 */ 322, 322, 139, 140, 322, 322, 322, 322, 322, 322,
+ /* 2190 */ 322, 322, 163, 322, 322, 322, 322, 322, 322, 322,
+ /* 2200 */ 322, 322, 322, 322, 322, 322, 163, 322, 322, 322,
+ /* 2210 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2220 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2230 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2240 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2250 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2260 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2270 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2280 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2290 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2300 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2310 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2330 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322,
+ /* 2340 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
+ /* 2350 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
+ /* 2360 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
+ /* 2370 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
+ /* 2380 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
+ /* 2390 */ 186, 186, 186,
};
-#define YY_SHIFT_COUNT (578)
+#define YY_SHIFT_COUNT (582)
#define YY_SHIFT_MIN (0)
-#define YY_SHIFT_MAX (2088)
+#define YY_SHIFT_MAX (2152)
static const unsigned short int yy_shift_ofst[] = {
- /* 0 */ 1648, 1477, 1272, 322, 322, 1, 1319, 1478, 1491, 1837,
- /* 10 */ 1837, 1837, 471, 0, 0, 214, 1093, 1837, 1837, 1837,
- /* 20 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /* 30 */ 1837, 271, 271, 1219, 1219, 216, 88, 1, 1, 1,
- /* 40 */ 1, 1, 40, 111, 258, 361, 469, 512, 583, 622,
- /* 50 */ 693, 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093,
- /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
- /* 70 */ 1093, 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635,
- /* 80 */ 1662, 1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /* 90 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /* 100 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /* 110 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /* 120 */ 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /* 130 */ 1837, 137, 181, 181, 181, 181, 181, 181, 181, 94,
- /* 140 */ 430, 66, 65, 112, 366, 533, 533, 740, 1257, 533,
- /* 150 */ 533, 79, 79, 533, 412, 412, 412, 77, 412, 123,
- /* 160 */ 113, 113, 113, 22, 22, 2100, 2100, 328, 328, 328,
- /* 170 */ 239, 468, 468, 468, 468, 1015, 1015, 409, 366, 1187,
- /* 180 */ 1232, 533, 533, 533, 533, 533, 533, 533, 533, 533,
- /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533,
- /* 200 */ 533, 969, 621, 621, 533, 642, 788, 788, 1133, 1133,
- /* 210 */ 822, 822, 67, 1193, 2100, 2100, 2100, 2100, 2100, 2100,
- /* 220 */ 2100, 1307, 954, 954, 585, 472, 640, 387, 695, 538,
- /* 230 */ 541, 700, 533, 533, 533, 533, 533, 533, 533, 533,
- /* 240 */ 533, 533, 222, 533, 533, 533, 533, 533, 533, 533,
- /* 250 */ 533, 533, 533, 533, 533, 1213, 1213, 1213, 533, 533,
- /* 260 */ 533, 565, 533, 533, 533, 916, 1147, 533, 533, 1288,
- /* 270 */ 533, 533, 533, 533, 533, 533, 533, 533, 639, 1280,
- /* 280 */ 209, 1129, 1129, 1129, 1129, 580, 209, 209, 1209, 768,
- /* 290 */ 917, 649, 1315, 1334, 405, 1334, 1383, 249, 1315, 1315,
- /* 300 */ 249, 1315, 405, 1383, 1441, 464, 1245, 1417, 1417, 1417,
- /* 310 */ 1323, 1323, 1323, 1323, 184, 184, 1335, 1476, 856, 1482,
- /* 320 */ 1744, 1744, 1665, 1665, 1773, 1773, 1665, 1669, 1671, 1802,
- /* 330 */ 1782, 1809, 1809, 1809, 1809, 1665, 1817, 1690, 1671, 1671,
- /* 340 */ 1690, 1802, 1782, 1690, 1782, 1690, 1665, 1817, 1693, 1791,
- /* 350 */ 1665, 1817, 1832, 1665, 1817, 1665, 1817, 1832, 1752, 1752,
- /* 360 */ 1752, 1805, 1850, 1850, 1832, 1752, 1749, 1752, 1805, 1752,
- /* 370 */ 1752, 1713, 1858, 1775, 1775, 1832, 1665, 1799, 1799, 1823,
- /* 380 */ 1823, 1761, 1765, 1890, 1665, 1757, 1761, 1771, 1774, 1690,
- /* 390 */ 1894, 1913, 1913, 1929, 1929, 1929, 2100, 2100, 2100, 2100,
- /* 400 */ 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100,
- /* 410 */ 2100, 207, 1220, 331, 620, 967, 806, 1074, 1499, 1432,
- /* 420 */ 1463, 1479, 1419, 1422, 1557, 1512, 1598, 1599, 1644, 1645,
- /* 430 */ 1654, 1660, 1555, 1505, 1684, 1462, 1670, 1563, 1619, 1593,
- /* 440 */ 1676, 1679, 1613, 1680, 1554, 1558, 1689, 1692, 1605, 1589,
- /* 450 */ 1955, 1959, 1941, 1803, 1950, 1951, 1945, 1946, 1831, 1820,
- /* 460 */ 1842, 1948, 1948, 1952, 1833, 1954, 1834, 1961, 1978, 1838,
- /* 470 */ 1851, 1948, 1852, 1922, 1947, 1948, 1836, 1932, 1935, 1936,
- /* 480 */ 1942, 1866, 1881, 1964, 1859, 1998, 1996, 1980, 1888, 1843,
- /* 490 */ 1937, 1981, 1939, 1933, 1968, 1869, 1896, 1988, 1993, 1995,
- /* 500 */ 1884, 1891, 1997, 1953, 1999, 2000, 1994, 2001, 1957, 1966,
- /* 510 */ 2002, 1931, 1990, 2006, 1962, 2003, 2007, 2004, 1882, 2010,
- /* 520 */ 2011, 2012, 2008, 2013, 2015, 1944, 1898, 2019, 2020, 1928,
- /* 530 */ 2014, 2023, 1903, 2022, 2016, 2017, 2018, 2021, 1965, 1974,
- /* 540 */ 1970, 2024, 1979, 1967, 2025, 2034, 2036, 2037, 2038, 2039,
- /* 550 */ 2028, 1923, 1924, 2044, 2022, 2046, 2047, 2048, 2049, 2050,
- /* 560 */ 2051, 2054, 2062, 2055, 2056, 2057, 2058, 2060, 2061, 2059,
- /* 570 */ 1956, 1938, 1949, 1958, 2063, 2064, 2070, 2085, 2088,
+ /* 0 */ 2029, 1801, 2043, 1380, 1380, 33, 391, 1496, 1569, 1642,
+ /* 10 */ 702, 702, 702, 193, 33, 33, 33, 33, 33, 0,
+ /* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702,
+ /* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 406, 406,
+ /* 40 */ 111, 111, 218, 447, 547, 598, 598, 260, 260, 260,
+ /* 50 */ 260, 40, 112, 320, 340, 445, 489, 593, 637, 741,
+ /* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177,
+ /* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
+ /* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554,
+ /* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702,
+ /* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702,
+ /* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702,
+ /* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702,
+ /* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702,
+ /* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198,
+ /* 150 */ 183, 99, 236, 292, 598, 793, 167, 598, 598, 880,
+ /* 160 */ 880, 598, 857, 150, 195, 195, 195, 264, 113, 113,
+ /* 170 */ 2207, 2207, 854, 854, 854, 751, 765, 765, 765, 765,
+ /* 180 */ 1096, 1096, 725, 292, 882, 904, 598, 598, 598, 598,
+ /* 190 */ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ /* 200 */ 598, 598, 598, 598, 598, 1273, 1032, 1032, 598, 147,
+ /* 210 */ 1098, 1098, 603, 603, 1276, 1276, 363, 2207, 2207, 2207,
+ /* 220 */ 2207, 2207, 2207, 2207, 469, 617, 617, 801, 336, 461,
+ /* 230 */ 804, 864, 615, 891, 913, 598, 598, 598, 598, 598,
+ /* 240 */ 598, 598, 598, 598, 598, 653, 598, 598, 598, 598,
+ /* 250 */ 598, 598, 598, 598, 598, 598, 598, 598, 1105, 1105,
+ /* 260 */ 1105, 598, 598, 598, 1194, 598, 598, 598, 1215, 1249,
+ /* 270 */ 598, 1353, 598, 598, 598, 598, 598, 598, 598, 598,
+ /* 280 */ 677, 449, 902, 1338, 1338, 1338, 1338, 1248, 902, 902,
+ /* 290 */ 326, 1151, 1047, 755, 749, 1371, 960, 1371, 1007, 1162,
+ /* 300 */ 749, 749, 1162, 749, 960, 1007, 1274, 738, 215, 1300,
+ /* 310 */ 1300, 1300, 1395, 1395, 1395, 1395, 1368, 1368, 1033, 1414,
+ /* 320 */ 1387, 1361, 1759, 1759, 1685, 1685, 1792, 1792, 1685, 1683,
+ /* 330 */ 1686, 1814, 1797, 1825, 1825, 1825, 1825, 1685, 1836, 1707,
+ /* 340 */ 1686, 1686, 1707, 1814, 1797, 1707, 1797, 1707, 1685, 1836,
+ /* 350 */ 1710, 1807, 1685, 1836, 1854, 1685, 1836, 1685, 1836, 1854,
+ /* 360 */ 1769, 1769, 1769, 1822, 1870, 1870, 1854, 1769, 1766, 1769,
+ /* 370 */ 1822, 1769, 1769, 1729, 1873, 1785, 1785, 1854, 1685, 1823,
+ /* 380 */ 1823, 1840, 1840, 1778, 1782, 1909, 1685, 1779, 1778, 1789,
+ /* 390 */ 1800, 1707, 1919, 1939, 1939, 1948, 1948, 1948, 2207, 2207,
+ /* 400 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207,
+ /* 410 */ 2207, 2207, 2207, 69, 1037, 79, 1088, 651, 1196, 1415,
+ /* 420 */ 1501, 1439, 1369, 1452, 911, 1211, 1524, 1469, 1551, 1567,
+ /* 430 */ 1570, 1624, 1640, 1644, 1499, 1440, 1572, 1464, 1597, 275,
+ /* 440 */ 782, 1586, 1648, 1678, 1553, 1682, 1687, 1388, 1502, 1696,
+ /* 450 */ 1706, 1588, 1486, 1971, 1975, 1957, 1820, 1972, 1973, 1965,
+ /* 460 */ 1967, 1851, 1841, 1861, 1969, 1969, 1974, 1852, 1976, 1855,
+ /* 470 */ 1981, 1998, 1858, 1871, 1969, 1872, 1942, 1968, 1969, 1856,
+ /* 480 */ 1952, 1953, 1955, 1956, 1881, 1896, 1980, 1874, 2014, 2015,
+ /* 490 */ 1997, 1905, 1860, 1954, 1999, 1964, 1950, 1994, 1894, 1921,
+ /* 500 */ 2020, 2018, 2026, 1915, 1923, 2028, 1984, 2036, 2040, 2047,
+ /* 510 */ 2041, 2003, 2012, 2050, 1979, 2049, 2056, 2011, 2044, 2057,
+ /* 520 */ 2048, 1934, 2063, 2064, 2065, 2061, 2066, 2068, 1993, 1959,
+ /* 530 */ 2069, 2071, 1978, 2062, 2075, 1958, 2073, 2070, 2072, 2076,
+ /* 540 */ 2078, 2010, 2027, 2022, 2074, 2031, 2019, 2081, 2082, 2094,
+ /* 550 */ 2093, 2095, 2096, 2085, 1983, 1986, 2100, 2073, 2101, 2104,
+ /* 560 */ 2107, 2109, 2108, 2110, 2111, 2114, 2121, 2115, 2116, 2117,
+ /* 570 */ 2118, 2122, 2123, 2124, 2007, 2004, 2005, 2006, 2125, 2128,
+ /* 580 */ 2137, 2138, 2152,
};
-#define YY_REDUCE_COUNT (410)
-#define YY_REDUCE_MIN (-271)
-#define YY_REDUCE_MAX (1753)
+#define YY_REDUCE_COUNT (412)
+#define YY_REDUCE_MIN (-276)
+#define YY_REDUCE_MAX (1775)
static const short yy_reduce_ofst[] = {
- /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187,
- /* 10 */ 166, 238, 133, -207, -199, -267, -176, -6, 204, 489,
- /* 20 */ 576, 598, -175, 686, 860, 615, 725, 1014, 778, 781,
- /* 30 */ 857, 616, 887, 87, 240, -192, 408, 626, 796, 843,
- /* 40 */ 854, 1004, -271, -271, -271, -271, -271, -271, -271, -271,
- /* 50 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
- /* 60 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
- /* 70 */ -271, -271, -271, -271, -271, -271, -271, -271, -271, 80,
- /* 80 */ 83, 313, 886, 888, 918, 938, 1021, 1034, 1036, 1141,
- /* 90 */ 1159, 1163, 1166, 1168, 1170, 1176, 1178, 1180, 1184, 1196,
- /* 100 */ 1198, 1205, 1215, 1225, 1227, 1236, 1252, 1254, 1264, 1303,
- /* 110 */ 1309, 1312, 1322, 1325, 1328, 1337, 1340, 1343, 1353, 1371,
- /* 120 */ 1373, 1384, 1386, 1411, 1413, 1420, 1424, 1426, 1458, 1470,
- /* 130 */ 1473, -271, -271, -271, -271, -271, -271, -271, -271, -271,
- /* 140 */ -271, -271, 138, 459, 396, -158, 470, 302, -212, 521,
- /* 150 */ 201, -195, -92, 559, 630, 632, 630, -271, 632, 901,
- /* 160 */ 63, 407, 670, -271, -271, -271, -271, 161, 161, 161,
- /* 170 */ 251, 335, 847, 979, 1097, 537, 588, 618, 628, 688,
- /* 180 */ 688, -166, -161, 674, 787, 794, 799, 852, 996, -122,
- /* 190 */ 837, -120, 1018, 1035, 415, 1047, 1001, 958, 1082, 400,
- /* 200 */ 1099, 779, 1137, 1142, 263, 1083, 1145, 1150, 1041, 1139,
- /* 210 */ 965, 1050, 362, 849, 752, 629, 675, 1162, 1173, 1090,
- /* 220 */ 1195, -194, 56, 185, -135, 232, 522, 560, 571, 601,
- /* 230 */ 617, 669, 683, 711, 850, 893, 1000, 1040, 1049, 1081,
- /* 240 */ 1087, 1101, 392, 1114, 1123, 1155, 1161, 1175, 1271, 1293,
- /* 250 */ 1299, 1330, 1339, 1342, 1347, 593, 1282, 1286, 1350, 1359,
- /* 260 */ 1368, 1314, 1480, 1483, 1507, 1085, 1338, 1526, 1527, 1487,
- /* 270 */ 1531, 560, 1532, 1534, 1535, 1538, 1539, 1541, 1448, 1450,
- /* 280 */ 1496, 1484, 1485, 1489, 1490, 1314, 1496, 1496, 1504, 1536,
- /* 290 */ 1564, 1451, 1486, 1492, 1509, 1493, 1465, 1515, 1494, 1495,
- /* 300 */ 1517, 1500, 1519, 1474, 1550, 1543, 1548, 1556, 1565, 1566,
- /* 310 */ 1518, 1523, 1542, 1544, 1525, 1545, 1513, 1553, 1552, 1604,
- /* 320 */ 1508, 1510, 1608, 1609, 1520, 1528, 1612, 1540, 1559, 1560,
- /* 330 */ 1592, 1591, 1595, 1596, 1597, 1629, 1638, 1594, 1569, 1570,
- /* 340 */ 1600, 1568, 1610, 1601, 1611, 1603, 1643, 1651, 1562, 1571,
- /* 350 */ 1655, 1659, 1640, 1663, 1666, 1664, 1667, 1641, 1650, 1652,
- /* 360 */ 1653, 1647, 1656, 1657, 1658, 1668, 1672, 1681, 1649, 1682,
- /* 370 */ 1683, 1573, 1582, 1607, 1615, 1685, 1702, 1586, 1587, 1642,
- /* 380 */ 1646, 1673, 1675, 1636, 1714, 1637, 1677, 1674, 1678, 1694,
- /* 390 */ 1719, 1734, 1735, 1746, 1747, 1750, 1633, 1661, 1686, 1738,
- /* 400 */ 1728, 1733, 1736, 1737, 1740, 1726, 1730, 1742, 1743, 1748,
- /* 410 */ 1753,
+ /* 0 */ -66, 217, -63, -177, -180, 161, 364, 64, -183, 162,
+ /* 10 */ 223, 367, 414, -173, 473, 514, 525, 622, 626, -207,
+ /* 20 */ 351, -276, -38, 693, 811, 831, 833, 888, -188, 945,
+ /* 30 */ 947, 416, 558, 951, 867, 287, 1078, 1080, -186, 224,
+ /* 40 */ -132, 42, 964, 269, 417, 796, 810, -237, -231, -237,
+ /* 50 */ -231, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ /* 60 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ /* 70 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45,
+ /* 80 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, 895,
+ /* 90 */ 925, 967, 980, 1100, 1143, 1169, 1203, 1225, 1228, 1242,
+ /* 100 */ 1247, 1250, 1253, 1255, 1261, 1267, 1272, 1275, 1283, 1286,
+ /* 110 */ 1288, 1292, 1333, 1335, 1347, 1349, 1352, 1354, 1360, 1366,
+ /* 120 */ 1381, 1391, 1406, 1408, 1413, 1416, 1418, 1422, 1425, 1427,
+ /* 130 */ 1463, 1465, 1472, 1478, 1480, 1491, 1498, 1500, 1517, 1519,
+ /* 140 */ 1528, 1536, -45, -45, -45, -45, -45, -45, -45, -45,
+ /* 150 */ -45, -45, -45, 312, -158, 285, -219, 9, 166, 370,
+ /* 160 */ 545, 707, -45, 930, 601, 963, 1067, 792, -45, -45,
+ /* 170 */ -45, -45, -204, -204, -204, 369, -171, -129, 632, 678,
+ /* 180 */ 202, 352, -270, 412, 627, 627, -9, 122, 415, 419,
+ /* 190 */ -56, 248, 583, 920, 6, 261, 459, 795, 1049, 813,
+ /* 200 */ 1062, 1082, -161, 778, 1063, 797, 870, 1003, 1128, 443,
+ /* 210 */ 1031, 1072, 1191, 1192, 957, 1120, 105, 1149, 523, 933,
+ /* 220 */ 1218, 1238, 1254, 1251, -138, 96, 117, 146, 181, 277,
+ /* 230 */ 280, 421, 480, 712, 830, 850, 1085, 1099, 1129, 1209,
+ /* 240 */ 1323, 1331, 1336, 1364, 1407, 368, 1412, 1433, 1438, 1474,
+ /* 250 */ 1481, 1505, 1506, 1526, 1538, 1544, 1545, 1546, 722, 764,
+ /* 260 */ 856, 1547, 1548, 1550, 1188, 1554, 1557, 1561, 1298, 1260,
+ /* 270 */ 1562, 1456, 1564, 280, 1568, 1571, 1573, 1574, 1575, 1576,
+ /* 280 */ 1457, 1477, 1520, 1514, 1515, 1516, 1518, 1188, 1520, 1520,
+ /* 290 */ 1530, 1563, 1584, 1482, 1504, 1510, 1534, 1513, 1488, 1537,
+ /* 300 */ 1512, 1521, 1539, 1522, 1541, 1493, 1583, 1559, 1565, 1585,
+ /* 310 */ 1587, 1589, 1529, 1531, 1532, 1549, 1558, 1566, 1535, 1577,
+ /* 320 */ 1582, 1622, 1533, 1540, 1627, 1628, 1552, 1555, 1633, 1560,
+ /* 330 */ 1578, 1581, 1607, 1606, 1608, 1609, 1611, 1649, 1655, 1612,
+ /* 340 */ 1590, 1591, 1613, 1594, 1621, 1614, 1623, 1616, 1666, 1668,
+ /* 350 */ 1579, 1593, 1672, 1675, 1656, 1676, 1679, 1680, 1688, 1660,
+ /* 360 */ 1667, 1670, 1671, 1663, 1669, 1673, 1674, 1689, 1681, 1692,
+ /* 370 */ 1677, 1693, 1694, 1592, 1599, 1617, 1620, 1700, 1713, 1596,
+ /* 380 */ 1598, 1658, 1659, 1691, 1684, 1654, 1735, 1664, 1697, 1690,
+ /* 390 */ 1701, 1703, 1748, 1758, 1760, 1768, 1770, 1772, 1657, 1661,
+ /* 400 */ 1665, 1761, 1754, 1757, 1762, 1763, 1764, 1750, 1751, 1765,
+ /* 410 */ 1771, 1767, 1775,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1648, 1648, 1648, 1478, 1243, 1354, 1243, 1243, 1243, 1478,
- /* 10 */ 1478, 1478, 1243, 1384, 1384, 1531, 1276, 1243, 1243, 1243,
- /* 20 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1477, 1243,
- /* 30 */ 1243, 1243, 1243, 1564, 1564, 1243, 1243, 1243, 1243, 1243,
- /* 40 */ 1243, 1243, 1243, 1393, 1243, 1400, 1243, 1243, 1243, 1243,
- /* 50 */ 1243, 1479, 1480, 1243, 1243, 1243, 1530, 1532, 1495, 1407,
- /* 60 */ 1406, 1405, 1404, 1513, 1372, 1398, 1391, 1395, 1474, 1475,
- /* 70 */ 1473, 1626, 1480, 1479, 1243, 1394, 1442, 1458, 1441, 1243,
- /* 80 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 90 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 100 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 110 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 120 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 130 */ 1243, 1450, 1457, 1456, 1455, 1464, 1454, 1451, 1444, 1443,
- /* 140 */ 1445, 1446, 1243, 1243, 1267, 1243, 1243, 1264, 1318, 1243,
- /* 150 */ 1243, 1243, 1243, 1243, 1550, 1549, 1243, 1447, 1243, 1276,
- /* 160 */ 1435, 1434, 1433, 1461, 1448, 1460, 1459, 1538, 1600, 1599,
- /* 170 */ 1496, 1243, 1243, 1243, 1243, 1243, 1243, 1564, 1243, 1243,
- /* 180 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 190 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 200 */ 1243, 1374, 1564, 1564, 1243, 1276, 1564, 1564, 1375, 1375,
- /* 210 */ 1272, 1272, 1378, 1243, 1545, 1345, 1345, 1345, 1345, 1354,
- /* 220 */ 1345, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 230 */ 1243, 1243, 1243, 1243, 1243, 1243, 1535, 1533, 1243, 1243,
- /* 240 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 250 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 260 */ 1243, 1243, 1243, 1243, 1243, 1350, 1243, 1243, 1243, 1243,
- /* 270 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1593, 1243, 1508,
- /* 280 */ 1332, 1350, 1350, 1350, 1350, 1352, 1333, 1331, 1344, 1277,
- /* 290 */ 1250, 1640, 1410, 1399, 1351, 1399, 1637, 1397, 1410, 1410,
- /* 300 */ 1397, 1410, 1351, 1637, 1293, 1615, 1288, 1384, 1384, 1384,
- /* 310 */ 1374, 1374, 1374, 1374, 1378, 1378, 1476, 1351, 1344, 1243,
- /* 320 */ 1640, 1640, 1360, 1360, 1639, 1639, 1360, 1496, 1623, 1419,
- /* 330 */ 1321, 1327, 1327, 1327, 1327, 1360, 1261, 1397, 1623, 1623,
- /* 340 */ 1397, 1419, 1321, 1397, 1321, 1397, 1360, 1261, 1512, 1634,
- /* 350 */ 1360, 1261, 1486, 1360, 1261, 1360, 1261, 1486, 1319, 1319,
- /* 360 */ 1319, 1308, 1243, 1243, 1486, 1319, 1293, 1319, 1308, 1319,
- /* 370 */ 1319, 1582, 1243, 1490, 1490, 1486, 1360, 1574, 1574, 1387,
- /* 380 */ 1387, 1392, 1378, 1481, 1360, 1243, 1392, 1390, 1388, 1397,
- /* 390 */ 1311, 1596, 1596, 1592, 1592, 1592, 1645, 1645, 1545, 1608,
- /* 400 */ 1276, 1276, 1276, 1276, 1608, 1295, 1295, 1277, 1277, 1276,
- /* 410 */ 1608, 1243, 1243, 1243, 1243, 1243, 1243, 1603, 1243, 1540,
- /* 420 */ 1497, 1364, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 430 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1551, 1243,
- /* 440 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1424,
- /* 450 */ 1243, 1246, 1542, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 460 */ 1243, 1401, 1402, 1365, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 470 */ 1243, 1416, 1243, 1243, 1243, 1411, 1243, 1243, 1243, 1243,
- /* 480 */ 1243, 1243, 1243, 1243, 1636, 1243, 1243, 1243, 1243, 1243,
- /* 490 */ 1243, 1511, 1510, 1243, 1243, 1362, 1243, 1243, 1243, 1243,
- /* 500 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1291,
- /* 510 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 520 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 530 */ 1243, 1243, 1243, 1389, 1243, 1243, 1243, 1243, 1243, 1243,
- /* 540 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1579, 1379,
- /* 550 */ 1243, 1243, 1243, 1243, 1627, 1243, 1243, 1243, 1243, 1243,
- /* 560 */ 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1619,
- /* 570 */ 1335, 1425, 1243, 1428, 1265, 1243, 1255, 1243, 1243,
+ /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254,
+ /* 10 */ 1491, 1491, 1491, 1254, 1254, 1254, 1254, 1254, 1254, 1397,
+ /* 20 */ 1397, 1544, 1287, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254,
+ /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254,
+ /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254,
+ /* 60 */ 1492, 1493, 1254, 1254, 1254, 1254, 1543, 1545, 1508, 1420,
+ /* 70 */ 1419, 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488,
+ /* 80 */ 1486, 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254,
+ /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 140 */ 1254, 1254, 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457,
+ /* 150 */ 1456, 1458, 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254,
+ /* 160 */ 1254, 1254, 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461,
+ /* 170 */ 1473, 1472, 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254,
+ /* 180 */ 1254, 1254, 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 200 */ 1254, 1254, 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287,
+ /* 210 */ 1578, 1578, 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358,
+ /* 220 */ 1358, 1358, 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548,
+ /* 240 */ 1546, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254,
+ /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608,
+ /* 280 */ 1254, 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342,
+ /* 290 */ 1357, 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410,
+ /* 300 */ 1423, 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397,
+ /* 310 */ 1397, 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364,
+ /* 320 */ 1357, 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509,
+ /* 330 */ 1638, 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410,
+ /* 340 */ 1638, 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272,
+ /* 350 */ 1525, 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499,
+ /* 360 */ 1330, 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330,
+ /* 370 */ 1319, 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588,
+ /* 380 */ 1588, 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403,
+ /* 390 */ 1401, 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660,
+ /* 400 */ 1558, 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288,
+ /* 410 */ 1288, 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618,
+ /* 420 */ 1254, 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 440 */ 1564, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 450 */ 1254, 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254,
+ /* 460 */ 1254, 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254,
+ /* 470 */ 1254, 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254,
+ /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254,
+ /* 490 */ 1254, 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254,
+ /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 510 */ 1254, 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 530 */ 1254, 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254,
+ /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 550 */ 1254, 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254,
+ /* 560 */ 1254, 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
+ /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254,
+ /* 580 */ 1266, 1254, 1254,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -172350,52 +175049,53 @@ static const YYACTIONTYPE yy_default[] = {
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 59, /* EXPLAIN => ID */
- 59, /* QUERY => ID */
- 59, /* PLAN => ID */
- 59, /* BEGIN => ID */
+ 60, /* EXPLAIN => ID */
+ 60, /* QUERY => ID */
+ 60, /* PLAN => ID */
+ 60, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 59, /* DEFERRED => ID */
- 59, /* IMMEDIATE => ID */
- 59, /* EXCLUSIVE => ID */
+ 60, /* DEFERRED => ID */
+ 60, /* IMMEDIATE => ID */
+ 60, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
- 59, /* END => ID */
- 59, /* ROLLBACK => ID */
- 59, /* SAVEPOINT => ID */
- 59, /* RELEASE => ID */
+ 60, /* END => ID */
+ 60, /* ROLLBACK => ID */
+ 60, /* SAVEPOINT => ID */
+ 60, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 59, /* IF => ID */
+ 60, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 59, /* TEMP => ID */
+ 60, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
0, /* COMMA => nothing */
- 59, /* WITHOUT => ID */
- 59, /* ABORT => ID */
- 59, /* ACTION => ID */
- 59, /* AFTER => ID */
- 59, /* ANALYZE => ID */
- 59, /* ASC => ID */
- 59, /* ATTACH => ID */
- 59, /* BEFORE => ID */
- 59, /* BY => ID */
- 59, /* CASCADE => ID */
- 59, /* CAST => ID */
- 59, /* CONFLICT => ID */
- 59, /* DATABASE => ID */
- 59, /* DESC => ID */
- 59, /* DETACH => ID */
- 59, /* EACH => ID */
- 59, /* FAIL => ID */
+ 60, /* WITHOUT => ID */
+ 60, /* ABORT => ID */
+ 60, /* ACTION => ID */
+ 60, /* AFTER => ID */
+ 60, /* ANALYZE => ID */
+ 60, /* ASC => ID */
+ 60, /* ATTACH => ID */
+ 60, /* BEFORE => ID */
+ 60, /* BY => ID */
+ 60, /* CASCADE => ID */
+ 60, /* CAST => ID */
+ 60, /* CONFLICT => ID */
+ 60, /* DATABASE => ID */
+ 60, /* DESC => ID */
+ 60, /* DETACH => ID */
+ 60, /* EACH => ID */
+ 60, /* FAIL => ID */
0, /* OR => nothing */
0, /* AND => nothing */
0, /* IS => nothing */
- 59, /* MATCH => ID */
- 59, /* LIKE_KW => ID */
+ 0, /* ISNOT => nothing */
+ 60, /* MATCH => ID */
+ 60, /* LIKE_KW => ID */
0, /* BETWEEN => nothing */
0, /* IN => nothing */
0, /* ISNULL => nothing */
@@ -172408,47 +175108,47 @@ static const YYCODETYPE yyFallback[] = {
0, /* GE => nothing */
0, /* ESCAPE => nothing */
0, /* ID => nothing */
- 59, /* COLUMNKW => ID */
- 59, /* DO => ID */
- 59, /* FOR => ID */
- 59, /* IGNORE => ID */
- 59, /* INITIALLY => ID */
- 59, /* INSTEAD => ID */
- 59, /* NO => ID */
- 59, /* KEY => ID */
- 59, /* OF => ID */
- 59, /* OFFSET => ID */
- 59, /* PRAGMA => ID */
- 59, /* RAISE => ID */
- 59, /* RECURSIVE => ID */
- 59, /* REPLACE => ID */
- 59, /* RESTRICT => ID */
- 59, /* ROW => ID */
- 59, /* ROWS => ID */
- 59, /* TRIGGER => ID */
- 59, /* VACUUM => ID */
- 59, /* VIEW => ID */
- 59, /* VIRTUAL => ID */
- 59, /* WITH => ID */
- 59, /* NULLS => ID */
- 59, /* FIRST => ID */
- 59, /* LAST => ID */
- 59, /* CURRENT => ID */
- 59, /* FOLLOWING => ID */
- 59, /* PARTITION => ID */
- 59, /* PRECEDING => ID */
- 59, /* RANGE => ID */
- 59, /* UNBOUNDED => ID */
- 59, /* EXCLUDE => ID */
- 59, /* GROUPS => ID */
- 59, /* OTHERS => ID */
- 59, /* TIES => ID */
- 59, /* GENERATED => ID */
- 59, /* ALWAYS => ID */
- 59, /* MATERIALIZED => ID */
- 59, /* REINDEX => ID */
- 59, /* RENAME => ID */
- 59, /* CTIME_KW => ID */
+ 60, /* COLUMNKW => ID */
+ 60, /* DO => ID */
+ 60, /* FOR => ID */
+ 60, /* IGNORE => ID */
+ 60, /* INITIALLY => ID */
+ 60, /* INSTEAD => ID */
+ 60, /* NO => ID */
+ 60, /* KEY => ID */
+ 60, /* OF => ID */
+ 60, /* OFFSET => ID */
+ 60, /* PRAGMA => ID */
+ 60, /* RAISE => ID */
+ 60, /* RECURSIVE => ID */
+ 60, /* REPLACE => ID */
+ 60, /* RESTRICT => ID */
+ 60, /* ROW => ID */
+ 60, /* ROWS => ID */
+ 60, /* TRIGGER => ID */
+ 60, /* VACUUM => ID */
+ 60, /* VIEW => ID */
+ 60, /* VIRTUAL => ID */
+ 60, /* WITH => ID */
+ 60, /* NULLS => ID */
+ 60, /* FIRST => ID */
+ 60, /* LAST => ID */
+ 60, /* CURRENT => ID */
+ 60, /* FOLLOWING => ID */
+ 60, /* PARTITION => ID */
+ 60, /* PRECEDING => ID */
+ 60, /* RANGE => ID */
+ 60, /* UNBOUNDED => ID */
+ 60, /* EXCLUDE => ID */
+ 60, /* GROUPS => ID */
+ 60, /* OTHERS => ID */
+ 60, /* TIES => ID */
+ 60, /* GENERATED => ID */
+ 60, /* ALWAYS => ID */
+ 60, /* MATERIALIZED => ID */
+ 60, /* REINDEX => ID */
+ 60, /* RENAME => ID */
+ 60, /* CTIME_KW => ID */
0, /* ANY => nothing */
0, /* BITAND => nothing */
0, /* BITOR => nothing */
@@ -172519,10 +175219,9 @@ static const YYCODETYPE yyFallback[] = {
0, /* AGG_FUNCTION => nothing */
0, /* AGG_COLUMN => nothing */
0, /* TRUEFALSE => nothing */
- 0, /* ISNOT => nothing */
0, /* FUNCTION => nothing */
- 0, /* UMINUS => nothing */
0, /* UPLUS => nothing */
+ 0, /* UMINUS => nothing */
0, /* TRUTH => nothing */
0, /* REGISTER => nothing */
0, /* VECTOR => nothing */
@@ -172531,6 +175230,7 @@ static const YYCODETYPE yyFallback[] = {
0, /* ASTERISK => nothing */
0, /* SPAN => nothing */
0, /* ERROR => nothing */
+ 0, /* QNUMBER => nothing */
0, /* SPACE => nothing */
0, /* ILLEGAL => nothing */
};
@@ -172573,14 +175273,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;
@@ -172667,135 +175362,135 @@ static const char *const yyTokenName[] = {
/* 43 */ "OR",
/* 44 */ "AND",
/* 45 */ "IS",
- /* 46 */ "MATCH",
- /* 47 */ "LIKE_KW",
- /* 48 */ "BETWEEN",
- /* 49 */ "IN",
- /* 50 */ "ISNULL",
- /* 51 */ "NOTNULL",
- /* 52 */ "NE",
- /* 53 */ "EQ",
- /* 54 */ "GT",
- /* 55 */ "LE",
- /* 56 */ "LT",
- /* 57 */ "GE",
- /* 58 */ "ESCAPE",
- /* 59 */ "ID",
- /* 60 */ "COLUMNKW",
- /* 61 */ "DO",
- /* 62 */ "FOR",
- /* 63 */ "IGNORE",
- /* 64 */ "INITIALLY",
- /* 65 */ "INSTEAD",
- /* 66 */ "NO",
- /* 67 */ "KEY",
- /* 68 */ "OF",
- /* 69 */ "OFFSET",
- /* 70 */ "PRAGMA",
- /* 71 */ "RAISE",
- /* 72 */ "RECURSIVE",
- /* 73 */ "REPLACE",
- /* 74 */ "RESTRICT",
- /* 75 */ "ROW",
- /* 76 */ "ROWS",
- /* 77 */ "TRIGGER",
- /* 78 */ "VACUUM",
- /* 79 */ "VIEW",
- /* 80 */ "VIRTUAL",
- /* 81 */ "WITH",
- /* 82 */ "NULLS",
- /* 83 */ "FIRST",
- /* 84 */ "LAST",
- /* 85 */ "CURRENT",
- /* 86 */ "FOLLOWING",
- /* 87 */ "PARTITION",
- /* 88 */ "PRECEDING",
- /* 89 */ "RANGE",
- /* 90 */ "UNBOUNDED",
- /* 91 */ "EXCLUDE",
- /* 92 */ "GROUPS",
- /* 93 */ "OTHERS",
- /* 94 */ "TIES",
- /* 95 */ "GENERATED",
- /* 96 */ "ALWAYS",
- /* 97 */ "MATERIALIZED",
- /* 98 */ "REINDEX",
- /* 99 */ "RENAME",
- /* 100 */ "CTIME_KW",
- /* 101 */ "ANY",
- /* 102 */ "BITAND",
- /* 103 */ "BITOR",
- /* 104 */ "LSHIFT",
- /* 105 */ "RSHIFT",
- /* 106 */ "PLUS",
- /* 107 */ "MINUS",
- /* 108 */ "STAR",
- /* 109 */ "SLASH",
- /* 110 */ "REM",
- /* 111 */ "CONCAT",
- /* 112 */ "PTR",
- /* 113 */ "COLLATE",
- /* 114 */ "BITNOT",
- /* 115 */ "ON",
- /* 116 */ "INDEXED",
- /* 117 */ "STRING",
- /* 118 */ "JOIN_KW",
- /* 119 */ "CONSTRAINT",
- /* 120 */ "DEFAULT",
- /* 121 */ "NULL",
- /* 122 */ "PRIMARY",
- /* 123 */ "UNIQUE",
- /* 124 */ "CHECK",
- /* 125 */ "REFERENCES",
- /* 126 */ "AUTOINCR",
- /* 127 */ "INSERT",
- /* 128 */ "DELETE",
- /* 129 */ "UPDATE",
- /* 130 */ "SET",
- /* 131 */ "DEFERRABLE",
- /* 132 */ "FOREIGN",
- /* 133 */ "DROP",
- /* 134 */ "UNION",
- /* 135 */ "ALL",
- /* 136 */ "EXCEPT",
- /* 137 */ "INTERSECT",
- /* 138 */ "SELECT",
- /* 139 */ "VALUES",
- /* 140 */ "DISTINCT",
- /* 141 */ "DOT",
- /* 142 */ "FROM",
- /* 143 */ "JOIN",
- /* 144 */ "USING",
- /* 145 */ "ORDER",
- /* 146 */ "GROUP",
- /* 147 */ "HAVING",
- /* 148 */ "LIMIT",
- /* 149 */ "WHERE",
- /* 150 */ "RETURNING",
- /* 151 */ "INTO",
- /* 152 */ "NOTHING",
- /* 153 */ "FLOAT",
- /* 154 */ "BLOB",
- /* 155 */ "INTEGER",
- /* 156 */ "VARIABLE",
- /* 157 */ "CASE",
- /* 158 */ "WHEN",
- /* 159 */ "THEN",
- /* 160 */ "ELSE",
- /* 161 */ "INDEX",
- /* 162 */ "ALTER",
- /* 163 */ "ADD",
- /* 164 */ "WINDOW",
- /* 165 */ "OVER",
- /* 166 */ "FILTER",
- /* 167 */ "COLUMN",
- /* 168 */ "AGG_FUNCTION",
- /* 169 */ "AGG_COLUMN",
- /* 170 */ "TRUEFALSE",
- /* 171 */ "ISNOT",
+ /* 46 */ "ISNOT",
+ /* 47 */ "MATCH",
+ /* 48 */ "LIKE_KW",
+ /* 49 */ "BETWEEN",
+ /* 50 */ "IN",
+ /* 51 */ "ISNULL",
+ /* 52 */ "NOTNULL",
+ /* 53 */ "NE",
+ /* 54 */ "EQ",
+ /* 55 */ "GT",
+ /* 56 */ "LE",
+ /* 57 */ "LT",
+ /* 58 */ "GE",
+ /* 59 */ "ESCAPE",
+ /* 60 */ "ID",
+ /* 61 */ "COLUMNKW",
+ /* 62 */ "DO",
+ /* 63 */ "FOR",
+ /* 64 */ "IGNORE",
+ /* 65 */ "INITIALLY",
+ /* 66 */ "INSTEAD",
+ /* 67 */ "NO",
+ /* 68 */ "KEY",
+ /* 69 */ "OF",
+ /* 70 */ "OFFSET",
+ /* 71 */ "PRAGMA",
+ /* 72 */ "RAISE",
+ /* 73 */ "RECURSIVE",
+ /* 74 */ "REPLACE",
+ /* 75 */ "RESTRICT",
+ /* 76 */ "ROW",
+ /* 77 */ "ROWS",
+ /* 78 */ "TRIGGER",
+ /* 79 */ "VACUUM",
+ /* 80 */ "VIEW",
+ /* 81 */ "VIRTUAL",
+ /* 82 */ "WITH",
+ /* 83 */ "NULLS",
+ /* 84 */ "FIRST",
+ /* 85 */ "LAST",
+ /* 86 */ "CURRENT",
+ /* 87 */ "FOLLOWING",
+ /* 88 */ "PARTITION",
+ /* 89 */ "PRECEDING",
+ /* 90 */ "RANGE",
+ /* 91 */ "UNBOUNDED",
+ /* 92 */ "EXCLUDE",
+ /* 93 */ "GROUPS",
+ /* 94 */ "OTHERS",
+ /* 95 */ "TIES",
+ /* 96 */ "GENERATED",
+ /* 97 */ "ALWAYS",
+ /* 98 */ "MATERIALIZED",
+ /* 99 */ "REINDEX",
+ /* 100 */ "RENAME",
+ /* 101 */ "CTIME_KW",
+ /* 102 */ "ANY",
+ /* 103 */ "BITAND",
+ /* 104 */ "BITOR",
+ /* 105 */ "LSHIFT",
+ /* 106 */ "RSHIFT",
+ /* 107 */ "PLUS",
+ /* 108 */ "MINUS",
+ /* 109 */ "STAR",
+ /* 110 */ "SLASH",
+ /* 111 */ "REM",
+ /* 112 */ "CONCAT",
+ /* 113 */ "PTR",
+ /* 114 */ "COLLATE",
+ /* 115 */ "BITNOT",
+ /* 116 */ "ON",
+ /* 117 */ "INDEXED",
+ /* 118 */ "STRING",
+ /* 119 */ "JOIN_KW",
+ /* 120 */ "CONSTRAINT",
+ /* 121 */ "DEFAULT",
+ /* 122 */ "NULL",
+ /* 123 */ "PRIMARY",
+ /* 124 */ "UNIQUE",
+ /* 125 */ "CHECK",
+ /* 126 */ "REFERENCES",
+ /* 127 */ "AUTOINCR",
+ /* 128 */ "INSERT",
+ /* 129 */ "DELETE",
+ /* 130 */ "UPDATE",
+ /* 131 */ "SET",
+ /* 132 */ "DEFERRABLE",
+ /* 133 */ "FOREIGN",
+ /* 134 */ "DROP",
+ /* 135 */ "UNION",
+ /* 136 */ "ALL",
+ /* 137 */ "EXCEPT",
+ /* 138 */ "INTERSECT",
+ /* 139 */ "SELECT",
+ /* 140 */ "VALUES",
+ /* 141 */ "DISTINCT",
+ /* 142 */ "DOT",
+ /* 143 */ "FROM",
+ /* 144 */ "JOIN",
+ /* 145 */ "USING",
+ /* 146 */ "ORDER",
+ /* 147 */ "GROUP",
+ /* 148 */ "HAVING",
+ /* 149 */ "LIMIT",
+ /* 150 */ "WHERE",
+ /* 151 */ "RETURNING",
+ /* 152 */ "INTO",
+ /* 153 */ "NOTHING",
+ /* 154 */ "FLOAT",
+ /* 155 */ "BLOB",
+ /* 156 */ "INTEGER",
+ /* 157 */ "VARIABLE",
+ /* 158 */ "CASE",
+ /* 159 */ "WHEN",
+ /* 160 */ "THEN",
+ /* 161 */ "ELSE",
+ /* 162 */ "INDEX",
+ /* 163 */ "ALTER",
+ /* 164 */ "ADD",
+ /* 165 */ "WINDOW",
+ /* 166 */ "OVER",
+ /* 167 */ "FILTER",
+ /* 168 */ "COLUMN",
+ /* 169 */ "AGG_FUNCTION",
+ /* 170 */ "AGG_COLUMN",
+ /* 171 */ "TRUEFALSE",
/* 172 */ "FUNCTION",
- /* 173 */ "UMINUS",
- /* 174 */ "UPLUS",
+ /* 173 */ "UPLUS",
+ /* 174 */ "UMINUS",
/* 175 */ "TRUTH",
/* 176 */ "REGISTER",
/* 177 */ "VECTOR",
@@ -172804,142 +175499,145 @@ static const char *const yyTokenName[] = {
/* 180 */ "ASTERISK",
/* 181 */ "SPAN",
/* 182 */ "ERROR",
- /* 183 */ "SPACE",
- /* 184 */ "ILLEGAL",
- /* 185 */ "input",
- /* 186 */ "cmdlist",
- /* 187 */ "ecmd",
- /* 188 */ "cmdx",
- /* 189 */ "explain",
- /* 190 */ "cmd",
- /* 191 */ "transtype",
- /* 192 */ "trans_opt",
- /* 193 */ "nm",
- /* 194 */ "savepoint_opt",
- /* 195 */ "create_table",
- /* 196 */ "create_table_args",
- /* 197 */ "createkw",
- /* 198 */ "temp",
- /* 199 */ "ifnotexists",
- /* 200 */ "dbnm",
- /* 201 */ "columnlist",
- /* 202 */ "conslist_opt",
- /* 203 */ "table_option_set",
- /* 204 */ "select",
- /* 205 */ "table_option",
- /* 206 */ "columnname",
- /* 207 */ "carglist",
- /* 208 */ "typetoken",
- /* 209 */ "typename",
- /* 210 */ "signed",
- /* 211 */ "plus_num",
- /* 212 */ "minus_num",
- /* 213 */ "scanpt",
- /* 214 */ "scantok",
- /* 215 */ "ccons",
- /* 216 */ "term",
- /* 217 */ "expr",
- /* 218 */ "onconf",
- /* 219 */ "sortorder",
- /* 220 */ "autoinc",
- /* 221 */ "eidlist_opt",
- /* 222 */ "refargs",
- /* 223 */ "defer_subclause",
- /* 224 */ "generated",
- /* 225 */ "refarg",
- /* 226 */ "refact",
- /* 227 */ "init_deferred_pred_opt",
- /* 228 */ "conslist",
- /* 229 */ "tconscomma",
- /* 230 */ "tcons",
- /* 231 */ "sortlist",
- /* 232 */ "eidlist",
- /* 233 */ "defer_subclause_opt",
- /* 234 */ "orconf",
- /* 235 */ "resolvetype",
- /* 236 */ "raisetype",
- /* 237 */ "ifexists",
- /* 238 */ "fullname",
- /* 239 */ "selectnowith",
- /* 240 */ "oneselect",
- /* 241 */ "wqlist",
- /* 242 */ "multiselect_op",
- /* 243 */ "distinct",
- /* 244 */ "selcollist",
- /* 245 */ "from",
- /* 246 */ "where_opt",
- /* 247 */ "groupby_opt",
- /* 248 */ "having_opt",
- /* 249 */ "orderby_opt",
- /* 250 */ "limit_opt",
- /* 251 */ "window_clause",
- /* 252 */ "values",
- /* 253 */ "nexprlist",
- /* 254 */ "sclp",
- /* 255 */ "as",
- /* 256 */ "seltablist",
- /* 257 */ "stl_prefix",
- /* 258 */ "joinop",
- /* 259 */ "on_using",
- /* 260 */ "indexed_by",
- /* 261 */ "exprlist",
- /* 262 */ "xfullname",
- /* 263 */ "idlist",
- /* 264 */ "indexed_opt",
- /* 265 */ "nulls",
- /* 266 */ "with",
- /* 267 */ "where_opt_ret",
- /* 268 */ "setlist",
- /* 269 */ "insert_cmd",
- /* 270 */ "idlist_opt",
- /* 271 */ "upsert",
- /* 272 */ "returning",
- /* 273 */ "filter_over",
- /* 274 */ "likeop",
- /* 275 */ "between_op",
- /* 276 */ "in_op",
- /* 277 */ "paren_exprlist",
- /* 278 */ "case_operand",
- /* 279 */ "case_exprlist",
- /* 280 */ "case_else",
- /* 281 */ "uniqueflag",
- /* 282 */ "collate",
- /* 283 */ "vinto",
- /* 284 */ "nmnum",
- /* 285 */ "trigger_decl",
- /* 286 */ "trigger_cmd_list",
- /* 287 */ "trigger_time",
- /* 288 */ "trigger_event",
- /* 289 */ "foreach_clause",
- /* 290 */ "when_clause",
- /* 291 */ "trigger_cmd",
- /* 292 */ "trnm",
- /* 293 */ "tridxby",
- /* 294 */ "database_kw_opt",
- /* 295 */ "key_opt",
- /* 296 */ "add_column_fullname",
- /* 297 */ "kwcolumn_opt",
- /* 298 */ "create_vtab",
- /* 299 */ "vtabarglist",
- /* 300 */ "vtabarg",
- /* 301 */ "vtabargtoken",
- /* 302 */ "lp",
- /* 303 */ "anylist",
- /* 304 */ "wqitem",
- /* 305 */ "wqas",
- /* 306 */ "windowdefn_list",
- /* 307 */ "windowdefn",
- /* 308 */ "window",
- /* 309 */ "frame_opt",
- /* 310 */ "part_opt",
- /* 311 */ "filter_clause",
- /* 312 */ "over_clause",
- /* 313 */ "range_or_rows",
- /* 314 */ "frame_bound",
- /* 315 */ "frame_bound_s",
- /* 316 */ "frame_bound_e",
- /* 317 */ "frame_exclude_opt",
- /* 318 */ "frame_exclude",
+ /* 183 */ "QNUMBER",
+ /* 184 */ "SPACE",
+ /* 185 */ "ILLEGAL",
+ /* 186 */ "input",
+ /* 187 */ "cmdlist",
+ /* 188 */ "ecmd",
+ /* 189 */ "cmdx",
+ /* 190 */ "explain",
+ /* 191 */ "cmd",
+ /* 192 */ "transtype",
+ /* 193 */ "trans_opt",
+ /* 194 */ "nm",
+ /* 195 */ "savepoint_opt",
+ /* 196 */ "create_table",
+ /* 197 */ "create_table_args",
+ /* 198 */ "createkw",
+ /* 199 */ "temp",
+ /* 200 */ "ifnotexists",
+ /* 201 */ "dbnm",
+ /* 202 */ "columnlist",
+ /* 203 */ "conslist_opt",
+ /* 204 */ "table_option_set",
+ /* 205 */ "select",
+ /* 206 */ "table_option",
+ /* 207 */ "columnname",
+ /* 208 */ "carglist",
+ /* 209 */ "typetoken",
+ /* 210 */ "typename",
+ /* 211 */ "signed",
+ /* 212 */ "plus_num",
+ /* 213 */ "minus_num",
+ /* 214 */ "scanpt",
+ /* 215 */ "scantok",
+ /* 216 */ "ccons",
+ /* 217 */ "term",
+ /* 218 */ "expr",
+ /* 219 */ "onconf",
+ /* 220 */ "sortorder",
+ /* 221 */ "autoinc",
+ /* 222 */ "eidlist_opt",
+ /* 223 */ "refargs",
+ /* 224 */ "defer_subclause",
+ /* 225 */ "generated",
+ /* 226 */ "refarg",
+ /* 227 */ "refact",
+ /* 228 */ "init_deferred_pred_opt",
+ /* 229 */ "conslist",
+ /* 230 */ "tconscomma",
+ /* 231 */ "tcons",
+ /* 232 */ "sortlist",
+ /* 233 */ "eidlist",
+ /* 234 */ "defer_subclause_opt",
+ /* 235 */ "orconf",
+ /* 236 */ "resolvetype",
+ /* 237 */ "raisetype",
+ /* 238 */ "ifexists",
+ /* 239 */ "fullname",
+ /* 240 */ "selectnowith",
+ /* 241 */ "oneselect",
+ /* 242 */ "wqlist",
+ /* 243 */ "multiselect_op",
+ /* 244 */ "distinct",
+ /* 245 */ "selcollist",
+ /* 246 */ "from",
+ /* 247 */ "where_opt",
+ /* 248 */ "groupby_opt",
+ /* 249 */ "having_opt",
+ /* 250 */ "orderby_opt",
+ /* 251 */ "limit_opt",
+ /* 252 */ "window_clause",
+ /* 253 */ "values",
+ /* 254 */ "nexprlist",
+ /* 255 */ "mvalues",
+ /* 256 */ "sclp",
+ /* 257 */ "as",
+ /* 258 */ "seltablist",
+ /* 259 */ "stl_prefix",
+ /* 260 */ "joinop",
+ /* 261 */ "on_using",
+ /* 262 */ "indexed_by",
+ /* 263 */ "exprlist",
+ /* 264 */ "xfullname",
+ /* 265 */ "idlist",
+ /* 266 */ "indexed_opt",
+ /* 267 */ "nulls",
+ /* 268 */ "with",
+ /* 269 */ "where_opt_ret",
+ /* 270 */ "setlist",
+ /* 271 */ "insert_cmd",
+ /* 272 */ "idlist_opt",
+ /* 273 */ "upsert",
+ /* 274 */ "returning",
+ /* 275 */ "filter_over",
+ /* 276 */ "likeop",
+ /* 277 */ "between_op",
+ /* 278 */ "in_op",
+ /* 279 */ "paren_exprlist",
+ /* 280 */ "case_operand",
+ /* 281 */ "case_exprlist",
+ /* 282 */ "case_else",
+ /* 283 */ "uniqueflag",
+ /* 284 */ "collate",
+ /* 285 */ "vinto",
+ /* 286 */ "nmnum",
+ /* 287 */ "trigger_decl",
+ /* 288 */ "trigger_cmd_list",
+ /* 289 */ "trigger_time",
+ /* 290 */ "trigger_event",
+ /* 291 */ "foreach_clause",
+ /* 292 */ "when_clause",
+ /* 293 */ "trigger_cmd",
+ /* 294 */ "trnm",
+ /* 295 */ "tridxby",
+ /* 296 */ "database_kw_opt",
+ /* 297 */ "key_opt",
+ /* 298 */ "add_column_fullname",
+ /* 299 */ "kwcolumn_opt",
+ /* 300 */ "create_vtab",
+ /* 301 */ "vtabarglist",
+ /* 302 */ "vtabarg",
+ /* 303 */ "vtabargtoken",
+ /* 304 */ "lp",
+ /* 305 */ "anylist",
+ /* 306 */ "wqitem",
+ /* 307 */ "wqas",
+ /* 308 */ "withnm",
+ /* 309 */ "windowdefn_list",
+ /* 310 */ "windowdefn",
+ /* 311 */ "window",
+ /* 312 */ "frame_opt",
+ /* 313 */ "part_opt",
+ /* 314 */ "filter_clause",
+ /* 315 */ "over_clause",
+ /* 316 */ "range_or_rows",
+ /* 317 */ "frame_bound",
+ /* 318 */ "frame_bound_s",
+ /* 319 */ "frame_bound_e",
+ /* 320 */ "frame_exclude_opt",
+ /* 321 */ "frame_exclude",
};
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
@@ -173042,351 +175740,363 @@ static const char *const yyRuleName[] = {
/* 92 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
/* 93 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
/* 94 */ "values ::= VALUES LP nexprlist RP",
- /* 95 */ "values ::= values COMMA LP nexprlist RP",
- /* 96 */ "distinct ::= DISTINCT",
- /* 97 */ "distinct ::= ALL",
- /* 98 */ "distinct ::=",
- /* 99 */ "sclp ::=",
- /* 100 */ "selcollist ::= sclp scanpt expr scanpt as",
- /* 101 */ "selcollist ::= sclp scanpt STAR",
- /* 102 */ "selcollist ::= sclp scanpt nm DOT STAR",
- /* 103 */ "as ::= AS nm",
- /* 104 */ "as ::=",
- /* 105 */ "from ::=",
- /* 106 */ "from ::= FROM seltablist",
- /* 107 */ "stl_prefix ::= seltablist joinop",
- /* 108 */ "stl_prefix ::=",
- /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using",
- /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using",
- /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using",
- /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using",
- /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using",
- /* 114 */ "dbnm ::=",
- /* 115 */ "dbnm ::= DOT nm",
- /* 116 */ "fullname ::= nm",
- /* 117 */ "fullname ::= nm DOT nm",
- /* 118 */ "xfullname ::= nm",
- /* 119 */ "xfullname ::= nm DOT nm",
- /* 120 */ "xfullname ::= nm DOT nm AS nm",
- /* 121 */ "xfullname ::= nm AS nm",
- /* 122 */ "joinop ::= COMMA|JOIN",
- /* 123 */ "joinop ::= JOIN_KW JOIN",
- /* 124 */ "joinop ::= JOIN_KW nm JOIN",
- /* 125 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 126 */ "on_using ::= ON expr",
- /* 127 */ "on_using ::= USING LP idlist RP",
- /* 128 */ "on_using ::=",
- /* 129 */ "indexed_opt ::=",
- /* 130 */ "indexed_by ::= INDEXED BY nm",
- /* 131 */ "indexed_by ::= NOT INDEXED",
- /* 132 */ "orderby_opt ::=",
- /* 133 */ "orderby_opt ::= ORDER BY sortlist",
- /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls",
- /* 135 */ "sortlist ::= expr sortorder nulls",
- /* 136 */ "sortorder ::= ASC",
- /* 137 */ "sortorder ::= DESC",
- /* 138 */ "sortorder ::=",
- /* 139 */ "nulls ::= NULLS FIRST",
- /* 140 */ "nulls ::= NULLS LAST",
- /* 141 */ "nulls ::=",
- /* 142 */ "groupby_opt ::=",
- /* 143 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 144 */ "having_opt ::=",
- /* 145 */ "having_opt ::= HAVING expr",
- /* 146 */ "limit_opt ::=",
- /* 147 */ "limit_opt ::= LIMIT expr",
- /* 148 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 149 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 150 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret",
- /* 151 */ "where_opt ::=",
- /* 152 */ "where_opt ::= WHERE expr",
- /* 153 */ "where_opt_ret ::=",
- /* 154 */ "where_opt_ret ::= WHERE expr",
- /* 155 */ "where_opt_ret ::= RETURNING selcollist",
- /* 156 */ "where_opt_ret ::= WHERE expr RETURNING selcollist",
- /* 157 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret",
- /* 158 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 159 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
- /* 160 */ "setlist ::= nm EQ expr",
- /* 161 */ "setlist ::= LP idlist RP EQ expr",
- /* 162 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
- /* 163 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning",
- /* 164 */ "upsert ::=",
- /* 165 */ "upsert ::= RETURNING selcollist",
- /* 166 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert",
- /* 167 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert",
- /* 168 */ "upsert ::= ON CONFLICT DO NOTHING returning",
- /* 169 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning",
- /* 170 */ "returning ::= RETURNING selcollist",
- /* 171 */ "insert_cmd ::= INSERT orconf",
- /* 172 */ "insert_cmd ::= REPLACE",
- /* 173 */ "idlist_opt ::=",
- /* 174 */ "idlist_opt ::= LP idlist RP",
- /* 175 */ "idlist ::= idlist COMMA nm",
- /* 176 */ "idlist ::= nm",
- /* 177 */ "expr ::= LP expr RP",
- /* 178 */ "expr ::= ID|INDEXED|JOIN_KW",
- /* 179 */ "expr ::= nm DOT nm",
- /* 180 */ "expr ::= nm DOT nm DOT nm",
- /* 181 */ "term ::= NULL|FLOAT|BLOB",
- /* 182 */ "term ::= STRING",
- /* 183 */ "term ::= INTEGER",
- /* 184 */ "expr ::= VARIABLE",
- /* 185 */ "expr ::= expr COLLATE ID|STRING",
- /* 186 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP",
- /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP",
- /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP",
- /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over",
- /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over",
- /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over",
- /* 193 */ "term ::= CTIME_KW",
- /* 194 */ "expr ::= LP nexprlist COMMA expr RP",
- /* 195 */ "expr ::= expr AND expr",
- /* 196 */ "expr ::= expr OR expr",
- /* 197 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 198 */ "expr ::= expr EQ|NE expr",
- /* 199 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 200 */ "expr ::= expr PLUS|MINUS expr",
- /* 201 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 202 */ "expr ::= expr CONCAT expr",
- /* 203 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 204 */ "expr ::= expr likeop expr",
- /* 205 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 206 */ "expr ::= expr ISNULL|NOTNULL",
- /* 207 */ "expr ::= expr NOT NULL",
- /* 208 */ "expr ::= expr IS expr",
- /* 209 */ "expr ::= expr IS NOT expr",
- /* 210 */ "expr ::= expr IS NOT DISTINCT FROM expr",
- /* 211 */ "expr ::= expr IS DISTINCT FROM expr",
- /* 212 */ "expr ::= NOT expr",
- /* 213 */ "expr ::= BITNOT expr",
- /* 214 */ "expr ::= PLUS|MINUS expr",
- /* 215 */ "expr ::= expr PTR expr",
- /* 216 */ "between_op ::= BETWEEN",
- /* 217 */ "between_op ::= NOT BETWEEN",
- /* 218 */ "expr ::= expr between_op expr AND expr",
- /* 219 */ "in_op ::= IN",
- /* 220 */ "in_op ::= NOT IN",
- /* 221 */ "expr ::= expr in_op LP exprlist RP",
- /* 222 */ "expr ::= LP select RP",
- /* 223 */ "expr ::= expr in_op LP select RP",
- /* 224 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 225 */ "expr ::= EXISTS LP select RP",
- /* 226 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 227 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 228 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 229 */ "case_else ::= ELSE expr",
- /* 230 */ "case_else ::=",
- /* 231 */ "case_operand ::=",
- /* 232 */ "exprlist ::=",
- /* 233 */ "nexprlist ::= nexprlist COMMA expr",
- /* 234 */ "nexprlist ::= expr",
- /* 235 */ "paren_exprlist ::=",
- /* 236 */ "paren_exprlist ::= LP exprlist RP",
- /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 238 */ "uniqueflag ::= UNIQUE",
- /* 239 */ "uniqueflag ::=",
- /* 240 */ "eidlist_opt ::=",
- /* 241 */ "eidlist_opt ::= LP eidlist RP",
- /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 243 */ "eidlist ::= nm collate sortorder",
- /* 244 */ "collate ::=",
- /* 245 */ "collate ::= COLLATE ID|STRING",
- /* 246 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 247 */ "cmd ::= VACUUM vinto",
- /* 248 */ "cmd ::= VACUUM nm vinto",
- /* 249 */ "vinto ::= INTO expr",
- /* 250 */ "vinto ::=",
- /* 251 */ "cmd ::= PRAGMA nm dbnm",
- /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 260 */ "trigger_time ::= BEFORE|AFTER",
- /* 261 */ "trigger_time ::= INSTEAD OF",
- /* 262 */ "trigger_time ::=",
- /* 263 */ "trigger_event ::= DELETE|INSERT",
- /* 264 */ "trigger_event ::= UPDATE",
- /* 265 */ "trigger_event ::= UPDATE OF idlist",
- /* 266 */ "when_clause ::=",
- /* 267 */ "when_clause ::= WHEN expr",
- /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 270 */ "trnm ::= nm DOT nm",
- /* 271 */ "tridxby ::= INDEXED BY nm",
- /* 272 */ "tridxby ::= NOT INDEXED",
- /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
- /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
- /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
- /* 276 */ "trigger_cmd ::= scanpt select scanpt",
- /* 277 */ "expr ::= RAISE LP IGNORE RP",
- /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 279 */ "raisetype ::= ROLLBACK",
- /* 280 */ "raisetype ::= ABORT",
- /* 281 */ "raisetype ::= FAIL",
- /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 284 */ "cmd ::= DETACH database_kw_opt expr",
- /* 285 */ "key_opt ::=",
- /* 286 */ "key_opt ::= KEY expr",
- /* 287 */ "cmd ::= REINDEX",
- /* 288 */ "cmd ::= REINDEX nm dbnm",
- /* 289 */ "cmd ::= ANALYZE",
- /* 290 */ "cmd ::= ANALYZE nm dbnm",
- /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
- /* 294 */ "add_column_fullname ::= fullname",
- /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
- /* 296 */ "cmd ::= create_vtab",
- /* 297 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 299 */ "vtabarg ::=",
- /* 300 */ "vtabargtoken ::= ANY",
- /* 301 */ "vtabargtoken ::= lp anylist RP",
- /* 302 */ "lp ::= LP",
- /* 303 */ "with ::= WITH wqlist",
- /* 304 */ "with ::= WITH RECURSIVE wqlist",
- /* 305 */ "wqas ::= AS",
- /* 306 */ "wqas ::= AS MATERIALIZED",
- /* 307 */ "wqas ::= AS NOT MATERIALIZED",
- /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP",
- /* 309 */ "wqlist ::= wqitem",
- /* 310 */ "wqlist ::= wqlist COMMA wqitem",
- /* 311 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
- /* 312 */ "windowdefn ::= nm AS LP window RP",
- /* 313 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
- /* 314 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
- /* 315 */ "window ::= ORDER BY sortlist frame_opt",
- /* 316 */ "window ::= nm ORDER BY sortlist frame_opt",
- /* 317 */ "window ::= nm frame_opt",
- /* 318 */ "frame_opt ::=",
- /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
- /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
- /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
- /* 322 */ "frame_bound_s ::= frame_bound",
- /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
- /* 324 */ "frame_bound_e ::= frame_bound",
- /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
- /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
- /* 327 */ "frame_bound ::= CURRENT ROW",
- /* 328 */ "frame_exclude_opt ::=",
- /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
- /* 330 */ "frame_exclude ::= NO OTHERS",
- /* 331 */ "frame_exclude ::= CURRENT ROW",
- /* 332 */ "frame_exclude ::= GROUP|TIES",
- /* 333 */ "window_clause ::= WINDOW windowdefn_list",
- /* 334 */ "filter_over ::= filter_clause over_clause",
- /* 335 */ "filter_over ::= over_clause",
- /* 336 */ "filter_over ::= filter_clause",
- /* 337 */ "over_clause ::= OVER LP window RP",
- /* 338 */ "over_clause ::= OVER nm",
- /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP",
- /* 340 */ "input ::= cmdlist",
- /* 341 */ "cmdlist ::= cmdlist ecmd",
- /* 342 */ "cmdlist ::= ecmd",
- /* 343 */ "ecmd ::= SEMI",
- /* 344 */ "ecmd ::= cmdx SEMI",
- /* 345 */ "ecmd ::= explain cmdx SEMI",
- /* 346 */ "trans_opt ::=",
- /* 347 */ "trans_opt ::= TRANSACTION",
- /* 348 */ "trans_opt ::= TRANSACTION nm",
- /* 349 */ "savepoint_opt ::= SAVEPOINT",
- /* 350 */ "savepoint_opt ::=",
- /* 351 */ "cmd ::= create_table create_table_args",
- /* 352 */ "table_option_set ::= table_option",
- /* 353 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 354 */ "columnlist ::= columnname carglist",
- /* 355 */ "nm ::= ID|INDEXED|JOIN_KW",
- /* 356 */ "nm ::= STRING",
- /* 357 */ "typetoken ::= typename",
- /* 358 */ "typename ::= ID|STRING",
- /* 359 */ "signed ::= plus_num",
- /* 360 */ "signed ::= minus_num",
- /* 361 */ "carglist ::= carglist ccons",
- /* 362 */ "carglist ::=",
- /* 363 */ "ccons ::= NULL onconf",
- /* 364 */ "ccons ::= GENERATED ALWAYS AS generated",
- /* 365 */ "ccons ::= AS generated",
- /* 366 */ "conslist_opt ::= COMMA conslist",
- /* 367 */ "conslist ::= conslist tconscomma tcons",
- /* 368 */ "conslist ::= tcons",
- /* 369 */ "tconscomma ::=",
- /* 370 */ "defer_subclause_opt ::= defer_subclause",
- /* 371 */ "resolvetype ::= raisetype",
- /* 372 */ "selectnowith ::= oneselect",
- /* 373 */ "oneselect ::= values",
- /* 374 */ "sclp ::= selcollist COMMA",
- /* 375 */ "as ::= ID|STRING",
- /* 376 */ "indexed_opt ::= indexed_by",
- /* 377 */ "returning ::=",
- /* 378 */ "expr ::= term",
- /* 379 */ "likeop ::= LIKE_KW|MATCH",
- /* 380 */ "case_operand ::= expr",
- /* 381 */ "exprlist ::= nexprlist",
- /* 382 */ "nmnum ::= plus_num",
- /* 383 */ "nmnum ::= nm",
- /* 384 */ "nmnum ::= ON",
- /* 385 */ "nmnum ::= DELETE",
- /* 386 */ "nmnum ::= DEFAULT",
- /* 387 */ "plus_num ::= INTEGER|FLOAT",
- /* 388 */ "foreach_clause ::=",
- /* 389 */ "foreach_clause ::= FOR EACH ROW",
- /* 390 */ "trnm ::= nm",
- /* 391 */ "tridxby ::=",
- /* 392 */ "database_kw_opt ::= DATABASE",
- /* 393 */ "database_kw_opt ::=",
- /* 394 */ "kwcolumn_opt ::=",
- /* 395 */ "kwcolumn_opt ::= COLUMNKW",
- /* 396 */ "vtabarglist ::= vtabarg",
- /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 398 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 399 */ "anylist ::=",
- /* 400 */ "anylist ::= anylist LP anylist RP",
- /* 401 */ "anylist ::= anylist ANY",
- /* 402 */ "with ::=",
- /* 403 */ "windowdefn_list ::= windowdefn",
- /* 404 */ "window ::= frame_opt",
+ /* 95 */ "oneselect ::= mvalues",
+ /* 96 */ "mvalues ::= values COMMA LP nexprlist RP",
+ /* 97 */ "mvalues ::= mvalues COMMA LP nexprlist RP",
+ /* 98 */ "distinct ::= DISTINCT",
+ /* 99 */ "distinct ::= ALL",
+ /* 100 */ "distinct ::=",
+ /* 101 */ "sclp ::=",
+ /* 102 */ "selcollist ::= sclp scanpt expr scanpt as",
+ /* 103 */ "selcollist ::= sclp scanpt STAR",
+ /* 104 */ "selcollist ::= sclp scanpt nm DOT STAR",
+ /* 105 */ "as ::= AS nm",
+ /* 106 */ "as ::=",
+ /* 107 */ "from ::=",
+ /* 108 */ "from ::= FROM seltablist",
+ /* 109 */ "stl_prefix ::= seltablist joinop",
+ /* 110 */ "stl_prefix ::=",
+ /* 111 */ "seltablist ::= stl_prefix nm dbnm as on_using",
+ /* 112 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using",
+ /* 113 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using",
+ /* 114 */ "seltablist ::= stl_prefix LP select RP as on_using",
+ /* 115 */ "seltablist ::= stl_prefix LP seltablist RP as on_using",
+ /* 116 */ "dbnm ::=",
+ /* 117 */ "dbnm ::= DOT nm",
+ /* 118 */ "fullname ::= nm",
+ /* 119 */ "fullname ::= nm DOT nm",
+ /* 120 */ "xfullname ::= nm",
+ /* 121 */ "xfullname ::= nm DOT nm",
+ /* 122 */ "xfullname ::= nm DOT nm AS nm",
+ /* 123 */ "xfullname ::= nm AS nm",
+ /* 124 */ "joinop ::= COMMA|JOIN",
+ /* 125 */ "joinop ::= JOIN_KW JOIN",
+ /* 126 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 127 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 128 */ "on_using ::= ON expr",
+ /* 129 */ "on_using ::= USING LP idlist RP",
+ /* 130 */ "on_using ::=",
+ /* 131 */ "indexed_opt ::=",
+ /* 132 */ "indexed_by ::= INDEXED BY nm",
+ /* 133 */ "indexed_by ::= NOT INDEXED",
+ /* 134 */ "orderby_opt ::=",
+ /* 135 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 136 */ "sortlist ::= sortlist COMMA expr sortorder nulls",
+ /* 137 */ "sortlist ::= expr sortorder nulls",
+ /* 138 */ "sortorder ::= ASC",
+ /* 139 */ "sortorder ::= DESC",
+ /* 140 */ "sortorder ::=",
+ /* 141 */ "nulls ::= NULLS FIRST",
+ /* 142 */ "nulls ::= NULLS LAST",
+ /* 143 */ "nulls ::=",
+ /* 144 */ "groupby_opt ::=",
+ /* 145 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 146 */ "having_opt ::=",
+ /* 147 */ "having_opt ::= HAVING expr",
+ /* 148 */ "limit_opt ::=",
+ /* 149 */ "limit_opt ::= LIMIT expr",
+ /* 150 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 151 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 152 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret",
+ /* 153 */ "where_opt ::=",
+ /* 154 */ "where_opt ::= WHERE expr",
+ /* 155 */ "where_opt_ret ::=",
+ /* 156 */ "where_opt_ret ::= WHERE expr",
+ /* 157 */ "where_opt_ret ::= RETURNING selcollist",
+ /* 158 */ "where_opt_ret ::= WHERE expr RETURNING selcollist",
+ /* 159 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret",
+ /* 160 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 161 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+ /* 162 */ "setlist ::= nm EQ expr",
+ /* 163 */ "setlist ::= LP idlist RP EQ expr",
+ /* 164 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
+ /* 165 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning",
+ /* 166 */ "upsert ::=",
+ /* 167 */ "upsert ::= RETURNING selcollist",
+ /* 168 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert",
+ /* 169 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert",
+ /* 170 */ "upsert ::= ON CONFLICT DO NOTHING returning",
+ /* 171 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning",
+ /* 172 */ "returning ::= RETURNING selcollist",
+ /* 173 */ "insert_cmd ::= INSERT orconf",
+ /* 174 */ "insert_cmd ::= REPLACE",
+ /* 175 */ "idlist_opt ::=",
+ /* 176 */ "idlist_opt ::= LP idlist RP",
+ /* 177 */ "idlist ::= idlist COMMA nm",
+ /* 178 */ "idlist ::= nm",
+ /* 179 */ "expr ::= LP expr RP",
+ /* 180 */ "expr ::= ID|INDEXED|JOIN_KW",
+ /* 181 */ "expr ::= nm DOT nm",
+ /* 182 */ "expr ::= nm DOT nm DOT nm",
+ /* 183 */ "term ::= NULL|FLOAT|BLOB",
+ /* 184 */ "term ::= STRING",
+ /* 185 */ "term ::= INTEGER",
+ /* 186 */ "expr ::= VARIABLE",
+ /* 187 */ "expr ::= expr COLLATE ID|STRING",
+ /* 188 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP",
+ /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP",
+ /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP",
+ /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over",
+ /* 193 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over",
+ /* 194 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over",
+ /* 195 */ "term ::= CTIME_KW",
+ /* 196 */ "expr ::= LP nexprlist COMMA expr RP",
+ /* 197 */ "expr ::= expr AND expr",
+ /* 198 */ "expr ::= expr OR expr",
+ /* 199 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 200 */ "expr ::= expr EQ|NE expr",
+ /* 201 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 202 */ "expr ::= expr PLUS|MINUS expr",
+ /* 203 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 204 */ "expr ::= expr CONCAT expr",
+ /* 205 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 206 */ "expr ::= expr likeop expr",
+ /* 207 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 208 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 209 */ "expr ::= expr NOT NULL",
+ /* 210 */ "expr ::= expr IS expr",
+ /* 211 */ "expr ::= expr IS NOT expr",
+ /* 212 */ "expr ::= expr IS NOT DISTINCT FROM expr",
+ /* 213 */ "expr ::= expr IS DISTINCT FROM expr",
+ /* 214 */ "expr ::= NOT expr",
+ /* 215 */ "expr ::= BITNOT expr",
+ /* 216 */ "expr ::= PLUS|MINUS expr",
+ /* 217 */ "expr ::= expr PTR expr",
+ /* 218 */ "between_op ::= BETWEEN",
+ /* 219 */ "between_op ::= NOT BETWEEN",
+ /* 220 */ "expr ::= expr between_op expr AND expr",
+ /* 221 */ "in_op ::= IN",
+ /* 222 */ "in_op ::= NOT IN",
+ /* 223 */ "expr ::= expr in_op LP exprlist RP",
+ /* 224 */ "expr ::= LP select RP",
+ /* 225 */ "expr ::= expr in_op LP select RP",
+ /* 226 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 227 */ "expr ::= EXISTS LP select RP",
+ /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 230 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 231 */ "case_else ::= ELSE expr",
+ /* 232 */ "case_else ::=",
+ /* 233 */ "case_operand ::=",
+ /* 234 */ "exprlist ::=",
+ /* 235 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 236 */ "nexprlist ::= expr",
+ /* 237 */ "paren_exprlist ::=",
+ /* 238 */ "paren_exprlist ::= LP exprlist RP",
+ /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 240 */ "uniqueflag ::= UNIQUE",
+ /* 241 */ "uniqueflag ::=",
+ /* 242 */ "eidlist_opt ::=",
+ /* 243 */ "eidlist_opt ::= LP eidlist RP",
+ /* 244 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 245 */ "eidlist ::= nm collate sortorder",
+ /* 246 */ "collate ::=",
+ /* 247 */ "collate ::= COLLATE ID|STRING",
+ /* 248 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 249 */ "cmd ::= VACUUM vinto",
+ /* 250 */ "cmd ::= VACUUM nm vinto",
+ /* 251 */ "vinto ::= INTO expr",
+ /* 252 */ "vinto ::=",
+ /* 253 */ "cmd ::= PRAGMA nm dbnm",
+ /* 254 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 255 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 256 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 257 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 258 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 259 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 260 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 261 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 262 */ "trigger_time ::= BEFORE|AFTER",
+ /* 263 */ "trigger_time ::= INSTEAD OF",
+ /* 264 */ "trigger_time ::=",
+ /* 265 */ "trigger_event ::= DELETE|INSERT",
+ /* 266 */ "trigger_event ::= UPDATE",
+ /* 267 */ "trigger_event ::= UPDATE OF idlist",
+ /* 268 */ "when_clause ::=",
+ /* 269 */ "when_clause ::= WHEN expr",
+ /* 270 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 271 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 272 */ "trnm ::= nm DOT nm",
+ /* 273 */ "tridxby ::= INDEXED BY nm",
+ /* 274 */ "tridxby ::= NOT INDEXED",
+ /* 275 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
+ /* 276 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
+ /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+ /* 278 */ "trigger_cmd ::= scanpt select scanpt",
+ /* 279 */ "expr ::= RAISE LP IGNORE RP",
+ /* 280 */ "expr ::= RAISE LP raisetype COMMA expr RP",
+ /* 281 */ "raisetype ::= ROLLBACK",
+ /* 282 */ "raisetype ::= ABORT",
+ /* 283 */ "raisetype ::= FAIL",
+ /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 286 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 287 */ "key_opt ::=",
+ /* 288 */ "key_opt ::= KEY expr",
+ /* 289 */ "cmd ::= REINDEX",
+ /* 290 */ "cmd ::= REINDEX nm dbnm",
+ /* 291 */ "cmd ::= ANALYZE",
+ /* 292 */ "cmd ::= ANALYZE nm dbnm",
+ /* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 294 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 295 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
+ /* 296 */ "add_column_fullname ::= fullname",
+ /* 297 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
+ /* 298 */ "cmd ::= create_vtab",
+ /* 299 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 300 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 301 */ "vtabarg ::=",
+ /* 302 */ "vtabargtoken ::= ANY",
+ /* 303 */ "vtabargtoken ::= lp anylist RP",
+ /* 304 */ "lp ::= LP",
+ /* 305 */ "with ::= WITH wqlist",
+ /* 306 */ "with ::= WITH RECURSIVE wqlist",
+ /* 307 */ "wqas ::= AS",
+ /* 308 */ "wqas ::= AS MATERIALIZED",
+ /* 309 */ "wqas ::= AS NOT MATERIALIZED",
+ /* 310 */ "wqitem ::= withnm eidlist_opt wqas LP select RP",
+ /* 311 */ "withnm ::= nm",
+ /* 312 */ "wqlist ::= wqitem",
+ /* 313 */ "wqlist ::= wqlist COMMA wqitem",
+ /* 314 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
+ /* 315 */ "windowdefn ::= nm AS LP window RP",
+ /* 316 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 317 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 318 */ "window ::= ORDER BY sortlist frame_opt",
+ /* 319 */ "window ::= nm ORDER BY sortlist frame_opt",
+ /* 320 */ "window ::= nm frame_opt",
+ /* 321 */ "frame_opt ::=",
+ /* 322 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
+ /* 323 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
+ /* 324 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
+ /* 325 */ "frame_bound_s ::= frame_bound",
+ /* 326 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
+ /* 327 */ "frame_bound_e ::= frame_bound",
+ /* 328 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
+ /* 329 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
+ /* 330 */ "frame_bound ::= CURRENT ROW",
+ /* 331 */ "frame_exclude_opt ::=",
+ /* 332 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
+ /* 333 */ "frame_exclude ::= NO OTHERS",
+ /* 334 */ "frame_exclude ::= CURRENT ROW",
+ /* 335 */ "frame_exclude ::= GROUP|TIES",
+ /* 336 */ "window_clause ::= WINDOW windowdefn_list",
+ /* 337 */ "filter_over ::= filter_clause over_clause",
+ /* 338 */ "filter_over ::= over_clause",
+ /* 339 */ "filter_over ::= filter_clause",
+ /* 340 */ "over_clause ::= OVER LP window RP",
+ /* 341 */ "over_clause ::= OVER nm",
+ /* 342 */ "filter_clause ::= FILTER LP WHERE expr RP",
+ /* 343 */ "term ::= QNUMBER",
+ /* 344 */ "input ::= cmdlist",
+ /* 345 */ "cmdlist ::= cmdlist ecmd",
+ /* 346 */ "cmdlist ::= ecmd",
+ /* 347 */ "ecmd ::= SEMI",
+ /* 348 */ "ecmd ::= cmdx SEMI",
+ /* 349 */ "ecmd ::= explain cmdx SEMI",
+ /* 350 */ "trans_opt ::=",
+ /* 351 */ "trans_opt ::= TRANSACTION",
+ /* 352 */ "trans_opt ::= TRANSACTION nm",
+ /* 353 */ "savepoint_opt ::= SAVEPOINT",
+ /* 354 */ "savepoint_opt ::=",
+ /* 355 */ "cmd ::= create_table create_table_args",
+ /* 356 */ "table_option_set ::= table_option",
+ /* 357 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 358 */ "columnlist ::= columnname carglist",
+ /* 359 */ "nm ::= ID|INDEXED|JOIN_KW",
+ /* 360 */ "nm ::= STRING",
+ /* 361 */ "typetoken ::= typename",
+ /* 362 */ "typename ::= ID|STRING",
+ /* 363 */ "signed ::= plus_num",
+ /* 364 */ "signed ::= minus_num",
+ /* 365 */ "carglist ::= carglist ccons",
+ /* 366 */ "carglist ::=",
+ /* 367 */ "ccons ::= NULL onconf",
+ /* 368 */ "ccons ::= GENERATED ALWAYS AS generated",
+ /* 369 */ "ccons ::= AS generated",
+ /* 370 */ "conslist_opt ::= COMMA conslist",
+ /* 371 */ "conslist ::= conslist tconscomma tcons",
+ /* 372 */ "conslist ::= tcons",
+ /* 373 */ "tconscomma ::=",
+ /* 374 */ "defer_subclause_opt ::= defer_subclause",
+ /* 375 */ "resolvetype ::= raisetype",
+ /* 376 */ "selectnowith ::= oneselect",
+ /* 377 */ "oneselect ::= values",
+ /* 378 */ "sclp ::= selcollist COMMA",
+ /* 379 */ "as ::= ID|STRING",
+ /* 380 */ "indexed_opt ::= indexed_by",
+ /* 381 */ "returning ::=",
+ /* 382 */ "expr ::= term",
+ /* 383 */ "likeop ::= LIKE_KW|MATCH",
+ /* 384 */ "case_operand ::= expr",
+ /* 385 */ "exprlist ::= nexprlist",
+ /* 386 */ "nmnum ::= plus_num",
+ /* 387 */ "nmnum ::= nm",
+ /* 388 */ "nmnum ::= ON",
+ /* 389 */ "nmnum ::= DELETE",
+ /* 390 */ "nmnum ::= DEFAULT",
+ /* 391 */ "plus_num ::= INTEGER|FLOAT",
+ /* 392 */ "foreach_clause ::=",
+ /* 393 */ "foreach_clause ::= FOR EACH ROW",
+ /* 394 */ "trnm ::= nm",
+ /* 395 */ "tridxby ::=",
+ /* 396 */ "database_kw_opt ::= DATABASE",
+ /* 397 */ "database_kw_opt ::=",
+ /* 398 */ "kwcolumn_opt ::=",
+ /* 399 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 400 */ "vtabarglist ::= vtabarg",
+ /* 401 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 402 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 403 */ "anylist ::=",
+ /* 404 */ "anylist ::= anylist LP anylist RP",
+ /* 405 */ "anylist ::= anylist ANY",
+ /* 406 */ "with ::=",
+ /* 407 */ "windowdefn_list ::= windowdefn",
+ /* 408 */ "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
@@ -173406,24 +176116,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
@@ -173477,97 +176177,98 @@ static void yy_destructor(
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
- case 204: /* select */
- case 239: /* selectnowith */
- case 240: /* oneselect */
- case 252: /* values */
+ case 205: /* select */
+ case 240: /* selectnowith */
+ case 241: /* oneselect */
+ case 253: /* values */
+ case 255: /* mvalues */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy47));
-}
- break;
- case 216: /* term */
- case 217: /* expr */
- case 246: /* where_opt */
- case 248: /* having_opt */
- case 267: /* where_opt_ret */
- case 278: /* case_operand */
- case 280: /* case_else */
- case 283: /* vinto */
- case 290: /* when_clause */
- case 295: /* key_opt */
- case 311: /* filter_clause */
+sqlite3SelectDelete(pParse->db, (yypminor->yy555));
+}
+ break;
+ case 217: /* term */
+ case 218: /* expr */
+ case 247: /* where_opt */
+ case 249: /* having_opt */
+ case 269: /* where_opt_ret */
+ case 280: /* case_operand */
+ case 282: /* case_else */
+ case 285: /* vinto */
+ case 292: /* when_clause */
+ case 297: /* key_opt */
+ case 314: /* filter_clause */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy528));
-}
- break;
- case 221: /* eidlist_opt */
- case 231: /* sortlist */
- case 232: /* eidlist */
- case 244: /* selcollist */
- case 247: /* groupby_opt */
- case 249: /* orderby_opt */
- case 253: /* nexprlist */
- case 254: /* sclp */
- case 261: /* exprlist */
- case 268: /* setlist */
- case 277: /* paren_exprlist */
- case 279: /* case_exprlist */
- case 310: /* part_opt */
+sqlite3ExprDelete(pParse->db, (yypminor->yy454));
+}
+ break;
+ case 222: /* eidlist_opt */
+ case 232: /* sortlist */
+ case 233: /* eidlist */
+ case 245: /* selcollist */
+ case 248: /* groupby_opt */
+ case 250: /* orderby_opt */
+ case 254: /* nexprlist */
+ case 256: /* sclp */
+ case 263: /* exprlist */
+ case 270: /* setlist */
+ case 279: /* paren_exprlist */
+ case 281: /* case_exprlist */
+ case 313: /* part_opt */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
}
break;
- case 238: /* fullname */
- case 245: /* from */
- case 256: /* seltablist */
- case 257: /* stl_prefix */
- case 262: /* xfullname */
+ case 239: /* fullname */
+ case 246: /* from */
+ case 258: /* seltablist */
+ case 259: /* stl_prefix */
+ case 264: /* xfullname */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy131));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy203));
}
break;
- case 241: /* wqlist */
+ case 242: /* wqlist */
{
-sqlite3WithDelete(pParse->db, (yypminor->yy521));
+sqlite3WithDelete(pParse->db, (yypminor->yy59));
}
break;
- case 251: /* window_clause */
- case 306: /* windowdefn_list */
+ case 252: /* window_clause */
+ case 309: /* windowdefn_list */
{
-sqlite3WindowListDelete(pParse->db, (yypminor->yy41));
+sqlite3WindowListDelete(pParse->db, (yypminor->yy211));
}
break;
- case 263: /* idlist */
- case 270: /* idlist_opt */
+ case 265: /* idlist */
+ case 272: /* idlist_opt */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy254));
+sqlite3IdListDelete(pParse->db, (yypminor->yy132));
}
break;
- case 273: /* filter_over */
- case 307: /* windowdefn */
- case 308: /* window */
- case 309: /* frame_opt */
- case 312: /* over_clause */
+ case 275: /* filter_over */
+ case 310: /* windowdefn */
+ case 311: /* window */
+ case 312: /* frame_opt */
+ case 315: /* over_clause */
{
-sqlite3WindowDelete(pParse->db, (yypminor->yy41));
+sqlite3WindowDelete(pParse->db, (yypminor->yy211));
}
break;
- case 286: /* trigger_cmd_list */
- case 291: /* trigger_cmd */
+ case 288: /* trigger_cmd_list */
+ case 293: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy33));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427));
}
break;
- case 288: /* trigger_event */
+ case 290: /* trigger_event */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy180).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy286).b);
}
break;
- case 314: /* frame_bound */
- case 315: /* frame_bound_s */
- case 316: /* frame_bound_e */
+ case 317: /* frame_bound */
+ case 318: /* frame_bound_s */
+ case 319: /* frame_bound_e */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy595).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr);
}
break;
/********* End destructor definitions *****************************************/
@@ -173601,9 +176302,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
}
@@ -173786,7 +176504,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
@@ -173830,25 +176548,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;
@@ -173858,411 +176570,415 @@ static void yy_shift(
/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
** of that rule */
static const YYCODETYPE yyRuleInfoLhs[] = {
- 189, /* (0) explain ::= EXPLAIN */
- 189, /* (1) explain ::= EXPLAIN QUERY PLAN */
- 188, /* (2) cmdx ::= cmd */
- 190, /* (3) cmd ::= BEGIN transtype trans_opt */
- 191, /* (4) transtype ::= */
- 191, /* (5) transtype ::= DEFERRED */
- 191, /* (6) transtype ::= IMMEDIATE */
- 191, /* (7) transtype ::= EXCLUSIVE */
- 190, /* (8) cmd ::= COMMIT|END trans_opt */
- 190, /* (9) cmd ::= ROLLBACK trans_opt */
- 190, /* (10) cmd ::= SAVEPOINT nm */
- 190, /* (11) cmd ::= RELEASE savepoint_opt nm */
- 190, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
- 195, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
- 197, /* (14) createkw ::= CREATE */
- 199, /* (15) ifnotexists ::= */
- 199, /* (16) ifnotexists ::= IF NOT EXISTS */
- 198, /* (17) temp ::= TEMP */
- 198, /* (18) temp ::= */
- 196, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */
- 196, /* (20) create_table_args ::= AS select */
- 203, /* (21) table_option_set ::= */
- 203, /* (22) table_option_set ::= table_option_set COMMA table_option */
- 205, /* (23) table_option ::= WITHOUT nm */
- 205, /* (24) table_option ::= nm */
- 206, /* (25) columnname ::= nm typetoken */
- 208, /* (26) typetoken ::= */
- 208, /* (27) typetoken ::= typename LP signed RP */
- 208, /* (28) typetoken ::= typename LP signed COMMA signed RP */
- 209, /* (29) typename ::= typename ID|STRING */
- 213, /* (30) scanpt ::= */
- 214, /* (31) scantok ::= */
- 215, /* (32) ccons ::= CONSTRAINT nm */
- 215, /* (33) ccons ::= DEFAULT scantok term */
- 215, /* (34) ccons ::= DEFAULT LP expr RP */
- 215, /* (35) ccons ::= DEFAULT PLUS scantok term */
- 215, /* (36) ccons ::= DEFAULT MINUS scantok term */
- 215, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */
- 215, /* (38) ccons ::= NOT NULL onconf */
- 215, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */
- 215, /* (40) ccons ::= UNIQUE onconf */
- 215, /* (41) ccons ::= CHECK LP expr RP */
- 215, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */
- 215, /* (43) ccons ::= defer_subclause */
- 215, /* (44) ccons ::= COLLATE ID|STRING */
- 224, /* (45) generated ::= LP expr RP */
- 224, /* (46) generated ::= LP expr RP ID */
- 220, /* (47) autoinc ::= */
- 220, /* (48) autoinc ::= AUTOINCR */
- 222, /* (49) refargs ::= */
- 222, /* (50) refargs ::= refargs refarg */
- 225, /* (51) refarg ::= MATCH nm */
- 225, /* (52) refarg ::= ON INSERT refact */
- 225, /* (53) refarg ::= ON DELETE refact */
- 225, /* (54) refarg ::= ON UPDATE refact */
- 226, /* (55) refact ::= SET NULL */
- 226, /* (56) refact ::= SET DEFAULT */
- 226, /* (57) refact ::= CASCADE */
- 226, /* (58) refact ::= RESTRICT */
- 226, /* (59) refact ::= NO ACTION */
- 223, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- 223, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- 227, /* (62) init_deferred_pred_opt ::= */
- 227, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */
- 227, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
- 202, /* (65) conslist_opt ::= */
- 229, /* (66) tconscomma ::= COMMA */
- 230, /* (67) tcons ::= CONSTRAINT nm */
- 230, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
- 230, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */
- 230, /* (70) tcons ::= CHECK LP expr RP onconf */
- 230, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
- 233, /* (72) defer_subclause_opt ::= */
- 218, /* (73) onconf ::= */
- 218, /* (74) onconf ::= ON CONFLICT resolvetype */
- 234, /* (75) orconf ::= */
- 234, /* (76) orconf ::= OR resolvetype */
- 235, /* (77) resolvetype ::= IGNORE */
- 235, /* (78) resolvetype ::= REPLACE */
- 190, /* (79) cmd ::= DROP TABLE ifexists fullname */
- 237, /* (80) ifexists ::= IF EXISTS */
- 237, /* (81) ifexists ::= */
- 190, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
- 190, /* (83) cmd ::= DROP VIEW ifexists fullname */
- 190, /* (84) cmd ::= select */
- 204, /* (85) select ::= WITH wqlist selectnowith */
- 204, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */
- 204, /* (87) select ::= selectnowith */
- 239, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */
- 242, /* (89) multiselect_op ::= UNION */
- 242, /* (90) multiselect_op ::= UNION ALL */
- 242, /* (91) multiselect_op ::= EXCEPT|INTERSECT */
- 240, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
- 240, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
- 252, /* (94) values ::= VALUES LP nexprlist RP */
- 252, /* (95) values ::= values COMMA LP nexprlist RP */
- 243, /* (96) distinct ::= DISTINCT */
- 243, /* (97) distinct ::= ALL */
- 243, /* (98) distinct ::= */
- 254, /* (99) sclp ::= */
- 244, /* (100) selcollist ::= sclp scanpt expr scanpt as */
- 244, /* (101) selcollist ::= sclp scanpt STAR */
- 244, /* (102) selcollist ::= sclp scanpt nm DOT STAR */
- 255, /* (103) as ::= AS nm */
- 255, /* (104) as ::= */
- 245, /* (105) from ::= */
- 245, /* (106) from ::= FROM seltablist */
- 257, /* (107) stl_prefix ::= seltablist joinop */
- 257, /* (108) stl_prefix ::= */
- 256, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */
- 256, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
- 256, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
- 256, /* (112) seltablist ::= stl_prefix LP select RP as on_using */
- 256, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */
- 200, /* (114) dbnm ::= */
- 200, /* (115) dbnm ::= DOT nm */
- 238, /* (116) fullname ::= nm */
- 238, /* (117) fullname ::= nm DOT nm */
- 262, /* (118) xfullname ::= nm */
- 262, /* (119) xfullname ::= nm DOT nm */
- 262, /* (120) xfullname ::= nm DOT nm AS nm */
- 262, /* (121) xfullname ::= nm AS nm */
- 258, /* (122) joinop ::= COMMA|JOIN */
- 258, /* (123) joinop ::= JOIN_KW JOIN */
- 258, /* (124) joinop ::= JOIN_KW nm JOIN */
- 258, /* (125) joinop ::= JOIN_KW nm nm JOIN */
- 259, /* (126) on_using ::= ON expr */
- 259, /* (127) on_using ::= USING LP idlist RP */
- 259, /* (128) on_using ::= */
- 264, /* (129) indexed_opt ::= */
- 260, /* (130) indexed_by ::= INDEXED BY nm */
- 260, /* (131) indexed_by ::= NOT INDEXED */
- 249, /* (132) orderby_opt ::= */
- 249, /* (133) orderby_opt ::= ORDER BY sortlist */
- 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
- 231, /* (135) sortlist ::= expr sortorder nulls */
- 219, /* (136) sortorder ::= ASC */
- 219, /* (137) sortorder ::= DESC */
- 219, /* (138) sortorder ::= */
- 265, /* (139) nulls ::= NULLS FIRST */
- 265, /* (140) nulls ::= NULLS LAST */
- 265, /* (141) nulls ::= */
- 247, /* (142) groupby_opt ::= */
- 247, /* (143) groupby_opt ::= GROUP BY nexprlist */
- 248, /* (144) having_opt ::= */
- 248, /* (145) having_opt ::= HAVING expr */
- 250, /* (146) limit_opt ::= */
- 250, /* (147) limit_opt ::= LIMIT expr */
- 250, /* (148) limit_opt ::= LIMIT expr OFFSET expr */
- 250, /* (149) limit_opt ::= LIMIT expr COMMA expr */
- 190, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
- 246, /* (151) where_opt ::= */
- 246, /* (152) where_opt ::= WHERE expr */
- 267, /* (153) where_opt_ret ::= */
- 267, /* (154) where_opt_ret ::= WHERE expr */
- 267, /* (155) where_opt_ret ::= RETURNING selcollist */
- 267, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */
- 190, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
- 268, /* (158) setlist ::= setlist COMMA nm EQ expr */
- 268, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */
- 268, /* (160) setlist ::= nm EQ expr */
- 268, /* (161) setlist ::= LP idlist RP EQ expr */
- 190, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
- 190, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
- 271, /* (164) upsert ::= */
- 271, /* (165) upsert ::= RETURNING selcollist */
- 271, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
- 271, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
- 271, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */
- 271, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
- 272, /* (170) returning ::= RETURNING selcollist */
- 269, /* (171) insert_cmd ::= INSERT orconf */
- 269, /* (172) insert_cmd ::= REPLACE */
- 270, /* (173) idlist_opt ::= */
- 270, /* (174) idlist_opt ::= LP idlist RP */
- 263, /* (175) idlist ::= idlist COMMA nm */
- 263, /* (176) idlist ::= nm */
- 217, /* (177) expr ::= LP expr RP */
- 217, /* (178) expr ::= ID|INDEXED|JOIN_KW */
- 217, /* (179) expr ::= nm DOT nm */
- 217, /* (180) expr ::= nm DOT nm DOT nm */
- 216, /* (181) term ::= NULL|FLOAT|BLOB */
- 216, /* (182) term ::= STRING */
- 216, /* (183) term ::= INTEGER */
- 217, /* (184) expr ::= VARIABLE */
- 217, /* (185) expr ::= expr COLLATE ID|STRING */
- 217, /* (186) expr ::= CAST LP expr AS typetoken RP */
- 217, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
- 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
- 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
- 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
- 217, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
- 217, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
- 216, /* (193) term ::= CTIME_KW */
- 217, /* (194) expr ::= LP nexprlist COMMA expr RP */
- 217, /* (195) expr ::= expr AND expr */
- 217, /* (196) expr ::= expr OR expr */
- 217, /* (197) expr ::= expr LT|GT|GE|LE expr */
- 217, /* (198) expr ::= expr EQ|NE expr */
- 217, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- 217, /* (200) expr ::= expr PLUS|MINUS expr */
- 217, /* (201) expr ::= expr STAR|SLASH|REM expr */
- 217, /* (202) expr ::= expr CONCAT expr */
- 274, /* (203) likeop ::= NOT LIKE_KW|MATCH */
- 217, /* (204) expr ::= expr likeop expr */
- 217, /* (205) expr ::= expr likeop expr ESCAPE expr */
- 217, /* (206) expr ::= expr ISNULL|NOTNULL */
- 217, /* (207) expr ::= expr NOT NULL */
- 217, /* (208) expr ::= expr IS expr */
- 217, /* (209) expr ::= expr IS NOT expr */
- 217, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */
- 217, /* (211) expr ::= expr IS DISTINCT FROM expr */
- 217, /* (212) expr ::= NOT expr */
- 217, /* (213) expr ::= BITNOT expr */
- 217, /* (214) expr ::= PLUS|MINUS expr */
- 217, /* (215) expr ::= expr PTR expr */
- 275, /* (216) between_op ::= BETWEEN */
- 275, /* (217) between_op ::= NOT BETWEEN */
- 217, /* (218) expr ::= expr between_op expr AND expr */
- 276, /* (219) in_op ::= IN */
- 276, /* (220) in_op ::= NOT IN */
- 217, /* (221) expr ::= expr in_op LP exprlist RP */
- 217, /* (222) expr ::= LP select RP */
- 217, /* (223) expr ::= expr in_op LP select RP */
- 217, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */
- 217, /* (225) expr ::= EXISTS LP select RP */
- 217, /* (226) expr ::= CASE case_operand case_exprlist case_else END */
- 279, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */
- 279, /* (228) case_exprlist ::= WHEN expr THEN expr */
- 280, /* (229) case_else ::= ELSE expr */
- 280, /* (230) case_else ::= */
- 278, /* (231) case_operand ::= */
- 261, /* (232) exprlist ::= */
- 253, /* (233) nexprlist ::= nexprlist COMMA expr */
- 253, /* (234) nexprlist ::= expr */
- 277, /* (235) paren_exprlist ::= */
- 277, /* (236) paren_exprlist ::= LP exprlist RP */
- 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
- 281, /* (238) uniqueflag ::= UNIQUE */
- 281, /* (239) uniqueflag ::= */
- 221, /* (240) eidlist_opt ::= */
- 221, /* (241) eidlist_opt ::= LP eidlist RP */
- 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */
- 232, /* (243) eidlist ::= nm collate sortorder */
- 282, /* (244) collate ::= */
- 282, /* (245) collate ::= COLLATE ID|STRING */
- 190, /* (246) cmd ::= DROP INDEX ifexists fullname */
- 190, /* (247) cmd ::= VACUUM vinto */
- 190, /* (248) cmd ::= VACUUM nm vinto */
- 283, /* (249) vinto ::= INTO expr */
- 283, /* (250) vinto ::= */
- 190, /* (251) cmd ::= PRAGMA nm dbnm */
- 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */
- 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */
- 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */
- 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */
- 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */
- 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */
- 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
- 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
- 287, /* (260) trigger_time ::= BEFORE|AFTER */
- 287, /* (261) trigger_time ::= INSTEAD OF */
- 287, /* (262) trigger_time ::= */
- 288, /* (263) trigger_event ::= DELETE|INSERT */
- 288, /* (264) trigger_event ::= UPDATE */
- 288, /* (265) trigger_event ::= UPDATE OF idlist */
- 290, /* (266) when_clause ::= */
- 290, /* (267) when_clause ::= WHEN expr */
- 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
- 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */
- 292, /* (270) trnm ::= nm DOT nm */
- 293, /* (271) tridxby ::= INDEXED BY nm */
- 293, /* (272) tridxby ::= NOT INDEXED */
- 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
- 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
- 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
- 291, /* (276) trigger_cmd ::= scanpt select scanpt */
- 217, /* (277) expr ::= RAISE LP IGNORE RP */
- 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */
- 236, /* (279) raisetype ::= ROLLBACK */
- 236, /* (280) raisetype ::= ABORT */
- 236, /* (281) raisetype ::= FAIL */
- 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */
- 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
- 190, /* (284) cmd ::= DETACH database_kw_opt expr */
- 295, /* (285) key_opt ::= */
- 295, /* (286) key_opt ::= KEY expr */
- 190, /* (287) cmd ::= REINDEX */
- 190, /* (288) cmd ::= REINDEX nm dbnm */
- 190, /* (289) cmd ::= ANALYZE */
- 190, /* (290) cmd ::= ANALYZE nm dbnm */
- 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */
- 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
- 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
- 296, /* (294) add_column_fullname ::= fullname */
- 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
- 190, /* (296) cmd ::= create_vtab */
- 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */
- 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
- 300, /* (299) vtabarg ::= */
- 301, /* (300) vtabargtoken ::= ANY */
- 301, /* (301) vtabargtoken ::= lp anylist RP */
- 302, /* (302) lp ::= LP */
- 266, /* (303) with ::= WITH wqlist */
- 266, /* (304) with ::= WITH RECURSIVE wqlist */
- 305, /* (305) wqas ::= AS */
- 305, /* (306) wqas ::= AS MATERIALIZED */
- 305, /* (307) wqas ::= AS NOT MATERIALIZED */
- 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */
- 241, /* (309) wqlist ::= wqitem */
- 241, /* (310) wqlist ::= wqlist COMMA wqitem */
- 306, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */
- 307, /* (312) windowdefn ::= nm AS LP window RP */
- 308, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
- 308, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
- 308, /* (315) window ::= ORDER BY sortlist frame_opt */
- 308, /* (316) window ::= nm ORDER BY sortlist frame_opt */
- 308, /* (317) window ::= nm frame_opt */
- 309, /* (318) frame_opt ::= */
- 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
- 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
- 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */
- 315, /* (322) frame_bound_s ::= frame_bound */
- 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */
- 316, /* (324) frame_bound_e ::= frame_bound */
- 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */
- 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */
- 314, /* (327) frame_bound ::= CURRENT ROW */
- 317, /* (328) frame_exclude_opt ::= */
- 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */
- 318, /* (330) frame_exclude ::= NO OTHERS */
- 318, /* (331) frame_exclude ::= CURRENT ROW */
- 318, /* (332) frame_exclude ::= GROUP|TIES */
- 251, /* (333) window_clause ::= WINDOW windowdefn_list */
- 273, /* (334) filter_over ::= filter_clause over_clause */
- 273, /* (335) filter_over ::= over_clause */
- 273, /* (336) filter_over ::= filter_clause */
- 312, /* (337) over_clause ::= OVER LP window RP */
- 312, /* (338) over_clause ::= OVER nm */
- 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */
- 185, /* (340) input ::= cmdlist */
- 186, /* (341) cmdlist ::= cmdlist ecmd */
- 186, /* (342) cmdlist ::= ecmd */
- 187, /* (343) ecmd ::= SEMI */
- 187, /* (344) ecmd ::= cmdx SEMI */
- 187, /* (345) ecmd ::= explain cmdx SEMI */
- 192, /* (346) trans_opt ::= */
- 192, /* (347) trans_opt ::= TRANSACTION */
- 192, /* (348) trans_opt ::= TRANSACTION nm */
- 194, /* (349) savepoint_opt ::= SAVEPOINT */
- 194, /* (350) savepoint_opt ::= */
- 190, /* (351) cmd ::= create_table create_table_args */
- 203, /* (352) table_option_set ::= table_option */
- 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */
- 201, /* (354) columnlist ::= columnname carglist */
- 193, /* (355) nm ::= ID|INDEXED|JOIN_KW */
- 193, /* (356) nm ::= STRING */
- 208, /* (357) typetoken ::= typename */
- 209, /* (358) typename ::= ID|STRING */
- 210, /* (359) signed ::= plus_num */
- 210, /* (360) signed ::= minus_num */
- 207, /* (361) carglist ::= carglist ccons */
- 207, /* (362) carglist ::= */
- 215, /* (363) ccons ::= NULL onconf */
- 215, /* (364) ccons ::= GENERATED ALWAYS AS generated */
- 215, /* (365) ccons ::= AS generated */
- 202, /* (366) conslist_opt ::= COMMA conslist */
- 228, /* (367) conslist ::= conslist tconscomma tcons */
- 228, /* (368) conslist ::= tcons */
- 229, /* (369) tconscomma ::= */
- 233, /* (370) defer_subclause_opt ::= defer_subclause */
- 235, /* (371) resolvetype ::= raisetype */
- 239, /* (372) selectnowith ::= oneselect */
- 240, /* (373) oneselect ::= values */
- 254, /* (374) sclp ::= selcollist COMMA */
- 255, /* (375) as ::= ID|STRING */
- 264, /* (376) indexed_opt ::= indexed_by */
- 272, /* (377) returning ::= */
- 217, /* (378) expr ::= term */
- 274, /* (379) likeop ::= LIKE_KW|MATCH */
- 278, /* (380) case_operand ::= expr */
- 261, /* (381) exprlist ::= nexprlist */
- 284, /* (382) nmnum ::= plus_num */
- 284, /* (383) nmnum ::= nm */
- 284, /* (384) nmnum ::= ON */
- 284, /* (385) nmnum ::= DELETE */
- 284, /* (386) nmnum ::= DEFAULT */
- 211, /* (387) plus_num ::= INTEGER|FLOAT */
- 289, /* (388) foreach_clause ::= */
- 289, /* (389) foreach_clause ::= FOR EACH ROW */
- 292, /* (390) trnm ::= nm */
- 293, /* (391) tridxby ::= */
- 294, /* (392) database_kw_opt ::= DATABASE */
- 294, /* (393) database_kw_opt ::= */
- 297, /* (394) kwcolumn_opt ::= */
- 297, /* (395) kwcolumn_opt ::= COLUMNKW */
- 299, /* (396) vtabarglist ::= vtabarg */
- 299, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
- 300, /* (398) vtabarg ::= vtabarg vtabargtoken */
- 303, /* (399) anylist ::= */
- 303, /* (400) anylist ::= anylist LP anylist RP */
- 303, /* (401) anylist ::= anylist ANY */
- 266, /* (402) with ::= */
- 306, /* (403) windowdefn_list ::= windowdefn */
- 308, /* (404) window ::= frame_opt */
+ 190, /* (0) explain ::= EXPLAIN */
+ 190, /* (1) explain ::= EXPLAIN QUERY PLAN */
+ 189, /* (2) cmdx ::= cmd */
+ 191, /* (3) cmd ::= BEGIN transtype trans_opt */
+ 192, /* (4) transtype ::= */
+ 192, /* (5) transtype ::= DEFERRED */
+ 192, /* (6) transtype ::= IMMEDIATE */
+ 192, /* (7) transtype ::= EXCLUSIVE */
+ 191, /* (8) cmd ::= COMMIT|END trans_opt */
+ 191, /* (9) cmd ::= ROLLBACK trans_opt */
+ 191, /* (10) cmd ::= SAVEPOINT nm */
+ 191, /* (11) cmd ::= RELEASE savepoint_opt nm */
+ 191, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ 196, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ 198, /* (14) createkw ::= CREATE */
+ 200, /* (15) ifnotexists ::= */
+ 200, /* (16) ifnotexists ::= IF NOT EXISTS */
+ 199, /* (17) temp ::= TEMP */
+ 199, /* (18) temp ::= */
+ 197, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */
+ 197, /* (20) create_table_args ::= AS select */
+ 204, /* (21) table_option_set ::= */
+ 204, /* (22) table_option_set ::= table_option_set COMMA table_option */
+ 206, /* (23) table_option ::= WITHOUT nm */
+ 206, /* (24) table_option ::= nm */
+ 207, /* (25) columnname ::= nm typetoken */
+ 209, /* (26) typetoken ::= */
+ 209, /* (27) typetoken ::= typename LP signed RP */
+ 209, /* (28) typetoken ::= typename LP signed COMMA signed RP */
+ 210, /* (29) typename ::= typename ID|STRING */
+ 214, /* (30) scanpt ::= */
+ 215, /* (31) scantok ::= */
+ 216, /* (32) ccons ::= CONSTRAINT nm */
+ 216, /* (33) ccons ::= DEFAULT scantok term */
+ 216, /* (34) ccons ::= DEFAULT LP expr RP */
+ 216, /* (35) ccons ::= DEFAULT PLUS scantok term */
+ 216, /* (36) ccons ::= DEFAULT MINUS scantok term */
+ 216, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */
+ 216, /* (38) ccons ::= NOT NULL onconf */
+ 216, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ 216, /* (40) ccons ::= UNIQUE onconf */
+ 216, /* (41) ccons ::= CHECK LP expr RP */
+ 216, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */
+ 216, /* (43) ccons ::= defer_subclause */
+ 216, /* (44) ccons ::= COLLATE ID|STRING */
+ 225, /* (45) generated ::= LP expr RP */
+ 225, /* (46) generated ::= LP expr RP ID */
+ 221, /* (47) autoinc ::= */
+ 221, /* (48) autoinc ::= AUTOINCR */
+ 223, /* (49) refargs ::= */
+ 223, /* (50) refargs ::= refargs refarg */
+ 226, /* (51) refarg ::= MATCH nm */
+ 226, /* (52) refarg ::= ON INSERT refact */
+ 226, /* (53) refarg ::= ON DELETE refact */
+ 226, /* (54) refarg ::= ON UPDATE refact */
+ 227, /* (55) refact ::= SET NULL */
+ 227, /* (56) refact ::= SET DEFAULT */
+ 227, /* (57) refact ::= CASCADE */
+ 227, /* (58) refact ::= RESTRICT */
+ 227, /* (59) refact ::= NO ACTION */
+ 224, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ 224, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ 228, /* (62) init_deferred_pred_opt ::= */
+ 228, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ 228, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ 203, /* (65) conslist_opt ::= */
+ 230, /* (66) tconscomma ::= COMMA */
+ 231, /* (67) tcons ::= CONSTRAINT nm */
+ 231, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ 231, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */
+ 231, /* (70) tcons ::= CHECK LP expr RP onconf */
+ 231, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ 234, /* (72) defer_subclause_opt ::= */
+ 219, /* (73) onconf ::= */
+ 219, /* (74) onconf ::= ON CONFLICT resolvetype */
+ 235, /* (75) orconf ::= */
+ 235, /* (76) orconf ::= OR resolvetype */
+ 236, /* (77) resolvetype ::= IGNORE */
+ 236, /* (78) resolvetype ::= REPLACE */
+ 191, /* (79) cmd ::= DROP TABLE ifexists fullname */
+ 238, /* (80) ifexists ::= IF EXISTS */
+ 238, /* (81) ifexists ::= */
+ 191, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ 191, /* (83) cmd ::= DROP VIEW ifexists fullname */
+ 191, /* (84) cmd ::= select */
+ 205, /* (85) select ::= WITH wqlist selectnowith */
+ 205, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */
+ 205, /* (87) select ::= selectnowith */
+ 240, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */
+ 243, /* (89) multiselect_op ::= UNION */
+ 243, /* (90) multiselect_op ::= UNION ALL */
+ 243, /* (91) multiselect_op ::= EXCEPT|INTERSECT */
+ 241, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ 241, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ 253, /* (94) values ::= VALUES LP nexprlist RP */
+ 241, /* (95) oneselect ::= mvalues */
+ 255, /* (96) mvalues ::= values COMMA LP nexprlist RP */
+ 255, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */
+ 244, /* (98) distinct ::= DISTINCT */
+ 244, /* (99) distinct ::= ALL */
+ 244, /* (100) distinct ::= */
+ 256, /* (101) sclp ::= */
+ 245, /* (102) selcollist ::= sclp scanpt expr scanpt as */
+ 245, /* (103) selcollist ::= sclp scanpt STAR */
+ 245, /* (104) selcollist ::= sclp scanpt nm DOT STAR */
+ 257, /* (105) as ::= AS nm */
+ 257, /* (106) as ::= */
+ 246, /* (107) from ::= */
+ 246, /* (108) from ::= FROM seltablist */
+ 259, /* (109) stl_prefix ::= seltablist joinop */
+ 259, /* (110) stl_prefix ::= */
+ 258, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */
+ 258, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
+ 258, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
+ 258, /* (114) seltablist ::= stl_prefix LP select RP as on_using */
+ 258, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */
+ 201, /* (116) dbnm ::= */
+ 201, /* (117) dbnm ::= DOT nm */
+ 239, /* (118) fullname ::= nm */
+ 239, /* (119) fullname ::= nm DOT nm */
+ 264, /* (120) xfullname ::= nm */
+ 264, /* (121) xfullname ::= nm DOT nm */
+ 264, /* (122) xfullname ::= nm DOT nm AS nm */
+ 264, /* (123) xfullname ::= nm AS nm */
+ 260, /* (124) joinop ::= COMMA|JOIN */
+ 260, /* (125) joinop ::= JOIN_KW JOIN */
+ 260, /* (126) joinop ::= JOIN_KW nm JOIN */
+ 260, /* (127) joinop ::= JOIN_KW nm nm JOIN */
+ 261, /* (128) on_using ::= ON expr */
+ 261, /* (129) on_using ::= USING LP idlist RP */
+ 261, /* (130) on_using ::= */
+ 266, /* (131) indexed_opt ::= */
+ 262, /* (132) indexed_by ::= INDEXED BY nm */
+ 262, /* (133) indexed_by ::= NOT INDEXED */
+ 250, /* (134) orderby_opt ::= */
+ 250, /* (135) orderby_opt ::= ORDER BY sortlist */
+ 232, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */
+ 232, /* (137) sortlist ::= expr sortorder nulls */
+ 220, /* (138) sortorder ::= ASC */
+ 220, /* (139) sortorder ::= DESC */
+ 220, /* (140) sortorder ::= */
+ 267, /* (141) nulls ::= NULLS FIRST */
+ 267, /* (142) nulls ::= NULLS LAST */
+ 267, /* (143) nulls ::= */
+ 248, /* (144) groupby_opt ::= */
+ 248, /* (145) groupby_opt ::= GROUP BY nexprlist */
+ 249, /* (146) having_opt ::= */
+ 249, /* (147) having_opt ::= HAVING expr */
+ 251, /* (148) limit_opt ::= */
+ 251, /* (149) limit_opt ::= LIMIT expr */
+ 251, /* (150) limit_opt ::= LIMIT expr OFFSET expr */
+ 251, /* (151) limit_opt ::= LIMIT expr COMMA expr */
+ 191, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
+ 247, /* (153) where_opt ::= */
+ 247, /* (154) where_opt ::= WHERE expr */
+ 269, /* (155) where_opt_ret ::= */
+ 269, /* (156) where_opt_ret ::= WHERE expr */
+ 269, /* (157) where_opt_ret ::= RETURNING selcollist */
+ 269, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */
+ 191, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
+ 270, /* (160) setlist ::= setlist COMMA nm EQ expr */
+ 270, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ 270, /* (162) setlist ::= nm EQ expr */
+ 270, /* (163) setlist ::= LP idlist RP EQ expr */
+ 191, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ 191, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
+ 273, /* (166) upsert ::= */
+ 273, /* (167) upsert ::= RETURNING selcollist */
+ 273, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
+ 273, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
+ 273, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */
+ 273, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
+ 274, /* (172) returning ::= RETURNING selcollist */
+ 271, /* (173) insert_cmd ::= INSERT orconf */
+ 271, /* (174) insert_cmd ::= REPLACE */
+ 272, /* (175) idlist_opt ::= */
+ 272, /* (176) idlist_opt ::= LP idlist RP */
+ 265, /* (177) idlist ::= idlist COMMA nm */
+ 265, /* (178) idlist ::= nm */
+ 218, /* (179) expr ::= LP expr RP */
+ 218, /* (180) expr ::= ID|INDEXED|JOIN_KW */
+ 218, /* (181) expr ::= nm DOT nm */
+ 218, /* (182) expr ::= nm DOT nm DOT nm */
+ 217, /* (183) term ::= NULL|FLOAT|BLOB */
+ 217, /* (184) term ::= STRING */
+ 217, /* (185) term ::= INTEGER */
+ 218, /* (186) expr ::= VARIABLE */
+ 218, /* (187) expr ::= expr COLLATE ID|STRING */
+ 218, /* (188) expr ::= CAST LP expr AS typetoken RP */
+ 218, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
+ 218, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
+ 218, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
+ 218, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
+ 218, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
+ 218, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
+ 217, /* (195) term ::= CTIME_KW */
+ 218, /* (196) expr ::= LP nexprlist COMMA expr RP */
+ 218, /* (197) expr ::= expr AND expr */
+ 218, /* (198) expr ::= expr OR expr */
+ 218, /* (199) expr ::= expr LT|GT|GE|LE expr */
+ 218, /* (200) expr ::= expr EQ|NE expr */
+ 218, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ 218, /* (202) expr ::= expr PLUS|MINUS expr */
+ 218, /* (203) expr ::= expr STAR|SLASH|REM expr */
+ 218, /* (204) expr ::= expr CONCAT expr */
+ 276, /* (205) likeop ::= NOT LIKE_KW|MATCH */
+ 218, /* (206) expr ::= expr likeop expr */
+ 218, /* (207) expr ::= expr likeop expr ESCAPE expr */
+ 218, /* (208) expr ::= expr ISNULL|NOTNULL */
+ 218, /* (209) expr ::= expr NOT NULL */
+ 218, /* (210) expr ::= expr IS expr */
+ 218, /* (211) expr ::= expr IS NOT expr */
+ 218, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */
+ 218, /* (213) expr ::= expr IS DISTINCT FROM expr */
+ 218, /* (214) expr ::= NOT expr */
+ 218, /* (215) expr ::= BITNOT expr */
+ 218, /* (216) expr ::= PLUS|MINUS expr */
+ 218, /* (217) expr ::= expr PTR expr */
+ 277, /* (218) between_op ::= BETWEEN */
+ 277, /* (219) between_op ::= NOT BETWEEN */
+ 218, /* (220) expr ::= expr between_op expr AND expr */
+ 278, /* (221) in_op ::= IN */
+ 278, /* (222) in_op ::= NOT IN */
+ 218, /* (223) expr ::= expr in_op LP exprlist RP */
+ 218, /* (224) expr ::= LP select RP */
+ 218, /* (225) expr ::= expr in_op LP select RP */
+ 218, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */
+ 218, /* (227) expr ::= EXISTS LP select RP */
+ 218, /* (228) expr ::= CASE case_operand case_exprlist case_else END */
+ 281, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ 281, /* (230) case_exprlist ::= WHEN expr THEN expr */
+ 282, /* (231) case_else ::= ELSE expr */
+ 282, /* (232) case_else ::= */
+ 280, /* (233) case_operand ::= */
+ 263, /* (234) exprlist ::= */
+ 254, /* (235) nexprlist ::= nexprlist COMMA expr */
+ 254, /* (236) nexprlist ::= expr */
+ 279, /* (237) paren_exprlist ::= */
+ 279, /* (238) paren_exprlist ::= LP exprlist RP */
+ 191, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ 283, /* (240) uniqueflag ::= UNIQUE */
+ 283, /* (241) uniqueflag ::= */
+ 222, /* (242) eidlist_opt ::= */
+ 222, /* (243) eidlist_opt ::= LP eidlist RP */
+ 233, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */
+ 233, /* (245) eidlist ::= nm collate sortorder */
+ 284, /* (246) collate ::= */
+ 284, /* (247) collate ::= COLLATE ID|STRING */
+ 191, /* (248) cmd ::= DROP INDEX ifexists fullname */
+ 191, /* (249) cmd ::= VACUUM vinto */
+ 191, /* (250) cmd ::= VACUUM nm vinto */
+ 285, /* (251) vinto ::= INTO expr */
+ 285, /* (252) vinto ::= */
+ 191, /* (253) cmd ::= PRAGMA nm dbnm */
+ 191, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ 191, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ 191, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ 191, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ 212, /* (258) plus_num ::= PLUS INTEGER|FLOAT */
+ 213, /* (259) minus_num ::= MINUS INTEGER|FLOAT */
+ 191, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ 287, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ 289, /* (262) trigger_time ::= BEFORE|AFTER */
+ 289, /* (263) trigger_time ::= INSTEAD OF */
+ 289, /* (264) trigger_time ::= */
+ 290, /* (265) trigger_event ::= DELETE|INSERT */
+ 290, /* (266) trigger_event ::= UPDATE */
+ 290, /* (267) trigger_event ::= UPDATE OF idlist */
+ 292, /* (268) when_clause ::= */
+ 292, /* (269) when_clause ::= WHEN expr */
+ 288, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ 288, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */
+ 294, /* (272) trnm ::= nm DOT nm */
+ 295, /* (273) tridxby ::= INDEXED BY nm */
+ 295, /* (274) tridxby ::= NOT INDEXED */
+ 293, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+ 293, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ 293, /* (278) trigger_cmd ::= scanpt select scanpt */
+ 218, /* (279) expr ::= RAISE LP IGNORE RP */
+ 218, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */
+ 237, /* (281) raisetype ::= ROLLBACK */
+ 237, /* (282) raisetype ::= ABORT */
+ 237, /* (283) raisetype ::= FAIL */
+ 191, /* (284) cmd ::= DROP TRIGGER ifexists fullname */
+ 191, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ 191, /* (286) cmd ::= DETACH database_kw_opt expr */
+ 297, /* (287) key_opt ::= */
+ 297, /* (288) key_opt ::= KEY expr */
+ 191, /* (289) cmd ::= REINDEX */
+ 191, /* (290) cmd ::= REINDEX nm dbnm */
+ 191, /* (291) cmd ::= ANALYZE */
+ 191, /* (292) cmd ::= ANALYZE nm dbnm */
+ 191, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ 191, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ 191, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+ 298, /* (296) add_column_fullname ::= fullname */
+ 191, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ 191, /* (298) cmd ::= create_vtab */
+ 191, /* (299) cmd ::= create_vtab LP vtabarglist RP */
+ 300, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 302, /* (301) vtabarg ::= */
+ 303, /* (302) vtabargtoken ::= ANY */
+ 303, /* (303) vtabargtoken ::= lp anylist RP */
+ 304, /* (304) lp ::= LP */
+ 268, /* (305) with ::= WITH wqlist */
+ 268, /* (306) with ::= WITH RECURSIVE wqlist */
+ 307, /* (307) wqas ::= AS */
+ 307, /* (308) wqas ::= AS MATERIALIZED */
+ 307, /* (309) wqas ::= AS NOT MATERIALIZED */
+ 306, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */
+ 308, /* (311) withnm ::= nm */
+ 242, /* (312) wqlist ::= wqitem */
+ 242, /* (313) wqlist ::= wqlist COMMA wqitem */
+ 309, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ 310, /* (315) windowdefn ::= nm AS LP window RP */
+ 311, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ 311, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ 311, /* (318) window ::= ORDER BY sortlist frame_opt */
+ 311, /* (319) window ::= nm ORDER BY sortlist frame_opt */
+ 311, /* (320) window ::= nm frame_opt */
+ 312, /* (321) frame_opt ::= */
+ 312, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ 312, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ 316, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */
+ 318, /* (325) frame_bound_s ::= frame_bound */
+ 318, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */
+ 319, /* (327) frame_bound_e ::= frame_bound */
+ 319, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ 317, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */
+ 317, /* (330) frame_bound ::= CURRENT ROW */
+ 320, /* (331) frame_exclude_opt ::= */
+ 320, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */
+ 321, /* (333) frame_exclude ::= NO OTHERS */
+ 321, /* (334) frame_exclude ::= CURRENT ROW */
+ 321, /* (335) frame_exclude ::= GROUP|TIES */
+ 252, /* (336) window_clause ::= WINDOW windowdefn_list */
+ 275, /* (337) filter_over ::= filter_clause over_clause */
+ 275, /* (338) filter_over ::= over_clause */
+ 275, /* (339) filter_over ::= filter_clause */
+ 315, /* (340) over_clause ::= OVER LP window RP */
+ 315, /* (341) over_clause ::= OVER nm */
+ 314, /* (342) filter_clause ::= FILTER LP WHERE expr RP */
+ 217, /* (343) term ::= QNUMBER */
+ 186, /* (344) input ::= cmdlist */
+ 187, /* (345) cmdlist ::= cmdlist ecmd */
+ 187, /* (346) cmdlist ::= ecmd */
+ 188, /* (347) ecmd ::= SEMI */
+ 188, /* (348) ecmd ::= cmdx SEMI */
+ 188, /* (349) ecmd ::= explain cmdx SEMI */
+ 193, /* (350) trans_opt ::= */
+ 193, /* (351) trans_opt ::= TRANSACTION */
+ 193, /* (352) trans_opt ::= TRANSACTION nm */
+ 195, /* (353) savepoint_opt ::= SAVEPOINT */
+ 195, /* (354) savepoint_opt ::= */
+ 191, /* (355) cmd ::= create_table create_table_args */
+ 204, /* (356) table_option_set ::= table_option */
+ 202, /* (357) columnlist ::= columnlist COMMA columnname carglist */
+ 202, /* (358) columnlist ::= columnname carglist */
+ 194, /* (359) nm ::= ID|INDEXED|JOIN_KW */
+ 194, /* (360) nm ::= STRING */
+ 209, /* (361) typetoken ::= typename */
+ 210, /* (362) typename ::= ID|STRING */
+ 211, /* (363) signed ::= plus_num */
+ 211, /* (364) signed ::= minus_num */
+ 208, /* (365) carglist ::= carglist ccons */
+ 208, /* (366) carglist ::= */
+ 216, /* (367) ccons ::= NULL onconf */
+ 216, /* (368) ccons ::= GENERATED ALWAYS AS generated */
+ 216, /* (369) ccons ::= AS generated */
+ 203, /* (370) conslist_opt ::= COMMA conslist */
+ 229, /* (371) conslist ::= conslist tconscomma tcons */
+ 229, /* (372) conslist ::= tcons */
+ 230, /* (373) tconscomma ::= */
+ 234, /* (374) defer_subclause_opt ::= defer_subclause */
+ 236, /* (375) resolvetype ::= raisetype */
+ 240, /* (376) selectnowith ::= oneselect */
+ 241, /* (377) oneselect ::= values */
+ 256, /* (378) sclp ::= selcollist COMMA */
+ 257, /* (379) as ::= ID|STRING */
+ 266, /* (380) indexed_opt ::= indexed_by */
+ 274, /* (381) returning ::= */
+ 218, /* (382) expr ::= term */
+ 276, /* (383) likeop ::= LIKE_KW|MATCH */
+ 280, /* (384) case_operand ::= expr */
+ 263, /* (385) exprlist ::= nexprlist */
+ 286, /* (386) nmnum ::= plus_num */
+ 286, /* (387) nmnum ::= nm */
+ 286, /* (388) nmnum ::= ON */
+ 286, /* (389) nmnum ::= DELETE */
+ 286, /* (390) nmnum ::= DEFAULT */
+ 212, /* (391) plus_num ::= INTEGER|FLOAT */
+ 291, /* (392) foreach_clause ::= */
+ 291, /* (393) foreach_clause ::= FOR EACH ROW */
+ 294, /* (394) trnm ::= nm */
+ 295, /* (395) tridxby ::= */
+ 296, /* (396) database_kw_opt ::= DATABASE */
+ 296, /* (397) database_kw_opt ::= */
+ 299, /* (398) kwcolumn_opt ::= */
+ 299, /* (399) kwcolumn_opt ::= COLUMNKW */
+ 301, /* (400) vtabarglist ::= vtabarg */
+ 301, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */
+ 302, /* (402) vtabarg ::= vtabarg vtabargtoken */
+ 305, /* (403) anylist ::= */
+ 305, /* (404) anylist ::= anylist LP anylist RP */
+ 305, /* (405) anylist ::= anylist ANY */
+ 268, /* (406) with ::= */
+ 309, /* (407) windowdefn_list ::= windowdefn */
+ 311, /* (408) window ::= frame_opt */
};
/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
@@ -174363,316 +177079,320 @@ static const signed char yyRuleInfoNRhs[] = {
-9, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
-10, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
-4, /* (94) values ::= VALUES LP nexprlist RP */
- -5, /* (95) values ::= values COMMA LP nexprlist RP */
- -1, /* (96) distinct ::= DISTINCT */
- -1, /* (97) distinct ::= ALL */
- 0, /* (98) distinct ::= */
- 0, /* (99) sclp ::= */
- -5, /* (100) selcollist ::= sclp scanpt expr scanpt as */
- -3, /* (101) selcollist ::= sclp scanpt STAR */
- -5, /* (102) selcollist ::= sclp scanpt nm DOT STAR */
- -2, /* (103) as ::= AS nm */
- 0, /* (104) as ::= */
- 0, /* (105) from ::= */
- -2, /* (106) from ::= FROM seltablist */
- -2, /* (107) stl_prefix ::= seltablist joinop */
- 0, /* (108) stl_prefix ::= */
- -5, /* (109) seltablist ::= stl_prefix nm dbnm as on_using */
- -6, /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
- -8, /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
- -6, /* (112) seltablist ::= stl_prefix LP select RP as on_using */
- -6, /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */
- 0, /* (114) dbnm ::= */
- -2, /* (115) dbnm ::= DOT nm */
- -1, /* (116) fullname ::= nm */
- -3, /* (117) fullname ::= nm DOT nm */
- -1, /* (118) xfullname ::= nm */
- -3, /* (119) xfullname ::= nm DOT nm */
- -5, /* (120) xfullname ::= nm DOT nm AS nm */
- -3, /* (121) xfullname ::= nm AS nm */
- -1, /* (122) joinop ::= COMMA|JOIN */
- -2, /* (123) joinop ::= JOIN_KW JOIN */
- -3, /* (124) joinop ::= JOIN_KW nm JOIN */
- -4, /* (125) joinop ::= JOIN_KW nm nm JOIN */
- -2, /* (126) on_using ::= ON expr */
- -4, /* (127) on_using ::= USING LP idlist RP */
- 0, /* (128) on_using ::= */
- 0, /* (129) indexed_opt ::= */
- -3, /* (130) indexed_by ::= INDEXED BY nm */
- -2, /* (131) indexed_by ::= NOT INDEXED */
- 0, /* (132) orderby_opt ::= */
- -3, /* (133) orderby_opt ::= ORDER BY sortlist */
- -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
- -3, /* (135) sortlist ::= expr sortorder nulls */
- -1, /* (136) sortorder ::= ASC */
- -1, /* (137) sortorder ::= DESC */
- 0, /* (138) sortorder ::= */
- -2, /* (139) nulls ::= NULLS FIRST */
- -2, /* (140) nulls ::= NULLS LAST */
- 0, /* (141) nulls ::= */
- 0, /* (142) groupby_opt ::= */
- -3, /* (143) groupby_opt ::= GROUP BY nexprlist */
- 0, /* (144) having_opt ::= */
- -2, /* (145) having_opt ::= HAVING expr */
- 0, /* (146) limit_opt ::= */
- -2, /* (147) limit_opt ::= LIMIT expr */
- -4, /* (148) limit_opt ::= LIMIT expr OFFSET expr */
- -4, /* (149) limit_opt ::= LIMIT expr COMMA expr */
- -6, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
- 0, /* (151) where_opt ::= */
- -2, /* (152) where_opt ::= WHERE expr */
- 0, /* (153) where_opt_ret ::= */
- -2, /* (154) where_opt_ret ::= WHERE expr */
- -2, /* (155) where_opt_ret ::= RETURNING selcollist */
- -4, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */
- -9, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
- -5, /* (158) setlist ::= setlist COMMA nm EQ expr */
- -7, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */
- -3, /* (160) setlist ::= nm EQ expr */
- -5, /* (161) setlist ::= LP idlist RP EQ expr */
- -7, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
- -8, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
- 0, /* (164) upsert ::= */
- -2, /* (165) upsert ::= RETURNING selcollist */
- -12, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
- -9, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
- -5, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */
- -8, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
- -2, /* (170) returning ::= RETURNING selcollist */
- -2, /* (171) insert_cmd ::= INSERT orconf */
- -1, /* (172) insert_cmd ::= REPLACE */
- 0, /* (173) idlist_opt ::= */
- -3, /* (174) idlist_opt ::= LP idlist RP */
- -3, /* (175) idlist ::= idlist COMMA nm */
- -1, /* (176) idlist ::= nm */
- -3, /* (177) expr ::= LP expr RP */
- -1, /* (178) expr ::= ID|INDEXED|JOIN_KW */
- -3, /* (179) expr ::= nm DOT nm */
- -5, /* (180) expr ::= nm DOT nm DOT nm */
- -1, /* (181) term ::= NULL|FLOAT|BLOB */
- -1, /* (182) term ::= STRING */
- -1, /* (183) term ::= INTEGER */
- -1, /* (184) expr ::= VARIABLE */
- -3, /* (185) expr ::= expr COLLATE ID|STRING */
- -6, /* (186) expr ::= CAST LP expr AS typetoken RP */
- -5, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
- -8, /* (188) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
- -4, /* (189) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
- -6, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
- -9, /* (191) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
- -5, /* (192) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
- -1, /* (193) term ::= CTIME_KW */
- -5, /* (194) expr ::= LP nexprlist COMMA expr RP */
- -3, /* (195) expr ::= expr AND expr */
- -3, /* (196) expr ::= expr OR expr */
- -3, /* (197) expr ::= expr LT|GT|GE|LE expr */
- -3, /* (198) expr ::= expr EQ|NE expr */
- -3, /* (199) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- -3, /* (200) expr ::= expr PLUS|MINUS expr */
- -3, /* (201) expr ::= expr STAR|SLASH|REM expr */
- -3, /* (202) expr ::= expr CONCAT expr */
- -2, /* (203) likeop ::= NOT LIKE_KW|MATCH */
- -3, /* (204) expr ::= expr likeop expr */
- -5, /* (205) expr ::= expr likeop expr ESCAPE expr */
- -2, /* (206) expr ::= expr ISNULL|NOTNULL */
- -3, /* (207) expr ::= expr NOT NULL */
- -3, /* (208) expr ::= expr IS expr */
- -4, /* (209) expr ::= expr IS NOT expr */
- -6, /* (210) expr ::= expr IS NOT DISTINCT FROM expr */
- -5, /* (211) expr ::= expr IS DISTINCT FROM expr */
- -2, /* (212) expr ::= NOT expr */
- -2, /* (213) expr ::= BITNOT expr */
- -2, /* (214) expr ::= PLUS|MINUS expr */
- -3, /* (215) expr ::= expr PTR expr */
- -1, /* (216) between_op ::= BETWEEN */
- -2, /* (217) between_op ::= NOT BETWEEN */
- -5, /* (218) expr ::= expr between_op expr AND expr */
- -1, /* (219) in_op ::= IN */
- -2, /* (220) in_op ::= NOT IN */
- -5, /* (221) expr ::= expr in_op LP exprlist RP */
- -3, /* (222) expr ::= LP select RP */
- -5, /* (223) expr ::= expr in_op LP select RP */
- -5, /* (224) expr ::= expr in_op nm dbnm paren_exprlist */
- -4, /* (225) expr ::= EXISTS LP select RP */
- -5, /* (226) expr ::= CASE case_operand case_exprlist case_else END */
- -5, /* (227) case_exprlist ::= case_exprlist WHEN expr THEN expr */
- -4, /* (228) case_exprlist ::= WHEN expr THEN expr */
- -2, /* (229) case_else ::= ELSE expr */
- 0, /* (230) case_else ::= */
- 0, /* (231) case_operand ::= */
- 0, /* (232) exprlist ::= */
- -3, /* (233) nexprlist ::= nexprlist COMMA expr */
- -1, /* (234) nexprlist ::= expr */
- 0, /* (235) paren_exprlist ::= */
- -3, /* (236) paren_exprlist ::= LP exprlist RP */
- -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
- -1, /* (238) uniqueflag ::= UNIQUE */
- 0, /* (239) uniqueflag ::= */
- 0, /* (240) eidlist_opt ::= */
- -3, /* (241) eidlist_opt ::= LP eidlist RP */
- -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */
- -3, /* (243) eidlist ::= nm collate sortorder */
- 0, /* (244) collate ::= */
- -2, /* (245) collate ::= COLLATE ID|STRING */
- -4, /* (246) cmd ::= DROP INDEX ifexists fullname */
- -2, /* (247) cmd ::= VACUUM vinto */
- -3, /* (248) cmd ::= VACUUM nm vinto */
- -2, /* (249) vinto ::= INTO expr */
- 0, /* (250) vinto ::= */
- -3, /* (251) cmd ::= PRAGMA nm dbnm */
- -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */
- -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */
- -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */
- -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */
- -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */
- -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */
- -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
- -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
- -1, /* (260) trigger_time ::= BEFORE|AFTER */
- -2, /* (261) trigger_time ::= INSTEAD OF */
- 0, /* (262) trigger_time ::= */
- -1, /* (263) trigger_event ::= DELETE|INSERT */
- -1, /* (264) trigger_event ::= UPDATE */
- -3, /* (265) trigger_event ::= UPDATE OF idlist */
- 0, /* (266) when_clause ::= */
- -2, /* (267) when_clause ::= WHEN expr */
- -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
- -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */
- -3, /* (270) trnm ::= nm DOT nm */
- -3, /* (271) tridxby ::= INDEXED BY nm */
- -2, /* (272) tridxby ::= NOT INDEXED */
- -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
- -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
- -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
- -3, /* (276) trigger_cmd ::= scanpt select scanpt */
- -4, /* (277) expr ::= RAISE LP IGNORE RP */
- -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */
- -1, /* (279) raisetype ::= ROLLBACK */
- -1, /* (280) raisetype ::= ABORT */
- -1, /* (281) raisetype ::= FAIL */
- -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */
- -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
- -3, /* (284) cmd ::= DETACH database_kw_opt expr */
- 0, /* (285) key_opt ::= */
- -2, /* (286) key_opt ::= KEY expr */
- -1, /* (287) cmd ::= REINDEX */
- -3, /* (288) cmd ::= REINDEX nm dbnm */
- -1, /* (289) cmd ::= ANALYZE */
- -3, /* (290) cmd ::= ANALYZE nm dbnm */
- -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */
- -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
- -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
- -1, /* (294) add_column_fullname ::= fullname */
- -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
- -1, /* (296) cmd ::= create_vtab */
- -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */
- -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
- 0, /* (299) vtabarg ::= */
- -1, /* (300) vtabargtoken ::= ANY */
- -3, /* (301) vtabargtoken ::= lp anylist RP */
- -1, /* (302) lp ::= LP */
- -2, /* (303) with ::= WITH wqlist */
- -3, /* (304) with ::= WITH RECURSIVE wqlist */
- -1, /* (305) wqas ::= AS */
- -2, /* (306) wqas ::= AS MATERIALIZED */
- -3, /* (307) wqas ::= AS NOT MATERIALIZED */
- -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */
- -1, /* (309) wqlist ::= wqitem */
- -3, /* (310) wqlist ::= wqlist COMMA wqitem */
- -3, /* (311) windowdefn_list ::= windowdefn_list COMMA windowdefn */
- -5, /* (312) windowdefn ::= nm AS LP window RP */
- -5, /* (313) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
- -6, /* (314) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
- -4, /* (315) window ::= ORDER BY sortlist frame_opt */
- -5, /* (316) window ::= nm ORDER BY sortlist frame_opt */
- -2, /* (317) window ::= nm frame_opt */
- 0, /* (318) frame_opt ::= */
- -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
- -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
- -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */
- -1, /* (322) frame_bound_s ::= frame_bound */
- -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */
- -1, /* (324) frame_bound_e ::= frame_bound */
- -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */
- -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */
- -2, /* (327) frame_bound ::= CURRENT ROW */
- 0, /* (328) frame_exclude_opt ::= */
- -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */
- -2, /* (330) frame_exclude ::= NO OTHERS */
- -2, /* (331) frame_exclude ::= CURRENT ROW */
- -1, /* (332) frame_exclude ::= GROUP|TIES */
- -2, /* (333) window_clause ::= WINDOW windowdefn_list */
- -2, /* (334) filter_over ::= filter_clause over_clause */
- -1, /* (335) filter_over ::= over_clause */
- -1, /* (336) filter_over ::= filter_clause */
- -4, /* (337) over_clause ::= OVER LP window RP */
- -2, /* (338) over_clause ::= OVER nm */
- -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */
- -1, /* (340) input ::= cmdlist */
- -2, /* (341) cmdlist ::= cmdlist ecmd */
- -1, /* (342) cmdlist ::= ecmd */
- -1, /* (343) ecmd ::= SEMI */
- -2, /* (344) ecmd ::= cmdx SEMI */
- -3, /* (345) ecmd ::= explain cmdx SEMI */
- 0, /* (346) trans_opt ::= */
- -1, /* (347) trans_opt ::= TRANSACTION */
- -2, /* (348) trans_opt ::= TRANSACTION nm */
- -1, /* (349) savepoint_opt ::= SAVEPOINT */
- 0, /* (350) savepoint_opt ::= */
- -2, /* (351) cmd ::= create_table create_table_args */
- -1, /* (352) table_option_set ::= table_option */
- -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */
- -2, /* (354) columnlist ::= columnname carglist */
- -1, /* (355) nm ::= ID|INDEXED|JOIN_KW */
- -1, /* (356) nm ::= STRING */
- -1, /* (357) typetoken ::= typename */
- -1, /* (358) typename ::= ID|STRING */
- -1, /* (359) signed ::= plus_num */
- -1, /* (360) signed ::= minus_num */
- -2, /* (361) carglist ::= carglist ccons */
- 0, /* (362) carglist ::= */
- -2, /* (363) ccons ::= NULL onconf */
- -4, /* (364) ccons ::= GENERATED ALWAYS AS generated */
- -2, /* (365) ccons ::= AS generated */
- -2, /* (366) conslist_opt ::= COMMA conslist */
- -3, /* (367) conslist ::= conslist tconscomma tcons */
- -1, /* (368) conslist ::= tcons */
- 0, /* (369) tconscomma ::= */
- -1, /* (370) defer_subclause_opt ::= defer_subclause */
- -1, /* (371) resolvetype ::= raisetype */
- -1, /* (372) selectnowith ::= oneselect */
- -1, /* (373) oneselect ::= values */
- -2, /* (374) sclp ::= selcollist COMMA */
- -1, /* (375) as ::= ID|STRING */
- -1, /* (376) indexed_opt ::= indexed_by */
- 0, /* (377) returning ::= */
- -1, /* (378) expr ::= term */
- -1, /* (379) likeop ::= LIKE_KW|MATCH */
- -1, /* (380) case_operand ::= expr */
- -1, /* (381) exprlist ::= nexprlist */
- -1, /* (382) nmnum ::= plus_num */
- -1, /* (383) nmnum ::= nm */
- -1, /* (384) nmnum ::= ON */
- -1, /* (385) nmnum ::= DELETE */
- -1, /* (386) nmnum ::= DEFAULT */
- -1, /* (387) plus_num ::= INTEGER|FLOAT */
- 0, /* (388) foreach_clause ::= */
- -3, /* (389) foreach_clause ::= FOR EACH ROW */
- -1, /* (390) trnm ::= nm */
- 0, /* (391) tridxby ::= */
- -1, /* (392) database_kw_opt ::= DATABASE */
- 0, /* (393) database_kw_opt ::= */
- 0, /* (394) kwcolumn_opt ::= */
- -1, /* (395) kwcolumn_opt ::= COLUMNKW */
- -1, /* (396) vtabarglist ::= vtabarg */
- -3, /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
- -2, /* (398) vtabarg ::= vtabarg vtabargtoken */
- 0, /* (399) anylist ::= */
- -4, /* (400) anylist ::= anylist LP anylist RP */
- -2, /* (401) anylist ::= anylist ANY */
- 0, /* (402) with ::= */
- -1, /* (403) windowdefn_list ::= windowdefn */
- -1, /* (404) window ::= frame_opt */
+ -1, /* (95) oneselect ::= mvalues */
+ -5, /* (96) mvalues ::= values COMMA LP nexprlist RP */
+ -5, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */
+ -1, /* (98) distinct ::= DISTINCT */
+ -1, /* (99) distinct ::= ALL */
+ 0, /* (100) distinct ::= */
+ 0, /* (101) sclp ::= */
+ -5, /* (102) selcollist ::= sclp scanpt expr scanpt as */
+ -3, /* (103) selcollist ::= sclp scanpt STAR */
+ -5, /* (104) selcollist ::= sclp scanpt nm DOT STAR */
+ -2, /* (105) as ::= AS nm */
+ 0, /* (106) as ::= */
+ 0, /* (107) from ::= */
+ -2, /* (108) from ::= FROM seltablist */
+ -2, /* (109) stl_prefix ::= seltablist joinop */
+ 0, /* (110) stl_prefix ::= */
+ -5, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */
+ -6, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
+ -8, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
+ -6, /* (114) seltablist ::= stl_prefix LP select RP as on_using */
+ -6, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */
+ 0, /* (116) dbnm ::= */
+ -2, /* (117) dbnm ::= DOT nm */
+ -1, /* (118) fullname ::= nm */
+ -3, /* (119) fullname ::= nm DOT nm */
+ -1, /* (120) xfullname ::= nm */
+ -3, /* (121) xfullname ::= nm DOT nm */
+ -5, /* (122) xfullname ::= nm DOT nm AS nm */
+ -3, /* (123) xfullname ::= nm AS nm */
+ -1, /* (124) joinop ::= COMMA|JOIN */
+ -2, /* (125) joinop ::= JOIN_KW JOIN */
+ -3, /* (126) joinop ::= JOIN_KW nm JOIN */
+ -4, /* (127) joinop ::= JOIN_KW nm nm JOIN */
+ -2, /* (128) on_using ::= ON expr */
+ -4, /* (129) on_using ::= USING LP idlist RP */
+ 0, /* (130) on_using ::= */
+ 0, /* (131) indexed_opt ::= */
+ -3, /* (132) indexed_by ::= INDEXED BY nm */
+ -2, /* (133) indexed_by ::= NOT INDEXED */
+ 0, /* (134) orderby_opt ::= */
+ -3, /* (135) orderby_opt ::= ORDER BY sortlist */
+ -5, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */
+ -3, /* (137) sortlist ::= expr sortorder nulls */
+ -1, /* (138) sortorder ::= ASC */
+ -1, /* (139) sortorder ::= DESC */
+ 0, /* (140) sortorder ::= */
+ -2, /* (141) nulls ::= NULLS FIRST */
+ -2, /* (142) nulls ::= NULLS LAST */
+ 0, /* (143) nulls ::= */
+ 0, /* (144) groupby_opt ::= */
+ -3, /* (145) groupby_opt ::= GROUP BY nexprlist */
+ 0, /* (146) having_opt ::= */
+ -2, /* (147) having_opt ::= HAVING expr */
+ 0, /* (148) limit_opt ::= */
+ -2, /* (149) limit_opt ::= LIMIT expr */
+ -4, /* (150) limit_opt ::= LIMIT expr OFFSET expr */
+ -4, /* (151) limit_opt ::= LIMIT expr COMMA expr */
+ -6, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
+ 0, /* (153) where_opt ::= */
+ -2, /* (154) where_opt ::= WHERE expr */
+ 0, /* (155) where_opt_ret ::= */
+ -2, /* (156) where_opt_ret ::= WHERE expr */
+ -2, /* (157) where_opt_ret ::= RETURNING selcollist */
+ -4, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */
+ -9, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
+ -5, /* (160) setlist ::= setlist COMMA nm EQ expr */
+ -7, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ -3, /* (162) setlist ::= nm EQ expr */
+ -5, /* (163) setlist ::= LP idlist RP EQ expr */
+ -7, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ -8, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
+ 0, /* (166) upsert ::= */
+ -2, /* (167) upsert ::= RETURNING selcollist */
+ -12, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
+ -9, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
+ -5, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */
+ -8, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
+ -2, /* (172) returning ::= RETURNING selcollist */
+ -2, /* (173) insert_cmd ::= INSERT orconf */
+ -1, /* (174) insert_cmd ::= REPLACE */
+ 0, /* (175) idlist_opt ::= */
+ -3, /* (176) idlist_opt ::= LP idlist RP */
+ -3, /* (177) idlist ::= idlist COMMA nm */
+ -1, /* (178) idlist ::= nm */
+ -3, /* (179) expr ::= LP expr RP */
+ -1, /* (180) expr ::= ID|INDEXED|JOIN_KW */
+ -3, /* (181) expr ::= nm DOT nm */
+ -5, /* (182) expr ::= nm DOT nm DOT nm */
+ -1, /* (183) term ::= NULL|FLOAT|BLOB */
+ -1, /* (184) term ::= STRING */
+ -1, /* (185) term ::= INTEGER */
+ -1, /* (186) expr ::= VARIABLE */
+ -3, /* (187) expr ::= expr COLLATE ID|STRING */
+ -6, /* (188) expr ::= CAST LP expr AS typetoken RP */
+ -5, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
+ -8, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
+ -4, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
+ -6, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
+ -9, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
+ -5, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
+ -1, /* (195) term ::= CTIME_KW */
+ -5, /* (196) expr ::= LP nexprlist COMMA expr RP */
+ -3, /* (197) expr ::= expr AND expr */
+ -3, /* (198) expr ::= expr OR expr */
+ -3, /* (199) expr ::= expr LT|GT|GE|LE expr */
+ -3, /* (200) expr ::= expr EQ|NE expr */
+ -3, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ -3, /* (202) expr ::= expr PLUS|MINUS expr */
+ -3, /* (203) expr ::= expr STAR|SLASH|REM expr */
+ -3, /* (204) expr ::= expr CONCAT expr */
+ -2, /* (205) likeop ::= NOT LIKE_KW|MATCH */
+ -3, /* (206) expr ::= expr likeop expr */
+ -5, /* (207) expr ::= expr likeop expr ESCAPE expr */
+ -2, /* (208) expr ::= expr ISNULL|NOTNULL */
+ -3, /* (209) expr ::= expr NOT NULL */
+ -3, /* (210) expr ::= expr IS expr */
+ -4, /* (211) expr ::= expr IS NOT expr */
+ -6, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */
+ -5, /* (213) expr ::= expr IS DISTINCT FROM expr */
+ -2, /* (214) expr ::= NOT expr */
+ -2, /* (215) expr ::= BITNOT expr */
+ -2, /* (216) expr ::= PLUS|MINUS expr */
+ -3, /* (217) expr ::= expr PTR expr */
+ -1, /* (218) between_op ::= BETWEEN */
+ -2, /* (219) between_op ::= NOT BETWEEN */
+ -5, /* (220) expr ::= expr between_op expr AND expr */
+ -1, /* (221) in_op ::= IN */
+ -2, /* (222) in_op ::= NOT IN */
+ -5, /* (223) expr ::= expr in_op LP exprlist RP */
+ -3, /* (224) expr ::= LP select RP */
+ -5, /* (225) expr ::= expr in_op LP select RP */
+ -5, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */
+ -4, /* (227) expr ::= EXISTS LP select RP */
+ -5, /* (228) expr ::= CASE case_operand case_exprlist case_else END */
+ -5, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ -4, /* (230) case_exprlist ::= WHEN expr THEN expr */
+ -2, /* (231) case_else ::= ELSE expr */
+ 0, /* (232) case_else ::= */
+ 0, /* (233) case_operand ::= */
+ 0, /* (234) exprlist ::= */
+ -3, /* (235) nexprlist ::= nexprlist COMMA expr */
+ -1, /* (236) nexprlist ::= expr */
+ 0, /* (237) paren_exprlist ::= */
+ -3, /* (238) paren_exprlist ::= LP exprlist RP */
+ -12, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ -1, /* (240) uniqueflag ::= UNIQUE */
+ 0, /* (241) uniqueflag ::= */
+ 0, /* (242) eidlist_opt ::= */
+ -3, /* (243) eidlist_opt ::= LP eidlist RP */
+ -5, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */
+ -3, /* (245) eidlist ::= nm collate sortorder */
+ 0, /* (246) collate ::= */
+ -2, /* (247) collate ::= COLLATE ID|STRING */
+ -4, /* (248) cmd ::= DROP INDEX ifexists fullname */
+ -2, /* (249) cmd ::= VACUUM vinto */
+ -3, /* (250) cmd ::= VACUUM nm vinto */
+ -2, /* (251) vinto ::= INTO expr */
+ 0, /* (252) vinto ::= */
+ -3, /* (253) cmd ::= PRAGMA nm dbnm */
+ -5, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ -6, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ -5, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ -6, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ -2, /* (258) plus_num ::= PLUS INTEGER|FLOAT */
+ -2, /* (259) minus_num ::= MINUS INTEGER|FLOAT */
+ -5, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ -11, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ -1, /* (262) trigger_time ::= BEFORE|AFTER */
+ -2, /* (263) trigger_time ::= INSTEAD OF */
+ 0, /* (264) trigger_time ::= */
+ -1, /* (265) trigger_event ::= DELETE|INSERT */
+ -1, /* (266) trigger_event ::= UPDATE */
+ -3, /* (267) trigger_event ::= UPDATE OF idlist */
+ 0, /* (268) when_clause ::= */
+ -2, /* (269) when_clause ::= WHEN expr */
+ -3, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ -2, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */
+ -3, /* (272) trnm ::= nm DOT nm */
+ -3, /* (273) tridxby ::= INDEXED BY nm */
+ -2, /* (274) tridxby ::= NOT INDEXED */
+ -9, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+ -8, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ -3, /* (278) trigger_cmd ::= scanpt select scanpt */
+ -4, /* (279) expr ::= RAISE LP IGNORE RP */
+ -6, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */
+ -1, /* (281) raisetype ::= ROLLBACK */
+ -1, /* (282) raisetype ::= ABORT */
+ -1, /* (283) raisetype ::= FAIL */
+ -4, /* (284) cmd ::= DROP TRIGGER ifexists fullname */
+ -6, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ -3, /* (286) cmd ::= DETACH database_kw_opt expr */
+ 0, /* (287) key_opt ::= */
+ -2, /* (288) key_opt ::= KEY expr */
+ -1, /* (289) cmd ::= REINDEX */
+ -3, /* (290) cmd ::= REINDEX nm dbnm */
+ -1, /* (291) cmd ::= ANALYZE */
+ -3, /* (292) cmd ::= ANALYZE nm dbnm */
+ -6, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ -7, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ -6, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+ -1, /* (296) add_column_fullname ::= fullname */
+ -8, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ -1, /* (298) cmd ::= create_vtab */
+ -4, /* (299) cmd ::= create_vtab LP vtabarglist RP */
+ -8, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 0, /* (301) vtabarg ::= */
+ -1, /* (302) vtabargtoken ::= ANY */
+ -3, /* (303) vtabargtoken ::= lp anylist RP */
+ -1, /* (304) lp ::= LP */
+ -2, /* (305) with ::= WITH wqlist */
+ -3, /* (306) with ::= WITH RECURSIVE wqlist */
+ -1, /* (307) wqas ::= AS */
+ -2, /* (308) wqas ::= AS MATERIALIZED */
+ -3, /* (309) wqas ::= AS NOT MATERIALIZED */
+ -6, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */
+ -1, /* (311) withnm ::= nm */
+ -1, /* (312) wqlist ::= wqitem */
+ -3, /* (313) wqlist ::= wqlist COMMA wqitem */
+ -3, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ -5, /* (315) windowdefn ::= nm AS LP window RP */
+ -5, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ -6, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ -4, /* (318) window ::= ORDER BY sortlist frame_opt */
+ -5, /* (319) window ::= nm ORDER BY sortlist frame_opt */
+ -2, /* (320) window ::= nm frame_opt */
+ 0, /* (321) frame_opt ::= */
+ -3, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ -6, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ -1, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */
+ -1, /* (325) frame_bound_s ::= frame_bound */
+ -2, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */
+ -1, /* (327) frame_bound_e ::= frame_bound */
+ -2, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ -2, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */
+ -2, /* (330) frame_bound ::= CURRENT ROW */
+ 0, /* (331) frame_exclude_opt ::= */
+ -2, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */
+ -2, /* (333) frame_exclude ::= NO OTHERS */
+ -2, /* (334) frame_exclude ::= CURRENT ROW */
+ -1, /* (335) frame_exclude ::= GROUP|TIES */
+ -2, /* (336) window_clause ::= WINDOW windowdefn_list */
+ -2, /* (337) filter_over ::= filter_clause over_clause */
+ -1, /* (338) filter_over ::= over_clause */
+ -1, /* (339) filter_over ::= filter_clause */
+ -4, /* (340) over_clause ::= OVER LP window RP */
+ -2, /* (341) over_clause ::= OVER nm */
+ -5, /* (342) filter_clause ::= FILTER LP WHERE expr RP */
+ -1, /* (343) term ::= QNUMBER */
+ -1, /* (344) input ::= cmdlist */
+ -2, /* (345) cmdlist ::= cmdlist ecmd */
+ -1, /* (346) cmdlist ::= ecmd */
+ -1, /* (347) ecmd ::= SEMI */
+ -2, /* (348) ecmd ::= cmdx SEMI */
+ -3, /* (349) ecmd ::= explain cmdx SEMI */
+ 0, /* (350) trans_opt ::= */
+ -1, /* (351) trans_opt ::= TRANSACTION */
+ -2, /* (352) trans_opt ::= TRANSACTION nm */
+ -1, /* (353) savepoint_opt ::= SAVEPOINT */
+ 0, /* (354) savepoint_opt ::= */
+ -2, /* (355) cmd ::= create_table create_table_args */
+ -1, /* (356) table_option_set ::= table_option */
+ -4, /* (357) columnlist ::= columnlist COMMA columnname carglist */
+ -2, /* (358) columnlist ::= columnname carglist */
+ -1, /* (359) nm ::= ID|INDEXED|JOIN_KW */
+ -1, /* (360) nm ::= STRING */
+ -1, /* (361) typetoken ::= typename */
+ -1, /* (362) typename ::= ID|STRING */
+ -1, /* (363) signed ::= plus_num */
+ -1, /* (364) signed ::= minus_num */
+ -2, /* (365) carglist ::= carglist ccons */
+ 0, /* (366) carglist ::= */
+ -2, /* (367) ccons ::= NULL onconf */
+ -4, /* (368) ccons ::= GENERATED ALWAYS AS generated */
+ -2, /* (369) ccons ::= AS generated */
+ -2, /* (370) conslist_opt ::= COMMA conslist */
+ -3, /* (371) conslist ::= conslist tconscomma tcons */
+ -1, /* (372) conslist ::= tcons */
+ 0, /* (373) tconscomma ::= */
+ -1, /* (374) defer_subclause_opt ::= defer_subclause */
+ -1, /* (375) resolvetype ::= raisetype */
+ -1, /* (376) selectnowith ::= oneselect */
+ -1, /* (377) oneselect ::= values */
+ -2, /* (378) sclp ::= selcollist COMMA */
+ -1, /* (379) as ::= ID|STRING */
+ -1, /* (380) indexed_opt ::= indexed_by */
+ 0, /* (381) returning ::= */
+ -1, /* (382) expr ::= term */
+ -1, /* (383) likeop ::= LIKE_KW|MATCH */
+ -1, /* (384) case_operand ::= expr */
+ -1, /* (385) exprlist ::= nexprlist */
+ -1, /* (386) nmnum ::= plus_num */
+ -1, /* (387) nmnum ::= nm */
+ -1, /* (388) nmnum ::= ON */
+ -1, /* (389) nmnum ::= DELETE */
+ -1, /* (390) nmnum ::= DEFAULT */
+ -1, /* (391) plus_num ::= INTEGER|FLOAT */
+ 0, /* (392) foreach_clause ::= */
+ -3, /* (393) foreach_clause ::= FOR EACH ROW */
+ -1, /* (394) trnm ::= nm */
+ 0, /* (395) tridxby ::= */
+ -1, /* (396) database_kw_opt ::= DATABASE */
+ 0, /* (397) database_kw_opt ::= */
+ 0, /* (398) kwcolumn_opt ::= */
+ -1, /* (399) kwcolumn_opt ::= COLUMNKW */
+ -1, /* (400) vtabarglist ::= vtabarg */
+ -3, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */
+ -2, /* (402) vtabarg ::= vtabarg vtabargtoken */
+ 0, /* (403) anylist ::= */
+ -4, /* (404) anylist ::= anylist LP anylist RP */
+ -2, /* (405) anylist ::= anylist ANY */
+ 0, /* (406) with ::= */
+ -1, /* (407) windowdefn_list ::= windowdefn */
+ -1, /* (408) window ::= frame_opt */
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -174724,16 +177444,16 @@ static YYACTIONTYPE yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy394);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);}
break;
case 4: /* transtype ::= */
-{yymsp[1].minor.yy394 = TK_DEFERRED;}
+{yymsp[1].minor.yy144 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
- case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321);
-{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/}
+ case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324);
+{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* cmd ::= COMMIT|END trans_opt */
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
@@ -174756,7 +177476,7 @@ static YYACTIONTYPE yy_reduce(
break;
case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy394,0,0,yymsp[-2].minor.yy394);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144);
}
break;
case 14: /* createkw ::= CREATE */
@@ -174768,40 +177488,40 @@ static YYACTIONTYPE yy_reduce(
case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
- case 98: /* distinct ::= */ yytestcase(yyruleno==98);
- case 244: /* collate ::= */ yytestcase(yyruleno==244);
-{yymsp[1].minor.yy394 = 0;}
+ case 100: /* distinct ::= */ yytestcase(yyruleno==100);
+ case 246: /* collate ::= */ yytestcase(yyruleno==246);
+{yymsp[1].minor.yy144 = 0;}
break;
case 16: /* ifnotexists ::= IF NOT EXISTS */
-{yymsp[-2].minor.yy394 = 1;}
+{yymsp[-2].minor.yy144 = 1;}
break;
case 17: /* temp ::= TEMP */
-{yymsp[0].minor.yy394 = pParse->db->init.busy==0;}
+{yymsp[0].minor.yy144 = pParse->db->init.busy==0;}
break;
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */
{
- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy285,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0);
}
break;
case 20: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy47);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
}
break;
case 21: /* table_option_set ::= */
-{yymsp[1].minor.yy285 = 0;}
+{yymsp[1].minor.yy391 = 0;}
break;
case 22: /* table_option_set ::= table_option_set COMMA table_option */
-{yylhsminor.yy285 = yymsp[-2].minor.yy285|yymsp[0].minor.yy285;}
- yymsp[-2].minor.yy285 = yylhsminor.yy285;
+{yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;}
+ yymsp[-2].minor.yy391 = yylhsminor.yy391;
break;
case 23: /* table_option ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yymsp[-1].minor.yy285 = TF_WithoutRowid | TF_NoVisibleRowid;
+ yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid;
}else{
- yymsp[-1].minor.yy285 = 0;
+ yymsp[-1].minor.yy391 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -174809,20 +177529,20 @@ static YYACTIONTYPE yy_reduce(
case 24: /* table_option ::= nm */
{
if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){
- yylhsminor.yy285 = TF_Strict;
+ yylhsminor.yy391 = TF_Strict;
}else{
- yylhsminor.yy285 = 0;
+ yylhsminor.yy391 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
- yymsp[0].minor.yy285 = yylhsminor.yy285;
+ yymsp[0].minor.yy391 = yylhsminor.yy391;
break;
case 25: /* columnname ::= nm typetoken */
{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);}
break;
case 26: /* typetoken ::= */
case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65);
- case 104: /* as ::= */ yytestcase(yyruleno==104);
+ case 106: /* as ::= */ yytestcase(yyruleno==106);
{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
break;
case 27: /* typetoken ::= typename LP signed RP */
@@ -174841,7 +177561,7 @@ static YYACTIONTYPE yy_reduce(
case 30: /* scanpt ::= */
{
assert( yyLookahead!=YYNOCODE );
- yymsp[1].minor.yy522 = yyLookaheadToken.z;
+ yymsp[1].minor.yy168 = yyLookaheadToken.z;
}
break;
case 31: /* scantok ::= */
@@ -174855,17 +177575,17 @@ static YYACTIONTYPE yy_reduce(
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
case 33: /* ccons ::= DEFAULT scantok term */
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
case 34: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
break;
case 35: /* ccons ::= DEFAULT PLUS scantok term */
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
case 36: /* ccons ::= DEFAULT MINUS scantok term */
{
- Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy528, 0);
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0);
sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
}
break;
@@ -174880,151 +177600,151 @@ static YYACTIONTYPE yy_reduce(
}
break;
case 38: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy394);}
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);}
break;
case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy394,yymsp[0].minor.yy394,yymsp[-2].minor.yy394);}
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);}
break;
case 40: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy394,0,0,0,0,
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
case 41: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
break;
case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy394);}
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);}
break;
case 43: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy394);}
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);}
break;
case 44: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
case 45: /* generated ::= LP expr RP */
-{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy528,0);}
+{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);}
break;
case 46: /* generated ::= LP expr RP ID */
-{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy528,&yymsp[0].minor.yy0);}
+{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);}
break;
case 48: /* autoinc ::= AUTOINCR */
-{yymsp[0].minor.yy394 = 1;}
+{yymsp[0].minor.yy144 = 1;}
break;
case 49: /* refargs ::= */
-{ yymsp[1].minor.yy394 = OE_None*0x0101; /* EV: R-19803-45884 */}
+{ yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
case 50: /* refargs ::= refargs refarg */
-{ yymsp[-1].minor.yy394 = (yymsp[-1].minor.yy394 & ~yymsp[0].minor.yy231.mask) | yymsp[0].minor.yy231.value; }
+{ yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; }
break;
case 51: /* refarg ::= MATCH nm */
-{ yymsp[-1].minor.yy231.value = 0; yymsp[-1].minor.yy231.mask = 0x000000; }
+{ yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; }
break;
case 52: /* refarg ::= ON INSERT refact */
-{ yymsp[-2].minor.yy231.value = 0; yymsp[-2].minor.yy231.mask = 0x000000; }
+{ yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; }
break;
case 53: /* refarg ::= ON DELETE refact */
-{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394; yymsp[-2].minor.yy231.mask = 0x0000ff; }
+{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; }
break;
case 54: /* refarg ::= ON UPDATE refact */
-{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394<<8; yymsp[-2].minor.yy231.mask = 0x00ff00; }
+{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; }
break;
case 55: /* refact ::= SET NULL */
-{ yymsp[-1].minor.yy394 = OE_SetNull; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */}
break;
case 56: /* refact ::= SET DEFAULT */
-{ yymsp[-1].minor.yy394 = OE_SetDflt; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
case 57: /* refact ::= CASCADE */
-{ yymsp[0].minor.yy394 = OE_Cascade; /* EV: R-33326-45252 */}
+{ yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */}
break;
case 58: /* refact ::= RESTRICT */
-{ yymsp[0].minor.yy394 = OE_Restrict; /* EV: R-33326-45252 */}
+{ yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */}
break;
case 59: /* refact ::= NO ACTION */
-{ yymsp[-1].minor.yy394 = OE_None; /* EV: R-33326-45252 */}
+{ yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */}
break;
case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-{yymsp[-2].minor.yy394 = 0;}
+{yymsp[-2].minor.yy144 = 0;}
break;
case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76);
- case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171);
-{yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;}
+ case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173);
+{yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;}
break;
case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
- case 217: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==217);
- case 220: /* in_op ::= NOT IN */ yytestcase(yyruleno==220);
- case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245);
-{yymsp[-1].minor.yy394 = 1;}
+ case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219);
+ case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222);
+ case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247);
+{yymsp[-1].minor.yy144 = 1;}
break;
case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
-{yymsp[-1].minor.yy394 = 0;}
+{yymsp[-1].minor.yy144 = 0;}
break;
case 66: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy394,yymsp[-2].minor.yy394,0);}
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);}
break;
case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy394,0,0,0,0,
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
case 70: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy528,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
break;
case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy394);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy394);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144);
}
break;
case 73: /* onconf ::= */
case 75: /* orconf ::= */ yytestcase(yyruleno==75);
-{yymsp[1].minor.yy394 = OE_Default;}
+{yymsp[1].minor.yy144 = OE_Default;}
break;
case 74: /* onconf ::= ON CONFLICT resolvetype */
-{yymsp[-2].minor.yy394 = yymsp[0].minor.yy394;}
+{yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;}
break;
case 77: /* resolvetype ::= IGNORE */
-{yymsp[0].minor.yy394 = OE_Ignore;}
+{yymsp[0].minor.yy144 = OE_Ignore;}
break;
case 78: /* resolvetype ::= REPLACE */
- case 172: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==172);
-{yymsp[0].minor.yy394 = OE_Replace;}
+ case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174);
+{yymsp[0].minor.yy144 = OE_Replace;}
break;
case 79: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy131, 0, yymsp[-1].minor.yy394);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144);
}
break;
case 82: /* 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.yy322, yymsp[0].minor.yy47, yymsp[-7].minor.yy394, yymsp[-5].minor.yy394);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144);
}
break;
case 83: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy131, 1, yymsp[-1].minor.yy394);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144);
}
break;
case 84: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy47, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47);
+ sqlite3Select(pParse, yymsp[0].minor.yy555, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
}
break;
case 85: /* select ::= WITH wqlist selectnowith */
-{yymsp[-2].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);}
+{yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
break;
case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */
-{yymsp[-3].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);}
+{yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
break;
case 87: /* select ::= selectnowith */
{
- Select *p = yymsp[0].minor.yy47;
+ Select *p = yymsp[0].minor.yy555;
if( p ){
parserDoubleLinkSelect(pParse, p);
}
@@ -175032,8 +177752,8 @@ static YYACTIONTYPE yy_reduce(
break;
case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
- Select *pRhs = yymsp[0].minor.yy47;
- Select *pLhs = yymsp[-2].minor.yy47;
+ Select *pRhs = yymsp[0].minor.yy555;
+ Select *pLhs = yymsp[-2].minor.yy555;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
@@ -175043,153 +177763,160 @@ static YYACTIONTYPE yy_reduce(
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
- pRhs->op = (u8)yymsp[-1].minor.yy394;
+ pRhs->op = (u8)yymsp[-1].minor.yy144;
pRhs->pPrior = pLhs;
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
pRhs->selFlags &= ~SF_MultiValue;
- if( yymsp[-1].minor.yy394!=TK_ALL ) pParse->hasCompound = 1;
+ if( yymsp[-1].minor.yy144!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, pLhs);
}
- yymsp[-2].minor.yy47 = pRhs;
+ yymsp[-2].minor.yy555 = pRhs;
}
break;
case 89: /* multiselect_op ::= UNION */
case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91);
-{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-OP*/}
+{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/}
break;
case 90: /* multiselect_op ::= UNION ALL */
-{yymsp[-1].minor.yy394 = TK_ALL;}
+{yymsp[-1].minor.yy144 = TK_ALL;}
break;
case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
- yymsp[-8].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy131,yymsp[-4].minor.yy528,yymsp[-3].minor.yy322,yymsp[-2].minor.yy528,yymsp[-1].minor.yy322,yymsp[-7].minor.yy394,yymsp[0].minor.yy528);
+ yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454);
}
break;
case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
{
- yymsp[-9].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy322,yymsp[-6].minor.yy131,yymsp[-5].minor.yy528,yymsp[-4].minor.yy322,yymsp[-3].minor.yy528,yymsp[-1].minor.yy322,yymsp[-8].minor.yy394,yymsp[0].minor.yy528);
- if( yymsp[-9].minor.yy47 ){
- yymsp[-9].minor.yy47->pWinDefn = yymsp[-2].minor.yy41;
+ yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454);
+ if( yymsp[-9].minor.yy555 ){
+ yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211;
}else{
- sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy41);
+ sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211);
}
}
break;
case 94: /* values ::= VALUES LP nexprlist RP */
{
- yymsp[-3].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0);
+ yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0);
}
break;
- case 95: /* values ::= values COMMA LP nexprlist RP */
+ case 95: /* oneselect ::= mvalues */
{
- Select *pRight, *pLeft = yymsp[-4].minor.yy47;
- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0);
- if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
- if( pRight ){
- pRight->op = TK_ALL;
- pRight->pPrior = pLeft;
- yymsp[-4].minor.yy47 = pRight;
- }else{
- yymsp[-4].minor.yy47 = pLeft;
- }
+ sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555);
}
break;
- case 96: /* distinct ::= DISTINCT */
-{yymsp[0].minor.yy394 = SF_Distinct;}
+ case 96: /* mvalues ::= values COMMA LP nexprlist RP */
+ case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97);
+{
+ yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14);
+}
break;
- case 97: /* distinct ::= ALL */
-{yymsp[0].minor.yy394 = SF_All;}
+ case 98: /* distinct ::= DISTINCT */
+{yymsp[0].minor.yy144 = SF_Distinct;}
break;
- case 99: /* sclp ::= */
- case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132);
- case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142);
- case 232: /* exprlist ::= */ yytestcase(yyruleno==232);
- case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235);
- case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240);
-{yymsp[1].minor.yy322 = 0;}
+ case 99: /* distinct ::= ALL */
+{yymsp[0].minor.yy144 = SF_All;}
break;
- case 100: /* selcollist ::= sclp scanpt expr scanpt as */
+ case 101: /* sclp ::= */
+ case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134);
+ case 144: /* groupby_opt ::= */ yytestcase(yyruleno==144);
+ case 234: /* exprlist ::= */ yytestcase(yyruleno==234);
+ case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237);
+ case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242);
+{yymsp[1].minor.yy14 = 0;}
+ break;
+ case 102: /* selcollist ::= sclp scanpt expr scanpt as */
{
- yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy522,yymsp[-1].minor.yy522);
+ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168);
}
break;
- case 101: /* selcollist ::= sclp scanpt STAR */
+ case 103: /* 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.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p);
+ yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p);
}
break;
- case 102: /* selcollist ::= sclp scanpt nm DOT STAR */
+ case 104: /* 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.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
+ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot);
}
break;
- case 103: /* as ::= AS nm */
- case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115);
- case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256);
- case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257);
+ case 105: /* as ::= AS nm */
+ case 117: /* dbnm ::= DOT nm */ yytestcase(yyruleno==117);
+ case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258);
+ case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 105: /* from ::= */
- case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108);
-{yymsp[1].minor.yy131 = 0;}
+ case 107: /* from ::= */
+ case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110);
+{yymsp[1].minor.yy203 = 0;}
break;
- case 106: /* from ::= FROM seltablist */
+ case 108: /* from ::= FROM seltablist */
{
- yymsp[-1].minor.yy131 = yymsp[0].minor.yy131;
- sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131);
+ yymsp[-1].minor.yy203 = yymsp[0].minor.yy203;
+ sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203);
}
break;
- case 107: /* stl_prefix ::= seltablist joinop */
+ case 109: /* stl_prefix ::= seltablist joinop */
{
- if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394;
+ if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144;
}
break;
- case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */
+ case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */
{
- yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
+ yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
}
break;
- case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
+ case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
{
- yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561);
- sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0);
+ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0);
}
break;
- case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
+ case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
{
- yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
- sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322);
+ yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
+ sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14);
}
break;
- case 112: /* seltablist ::= stl_prefix LP select RP as on_using */
+ case 114: /* seltablist ::= stl_prefix LP select RP as on_using */
{
- yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561);
+ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269);
}
break;
- case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
+ case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
{
- if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){
- yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131;
- }else if( ALWAYS(yymsp[-3].minor.yy131!=0) && yymsp[-3].minor.yy131->nSrc==1 ){
- yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
- if( yymsp[-5].minor.yy131 ){
- SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1];
- SrcItem *pOld = yymsp[-3].minor.yy131->a;
+ if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){
+ yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203;
+ }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){
+ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
+ if( yymsp[-5].minor.yy203 ){
+ SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1];
+ SrcItem *pOld = yymsp[-3].minor.yy203->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;
@@ -175197,156 +177924,155 @@ 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.yy131);
+ sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0);
- yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561);
+ sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0);
+ yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269);
}
}
break;
- case 114: /* dbnm ::= */
- case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129);
+ case 116: /* dbnm ::= */
+ case 131: /* indexed_opt ::= */ yytestcase(yyruleno==131);
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
break;
- case 116: /* fullname ::= nm */
+ case 118: /* fullname ::= nm */
{
- yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
- if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[0].minor.yy131 = yylhsminor.yy131;
+ yymsp[0].minor.yy203 = yylhsminor.yy203;
break;
- case 117: /* fullname ::= nm DOT nm */
+ case 119: /* fullname ::= nm DOT nm */
{
- yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
- if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[-2].minor.yy131 = yylhsminor.yy131;
+ yymsp[-2].minor.yy203 = yylhsminor.yy203;
break;
- case 118: /* xfullname ::= nm */
-{yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+ case 120: /* xfullname ::= nm */
+{yymsp[0].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
break;
- case 119: /* xfullname ::= nm DOT nm */
-{yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 121: /* xfullname ::= nm DOT nm */
+{yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 120: /* xfullname ::= nm DOT nm AS nm */
+ case 122: /* xfullname ::= nm DOT nm AS nm */
{
- yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
- if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-4].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
+ if( yymsp[-4].minor.yy203 ) yymsp[-4].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
- case 121: /* xfullname ::= nm AS nm */
+ case 123: /* xfullname ::= nm AS nm */
{
- yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
- if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
+ if( yymsp[-2].minor.yy203 ) yymsp[-2].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
- case 122: /* joinop ::= COMMA|JOIN */
-{ yymsp[0].minor.yy394 = JT_INNER; }
+ case 124: /* joinop ::= COMMA|JOIN */
+{ yymsp[0].minor.yy144 = JT_INNER; }
break;
- case 123: /* joinop ::= JOIN_KW JOIN */
-{yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
+ case 125: /* joinop ::= JOIN_KW JOIN */
+{yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
break;
- case 124: /* joinop ::= JOIN_KW nm JOIN */
-{yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
+ case 126: /* joinop ::= JOIN_KW nm JOIN */
+{yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
break;
- case 125: /* joinop ::= JOIN_KW nm nm JOIN */
-{yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+ case 127: /* joinop ::= JOIN_KW nm nm JOIN */
+{yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
break;
- case 126: /* on_using ::= ON expr */
-{yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;}
+ case 128: /* on_using ::= ON expr */
+{yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;}
break;
- case 127: /* on_using ::= USING LP idlist RP */
-{yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;}
+ case 129: /* on_using ::= USING LP idlist RP */
+{yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;}
break;
- case 128: /* on_using ::= */
-{yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;}
+ case 130: /* on_using ::= */
+{yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;}
break;
- case 130: /* indexed_by ::= INDEXED BY nm */
+ case 132: /* indexed_by ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 131: /* indexed_by ::= NOT INDEXED */
+ case 133: /* indexed_by ::= NOT INDEXED */
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
- case 133: /* orderby_opt ::= ORDER BY sortlist */
- case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143);
-{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;}
+ case 135: /* orderby_opt ::= ORDER BY sortlist */
+ case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145);
+{yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;}
break;
- case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */
+ case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */
{
- yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322,yymsp[-2].minor.yy528);
- sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394);
+ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454);
+ sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
}
break;
- case 135: /* sortlist ::= expr sortorder nulls */
+ case 137: /* sortlist ::= expr sortorder nulls */
{
- yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy528); /*A-overwrites-Y*/
- sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394);
+ yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/
+ sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
}
break;
- case 136: /* sortorder ::= ASC */
-{yymsp[0].minor.yy394 = SQLITE_SO_ASC;}
+ case 138: /* sortorder ::= ASC */
+{yymsp[0].minor.yy144 = SQLITE_SO_ASC;}
break;
- case 137: /* sortorder ::= DESC */
-{yymsp[0].minor.yy394 = SQLITE_SO_DESC;}
+ case 139: /* sortorder ::= DESC */
+{yymsp[0].minor.yy144 = SQLITE_SO_DESC;}
break;
- case 138: /* sortorder ::= */
- case 141: /* nulls ::= */ yytestcase(yyruleno==141);
-{yymsp[1].minor.yy394 = SQLITE_SO_UNDEFINED;}
+ case 140: /* sortorder ::= */
+ case 143: /* nulls ::= */ yytestcase(yyruleno==143);
+{yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;}
break;
- case 139: /* nulls ::= NULLS FIRST */
-{yymsp[-1].minor.yy394 = SQLITE_SO_ASC;}
+ case 141: /* nulls ::= NULLS FIRST */
+{yymsp[-1].minor.yy144 = SQLITE_SO_ASC;}
break;
- case 140: /* nulls ::= NULLS LAST */
-{yymsp[-1].minor.yy394 = SQLITE_SO_DESC;}
+ case 142: /* nulls ::= NULLS LAST */
+{yymsp[-1].minor.yy144 = SQLITE_SO_DESC;}
break;
- case 144: /* having_opt ::= */
- case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
- case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
- case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
- case 230: /* case_else ::= */ yytestcase(yyruleno==230);
- case 231: /* case_operand ::= */ yytestcase(yyruleno==231);
- case 250: /* vinto ::= */ yytestcase(yyruleno==250);
-{yymsp[1].minor.yy528 = 0;}
+ case 146: /* having_opt ::= */
+ case 148: /* limit_opt ::= */ yytestcase(yyruleno==148);
+ case 153: /* where_opt ::= */ yytestcase(yyruleno==153);
+ case 155: /* where_opt_ret ::= */ yytestcase(yyruleno==155);
+ case 232: /* case_else ::= */ yytestcase(yyruleno==232);
+ case 233: /* case_operand ::= */ yytestcase(yyruleno==233);
+ case 252: /* vinto ::= */ yytestcase(yyruleno==252);
+{yymsp[1].minor.yy454 = 0;}
break;
- case 145: /* having_opt ::= HAVING expr */
- case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
- case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
- case 229: /* case_else ::= ELSE expr */ yytestcase(yyruleno==229);
- case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249);
-{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
+ case 147: /* having_opt ::= HAVING expr */
+ case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154);
+ case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156);
+ case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231);
+ case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251);
+{yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;}
break;
- case 147: /* limit_opt ::= LIMIT expr */
-{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);}
+ case 149: /* limit_opt ::= LIMIT expr */
+{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);}
break;
- case 148: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);}
+ case 150: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
break;
- case 149: /* limit_opt ::= LIMIT expr COMMA expr */
-{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,yymsp[-2].minor.yy528);}
+ case 151: /* limit_opt ::= LIMIT expr COMMA expr */
+{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);}
break;
- case 150: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
+ case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy131, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy131,yymsp[0].minor.yy528,0,0);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0);
}
break;
- case 155: /* where_opt_ret ::= RETURNING selcollist */
-{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-1].minor.yy528 = 0;}
+ case 157: /* where_opt_ret ::= RETURNING selcollist */
+{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;}
break;
- case 156: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
-{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-3].minor.yy528 = yymsp[-2].minor.yy528;}
+ case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
+{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;}
break;
- case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
+ case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list");
- if( yymsp[-1].minor.yy131 ){
- SrcList *pFromClause = yymsp[-1].minor.yy131;
+ sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list");
+ if( yymsp[-1].minor.yy203 ){
+ SrcList *pFromClause = yymsp[-1].minor.yy203;
if( pFromClause->nSrc>1 ){
Select *pSubquery;
Token as;
@@ -175355,92 +178081,92 @@ static YYACTIONTYPE yy_reduce(
as.z = 0;
pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
}
- yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, pFromClause);
+ yymsp[-5].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause);
}
- sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0);
+ sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0);
}
break;
- case 158: /* setlist ::= setlist COMMA nm EQ expr */
+ case 160: /* setlist ::= setlist COMMA nm EQ expr */
{
- yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy528);
- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1);
+ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
+ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1);
}
break;
- case 159: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+ case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
{
- yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy254, yymsp[0].minor.yy528);
+ yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
}
break;
- case 160: /* setlist ::= nm EQ expr */
+ case 162: /* setlist ::= nm EQ expr */
{
- yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy528);
- sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1);
+ yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454);
+ sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1);
}
- yymsp[-2].minor.yy322 = yylhsminor.yy322;
+ yymsp[-2].minor.yy14 = yylhsminor.yy14;
break;
- case 161: /* setlist ::= LP idlist RP EQ expr */
+ case 163: /* setlist ::= LP idlist RP EQ expr */
{
- yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy528);
+ yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
}
break;
- case 162: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
{
- sqlite3Insert(pParse, yymsp[-3].minor.yy131, yymsp[-1].minor.yy47, yymsp[-2].minor.yy254, yymsp[-5].minor.yy394, yymsp[0].minor.yy444);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122);
}
break;
- case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
+ case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
{
- sqlite3Insert(pParse, yymsp[-4].minor.yy131, 0, yymsp[-3].minor.yy254, yymsp[-6].minor.yy394, 0);
+ sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0);
}
break;
- case 164: /* upsert ::= */
-{ yymsp[1].minor.yy444 = 0; }
+ case 166: /* upsert ::= */
+{ yymsp[1].minor.yy122 = 0; }
break;
- case 165: /* upsert ::= RETURNING selcollist */
-{ yymsp[-1].minor.yy444 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy322); }
+ case 167: /* upsert ::= RETURNING selcollist */
+{ yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); }
break;
- case 166: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
-{ yymsp[-11].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy322,yymsp[-6].minor.yy528,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,yymsp[0].minor.yy444);}
+ case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
+{ yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);}
break;
- case 167: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
-{ yymsp[-8].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy322,yymsp[-3].minor.yy528,0,0,yymsp[0].minor.yy444); }
+ case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
+{ yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); }
break;
- case 168: /* upsert ::= ON CONFLICT DO NOTHING returning */
-{ yymsp[-4].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
+ case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */
+{ yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
break;
- case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
-{ yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);}
+ case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
+{ yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);}
break;
- case 170: /* returning ::= RETURNING selcollist */
-{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);}
+ case 172: /* returning ::= RETURNING selcollist */
+{sqlite3AddReturning(pParse,yymsp[0].minor.yy14);}
break;
- case 173: /* idlist_opt ::= */
-{yymsp[1].minor.yy254 = 0;}
+ case 175: /* idlist_opt ::= */
+{yymsp[1].minor.yy132 = 0;}
break;
- case 174: /* idlist_opt ::= LP idlist RP */
-{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
+ case 176: /* idlist_opt ::= LP idlist RP */
+{yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;}
break;
- case 175: /* idlist ::= idlist COMMA nm */
-{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
+ case 177: /* idlist ::= idlist COMMA nm */
+{yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);}
break;
- case 176: /* idlist ::= nm */
-{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+ case 178: /* idlist ::= nm */
+{yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
- case 177: /* expr ::= LP expr RP */
-{yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;}
+ case 179: /* expr ::= LP expr RP */
+{yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;}
break;
- case 178: /* expr ::= ID|INDEXED|JOIN_KW */
-{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 180: /* expr ::= ID|INDEXED|JOIN_KW */
+{yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 179: /* expr ::= nm DOT nm */
+ case 181: /* 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.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
- yymsp[-2].minor.yy528 = yylhsminor.yy528;
+ yymsp[-2].minor.yy454 = yylhsminor.yy454;
break;
- case 180: /* expr ::= nm DOT nm DOT nm */
+ case 182: /* 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);
@@ -175449,27 +178175,27 @@ static YYACTIONTYPE yy_reduce(
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, 0, temp1);
}
- yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
- yymsp[-4].minor.yy528 = yylhsminor.yy528;
+ yymsp[-4].minor.yy454 = yylhsminor.yy454;
break;
- case 181: /* term ::= NULL|FLOAT|BLOB */
- case 182: /* term ::= STRING */ yytestcase(yyruleno==182);
-{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 183: /* term ::= NULL|FLOAT|BLOB */
+ case 184: /* term ::= STRING */ yytestcase(yyruleno==184);
+{yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 183: /* term ::= INTEGER */
+ case 185: /* term ::= INTEGER */
{
- yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
- if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
+ yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+ if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
}
- yymsp[0].minor.yy528 = yylhsminor.yy528;
+ yymsp[0].minor.yy454 = yylhsminor.yy454;
break;
- case 184: /* expr ::= VARIABLE */
+ case 186: /* 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.yy528 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy528, n);
+ yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, 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
@@ -175478,194 +178204,203 @@ static YYACTIONTYPE yy_reduce(
assert( t.n>=2 );
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
- yymsp[0].minor.yy528 = 0;
+ yymsp[0].minor.yy454 = 0;
}else{
- yymsp[0].minor.yy528 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
- if( yymsp[0].minor.yy528 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy528->iTable);
+ yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+ if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable);
}
}
}
break;
- case 185: /* expr ::= expr COLLATE ID|STRING */
+ case 187: /* expr ::= expr COLLATE ID|STRING */
{
- yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1);
+ yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1);
}
break;
- case 186: /* expr ::= CAST LP expr AS typetoken RP */
+ case 188: /* expr ::= CAST LP expr AS typetoken RP */
{
- yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0);
+ yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0);
}
break;
- case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
+ case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
{
- yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394);
+ yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144);
}
- yymsp[-4].minor.yy528 = yylhsminor.yy528;
+ yymsp[-4].minor.yy454 = yylhsminor.yy454;
break;
- case 188: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
+ case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
{
- yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy322, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy394);
- sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-1].minor.yy322);
+ yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144);
+ sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14);
}
- yymsp[-7].minor.yy528 = yylhsminor.yy528;
+ yymsp[-7].minor.yy454 = yylhsminor.yy454;
break;
- case 189: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
+ case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
{
- yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
+ yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
- yymsp[-3].minor.yy528 = yylhsminor.yy528;
+ yymsp[-3].minor.yy454 = yylhsminor.yy454;
break;
- case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
+ case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
{
- yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394);
- sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41);
+ yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144);
+ sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
}
- yymsp[-5].minor.yy528 = yylhsminor.yy528;
+ yymsp[-5].minor.yy454 = yylhsminor.yy454;
break;
- case 191: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
+ case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
{
- yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy322, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy394);
- sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41);
- sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy528, yymsp[-2].minor.yy322);
+ yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144);
+ sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
+ sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14);
}
- yymsp[-8].minor.yy528 = yylhsminor.yy528;
+ yymsp[-8].minor.yy454 = yylhsminor.yy454;
break;
- case 192: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
+ case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
{
- yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
- sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41);
+ yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
+ sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
}
- yymsp[-4].minor.yy528 = yylhsminor.yy528;
+ yymsp[-4].minor.yy454 = yylhsminor.yy454;
break;
- case 193: /* term ::= CTIME_KW */
+ case 195: /* term ::= CTIME_KW */
{
- yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
+ yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
}
- yymsp[0].minor.yy528 = yylhsminor.yy528;
+ yymsp[0].minor.yy454 = yylhsminor.yy454;
break;
- case 194: /* expr ::= LP nexprlist COMMA expr RP */
+ case 196: /* expr ::= LP nexprlist COMMA expr RP */
{
- ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528);
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
- if( yymsp[-4].minor.yy528 ){
- yymsp[-4].minor.yy528->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454);
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( yymsp[-4].minor.yy454 ){
+ yymsp[-4].minor.yy454->x.pList = pList;
if( ALWAYS(pList->nExpr) ){
- yymsp[-4].minor.yy528->flags |= pList->a[0].pExpr->flags & EP_Propagate;
+ yymsp[-4].minor.yy454->flags |= pList->a[0].pExpr->flags & EP_Propagate;
}
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
break;
- case 195: /* expr ::= expr AND expr */
-{yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);}
+ case 197: /* expr ::= expr AND expr */
+{yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
break;
- case 196: /* expr ::= expr OR expr */
- case 197: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==197);
- case 198: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==198);
- case 199: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==199);
- case 200: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==200);
- case 201: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==201);
- case 202: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==202);
-{yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);}
+ case 198: /* expr ::= expr OR expr */
+ case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199);
+ case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200);
+ case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201);
+ case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202);
+ case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203);
+ case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204);
+{yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
break;
- case 203: /* likeop ::= NOT LIKE_KW|MATCH */
+ case 205: /* 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 204: /* expr ::= expr likeop expr */
+ case 206: /* 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.yy528);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy528);
- yymsp[-2].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
- if( bNot ) yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy528, 0);
- if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454);
+ yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+ if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0);
+ if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc;
}
break;
- case 205: /* expr ::= expr likeop expr ESCAPE expr */
+ case 207: /* 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.yy528);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy528);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528);
- yymsp[-4].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
- if( bNot ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
- if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy454);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
+ yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
+ if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
+ if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc;
}
break;
- case 206: /* expr ::= expr ISNULL|NOTNULL */
-{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);}
+ case 208: /* expr ::= expr ISNULL|NOTNULL */
+{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy454,0);}
break;
- case 207: /* expr ::= expr NOT NULL */
-{yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);}
+ case 209: /* expr ::= expr NOT NULL */
+{yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy454,0);}
break;
- case 208: /* expr ::= expr IS expr */
+ case 210: /* expr ::= expr IS expr */
{
- yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL);
+ yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-2].minor.yy454, TK_ISNULL);
}
break;
- case 209: /* expr ::= expr IS NOT expr */
+ case 211: /* expr ::= expr IS NOT expr */
{
- yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL);
+ yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy454,yymsp[0].minor.yy454);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-3].minor.yy454, TK_NOTNULL);
}
break;
- case 210: /* expr ::= expr IS NOT DISTINCT FROM expr */
+ case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */
{
- yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL);
+ yymsp[-5].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy454,yymsp[0].minor.yy454);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-5].minor.yy454, TK_ISNULL);
}
break;
- case 211: /* expr ::= expr IS DISTINCT FROM expr */
+ case 213: /* expr ::= expr IS DISTINCT FROM expr */
{
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL);
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy454,yymsp[0].minor.yy454);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-4].minor.yy454, TK_NOTNULL);
}
break;
- case 212: /* expr ::= NOT expr */
- case 213: /* expr ::= BITNOT expr */ yytestcase(yyruleno==213);
-{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/}
+ case 214: /* expr ::= NOT expr */
+ case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
+{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/}
break;
- case 214: /* expr ::= PLUS|MINUS expr */
+ case 216: /* expr ::= PLUS|MINUS expr */
{
- yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0);
- /*A-overwrites-B*/
+ Expr *p = yymsp[0].minor.yy454;
+ 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.yy454 = p;
+ }else{
+ yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0);
+ /*A-overwrites-B*/
+ }
}
break;
- case 215: /* expr ::= expr PTR expr */
+ case 217: /* expr ::= expr PTR expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528);
- pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528);
- yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+ ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454);
+ pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454);
+ yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
}
- yymsp[-2].minor.yy528 = yylhsminor.yy528;
+ yymsp[-2].minor.yy454 = yylhsminor.yy454;
break;
- case 216: /* between_op ::= BETWEEN */
- case 219: /* in_op ::= IN */ yytestcase(yyruleno==219);
-{yymsp[0].minor.yy394 = 0;}
+ case 218: /* between_op ::= BETWEEN */
+ case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
+{yymsp[0].minor.yy144 = 0;}
break;
- case 218: /* expr ::= expr between_op expr AND expr */
+ case 220: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528);
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0);
- if( yymsp[-4].minor.yy528 ){
- yymsp[-4].minor.yy528->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0);
+ if( yymsp[-4].minor.yy454 ){
+ yymsp[-4].minor.yy454->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
+ if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
}
break;
- case 221: /* expr ::= expr in_op LP exprlist RP */
+ case 223: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy322==0 ){
+ if( yymsp[-1].minor.yy14==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -175674,208 +178409,208 @@ static YYACTIONTYPE yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528);
- yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false");
- if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528);
- }else{
- Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
- if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){
- yymsp[-1].minor.yy322->a[0].pExpr = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
+ sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy454);
+ yymsp[-4].minor.yy454 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy144 ? "true" : "false");
+ if( yymsp[-4].minor.yy454 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy454);
+ }else{
+ Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr;
+ if( yymsp[-1].minor.yy14->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy454->op!=TK_VECTOR ){
+ yymsp[-1].minor.yy14->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS);
- }else if( yymsp[-1].minor.yy322->nExpr==1 && pRHS->op==TK_SELECT ){
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pRHS->x.pSelect);
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy454, pRHS);
+ }else if( yymsp[-1].minor.yy14->nExpr==1 && pRHS->op==TK_SELECT ){
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pRHS->x.pSelect);
pRHS->x.pSelect = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
- }else{
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
- if( yymsp[-4].minor.yy528==0 ){
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
- }else if( yymsp[-4].minor.yy528->pLeft->op==TK_VECTOR ){
- int nExpr = yymsp[-4].minor.yy528->pLeft->x.pList->nExpr;
- Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy322);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
+ }else{
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
+ if( yymsp[-4].minor.yy454==0 ){
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
+ }else if( yymsp[-4].minor.yy454->pLeft->op==TK_VECTOR ){
+ int nExpr = yymsp[-4].minor.yy454->pLeft->x.pList->nExpr;
+ Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy14);
if( pSelectRHS ){
parserDoubleLinkSelect(pParse, pSelectRHS);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelectRHS);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelectRHS);
}
}else{
- yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy322;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528);
+ yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy14;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454);
}
}
- if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
+ if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
}
}
break;
- case 222: /* expr ::= LP select RP */
+ case 224: /* expr ::= LP select RP */
{
- yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47);
+ yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555);
}
break;
- case 223: /* expr ::= expr in_op LP select RP */
+ case 225: /* expr ::= expr in_op LP select RP */
{
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47);
- if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555);
+ if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
}
break;
- case 224: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ case 226: /* 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.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322);
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect);
- if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
+ if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14);
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect);
+ if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
}
break;
- case 225: /* expr ::= EXISTS LP select RP */
+ case 227: /* expr ::= EXISTS LP select RP */
{
Expr *p;
- p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47);
+ p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555);
}
break;
- case 226: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0);
- if( yymsp[-4].minor.yy528 ){
- yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528);
+ yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0);
+ if( yymsp[-4].minor.yy454 ){
+ yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
}
}
break;
- case 227: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
- yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528);
+ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
+ yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
}
break;
- case 228: /* case_exprlist ::= WHEN expr THEN expr */
+ case 230: /* case_exprlist ::= WHEN expr THEN expr */
{
- yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
- yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528);
+ yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
+ yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454);
}
break;
- case 233: /* nexprlist ::= nexprlist COMMA expr */
-{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);}
+ case 235: /* nexprlist ::= nexprlist COMMA expr */
+{yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);}
break;
- case 234: /* nexprlist ::= expr */
-{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/}
+ case 236: /* nexprlist ::= expr */
+{yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/}
break;
- case 236: /* paren_exprlist ::= LP exprlist RP */
- case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241);
-{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;}
+ case 238: /* paren_exprlist ::= LP exprlist RP */
+ case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243);
+{yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;}
break;
- case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
- sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394,
- &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF);
+ sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF);
if( IN_RENAME_OBJECT && pParse->pNewIndex ){
sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
}
}
break;
- case 238: /* uniqueflag ::= UNIQUE */
- case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280);
-{yymsp[0].minor.yy394 = OE_Abort;}
+ case 240: /* uniqueflag ::= UNIQUE */
+ case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282);
+{yymsp[0].minor.yy144 = OE_Abort;}
break;
- case 239: /* uniqueflag ::= */
-{yymsp[1].minor.yy394 = OE_None;}
+ case 241: /* uniqueflag ::= */
+{yymsp[1].minor.yy144 = OE_None;}
break;
- case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
- yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394);
+ yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144);
}
break;
- case 243: /* eidlist ::= nm collate sortorder */
+ case 245: /* eidlist ::= nm collate sortorder */
{
- yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/
+ yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/
}
break;
- case 246: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);}
+ case 248: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);}
break;
- case 247: /* cmd ::= VACUUM vinto */
-{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);}
+ case 249: /* cmd ::= VACUUM vinto */
+{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);}
break;
- case 248: /* cmd ::= VACUUM nm vinto */
-{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);}
+ case 250: /* cmd ::= VACUUM nm vinto */
+{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);}
break;
- case 251: /* cmd ::= PRAGMA nm dbnm */
+ case 253: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 257: /* 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 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 260: /* 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.yy33, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all);
}
break;
- case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 261: /* 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.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 260: /* trigger_time ::= BEFORE|AFTER */
-{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ }
+ case 262: /* trigger_time ::= BEFORE|AFTER */
+{ yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ }
break;
- case 261: /* trigger_time ::= INSTEAD OF */
-{ yymsp[-1].minor.yy394 = TK_INSTEAD;}
+ case 263: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy144 = TK_INSTEAD;}
break;
- case 262: /* trigger_time ::= */
-{ yymsp[1].minor.yy394 = TK_BEFORE; }
+ case 264: /* trigger_time ::= */
+{ yymsp[1].minor.yy144 = TK_BEFORE; }
break;
- case 263: /* trigger_event ::= DELETE|INSERT */
- case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264);
-{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;}
+ case 265: /* trigger_event ::= DELETE|INSERT */
+ case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266);
+{yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;}
break;
- case 265: /* trigger_event ::= UPDATE OF idlist */
-{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;}
+ case 267: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;}
break;
- case 266: /* when_clause ::= */
- case 285: /* key_opt ::= */ yytestcase(yyruleno==285);
-{ yymsp[1].minor.yy528 = 0; }
+ case 268: /* when_clause ::= */
+ case 287: /* key_opt ::= */ yytestcase(yyruleno==287);
+{ yymsp[1].minor.yy454 = 0; }
break;
- case 267: /* when_clause ::= WHEN expr */
- case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286);
-{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; }
+ case 269: /* when_clause ::= WHEN expr */
+ case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288);
+{ yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; }
break;
- case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
- assert( yymsp[-2].minor.yy33!=0 );
- yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33;
- yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33;
+ assert( yymsp[-2].minor.yy427!=0 );
+ yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427;
+ yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427;
}
break;
- case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy33!=0 );
- yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33;
+ assert( yymsp[-1].minor.yy427!=0 );
+ yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427;
}
break;
- case 270: /* trnm ::= nm DOT nm */
+ case 272: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -175883,367 +178618,377 @@ static YYACTIONTYPE yy_reduce(
"statements within triggers");
}
break;
- case 271: /* tridxby ::= INDEXED BY nm */
+ case 273: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 272: /* tridxby ::= NOT INDEXED */
+ case 274: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
-{yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);}
- yymsp[-8].minor.yy33 = yylhsminor.yy33;
+ case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+{yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);}
+ yymsp[-8].minor.yy427 = yylhsminor.yy427;
break;
- case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
{
- yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/
+ yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/
}
- yymsp[-7].minor.yy33 = yylhsminor.yy33;
+ yymsp[-7].minor.yy427 = yylhsminor.yy427;
break;
- case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
-{yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);}
- yymsp[-5].minor.yy33 = yylhsminor.yy33;
+ case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+{yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);}
+ yymsp[-5].minor.yy427 = yylhsminor.yy427;
break;
- case 276: /* trigger_cmd ::= scanpt select scanpt */
-{yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/}
- yymsp[-2].minor.yy33 = yylhsminor.yy33;
+ case 278: /* trigger_cmd ::= scanpt select scanpt */
+{yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/}
+ yymsp[-2].minor.yy427 = yylhsminor.yy427;
break;
- case 277: /* expr ::= RAISE LP IGNORE RP */
+ case 279: /* expr ::= RAISE LP IGNORE RP */
{
- yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
- if( yymsp[-3].minor.yy528 ){
- yymsp[-3].minor.yy528->affExpr = OE_Ignore;
+ yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
+ if( yymsp[-3].minor.yy454 ){
+ yymsp[-3].minor.yy454->affExpr = OE_Ignore;
}
}
break;
- case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */
{
- yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
- if( yymsp[-5].minor.yy528 ) {
- yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394;
+ yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0);
+ if( yymsp[-5].minor.yy454 ) {
+ yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144;
}
}
break;
- case 279: /* raisetype ::= ROLLBACK */
-{yymsp[0].minor.yy394 = OE_Rollback;}
+ case 281: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy144 = OE_Rollback;}
break;
- case 281: /* raisetype ::= FAIL */
-{yymsp[0].minor.yy394 = OE_Fail;}
+ case 283: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy144 = OE_Fail;}
break;
- case 282: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 284: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144);
}
break;
- case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454);
}
break;
- case 284: /* cmd ::= DETACH database_kw_opt expr */
+ case 286: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy528);
+ sqlite3Detach(pParse, yymsp[0].minor.yy454);
}
break;
- case 287: /* cmd ::= REINDEX */
+ case 289: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 288: /* cmd ::= REINDEX nm dbnm */
+ case 290: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 289: /* cmd ::= ANALYZE */
+ case 291: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 290: /* cmd ::= ANALYZE nm dbnm */
+ case 292: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0);
}
break;
- case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 294: /* 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 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+ case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
{
- sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0);
+ sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0);
}
break;
- case 294: /* add_column_fullname ::= fullname */
+ case 296: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy203);
}
break;
- case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
- sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
+ sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 296: /* cmd ::= create_vtab */
+ case 298: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 297: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 299: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 300: /* 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.yy394);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144);
}
break;
- case 299: /* vtabarg ::= */
+ case 301: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 300: /* vtabargtoken ::= ANY */
- case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301);
- case 302: /* lp ::= LP */ yytestcase(yyruleno==302);
+ case 302: /* vtabargtoken ::= ANY */
+ case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303);
+ case 304: /* lp ::= LP */ yytestcase(yyruleno==304);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 303: /* with ::= WITH wqlist */
- case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304);
-{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); }
+ case 305: /* with ::= WITH wqlist */
+ case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306);
+{ sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); }
break;
- case 305: /* wqas ::= AS */
-{yymsp[0].minor.yy516 = M10d_Any;}
+ case 307: /* wqas ::= AS */
+{yymsp[0].minor.yy462 = M10d_Any;}
break;
- case 306: /* wqas ::= AS MATERIALIZED */
-{yymsp[-1].minor.yy516 = M10d_Yes;}
+ case 308: /* wqas ::= AS MATERIALIZED */
+{yymsp[-1].minor.yy462 = M10d_Yes;}
break;
- case 307: /* wqas ::= AS NOT MATERIALIZED */
-{yymsp[-2].minor.yy516 = M10d_No;}
+ case 309: /* wqas ::= AS NOT MATERIALIZED */
+{yymsp[-2].minor.yy462 = M10d_No;}
break;
- case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */
+ case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */
{
- yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/
+ yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/
}
break;
- case 309: /* wqlist ::= wqitem */
+ case 311: /* withnm ::= nm */
+{pParse->bHasWith = 1;}
+ break;
+ case 312: /* wqlist ::= wqitem */
{
- yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/
+ yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/
}
break;
- case 310: /* wqlist ::= wqlist COMMA wqitem */
+ case 313: /* wqlist ::= wqlist COMMA wqitem */
{
- yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385);
+ yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67);
}
break;
- case 311: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
- assert( yymsp[0].minor.yy41!=0 );
- sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41);
- yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41;
- yylhsminor.yy41 = yymsp[0].minor.yy41;
+ assert( yymsp[0].minor.yy211!=0 );
+ sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211);
+ yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211;
+ yylhsminor.yy211 = yymsp[0].minor.yy211;
}
- yymsp[-2].minor.yy41 = yylhsminor.yy41;
+ yymsp[-2].minor.yy211 = yylhsminor.yy211;
break;
- case 312: /* windowdefn ::= nm AS LP window RP */
+ case 315: /* windowdefn ::= nm AS LP window RP */
{
- if( ALWAYS(yymsp[-1].minor.yy41) ){
- yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
+ if( ALWAYS(yymsp[-1].minor.yy211) ){
+ yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
}
- yylhsminor.yy41 = yymsp[-1].minor.yy41;
+ yylhsminor.yy211 = yymsp[-1].minor.yy211;
}
- yymsp[-4].minor.yy41 = yylhsminor.yy41;
+ yymsp[-4].minor.yy211 = yylhsminor.yy211;
break;
- case 313: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
{
- yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0);
+ yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0);
}
break;
- case 314: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
{
- yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0);
+ yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0);
}
- yymsp[-5].minor.yy41 = yylhsminor.yy41;
+ yymsp[-5].minor.yy211 = yylhsminor.yy211;
break;
- case 315: /* window ::= ORDER BY sortlist frame_opt */
+ case 318: /* window ::= ORDER BY sortlist frame_opt */
{
- yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0);
+ yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0);
}
break;
- case 316: /* window ::= nm ORDER BY sortlist frame_opt */
+ case 319: /* window ::= nm ORDER BY sortlist frame_opt */
{
- yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
+ yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
}
- yymsp[-4].minor.yy41 = yylhsminor.yy41;
+ yymsp[-4].minor.yy211 = yylhsminor.yy211;
break;
- case 317: /* window ::= nm frame_opt */
+ case 320: /* window ::= nm frame_opt */
{
- yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0);
+ yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0);
}
- yymsp[-1].minor.yy41 = yylhsminor.yy41;
+ yymsp[-1].minor.yy211 = yylhsminor.yy211;
break;
- case 318: /* frame_opt ::= */
+ case 321: /* frame_opt ::= */
{
- yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
+ yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
break;
- case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
{
- yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516);
+ yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462);
}
- yymsp[-2].minor.yy41 = yylhsminor.yy41;
+ yymsp[-2].minor.yy211 = yylhsminor.yy211;
break;
- case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
{
- yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516);
+ yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462);
}
- yymsp[-5].minor.yy41 = yylhsminor.yy41;
+ yymsp[-5].minor.yy211 = yylhsminor.yy211;
break;
- case 322: /* frame_bound_s ::= frame_bound */
- case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324);
-{yylhsminor.yy595 = yymsp[0].minor.yy595;}
- yymsp[0].minor.yy595 = yylhsminor.yy595;
+ case 325: /* frame_bound_s ::= frame_bound */
+ case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327);
+{yylhsminor.yy509 = yymsp[0].minor.yy509;}
+ yymsp[0].minor.yy509 = yylhsminor.yy509;
break;
- case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */
- case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325);
- case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327);
-{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;}
- yymsp[-1].minor.yy595 = yylhsminor.yy595;
+ case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */
+ case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328);
+ case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330);
+{yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;}
+ yymsp[-1].minor.yy509 = yylhsminor.yy509;
break;
- case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */
-{yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;}
- yymsp[-1].minor.yy595 = yylhsminor.yy595;
+ case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */
+{yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;}
+ yymsp[-1].minor.yy509 = yylhsminor.yy509;
break;
- case 328: /* frame_exclude_opt ::= */
-{yymsp[1].minor.yy516 = 0;}
+ case 331: /* frame_exclude_opt ::= */
+{yymsp[1].minor.yy462 = 0;}
break;
- case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
-{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;}
+ case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
+{yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;}
break;
- case 330: /* frame_exclude ::= NO OTHERS */
- case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331);
-{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/}
+ case 333: /* frame_exclude ::= NO OTHERS */
+ case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334);
+{yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/}
break;
- case 332: /* frame_exclude ::= GROUP|TIES */
-{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/}
+ case 335: /* frame_exclude ::= GROUP|TIES */
+{yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/}
break;
- case 333: /* window_clause ::= WINDOW windowdefn_list */
-{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; }
+ case 336: /* window_clause ::= WINDOW windowdefn_list */
+{ yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; }
break;
- case 334: /* filter_over ::= filter_clause over_clause */
+ case 337: /* filter_over ::= filter_clause over_clause */
{
- if( yymsp[0].minor.yy41 ){
- yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528;
+ if( yymsp[0].minor.yy211 ){
+ yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454;
}else{
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
}
- yylhsminor.yy41 = yymsp[0].minor.yy41;
+ yylhsminor.yy211 = yymsp[0].minor.yy211;
}
- yymsp[-1].minor.yy41 = yylhsminor.yy41;
+ yymsp[-1].minor.yy211 = yylhsminor.yy211;
break;
- case 335: /* filter_over ::= over_clause */
+ case 338: /* filter_over ::= over_clause */
{
- yylhsminor.yy41 = yymsp[0].minor.yy41;
+ yylhsminor.yy211 = yymsp[0].minor.yy211;
}
- yymsp[0].minor.yy41 = yylhsminor.yy41;
+ yymsp[0].minor.yy211 = yylhsminor.yy211;
break;
- case 336: /* filter_over ::= filter_clause */
+ case 339: /* filter_over ::= filter_clause */
{
- yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( yylhsminor.yy41 ){
- yylhsminor.yy41->eFrmType = TK_FILTER;
- yylhsminor.yy41->pFilter = yymsp[0].minor.yy528;
+ yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( yylhsminor.yy211 ){
+ yylhsminor.yy211->eFrmType = TK_FILTER;
+ yylhsminor.yy211->pFilter = yymsp[0].minor.yy454;
}else{
- sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528);
+ sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454);
}
}
- yymsp[0].minor.yy41 = yylhsminor.yy41;
+ yymsp[0].minor.yy211 = yylhsminor.yy211;
break;
- case 337: /* over_clause ::= OVER LP window RP */
+ case 340: /* over_clause ::= OVER LP window RP */
{
- yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41;
- assert( yymsp[-3].minor.yy41!=0 );
+ yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211;
+ assert( yymsp[-3].minor.yy211!=0 );
}
break;
- case 338: /* over_clause ::= OVER nm */
+ case 341: /* over_clause ::= OVER nm */
{
- yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( yymsp[-1].minor.yy41 ){
- yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
+ yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( yymsp[-1].minor.yy211 ){
+ yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
}
}
break;
- case 339: /* filter_clause ::= FILTER LP WHERE expr RP */
-{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; }
+ case 342: /* filter_clause ::= FILTER LP WHERE expr RP */
+{ yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; }
+ break;
+ case 343: /* term ::= QNUMBER */
+{
+ yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0);
+ sqlite3DequoteNumber(pParse, yylhsminor.yy454);
+}
+ yymsp[0].minor.yy454 = yylhsminor.yy454;
break;
default:
- /* (340) input ::= cmdlist */ yytestcase(yyruleno==340);
- /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341);
- /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342);
- /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343);
- /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344);
- /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345);
- /* (346) trans_opt ::= */ yytestcase(yyruleno==346);
- /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347);
- /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348);
- /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349);
- /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350);
- /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351);
- /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352);
- /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353);
- /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354);
- /* (355) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==355);
- /* (356) nm ::= STRING */ yytestcase(yyruleno==356);
- /* (357) typetoken ::= typename */ yytestcase(yyruleno==357);
- /* (358) typename ::= ID|STRING */ yytestcase(yyruleno==358);
- /* (359) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=359);
- /* (360) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=360);
- /* (361) carglist ::= carglist ccons */ yytestcase(yyruleno==361);
- /* (362) carglist ::= */ yytestcase(yyruleno==362);
- /* (363) ccons ::= NULL onconf */ yytestcase(yyruleno==363);
- /* (364) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==364);
- /* (365) ccons ::= AS generated */ yytestcase(yyruleno==365);
- /* (366) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==366);
- /* (367) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==367);
- /* (368) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=368);
- /* (369) tconscomma ::= */ yytestcase(yyruleno==369);
- /* (370) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=370);
- /* (371) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=371);
- /* (372) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=372);
- /* (373) oneselect ::= values */ yytestcase(yyruleno==373);
- /* (374) sclp ::= selcollist COMMA */ yytestcase(yyruleno==374);
- /* (375) as ::= ID|STRING */ yytestcase(yyruleno==375);
- /* (376) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=376);
- /* (377) returning ::= */ yytestcase(yyruleno==377);
- /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378);
- /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379);
- /* (380) case_operand ::= expr */ yytestcase(yyruleno==380);
- /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381);
- /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382);
- /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383);
- /* (384) nmnum ::= ON */ yytestcase(yyruleno==384);
- /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385);
- /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386);
- /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387);
- /* (388) foreach_clause ::= */ yytestcase(yyruleno==388);
- /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389);
- /* (390) trnm ::= nm */ yytestcase(yyruleno==390);
- /* (391) tridxby ::= */ yytestcase(yyruleno==391);
- /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392);
- /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393);
- /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394);
- /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395);
- /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396);
- /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397);
- /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398);
- /* (399) anylist ::= */ yytestcase(yyruleno==399);
- /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400);
- /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401);
- /* (402) with ::= */ yytestcase(yyruleno==402);
- /* (403) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=403);
- /* (404) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=404);
+ /* (344) input ::= cmdlist */ yytestcase(yyruleno==344);
+ /* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345);
+ /* (346) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=346);
+ /* (347) ecmd ::= SEMI */ yytestcase(yyruleno==347);
+ /* (348) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==348);
+ /* (349) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=349);
+ /* (350) trans_opt ::= */ yytestcase(yyruleno==350);
+ /* (351) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==351);
+ /* (352) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==352);
+ /* (353) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==353);
+ /* (354) savepoint_opt ::= */ yytestcase(yyruleno==354);
+ /* (355) cmd ::= create_table create_table_args */ yytestcase(yyruleno==355);
+ /* (356) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=356);
+ /* (357) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==357);
+ /* (358) columnlist ::= columnname carglist */ yytestcase(yyruleno==358);
+ /* (359) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==359);
+ /* (360) nm ::= STRING */ yytestcase(yyruleno==360);
+ /* (361) typetoken ::= typename */ yytestcase(yyruleno==361);
+ /* (362) typename ::= ID|STRING */ yytestcase(yyruleno==362);
+ /* (363) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=363);
+ /* (364) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=364);
+ /* (365) carglist ::= carglist ccons */ yytestcase(yyruleno==365);
+ /* (366) carglist ::= */ yytestcase(yyruleno==366);
+ /* (367) ccons ::= NULL onconf */ yytestcase(yyruleno==367);
+ /* (368) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==368);
+ /* (369) ccons ::= AS generated */ yytestcase(yyruleno==369);
+ /* (370) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==370);
+ /* (371) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==371);
+ /* (372) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=372);
+ /* (373) tconscomma ::= */ yytestcase(yyruleno==373);
+ /* (374) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=374);
+ /* (375) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=375);
+ /* (376) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=376);
+ /* (377) oneselect ::= values */ yytestcase(yyruleno==377);
+ /* (378) sclp ::= selcollist COMMA */ yytestcase(yyruleno==378);
+ /* (379) as ::= ID|STRING */ yytestcase(yyruleno==379);
+ /* (380) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=380);
+ /* (381) returning ::= */ yytestcase(yyruleno==381);
+ /* (382) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=382);
+ /* (383) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==383);
+ /* (384) case_operand ::= expr */ yytestcase(yyruleno==384);
+ /* (385) exprlist ::= nexprlist */ yytestcase(yyruleno==385);
+ /* (386) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=386);
+ /* (387) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=387);
+ /* (388) nmnum ::= ON */ yytestcase(yyruleno==388);
+ /* (389) nmnum ::= DELETE */ yytestcase(yyruleno==389);
+ /* (390) nmnum ::= DEFAULT */ yytestcase(yyruleno==390);
+ /* (391) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==391);
+ /* (392) foreach_clause ::= */ yytestcase(yyruleno==392);
+ /* (393) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==393);
+ /* (394) trnm ::= nm */ yytestcase(yyruleno==394);
+ /* (395) tridxby ::= */ yytestcase(yyruleno==395);
+ /* (396) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==396);
+ /* (397) database_kw_opt ::= */ yytestcase(yyruleno==397);
+ /* (398) kwcolumn_opt ::= */ yytestcase(yyruleno==398);
+ /* (399) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==399);
+ /* (400) vtabarglist ::= vtabarg */ yytestcase(yyruleno==400);
+ /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==401);
+ /* (402) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==402);
+ /* (403) anylist ::= */ yytestcase(yyruleno==403);
+ /* (404) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==404);
+ /* (405) anylist ::= anylist ANY */ yytestcase(yyruleno==405);
+ /* (406) with ::= */ yytestcase(yyruleno==406);
+ /* (407) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=407);
+ /* (408) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=408);
break;
/********** End reduce actions ************************************************/
};
@@ -176430,19 +179175,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 ){
@@ -177513,27 +180251,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++;
@@ -177698,10 +180467,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;
@@ -177734,7 +180506,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;
@@ -178479,32 +181251,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.
**
@@ -178699,13 +181445,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;
}
@@ -180246,7 +182985,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
@@ -181801,6 +184541,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 ){
@@ -182713,6 +185454,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.
@@ -182944,24 +185697,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)
**
@@ -183269,7 +186004,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);
}
@@ -188729,22 +191468,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;
}
@@ -194038,11 +196779,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 */
/*
@@ -200406,7 +203143,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;
}
@@ -201264,6 +204006,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];
@@ -201312,7 +204055,7 @@ static void fts3SnippetDetails(
}
mCover |= mPhrase;
- for(j=0; jnToken; j++){
+ for(j=0; jnToken && jnSnippet; j++){
mHighlight |= (mPos>>j);
}
@@ -203973,7 +206716,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, ...){
@@ -204031,6 +206773,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
@@ -204090,35 +206866,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--;
@@ -204819,7 +207574,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++;
@@ -205114,9 +207872,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;
}
@@ -205332,6 +208095,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;
@@ -205600,7 +208364,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 ){
@@ -205615,6 +208379,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 ){
@@ -205717,6 +208488,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
@@ -206123,7 +209000,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++;
@@ -206967,11 +209846,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 */
@@ -207070,13 +209950,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) ){
@@ -207635,6 +210514,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)
@@ -208649,6 +211562,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),
@@ -210548,6 +213463,8 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
return SQLITE_OK;
}
+SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double);
+
/*
** Rtree virtual table module xFilter method.
*/
@@ -210577,7 +213494,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{
@@ -211932,6 +214850,7 @@ static int rtreeUpdate(
*/
static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
Rtree *pRtree = (Rtree *)pVtab;
+ assert( pRtree->inWrTrans==0 );
pRtree->inWrTrans = 1;
return SQLITE_OK;
}
@@ -215486,7 +218405,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]);
@@ -215501,7 +218420,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);
@@ -218741,13 +221717,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=='`' ){
@@ -219437,6 +222413,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
}
@@ -219454,7 +222432,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;
@@ -220021,7 +222999,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
"(%d, %Q), "
"(%d, %Q), "
"(%d, %d), "
- "(%d, %d), "
+ "(%d, %lld), "
"(%d, %lld), "
"(%d, %lld), "
"(%d, %lld), "
@@ -220379,6 +223357,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 "
@@ -220654,7 +223633,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();
}
@@ -220871,6 +223850,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;
@@ -221775,6 +224755,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;
}
@@ -222173,6 +225156,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;
}
@@ -222830,7 +225814,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 ** */
@@ -222853,6 +225843,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 */
@@ -222861,7 +225853,6 @@ struct DbpageTable {
#define DBPAGE_COLUMN_SCHEMA 2
-
/*
** Connect to or create a dbpagevfs virtual table.
*/
@@ -223123,11 +226114,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 ){
@@ -223138,21 +226129,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;
}
@@ -223160,18 +226159,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);
@@ -223195,9 +226201,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
@@ -223219,14 +226247,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 */
};
@@ -223314,6 +226342,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() */
@@ -224997,16 +228029,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 ){
@@ -226925,14 +229960,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;
@@ -228364,15 +231399,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);
}
@@ -228534,6 +231575,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;
}
@@ -228562,12 +231609,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(
@@ -228575,11 +231616,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;
}
@@ -228667,6 +231703,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() */
@@ -228899,6 +231936,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);
@@ -228915,6 +231955,7 @@ static int sessionChangesetExtendRecord(
}
if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){
sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal);
+ pOut->nBuf += 8;
}
break;
}
@@ -228965,108 +232006,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;
@@ -229081,19 +232144,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;
}
@@ -229221,6 +232307,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.
@@ -229270,6 +232373,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);
}
}
@@ -229671,6 +232775,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);
}
}
@@ -229768,8 +232873,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
@@ -229951,6 +233056,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.
**
@@ -230017,9 +233126,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*);
@@ -230061,6 +233193,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 */
+ );
};
/*
@@ -230081,7 +233222,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
@@ -230105,7 +233246,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:
**
@@ -230129,6 +233270,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
@@ -230152,6 +233300,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
@@ -230260,6 +233432,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);
@@ -230279,6 +233478,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
@@ -230298,7 +233498,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)(
@@ -230325,6 +233525,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
+ );
};
/*
@@ -230398,6 +233617,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
@@ -230481,6 +233716,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
@@ -230520,9 +233767,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 */
@@ -230532,16 +233782,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' */
@@ -230570,9 +233821,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
@@ -230607,6 +233859,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.
**************************************************************************/
@@ -230651,7 +233905,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;
@@ -230936,18 +234190,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.
**************************************************************************/
@@ -231027,8 +234283,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);
@@ -231053,6 +234309,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.
**************************************************************************/
@@ -231205,6 +234464,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.
**************************************************************************/
@@ -231365,6 +234625,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.
@@ -231378,6 +234641,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
@@ -231404,6 +234669,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
@@ -231421,6 +234689,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])))
@@ -231436,6 +234706,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
@@ -231596,14 +234882,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;
@@ -231710,37 +234991,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
@@ -231760,24 +235049,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
@@ -231891,9 +235170,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
}
@@ -232120,25 +235416,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;
@@ -232575,19 +235865,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 ){
@@ -232959,6 +236242,7 @@ static int fts5HighlightCb(
return rc;
}
+
/*
** Implementation of highlight() function.
*/
@@ -232989,12 +236273,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);
@@ -233191,6 +236482,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);
@@ -233257,6 +236552,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);
}
@@ -233275,7 +236573,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);
@@ -233459,6 +236762,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) */
@@ -233466,9 +236816,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 */
@@ -234133,7 +237484,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 */
@@ -234141,6 +237491,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;
@@ -234197,12 +237548,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{
@@ -234225,16 +237575,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;
}
@@ -234263,6 +237611,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");
@@ -234283,6 +237641,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 },
@@ -234311,16 +237679,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
@@ -234380,7 +237738,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)
@@ -234391,6 +237750,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;
@@ -234411,11 +237771,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");
}
}
}
@@ -234449,10 +237824,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;
@@ -234501,13 +237878,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;
}
}
@@ -234539,11 +237916,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. */
@@ -234554,6 +237937,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";
}
@@ -234587,9 +237973,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++){
@@ -234664,10 +238055,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;
}
/*
@@ -234921,13 +238326,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;
}
@@ -234938,6 +238340,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
**
@@ -234994,7 +238419,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)
@@ -235002,6 +238427,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
@@ -235222,11 +238651,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 ){
@@ -235243,15 +238673,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;
@@ -235264,7 +238686,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;
}
@@ -236065,7 +239491,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;
@@ -236587,9 +240013,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*);
@@ -236811,6 +240234,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;
}
@@ -236830,7 +240254,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];
@@ -237198,6 +240622,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 ){
@@ -237342,19 +240769,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;
}
}
@@ -237392,6 +240823,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 ){
@@ -237405,6 +240837,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;
@@ -238037,6 +241471,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);
@@ -239620,11 +243055,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;
}
@@ -239647,6 +243083,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;
}
@@ -240972,7 +244409,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;
@@ -243676,6 +247113,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;
@@ -247600,7 +251042,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(
@@ -247942,8 +251384,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
@@ -247962,11 +251413,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 */
};
@@ -248054,7 +251522,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 */
@@ -248165,10 +251633,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)
+ );
}
/*
@@ -248236,8 +251710,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 */
@@ -248259,11 +251737,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 ){
@@ -248273,6 +251747,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;
@@ -248340,10 +251815,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;
@@ -248390,10 +251865,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:
@@ -248426,7 +251901,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;
@@ -248457,18 +251932,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]);
@@ -248485,6 +251957,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;
@@ -248521,7 +251994,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;
@@ -248536,14 +252009,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;
@@ -248819,6 +252295,7 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
}
}else{
rc = SQLITE_OK;
+ CsrFlagSet(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
}
break;
}
@@ -248848,7 +252325,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);
}
@@ -249072,6 +252549,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
@@ -249106,13 +252722,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));
@@ -249136,8 +252746,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');
@@ -249149,7 +252765,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);
@@ -249157,9 +252773,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':
@@ -249247,9 +252869,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
@@ -249292,9 +252912,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);
}
@@ -249311,25 +252935,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.
@@ -249366,8 +252981,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)
);
}
@@ -249376,14 +252996,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:
@@ -249421,7 +253033,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"
);
@@ -249477,7 +253089,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;
}
@@ -249490,7 +253102,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);
@@ -249498,6 +253110,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
@@ -249559,6 +253232,7 @@ static int fts5UpdateMethod(
rc = SQLITE_ERROR;
}else{
rc = fts5SpecialDelete(pTab, apVal);
+ bUpdateOrDelete = 1;
}
}else{
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
@@ -249583,41 +253257,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);
@@ -249625,30 +253304,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 = sqlite3Fts5StorageContentInsert(pStorage, 0, apVal, pRowid);
+ }
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
+ rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 0);
}
if( rc==SQLITE_OK ){
- rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid);
+ 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);
}
+
}
}
@@ -249665,6 +253371,7 @@ static int fts5UpdateMethod(
}
}
+ update_out:
pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
@@ -249686,9 +253393,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;
}
/*
@@ -249742,17 +253451,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){
@@ -249765,6 +253497,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,
@@ -249774,28 +253549,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;
@@ -249803,20 +253585,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);
@@ -249841,7 +253635,6 @@ static int fts5CsrPoslist(
*pn = 0;
}
-
return rc;
}
@@ -249910,7 +253703,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;
}
@@ -249988,7 +253782,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 ){
@@ -249997,17 +253791,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);
}
}
}
@@ -250087,11 +253883,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;
@@ -250099,8 +253894,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);
}
@@ -250250,8 +254049,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,
@@ -250272,7 +254111,9 @@ static const Fts5ExtensionApi sFts5Api = {
fts5ApiPhraseFirstColumn,
fts5ApiPhraseNextColumn,
fts5ApiQueryToken,
- fts5ApiInstToken
+ fts5ApiInstToken,
+ fts5ApiColumnLocale,
+ fts5ApiTokenize_v2
};
/*
@@ -250323,6 +254164,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;
@@ -250336,6 +254178,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,
@@ -250351,12 +254208,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;
}
}
@@ -250474,8 +254332,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(
@@ -250486,20 +254344,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;
}
@@ -250639,47 +254509,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;
@@ -250694,6 +254727,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.
@@ -250709,53 +254772,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;
@@ -250776,6 +254861,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 */
@@ -250799,7 +254888,68 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2024-04-15 13:34:05 8653b758870e6ef0c98d46b3ace27849054af85da891eb121e9aaa537f1e8355", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e", -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);
+ }
}
/*
@@ -250834,18 +254984,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){
@@ -250887,10 +255044,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);
@@ -250909,6 +255078,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
@@ -250983,13 +255159,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];
};
@@ -251003,14 +255206,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
@@ -251040,6 +255244,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 */
@@ -251055,6 +255260,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],
@@ -251071,6 +255278,7 @@ static int fts5StorageGetStmt(
break;
case FTS5_STMT_LOOKUP:
+ case FTS5_STMT_LOOKUP2:
zSql = sqlite3_mprintf(azStmt[eStmt],
pC->zContentExprlist, pC->zContent, pC->zContentRowid
);
@@ -251078,20 +255286,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);
+ }
+ }
+
+ /* 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);
+ }
}
- zBind[i*2-1] = '\0';
- zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
- sqlite3_free(zBind);
}
+
+ zSql = sqlite3Fts5Mprintf(&rc, azStmt[eStmt], pC->zDb, pC->zName,zBind);
+ sqlite3_free(zBind);
break;
}
@@ -251117,7 +255340,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--;
@@ -251277,9 +255500,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{
@@ -251288,8 +255513,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);
}
@@ -251366,15 +255603,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 */
@@ -251383,12 +255654,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);
+ }
}
}
@@ -251396,26 +255676,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);
}
}
}
@@ -251425,11 +255721,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
@@ -251442,7 +255756,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. */
@@ -251486,12 +255802,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;
@@ -251545,7 +255861,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;
@@ -251561,8 +255882,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);
}
}
@@ -251577,7 +255904,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);
}
@@ -251609,8 +255938,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
);
}
@@ -251651,14 +255985,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;
@@ -251724,6 +256080,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
){
@@ -251731,7 +256088,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{
@@ -251740,9 +256099,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);
@@ -251777,14 +256179,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;
@@ -251948,29 +256374,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);
@@ -252396,7 +256854,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);
}
@@ -252784,6 +257240,7 @@ static int fts5PorterCreate(
PorterTokenizer *pRet;
void *pUserdata = 0;
const char *zBase = "unicode61";
+ fts5_tokenizer_v2 *pV2 = 0;
if( nArg>0 ){
zBase = azArg[0];
@@ -252792,14 +257249,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 ){
@@ -253450,6 +257908,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;
@@ -253457,8 +257916,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
);
}
@@ -253488,40 +257947,46 @@ static int fts5TriCreate(
Fts5Tokenizer **ppOut
){
int rc = SQLITE_OK;
- TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew));
+ TrigramTokenizer *pNew = 0;
UNUSED_PARAM(pUnused);
- if( pNew==0 ){
- rc = SQLITE_NOMEM;
+ if( nArg%2 ){
+ rc = SQLITE_ERROR;
}else{
int i;
- pNew->bFold = 1;
- pNew->iFoldParam = 0;
- for(i=0; rc==SQLITE_OK && ibFold = 1;
+ pNew->iFoldParam = 0;
+
+ for(i=0; rc==SQLITE_OK && ibFold = (zArg[0]=='0');
+ }
+ }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
+ if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
+ rc = SQLITE_ERROR;
+ }else{
+ pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
+ }
}else{
- pNew->bFold = (zArg[0]=='0');
- }
- }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
- if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){
rc = SQLITE_ERROR;
- }else{
- pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0;
}
- }else{
- rc = SQLITE_ERROR;
}
- }
- if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
- rc = SQLITE_ERROR;
- }
+ if( pNew->iFoldParam!=0 && pNew->bFold==0 ){
+ rc = SQLITE_ERROR;
+ }
- if( rc!=SQLITE_OK ){
- fts5TriDelete((Fts5Tokenizer*)pNew);
- pNew = 0;
+ if( rc!=SQLITE_OK ){
+ fts5TriDelete((Fts5Tokenizer*)pNew);
+ pNew = 0;
+ }
}
}
*ppOut = (Fts5Tokenizer*)pNew;
@@ -253626,6 +258091,16 @@ static int sqlite3Fts5TokenizerPattern(
return FTS5_PATTERN_NONE;
}
+/*
+** Return true if the tokenizer described by p->azArg[] 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.
*/
@@ -253636,7 +258111,6 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){
} aBuiltin[] = {
{ "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}},
{ "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
- { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
{ "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}},
};
@@ -253651,7 +258125,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;
}
@@ -254021,6 +258508,9 @@ static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){
default: return 1; }
break;
+
+ default:
+ return 1;
}
return 0;
}
@@ -254845,6 +259335,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;
@@ -254871,9 +259362,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
/*
@@ -255050,11 +259543,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;
@@ -255146,7 +259641,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{
@@ -255306,9 +259801,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]++;
@@ -255406,6 +259911,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);
diff --git a/deps.sh b/deps.sh
index 3f74476..77e9e99 100755
--- a/deps.sh
+++ b/deps.sh
@@ -2,17 +2,17 @@
# download sqlite amalgamation
-curl -o sqlite-amalgamation.zip https://www.sqlite.org/2024/sqlite-amalgamation-3450300.zip
+curl -o sqlite-amalgamation.zip https://www.sqlite.org/2024/sqlite-amalgamation-3470000.zip
unzip sqlite-amalgamation.zip
-cp sqlite-amalgamation-3450300/sqlite3.c Sources/CSQLiteVec/
-cp sqlite-amalgamation-3450300/sqlite3.h Sources/CSQLiteVec/include/
-cp sqlite-amalgamation-3450300/sqlite3ext.h Sources/CSQLiteVec/include/
-rm -rf sqlite-amalgamation-3450300
+cp sqlite-amalgamation-3470000/sqlite3.c Sources/CSQLiteVec/
+cp sqlite-amalgamation-3470000/sqlite3.h Sources/CSQLiteVec/include/
+cp sqlite-amalgamation-3470000/sqlite3ext.h Sources/CSQLiteVec/include/
+rm -rf sqlite-amalgamation-3470000
rm sqlite-amalgamation.zip
# download sqlite-vec amalgamation
-curl -o sqlite-vec-amalgamation.zip -L https://github.com/asg017/sqlite-vec/releases/download/v0.1.2/sqlite-vec-0.1.2-amalgamation.zip
+curl -o sqlite-vec-amalgamation.zip -L https://github.com/asg017/sqlite-vec/releases/download/v0.1.3/sqlite-vec-0.1.3-amalgamation.zip
unzip sqlite-vec-amalgamation.zip
mv sqlite-vec.c Sources/CSQLiteVec/
mv sqlite-vec.h Sources/CSQLiteVec/include/