sqlite3_value_frombind
+** | → | True if value originated from a [bound parameter]
**
**
** Details:
@@ -5980,6 +6125,11 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** than within an [xUpdate] method call for an UPDATE statement, then
** the return value is arbitrary and meaningless.
**
+** ^The sqlite3_value_frombind(X) interface returns non-zero if the
+** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
+** interfaces. ^If X comes from an SQL literal value, or a table column,
+** and expression, then sqlite3_value_frombind(X) returns zero.
+**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
@@ -6025,6 +6175,7 @@ SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
+SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@@ -6760,7 +6911,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** associated with database N of connection D. ^The main database file
** has the name "main". If there is no attached database N on the database
** connection D, or if database N is a temporary or in-memory database, then
-** a NULL pointer is returned.
+** this function will return either a NULL pointer or an empty string.
**
** ^The filename returned by this function is the output of the
** xFullPathname method of the [VFS]. ^In other words, the filename
@@ -7315,6 +7466,9 @@ struct sqlite3_module {
int (*xSavepoint)(sqlite3_vtab *pVTab, int);
int (*xRelease)(sqlite3_vtab *pVTab, int);
int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
+ /* The methods above are in versions 1 and 2 of the sqlite_module object.
+ ** Those below are for version 3 and greater. */
+ int (*xShadowName)(const char*);
};
/*
@@ -8237,6 +8391,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -8247,7 +8402,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
-#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
+#define SQLITE_TESTCTRL_RESULT_INTREAL 27
+#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */
/*
** CAPI3REF: SQL Keyword Checking
@@ -9649,6 +9805,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** can use to customize and optimize their behavior.
**
**
+** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
** - SQLITE_VTAB_CONSTRAINT_SUPPORT
**
- Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
@@ -10418,7 +10575,7 @@ struct sqlite3_rtree_query_info {
sqlite3_int64 iRowid; /* Rowid for current entry */
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
int eParentWithin; /* Visibility of parent node */
- int eWithin; /* OUT: Visiblity */
+ int eWithin; /* OUT: Visibility */
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
/* The following fields are only available in 3.8.11 and later */
sqlite3_value **apSqlParam; /* Original SQL values of parameters */
@@ -10914,12 +11071,38 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
** another change for table X.
+**
+** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
+** may be modified by passing a combination of
+** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
+**
+** Note that the sqlite3changeset_start_v2() API is still experimental
+** and therefore subject to change.
*/
SQLITE_API int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset /* Pointer to blob containing changeset */
);
+SQLITE_API int sqlite3changeset_start_v2(
+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
+ int nChangeset, /* Size of changeset blob in bytes */
+ void *pChangeset, /* Pointer to blob containing changeset */
+ int flags /* SESSION_CHANGESETSTART_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3changeset_start_v2
+**
+** The following flags may passed via the 4th parameter to
+** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
+**
+**
- SQLITE_CHANGESETAPPLY_INVERT
-
+** Invert the changeset while iterating through it. This is equivalent to
+** inverting a changeset using sqlite3changeset_invert() before applying it.
+** It is an error to specify this flag with a patchset.
+*/
+#define SQLITE_CHANGESETSTART_INVERT 0x0002
/*
@@ -10963,7 +11146,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
** sqlite3changeset_next() is called on the iterator or until the
** conflict-handler function returns. If pnCol is not NULL, then *pnCol is
** set to the number of columns in the table affected by the change. If
-** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
+** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
** is an indirect change, or false (0) otherwise. See the documentation for
** [sqlite3session_indirect()] for a description of direct and indirect
** changes. Finally, if pOp is not NULL, then *pOp is set to one of
@@ -11574,7 +11757,7 @@ SQLITE_API int sqlite3changeset_apply_v2(
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
- int flags /* Combination of SESSION_APPLY_* flags */
+ int flags /* SESSION_CHANGESETAPPLY_* flags */
);
/*
@@ -11592,8 +11775,14 @@ SQLITE_API int sqlite3changeset_apply_v2(
** causes the sessions module to omit this savepoint. In this case, if the
** caller has an open transaction or savepoint when apply_v2() is called,
** it may revert the partially applied changeset by rolling it back.
+**
+**
- SQLITE_CHANGESETAPPLY_INVERT
-
+** Invert the changeset before applying it. This is equivalent to inverting
+** a changeset using sqlite3changeset_invert() before applying it. It is
+** an error to specify this flag with a patchset.
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
+#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
/*
** CAPI3REF: Constants Passed To The Conflict Handler
@@ -11824,7 +12013,7 @@ SQLITE_API int sqlite3rebaser_configure(
** in size. This function allocates and populates a buffer with a copy
** of the changeset rebased rebased according to the configuration of the
** rebaser object passed as the first argument. If successful, (*ppOut)
-** is set to point to the new buffer containing the rebased changset and
+** is set to point to the new buffer containing the rebased changeset and
** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
** responsibility of the caller to eventually free the new buffer using
** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
@@ -11987,6 +12176,12 @@ SQLITE_API int sqlite3changeset_start_strm(
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
+SQLITE_API int sqlite3changeset_start_v2_strm(
+ sqlite3_changeset_iter **pp,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int flags
+);
SQLITE_API int sqlite3session_changeset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
@@ -12013,6 +12208,45 @@ SQLITE_API int sqlite3rebaser_rebase_strm(
void *pOut
);
+/*
+** CAPI3REF: Configure global parameters
+**
+** The sqlite3session_config() interface is used to make global configuration
+** changes to the sessions module in order to tune it to the specific needs
+** of the application.
+**
+** The sqlite3session_config() interface is not threadsafe. If it is invoked
+** while any other thread is inside any other sessions method then the
+** results are undefined. Furthermore, if it is invoked after any sessions
+** related objects have been created, the results are also undefined.
+**
+** The first argument to the sqlite3session_config() function must be one
+** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
+** interpretation of the (void*) value passed as the second parameter and
+** the effect of calling this function depends on the value of the first
+** parameter.
+**
+**
+** - SQLITE_SESSION_CONFIG_STRMSIZE
-
+** By default, the sessions module streaming interfaces attempt to input
+** and output data in approximately 1 KiB chunks. This operand may be used
+** to set and query the value of this configuration setting. The pointer
+** passed as the second argument must point to a value of type (int).
+** If this value is greater than 0, it is used as the new streaming data
+** chunk size for both input and output. Before returning, the (int) value
+** pointed to by pArg is set to the final value of the streaming interface
+** chunk size.
+**
+**
+** This function returns SQLITE_OK if successful, or an SQLite error code
+** otherwise.
+*/
+SQLITE_API int sqlite3session_config(int op, void *pArg);
+
+/*
+** CAPI3REF: Values for sqlite3session_config().
+*/
+#define SQLITE_SESSION_CONFIG_STRMSIZE 1
/*
** Make sure we can call this stuff from C++.
@@ -12146,12 +12380,8 @@ struct Fts5PhraseIter {
**
** Usually, output parameter *piPhrase is set to the phrase number, *piCol
** to the column in which it occurs and *piOff the token offset of the
-** first token of the phrase. The exception is if the table was created
-** with the offsets=0 option specified. In this case *piOff is always
-** set to -1.
-**
-** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM)
-** if an error occurs.
+** first token of the phrase. Returns SQLITE_OK if successful, or an error
+** code (i.e. SQLITE_NOMEM) if an error occurs.
**
** This API can be quite slow if used with an FTS5 table created with the
** "detail=none" or "detail=column" option.
@@ -12192,7 +12422,7 @@ struct Fts5PhraseIter {
** Save the pointer passed as the second argument as the extension functions
** "auxiliary data". The pointer may then be retrieved by the current or any
** future invocation of the same fts5 extension function made as part of
-** of the same MATCH query using the xGetAuxdata() API.
+** the same MATCH query using the xGetAuxdata() API.
**
** Each extension function is allocated a single auxiliary data slot for
** each FTS query (MATCH expression). If the extension function is invoked
@@ -12207,7 +12437,7 @@ struct Fts5PhraseIter {
** The xDelete callback, if one is specified, is also invoked on the
** auxiliary data pointer after the FTS5 query has finished.
**
-** If an error (e.g. an OOM condition) occurs within this function, an
+** If an error (e.g. an OOM condition) occurs within this function,
** the auxiliary data is set to NULL and an error code returned. If the
** xDelete parameter was not NULL, it is invoked on the auxiliary data
** pointer before returning.
@@ -12440,11 +12670,11 @@ struct Fts5ExtensionApi {
** the tokenizer substitutes "first" for "1st" and the query works
** as expected.
**
-** - By adding multiple synonyms for a single term to the FTS index.
-** In this case, when tokenizing query text, the tokenizer may
-** provide multiple synonyms for a single term within the document.
-** FTS5 then queries the index for each synonym individually. For
-** example, faced with the query:
+**
- By querying the index for all synonyms of each query term
+** separately. In this case, when tokenizing query text, the
+** tokenizer may provide multiple synonyms for a single term
+** within the document. FTS5 then queries the index for each
+** synonym individually. For example, faced with the query:
**
**
** ... MATCH 'first place'
@@ -12468,7 +12698,7 @@ struct Fts5ExtensionApi {
** "place".
**
** This way, even if the tokenizer does not provide synonyms
-** when tokenizing query text (it should not - to do would be
+** when tokenizing query text (it should not - to do so would be
** inefficient), it doesn't matter if the user queries for
** 'first + place' or '1st + place', as there are entries in the
** FTS index corresponding to both forms of the first token.
@@ -13233,7 +13463,7 @@ struct Hash {
unsigned int count; /* Number of entries in this table */
HashElem *first; /* The first element of the array */
struct _ht { /* the hash table */
- int count; /* Number of entries with this hash */
+ unsigned int count; /* Number of entries with this hash */
HashElem *chain; /* Pointer to first entry with this hash */
} *ht;
};
@@ -13374,99 +13604,94 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_PRECEDING 85
#define TK_RANGE 86
#define TK_UNBOUNDED 87
-#define TK_REINDEX 88
-#define TK_RENAME 89
-#define TK_CTIME_KW 90
-#define TK_ANY 91
-#define TK_BITAND 92
-#define TK_BITOR 93
-#define TK_LSHIFT 94
-#define TK_RSHIFT 95
-#define TK_PLUS 96
-#define TK_MINUS 97
-#define TK_STAR 98
-#define TK_SLASH 99
-#define TK_REM 100
-#define TK_CONCAT 101
-#define TK_COLLATE 102
-#define TK_BITNOT 103
-#define TK_ON 104
-#define TK_INDEXED 105
-#define TK_STRING 106
-#define TK_JOIN_KW 107
-#define TK_CONSTRAINT 108
-#define TK_DEFAULT 109
-#define TK_NULL 110
-#define TK_PRIMARY 111
-#define TK_UNIQUE 112
-#define TK_CHECK 113
-#define TK_REFERENCES 114
-#define TK_AUTOINCR 115
-#define TK_INSERT 116
-#define TK_DELETE 117
-#define TK_UPDATE 118
-#define TK_SET 119
-#define TK_DEFERRABLE 120
-#define TK_FOREIGN 121
-#define TK_DROP 122
-#define TK_UNION 123
-#define TK_ALL 124
-#define TK_EXCEPT 125
-#define TK_INTERSECT 126
-#define TK_SELECT 127
-#define TK_VALUES 128
-#define TK_DISTINCT 129
-#define TK_DOT 130
-#define TK_FROM 131
-#define TK_JOIN 132
-#define TK_USING 133
-#define TK_ORDER 134
-#define TK_GROUP 135
-#define TK_HAVING 136
-#define TK_LIMIT 137
-#define TK_WHERE 138
-#define TK_INTO 139
-#define TK_NOTHING 140
-#define TK_FLOAT 141
-#define TK_BLOB 142
-#define TK_INTEGER 143
-#define TK_VARIABLE 144
-#define TK_CASE 145
-#define TK_WHEN 146
-#define TK_THEN 147
-#define TK_ELSE 148
-#define TK_INDEX 149
-#define TK_ALTER 150
-#define TK_ADD 151
-#define TK_WINDOW 152
-#define TK_OVER 153
-#define TK_FILTER 154
-#define TK_TRUEFALSE 155
-#define TK_ISNOT 156
-#define TK_FUNCTION 157
-#define TK_COLUMN 158
-#define TK_AGG_FUNCTION 159
-#define TK_AGG_COLUMN 160
-#define TK_UMINUS 161
-#define TK_UPLUS 162
-#define TK_TRUTH 163
-#define TK_REGISTER 164
-#define TK_VECTOR 165
-#define TK_SELECT_COLUMN 166
-#define TK_IF_NULL_ROW 167
-#define TK_ASTERISK 168
-#define TK_SPAN 169
-#define TK_END_OF_FILE 170
-#define TK_UNCLOSED_STRING 171
-#define TK_SPACE 172
-#define TK_ILLEGAL 173
-
-/* The token codes above must all fit in 8 bits */
-#define TKFLG_MASK 0xff
-
-/* Flags that can be added to a token code when it is not
-** being stored in a u8: */
-#define TKFLG_DONTFOLD 0x100 /* Omit constant folding optimizations */
+#define TK_EXCLUDE 88
+#define TK_GROUPS 89
+#define TK_OTHERS 90
+#define TK_TIES 91
+#define TK_REINDEX 92
+#define TK_RENAME 93
+#define TK_CTIME_KW 94
+#define TK_ANY 95
+#define TK_BITAND 96
+#define TK_BITOR 97
+#define TK_LSHIFT 98
+#define TK_RSHIFT 99
+#define TK_PLUS 100
+#define TK_MINUS 101
+#define TK_STAR 102
+#define TK_SLASH 103
+#define TK_REM 104
+#define TK_CONCAT 105
+#define TK_COLLATE 106
+#define TK_BITNOT 107
+#define TK_ON 108
+#define TK_INDEXED 109
+#define TK_STRING 110
+#define TK_JOIN_KW 111
+#define TK_CONSTRAINT 112
+#define TK_DEFAULT 113
+#define TK_NULL 114
+#define TK_PRIMARY 115
+#define TK_UNIQUE 116
+#define TK_CHECK 117
+#define TK_REFERENCES 118
+#define TK_AUTOINCR 119
+#define TK_INSERT 120
+#define TK_DELETE 121
+#define TK_UPDATE 122
+#define TK_SET 123
+#define TK_DEFERRABLE 124
+#define TK_FOREIGN 125
+#define TK_DROP 126
+#define TK_UNION 127
+#define TK_ALL 128
+#define TK_EXCEPT 129
+#define TK_INTERSECT 130
+#define TK_SELECT 131
+#define TK_VALUES 132
+#define TK_DISTINCT 133
+#define TK_DOT 134
+#define TK_FROM 135
+#define TK_JOIN 136
+#define TK_USING 137
+#define TK_ORDER 138
+#define TK_GROUP 139
+#define TK_HAVING 140
+#define TK_LIMIT 141
+#define TK_WHERE 142
+#define TK_INTO 143
+#define TK_NOTHING 144
+#define TK_FLOAT 145
+#define TK_BLOB 146
+#define TK_INTEGER 147
+#define TK_VARIABLE 148
+#define TK_CASE 149
+#define TK_WHEN 150
+#define TK_THEN 151
+#define TK_ELSE 152
+#define TK_INDEX 153
+#define TK_ALTER 154
+#define TK_ADD 155
+#define TK_WINDOW 156
+#define TK_OVER 157
+#define TK_FILTER 158
+#define TK_TRUEFALSE 159
+#define TK_ISNOT 160
+#define TK_FUNCTION 161
+#define TK_COLUMN 162
+#define TK_AGG_FUNCTION 163
+#define TK_AGG_COLUMN 164
+#define TK_UMINUS 165
+#define TK_UPLUS 166
+#define TK_TRUTH 167
+#define TK_REGISTER 168
+#define TK_VECTOR 169
+#define TK_SELECT_COLUMN 170
+#define TK_IF_NULL_ROW 171
+#define TK_ASTERISK 172
+#define TK_SPAN 173
+#define TK_SPACE 174
+#define TK_ILLEGAL 175
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -13772,12 +13997,13 @@ typedef INT16_TYPE LogEst;
** at run-time.
*/
#ifndef SQLITE_BYTEORDER
-# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
- defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
- defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
- defined(__arm__) || defined(_M_ARM64)
+# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
+ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
+ defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
# define SQLITE_BYTEORDER 1234
-# elif defined(sparc) || defined(__ppc__)
+# elif defined(sparc) || defined(__ppc__) || \
+ defined(__ARMEB__) || defined(__AARCH64EB__)
# define SQLITE_BYTEORDER 4321
# else
# define SQLITE_BYTEORDER 0
@@ -14398,9 +14624,6 @@ struct BtreePayload {
SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
int flags, int seekResult);
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
-#ifndef SQLITE_OMIT_WINDOWFUNC
-SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor*);
-#endif
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
@@ -14412,6 +14635,7 @@ SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
+SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
@@ -14651,12 +14875,11 @@ typedef struct VdbeOpList VdbeOpList;
#endif
/*
-** The following macro converts a relative address in the p2 field
-** of a VdbeOp structure into a negative number so that
-** sqlite3VdbeAddOpList() knows that the address is relative. Calling
-** the macro again restores the address.
+** The following macro converts a label returned by sqlite3VdbeMakeLabel()
+** into an index into the Parse.aLabel[] array that contains the resolved
+** address of that label.
*/
-#define ADDR(X) (-1-(X))
+#define ADDR(X) (~(X))
/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
@@ -14758,25 +14981,25 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Offset 89 /* synopsis: r[P3] = sqlite_offset(P1) */
#define OP_Column 90 /* synopsis: r[P3]=PX */
#define OP_Affinity 91 /* synopsis: affinity(r[P1@P2]) */
-#define OP_BitAnd 92 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 93 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 94 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
-#define OP_Add 96 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 97 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 98 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 99 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 100 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 101 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_MakeRecord 102 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
-#define OP_BitNot 103 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
-#define OP_Count 104 /* synopsis: r[P2]=count() */
-#define OP_ReadCookie 105
-#define OP_String8 106 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_SetCookie 107
-#define OP_ReopenIdx 108 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenRead 109 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenWrite 110 /* synopsis: root=P2 iDb=P3 */
+#define OP_MakeRecord 92 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 93 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 94
+#define OP_SetCookie 95
+#define OP_BitAnd 96 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 97 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 98 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
+#define OP_Add 100 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 101 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 102 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 103 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 104 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 105 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_ReopenIdx 106 /* synopsis: root=P2 iDb=P3 */
+#define OP_BitNot 107 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
+#define OP_OpenRead 108 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 109 /* synopsis: root=P2 iDb=P3 */
+#define OP_String8 110 /* same as TK_STRING, synopsis: r[P2]='P4' */
#define OP_OpenDup 111
#define OP_OpenAutoindex 112 /* synopsis: nColumn=P2 */
#define OP_OpenEphemeral 113 /* synopsis: nColumn=P2 */
@@ -14789,57 +15012,56 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */
#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */
#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */
-#define OP_InsertInt 123 /* synopsis: intkey=P3 data=r[P2] */
-#define OP_Delete 124
-#define OP_ResetCount 125
-#define OP_SorterCompare 126 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-#define OP_SorterData 127 /* synopsis: r[P2]=data */
-#define OP_RowData 128 /* synopsis: r[P2]=data */
-#define OP_Rowid 129 /* synopsis: r[P2]=rowid */
-#define OP_NullRow 130
-#define OP_SeekEnd 131
-#define OP_SorterInsert 132 /* synopsis: key=r[P2] */
-#define OP_IdxInsert 133 /* synopsis: key=r[P2] */
-#define OP_IdxDelete 134 /* synopsis: key=r[P2@P3] */
-#define OP_DeferredSeek 135 /* synopsis: Move P3 to P1.rowid if needed */
-#define OP_IdxRowid 136 /* synopsis: r[P2]=rowid */
-#define OP_Destroy 137
-#define OP_Clear 138
-#define OP_ResetSorter 139
-#define OP_CreateBtree 140 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
-#define OP_Real 141 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_SqlExec 142
-#define OP_ParseSchema 143
-#define OP_LoadAnalysis 144
-#define OP_DropTable 145
-#define OP_DropIndex 146
-#define OP_DropTrigger 147
-#define OP_IntegrityCk 148
-#define OP_RowSetAdd 149 /* synopsis: rowset(P1)=r[P2] */
-#define OP_Param 150
-#define OP_FkCounter 151 /* synopsis: fkctr[P1]+=P2 */
-#define OP_MemMax 152 /* synopsis: r[P1]=max(r[P1],r[P2]) */
-#define OP_OffsetLimit 153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
-#define OP_AggInverse 154 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
-#define OP_AggStep 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggStep1 156 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggValue 157 /* synopsis: r[P3]=value N=P2 */
-#define OP_AggFinal 158 /* synopsis: accum=r[P1] N=P2 */
-#define OP_Expire 159
-#define OP_TableLock 160 /* synopsis: iDb=P1 root=P2 write=P3 */
-#define OP_VBegin 161
-#define OP_VCreate 162
-#define OP_VDestroy 163
-#define OP_VOpen 164
-#define OP_VColumn 165 /* synopsis: r[P3]=vcolumn(P2) */
-#define OP_VRename 166
-#define OP_Pagecount 167
-#define OP_MaxPgcnt 168
-#define OP_Trace 169
-#define OP_CursorHint 170
-#define OP_Noop 171
-#define OP_Explain 172
-#define OP_Abortable 173
+#define OP_Delete 123
+#define OP_ResetCount 124
+#define OP_SorterCompare 125 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData 126 /* synopsis: r[P2]=data */
+#define OP_RowData 127 /* synopsis: r[P2]=data */
+#define OP_Rowid 128 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 129
+#define OP_SeekEnd 130
+#define OP_SorterInsert 131 /* synopsis: key=r[P2] */
+#define OP_IdxInsert 132 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 133 /* synopsis: key=r[P2@P3] */
+#define OP_DeferredSeek 134 /* synopsis: Move P3 to P1.rowid if needed */
+#define OP_IdxRowid 135 /* synopsis: r[P2]=rowid */
+#define OP_Destroy 136
+#define OP_Clear 137
+#define OP_ResetSorter 138
+#define OP_CreateBtree 139 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
+#define OP_SqlExec 140
+#define OP_ParseSchema 141
+#define OP_LoadAnalysis 142
+#define OP_DropTable 143
+#define OP_DropIndex 144
+#define OP_Real 145 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
+#define OP_DropTrigger 146
+#define OP_IntegrityCk 147
+#define OP_RowSetAdd 148 /* synopsis: rowset(P1)=r[P2] */
+#define OP_Param 149
+#define OP_FkCounter 150 /* synopsis: fkctr[P1]+=P2 */
+#define OP_MemMax 151 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_OffsetLimit 152 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+#define OP_AggInverse 153 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
+#define OP_AggStep 154 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggStep1 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggValue 156 /* synopsis: r[P3]=value N=P2 */
+#define OP_AggFinal 157 /* synopsis: accum=r[P1] N=P2 */
+#define OP_Expire 158
+#define OP_TableLock 159 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 160
+#define OP_VCreate 161
+#define OP_VDestroy 162
+#define OP_VOpen 163
+#define OP_VColumn 164 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VRename 165
+#define OP_Pagecount 166
+#define OP_MaxPgcnt 167
+#define OP_Trace 168
+#define OP_CursorHint 169
+#define OP_Noop 170
+#define OP_Explain 171
+#define OP_Abortable 172
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
@@ -14863,17 +15085,17 @@ typedef struct VdbeOpList VdbeOpList;
/* 64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\
/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\
/* 80 */ 0x10, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
-/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x26, 0x26, 0x26, 0x26,\
-/* 96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
-/* 104 */ 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
+/* 96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
+/* 104 */ 0x26, 0x26, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00,\
/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 128 */ 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,\
-/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
-/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\
-/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
-/* 168 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,}
+/* 128 */ 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10,\
+/* 136 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
+/* 144 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
+/* 152 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
+/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00,}
/* The sqlite3P2Values() routine is able to run faster if it knows
** the value of the largest JUMP opcode. The smaller the maximum
@@ -14932,6 +15154,12 @@ SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*);
# define ExplainQueryPlan(P)
# define ExplainQueryPlanPop(P)
# define ExplainQueryPlanParent(P) 0
+# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
+#endif
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN)
+SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char*,const char*);
+#else
+# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
@@ -14947,7 +15175,7 @@ SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
+SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*);
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
@@ -14968,6 +15196,10 @@ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8);
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*);
+SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*);
+#endif
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
@@ -15278,9 +15510,6 @@ SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
-# ifdef SQLITE_DIRECT_OVERFLOW_READ
-SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno);
-# endif
# ifdef SQLITE_ENABLE_SNAPSHOT
SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
@@ -15288,8 +15517,10 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
-#else
-# define sqlite3PagerUseWal(x,y) 0
+#endif
+
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -15534,6 +15765,10 @@ SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
/* Number of dirty pages as a percentage of the configured cache size */
SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
+#endif
+
#endif /* _PCACHE_H_ */
/************** End of pcache.h **********************************************/
@@ -16039,12 +16274,14 @@ struct LookasideSlot {
** functions use a regular table table from hash.h.)
**
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
-** Collisions are on the FuncDef.u.pHash chain.
+** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH()
+** macro to compute a hash on the function name.
*/
#define SQLITE_FUNC_HASH_SZ 23
struct FuncDefHash {
FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
};
+#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
#ifdef SQLITE_USER_AUTHENTICATION
/*
@@ -16088,10 +16325,13 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
** in the style of sqlite3_trace()
*/
-#define SQLITE_TRACE_LEGACY 0x80
+#define SQLITE_TRACE_LEGACY 0x40 /* Use the legacy xTrace */
+#define SQLITE_TRACE_XPROFILE 0x80 /* Use the legacy xProfile */
#else
-#define SQLITE_TRACE_LEGACY 0
+#define SQLITE_TRACE_LEGACY 0
+#define SQLITE_TRACE_XPROFILE 0
#endif /* SQLITE_OMIT_DEPRECATED */
+#define SQLITE_TRACE_NONLEGACY_MASK 0x0f /* Normal flags */
/*
@@ -16105,7 +16345,7 @@ struct sqlite3 {
Db *aDb; /* All backends */
int nDb; /* Number of backends currently in use */
u32 mDbFlags; /* flags recording internal state */
- u32 flags; /* flags settable by pragmas. See below */
+ u64 flags; /* flags settable by pragmas. See below */
i64 lastRowid; /* ROWID of most recent insert (see above) */
i64 szMmap; /* Default mmap_size setting */
u32 nSchemaLock; /* Do not reset the schema when non-zero */
@@ -16150,14 +16390,17 @@ struct sqlite3 {
void **aExtension; /* Array of shared library handles */
int (*xTrace)(u32,void*,void*,void*); /* Trace function */
void *pTraceArg; /* Argument to the trace function */
+#ifndef SQLITE_OMIT_DEPRECATED
void (*xProfile)(void*,const char*,u64); /* Profiling function */
void *pProfileArg; /* Argument to profile function */
+#endif
void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*); /* Invoked at every commit. */
void *pRollbackArg; /* Argument to xRollbackCallback() */
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
+ Parse *pParse; /* Current parse */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
@@ -16271,14 +16514,20 @@ struct sqlite3 {
#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
+#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
+#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
+#define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/
+#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
/* Flags used only if debugging */
+#define HI(X) ((u64)(X)<<32)
#ifdef SQLITE_DEBUG
-#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */
-#define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */
-#define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */
-#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
+#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */
+#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */
+#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
+#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
+#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
+#define SQLITE_ParserTrace HI(0x0020) /* PRAGMA parser_trace=ON */
#endif
/*
@@ -16287,7 +16536,8 @@ struct sqlite3 {
#define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */
#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */
#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */
-#define DBFLAG_SchemaKnownOk 0x0008 /* Schema is known to be valid */
+#define DBFLAG_VacuumInto 0x0008 /* Currently running VACUUM INTO */
+#define DBFLAG_SchemaKnownOk 0x0010 /* Schema is known to be valid */
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
@@ -16295,7 +16545,7 @@ struct sqlite3 {
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x0001 /* Query flattening */
- /* 0x0002 available for reuse */
+#define SQLITE_WindowFunc 0x0002 /* Use xInverse for window functions */
#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
#define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */
@@ -16412,8 +16662,8 @@ struct FuncDestructor {
** single query - might change over time */
#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
-#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */
-#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
+#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
+#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -16489,10 +16739,13 @@ struct FuncDestructor {
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
-
#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
+#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
+ {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
+ 0, 0, xFunc, 0, 0, 0, #zName, {0} }
+
/*
** All current savepoints are stored in a linked list starting at
@@ -16727,6 +16980,7 @@ struct Table {
#define TF_StatsUsed 0x0100 /* Query planner decisions affected by
** Index.aiRowLogEst[] values */
#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
+#define TF_Shadow 0x0400 /* True for a shadow table */
/*
** Test to see whether or not a table is a virtual table. This is
@@ -16962,7 +17216,7 @@ struct Index {
u16 nKeyCol; /* Number of columns forming the key */
u16 nColumn; /* Number of columns stored in the index */
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
- unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
+ unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */
unsigned bUnordered:1; /* Use this index for == or IN queries only */
unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
unsigned isResized:1; /* True if resizeIndexObject() has been called */
@@ -16970,6 +17224,7 @@ struct Index {
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
unsigned bNoQuery:1; /* Do not use this index to optimize queries */
+ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -16987,6 +17242,7 @@ struct Index {
#define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */
#define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */
#define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */
+#define SQLITE_IDXTYPE_IPK 3 /* INTEGER PRIMARY KEY index */
/* Return true if index X is a PRIMARY KEY index */
#define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY)
@@ -17013,6 +17269,12 @@ struct IndexSample {
tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
};
+/*
+** Possible values to use within the flags argument to sqlite3GetToken().
+*/
+#define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */
+#define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */
+
/*
** Each token coming out of the lexer is an instance of
** this structure. Tokens are also used as part of an expression.
@@ -17190,25 +17452,33 @@ struct Expr {
** TK_SELECT_COLUMN: column of the result vector */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- u8 op2; /* TK_REGISTER: original value of Expr.op
+ u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
- Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
- ** for a column of an index on an expression */
-#ifndef SQLITE_OMIT_WINDOWFUNC
- Window *pWin; /* Window definition for window functions */
-#endif
+ union {
+ Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
+ ** for a column of an index on an expression */
+ Window *pWin; /* TK_FUNCTION: Window definition for the func */
+ struct { /* TK_IN, TK_SELECT, and TK_EXISTS */
+ int iAddr; /* Subroutine entry address */
+ int regReturn; /* Register used to hold return address */
+ } sub;
+ } y;
};
/*
** The following are the meanings of bits in the Expr.flags field.
+** Value restrictions:
+**
+** EP_Agg == NC_HasAgg == SF_HasAgg
+** EP_Win == NC_HasWin
*/
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
-#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
+#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */
#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */
-#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
+#define EP_Agg 0x000010 /* Contains one or more aggregate functions */
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
@@ -17216,10 +17486,10 @@ struct Expr {
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
-#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
+#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
-#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */
+#define EP_Win 0x008000 /* Contains window functions */
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
@@ -17228,6 +17498,12 @@ struct Expr {
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias 0x400000 /* Is an alias for a result set column */
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
+#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
+#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
+#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */
+#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
+#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
+#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
@@ -17243,6 +17519,8 @@ struct Expr {
#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
#define ExprSetProperty(E,P) (E)->flags|=(P)
#define ExprClearProperty(E,P) (E)->flags&=~(P)
+#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
+#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
** and Accreditation only. It works like ExprSetProperty() during VVA
@@ -17459,7 +17737,7 @@ struct NameContext {
NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
- u16 ncFlags; /* Zero or more NC_* flags defined below */
+ int ncFlags; /* Zero or more NC_* flags defined below */
Select *pWinSelect; /* SELECT statement for any window functions */
};
@@ -17467,8 +17745,9 @@ struct NameContext {
** Allowed values for the NameContext, ncFlags field.
**
** Value constraints (all checked via assert()):
-** NC_HasAgg == SF_HasAgg
+** NC_HasAgg == SF_HasAgg == EP_Agg
** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
+** NC_HasWin == EP_Win
**
*/
#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
@@ -17484,6 +17763,8 @@ struct NameContext {
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
#define NC_Complex 0x2000 /* True if a function or subquery seen */
#define NC_AllowWin 0x4000 /* Window functions are allowed here */
+#define NC_HasWin 0x8000 /* One or more window functions seen */
+#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */
/*
** An instance of the following object describes a single ON CONFLICT
@@ -17771,16 +18052,17 @@ struct Parse {
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
u8 okConstFactor; /* OK to factor out constants */
u8 disableLookaside; /* Number of times lookaside has been disabled */
+ u8 disableVtab; /* Disable all virtual tables for this parse */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
- int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
int iSelfTab; /* Table associated with an index on expr, or negative
** of the base register during check-constraint eval */
- int nLabel; /* Number of labels used */
+ int nLabel; /* The *negative* of the number of labels used */
+ int nLabelAlloc; /* Number of slots in aLabel */
int *aLabel; /* Space to hold the labels */
ExprList *pConstExpr;/* Constant expressions */
Token constraintName;/* Name of the constraint currently being parsed */
@@ -17797,6 +18079,7 @@ struct Parse {
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
+ Parse *pParentParse; /* Parent parser if this parser is nested */
int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
@@ -17840,7 +18123,9 @@ struct Parse {
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
- Index *pNewIndex; /* An index being constructed by CREATE INDEX */
+ Index *pNewIndex; /* An index being constructed by CREATE INDEX.
+ ** Also used to hold redundant UNIQUE constraints
+ ** during a RENAME COLUMN */
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -17913,6 +18198,7 @@ struct AuthContext {
*/
#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
/* Also used in P2 (not P5) of OP_Delete */
+#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */
#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
@@ -18067,6 +18353,7 @@ typedef struct {
int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
int rc; /* Result code stored here */
u32 mInitFlags; /* Flags controlling error messages */
+ u32 nInitRow; /* Number of rows processed */
} InitData;
/*
@@ -18127,10 +18414,14 @@ struct Sqlite3Config {
void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */
void *pVdbeBranchArg; /* 1st argument */
#endif
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ sqlite3_int64 mxMemdbSize; /* Default max memdb size */
+#endif
#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
+ int bInternalFunctions; /* Internal SQL functions are visible */
int iOnceResetThreshold; /* When to reset OP_Once counters */
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
};
@@ -18229,7 +18520,7 @@ struct TreeView {
#endif /* SQLITE_DEBUG */
/*
-** This object is used in varioius ways, all related to window functions
+** This object is used in various ways, all related to window functions
**
** (1) A single instance of this structure is attached to the
** the Expr.pWin field for each window function in an expression tree.
@@ -18244,15 +18535,18 @@ struct TreeView {
** object on a linked list attached to Select.pWinDefn.
**
** The uses (1) and (2) are really the same Window object that just happens
-** to be accessible in two different ways. Use (3) is are separate objects.
+** to be accessible in two different ways. Use case (3) are separate objects.
*/
struct Window {
char *zName; /* Name of window (may be NULL) */
+ char *zBase; /* Name of base window for chaining (may be NULL) */
ExprList *pPartition; /* PARTITION BY clause */
ExprList *pOrderBy; /* ORDER BY clause */
- u8 eType; /* TK_RANGE or TK_ROWS */
+ u8 eFrmType; /* TK_RANGE, TK_GROUPS, TK_ROWS, or 0 */
u8 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
+ u8 bImplicitFrame; /* True if frame was implicitly specified */
+ u8 eExclude; /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
Expr *pStart; /* Expression for " PRECEDING" */
Expr *pEnd; /* Expression for " FOLLOWING" */
Window *pNextWin; /* Next window function belonging to this SELECT */
@@ -18263,17 +18557,19 @@ struct Window {
int regResult;
int csrApp; /* Function cursor (used by min/max) */
int regApp; /* Function register (also used by min/max) */
- int regPart; /* First in a set of registers holding PARTITION BY
- ** and ORDER BY values for the window */
+ int regPart; /* Array of registers for PARTITION BY values */
Expr *pOwner; /* Expression object this window is attached to */
int nBufferCol; /* Number of columns in buffer table */
int iArgCol; /* Offset of first argument for this function */
+ int regOne; /* Register containing constant value 1 */
+ int regStartRowid;
+ int regEndRowid;
};
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*);
SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p);
-SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
+SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*);
SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*);
SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Window*);
@@ -18284,6 +18580,8 @@ SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
SQLITE_PRIVATE void sqlite3WindowFunctions(void);
+SQLITE_PRIVATE void sqlite3WindowChain(Parse*, Window*, Window*);
+SQLITE_PRIVATE Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*);
#else
# define sqlite3WindowDelete(a,b)
# define sqlite3WindowFunctions()
@@ -18384,6 +18682,7 @@ SQLITE_PRIVATE int sqlite3IsIdChar(u8);
*/
SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
SQLITE_PRIVATE int sqlite3Strlen30(const char*);
+#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
#define sqlite3StrNICmp sqlite3_strnicmp
@@ -18472,8 +18771,12 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
#endif
#ifndef SQLITE_OMIT_FLOATING_POINT
+# define EXP754 (((u64)0x7ff)<<52)
+# define MAN754 ((((u64)1)<<52)-1)
+# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0)
SQLITE_PRIVATE int sqlite3IsNaN(double);
#else
+# define IsNaN(X) 0
# define sqlite3IsNaN(X) 0
#endif
@@ -18500,6 +18803,7 @@ SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
+SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -18511,7 +18815,9 @@ SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
+SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
SQLITE_PRIVATE void sqlite3Dequote(char*);
+SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*);
SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*);
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
@@ -18529,10 +18835,12 @@ SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
+SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
+SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
+SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
@@ -18540,6 +18848,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
+SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32);
@@ -18573,6 +18882,11 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
sqlite3_vfs**,char**,char **);
+#ifdef SQLITE_HAS_CODEC
+SQLITE_PRIVATE int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*);
+#else
+# define sqlite3CodecQueryParameters(A,B,C) 0
+#endif
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
#ifdef SQLITE_UNTESTABLE
@@ -18625,8 +18939,8 @@ SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upser
SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
-SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
+SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
+SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
Token*, Select*, Expr*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
@@ -18693,8 +19007,8 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_ite
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*);
-SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int);
+SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
+SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*);
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int);
@@ -18737,6 +19051,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
u8,u8,int,int*,int*,Upsert*);
#ifdef SQLITE_ENABLE_NULL_TRIM
@@ -18757,6 +19072,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*);
SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
@@ -18833,6 +19149,7 @@ SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*);
SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*);
SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*);
SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
+SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64);
SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8);
SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
SQLITE_PRIVATE int sqlite3Atoi(const char*);
@@ -18914,6 +19231,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Toke
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
+SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*);
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
@@ -18933,6 +19251,9 @@ SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
+#ifndef SQLITE_UNTESTABLE
+SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context*);
+#endif
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
#ifndef SQLITE_OMIT_UTF16
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
@@ -18962,14 +19283,15 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
-SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
+SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
+SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
-SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
+SQLITE_PRIVATE int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -19117,6 +19439,9 @@ SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*);
+#endif
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
@@ -19211,7 +19536,7 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */
#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */
#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*);
+SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*);
SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
@@ -19491,8 +19816,15 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
** that compile-time option is omitted.
*/
-#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
+#if !defined(SQLITE_ALLOW_COVERING_INDEX_SCAN)
# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
+#else
+# if !SQLITE_ALLOW_COVERING_INDEX_SCAN
+# error "Compile-time disabling of covering index scan using the\
+ -DSQLITE_ALLOW_COVERING_INDEX_SCAN=0 option is deprecated.\
+ Contact SQLite developers if this is a problem for you, and\
+ delete this #error macro to continue with your build."
+# endif
#endif
/* The minimum PMA size is set to this value multiplied by the database
@@ -19527,6 +19859,13 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
#endif
+/* The default maximum size of an in-memory database created using
+** sqlite3_deserialize()
+*/
+#ifndef SQLITE_MEMDB_DEFAULT_MAXSIZE
+# define SQLITE_MEMDB_DEFAULT_MAXSIZE 1073741824
+#endif
+
/*
** The following singleton contains the global configuration for
** the SQLite library.
@@ -19574,12 +19913,16 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xVdbeBranch */
0, /* pVbeBranchArg */
#endif
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */
+#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
0, /* bLocaltimeFault */
+ 0, /* bInternalFunctions */
0x7ffffffe, /* iOnceResetThreshold */
- SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
+ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
};
/*
@@ -19908,12 +20251,12 @@ struct sqlite3_value {
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
-#define MEM_AffMask 0x001f /* Mask of affinity bits */
-/* Available 0x0020 */
-/* Available 0x0040 */
+#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */
+#define MEM_AffMask 0x003f /* Mask of affinity bits */
+#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
-#define MEM_TypeMask 0xc1ff /* Mask of type bits */
+#define MEM_TypeMask 0xc1bf /* Mask of type bits */
/* Whenever Mem contains a valid string or blob representation, one of
@@ -19945,6 +20288,12 @@ struct sqlite3_value {
#define MemSetTypeFlag(p, f) \
((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
+/*
+** True if Mem X is a NULL-nochng type.
+*/
+#define MemNullNochng(X) \
+ ((X)->flags==(MEM_Null|MEM_Zero) && (X)->n==0 && (X)->u.nZero==0)
+
/*
** Return true if a memory cell is not marked as invalid. This macro
** is for use inside assert() statements only.
@@ -19998,6 +20347,9 @@ struct sqlite3_context {
*/
typedef unsigned bft; /* Bit Field Type */
+/* The ScanStatus object holds a single value for the
+** sqlite3_stmt_scanstatus() interface.
+*/
typedef struct ScanStatus ScanStatus;
struct ScanStatus {
int addrExplain; /* OP_Explain for loop */
@@ -20008,6 +20360,19 @@ struct ScanStatus {
char *zName; /* Name of table or index */
};
+/* The DblquoteStr object holds the text of a double-quoted
+** string for a prepared statement. A linked list of these objects
+** is constructed during statement parsing and is held on Vdbe.pDblStr.
+** When computing a normalized SQL statement for an SQL statement, that
+** list is consulted for each double-quoted identifier to see if the
+** identifier should really be a string literal.
+*/
+typedef struct DblquoteStr DblquoteStr;
+struct DblquoteStr {
+ DblquoteStr *pNextStr; /* Next string literal in the list */
+ char z[8]; /* Dequoted value for the string */
+};
+
/*
** An instance of the virtual machine. This structure contains the complete
** state of the virtual machine.
@@ -20027,28 +20392,29 @@ struct Vdbe {
int pc; /* The program counter */
int rc; /* Value to return */
int nChange; /* Number of db changes made since last reset */
- int iStatement; /* Statement number (or 0 if has not opened stmt) */
+ int iStatement; /* Statement number (or 0 if has no opened stmt) */
i64 iCurrentTime; /* Value of julianday('now') for this statement */
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
+ Mem *aMem; /* The memory locations */
+ Mem **apArg; /* Arguments to currently executing user function */
+ VdbeCursor **apCsr; /* One element of this array for each open cursor */
+ Mem *aVar; /* Values for the OP_Variable opcode. */
/* When allocating a new Vdbe object, all of the fields below should be
** initialized to zero or NULL */
Op *aOp; /* Space to hold the virtual machine's program */
- Mem *aMem; /* The memory locations */
- Mem **apArg; /* Arguments to currently executing user function */
+ int nOp; /* Number of instructions in the program */
+ int nOpAlloc; /* Slots allocated for aOp[] */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
char *zErrMsg; /* Error message written here */
- VdbeCursor **apCsr; /* One element of this array for each open cursor */
- Mem *aVar; /* Values for the OP_Variable opcode. */
VList *pVList; /* Name of variables */
#ifndef SQLITE_OMIT_TRACE
i64 startTime; /* Time when query started - used for profiling */
#endif
- int nOp; /* Number of instructions in the program */
#ifdef SQLITE_DEBUG
int rcApp; /* errcode set by sqlite3_result_error_code() */
u32 nWrite; /* Number of write operations that have occurred */
@@ -20069,6 +20435,10 @@ struct Vdbe {
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
char *zSql; /* Text of the SQL statement that generated this */
+#ifdef SQLITE_ENABLE_NORMALIZE
+ char *zNormSql; /* Normalization of the associated SQL statement */
+ DblquoteStr *pDblStr; /* List of double-quoted string literals */
+#endif
void *pFree; /* Free this when deleting the vdbe */
VdbeFrame *pFrame; /* Parent frame */
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
@@ -20131,7 +20501,9 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
+#ifndef SQLITE_OMIT_EXPLAIN
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
+#endif
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
@@ -20170,7 +20542,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
#endif
+#ifndef SQLITE_OMIT_EXPLAIN
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
+#endif
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
@@ -21002,7 +21376,7 @@ static int parseDateOrTime(
return 0;
}else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){
return setDateTimeToCurrent(context, p);
- }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
+ }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
setRawDateNumber(p, r);
return 0;
}
@@ -21336,7 +21710,7 @@ static int parseModifier(
** date is already on the appropriate weekday, this is a no-op.
*/
if( sqlite3_strnicmp(z, "weekday ", 8)==0
- && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
+ && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0
&& (n=(int)r)==r && n>=0 && r<7 ){
sqlite3_int64 Z;
computeYMD_HMS(p);
@@ -21395,7 +21769,7 @@ static int parseModifier(
double rRounder;
int i;
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
- if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
+ if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){
rc = 1;
break;
}
@@ -26869,6 +27243,9 @@ SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
db->u1.isInterrupted = 1;
}
db->lookaside.bDisable++;
+ if( db->pParse ){
+ db->pParse->rc = SQLITE_NOMEM_BKPT;
+ }
}
}
@@ -27025,6 +27402,12 @@ static const et_info fmtinfo[] = {
{ 'r', 10, 1, etORDINAL, 0, 0 },
};
+/* Floating point constants used for rounding */
+static const double arRound[] = {
+ 5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05,
+ 5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10,
+};
+
/*
** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
** conversions will work.
@@ -27062,7 +27445,8 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
static void setStrAccumError(StrAccum *p, u8 eError){
assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
p->accError = eError;
- p->nAlloc = 0;
+ if( p->mxAlloc ) sqlite3_str_reset(p);
+ if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError);
}
/*
@@ -27081,6 +27465,28 @@ static char *getTextArg(PrintfArguments *p){
return (char*)sqlite3_value_text(p->apArg[p->nUsed++]);
}
+/*
+** Allocate memory for a temporary buffer needed for printf rendering.
+**
+** If the requested size of the temp buffer is larger than the size
+** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error.
+** Do the size check before the memory allocation to prevent rogue
+** SQL from requesting large allocations using the precision or width
+** field of the printf() function.
+*/
+static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
+ char *z;
+ if( pAccum->accError ) return 0;
+ if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){
+ setStrAccumError(pAccum, SQLITE_TOOBIG);
+ return 0;
+ }
+ z = sqlite3DbMallocRaw(pAccum->db, n);
+ if( z==0 ){
+ setStrAccumError(pAccum, SQLITE_NOMEM);
+ }
+ return z;
+}
/*
** On machines with a small stack size, you can redefine the
@@ -27163,6 +27569,9 @@ SQLITE_API void sqlite3_str_vappendf(
flag_leftjustify = flag_prefix = cThousand =
flag_alternateform = flag_altform2 = flag_zeropad = 0;
done = 0;
+ width = 0;
+ flag_long = 0;
+ precision = -1;
do{
switch( c ){
case '-': flag_leftjustify = 1; break;
@@ -27173,80 +27582,93 @@ SQLITE_API void sqlite3_str_vappendf(
case '0': flag_zeropad = 1; break;
case ',': cThousand = ','; break;
default: done = 1; break;
- }
- }while( !done && (c=(*++fmt))!=0 );
- /* Get the field width */
- if( c=='*' ){
- if( bArgList ){
- width = (int)getIntArg(pArgList);
- }else{
- width = va_arg(ap,int);
- }
- if( width<0 ){
- flag_leftjustify = 1;
- width = width >= -2147483647 ? -width : 0;
- }
- c = *++fmt;
- }else{
- unsigned wx = 0;
- while( c>='0' && c<='9' ){
- wx = wx*10 + c - '0';
- c = *++fmt;
- }
- testcase( wx>0x7fffffff );
- width = wx & 0x7fffffff;
- }
- assert( width>=0 );
+ case 'l': {
+ flag_long = 1;
+ c = *++fmt;
+ if( c=='l' ){
+ c = *++fmt;
+ flag_long = 2;
+ }
+ done = 1;
+ break;
+ }
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': {
+ unsigned wx = c - '0';
+ while( (c = *++fmt)>='0' && c<='9' ){
+ wx = wx*10 + c - '0';
+ }
+ testcase( wx>0x7fffffff );
+ width = wx & 0x7fffffff;
#ifdef SQLITE_PRINTF_PRECISION_LIMIT
- if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
- width = SQLITE_PRINTF_PRECISION_LIMIT;
- }
+ if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
+ width = SQLITE_PRINTF_PRECISION_LIMIT;
+ }
#endif
-
- /* Get the precision */
- if( c=='.' ){
- c = *++fmt;
- if( c=='*' ){
- if( bArgList ){
- precision = (int)getIntArg(pArgList);
- }else{
- precision = va_arg(ap,int);
+ if( c!='.' && c!='l' ){
+ done = 1;
+ }else{
+ fmt--;
+ }
+ break;
}
- c = *++fmt;
- if( precision<0 ){
- precision = precision >= -2147483647 ? -precision : -1;
+ case '*': {
+ if( bArgList ){
+ width = (int)getIntArg(pArgList);
+ }else{
+ width = va_arg(ap,int);
+ }
+ if( width<0 ){
+ flag_leftjustify = 1;
+ width = width >= -2147483647 ? -width : 0;
+ }
+#ifdef SQLITE_PRINTF_PRECISION_LIMIT
+ if( width>SQLITE_PRINTF_PRECISION_LIMIT ){
+ width = SQLITE_PRINTF_PRECISION_LIMIT;
+ }
+#endif
+ if( (c = fmt[1])!='.' && c!='l' ){
+ c = *++fmt;
+ done = 1;
+ }
+ break;
}
- }else{
- unsigned px = 0;
- while( c>='0' && c<='9' ){
- px = px*10 + c - '0';
+ case '.': {
c = *++fmt;
- }
- testcase( px>0x7fffffff );
- precision = px & 0x7fffffff;
- }
- }else{
- precision = -1;
- }
- assert( precision>=(-1) );
+ if( c=='*' ){
+ if( bArgList ){
+ precision = (int)getIntArg(pArgList);
+ }else{
+ precision = va_arg(ap,int);
+ }
+ if( precision<0 ){
+ precision = precision >= -2147483647 ? -precision : -1;
+ }
+ c = *++fmt;
+ }else{
+ unsigned px = 0;
+ while( c>='0' && c<='9' ){
+ px = px*10 + c - '0';
+ c = *++fmt;
+ }
+ testcase( px>0x7fffffff );
+ precision = px & 0x7fffffff;
+ }
#ifdef SQLITE_PRINTF_PRECISION_LIMIT
- if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
- precision = SQLITE_PRINTF_PRECISION_LIMIT;
- }
+ if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){
+ precision = SQLITE_PRINTF_PRECISION_LIMIT;
+ }
#endif
-
-
- /* Get the conversion type modifier */
- if( c=='l' ){
- flag_long = 1;
- c = *++fmt;
- if( c=='l' ){
- flag_long = 2;
- c = *++fmt;
+ if( c=='l' ){
+ --fmt;
+ }else{
+ done = 1;
+ }
+ break;
+ }
}
- }else{
- flag_long = 0;
- }
+ }while( !done && (c=(*++fmt))!=0 );
+
/* Fetch the info entry for the field */
infop = &fmtinfo[0];
xtype = etINVALID;
@@ -27331,12 +27753,11 @@ SQLITE_API void sqlite3_str_vappendf(
nOut = etBUFSIZE;
zOut = buf;
}else{
- u64 n = (u64)precision + 10 + precision/3;
- zOut = zExtra = sqlite3Malloc( n );
- if( zOut==0 ){
- setStrAccumError(pAccum, SQLITE_NOMEM);
- return;
- }
+ u64 n;
+ n = (u64)precision + 10;
+ if( cThousand ) n += precision/3;
+ zOut = zExtra = printfTempBuf(pAccum, n);
+ if( zOut==0 ) return;
nOut = (int)n;
}
bufpt = &zOut[nOut-1];
@@ -27405,8 +27826,18 @@ SQLITE_API void sqlite3_str_vappendf(
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
- for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
- if( xtype==etFLOAT ) realvalue += rounder;
+ idx = precision & 0xfff;
+ rounder = arRound[idx%10];
+ while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; }
+ if( xtype==etFLOAT ){
+ double rx = (double)realvalue;
+ sqlite3_uint64 u;
+ int ex;
+ memcpy(&u, &rx, sizeof(u));
+ ex = -1023 + (int)((u>>52)&0x7ff);
+ if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16;
+ realvalue += rounder;
+ }
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
if( sqlite3IsNaN((double)realvalue) ){
@@ -27455,12 +27886,12 @@ SQLITE_API void sqlite3_str_vappendf(
}else{
e2 = exp;
}
- if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
- bufpt = zExtra
- = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
- if( bufpt==0 ){
- setStrAccumError(pAccum, SQLITE_NOMEM);
- return;
+ {
+ i64 szBufNeeded; /* Size of a temporary buffer needed */
+ szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15;
+ if( szBufNeeded > etBUFSIZE ){
+ bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded);
+ if( bufpt==0 ) return;
}
}
zOut = bufpt;
@@ -27684,11 +28115,8 @@ SQLITE_API void sqlite3_str_vappendf(
needQuote = !isnull && xtype==etSQLESCAPE2;
n += i + 3;
if( n>etBUFSIZE ){
- bufpt = zExtra = sqlite3Malloc( n );
- if( bufpt==0 ){
- setStrAccumError(pAccum, SQLITE_NOMEM);
- return;
- }
+ bufpt = zExtra = printfTempBuf(pAccum, n);
+ if( bufpt==0 ) return;
}else{
bufpt = buf;
}
@@ -27778,9 +28206,8 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
return 0;
}
if( p->mxAlloc==0 ){
- N = p->nAlloc - p->nChar - 1;
setStrAccumError(p, SQLITE_TOOBIG);
- return N;
+ return p->nAlloc - p->nChar - 1;
}else{
char *zOld = isMalloced(p) ? p->zText : 0;
i64 szNew = p->nChar;
@@ -27852,7 +28279,7 @@ SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){
assert( z!=0 || N==0 );
assert( p->zText!=0 || p->nChar==0 || p->accError );
assert( N>=0 );
- assert( p->accError==0 || p->nAlloc==0 );
+ assert( p->accError==0 || p->nAlloc==0 || p->mxAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
enlargeAndAppend(p,z,N);
}else if( N ){
@@ -28297,6 +28724,43 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
}
}
+/*
+** Generate a human-readable description of a SrcList object.
+*/
+SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
+ int i;
+ for(i=0; inSrc; i++){
+ const struct SrcList_item *pItem = &pSrc->a[i];
+ StrAccum x;
+ char zLine[100];
+ sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+ sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
+ if( pItem->zDatabase ){
+ sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
+ }else if( pItem->zName ){
+ sqlite3_str_appendf(&x, " %s", pItem->zName);
+ }
+ if( pItem->pTab ){
+ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
+ pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
+ }
+ if( pItem->zAlias ){
+ sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
+ }
+ if( pItem->fg.jointype & JT_LEFT ){
+ sqlite3_str_appendf(&x, " LEFT-JOIN");
+ }
+ sqlite3StrAccumFinish(&x);
+ sqlite3TreeViewItem(pView, zLine, inSrc-1);
+ if( pItem->pSelect ){
+ sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+ }
+ if( pItem->fg.isTabFunc ){
+ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
+ }
+ sqlite3TreeViewPop(pView);
+ }
+}
/*
** Generate a human-readable description of a Select object.
@@ -28351,39 +28815,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
}
#endif
if( p->pSrc && p->pSrc->nSrc ){
- int i;
pView = sqlite3TreeViewPush(pView, (n--)>0);
sqlite3TreeViewLine(pView, "FROM");
- for(i=0; ipSrc->nSrc; i++){
- struct SrcList_item *pItem = &p->pSrc->a[i];
- StrAccum x;
- char zLine[100];
- sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
- sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
- if( pItem->zDatabase ){
- sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
- }else if( pItem->zName ){
- sqlite3_str_appendf(&x, " %s", pItem->zName);
- }
- if( pItem->pTab ){
- sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
- }
- if( pItem->zAlias ){
- sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
- }
- if( pItem->fg.jointype & JT_LEFT ){
- sqlite3_str_appendf(&x, " LEFT-JOIN");
- }
- sqlite3StrAccumFinish(&x);
- sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1);
- if( pItem->pSelect ){
- sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
- }
- if( pItem->fg.isTabFunc ){
- sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
- }
- sqlite3TreeViewPop(pView);
- }
+ sqlite3TreeViewSrcList(pView, p->pSrc);
sqlite3TreeViewPop(pView);
}
if( p->pWhere ){
@@ -28478,24 +28912,62 @@ SQLITE_PRIVATE void sqlite3TreeViewBound(
** Generate a human-readable explanation for a Window object
*/
SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
+ int nElement = 0;
+ if( pWin->pFilter ){
+ sqlite3TreeViewItem(pView, "FILTER", 1);
+ sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
+ sqlite3TreeViewPop(pView);
+ }
pView = sqlite3TreeViewPush(pView, more);
if( pWin->zName ){
- sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
+ sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
}else{
- sqlite3TreeViewLine(pView, "OVER");
+ sqlite3TreeViewLine(pView, "OVER (%p)", pWin);
+ }
+ if( pWin->zBase ) nElement++;
+ if( pWin->pOrderBy ) nElement++;
+ if( pWin->eFrmType ) nElement++;
+ if( pWin->eExclude ) nElement++;
+ if( pWin->zBase ){
+ sqlite3TreeViewPush(pView, (--nElement)>0);
+ sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
+ sqlite3TreeViewPop(pView);
}
if( pWin->pPartition ){
- sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
+ sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
}
if( pWin->pOrderBy ){
- sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
- }
- if( pWin->eType ){
- sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
+ sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY");
+ }
+ if( pWin->eFrmType ){
+ char zBuf[30];
+ const char *zFrmType = "ROWS";
+ if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE";
+ if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS";
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType,
+ pWin->bImplicitFrame ? " (implied)" : "");
+ sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
sqlite3TreeViewPop(pView);
}
+ if( pWin->eExclude ){
+ char zBuf[30];
+ const char *zExclude;
+ switch( pWin->eExclude ){
+ case TK_NO: zExclude = "NO OTHERS"; break;
+ case TK_CURRENT: zExclude = "CURRENT ROW"; break;
+ case TK_GROUP: zExclude = "GROUP"; break;
+ case TK_TIES: zExclude = "TIES"; break;
+ default:
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude);
+ zExclude = zBuf;
+ break;
+ }
+ sqlite3TreeViewPush(pView, 0);
+ sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
+ sqlite3TreeViewPop(pView);
+ }
sqlite3TreeViewPop(pView);
}
#endif /* SQLITE_OMIT_WINDOWFUNC */
@@ -28645,7 +29117,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
};
assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT );
assert( pExpr->pRight );
- assert( pExpr->pRight->op==TK_TRUEFALSE );
+ assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE );
x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight);
zUniOp = azOp[x];
break;
@@ -28673,7 +29145,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
}else{
pFarg = pExpr->x.pList;
#ifndef SQLITE_OMIT_WINDOWFUNC
- pWin = pExpr->pWin;
+ pWin = pExpr->y.pWin;
#else
pWin = 0;
#endif
@@ -29475,11 +29947,11 @@ SQLITE_PRIVATE u32 sqlite3Utf8Read(
** encoding, or if *pMem does not contain a string value.
*/
SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
- int len; /* Maximum length of output string in bytes */
- unsigned char *zOut; /* Output buffer */
- unsigned char *zIn; /* Input iterator */
- unsigned char *zTerm; /* End of input */
- unsigned char *z; /* Output iterator */
+ sqlite3_int64 len; /* Maximum length of output string in bytes */
+ unsigned char *zOut; /* Output buffer */
+ unsigned char *zIn; /* Input iterator */
+ unsigned char *zTerm; /* End of input */
+ unsigned char *z; /* Output iterator */
unsigned int c;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -29528,14 +30000,14 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
** nul-terminator.
*/
pMem->n &= ~1;
- len = pMem->n * 2 + 1;
+ len = 2 * (sqlite3_int64)pMem->n + 1;
}else{
/* When converting from UTF-8 to UTF-16 the maximum growth is caused
** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
** character. Two bytes are required in the output buffer for the
** nul-terminator.
*/
- len = pMem->n * 2 + 2;
+ len = 2 * (sqlite3_int64)pMem->n + 2;
}
/* Set zIn to point at the start of the input buffer and zTerm to point 1
@@ -29827,9 +30299,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
*/
/* #include "sqliteInt.h" */
/* #include */
-#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
-# include
-#endif
+#include
/*
** Routine needed to support the testcase() macro.
@@ -29842,15 +30312,23 @@ SQLITE_PRIVATE void sqlite3Coverage(int x){
#endif
/*
-** Give a callback to the test harness that can be used to simulate faults
-** in places where it is difficult or expensive to do so purely by means
-** of inputs.
+** Calls to sqlite3FaultSim() are used to simulate a failure during testing,
+** or to bypass normal error detection during testing in order to let
+** execute proceed futher downstream.
**
-** The intent of the integer argument is to let the fault simulator know
-** which of multiple sqlite3FaultSim() calls has been hit.
+** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0). The
+** sqlite3FaultSim() function only returns non-zero during testing.
**
-** Return whatever integer value the test callback returns, or return
-** SQLITE_OK if no test callback is installed.
+** During testing, if the test harness has set a fault-sim callback using
+** a call to sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL), then
+** each call to sqlite3FaultSim() is relayed to that application-supplied
+** callback and the integer return value form the application-supplied
+** callback is returned by sqlite3FaultSim().
+**
+** The integer argument to sqlite3FaultSim() is a code to identify which
+** sqlite3FaultSim() instance is being invoked. Each call to sqlite3FaultSim()
+** should have a unique code. To prevent legacy testing applications from
+** breaking, the codes should not be changed or reused.
*/
#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
@@ -29862,47 +30340,11 @@ SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).
-**
-** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
-** Otherwise, we have our own implementation that works on most systems.
*/
SQLITE_PRIVATE int sqlite3IsNaN(double x){
- int rc; /* The value return */
-#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
- /*
- ** Systems that support the isnan() library function should probably
- ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have
- ** found that many systems do not have a working isnan() function so
- ** this implementation is provided as an alternative.
- **
- ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
- ** On the other hand, the use of -ffast-math comes with the following
- ** warning:
- **
- ** This option [-ffast-math] should never be turned on by any
- ** -O option since it can result in incorrect output for programs
- ** which depend on an exact implementation of IEEE or ISO
- ** rules/specifications for math functions.
- **
- ** Under MSVC, this NaN test may fail if compiled with a floating-
- ** point precision mode other than /fp:precise. From the MSDN
- ** documentation:
- **
- ** The compiler [with /fp:precise] will properly handle comparisons
- ** involving NaN. For example, x != x evaluates to true if x is NaN
- ** ...
- */
-#ifdef __FAST_MATH__
-# error SQLite will not work correctly with the -ffast-math option of GCC.
-#endif
- volatile double y = x;
- volatile double z = y;
- rc = (y!=z);
-#else /* if HAVE_ISNAN */
- rc = isnan(x);
-#endif /* HAVE_ISNAN */
- testcase( rc );
- return rc;
+ u64 y;
+ memcpy(&y,&x,sizeof(y));
+ return IsNaN(y);
}
#endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -30035,6 +30477,19 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
}
}
+/*
+** If database connection db is currently parsing SQL, then transfer
+** error code errCode to that parser if the parser has not already
+** encountered some other kind of error.
+*/
+SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3 *db, int errCode){
+ Parse *pParse;
+ if( db==0 || (pParse = db->pParse)==0 ) return errCode;
+ pParse->rc = errCode;
+ pParse->nErr++;
+ return errCode;
+}
+
/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters. The conversion is done in-place. If the
@@ -30048,7 +30503,7 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
** dequoted string, exclusive of the zero terminator, if dequoting does
** occur.
**
-** 2002-Feb-14: This routine is extended to remove MS-Access style
+** 2002-02-14: This routine is extended to remove MS-Access style
** brackets from around identifiers. For example: "[a-b-c]" becomes
** "a-b-c".
*/
@@ -30074,6 +30529,11 @@ SQLITE_PRIVATE void sqlite3Dequote(char *z){
}
z[j] = 0;
}
+SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
+ assert( sqlite3Isquote(p->u.zToken[0]) );
+ p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted;
+ sqlite3Dequote(p->u.zToken);
+}
/*
** Generate a Token object from a string
@@ -30106,12 +30566,18 @@ SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
}
SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
unsigned char *a, *b;
- int c;
+ int c, x;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
for(;;){
- c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
- if( c || *a==0 ) break;
+ c = *a;
+ x = *b;
+ if( c==x ){
+ if( c==0 ) break;
+ }else{
+ c = (int)UpperToLower[c] - (int)UpperToLower[x];
+ if( c ) break;
+ }
a++;
b++;
}
@@ -30139,15 +30605,15 @@ SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
static LONGDOUBLE_TYPE sqlite3Pow10(int E){
#if defined(_MSC_VER)
static const LONGDOUBLE_TYPE x[] = {
- 1.0e+001,
- 1.0e+002,
- 1.0e+004,
- 1.0e+008,
- 1.0e+016,
- 1.0e+032,
- 1.0e+064,
- 1.0e+128,
- 1.0e+256
+ 1.0e+001L,
+ 1.0e+002L,
+ 1.0e+004L,
+ 1.0e+008L,
+ 1.0e+016L,
+ 1.0e+032L,
+ 1.0e+064L,
+ 1.0e+128L,
+ 1.0e+256L
};
LONGDOUBLE_TYPE r = 1.0;
int i;
@@ -30177,8 +30643,15 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){
** uses the encoding enc. The string is not necessarily zero-terminated.
**
** Return TRUE if the result is a valid real number (or integer) and FALSE
-** if the string is empty or contains extraneous text. Valid numbers
-** are in one of these formats:
+** if the string is empty or contains extraneous text. More specifically
+** return
+** 1 => The input string is a pure integer
+** 2 or more => The input has a decimal point or eNNN clause
+** 0 or less => The input string is not a valid number
+** -1 => Not a valid number, but has a valid prefix which
+** includes a decimal point and/or an eNNN clause
+**
+** Valid numbers are in one of these formats:
**
** [+-]digits[E[+-]digits]
** [+-]digits.[digits][E[+-]digits]
@@ -30203,8 +30676,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
int e = 0; /* exponent */
int eValid = 1; /* True exponent is either not used or is well-formed */
double result;
- int nDigits = 0;
- int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
+ int nDigit = 0; /* Number of digits processed */
+ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
@@ -30215,8 +30688,10 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
int i;
incr = 2;
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
+ testcase( enc==SQLITE_UTF16LE );
+ testcase( enc==SQLITE_UTF16BE );
for(i=3-enc; i=((LARGEST_INT64-9)/10) ){
+ /* skip non-significant significand digits
+ ** (increase exponent by d to shift decimal left) */
+ while( z=zEnd ) goto do_atof_calc;
/* if decimal point is present */
if( *z=='.' ){
z+=incr;
+ eType++;
/* copy digits from after decimal to significand
** (decrease exponent by d to shift decimal right) */
while( z=zEnd ) goto do_atof_calc;
@@ -30263,6 +30741,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
if( *z=='e' || *z=='E' ){
z+=incr;
eValid = 0;
+ eType++;
/* This branch is needed to avoid a (harmless) buffer overread. The
** special comment alerts the mutation tester that the correct answer
@@ -30361,7 +30840,13 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
*pResult = result;
/* return true if number and no extra non-whitespace chracters after */
- return z==zEnd && nDigits>0 && eValid && nonNum==0;
+ if( z==zEnd && nDigit>0 && eValid && eType>0 ){
+ return eType;
+ }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){
+ return -1;
+ }else{
+ return 0;
+ }
#else
return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
@@ -30404,6 +30889,7 @@ static int compare2pow63(const char *zNum, int incr){
**
** Returns:
**
+** -1 Not even a prefix of the input text looks like an integer
** 0 Successful transformation. Fits in a 64-bit signed integer.
** 1 Excess non-space text after the integer value
** 2 Integer too large for a 64-bit signed integer or is malformed
@@ -30463,9 +30949,9 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
*pNum = (i64)u;
}
rc = 0;
- if( (i==0 && zStart==zNum) /* No digits */
- || nonNum /* UTF16 with high-order bytes non-zero */
- ){
+ if( i==0 && zStart==zNum ){ /* No digits */
+ rc = -1;
+ }else if( nonNum ){ /* UTF16 with high-order bytes non-zero */
rc = 1;
}else if( &zNum[i]=0 ){
+ *v = *p;
return 1;
}
-
- p++;
- b = *p;
- /* b: p1 (unmasked) */
- if (!(b&0x80))
- {
- a &= 0x7f;
- a = a<<7;
- a |= b;
- *v = a;
+ if( ((signed char*)p)[1]>=0 ){
+ *v = ((u32)(p[0]&0x7f)<<7) | p[1];
return 2;
}
@@ -30720,8 +31195,9 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
- p++;
- a = a<<14;
+ a = ((u32)p[0])<<14;
+ b = p[1];
+ p += 2;
a |= *p;
/* a: p0<<14 | p2 (unmasked) */
if (!(a&0x80))
@@ -31381,7 +31857,7 @@ SQLITE_PRIVATE VList *sqlite3VListAdd(
assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */
if( pIn==0 || pIn[1]+nInt > pIn[0] ){
/* Enlarge the allocation */
- int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt;
+ sqlite3_int64 nAlloc = (pIn ? 2*(sqlite3_int64)pIn[0] : 10) + nInt;
VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
if( pOut==0 ) return pIn;
if( pIn==0 ) pOut[1] = 2;
@@ -31587,7 +32063,7 @@ static HashElem *findElementWithHash(
unsigned int *pHash /* Write the hash value here */
){
HashElem *elem; /* Used to loop thru the element list */
- int count; /* Number of elements left to test */
+ unsigned int count; /* Number of elements left to test */
unsigned int h; /* The computed hash */
static HashElem nullElement = { 0, 0, 0, 0 };
@@ -31635,8 +32111,8 @@ static void removeElementGivenHash(
if( pEntry->chain==elem ){
pEntry->chain = elem->next;
}
+ assert( pEntry->count>0 );
pEntry->count--;
- assert( pEntry->count>=0 );
}
sqlite3_free( elem );
pH->count--;
@@ -31811,25 +32287,25 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 89 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
/* 90 */ "Column" OpHelp("r[P3]=PX"),
/* 91 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
- /* 92 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 93 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 94 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
- /* 96 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 97 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 98 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 99 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 100 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 101 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 102 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
- /* 103 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
- /* 104 */ "Count" OpHelp("r[P2]=count()"),
- /* 105 */ "ReadCookie" OpHelp(""),
- /* 106 */ "String8" OpHelp("r[P2]='P4'"),
- /* 107 */ "SetCookie" OpHelp(""),
- /* 108 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
- /* 109 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
- /* 110 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 92 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 93 */ "Count" OpHelp("r[P2]=count()"),
+ /* 94 */ "ReadCookie" OpHelp(""),
+ /* 95 */ "SetCookie" OpHelp(""),
+ /* 96 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 97 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 98 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
+ /* 100 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 101 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 102 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 103 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 104 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 105 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 106 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
+ /* 107 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
+ /* 108 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 109 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 110 */ "String8" OpHelp("r[P2]='P4'"),
/* 111 */ "OpenDup" OpHelp(""),
/* 112 */ "OpenAutoindex" OpHelp("nColumn=P2"),
/* 113 */ "OpenEphemeral" OpHelp("nColumn=P2"),
@@ -31842,57 +32318,56 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 120 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
/* 121 */ "NewRowid" OpHelp("r[P2]=rowid"),
/* 122 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
- /* 123 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
- /* 124 */ "Delete" OpHelp(""),
- /* 125 */ "ResetCount" OpHelp(""),
- /* 126 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
- /* 127 */ "SorterData" OpHelp("r[P2]=data"),
- /* 128 */ "RowData" OpHelp("r[P2]=data"),
- /* 129 */ "Rowid" OpHelp("r[P2]=rowid"),
- /* 130 */ "NullRow" OpHelp(""),
- /* 131 */ "SeekEnd" OpHelp(""),
- /* 132 */ "SorterInsert" OpHelp("key=r[P2]"),
- /* 133 */ "IdxInsert" OpHelp("key=r[P2]"),
- /* 134 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
- /* 135 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
- /* 136 */ "IdxRowid" OpHelp("r[P2]=rowid"),
- /* 137 */ "Destroy" OpHelp(""),
- /* 138 */ "Clear" OpHelp(""),
- /* 139 */ "ResetSorter" OpHelp(""),
- /* 140 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
- /* 141 */ "Real" OpHelp("r[P2]=P4"),
- /* 142 */ "SqlExec" OpHelp(""),
- /* 143 */ "ParseSchema" OpHelp(""),
- /* 144 */ "LoadAnalysis" OpHelp(""),
- /* 145 */ "DropTable" OpHelp(""),
- /* 146 */ "DropIndex" OpHelp(""),
- /* 147 */ "DropTrigger" OpHelp(""),
- /* 148 */ "IntegrityCk" OpHelp(""),
- /* 149 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
- /* 150 */ "Param" OpHelp(""),
- /* 151 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
- /* 152 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
- /* 153 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
- /* 154 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
- /* 155 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 156 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 157 */ "AggValue" OpHelp("r[P3]=value N=P2"),
- /* 158 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
- /* 159 */ "Expire" OpHelp(""),
- /* 160 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
- /* 161 */ "VBegin" OpHelp(""),
- /* 162 */ "VCreate" OpHelp(""),
- /* 163 */ "VDestroy" OpHelp(""),
- /* 164 */ "VOpen" OpHelp(""),
- /* 165 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
- /* 166 */ "VRename" OpHelp(""),
- /* 167 */ "Pagecount" OpHelp(""),
- /* 168 */ "MaxPgcnt" OpHelp(""),
- /* 169 */ "Trace" OpHelp(""),
- /* 170 */ "CursorHint" OpHelp(""),
- /* 171 */ "Noop" OpHelp(""),
- /* 172 */ "Explain" OpHelp(""),
- /* 173 */ "Abortable" OpHelp(""),
+ /* 123 */ "Delete" OpHelp(""),
+ /* 124 */ "ResetCount" OpHelp(""),
+ /* 125 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+ /* 126 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 127 */ "RowData" OpHelp("r[P2]=data"),
+ /* 128 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 129 */ "NullRow" OpHelp(""),
+ /* 130 */ "SeekEnd" OpHelp(""),
+ /* 131 */ "SorterInsert" OpHelp("key=r[P2]"),
+ /* 132 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 133 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 134 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
+ /* 135 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 136 */ "Destroy" OpHelp(""),
+ /* 137 */ "Clear" OpHelp(""),
+ /* 138 */ "ResetSorter" OpHelp(""),
+ /* 139 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
+ /* 140 */ "SqlExec" OpHelp(""),
+ /* 141 */ "ParseSchema" OpHelp(""),
+ /* 142 */ "LoadAnalysis" OpHelp(""),
+ /* 143 */ "DropTable" OpHelp(""),
+ /* 144 */ "DropIndex" OpHelp(""),
+ /* 145 */ "Real" OpHelp("r[P2]=P4"),
+ /* 146 */ "DropTrigger" OpHelp(""),
+ /* 147 */ "IntegrityCk" OpHelp(""),
+ /* 148 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 149 */ "Param" OpHelp(""),
+ /* 150 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 151 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 152 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+ /* 153 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
+ /* 154 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 155 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 156 */ "AggValue" OpHelp("r[P3]=value N=P2"),
+ /* 157 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 158 */ "Expire" OpHelp(""),
+ /* 159 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 160 */ "VBegin" OpHelp(""),
+ /* 161 */ "VCreate" OpHelp(""),
+ /* 162 */ "VDestroy" OpHelp(""),
+ /* 163 */ "VOpen" OpHelp(""),
+ /* 164 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 165 */ "VRename" OpHelp(""),
+ /* 166 */ "Pagecount" OpHelp(""),
+ /* 167 */ "MaxPgcnt" OpHelp(""),
+ /* 168 */ "Trace" OpHelp(""),
+ /* 169 */ "CursorHint" OpHelp(""),
+ /* 170 */ "Noop" OpHelp(""),
+ /* 171 */ "Explain" OpHelp(""),
+ /* 172 */ "Abortable" OpHelp(""),
};
return azName[i];
}
@@ -32038,12 +32513,10 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#define SQLITE_FSFLAGS_IS_MSDOS 0x1
/*
-** If we are to be thread-safe, include the pthreads header and define
-** the SQLITE_UNIX_THREADS macro.
+** If we are to be thread-safe, include the pthreads header.
*/
#if SQLITE_THREADSAFE
/* # include */
-# define SQLITE_UNIX_THREADS 1
#endif
/*
@@ -33219,8 +33692,7 @@ struct unixFileId {
/*
** An instance of the following structure is allocated for each open
-** inode. Or, on LinuxThreads, there is one of these structures for
-** each inode opened by each thread.
+** inode.
**
** A single inode can have multiple file descriptors, so each unixFile
** structure contains a pointer to an instance of this object and this
@@ -33266,13 +33738,16 @@ struct unixInodeInfo {
/*
** A lists of all unixInodeInfo objects.
+**
+** Must hold unixBigLock in order to read or write this variable.
*/
static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
#ifdef SQLITE_DEBUG
/*
-** True if the inode mutex is held, or not. Used only within assert()
-** to help verify correct mutex usage.
+** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
+** This routine is used only within assert() to help verify correct mutex
+** usage.
*/
int unixFileMutexHeld(unixFile *pFile){
assert( pFile->pInode );
@@ -33400,8 +33875,8 @@ static void closePendingFds(unixFile *pFile){
/*
** Release a unixInodeInfo structure previously allocated by findInodeInfo().
**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
+** The global mutex must be held when this routine is called, but the mutex
+** on the inode being deleted must NOT be held.
*/
static void releaseInodeInfo(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
@@ -33436,8 +33911,7 @@ static void releaseInodeInfo(unixFile *pFile){
** describes that file descriptor. Create a new one if necessary. The
** return value might be uninitialized if an error occurs.
**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
+** The global mutex must held when calling this routine.
**
** Return an appropriate error code.
*/
@@ -33498,6 +33972,7 @@ static int findInodeInfo(
#else
fileId.ino = (u64)statbuf.st_ino;
#endif
+ assert( unixMutexHeld() );
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
@@ -33517,6 +33992,7 @@ static int findInodeInfo(
}
}
pInode->nRef = 1;
+ assert( unixMutexHeld() );
pInode->pNext = inodeList;
pInode->pPrev = 0;
if( inodeList ) inodeList->pPrev = pInode;
@@ -36314,18 +36790,18 @@ static int unixGetpagesize(void){
**
** The following fields are read-only after the object is created:
**
-** fid
+** hShm
** zFilename
**
-** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
+** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
** unixMutexHeld() is true when reading or writing any other field
** in this structure.
*/
struct unixShmNode {
unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
- sqlite3_mutex *mutex; /* Mutex to access this object */
+ sqlite3_mutex *pShmMutex; /* Mutex to access this object */
char *zFilename; /* Name of the mmapped file */
- int h; /* Open file descriptor */
+ int hShm; /* Open file descriptor */
int szRegion; /* Size of shared-memory regions */
u16 nRegion; /* Size of array apRegion */
u8 isReadonly; /* True if read-only */
@@ -36347,16 +36823,16 @@ struct unixShmNode {
** The following fields are initialized when this object is created and
** are read-only thereafter:
**
-** unixShm.pFile
+** unixShm.pShmNode
** unixShm.id
**
-** All other fields are read/write. The unixShm.pFile->mutex must be held
-** while accessing any read/write fields.
+** All other fields are read/write. The unixShm.pShmNode->pShmMutex must
+** be held while accessing any read/write fields.
*/
struct unixShm {
unixShmNode *pShmNode; /* The underlying unixShmNode object */
unixShm *pNext; /* Next unixShm with the same unixShmNode */
- u8 hasMutex; /* True if holding the unixShmNode mutex */
+ u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */
u8 id; /* Id of this connection within its unixShmNode */
u16 sharedMask; /* Mask of shared locks held */
u16 exclMask; /* Mask of exclusive locks held */
@@ -36386,7 +36862,8 @@ static int unixShmSystemLock(
/* Access to the unixShmNode object is serialized by the caller */
pShmNode = pFile->pInode->pShmNode;
- assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
+ assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
+ assert( pShmNode->nRef>0 || unixMutexHeld() );
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
@@ -36394,13 +36871,13 @@ static int unixShmSystemLock(
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
- if( pShmNode->h>=0 ){
+ if( pShmNode->hShm>=0 ){
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
- rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
+ rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
}
@@ -36472,18 +36949,18 @@ static void unixShmPurge(unixFile *pFd){
int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
- sqlite3_mutex_free(p->mutex);
+ sqlite3_mutex_free(p->pShmMutex);
for(i=0; inRegion; i+=nShmPerMap){
- if( p->h>=0 ){
+ if( p->hShm>=0 ){
osMunmap(p->apRegion[i], p->szRegion);
}else{
sqlite3_free(p->apRegion[i]);
}
}
sqlite3_free(p->apRegion);
- if( p->h>=0 ){
- robust_close(pFd, p->h, __LINE__);
- p->h = -1;
+ if( p->hShm>=0 ){
+ robust_close(pFd, p->hShm, __LINE__);
+ p->hShm = -1;
}
p->pInode->pShmNode = 0;
sqlite3_free(p);
@@ -36525,7 +37002,7 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
lock.l_start = UNIX_SHM_DMS;
lock.l_len = 1;
lock.l_type = F_WRLCK;
- if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
+ if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
rc = SQLITE_IOERR_LOCK;
}else if( lock.l_type==F_UNLCK ){
if( pShmNode->isReadonly ){
@@ -36533,7 +37010,12 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
rc = SQLITE_READONLY_CANTINIT;
}else{
rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
- if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
+ /* The first connection to attach must truncate the -shm file. We
+ ** truncate to 3 bytes (an arbitrary small number, less than the
+ ** -shm header size) rather than 0 as a system debugging aid, to
+ ** help detect if a -shm file truncation is legitimate or is the work
+ ** or a rogue process. */
+ if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
}
}
@@ -36639,12 +37121,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
sqlite3FileSuffix3(pDbFd->zPath, zShm);
#endif
- pShmNode->h = -1;
+ pShmNode->hShm = -1;
pDbFd->pInode->pShmNode = pShmNode;
pShmNode->pInode = pDbFd->pInode;
if( sqlite3GlobalConfig.bCoreMutex ){
- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
- if( pShmNode->mutex==0 ){
+ pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ if( pShmNode->pShmMutex==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
@@ -36652,11 +37134,11 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
if( pInode->bProcessLock==0 ){
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
}
- if( pShmNode->h<0 ){
- pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
- if( pShmNode->h<0 ){
+ if( pShmNode->hShm<0 ){
+ pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+ if( pShmNode->hShm<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
goto shm_open_err;
}
@@ -36667,7 +37149,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect.
*/
- robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
+ robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
rc = unixLockSharedMemory(pDbFd, pShmNode);
if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
@@ -36687,13 +37169,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** the cover of the unixEnterMutex() mutex and the pointer from the
** new (struct unixShm) object to the pShmNode has been set. All that is
** left to do is to link the new object into the linked list starting
- ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
- ** mutex.
+ ** at pShmNode->pFirst. This must be done while holding the
+ ** pShmNode->pShmMutex.
*/
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
return rc;
/* Jump here on any error */
@@ -36745,7 +37227,7 @@ static int unixShmMap(
p = pDbFd->pShm;
pShmNode = p->pShmNode;
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
if( pShmNode->isUnlocked ){
rc = unixLockSharedMemory(pDbFd, pShmNode);
if( rc!=SQLITE_OK ) goto shmpage_out;
@@ -36753,8 +37235,8 @@ static int unixShmMap(
}
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
assert( pShmNode->pInode==pDbFd->pInode );
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
/* Minimum number of regions required to be mapped. */
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
@@ -36766,12 +37248,12 @@ static int unixShmMap(
pShmNode->szRegion = szRegion;
- if( pShmNode->h>=0 ){
+ if( pShmNode->hShm>=0 ){
/* The requested region is not mapped into this processes address space.
** Check to see if it has been allocated (i.e. if the wal-index file is
** large enough to contain the requested region).
*/
- if( osFstat(pShmNode->h, &sStat) ){
+ if( osFstat(pShmNode->hShm, &sStat) ){
rc = SQLITE_IOERR_SHMSIZE;
goto shmpage_out;
}
@@ -36799,7 +37281,7 @@ static int unixShmMap(
assert( (nByte % pgsz)==0 );
for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
int x = 0;
- if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
+ if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
const char *zFile = pShmNode->zFilename;
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
goto shmpage_out;
@@ -36822,22 +37304,22 @@ static int unixShmMap(
int nMap = szRegion*nShmPerMap;
int i;
void *pMem;
- if( pShmNode->h>=0 ){
+ if( pShmNode->hShm>=0 ){
pMem = osMmap(0, nMap,
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
- MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
+ MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
);
if( pMem==MAP_FAILED ){
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
goto shmpage_out;
}
}else{
- pMem = sqlite3_malloc64(szRegion);
+ pMem = sqlite3_malloc64(nMap);
if( pMem==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shmpage_out;
}
- memset(pMem, 0, szRegion);
+ memset(pMem, 0, nMap);
}
for(i=0; iisReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
return rc;
}
@@ -36888,12 +37370,12 @@ static int unixShmLock(
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
|| flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
mask = (1<<(ofst+n)) - (1<1 || mask==(1<mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
if( flags & SQLITE_SHM_UNLOCK ){
u16 allMask = 0; /* Mask of locks held by siblings */
@@ -36966,7 +37448,7 @@ static int unixShmLock(
}
}
}
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
p->id, osGetpid(0), p->sharedMask, p->exclMask));
return rc;
@@ -37016,14 +37498,14 @@ static int unixShmUnmap(
/* Remove connection p from the set of connections associated
** with pShmNode */
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
*pp = p->pNext;
/* Free the connection p */
sqlite3_free(p);
pDbFd->pShm = 0;
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
/* If pShmNode->nRef has reached 0, then close the underlying
** shared-memory file, too */
@@ -37032,7 +37514,7 @@ static int unixShmUnmap(
assert( pShmNode->nRef>0 );
pShmNode->nRef--;
if( pShmNode->nRef==0 ){
- if( deleteFlag && pShmNode->h>=0 ){
+ if( deleteFlag && pShmNode->hShm>=0 ){
osUnlink(pShmNode->zFilename);
}
unixShmPurge(pDbFd);
@@ -40450,8 +40932,7 @@ struct winFile {
int nFetchOut; /* Number of outstanding xFetch references */
HANDLE hMap; /* Handle for accessing memory mapping */
void *pMapRegion; /* Area memory mapped */
- sqlite3_int64 mmapSize; /* Usable size of mapped region */
- sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
+ sqlite3_int64 mmapSize; /* Size of mapped region */
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
#endif
};
@@ -43072,6 +43553,26 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
DWORD lastErrno;
#if SQLITE_MAX_MMAP_SIZE>0
sqlite3_int64 oldMmapSize;
+ if( pFile->nFetchOut>0 ){
+ /* File truncation is a no-op if there are outstanding memory mapped
+ ** pages. This is because truncating the file means temporarily unmapping
+ ** the file, and that might delete memory out from under existing cursors.
+ **
+ ** This can result in incremental vacuum not truncating the file,
+ ** if there is an active read cursor when the incremental vacuum occurs.
+ ** No real harm comes of this - the database file is not corrupted,
+ ** though some folks might complain that the file is bigger than it
+ ** needs to be.
+ **
+ ** The only feasible work-around is to defer the truncation until after
+ ** all references to memory-mapped content are closed. That is doable,
+ ** but involves adding a few branches in the common write code path which
+ ** could slow down normal operations slightly. Hence, we have decided for
+ ** now to simply make trancations a no-op if there are pending reads. We
+ ** can maybe revisit this decision in the future.
+ */
+ return SQLITE_OK;
+ }
#endif
assert( pFile );
@@ -44500,9 +45001,9 @@ static int winShmMap(
static int winUnmapfile(winFile *pFile){
assert( pFile!=0 );
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
- "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
+ "mmapSize=%lld, mmapSizeMax=%lld\n",
osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
- pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
+ pFile->mmapSize, pFile->mmapSizeMax));
if( pFile->pMapRegion ){
if( !osUnmapViewOfFile(pFile->pMapRegion) ){
pFile->lastErrno = osGetLastError();
@@ -44514,7 +45015,6 @@ static int winUnmapfile(winFile *pFile){
}
pFile->pMapRegion = 0;
pFile->mmapSize = 0;
- pFile->mmapSizeActual = 0;
}
if( pFile->hMap!=NULL ){
if( !osCloseHandle(pFile->hMap) ){
@@ -44625,7 +45125,6 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
}
pFd->pMapRegion = pNew;
pFd->mmapSize = nMap;
- pFd->mmapSizeActual = nMap;
}
OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
@@ -45427,7 +45926,6 @@ static int winOpen(
pFile->hMap = NULL;
pFile->pMapRegion = 0;
pFile->mmapSize = 0;
- pFile->mmapSizeActual = 0;
pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
@@ -46320,7 +46818,8 @@ typedef struct MemFile MemFile;
struct MemFile {
sqlite3_file base; /* IO methods */
sqlite3_int64 sz; /* Size of the file */
- sqlite3_int64 szMax; /* Space allocated to aData */
+ sqlite3_int64 szAlloc; /* Space allocated to aData */
+ sqlite3_int64 szMax; /* Maximum allowed size of the file */
unsigned char *aData; /* content of the file */
int nMmap; /* Number of memory mapped pages */
unsigned mFlags; /* Flags */
@@ -46446,10 +46945,15 @@ static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
return SQLITE_FULL;
}
+ if( newSz>p->szMax ){
+ return SQLITE_FULL;
+ }
+ newSz *= 2;
+ if( newSz>p->szMax ) newSz = p->szMax;
pNew = sqlite3_realloc64(p->aData, newSz);
if( pNew==0 ) return SQLITE_NOMEM;
p->aData = pNew;
- p->szMax = newSz;
+ p->szAlloc = newSz;
return SQLITE_OK;
}
@@ -46463,10 +46967,11 @@ static int memdbWrite(
sqlite_int64 iOfst
){
MemFile *p = (MemFile *)pFile;
+ if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ) return SQLITE_READONLY;
if( iOfst+iAmt>p->sz ){
int rc;
- if( iOfst+iAmt>p->szMax
- && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK
+ if( iOfst+iAmt>p->szAlloc
+ && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK
){
return rc;
}
@@ -46512,6 +47017,11 @@ static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
*/
static int memdbLock(sqlite3_file *pFile, int eLock){
MemFile *p = (MemFile *)pFile;
+ if( eLock>SQLITE_LOCK_SHARED
+ && (p->mFlags & SQLITE_DESERIALIZE_READONLY)!=0
+ ){
+ return SQLITE_READONLY;
+ }
p->eLock = eLock;
return SQLITE_OK;
}
@@ -46536,6 +47046,19 @@ static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){
*(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz);
rc = SQLITE_OK;
}
+ if( op==SQLITE_FCNTL_SIZE_LIMIT ){
+ sqlite3_int64 iLimit = *(sqlite3_int64*)pArg;
+ if( iLimitsz ){
+ if( iLimit<0 ){
+ iLimit = p->szMax;
+ }else{
+ iLimit = p->sz;
+ }
+ }
+ p->szMax = iLimit;
+ *(sqlite3_int64*)pArg = iLimit;
+ rc = SQLITE_OK;
+ }
return rc;
}
@@ -46566,8 +47089,12 @@ static int memdbFetch(
void **pp
){
MemFile *p = (MemFile *)pFile;
- p->nMmap++;
- *pp = (void*)(p->aData + iOfst);
+ if( iOfst+iAmt>p->sz ){
+ *pp = 0;
+ }else{
+ p->nMmap++;
+ *pp = (void*)(p->aData + iOfst);
+ }
return SQLITE_OK;
}
@@ -46597,6 +47124,7 @@ static int memdbOpen(
assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
*pOutFlags = flags | SQLITE_OPEN_MEMORY;
p->base.pMethods = &memdb_io_methods;
+ p->szMax = sqlite3GlobalConfig.mxMemdbSize;
return SQLITE_OK;
}
@@ -46846,7 +47374,11 @@ SQLITE_API int sqlite3_deserialize(
}else{
p->aData = pData;
p->sz = szDb;
+ p->szAlloc = szBuf;
p->szMax = szBuf;
+ if( p->szMaxszMax = sqlite3GlobalConfig.mxMemdbSize;
+ }
p->mFlags = mFlags;
rc = SQLITE_OK;
}
@@ -47324,7 +47856,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
** The PCache.pSynced variable is used to optimize searching for a dirty
** page to eject from the cache mid-transaction. It is better to eject
** a page that does not require a journal sync than one that does.
-** Therefore, pSynced is maintained to that it *almost* always points
+** Therefore, pSynced is maintained so that it *almost* always points
** to either the oldest page in the pDirty/pDirtyTail list that has a
** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
** (so that the right page to eject can be found by following pDirtyPrev
@@ -47535,9 +48067,10 @@ static int numberOfCachePages(PCache *p){
** suggested cache size is set to N. */
return p->szCache;
}else{
- /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
- ** the number of cache pages is adjusted to use approximately abs(N*1024)
- ** bytes of memory. */
+ /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
+ ** number of cache pages is adjusted to be a number of pages that would
+ ** use approximately abs(N*1024) bytes of memory based on the current
+ ** page size. */
return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
}
}
@@ -48148,6 +48681,15 @@ SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){
return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
}
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+/*
+** Return true if there are one or more dirty pages in the cache. Else false.
+*/
+SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){
+ return (pCache->pDirty!=0);
+}
+#endif
+
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/*
** For all dirty pages currently in the cache, invoke the specified
@@ -48258,20 +48800,32 @@ typedef struct PGroup PGroup;
** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
** PgHdr1.pCache->szPage bytes is allocated directly before this structure
** in memory.
+**
+** Note: Variables isBulkLocal and isAnchor were once type "u8". That works,
+** but causes a 2-byte gap in the structure for most architectures (since
+** pointers must be either 4 or 8-byte aligned). As this structure is located
+** in memory directly after the associated page data, if the database is
+** corrupt, code at the b-tree layer may overread the page buffer and
+** read part of this structure before the corruption is detected. This
+** can cause a valgrind error if the unitialized gap is accessed. Using u16
+** ensures there is no such gap, and therefore no bytes of unitialized memory
+** in the structure.
*/
struct PgHdr1 {
sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */
unsigned int iKey; /* Key value (page number) */
- u8 isBulkLocal; /* This page from bulk local storage */
- u8 isAnchor; /* This is the PGroup.lru element */
+ u16 isBulkLocal; /* This page from bulk local storage */
+ u16 isAnchor; /* This is the PGroup.lru element */
PgHdr1 *pNext; /* Next in hash table chain */
PCache1 *pCache; /* Cache that currently owns this page */
PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
+ /* NB: pLruPrev is only valid if pLruNext!=0 */
};
/*
-** A page is pinned if it is no on the LRU list
+** A page is pinned if it is not on the LRU list. To be "pinned" means
+** that the page is in active use and must not be deallocated.
*/
#define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
@@ -48332,6 +48886,7 @@ struct PCache1 {
unsigned int nMax; /* Configured "cache_size" value */
unsigned int n90pct; /* nMax*9/10 */
unsigned int iMaxKey; /* Largest key seen since xTruncate() */
+ unsigned int nPurgeableDummy; /* pnPurgeable points here when not used*/
/* Hash table of all pages. The following variables may only be accessed
** when the accessor is holding the PGroup mutex.
@@ -48466,6 +49021,7 @@ static int pcache1InitBulk(PCache1 *pCache){
pX->isBulkLocal = 1;
pX->isAnchor = 0;
pX->pNext = pCache->pFree;
+ pX->pLruPrev = 0; /* Initializing this saves a valgrind error */
pCache->pFree = pX;
zBulk += pCache->szAlloc;
}while( --nBulk );
@@ -48641,6 +49197,7 @@ static void pcache1FreePage(PgHdr1 *p){
** exists, this function falls back to sqlite3Malloc().
*/
SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
+ assert( sz<=65536+8 ); /* These allocations are never very large */
return pcache1Alloc(sz);
}
@@ -48735,7 +49292,8 @@ static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
pPage->pLruPrev->pLruNext = pPage->pLruNext;
pPage->pLruNext->pLruPrev = pPage->pLruPrev;
pPage->pLruNext = 0;
- pPage->pLruPrev = 0;
+ /* pPage->pLruPrev = 0;
+ ** No need to clear pLruPrev as it is never accessed if pLruNext is 0 */
assert( pPage->isAnchor==0 );
assert( pPage->pCache->pGroup->lru.isAnchor==1 );
pPage->pCache->nRecyclable--;
@@ -48928,6 +49486,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
}else{
pGroup = &pcache1.grp;
}
+ pcache1EnterMutex(pGroup);
if( pGroup->lru.isAnchor==0 ){
pGroup->lru.isAnchor = 1;
pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru;
@@ -48937,7 +49496,6 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pCache->szExtra = szExtra;
pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1));
pCache->bPurgeable = (bPurgeable ? 1 : 0);
- pcache1EnterMutex(pGroup);
pcache1ResizeHash(pCache);
if( bPurgeable ){
pCache->nMin = 10;
@@ -48945,8 +49503,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
pCache->pnPurgeable = &pGroup->nPurgeable;
}else{
- static unsigned int dummyCurrentPage;
- pCache->pnPurgeable = &dummyCurrentPage;
+ pCache->pnPurgeable = &pCache->nPurgeableDummy;
}
pcache1LeaveMutex(pGroup);
if( pCache->nHash==0 ){
@@ -49073,8 +49630,9 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
pPage->iKey = iKey;
pPage->pNext = pCache->apHash[h];
pPage->pCache = pCache;
- pPage->pLruPrev = 0;
pPage->pLruNext = 0;
+ /* pPage->pLruPrev = 0;
+ ** No need to clear pLruPrev since it is not accessed when pLruNext==0 */
*(void **)pPage->page.pExtra = 0;
pCache->apHash[h] = pPage;
if( iKey>pCache->iMaxKey ){
@@ -49234,7 +49792,7 @@ static void pcache1Unpin(
/* It is an error to call this function if the page is already
** part of the PGroup LRU list.
*/
- assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
+ assert( pPage->pLruNext==0 );
assert( PAGE_IS_PINNED(pPage) );
if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){
@@ -50911,19 +51469,33 @@ static const unsigned char aJournalMagic[] = {
*/
#define isOpen(pFd) ((pFd)->pMethods!=0)
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
/*
-** Return true if this pager uses a write-ahead log to read page pgno.
-** Return false if the pager reads pgno directly from the database.
+** Return true if page pgno can be read directly from the database file
+** by the b-tree layer. This is the case if:
+**
+** * the database file is open,
+** * there are no dirty pages in the cache, and
+** * the desired page is not currently in the wal file.
*/
-#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
-SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
- u32 iRead = 0;
- int rc;
- if( pPager->pWal==0 ) return 0;
- rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
- return rc || iRead;
+SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
+ if( pPager->fd->pMethods==0 ) return 0;
+ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
+#ifdef SQLITE_HAS_CODEC
+ if( pPager->xCodec!=0 ) return 0;
+#endif
+#ifndef SQLITE_OMIT_WAL
+ if( pPager->pWal ){
+ u32 iRead = 0;
+ int rc;
+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
+ return (rc==SQLITE_OK && iRead==0);
+ }
+#endif
+ return 1;
}
#endif
+
#ifndef SQLITE_OMIT_WAL
# define pagerUseWal(x) ((x)->pWal!=0)
#else
@@ -53861,8 +54433,14 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nR
rc = sqlite3OsFileSize(pPager->fd, &nByte);
}
if( rc==SQLITE_OK ){
- pNew = (char *)sqlite3PageMalloc(pageSize);
- if( !pNew ) rc = SQLITE_NOMEM_BKPT;
+ /* 8 bytes of zeroed overrun space is sufficient so that the b-tree
+ * cell header parser will never run off the end of the allocation */
+ pNew = (char *)sqlite3PageMalloc(pageSize+8);
+ if( !pNew ){
+ rc = SQLITE_NOMEM_BKPT;
+ }else{
+ memset(pNew+pageSize, 0, 8);
+ }
}
if( rc==SQLITE_OK ){
@@ -53914,7 +54492,10 @@ SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
pPager->mxPgno = mxPage;
}
assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */
- assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */
+ /* assert( pPager->mxPgno>=pPager->dbSize ); */
+ /* OP_MaxPgcnt ensures that the parameter passed to this function is not
+ ** less than the total number of valid pages in the database. But this
+ ** may be less than Pager.dbSize, and so the assert() above is not valid */
return pPager->mxPgno;
}
@@ -57107,7 +57688,11 @@ SQLITE_PRIVATE void sqlite3PagerSetCodec(
void (*xCodecFree)(void*),
void *pCodec
){
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
+ if( pPager->xCodecFree ){
+ pPager->xCodecFree(pPager->pCodec);
+ }else{
+ pager_reset(pPager);
+ }
pPager->xCodec = pPager->memDb ? 0 : xCodec;
pPager->xCodecSizeChng = xCodecSizeChng;
pPager->xCodecFree = xCodecFree;
@@ -57236,8 +57821,12 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
*/
pPg->flags &= ~PGHDR_NEED_SYNC;
pPgOld = sqlite3PagerLookup(pPager, pgno);
- assert( !pPgOld || pPgOld->nRef==1 );
+ assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB );
if( pPgOld ){
+ if( pPgOld->nRef>1 ){
+ sqlite3PagerUnrefNotNull(pPgOld);
+ return SQLITE_CORRUPT_BKPT;
+ }
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
if( pPager->tempFile ){
/* Do not discard pages from an in-memory database since we might
@@ -57765,7 +58354,7 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pS
*/
SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){
assert( pPager->pWal );
- return sqlite3WalSnapshotUnlock(pPager->pWal);
+ sqlite3WalSnapshotUnlock(pPager->pWal);
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
@@ -58366,7 +58955,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc(
/* Enlarge the pWal->apWiData[] array if required */
if( pWal->nWiData<=iPage ){
- int nByte = sizeof(u32*)*(iPage+1);
+ sqlite3_int64 nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
if( !apNew ){
@@ -58470,6 +59059,7 @@ static void walChecksumBytes(
assert( nByte>=8 );
assert( (nByte&0x00000007)==0 );
+ assert( nByte<=65536 );
if( nativeCksum ){
do {
@@ -58777,6 +59367,7 @@ static void walCleanupHash(Wal *pWal){
int iLimit = 0; /* Zero values greater than this */
int nByte; /* Number of bytes to zero in aPgno[] */
int i; /* Used to iterate through aHash[] */
+ int rc; /* Return code form walHashGet() */
assert( pWal->writeLock );
testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
@@ -58787,11 +59378,12 @@ static void walCleanupHash(Wal *pWal){
/* Obtain pointers to the hash-table and page-number array containing
** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
- ** that the page said hash-table and array reside on is already mapped.
+ ** that the page said hash-table and array reside on is already mapped.(1)
*/
assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
- walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
+ rc = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc);
+ if( NEVER(rc) ) return; /* Defense-in-depth, in case (1) above is wrong */
/* Zero all hash-table entries that correspond to frame numbers greater
** than pWal->hdr.mxFrame.
@@ -59405,7 +59997,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
WalIterator *p; /* Return value */
int nSegment; /* Number of segments to merge */
u32 iLast; /* Last frame in log */
- int nByte; /* Number of bytes to allocate */
+ sqlite3_int64 nByte; /* Number of bytes to allocate */
int i; /* Iterator variable */
ht_slot *aTmp; /* Temp space used by merge-sort */
int rc = SQLITE_OK; /* Return Code */
@@ -60696,9 +61288,9 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
}
nCollide = HASHTABLE_NSLOT;
for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
- u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero;
- if( iFrame<=iLast && iFrame>=pWal->minFrame
- && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){
+ u32 iH = sLoc.aHash[iKey];
+ u32 iFrame = iH + sLoc.iZero;
+ if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
iRead = iFrame;
}
@@ -61941,7 +62533,7 @@ struct MemPage {
u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
u16 cellOffset; /* Index in aData of first cell pointer */
- u16 nFree; /* Number of free bytes on the page */
+ int nFree; /* Number of free bytes on the page. -1 for unknown */
u16 nCell; /* Number of cells on this page, local and ovfl */
u16 maskPage; /* Mask for page offset */
u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
@@ -62149,9 +62741,16 @@ struct CellInfo {
** found at self->pBt->mutex.
**
** skipNext meaning:
-** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op.
-** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op.
-** eState==FAULT: Cursor fault with skipNext as error code.
+** The meaning of skipNext depends on the value of eState:
+**
+** eState Meaning of skipNext
+** VALID skipNext is meaningless and is ignored
+** INVALID skipNext is meaningless and is ignored
+** SKIPNEXT sqlite3BtreeNext() is a no-op if skipNext>0 and
+** sqlite3BtreePrevious() is no-op if skipNext<0.
+** REQUIRESEEK restoreCursorPosition() restores the cursor to
+** eState=SKIPNEXT if skipNext!=0
+** FAULT skipNext holds the cursor fault error code.
*/
struct BtCursor {
u8 eState; /* One of the CURSOR_XXX constants (see below) */
@@ -63315,13 +63914,19 @@ static int saveCursorKey(BtCursor *pCur){
/* Only the rowid is required for a table btree */
pCur->nKey = sqlite3BtreeIntegerKey(pCur);
}else{
- /* For an index btree, save the complete key content */
+ /* For an index btree, save the complete key content. It is possible
+ ** that the current key is corrupt. In that case, it is possible that
+ ** the sqlite3VdbeRecordUnpack() function may overread the buffer by
+ ** up to the size of 1 varint plus 1 8-byte value when the cursor
+ ** position is restored. Hence the 17 bytes of padding allocated
+ ** below. */
void *pKey;
pCur->nKey = sqlite3BtreePayloadSize(pCur);
- pKey = sqlite3Malloc( pCur->nKey );
+ pKey = sqlite3Malloc( pCur->nKey + 9 + 8 );
if( pKey ){
rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
if( rc==SQLITE_OK ){
+ memset(((u8*)pKey)+pCur->nKey, 0, 9+8);
pCur->pKey = pKey;
}else{
sqlite3_free(pKey);
@@ -63453,11 +64058,12 @@ static int btreeMoveto(
UnpackedRecord *pIdxKey; /* Unpacked index key */
if( pKey ){
+ KeyInfo *pKeyInfo = pCur->pKeyInfo;
assert( nKey==(i64)(int)nKey );
- pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo);
+ pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
- sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
- if( pIdxKey->nField==0 ){
+ sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey);
+ if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){
rc = SQLITE_CORRUPT_BKPT;
goto moveto_done;
}
@@ -63481,19 +64087,23 @@ static int btreeMoveto(
*/
static int btreeRestoreCursorPosition(BtCursor *pCur){
int rc;
- int skipNext;
+ int skipNext = 0;
assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState>=CURSOR_REQUIRESEEK );
if( pCur->eState==CURSOR_FAULT ){
return pCur->skipNext;
}
pCur->eState = CURSOR_INVALID;
- rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
+ if( sqlite3FaultSim(410) ){
+ rc = SQLITE_IOERR;
+ }else{
+ rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
+ }
if( rc==SQLITE_OK ){
sqlite3_free(pCur->pKey);
pCur->pKey = 0;
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
- pCur->skipNext |= skipNext;
+ if( skipNext ) pCur->skipNext = skipNext;
if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
pCur->eState = CURSOR_SKIPNEXT;
}
@@ -63563,7 +64173,6 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow)
if( pCur->eState!=CURSOR_VALID ){
*pDifferentRow = 1;
}else{
- assert( pCur->skipNext==0 );
*pDifferentRow = 0;
}
return SQLITE_OK;
@@ -63647,6 +64256,13 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
*pRC = rc;
return;
}
+ if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){
+ /* The first byte of the extra data is the MemPage.isInit byte.
+ ** If that byte is set, it means this page is also being used
+ ** as a btree page. */
+ *pRC = SQLITE_CORRUPT_BKPT;
+ goto ptrmap_exit;
+ }
offset = PTRMAP_PTROFFSET(iPtrmap, key);
if( offset<0 ){
*pRC = SQLITE_CORRUPT_BKPT;
@@ -63709,7 +64325,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
#else /* if defined SQLITE_OMIT_AUTOVACUUM */
#define ptrmapPut(w,x,y,z,rc)
#define ptrmapGet(w,x,y,z) SQLITE_OK
- #define ptrmapPutOvflPtr(x, y, rc)
+ #define ptrmapPutOvflPtr(x, y, z, rc)
#endif
/*
@@ -64002,17 +64618,24 @@ static u16 cellSize(MemPage *pPage, int iCell){
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
-** If the cell pCell, part of page pPage contains a pointer
-** to an overflow page, insert an entry into the pointer-map
-** for the overflow page.
+** The cell pCell is currently part of page pSrc but will ultimately be part
+** of pPage. (pSrc and pPager are often the same.) If pCell contains a
+** pointer to an overflow page, insert an entry into the pointer-map for
+** the overflow page that will be valid after pCell has been moved to pPage.
*/
-static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
+static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
CellInfo info;
if( *pRC ) return;
assert( pCell!=0 );
pPage->xParseCell(pPage, pCell, &info);
if( info.nLocalaDataEnd, pCell, pCell+info.nLocal) ){
+ testcase( pSrc!=pPage );
+ *pRC = SQLITE_CORRUPT_BKPT;
+ return;
+ }
+ ovfl = get4byte(&pCell[info.nSize-4]);
ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
}
}
@@ -64056,7 +64679,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
hdr = pPage->hdrOffset;
cellOffset = pPage->cellOffset;
nCell = pPage->nCell;
- assert( nCell==get2byte(&data[hdr+3]) );
+ assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB );
iCellFirst = cellOffset + 2*nCell;
usableSize = pPage->pBt->usableSize;
@@ -64067,19 +64690,10 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
** reconstruct the entire page. */
if( (int)data[hdr+7]<=nMaxFrag ){
int iFree = get2byte(&data[hdr+1]);
+ if( iFree>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
if( iFree ){
int iFree2 = get2byte(&data[iFree]);
-
- /* pageFindSlot() has already verified that free blocks are sorted
- ** in order of offset within the page, and that no block extends
- ** past the end of the page. Provided the two free slots do not
- ** overlap, this guarantees that the memmove() calls below will not
- ** overwrite the usableSize byte buffer, even if the database page
- ** is corrupt. */
- assert( iFree2==0 || iFree2>iFree );
- assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
- assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
-
+ if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
u8 *pEnd = &data[cellOffset + nCell*2];
u8 *pAddr;
@@ -64090,12 +64704,15 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
return SQLITE_CORRUPT_PAGE(pPage);
}
if( iFree2 ){
- assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */
+ if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
sz2 = get2byte(&data[iFree2+2]);
- assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
+ if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
sz += sz2;
+ }else if( iFree+sz>usableSize ){
+ return SQLITE_CORRUPT_PAGE(pPage);
}
+
cbrk = top+sz;
assert( cbrk+(iFree-top) <= usableSize );
memmove(&data[cbrk], &data[top], iFree-top);
@@ -64146,6 +64763,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
data[hdr+7] = 0;
defragment_out:
+ assert( pPage->nFree>=0 );
if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
return SQLITE_CORRUPT_PAGE(pPage);
}
@@ -64173,16 +64791,16 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
** causes the fragmentation count to exceed 60.
*/
static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
- const int hdr = pPg->hdrOffset;
- u8 * const aData = pPg->aData;
- int iAddr = hdr + 1;
- int pc = get2byte(&aData[iAddr]);
- int x;
- int usableSize = pPg->pBt->usableSize;
- int size; /* Size of the free slot */
+ const int hdr = pPg->hdrOffset; /* Offset to page header */
+ u8 * const aData = pPg->aData; /* Page data */
+ int iAddr = hdr + 1; /* Address of ptr to pc */
+ int pc = get2byte(&aData[iAddr]); /* Address of a free slot */
+ int x; /* Excess size of the slot */
+ int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */
+ int size; /* Size of the free slot */
assert( pc>0 );
- while( pc<=usableSize-4 ){
+ while( pc<=maxPC ){
/* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
** freeblock form a big-endian integer which is the size of the freeblock
** in bytes, including the 4-byte header. */
@@ -64190,10 +64808,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
if( (x = size - nByte)>=0 ){
testcase( x==4 );
testcase( x==3 );
- if( size+pc > usableSize ){
- *pRc = SQLITE_CORRUPT_PAGE(pPg);
- return 0;
- }else if( x<4 ){
+ if( x<4 ){
/* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
** number of bytes in fragments may not exceed 60. */
if( aData[hdr+7]>57 ) return 0;
@@ -64202,21 +64817,31 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
** fragmented bytes within the page. */
memcpy(&aData[iAddr], &aData[pc], 2);
aData[hdr+7] += (u8)x;
+ }else if( x+pc > maxPC ){
+ /* This slot extends off the end of the usable part of the page */
+ *pRc = SQLITE_CORRUPT_PAGE(pPg);
+ return 0;
}else{
/* The slot remains on the free-list. Reduce its size to account
- ** for the portion used by the new allocation. */
+ ** for the portion used by the new allocation. */
put2byte(&aData[pc+2], x);
}
return &aData[pc + x];
}
iAddr = pc;
pc = get2byte(&aData[pc]);
- if( pcmaxPC+nByte-4 ){
+ /* The free slot chain extends off the end of the page */
*pRc = SQLITE_CORRUPT_PAGE(pPg);
}
-
return 0;
}
@@ -64257,7 +64882,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
** However, that integer is too large to be stored in a 2-byte unsigned
** integer, so a value of 0 is used in its place. */
top = get2byte(&data[hdr+5]);
- assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */
+ assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
if( gap>top ){
if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536;
@@ -64266,9 +64891,9 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
}
}
- /* If there is enough space between gap and top for one more cell pointer
- ** array entry offset, and if the freelist is not empty, then search the
- ** freelist looking for a free slot big enough to satisfy the request.
+ /* If there is enough space between gap and top for one more cell pointer,
+ ** and if the freelist is not empty, then search the
+ ** freelist looking for a slot big enough to satisfy the request.
*/
testcase( gap+2==top );
testcase( gap+1==top );
@@ -64290,6 +64915,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
testcase( gap+2+nByte==top );
if( gap+2+nByte>top ){
assert( pPage->nCell>0 || CORRUPT_DB );
+ assert( pPage->nFree>=0 );
rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]);
@@ -64298,7 +64924,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
/* Allocate memory from the gap in between the cell pointer array
- ** and the cell content area. The btreeInitPage() call has already
+ ** and the cell content area. The btreeComputeFreeSpace() call has already
** validated the freelist. Given that the freelist is valid, there
** is no way that the allocation can extend off the end of the page.
** The assert() below verifies the previous sentence.
@@ -64317,7 +64943,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
**
** Adjacent freeblocks are coalesced.
**
-** Note that even though the freeblock list was checked by btreeInitPage(),
+** Even though the freeblock list was checked by btreeComputeFreeSpace(),
** that routine will not detect overlap between cells or freeblocks. Nor
** does it detect cells or freeblocks that encrouch into the reserved bytes
** at the end of the page. So do additional corruption checks inside this
@@ -64479,21 +65105,14 @@ static int decodeFlags(MemPage *pPage, int flagByte){
}
/*
-** Initialize the auxiliary information for a disk block.
-**
-** Return SQLITE_OK on success. If we see that the page does
-** not contain a well-formed database page, then return
-** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
-** guarantee that the page is well-formed. It only shows that
-** we failed to detect any corruption.
+** Compute the amount of freespace on the page. In other words, fill
+** in the pPage->nFree field.
*/
-static int btreeInitPage(MemPage *pPage){
+static int btreeComputeFreeSpace(MemPage *pPage){
int pc; /* Address of a freeblock within pPage->aData[] */
u8 hdr; /* Offset to beginning of page header */
u8 *data; /* Equal to pPage->aData */
- BtShared *pBt; /* The main btree structure */
int usableSize; /* Amount of usable space on each page */
- u16 cellOffset; /* Offset from start of page to first cell pointer */
int nFree; /* Number of unused bytes on the page */
int top; /* First byte of the cell content area */
int iCellFirst; /* First allowable cell or freeblock offset */
@@ -64505,71 +65124,18 @@ static int btreeInitPage(MemPage *pPage){
assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
- assert( pPage->isInit==0 );
+ assert( pPage->isInit==1 );
+ assert( pPage->nFree<0 );
- pBt = pPage->pBt;
+ usableSize = pPage->pBt->usableSize;
hdr = pPage->hdrOffset;
data = pPage->aData;
- /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
- ** the b-tree page type. */
- if( decodeFlags(pPage, data[hdr]) ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
- pPage->maskPage = (u16)(pBt->pageSize - 1);
- pPage->nOverflow = 0;
- usableSize = pBt->usableSize;
- pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize;
- pPage->aDataEnd = &data[usableSize];
- pPage->aCellIdx = &data[cellOffset];
- pPage->aDataOfst = &data[pPage->childPtrSize];
/* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
** the start of the cell content area. A zero value for this integer is
** interpreted as 65536. */
top = get2byteNotZero(&data[hdr+5]);
- /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
- ** number of cells on the page. */
- pPage->nCell = get2byte(&data[hdr+3]);
- if( pPage->nCell>MX_CELL(pBt) ){
- /* To many cells for a single page. The page must be corrupt */
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- testcase( pPage->nCell==MX_CELL(pBt) );
- /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
- ** possible for a root page of a table that contains no rows) then the
- ** offset to the cell content area will equal the page size minus the
- ** bytes of reserved space. */
- assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB );
-
- /* A malformed database page might cause us to read past the end
- ** of page when parsing a cell.
- **
- ** The following block of code checks early to see if a cell extends
- ** past the end of a page boundary and causes SQLITE_CORRUPT to be
- ** returned if it does.
- */
- iCellFirst = cellOffset + 2*pPage->nCell;
+ iCellFirst = hdr + 8 + pPage->childPtrSize + 2*pPage->nCell;
iCellLast = usableSize - 4;
- if( pBt->db->flags & SQLITE_CellSizeCk ){
- int i; /* Index into the cell pointer array */
- int sz; /* Size of a cell */
-
- if( !pPage->leaf ) iCellLast--;
- for(i=0; inCell; i++){
- pc = get2byteAligned(&data[cellOffset+i*2]);
- testcase( pc==iCellFirst );
- testcase( pc==iCellLast );
- if( pciCellLast ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- sz = pPage->xCellSize(pPage, &data[pc]);
- testcase( pc+sz==usableSize );
- if( pc+sz>usableSize ){
- return SQLITE_CORRUPT_PAGE(pPage);
- }
- }
- if( !pPage->leaf ) iCellLast++;
- }
/* Compute the total free space on the page
** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
@@ -64613,11 +65179,104 @@ static int btreeInitPage(MemPage *pPage){
** serves to verify that the offset to the start of the cell-content
** area, according to the page header, lies within the page.
*/
- if( nFree>usableSize ){
+ if( nFree>usableSize || nFreenFree = (u16)(nFree - iCellFirst);
+ return SQLITE_OK;
+}
+
+/*
+** Do additional sanity check after btreeInitPage() if
+** PRAGMA cell_size_check=ON
+*/
+static SQLITE_NOINLINE int btreeCellSizeCheck(MemPage *pPage){
+ int iCellFirst; /* First allowable cell or freeblock offset */
+ int iCellLast; /* Last possible cell or freeblock offset */
+ int i; /* Index into the cell pointer array */
+ int sz; /* Size of a cell */
+ int pc; /* Address of a freeblock within pPage->aData[] */
+ u8 *data; /* Equal to pPage->aData */
+ int usableSize; /* Maximum usable space on the page */
+ int cellOffset; /* Start of cell content area */
+
+ iCellFirst = pPage->cellOffset + 2*pPage->nCell;
+ usableSize = pPage->pBt->usableSize;
+ iCellLast = usableSize - 4;
+ data = pPage->aData;
+ cellOffset = pPage->cellOffset;
+ if( !pPage->leaf ) iCellLast--;
+ for(i=0; inCell; i++){
+ pc = get2byteAligned(&data[cellOffset+i*2]);
+ testcase( pc==iCellFirst );
+ testcase( pc==iCellLast );
+ if( pciCellLast ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ sz = pPage->xCellSize(pPage, &data[pc]);
+ testcase( pc+sz==usableSize );
+ if( pc+sz>usableSize ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Initialize the auxiliary information for a disk block.
+**
+** Return SQLITE_OK on success. If we see that the page does
+** not contain a well-formed database page, then return
+** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
+** guarantee that the page is well-formed. It only shows that
+** we failed to detect any corruption.
+*/
+static int btreeInitPage(MemPage *pPage){
+ u8 *data; /* Equal to pPage->aData */
+ BtShared *pBt; /* The main btree structure */
+
+ assert( pPage->pBt!=0 );
+ assert( pPage->pBt->db!=0 );
+ assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+ assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
+ assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
+ assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
+ assert( pPage->isInit==0 );
+
+ pBt = pPage->pBt;
+ data = pPage->aData + pPage->hdrOffset;
+ /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
+ ** the b-tree page type. */
+ if( decodeFlags(pPage, data[0]) ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
+ pPage->maskPage = (u16)(pBt->pageSize - 1);
+ pPage->nOverflow = 0;
+ pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize;
+ pPage->aCellIdx = data + pPage->childPtrSize + 8;
+ pPage->aDataEnd = pPage->aData + pBt->usableSize;
+ pPage->aDataOfst = pPage->aData + pPage->childPtrSize;
+ /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
+ ** number of cells on the page. */
+ pPage->nCell = get2byte(&data[3]);
+ if( pPage->nCell>MX_CELL(pBt) ){
+ /* To many cells for a single page. The page must be corrupt */
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
+ testcase( pPage->nCell==MX_CELL(pBt) );
+ /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
+ ** possible for a root page of a table that contains no rows) then the
+ ** offset to the cell content area will equal the page size minus the
+ ** bytes of reserved space. */
+ assert( pPage->nCell>0
+ || get2byteNotZero(&data[5])==(int)pBt->usableSize
+ || CORRUPT_DB );
+ pPage->nFree = -1; /* Indicate that this value is yet uncomputed */
pPage->isInit = 1;
+ if( pBt->db->flags & SQLITE_CellSizeCk ){
+ return btreeCellSizeCheck(pPage);
+ }
return SQLITE_OK;
}
@@ -64760,19 +65419,18 @@ static int getAndInitPage(
if( pgno>btreePagecount(pBt) ){
rc = SQLITE_CORRUPT_BKPT;
- goto getAndInitPage_error;
+ goto getAndInitPage_error1;
}
rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly);
if( rc ){
- goto getAndInitPage_error;
+ goto getAndInitPage_error1;
}
*ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
if( (*ppPage)->isInit==0 ){
btreePageFromDbPage(pDbPage, pgno, pBt);
rc = btreeInitPage(*ppPage);
if( rc!=SQLITE_OK ){
- releasePage(*ppPage);
- goto getAndInitPage_error;
+ goto getAndInitPage_error2;
}
}
assert( (*ppPage)->pgno==pgno );
@@ -64782,12 +65440,13 @@ static int getAndInitPage(
** compatible with the root page. */
if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){
rc = SQLITE_CORRUPT_PGNO(pgno);
- releasePage(*ppPage);
- goto getAndInitPage_error;
+ goto getAndInitPage_error2;
}
return SQLITE_OK;
-getAndInitPage_error:
+getAndInitPage_error2:
+ releasePage(*ppPage);
+getAndInitPage_error1:
if( pCur ){
pCur->iPage--;
pCur->pPage = pCur->apPage[pCur->iPage];
@@ -65647,9 +66306,9 @@ static int newDatabase(BtShared*);
static int lockBtree(BtShared *pBt){
int rc; /* Result code from subfunctions */
MemPage *pPage1; /* Page 1 of the database file */
- int nPage; /* Number of pages in the database */
- int nPageFile = 0; /* Number of pages in the database file */
- int nPageHeader; /* Number of pages in the database according to hdr */
+ u32 nPage; /* Number of pages in the database */
+ u32 nPageFile = 0; /* Number of pages in the database file */
+ u32 nPageHeader; /* Number of pages in the database according to hdr */
assert( sqlite3_mutex_held(pBt->mutex) );
assert( pBt->pPage1==0 );
@@ -65662,7 +66321,7 @@ static int lockBtree(BtShared *pBt){
** a valid database file.
*/
nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
- sqlite3PagerPagecount(pBt->pPager, &nPageFile);
+ sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile);
if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
nPage = nPageFile;
}
@@ -65743,6 +66402,7 @@ static int lockBtree(BtShared *pBt){
){
goto page1_init_failed;
}
+ pBt->btsFlags |= BTS_PAGESIZE_FIXED;
assert( (pageSize & 7)==0 );
/* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte
** integer at offset 20 is the number of bytes of space at the end of
@@ -65767,7 +66427,7 @@ static int lockBtree(BtShared *pBt){
pageSize-usableSize);
return rc;
}
- if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
+ if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
rc = SQLITE_CORRUPT_BKPT;
goto page1_init_failed;
}
@@ -66133,7 +66793,7 @@ static int setChildPtrmaps(MemPage *pPage){
for(i=0; ileaf ){
Pgno childPgno = get4byte(pCell);
@@ -66241,6 +66901,7 @@ static int relocatePage(
eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
assert( sqlite3_mutex_held(pBt->mutex) );
assert( pDbPage->pBt==pBt );
+ if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;
/* Move page iDbPage from its current location to page number iFreePage */
TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
@@ -66746,6 +67407,18 @@ SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int wr
return rc;
}
+/*
+** Set the pBt->nPage field correctly, according to the current
+** state of the database. Assume pBt->pPage1 is valid.
+*/
+static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){
+ int nPage = get4byte(&pPage1->aData[28]);
+ testcase( nPage==0 );
+ if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
+ testcase( pBt->nPage!=nPage );
+ pBt->nPage = nPage;
+}
+
/*
** Rollback the transaction in progress.
**
@@ -66791,11 +67464,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
** call btreeGetPage() on page 1 again to make
** sure pPage1->aData is set correctly. */
if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
- int nPage = get4byte(28+(u8*)pPage1->aData);
- testcase( nPage==0 );
- if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
- testcase( pBt->nPage!=nPage );
- pBt->nPage = nPage;
+ btreeSetNPage(pBt, pPage1);
releasePageOne(pPage1);
}
assert( countValidCursors(pBt, 1)==0 );
@@ -66875,12 +67544,11 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
pBt->nPage = 0;
}
rc = newDatabase(pBt);
- pBt->nPage = get4byte(28 + pBt->pPage1->aData);
+ btreeSetNPage(pBt, pBt->pPage1);
- /* The database size was written into the offset 28 of the header
- ** when the transaction started, so we know that the value at offset
- ** 28 is nonzero. */
- assert( pBt->nPage>0 );
+ /* pBt->nPage might be zero if the database was corrupt when
+ ** the transaction was started. Otherwise, it must be at least 1. */
+ assert( CORRUPT_DB || pBt->nPage>0 );
}
sqlite3BtreeLeave(p);
}
@@ -67058,6 +67726,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
sqlite3_free(pCur->aOverflow);
sqlite3_free(pCur->pKey);
sqlite3BtreeLeave(pBtree);
+ pCur->pBtree = 0;
}
return SQLITE_OK;
}
@@ -67156,6 +67825,25 @@ SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){
return pCur->info.nPayload;
}
+/*
+** Return an upper bound on the size of any record for the table
+** that the cursor is pointing into.
+**
+** This is an optimization. Everything will still work if this
+** routine always returns 2147483647 (which is the largest record
+** that SQLite can handle) or more. But returning a smaller value might
+** prevent large memory allocations when trying to interpret a
+** corrupt datrabase.
+**
+** The current implementation merely returns the size of the underlying
+** database file.
+*/
+SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){
+ assert( cursorHoldsMutex(pCur) );
+ assert( pCur->eState==CURSOR_VALID );
+ return pCur->pBt->pageSize * (sqlite3_int64)pCur->pBt->nPage;
+}
+
/*
** Given the page number of an overflow page in the database (parameter
** ovfl), this function finds the page number of the next page in the
@@ -67412,9 +68100,6 @@ static int accessPayload(
/* Need to read this page properly. It contains some of the
** range of data that is being read (eOp==0) or written (eOp!=0).
*/
-#ifdef SQLITE_DIRECT_OVERFLOW_READ
- sqlite3_file *fd; /* File from which to do direct overflow read */
-#endif
int a = amt;
if( a + offset > ovflSize ){
a = ovflSize - offset;
@@ -67425,7 +68110,7 @@ static int accessPayload(
**
** 1) this is a read operation, and
** 2) data is required from the start of this overflow page, and
- ** 3) there is no open write-transaction, and
+ ** 3) there are no dirty pages in the page-cache
** 4) the database is file-backed, and
** 5) the page is not in the WAL file
** 6) at least 4 bytes have already been read into the output buffer
@@ -67436,11 +68121,10 @@ static int accessPayload(
*/
if( eOp==0 /* (1) */
&& offset==0 /* (2) */
- && pBt->inTransaction==TRANS_READ /* (3) */
- && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */
- && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */
+ && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */
&& &pBuf[-4]>=pBufStart /* (6) */
){
+ sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
u8 aSave[4];
u8 *aWrite = &pBuf[-4];
assert( aWrite>=pBufStart ); /* due to (6) */
@@ -67850,23 +68534,6 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
return rc;
}
-/*
-** This function is a no-op if cursor pCur does not point to a valid row.
-** Otherwise, if pCur is valid, configure it so that the next call to
-** sqlite3BtreeNext() is a no-op.
-*/
-#ifndef SQLITE_OMIT_WINDOWFUNC
-SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor *pCur){
- /* We believe that the cursor must always be in the valid state when
- ** this routine is called, but the proof is difficult, so we add an
- ** ALWaYS() test just in case we are wrong. */
- if( ALWAYS(pCur->eState==CURSOR_VALID) ){
- pCur->eState = CURSOR_SKIPNEXT;
- pCur->skipNext = 1;
- }
-}
-#endif /* SQLITE_OMIT_WINDOWFUNC */
-
/* 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.
@@ -67889,6 +68556,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
assert( pCur->ix==pCur->pPage->nCell-1 );
assert( pCur->pPage->leaf );
#endif
+ *pRes = 0;
return SQLITE_OK;
}
@@ -67974,7 +68642,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
** try to get there using sqlite3BtreeNext() rather than a full
** binary search. This is an optimization only. The correct answer
** is still obtained without this case, only a little more slowely */
- if( pCur->info.nKey+1==intKey && !pCur->skipNext ){
+ if( pCur->info.nKey+1==intKey ){
*pRes = 0;
rc = sqlite3BtreeNext(pCur, 0);
if( rc==SQLITE_OK ){
@@ -68110,29 +68778,31 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
** case this happens. */
void *pCellKey;
u8 * const pCellBody = pCell - pPage->childPtrSize;
+ const int nOverrun = 18; /* Size of the overrun padding */
pPage->xParseCell(pPage, pCellBody, &pCur->info);
nCell = (int)pCur->info.nKey;
testcase( nCell<0 ); /* True if key size is 2^32 or more */
testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
testcase( nCell==2 ); /* Minimum legal index key size */
- if( nCell<2 ){
+ if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){
rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_finish;
}
- pCellKey = sqlite3Malloc( nCell+18 );
+ pCellKey = sqlite3Malloc( nCell+nOverrun );
if( pCellKey==0 ){
rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
pCur->ix = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
+ memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */
pCur->curFlags &= ~BTCF_ValidOvfl;
if( rc ){
sqlite3_free(pCellKey);
goto moveto_finish;
}
- c = xRecordCompare(nCell, pCellKey, pIdxKey);
+ c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
sqlite3_free(pCellKey);
}
assert(
@@ -68248,7 +68918,6 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
MemPage *pPage;
assert( cursorOwnsBtShared(pCur) );
- assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
if( pCur->eState!=CURSOR_VALID ){
assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
rc = restoreCursorPosition(pCur);
@@ -68258,14 +68927,9 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
if( CURSOR_INVALID==pCur->eState ){
return SQLITE_DONE;
}
- if( pCur->skipNext ){
- assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+ if( pCur->eState==CURSOR_SKIPNEXT ){
pCur->eState = CURSOR_VALID;
- if( pCur->skipNext>0 ){
- pCur->skipNext = 0;
- return SQLITE_OK;
- }
- pCur->skipNext = 0;
+ if( pCur->skipNext>0 ) return SQLITE_OK;
}
}
@@ -68320,7 +68984,6 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){
UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */
assert( cursorOwnsBtShared(pCur) );
assert( flags==0 || flags==1 );
- assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
@@ -68361,7 +69024,6 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
MemPage *pPage;
assert( cursorOwnsBtShared(pCur) );
- assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
assert( pCur->info.nSize==0 );
if( pCur->eState!=CURSOR_VALID ){
@@ -68372,14 +69034,9 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
if( CURSOR_INVALID==pCur->eState ){
return SQLITE_DONE;
}
- if( pCur->skipNext ){
- assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+ if( CURSOR_SKIPNEXT==pCur->eState ){
pCur->eState = CURSOR_VALID;
- if( pCur->skipNext<0 ){
- pCur->skipNext = 0;
- return SQLITE_OK;
- }
- pCur->skipNext = 0;
+ if( pCur->skipNext<0 ) return SQLITE_OK;
}
}
@@ -68414,7 +69071,6 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){
assert( cursorOwnsBtShared(pCur) );
assert( flags==0 || flags==1 );
- assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
pCur->info.nSize = 0;
@@ -68750,7 +69406,7 @@ static int allocateBtreePage(
TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
}
- assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+ assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) );
end_allocate_page:
releasePage(pTrunk);
@@ -68778,13 +69434,15 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */
MemPage *pPage; /* Page being freed. May be NULL. */
int rc; /* Return Code */
- int nFree; /* Initial number of pages on free-list */
+ u32 nFree; /* Initial number of pages on free-list */
assert( sqlite3_mutex_held(pBt->mutex) );
assert( CORRUPT_DB || iPage>1 );
assert( !pMemPage || pMemPage->pgno==iPage );
- if( iPage<2 ) return SQLITE_CORRUPT_BKPT;
+ if( iPage<2 || iPage>pBt->nPage ){
+ return SQLITE_CORRUPT_BKPT;
+ }
if( pMemPage ){
pPage = pMemPage;
sqlite3PagerRef(pPage->pDbPage);
@@ -69195,6 +69853,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+ assert( pPage->nFree>=0 );
data = pPage->aData;
ptr = &pPage->aCellIdx[2*idx];
pc = get2byte(ptr);
@@ -69265,6 +69924,7 @@ static void insertCell(
** might be less than 8 (leaf-size + pointer) on the interior node. Hence
** the term after the || in the following assert(). */
assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) );
+ assert( pPage->nFree>=0 );
if( pPage->nOverflow || sz+2>pPage->nFree ){
if( pTemp ){
memcpy(pTemp, pCell, sz);
@@ -69305,9 +69965,16 @@ static void insertCell(
assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB );
assert( idx+sz <= (int)pPage->pBt->usableSize );
pPage->nFree -= (u16)(2 + sz);
- memcpy(&data[idx], pCell, sz);
if( iChild ){
+ /* In a corrupt database where an entry in the cell index section of
+ ** a btree page has a value of 3 or less, the pCell value might point
+ ** as many as 4 bytes in front of the start of the aData buffer for
+ ** the source page. Make sure this does not cause problems by not
+ ** reading the first 4 bytes */
+ memcpy(&data[idx+4], pCell+4, sz-4);
put4byte(&data[idx], iChild);
+ }else{
+ memcpy(&data[idx], pCell, sz);
}
pIns = pPage->aCellIdx + i*2;
memmove(pIns+2, pIns, 2*(pPage->nCell - i));
@@ -69315,21 +69982,100 @@ static void insertCell(
pPage->nCell++;
/* increment the cell count */
if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++;
- assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell );
+ assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB );
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pPage->pBt->autoVacuum ){
/* The cell may contain a pointer to an overflow page. If so, write
** the entry for the overflow page into the pointer map.
*/
- ptrmapPutOvflPtr(pPage, pCell, pRC);
+ ptrmapPutOvflPtr(pPage, pPage, pCell, pRC);
}
#endif
}
}
+/*
+** The following parameters determine how many adjacent pages get involved
+** in a balancing operation. NN is the number of neighbors on either side
+** of the page that participate in the balancing operation. NB is the
+** total number of pages that participate, including the target page and
+** NN neighbors on either side.
+**
+** The minimum value of NN is 1 (of course). Increasing NN above 1
+** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
+** in exchange for a larger degradation in INSERT and UPDATE performance.
+** The value of NN appears to give the best results overall.
+**
+** (Later:) The description above makes it seem as if these values are
+** tunable - as if you could change them and recompile and it would all work.
+** But that is unlikely. NB has been 3 since the inception of SQLite and
+** we have never tested any other value.
+*/
+#define NN 1 /* Number of neighbors on either side of pPage */
+#define NB 3 /* (NN*2+1): Total pages involved in the balance */
+
/*
** A CellArray object contains a cache of pointers and sizes for a
** consecutive sequence of cells that might be held on multiple pages.
+**
+** The cells in this array are the divider cell or cells from the pParent
+** page plus up to three child pages. There are a total of nCell cells.
+**
+** pRef is a pointer to one of the pages that contributes cells. This is
+** used to access information such as MemPage.intKey and MemPage.pBt->pageSize
+** which should be common to all pages that contribute cells to this array.
+**
+** apCell[] and szCell[] hold, respectively, pointers to the start of each
+** cell and the size of each cell. Some of the apCell[] pointers might refer
+** to overflow cells. In other words, some apCel[] pointers might not point
+** to content area of the pages.
+**
+** A szCell[] of zero means the size of that cell has not yet been computed.
+**
+** The cells come from as many as four different pages:
+**
+** -----------
+** | Parent |
+** -----------
+** / | \
+** / | \
+** --------- --------- ---------
+** |Child-1| |Child-2| |Child-3|
+** --------- --------- ---------
+**
+** The order of cells is in the array is for an index btree is:
+**
+** 1. All cells from Child-1 in order
+** 2. The first divider cell from Parent
+** 3. All cells from Child-2 in order
+** 4. The second divider cell from Parent
+** 5. All cells from Child-3 in order
+**
+** For a table-btree (with rowids) the items 2 and 4 are empty because
+** content exists only in leaves and there are no divider cells.
+**
+** For an index btree, the apEnd[] array holds pointer to the end of page
+** for Child-1, the Parent, Child-2, the Parent (again), and Child-3,
+** respectively. The ixNx[] array holds the number of cells contained in
+** each of these 5 stages, and all stages to the left. Hence:
+**
+** ixNx[0] = Number of cells in Child-1.
+** ixNx[1] = Number of cells in Child-1 plus 1 for first divider.
+** ixNx[2] = Number of cells in Child-1 and Child-2 + 1 for 1st divider.
+** ixNx[3] = Number of cells in Child-1 and Child-2 + both divider cells
+** ixNx[4] = Total number of cells.
+**
+** For a table-btree, the concept is similar, except only apEnd[0]..apEnd[2]
+** are used and they point to the leaf pages only, and the ixNx value are:
+**
+** ixNx[0] = Number of cells in Child-1.
+** ixNx[1] = Number of cells in Child-1 and Child-2.
+** ixNx[2] = Total number of cells.
+**
+** Sometimes when deleting, a child page can have zero cells. In those
+** cases, ixNx[] entries with higher indexes, and the corresponding apEnd[]
+** entries, shift down. The end result is that each ixNx[] entry should
+** be larger than the previous
*/
typedef struct CellArray CellArray;
struct CellArray {
@@ -69337,6 +70083,8 @@ struct CellArray {
MemPage *pRef; /* Reference page */
u8 **apCell; /* All cells begin balanced */
u16 *szCell; /* Local size of all cells in apCell[] */
+ u8 *apEnd[NB*2]; /* MemPage.aDataEnd values */
+ int ixNx[NB*2]; /* Index of at which we move to the next apEnd[] */
};
/*
@@ -69387,36 +70135,59 @@ static u16 cachedCellSize(CellArray *p, int N){
** responsibility of the caller to set it correctly.
*/
static int rebuildPage(
- MemPage *pPg, /* Edit this page */
+ CellArray *pCArray, /* Content to be added to page pPg */
+ int iFirst, /* First cell in pCArray to use */
int nCell, /* Final number of cells on page */
- u8 **apCell, /* Array of cells */
- u16 *szCell /* Array of cell sizes */
+ MemPage *pPg /* The page to be reconstructed */
){
const int hdr = pPg->hdrOffset; /* Offset of header on pPg */
u8 * const aData = pPg->aData; /* Pointer to data for pPg */
const int usableSize = pPg->pBt->usableSize;
u8 * const pEnd = &aData[usableSize];
- int i;
+ int i = iFirst; /* Which cell to copy from pCArray*/
+ u32 j; /* Start of cell content area */
+ int iEnd = i+nCell; /* Loop terminator */
u8 *pCellptr = pPg->aCellIdx;
u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
u8 *pData;
+ int k; /* Current slot in pCArray->apEnd[] */
+ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */
+
+ assert( i(u32)usableSize) ){ j = 0; }
+ memcpy(&pTmp[j], &aData[j], usableSize - j);
- i = get2byte(&aData[hdr+5]);
- memcpy(&pTmp[i], &aData[i], usableSize - i);
+ for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kapEnd[k];
pData = pEnd;
- for(i=0; iapCell[i];
+ u16 sz = pCArray->szCell[i];
+ assert( sz>0 );
if( SQLITE_WITHIN(pCell,aData,pEnd) ){
+ if( ((uptr)(pCell+sz))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT;
pCell = &pTmp[pCell - aData];
+ }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd
+ && (uptr)(pCell)<(uptr)pSrcEnd
+ ){
+ return SQLITE_CORRUPT_BKPT;
}
- pData -= szCell[i];
+
+ pData -= sz;
put2byte(pCellptr, (pData - aData));
pCellptr += 2;
if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
- memcpy(pData, pCell, szCell[i]);
- assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
- testcase( szCell[i]!=pPg->xCellSize(pPg,pCell) );
+ memcpy(pData, pCell, sz);
+ assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
+ testcase( sz!=pPg->xCellSize(pPg,pCell) );
+ i++;
+ if( i>=iEnd ) break;
+ if( pCArray->ixNx[k]<=i ){
+ k++;
+ pSrcEnd = pCArray->apEnd[k];
+ }
}
/* The pPg->nFree field is now set incorrectly. The caller will fix it. */
@@ -69431,12 +70202,11 @@ static int rebuildPage(
}
/*
-** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
-** contains the size in bytes of each such cell. This function attempts to
-** add the cells stored in the array to page pPg. If it cannot (because
-** the page needs to be defragmented before the cells will fit), non-zero
-** is returned. Otherwise, if the cells are added successfully, zero is
-** returned.
+** The pCArray objects contains pointers to b-tree cells and the cell sizes.
+** This function attempts to add the cells stored in the array to page pPg.
+** If it cannot (because the page needs to be defragmented before the cells
+** will fit), non-zero is returned. Otherwise, if the cells are added
+** successfully, zero is returned.
**
** Argument pCellptr points to the first entry in the cell-pointer array
** (part of page pPg) to populate. After cell apCell[0] is written to the
@@ -69458,18 +70228,23 @@ static int rebuildPage(
static int pageInsertArray(
MemPage *pPg, /* Page to add cells to */
u8 *pBegin, /* End of cell-pointer array */
- u8 **ppData, /* IN/OUT: Page content -area pointer */
+ u8 **ppData, /* IN/OUT: Page content-area pointer */
u8 *pCellptr, /* Pointer to cell-pointer area */
int iFirst, /* Index of first cell to add */
int nCell, /* Number of cells to add to pPg */
CellArray *pCArray /* Array of cells */
){
- int i;
- u8 *aData = pPg->aData;
- u8 *pData = *ppData;
- int iEnd = iFirst + nCell;
+ int i = iFirst; /* Loop counter - cell index to insert */
+ u8 *aData = pPg->aData; /* Complete page */
+ u8 *pData = *ppData; /* Content area. A subset of aData[] */
+ int iEnd = iFirst + nCell; /* End of loop. One past last cell to ins */
+ int k; /* Current slot in pCArray->apEnd[] */
+ u8 *pEnd; /* Maximum extent of cell data */
assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */
- for(i=iFirst; iixNx[k]<=i && ALWAYS(kapEnd[k];
+ while( 1 /*Exit by break*/ ){
int sz, rc;
u8 *pSlot;
sz = cachedCellSize(pCArray, i);
@@ -69484,20 +70259,33 @@ static int pageInsertArray(
assert( (pSlot+sz)<=pCArray->apCell[i]
|| pSlot>=(pCArray->apCell[i]+sz)
|| CORRUPT_DB );
+ if( (uptr)(pCArray->apCell[i]+sz)>(uptr)pEnd
+ && (uptr)(pCArray->apCell[i])<(uptr)pEnd
+ ){
+ assert( CORRUPT_DB );
+ (void)SQLITE_CORRUPT_BKPT;
+ return 1;
+ }
memmove(pSlot, pCArray->apCell[i], sz);
put2byte(pCellptr, (pSlot - aData));
pCellptr += 2;
+ i++;
+ if( i>=iEnd ) break;
+ if( pCArray->ixNx[k]<=i ){
+ k++;
+ pEnd = pCArray->apEnd[k];
+ }
}
*ppData = pData;
return 0;
}
/*
-** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
-** contains the size in bytes of each such cell. This function adds the
-** space associated with each cell in the array that is currently stored
-** within the body of pPg to the pPg free-list. The cell-pointers and other
-** fields of the page are not updated.
+** The pCArray object contains pointers to b-tree cells and their sizes.
+**
+** This function adds the space associated with each cell in the array
+** that is currently stored within the body of pPg to the pPg free-list.
+** The cell-pointers and other fields of the page are not updated.
**
** This function returns the total number of cells added to the free-list.
*/
@@ -69547,9 +70335,9 @@ static int pageFreeArray(
}
/*
-** apCell[] and szCell[] contains pointers to and sizes of all cells in the
-** pages being balanced. The current page, pPg, has pPg->nCell cells starting
-** with apCell[iOld]. After balancing, this page should hold nNew cells
+** pCArray contains pointers to and sizes of all cells in the page being
+** balanced. The current page, pPg, has pPg->nCell cells starting with
+** pCArray->apCell[iOld]. After balancing, this page should hold nNew cells
** starting at apCell[iNew].
**
** This routine makes the necessary adjustments to pPg so that it contains
@@ -69581,13 +70369,17 @@ static int editPage(
#endif
/* Remove cells from the start and end of the page */
+ assert( nCell>=0 );
if( iOldnCell ) return SQLITE_CORRUPT_BKPT;
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
nCell -= nShift;
}
if( iNewEnd < iOldEnd ){
- nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
+ int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
+ assert( nCell>=nTail );
+ nCell -= nTail;
}
pData = &aData[get2byteNotZero(&aData[hdr+5])];
@@ -69597,6 +70389,7 @@ static int editPage(
if( iNew=0 );
pCellptr = pPg->aCellIdx;
memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
if( pageInsertArray(
@@ -69611,7 +70404,9 @@ static int editPage(
int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
if( iCell>=0 && iCellaCellIdx[iCell * 2];
- memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
+ if( nCell>iCell ){
+ memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
+ }
nCell++;
if( pageInsertArray(
pPg, pBegin, &pData, pCellptr,
@@ -69621,6 +70416,7 @@ static int editPage(
}
/* Append cells to the end of the page */
+ assert( nCell>=0 );
pCellptr = &pPg->aCellIdx[nCell*2];
if( pageInsertArray(
pPg, pBegin, &pData, pCellptr,
@@ -69649,24 +70445,9 @@ static int editPage(
editpage_fail:
/* Unable to edit this page. Rebuild it from scratch instead. */
populateCellCache(pCArray, iNew, nNew);
- return rebuildPage(pPg, nNew, &pCArray->apCell[iNew], &pCArray->szCell[iNew]);
+ return rebuildPage(pCArray, iNew, nNew, pPg);
}
-/*
-** The following parameters determine how many adjacent pages get involved
-** in a balancing operation. NN is the number of neighbors on either side
-** of the page that participate in the balancing operation. NB is the
-** total number of pages that participate, including the target page and
-** NN neighbors on either side.
-**
-** The minimum value of NN is 1 (of course). Increasing NN above 1
-** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
-** in exchange for a larger degradation in INSERT and UPDATE performance.
-** The value of NN appears to give the best results overall.
-*/
-#define NN 1 /* Number of neighbors on either side of pPage */
-#define NB (NN*2+1) /* Total pages involved in the balance */
-
#ifndef SQLITE_OMIT_QUICKBALANCE
/*
@@ -69701,9 +70482,10 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
assert( pPage->nOverflow==1 );
-
- /* This error condition is now caught prior to reaching this function */
- if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT;
+
+ if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* dbfuzz001.test */
+ assert( pPage->nFree>=0 );
+ assert( pParent->nFree>=0 );
/* Allocate a new page. This page will become the right-sibling of
** pPage. Make the parent page writable, so that the new divider cell
@@ -69717,12 +70499,22 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
u8 *pCell = pPage->apOvfl[0];
u16 szCell = pPage->xCellSize(pPage, pCell);
u8 *pStop;
+ CellArray b;
assert( sqlite3PagerIswriteable(pNew->pDbPage) );
- assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
+ assert( CORRUPT_DB || pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
- rc = rebuildPage(pNew, 1, &pCell, &szCell);
- if( NEVER(rc) ) return rc;
+ b.nCell = 1;
+ b.pRef = pPage;
+ b.apCell = &pCell;
+ b.szCell = &szCell;
+ b.apEnd[0] = pPage->aDataEnd;
+ b.ixNx[0] = 2;
+ rc = rebuildPage(&b, 0, 1, pNew);
+ if( NEVER(rc) ){
+ releasePage(pNew);
+ return rc;
+ }
pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
/* If this is an auto-vacuum database, update the pointer map
@@ -69737,7 +70529,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
if( ISAUTOVACUUM ){
ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
if( szCell>pNew->minLocal ){
- ptrmapPutOvflPtr(pNew, pCell, &rc);
+ ptrmapPutOvflPtr(pNew, pNew, pCell, &rc);
}
}
@@ -69863,6 +70655,7 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
*/
pTo->isInit = 0;
rc = btreeInitPage(pTo);
+ if( rc==SQLITE_OK ) rc = btreeComputeFreeSpace(pTo);
if( rc!=SQLITE_OK ){
*pRC = rc;
return;
@@ -69960,10 +70753,6 @@ static int balance_nonroot(
assert( sqlite3_mutex_held(pBt->mutex) );
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
-#if 0
- TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
-#endif
-
/* At this point pParent may have at most one overflow cell. And if
** this overflow cell is present, it must be the cell with
** index iParentIdx. This scenario comes about when this function
@@ -69975,6 +70764,7 @@ static int balance_nonroot(
if( !aOvflSpace ){
return SQLITE_NOMEM_BKPT;
}
+ assert( pParent->nFree>=0 );
/* Find the sibling pages to balance. Also locate the cells in pParent
** that divide the siblings. An attempt is made to find NN siblings on
@@ -70014,7 +70804,13 @@ static int balance_nonroot(
memset(apOld, 0, (i+1)*sizeof(MemPage*));
goto balance_cleanup;
}
- nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
+ if( apOld[i]->nFree<0 ){
+ rc = btreeComputeFreeSpace(apOld[i]);
+ if( rc ){
+ memset(apOld, 0, (i)*sizeof(MemPage*));
+ goto balance_cleanup;
+ }
+ }
if( (i--)==0 ) break;
if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){
@@ -70058,6 +70854,7 @@ static int balance_nonroot(
/* Make nMaxCells a multiple of 4 in order to preserve 8-byte
** alignment */
+ nMaxCells = nOld*(MX_CELL(pBt) + ArraySize(pParent->apOvfl));
nMaxCells = (nMaxCells + 3)&~3;
/*
@@ -70068,7 +70865,7 @@ static int balance_nonroot(
+ nMaxCells*sizeof(u16) /* b.szCell */
+ pBt->pageSize; /* aSpace1 */
- assert( szScratch<=6*(int)pBt->pageSize );
+ assert( szScratch<=7*(int)pBt->pageSize );
b.apCell = sqlite3StackAllocRaw(0, szScratch );
if( b.apCell==0 ){
rc = SQLITE_NOMEM_BKPT;
@@ -70104,6 +70901,7 @@ static int balance_nonroot(
u16 maskPage = pOld->maskPage;
u8 *piCell = aData + pOld->cellOffset;
u8 *piEnd;
+ VVA_ONLY( int nCellAtStart = b.nCell; )
/* Verify that all sibling pages are of the same "type" (table-leaf,
** table-interior, index-leaf, or index-interior).
@@ -70132,6 +70930,10 @@ static int balance_nonroot(
*/
memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow));
if( pOld->nOverflow>0 ){
+ if( limitaiOvfl[0] ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto balance_cleanup;
+ }
limit = pOld->aiOvfl[0];
for(j=0; jnCell+pOld->nOverflow) );
cntOld[i] = b.nCell;
if( iusableSize - 12 + leafCorrection;
- for(i=0; iaDataEnd;
+ b.ixNx[k] = cntOld[i];
+ if( k && b.ixNx[k]==b.ixNx[k-1] ){
+ k--; /* Omit b.ixNx[] entry for child pages with no cells */
+ }
+ if( !leafData ){
+ k++;
+ b.apEnd[k] = pParent->aDataEnd;
+ b.ixNx[k] = cntOld[i]+1;
+ }
+ assert( p->nFree>=0 );
szNew[i] = usableSpace - p->nFree;
for(j=0; jnOverflow; j++){
szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]);
@@ -70429,19 +71243,20 @@ static int balance_nonroot(
** populated, not here.
*/
if( ISAUTOVACUUM ){
- MemPage *pNew = apNew[0];
- u8 *aOld = pNew->aData;
+ MemPage *pOld;
+ MemPage *pNew = pOld = apNew[0];
int cntOldNext = pNew->nCell + pNew->nOverflow;
- int usableSize = pBt->usableSize;
int iNew = 0;
int iOld = 0;
for(i=0; i=0 && iOldnCell + pOld->nOverflow + !leafData;
- aOld = pOld->aData;
}
if( i==cntNew[iNew] ){
pNew = apNew[++iNew];
@@ -70456,13 +71271,13 @@ static int balance_nonroot(
** overflow cell), we can skip updating the pointer map entries. */
if( iOld>=nNew
|| pNew->pgno!=aPgno[iOld]
- || !SQLITE_WITHIN(pCell,aOld,&aOld[usableSize])
+ || !SQLITE_WITHIN(pCell,pOld->aData,pOld->aDataEnd)
){
if( !leafCorrection ){
ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
}
if( cachedCellSize(&b,i)>pNew->minLocal ){
- ptrmapPutOvflPtr(pNew, pCell, &rc);
+ ptrmapPutOvflPtr(pNew, pOld, pCell, &rc);
}
if( rc ) goto balance_cleanup;
}
@@ -70607,7 +71422,8 @@ static int balance_nonroot(
rc = defragmentPage(apNew[0], -1);
testcase( rc!=SQLITE_OK );
assert( apNew[0]->nFree ==
- (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
+ (get2byteNotZero(&apNew[0]->aData[5]) - apNew[0]->cellOffset
+ - apNew[0]->nCell*2)
|| rc!=SQLITE_OK
);
copyNodeContent(apNew[0], pParent, &rc);
@@ -70706,7 +71522,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
}
assert( sqlite3PagerIswriteable(pChild->pDbPage) );
assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
- assert( pChild->nCell==pRoot->nCell );
+ assert( pChild->nCell==pRoot->nCell || CORRUPT_DB );
TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno));
@@ -70748,6 +71564,7 @@ static int balance(BtCursor *pCur){
int iPage = pCur->iPage;
MemPage *pPage = pCur->pPage;
+ if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
if( iPage==0 ){
if( pPage->nOverflow ){
/* The root page of the b-tree is overfull. In this case call the
@@ -70776,6 +71593,9 @@ static int balance(BtCursor *pCur){
int const iIdx = pCur->aiIdx[iPage-1];
rc = sqlite3PagerWrite(pParent->pDbPage);
+ if( rc==SQLITE_OK && pParent->nFree<0 ){
+ rc = btreeComputeFreeSpace(pParent);
+ }
if( rc==SQLITE_OK ){
#ifndef SQLITE_OMIT_QUICKBALANCE
if( pPage->intKeyLeaf
@@ -70886,7 +71706,11 @@ static int btreeOverwriteContent(
if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){
int rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ) return rc;
- memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt);
+ /* In a corrupt database, it is possible for the source and destination
+ ** buffers to overlap. This is harmless since the database is already
+ ** corrupt but it does cause valgrind and ASAN warnings. So use
+ ** memmove(). */
+ memmove(pDest, ((u8*)pX->pData) + iOffset, iAmt);
}
}
return SQLITE_OK;
@@ -71118,6 +71942,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
pPage = pCur->pPage;
assert( pPage->intKey || pX->nKey>=0 );
assert( pPage->leaf || !pPage->intKey );
+ if( pPage->nFree<0 ){
+ rc = btreeComputeFreeSpace(pPage);
+ if( rc ) return rc;
+ }
TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
@@ -71260,14 +72088,18 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
assert( pCur->curFlags & BTCF_WriteFlag );
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
- assert( pCur->ixpPage->nCell );
- assert( pCur->eState==CURSOR_VALID );
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
+ if( pCur->eState==CURSOR_REQUIRESEEK ){
+ rc = btreeRestoreCursorPosition(pCur);
+ if( rc ) return rc;
+ }
+ assert( pCur->eState==CURSOR_VALID );
iCellDepth = pCur->iPage;
iCellIdx = pCur->ix;
pPage = pCur->pPage;
pCell = findCell(pPage, iCellIdx);
+ if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ) return SQLITE_CORRUPT;
/* If the bPreserve flag is set to true, then the cursor position must
** be preserved following this delete operation. If the current delete
@@ -71281,6 +72113,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
if( bPreserve ){
if( !pPage->leaf
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
+ || pPage->nCell==1 /* See dbfuzz001.test for a test case */
){
/* A b-tree rebalance will be required after deleting this entry.
** Save the cursor key. */
@@ -71337,6 +72170,10 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
Pgno n;
unsigned char *pTmp;
+ if( pLeaf->nFree<0 ){
+ rc = btreeComputeFreeSpace(pLeaf);
+ if( rc ) return rc;
+ }
if( iCellDepthiPage-1 ){
n = pCur->apPage[iCellDepth+1]->pgno;
}else{
@@ -71695,6 +72532,9 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
assert( sqlite3BtreeHoldsMutex(p) );
assert( p->inTrans==TRANS_WRITE );
assert( iTable>=2 );
+ if( iTable>btreePagecount(pBt) ){
+ return SQLITE_CORRUPT_BKPT;
+ }
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
if( rc ) return rc;
@@ -72043,10 +72883,10 @@ static void checkList(
IntegrityCk *pCheck, /* Integrity checking context */
int isFreeList, /* True for a freelist. False for overflow page list */
int iPage, /* Page number for first page in the list */
- int N /* Expected number of pages in the list */
+ u32 N /* Expected number of pages in the list */
){
int i;
- int expected = N;
+ u32 expected = N;
int nErrAtStart = pCheck->nErr;
while( iPage!=0 && pCheck->mxErr ){
DbPage *pOvflPage;
@@ -72059,18 +72899,18 @@ static void checkList(
}
pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
if( isFreeList ){
- int n = get4byte(&pOvflData[4]);
+ u32 n = (u32)get4byte(&pOvflData[4]);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pCheck->pBt->autoVacuum ){
checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
}
#endif
- if( n>(int)pCheck->pBt->usableSize/4-2 ){
+ if( n>pCheck->pBt->usableSize/4-2 ){
checkAppendMsg(pCheck,
"freelist leaf count too big on page %d", iPage);
N--;
}else{
- for(i=0; ipBt->autoVacuum ){
@@ -72228,6 +73068,11 @@ static int checkTreePage(
"btreeInitPage() returns error code %d", rc);
goto end_of_check;
}
+ if( (rc = btreeComputeFreeSpace(pPage))!=0 ){
+ assert( rc==SQLITE_CORRUPT );
+ checkAppendMsg(pCheck, "free space corruption", rc);
+ goto end_of_check;
+ }
data = pPage->aData;
hdr = pPage->hdrOffset;
@@ -72300,7 +73145,7 @@ static int checkTreePage(
/* Check the content overflow list */
if( info.nPayload>info.nLocal ){
- int nPage; /* Number of pages on the overflow chain */
+ u32 nPage; /* Number of pages on the overflow chain */
Pgno pgnoOvfl; /* First page of the overflow chain */
assert( pc + info.nSize - 4 <= usableSize );
nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4);
@@ -72360,9 +73205,9 @@ static int checkTreePage(
i = get2byte(&data[hdr+1]);
while( i>0 ){
int size, j;
- assert( (u32)i<=usableSize-4 ); /* Enforced by btreeInitPage() */
+ assert( (u32)i<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */
size = get2byte(&data[i+2]);
- assert( (u32)(i+size)<=usableSize ); /* Enforced by btreeInitPage() */
+ assert( (u32)(i+size)<=usableSize ); /* due to btreeComputeFreeSpace() */
btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1));
/* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
** big-endian integer which is the offset in the b-tree page of the next
@@ -72371,8 +73216,8 @@ static int checkTreePage(
j = get2byte(&data[i]);
/* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
** increasing offset. */
- assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */
- assert( (u32)j<=usableSize-4 ); /* Enforced by btreeInitPage() */
+ assert( j==0 || j>i+size ); /* Enforced by btreeComputeFreeSpace() */
+ assert( (u32)j<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */
i = j;
}
/* Analyze the min-heap looking for overlap between cells and/or
@@ -72447,7 +73292,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
Pgno i;
IntegrityCk sCheck;
BtShared *pBt = p->pBt;
- int savedDbFlags = pBt->db->flags;
+ u64 savedDbFlags = pBt->db->flags;
char zErr[100];
VVA_ONLY( int nRef );
@@ -72514,7 +73359,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
}
#endif
testcase( pBt->db->flags & SQLITE_CellSizeCk );
- pBt->db->flags &= ~SQLITE_CellSizeCk;
+ pBt->db->flags &= ~(u64)SQLITE_CellSizeCk;
for(i=0; (int)iflags & MEM_Dyn)==0 || p->szMalloc==0 );
- /* Cannot be both MEM_Int and MEM_Real at the same time */
- assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+ /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */
+ assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) );
if( p->flags & MEM_Null ){
/* Cannot be both MEM_Null and some other type */
@@ -73716,7 +74566,7 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
/* No other bits set */
- assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
+ assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind
|MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
}else{
/* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
@@ -73751,9 +74601,31 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
}
#endif
+/*
+** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal
+** into a buffer.
+*/
+static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
+ StrAccum acc;
+ assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) );
+ sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
+ if( p->flags & MEM_Int ){
+ sqlite3_str_appendf(&acc, "%lld", p->u.i);
+ }else if( p->flags & MEM_IntReal ){
+ sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i);
+ }else{
+ sqlite3_str_appendf(&acc, "%!.15g", p->u.r);
+ }
+ assert( acc.zText==zBuf && acc.mxAlloc<=0 );
+ zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
+}
+
#ifdef SQLITE_DEBUG
/*
-** Check that string value of pMem agrees with its integer or real value.
+** Validity checks on pMem. pMem holds a string.
+**
+** (1) Check that string value of pMem agrees with its integer or real value.
+** (2) Check that the string is correctly zero terminated
**
** A single int or real value always converts to the same strings. But
** many different strings can be converted into the same int or real.
@@ -73771,17 +74643,24 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
**
** This routine is for use inside of assert() statements only.
*/
-SQLITE_PRIVATE int sqlite3VdbeMemConsistentDualRep(Mem *p){
+SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){
char zBuf[100];
char *z;
int i, j, incr;
if( (p->flags & MEM_Str)==0 ) return 1;
- if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
- if( p->flags & MEM_Int ){
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
- }else{
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r);
- }
+ if( p->flags & MEM_Term ){
+ /* Insure that the string is properly zero-terminated. Pay particular
+ ** attention to the case where p->n is odd */
+ if( p->szMalloc>0 && p->z==p->zMalloc ){
+ assert( p->enc==SQLITE_UTF8 || p->szMalloc >= ((p->n+1)&~1)+2 );
+ assert( p->enc!=SQLITE_UTF8 || p->szMalloc >= p->n+1 );
+ }
+ assert( p->z[p->n]==0 );
+ assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 );
+ assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 );
+ }
+ if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
+ vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
z = p->z;
i = j = 0;
incr = 1;
@@ -73837,8 +74716,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
}
/*
-** Make sure pMem->z points to a writable allocation of at least
-** min(n,32) bytes.
+** Make sure pMem->z points to a writable allocation of at least n bytes.
**
** If the bPreserve argument is true, then copy of the content of
** pMem->z into the new allocation. pMem must be either a string or
@@ -73857,7 +74735,6 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
assert( pMem->szMalloc==0
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
- if( n<32 ) n = 32;
if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
bPreserve = 0;
@@ -73895,34 +74772,40 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
**
** Any prior string or blob content in the pMem object may be discarded.
** The pMem->xDel destructor is called, if it exists. Though MEM_Str
-** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
-** values are preserved.
+** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal,
+** and MEM_Null values are preserved.
**
** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
** if unable to complete the resizing.
*/
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
- assert( szNew>0 );
+ assert( CORRUPT_DB || szNew>0 );
assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
if( pMem->szMallocflags & MEM_Dyn)==0 );
pMem->z = pMem->zMalloc;
- pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
+ pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal);
return SQLITE_OK;
}
/*
** It is already known that pMem contains an unterminated string.
** Add the zero terminator.
+**
+** Three bytes of zero are added. In this way, there is guaranteed
+** to be a double-zero byte at an even byte boundary in order to
+** terminate a UTF16 string, even if the initial size of the buffer
+** is an odd number of bytes.
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
- if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
+ if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
+ pMem->z[pMem->n+2] = 0;
pMem->flags |= MEM_Term;
return SQLITE_OK;
}
@@ -73959,13 +74842,15 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
int nByte;
assert( pMem->flags & MEM_Zero );
- assert( pMem->flags&MEM_Blob );
+ assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) );
+ testcase( sqlite3_value_nochange(pMem) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
/* Set nByte to the number of bytes required to store the expanded blob. */
nByte = pMem->n + pMem->u.nZero;
if( nByte<=0 ){
+ if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK;
nByte = 1;
}
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
@@ -73994,12 +74879,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
}
/*
-** Add MEM_Str to the set of representations for the given Mem. Numbers
-** are converted using sqlite3_snprintf(). Converting a BLOB to a string
-** is a no-op.
+** Add MEM_Str to the set of representations for the given Mem. This
+** routine is only called if pMem is a number of some kind, not a NULL
+** or a BLOB.
**
-** Existing representations MEM_Int and MEM_Real are invalidated if
-** bForce is true but are retained if bForce is false.
+** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated
+** if bForce is true but are retained if bForce is false.
**
** A MEM_Null value will never be passed to this function. This function is
** used for converting values to text for returning to the user (i.e. via
@@ -74008,13 +74893,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
** user and the latter is an internal programming error.
*/
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
- int fg = pMem->flags;
const int nByte = 32;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( !(fg&MEM_Zero) );
- assert( !(fg&(MEM_Str|MEM_Blob)) );
- assert( fg&(MEM_Int|MEM_Real) );
+ assert( !(pMem->flags&MEM_Zero) );
+ assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
+ assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
assert( !sqlite3VdbeMemIsRowSet(pMem) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
@@ -74024,22 +74908,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
return SQLITE_NOMEM_BKPT;
}
- /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
- ** string representation of the value. Then, if the required encoding
- ** is UTF-16le or UTF-16be do a translation.
- **
- ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
- */
- if( fg & MEM_Int ){
- sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
- }else{
- assert( fg & MEM_Real );
- sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
- }
- pMem->n = sqlite3Strlen30(pMem->z);
+ vdbeMemRenderNum(nByte, pMem->z, pMem);
+ assert( pMem->z!=0 );
+ pMem->n = sqlite3Strlen30NN(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
- if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
+ if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
sqlite3VdbeChangeEncoding(pMem, enc);
return SQLITE_OK;
}
@@ -74213,7 +75087,8 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
flags = pMem->flags;
- if( flags & MEM_Int ){
+ if( flags & (MEM_Int|MEM_IntReal) ){
+ testcase( flags & MEM_IntReal );
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->u.r);
@@ -74242,7 +75117,8 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
if( pMem->flags & MEM_Real ){
return pMem->u.r;
- }else if( pMem->flags & MEM_Int ){
+ }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
+ testcase( pMem->flags & MEM_IntReal );
return (double)pMem->u.i;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
return memRealValue(pMem);
@@ -74257,7 +75133,8 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
** Return the value ifNull if pMem is NULL.
*/
SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
- if( pMem->flags & MEM_Int ) return pMem->u.i!=0;
+ testcase( pMem->flags & MEM_IntReal );
+ if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0;
if( pMem->flags & MEM_Null ) return ifNull;
return sqlite3VdbeRealValue(pMem)!=0.0;
}
@@ -74320,17 +75197,21 @@ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
/* Compare a floating point value to an integer. Return true if the two
** values are the same within the precision of the floating point value.
**
+** This function assumes that i was obtained by assignment from r1.
+**
** For some versions of GCC on 32-bit machines, if you do the more obvious
** comparison of "r1==(double)i" you sometimes get an answer of false even
** though the r1 and (double)i values are bit-for-bit the same.
*/
-static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
+SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
double r2 = (double)i;
- return memcmp(&r1, &r2, sizeof(r1))==0;
+ return r1==0.0
+ || (memcmp(&r1, &r2, sizeof(r1))==0
+ && i >= -2251799813685248LL && i < 2251799813685248LL);
}
/*
-** Convert pMem so that it has types MEM_Real or MEM_Int or both.
+** Convert pMem so that it has type MEM_Real or MEM_Int.
** Invalidate any prior representations.
**
** Every effort is made to force the conversion, even if the input
@@ -74338,25 +75219,26 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
** as much of the string as we can and ignore the rest.
*/
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
- if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
+ testcase( pMem->flags & MEM_Int );
+ testcase( pMem->flags & MEM_Real );
+ testcase( pMem->flags & MEM_IntReal );
+ testcase( pMem->flags & MEM_Null );
+ if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
int rc;
+ sqlite3_int64 ix;
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
- if( rc==0 ){
+ rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
+ if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1)
+ || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r))
+ ){
+ pMem->u.i = ix;
MemSetTypeFlag(pMem, MEM_Int);
}else{
- i64 i = pMem->u.i;
- sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
- if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
- pMem->u.i = i;
- MemSetTypeFlag(pMem, MEM_Int);
- }else{
- MemSetTypeFlag(pMem, MEM_Real);
- }
+ MemSetTypeFlag(pMem, MEM_Real);
}
}
- assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
+ assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 );
pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
return SQLITE_OK;
}
@@ -74399,7 +75281,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
- pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
+ pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
break;
}
}
@@ -74583,7 +75465,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
** dual type, are allowed, as long as the underlying value is the
** same. */
u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
- assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i );
+ assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
@@ -74705,7 +75587,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
assert( enc!=0 );
if( enc==SQLITE_UTF8 ){
nByte = 0x7fffffff & (int)strlen(z);
- if( nByte>iLimit ) nByte = iLimit+1;
}else{
for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
}
@@ -74717,29 +75598,30 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
** management (one of MEM_Dyn or MEM_Static).
*/
if( xDel==SQLITE_TRANSIENT ){
- int nAlloc = nByte;
+ u32 nAlloc = nByte;
if( flags&MEM_Term ){
nAlloc += (enc==SQLITE_UTF8?1:2);
}
if( nByte>iLimit ){
- return SQLITE_TOOBIG;
+ return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
}
testcase( nAlloc==0 );
testcase( nAlloc==31 );
testcase( nAlloc==32 );
- if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
+ if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
return SQLITE_NOMEM_BKPT;
}
memcpy(pMem->z, z, nAlloc);
- }else if( xDel==SQLITE_DYNAMIC ){
- sqlite3VdbeMemRelease(pMem);
- pMem->zMalloc = pMem->z = (char *)z;
- pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}else{
sqlite3VdbeMemRelease(pMem);
pMem->z = (char *)z;
- pMem->xDel = xDel;
- flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
+ if( xDel==SQLITE_DYNAMIC ){
+ pMem->zMalloc = pMem->z;
+ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
+ }else{
+ pMem->xDel = xDel;
+ flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
+ }
}
pMem->n = nByte;
@@ -74782,6 +75664,9 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
){
int rc;
pMem->flags = MEM_Null;
+ if( sqlite3BtreeMaxRecordSize(pCur)z);
if( rc==SQLITE_OK ){
@@ -74855,7 +75740,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
- assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+ assert( sqlite3VdbeMemValidStrRep(pVal) );
return pVal->z;
}else{
return 0;
@@ -74878,7 +75763,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( !sqlite3VdbeMemIsRowSet(pVal) );
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
- assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+ assert( sqlite3VdbeMemValidStrRep(pVal) );
return pVal->z;
}
if( pVal->flags&MEM_Null ){
@@ -75143,7 +76028,12 @@ static int valueFromExpr(
}else{
sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
}
- if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
+ assert( (pVal->flags & MEM_IntReal)==0 );
+ if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){
+ testcase( pVal->flags & MEM_Int );
+ testcase( pVal->flags & MEM_Real );
+ pVal->flags &= ~MEM_Str;
+ }
if( enc!=SQLITE_UTF8 ){
rc = sqlite3VdbeChangeEncoding(pVal, enc);
}
@@ -75166,7 +76056,7 @@ static int valueFromExpr(
}else if( op==TK_NULL ){
pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
- sqlite3VdbeMemNumerify(pVal);
+ sqlite3VdbeMemSetNull(pVal);
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
@@ -75188,9 +76078,11 @@ static int valueFromExpr(
}
#endif
else if( op==TK_TRUEFALSE ){
- pVal = valueNew(db, pCtx);
- pVal->flags = MEM_Int;
- pVal->u.i = pExpr->u.zToken[4]==0;
+ pVal = valueNew(db, pCtx);
+ if( pVal ){
+ pVal->flags = MEM_Int;
+ pVal->u.i = pExpr->u.zToken[4]==0;
+ }
}
*ppVal = pVal;
@@ -75583,7 +76475,7 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
pParse->pVdbe = p;
assert( pParse->aLabel==0 );
assert( pParse->nLabel==0 );
- assert( pParse->nOpAlloc==0 );
+ assert( p->nOpAlloc==0 );
assert( pParse->szOpAlloc==0 );
sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
return p;
@@ -75613,6 +76505,43 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlag
p->zSql = sqlite3DbStrNDup(p->db, z, n);
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Add a new element to the Vdbe->pDblStr list.
+*/
+SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3 *db, Vdbe *p, const char *z){
+ if( p ){
+ int n = sqlite3Strlen30(z);
+ DblquoteStr *pStr = sqlite3DbMallocRawNN(db,
+ sizeof(*pStr)+n+1-sizeof(pStr->z));
+ if( pStr ){
+ pStr->pNextStr = p->pDblStr;
+ p->pDblStr = pStr;
+ memcpy(pStr->z, z, n+1);
+ }
+ }
+}
+#endif
+
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** zId of length nId is a double-quoted identifier. Check to see if
+** that identifier is really used as a string literal.
+*/
+SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(
+ Vdbe *pVdbe, /* The prepared statement */
+ const char *zId /* The double-quoted identifier, already dequoted */
+){
+ DblquoteStr *pStr;
+ assert( zId!=0 );
+ if( pVdbe->pDblStr==0 ) return 0;
+ for(pStr=pVdbe->pDblStr; pStr; pStr=pStr->pNextStr){
+ if( strcmp(zId, pStr->z)==0 ) return 1;
+ }
+ return 0;
+}
+#endif
+
/*
** Swap all content between two VDBE structures.
*/
@@ -75632,6 +76561,11 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
zTmp = pA->zSql;
pA->zSql = pB->zSql;
pB->zSql = zTmp;
+#if 0
+ zTmp = pA->zNormSql;
+ pA->zNormSql = pB->zNormSql;
+ pB->zNormSql = zTmp;
+#endif
pB->expmask = pA->expmask;
pB->prepFlags = pA->prepFlags;
memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
@@ -75644,7 +76578,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
** to 1024/sizeof(Op).
**
** If an out-of-memory error occurs while resizing the array, return
-** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain
+** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
** unchanged (this is so that any opcodes already allocated can be
** correctly deallocated along with the rest of the Vdbe).
*/
@@ -75660,9 +76594,11 @@ static int growOpArray(Vdbe *v, int nOp){
** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
** size of the op array or add 1KB of space, whichever is smaller. */
#ifdef SQLITE_TEST_REALLOC_STRESS
- int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp);
+ sqlite3_int64 nNew = (v->nOpAlloc>=512 ? 2*(sqlite3_int64)v->nOpAlloc
+ : (sqlite3_int64)v->nOpAlloc+nOp);
#else
- int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
+ sqlite3_int64 nNew = (v->nOpAlloc ? 2*(sqlite3_int64)v->nOpAlloc
+ : (sqlite3_int64)(1024/sizeof(Op)));
UNUSED_PARAMETER(nOp);
#endif
@@ -75673,11 +76609,11 @@ static int growOpArray(Vdbe *v, int nOp){
}
assert( nOp<=(1024/sizeof(Op)) );
- assert( nNew>=(p->nOpAlloc+nOp) );
+ assert( nNew>=(v->nOpAlloc+nOp) );
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
if( pNew ){
p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
- p->nOpAlloc = p->szOpAlloc/sizeof(Op);
+ v->nOpAlloc = p->szOpAlloc/sizeof(Op);
v->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
@@ -75711,9 +76647,9 @@ static void test_addop_breakpoint(void){
** operand.
*/
static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
- assert( p->pParse->nOpAlloc<=p->nOp );
+ assert( p->nOpAlloc<=p->nOp );
if( growOpArray(p, 1) ) return 1;
- assert( p->pParse->nOpAlloc>p->nOp );
+ assert( p->nOpAlloc>p->nOp );
return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
}
SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
@@ -75723,7 +76659,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
i = p->nOp;
assert( p->magic==VDBE_MAGIC_INIT );
assert( op>=0 && op<0xff );
- if( p->pParse->nOpAlloc<=i ){
+ if( p->nOpAlloc<=i ){
return growOp3(p, op, p1, p2, p3);
}
p->nOp++;
@@ -75855,13 +76791,29 @@ SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){
}
/*
-** Add a new OP_Explain opcode.
+** Set a debugger breakpoint on the following routine in order to
+** monitor the EXPLAIN QUERY PLAN code generation.
+*/
+#if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
+ (void)z1;
+ (void)z2;
+}
+#endif
+
+/*
+** Add a new OP_ opcode.
**
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
*/
SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
- if( pParse->explain==2 ){
+#ifndef SQLITE_DEBUG
+ /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
+ ** But omit them (for performance) during production builds */
+ if( pParse->explain==2 )
+#endif
+ {
char *zMsg;
Vdbe *v;
va_list ap;
@@ -75873,7 +76825,10 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt
iThis = v->nOp;
sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
zMsg, P4_DYNAMIC);
- if( bPush) pParse->addrExplain = iThis;
+ sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z);
+ if( bPush){
+ pParse->addrExplain = iThis;
+ }
}
}
@@ -75881,6 +76836,7 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt
** Pop the EXPLAIN QUERY PLAN stack one level.
*/
SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){
+ sqlite3ExplainBreakpoint("POP", 0);
pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
}
#endif /* SQLITE_OMIT_EXPLAIN */
@@ -75945,21 +76901,22 @@ SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){
** The VDBE knows that a P2 value is a label because labels are
** always negative and P2 values are suppose to be non-negative.
** Hence, a negative P2 value is a label that has yet to be resolved.
+** (Later:) This is only true for opcodes that have the OPFLG_JUMP
+** property.
+**
+** Variable usage notes:
**
-** Zero is returned if a malloc() fails.
+** Parse.aLabel[x] Stores the address that the x-th label resolves
+** into. For testing (SQLITE_DEBUG), unresolved
+** labels stores -1, but that is not required.
+** Parse.nLabelAlloc Number of slots allocated to Parse.aLabel[]
+** Parse.nLabel The *negative* of the number of labels that have
+** been issued. The negative is stored because
+** that gives a performance improvement over storing
+** the equivalent positive value.
*/
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){
- Parse *p = v->pParse;
- int i = p->nLabel++;
- assert( v->magic==VDBE_MAGIC_INIT );
- if( (i & (i-1))==0 ){
- p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
- (i*2+1)*sizeof(p->aLabel[0]));
- }
- if( p->aLabel ){
- p->aLabel[i] = -1;
- }
- return ADDR(i);
+SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse *pParse){
+ return --pParse->nLabel;
}
/*
@@ -75967,18 +76924,35 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){
** be inserted. The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
+static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
+ int nNewSize = 10 - p->nLabel;
+ p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
+ nNewSize*sizeof(p->aLabel[0]));
+ if( p->aLabel==0 ){
+ p->nLabelAlloc = 0;
+ }else{
+#ifdef SQLITE_DEBUG
+ int i;
+ for(i=p->nLabelAlloc; iaLabel[i] = -1;
+#endif
+ p->nLabelAlloc = nNewSize;
+ p->aLabel[j] = v->nOp;
+ }
+}
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
Parse *p = v->pParse;
int j = ADDR(x);
assert( v->magic==VDBE_MAGIC_INIT );
- assert( jnLabel );
+ assert( j<-p->nLabel );
assert( j>=0 );
- if( p->aLabel ){
#ifdef SQLITE_DEBUG
- if( p->db->flags & SQLITE_VdbeAddopTrace ){
- printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
- }
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
+ }
#endif
+ if( p->nLabelAlloc + p->nLabel < 0 ){
+ resizeResolveLabel(p,v,j);
+ }else{
assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
p->aLabel[j] = v->nOp;
}
@@ -76094,6 +77068,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
int hasAbort = 0;
int hasFkCounter = 0;
int hasCreateTable = 0;
+ int hasCreateIndex = 0;
int hasInitCoroutine = 0;
Op *pOp;
VdbeOpIter sIter;
@@ -76103,13 +77078,23 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
while( (pOp = opIterNext(&sIter))!=0 ){
int opcode = pOp->opcode;
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
+ || opcode==OP_VDestroy
+ || (opcode==OP_Function0 && pOp->p4.pFunc->funcFlags&SQLITE_FUNC_INTERNAL)
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
- && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
+ && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
){
hasAbort = 1;
break;
}
if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
+ if( mayAbort ){
+ /* hasCreateIndex may also be set for some DELETE statements that use
+ ** OP_Clear. So this routine may end up returning true in the case
+ ** where a "DELETE FROM tbl" has a statement-journal but does not
+ ** require one. This is not so bad - it is an inefficiency, not a bug. */
+ if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1;
+ if( opcode==OP_Clear ) hasCreateIndex = 1;
+ }
if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
#ifndef SQLITE_OMIT_FOREIGN_KEY
if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
@@ -76125,7 +77110,8 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
** true for this case to prevent the assert() in the callers frame
** from failing. */
return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter
- || (hasCreateTable && hasInitCoroutine) );
+ || (hasCreateTable && hasInitCoroutine) || hasCreateIndex
+ );
}
#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
@@ -76253,7 +77239,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
** have non-negative values for P2. */
assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
- assert( ADDR(pOp->p2)nLabel );
+ assert( ADDR(pOp->p2)<-pParse->nLabel );
pOp->p2 = aLabel[ADDR(pOp->p2)];
}
break;
@@ -76292,7 +77278,7 @@ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
*/
#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
- assert( p->nOp + N <= p->pParse->nOpAlloc );
+ assert( p->nOp + N <= p->nOpAlloc );
}
#endif
@@ -76364,7 +77350,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(
VdbeOp *pOut, *pFirst;
assert( nOp>0 );
assert( p->magic==VDBE_MAGIC_INIT );
- if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
+ if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
return 0;
}
pFirst = pOut = &p->aOp[p->nOp];
@@ -76410,7 +77396,7 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus(
LogEst nEst, /* Estimated number of output rows */
const char *zName /* Name of table or index being scanned */
){
- int nByte = (p->nScan+1) * sizeof(ScanStatus);
+ sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus);
ScanStatus *aNew;
aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
if( aNew ){
@@ -76997,7 +77983,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
Mem *pMem = pOp->p4.pMem;
if( pMem->flags & MEM_Str ){
zP4 = pMem->z;
- }else if( pMem->flags & MEM_Int ){
+ }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
sqlite3_str_appendf(&x, "%lld", pMem->u.i);
}else if( pMem->flags & MEM_Real ){
sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
@@ -77531,9 +78517,9 @@ SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){
** of a ReusableSpace object by the allocSpace() routine below.
*/
struct ReusableSpace {
- u8 *pSpace; /* Available memory */
- int nFree; /* Bytes of available memory */
- int nNeeded; /* Total bytes that could not be allocated */
+ u8 *pSpace; /* Available memory */
+ sqlite3_int64 nFree; /* Bytes of available memory */
+ sqlite3_int64 nNeeded; /* Total bytes that could not be allocated */
};
/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
@@ -77553,7 +78539,7 @@ struct ReusableSpace {
static void *allocSpace(
struct ReusableSpace *p, /* Bulk memory available for allocation */
void *pBuf, /* Pointer to a prior allocation */
- int nByte /* Bytes of memory needed */
+ sqlite3_int64 nByte /* Bytes of memory needed */
){
assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
if( pBuf==0 ){
@@ -77686,19 +78672,27 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
** the leftover memory at the end of the opcode array. This can significantly
** reduce the amount of memory held by a prepared statement.
*/
- do {
- x.nNeeded = 0;
- p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
- p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
- p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
- p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+ x.nNeeded = 0;
+ p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem));
+ p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem));
+ p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*));
+ p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
- p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+ p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64));
#endif
- if( x.nNeeded==0 ) break;
+ if( x.nNeeded ){
x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
x.nFree = x.nNeeded;
- }while( !db->mallocFailed );
+ if( !db->mallocFailed ){
+ p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
+ p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
+ p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
+ p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+#endif
+ }
+ }
p->pVList = pParse->pVList;
pParse->pVList = 0;
@@ -78351,7 +79345,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
}
/* Check for immediate foreign key violations. */
- if( p->rc==SQLITE_OK ){
+ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
sqlite3VdbeCheckFk(p, 0);
}
@@ -78390,7 +79384,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
}else{
db->nDeferredCons = 0;
db->nDeferredImmCons = 0;
- db->flags &= ~SQLITE_DeferFKs;
+ db->flags &= ~(u64)SQLITE_DeferFKs;
sqlite3CommitInternalChanges(db);
}
}else{
@@ -78703,6 +79697,16 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
vdbeFreeOpArray(db, p->aOp, p->nOp);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
+#ifdef SQLITE_ENABLE_NORMALIZE
+ sqlite3DbFree(db, p->zNormSql);
+ {
+ DblquoteStr *pThis, *pNext;
+ for(pThis=p->pDblStr; pThis; pThis=pNext){
+ pNext = pThis->pNextStr;
+ sqlite3DbFree(db, pThis);
+ }
+ }
+#endif
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
{
int i;
@@ -78867,6 +79871,8 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
/*
** Return the serial-type for the value stored in pMem.
+**
+** This routine might convert a large MEM_IntReal value into MEM_Real.
*/
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
int flags = pMem->flags;
@@ -78877,11 +79883,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
*pLen = 0;
return 0;
}
- if( flags&MEM_Int ){
+ if( flags&(MEM_Int|MEM_IntReal) ){
/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
i64 i = pMem->u.i;
u64 u;
+ testcase( flags & MEM_Int );
+ testcase( flags & MEM_IntReal );
if( i<0 ){
u = ~i;
}else{
@@ -78901,6 +79909,15 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
if( u<=2147483647 ){ *pLen = 4; return 4; }
if( u<=MAX_6BYTE ){ *pLen = 6; return 5; }
*pLen = 8;
+ if( flags&MEM_IntReal ){
+ /* If the value is IntReal and is going to take up 8 bytes to store
+ ** as an integer, then we might as well make it an 8-byte floating
+ ** point value */
+ pMem->u.r = (double)pMem->u.i;
+ pMem->flags &= ~MEM_IntReal;
+ pMem->flags |= MEM_Real;
+ return 7;
+ }
return 6;
}
if( flags&MEM_Real ){
@@ -79074,7 +80091,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
** routine so that in most cases the overhead of moving the stack pointer
** is avoided.
*/
-static u32 SQLITE_NOINLINE serialGet(
+static u32 serialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
@@ -79106,7 +80123,7 @@ static u32 SQLITE_NOINLINE serialGet(
assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
swapMixedEndianFloat(x);
memcpy(&pMem->u.r, &x, sizeof(x));
- pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
+ pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real;
}
return 8;
}
@@ -79242,7 +80259,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
UnpackedRecord *p /* Populate this structure before returning. */
){
const unsigned char *aKey = (const unsigned char *)pKey;
- int d;
+ u32 d;
u32 idx; /* Offset in aKey[] to read from */
u16 u; /* Unsigned loop counter */
u32 szHdr;
@@ -79253,7 +80270,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
idx = getVarint32(aKey, szHdr);
d = szHdr;
u = 0;
- while( idx=p->nField ) break;
}
+ if( d>(u32)nKey && u ){
+ assert( CORRUPT_DB );
+ /* In a corrupt record entry, the last pMem might have been set up using
+ ** uninitialized memory. Overwrite its value with NULL, to prevent
+ ** warnings from MSAN. */
+ sqlite3VdbeMemSetNull(pMem-1);
+ }
assert( u<=pKeyInfo->nKeyField + 1 );
p->nField = u;
}
@@ -79331,8 +80355,8 @@ static int vdbeRecordCompareDebug(
** Use that approximation to avoid the more expensive call to
** sqlite3VdbeSerialTypeLen() in the common case.
*/
- if( d1+serial_type1+2>(u32)nKey1
- && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1
+ if( d1+(u64)serial_type1+2>(u64)nKey1
+ && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1
){
break;
}
@@ -79343,7 +80367,8 @@ static int vdbeRecordCompareDebug(
/* Do the comparison
*/
- rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
+ rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
+ pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0);
if( rc!=0 ){
assert( mem1.szMalloc==0 ); /* See comment below */
if( pKeyInfo->aSortOrder[i] ){
@@ -79548,8 +80573,13 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
/* At least one of the two values is a number
*/
- if( combined_flags&(MEM_Int|MEM_Real) ){
- if( (f1 & f2 & MEM_Int)!=0 ){
+ if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){
+ testcase( combined_flags & MEM_Int );
+ testcase( combined_flags & MEM_Real );
+ testcase( combined_flags & MEM_IntReal );
+ if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){
+ testcase( f1 & f2 & MEM_Int );
+ testcase( f1 & f2 & MEM_IntReal );
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return +1;
return 0;
@@ -79559,15 +80589,23 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
if( pMem1->u.r > pMem2->u.r ) return +1;
return 0;
}
- if( (f1&MEM_Int)!=0 ){
+ if( (f1&(MEM_Int|MEM_IntReal))!=0 ){
+ testcase( f1 & MEM_Int );
+ testcase( f1 & MEM_IntReal );
if( (f2&MEM_Real)!=0 ){
return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r);
+ }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
+ if( pMem1->u.i < pMem2->u.i ) return -1;
+ if( pMem1->u.i > pMem2->u.i ) return +1;
+ return 0;
}else{
return -1;
}
}
if( (f1&MEM_Real)!=0 ){
- if( (f2&MEM_Int)!=0 ){
+ if( (f2&(MEM_Int|MEM_IntReal))!=0 ){
+ testcase( f2 & MEM_Int );
+ testcase( f2 & MEM_IntReal );
return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r);
}else{
return -1;
@@ -79699,12 +80737,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
}else{
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
- if( d1>(unsigned)nKey1 ){
- pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
- return 0; /* Corruption */
- }
i = 0;
}
+ if( d1>(unsigned)nKey1 ){
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
+ return 0; /* Corruption */
+ }
VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField
@@ -79716,7 +80754,9 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
u32 serial_type;
/* RHS is an integer */
- if( pRhs->flags & MEM_Int ){
+ if( pRhs->flags & (MEM_Int|MEM_IntReal) ){
+ testcase( pRhs->flags & MEM_Int );
+ testcase( pRhs->flags & MEM_IntReal );
serial_type = aKey1[idx1];
testcase( serial_type==12 );
if( serial_type>=10 ){
@@ -79774,10 +80814,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
mem1.n = (serial_type - 12) / 2;
testcase( (d1+mem1.n)==(unsigned)nKey1 );
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
- if( (d1+mem1.n) > (unsigned)nKey1 ){
+ if( (d1+mem1.n) > (unsigned)nKey1
+ || (pKeyInfo = pPKey2->pKeyInfo)->nAllField<=i
+ ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
- }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){
+ }else if( pKeyInfo->aColl[i] ){
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
mem1.flags = MEM_Str;
@@ -80059,7 +81101,9 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
testcase( flags & MEM_Real );
testcase( flags & MEM_Null );
testcase( flags & MEM_Blob );
- if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
+ if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0
+ && p->pKeyInfo->aColl[0]==0
+ ){
assert( flags & MEM_Str );
return vdbeRecordCompareString;
}
@@ -80104,7 +81148,9 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
(void)getVarint32((u8*)m.z, szHdr);
testcase( szHdr==3 );
testcase( szHdr==m.n );
- if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
+ testcase( szHdr>0x7fffffff );
+ assert( m.n>=0 );
+ if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){
goto idx_rowid_corruption;
}
@@ -80475,14 +81521,16 @@ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
sqlite3_int64 iNow;
sqlite3_int64 iElapse;
assert( p->startTime>0 );
- assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 );
+ assert( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 );
assert( db->init.busy==0 );
assert( p->zSql!=0 );
sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
iElapse = (iNow - p->startTime)*1000000;
+#ifndef SQLITE_OMIT_DEPRECATED
if( db->xProfile ){
db->xProfile(db->pProfileArg, p->zSql, iElapse);
}
+#endif
if( db->mTrace & SQLITE_TRACE_PROFILE ){
db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
}
@@ -80645,39 +81693,86 @@ SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
*/
SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
- SQLITE_BLOB, /* 0x00 */
- SQLITE_NULL, /* 0x01 */
- SQLITE_TEXT, /* 0x02 */
- SQLITE_NULL, /* 0x03 */
- SQLITE_INTEGER, /* 0x04 */
- SQLITE_NULL, /* 0x05 */
- SQLITE_INTEGER, /* 0x06 */
- SQLITE_NULL, /* 0x07 */
- SQLITE_FLOAT, /* 0x08 */
- SQLITE_NULL, /* 0x09 */
- SQLITE_FLOAT, /* 0x0a */
- SQLITE_NULL, /* 0x0b */
- SQLITE_INTEGER, /* 0x0c */
- SQLITE_NULL, /* 0x0d */
- SQLITE_INTEGER, /* 0x0e */
- SQLITE_NULL, /* 0x0f */
- SQLITE_BLOB, /* 0x10 */
- SQLITE_NULL, /* 0x11 */
- SQLITE_TEXT, /* 0x12 */
- SQLITE_NULL, /* 0x13 */
- SQLITE_INTEGER, /* 0x14 */
- SQLITE_NULL, /* 0x15 */
- SQLITE_INTEGER, /* 0x16 */
- SQLITE_NULL, /* 0x17 */
- SQLITE_FLOAT, /* 0x18 */
- SQLITE_NULL, /* 0x19 */
- SQLITE_FLOAT, /* 0x1a */
- SQLITE_NULL, /* 0x1b */
- SQLITE_INTEGER, /* 0x1c */
- SQLITE_NULL, /* 0x1d */
- SQLITE_INTEGER, /* 0x1e */
- SQLITE_NULL, /* 0x1f */
+ SQLITE_BLOB, /* 0x00 (not possible) */
+ SQLITE_NULL, /* 0x01 NULL */
+ SQLITE_TEXT, /* 0x02 TEXT */
+ SQLITE_NULL, /* 0x03 (not possible) */
+ SQLITE_INTEGER, /* 0x04 INTEGER */
+ SQLITE_NULL, /* 0x05 (not possible) */
+ SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */
+ SQLITE_NULL, /* 0x07 (not possible) */
+ SQLITE_FLOAT, /* 0x08 FLOAT */
+ SQLITE_NULL, /* 0x09 (not possible) */
+ SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */
+ SQLITE_NULL, /* 0x0b (not possible) */
+ SQLITE_INTEGER, /* 0x0c (not possible) */
+ SQLITE_NULL, /* 0x0d (not possible) */
+ SQLITE_INTEGER, /* 0x0e (not possible) */
+ SQLITE_NULL, /* 0x0f (not possible) */
+ SQLITE_BLOB, /* 0x10 BLOB */
+ SQLITE_NULL, /* 0x11 (not possible) */
+ SQLITE_TEXT, /* 0x12 (not possible) */
+ SQLITE_NULL, /* 0x13 (not possible) */
+ SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */
+ SQLITE_NULL, /* 0x15 (not possible) */
+ SQLITE_INTEGER, /* 0x16 (not possible) */
+ SQLITE_NULL, /* 0x17 (not possible) */
+ SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */
+ SQLITE_NULL, /* 0x19 (not possible) */
+ SQLITE_FLOAT, /* 0x1a (not possible) */
+ SQLITE_NULL, /* 0x1b (not possible) */
+ SQLITE_INTEGER, /* 0x1c (not possible) */
+ SQLITE_NULL, /* 0x1d (not possible) */
+ SQLITE_INTEGER, /* 0x1e (not possible) */
+ SQLITE_NULL, /* 0x1f (not possible) */
+ SQLITE_FLOAT, /* 0x20 INTREAL */
+ SQLITE_NULL, /* 0x21 (not possible) */
+ SQLITE_TEXT, /* 0x22 INTREAL + TEXT */
+ SQLITE_NULL, /* 0x23 (not possible) */
+ SQLITE_FLOAT, /* 0x24 (not possible) */
+ SQLITE_NULL, /* 0x25 (not possible) */
+ SQLITE_FLOAT, /* 0x26 (not possible) */
+ SQLITE_NULL, /* 0x27 (not possible) */
+ SQLITE_FLOAT, /* 0x28 (not possible) */
+ SQLITE_NULL, /* 0x29 (not possible) */
+ SQLITE_FLOAT, /* 0x2a (not possible) */
+ SQLITE_NULL, /* 0x2b (not possible) */
+ SQLITE_FLOAT, /* 0x2c (not possible) */
+ SQLITE_NULL, /* 0x2d (not possible) */
+ SQLITE_FLOAT, /* 0x2e (not possible) */
+ SQLITE_NULL, /* 0x2f (not possible) */
+ SQLITE_BLOB, /* 0x30 (not possible) */
+ SQLITE_NULL, /* 0x31 (not possible) */
+ SQLITE_TEXT, /* 0x32 (not possible) */
+ SQLITE_NULL, /* 0x33 (not possible) */
+ SQLITE_FLOAT, /* 0x34 (not possible) */
+ SQLITE_NULL, /* 0x35 (not possible) */
+ SQLITE_FLOAT, /* 0x36 (not possible) */
+ SQLITE_NULL, /* 0x37 (not possible) */
+ SQLITE_FLOAT, /* 0x38 (not possible) */
+ SQLITE_NULL, /* 0x39 (not possible) */
+ SQLITE_FLOAT, /* 0x3a (not possible) */
+ SQLITE_NULL, /* 0x3b (not possible) */
+ SQLITE_FLOAT, /* 0x3c (not possible) */
+ SQLITE_NULL, /* 0x3d (not possible) */
+ SQLITE_FLOAT, /* 0x3e (not possible) */
+ SQLITE_NULL, /* 0x3f (not possible) */
};
+#ifdef SQLITE_DEBUG
+ {
+ int eType = SQLITE_BLOB;
+ if( pVal->flags & MEM_Null ){
+ eType = SQLITE_NULL;
+ }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){
+ eType = SQLITE_FLOAT;
+ }else if( pVal->flags & MEM_Int ){
+ eType = SQLITE_INTEGER;
+ }else if( pVal->flags & MEM_Str ){
+ eType = SQLITE_TEXT;
+ }
+ assert( eType == aType[pVal->flags&MEM_AffMask] );
+ }
+#endif
return aType[pVal->flags&MEM_AffMask];
}
@@ -80686,6 +81781,11 @@ SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
}
+/* Return true if a parameter value originated from an sqlite3_bind() */
+SQLITE_API int sqlite3_value_frombind(sqlite3_value *pVal){
+ return (pVal->flags&MEM_FromBind)!=0;
+}
+
/* Make a copy of an sqlite3_value object
*/
SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
@@ -80922,6 +82022,21 @@ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
sqlite3OomFault(pCtx->pOut->db);
}
+#ifndef SQLITE_UNTESTABLE
+/* Force the INT64 value currently stored as the result to be
+** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL
+** test-control.
+*/
+SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context *pCtx){
+ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+ if( pCtx->pOut->flags & MEM_Int ){
+ pCtx->pOut->flags &= ~MEM_Int;
+ pCtx->pOut->flags |= MEM_IntReal;
+ }
+}
+#endif
+
+
/*
** This function is called after a transaction has been committed. It
** invokes callbacks registered with sqlite3_wal_hook() as required.
@@ -80996,7 +82111,7 @@ static int sqlite3Step(Vdbe *p){
return SQLITE_NOMEM_BKPT;
}
- if( p->pc<=0 && p->expired ){
+ if( p->pc<0 && p->expired ){
p->rc = SQLITE_SCHEMA;
rc = SQLITE_ERROR;
goto end_of_step;
@@ -81015,7 +82130,7 @@ static int sqlite3Step(Vdbe *p){
);
#ifndef SQLITE_OMIT_TRACE
- if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0)
+ if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
&& !db->init.busy && p->zSql ){
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
}else{
@@ -81042,16 +82157,18 @@ static int sqlite3Step(Vdbe *p){
db->nVdbeExec--;
}
+ if( rc!=SQLITE_ROW ){
#ifndef SQLITE_OMIT_TRACE
- /* If the statement completed successfully, invoke the profile callback */
- if( rc!=SQLITE_ROW ) checkProfileCallback(db, p);
+ /* If the statement completed successfully, invoke the profile callback */
+ checkProfileCallback(db, p);
#endif
- if( rc==SQLITE_DONE && db->autoCommit ){
- assert( p->rc==SQLITE_OK );
- p->rc = doWalCallbacks(db);
- if( p->rc!=SQLITE_OK ){
- rc = SQLITE_ERROR;
+ if( rc==SQLITE_DONE && db->autoCommit ){
+ assert( p->rc==SQLITE_OK );
+ p->rc = doWalCallbacks(db);
+ if( p->rc!=SQLITE_OK ){
+ rc = SQLITE_ERROR;
+ }
}
}
@@ -81071,9 +82188,9 @@ static int sqlite3Step(Vdbe *p){
|| (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE
);
assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
- if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0
- && rc!=SQLITE_ROW
- && rc!=SQLITE_DONE
+ if( rc!=SQLITE_ROW
+ && rc!=SQLITE_DONE
+ && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0
){
/* If this statement was prepared using saved SQL and an
** error has occurred, then return the error code in p->rc to the
@@ -81529,10 +82646,10 @@ SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
** or a constant) then useTypes 2, 3, and 4 return NULL.
*/
static const void *columnName(
- sqlite3_stmt *pStmt,
- int N,
- const void *(*xFunc)(Mem*),
- int useType
+ sqlite3_stmt *pStmt, /* The statement */
+ int N, /* Which column to get the name for */
+ int useUtf16, /* True to return the name as UTF16 */
+ int useType /* What type of name */
){
const void *ret;
Vdbe *p;
@@ -81553,8 +82670,15 @@ static const void *columnName(
N += useType*n;
sqlite3_mutex_enter(db->mutex);
assert( db->mallocFailed==0 );
- ret = xFunc(&p->aColName[N]);
- /* A malloc may have failed inside of the xFunc() call. If this
+#ifndef SQLITE_OMIT_UTF16
+ if( useUtf16 ){
+ ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
+ }else
+#endif
+ {
+ ret = sqlite3_value_text((sqlite3_value*)&p->aColName[N]);
+ }
+ /* A malloc may have failed inside of the _text() call. If this
** is the case, clear the mallocFailed flag and return NULL.
*/
if( db->mallocFailed ){
@@ -81571,13 +82695,11 @@ static const void *columnName(
** statement pStmt.
*/
SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
+ return columnName(pStmt, N, 0, COLNAME_NAME);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
+ return columnName(pStmt, N, 1, COLNAME_NAME);
}
#endif
@@ -81596,13 +82718,11 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
** of the result set of SQL statement pStmt.
*/
SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
+ return columnName(pStmt, N, 0, COLNAME_DECLTYPE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
+ return columnName(pStmt, N, 1, COLNAME_DECLTYPE);
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_OMIT_DECLTYPE */
@@ -81614,13 +82734,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
** anything else which is not an unambiguous reference to a database column.
*/
SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
+ return columnName(pStmt, N, 0, COLNAME_DATABASE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
+ return columnName(pStmt, N, 1, COLNAME_DATABASE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -81630,13 +82748,11 @@ SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N
** anything else which is not an unambiguous reference to a database column.
*/
SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
+ return columnName(pStmt, N, 0, COLNAME_TABLE);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
+ return columnName(pStmt, N, 1, COLNAME_TABLE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -81646,13 +82762,11 @@ SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
** anything else which is not an unambiguous reference to a database column.
*/
SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
+ return columnName(pStmt, N, 0, COLNAME_COLUMN);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
+ return columnName(pStmt, N, 1, COLNAME_COLUMN);
}
#endif /* SQLITE_OMIT_UTF16 */
#endif /* SQLITE_ENABLE_COLUMN_METADATA */
@@ -81695,7 +82809,7 @@ static int vdbeUnbind(Vdbe *p, int i){
pVar = &p->aVar[i];
sqlite3VdbeMemRelease(pVar);
pVar->flags = MEM_Null;
- sqlite3Error(p->db, SQLITE_OK);
+ p->db->errCode = SQLITE_OK;
/* If the bit corresponding to this variable in Vdbe.expmask is set, then
** binding a new value to this variable invalidates the current query plan.
@@ -82020,6 +83134,14 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
}
+/*
+** Return 1 if the statement is an EXPLAIN and return 2 if the
+** statement is an EXPLAIN QUERY PLAN
+*/
+SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
+ return pStmt ? ((Vdbe*)pStmt)->explain : 0;
+}
+
/*
** Return true if the prepared statement is in need of being reset.
*/
@@ -82115,6 +83237,22 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
#endif
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Return the normalized SQL associated with a prepared statement.
+*/
+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
+ Vdbe *p = (Vdbe *)pStmt;
+ if( p==0 ) return 0;
+ if( p->zNormSql==0 && ALWAYS(p->zSql!=0) ){
+ sqlite3_mutex_enter(p->db->mutex);
+ p->zNormSql = sqlite3Normalize(p, p->zSql);
+ sqlite3_mutex_leave(p->db->mutex);
+ }
+ return p->zNormSql;
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
+
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/*
** Allocate and populate an UnpackedRecord structure based on the serialized
@@ -82185,7 +83323,9 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa
}else if( iIdx>=p->pUnpacked->nField ){
*ppValue = (sqlite3_value *)columnNullValue();
}else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
- if( pMem->flags & MEM_Int ){
+ if( pMem->flags & (MEM_Int|MEM_IntReal) ){
+ testcase( pMem->flags & MEM_Int );
+ testcase( pMem->flags & MEM_IntReal );
sqlite3VdbeMemRealify(pMem);
}
}
@@ -82504,7 +83644,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
pVar = &p->aVar[idx-1];
if( pVar->flags & MEM_Null ){
sqlite3_str_append(&out, "NULL", 4);
- }else if( pVar->flags & MEM_Int ){
+ }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){
sqlite3_str_appendf(&out, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
@@ -82693,12 +83833,20 @@ SQLITE_API int sqlite3_found_count = 0;
** feature is used for test suite validation only and does not appear an
** production builds.
**
-** M is an integer between 2 and 4. 2 indicates a ordinary two-way
-** branch (I=0 means fall through and I=1 means taken). 3 indicates
-** a 3-way branch where the third way is when one of the operands is
-** NULL. 4 indicates the OP_Jump instruction which has three destinations
-** depending on whether the first operand is less than, equal to, or greater
-** than the second.
+** M is the type of branch. I is the direction taken for this instance of
+** the branch.
+**
+** M: 2 - two-way branch (I=0: fall-thru 1: jump )
+** 3 - two-way + NULL (I=0: fall-thru 1: jump 2: NULL )
+** 4 - OP_Jump (I=0: jump p1 1: jump p2 2: jump p3)
+**
+** In other words, if M is 2, then I is either 0 (for fall-through) or
+** 1 (for when the branch is taken). If M is 3, the I is 0 for an
+** ordinary fall-through, I is 1 if the branch was taken, and I is 2
+** if the result of comparison is NULL. For M=3, I=2 the jump may or
+** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5.
+** When M is 4, that means that an OP_Jump is being run. I is 0, 1, or 2
+** depending on if the operands are less than, equal, or greater than.
**
** iSrcLine is the source code line (from the __LINE__ macro) that
** generated the VDBE instruction combined with flag bits. The source
@@ -82709,9 +83857,9 @@ SQLITE_API int sqlite3_found_count = 0;
** alternate branch are never taken. If a branch is never taken then
** flags should be 0x06 since only the fall-through approach is allowed.
**
-** Bit 0x04 of the flags indicates an OP_Jump opcode that is only
+** Bit 0x08 of the flags indicates an OP_Jump opcode that is only
** interested in equal or not-equal. In other words, I==0 and I==2
-** should be treated the same.
+** should be treated as equivalent
**
** Since only a line number is retained, not the filename, this macro
** only works for amalgamation builds. But that is ok, since these macros
@@ -82735,6 +83883,18 @@ SQLITE_API int sqlite3_found_count = 0;
mNever = iSrcLine >> 24;
assert( (I & mNever)==0 );
if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/
+ /* Invoke the branch coverage callback with three arguments:
+ ** iSrcLine - the line number of the VdbeCoverage() macro, with
+ ** flags removed.
+ ** I - Mask of bits 0x07 indicating which cases are are
+ ** fulfilled by this instance of the jump. 0x01 means
+ ** fall-thru, 0x02 means taken, 0x04 means NULL. Any
+ ** impossible cases (ex: if the comparison is never NULL)
+ ** are filled in automatically so that the coverage
+ ** measurement logic does not flag those impossible cases
+ ** as missed coverage.
+ ** M - Type of jump. Same as M argument above
+ */
I |= mNever;
if( M==2 ) I |= 0x04;
if( M==4 ){
@@ -82746,14 +83906,6 @@ SQLITE_API int sqlite3_found_count = 0;
}
#endif
-/*
-** Convert the given register into a string if it isn't one
-** already. Return non-zero if a malloc() fails.
-*/
-#define Stringify(P, enc) \
- if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
- { goto no_mem; }
-
/*
** An ephemeral string value (signified by the MEM_Ephem flag) contains
** a pointer to a dynamically allocated string where some other entity
@@ -82811,6 +83963,11 @@ static VdbeCursor *allocateCursor(
assert( iCur>=0 && iCurnCursor );
if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
+ /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
+ ** is clear. Otherwise, if this is an ephemeral cursor created by
+ ** OP_OpenDup, the cursor will not be closed and will still be part
+ ** of a BtShared.pCursor list. */
+ if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0;
sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
p->apCsr[iCur] = 0;
}
@@ -82830,6 +83987,21 @@ static VdbeCursor *allocateCursor(
return pCx;
}
+/*
+** The string in pRec is known to look like an integer and to have a
+** floating point value of rValue. Return true and set *piValue to the
+** integer value if the string is in range to be an integer. Otherwise,
+** return false.
+*/
+static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){
+ i64 iValue = (double)rValue;
+ if( sqlite3RealSameAsInt(rValue,iValue) ){
+ *piValue = iValue;
+ return 1;
+ }
+ return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc);
+}
+
/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information. In other words, if the string
@@ -82847,12 +84019,12 @@ static VdbeCursor *allocateCursor(
*/
static void applyNumericAffinity(Mem *pRec, int bTryForInt){
double rValue;
- i64 iValue;
u8 enc = pRec->enc;
- assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
- if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
- if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
- pRec->u.i = iValue;
+ int rc;
+ assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str );
+ rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc);
+ if( rc<=0 ) return;
+ if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){
pRec->flags |= MEM_Int;
}else{
pRec->u.r = rValue;
@@ -82906,11 +84078,14 @@ static void applyAffinity(
** there is already a string rep, but it is pointless to waste those
** CPU cycles. */
if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/
- if( (pRec->flags&(MEM_Real|MEM_Int)) ){
+ if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){
+ testcase( pRec->flags & MEM_Int );
+ testcase( pRec->flags & MEM_Real );
+ testcase( pRec->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pRec, enc, 1);
}
}
- pRec->flags &= ~(MEM_Real|MEM_Int);
+ pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal);
}
}
@@ -82949,12 +84124,21 @@ SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
** accordingly.
*/
static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
- assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
+ int rc;
+ sqlite3_int64 ix;
+ assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 );
assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
- if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
- return 0;
- }
- if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){
+ ExpandBlob(pMem);
+ rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
+ if( rc<=0 ){
+ if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){
+ pMem->u.i = ix;
+ return MEM_Int;
+ }else{
+ return MEM_Real;
+ }
+ }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){
+ pMem->u.i = ix;
return MEM_Int;
}
return MEM_Real;
@@ -82968,10 +84152,15 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
** But it does set pMem->u.r and pMem->u.i appropriately.
*/
static u16 numericType(Mem *pMem){
- if( pMem->flags & (MEM_Int|MEM_Real) ){
- return pMem->flags & (MEM_Int|MEM_Real);
+ if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){
+ testcase( pMem->flags & MEM_Int );
+ testcase( pMem->flags & MEM_Real );
+ testcase( pMem->flags & MEM_IntReal );
+ return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal);
}
if( pMem->flags & (MEM_Str|MEM_Blob) ){
+ testcase( pMem->flags & MEM_Str );
+ testcase( pMem->flags & MEM_Blob );
return computeNumericType(pMem);
}
return 0;
@@ -83067,6 +84256,8 @@ static void memTracePrint(Mem *p){
printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
printf(" si:%lld", p->u.i);
+ }else if( (p->flags & (MEM_IntReal))!=0 ){
+ printf(" ir:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -83276,6 +84467,15 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
sqlite3VdbeEnter(p);
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ if( db->xProgress ){
+ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
+ assert( 0 < db->nProgressOps );
+ nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
+ }else{
+ nProgressLimit = 0xffffffff;
+ }
+#endif
if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
** sqlite3_column_text16() failed. */
@@ -83289,15 +84489,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
db->busyHandler.nBusy = 0;
if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
sqlite3VdbeIOTraceSql(p);
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- if( db->xProgress ){
- u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
- assert( 0 < db->nProgressOps );
- nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
- }else{
- nProgressLimit = 0xffffffff;
- }
-#endif
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
if( p->pc==0
@@ -83473,10 +84664,11 @@ case OP_Goto: { /* jump */
** If the progress callback returns non-zero, exit the virtual machine with
** a return code SQLITE_ABORT.
*/
- if( nVmStep>=nProgressLimit && db->xProgress!=0 ){
+ while( nVmStep>=nProgressLimit && db->xProgress!=0 ){
assert( db->nProgressOps!=0 );
- nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
+ nProgressLimit += db->nProgressOps;
if( db->xProgress(db->pProgressArg) ){
+ nProgressLimit = 0xffffffff;
rc = SQLITE_INTERRUPT;
goto abort_due_to_error;
}
@@ -83755,6 +84947,7 @@ case OP_String8: { /* same as TK_STRING, out2 */
if( encoding!=SQLITE_UTF8 ){
rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG );
+ if( rc ) goto too_big;
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
assert( VdbeMemDynamic(pOut)==0 );
@@ -83767,7 +84960,6 @@ case OP_String8: { /* same as TK_STRING, out2 */
pOp->p4.z = pOut->z;
pOp->p1 = pOut->n;
}
- testcase( rc==SQLITE_TOOBIG );
#endif
if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
@@ -83889,7 +85081,10 @@ case OP_Variable: { /* out2 */
goto too_big;
}
pOut = &aMem[pOp->p2];
- sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
+ if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
+ memcpy(pOut, pVar, MEMCELLSIZE);
+ pOut->flags &= ~(MEM_Dyn|MEM_Ephem);
+ pOut->flags |= MEM_Static|MEM_FromBind;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -84022,18 +85217,6 @@ case OP_ResultRow: {
assert( pOp->p1>0 );
assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- /* Run the progress counter just before returning.
- */
- if( db->xProgress!=0
- && nVmStep>=nProgressLimit
- && db->xProgress(db->pProgressArg)!=0
- ){
- rc = SQLITE_INTERRUPT;
- goto abort_due_to_error;
- }
-#endif
-
/* If this statement has violated immediate foreign key constraints, do
** not return the number of rows modified. And do not RELEASE the statement
** transaction. It needs to be rolled back. */
@@ -84105,33 +85288,57 @@ case OP_ResultRow: {
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
- i64 nByte;
+ i64 nByte; /* Total size of the output string or blob */
+ u16 flags1; /* Initial flags for P1 */
+ u16 flags2; /* Initial flags for P2 */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
+ testcase( pIn1==pIn2 );
+ testcase( pOut==pIn2 );
assert( pIn1!=pOut );
- if( (pIn1->flags | pIn2->flags) & MEM_Null ){
+ flags1 = pIn1->flags;
+ testcase( flags1 & MEM_Null );
+ testcase( pIn2->flags & MEM_Null );
+ if( (flags1 | pIn2->flags) & MEM_Null ){
sqlite3VdbeMemSetNull(pOut);
break;
}
- if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
- Stringify(pIn1, encoding);
- Stringify(pIn2, encoding);
+ if( (flags1 & (MEM_Str|MEM_Blob))==0 ){
+ if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem;
+ flags1 = pIn1->flags & ~MEM_Str;
+ }else if( (flags1 & MEM_Zero)!=0 ){
+ if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem;
+ flags1 = pIn1->flags & ~MEM_Str;
+ }
+ flags2 = pIn2->flags;
+ if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
+ if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
+ flags2 = pIn2->flags & ~MEM_Str;
+ }else if( (flags2 & MEM_Zero)!=0 ){
+ if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
+ flags2 = pIn2->flags & ~MEM_Str;
+ }
nByte = pIn1->n + pIn2->n;
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){
goto no_mem;
}
MemSetTypeFlag(pOut, MEM_Str);
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
+ assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
+ pIn2->flags = flags2;
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
+ assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
+ pIn1->flags = flags1;
pOut->z[nByte]=0;
pOut->z[nByte+1] = 0;
+ pOut->z[nByte+2] = 0;
pOut->flags |= MEM_Term;
pOut->n = (int)nByte;
pOut->enc = encoding;
@@ -84182,7 +85389,6 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
- char bIntint; /* Started out as two integer operands */
u16 flags; /* Combined MEM_* flags from both inputs */
u16 type1; /* Numeric type of left operand */
u16 type2; /* Numeric type of right operand */
@@ -84200,7 +85406,6 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
if( (type1 & type2 & MEM_Int)!=0 ){
iA = pIn1->u.i;
iB = pIn2->u.i;
- bIntint = 1;
switch( pOp->opcode ){
case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break;
case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break;
@@ -84223,7 +85428,6 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
}else if( (flags & MEM_Null)!=0 ){
goto arithmetic_result_is_null;
}else{
- bIntint = 0;
fp_math:
rA = sqlite3VdbeRealValue(pIn1);
rB = sqlite3VdbeRealValue(pIn2);
@@ -84238,8 +85442,8 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
break;
}
default: {
- iA = (i64)rA;
- iB = (i64)rB;
+ iA = sqlite3VdbeIntValue(pIn1);
+ iB = sqlite3VdbeIntValue(pIn2);
if( iA==0 ) goto arithmetic_result_is_null;
if( iA==-1 ) iA = 1;
rB = (double)(iB % iA);
@@ -84255,9 +85459,6 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
}
pOut->u.r = rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
- sqlite3VdbeIntegerAffinity(pOut);
- }
#endif
}
break;
@@ -84399,8 +85600,8 @@ case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_Int)==0 ){
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
- VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
if( (pIn1->flags & MEM_Int)==0 ){
+ VdbeBranchTaken(1, 2);
if( pOp->p2==0 ){
rc = SQLITE_MISMATCH;
goto abort_due_to_error;
@@ -84409,6 +85610,7 @@ case OP_MustBeInt: { /* jump, in1 */
}
}
}
+ VdbeBranchTaken(0, 2);
MemSetTypeFlag(pIn1, MEM_Int);
break;
}
@@ -84425,7 +85627,9 @@ case OP_MustBeInt: { /* jump, in1 */
*/
case OP_RealAffinity: { /* in1 */
pIn1 = &aMem[pOp->p1];
- if( pIn1->flags & MEM_Int ){
+ if( pIn1->flags & (MEM_Int|MEM_IntReal) ){
+ testcase( pIn1->flags & MEM_Int );
+ testcase( pIn1->flags & MEM_IntReal );
sqlite3VdbeMemRealify(pIn1);
}
break;
@@ -84583,15 +85787,15 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** OP_Eq or OP_Ne) then take the jump or not depending on whether
** or not both operands are null.
*/
- assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
assert( (flags1 & MEM_Cleared)==0 );
- assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
+ assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
+ testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
if( (flags1&flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0
){
res = 0; /* Operands are equal */
}else{
- res = 1; /* Operands are not equal */
+ res = ((flags3 & MEM_Null) ? -1 : +1); /* Operands are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
@@ -84617,7 +85821,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
affinity = pOp->p5 & SQLITE_AFF_MASK;
if( affinity>=SQLITE_AFF_NUMERIC ){
if( (flags1 | flags3)&MEM_Str ){
- if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
assert( flags3==pIn3->flags );
/* testcase( flags3!=pIn3->flags );
@@ -84627,7 +85831,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** in case our analysis is incorrect, so it is left in. */
flags3 = pIn3->flags;
}
- if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
}
@@ -84640,17 +85844,19 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
goto compare_op;
}
}else if( affinity==SQLITE_AFF_TEXT ){
- if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
+ if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn1->flags & MEM_Int );
testcase( pIn1->flags & MEM_Real );
+ testcase( pIn1->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
assert( pIn1!=pIn3 );
}
- if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
+ if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_Real );
+ testcase( pIn3->flags & MEM_IntReal );
sqlite3VdbeMemStringify(pIn3, encoding, 1);
testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
@@ -84709,7 +85915,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
pOut->u.i = res2;
REGISTER_TRACE(pOp->p2, pOut);
}else{
- VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
+ VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
if( res2 ){
goto jump_to_p2;
}
@@ -85259,15 +86465,15 @@ case OP_Column: {
zEndHdr = zData + aOffset[0];
testcase( zHdr>=zEndHdr );
do{
- if( (t = zHdr[0])<0x80 ){
+ if( (pC->aType[i] = t = zHdr[0])<0x80 ){
zHdr++;
offset64 += sqlite3VdbeOneByteSerialTypeLen(t);
}else{
zHdr += sqlite3GetVarint32(zHdr, &t);
+ pC->aType[i] = t;
offset64 += sqlite3VdbeSerialTypeLen(t);
}
- pC->aType[i++] = t;
- aOffset[i] = (u32)(offset64 & 0xffffffff);
+ aOffset[++i] = (u32)(offset64 & 0xffffffff);
}while( i<=p2 && zHdrp2>0 );
assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
- do{
+ while( 1 /*edit-by-break*/ ){
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
assert( memIsValid(pIn1) );
- applyAffinity(pIn1, *(zAffinity++), encoding);
+ applyAffinity(pIn1, zAffinity[0], encoding);
+ if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
+ /* When applying REAL affinity, if the result is still MEM_Int,
+ ** indicate that REAL is actually desired */
+ pIn1->flags |= MEM_IntReal;
+ pIn1->flags &= ~MEM_Int;
+ }
+ REGISTER_TRACE((int)(pIn1-aMem), pIn1);
+ zAffinity++;
+ if( zAffinity[0]==0 ) break;
pIn1++;
- }while( zAffinity[0] );
+ }
break;
}
@@ -85432,7 +86647,6 @@ case OP_Affinity: {
** If P4 is NULL then all index fields have the affinity BLOB.
*/
case OP_MakeRecord: {
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
@@ -85445,9 +86659,9 @@ case OP_MakeRecord: {
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] header */
- int j; /* Space used in zNewRecord[] content */
u32 len; /* Length of a field */
+ u8 *zHdr; /* Where to write next byte of the header */
+ u8 *zPayload; /* Where to write next byte of the payload */
/* Assuming the record contains N fields, the record format looks
** like this:
@@ -85486,7 +86700,14 @@ case OP_MakeRecord: {
if( zAffinity ){
pRec = pData0;
do{
- applyAffinity(pRec++, *(zAffinity++), encoding);
+ applyAffinity(pRec, zAffinity[0], encoding);
+ if( zAffinity[0]==SQLITE_AFF_REAL && (pRec->flags & MEM_Int) ){
+ pRec->flags |= MEM_IntReal;
+ pRec->flags &= ~(MEM_Int);
+ }
+ REGISTER_TRACE((int)(pRec-aMem), pRec);
+ zAffinity++;
+ pRec++;
assert( zAffinity[0]==0 || pRec<=pLast );
}while( zAffinity[0] );
}
@@ -85554,46 +86775,54 @@ case OP_MakeRecord: {
if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
/* Make sure the output register has a buffer large enough to store
** the new record. The output register (pOp->p3) is not allowed to
** be one of the input registers (because the following call to
** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
*/
- if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
- goto no_mem;
+ if( nByte+nZero<=pOut->szMalloc ){
+ /* The output register is already large enough to hold the record.
+ ** No error checks or buffer enlargement is required */
+ pOut->z = pOut->zMalloc;
+ }else{
+ /* Need to make sure that the output is not too big and then enlarge
+ ** the output register to hold the full result */
+ if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ goto too_big;
+ }
+ if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
+ goto no_mem;
+ }
+ }
+ pOut->n = (int)nByte;
+ pOut->flags = MEM_Blob;
+ if( nZero ){
+ pOut->u.nZero = nZero;
+ pOut->flags |= MEM_Zero;
}
- zNewRecord = (u8 *)pOut->z;
+ UPDATE_MAX_BLOBSIZE(pOut);
+ zHdr = (u8 *)pOut->z;
+ zPayload = zHdr + nHdr;
/* Write the record */
- i = putVarint32(zNewRecord, nHdr);
- j = nHdr;
+ zHdr += putVarint32(zHdr, nHdr);
assert( pData0<=pLast );
pRec = pData0;
do{
serial_type = pRec->uTemp;
/* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
** additional varints, one per column. */
- i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
+ zHdr += putVarint32(zHdr, serial_type); /* serial type */
/* EVIDENCE-OF: R-64536-51728 The values for each column in the record
** immediately follow the header. */
- j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
+ zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
}while( (++pRec)<=pLast );
- assert( i==nHdr );
- assert( j==nByte );
+ assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
+ assert( nByte==(int)(zPayload - (u8*)pOut->z) );
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
- pOut->n = (int)nByte;
- pOut->flags = MEM_Blob;
- if( nZero ){
- pOut->u.nZero = nZero;
- pOut->flags |= MEM_Zero;
- }
REGISTER_TRACE(pOp->p3, pOut);
- UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -85623,8 +86852,9 @@ case OP_Count: { /* out2 */
/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
-** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
-** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
+** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN).
+** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE).
+** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK).
*/
case OP_Savepoint: {
int p1; /* Value of P1 operand */
@@ -85692,6 +86922,7 @@ case OP_Savepoint: {
}
}
}else{
+ assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK );
iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
@@ -85745,6 +86976,7 @@ case OP_Savepoint: {
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}else{
+ assert( p1==SAVEPOINT_RELEASE );
isSchemaChange = 0;
}
for(ii=0; iinDb; ii++){
@@ -85781,6 +87013,7 @@ case OP_Savepoint: {
db->nSavepoint--;
}
}else{
+ assert( p1==SAVEPOINT_ROLLBACK );
db->nDeferredCons = pSavepoint->nDeferredCons;
db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
@@ -86261,7 +87494,9 @@ case OP_OpenDup: {
pCx->isEphemeral = 1;
pCx->pKeyInfo = pOrig->pKeyInfo;
pCx->isTable = pOrig->isTable;
- rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR,
+ pCx->pgnoRoot = pOrig->pgnoRoot;
+ pCx->isOrdered = pOrig->isOrdered;
+ rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
pCx->pKeyInfo, pCx->uc.pCursor);
/* The sqlite3BtreeCursor() routine can only fail for the first cursor
** opened for a database. Since there is already an open cursor when this
@@ -86279,6 +87514,9 @@ case OP_OpenDup: {
** the main database is read-only. The ephemeral
** table is deleted automatically when the cursor is closed.
**
+** If the cursor P1 is already opened on an ephemeral table, the table
+** is cleared (all content is erased).
+**
** P2 is the number of columns in the ephemeral table.
** The cursor points to a BTree table if P4==0 and to a BTree index
** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
@@ -86310,41 +87548,55 @@ case OP_OpenEphemeral: {
SQLITE_OPEN_TRANSIENT_DB;
assert( pOp->p1>=0 );
assert( pOp->p2>=0 );
- pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
- pCx->isEphemeral = 1;
- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx,
- BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
- }
- if( rc==SQLITE_OK ){
- /* If a transient index is required, create it by calling
- ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
- ** opening it. If a transient table is required, just use the
- ** automatically created table with root-page 1 (an BLOB_INTKEY table).
- */
- if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
- int pgno;
- assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5);
- if( rc==SQLITE_OK ){
- assert( pgno==MASTER_ROOT+1 );
- assert( pKeyInfo->db==db );
- assert( pKeyInfo->enc==ENC(db) );
- rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR,
- pKeyInfo, pCx->uc.pCursor);
+ pCx = p->apCsr[pOp->p1];
+ if( pCx ){
+ /* If the ephermeral table is already open, erase all existing content
+ ** so that the table is empty again, rather than creating a new table. */
+ assert( pCx->isEphemeral );
+ pCx->seqCount = 0;
+ pCx->cacheStatus = CACHE_STALE;
+ if( pCx->pBtx ){
+ rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
+ }
+ }else{
+ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
+ if( pCx==0 ) goto no_mem;
+ pCx->isEphemeral = 1;
+ rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx,
+ BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,
+ vfsFlags);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
+ }
+ if( rc==SQLITE_OK ){
+ /* If a transient index is required, create it by calling
+ ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
+ ** opening it. If a transient table is required, just use the
+ ** automatically created table with root-page 1 (an BLOB_INTKEY table).
+ */
+ if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
+ assert( pOp->p4type==P4_KEYINFO );
+ rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
+ BTREE_BLOBKEY | pOp->p5);
+ if( rc==SQLITE_OK ){
+ assert( pCx->pgnoRoot==MASTER_ROOT+1 );
+ assert( pKeyInfo->db==db );
+ assert( pKeyInfo->enc==ENC(db) );
+ rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
+ pKeyInfo, pCx->uc.pCursor);
+ }
+ pCx->isTable = 0;
+ }else{
+ pCx->pgnoRoot = MASTER_ROOT;
+ rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
+ 0, pCx->uc.pCursor);
+ pCx->isTable = 1;
}
- pCx->isTable = 0;
- }else{
- rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
- 0, pCx->uc.pCursor);
- pCx->isTable = 1;
}
+ pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
}
if( rc ) goto abort_due_to_error;
- pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
+ pCx->nullRow = 1;
break;
}
@@ -86573,6 +87825,8 @@ case OP_SeekGT: { /* jump, in3, group */
pC->seekOp = pOp->opcode;
#endif
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
if( pC->isTable ){
/* The BTREE_SEEK_EQ flag is only set on index cursors */
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
@@ -86582,20 +87836,24 @@ case OP_SeekGT: { /* jump, in3, group */
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so convert it. */
pIn3 = &aMem[pOp->p3];
- if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+ if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3, 0);
}
iKey = sqlite3VdbeIntValue(pIn3);
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
- if( (pIn3->flags & MEM_Int)==0 ){
+ if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
if( (pIn3->flags & MEM_Real)==0 ){
- /* If the P3 value cannot be converted into any kind of a number,
- ** then the seek is not possible, so jump to P2 */
- VdbeBranchTaken(1,2); goto jump_to_p2;
- break;
- }
+ if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){
+ VdbeBranchTaken(1,2); goto jump_to_p2;
+ break;
+ }else{
+ rc = sqlite3BtreeLast(pC->uc.pCursor, &res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ goto seek_not_found;
+ }
+ }else
/* If the approximation iKey is larger than the actual real search
** term, substitute >= for > and < for <=. e.g. if the search term
@@ -86619,7 +87877,7 @@ case OP_SeekGT: { /* jump, in3, group */
assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
}
- }
+ }
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res);
pC->movetoTarget = iKey; /* Used by OP_Delete */
if( rc!=SQLITE_OK ){
@@ -86673,8 +87931,6 @@ case OP_SeekGT: { /* jump, in3, group */
goto seek_not_found;
}
}
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
@@ -86974,7 +88230,9 @@ case OP_SeekRowid: { /* jump, in3 */
u64 iKey;
pIn3 = &aMem[pOp->p3];
- if( (pIn3->flags & MEM_Int)==0 ){
+ testcase( pIn3->flags & MEM_Int );
+ testcase( pIn3->flags & MEM_IntReal );
+ if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
/* Make sure pIn3->u.i contains a valid integer representation of
** the key value, but do not change the datatype of the register, as
** other parts of the perpared statement might be depending on the
@@ -86994,7 +88252,7 @@ case OP_NotExists: /* jump, in3 */
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
#ifdef SQLITE_DEBUG
- pC->seekOp = OP_SeekRowid;
+ if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid;
#endif
assert( pC->isTable );
assert( pC->eCurType==CURTYPE_BTREE );
@@ -87212,14 +88470,7 @@ case OP_NewRowid: { /* out2 */
** This instruction only works on tables. The equivalent instruction
** for indices is OP_IdxInsert.
*/
-/* Opcode: InsertInt P1 P2 P3 P4 P5
-** Synopsis: intkey=P3 data=r[P2]
-**
-** This works exactly like OP_Insert except that the key is the
-** integer value P3, not the value of the integer stored in register P3.
-*/
-case OP_Insert:
-case OP_InsertInt: {
+case OP_Insert: {
Mem *pData; /* MEM cell holding data for the record to be inserted */
Mem *pKey; /* MEM cell holding key for the record */
VdbeCursor *pC; /* Cursor to table into which insert is written */
@@ -87240,16 +88491,11 @@ case OP_InsertInt: {
REGISTER_TRACE(pOp->p2, pData);
sqlite3VdbeIncrWriteCounter(p, pC);
- if( pOp->opcode==OP_Insert ){
- pKey = &aMem[pOp->p3];
- assert( pKey->flags & MEM_Int );
- assert( memIsValid(pKey) );
- REGISTER_TRACE(pOp->p3, pKey);
- x.nKey = pKey->u.i;
- }else{
- assert( pOp->opcode==OP_InsertInt );
- x.nKey = pOp->p3;
- }
+ pKey = &aMem[pOp->p3];
+ assert( pKey->flags & MEM_Int );
+ assert( memIsValid(pKey) );
+ REGISTER_TRACE(pOp->p3, pKey);
+ x.nKey = pKey->u.i;
if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
assert( pC->iDb>=0 );
@@ -87361,7 +88607,7 @@ case OP_Delete: {
** OP_Delete will have also set the pC->movetoTarget field to the rowid of
** the row that is being deleted */
i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor);
- assert( pC->movetoTarget==iKey );
+ assert( CORRUPT_DB || pC->movetoTarget==iKey );
}
#endif
@@ -87769,7 +89015,7 @@ case OP_Sort: { /* jump */
p->aCounter[SQLITE_STMTSTATUS_SORT]++;
/* Fall through into OP_Rewind */
}
-/* Opcode: Rewind P1 P2 * * P5
+/* Opcode: Rewind P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1
** will refer to the first entry in the database table or index.
@@ -87777,10 +89023,6 @@ case OP_Sort: { /* jump */
** If the table or index is not empty, fall through to the following
** instruction.
**
-** If P5 is non-zero and the table is not empty, then the "skip-next"
-** flag is set on the cursor so that the next OP_Next instruction
-** executed on it is a no-op.
-**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
** configured to use Next, not Prev.
@@ -87791,6 +89033,7 @@ case OP_Rewind: { /* jump */
int res;
assert( pOp->p1>=0 && pOp->p1nCursor );
+ assert( pOp->p5==0 );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
@@ -87805,9 +89048,6 @@ case OP_Rewind: { /* jump */
pCrsr = pC->uc.pCursor;
assert( pCrsr );
rc = sqlite3BtreeFirst(pCrsr, &res);
-#ifndef SQLITE_OMIT_WINDOWFUNC
- if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
-#endif
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
@@ -87902,7 +89142,7 @@ case OP_Next: /* jump */
assert( pOp->opcode!=OP_Next
|| pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
|| pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
- || pC->seekOp==OP_NullRow);
+ || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid);
assert( pOp->opcode!=OP_Prev
|| pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
|| pC->seekOp==OP_Last
@@ -88420,7 +89660,7 @@ case OP_ParseSchema: {
{
zMaster = MASTER_NAME;
initData.db = db;
- initData.iDb = pOp->p1;
+ initData.iDb = iDb;
initData.pzErrMsg = &p->zErrMsg;
initData.mInitFlags = 0;
zSql = sqlite3MPrintf(db,
@@ -88432,9 +89672,16 @@ case OP_ParseSchema: {
assert( db->init.busy==0 );
db->init.busy = 1;
initData.rc = SQLITE_OK;
+ initData.nInitRow = 0;
assert( !db->mallocFailed );
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
if( rc==SQLITE_OK ) rc = initData.rc;
+ if( rc==SQLITE_OK && initData.nInitRow==0 ){
+ /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse
+ ** at least one SQL statement. Any less than that indicates that
+ ** the sqlite_master table is corrupt. */
+ rc = SQLITE_CORRUPT_BKPT;
+ }
sqlite3DbFreeNN(db, zSql);
db->init.busy = 0;
}
@@ -88797,10 +90044,20 @@ case OP_Program: { /* jump */
p->nOp = pProgram->nOp;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0;
+#endif
+#ifdef SQLITE_DEBUG
+ /* Verify that second and subsequent executions of the same trigger do not
+ ** try to reuse register values from the first use. */
+ {
+ int i;
+ for(i=0; inMem; i++){
+ aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */
+ aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */
+ }
+ }
#endif
pOp = &aOp[-1];
-
- break;
+ goto check_for_interrupt;
}
/* Opcode: Param P1 P2 * * *
@@ -89172,6 +90429,7 @@ case OP_AggFinal: {
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pOp->p3 ){
+ memAboutToChange(p, &aMem[pOp->p3]);
rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
pMem = &aMem[pOp->p3];
}else
@@ -89336,14 +90594,19 @@ case OP_JournalMode: { /* out2 */
#endif /* SQLITE_OMIT_PRAGMA */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/* Opcode: Vacuum P1 * * * *
+/* Opcode: Vacuum P1 P2 * * *
**
** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more
** for an attached database. The "temp" database may not be vacuumed.
+**
+** If P2 is not zero, then it is a register holding a string which is
+** the file into which the result of vacuum should be written. When
+** P2 is zero, the vacuum overwrites the original database.
*/
case OP_Vacuum: {
assert( p->readOnly==0 );
- rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1);
+ rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1,
+ pOp->p2 ? &aMem[pOp->p2] : 0);
if( rc ) goto abort_due_to_error;
break;
}
@@ -89495,6 +90758,7 @@ case OP_VDestroy: {
db->nVDestroy++;
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
db->nVDestroy--;
+ assert( p->errorAction==OE_Abort && p->usesStmtJournal );
if( rc ) goto abort_due_to_error;
break;
}
@@ -89617,10 +90881,11 @@ case OP_VFilter: { /* jump */
**
** If the VColumn opcode is being used to fetch the value of
** an unchanging column during an UPDATE operation, then the P5
-** value is 1. Otherwise, P5 is 0. The P5 value is returned
-** by sqlite3_vtab_nochange() routine and can be used
-** by virtual table implementations to return special "no-change"
-** marks which can be more efficient, depending on the virtual table.
+** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange()
+** function to return true inside the xColumn method of the virtual
+** table implementation. The P5 column might also contain other
+** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
+** unused by OP_VColumn.
*/
case OP_VColumn: {
sqlite3_vtab *pVtab;
@@ -89642,7 +90907,8 @@ case OP_VColumn: {
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
- if( pOp->p5 ){
+ testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
+ if( pOp->p5 & OPFLAG_NOCHNG ){
sqlite3VdbeMemSetNull(pDest);
pDest->flags = MEM_Null|MEM_Zero;
pDest->u.nZero = 0;
@@ -89736,7 +91002,7 @@ case OP_VRename: {
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
if( rc ) goto abort_due_to_error;
rc = pVtab->pModule->xRename(pVtab, pName->z);
- if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter;
+ if( isLegacy==0 ) db->flags &= ~(u64)SQLITE_LegacyAlter;
sqlite3VtabImportErrmsg(p, pVtab);
p->expired = 0;
if( rc ) goto abort_due_to_error;
@@ -90201,7 +91467,16 @@ default: { /* This is really OP_Noop, OP_Explain */
** release the mutexes on btrees that were acquired at the
** top. */
vdbe_return:
- testcase( nVmStep>0 );
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ while( nVmStep>=nProgressLimit && db->xProgress!=0 ){
+ nProgressLimit += db->nProgressOps;
+ if( db->xProgress(db->pProgressArg) ){
+ nProgressLimit = 0xffffffff;
+ rc = SQLITE_INTERRUPT;
+ goto abort_due_to_error;
+ }
+ }
+#endif
p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
sqlite3VdbeLeave(p);
assert( rc!=SQLITE_OK || nExtraDelete==0
@@ -91288,7 +92563,7 @@ static int vdbePmaReadBlob(
/* Extend the p->aAlloc[] allocation if required. */
if( p->nAllocnAlloc*2);
+ sqlite3_int64 nNew = MAX(128, 2*(sqlite3_int64)p->nAlloc);
while( nByte>nNew ) nNew = nNew*2;
aNew = sqlite3Realloc(p->aAlloc, nNew);
if( !aNew ) return SQLITE_NOMEM_BKPT;
@@ -92579,15 +93854,19 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
if( nMin>pSorter->nMemory ){
u8 *aNew;
- int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory;
- int nNew = pSorter->nMemory * 2;
+ sqlite3_int64 nNew = 2 * (sqlite3_int64)pSorter->nMemory;
+ int iListOff = -1;
+ if( pSorter->list.pList ){
+ iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory;
+ }
while( nNew < nMin ) nNew = nNew*2;
if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
if( nNew < nMin ) nNew = nMin;
-
aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
if( !aNew ) return SQLITE_NOMEM_BKPT;
- pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
+ if( iListOff>=0 ){
+ pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
+ }
pSorter->list.aMemory = aNew;
pSorter->nMemory = nNew;
}
@@ -93963,6 +95242,22 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
/* #include */
+#if !defined(SQLITE_OMIT_WINDOWFUNC)
+/*
+** Walk all expressions linked into the list of Window objects passed
+** as the second argument.
+*/
+static int walkWindowList(Walker *pWalker, Window *pList){
+ Window *pWin;
+ for(pWin=pList; pWin; pWin=pWin->pNextWin){
+ if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
+ if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
+ if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
+ }
+ return WRC_Continue;
+}
+#endif
+
/*
** Walk an expression tree. Invoke the callback once for each node
** of the expression, while descending. (In other words, the callback
@@ -94001,11 +95296,8 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
}
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
- Window *pWin = pExpr->pWin;
- if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
- if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort;
}
#endif
}
@@ -94045,6 +95337,16 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
+#if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE)
+ {
+ Parse *pParse = pWalker->pParse;
+ if( pParse && IN_RENAME_OBJECT ){
+ int rc = walkWindowList(pWalker, p->pWinDefn);
+ assert( rc==WRC_Continue );
+ return rc;
+ }
+ }
+#endif
return WRC_Continue;
}
@@ -94196,7 +95498,6 @@ static void resolveAlias(
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
}
- ExprSetProperty(pDup, EP_Alias);
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
** prevents ExprDelete() from deleting the Expr structure itself,
@@ -94265,6 +95566,23 @@ SQLITE_PRIVATE int sqlite3MatchSpanName(
return 1;
}
+/*
+** Return TRUE if the double-quoted string mis-feature should be supported.
+*/
+static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
+ if( db->init.busy ) return 1; /* Always support for legacy schemas */
+ if( pTopNC->ncFlags & NC_IsDDL ){
+ /* Currently parsing a DDL statement */
+ if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){
+ return 1;
+ }
+ return (db->flags & SQLITE_DqsDDL)!=0;
+ }else{
+ /* Currently parsing a DML statement */
+ return (db->flags & SQLITE_DqsDML)!=0;
+ }
+}
+
/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr
@@ -94275,7 +95593,7 @@ SQLITE_PRIVATE int sqlite3MatchSpanName(
** (even if X is implied).
** pExpr->iTable Set to the cursor number for the table obtained
** from pSrcList.
-** pExpr->pTab Points to the Table structure of X.Y (even if
+** pExpr->y.pTab Points to the Table structure of X.Y (even if
** X and/or Y are implied.)
** pExpr->iColumn Set to the column number within the table.
** pExpr->op Set to TK_COLUMN.
@@ -94319,7 +95637,6 @@ static int lookupName(
/* Initialize the node to no-match */
pExpr->iTable = -1;
- pExpr->pTab = 0;
ExprSetVVAProperty(pExpr, EP_NoReduce);
/* Translate the schema name in zDb into a pointer to the corresponding
@@ -94381,7 +95698,7 @@ static int lookupName(
continue;
}
if( IN_RENAME_OBJECT && pItem->zAlias ){
- sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
+ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
}
}
if( 0==(cntTab++) ){
@@ -94407,13 +95724,13 @@ static int lookupName(
}
if( pMatch ){
pExpr->iTable = pMatch->iCursor;
- pExpr->pTab = pMatch->pTab;
+ pExpr->y.pTab = pMatch->pTab;
/* RIGHT JOIN not (yet) supported */
assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
- pSchema = pExpr->pTab->pSchema;
+ pSchema = pExpr->y.pTab->pSchema;
}
} /* if( pSrcList ) */
@@ -94470,7 +95787,7 @@ static int lookupName(
testcase( iCol==(-1) );
if( IN_RENAME_OBJECT ){
pExpr->iColumn = iCol;
- pExpr->pTab = pTab;
+ pExpr->y.pTab = pTab;
eNewExprOp = TK_COLUMN;
}else{
pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
@@ -94492,7 +95809,7 @@ static int lookupName(
testcase( iCol==32 );
pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<pTab = pTab;
+ pExpr->y.pTab = pTab;
pExpr->iColumn = (i16)iCol;
eNewExprOp = TK_TRIGGER;
#endif /* SQLITE_OMIT_TRIGGER */
@@ -94553,6 +95870,10 @@ static int lookupName(
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
+ if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){
+ sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
+ return WRC_Abort;
+ }
if( sqlite3ExprVectorSize(pOrig)!=1 ){
sqlite3ErrorMsg(pParse, "row value misused");
return WRC_Abort;
@@ -94590,9 +95911,30 @@ static int lookupName(
*/
if( cnt==0 && zTab==0 ){
assert( pExpr->op==TK_ID );
- if( ExprHasProperty(pExpr,EP_DblQuoted) ){
+ if( ExprHasProperty(pExpr,EP_DblQuoted)
+ && areDoubleQuotedStringsEnabled(db, pTopNC)
+ ){
+ /* If a double-quoted identifier does not match any known column name,
+ ** then treat it as a string.
+ **
+ ** This hack was added in the early days of SQLite in a misguided attempt
+ ** to be compatible with MySQL 3.x, which used double-quotes for strings.
+ ** I now sorely regret putting in this hack. The effect of this hack is
+ ** that misspelled identifier names are silently converted into strings
+ ** rather than causing an error, to the frustration of countless
+ ** programmers. To all those frustrated programmers, my apologies.
+ **
+ ** Someday, I hope to get rid of this hack. Unfortunately there is
+ ** a huge amount of legacy SQL that uses it. So for now, we just
+ ** issue a warning.
+ */
+ sqlite3_log(SQLITE_WARNING,
+ "double-quoted string literal: \"%w\"", zCol);
+#ifdef SQLITE_ENABLE_NORMALIZE
+ sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol);
+#endif
pExpr->op = TK_STRING;
- pExpr->pTab = 0;
+ pExpr->y.pTab = 0;
return WRC_Prune;
}
if( sqlite3ExprIdToTrueFalse(pExpr) ){
@@ -94670,9 +96012,9 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
if( p ){
struct SrcList_item *pItem = &pSrc->a[iSrc];
- p->pTab = pItem->pTab;
+ p->y.pTab = pItem->pTab;
p->iTable = pItem->iCursor;
- if( p->pTab->iPKey==iCol ){
+ if( p->y.pTab->iPKey==iCol ){
p->iColumn = -1;
}else{
p->iColumn = (ynVar)iCol;
@@ -94762,7 +96104,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pItem = pSrcList->a;
assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
pExpr->op = TK_COLUMN;
- pExpr->pTab = pItem->pTab;
+ pExpr->y.pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor;
pExpr->iColumn = -1;
pExpr->affinity = SQLITE_AFF_INTEGER;
@@ -94806,9 +96148,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
zColumn = pRight->u.zToken;
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
- }
- if( IN_RENAME_OBJECT ){
- sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
+ sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
}
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
@@ -94826,6 +96166,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
const char *zId; /* The function name. */
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
+ int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
zId = pExpr->u.zToken;
@@ -94841,7 +96182,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}else{
is_agg = pDef->xFinalize!=0;
if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
- ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
+ ExprSetProperty(pExpr, EP_Unlikely);
if( n==2 ){
pExpr->iTable = exprProbability(pList->a[1].pExpr);
if( pExpr->iTable<0 ){
@@ -94890,6 +96231,15 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "non-deterministic functions",
NC_IdxExpr|NC_PartIdx);
}
+ if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
+ && pParse->nested==0
+ && sqlite3Config.bInternalFunctions==0
+ ){
+ /* Internal-use-only functions are disallowed unless the
+ ** SQL is being compiled using sqlite3NestedParse() */
+ no_such_func = 1;
+ pDef = 0;
+ }
}
if( 0==IN_RENAME_OBJECT ){
@@ -94898,18 +96248,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|| (pDef->xValue==0 && pDef->xInverse==0)
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
);
- if( pDef && pDef->xValue==0 && pExpr->pWin ){
+ if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
sqlite3ErrorMsg(pParse,
"%.*s() may not be used as a window function", nId, zId
);
pNC->nErr++;
}else if(
(is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
- || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
- || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
+ || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
+ || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
){
const char *zType;
- if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
+ if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
zType = "window";
}else{
zType = "aggregate";
@@ -94938,8 +96288,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pNC->nErr++;
}
if( is_agg ){
+ /* Window functions may not be arguments of aggregate functions.
+ ** Or arguments of other window functions. But aggregate functions
+ ** may be arguments for window functions. */
#ifndef SQLITE_OMIT_WINDOWFUNC
- pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
+ pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0));
#else
pNC->ncFlags &= ~NC_AllowAgg;
#endif
@@ -94948,19 +96301,21 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
sqlite3WalkExprList(pWalker, pList);
if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( pExpr->pWin ){
+ if( pExpr->y.pWin ){
Select *pSel = pNC->pWinSelect;
- sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
- sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
- sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
- sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
+ if( IN_RENAME_OBJECT==0 ){
+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
+ }
+ sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
+ sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
+ sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
if( 0==pSel->pWin
- || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin)
+ || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
){
- pExpr->pWin->pNextWin = pSel->pWin;
- pSel->pWin = pExpr->pWin;
+ pExpr->y.pWin->pNextWin = pSel->pWin;
+ pSel->pWin = pExpr->y.pWin;
}
- pNC->ncFlags |= NC_AllowWin;
+ pNC->ncFlags |= NC_HasWin;
}else
#endif /* SQLITE_OMIT_WINDOWFUNC */
{
@@ -94978,8 +96333,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
}
- pNC->ncFlags |= NC_AllowAgg;
}
+ pNC->ncFlags |= savedAllowFlags;
}
/* FIX ME: Compute pExpr->affinity based on the expected return
** type of the function
@@ -95010,11 +96365,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
case TK_IS:
case TK_ISNOT: {
- Expr *pRight;
+ Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
- if( (pRight = pExpr->pRight)->op==TK_ID ){
+ if( pRight->op==TK_ID ){
int rc = resolveExprStep(pWalker, pRight);
if( rc==WRC_Abort ) return WRC_Abort;
if( pRight->op==TK_TRUEFALSE ){
@@ -95230,32 +96585,53 @@ static int resolveCompoundOrderBy(
}else{
iCol = resolveAsName(pParse, pEList, pE);
if( iCol==0 ){
- pDup = sqlite3ExprDup(db, pE, 0);
+ /* Now test if expression pE matches one of the values returned
+ ** by pSelect. In the usual case this is done by duplicating the
+ ** expression, resolving any symbols in it, and then comparing
+ ** it against each expression returned by the SELECT statement.
+ ** Once the comparisons are finished, the duplicate expression
+ ** is deleted.
+ **
+ ** Or, if this is running as part of an ALTER TABLE operation,
+ ** resolve the symbols in the actual expression, not a duplicate.
+ ** And, if one of the comparisons is successful, leave the expression
+ ** as is instead of transforming it to an integer as in the usual
+ ** case. This allows the code in alter.c to modify column
+ ** refererences within the ORDER BY expression as required. */
+ if( IN_RENAME_OBJECT ){
+ pDup = pE;
+ }else{
+ pDup = sqlite3ExprDup(db, pE, 0);
+ }
if( !db->mallocFailed ){
assert(pDup);
iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);
}
- sqlite3ExprDelete(db, pDup);
+ if( !IN_RENAME_OBJECT ){
+ sqlite3ExprDelete(db, pDup);
+ }
}
}
if( iCol>0 ){
/* Convert the ORDER BY term into an integer column number iCol,
** taking care to preserve the COLLATE clause if it exists */
- Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
- if( pNew==0 ) return 1;
- pNew->flags |= EP_IntValue;
- pNew->u.iValue = iCol;
- if( pItem->pExpr==pE ){
- pItem->pExpr = pNew;
- }else{
- Expr *pParent = pItem->pExpr;
- assert( pParent->op==TK_COLLATE );
- while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
- assert( pParent->pLeft==pE );
- pParent->pLeft = pNew;
+ if( !IN_RENAME_OBJECT ){
+ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
+ if( pNew==0 ) return 1;
+ pNew->flags |= EP_IntValue;
+ pNew->u.iValue = iCol;
+ if( pItem->pExpr==pE ){
+ pItem->pExpr = pNew;
+ }else{
+ Expr *pParent = pItem->pExpr;
+ assert( pParent->op==TK_COLLATE );
+ while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
+ assert( pParent->pLeft==pE );
+ pParent->pLeft = pNew;
+ }
+ sqlite3ExprDelete(db, pE);
+ pItem->u.x.iOrderByCol = (u16)iCol;
}
- sqlite3ExprDelete(db, pE);
- pItem->u.x.iOrderByCol = (u16)iCol;
pItem->done = 1;
}else{
moreToDo = 1;
@@ -95314,6 +96690,38 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
return 0;
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** Walker callback for resolveRemoveWindows().
+*/
+static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ Window **pp;
+ for(pp=&pWalker->u.pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
+ if( *pp==pExpr->y.pWin ){
+ *pp = (*pp)->pNextWin;
+ break;
+ }
+ }
+ }
+ return WRC_Continue;
+}
+
+/*
+** Remove any Window objects owned by the expression pExpr from the
+** Select.pWin list of Select object pSelect.
+*/
+static void resolveRemoveWindows(Select *pSelect, Expr *pExpr){
+ Walker sWalker;
+ memset(&sWalker, 0, sizeof(Walker));
+ sWalker.xExprCallback = resolveRemoveWindowsCb;
+ sWalker.u.pSelect = pSelect;
+ sqlite3WalkExpr(&sWalker, pExpr);
+}
+#else
+# define resolveRemoveWindows(x,y)
+#endif
+
/*
** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
** The Name context of the SELECT statement is pNC. zType is either
@@ -95380,19 +96788,10 @@ static int resolveOrderGroupBy(
}
for(j=0; jpEList->nExpr; j++){
if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
-#ifndef SQLITE_OMIT_WINDOWFUNC
- if( pE->pWin ){
- /* Since this window function is being changed into a reference
- ** to the same window function the result set, remove the instance
- ** of this window function from the Select.pWin list. */
- Window **pp;
- for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
- if( *pp==pE->pWin ){
- *pp = (*pp)->pNextWin;
- }
- }
- }
-#endif
+ /* Since this expresion is being changed into a reference
+ ** to an identical expression in the result set, remove all Window
+ ** objects belonging to the expression from the Select.pWin list. */
+ resolveRemoveWindows(pSelect, pE);
pItem->u.x.iOrderByCol = j+1;
}
}
@@ -95472,7 +96871,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
*/
for(i=0; ipSrc->nSrc; i++){
struct SrcList_item *pItem = &p->pSrc->a[i];
- if( pItem->pSelect ){
+ if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
NameContext *pNC; /* Used to iterate name contexts */
int nRef = 0; /* Refcount for pOuterNC and outer contexts */
const char *zSavedContext = pParse->zAuthContext;
@@ -95604,6 +97003,19 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
}
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( IN_RENAME_OBJECT ){
+ Window *pWin;
+ for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){
+ if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy)
+ || sqlite3ResolveExprListNames(&sNC, pWin->pPartition)
+ ){
+ return WRC_Abort;
+ }
+ }
+ }
+#endif
+
/* If this is part of a compound SELECT, check that it has the right
** number of expressions in the select list. */
if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){
@@ -95679,12 +97091,12 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
Expr *pExpr /* The expression to be analyzed. */
){
- u16 savedHasAgg;
+ int savedHasAgg;
Walker w;
if( pExpr==0 ) return SQLITE_OK;
- savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
- pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
+ savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
+ pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
w.pParse = pNC->pParse;
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
@@ -95700,9 +97112,11 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
#if SQLITE_MAX_EXPR_DEPTH>0
w.pParse->nHeight -= pExpr->nHeight;
#endif
- if( pNC->ncFlags & NC_HasAgg ){
- ExprSetProperty(pExpr, EP_Agg);
- }
+ assert( EP_Agg==NC_HasAgg );
+ assert( EP_Win==NC_HasWin );
+ testcase( pNC->ncFlags & NC_HasAgg );
+ testcase( pNC->ncFlags & NC_HasWin );
+ ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
pNC->ncFlags |= savedHasAgg;
return pNC->nErr>0 || w.pParse->nErr>0;
}
@@ -95754,38 +97168,47 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
}
/*
-** Resolve names in expressions that can only reference a single table:
+** Resolve names in expressions that can only reference a single table
+** or which cannot reference any tables at all. Examples:
**
-** * CHECK constraints
-** * WHERE clauses on partial indices
+** (1) CHECK constraints
+** (2) WHERE clauses on partial indices
+** (3) Expressions in indexes on expressions
+** (4) Expression arguments to VACUUM INTO.
**
-** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
-** is set to -1 and the Expr.iColumn value is set to the column number.
+** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
+** nodes of the expression is set to -1 and the Expr.iColumn value is
+** set to the column number. In case (4), TK_COLUMN nodes cause an error.
**
** Any errors cause an error message to be set in pParse.
*/
-SQLITE_PRIVATE void sqlite3ResolveSelfReference(
+SQLITE_PRIVATE int sqlite3ResolveSelfReference(
Parse *pParse, /* Parsing context */
- Table *pTab, /* The table being referenced */
- int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
+ Table *pTab, /* The table being referenced, or NULL */
+ int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */
Expr *pExpr, /* Expression to resolve. May be NULL. */
ExprList *pList /* Expression list to resolve. May be NULL. */
){
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
NameContext sNC; /* Name context for pParse->pNewTable */
+ int rc;
- assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr );
+ assert( type==0 || pTab!=0 );
+ assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 );
memset(&sNC, 0, sizeof(sNC));
memset(&sSrc, 0, sizeof(sSrc));
- sSrc.nSrc = 1;
- sSrc.a[0].zName = pTab->zName;
- sSrc.a[0].pTab = pTab;
- sSrc.a[0].iCursor = -1;
+ if( pTab ){
+ sSrc.nSrc = 1;
+ sSrc.a[0].zName = pTab->zName;
+ sSrc.a[0].pTab = pTab;
+ sSrc.a[0].iCursor = -1;
+ }
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
- sNC.ncFlags = type;
- if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
- if( pList ) sqlite3ResolveExprListNames(&sNC, pList);
+ sNC.ncFlags = type | NC_IsDDL;
+ if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc;
+ if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList);
+ return rc;
}
/************** End of resolve.c *********************************************/
@@ -95836,8 +97259,12 @@ SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){
*/
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
int op;
- pExpr = sqlite3ExprSkipCollate(pExpr);
if( pExpr->flags & EP_Generic ) return 0;
+ while( ExprHasProperty(pExpr, EP_Skip) ){
+ assert( pExpr->op==TK_COLLATE );
+ pExpr = pExpr->pLeft;
+ assert( pExpr!=0 );
+ }
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
@@ -95850,8 +97277,8 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
- return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
+ return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
}
if( op==TK_SELECT_COLUMN ){
assert( pExpr->pLeft->flags&EP_xIsSelect );
@@ -95898,7 +97325,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con
** or likelihood() function at the root of an expression.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
- while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
+ while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( pExpr->x.pList->nExpr>0 );
@@ -95933,15 +97360,15 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
while( p ){
int op = p->op;
if( p->flags & EP_Generic ) break;
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN
- || op==TK_REGISTER || op==TK_TRIGGER)
- && p->pTab!=0
+ if( op==TK_REGISTER ) op = p->op2;
+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
+ && p->y.pTab!=0
){
- /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
+ /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
int j = p->iColumn;
if( j>=0 ){
- const char *zColl = p->pTab->aCol[j].zColl;
+ const char *zColl = p->y.pTab->aCol[j].zColl;
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
}
break;
@@ -95950,7 +97377,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
p = p->pLeft;
continue;
}
- if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
+ if( op==TK_COLLATE ){
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
}
@@ -96257,6 +97684,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
}else{
if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
pRet = sqlite3ExprDup(pParse->db, pVector, 0);
+ sqlite3RenameTokenRemap(pParse, pRet, pVector);
}
return pRet;
}
@@ -96273,7 +97701,7 @@ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
int reg = 0;
#ifndef SQLITE_OMIT_SUBQUERY
if( pExpr->op==TK_SELECT ){
- reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+ reg = sqlite3CodeSubselect(pParse, pExpr);
}
#endif
return reg;
@@ -96345,7 +97773,7 @@ static void codeVectorCompare(
int regLeft = 0;
int regRight = 0;
u8 opx = op;
- int addrDone = sqlite3VdbeMakeLabel(v);
+ int addrDone = sqlite3VdbeMakeLabel(pParse);
if( nLeft!=sqlite3ExprVectorSize(pRight) ){
sqlite3ErrorMsg(pParse, "row value misused");
@@ -96564,7 +97992,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
pNew->iAgg = -1;
if( pToken ){
if( nExtra==0 ){
- pNew->flags |= EP_IntValue|EP_Leaf;
+ pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse);
pNew->u.iValue = iValue;
}else{
pNew->u.zToken = (char*)&pNew[1];
@@ -96572,8 +98000,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
pNew->u.zToken[pToken->n] = 0;
if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){
- if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted;
- sqlite3Dequote(pNew->u.zToken);
+ sqlite3DequoteExpr(pNew);
}
}
}
@@ -96642,20 +98069,16 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
Expr *pRight /* Right operand */
){
Expr *p;
- if( op==TK_AND && pParse->nErr==0 ){
- /* Take advantage of short-circuit false optimization for AND */
- p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
- }else{
- p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
- if( p ){
- memset(p, 0, sizeof(Expr));
- p->op = op & TKFLG_MASK;
- p->iAgg = -1;
- }
+ p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
+ if( p ){
+ memset(p, 0, sizeof(Expr));
+ p->op = op & 0xff;
+ p->iAgg = -1;
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
- }
- if( p ) {
sqlite3ExprCheckHeight(pParse, p->nHeight);
+ }else{
+ sqlite3ExprDelete(pParse->db, pLeft);
+ sqlite3ExprDelete(pParse->db, pRight);
}
return p;
}
@@ -96676,33 +98099,6 @@ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pS
}
-/*
-** If the expression is always either TRUE or FALSE (respectively),
-** then return 1. If one cannot determine the truth value of the
-** expression at compile-time return 0.
-**
-** This is an optimization. If is OK to return 0 here even if
-** the expression really is always false or false (a false negative).
-** But it is a bug to return 1 if the expression might have different
-** boolean values in different circumstances (a false positive.)
-**
-** Note that if the expression is part of conditional for a
-** LEFT JOIN, then we cannot determine at compile-time whether or not
-** is it true or false, so always return 0.
-*/
-static int exprAlwaysTrue(Expr *p){
- int v = 0;
- if( ExprHasProperty(p, EP_FromJoin) ) return 0;
- if( !sqlite3ExprIsInteger(p, &v) ) return 0;
- return v!=0;
-}
-static int exprAlwaysFalse(Expr *p){
- int v = 0;
- if( ExprHasProperty(p, EP_FromJoin) ) return 0;
- if( !sqlite3ExprIsInteger(p, &v) ) return 0;
- return v==0;
-}
-
/*
** Join two expressions using an AND operator. If either expression is
** NULL, then just return the other expression.
@@ -96711,19 +98107,18 @@ static int exprAlwaysFalse(Expr *p){
** of returning an AND expression, just return a constant expression with
** a value of false.
*/
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
- if( pLeft==0 ){
+SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
+ sqlite3 *db = pParse->db;
+ if( pLeft==0 ){
return pRight;
}else if( pRight==0 ){
return pLeft;
- }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
- sqlite3ExprDelete(db, pLeft);
- sqlite3ExprDelete(db, pRight);
+ }else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
+ sqlite3ExprUnmapAndDelete(pParse, pLeft);
+ sqlite3ExprUnmapAndDelete(pParse, pRight);
return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
}else{
- Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
- sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
- return pNew;
+ return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
}
}
@@ -96844,6 +98239,10 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
+
+ assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
+ assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
+ || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
#ifdef SQLITE_DEBUG
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
assert( p->pLeft==0 );
@@ -96862,8 +98261,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
}else{
sqlite3ExprListDelete(db, p->x.pList);
}
- if( !ExprHasProperty(p, EP_Reduced) ){
- sqlite3WindowDelete(db, p->pWin);
+ if( ExprHasProperty(p, EP_WinFunc) ){
+ assert( p->op==TK_FUNCTION );
+ sqlite3WindowDelete(db, p->y.pWin);
}
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
@@ -96875,6 +98275,18 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p ) sqlite3ExprDeleteNN(db, p);
}
+/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
+** expression.
+*/
+SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){
+ if( p ){
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameExprUnmap(pParse, p);
+ }
+ sqlite3ExprDeleteNN(pParse->db, p);
+ }
+}
+
/*
** Return the number of bytes allocated for the expression structure
** passed as the first argument. This is always one of EXPR_FULLSIZE,
@@ -96886,6 +98298,16 @@ static int exprStructSize(Expr *p){
return EXPR_FULLSIZE;
}
+/*
+** Copy the complete content of an Expr node, taking care not to read
+** past the end of the structure for a reduced-size version of the source
+** Expr.
+*/
+static void exprNodeCopy(Expr *pDest, Expr *pSrc){
+ memset(pDest, 0, sizeof(Expr));
+ memcpy(pDest, pSrc, exprStructSize(pSrc));
+}
+
/*
** The dupedExpr*Size() routines each return the number of bytes required
** to store a copy of an expression or expression tree. They differ in
@@ -96927,7 +98349,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
if( 0==flags || p->op==TK_SELECT_COLUMN
#ifndef SQLITE_OMIT_WINDOWFUNC
- || p->pWin
+ || ExprHasProperty(p, EP_WinFunc)
#endif
){
nSize = EXPR_FULLSIZE;
@@ -96954,7 +98376,7 @@ static int dupedExprStructSize(Expr *p, int flags){
static int dupedExprNodeSize(Expr *p, int flags){
int nByte = dupedExprStructSize(p, flags) & 0xfff;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
- nByte += sqlite3Strlen30(p->u.zToken)+1;
+ nByte += sqlite3Strlen30NN(p->u.zToken)+1;
}
return ROUND8(nByte);
}
@@ -97057,22 +98479,24 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
}
/* Fill in pNew->pLeft and pNew->pRight. */
- zAlloc += dupedExprNodeSize(p, dupFlags);
- if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
+ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
+ zAlloc += dupedExprNodeSize(p, dupFlags);
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
pNew->pLeft = p->pLeft ?
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
pNew->pRight = p->pRight ?
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
}
- }else{
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
- pNew->pWin = 0;
- }else{
- pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
+ if( ExprHasProperty(p, EP_WinFunc) ){
+ pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
+ assert( ExprHasProperty(pNew, EP_WinFunc) );
}
#endif /* SQLITE_OMIT_WINDOWFUNC */
+ if( pzBuffer ){
+ *pzBuffer = zAlloc;
+ }
+ }else{
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft;
@@ -97084,9 +98508,6 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
- if( pzBuffer ){
- *pzBuffer = zAlloc;
- }
}
return pNew;
}
@@ -97100,7 +98521,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
static With *withDup(sqlite3 *db, With *p){
With *pRet = 0;
if( p ){
- int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
+ sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
pRet = sqlite3DbMallocZero(db, nByte);
if( pRet ){
int i;
@@ -97118,6 +98539,36 @@ static With *withDup(sqlite3 *db, With *p){
# define withDup(x,y) 0
#endif
+#ifndef SQLITE_OMIT_WINDOWFUNC
+/*
+** The gatherSelectWindows() procedure and its helper routine
+** gatherSelectWindowsCallback() are used to scan all the expressions
+** an a newly duplicated SELECT statement and gather all of the Window
+** objects found there, assembling them onto the linked list at Select->pWin.
+*/
+static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){
+ if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){
+ assert( ExprHasProperty(pExpr, EP_WinFunc) );
+ pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin;
+ pWalker->u.pSelect->pWin = pExpr->y.pWin;
+ }
+ return WRC_Continue;
+}
+static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){
+ return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune;
+}
+static void gatherSelectWindows(Select *p){
+ Walker w;
+ w.xExprCallback = gatherSelectWindowsCallback;
+ w.xSelectCallback = gatherSelectWindowsSelectCallback;
+ w.xSelectCallback2 = 0;
+ w.pParse = 0;
+ w.u.pSelect = p;
+ sqlite3WalkSelect(&w, p);
+}
+#endif
+
+
/*
** The following group of routines make deep copies of expressions,
** expression lists, ID lists, and select statements. The copies can
@@ -97285,6 +98736,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
#ifndef SQLITE_OMIT_WINDOWFUNC
pNew->pWin = 0;
pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn);
+ if( p->pWin ) gatherSelectWindows(pNew);
#endif
pNew->selId = p->selId;
*pp = pNew;
@@ -97334,7 +98786,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
}else if( (pList->nExpr & (pList->nExpr-1))==0 ){
ExprList *pNew;
pNew = sqlite3DbRealloc(db, pList,
- sizeof(*pList)+(2*pList->nExpr - 1)*sizeof(pList->a[0]));
+ sizeof(*pList)+(2*(sqlite3_int64)pList->nExpr-1)*sizeof(pList->a[0]));
if( pNew==0 ){
goto no_mem;
}
@@ -97417,7 +98869,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
}
vector_append_error:
- sqlite3ExprDelete(db, pExpr);
+ sqlite3ExprUnmapAndDelete(pParse, pExpr);
sqlite3IdListDelete(db, pColumns);
return pList;
}
@@ -97560,10 +99012,12 @@ SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
*/
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
- if( sqlite3StrICmp(pExpr->u.zToken, "true")==0
- || sqlite3StrICmp(pExpr->u.zToken, "false")==0
+ if( !ExprHasProperty(pExpr, EP_Quoted)
+ && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
+ || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
){
pExpr->op = TK_TRUEFALSE;
+ ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
return 1;
}
return 0;
@@ -97574,12 +99028,40 @@ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
** and 0 if it is FALSE.
*/
SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){
+ pExpr = sqlite3ExprSkipCollate((Expr*)pExpr);
assert( pExpr->op==TK_TRUEFALSE );
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
return pExpr->u.zToken[4]==0;
}
+/*
+** If pExpr is an AND or OR expression, try to simplify it by eliminating
+** terms that are always true or false. Return the simplified expression.
+** Or return the original expression if no simplification is possible.
+**
+** Examples:
+**
+** (x<10) AND true => (x<10)
+** (x<10) AND false => false
+** (x<10) AND (y=22 OR false) => (x<10) AND (y=22)
+** (x<10) AND (y=22 OR true) => (x<10)
+** (y=22) OR true => true
+*/
+SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
+ assert( pExpr!=0 );
+ if( pExpr->op==TK_AND || pExpr->op==TK_OR ){
+ Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight);
+ Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft);
+ if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){
+ pExpr = pExpr->op==TK_AND ? pRight : pLeft;
+ }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){
+ pExpr = pExpr->op==TK_AND ? pLeft : pRight;
+ }
+ }
+ return pExpr;
+}
+
/*
** These routines are Walker callbacks used to check expressions to
@@ -97824,7 +99306,7 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
*/
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
- if( p==0 ) return 0; /* Can only happen following on OOM */
+ if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */
/* If an expression is an integer literal that fits in a signed 32-bit
** integer, then the EP_IntValue flag will have already been set */
@@ -97870,7 +99352,9 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
*/
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
u8 op;
- while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
+ while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
+ p = p->pLeft;
+ }
op = p->op;
if( op==TK_REGISTER ) op = p->op2;
switch( op ){
@@ -97881,8 +99365,8 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
return 0;
case TK_COLUMN:
return ExprHasProperty(p, EP_CanBeNull) ||
- p->pTab==0 || /* Reference to column of index on expression */
- (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
+ p->y.pTab==0 || /* Reference to column of index on expression */
+ (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
default:
return 1;
}
@@ -98106,7 +99590,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
Expr *pX, /* The right-hand side (RHS) of the IN operator */
u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
int *prRhsHasNull, /* Register holding NULL status. See notes */
- int *aiMap /* Mapping from Index fields to RHS fields */
+ int *aiMap, /* Mapping from Index fields to RHS fields */
+ int *piTab /* OUT: index to use */
){
Select *p; /* SELECT to the right of IN operator */
int eType = 0; /* Type of RHS table. IN_INDEX_* */
@@ -98201,6 +99686,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
Bitmask colUsed; /* Columns of the index used */
Bitmask mCol; /* Mask for the current column */
if( pIdx->nColumnpPartIdxWhere!=0 ) continue;
/* Maximum nColumn is BMS-2, not BMS-1, so that we can compute
** BITMASK(nExpr) without overflowing */
testcase( pIdx->nColumn==BMS-2 );
@@ -98291,16 +99777,15 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
eType = IN_INDEX_EPH;
if( inFlags & IN_INDEX_LOOP ){
pParse->nQueryLoop = 0;
- if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
- eType = IN_INDEX_ROWID;
- }
}else if( prRhsHasNull ){
*prRhsHasNull = rMayHaveNull = ++pParse->nMem;
}
- sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
+ assert( pX->op==TK_IN );
+ sqlite3CodeRhsOfIN(pParse, pX, iTab);
+ if( rMayHaveNull ){
+ sqlite3SetHasNullFlag(v, iTab, rMayHaveNull);
+ }
pParse->nQueryLoop = savedNQueryLoop;
- }else{
- pX->iTable = iTab;
}
if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
@@ -98308,6 +99793,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
n = sqlite3ExprVectorSize(pX->pLeft);
for(i=0; i IN (?, ?, ?)", where is a reference
-** to some integer key column of a table B-Tree. In this case, use an
-** intkey B-Tree to store the set of IN(...) values instead of the usual
-** (slower) variable length keys B-Tree.
-**
-** If rMayHaveNull is non-zero, that means that the operation is an IN
-** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
-** All this routine does is initialize the register given by rMayHaveNull
-** to NULL. Calling routines will take care of changing this register
-** value to non-NULL if the RHS is NULL-free.
-**
-** For a SELECT or EXISTS operator, return the register that holds the
-** result. For a multi-column SELECT, the result is stored in a contiguous
-** array of registers and the return value is the register of the left-most
-** result column. Return 0 for IN operators or if an error occurs.
-*/
-#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3CodeSubselect(
+** The pExpr parameter is the IN operator. The cursor number for the
+** constructed ephermeral table is returned. The first time the ephemeral
+** table is computed, the cursor number is also stored in pExpr->iTable,
+** however the cursor number returned might not be the same, as it might
+** have been duplicated using OP_OpenDup.
+**
+** If the LHS expression ("x" in the examples) is a column value, or
+** the SELECT statement returns a column value, then the affinity of that
+** column is used to build the index keys. If both 'x' and the
+** SELECT... statement are columns, then numeric affinity is used
+** if either column has NUMERIC or INTEGER affinity. If neither
+** 'x' nor the SELECT... statement are columns, then numeric affinity
+** is used.
+*/
+SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
Parse *pParse, /* Parsing context */
- Expr *pExpr, /* The IN, SELECT, or EXISTS operator */
- int rHasNullFlag, /* Register that records whether NULLs exist in RHS */
- int isRowid /* If true, LHS of IN operator is a rowid */
+ Expr *pExpr, /* The IN operator */
+ int iTab /* Use this cursor number */
){
- int jmpIfDynamic = -1; /* One-time test address */
- int rReg = 0; /* Register storing resulting */
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return 0;
+ int addrOnce = 0; /* Address of the OP_Once instruction at top */
+ int addr; /* Address of OP_OpenEphemeral instruction */
+ Expr *pLeft; /* the LHS of the IN operator */
+ KeyInfo *pKeyInfo = 0; /* Key information */
+ int nVal; /* Size of vector pLeft */
+ Vdbe *v; /* The prepared statement under construction */
- /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
+ v = pParse->pVdbe;
+ assert( v!=0 );
+
+ /* The evaluation of the IN must be repeated every time it
** is encountered if any of the following is true:
**
** * The right-hand side is a correlated subquery
** * The right-hand side is an expression list containing variables
** * We are inside a trigger
**
- ** If all of the above are false, then we can run this code just once
- ** save the results, and reuse the same result on subsequent invocations.
+ ** If all of the above are false, then we can compute the RHS just once
+ ** and reuse it many names.
*/
- if( !ExprHasProperty(pExpr, EP_VarSelect) ){
- jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
- }
+ 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.
+ */
+ if( ExprHasProperty(pExpr, EP_Subrtn) ){
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
+ pExpr->x.pSelect->selId));
+ }
+ sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
+ pExpr->y.sub.iAddr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
+ sqlite3VdbeJumpHere(v, addrOnce);
+ return;
+ }
- switch( pExpr->op ){
- case TK_IN: {
- int addr; /* Address of OP_OpenEphemeral instruction */
- Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
- KeyInfo *pKeyInfo = 0; /* Key information */
- int nVal; /* Size of vector pLeft */
-
- nVal = sqlite3ExprVectorSize(pLeft);
- assert( !isRowid || nVal==1 );
+ /* Begin coding the subroutine */
+ ExprSetProperty(pExpr, EP_Subrtn);
+ pExpr->y.sub.regReturn = ++pParse->nMem;
+ pExpr->y.sub.iAddr =
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
+ VdbeComment((v, "return address"));
- /* Whether this is an 'x IN(SELECT...)' or an 'x IN()'
- ** expression it is handled the same way. An ephemeral table is
- ** filled with index keys representing the results from the
- ** SELECT or the .
- **
- ** If the 'x' expression is a column value, or the SELECT...
- ** statement returns a column value, then the affinity of that
- ** column is used to build the index keys. If both 'x' and the
- ** SELECT... statement are columns, then numeric affinity is used
- ** if either column has NUMERIC or INTEGER affinity. If neither
- ** 'x' nor the SELECT... statement are columns, then numeric affinity
- ** is used.
- */
- pExpr->iTable = pParse->nTab++;
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral,
- pExpr->iTable, (isRowid?0:nVal));
- pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- /* Case 1: expr IN (SELECT ...)
- **
- ** Generate code to write the results of the select into the temporary
- ** table allocated and opened above.
- */
- Select *pSelect = pExpr->x.pSelect;
- ExprList *pEList = pSelect->pEList;
-
- ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
- jmpIfDynamic>=0?"":"CORRELATED "
- ));
- assert( !isRowid );
- /* If the LHS and RHS of the IN operator do not match, that
- ** error will have been caught long before we reach this point. */
- if( ALWAYS(pEList->nExpr==nVal) ){
- SelectDest dest;
- int i;
- sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
- dest.zAffSdst = exprINAffinity(pParse, pExpr);
- pSelect->iLimit = 0;
- testcase( pSelect->selFlags & SF_Distinct );
- testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
- if( sqlite3Select(pParse, pSelect, &dest) ){
- sqlite3DbFree(pParse->db, dest.zAffSdst);
- sqlite3KeyInfoUnref(pKeyInfo);
- return 0;
- }
- sqlite3DbFree(pParse->db, dest.zAffSdst);
- assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
- assert( pEList!=0 );
- assert( pEList->nExpr>0 );
- assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
- for(i=0; iaColl[i] = sqlite3BinaryCompareCollSeq(
- pParse, p, pEList->a[i].pExpr
- );
- }
- }
- }else if( ALWAYS(pExpr->x.pList!=0) ){
- /* Case 2: expr IN (exprlist)
- **
- ** For each expression, build an index key from the evaluation and
- ** store it in the temporary table. If is a column, then use
- ** that columns affinity when building index keys. If is not
- ** a column, use numeric affinity.
- */
- char affinity; /* Affinity of the LHS of the IN */
- int i;
- ExprList *pList = pExpr->x.pList;
- struct ExprList_item *pItem;
- int r1, r2, r3;
- affinity = sqlite3ExprAffinity(pLeft);
- if( !affinity ){
- affinity = SQLITE_AFF_BLOB;
- }
- if( pKeyInfo ){
- assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
- pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
- }
+ /* Check to see if this is a vector IN operator */
+ pLeft = pExpr->pLeft;
+ nVal = sqlite3ExprVectorSize(pLeft);
- /* Loop through each expression in . */
- r1 = sqlite3GetTempReg(pParse);
- r2 = sqlite3GetTempReg(pParse);
- if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
- for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
- Expr *pE2 = pItem->pExpr;
- int iValToIns;
-
- /* If the expression is not constant then we will need to
- ** disable the test that was generated above that makes sure
- ** this code only executes once. Because for a non-constant
- ** expression we need to rerun this code each time.
- */
- if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
- sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
- jmpIfDynamic = -1;
- }
+ /* Construct the ephemeral table that will contain the content of
+ ** RHS of the IN operator.
+ */
+ pExpr->iTable = iTab;
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal);
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
+ }else{
+ VdbeComment((v, "RHS of IN operator"));
+ }
+#endif
+ pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
- /* Evaluate the expression and insert it into the temp table */
- if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
- sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
- }else{
- r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
- if( isRowid ){
- sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
- sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
- }else{
- sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
- sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
- }
- }
- }
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ReleaseTempReg(pParse, r2);
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ /* Case 1: expr IN (SELECT ...)
+ **
+ ** Generate code to write the results of the select into the temporary
+ ** table allocated and opened above.
+ */
+ Select *pSelect = pExpr->x.pSelect;
+ ExprList *pEList = pSelect->pEList;
+
+ ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d",
+ addrOnce?"":"CORRELATED ", pSelect->selId
+ ));
+ /* If the LHS and RHS of the IN operator do not match, that
+ ** error will have been caught long before we reach this point. */
+ if( ALWAYS(pEList->nExpr==nVal) ){
+ SelectDest dest;
+ int i;
+ sqlite3SelectDestInit(&dest, SRT_Set, iTab);
+ dest.zAffSdst = exprINAffinity(pParse, pExpr);
+ pSelect->iLimit = 0;
+ testcase( pSelect->selFlags & SF_Distinct );
+ testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
+ if( sqlite3Select(pParse, pSelect, &dest) ){
+ sqlite3DbFree(pParse->db, dest.zAffSdst);
+ sqlite3KeyInfoUnref(pKeyInfo);
+ return;
}
- if( pKeyInfo ){
- sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
+ sqlite3DbFree(pParse->db, dest.zAffSdst);
+ assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
+ assert( pEList!=0 );
+ assert( pEList->nExpr>0 );
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ for(i=0; iaColl[i] = sqlite3BinaryCompareCollSeq(
+ pParse, p, pEList->a[i].pExpr
+ );
}
- break;
+ }
+ }else if( ALWAYS(pExpr->x.pList!=0) ){
+ /* Case 2: expr IN (exprlist)
+ **
+ ** For each expression, build an index key from the evaluation and
+ ** store it in the temporary table. If is a column, then use
+ ** that columns affinity when building index keys. If is not
+ ** a column, use numeric affinity.
+ */
+ char affinity; /* Affinity of the LHS of the IN */
+ int i;
+ ExprList *pList = pExpr->x.pList;
+ struct ExprList_item *pItem;
+ int r1, r2, r3;
+ affinity = sqlite3ExprAffinity(pLeft);
+ if( !affinity ){
+ affinity = SQLITE_AFF_BLOB;
+ }
+ if( pKeyInfo ){
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
}
- case TK_EXISTS:
- case TK_SELECT:
- default: {
- /* Case 3: (SELECT ... FROM ...)
- ** or: EXISTS(SELECT ... FROM ...)
- **
- ** For a SELECT, generate code to put the values for all columns of
- ** the first row into an array of registers and return the index of
- ** the first register.
- **
- ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
- ** into a register and return that register number.
- **
- ** In both cases, the query is augmented with "LIMIT 1". Any
- ** preexisting limit is discarded in place of the new LIMIT 1.
+ /* Loop through each expression in . */
+ r1 = sqlite3GetTempReg(pParse);
+ r2 = sqlite3GetTempReg(pParse);
+ for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
+ Expr *pE2 = pItem->pExpr;
+
+ /* If the expression is not constant then we will need to
+ ** disable the test that was generated above that makes sure
+ ** this code only executes once. Because for a non-constant
+ ** expression we need to rerun this code each time.
*/
- Select *pSel; /* SELECT statement to encode */
- SelectDest dest; /* How to deal with SELECT result */
- int nReg; /* Registers to allocate */
- Expr *pLimit; /* New limit expression */
-
- testcase( pExpr->op==TK_EXISTS );
- testcase( pExpr->op==TK_SELECT );
- assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
- assert( ExprHasProperty(pExpr, EP_xIsSelect) );
-
- pSel = pExpr->x.pSelect;
- ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
- jmpIfDynamic>=0?"":"CORRELATED "));
- nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
- sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
- pParse->nMem += nReg;
- if( pExpr->op==TK_SELECT ){
- dest.eDest = SRT_Mem;
- dest.iSdst = dest.iSDParm;
- dest.nSdst = nReg;
- sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
- VdbeComment((v, "Init subquery result"));
- }else{
- dest.eDest = SRT_Exists;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
- VdbeComment((v, "Init EXISTS result"));
- }
- pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
- if( pSel->pLimit ){
- sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
- pSel->pLimit->pLeft = pLimit;
- }else{
- pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
+ if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
+ sqlite3VdbeChangeToNoop(v, addrOnce);
+ ExprClearProperty(pExpr, EP_Subrtn);
+ addrOnce = 0;
}
- pSel->iLimit = 0;
- if( sqlite3Select(pParse, pSel, &dest) ){
- return 0;
- }
- rReg = dest.iSDParm;
- ExprSetVVAProperty(pExpr, EP_NoReduce);
- break;
+
+ /* Evaluate the expression and insert it into the temp table */
+ r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
}
+ sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempReg(pParse, r2);
+ }
+ if( pKeyInfo ){
+ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
+ }
+ if( addrOnce ){
+ sqlite3VdbeJumpHere(v, addrOnce);
+ /* Subroutine return */
+ sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
+ sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
}
+}
+#endif /* SQLITE_OMIT_SUBQUERY */
- if( rHasNullFlag ){
- sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag);
+/*
+** Generate code for scalar subqueries used as a subquery expression
+** or EXISTS operator:
+**
+** (SELECT a FROM b) -- subquery
+** EXISTS (SELECT a FROM b) -- EXISTS subquery
+**
+** The pExpr parameter is the SELECT or EXISTS operator to be coded.
+**
+** The register that holds the result. For a multi-column SELECT,
+** the result is stored in a contiguous array of registers and the
+** return value is the register of the left-most result column.
+** Return 0 if an error occurs.
+*/
+#ifndef SQLITE_OMIT_SUBQUERY
+SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
+ int addrOnce = 0; /* Address of OP_Once at top of subroutine */
+ int rReg = 0; /* Register storing resulting */
+ Select *pSel; /* SELECT statement to encode */
+ SelectDest dest; /* How to deal with SELECT result */
+ int nReg; /* Registers to allocate */
+ Expr *pLimit; /* New limit expression */
+
+ Vdbe *v = pParse->pVdbe;
+ assert( v!=0 );
+ testcase( pExpr->op==TK_EXISTS );
+ testcase( pExpr->op==TK_SELECT );
+ assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
+ assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+ pSel = pExpr->x.pSelect;
+
+ /* The evaluation of the EXISTS/SELECT must be repeated every time it
+ ** is encountered if any of the following is true:
+ **
+ ** * The right-hand side is a correlated subquery
+ ** * The right-hand side is an expression list containing variables
+ ** * We are inside a trigger
+ **
+ ** If all of the above are false, then we can run this code just once
+ ** save the results, and reuse the same result on subsequent invocations.
+ */
+ if( !ExprHasProperty(pExpr, EP_VarSelect) ){
+ /* If this routine has already been coded, then invoke it as a
+ ** subroutine. */
+ if( ExprHasProperty(pExpr, EP_Subrtn) ){
+ ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
+ sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
+ pExpr->y.sub.iAddr);
+ return pExpr->iTable;
+ }
+
+ /* Begin coding the subroutine */
+ ExprSetProperty(pExpr, EP_Subrtn);
+ pExpr->y.sub.regReturn = ++pParse->nMem;
+ pExpr->y.sub.iAddr =
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
+ VdbeComment((v, "return address"));
+
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
+
+ /* For a SELECT, generate code to put the values for all columns of
+ ** the first row into an array of registers and return the index of
+ ** the first register.
+ **
+ ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
+ ** into a register and return that register number.
+ **
+ ** In both cases, the query is augmented with "LIMIT 1". Any
+ ** preexisting limit is discarded in place of the new LIMIT 1.
+ */
+ ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d",
+ addrOnce?"":"CORRELATED ", pSel->selId));
+ nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
+ sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
+ pParse->nMem += nReg;
+ if( pExpr->op==TK_SELECT ){
+ dest.eDest = SRT_Mem;
+ dest.iSdst = dest.iSDParm;
+ dest.nSdst = nReg;
+ sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
+ VdbeComment((v, "Init subquery result"));
+ }else{
+ dest.eDest = SRT_Exists;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
+ VdbeComment((v, "Init EXISTS result"));
+ }
+ pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
+ if( pSel->pLimit ){
+ sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
+ pSel->pLimit->pLeft = pLimit;
+ }else{
+ pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
+ }
+ pSel->iLimit = 0;
+ if( sqlite3Select(pParse, pSel, &dest) ){
+ return 0;
+ }
+ pExpr->iTable = rReg = dest.iSDParm;
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
+ if( addrOnce ){
+ sqlite3VdbeJumpHere(v, addrOnce);
- if( jmpIfDynamic>=0 ){
- sqlite3VdbeJumpHere(v, jmpIfDynamic);
+ /* Subroutine return */
+ sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
+ sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
}
return rReg;
@@ -98711,6 +100241,7 @@ static void sqlite3ExprCodeIN(
int addrTruthOp; /* Address of opcode that determines the IN is true */
int destNotNull; /* Jump here if a comparison is not true in step 6 */
int addrTop; /* Top of the step-6 loop */
+ int iTab = 0; /* Index to use */
pLeft = pExpr->pLeft;
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
@@ -98722,7 +100253,7 @@ static void sqlite3ExprCodeIN(
if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
/* Attempt to compute the RHS. After this step, if anything other than
- ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable
+ ** IN_INDEX_NOOP is returned, the table opened with cursor iTab
** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
** the RHS has not yet been coded. */
v = pParse->pVdbe;
@@ -98730,7 +100261,8 @@ static void sqlite3ExprCodeIN(
VdbeNoopComment((v, "begin IN expr"));
eType = sqlite3FindInIndex(pParse, pExpr,
IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
- destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap);
+ destIfFalse==destIfNull ? 0 : &rRhsHasNull,
+ aiMap, &iTab);
assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
|| eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC
@@ -98776,7 +100308,7 @@ static void sqlite3ExprCodeIN(
if( eType==IN_INDEX_NOOP ){
ExprList *pList = pExpr->x.pList;
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
- int labelOk = sqlite3VdbeMakeLabel(v);
+ int labelOk = sqlite3VdbeMakeLabel(pParse);
int r2, regToFree;
int regCkNull = 0;
int ii;
@@ -98820,7 +100352,7 @@ static void sqlite3ExprCodeIN(
if( destIfNull==destIfFalse ){
destStep2 = destIfFalse;
}else{
- destStep2 = destStep6 = sqlite3VdbeMakeLabel(v);
+ destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
}
for(i=0; ipLeft, i);
@@ -98838,19 +100370,19 @@ static void sqlite3ExprCodeIN(
/* In this case, the RHS is the ROWID of table b-tree and so we also
** know that the RHS is non-NULL. Hence, we combine steps 3 and 4
** into a single opcode. */
- sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs);
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
VdbeCoverage(v);
addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */
}else{
sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
if( destIfFalse==destIfNull ){
/* Combine Step 3 and Step 5 into a single opcode */
- sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse,
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse,
rLhs, nVector); VdbeCoverage(v);
goto sqlite3ExprCodeIN_finished;
}
/* Ordinary Step 3, for the case where FALSE and NULL are distinct */
- addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0,
+ addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0,
rLhs, nVector); VdbeCoverage(v);
}
@@ -98875,10 +100407,10 @@ static void sqlite3ExprCodeIN(
** of the RHS.
*/
if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
- addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
+ addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse);
VdbeCoverage(v);
if( nVector>1 ){
- destNotNull = sqlite3VdbeMakeLabel(v);
+ destNotNull = sqlite3VdbeMakeLabel(pParse);
}else{
/* For nVector==1, combine steps 6 and 7 by immediately returning
** FALSE if the first comparison is not NULL */
@@ -98890,7 +100422,7 @@ static void sqlite3ExprCodeIN(
int r3 = sqlite3GetTempReg(pParse);
p = sqlite3VectorFieldSubexpr(pLeft, i);
pColl = sqlite3ExprCollSeq(pParse, p);
- sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, i, r3);
+ sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3);
sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
(void*)pColl, P4_COLLSEQ);
VdbeCoverage(v);
@@ -98899,7 +100431,7 @@ static void sqlite3ExprCodeIN(
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
if( nVector>1 ){
sqlite3VdbeResolveLabel(v, destNotNull);
- sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1);
+ sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1);
VdbeCoverage(v);
/* Step 7: If we reach this point, we know that the result must
@@ -99070,7 +100602,8 @@ 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 *p, int iReg){
+static void exprToRegister(Expr *pExpr, int iReg){
+ Expr *p = sqlite3ExprSkipCollate(pExpr);
p->op2 = p->op;
p->op = TK_REGISTER;
p->iTable = iReg;
@@ -99098,7 +100631,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
#if SQLITE_OMIT_SUBQUERY
iResult = 0;
#else
- iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
+ iResult = sqlite3CodeSubselect(pParse, p);
#endif
}else{
int i;
@@ -99170,7 +100703,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** constant.
*/
int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
- int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+ int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
if( aff!=SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' );
@@ -99194,7 +100727,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
iTab = pParse->iSelfTab - 1;
}
}
- return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+ return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
}
@@ -99408,8 +100941,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
CollSeq *pColl = 0; /* A collating sequence */
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
- return pExpr->pWin->regResult;
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ return pExpr->y.pWin->regResult;
}
#endif
@@ -99443,7 +100976,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** arguments past the first non-NULL argument.
*/
if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
- int endCoalesce = sqlite3VdbeMakeLabel(v);
+ int endCoalesce = sqlite3VdbeMakeLabel(pParse);
assert( nFarg>=2 );
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
for(i=1; ix.pSelect->pEList->nExpr)!=1 ){
sqlite3SubselectError(pParse, nCol, 1);
}else{
- return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+ return sqlite3CodeSubselect(pParse, pExpr);
}
break;
}
case TK_SELECT_COLUMN: {
int n;
if( pExpr->pLeft->iTable==0 ){
- pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
+ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
}
assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
if( pExpr->iTable
@@ -99591,8 +101124,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
return pExpr->pLeft->iTable + pExpr->iColumn;
}
case TK_IN: {
- int destIfFalse = sqlite3VdbeMakeLabel(v);
- int destIfNull = sqlite3VdbeMakeLabel(v);
+ int destIfFalse = sqlite3VdbeMakeLabel(pParse);
+ int destIfNull = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
@@ -99652,7 +101185,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** p1==1 -> old.a p1==4 -> new.a
** p1==2 -> old.b p1==5 -> new.b
*/
- Table *pTab = pExpr->pTab;
+ Table *pTab = pExpr->y.pTab;
int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
assert( pExpr->iTable==0 || pExpr->iTable==1 );
@@ -99663,7 +101196,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
VdbeComment((v, "r[%d]=%s.%s", target,
(pExpr->iTable ? "new" : "old"),
- (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
+ (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
));
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -99732,9 +101265,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
pEList = pExpr->x.pList;
aListelem = pEList->a;
nExpr = pEList->nExpr;
- endLabel = sqlite3VdbeMakeLabel(v);
+ endLabel = sqlite3VdbeMakeLabel(pParse);
if( (pX = pExpr->pLeft)!=0 ){
- tempX = *pX;
+ exprNodeCopy(&tempX, pX);
testcase( pX->op==TK_COLUMN );
exprToRegister(&tempX, exprCodeVector(pParse, &tempX, ®Free1));
testcase( regFree1==0 );
@@ -99755,7 +101288,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}else{
pTest = aListelem[i].pExpr;
}
- nextCase = sqlite3VdbeMakeLabel(v);
+ nextCase = sqlite3VdbeMakeLabel(pParse);
testcase( pTest->op==TK_COLUMN );
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
@@ -100055,13 +101588,12 @@ static void exprCodeBetween(
Expr exprX; /* The x subexpression */
int regFree1 = 0; /* Temporary use register */
-
memset(&compLeft, 0, sizeof(Expr));
memset(&compRight, 0, sizeof(Expr));
memset(&exprAnd, 0, sizeof(Expr));
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- exprX = *pExpr->pLeft;
+ exprNodeCopy(&exprX, pExpr->pLeft);
exprAnd.op = TK_AND;
exprAnd.pLeft = &compLeft;
exprAnd.pRight = &compRight;
@@ -100123,18 +101655,23 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
if( NEVER(pExpr==0) ) return; /* No way this can happen */
op = pExpr->op;
switch( op ){
- case TK_AND: {
- int d2 = sqlite3VdbeMakeLabel(v);
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
- break;
- }
+ case TK_AND:
case TK_OR: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
+ if( pAlt!=pExpr ){
+ sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull);
+ }else if( op==TK_AND ){
+ int d2 = sqlite3VdbeMakeLabel(pParse);
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,
+ jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3VdbeResolveLabel(v, d2);
+ }else{
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ }
break;
}
case TK_NOT: {
@@ -100210,7 +101747,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_IN: {
- int destIfFalse = sqlite3VdbeMakeLabel(v);
+ int destIfFalse = sqlite3VdbeMakeLabel(pParse);
int destIfNull = jumpIfNull ? dest : destIfFalse;
sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
sqlite3VdbeGoto(v, dest);
@@ -100220,9 +101757,9 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
#endif
default: {
default_expr:
- if( exprAlwaysTrue(pExpr) ){
+ if( ExprAlwaysTrue(pExpr) ){
sqlite3VdbeGoto(v, dest);
- }else if( exprAlwaysFalse(pExpr) ){
+ }else if( ExprAlwaysFalse(pExpr) ){
/* No-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
@@ -100290,18 +101827,23 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
assert( pExpr->op!=TK_GE || op==OP_Lt );
switch( pExpr->op ){
- case TK_AND: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- break;
- }
+ case TK_AND:
case TK_OR: {
- int d2 = sqlite3VdbeMakeLabel(v);
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
+ Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
+ if( pAlt!=pExpr ){
+ sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull);
+ }else if( pExpr->op==TK_AND ){
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ }else{
+ int d2 = sqlite3VdbeMakeLabel(pParse);
+ testcase( jumpIfNull==0 );
+ sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2,
+ jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3VdbeResolveLabel(v, d2);
+ }
break;
}
case TK_NOT: {
@@ -100381,7 +101923,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
if( jumpIfNull ){
sqlite3ExprCodeIN(pParse, pExpr, dest, dest);
}else{
- int destIfNull = sqlite3VdbeMakeLabel(v);
+ int destIfNull = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull);
sqlite3VdbeResolveLabel(v, destIfNull);
}
@@ -100390,9 +101932,9 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
#endif
default: {
default_expr:
- if( exprAlwaysFalse(pExpr) ){
+ if( ExprAlwaysFalse(pExpr) ){
sqlite3VdbeGoto(v, dest);
- }else if( exprAlwaysTrue(pExpr) ){
+ }else if( ExprAlwaysTrue(pExpr) ){
/* no-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1);
@@ -100502,7 +102044,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
}
return 2;
}
- if( pA->op!=pB->op ){
+ if( pA->op!=pB->op || pA->op==TK_RAISE ){
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
return 1;
}
@@ -100514,40 +102056,44 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
if( pA->op==TK_FUNCTION ){
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ /* Justification for the assert():
+ ** window functions have p->op==TK_FUNCTION but aggregate functions
+ ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
+ ** function and a window function should have failed before reaching
+ ** this point. And, it is not possible to have a window function and
+ ** a scalar function with the same name and number of arguments. So
+ ** if we reach this point, either A and B both window functions or
+ ** neither are a window functions. */
+ assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
+ if( ExprHasProperty(pA,EP_WinFunc) ){
+ if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
+ }
+#endif
+ }else if( pA->op==TK_NULL ){
+ return 0;
}else if( pA->op==TK_COLLATE ){
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
- }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
+ }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2;
}
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
- if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+ if( (combinedFlags & EP_TokenOnly)==0 ){
if( combinedFlags & EP_xIsSelect ) return 2;
if( (combinedFlags & EP_FixedCol)==0
&& sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
- assert( (combinedFlags & EP_Reduced)==0 );
- if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
+ if( pA->op!=TK_STRING
+ && pA->op!=TK_TRUEFALSE
+ && (combinedFlags & EP_Reduced)==0
+ ){
if( pA->iColumn!=pB->iColumn ) return 2;
+ if( pA->op2!=pB->op2 ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
-#ifndef SQLITE_OMIT_WINDOWFUNC
- /* Justification for the assert():
- ** window functions have p->op==TK_FUNCTION but aggregate functions
- ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
- ** function and a window function should have failed before reaching
- ** this point. And, it is not possible to have a window function and
- ** a scalar function with the same name and number of arguments. So
- ** if we reach this point, either A and B both window functions or
- ** neither are a window functions. */
- assert( (pA->pWin==0)==(pB->pWin==0) );
-
- if( pA->pWin!=0 ){
- if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
- }
-#endif
}
return 0;
}
@@ -100592,6 +102138,76 @@ SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
iTab);
}
+/*
+** Return non-zero if Expr p can only be true if pNN is not NULL.
+*/
+static int exprImpliesNotNull(
+ Parse *pParse, /* Parsing context */
+ Expr *p, /* The expression to be checked */
+ Expr *pNN, /* The expression that is NOT NULL */
+ int iTab, /* Table being evaluated */
+ int seenNot /* True if p is an operand of NOT */
+){
+ assert( p );
+ assert( pNN );
+ if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ) return 1;
+ switch( p->op ){
+ case TK_IN: {
+ if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
+ assert( ExprHasProperty(p,EP_xIsSelect)
+ || (p->x.pList!=0 && p->x.pList->nExpr>0) );
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+ }
+ case TK_BETWEEN: {
+ ExprList *pList = p->x.pList;
+ assert( pList!=0 );
+ assert( pList->nExpr==2 );
+ if( seenNot ) return 0;
+ if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, seenNot)
+ || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, seenNot)
+ ){
+ return 1;
+ }
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+ }
+ case TK_EQ:
+ case TK_NE:
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_PLUS:
+ case TK_MINUS:
+ case TK_STAR:
+ case TK_REM:
+ case TK_BITAND:
+ case TK_BITOR:
+ case TK_SLASH:
+ case TK_LSHIFT:
+ case TK_RSHIFT:
+ case TK_CONCAT: {
+ if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1;
+ /* Fall thru into the next case */
+ }
+ case TK_SPAN:
+ case TK_COLLATE:
+ case TK_BITNOT:
+ case TK_UPLUS:
+ case TK_UMINUS: {
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+ }
+ case TK_TRUTH: {
+ if( seenNot ) return 0;
+ if( p->op2!=TK_IS ) return 0;
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot);
+ }
+ case TK_NOT: {
+ return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
+ }
+ }
+ return 0;
+}
+
/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true. Return false if we cannot complete the proof or if pE2 might
@@ -100627,10 +102243,10 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, i
){
return 1;
}
- if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
- Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
- testcase( pX!=pE1->pLeft );
- if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1;
+ if( pE2->op==TK_NOTNULL
+ && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0)
+ ){
+ return 1;
}
return 0;
}
@@ -100652,6 +102268,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
case TK_ISNOT:
case TK_NOT:
case TK_ISNULL:
+ case TK_NOTNULL:
case TK_IS:
case TK_OR:
case TK_CASE:
@@ -100660,6 +102277,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_ISNOT );
testcase( pExpr->op==TK_NOT );
testcase( pExpr->op==TK_ISNULL );
+ testcase( pExpr->op==TK_NOTNULL );
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_OR );
testcase( pExpr->op==TK_CASE );
@@ -100688,8 +102306,8 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_LE );
testcase( pExpr->op==TK_GT );
testcase( pExpr->op==TK_GE );
- if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
- || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
+ if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
+ || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
){
return WRC_Prune;
}
@@ -100722,6 +102340,17 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
*/
SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
Walker w;
+ p = sqlite3ExprSkipCollate(p);
+ while( p ){
+ if( p->op==TK_NOTNULL ){
+ p = p->pLeft;
+ }else if( p->op==TK_AND ){
+ if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1;
+ p = p->pRight;
+ }else{
+ break;
+ }
+ }
w.xExprCallback = impliesNotNullRow;
w.xSelectCallback = 0;
w.xSelectCallback2 = 0;
@@ -100920,7 +102549,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
&& (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
){
pCol = &pAggInfo->aCol[k];
- pCol->pTab = pExpr->pTab;
+ pCol->pTab = pExpr->y.pTab;
pCol->iTable = pExpr->iTable;
pCol->iColumn = pExpr->iColumn;
pCol->iMem = ++pParse->nMem;
@@ -101033,6 +102662,7 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
w.walkerDepth = 0;
w.u.pNC = pNC;
+ w.pParse = 0;
assert( pNC->pSrcList!=0 );
sqlite3WalkExpr(&w, pExpr);
}
@@ -101164,9 +102794,16 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
**
** Or, if zName is not a system table, zero is returned.
*/
-static int isSystemTable(Parse *pParse, const char *zName){
- if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
- sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
+static int isAlterableTable(Parse *pParse, Table *pTab){
+ if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ || ( (pTab->tabFlags & TF_Shadow)
+ && (pParse->db->flags & SQLITE_Defensive)
+ && pParse->db->nVdbeExec==0
+ )
+#endif
+ ){
+ sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
return 1;
}
return 0;
@@ -101183,7 +102820,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
sqlite3NestedParse(pParse,
"SELECT 1 "
"FROM \"%w\".%s "
- "WHERE name NOT LIKE 'sqlite_%%'"
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
" AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
zDb, MASTER_NAME,
@@ -101194,7 +102831,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
sqlite3NestedParse(pParse,
"SELECT 1 "
"FROM temp.%s "
- "WHERE name NOT LIKE 'sqlite_%%'"
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
" AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
MASTER_NAME, zDb
@@ -101262,7 +102899,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
/* Make sure it is not a system table being altered, or a reserved name
** that the table is being renamed to.
*/
- if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
+ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
goto exit_rename_table;
}
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
@@ -101295,15 +102932,15 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
}
#endif
- /* Begin a transaction for database iDb.
- ** Then modify the schema cookie (since the ALTER TABLE modifies the
- ** schema). Open a statement transaction if the table is a virtual
- ** table.
- */
+ /* Begin a transaction for database iDb. Then modify the schema cookie
+ ** (since the ALTER TABLE modifies the schema). Call sqlite3MayAbort(),
+ ** as the scalar functions (e.g. sqlite_rename_table()) invoked by the
+ ** nested SQL may raise an exception. */
v = sqlite3GetVdbe(pParse);
if( v==0 ){
goto exit_rename_table;
}
+ sqlite3MayAbort(pParse);
/* figure out how many UTF-8 characters are in zName */
zTabName = pTab->zName;
@@ -101315,7 +102952,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
- "AND name NOT LIKE 'sqlite_%%'"
+ "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
, zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName
);
@@ -101326,7 +102963,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
"tbl_name = %Q, "
"name = CASE "
"WHEN type='table' THEN %Q "
- "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
+ "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
+ " AND type='index' THEN "
"'sqlite_autoindex_' || %Q || substr(name,%d+18) "
"ELSE name END "
"WHERE tbl_name=%Q COLLATE nocase AND "
@@ -101372,7 +103010,6 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
int i = ++pParse->nMem;
sqlite3VdbeLoadString(v, i, zName);
sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
- sqlite3MayAbort(pParse);
}
#endif
@@ -101560,7 +103197,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
goto exit_begin_add_column;
}
- if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
+ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
goto exit_begin_add_column;
}
@@ -101662,7 +103299,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(
if( !pTab ) goto exit_rename_column;
/* Cannot alter a system table */
- if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
+ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column;
if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;
/* Which schema holds the table to be altered */
@@ -101693,6 +103330,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(
** uses the sqlite_rename_column() SQL function to compute the new
** CREATE statement text for the sqlite_master table.
*/
+ sqlite3MayAbort(pParse);
zNew = sqlite3NameFromToken(db, pNew);
if( !zNew ) goto exit_rename_column;
assert( pNew->n>0 );
@@ -101700,7 +103338,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn(
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
- "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)"
+ "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
+ " AND (type != 'index' OR tbl_name = %Q)"
" AND sql NOT LIKE 'create virtual%%'",
zDb, MASTER_NAME,
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
@@ -101803,10 +103442,16 @@ static void renameTokenCheckAll(Parse *pParse, void *pPtr){
#endif
/*
-** Add a new RenameToken object mapping parse tree element pPtr into
-** token *pToken to the Parse object currently under construction.
+** Remember that the parser tree element pPtr was created using
+** the token pToken.
**
-** Return a copy of pPtr.
+** In other words, construct a new RenameToken object and add it
+** to the list of RenameToken objects currently being built up
+** in pParse->pRename.
+**
+** The pPtr argument is returned so that this routine can be used
+** with tail recursion in tokenExpr() routine, for a small performance
+** improvement.
*/
SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
RenameToken *pNew;
@@ -101848,6 +103493,29 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
return WRC_Continue;
}
+/*
+** Walker callback used by sqlite3RenameExprUnmap().
+*/
+static int renameUnmapSelectCb(Walker *pWalker, Select *p){
+ Parse *pParse = pWalker->pParse;
+ int i;
+ if( ALWAYS(p->pEList) ){
+ ExprList *pList = p->pEList;
+ for(i=0; inExpr; i++){
+ if( pList->a[i].zName ){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zName);
+ }
+ }
+ }
+ if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */
+ SrcList *pSrc = p->pSrc;
+ for(i=0; inSrc; i++){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
+ }
+ }
+ return WRC_Continue;
+}
+
/*
** Remove all nodes that are part of expression pExpr from the rename list.
*/
@@ -101856,6 +103524,7 @@ SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
memset(&sWalker, 0, sizeof(Walker));
sWalker.pParse = pParse;
sWalker.xExprCallback = renameUnmapExprCb;
+ sWalker.xSelectCallback = renameUnmapSelectCb;
sqlite3WalkExpr(&sWalker, pExpr);
}
@@ -101910,14 +103579,31 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
}
}
+/*
+** Iterate through the Select objects that are part of WITH clauses attached
+** to select statement pSelect.
+*/
+static void renameWalkWith(Walker *pWalker, Select *pSelect){
+ if( pSelect->pWith ){
+ int i;
+ for(i=0; ipWith->nCte; i++){
+ Select *p = pSelect->pWith->a[i].pSelect;
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pWalker->pParse;
+ sqlite3SelectPrep(sNC.pParse, p, &sNC);
+ sqlite3WalkSelect(pWalker, p);
+ }
+ }
+}
+
/*
** This is a Walker select callback. It does nothing. It is only required
** because without a dummy callback, sqlite3WalkExpr() and similar do not
** descend into sub-select statements.
*/
static int renameColumnSelectCb(Walker *pWalker, Select *p){
- UNUSED_PARAMETER(pWalker);
- UNUSED_PARAMETER(p);
+ renameWalkWith(pWalker, p);
return WRC_Continue;
}
@@ -101939,7 +103625,7 @@ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
}else if( pExpr->op==TK_COLUMN
&& pExpr->iColumn==p->iCol
- && p->pTab==pExpr->pTab
+ && p->pTab==pExpr->y.pTab
){
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
}
@@ -102067,7 +103753,6 @@ static int renameParseSql(
rc = sqlite3RunParser(p, zSql, &zErr);
assert( p->zErrMsg==0 );
assert( rc!=SQLITE_OK || zErr==0 );
- assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 );
p->zErrMsg = zErr;
if( db->mallocFailed ) rc = SQLITE_NOMEM;
if( rc==SQLITE_OK
@@ -102197,9 +103882,14 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
);
pParse->eTriggerOp = pNew->op;
+ /* 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);
+ }
/* Resolve symbols in WHEN clause */
- if( pNew->pWhen ){
+ if( rc==SQLITE_OK && pNew->pWhen ){
rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
}
@@ -102245,6 +103935,7 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){
}
sNC.ncFlags = 0;
}
+ sNC.pSrcList = 0;
}
}
}
@@ -102282,11 +103973,15 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){
*/
static void renameParseCleanup(Parse *pParse){
sqlite3 *db = pParse->db;
+ Index *pIdx;
if( pParse->pVdbe ){
sqlite3VdbeFinalize(pParse->pVdbe);
}
sqlite3DeleteTable(db, pParse->pNewTable);
- if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex);
+ while( (pIdx = pParse->pNewIndex)!=0 ){
+ pParse->pNewIndex = pIdx->pNext;
+ sqlite3FreeIndex(db, pIdx);
+ }
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
sqlite3DbFree(db, pParse->zErrMsg);
renameTokenFree(db, pParse->pRename);
@@ -102313,15 +104008,8 @@ static void renameParseCleanup(Parse *pParse){
** into zNew. The name should be quoted if bQuote is true.
**
** This function is used internally by the ALTER TABLE RENAME COLUMN command.
-** Though accessible to application code, it is not intended for use by
-** applications. The existance of this function, and the way it works,
-** is subject to change without notice.
-**
-** If any of the parameters are out-of-bounds, then simply return NULL.
-** An out-of-bounds parameter can only occur when the application calls
-** this function directly. The parameters will always be well-formed when
-** this routine is invoked by the bytecode for a legitimate ALTER TABLE
-** statement.
+** It is only accessible to SQL created using sqlite3NestedParse(). It is
+** not reachable from ordinary SQL passed into sqlite3_prepare().
*/
static void renameColumnFunc(
sqlite3_context *context,
@@ -102404,6 +104092,9 @@ static void renameColumnFunc(
for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
}
+ for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){
+ sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
+ }
}
for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
@@ -102477,8 +104168,8 @@ static void renameColumnFunc(
*/
static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
RenameCtx *p = pWalker->u.pRename;
- if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
- renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
+ if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
+ renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
}
return WRC_Continue;
}
@@ -102490,12 +104181,17 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
int i;
RenameCtx *p = pWalker->u.pRename;
SrcList *pSrc = pSelect->pSrc;
+ if( pSrc==0 ){
+ assert( pWalker->pParse->db->mallocFailed );
+ return WRC_Abort;
+ }
for(i=0; inSrc; i++){
struct SrcList_item *pItem = &pSrc->a[i];
if( pItem->pTab==p->pTab ){
renameTokenFind(pWalker->pParse, p, pItem->zName);
}
}
+ renameWalkWith(pWalker, pSelect);
return WRC_Continue;
}
@@ -102575,7 +104271,7 @@ static void renameTableFunc(
}else{
/* Modify any FK definitions to point to the new table. */
#ifndef SQLITE_OMIT_FOREIGN_KEY
- if( db->flags & SQLITE_ForeignKeys ){
+ if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
FKey *pFKey;
for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
@@ -102729,9 +104425,9 @@ static void renameTableTest(
*/
SQLITE_PRIVATE void sqlite3AlterFunctions(void){
static FuncDef aAlterTableFuncs[] = {
- FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc),
- FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc),
- FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest),
+ INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
+ INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc),
+ INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest),
};
sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
@@ -103897,7 +105593,7 @@ static void analyzeOneTable(
addrNextRow = sqlite3VdbeCurrentAddr(v);
if( nColTest>0 ){
- int endDistinctTest = sqlite3VdbeMakeLabel(v);
+ int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
int *aGotoChng; /* Array of jump instruction addresses */
aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
if( aGotoChng==0 ) continue;
@@ -104780,7 +106476,7 @@ static void attachFunc(
if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
pNew->pBt = 0;
pNew->pSchema = 0;
- rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
+ rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
}else{
/* This is a real ATTACH
**
@@ -104835,8 +106531,8 @@ static void attachFunc(
assert( pVfs );
flags |= SQLITE_OPEN_MAIN_DB;
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
- sqlite3_free( zPath );
db->nDb++;
+ pNew->zDbSName = sqlite3DbStrDup(db, zName);
}
db->noSharedCache = 0;
if( rc==SQLITE_CONSTRAINT ){
@@ -104864,7 +106560,6 @@ static void attachFunc(
sqlite3BtreeLeave(pNew->pBt);
}
pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
- if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName);
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
@@ -104892,15 +106587,19 @@ static void attachFunc(
break;
case SQLITE_NULL:
- /* No key specified. Use the key from the main database */
- sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
- rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+ /* No key specified. Use the key from URI filename, or if none,
+ ** use the key from the main database. */
+ if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){
+ sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+ if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
+ rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
+ }
}
break;
}
}
#endif
+ sqlite3_free( zPath );
/* If the file was opened successfully, read the schema for the new database.
** If this fails, or if opening the file failed, then close the file and
@@ -104911,12 +106610,14 @@ static void attachFunc(
sqlite3BtreeEnterAll(db);
db->init.iDb = 0;
db->mDbFlags &= ~(DBFLAG_SchemaKnownOk);
- rc = sqlite3Init(db, &zErrDyn);
+ if( !REOPEN_AS_MEMDB(db) ){
+ rc = sqlite3Init(db, &zErrDyn);
+ }
sqlite3BtreeLeaveAll(db);
assert( zErrDyn==0 || rc!=SQLITE_OK );
}
#ifdef SQLITE_USER_AUTHENTICATION
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){
u8 newAuth = 0;
rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth);
if( newAuthauth.authLevel ){
@@ -105460,6 +107161,7 @@ SQLITE_PRIVATE void sqlite3AuthRead(
int iCol; /* Index of column in table */
assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
+ assert( !IN_RENAME_OBJECT || db->xAuth==0 );
if( db->xAuth==0 ) return;
iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
if( iDb<0 ){
@@ -105516,6 +107218,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck(
/* Don't do any authorization checks if the database is initialising
** or if the parser is being invoked from within sqlite3_declare_vtab.
*/
+ assert( !IN_RENAME_OBJECT || db->xAuth==0 );
if( db->init.busy || IN_SPECIAL_PARSE ){
return SQLITE_OK;
}
@@ -105810,7 +107513,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
if( v && pParse->nErr==0 && !db->mallocFailed ){
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
- if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
+ assert( pParse->pAinc==0 || pParse->nTab>0 );
sqlite3VdbeMakeReady(v, pParse);
pParse->rc = SQLITE_DONE;
}else{
@@ -105843,7 +107546,12 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
zSql = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
if( zSql==0 ){
- return; /* A malloc must have failed */
+ /* This can result either from an OOM or because the formatted string
+ ** exceeds SQLITE_LIMIT_LENGTH. In the latter case, we need to set
+ ** an error */
+ if( !db->mallocFailed ) pParse->rc = SQLITE_TOOBIG;
+ pParse->nErr++;
+ return;
}
pParse->nested++;
memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
@@ -105937,12 +107645,11 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
p = sqlite3FindTable(db, zName, zDbase);
if( p==0 ){
- const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( sqlite3FindDbName(db, zDbase)<1 ){
- /* If zName is the not the name of a table in the schema created using
- ** CREATE, then check to see if it is the name of an virtual table that
- ** can be an eponymous virtual table. */
+ /* If zName is the not the name of a table in the schema created using
+ ** CREATE, then check to see if it is the name of an virtual table that
+ ** can be an eponymous virtual table. */
+ if( pParse->disableVtab==0 ){
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
pMod = sqlite3PragmaVtabRegister(db, zName);
@@ -105952,13 +107659,18 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
}
}
#endif
- if( (flags & LOCATE_NOERR)==0 ){
- if( zDbase ){
- sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
- }else{
- sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
- }
- pParse->checkSchema = 1;
+ if( flags & LOCATE_NOERR ) return 0;
+ pParse->checkSchema = 1;
+ }else if( IsVirtual(p) && pParse->disableVtab ){
+ p = 0;
+ }
+
+ if( p==0 ){
+ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
+ if( zDbase ){
+ sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
+ }else{
+ sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
}
}
@@ -106129,17 +107841,22 @@ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
int i;
sqlite3BtreeEnterAll(db);
- assert( db->nSchemaLock==0 );
for(i=0; inDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pSchema ){
- sqlite3SchemaClear(pDb->pSchema);
+ if( db->nSchemaLock==0 ){
+ sqlite3SchemaClear(pDb->pSchema);
+ }else{
+ DbSetProperty(db, i, DB_ResetWanted);
+ }
}
}
db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
- sqlite3CollapseDatabaseArray(db);
+ if( db->nSchemaLock==0 ){
+ sqlite3CollapseDatabaseArray(db);
+ }
}
/*
@@ -106187,10 +107904,14 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
#ifdef SQLITE_DEBUG
/* Record the number of outstanding lookaside allocations in schema Tables
- ** prior to doing any free() operations. Since schema Tables do not use
- ** lookaside, this number should not change. */
+ ** prior to doing any free() operations. Since schema Tables do not use
+ ** lookaside, this number should not change.
+ **
+ ** If malloc has already failed, it may be that it failed while allocating
+ ** a Table object that was going to be marked ephemeral. So do not check
+ ** that no lookaside memory is used in this case either. */
int nLookaside = 0;
- if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
+ if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
nLookaside = sqlite3LookasideUsed(db, 0);
}
#endif
@@ -106374,6 +108095,20 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
return iDb;
}
+/*
+** True if PRAGMA writable_schema is ON
+*/
+SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
+ SQLITE_WriteSchema );
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
+ SQLITE_Defensive );
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
+ (SQLITE_WriteSchema|SQLITE_Defensive) );
+ return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
+}
+
/*
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
@@ -106383,7 +108118,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
*/
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
if( !pParse->db->init.busy && pParse->nested==0
- && (pParse->db->flags & SQLITE_WriteSchema)==0
+ && sqlite3WritableSchema(pParse->db)==0
&& 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
return SQLITE_ERROR;
@@ -106884,7 +108619,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(
** accept it. This routine does the necessary conversion. It converts
** the expression given in its argument from a TK_STRING into a TK_ID
** if the expression is just a TK_STRING with an optional COLLATE clause.
-** If the epxression is anything other than TK_STRING, the expression is
+** If the expression is anything other than TK_STRING, the expression is
** unchanged.
*/
static void sqlite3StringToId(Expr *p){
@@ -106960,7 +108695,8 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
&& sortOrder!=SQLITE_SO_DESC
){
if( IN_RENAME_OBJECT && pList ){
- sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr);
+ Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
+ sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr);
}
pTab->iPKey = iCol;
pTab->keyConf = (u8)onError;
@@ -107280,10 +109016,51 @@ static void estimateIndexWidth(Index *pIdx){
pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
}
-/* Return true if value x is found any of the first nCol entries of aiCol[]
+/* Return true if column number x is any of the first nCol entries of aiCol[].
+** This is used to determine if the column number x appears in any of the
+** first nCol entries of an index.
*/
static int hasColumn(const i16 *aiCol, int nCol, int x){
- while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
+ while( nCol-- > 0 ){
+ assert( aiCol[0]>=0 );
+ if( x==*(aiCol++) ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** Return true if any of the first nKey entries of index pIdx exactly
+** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID
+** PRIMARY KEY index. pIdx is an index on the same table. pIdx may
+** or may not be the same index as pPk.
+**
+** The first nKey entries of pIdx are guaranteed to be ordinary columns,
+** not a rowid or expression.
+**
+** This routine differs from hasColumn() in that both the column and the
+** collating sequence must match for this routine, but for hasColumn() only
+** the column name must match.
+*/
+static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
+ int i, j;
+ assert( nKey<=pIdx->nColumn );
+ assert( iColnColumn,pPk->nKeyCol) );
+ assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY );
+ assert( pPk->pTable->tabFlags & TF_WithoutRowid );
+ assert( pPk->pTable==pIdx->pTable );
+ testcase( pPk==pIdx );
+ j = pPk->aiColumn[iCol];
+ assert( j!=XN_ROWID && j!=XN_EXPR );
+ for(i=0; iaiColumn[i]>=0 || j>=0 );
+ if( pIdx->aiColumn[i]==j
+ && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0
+ ){
+ return 1;
+ }
+ }
return 0;
}
@@ -107372,15 +109149,19 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
pList = sqlite3ExprListAppend(pParse, 0,
sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
if( pList==0 ) return;
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
+ }
pList->a[0].sortOrder = pParse->iPkSortOrder;
assert( pParse->pNewTable==pTab );
+ pTab->iPKey = -1;
sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
SQLITE_IDXTYPE_PRIMARYKEY);
if( db->mallocFailed || pParse->nErr ) return;
pPk = sqlite3PrimaryKeyIndex(pTab);
- pTab->iPKey = -1;
}else{
pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
/*
** Remove all redundant columns from the PRIMARY KEY. For example, change
@@ -107388,9 +109169,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
** code assumes the PRIMARY KEY contains no repeated columns.
*/
for(i=j=1; inKeyCol; i++){
- if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
+ if( isDupColumn(pPk, j, pPk, i) ){
pPk->nColumn--;
}else{
+ testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) );
pPk->aiColumn[j++] = pPk->aiColumn[i];
}
}
@@ -107420,7 +109202,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
int n;
if( IsPrimaryKeyIndex(pIdx) ) continue;
for(i=n=0; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
+ if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
+ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
+ n++;
+ }
}
if( n==0 ){
/* This index is a superset of the primary key */
@@ -107429,9 +109214,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}
if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
for(i=0, j=pIdx->nKeyCol; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
+ if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){
+ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) );
pIdx->aiColumn[j] = pPk->aiColumn[i];
pIdx->azColl[j] = pPk->azColl[i];
+ if( pPk->aSortOrder[i] ){
+ /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */
+ pIdx->bAscKeyBug = 1;
+ }
j++;
}
}
@@ -107459,6 +109249,36 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
recomputeColumnsNotIndexed(pPk);
}
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Return true if zName is a shadow table name in the current database
+** connection.
+**
+** zName is temporarily modified while this routine is running, but is
+** restored to its original value prior to this routine returning.
+*/
+static int isShadowTableName(sqlite3 *db, char *zName){
+ char *zTail; /* Pointer to the last "_" in zName */
+ Table *pTab; /* Table that zName is a shadow of */
+ Module *pMod; /* Module for the virtual table */
+
+ zTail = strrchr(zName, '_');
+ if( zTail==0 ) return 0;
+ *zTail = 0;
+ pTab = sqlite3FindTable(db, zName, 0);
+ *zTail = '_';
+ if( pTab==0 ) return 0;
+ if( !IsVirtual(pTab) ) return 0;
+ pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
+ if( pMod==0 ) return 0;
+ if( pMod->pModule->iVersion<3 ) return 0;
+ if( pMod->pModule->xShadowName==0 ) return 0;
+ return pMod->pModule->xShadowName(zTail+1);
+}
+#else
+# define isShadowTableName(x,y) 0
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+
/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
@@ -107498,6 +109318,10 @@ SQLITE_PRIVATE void sqlite3EndTable(
p = pParse->pNewTable;
if( p==0 ) return;
+ if( pSelect==0 && isShadowTableName(db, p->zName) ){
+ p->tabFlags |= TF_Shadow;
+ }
+
/* If the db->init.busy is 1 it means we are reading the SQL off the
** "sqlite_master" or "sqlite_temp_master" table on the disk.
** So do not write to the disk again. Extract the root page number
@@ -107516,6 +109340,11 @@ SQLITE_PRIVATE void sqlite3EndTable(
if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
}
+ assert( (p->tabFlags & TF_HasPrimaryKey)==0
+ || p->iPKey>=0 || sqlite3PrimaryKeyIndex(p)!=0 );
+ assert( (p->tabFlags & TF_HasPrimaryKey)!=0
+ || (p->iPKey<0 && sqlite3PrimaryKeyIndex(p)==0) );
+
/* Special processing for WITHOUT ROWID Tables */
if( tabOpts & TF_WithoutRowid ){
if( (p->tabFlags & TF_Autoincrement) ){
@@ -108005,7 +109834,7 @@ SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iT
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
Vdbe *v = sqlite3GetVdbe(pParse);
int r1 = sqlite3GetTempReg(pParse);
- assert( iTable>1 );
+ if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
sqlite3MayAbort(pParse);
#ifndef SQLITE_OMIT_AUTOVACUUM
@@ -108164,6 +109993,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in
*/
if( IsVirtual(pTab) ){
sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
+ sqlite3MayAbort(pParse);
}
sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
sqlite3ChangeCookie(pParse, iDb);
@@ -108510,10 +110340,27 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
sqlite3VdbeJumpHere(v, j2);
}else{
+ /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not
+ ** abort. The exception is if one of the indexed expressions contains a
+ ** user function that throws an exception when it is evaluated. But the
+ ** overhead of adding a statement journal to a CREATE INDEX statement is
+ ** very small (since most of the pages written do not contain content that
+ ** needs to be restored if the statement aborts), so we call
+ ** sqlite3MayAbort() for all CREATE INDEX statements. */
+ sqlite3MayAbort(pParse);
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
- sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
+ if( !pIndex->bAscKeyBug ){
+ /* This OP_SeekEnd opcode makes index insert for a REINDEX go much
+ ** faster by avoiding unnecessary seeks. But the optimization does
+ ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables
+ ** with DESC primary keys, since those indexes have there keys in
+ ** a different order from the main table.
+ ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf
+ */
+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
+ }
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
@@ -108668,13 +110515,13 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
assert( pParse->nErr==0 );
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
&& db->init.busy==0
+ && pTblName!=0
#if SQLITE_USER_AUTHENTICATION
&& sqlite3UserAuthTable(pTab->zName)==0
#endif
#ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX
&& sqlite3StrICmp(&pTab->zName[7],"master")!=0
#endif
- && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0
){
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
goto exit_create_index;
@@ -108778,6 +110625,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
sqlite3ExprListSetSortOrder(pList, sortOrder);
}else{
sqlite3ExprListCheckLength(pParse, pList, "index");
+ if( pParse->nErr ) goto exit_create_index;
}
/* Figure out how many bytes of space are required to store explicitly
@@ -108796,6 +110644,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
*/
nName = sqlite3Strlen30(zName);
nExtraCol = pPk ? pPk->nKeyCol : 1;
+ assert( pList->nExpr + nExtraCol <= 32767 /* Fits in i16 */ );
pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol,
nName + nExtra + 1, &zExtra);
if( db->mallocFailed ){
@@ -108903,9 +110752,10 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
for(j=0; jnKeyCol; j++){
int x = pPk->aiColumn[j];
assert( x>=0 );
- if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
+ if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){
pIndex->nColumn--;
}else{
+ testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) );
pIndex->aiColumn[i] = x;
pIndex->azColl[i] = pPk->azColl[j];
pIndex->aSortOrder[i] = pPk->aSortOrder[j];
@@ -108992,6 +110842,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
}
}
if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType;
+ if( IN_RENAME_OBJECT ){
+ pIndex->pNext = pParse->pNewIndex;
+ pParse->pNewIndex = pIndex;
+ pIndex = 0;
+ }
goto exit_create_index;
}
}
@@ -109007,6 +110862,14 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
Index *p;
assert( !IN_SPECIAL_PARSE );
assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
+ if( pTblName!=0 ){
+ pIndex->tnum = db->init.newTnum;
+ if( sqlite3IndexHasDuplicateRootPage(pIndex) ){
+ sqlite3ErrorMsg(pParse, "invalid rootpage");
+ pParse->rc = SQLITE_CORRUPT_BKPT;
+ goto exit_create_index;
+ }
+ }
p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
pIndex->zName, pIndex);
if( p ){
@@ -109015,9 +110878,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
goto exit_create_index;
}
db->mDbFlags |= DBFLAG_SchemaChange;
- if( pTblName!=0 ){
- pIndex->tnum = db->init.newTnum;
- }
}
/* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
@@ -109269,9 +111129,9 @@ SQLITE_PRIVATE void *sqlite3ArrayAllocate(
int *pIdx /* Write the index of a new slot here */
){
char *z;
- int n = *pnEntry;
+ sqlite3_int64 n = *pIdx = *pnEntry;
if( (n & (n-1))==0 ){
- int sz = (n==0) ? 1 : 2*n;
+ sqlite3_int64 sz = (n==0) ? 1 : 2*n;
void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry);
if( pNew==0 ){
*pIdx = -1;
@@ -109281,7 +111141,6 @@ SQLITE_PRIVATE void *sqlite3ArrayAllocate(
}
z = (char*)pArray;
memset(&z[n * szEntry], 0, szEntry);
- *pIdx = n;
++*pnEntry;
return pArray;
}
@@ -109343,6 +111202,18 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
return -1;
}
+/*
+** Maximum size of a SrcList object.
+** The SrcList object is used to represent the FROM clause of a
+** SELECT statement, and the query planner cannot deal with more
+** than 64 tables in a join. So any value larger than 64 here
+** is sufficient for most uses. Smaller values, like say 10, are
+** appropriate for small and memory-limited applications.
+*/
+#ifndef SQLITE_MAX_SRCLIST
+# define SQLITE_MAX_SRCLIST 200
+#endif
+
/*
** Expand the space allocated for the given SrcList object by
** creating nExtra new slots beginning at iStart. iStart is zero based.
@@ -109359,11 +111230,12 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
** the iStart value would be 0. The result then would
** be: nil, nil, nil, A, B.
**
-** If a memory allocation fails the SrcList is unchanged. The
-** db->mallocFailed flag will be set to true.
+** If a memory allocation fails or the SrcList becomes too large, leave
+** the original SrcList unchanged, return NULL, and leave an error message
+** in pParse.
*/
SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
- sqlite3 *db, /* Database connection to notify of OOM errors */
+ Parse *pParse, /* Parsing context into which errors are reported */
SrcList *pSrc, /* The SrcList to be enlarged */
int nExtra, /* Number of new slots to add to pSrc->a[] */
int iStart /* Index in pSrc->a[] of first new slot */
@@ -109379,17 +111251,23 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
/* Allocate additional space if needed */
if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
- int nAlloc = pSrc->nSrc*2+nExtra;
- int nGot;
+ sqlite3_int64 nAlloc = 2*(sqlite3_int64)pSrc->nSrc+nExtra;
+ sqlite3 *db = pParse->db;
+
+ if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){
+ sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d",
+ SQLITE_MAX_SRCLIST);
+ return 0;
+ }
+ if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST;
pNew = sqlite3DbRealloc(db, pSrc,
sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
if( pNew==0 ){
assert( db->mallocFailed );
- return pSrc;
+ return 0;
}
pSrc = pNew;
- nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
- pSrc->nAlloc = nGot;
+ pSrc->nAlloc = nAlloc;
}
/* Move existing slots that come after the newly inserted slots
@@ -109414,7 +111292,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
** Append a new table name to the given SrcList. Create a new SrcList if
** need be. A new entry is created in the SrcList even if pTable is NULL.
**
-** A SrcList is returned, or NULL if there is an OOM error. The returned
+** A SrcList is returned, or NULL if there is an OOM error or if the
+** SrcList grows to large. The returned
** SrcList might be the same as the SrcList that was input or it might be
** a new one. If an OOM error does occurs, then the prior value of pList
** that is input to this routine is automatically freed.
@@ -109445,27 +111324,32 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
** before being added to the SrcList.
*/
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
- sqlite3 *db, /* Connection to notify of malloc failures */
+ Parse *pParse, /* Parsing context, in which errors are reported */
SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */
Token *pTable, /* Table to append */
Token *pDatabase /* Database of the table */
){
struct SrcList_item *pItem;
+ sqlite3 *db;
assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */
- assert( db!=0 );
+ assert( pParse!=0 );
+ assert( pParse->db!=0 );
+ db = pParse->db;
if( pList==0 ){
- pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) );
+ pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) );
if( pList==0 ) return 0;
pList->nAlloc = 1;
pList->nSrc = 1;
memset(&pList->a[0], 0, sizeof(pList->a[0]));
pList->a[0].iCursor = -1;
}else{
- pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
- }
- if( db->mallocFailed ){
- sqlite3SrcListDelete(db, pList);
- return 0;
+ SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc);
+ if( pNew==0 ){
+ sqlite3SrcListDelete(db, pList);
+ return 0;
+ }else{
+ pList = pNew;
+ }
}
pItem = &pList->a[pList->nSrc-1];
if( pDatabase && pDatabase->z==0 ){
@@ -109554,7 +111438,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
);
goto append_from_error;
}
- p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
+ p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase);
if( p==0 ){
goto append_from_error;
}
@@ -109874,7 +111758,8 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint(
StrAccum errMsg;
Table *pTab = pIdx->pTable;
- sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
+ sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0,
+ pParse->db->aLimit[SQLITE_LIMIT_LENGTH]);
if( pIdx->aColExpr ){
sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
}else{
@@ -109943,13 +111828,15 @@ static int collationMatch(const char *zColl, Index *pIndex){
*/
#ifndef SQLITE_OMIT_REINDEX
static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){
- Index *pIndex; /* An index associated with pTab */
+ if( !IsVirtual(pTab) ){
+ Index *pIndex; /* An index associated with pTab */
- for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
- if( zColl==0 || collationMatch(zColl, pIndex) ){
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3RefillIndex(pParse, pIndex, -1);
+ for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
+ if( zColl==0 || collationMatch(zColl, pIndex) ){
+ int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3RefillIndex(pParse, pIndex, -1);
+ }
}
}
}
@@ -110121,7 +112008,7 @@ SQLITE_PRIVATE With *sqlite3WithAdd(
}
if( pWith ){
- int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
+ sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
pNew = sqlite3DbRealloc(db, pWith, nByte);
}else{
pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
@@ -110448,7 +112335,7 @@ static int matchQuality(
** Search a FuncDefHash for a function with the given name. Return
** a pointer to the matching FuncDef if found, or 0 if there is no match.
*/
-static FuncDef *functionSearch(
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(
int h, /* Hash of the name */
const char *zFunc /* Name of function */
){
@@ -110473,9 +112360,9 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
FuncDef *pOther;
const char *zName = aDef[i].zName;
int nName = sqlite3Strlen30(zName);
- int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ;
+ int h = SQLITE_FUNC_HASH(zName[0], nName);
assert( zName[0]>='a' && zName[0]<='z' );
- pOther = functionSearch(h, zName);
+ pOther = sqlite3FunctionSearch(h, zName);
if( pOther ){
assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
aDef[i].pNext = pOther->pNext;
@@ -110552,8 +112439,8 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
*/
if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
bestScore = 0;
- h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
- p = functionSearch(h, zName);
+ h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
+ p = sqlite3FunctionSearch(h, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
@@ -110700,32 +112587,49 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
return pTab;
}
+/* Return true if table pTab is read-only.
+**
+** A table is read-only if any of the following are true:
+**
+** 1) It is a virtual table and no implementation of the xUpdate method
+** has been provided
+**
+** 2) It is a system table (i.e. sqlite_master), this call is not
+** part of a nested parse and writable_schema pragma has not
+** been specified
+**
+** 3) The table is a shadow table, the database connection is in
+** defensive mode, and the current sqlite3_prepare()
+** is for a top-level SQL statement.
+*/
+static int tabIsReadOnly(Parse *pParse, Table *pTab){
+ sqlite3 *db;
+ if( IsVirtual(pTab) ){
+ return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
+ }
+ if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
+ db = pParse->db;
+ if( (pTab->tabFlags & TF_Readonly)!=0 ){
+ return sqlite3WritableSchema(db)==0 && pParse->nested==0;
+ }
+ assert( pTab->tabFlags & TF_Shadow );
+ return (db->flags & SQLITE_Defensive)!=0
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ && db->pVtabCtx==0
+#endif
+ && db->nVdbeExec==0;
+}
+
/*
** Check to make sure the given table is writable. If it is not
** writable, generate an error message and return 1. If it is
** writable return 0;
*/
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
- /* A table is not writable under the following circumstances:
- **
- ** 1) It is a virtual table and no implementation of the xUpdate method
- ** has been provided, or
- ** 2) It is a system table (i.e. sqlite_master), this call is not
- ** part of a nested parse and writable_schema pragma has not
- ** been specified.
- **
- ** In either case leave an error message in pParse and return non-zero.
- */
- if( ( IsVirtual(pTab)
- && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
- || ( (pTab->tabFlags & TF_Readonly)!=0
- && (pParse->db->flags & SQLITE_WriteSchema)==0
- && pParse->nested==0 )
- ){
+ if( tabIsReadOnly(pParse, pTab) ){
sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
return 1;
}
-
#ifndef SQLITE_OMIT_VIEW
if( !viewOk && pTab->pSelect ){
sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
@@ -110756,7 +112660,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
sqlite3 *db = pParse->db;
int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
pWhere = sqlite3ExprDup(db, pWhere, 0);
- pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
+ pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
@@ -111156,7 +113060,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
/* If this DELETE cannot use the ONEPASS strategy, this is the
** end of the WHERE loop */
if( eOnePass!=ONEPASS_OFF ){
- addrBypass = sqlite3VdbeMakeLabel(v);
+ addrBypass = sqlite3VdbeMakeLabel(pParse);
}else{
sqlite3WhereEnd(pWInfo);
}
@@ -111345,7 +113249,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
/* Seek cursor iCur to the row to delete. If this row no longer exists
** (this can happen if a trigger program has already deleted it), do
** not attempt to delete it or fire any DELETE triggers. */
- iLabel = sqlite3VdbeMakeLabel(v);
+ iLabel = sqlite3VdbeMakeLabel(pParse);
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
if( eMode==ONEPASS_OFF ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
@@ -111551,7 +113455,7 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
- *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+ *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse);
pParse->iSelfTab = iDataCur + 1;
sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
SQLITE_JUMPIFNULL);
@@ -111622,6 +113526,7 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
/* #include "sqliteInt.h" */
/* #include */
/* #include */
+/* #include */
/* #include "vdbeInt.h" */
/*
@@ -111807,6 +113712,7 @@ static void instrFunc(
int typeHaystack, typeNeedle;
int N = 1;
int isText;
+ unsigned char firstChar;
UNUSED_PARAMETER(argc);
typeHaystack = sqlite3_value_type(argv[0]);
@@ -111825,7 +113731,10 @@ static void instrFunc(
isText = 1;
}
if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
- while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
+ firstChar = zNeedle[0];
+ while( nNeedle<=nHaystack
+ && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0)
+ ){
N++;
do{
nHaystack--;
@@ -111988,10 +113897,10 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
** handle the rounding directly,
** otherwise use printf.
*/
- if( n==0 && r>=0 && r+4503599627370496.0 ){
+ /* The value has no fractional part so there is nothing to round */
+ }else if( n==0 ){
+ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
}else{
zBuf = sqlite3_mprintf("%.*f",n,r);
if( zBuf==0 ){
@@ -112116,11 +114025,11 @@ static void randomBlob(
int argc,
sqlite3_value **argv
){
- int n;
+ sqlite3_int64 n;
unsigned char *p;
assert( argc==1 );
UNUSED_PARAMETER(argc);
- n = sqlite3_value_int(argv[0]);
+ n = sqlite3_value_int64(argv[0]);
if( n<1 ){
n = 1;
}
@@ -112445,8 +114354,6 @@ static void likeFunc(
return;
}
#endif
- zB = sqlite3_value_text(argv[0]);
- zA = sqlite3_value_text(argv[1]);
/* Limit the length of the LIKE or GLOB pattern to avoid problems
** of deep recursion and N*N behavior in patternCompare().
@@ -112458,8 +114365,6 @@ static void likeFunc(
sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
return;
}
- assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
-
if( argc==3 ){
/* The escape character string must consist of a single UTF-8 character.
** Otherwise, return an error.
@@ -112475,6 +114380,8 @@ static void likeFunc(
}else{
escape = pInfo->matchSet;
}
+ zB = sqlite3_value_text(argv[0]);
+ zA = sqlite3_value_text(argv[1]);
if( zA && zB ){
#ifdef SQLITE_TEST
sqlite3_like_count++;
@@ -113400,35 +115307,24 @@ SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
}
/*
-** Set the LIKEOPT flag on the 2-argument function with the given name.
-*/
-static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
- FuncDef *pDef;
- pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
- if( ALWAYS(pDef) ){
- pDef->funcFlags |= flagVal;
- }
-}
-
-/*
-** Register the built-in LIKE and GLOB functions. The caseSensitive
+** Re-register the built-in LIKE functions. The caseSensitive
** parameter determines whether or not the LIKE operator is case
-** sensitive. GLOB is always case sensitive.
+** sensitive.
*/
SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
struct compareInfo *pInfo;
+ int flags;
if( caseSensitive ){
pInfo = (struct compareInfo*)&likeInfoAlt;
+ flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE;
}else{
pInfo = (struct compareInfo*)&likeInfoNorm;
+ flags = SQLITE_FUNC_LIKE;
}
sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0);
- sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
- (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0);
- setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
- setLikeOptFlag(db, "like",
- caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
+ sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags;
+ sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags;
}
/*
@@ -113956,7 +115852,7 @@ static void fkLookupParent(
int i; /* Iterator variable */
Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */
int iCur = pParse->nTab - 1; /* Cursor number to use */
- int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */
+ int iOk = sqlite3VdbeMakeLabel(pParse); /* jump here if parent key found */
sqlite3VdbeVerifyAbortable(v,
(!pFKey->isDeferred
@@ -114129,7 +116025,7 @@ static Expr *exprTableColumn(
){
Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
if( pExpr ){
- pExpr->pTab = pTab;
+ pExpr->y.pTab = pTab;
pExpr->iTable = iCursor;
pExpr->iColumn = iCol;
}
@@ -114218,7 +116114,7 @@ static void fkScanChildren(
zCol = pFKey->pFrom->aCol[iCol].zName;
pRight = sqlite3Expr(db, TK_ID, zCol);
pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
}
/* If the child table is the same as the parent table, then add terms
@@ -114229,8 +116125,11 @@ static void fkScanChildren(
** NOT( $current_a==a AND $current_b==b AND ... )
**
** The first form is used for rowid tables. The second form is used
- ** for WITHOUT ROWID tables. In the second form, the primary key is
- ** (a,b,...)
+ ** for WITHOUT ROWID tables. In the second form, the *parent* key is
+ ** (a,b,...). Either the parent or primary key could be used to
+ ** uniquely identify the current row, but the parent key is more convenient
+ ** as the required values have already been loaded into registers
+ ** by the caller.
*/
if( pTab==pFKey->pFrom && nIncr>0 ){
Expr *pNe; /* Expression (pLeft != pRight) */
@@ -114242,19 +116141,18 @@ static void fkScanChildren(
pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
}else{
Expr *pEq, *pAll = 0;
- Index *pPk = sqlite3PrimaryKeyIndex(pTab);
assert( pIdx!=0 );
- for(i=0; inKeyCol; i++){
+ for(i=0; inKeyCol; i++){
i16 iCol = pIdx->aiColumn[i];
assert( iCol>=0 );
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
- pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
- pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
- pAll = sqlite3ExprAnd(db, pAll, pEq);
+ pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
+ pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
+ pAll = sqlite3ExprAnd(pParse, pAll, pEq);
}
pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
}
- pWhere = sqlite3ExprAnd(db, pWhere, pNe);
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pNe);
}
/* Resolve the references in the WHERE clause. */
@@ -114354,7 +116252,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
}
if( !p ) return;
- iSkip = sqlite3VdbeMakeLabel(v);
+ iSkip = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
}
@@ -114639,7 +116537,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
/* Create a SrcList structure containing the child table. We need the
** child table as a SrcList for sqlite3WhereBegin() */
- pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( pSrc ){
struct SrcList_item *pItem = pSrc->a;
pItem->pTab = pFKey->pFrom;
@@ -114860,7 +116758,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+ pWhere = sqlite3ExprAnd(pParse, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
** The final WHEN clause will be like this:
@@ -114876,7 +116774,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
);
- pWhen = sqlite3ExprAnd(db, pWhen, pEq);
+ pWhen = sqlite3ExprAnd(pParse, pWhen, pEq);
}
if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
@@ -114916,7 +116814,7 @@ static Trigger *fkActionTrigger(
}
pSelect = sqlite3SelectNew(pParse,
sqlite3ExprListAppend(pParse, 0, pRaise),
- sqlite3SrcListAppend(db, 0, &tFrom, 0),
+ sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
pWhere,
0, 0, 0, 0, 0
);
@@ -115205,7 +117103,8 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
}while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
pTab->zColAff = zColAff;
}
- i = sqlite3Strlen30(zColAff);
+ assert( zColAff!=0 );
+ i = sqlite3Strlen30NN(zColAff);
if( i ){
if( iReg ){
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
@@ -115377,6 +117276,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
aOp[7].p2 = memId+2;
aOp[7].p1 = memId;
aOp[10].p2 = memId;
+ if( pParse->nTab==0 ) pParse->nTab = 1;
}
}
@@ -115871,7 +117771,7 @@ SQLITE_PRIVATE void sqlite3Insert(
int nIdx;
nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0,
&iDataCur, &iIdxCur);
- aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1));
+ aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2));
if( aRegIdx==0 ){
goto insert_cleanup;
}
@@ -115880,9 +117780,15 @@ SQLITE_PRIVATE void sqlite3Insert(
aRegIdx[i] = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}
+ aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */
}
#ifndef SQLITE_OMIT_UPSERT
if( pUpsert ){
+ if( IsVirtual(pTab) ){
+ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"",
+ pTab->zName);
+ goto insert_cleanup;
+ }
pTabList->a[0].iCursor = iDataCur;
pUpsert->pUpsertSrc = pTabList;
pUpsert->regData = regData;
@@ -115923,7 +117829,7 @@ SQLITE_PRIVATE void sqlite3Insert(
/* Run the BEFORE and INSTEAD OF triggers, if there are any
*/
- endOfLoop = sqlite3VdbeMakeLabel(v);
+ endOfLoop = sqlite3VdbeMakeLabel(pParse);
if( tmask & TRIGGER_BEFORE ){
int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);
@@ -116005,16 +117911,12 @@ SQLITE_PRIVATE void sqlite3Insert(
}else if( pSelect ){
sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
}else{
- VdbeOp *pOp;
- sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
- pOp = sqlite3VdbeGetOp(v, -1);
- assert( pOp!=0 );
- if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){
+ Expr *pIpk = pList->a[ipkColumn].pExpr;
+ if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
appendFlag = 1;
- pOp->opcode = OP_NewRowid;
- pOp->p1 = iDataCur;
- pOp->p2 = regRowid;
- pOp->p3 = regAutoinc;
+ }else{
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
}
}
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
@@ -116185,14 +118087,15 @@ SQLITE_PRIVATE void sqlite3Insert(
#endif
/*
-** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
+** Meanings of bits in of pWalker->eCode for
+** sqlite3ExprReferencesUpdatedColumn()
*/
#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
-/* This is the Walker callback from checkConstraintUnchanged(). Set
-** bit 0x01 of pWalker->eCode if
-** pWalker->eCode to 0 if this expression node references any of the
+/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
+* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
+** expression node references any of the
** columns that are being modifed by an UPDATE statement.
*/
static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
@@ -116214,12 +118117,21 @@ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
** only columns that are modified by the UPDATE are those for which
** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
**
-** Return true if CHECK constraint pExpr does not use any of the
+** Return true if CHECK constraint pExpr uses any of the
** changing columns (or the rowid if it is changing). In other words,
-** return true if this CHECK constraint can be skipped when validating
+** return true if this CHECK constraint must be validated for
** the new row in the UPDATE statement.
+**
+** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
+** The operation of this routine is the same - return true if an only if
+** the expression uses one or more of columns identified by the second and
+** third arguments.
*/
-static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
+ Expr *pExpr, /* The expression to be checked */
+ int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */
+ int chngRowid /* True if UPDATE changes the rowid */
+){
Walker w;
memset(&w, 0, sizeof(w));
w.eCode = 0;
@@ -116234,7 +118146,7 @@ static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
testcase( w.eCode==CKCNSTRNT_COLUMN );
testcase( w.eCode==CKCNSTRNT_ROWID );
testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
- return !w.eCode;
+ return w.eCode!=0;
}
/*
@@ -116272,6 +118184,14 @@ static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
** the same as the order of indices on the linked list of indices
** at pTab->pIndex.
**
+** (2019-05-07) The generated code also creates a new record for the
+** main table, if pTab is a rowid table, and stores that record in the
+** register identified by aRegIdx[nIdx] - in other words in the first
+** entry of aRegIdx[] past the last index. It is important that the
+** record be generated during constraint checks to avoid affinity changes
+** to the register content that occur after constraint checks but before
+** the new record is inserted.
+**
** The caller must have already opened writeable cursors on the main
** table and all applicable indices (that is to say, all indices for which
** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
@@ -116399,7 +118319,20 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|| onError==OE_Ignore || onError==OE_Replace );
+ addr1 = 0;
switch( onError ){
+ case OE_Replace: {
+ assert( onError==OE_Replace );
+ addr1 = sqlite3VdbeMakeLabel(pParse);
+ sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
+ VdbeCoverage(v);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
+ sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
+ VdbeCoverage(v);
+ onError = OE_Abort;
+ /* Fall through into the OE_Abort case to generate code that runs
+ ** if both the input and the default value are NULL */
+ }
case OE_Abort:
sqlite3MayAbort(pParse);
/* Fall through */
@@ -116412,21 +118345,15 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
VdbeCoverage(v);
+ if( addr1 ) sqlite3VdbeResolveLabel(v, addr1);
break;
}
- case OE_Ignore: {
+ default: {
+ assert( onError==OE_Ignore );
sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
VdbeCoverage(v);
break;
}
- default: {
- assert( onError==OE_Replace );
- addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
- VdbeCoverage(v);
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
- sqlite3VdbeJumpHere(v, addr1);
- break;
- }
}
}
@@ -116440,8 +118367,14 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
for(i=0; inExpr; i++){
int allOk;
Expr *pExpr = pCheck->a[i].pExpr;
- if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
- allOk = sqlite3VdbeMakeLabel(v);
+ if( aiChng
+ && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
+ ){
+ /* The check constraints do not reference any of the columns being
+ ** updated so there is no point it verifying the check constraint */
+ continue;
+ }
+ allOk = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeVerifyAbortable(v, onError);
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
@@ -116449,7 +118382,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}else{
char *zName = pCheck->a[i].zName;
if( zName==0 ) zName = pTab->zName;
- if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
+ if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
onError, zName, P4_TRANSIENT,
P5_ConstraintCheck);
@@ -116508,7 +118441,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** exist in the table.
*/
if( pkChng && pPk==0 ){
- int addrRowidOk = sqlite3VdbeMakeLabel(v);
+ int addrRowidOk = sqlite3VdbeMakeLabel(pParse);
/* Figure out what action to take in case of a rowid collision */
onError = pTab->keyConf;
@@ -116658,7 +118591,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
VdbeComment((v, "Skip upsert subroutine"));
sqlite3VdbeJumpHere(v, upsertJump);
}else{
- addrUniqueOk = sqlite3VdbeMakeLabel(v);
+ addrUniqueOk = sqlite3VdbeMakeLabel(pParse);
}
if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
sqlite3TableAffinity(v, pTab, regNewData+1);
@@ -116702,7 +118635,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
VdbeComment((v, "for %s", pIdx->zName));
#ifdef SQLITE_ENABLE_NULL_TRIM
- if( pIdx->idxType==2 ) sqlite3SetMakeRecordP5(v, pIdx->pTable);
+ if( pIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
+ sqlite3SetMakeRecordP5(v, pIdx->pTable);
+ }
#endif
/* In an UPDATE operation, if this index is the PRIMARY KEY index
@@ -116741,7 +118676,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** (3) There are no secondary indexes on the table
** (4) No delete triggers need to be fired if there is a conflict
** (5) No FK constraint counters need to be updated if a conflict occurs.
- */
+ **
+ ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row
+ ** must be explicitly deleted in order to ensure any pre-update hook
+ ** is invoked. */
+#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
&& pPk==pIdx /* Condition 2 */
&& onError==OE_Replace /* Condition 1 */
@@ -116753,6 +118692,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeResolveLabel(v, addrUniqueOk);
continue;
}
+#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */
/* Check to see if the new index entry will be unique */
sqlite3VdbeVerifyAbortable(v, onError);
@@ -116866,11 +118806,21 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
/* If the IPK constraint is a REPLACE, run it last */
if( ipkTop ){
- sqlite3VdbeGoto(v, ipkTop+1);
+ sqlite3VdbeGoto(v, ipkTop);
VdbeComment((v, "Do IPK REPLACE"));
sqlite3VdbeJumpHere(v, ipkBottom);
}
+ /* Generate the table record */
+ if( HasRowid(pTab) ){
+ int regRec = aRegIdx[ix];
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec);
+ sqlite3SetMakeRecordP5(v, pTab);
+ if( !bAffinityDone ){
+ sqlite3TableAffinity(v, pTab, 0);
+ }
+ }
+
*pbMayReplace = seenReplace;
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
@@ -116920,10 +118870,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
Vdbe *v; /* Prepared statements under construction */
Index *pIdx; /* An index being inserted or updated */
u8 pik_flags; /* flag values passed to the btree insert */
- int regData; /* Content registers (after the rowid) */
- int regRec; /* Register holding assembled record for the table */
int i; /* Loop counter */
- u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
assert( update_flags==0
|| update_flags==OPFLAG_ISUPDATE
@@ -116935,7 +118882,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
- bAffinityDone = 1;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
@@ -116947,10 +118893,13 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
if( update_flags==0 ){
- sqlite3VdbeAddOp4(v, OP_InsertInt,
- iIdxCur+i, aRegIdx[i], 0, (char*)pTab, P4_TABLE
+ int r = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, r);
+ sqlite3VdbeAddOp4(v, OP_Insert,
+ iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE
);
sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP);
+ sqlite3ReleaseTempReg(pParse, r);
}
#endif
}
@@ -116960,13 +118909,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
sqlite3VdbeChangeP5(v, pik_flags);
}
if( !HasRowid(pTab) ) return;
- regData = regNewData + 1;
- regRec = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
- sqlite3SetMakeRecordP5(v, pTab);
- if( !bAffinityDone ){
- sqlite3TableAffinity(v, pTab, 0);
- }
if( pParse->nested ){
pik_flags = 0;
}else{
@@ -116979,7 +118921,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
if( useSeekResult ){
pik_flags |= OPFLAG_USESEEKRESULT;
}
- sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
+ sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData);
if( !pParse->nested ){
sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
@@ -117236,7 +119178,8 @@ static int xferOptimization(
if( pSrc==0 ){
return 0; /* FROM clause does not contain a real table */
}
- if( pSrc==pDest ){
+ if( pSrc->tnum==pDest->tnum && pSrc->pSchema==pDest->pSchema ){
+ testcase( pSrc!=pDest ); /* Possible due to bad sqlite_master.rootpage */
return 0; /* tab1 and tab2 may not be the same table */
}
if( HasRowid(pDest)!=HasRowid(pSrc) ){
@@ -117297,6 +119240,13 @@ static int xferOptimization(
if( pSrcIdx==0 ){
return 0; /* pDestIdx has no corresponding index in pSrc */
}
+ if( pSrcIdx->tnum==pDestIdx->tnum && pSrc->pSchema==pDest->pSchema
+ && sqlite3FaultSim(411)==SQLITE_OK ){
+ /* The sqlite3FaultSim() call allows this corruption test to be
+ ** bypassed during testing, in order to exercise other corruption tests
+ ** further downstream. */
+ return 0; /* Corrupt schema - two indexes on the same btree */
+ }
}
#ifndef SQLITE_OMIT_CHECK
if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
@@ -117374,7 +119324,7 @@ static int xferOptimization(
sqlite3RowidConstraint(pParse, onError, pDest);
sqlite3VdbeJumpHere(v, addr2);
autoIncStep(pParse, regAutoinc, regRowid);
- }else if( pDest->pIndex==0 ){
+ }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
}else{
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
@@ -117437,7 +119387,7 @@ static int xferOptimization(
sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
}
}
- if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
+ if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
idxInsFlags |= OPFLAG_NCHANGE;
}
sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
@@ -117512,7 +119462,7 @@ SQLITE_API int sqlite3_exec(
sqlite3_mutex_enter(db->mutex);
sqlite3Error(db, SQLITE_OK);
while( rc==SQLITE_OK && zSql[0] ){
- int nCol;
+ int nCol = 0;
char **azVals = 0;
pStmt = 0;
@@ -117526,9 +119476,7 @@ SQLITE_API int sqlite3_exec(
zSql = zLeftover;
continue;
}
-
callbackIsInit = 0;
- nCol = sqlite3_column_count(pStmt);
while( 1 ){
int i;
@@ -117539,6 +119487,7 @@ SQLITE_API int sqlite3_exec(
(SQLITE_DONE==rc && !callbackIsInit
&& db->flags&SQLITE_NullCallback)) ){
if( !callbackIsInit ){
+ nCol = sqlite3_column_count(pStmt);
azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
if( azCols==0 ){
goto exec_out;
@@ -117941,12 +119890,18 @@ struct sqlite3_api_routines {
int (*str_errcode)(sqlite3_str*);
int (*str_length)(sqlite3_str*);
char *(*str_value)(sqlite3_str*);
+ /* Version 3.25.0 and later */
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
void(*xDestroy)(void*));
+ /* Version 3.26.0 and later */
+ const char *(*normalized_sql)(sqlite3_stmt*);
+ /* Version 3.28.0 and later */
+ int (*stmt_isexplain)(sqlite3_stmt*);
+ int (*value_frombind)(sqlite3_value*);
};
/*
@@ -118234,6 +120189,11 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_str_value sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
+/* Version 3.26.0 and later */
+#define sqlite3_normalized_sql sqlite3_api->normalized_sql
+/* Version 3.28.0 and later */
+#define sqlite3_stmt_isexplain sqlite3_api->isexplain
+#define sqlite3_value_frombind sqlite3_api->frombind
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -118322,6 +120282,7 @@ typedef int (*sqlite3_loadext_entry)(
# define sqlite3_declare_vtab 0
# define sqlite3_vtab_config 0
# define sqlite3_vtab_on_conflict 0
+# define sqlite3_vtab_collation 0
#endif
#ifdef SQLITE_OMIT_SHARED_CACHE
@@ -118689,7 +120650,16 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_str_length,
sqlite3_str_value,
/* Version 3.25.0 and later */
- sqlite3_create_window_function
+ sqlite3_create_window_function,
+ /* Version 3.26.0 and later */
+#ifdef SQLITE_ENABLE_NORMALIZE
+ sqlite3_normalized_sql,
+#else
+ 0,
+#endif
+ /* Version 3.28.0 and later */
+ sqlite3_stmt_isexplain,
+ sqlite3_value_frombind
};
/*
@@ -118881,7 +120851,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
if( onoff ){
db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
}else{
- db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
+ db->flags &= ~(u64)(SQLITE_LoadExtension|SQLITE_LoadExtFunc);
}
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
@@ -119137,12 +121107,9 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#define PragTyp_WAL_AUTOCHECKPOINT 38
#define PragTyp_WAL_CHECKPOINT 39
#define PragTyp_ACTIVATE_EXTENSIONS 40
-#define PragTyp_HEXKEY 41
-#define PragTyp_KEY 42
-#define PragTyp_REKEY 43
-#define PragTyp_LOCK_STATUS 44
-#define PragTyp_PARSER_TRACE 45
-#define PragTyp_STATS 46
+#define PragTyp_KEY 41
+#define PragTyp_LOCK_STATUS 42
+#define PragTyp_STATS 43
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
@@ -119159,58 +121126,57 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
** result column is different from the name of the pragma
*/
static const char *const pragCName[] = {
- /* 0 */ "cache_size", /* Used by: default_cache_size */
- /* 1 */ "cid", /* Used by: table_info */
- /* 2 */ "name",
- /* 3 */ "type",
- /* 4 */ "notnull",
- /* 5 */ "dflt_value",
- /* 6 */ "pk",
- /* 7 */ "tbl", /* Used by: stats */
- /* 8 */ "idx",
- /* 9 */ "wdth",
- /* 10 */ "hght",
- /* 11 */ "flgs",
- /* 12 */ "seqno", /* Used by: index_info */
- /* 13 */ "cid",
- /* 14 */ "name",
+ /* 0 */ "id", /* Used by: foreign_key_list */
+ /* 1 */ "seq",
+ /* 2 */ "table",
+ /* 3 */ "from",
+ /* 4 */ "to",
+ /* 5 */ "on_update",
+ /* 6 */ "on_delete",
+ /* 7 */ "match",
+ /* 8 */ "cid", /* Used by: table_xinfo */
+ /* 9 */ "name",
+ /* 10 */ "type",
+ /* 11 */ "notnull",
+ /* 12 */ "dflt_value",
+ /* 13 */ "pk",
+ /* 14 */ "hidden",
+ /* table_info reuses 8 */
/* 15 */ "seqno", /* Used by: index_xinfo */
/* 16 */ "cid",
/* 17 */ "name",
/* 18 */ "desc",
/* 19 */ "coll",
/* 20 */ "key",
- /* 21 */ "seq", /* Used by: index_list */
- /* 22 */ "name",
- /* 23 */ "unique",
- /* 24 */ "origin",
- /* 25 */ "partial",
- /* 26 */ "seq", /* Used by: database_list */
+ /* 21 */ "tbl", /* Used by: stats */
+ /* 22 */ "idx",
+ /* 23 */ "wdth",
+ /* 24 */ "hght",
+ /* 25 */ "flgs",
+ /* 26 */ "seq", /* Used by: index_list */
/* 27 */ "name",
- /* 28 */ "file",
- /* 29 */ "name", /* Used by: function_list */
- /* 30 */ "builtin",
- /* 31 */ "name", /* Used by: module_list pragma_list */
- /* 32 */ "seq", /* Used by: collation_list */
- /* 33 */ "name",
- /* 34 */ "id", /* Used by: foreign_key_list */
- /* 35 */ "seq",
- /* 36 */ "table",
- /* 37 */ "from",
- /* 38 */ "to",
- /* 39 */ "on_update",
- /* 40 */ "on_delete",
- /* 41 */ "match",
- /* 42 */ "table", /* Used by: foreign_key_check */
- /* 43 */ "rowid",
- /* 44 */ "parent",
- /* 45 */ "fkid",
- /* 46 */ "busy", /* Used by: wal_checkpoint */
- /* 47 */ "log",
- /* 48 */ "checkpointed",
- /* 49 */ "timeout", /* Used by: busy_timeout */
- /* 50 */ "database", /* Used by: lock_status */
- /* 51 */ "status",
+ /* 28 */ "unique",
+ /* 29 */ "origin",
+ /* 30 */ "partial",
+ /* 31 */ "table", /* Used by: foreign_key_check */
+ /* 32 */ "rowid",
+ /* 33 */ "parent",
+ /* 34 */ "fkid",
+ /* index_info reuses 15 */
+ /* 35 */ "seq", /* Used by: database_list */
+ /* 36 */ "name",
+ /* 37 */ "file",
+ /* 38 */ "busy", /* Used by: wal_checkpoint */
+ /* 39 */ "log",
+ /* 40 */ "checkpointed",
+ /* 41 */ "name", /* Used by: function_list */
+ /* 42 */ "builtin",
+ /* collation_list reuses 26 */
+ /* 43 */ "database", /* Used by: lock_status */
+ /* 44 */ "status",
+ /* 45 */ "cache_size", /* Used by: default_cache_size */
+ /* module_list pragma_list reuses 9 */
+ /* 46 */ "timeout", /* Used by: busy_timeout */
};
/* Definitions of all built-in pragmas */
@@ -119220,7 +121186,7 @@ typedef struct PragmaName {
u8 mPragFlg; /* Zero or more PragFlg_XXX values */
u8 iPragCName; /* Start of column names in pragCName[] */
u8 nPragCName; /* Num of col names. 0 means use pragma name */
- u32 iArg; /* Extra argument */
+ u64 iArg; /* Extra argument */
} PragmaName;
static const PragmaName aPragmaName[] = {
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
@@ -119256,7 +121222,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "busy_timeout",
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 49, 1,
+ /* ColNames: */ 46, 1,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "cache_size",
@@ -119272,11 +121238,13 @@ static const PragmaName aPragmaName[] = {
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
{/* zName: */ "case_sensitive_like",
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
/* ePragFlg: */ PragFlg_NoColumns,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
+#endif
{/* zName: */ "cell_size_check",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119293,7 +121261,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "collation_list",
/* ePragTyp: */ PragTyp_COLLATION_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 32, 2,
+ /* ColNames: */ 26, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
@@ -119328,14 +121296,14 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "database_list",
/* ePragTyp: */ PragTyp_DATABASE_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
- /* ColNames: */ 26, 3,
+ /* ColNames: */ 35, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
{/* zName: */ "default_cache_size",
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
- /* ColNames: */ 0, 1,
+ /* ColNames: */ 45, 1,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -119365,14 +121333,14 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "foreign_key_check",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
- /* ColNames: */ 42, 4,
+ /* ColNames: */ 31, 4,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
{/* zName: */ "foreign_key_list",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 34, 8,
+ /* ColNames: */ 0, 8,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -119408,21 +121376,21 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "function_list",
/* ePragTyp: */ PragTyp_FUNCTION_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 29, 2,
+ /* ColNames: */ 41, 2,
/* iArg: */ 0 },
#endif
#endif
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "hexkey",
- /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* iArg: */ 2 },
{/* zName: */ "hexrekey",
- /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* iArg: */ 3 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_CHECK)
@@ -119444,12 +121412,12 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "index_info",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 12, 3,
+ /* ColNames: */ 15, 3,
/* iArg: */ 0 },
{/* zName: */ "index_list",
/* ePragTyp: */ PragTyp_INDEX_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 21, 5,
+ /* ColNames: */ 26, 5,
/* iArg: */ 0 },
{/* zName: */ "index_xinfo",
/* ePragTyp: */ PragTyp_INDEX_INFO,
@@ -119506,7 +121474,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "lock_status",
/* ePragTyp: */ PragTyp_LOCK_STATUS,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 50, 2,
+ /* ColNames: */ 43, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -119532,7 +121500,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "module_list",
/* ePragTyp: */ PragTyp_MODULE_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 31, 1,
+ /* ColNames: */ 9, 1,
/* iArg: */ 0 },
#endif
#endif
@@ -119554,18 +121522,20 @@ static const PragmaName aPragmaName[] = {
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
#endif
-#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
{/* zName: */ "parser_trace",
- /* ePragTyp: */ PragTyp_PARSER_TRACE,
- /* ePragFlg: */ 0,
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* iArg: */ SQLITE_ParserTrace },
+#endif
#endif
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
{/* zName: */ "pragma_list",
/* ePragTyp: */ PragTyp_PRAGMA_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 31, 1,
+ /* ColNames: */ 9, 1,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -119596,10 +121566,10 @@ static const PragmaName aPragmaName[] = {
#endif
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "rekey",
- /* ePragTyp: */ PragTyp_REKEY,
+ /* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "reverse_unordered_selects",
@@ -119652,7 +121622,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "stats",
/* ePragTyp: */ PragTyp_STATS,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 7, 5,
+ /* ColNames: */ 21, 5,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -119666,8 +121636,13 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "table_info",
/* ePragTyp: */ PragTyp_TABLE_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 1, 6,
+ /* ColNames: */ 8, 6,
/* iArg: */ 0 },
+ {/* zName: */ "table_xinfo",
+ /* ePragTyp: */ PragTyp_TABLE_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 8, 7,
+ /* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "temp_store",
@@ -119680,6 +121655,18 @@ static const PragmaName aPragmaName[] = {
/* ePragFlg: */ PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "textkey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 4 },
+ {/* zName: */ "textrekey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 5 },
#endif
{/* zName: */ "threads",
/* ePragTyp: */ PragTyp_THREADS,
@@ -119731,7 +121718,7 @@ static const PragmaName aPragmaName[] = {
{/* zName: */ "wal_checkpoint",
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
/* ePragFlg: */ PragFlg_NeedSchema,
- /* ColNames: */ 46, 3,
+ /* ColNames: */ 38, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
@@ -119739,10 +121726,10 @@ static const PragmaName aPragmaName[] = {
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_WriteSchema },
+ /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
-/* Number of pragmas: 61 on by default, 78 total. */
+/* Number of pragmas: 62 on by default, 81 total. */
/************** End of pragma.h **********************************************/
/************** Continuing where we left off in pragma.c *********************/
@@ -120361,6 +122348,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
** then do a query */
eMode = PAGER_JOURNALMODE_QUERY;
}
+ if( eMode==PAGER_JOURNALMODE_OFF && (db->flags & SQLITE_Defensive)!=0 ){
+ /* Do not allow journal-mode "OFF" in defensive since the database
+ ** can become corrupted using ordinary SQL when the journal is off */
+ eMode = PAGER_JOURNALMODE_QUERY;
+ }
}
if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
/* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
@@ -120533,7 +122525,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( sqlite3GetBoolean(zRight, size!=0) ){
db->flags |= SQLITE_CacheSpill;
}else{
- db->flags &= ~SQLITE_CacheSpill;
+ db->flags &= ~(u64)SQLITE_CacheSpill;
}
setAllPagerFlags(db);
}
@@ -120754,7 +122746,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
setPragmaResultColumnNames(v, pPragma);
returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
}else{
- int mask = pPragma->iArg; /* Mask of bits to set or clear. */
+ u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */
if( db->autoCommit==0 ){
/* Foreign key support may not be enabled or disabled while not
** in auto-commit mode. */
@@ -120803,15 +122795,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
Table *pTab;
pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
if( pTab ){
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
int i, k;
int nHidden = 0;
Column *pCol;
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
- pParse->nMem = 6;
- sqlite3CodeVerifySchema(pParse, iDb);
+ pParse->nMem = 7;
+ sqlite3CodeVerifySchema(pParse, iTabDb);
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){
- if( IsHiddenColumn(pCol) ){
+ int isHidden = IsHiddenColumn(pCol);
+ if( isHidden && pPragma->iArg==0 ){
nHidden++;
continue;
}
@@ -120823,13 +122817,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
- sqlite3VdbeMultiLoad(v, 1, "issisi",
+ sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
i-nHidden,
pCol->zName,
sqlite3ColumnType(pCol,""),
pCol->notNull ? 1 : 0,
pCol->pDflt ? pCol->pDflt->u.zToken : 0,
- k);
+ k,
+ isHidden);
}
}
}
@@ -120867,6 +122862,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
Table *pTab;
pIdx = sqlite3FindIndex(db, zRight, zDb);
if( pIdx ){
+ int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
int i;
int mx;
if( pPragma->iArg ){
@@ -120879,7 +122875,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
pParse->nMem = 3;
}
pTab = pIdx->pTable;
- sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3CodeVerifySchema(pParse, iIdxDb);
assert( pParse->nMem<=pPragma->nPragCName );
for(i=0; iaiColumn[i];
@@ -120903,8 +122899,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
int i;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pParse->nMem = 5;
- sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3CodeVerifySchema(pParse, iTabDb);
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
const char *azOrigin[] = { "c", "u", "pk" };
sqlite3VdbeMultiLoad(v, 1, "isisi",
@@ -120951,6 +122948,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
pParse->nMem = 2;
for(i=0; iu.pHash ){
+ if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
}
}
@@ -120992,9 +122990,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( pTab ){
pFK = pTab->pFKey;
if( pFK ){
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
int i = 0;
pParse->nMem = 8;
- sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3CodeVerifySchema(pParse, iTabDb);
while(pFK){
int j;
for(j=0; jnCol; j++){
@@ -121039,9 +123038,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
pParse->nMem += 4;
regKey = ++pParse->nMem;
regRow = ++pParse->nMem;
- sqlite3CodeVerifySchema(pParse, iDb);
k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
while( k ){
+ int iTabDb;
if( zRight ){
pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
k = 0;
@@ -121050,21 +123049,23 @@ SQLITE_PRIVATE void sqlite3Pragma(
k = sqliteHashNext(k);
}
if( pTab==0 || pTab->pFKey==0 ) continue;
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+ iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ sqlite3CodeVerifySchema(pParse, iTabDb);
+ sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName);
if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
- sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
+ sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead);
sqlite3VdbeLoadString(v, regResult, pTab->zName);
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
if( pParent==0 ) continue;
pIdx = 0;
- sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
+ sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName);
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
if( x==0 ){
if( pIdx==0 ){
- sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
+ sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead);
}else{
- sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
+ sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
}
}else{
@@ -121084,7 +123085,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
assert( x==0 );
}
- addrOk = sqlite3VdbeMakeLabel(v);
+ addrOk = sqlite3VdbeMakeLabel(pParse);
/* Generate code to read the child key values into registers
** regRow..regRow+n. If any of the child key values are NULL, this
@@ -121129,19 +123130,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
-#ifndef NDEBUG
- case PragTyp_PARSER_TRACE: {
- if( zRight ){
- if( sqlite3GetBoolean(zRight, 0) ){
- sqlite3ParserTrace(stdout, "parser: ");
- }else{
- sqlite3ParserTrace(0, 0);
- }
- }
- }
- break;
-#endif
-
+#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/
@@ -121151,6 +123140,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
break;
+#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
@@ -121304,8 +123294,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
if( db->mallocFailed==0 ){
- int addrCkFault = sqlite3VdbeMakeLabel(v);
- int addrCkOk = sqlite3VdbeMakeLabel(v);
+ int addrCkFault = sqlite3VdbeMakeLabel(pParse);
+ int addrCkOk = sqlite3VdbeMakeLabel(pParse);
char *zErr;
int k;
pParse->iSelfTab = iDataCur + 1;
@@ -121328,7 +123318,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Validate index entries for the current row */
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4, jmp5;
- int ckUniq = sqlite3VdbeMakeLabel(v);
+ int ckUniq = sqlite3VdbeMakeLabel(pParse);
if( pPk==pIdx ) continue;
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
pPrior, r1);
@@ -121349,7 +123339,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** current key. The entry is unique if (1) any column is NULL
** or (2) the next entry has a different key */
if( IsUniqueIndex(pIdx) ){
- int uniqOk = sqlite3VdbeMakeLabel(v);
+ int uniqOk = sqlite3VdbeMakeLabel(pParse);
int jmp6;
int kk;
for(kk=0; kknKeyCol; kk++){
@@ -121833,27 +123823,41 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif
#ifdef SQLITE_HAS_CODEC
+ /* Pragma iArg
+ ** ---------- ------
+ ** key 0
+ ** rekey 1
+ ** hexkey 2
+ ** hexrekey 3
+ ** textkey 4
+ ** textrekey 5
+ */
case PragTyp_KEY: {
- if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
- break;
- }
- case PragTyp_REKEY: {
- if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
- break;
- }
- case PragTyp_HEXKEY: {
if( zRight ){
- u8 iByte;
- int i;
- char zKey[40];
- for(i=0, iByte=0; iiArg==2 || pPragma->iArg==3 ){
+ u8 iByte;
+ int i;
+ for(i=0, iByte=0; iiArg<4 ? sqlite3Strlen30(zRight) : -1;
}
- if( (zLeft[3] & 0xf)==0xb ){
- sqlite3_key_v2(db, zDb, zKey, i/2);
+ if( (pPragma->iArg & 1)==0 ){
+ rc = sqlite3_key_v2(db, zDb, zKey, n);
}else{
- sqlite3_rekey_v2(db, zDb, zKey, i/2);
+ rc = sqlite3_rekey_v2(db, zDb, zKey, n);
+ }
+ if( rc==SQLITE_OK && n!=0 ){
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC);
+ returnSingleText(v, "ok");
}
}
break;
@@ -122180,7 +124184,8 @@ static const sqlite3_module pragmaVtabModule = {
0, /* xRename - rename the table */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
+ 0 /* xShadowName */
};
/*
@@ -122250,6 +124255,19 @@ static void corruptSchema(
}
}
+/*
+** Check to see if any sibling index (another index on the same table)
+** of pIndex has the same root page number, and if it does, return true.
+** This would indicate a corrupt schema.
+*/
+SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index *pIndex){
+ Index *p;
+ for(p=pIndex->pTable->pIndex; p; p=p->pNext){
+ if( p->tnum==pIndex->tnum && p!=pIndex ) return 1;
+ }
+ return 0;
+}
+
/*
** This is the callback routine for the code that initializes the
** database. See sqlite3Init() below for additional information.
@@ -122271,6 +124289,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
UNUSED_PARAMETER2(NotUsed, argc);
assert( sqlite3_mutex_held(db->mutex) );
DbClearProperty(db, iDb, DB_Empty);
+ pData->nInitRow++;
if( db->mallocFailed ){
corruptSchema(pData, argv[0], 0);
return 1;
@@ -122324,15 +124343,12 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
*/
Index *pIndex;
pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
- if( pIndex==0 ){
- /* This can occur if there exists an index on a TEMP table which
- ** has the same name as another index on a permanent index. Since
- ** the permanent table is hidden by the TEMP table, we can also
- ** safely ignore the index on the permanent table.
- */
- /* Do Nothing */;
- }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){
- corruptSchema(pData, argv[0], "invalid rootpage");
+ if( pIndex==0
+ || sqlite3GetInt32(argv[1],&pIndex->tnum)==0
+ || pIndex->tnum<2
+ || sqlite3IndexHasDuplicateRootPage(pIndex)
+ ){
+ corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index");
}
}
return 0;
@@ -122382,6 +124398,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
initData.rc = SQLITE_OK;
initData.pzErrMsg = pzErrMsg;
initData.mInitFlags = mFlags;
+ initData.nInitRow = 0;
sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
if( initData.rc ){
rc = initData.rc;
@@ -122499,7 +124516,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
** indices that the user might have created.
*/
if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
- db->flags &= ~SQLITE_LegacyFileFmt;
+ db->flags &= ~(u64)SQLITE_LegacyFileFmt;
}
/* Read the schema information out of the schema tables
@@ -122533,8 +124550,8 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
rc = SQLITE_NOMEM_BKPT;
sqlite3ResetAllSchemasOfConnection(db);
}
- if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
- /* Black magic: If the SQLITE_WriteSchema flag is set, then consider
+ if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
+ /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
** the schema loaded, even if errors occurred. In this situation the
** current sqlite3_prepare() operation will fail, but the following one
** will attempt to compile the supplied statement against whatever subset
@@ -122751,6 +124768,7 @@ static int sqlite3Prepare(
sParse.disableLookaside++;
db->lookaside.bDisable++;
}
+ sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;
/* Check to verify that it is possible to get a read lock on all
** database schemas. The inability to get a read lock indicates that
@@ -122915,6 +124933,7 @@ static int sqlite3LockAndPrepare(
return rc;
}
+
/*
** Rerun the compilation of a statement after a schema change.
**
@@ -123479,7 +125498,7 @@ static void addWhereTerm(
ExprSetVVAProperty(pEq, EP_NoReduce);
pEq->iRightJoinTable = (i16)pE2->iTable;
}
- *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
+ *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
}
/*
@@ -123613,7 +125632,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
*/
if( pRight->pOn ){
if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
- p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
+ p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
pRight->pOn = 0;
}
@@ -123755,7 +125774,7 @@ static void pushOntoSorter(
}
assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
- pSort->labelDone = sqlite3VdbeMakeLabel(v);
+ pSort->labelDone = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
if( bSeq ){
@@ -123794,7 +125813,7 @@ static void pushOntoSorter(
pKI->nAllField-pKI->nKeyField-1);
addrJmp = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
- pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
+ pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse);
pSort->regReturn = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
@@ -123927,7 +125946,7 @@ static void selectExprDefer(
struct ExprList_item *pItem = &pEList->a[i];
if( pItem->u.x.iOrderByCol==0 ){
Expr *pExpr = pItem->pExpr;
- Table *pTab = pExpr->pTab;
+ Table *pTab = pExpr->y.pTab;
if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
&& (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
){
@@ -123950,12 +125969,12 @@ static void selectExprDefer(
Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
if( pNew ){
pNew->iTable = pExpr->iTable;
- pNew->pTab = pExpr->pTab;
+ pNew->y.pTab = pExpr->y.pTab;
pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
}
}
- pSort->aDefer[nDefer].pTab = pExpr->pTab;
+ pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
pSort->aDefer[nDefer].iCsr = pExpr->iTable;
pSort->aDefer[nDefer].nKey = nKey;
nDefer++;
@@ -124541,7 +126560,7 @@ static void generateSortTail(
){
Vdbe *v = pParse->pVdbe; /* The prepared statement */
int addrBreak = pSort->labelDone; /* Jump here to exit loop */
- int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
+ int addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */
int addr; /* Top of output loop. Jump for Next. */
int addrOnce = 0;
int iTab;
@@ -124581,7 +126600,12 @@ static void generateSortTail(
regRow = pDest->iSdst;
}else{
regRowid = sqlite3GetTempReg(pParse);
- regRow = sqlite3GetTempRange(pParse, nColumn);
+ if( eDest==SRT_EphemTab || eDest==SRT_Table ){
+ regRow = sqlite3GetTempReg(pParse);
+ nColumn = 0;
+ }else{
+ regRow = sqlite3GetTempRange(pParse, nColumn);
+ }
}
nKey = pOrderBy->nExpr - pSort->nOBSat;
if( pSort->sortFlags & SORTFLAG_UseSorter ){
@@ -124661,6 +126685,7 @@ static void generateSortTail(
switch( eDest ){
case SRT_Table:
case SRT_EphemTab: {
+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow);
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -124804,7 +126829,7 @@ static const char *columnTypeImpl(
break;
}
- assert( pTab && pExpr->pTab==pTab );
+ assert( pTab && pExpr->y.pTab==pTab );
if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
@@ -124989,7 +127014,7 @@ static void generateColumnNames(
assert( p!=0 );
assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
- assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
+ assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
if( pEList->a[i].zName ){
/* An AS clause always takes first priority */
char *zName = pEList->a[i].zName;
@@ -124997,7 +127022,7 @@ static void generateColumnNames(
}else if( srcName && p->op==TK_COLUMN ){
char *zCol;
int iCol = p->iColumn;
- pTab = p->pTab;
+ pTab = p->y.pTab;
assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iColnCol) );
@@ -125088,7 +127113,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
if( pColExpr->op==TK_COLUMN ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
- Table *pTab = pColExpr->pTab;
+ Table *pTab = pColExpr->y.pTab;
assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
@@ -125201,22 +127226,19 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
Table *pTab;
sqlite3 *db = pParse->db;
- int savedFlags;
+ u64 savedFlags;
savedFlags = db->flags;
- db->flags &= ~SQLITE_FullColNames;
+ db->flags &= ~(u64)SQLITE_FullColNames;
db->flags |= SQLITE_ShortColNames;
sqlite3SelectPrep(pParse, pSelect, 0);
+ db->flags = savedFlags;
if( pParse->nErr ) return 0;
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
- db->flags = savedFlags;
pTab = sqlite3DbMallocZero(db, sizeof(Table) );
if( pTab==0 ){
return 0;
}
- /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
- ** is disabled */
- assert( db->lookaside.bDisable );
pTab->nTabRef = 1;
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
@@ -125442,11 +127464,18 @@ static void generateWithRecursiveQuery(
Expr *pLimit; /* Saved LIMIT and OFFSET */
int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( p->pWin ){
+ sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries");
+ return;
+ }
+#endif
+
/* Obtain authorization to do a recursive query */
if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
/* Process the LIMIT and OFFSET clauses, if they exist */
- addrBreak = sqlite3VdbeMakeLabel(v);
+ addrBreak = sqlite3VdbeMakeLabel(pParse);
p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, addrBreak);
pLimit = p->pLimit;
@@ -125516,7 +127545,7 @@ static void generateWithRecursiveQuery(
sqlite3VdbeAddOp1(v, OP_Delete, iQueue);
/* Output the single row in Current */
- addrCont = sqlite3VdbeMakeLabel(v);
+ addrCont = sqlite3VdbeMakeLabel(pParse);
codeOffset(v, regOffset, addrCont);
selectInnerLoop(pParse, p, iCurrent,
0, 0, pDest, addrCont, addrBreak);
@@ -125651,6 +127680,7 @@ static int multiSelect(
*/
assert( p && p->pPrior ); /* Calling function guarantees this much */
assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
+ assert( p->selFlags & SF_Compound );
db = pParse->db;
pPrior = p->pPrior;
dest = *pDest;
@@ -125824,8 +127854,8 @@ static int multiSelect(
if( dest.eDest!=priorOp ){
int iCont, iBreak, iStart;
assert( p->pEList );
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
+ iBreak = sqlite3VdbeMakeLabel(pParse);
+ iCont = sqlite3VdbeMakeLabel(pParse);
computeLimitRegisters(pParse, p, iBreak);
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
iStart = sqlite3VdbeCurrentAddr(v);
@@ -125893,8 +127923,8 @@ static int multiSelect(
** tables.
*/
assert( p->pEList );
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
+ iBreak = sqlite3VdbeMakeLabel(pParse);
+ iCont = sqlite3VdbeMakeLabel(pParse);
computeLimitRegisters(pParse, p, iBreak);
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
r1 = sqlite3GetTempReg(pParse);
@@ -126024,7 +128054,7 @@ static int generateOutputSubroutine(
int addr;
addr = sqlite3VdbeCurrentAddr(v);
- iContinue = sqlite3VdbeMakeLabel(v);
+ iContinue = sqlite3VdbeMakeLabel(pParse);
/* Suppress duplicates for UNION, EXCEPT, and INTERSECT
*/
@@ -126261,8 +128291,8 @@ static int multiSelectOrderBy(
db = pParse->db;
v = pParse->pVdbe;
assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */
- labelEnd = sqlite3VdbeMakeLabel(v);
- labelCmpr = sqlite3VdbeMakeLabel(v);
+ labelEnd = sqlite3VdbeMakeLabel(pParse);
+ labelCmpr = sqlite3VdbeMakeLabel(pParse);
/* Patch up the ORDER BY clause
@@ -126578,6 +128608,7 @@ static Expr *substExpr(
ifNullRow.iTable = pSubst->iNewTable;
pCopy = &ifNullRow;
}
+ testcase( ExprHasProperty(pCopy, EP_Subquery) );
pNew = sqlite3ExprDup(db, pCopy, 0);
if( pNew && pSubst->isLeftJoin ){
ExprSetProperty(pNew, EP_CanBeNull);
@@ -127070,11 +129101,9 @@ static int flattenSubquery(
jointype = pSubitem->fg.jointype;
}else{
assert( pParent!=p ); /* 2nd and subsequent times through the loop */
- pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
- if( pSrc==0 ){
- assert( db->mallocFailed );
- break;
- }
+ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
+ if( pSrc==0 ) break;
+ pParent->pSrc = pSrc;
}
/* The subquery uses a single slot of the FROM clause of the outer
@@ -127093,10 +129122,9 @@ static int flattenSubquery(
** for the two elements in the FROM clause of the subquery.
*/
if( nSubSrc>1 ){
- pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
- if( db->mallocFailed ){
- break;
- }
+ pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1);
+ if( pSrc==0 ) break;
+ pParent->pSrc = pSrc;
}
/* Transfer the FROM clause terms from the subquery into the
@@ -127142,11 +129170,12 @@ static int flattenSubquery(
pParent->pOrderBy = pOrderBy;
pSub->pOrderBy = 0;
}
- pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
+ pWhere = pSub->pWhere;
+ pSub->pWhere = 0;
if( isLeftJoin>0 ){
setJoinExpr(pWhere, iNewParent);
}
- pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
+ pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere);
if( db->mallocFailed==0 ){
SubstContext x;
x.pParse = pParse;
@@ -127157,10 +129186,10 @@ static int flattenSubquery(
substSelect(&x, pParent, 0);
}
- /* The flattened query is distinct if either the inner or the
- ** outer query is distinct.
- */
- pParent->selFlags |= pSub->selFlags & SF_Distinct;
+ /* The flattened query is a compound if either the inner or the
+ ** outer query is a compound. */
+ pParent->selFlags |= pSub->selFlags & SF_Compound;
+ assert( (pSub->selFlags & SF_Distinct)==0 ); /* restriction (17b) */
/*
** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
@@ -127191,7 +129220,7 @@ static int flattenSubquery(
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
/*
-** A structure to keep track of all of the column values that fixed to
+** A structure to keep track of all of the column values that are fixed to
** a known value due to WHERE clause constraints of the form COLUMN=VALUE.
*/
typedef struct WhereConst WhereConst;
@@ -127203,13 +129232,28 @@ struct WhereConst {
};
/*
-** Add a new entry to the pConst object
+** Add a new entry to the pConst object. Except, do not add duplicate
+** pColumn entires.
*/
static void constInsert(
- WhereConst *pConst,
- Expr *pColumn,
- Expr *pValue
+ WhereConst *pConst, /* The WhereConst into which we are inserting */
+ Expr *pColumn, /* The COLUMN part of the constraint */
+ Expr *pValue /* The VALUE part of the constraint */
){
+ int i;
+ assert( pColumn->op==TK_COLUMN );
+
+ /* 2018-10-25 ticket [cf5ed20f]
+ ** Make sure the same pColumn is not inserted more than once */
+ for(i=0; inConst; i++){
+ const Expr *pExpr = pConst->apExpr[i*2];
+ assert( pExpr->op==TK_COLUMN );
+ if( pExpr->iTable==pColumn->iTable
+ && pExpr->iColumn==pColumn->iColumn
+ ){
+ return; /* Already present. Return without doing anything. */
+ }
+ }
pConst->nConst++;
pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr,
@@ -127466,9 +129510,9 @@ static int pushDownWhereTerms(
x.pEList = pSubq->pEList;
pNew = substExpr(&x, pNew);
if( pSubq->selFlags & SF_Aggregate ){
- pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
+ pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew);
}else{
- pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
+ pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew);
}
pSubq = pSubq->pPrior;
}
@@ -127894,7 +129938,7 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFr
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral;
- return SQLITE_OK;
+ return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
}
/*
@@ -127940,6 +129984,10 @@ static int selectExpander(Walker *pWalker, Select *p){
if( (selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
+ if( pWalker->eCode ){
+ /* Renumber selId because it has been copied from a view */
+ p->selId = ++pParse->nSelect;
+ }
pTabList = p->pSrc;
pEList = p->pEList;
sqlite3WithPush(pParse, p->pWith, 0);
@@ -127989,12 +130037,15 @@ static int selectExpander(Walker *pWalker, Select *p){
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
if( IsVirtual(pTab) || pTab->pSelect ){
i16 nCol;
+ u8 eCodeOrig = pWalker->eCode;
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
assert( pFrom->pSelect==0 );
pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
nCol = pTab->nCol;
pTab->nCol = -1;
+ pWalker->eCode = 1; /* Turn on Select.selId renumbering */
sqlite3WalkSelect(pWalker, pFrom->pSelect);
+ pWalker->eCode = eCodeOrig;
pTab->nCol = nCol;
}
#endif
@@ -128244,6 +130295,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
}
w.xSelectCallback = selectExpander;
w.xSelectCallback2 = selectPopWith;
+ w.eCode = 0;
sqlite3WalkSelect(&w, pSelect);
}
@@ -128403,7 +130455,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
**
** If regAcc is non-zero and there are no min() or max() aggregates
** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator
-** registers i register regAcc contains 0. The caller will take care
+** registers if register regAcc contains 0. The caller will take care
** of setting and clearing regAcc.
*/
static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
@@ -128430,7 +130482,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
regAgg = 0;
}
if( pF->iDistinct>=0 ){
- addrNext = sqlite3VdbeMakeLabel(v);
+ addrNext = sqlite3VdbeMakeLabel(pParse);
testcase( nArg==0 ); /* Error condition */
testcase( nArg>1 ); /* Also an error */
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
@@ -128515,7 +130567,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
if( pNew ){
Expr *pWhere = pS->pWhere;
SWAP(Expr, *pNew, *pExpr);
- pNew = sqlite3ExprAnd(db, pWhere, pNew);
+ pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew);
pS->pWhere = pNew;
pWalker->eCode = 1;
}
@@ -128566,13 +130618,22 @@ static struct SrcList_item *isSelfJoinView(
){
struct SrcList_item *pItem;
for(pItem = pTabList->a; pItempSelect==0 ) continue;
if( pItem->fg.viaCoroutine ) continue;
if( pItem->zName==0 ) continue;
- if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
+ assert( pItem->pTab!=0 );
+ assert( pThis->pTab!=0 );
+ if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue;
if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
- if( sqlite3ExprCompare(0,
- pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1)
+ pS1 = pItem->pSelect;
+ if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){
+ /* The query flattener left two different CTE tables with identical
+ ** names in the same FROM clause. */
+ continue;
+ }
+ if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1)
+ || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1)
){
/* The view was modified by some other optimization such as
** pushDownWhereTerms() */
@@ -128598,7 +130659,8 @@ static struct SrcList_item *isSelfJoinView(
** * The subquery is a UNION ALL of two or more terms
** * The subquery does not have a LIMIT clause
** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries
-** * The outer query is a simple count(*)
+** * The outer query is a simple count(*) with no WHERE clause or other
+** extraneous syntax.
**
** Return TRUE if the optimization is undertaken.
*/
@@ -128609,6 +130671,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
sqlite3 *db;
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;
+ if( p->pGroupBy ) return 0;
pExpr = p->pEList->a[0].pExpr;
if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
@@ -128835,6 +130899,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
if( flattenSubquery(pParse, p, i, isAgg) ){
+ if( pParse->nErr ) goto select_end;
/* This subquery can be absorbed into its parent. */
i = -1;
}
@@ -128930,22 +130995,12 @@ SQLITE_PRIVATE int sqlite3Select(
pSub = pItem->pSelect;
if( pSub==0 ) continue;
- /* Sometimes the code for a subquery will be generated more than
- ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
- ** for example. In that case, do not regenerate the code to manifest
- ** a view or the co-routine to implement a view. The first instance
- ** is sufficient, though the subroutine to manifest the view does need
- ** to be invoked again. */
- if( pItem->addrFillSub ){
- if( pItem->fg.viaCoroutine==0 ){
- /* The subroutine that manifests the view might be a one-time routine,
- ** or it might need to be rerun on each iteration because it
- ** encodes a correlated subquery. */
- testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
- sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
- }
- continue;
- }
+ /* The code for a subquery should only be generated once, though it is
+ ** technically harmless for it to be generated multiple times. The
+ ** following assert() will detect if something changes to cause
+ ** the same subquery to be coded multiple times, as a signal to the
+ ** developers to try to optimize the situation. */
+ assert( pItem->addrFillSub==0 );
/* Increment Parse.nHeight by the height of the largest expression
** tree referred to by this, the parent select. The child select
@@ -129133,7 +131188,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Set the limiter.
*/
- iEnd = sqlite3VdbeMakeLabel(v);
+ iEnd = sqlite3VdbeMakeLabel(pParse);
if( (p->selFlags & SF_FixedLimit)==0 ){
p->nSelectRow = 320; /* 4 billion rows */
}
@@ -129200,9 +131255,9 @@ SQLITE_PRIVATE int sqlite3Select(
assert( p->pEList==pEList );
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pWin ){
- int addrGosub = sqlite3VdbeMakeLabel(v);
- int iCont = sqlite3VdbeMakeLabel(v);
- int iBreak = sqlite3VdbeMakeLabel(v);
+ int addrGosub = sqlite3VdbeMakeLabel(pParse);
+ int iCont = sqlite3VdbeMakeLabel(pParse);
+ int iBreak = sqlite3VdbeMakeLabel(pParse);
int regGosub = ++pParse->nMem;
sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);
@@ -129277,7 +131332,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
/* Create a label to jump to when we want to abort the query */
- addrEnd = sqlite3VdbeMakeLabel(v);
+ addrEnd = sqlite3VdbeMakeLabel(pParse);
/* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
@@ -129366,9 +131421,9 @@ SQLITE_PRIVATE int sqlite3Select(
iUseFlag = ++pParse->nMem;
iAbortFlag = ++pParse->nMem;
regOutputRow = ++pParse->nMem;
- addrOutputRow = sqlite3VdbeMakeLabel(v);
+ addrOutputRow = sqlite3VdbeMakeLabel(pParse);
regReset = ++pParse->nMem;
- addrReset = sqlite3VdbeMakeLabel(v);
+ addrReset = sqlite3VdbeMakeLabel(pParse);
iAMem = pParse->nMem + 1;
pParse->nMem += pGroupBy->nExpr;
iBMem = pParse->nMem + 1;
@@ -130655,7 +132710,7 @@ static SrcList *targetSrcList(
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
- pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
+ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
@@ -130840,6 +132895,7 @@ static TriggerPrg *codeRowTrigger(
pSubParse->zAuthContext = pTrigger->zName;
pSubParse->eTriggerOp = pTrigger->op;
pSubParse->nQueryLoop = pParse->nQueryLoop;
+ pSubParse->disableVtab = pParse->disableVtab;
v = sqlite3GetVdbe(pSubParse);
if( v ){
@@ -130867,7 +132923,7 @@ static TriggerPrg *codeRowTrigger(
if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
&& db->mallocFailed==0
){
- iEndTrigger = sqlite3VdbeMakeLabel(v);
+ iEndTrigger = sqlite3VdbeMakeLabel(pSubParse);
sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
}
sqlite3ExprDelete(db, pWhen);
@@ -131191,6 +133247,57 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
#endif
}
+/*
+** Check to see if column iCol of index pIdx references any of the
+** columns defined by aXRef and chngRowid. Return true if it does
+** and false if not. This is an optimization. False-positives are a
+** performance degradation, but false-negatives can result in a corrupt
+** index and incorrect answers.
+**
+** aXRef[j] will be non-negative if column j of the original table is
+** being updated. chngRowid will be true if the rowid of the table is
+** being updated.
+*/
+static int indexColumnIsBeingUpdated(
+ Index *pIdx, /* The index to check */
+ int iCol, /* Which column of the index to check */
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
+ int chngRowid /* true if the rowid is being updated */
+){
+ i16 iIdxCol = pIdx->aiColumn[iCol];
+ assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
+ if( iIdxCol>=0 ){
+ return aXRef[iIdxCol]>=0;
+ }
+ assert( iIdxCol==XN_EXPR );
+ assert( pIdx->aColExpr!=0 );
+ assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
+ aXRef,chngRowid);
+}
+
+/*
+** Check to see if index pIdx is a partial index whose conditional
+** expression might change values due to an UPDATE. Return true if
+** the index is subject to change and false if the index is guaranteed
+** to be unchanged. This is an optimization. False-positives are a
+** performance degradation, but false-negatives can result in a corrupt
+** index and incorrect answers.
+**
+** aXRef[j] will be non-negative if column j of the original table is
+** being updated. chngRowid will be true if the rowid of the table is
+** being updated.
+*/
+static int indexWhereClauseMightChange(
+ Index *pIdx, /* The index to check */
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
+ int chngRowid /* true if the rowid is being updated */
+){
+ if( pIdx->pPartIdxWhere==0 ) return 0;
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
+ aXRef, chngRowid);
+}
+
/*
** Process an UPDATE statement.
**
@@ -131216,11 +133323,12 @@ SQLITE_PRIVATE void sqlite3Update(
Index *pIdx; /* For looping over indices */
Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
int nIdx; /* Number of indices that need updating */
+ int nAllIdx; /* Total number of indexes */
int iBaseCur; /* Base cursor number */
int iDataCur; /* Cursor for the canonical data btree */
int iIdxCur; /* Cursor for the first index */
sqlite3 *db; /* The database structure */
- int *aRegIdx = 0; /* First register in array assigned to each index */
+ int *aRegIdx = 0; /* Registers for to each index and the main table */
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
** an expression for the i-th column of the table.
** aXRef[i]==-1 if the i-th column is not changed. */
@@ -131334,10 +133442,10 @@ SQLITE_PRIVATE void sqlite3Update(
/* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
** Initialize aXRef[] and aToOpen[] to their default values.
*/
- aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
+ aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 );
if( aXRef==0 ) goto update_cleanup;
aRegIdx = aXRef+pTab->nCol;
- aToOpen = (u8*)(aRegIdx+nIdx);
+ aToOpen = (u8*)(aRegIdx+nIdx+1);
memset(aToOpen, 1, nIdx+1);
aToOpen[nIdx+1] = 0;
for(i=0; inCol; i++) aXRef[i] = -1;
@@ -131414,33 +133522,32 @@ SQLITE_PRIVATE void sqlite3Update(
/* There is one entry in the aRegIdx[] array for each index on the table
** being updated. Fill in aRegIdx[] with a register number that will hold
** the key for accessing each index.
- **
- ** FIXME: Be smarter about omitting indexes that use expressions.
*/
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( onError==OE_Replace ) bReplace = 1;
+ for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){
int reg;
- if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
+ if( chngKey || hasFK>1 || pIdx==pPk
+ || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
+ ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}else{
reg = 0;
for(i=0; inKeyCol; i++){
- i16 iIdxCol = pIdx->aiColumn[i];
- if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
+ if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
- if( (onError==OE_Replace)
- || (onError==OE_Default && pIdx->onError==OE_Replace)
- ){
+ if( onError==OE_Default && pIdx->onError==OE_Replace ){
bReplace = 1;
}
break;
}
}
}
- if( reg==0 ) aToOpen[j+1] = 0;
- aRegIdx[j] = reg;
+ if( reg==0 ) aToOpen[nAllIdx+1] = 0;
+ aRegIdx[nAllIdx] = reg;
}
+ aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */
if( bReplace ){
/* If REPLACE conflict resolution might be invoked, open cursors on all
** indexes in case they are needed to delete records. */
@@ -131455,7 +133562,13 @@ SQLITE_PRIVATE void sqlite3Update(
/* Allocate required registers. */
if( !IsVirtual(pTab) ){
- regRowSet = ++pParse->nMem;
+ /* For now, regRowSet and aRegIdx[nAllIdx] share the same register.
+ ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be
+ ** reallocated. aRegIdx[nAllIdx] is the register in which the main
+ ** table record is written. regRowSet holds the RowSet for the
+ ** two-pass update algorithm. */
+ assert( aRegIdx[nAllIdx]==pParse->nMem );
+ regRowSet = aRegIdx[nAllIdx];
regOldRowid = regNewRowid = ++pParse->nMem;
if( chngPk || pTrigger || hasFK ){
regOld = pParse->nMem + 1;
@@ -131503,7 +133616,7 @@ SQLITE_PRIVATE void sqlite3Update(
#endif
/* Jump to labelBreak to abandon further processing of this UPDATE */
- labelContinue = labelBreak = sqlite3VdbeMakeLabel(v);
+ labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse);
/* Not an UPSERT. Normal processing. Begin by
** initialize the count of updated rows */
@@ -131585,6 +133698,8 @@ SQLITE_PRIVATE void sqlite3Update(
** leave it in register regOldRowid. */
sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
if( eOnePass==ONEPASS_OFF ){
+ /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */
+ aRegIdx[nAllIdx] = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
}
}else{
@@ -131638,13 +133753,13 @@ SQLITE_PRIVATE void sqlite3Update(
VdbeCoverage(v);
}
if( eOnePass!=ONEPASS_SINGLE ){
- labelContinue = sqlite3VdbeMakeLabel(v);
+ labelContinue = sqlite3VdbeMakeLabel(pParse);
}
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
VdbeCoverageIf(v, pPk==0);
VdbeCoverageIf(v, pPk!=0);
}else if( pPk ){
- labelContinue = sqlite3VdbeMakeLabel(v);
+ labelContinue = sqlite3VdbeMakeLabel(pParse);
sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
@@ -131975,7 +134090,7 @@ static void updateVirtualTable(
sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
}else{
sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
- sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
+ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */
}
}
if( HasRowid(pTab) ){
@@ -132412,16 +134527,17 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
** transient would cause the database file to appear to be deleted
** following reboot.
*/
-SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
+SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){
Vdbe *v = sqlite3GetVdbe(pParse);
int iDb = 0;
- if( v==0 ) return;
+ if( v==0 ) goto build_vacuum_end;
+ if( pParse->nErr ) goto build_vacuum_end;
if( pNm ){
#ifndef SQLITE_BUG_COMPATIBLE_20160819
/* Default behavior: Report an error if the argument to VACUUM is
** not recognized */
iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
- if( iDb<0 ) return;
+ if( iDb<0 ) goto build_vacuum_end;
#else
/* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
** to VACUUM are silently ignored. This is a back-out of a bug fix that
@@ -132433,37 +134549,63 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
#endif
}
if( iDb!=1 ){
- sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
+ int iIntoReg = 0;
+ if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){
+ iIntoReg = ++pParse->nMem;
+ sqlite3ExprCode(pParse, pInto, iIntoReg);
+ }
+ sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg);
sqlite3VdbeUsesBtree(v, iDb);
}
+build_vacuum_end:
+ sqlite3ExprDelete(pParse->db, pInto);
return;
}
/*
** This routine implements the OP_Vacuum opcode of the VDBE.
*/
-SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
+SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
+ char **pzErrMsg, /* Write error message here */
+ sqlite3 *db, /* Database connection */
+ int iDb, /* Which attached DB to vacuum */
+ sqlite3_value *pOut /* Write results here, if not NULL. VACUUM INTO */
+){
int rc = SQLITE_OK; /* Return code from service routines */
Btree *pMain; /* The database being vacuumed */
Btree *pTemp; /* The temporary database we vacuum into */
- u16 saved_mDbFlags; /* Saved value of db->mDbFlags */
- u32 saved_flags; /* Saved value of db->flags */
+ u32 saved_mDbFlags; /* Saved value of db->mDbFlags */
+ u64 saved_flags; /* Saved value of db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
+ u32 saved_openFlags; /* Saved value of db->openFlags */
u8 saved_mTrace; /* Saved trace settings */
Db *pDb = 0; /* Database to detach at end of vacuum */
int isMemDb; /* True if vacuuming a :memory: database */
int nRes; /* Bytes of reserved space at the end of each page */
int nDb; /* Number of attached databases */
const char *zDbMain; /* Schema name of database to vacuum */
+ const char *zOut; /* Name of output file */
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
- return SQLITE_ERROR;
+ return SQLITE_ERROR; /* IMP: R-12218-18073 */
}
if( db->nVdbeActive>1 ){
sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
- return SQLITE_ERROR;
+ return SQLITE_ERROR; /* IMP: R-15610-35227 */
+ }
+ saved_openFlags = db->openFlags;
+ if( pOut ){
+ if( sqlite3_value_type(pOut)!=SQLITE_TEXT ){
+ sqlite3SetString(pzErrMsg, db, "non-text filename");
+ return SQLITE_ERROR;
+ }
+ zOut = (const char*)sqlite3_value_text(pOut);
+ db->openFlags &= ~SQLITE_OPEN_READONLY;
+ db->openFlags |= SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
+ }else{
+ zOut = "";
}
/* Save the current value of the database flags so that it can be
@@ -132476,7 +134618,8 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
saved_mTrace = db->mTrace;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
- db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
+ db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder
+ | SQLITE_Defensive | SQLITE_CountRows);
db->mTrace = 0;
zDbMain = db->aDb[iDb].zDbSName;
@@ -132498,19 +134641,23 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
** to write the journal header file.
*/
nDb = db->nDb;
- rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db");
+ rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
+ 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 );
pTemp = pDb->pBt;
-
- /* The call to execSql() to attach the temp database has left the file
- ** locked (as there was more than one active statement when the transaction
- ** to read the schema was concluded. Unlock it here so that this doesn't
- ** cause problems for the call to BtreeSetPageSize() below. */
- sqlite3BtreeCommit(pTemp);
-
+ if( pOut ){
+ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
+ i64 sz = 0;
+ if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
+ rc = SQLITE_ERROR;
+ sqlite3SetString(pzErrMsg, db, "output file already exists");
+ goto end_of_vacuum;
+ }
+ db->mDbFlags |= DBFLAG_VacuumInto;
+ }
nRes = sqlite3BtreeGetOptimalReserve(pMain);
/* A VACUUM cannot change the pagesize of an encrypted database. */
@@ -132534,7 +134681,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
*/
rc = execSql(db, pzErrMsg, "BEGIN");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = sqlite3BtreeBeginTrans(pMain, 2, 0);
+ rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Do not attempt to change the page size for a WAL database */
@@ -132629,7 +134776,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
};
assert( 1==sqlite3BtreeIsInTrans(pTemp) );
- assert( 1==sqlite3BtreeIsInTrans(pMain) );
+ assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) );
/* Copy Btree meta values */
for(i=0; iflags */
@@ -132992,9 +135145,13 @@ SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
** string will be freed automatically when the table is
** deleted.
*/
-static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
- int nBytes = sizeof(char *)*(2+pTable->nModuleArg);
+static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){
+ sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg);
char **azModuleArg;
+ sqlite3 *db = pParse->db;
+ if( pTable->nModuleArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){
+ sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName);
+ }
azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
if( azModuleArg==0 ){
sqlite3DbFree(db, zArg);
@@ -133018,7 +135175,6 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
Token *pModuleName, /* Name of the module for the virtual table */
int ifNotExists /* No error if the table already exists */
){
- int iDb; /* The database the table is being created in */
Table *pTable; /* The new virtual table */
sqlite3 *db; /* Database connection */
@@ -133028,13 +135184,11 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
assert( 0==pTable->pIndex );
db = pParse->db;
- iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
- assert( iDb>=0 );
assert( pTable->nModuleArg==0 );
- addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
- addModuleArgument(db, pTable, 0);
- addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
+ addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName));
+ addModuleArgument(pParse, pTable, 0);
+ addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName));
assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
|| (pParse->sNameToken.z==pName1->z && pName2->z==0)
);
@@ -133049,6 +135203,8 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
** The second call, to obtain permission to create the table, is made now.
*/
if( pTable->azModuleArg ){
+ int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
+ assert( iDb>=0 ); /* The database the table is being created in */
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
}
@@ -133065,7 +135221,7 @@ static void addArgumentToVtab(Parse *pParse){
const char *z = (const char*)pParse->sArg.z;
int n = pParse->sArg.n;
sqlite3 *db = pParse->db;
- addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
+ addModuleArgument(pParse, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
}
}
@@ -133354,7 +135510,8 @@ static int growVTrans(sqlite3 *db){
/* Grow the sqlite3.aVTrans array if required */
if( (db->nVTrans%ARRAY_INCR)==0 ){
VTable **aVTrans;
- int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
+ sqlite3_int64 nBytes = sizeof(sqlite3_vtab*)*
+ ((sqlite3_int64)db->nVTrans + ARRAY_INCR);
aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
if( !aVTrans ){
return SQLITE_NOMEM_BKPT;
@@ -133527,6 +135684,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
p = vtabDisconnectAll(db, pTab);
xDestroy = p->pMod->pModule->xDestroy;
assert( xDestroy!=0 ); /* Checked before the virtual table is created */
+ pTab->nTabRef++;
rc = xDestroy(p->pVtab);
/* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
if( rc==SQLITE_OK ){
@@ -133535,6 +135693,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
pTab->pVTable = 0;
sqlite3VtabUnlock(p);
}
+ sqlite3DeleteTable(db, pTab);
}
return rc;
@@ -133692,6 +135851,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
const sqlite3_module *pMod = pVTab->pMod->pModule;
if( pVTab->pVtab && pMod->iVersion>=2 ){
int (*xMethod)(sqlite3_vtab *, int);
+ sqlite3VtabLock(pVTab);
switch( op ){
case SAVEPOINT_BEGIN:
xMethod = pMod->xSavepoint;
@@ -133707,6 +135867,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
if( xMethod && pVTab->iSavepoint>iSavepoint ){
rc = xMethod(pVTab->pVtab, iSavepoint);
}
+ sqlite3VtabUnlock(pVTab);
}
}
}
@@ -133743,7 +135904,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
/* Check to see the left operand is a column in a virtual table */
if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
- pTab = pExpr->pTab;
+ pTab = pExpr->y.pTab;
if( pTab==0 ) return pDef;
if( !IsVirtual(pTab) ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
@@ -133848,9 +136009,9 @@ SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
pTab->pSchema = db->aDb[0].pSchema;
assert( pTab->nModuleArg==0 );
pTab->iPKey = -1;
- addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
- addModuleArgument(db, pTab, 0);
- addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
+ addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
+ addModuleArgument(pParse, pTab, 0);
+ addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
if( rc ){
sqlite3ErrorMsg(pParse, "%s", zErr);
@@ -133975,6 +136136,8 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
** planner logic in "where.c". These definitions are broken out into
** a separate source file for easier editing.
*/
+#ifndef SQLITE_WHEREINT_H
+#define SQLITE_WHEREINT_H
/*
** Trace output macros
@@ -134363,12 +136526,33 @@ struct WhereLoopBuilder {
int nRecValid; /* Number of valid fields currently in pRec */
#endif
unsigned int bldFlags; /* SQLITE_BLDF_* flags */
+ unsigned int iPlanLimit; /* Search limiter */
};
/* Allowed values for WhereLoopBuider.bldFlags */
#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
+/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
+** index+constraint combinations the query planner will consider for a
+** particular query. If this parameter is unlimited, then certain
+** pathological queries can spend excess time in the sqlite3WhereBegin()
+** routine. The limit is high enough that is should not impact real-world
+** queries.
+**
+** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is
+** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM
+** clause is processed, so that every table in a join is guaranteed to be
+** able to propose a some index+constraint combinations even if the initial
+** baseline limit was exhausted by prior tables of the join.
+*/
+#ifndef SQLITE_QUERY_PLANNER_LIMIT
+# define SQLITE_QUERY_PLANNER_LIMIT 20000
+#endif
+#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
+# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
+#endif
+
/*
** The WHERE clause processing routine has two halves. The
** first part does the start of the WHERE loop and the second
@@ -134447,8 +136631,11 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d)
#endif
SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
+ Parse *pParse, /* Parsing context */
+ Vdbe *v, /* Prepared statement under construction */
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
+ WhereLevel *pLevel, /* The current level pointer */
Bitmask notReady /* Which tables are currently available */
);
@@ -134522,6 +136709,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
+#endif /* !defined(SQLITE_WHEREINT_H) */
+
/************** End of whereInt.h ********************************************/
/************** Continuing where we left off in wherecode.c ******************/
@@ -134718,6 +136907,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
}
#endif
zMsg = sqlite3StrAccumFinish(&str);
+ sqlite3ExplainBreakpoint("",zMsg);
ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
}
@@ -134930,7 +137120,7 @@ static Expr *removeUnindexableInClauseTerms(
for(i=iEq; inLTerm; i++){
if( pLoop->aLTerm[i]->pExpr==pX ){
int iField = pLoop->aLTerm[i]->iField - 1;
- assert( pOrigRhs->a[iField].pExpr!=0 );
+ if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
pOrigRhs->a[iField].pExpr = 0;
assert( pOrigLhs->a[iField].pExpr!=0 );
@@ -135043,16 +137233,17 @@ static int codeEqualityTerm(
if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
}
+ iTab = 0;
if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0);
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
}else{
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);
- pTerm->pExpr->iTable = pX->iTable;
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
+ pTerm->pExpr->iTable = iTab;
}
sqlite3ExprDelete(db, pX);
pX = pTerm->pExpr;
@@ -135062,7 +137253,6 @@ static int codeEqualityTerm(
testcase( bRev );
bRev = !bRev;
}
- iTab = pX->iTable;
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
VdbeCoverageIf(v, bRev);
VdbeCoverageIf(v, !bRev);
@@ -135070,7 +137260,7 @@ static int codeEqualityTerm(
pLoop->wsFlags |= WHERE_IN_ABLE;
if( pLevel->u.in.nIn==0 ){
- pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
+ pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
}
i = pLevel->u.in.nIn;
@@ -135086,7 +137276,6 @@ static int codeEqualityTerm(
if( pLoop->aLTerm[i]->pExpr==pX ){
int iOut = iReg + i - iEq;
if( eType==IN_INDEX_ROWID ){
- testcase( nEq>1 ); /* Happens with a UNIQUE index on ROWID */
pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
}else{
int iCol = aiMap ? aiMap[iMap++] : 0;
@@ -135504,7 +137693,7 @@ static void codeCursorHint(
}
/* If we survive all prior tests, that means this term is worth hinting */
- pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
+ pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0));
}
if( pExpr!=0 ){
sWalker.xExprCallback = codeCursorHintFixExpr;
@@ -135581,7 +137770,9 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
#ifndef SQLITE_OMIT_SUBQUERY
if( (p->flags & EP_xIsSelect) ){
Vdbe *v = pParse->pVdbe;
- int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
+ int iSelect;
+ assert( p->op==TK_SELECT );
+ iSelect = sqlite3CodeSubselect(pParse, p);
sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
}else
#endif
@@ -135622,7 +137813,7 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
pExpr->op = TK_COLUMN;
pExpr->iTable = pX->iIdxCur;
pExpr->iColumn = pX->iIdxCol;
- pExpr->pTab = 0;
+ pExpr->y.pTab = 0;
return WRC_Prune;
}else{
return WRC_Continue;
@@ -135662,27 +137853,54 @@ static void whereIndexExprTrans(
}
}
+/*
+** The pTruth expression is always true because it is the WHERE clause
+** a partial index that is driving a query loop. Look through all of the
+** WHERE clause terms on the query, and if any of those terms must be
+** true because pTruth is true, then mark those WHERE clause terms as
+** coded.
+*/
+static void whereApplyPartialIndexConstraints(
+ Expr *pTruth,
+ int iTabCur,
+ WhereClause *pWC
+){
+ int i;
+ WhereTerm *pTerm;
+ while( pTruth->op==TK_AND ){
+ whereApplyPartialIndexConstraints(pTruth->pLeft, iTabCur, pWC);
+ pTruth = pTruth->pRight;
+ }
+ for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){
+ Expr *pExpr;
+ if( pTerm->wtFlags & TERM_CODED ) continue;
+ pExpr = pTerm->pExpr;
+ if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){
+ pTerm->wtFlags |= TERM_CODED;
+ }
+ }
+}
+
/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
+ Parse *pParse, /* Parsing context */
+ Vdbe *v, /* Prepared statement under construction */
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
+ WhereLevel *pLevel, /* The current level pointer */
Bitmask notReady /* Which tables are currently available */
){
int j, k; /* Loop counters */
int iCur; /* The VDBE cursor for the table */
int addrNxt; /* Where to jump to continue with the next IN case */
- int omitTable; /* True if we use the index only */
int bRev; /* True if we need to scan in reverse order */
- WhereLevel *pLevel; /* The where level to be coded */
WhereLoop *pLoop; /* The WhereLoop object being coded */
WhereClause *pWC; /* Decomposition of the entire WHERE clause */
WhereTerm *pTerm; /* A WHERE clause term */
- Parse *pParse; /* Parsing context */
sqlite3 *db; /* Database connection */
- Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
int addrHalt; /* addrBrk for the outermost loop */
@@ -135692,18 +137910,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
Index *pIdx = 0; /* Index used by loop (if any) */
int iLoop; /* Iteration of constraint generator loop */
- pParse = pWInfo->pParse;
- v = pParse->pVdbe;
pWC = &pWInfo->sWC;
db = pParse->db;
- pLevel = &pWInfo->a[iLevel];
pLoop = pLevel->pWLoop;
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
iCur = pTabItem->iCursor;
pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
bRev = (pWInfo->revMask>>iLevel)&1;
- omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
/* Create labels for the "break" and "continue" instructions
@@ -135716,8 +137929,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** there are no IN operators in the constraints, the "addrNxt" label
** is the same as "addrBrk".
*/
- addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
- addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);
+ addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
+ addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse);
/* If this is the right table of a LEFT OUTER JOIN, allocate and
** initialize a memory cell that records if this table matches any
@@ -135844,7 +138057,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
- assert( omitTable==0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
iReleaseReg = ++pParse->nMem;
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
@@ -135853,6 +138065,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
VdbeCoverage(v);
pLevel->op = OP_Noop;
+ if( (pTerm->prereqAll & pLevel->notReady)==0 ){
+ pTerm->wtFlags |= TERM_CODED;
+ }
}else if( (pLoop->wsFlags & WHERE_IPK)!=0
&& (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
){
@@ -135863,7 +138078,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int memEndValue = 0;
WhereTerm *pStart, *pEnd;
- assert( omitTable==0 );
j = 0;
pStart = pEnd = 0;
if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
@@ -136027,6 +138241,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
char *zEndAff = 0; /* Affinity for end of range constraint */
u8 bSeekPastNull = 0; /* True to seek past initial nulls */
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
+ int omitTable; /* True if we use the index only */
+
pIdx = pLoop->u.btree.pIndex;
iIdxCur = pLevel->iIdxCur;
@@ -136228,6 +138444,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
/* Seek the table cursor, if required */
+ omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
+ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
}else if( HasRowid(pIdx->pTable) ){
@@ -136262,11 +138480,24 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** the cursor. In this case it is important to do the full evaluation,
** as the result of the expression may not be NULL, even if all table
** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a
+ **
+ ** Also, do not do this when processing one index an a multi-index
+ ** OR clause, since the transformation will become invalid once we
+ ** move forward to the next index.
+ ** https://sqlite.org/src/info/4e8e4857d32d401f
*/
- if( pLevel->iLeftJoin==0 ){
+ if( pLevel->iLeftJoin==0 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
}
+ /* If a partial index is driving the loop, try to eliminate WHERE clause
+ ** terms from the query that must be true due to the WHERE clause of
+ ** the partial index
+ */
+ if( pIdx->pPartIdxWhere ){
+ whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC);
+ }
+
/* Record the instruction used to terminate the loop. */
if( pLoop->wsFlags & WHERE_ONEROW ){
pLevel->op = OP_Noop;
@@ -136338,7 +138569,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */
int regRowset = 0; /* Register for RowSet object */
int regRowid = 0; /* Register holding rowid */
- int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */
+ int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */
int iRetInit; /* Address of regReturn init */
int untestedTerms = 0; /* Some terms not completely tested */
int ii; /* Loop counter */
@@ -136427,10 +138658,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
pExpr = sqlite3ExprDup(db, pExpr, 0);
- pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
+ pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr);
}
if( pAndExpr ){
- pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr);
+ /* The extra 0x10000 bit on the opcode is masked off and does not
+ ** become part of the new Expr.op. However, it does make the
+ ** op==TK_AND comparison inside of sqlite3PExpr() false, and this
+ ** prevents sqlite3PExpr() from implementing AND short-circuit
+ ** optimization, which we do not want here. */
+ pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr);
}
}
@@ -136454,6 +138690,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pOrExpr = pAndExpr;
}
/* Loop through table entries that match term pOrTerm. */
+ ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
wctrlFlags, iCovCur);
@@ -136557,6 +138794,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
/* Finish the loop through table entries that match term pOrTerm. */
sqlite3WhereEnd(pSubWInfo);
+ ExplainQueryPlanPop(pParse);
}
}
}
@@ -136571,7 +138809,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeGoto(v, pLevel->addrBrk);
sqlite3VdbeResolveLabel(v, iLoopBody);
- if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
+ if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
if( !untestedTerms ) disableTerm(pLevel, pTerm);
}else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
@@ -136658,8 +138896,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
u32 x = pLevel->iLikeRepCntr;
if( x>0 ){
skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1));
+ VdbeCoverageIf(v, (x&1)==1);
+ VdbeCoverageIf(v, (x&1)==0);
}
- VdbeCoverage(v);
#endif
}
#ifdef WHERETRACE_ENABLED /* 0xffff */
@@ -137003,27 +139242,33 @@ static int isLikeOrGlob(
zNew[iTo++] = zNew[iFrom];
}
zNew[iTo] = 0;
+ assert( iTo>0 );
- /* If the RHS begins with a digit or a minus sign, then the LHS must be
- ** an ordinary column (not a virtual table column) with TEXT affinity.
- ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
- ** even though "lhs LIKE rhs" is true. But if the RHS does not start
- ** with a digit or '-', then "lhs LIKE rhs" will always be false if
- ** the LHS is numeric and so the optimization still works.
+ /* If the LHS is not an ordinary column with TEXT affinity, then the
+ ** pattern prefix boundaries (both the start and end boundaries) must
+ ** not look like a number. Otherwise the pattern might be treated as
+ ** a number, which will invalidate the LIKE optimization.
**
- ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033
- ** The RHS pattern must not be '/%' because the termination condition
- ** will then become "x<'0'" and if the affinity is numeric, will then
- ** be converted into "x<0", which is incorrect.
+ ** Getting this right has been a persistent source of bugs in the
+ ** LIKE optimization. See, for example:
+ ** 2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1
+ ** 2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
+ ** 2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
+ ** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
*/
- if( sqlite3Isdigit(zNew[0])
- || zNew[0]=='-'
- || (zNew[0]+1=='0' && iTo==1)
+ if( pLeft->op!=TK_COLUMN
+ || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
+ || IsVirtual(pLeft->y.pTab) /* Value might be numeric */
){
- if( pLeft->op!=TK_COLUMN
- || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab) /* Value might be numeric */
- ){
+ int isNum;
+ double rDummy;
+ isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
+ if( isNum<=0 ){
+ zNew[iTo-1]++;
+ isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
+ zNew[iTo-1]--;
+ }
+ if( isNum>0 ){
sqlite3ExprDelete(db, pPrefix);
sqlite3ValueFree(pVal);
return 0;
@@ -137123,7 +139368,7 @@ static int isAuxiliaryVtabOperator(
** MATCH(expression,vtab_column)
*/
pCol = pList->a[1].pExpr;
- if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
for(i=0; iu.zToken, aOp[i].zOp)==0 ){
*peOp2 = aOp[i].eOp2;
@@ -137145,12 +139390,12 @@ static int isAuxiliaryVtabOperator(
** with function names in an arbitrary case.
*/
pCol = pList->a[0].pExpr;
- if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
sqlite3_vtab *pVtab;
sqlite3_module *pMod;
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
void *pNotUsed;
- pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
+ pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
pMod = (sqlite3_module *)pVtab->pModule;
@@ -137168,10 +139413,10 @@ static int isAuxiliaryVtabOperator(
int res = 0;
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
- if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
+ if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
res++;
}
- if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
+ if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
res++;
SWAP(Expr*, pLeft, pRight);
}
@@ -137518,6 +139763,7 @@ static void exprAnalyzeOrTerm(
** and column is found but leave okToChngToIN false if not found.
*/
for(j=0; j<2 && !okToChngToIN; j++){
+ Expr *pLeft = 0;
pOrTerm = pOrWc->a;
for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
assert( pOrTerm->eOperator & WO_EQ );
@@ -137541,6 +139787,7 @@ static void exprAnalyzeOrTerm(
}
iColumn = pOrTerm->u.leftColumn;
iCursor = pOrTerm->leftCursor;
+ pLeft = pOrTerm->pExpr->pLeft;
break;
}
if( i<0 ){
@@ -137560,7 +139807,9 @@ static void exprAnalyzeOrTerm(
assert( pOrTerm->eOperator & WO_EQ );
if( pOrTerm->leftCursor!=iCursor ){
pOrTerm->wtFlags &= ~TERM_OR_OK;
- }else if( pOrTerm->u.leftColumn!=iColumn ){
+ }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR
+ && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
+ )){
okToChngToIN = 0;
}else{
int affLeft, affRight;
@@ -138123,6 +140372,7 @@ static void exprAnalyze(
if( pExpr->op==TK_NOTNULL
&& pExpr->pLeft->op==TK_COLUMN
&& pExpr->pLeft->iColumn>=0
+ && !ExprHasProperty(pExpr, EP_FromJoin)
&& OptimizationEnabled(db, SQLITE_Stat34)
){
Expr *pNewExpr;
@@ -138256,6 +140506,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
}else if( p->x.pList ){
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( p->op==TK_FUNCTION && p->y.pWin ){
+ mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition);
+ mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy);
+ }
+#endif
return mask;
}
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
@@ -138314,6 +140570,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
pArgs = pItem->u1.pFuncArg;
if( pArgs==0 ) return;
for(j=k=0; jnExpr; j++){
+ Expr *pRhs;
while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
if( k>=pTab->nCol ){
sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
@@ -138324,9 +140581,10 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
if( pColRef==0 ) return;
pColRef->iTable = pItem->iCursor;
pColRef->iColumn = k++;
- pColRef->pTab = pTab;
- pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
- sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
+ pColRef->y.pTab = pTab;
+ pRhs = sqlite3PExpr(pParse, TK_UPLUS,
+ sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
+ pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
}
}
@@ -138645,6 +140903,17 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
return 0;
}
+/*
+** This is whereScanInit() for the case of an index on an expression.
+** It is factored out into a separate tail-recursion subroutine so that
+** the normal whereScanInit() routine, which is a high-runner, does not
+** need to push registers onto the stack as part of its prologue.
+*/
+static SQLITE_NOINLINE WhereTerm *whereScanInitIndexExpr(WhereScan *pScan){
+ pScan->idxaff = sqlite3ExprAffinity(pScan->pIdxExpr);
+ return whereScanNext(pScan);
+}
+
/*
** Initialize a WHERE clause scanner object. Return a pointer to the
** first match. Return NULL if there are no matches.
@@ -138677,12 +140946,19 @@ static WhereTerm *whereScanInit(
pScan->pIdxExpr = 0;
pScan->idxaff = 0;
pScan->zCollName = 0;
+ pScan->opMask = opMask;
+ pScan->k = 0;
+ pScan->aiCur[0] = iCur;
+ pScan->nEquiv = 1;
+ pScan->iEquiv = 1;
if( pIdx ){
int j = iColumn;
iColumn = pIdx->aiColumn[j];
if( iColumn==XN_EXPR ){
pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
pScan->zCollName = pIdx->azColl[j];
+ pScan->aiColumn[0] = XN_EXPR;
+ return whereScanInitIndexExpr(pScan);
}else if( iColumn==pIdx->pTable->iPKey ){
iColumn = XN_ROWID;
}else if( iColumn>=0 ){
@@ -138692,12 +140968,7 @@ static WhereTerm *whereScanInit(
}else if( iColumn==XN_EXPR ){
return 0;
}
- pScan->opMask = opMask;
- pScan->k = 0;
- pScan->aiCur[0] = iCur;
pScan->aiColumn[0] = iColumn;
- pScan->nEquiv = 1;
- pScan->iEquiv = 1;
return whereScanNext(pScan);
}
@@ -138884,17 +141155,17 @@ static LogEst estLog(LogEst N){
** opcodes into OP_Copy when the table is being accessed via co-routine
** instead of via table lookup.
**
-** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on
-** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero,
-** then each OP_Rowid is transformed into an instruction to increment the
-** value stored in its output register.
+** If the iAutoidxCur is not zero, then any OP_Rowid instructions on
+** cursor iTabCur are transformed into OP_Sequence opcode for the
+** iAutoidxCur cursor, in order to generate unique rowids for the
+** automatic index being generated.
*/
static void translateColumnToCopy(
Parse *pParse, /* Parsing context */
int iStart, /* Translate from this opcode to the end */
int iTabCur, /* OP_Column/OP_Rowid references to this table */
int iRegister, /* The first column is in this register */
- int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */
+ int iAutoidxCur /* If non-zero, cursor of autoindex being generated */
){
Vdbe *v = pParse->pVdbe;
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
@@ -138908,11 +141179,9 @@ static void translateColumnToCopy(
pOp->p2 = pOp->p3;
pOp->p3 = 0;
}else if( pOp->opcode==OP_Rowid ){
- if( bIncrRowid ){
- /* Increment the value stored in the P2 operand of the OP_Rowid. */
- pOp->opcode = OP_AddImm;
- pOp->p1 = pOp->p2;
- pOp->p2 = 1;
+ if( iAutoidxCur ){
+ pOp->opcode = OP_Sequence;
+ pOp->p1 = iAutoidxCur;
}else{
pOp->opcode = OP_Null;
pOp->p1 = 0;
@@ -139059,7 +141328,7 @@ static void constructAutomaticIndex(
&& (pTerm->wtFlags & TERM_VIRTUAL)==0
&& !ExprHasProperty(pExpr, EP_FromJoin)
&& sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
- pPartial = sqlite3ExprAnd(pParse->db, pPartial,
+ pPartial = sqlite3ExprAnd(pParse, pPartial,
sqlite3ExprDup(pParse->db, pExpr, 0));
}
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
@@ -139172,7 +141441,7 @@ static void constructAutomaticIndex(
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
}
if( pPartial ){
- iContinue = sqlite3VdbeMakeLabel(v);
+ iContinue = sqlite3VdbeMakeLabel(pParse);
sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
pLoop->wsFlags |= WHERE_PARTIALIDX;
}
@@ -139186,8 +141455,9 @@ static void constructAutomaticIndex(
if( pTabItem->fg.viaCoroutine ){
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
testcase( pParse->db->mallocFailed );
+ assert( pLevel->iIdxCur>0 );
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
- pTabItem->regResult, 1);
+ pTabItem->regResult, pLevel->iIdxCur);
sqlite3VdbeGoto(v, addrTop);
pTabItem->fg.viaCoroutine = 0;
}else{
@@ -139367,9 +141637,11 @@ static sqlite3_index_info *allocateIndexInfo(
** method of the virtual table with the sqlite3_index_info object that
** comes in as the 3rd argument to this function.
**
-** If an error occurs, pParse is populated with an error message and a
-** non-zero value is returned. Otherwise, 0 is returned and the output
-** part of the sqlite3_index_info structure is left populated.
+** If an error occurs, pParse is populated with an error message and an
+** appropriate error code is returned. A return of SQLITE_CONSTRAINT from
+** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that
+** the current configuration of "unusable" flags in sqlite3_index_info can
+** not result in a valid plan.
**
** Whether or not an error is returned, it is the responsibility of the
** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
@@ -139383,7 +141655,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
rc = pVtab->pModule->xBestIndex(pVtab, p);
TRACE_IDX_OUTPUTS(p);
- if( rc!=SQLITE_OK ){
+ if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
if( rc==SQLITE_NOMEM ){
sqlite3OomFault(pParse->db);
}else if( !pVtab->zErrMsg ){
@@ -139394,19 +141666,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
}
sqlite3_free(pVtab->zErrMsg);
pVtab->zErrMsg = 0;
-
-#if 0
- /* This error is now caught by the caller.
- ** Search for "xBestIndex malfunction" below */
- for(i=0; inConstraint; i++){
- if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
- sqlite3ErrorMsg(pParse,
- "table %s: xBestIndex returned an invalid plan", pTab->zName);
- }
- }
-#endif
-
- return pParse->nErr;
+ return rc;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
@@ -140461,6 +142721,14 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
sqlite3 *db = pWInfo->pParse->db;
int rc;
+ /* Stop the search once we hit the query planner search limit */
+ if( pBuilder->iPlanLimit==0 ){
+ WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
+ if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
+ return SQLITE_DONE;
+ }
+ pBuilder->iPlanLimit--;
+
/* If pBuilder->pOrSet is defined, then only keep track of the costs
** and prereqs.
*/
@@ -140547,7 +142815,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
rc = whereLoopXfer(db, p, pTemplate);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
Index *pIndex = p->u.btree.pIndex;
- if( pIndex && pIndex->tnum==0 ){
+ if( pIndex && pIndex->idxType==SQLITE_IDXTYPE_IPK ){
p->u.btree.pIndex = 0;
}
}
@@ -140714,8 +142982,8 @@ static int whereRangeVectorLen(
** terms only. If it is modified, this value is restored before this
** function returns.
**
-** If pProbe->tnum==0, that means pIndex is a fake index used for the
-** INTEGER PRIMARY KEY.
+** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is
+** a fake index used for the INTEGER PRIMARY KEY.
*/
static int whereLoopAddBtreeIndex(
WhereLoopBuilder *pBuilder, /* The WhereLoop factory */
@@ -141215,6 +143483,7 @@ static int whereLoopAddBtree(
sPk.onError = OE_Replace;
sPk.pTable = pTab;
sPk.szIdxRow = pTab->szTabRow;
+ sPk.idxType = SQLITE_IDXTYPE_IPK;
aiRowEstPk[0] = pTab->nRowLogEst;
aiRowEstPk[1] = 0;
pFirst = pSrc->pTab->pIndex;
@@ -141305,7 +143574,7 @@ static int whereLoopAddBtree(
b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
/* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
- if( pProbe->tnum<=0 ){
+ if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
/* Integer primary key index */
pNew->wsFlags = WHERE_IPK;
@@ -141471,7 +143740,17 @@ static int whereLoopAddVirtualOne(
/* Invoke the virtual table xBestIndex() method */
rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
- if( rc ) return rc;
+ if( rc ){
+ if( rc==SQLITE_CONSTRAINT ){
+ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
+ ** that the particular combination of parameters provided is unusable.
+ ** Make no entries in the loop table.
+ */
+ WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n"));
+ return SQLITE_OK;
+ }
+ return rc;
+ }
mxTerm = -1;
assert( pNew->nLSlot>=nConstraint );
@@ -141648,11 +143927,11 @@ static int whereLoopAddVirtual(
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
/* If the call to xBestIndex() with all terms enabled produced a plan
- ** that does not require any source tables (IOW: a plan with mBest==0),
- ** then there is no point in making any further calls to xBestIndex()
- ** since they will all return the same result (if the xBestIndex()
- ** implementation is sane). */
- if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){
+ ** that does not require any source tables (IOW: a plan with mBest==0)
+ ** and does not use an IN(...) operator, then there is no point in making
+ ** any further calls to xBestIndex() since they will all return the same
+ ** result (if the xBestIndex() implementation is sane). */
+ if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){
int seenZero = 0; /* True if a plan with no prereqs seen */
int seenZeroNoIN = 0; /* Plan with no prereqs and no IN(...) seen */
Bitmask mPrev = 0;
@@ -141867,9 +144146,11 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
/* Loop over the tables in the join, from left to right */
pNew = pBuilder->pNew;
whereLoopInit(pNew);
+ pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
for(iTab=0, pItem=pTabList->a; pItemiTab = iTab;
+ pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
/* This condition is true when pItem is the FROM clause term on the
@@ -141895,7 +144176,15 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
}
mPrior |= pNew->maskSelf;
- if( rc || db->mallocFailed ) break;
+ if( rc || db->mallocFailed ){
+ if( rc==SQLITE_DONE ){
+ /* We hit the query planner search limit set by iPlanLimit */
+ sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
+ rc = SQLITE_OK;
+ }else{
+ break;
+ }
+ }
}
whereLoopClear(db, pNew);
@@ -142961,7 +145250,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pWInfo->pResultSet = pResultSet;
pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
pWInfo->nLevel = nTabList;
- pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
+ pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
pWInfo->wctrlFlags = wctrlFlags;
pWInfo->iLimit = iAuxArg;
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
@@ -143235,9 +145524,10 @@ 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) );
if( bOnerow || (
0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
- && 0==(wsFlags & WHERE_VIRTUALTABLE)
+ && !IsVirtual(pTabList->a[0].pTab)
&& (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
)){
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
@@ -143392,7 +145682,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pParse, pTabList, pLevel, wctrlFlags
);
pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
- notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
+ notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady);
pWInfo->iContinue = pLevel->addrCont;
if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
@@ -143577,6 +145867,29 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
continue;
}
+#ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE
+ /* Close all of the cursors that were opened by sqlite3WhereBegin.
+ ** Except, do not close cursors that will be reused by the OR optimization
+ ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors
+ ** created for the ONEPASS optimization.
+ */
+ if( (pTab->tabFlags & TF_Ephemeral)==0
+ && pTab->pSelect==0
+ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
+ ){
+ int ws = pLoop->wsFlags;
+ if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
+ sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
+ }
+ if( (ws & WHERE_INDEXED)!=0
+ && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
+ && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
+ ){
+ sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
+ }
+ }
+#endif
+
/* If this scan uses an index, make VDBE code substitutions to read data
** from the index instead of from the table where possible. In some cases
** this optimization prevents the table from ever being read, which can
@@ -143851,6 +146164,96 @@ static void dense_rankValueFunc(sqlite3_context *pCtx){
}
}
+/*
+** Implementation of built-in window function nth_value(). This
+** implementation is used in "slow mode" only - when the EXCLUDE clause
+** is not set to the default value "NO OTHERS".
+*/
+struct NthValueCtx {
+ i64 nStep;
+ sqlite3_value *pValue;
+};
+static void nth_valueStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct NthValueCtx *p;
+ p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p ){
+ i64 iVal;
+ switch( sqlite3_value_numeric_type(apArg[1]) ){
+ case SQLITE_INTEGER:
+ iVal = sqlite3_value_int64(apArg[1]);
+ break;
+ case SQLITE_FLOAT: {
+ double fVal = sqlite3_value_double(apArg[1]);
+ if( ((i64)fVal)!=fVal ) goto error_out;
+ iVal = (i64)fVal;
+ break;
+ }
+ default:
+ goto error_out;
+ }
+ if( iVal<=0 ) goto error_out;
+
+ p->nStep++;
+ if( iVal==p->nStep ){
+ p->pValue = sqlite3_value_dup(apArg[0]);
+ if( !p->pValue ){
+ sqlite3_result_error_nomem(pCtx);
+ }
+ }
+ }
+ UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+ return;
+
+ error_out:
+ sqlite3_result_error(
+ pCtx, "second argument to nth_value must be a positive integer", -1
+ );
+}
+static void nth_valueFinalizeFunc(sqlite3_context *pCtx){
+ struct NthValueCtx *p;
+ p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0);
+ if( p && p->pValue ){
+ sqlite3_result_value(pCtx, p->pValue);
+ sqlite3_value_free(p->pValue);
+ p->pValue = 0;
+ }
+}
+#define nth_valueInvFunc noopStepFunc
+#define nth_valueValueFunc noopValueFunc
+
+static void first_valueStepFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct NthValueCtx *p;
+ p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p && p->pValue==0 ){
+ p->pValue = sqlite3_value_dup(apArg[0]);
+ if( !p->pValue ){
+ sqlite3_result_error_nomem(pCtx);
+ }
+ }
+ UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+}
+static void first_valueFinalizeFunc(sqlite3_context *pCtx){
+ struct NthValueCtx *p;
+ p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ if( p && p->pValue ){
+ sqlite3_result_value(pCtx, p->pValue);
+ sqlite3_value_free(p->pValue);
+ p->pValue = 0;
+ }
+}
+#define first_valueInvFunc noopStepFunc
+#define first_valueValueFunc noopValueFunc
+
/*
** Implementation of built-in window function rank(). Assumes that
** the window frame has been set to:
@@ -143886,7 +146289,7 @@ static void rankValueFunc(sqlite3_context *pCtx){
** Implementation of built-in window function percent_rank(). Assumes that
** the window frame has been set to:
**
-** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+** GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
*/
static void percent_rankStepFunc(
sqlite3_context *pCtx,
@@ -143894,38 +146297,44 @@ static void percent_rankStepFunc(
sqlite3_value **apArg
){
struct CallCount *p;
- UNUSED_PARAMETER(nArg); assert( nArg==1 );
-
+ UNUSED_PARAMETER(nArg); assert( nArg==0 );
+ UNUSED_PARAMETER(apArg);
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
- if( p->nTotal==0 ){
- p->nTotal = sqlite3_value_int64(apArg[0]);
- }
- p->nStep++;
- if( p->nValue==0 ){
- p->nValue = p->nStep;
- }
+ p->nTotal++;
}
}
+static void percent_rankInvFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct CallCount *p;
+ UNUSED_PARAMETER(nArg); assert( nArg==0 );
+ UNUSED_PARAMETER(apArg);
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ p->nStep++;
+}
static void percent_rankValueFunc(sqlite3_context *pCtx){
struct CallCount *p;
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
+ p->nValue = p->nStep;
if( p->nTotal>1 ){
- double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
+ double r = (double)p->nValue / (double)(p->nTotal-1);
sqlite3_result_double(pCtx, r);
}else{
sqlite3_result_double(pCtx, 0.0);
}
- p->nValue = 0;
}
}
+#define percent_rankFinalizeFunc percent_rankValueFunc
/*
** Implementation of built-in window function cume_dist(). Assumes that
** the window frame has been set to:
**
-** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+** GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
*/
static void cume_distStepFunc(
sqlite3_context *pCtx,
@@ -143933,24 +146342,33 @@ static void cume_distStepFunc(
sqlite3_value **apArg
){
struct CallCount *p;
- assert( nArg==1 ); UNUSED_PARAMETER(nArg);
-
+ UNUSED_PARAMETER(nArg); assert( nArg==0 );
+ UNUSED_PARAMETER(apArg);
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
- if( p->nTotal==0 ){
- p->nTotal = sqlite3_value_int64(apArg[0]);
- }
- p->nStep++;
+ p->nTotal++;
}
}
-static void cume_distValueFunc(sqlite3_context *pCtx){
+static void cume_distInvFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
struct CallCount *p;
+ UNUSED_PARAMETER(nArg); assert( nArg==0 );
+ UNUSED_PARAMETER(apArg);
p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
- if( p && p->nTotal ){
+ p->nStep++;
+}
+static void cume_distValueFunc(sqlite3_context *pCtx){
+ struct CallCount *p;
+ p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0);
+ if( p ){
double r = (double)(p->nStep) / (double)(p->nTotal);
sqlite3_result_double(pCtx, r);
}
}
+#define cume_distFinalizeFunc cume_distValueFunc
/*
** Context object for ntile() window function.
@@ -143965,7 +146383,7 @@ struct NtileCtx {
** Implementation of ntile(). This assumes that the window frame has
** been coerced to:
**
-** ROWS UNBOUNDED PRECEDING AND CURRENT ROW
+** ROWS CURRENT ROW AND UNBOUNDED FOLLOWING
*/
static void ntileStepFunc(
sqlite3_context *pCtx,
@@ -143973,32 +146391,42 @@ static void ntileStepFunc(
sqlite3_value **apArg
){
struct NtileCtx *p;
- assert( nArg==2 ); UNUSED_PARAMETER(nArg);
+ assert( nArg==1 ); UNUSED_PARAMETER(nArg);
p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p ){
if( p->nTotal==0 ){
p->nParam = sqlite3_value_int64(apArg[0]);
- p->nTotal = sqlite3_value_int64(apArg[1]);
if( p->nParam<=0 ){
sqlite3_result_error(
pCtx, "argument of ntile must be a positive integer", -1
);
}
}
- p->iRow++;
+ p->nTotal++;
}
}
+static void ntileInvFunc(
+ sqlite3_context *pCtx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ struct NtileCtx *p;
+ assert( nArg==1 ); UNUSED_PARAMETER(nArg);
+ UNUSED_PARAMETER(apArg);
+ p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ p->iRow++;
+}
static void ntileValueFunc(sqlite3_context *pCtx){
struct NtileCtx *p;
p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p && p->nParam>0 ){
int nSize = (p->nTotal / p->nParam);
if( nSize==0 ){
- sqlite3_result_int64(pCtx, p->iRow);
+ sqlite3_result_int64(pCtx, p->iRow+1);
}else{
i64 nLarge = p->nTotal - p->nParam*nSize;
i64 iSmall = nLarge*(nSize+1);
- i64 iRow = p->iRow-1;
+ i64 iRow = p->iRow;
assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
@@ -144010,6 +146438,7 @@ static void ntileValueFunc(sqlite3_context *pCtx){
}
}
}
+#define ntileFinalizeFunc ntileValueFunc
/*
** Context object for last_value() window function.
@@ -144059,7 +146488,7 @@ static void last_valueInvFunc(
}
static void last_valueValueFunc(sqlite3_context *pCtx){
struct LastValueCtx *p;
- p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
+ p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, 0);
if( p && p->pVal ){
sqlite3_result_value(pCtx, p->pVal);
}
@@ -144149,12 +146578,12 @@ SQLITE_PRIVATE void sqlite3WindowFunctions(void){
WINDOWFUNCX(row_number, 0, 0),
WINDOWFUNCX(dense_rank, 0, 0),
WINDOWFUNCX(rank, 0, 0),
- WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
- WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
- WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
+ WINDOWFUNCALL(percent_rank, 0, 0),
+ WINDOWFUNCALL(cume_dist, 0, 0),
+ WINDOWFUNCALL(ntile, 1, 0),
WINDOWFUNCALL(last_value, 1, 0),
- WINDOWFUNCNOOP(nth_value, 2, 0),
- WINDOWFUNCNOOP(first_value, 1, 0),
+ WINDOWFUNCALL(nth_value, 2, 0),
+ WINDOWFUNCALL(first_value, 1, 0),
WINDOWFUNCNOOP(lead, 1, 0),
WINDOWFUNCNOOP(lead, 2, 0),
WINDOWFUNCNOOP(lead, 3, 0),
@@ -144165,6 +146594,17 @@ SQLITE_PRIVATE void sqlite3WindowFunctions(void){
sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
}
+static Window *windowFind(Parse *pParse, Window *pList, const char *zName){
+ Window *p;
+ for(p=pList; p; p=p->pNextWin){
+ if( sqlite3StrICmp(p->zName, zName)==0 ) break;
+ }
+ if( p==0 ){
+ sqlite3ErrorMsg(pParse, "no such window: %s", zName);
+ }
+ return p;
+}
+
/*
** This function is called immediately after resolving the function name
** for a window function within a SELECT statement. Argument pList is a
@@ -144188,48 +146628,66 @@ SQLITE_PRIVATE void sqlite3WindowUpdate(
Window *pWin, /* Window frame to update */
FuncDef *pFunc /* Window function definition */
){
- if( pWin->zName && pWin->eType==0 ){
- Window *p;
- for(p=pList; p; p=p->pNextWin){
- if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
- }
- if( p==0 ){
- sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
- return;
- }
+ if( pWin->zName && pWin->eFrmType==0 ){
+ Window *p = windowFind(pParse, pList, pWin->zName);
+ if( p==0 ) return;
pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
pWin->eStart = p->eStart;
pWin->eEnd = p->eEnd;
- pWin->eType = p->eType;
+ pWin->eFrmType = p->eFrmType;
+ pWin->eExclude = p->eExclude;
+ }else{
+ sqlite3WindowChain(pParse, pWin, pList);
}
+ if( (pWin->eFrmType==TK_RANGE)
+ && (pWin->pStart || pWin->pEnd)
+ && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
+ ){
+ sqlite3ErrorMsg(pParse,
+ "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression"
+ );
+ }else
if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
sqlite3 *db = pParse->db;
if( pWin->pFilter ){
sqlite3ErrorMsg(pParse,
"FILTER clause may only be used with aggregate window functions"
);
- }else
- if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
- sqlite3ExprDelete(db, pWin->pStart);
- sqlite3ExprDelete(db, pWin->pEnd);
- pWin->pStart = pWin->pEnd = 0;
- pWin->eType = TK_ROWS;
- pWin->eStart = TK_UNBOUNDED;
- pWin->eEnd = TK_CURRENT;
- }else
-
- if( pFunc->zName==dense_rankName || pFunc->zName==rankName
- || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
- ){
- sqlite3ExprDelete(db, pWin->pStart);
- sqlite3ExprDelete(db, pWin->pEnd);
- pWin->pStart = pWin->pEnd = 0;
- pWin->eType = TK_RANGE;
- pWin->eStart = TK_UNBOUNDED;
- pWin->eEnd = TK_CURRENT;
+ }else{
+ struct WindowUpdate {
+ const char *zFunc;
+ int eFrmType;
+ int eStart;
+ int eEnd;
+ } aUp[] = {
+ { row_numberName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT },
+ { dense_rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT },
+ { rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT },
+ { percent_rankName, TK_GROUPS, TK_CURRENT, TK_UNBOUNDED },
+ { cume_distName, TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED },
+ { ntileName, TK_ROWS, TK_CURRENT, TK_UNBOUNDED },
+ { leadName, TK_ROWS, TK_UNBOUNDED, TK_UNBOUNDED },
+ { lagName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT },
+ };
+ int i;
+ for(i=0; izName==aUp[i].zFunc ){
+ sqlite3ExprDelete(db, pWin->pStart);
+ sqlite3ExprDelete(db, pWin->pEnd);
+ pWin->pEnd = pWin->pStart = 0;
+ pWin->eFrmType = aUp[i].eFrmType;
+ pWin->eStart = aUp[i].eStart;
+ pWin->eEnd = aUp[i].eEnd;
+ pWin->eExclude = 0;
+ if( pWin->eStart==TK_FOLLOWING ){
+ pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1");
+ }
+ break;
+ }
+ }
}
}
pWin->pFunc = pFunc;
@@ -144244,6 +146702,7 @@ struct WindowRewrite {
Window *pWin;
SrcList *pSrc;
ExprList *pSub;
+ Table *pTab;
Select *pSubSelect; /* Current sub-select, if any */
};
@@ -144277,12 +146736,12 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
switch( pExpr->op ){
case TK_FUNCTION:
- if( pExpr->pWin==0 ){
+ if( !ExprHasProperty(pExpr, EP_WinFunc) ){
break;
}else{
Window *pWin;
for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
- if( pExpr->pWin==pWin ){
+ if( pExpr->y.pWin==pWin ){
assert( pWin->pOwner==pExpr );
return WRC_Prune;
}
@@ -144304,6 +146763,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
pExpr->op = TK_COLUMN;
pExpr->iColumn = p->pSub->nExpr-1;
pExpr->iTable = p->pWin->iEphCsr;
+ pExpr->y.pTab = p->pTab;
}
break;
@@ -144347,6 +146807,7 @@ static void selectWindowRewriteEList(
Window *pWin,
SrcList *pSrc,
ExprList *pEList, /* Rewrite expressions in this list */
+ Table *pTab,
ExprList **ppSub /* IN/OUT: Sub-select expression-list */
){
Walker sWalker;
@@ -144358,6 +146819,7 @@ static void selectWindowRewriteEList(
sRewrite.pSub = *ppSub;
sRewrite.pWin = pWin;
sRewrite.pSrc = pSrc;
+ sRewrite.pTab = pTab;
sWalker.pParse = pParse;
sWalker.xExprCallback = selectWindowRewriteExprCb;
@@ -144376,13 +146838,18 @@ static void selectWindowRewriteEList(
static ExprList *exprListAppendList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
- ExprList *pAppend /* List of values to append. Might be NULL */
+ ExprList *pAppend, /* List of values to append. Might be NULL */
+ int bIntToNull
){
if( pAppend ){
int i;
int nInit = pList ? pList->nExpr : 0;
for(i=0; inExpr; i++){
Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
+ if( bIntToNull && pDup && pDup->op==TK_INTEGER ){
+ pDup->op = TK_NULL;
+ pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse);
+ }
pList = sqlite3ExprListAppend(pParse, pList, pDup);
if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
}
@@ -144399,7 +146866,7 @@ static ExprList *exprListAppendList(
*/
SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
int rc = SQLITE_OK;
- if( p->pWin ){
+ if( p->pWin && p->pPrior==0 ){
Vdbe *v = sqlite3GetVdbe(pParse);
sqlite3 *db = pParse->db;
Select *pSub = 0; /* The subquery */
@@ -144412,17 +146879,24 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
ExprList *pSublist = 0; /* Expression list for sub-query */
Window *pMWin = p->pWin; /* Master window object */
Window *pWin; /* Window object iterator */
+ Table *pTab;
+
+ pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ){
+ return SQLITE_NOMEM;
+ }
p->pSrc = 0;
p->pWhere = 0;
p->pGroupBy = 0;
p->pHaving = 0;
+ p->selFlags &= ~SF_Aggregate;
/* Create the ORDER BY clause for the sub-select. This is the concatenation
** of the window PARTITION and ORDER BY clauses. Then, if this makes it
** redundant, remove the ORDER BY from the parent SELECT. */
pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0);
- pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy);
+ pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1);
if( pSort && p->pOrderBy ){
if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){
sqlite3ExprListDelete(db, p->pOrderBy);
@@ -144434,16 +146908,17 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
** The OpenEphemeral instruction is coded later, after it is known how
** many columns the table will have. */
pMWin->iEphCsr = pParse->nTab++;
+ pParse->nTab += 3;
- selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
- selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist);
+ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist);
pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
/* Append the PARTITION BY and ORDER BY expressions to the to the
** sub-select expression list. They are required to figure out where
** boundaries for partitions and sets of peer rows lie. */
- pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);
- pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy);
+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0);
+ pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0);
/* Append the arguments passed to each window function to the
** sub-select expression list. Also allocate two registers for each
@@ -144451,7 +146926,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
** results. */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
- pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList);
+ pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0);
if( pWin->pFilter ){
Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0);
pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter);
@@ -144476,24 +146951,30 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
pSub = sqlite3SelectNew(
pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
);
- p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
- assert( p->pSrc || db->mallocFailed );
+ p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( p->pSrc ){
+ Table *pTab2;
p->pSrc->a[0].pSelect = pSub;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
- if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){
+ pSub->selFlags |= SF_Expanded;
+ pTab2 = sqlite3ResultSetOfSelect(pParse, pSub);
+ if( pTab2==0 ){
rc = SQLITE_NOMEM;
}else{
- pSub->selFlags |= SF_Expanded;
- p->selFlags &= ~SF_Aggregate;
- sqlite3SelectPrep(pParse, pSub, 0);
+ memcpy(pTab, pTab2, sizeof(Table));
+ pTab->tabFlags |= TF_Ephemeral;
+ p->pSrc->a[0].pTab = pTab;
+ pTab = pTab2;
}
-
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
}else{
sqlite3SelectDelete(db, pSub);
}
if( db->mallocFailed ) rc = SQLITE_NOMEM;
+ sqlite3DbFree(db, pTab);
}
return rc;
@@ -144510,6 +146991,7 @@ SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){
sqlite3ExprDelete(db, p->pEnd);
sqlite3ExprDelete(db, p->pStart);
sqlite3DbFree(db, p->zName);
+ sqlite3DbFree(db, p->zBase);
sqlite3DbFree(db, p);
}
}
@@ -144534,6 +147016,7 @@ SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){
*/
static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
if( 0==sqlite3ExprIsConstant(pExpr) ){
+ if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr);
sqlite3ExprDelete(pParse->db, pExpr);
pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
}
@@ -144545,16 +147028,18 @@ static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
*/
SQLITE_PRIVATE Window *sqlite3WindowAlloc(
Parse *pParse, /* Parsing context */
- int eType, /* Frame type. TK_RANGE or TK_ROWS */
+ int eType, /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */
int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */
int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
- Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */
+ Expr *pEnd, /* End window size if TK_FOLLOWING or PRECEDING */
+ u8 eExclude /* EXCLUDE clause */
){
Window *pWin = 0;
+ int bImplicitFrame = 0;
/* Parser assures the following: */
- assert( eType==TK_RANGE || eType==TK_ROWS );
+ assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS );
assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
|| eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
@@ -144562,13 +147047,9 @@ SQLITE_PRIVATE Window *sqlite3WindowAlloc(
assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
-
- /* If a frame is declared "RANGE" (not "ROWS"), then it may not use
- ** either " PRECEDING" or " FOLLOWING".
- */
- if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){
- sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW");
- goto windowAllocErr;
+ if( eType==0 ){
+ bImplicitFrame = 1;
+ eType = TK_RANGE;
}
/* Additionally, the
@@ -144588,15 +147069,20 @@ SQLITE_PRIVATE Window *sqlite3WindowAlloc(
if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
|| (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
){
- sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");
+ sqlite3ErrorMsg(pParse, "unsupported frame specification");
goto windowAllocErr;
}
pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
if( pWin==0 ) goto windowAllocErr;
- pWin->eType = eType;
+ pWin->eFrmType = eType;
pWin->eStart = eStart;
pWin->eEnd = eEnd;
+ if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_WindowFunc) ){
+ eExclude = TK_NO;
+ }
+ pWin->eExclude = eExclude;
+ pWin->bImplicitFrame = bImplicitFrame;
pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
return pWin;
@@ -144607,16 +147093,81 @@ SQLITE_PRIVATE Window *sqlite3WindowAlloc(
return 0;
}
+/*
+** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window
+** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the
+** equivalent nul-terminated string.
+*/
+SQLITE_PRIVATE Window *sqlite3WindowAssemble(
+ Parse *pParse,
+ Window *pWin,
+ ExprList *pPartition,
+ ExprList *pOrderBy,
+ Token *pBase
+){
+ if( pWin ){
+ pWin->pPartition = pPartition;
+ pWin->pOrderBy = pOrderBy;
+ if( pBase ){
+ pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n);
+ }
+ }else{
+ sqlite3ExprListDelete(pParse->db, pPartition);
+ sqlite3ExprListDelete(pParse->db, pOrderBy);
+ }
+ return pWin;
+}
+
+/*
+** Window *pWin has just been created from a WINDOW clause. Tokne pBase
+** is the base window. Earlier windows from the same WINDOW clause are
+** stored in the linked list starting at pWin->pNextWin. This function
+** either updates *pWin according to the base specification, or else
+** leaves an error in pParse.
+*/
+SQLITE_PRIVATE void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){
+ if( pWin->zBase ){
+ sqlite3 *db = pParse->db;
+ Window *pExist = windowFind(pParse, pList, pWin->zBase);
+ if( pExist ){
+ const char *zErr = 0;
+ /* Check for errors */
+ if( pWin->pPartition ){
+ zErr = "PARTITION clause";
+ }else if( pExist->pOrderBy && pWin->pOrderBy ){
+ zErr = "ORDER BY clause";
+ }else if( pExist->bImplicitFrame==0 ){
+ zErr = "frame specification";
+ }
+ if( zErr ){
+ sqlite3ErrorMsg(pParse,
+ "cannot override %s of window: %s", zErr, pWin->zBase
+ );
+ }else{
+ pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0);
+ if( pExist->pOrderBy ){
+ assert( pWin->pOrderBy==0 );
+ pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0);
+ }
+ sqlite3DbFree(db, pWin->zBase);
+ pWin->zBase = 0;
+ }
+ }
+ }
+}
+
/*
** Attach window object pWin to expression p.
*/
SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
if( p ){
+ assert( p->op==TK_FUNCTION );
/* This routine is only called for the parser. If pWin was not
** allocated due to an OOM, then the parser would fail before ever
** invoking this routine */
if( ALWAYS(pWin) ){
- p->pWin = pWin;
+ p->y.pWin = pWin;
+ ExprSetProperty(p, EP_WinFunc);
pWin->pOwner = p;
if( p->flags & EP_Distinct ){
sqlite3ErrorMsg(pParse,
@@ -144633,9 +147184,10 @@ SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
** Identical window objects can be processed in a single scan.
*/
SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
- if( p1->eType!=p2->eType ) return 1;
+ if( p1->eFrmType!=p2->eFrmType ) return 1;
if( p1->eStart!=p2->eStart ) return 1;
if( p1->eEnd!=p2->eEnd ) return 1;
+ if( p1->eExclude!=p2->eExclude ) return 1;
if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
@@ -144652,12 +147204,27 @@ SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
Window *pWin;
Vdbe *v = sqlite3GetVdbe(pParse);
- int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
- nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
- if( nPart ){
+
+ /* Allocate registers to use for PARTITION BY values, if any. Initialize
+ ** said registers to NULL. */
+ if( pMWin->pPartition ){
+ int nExpr = pMWin->pPartition->nExpr;
pMWin->regPart = pParse->nMem+1;
- pParse->nMem += nPart;
- sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
+ pParse->nMem += nExpr;
+ sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1);
+ }
+
+ pMWin->regOne = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne);
+
+ if( pMWin->eExclude ){
+ pMWin->regStartRowid = ++pParse->nMem;
+ pMWin->regEndRowid = ++pParse->nMem;
+ pMWin->csrApp = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
+ sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
+ return;
}
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
@@ -144686,20 +147253,24 @@ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
else if( p->zName==nth_valueName || p->zName==first_valueName ){
/* Allocate two registers at pWin->regApp. These will be used to
** store the start and end index of the current frame. */
- assert( pMWin->iEphCsr );
pWin->regApp = pParse->nMem+1;
pWin->csrApp = pParse->nTab++;
pParse->nMem += 2;
sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
}
else if( p->zName==leadName || p->zName==lagName ){
- assert( pMWin->iEphCsr );
pWin->csrApp = pParse->nTab++;
sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
}
}
}
+#define WINDOW_STARTING_INT 0
+#define WINDOW_ENDING_INT 1
+#define WINDOW_NTH_VALUE_INT 2
+#define WINDOW_STARTING_NUM 3
+#define WINDOW_ENDING_NUM 4
+
/*
** A "PRECEDING " (eCond==0) or "FOLLOWING " (eCond==1) or the
** value of the second argument to nth_value() (eCond==2) has just been
@@ -144707,25 +147278,43 @@ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
** code to check that the value is a non-negative integer and throws an
** exception if it is not.
*/
-static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
+static void windowCheckValue(Parse *pParse, int reg, int eCond){
static const char *azErr[] = {
"frame starting offset must be a non-negative integer",
"frame ending offset must be a non-negative integer",
- "second argument to nth_value must be a positive integer"
+ "second argument to nth_value must be a positive integer",
+ "frame starting offset must be a non-negative number",
+ "frame ending offset must be a non-negative number",
};
- static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
+ static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge };
Vdbe *v = sqlite3GetVdbe(pParse);
int regZero = sqlite3GetTempReg(pParse);
- assert( eCond==0 || eCond==1 || eCond==2 );
+ assert( eCond>=0 && eCond=WINDOW_STARTING_NUM ){
+ int regString = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
+ sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg);
+ sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL);
+ VdbeCoverage(v);
+ assert( eCond==3 || eCond==4 );
+ VdbeCoverageIf(v, eCond==3);
+ VdbeCoverageIf(v, eCond==4);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ assert( eCond==0 || eCond==1 || eCond==2 );
+ VdbeCoverageIf(v, eCond==0);
+ VdbeCoverageIf(v, eCond==1);
+ VdbeCoverageIf(v, eCond==2);
+ }
sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
- VdbeCoverageNeverNullIf(v, eCond==0);
- VdbeCoverageNeverNullIf(v, eCond==1);
+ VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */
+ VdbeCoverageNeverNullIf(v, eCond==1); /* the OP_MustBeInt */
VdbeCoverageNeverNullIf(v, eCond==2);
+ VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */
+ VdbeCoverageNeverNullIf(v, eCond==4); /* the OP_Ge */
+ sqlite3MayAbort(pParse);
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
sqlite3ReleaseTempReg(pParse, regZero);
@@ -144764,37 +147353,28 @@ static void windowAggStep(
Window *pMWin, /* Linked list of window functions */
int csr, /* Read arguments from this cursor */
int bInverse, /* True to invoke xInverse instead of xStep */
- int reg, /* Array of registers */
- int regPartSize /* Register containing size of partition */
+ int reg /* Array of registers */
){
Vdbe *v = sqlite3GetVdbe(pParse);
Window *pWin;
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
- int flags = pWin->pFunc->funcFlags;
+ FuncDef *pFunc = pWin->pFunc;
int regArg;
int nArg = windowArgCount(pWin);
+ int i;
- if( csr>=0 ){
- int i;
- for(i=0; izName!=nth_valueName ){
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
}
- regArg = reg;
- if( flags & SQLITE_FUNC_WINDOW_SIZE ){
- if( nArg==0 ){
- regArg = regPartSize;
- }else{
- sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
- }
- nArg++;
- }
- }else{
- assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
- regArg = reg + pWin->iArgCol;
}
+ regArg = reg;
- if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
- && pWin->eStart!=TK_UNBOUNDED
+ if( pMWin->regStartRowid==0
+ && (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
+ && (pWin->eStart!=TK_UNBOUNDED)
){
int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
VdbeCoverage(v);
@@ -144811,34 +147391,24 @@ static void windowAggStep(
}
sqlite3VdbeJumpHere(v, addrIsNull);
}else if( pWin->regApp ){
- assert( pWin->pFunc->zName==nth_valueName
- || pWin->pFunc->zName==first_valueName
+ assert( pFunc->zName==nth_valueName
+ || pFunc->zName==first_valueName
);
assert( bInverse==0 || bInverse==1 );
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
- }else if( pWin->pFunc->zName==leadName
- || pWin->pFunc->zName==lagName
- ){
- /* no-op */
- }else{
+ }else if( pFunc->xSFunc!=noopStepFunc ){
int addrIf = 0;
if( pWin->pFilter ){
int regTmp;
assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
assert( nArg || pWin->pOwner->x.pList==0 );
- if( csr>0 ){
- regTmp = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
- }else{
- regTmp = regArg + nArg;
- }
+ regTmp = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
VdbeCoverage(v);
- if( csr>0 ){
- sqlite3ReleaseTempReg(pParse, regTmp);
- }
+ sqlite3ReleaseTempReg(pParse, regTmp);
}
- if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
+ if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl;
assert( nArg>0 );
pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
@@ -144846,45 +147416,96 @@ static void windowAggStep(
}
sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
bInverse, regArg, pWin->regAccum);
- sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
+ sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
}
}
+typedef struct WindowCodeArg WindowCodeArg;
+typedef struct WindowCsrAndReg WindowCsrAndReg;
+struct WindowCsrAndReg {
+ int csr;
+ int reg;
+};
+
+struct WindowCodeArg {
+ Parse *pParse;
+ Window *pMWin;
+ Vdbe *pVdbe;
+ int regGosub;
+ int addrGosub;
+ int regArg;
+ int eDelete;
+
+ WindowCsrAndReg start;
+ WindowCsrAndReg current;
+ WindowCsrAndReg end;
+};
+
+/*
+** Values that may be passed as the second argument to windowCodeOp().
+*/
+#define WINDOW_RETURN_ROW 1
+#define WINDOW_AGGINVERSE 2
+#define WINDOW_AGGSTEP 3
+
/*
-** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
-** (bFinal==1) for each window function in the linked list starting at
+** Generate VM code to read the window frames peer values from cursor csr into
+** an array of registers starting at reg.
+*/
+static void windowReadPeerValues(
+ WindowCodeArg *p,
+ int csr,
+ int reg
+){
+ Window *pMWin = p->pMWin;
+ ExprList *pOrderBy = pMWin->pOrderBy;
+ if( pOrderBy ){
+ Vdbe *v = sqlite3GetVdbe(p->pParse);
+ ExprList *pPart = pMWin->pPartition;
+ int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
+ int i;
+ for(i=0; inExpr; i++){
+ sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
+ }
+ }
+}
+
+/*
+** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
+** (bFin==1) for each window function in the linked list starting at
** pMWin. Or, for built-in window-functions that do not use the standard
** API, generate the equivalent VM code.
*/
-static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
+static void windowAggFinal(WindowCodeArg *p, int bFin){
+ Parse *pParse = p->pParse;
+ Window *pMWin = p->pMWin;
Vdbe *v = sqlite3GetVdbe(pParse);
Window *pWin;
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
- if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
- && pWin->eStart!=TK_UNBOUNDED
+ if( pMWin->regStartRowid==0
+ && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
+ && (pWin->eStart!=TK_UNBOUNDED)
){
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
- if( bFinal ){
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
- }
}else if( pWin->regApp ){
+ assert( pMWin->regStartRowid==0 );
}else{
- if( bFinal ){
- sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
+ int nArg = windowArgCount(pWin);
+ if( bFin ){
+ sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
}else{
- sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
- pWin->regResult);
+ sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
}
}
@@ -144892,66 +147513,97 @@ static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
}
/*
-** This function generates VM code to invoke the sub-routine at address
-** lblFlushPart once for each partition with the entire partition cached in
-** the Window.iEphCsr temp table.
+** Generate code to calculate the current values of all window functions in the
+** p->pMWin list by doing a full scan of the current window frame. Store the
+** results in the Window.regResult registers, ready to return the upper
+** layer.
*/
-static void windowPartitionCache(
- Parse *pParse,
- Select *p, /* The rewritten SELECT statement */
- WhereInfo *pWInfo, /* WhereInfo to call WhereEnd() on */
- int regFlushPart, /* Register to use with Gosub lblFlushPart */
- int lblFlushPart, /* Subroutine to Gosub to */
- int *pRegSize /* OUT: Register containing partition size */
-){
- Window *pMWin = p->pWin;
- Vdbe *v = sqlite3GetVdbe(pParse);
- int iSubCsr = p->pSrc->a[0].iCursor;
- int nSub = p->pSrc->a[0].pTab->nCol;
- int k;
+static void windowFullScan(WindowCodeArg *p){
+ Window *pWin;
+ Parse *pParse = p->pParse;
+ Window *pMWin = p->pMWin;
+ Vdbe *v = p->pVdbe;
- int reg = pParse->nMem+1;
- int regRecord = reg+nSub;
- int regRowid = regRecord+1;
+ int regCRowid = 0; /* Current rowid value */
+ int regCPeer = 0; /* Current peer values */
+ int regRowid = 0; /* AggStep rowid value */
+ int regPeer = 0; /* AggStep peer values */
- *pRegSize = regRowid;
- pParse->nMem += nSub + 2;
+ int nPeer;
+ int lblNext;
+ int lblBrk;
+ int addrNext;
+ int csr = pMWin->csrApp;
- /* Load the column values for the row returned by the sub-select
- ** into an array of registers starting at reg. */
- for(k=0; kpOrderBy ? pMWin->pOrderBy->nExpr : 0);
+
+ lblNext = sqlite3VdbeMakeLabel(pParse);
+ lblBrk = sqlite3VdbeMakeLabel(pParse);
+
+ regCRowid = sqlite3GetTempReg(pParse);
+ regRowid = sqlite3GetTempReg(pParse);
+ if( nPeer ){
+ regCPeer = sqlite3GetTempRange(pParse, nPeer);
+ regPeer = sqlite3GetTempRange(pParse, nPeer);
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
- /* Check if this is the start of a new partition. If so, call the
- ** flush_partition sub-routine. */
- if( pMWin->pPartition ){
+ sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid);
+ windowReadPeerValues(p, pMWin->iEphCsr, regCPeer);
+
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
+ }
+
+ sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid);
+ VdbeCoverage(v);
+ addrNext = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid);
+ VdbeCoverageNeverNull(v);
+
+ if( pMWin->eExclude==TK_CURRENT ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid);
+ VdbeCoverageNeverNull(v);
+ }else if( pMWin->eExclude!=TK_NO ){
int addr;
- ExprList *pPart = pMWin->pPartition;
- int nPart = pPart->nExpr;
- int regNewPart = reg + pMWin->nBufferCol;
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
+ int addrEq = 0;
+ KeyInfo *pKeyInfo = 0;
- addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
- sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
- sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
- VdbeCoverageEqNe(v);
- sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
- sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
- VdbeComment((v, "call flush_partition"));
+ if( pMWin->pOrderBy ){
+ pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0);
+ }
+ if( pMWin->eExclude==TK_TIES ){
+ addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid);
+ VdbeCoverageNeverNull(v);
+ }
+ if( pKeyInfo ){
+ windowReadPeerValues(p, csr, regPeer);
+ sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ addr = sqlite3VdbeCurrentAddr(v)+1;
+ sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr);
+ VdbeCoverageEqNe(v);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext);
+ }
+ if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
}
- /* Buffer the current row in the ephemeral table. */
- sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
+ windowAggStep(pParse, pMWin, csr, 0, p->regArg);
- /* End of the input loop */
- sqlite3WhereEnd(pWInfo);
+ sqlite3VdbeResolveLabel(v, lblNext);
+ sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
+ VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, addrNext-1);
+ sqlite3VdbeJumpHere(v, addrNext+1);
+ sqlite3ReleaseTempReg(pParse, regRowid);
+ sqlite3ReleaseTempReg(pParse, regCRowid);
+ if( nPeer ){
+ sqlite3ReleaseTempRange(pParse, regPeer, nPeer);
+ sqlite3ReleaseTempRange(pParse, regCPeer, nPeer);
+ }
- /* Invoke "flush_partition" to deal with the final (or only) partition */
- sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
- VdbeComment((v, "call flush_partition"));
+ windowAggFinal(p, 1);
}
/*
@@ -144967,110 +147619,74 @@ static void windowPartitionCache(
** lag()
** lead()
*/
-static void windowReturnOneRow(
- Parse *pParse,
- Window *pMWin,
- int regGosub,
- int addrGosub
-){
- Vdbe *v = sqlite3GetVdbe(pParse);
- Window *pWin;
- for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
- FuncDef *pFunc = pWin->pFunc;
- if( pFunc->zName==nth_valueName
- || pFunc->zName==first_valueName
- ){
- int csr = pWin->csrApp;
- int lbl = sqlite3VdbeMakeLabel(v);
- int tmpReg = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
+static void windowReturnOneRow(WindowCodeArg *p){
+ Window *pMWin = p->pMWin;
+ Vdbe *v = p->pVdbe;
- if( pFunc->zName==nth_valueName ){
- sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
- windowCheckIntValue(pParse, tmpReg, 2);
- }else{
- sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
- }
- sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
- sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
- VdbeCoverageNeverNull(v);
- sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
- VdbeCoverageNeverTaken(v);
- sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
- sqlite3VdbeResolveLabel(v, lbl);
- sqlite3ReleaseTempReg(pParse, tmpReg);
- }
- else if( pFunc->zName==leadName || pFunc->zName==lagName ){
- int nArg = pWin->pOwner->x.pList->nExpr;
- int iEph = pMWin->iEphCsr;
- int csr = pWin->csrApp;
- int lbl = sqlite3VdbeMakeLabel(v);
- int tmpReg = sqlite3GetTempReg(pParse);
-
- if( nArg<3 ){
+ if( pMWin->regStartRowid ){
+ windowFullScan(p);
+ }else{
+ Parse *pParse = p->pParse;
+ Window *pWin;
+
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ FuncDef *pFunc = pWin->pFunc;
+ if( pFunc->zName==nth_valueName
+ || pFunc->zName==first_valueName
+ ){
+ int csr = pWin->csrApp;
+ int lbl = sqlite3VdbeMakeLabel(pParse);
+ int tmpReg = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
- }else{
- sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
- }
- sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
- if( nArg<2 ){
- int val = (pFunc->zName==leadName ? 1 : -1);
- sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
- }else{
- int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
- int tmpReg2 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
- sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
- sqlite3ReleaseTempReg(pParse, tmpReg2);
+
+ if( pFunc->zName==nth_valueName ){
+ sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg);
+ windowCheckValue(pParse, tmpReg, 2);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
+ }
+ sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
+ sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
+ VdbeCoverageNeverNull(v);
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
+ VdbeCoverageNeverTaken(v);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
+ sqlite3VdbeResolveLabel(v, lbl);
+ sqlite3ReleaseTempReg(pParse, tmpReg);
+ }
+ else if( pFunc->zName==leadName || pFunc->zName==lagName ){
+ int nArg = pWin->pOwner->x.pList->nExpr;
+ int csr = pWin->csrApp;
+ int lbl = sqlite3VdbeMakeLabel(pParse);
+ int tmpReg = sqlite3GetTempReg(pParse);
+ int iEph = pMWin->iEphCsr;
+
+ if( nArg<3 ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_Column, iEph,pWin->iArgCol+2,pWin->regResult);
+ }
+ sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
+ if( nArg<2 ){
+ int val = (pFunc->zName==leadName ? 1 : -1);
+ sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val);
+ }else{
+ int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract);
+ int tmpReg2 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2);
+ sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg);
+ sqlite3ReleaseTempReg(pParse, tmpReg2);
+ }
+
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
+ sqlite3VdbeResolveLabel(v, lbl);
+ sqlite3ReleaseTempReg(pParse, tmpReg);
}
-
- sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
- sqlite3VdbeResolveLabel(v, lbl);
- sqlite3ReleaseTempReg(pParse, tmpReg);
}
}
- sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
-}
-
-/*
-** Invoke the code generated by windowReturnOneRow() and, optionally, the
-** xInverse() function for each window function, for one or more rows
-** from the Window.iEphCsr temp table. This routine generates VM code
-** similar to:
-**
-** while( regCtr>0 ){
-** regCtr--;
-** windowReturnOneRow()
-** if( bInverse ){
-** AggInverse
-** }
-** Next (Window.iEphCsr)
-** }
-*/
-static void windowReturnRows(
- Parse *pParse,
- Window *pMWin, /* List of window functions */
- int regCtr, /* Register containing number of rows */
- int regGosub, /* Register for Gosub addrGosub */
- int addrGosub, /* Address of sub-routine for ReturnOneRow */
- int regInvArg, /* Array of registers for xInverse args */
- int regInvSize /* Register containing size of partition */
-){
- int addr;
- Vdbe *v = sqlite3GetVdbe(pParse);
- windowAggFinal(pParse, pMWin, 0);
- addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
- windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
- if( regInvArg ){
- windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
- }
- sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
- VdbeCoverage(v);
- sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */
+ sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub);
}
/*
@@ -145088,17 +147704,17 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
FuncDef *pFunc = pWin->pFunc;
sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
nArg = MAX(nArg, windowArgCount(pWin));
- if( pFunc->zName==nth_valueName
- || pFunc->zName==first_valueName
- ){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
- }
+ if( pMWin->regStartRowid==0 ){
+ if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ }
- if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
- assert( pWin->eStart!=TK_UNBOUNDED );
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
+ assert( pWin->eStart!=TK_UNBOUNDED );
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
+ }
}
}
regArg = pParse->nMem+1;
@@ -145106,672 +147722,248 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
return regArg;
}
+/*
+** Return true if the current frame should be cached in the ephemeral table,
+** even if there are no xInverse() calls required.
+*/
+static int windowCacheFrame(Window *pMWin){
+ Window *pWin;
+ if( pMWin->regStartRowid ) return 1;
+ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
+ FuncDef *pFunc = pWin->pFunc;
+ if( (pFunc->zName==nth_valueName)
+ || (pFunc->zName==first_valueName)
+ || (pFunc->zName==leadName)
+ || (pFunc->zName==lagName)
+ ){
+ return 1;
+ }
+ }
+ return 0;
+}
/*
-** This function does the work of sqlite3WindowCodeStep() for all "ROWS"
-** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT
-** ROW". Pseudo-code for each follows.
-**
-** ROWS BETWEEN PRECEDING AND FOLLOWING
-**
-** ...
-** if( new partition ){
-** Gosub flush_partition
-** }
-** Insert (record in eph-table)
-** sqlite3WhereEnd()
-** Gosub flush_partition
-**
-** flush_partition:
-** Once {
-** OpenDup (iEphCsr -> csrStart)
-** OpenDup (iEphCsr -> csrEnd)
-** }
-** regStart = // PRECEDING expression
-** regEnd = // FOLLOWING expression
-** if( regStart<0 || regEnd<0 ){ error! }
-** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
-** Next(csrEnd) // if EOF skip Aggstep
-** Aggstep (csrEnd)
-** if( (regEnd--)<=0 ){
-** AggFinal (xValue)
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** if( (regStart--)<=0 ){
-** AggInverse (csrStart)
-** Next(csrStart)
-** }
-** }
-** flush_partition_done:
-** ResetSorter (csr)
-** Return
-**
-** ROWS BETWEEN PRECEDING AND CURRENT ROW
-** ROWS BETWEEN CURRENT ROW AND FOLLOWING
-** ROWS BETWEEN UNBOUNDED PRECEDING AND FOLLOWING
-**
-** These are similar to the above. For "CURRENT ROW", intialize the
-** register to 0. For "UNBOUNDED PRECEDING" to infinity.
-**
-** ROWS BETWEEN PRECEDING AND UNBOUNDED FOLLOWING
-** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
-**
-** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
-** while( 1 ){
-** Next(csrEnd) // Exit while(1) at EOF
-** Aggstep (csrEnd)
-** }
-** while( 1 ){
-** AggFinal (xValue)
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** if( (regStart--)<=0 ){
-** AggInverse (csrStart)
-** Next(csrStart)
-** }
-** }
-**
-** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if()
-** condition is always true (as if regStart were initialized to 0).
-**
-** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
-**
-** This is the only RANGE case handled by this routine. It modifies the
-** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
-** be:
-**
-** while( 1 ){
-** AggFinal (xValue)
-** while( 1 ){
-** regPeer++
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** if( new peer ) break;
-** }
-** while( (regPeer--)>0 ){
-** AggInverse (csrStart)
-** Next(csrStart)
-** }
-** }
-**
-** ROWS BETWEEN FOLLOWING AND FOLLOWING
-**
-** regEnd = regEnd - regStart
-** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done
-** Aggstep (csrEnd)
-** Next(csrEnd) // if EOF fall-through
-** if( (regEnd--)<=0 ){
-** if( (regStart--)<=0 ){
-** AggFinal (xValue)
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** }
-** AggInverse (csrStart)
-** Next (csrStart)
-** }
-**
-** ROWS BETWEEN PRECEDING AND PRECEDING
-**
-** Replace the bit after "Rewind" in the above with:
-**
-** if( (regEnd--)<=0 ){
-** AggStep (csrEnd)
-** Next (csrEnd)
-** }
-** AggFinal (xValue)
-** Gosub addrGosub
-** Next(csr) // if EOF goto flush_partition_done
-** if( (regStart--)<=0 ){
-** AggInverse (csr2)
-** Next (csr2)
-** }
+** regOld and regNew are each the first register in an array of size
+** pOrderBy->nExpr. This function generates code to compare the two
+** arrays of registers using the collation sequences and other comparison
+** parameters specified by pOrderBy.
**
+** If the two arrays are not equal, the contents of regNew is copied to
+** regOld and control falls through. Otherwise, if the contents of the arrays
+** are equal, an OP_Goto is executed. The address of the OP_Goto is returned.
*/
-static void windowCodeRowExprStep(
- Parse *pParse,
- Select *p,
- WhereInfo *pWInfo,
- int regGosub,
- int addrGosub
+static void windowIfNewPeer(
+ Parse *pParse,
+ ExprList *pOrderBy,
+ int regNew, /* First in array of new values */
+ int regOld, /* First in array of old values */
+ int addr /* Jump here */
){
- Window *pMWin = p->pWin;
Vdbe *v = sqlite3GetVdbe(pParse);
- int regFlushPart; /* Register for "Gosub flush_partition" */
- int lblFlushPart; /* Label for "Gosub flush_partition" */
- int lblFlushDone; /* Label for "Gosub flush_partition_done" */
-
- int regArg;
- int addr;
- int csrStart = pParse->nTab++;
- int csrEnd = pParse->nTab++;
- int regStart; /* Value of PRECEDING */
- int regEnd; /* Value of FOLLOWING */
- int addrGoto;
- int addrTop;
- int addrIfPos1 = 0;
- int addrIfPos2 = 0;
- int regSize = 0;
-
- assert( pMWin->eStart==TK_PRECEDING
- || pMWin->eStart==TK_CURRENT
- || pMWin->eStart==TK_FOLLOWING
- || pMWin->eStart==TK_UNBOUNDED
- );
- assert( pMWin->eEnd==TK_FOLLOWING
- || pMWin->eEnd==TK_CURRENT
- || pMWin->eEnd==TK_UNBOUNDED
- || pMWin->eEnd==TK_PRECEDING
- );
-
- /* Allocate register and label for the "flush_partition" sub-routine. */
- regFlushPart = ++pParse->nMem;
- lblFlushPart = sqlite3VdbeMakeLabel(v);
- lblFlushDone = sqlite3VdbeMakeLabel(v);
-
- regStart = ++pParse->nMem;
- regEnd = ++pParse->nMem;
-
- windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size);
-
- addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
-
- /* Start of "flush_partition" */
- sqlite3VdbeResolveLabel(v, lblFlushPart);
- sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
- VdbeCoverage(v);
- VdbeComment((v, "Flush_partition subroutine"));
- sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
- sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
-
- /* If either regStart or regEnd are not non-negative integers, throw
- ** an exception. */
- if( pMWin->pStart ){
- sqlite3ExprCode(pParse, pMWin->pStart, regStart);
- windowCheckIntValue(pParse, regStart, 0);
- }
- if( pMWin->pEnd ){
- sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
- windowCheckIntValue(pParse, regEnd, 1);
- }
-
- /* If this is "ROWS FOLLOWING AND ROWS FOLLOWING", do:
- **
- ** if( regEndpEnd && pMWin->eStart==TK_FOLLOWING ){
- assert( pMWin->pStart!=0 );
- assert( pMWin->eEnd==TK_FOLLOWING );
- sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
- VdbeCoverageNeverNull(v);
- sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
- sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
- }
-
- if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
- assert( pMWin->pEnd!=0 );
- assert( pMWin->eStart==TK_PRECEDING );
- sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
- VdbeCoverageNeverNull(v);
- sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
- sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
- }
-
- /* Initialize the accumulator register for each window function to NULL */
- regArg = windowInitAccum(pParse, pMWin);
-
- sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
- VdbeCoverageNeverTaken(v);
- sqlite3VdbeChangeP5(v, 1);
- sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
- VdbeCoverageNeverTaken(v);
- sqlite3VdbeChangeP5(v, 1);
-
- /* Invoke AggStep function for each window function using the row that
- ** csrEnd currently points to. Or, if csrEnd is already at EOF,
- ** do nothing. */
- addrTop = sqlite3VdbeCurrentAddr(v);
- if( pMWin->eEnd==TK_PRECEDING ){
- addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
- VdbeCoverage(v);
- }
- sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- addr = sqlite3VdbeAddOp0(v, OP_Goto);
- windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
- if( pMWin->eEnd==TK_UNBOUNDED ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
- sqlite3VdbeJumpHere(v, addr);
- addrTop = sqlite3VdbeCurrentAddr(v);
+ if( pOrderBy ){
+ int nVal = pOrderBy->nExpr;
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
+ sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeAddOp3(v, OP_Jump,
+ sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1
+ );
+ VdbeCoverageEqNe(v);
+ sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1);
}else{
- sqlite3VdbeJumpHere(v, addr);
- if( pMWin->eEnd==TK_PRECEDING ){
- sqlite3VdbeJumpHere(v, addrIfPos1);
- }
- }
-
- if( pMWin->eEnd==TK_FOLLOWING ){
- addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
- VdbeCoverage(v);
- }
- if( pMWin->eStart==TK_FOLLOWING ){
- addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
- VdbeCoverage(v);
- }
- windowAggFinal(pParse, pMWin, 0);
- windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
- sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
- if( pMWin->eStart==TK_FOLLOWING ){
- sqlite3VdbeJumpHere(v, addrIfPos2);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
}
-
- if( pMWin->eStart==TK_CURRENT
- || pMWin->eStart==TK_PRECEDING
- || pMWin->eStart==TK_FOLLOWING
- ){
- int lblSkipInverse = sqlite3VdbeMakeLabel(v);;
- if( pMWin->eStart==TK_PRECEDING ){
- sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
- VdbeCoverage(v);
- }
- if( pMWin->eStart==TK_FOLLOWING ){
- sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse);
- }else{
- sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
- VdbeCoverageAlwaysTaken(v);
- }
- windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
- sqlite3VdbeResolveLabel(v, lblSkipInverse);
- }
- if( pMWin->eEnd==TK_FOLLOWING ){
- sqlite3VdbeJumpHere(v, addrIfPos1);
- }
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
-
- /* flush_partition_done: */
- sqlite3VdbeResolveLabel(v, lblFlushDone);
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
- sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
- VdbeComment((v, "end flush_partition subroutine"));
-
- /* Jump to here to skip over flush_partition */
- sqlite3VdbeJumpHere(v, addrGoto);
}
/*
-** This function does the work of sqlite3WindowCodeStep() for cases that
-** would normally be handled by windowCodeDefaultStep() when there are
-** one or more built-in window-functions that require the entire partition
-** to be cached in a temp table before any rows can be returned. Additionally.
-** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by
-** this function.
-**
-** Pseudo-code corresponding to the VM code generated by this function
-** for each type of window follows.
-**
-** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-**
-** flush_partition:
-** Once {
-** OpenDup (iEphCsr -> csrLead)
-** }
-** Integer ctr 0
-** foreach row (csrLead){
-** if( new peer ){
-** AggFinal (xValue)
-** for(i=0; i= csr2.peerVal ) goto lbl;
**
-** flush_partition:
-** Once {
-** OpenDup (iEphCsr -> csrLead)
-** }
-** foreach row (csrLead) {
-** AggStep (csrLead)
-** }
-** foreach row (iEphCsr) {
-** Gosub addrGosub
-** }
-**
-** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
-**
-** flush_partition:
-** Once {
-** OpenDup (iEphCsr -> csrLead)
-** }
-** foreach row (csrLead){
-** AggStep (csrLead)
-** }
-** Rewind (csrLead)
-** Integer ctr 0
-** foreach row (csrLead){
-** if( new peer ){
-** AggFinal (xValue)
-** for(i=0; ipWin;
+ Parse *pParse = p->pParse;
Vdbe *v = sqlite3GetVdbe(pParse);
- int k;
- int addr;
- ExprList *pPart = pMWin->pPartition;
- ExprList *pOrderBy = pMWin->pOrderBy;
- int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
- int regNewPeer;
-
- int addrGoto; /* Address of Goto used to jump flush_par.. */
- int addrNext; /* Jump here for next iteration of loop */
- int regFlushPart;
- int lblFlushPart;
- int csrLead;
- int regCtr;
- int regArg; /* Register array to martial function args */
- int regSize;
- int lblEmpty;
- int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT
- && pMWin->eEnd==TK_UNBOUNDED;
-
- assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
- || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
- || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
- || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED)
- );
-
- lblEmpty = sqlite3VdbeMakeLabel(v);
- regNewPeer = pParse->nMem+1;
- pParse->nMem += nPeer;
-
- /* Allocate register and label for the "flush_partition" sub-routine. */
- regFlushPart = ++pParse->nMem;
- lblFlushPart = sqlite3VdbeMakeLabel(v);
-
- csrLead = pParse->nTab++;
- regCtr = ++pParse->nMem;
-
- windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size);
- addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
-
- /* Start of "flush_partition" */
- sqlite3VdbeResolveLabel(v, lblFlushPart);
- sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
-
- /* Initialize the accumulator register for each window function to NULL */
- regArg = windowInitAccum(pParse, pMWin);
-
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
- sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);
- VdbeCoverageNeverTaken(v);
+ int reg1 = sqlite3GetTempReg(pParse);
+ int reg2 = sqlite3GetTempReg(pParse);
+ int arith = OP_Add;
+ int addrGe;
- if( bReverse ){
- int addr2 = sqlite3VdbeCurrentAddr(v);
- windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
- sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
- VdbeCoverageNeverTaken(v);
- }
- addrNext = sqlite3VdbeCurrentAddr(v);
+ int regString = ++pParse->nMem;
- if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
- int bCurrent = (pMWin->eStart==TK_CURRENT);
- int addrJump = 0; /* Address of OP_Jump below */
- if( pMWin->eType==TK_RANGE ){
- int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
- int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
- for(k=0; kpMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 );
+ if( p->pMWin->pOrderBy->a[0].sortOrder ){
+ switch( op ){
+ case OP_Ge: op = OP_Le; break;
+ case OP_Gt: op = OP_Lt; break;
+ default: assert( op==OP_Le ); op = OP_Ge; break;
}
-
- windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub,
- (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)
- );
- if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
+ arith = OP_Subtract;
}
- if( bReverse==0 ){
- windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
- }
- sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);
- sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext);
- VdbeCoverage(v);
+ windowReadPeerValues(p, csr1, reg1);
+ windowReadPeerValues(p, csr2, reg2);
- windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0);
-
- sqlite3VdbeResolveLabel(v, lblEmpty);
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
- sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
+ /* Check if the peer value for csr1 value is a text or blob by comparing
+ ** it to the smallest possible string - ''. If it is, jump over the
+ ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
+ addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
+ sqlite3VdbeJumpHere(v, addrGe);
+ sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+ assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
+ testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
+ testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
+ testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
+ testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
- /* Jump to here to skip over flush_partition */
- sqlite3VdbeJumpHere(v, addrGoto);
+ sqlite3ReleaseTempReg(pParse, reg1);
+ sqlite3ReleaseTempReg(pParse, reg2);
}
-
/*
-** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-**
-** ...
-** if( new partition ){
-** AggFinal (xFinalize)
-** Gosub addrGosub
-** ResetSorter eph-table
-** }
-** else if( new peer ){
-** AggFinal (xValue)
-** Gosub addrGosub
-** ResetSorter eph-table
-** }
-** AggStep
-** Insert (record into eph-table)
-** sqlite3WhereEnd()
-** AggFinal (xFinalize)
-** Gosub addrGosub
-**
-** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
-**
-** As above, except take no action for a "new peer". Invoke
-** the sub-routine once only for each partition.
-**
-** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
-**
-** As above, except that the "new peer" condition is handled in the
-** same way as "new partition" (so there is no "else if" block).
-**
-** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
-**
-** As above, except assume every row is a "new peer".
+** Helper function for sqlite3WindowCodeStep(). Each call to this function
+** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE
+** operation. Refer to the header comment for sqlite3WindowCodeStep() for
+** details.
*/
-static void windowCodeDefaultStep(
- Parse *pParse,
- Select *p,
- WhereInfo *pWInfo,
- int regGosub,
- int addrGosub
+static int windowCodeOp(
+ WindowCodeArg *p, /* Context object */
+ int op, /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */
+ int regCountdown, /* Register for OP_IfPos countdown */
+ int jumpOnEof /* Jump here if stepped cursor reaches EOF */
){
- Window *pMWin = p->pWin;
- Vdbe *v = sqlite3GetVdbe(pParse);
- int k;
- int iSubCsr = p->pSrc->a[0].iCursor;
- int nSub = p->pSrc->a[0].pTab->nCol;
- int reg = pParse->nMem+1;
- int regRecord = reg+nSub;
- int regRowid = regRecord+1;
- int addr;
- ExprList *pPart = pMWin->pPartition;
- ExprList *pOrderBy = pMWin->pOrderBy;
-
- assert( pMWin->eType==TK_RANGE
- || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
- );
-
- assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
- || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
- || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
- || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
- );
-
- if( pMWin->eEnd==TK_UNBOUNDED ){
- pOrderBy = 0;
- }
-
- pParse->nMem += nSub + 2;
-
- /* Load the individual column values of the row returned by
- ** the sub-select into an array of registers. */
- for(k=0; kpParse;
+ Window *pMWin = p->pMWin;
+ int ret = 0;
+ Vdbe *v = p->pVdbe;
+ int addrIf = 0;
+ int addrContinue = 0;
+ int addrGoto = 0;
+ int bPeer = (pMWin->eFrmType!=TK_ROWS);
+
+ int lblDone = sqlite3VdbeMakeLabel(pParse);
+ int addrNextRange = 0;
+
+ /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
+ ** starts with UNBOUNDED PRECEDING. */
+ if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){
+ assert( regCountdown==0 && jumpOnEof==0 );
+ return 0;
}
- /* Check if this is the start of a new partition or peer group. */
- if( pPart || pOrderBy ){
- int nPart = (pPart ? pPart->nExpr : 0);
- int addrGoto = 0;
- int addrJump = 0;
- int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
-
- if( pPart ){
- int regNewPart = reg + pMWin->nBufferCol;
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
- addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
- sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
- addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
- VdbeCoverageEqNe(v);
- windowAggFinal(pParse, pMWin, 1);
- if( pOrderBy ){
- addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
+ if( regCountdown>0 ){
+ if( pMWin->eFrmType==TK_RANGE ){
+ addrNextRange = sqlite3VdbeCurrentAddr(v);
+ assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP );
+ if( op==WINDOW_AGGINVERSE ){
+ if( pMWin->eStart==TK_FOLLOWING ){
+ windowCodeRangeTest(
+ p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone
+ );
+ }else{
+ windowCodeRangeTest(
+ p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone
+ );
+ }
+ }else{
+ windowCodeRangeTest(
+ p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone
+ );
}
+ }else{
+ addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
+ VdbeCoverage(v);
}
+ }
- if( pOrderBy ){
- int regNewPeer = reg + pMWin->nBufferCol + nPart;
- int regPeer = pMWin->regPart + nPart;
+ if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){
+ windowAggFinal(p, 0);
+ }
+ addrContinue = sqlite3VdbeCurrentAddr(v);
+ switch( op ){
+ case WINDOW_RETURN_ROW:
+ csr = p->current.csr;
+ reg = p->current.reg;
+ windowReturnOneRow(p);
+ break;
- if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
- if( pMWin->eType==TK_RANGE ){
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
- addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
- sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
- addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
- VdbeCoverage(v);
+ case WINDOW_AGGINVERSE:
+ csr = p->start.csr;
+ reg = p->start.reg;
+ if( pMWin->regStartRowid ){
+ assert( pMWin->regEndRowid );
+ sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
}else{
- addrJump = 0;
+ windowAggStep(pParse, pMWin, csr, 1, p->regArg);
}
- windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
- if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
- }
-
- sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
- sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
- VdbeCoverage(v);
-
- sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
- sqlite3VdbeAddOp3(
- v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
- );
+ break;
- if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
+ default:
+ assert( op==WINDOW_AGGSTEP );
+ csr = p->end.csr;
+ reg = p->end.reg;
+ if( pMWin->regStartRowid ){
+ assert( pMWin->regEndRowid );
+ sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
+ }else{
+ windowAggStep(pParse, pMWin, csr, 0, p->regArg);
+ }
+ break;
}
- /* Invoke step function for window functions */
- windowAggStep(pParse, pMWin, -1, 0, reg, 0);
+ if( op==p->eDelete ){
+ sqlite3VdbeAddOp1(v, OP_Delete, csr);
+ sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
+ }
- /* Buffer the current row in the ephemeral table. */
- if( pMWin->nBufferCol>0 ){
- sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
+ if( jumpOnEof ){
+ sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
+ ret = sqlite3VdbeAddOp0(v, OP_Goto);
}else{
- sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
- sqlite3VdbeAppendP4(v, (void*)"", 0);
+ sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
+ VdbeCoverage(v);
+ if( bPeer ){
+ addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
+ }
}
- sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
- /* End the database scan loop. */
- sqlite3WhereEnd(pWInfo);
+ if( bPeer ){
+ int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
+ int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0);
+ windowReadPeerValues(p, csr, regTmp);
+ windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue);
+ sqlite3ReleaseTempRange(pParse, regTmp, nReg);
+ }
- windowAggFinal(pParse, pMWin, 1);
- sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
- sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
- VdbeCoverage(v);
+ if( addrNextRange ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
+ }
+ sqlite3VdbeResolveLabel(v, lblDone);
+ if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
+ if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
+ return ret;
}
+
/*
** Allocate and return a duplicate of the Window object indicated by the
** third argument. Set the Window.pOwner field of the new object to
@@ -145779,16 +147971,18 @@ static void windowCodeDefaultStep(
*/
SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
Window *pNew = 0;
- if( p ){
+ if( ALWAYS(p) ){
pNew = sqlite3DbMallocZero(db, sizeof(Window));
if( pNew ){
pNew->zName = sqlite3DbStrDup(db, p->zName);
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
+ pNew->pFunc = p->pFunc;
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
- pNew->eType = p->eType;
+ pNew->eFrmType = p->eFrmType;
pNew->eEnd = p->eEnd;
pNew->eStart = p->eStart;
+ pNew->eExclude = p->eExclude;
pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
pNew->pOwner = pOwner;
@@ -145815,12 +148009,360 @@ SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){
return pRet;
}
+/*
+** Return true if it can be determined at compile time that expression
+** pExpr evaluates to a value that, when cast to an integer, is greater
+** than zero. False otherwise.
+**
+** If an OOM error occurs, this function sets the Parse.db.mallocFailed
+** flag and returns zero.
+*/
+static int windowExprGtZero(Parse *pParse, Expr *pExpr){
+ int ret = 0;
+ sqlite3 *db = pParse->db;
+ sqlite3_value *pVal = 0;
+ sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal);
+ if( pVal && sqlite3_value_int(pVal)>0 ){
+ ret = 1;
+ }
+ sqlite3ValueFree(pVal);
+ return ret;
+}
+
/*
** sqlite3WhereBegin() has already been called for the SELECT statement
** passed as the second argument when this function is invoked. It generates
-** code to populate the Window.regResult register for each window function and
-** invoke the sub-routine at instruction addrGosub once for each row.
-** This function calls sqlite3WhereEnd() before returning.
+** code to populate the Window.regResult register for each window function
+** and invoke the sub-routine at instruction addrGosub once for each row.
+** sqlite3WhereEnd() is always called before returning.
+**
+** This function handles several different types of window frames, which
+** require slightly different processing. The following pseudo code is
+** used to implement window frames of the form:
+**
+** ROWS BETWEEN PRECEDING AND FOLLOWING
+**
+** Other window frame types use variants of the following:
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+**
+** if( first row of partition ){
+** // Rewind three cursors, all open on the eph table.
+** Rewind(csrEnd);
+** Rewind(csrStart);
+** Rewind(csrCurrent);
+**
+** regEnd = // FOLLOWING expression
+** regStart = // PRECEDING expression
+** }else{
+** // First time this branch is taken, the eph table contains two
+** // rows. The first row in the partition, which all three cursors
+** // currently point to, and the following row.
+** AGGSTEP
+** if( (regEnd--)<=0 ){
+** RETURN_ROW
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** }
+** }
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** RETURN ROW
+** if( csrCurrent is EOF ) break;
+** if( (regStart--)<=0 ){
+** AggInverse(csrStart)
+** Next(csrStart)
+** }
+** }
+**
+** The pseudo-code above uses the following shorthand:
+**
+** AGGSTEP: invoke the aggregate xStep() function for each window function
+** with arguments read from the current row of cursor csrEnd, then
+** step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()).
+**
+** RETURN_ROW: return a row to the caller based on the contents of the
+** current row of csrCurrent and the current state of all
+** aggregates. Then step cursor csrCurrent forward one row.
+**
+** AGGINVERSE: invoke the aggregate xInverse() function for each window
+** functions with arguments read from the current row of cursor
+** csrStart. Then step csrStart forward one row.
+**
+** There are two other ROWS window frames that are handled significantly
+** differently from the above - "BETWEEN PRECEDING AND PRECEDING"
+** and "BETWEEN FOLLOWING AND FOLLOWING". These are special
+** cases because they change the order in which the three cursors (csrStart,
+** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that
+** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these
+** three.
+**
+** ROWS BETWEEN PRECEDING AND PRECEDING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else{
+** if( (regEnd--)<=0 ){
+** AGGSTEP
+** }
+** RETURN_ROW
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** }
+** }
+** }
+** flush:
+** if( (regEnd--)<=0 ){
+** AGGSTEP
+** }
+** RETURN_ROW
+**
+**
+** ROWS BETWEEN FOLLOWING AND FOLLOWING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart = regEnd -
+** }else{
+** AGGSTEP
+** if( (regEnd--)<=0 ){
+** RETURN_ROW
+** }
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** }
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** if( (regEnd--)<=0 ){
+** RETURN_ROW
+** if( eof ) break;
+** }
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** if( eof ) break
+** }
+** }
+** while( !eof csrCurrent ){
+** RETURN_ROW
+** }
+**
+** For the most part, the patterns above are adapted to support UNBOUNDED by
+** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and
+** CURRENT ROW by assuming that it is equivilent to "0 PRECEDING/FOLLOWING".
+** This is optimized of course - branches that will never be taken and
+** conditions that are always true are omitted from the VM code. The only
+** exceptional case is:
+**
+** ROWS BETWEEN FOLLOWING AND UNBOUNDED FOLLOWING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regStart =
+** }else{
+** AGGSTEP
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** if( (regStart--)<=0 ){
+** AGGINVERSE
+** if( eof ) break
+** }
+** RETURN_ROW
+** }
+** while( !eof csrCurrent ){
+** RETURN_ROW
+** }
+**
+** Also requiring special handling are the cases:
+**
+** ROWS BETWEEN PRECEDING AND PRECEDING
+** ROWS BETWEEN FOLLOWING AND FOLLOWING
+**
+** when (expr1 < expr2). This is detected at runtime, not by this function.
+** To handle this case, the pseudo-code programs depicted above are modified
+** slightly to be:
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** if( regEnd < regStart ){
+** RETURN_ROW
+** delete eph table contents
+** continue
+** }
+** ...
+**
+** The new "continue" statement in the above jumps to the next iteration
+** of the outer loop - the one started by sqlite3WhereBegin().
+**
+** The various GROUPS cases are implemented using the same patterns as
+** ROWS. The VM code is modified slightly so that:
+**
+** 1. The else branch in the main loop is only taken if the row just
+** added to the ephemeral table is the start of a new group. In
+** other words, it becomes:
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else if( new group ){
+** ...
+** }
+** }
+**
+** 2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or
+** AGGINVERSE step processes the current row of the relevant cursor and
+** all subsequent rows belonging to the same group.
+**
+** RANGE window frames are a little different again. As for GROUPS, the
+** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE
+** deal in groups instead of rows. As for ROWS and GROUPS, there are three
+** basic cases:
+**
+** RANGE BETWEEN PRECEDING AND FOLLOWING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else{
+** AGGSTEP
+** while( (csrCurrent.key + regEnd) < csrEnd.key ){
+** RETURN_ROW
+** while( csrStart.key + regStart) < csrCurrent.key ){
+** AGGINVERSE
+** }
+** }
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** RETURN ROW
+** if( csrCurrent is EOF ) break;
+** while( csrStart.key + regStart) < csrCurrent.key ){
+** AGGINVERSE
+** }
+** }
+** }
+**
+** In the above notation, "csr.key" means the current value of the ORDER BY
+** expression (there is only ever 1 for a RANGE that uses an FOLLOWING
+** or PRECEDING AND PRECEDING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else{
+** if( (csrEnd.key + regEnd) <= csrCurrent.key ){
+** AGGSTEP
+** }
+** while( (csrStart.key + regStart) < csrCurrent.key ){
+** AGGINVERSE
+** }
+** RETURN_ROW
+** }
+** }
+** flush:
+** while( (csrEnd.key + regEnd) <= csrCurrent.key ){
+** AGGSTEP
+** }
+** while( (csrStart.key + regStart) < csrCurrent.key ){
+** AGGINVERSE
+** }
+** RETURN_ROW
+**
+** RANGE BETWEEN FOLLOWING AND FOLLOWING
+**
+** ... loop started by sqlite3WhereBegin() ...
+** if( new partition ){
+** Gosub flush
+** }
+** Insert new row into eph table.
+** if( first row of partition ){
+** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
+** regEnd =
+** regStart =
+** }else{
+** AGGSTEP
+** while( (csrCurrent.key + regEnd) < csrEnd.key ){
+** while( (csrCurrent.key + regStart) > csrStart.key ){
+** AGGINVERSE
+** }
+** RETURN_ROW
+** }
+** }
+** }
+** flush:
+** AGGSTEP
+** while( 1 ){
+** while( (csrCurrent.key + regStart) > csrStart.key ){
+** AGGINVERSE
+** if( eof ) break "while( 1 )" loop.
+** }
+** RETURN_ROW
+** }
+** while( !eof csrCurrent ){
+** RETURN_ROW
+** }
+**
+** The text above leaves out many details. Refer to the code and comments
+** below for a more complete picture.
*/
SQLITE_PRIVATE void sqlite3WindowCodeStep(
Parse *pParse, /* Parse context */
@@ -145830,75 +148372,321 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
int addrGosub /* OP_Gosub here to return each row */
){
Window *pMWin = p->pWin;
+ ExprList *pOrderBy = pMWin->pOrderBy;
+ 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 iInput; /* To iterate through sub cols */
+ int addrNe; /* Address of OP_Ne */
+ int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */
+ int addrInteger = 0; /* Address of OP_Integer */
+ int addrEmpty; /* Address of OP_Rewind in flush: */
+ int regStart = 0; /* Value of PRECEDING */
+ int regEnd = 0; /* Value of FOLLOWING */
+ int regNew; /* Array of registers holding new input row */
+ int regRecord; /* regNew array in record form */
+ int regRowid; /* Rowid for regRecord in eph table */
+ int regNewPeer = 0; /* Peer values for new row (part of regNew) */
+ int regPeer = 0; /* Peer values for current row */
+ int regFlushPart = 0; /* Register for "Gosub flush_partition" */
+ WindowCodeArg s; /* Context object for sub-routines */
+ int lblWhereEnd; /* Label just before sqlite3WhereEnd() code */
+
+ assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT
+ || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED
+ );
+ assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT
+ || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING
+ );
+ assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT
+ || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES
+ || pMWin->eExclude==TK_NO
+ );
- /* There are three different functions that may be used to do the work
- ** of this one, depending on the window frame and the specific built-in
- ** window functions used (if any).
- **
- ** windowCodeRowExprStep() handles all "ROWS" window frames, except for:
- **
- ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- **
- ** The exception is because windowCodeRowExprStep() implements all window
- ** frame types by caching the entire partition in a temp table, and
- ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to
- ** implement without such a cache.
- **
- ** windowCodeCacheStep() is used for:
- **
- ** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
- **
- ** It is also used for anything not handled by windowCodeRowExprStep()
- ** that invokes a built-in window function that requires the entire
- ** partition to be cached in a temp table before any rows are returned
- ** (e.g. nth_value() or percent_rank()).
- **
- ** Finally, assuming there is no built-in window function that requires
- ** the partition to be cached, windowCodeDefaultStep() is used for:
- **
- ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
- ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
- ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
- **
- ** windowCodeDefaultStep() is the only one of the three functions that
- ** does not cache each partition in a temp table before beginning to
- ** return rows.
- */
- if( pMWin->eType==TK_ROWS
- && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
- ){
- VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()"));
- windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
- }else{
- Window *pWin;
- int bCache = 0; /* True to use CacheStep() */
-
- if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){
- bCache = 1;
- }else{
- for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
- FuncDef *pFunc = pWin->pFunc;
- if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
- || (pFunc->zName==nth_valueName)
- || (pFunc->zName==first_valueName)
- || (pFunc->zName==leadName)
- || (pFunc->zName==lagName)
- ){
- bCache = 1;
- break;
+ lblWhereEnd = sqlite3VdbeMakeLabel(pParse);
+
+ /* Fill in the context object */
+ memset(&s, 0, sizeof(WindowCodeArg));
+ s.pParse = pParse;
+ s.pMWin = pMWin;
+ s.pVdbe = v;
+ s.regGosub = regGosub;
+ s.addrGosub = addrGosub;
+ s.current.csr = pMWin->iEphCsr;
+ csrWrite = s.current.csr+1;
+ s.start.csr = s.current.csr+2;
+ s.end.csr = s.current.csr+3;
+
+ /* Figure out when rows may be deleted from the ephemeral table. There
+ ** are four options - they may never be deleted (eDelete==0), they may
+ ** be deleted as soon as they are no longer part of the window frame
+ ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row
+ ** has been returned to the caller (WINDOW_RETURN_ROW), or they may
+ ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
+ switch( pMWin->eStart ){
+ case TK_FOLLOWING:
+ if( pMWin->eFrmType!=TK_RANGE
+ && windowExprGtZero(pParse, pMWin->pStart)
+ ){
+ s.eDelete = WINDOW_RETURN_ROW;
+ }
+ break;
+ case TK_UNBOUNDED:
+ if( windowCacheFrame(pMWin)==0 ){
+ if( pMWin->eEnd==TK_PRECEDING ){
+ if( pMWin->eFrmType!=TK_RANGE
+ && windowExprGtZero(pParse, pMWin->pEnd)
+ ){
+ s.eDelete = WINDOW_AGGSTEP;
+ }
+ }else{
+ s.eDelete = WINDOW_RETURN_ROW;
}
}
+ break;
+ default:
+ s.eDelete = WINDOW_AGGINVERSE;
+ break;
+ }
+
+ /* Allocate registers for the array of values from the sub-query, the
+ ** samve values in record form, and the rowid used to insert said record
+ ** into the ephemeral table. */
+ regNew = pParse->nMem+1;
+ pParse->nMem += nInput;
+ regRecord = ++pParse->nMem;
+ regRowid = ++pParse->nMem;
+
+ /* If the window frame contains an " PRECEDING" or " FOLLOWING"
+ ** clause, allocate registers to store the results of evaluating each
+ ** . */
+ if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){
+ regStart = ++pParse->nMem;
+ }
+ if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){
+ regEnd = ++pParse->nMem;
+ }
+
+ /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
+ ** registers to store copies of the ORDER BY expressions (peer values)
+ ** for the main loop, and for each cursor (start, current and end). */
+ if( pMWin->eFrmType!=TK_ROWS ){
+ int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
+ regNewPeer = regNew + pMWin->nBufferCol;
+ if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
+ regPeer = pParse->nMem+1; pParse->nMem += nPeer;
+ s.start.reg = pParse->nMem+1; pParse->nMem += nPeer;
+ s.current.reg = pParse->nMem+1; pParse->nMem += nPeer;
+ s.end.reg = pParse->nMem+1; pParse->nMem += nPeer;
+ }
+
+ /* Load the column values for the row returned by the sub-select
+ ** into an array of registers starting at regNew. Assemble them into
+ ** a record in register regRecord. */
+ for(iInput=0; iInputpPartition ){
+ int addr;
+ ExprList *pPart = pMWin->pPartition;
+ int nPart = pPart->nExpr;
+ int regNewPart = regNew + pMWin->nBufferCol;
+ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
+
+ regFlushPart = ++pParse->nMem;
+ addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart);
+ sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
+ VdbeCoverageEqNe(v);
+ addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart);
+ VdbeComment((v, "call flush_partition"));
+ sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
+ }
+
+ /* Insert the new row into the ephemeral table */
+ sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
+ addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid);
+ VdbeCoverageNeverNull(v);
+
+ /* This block is run for the first row of each partition */
+ s.regArg = windowInitAccum(pParse, pMWin);
+
+ if( regStart ){
+ sqlite3ExprCode(pParse, pMWin->pStart, regStart);
+ windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
+ }
+ if( regEnd ){
+ sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
+ windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
+ }
+
+ if( pMWin->eStart==pMWin->eEnd && regStart ){
+ int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
+ int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
+ VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound */
+ VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */
+ windowAggFinal(&s, 0);
+ sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
+ VdbeCoverageNeverTaken(v);
+ windowReturnOneRow(&s);
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
+ sqlite3VdbeJumpHere(v, addrGe);
+ }
+ if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){
+ assert( pMWin->eEnd==TK_FOLLOWING );
+ sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
+ }
+
+ if( pMWin->eStart!=TK_UNBOUNDED ){
+ sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1);
+ VdbeCoverageNeverTaken(v);
+ }
+ sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
+ VdbeCoverageNeverTaken(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
+ VdbeCoverageNeverTaken(v);
+ if( regPeer && pOrderBy ){
+ sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
+ sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
+ sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1);
+ sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1);
+ }
+
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
+
+ sqlite3VdbeJumpHere(v, addrNe);
+
+ /* Beginning of the block executed for the second and subsequent rows. */
+ if( regPeer ){
+ windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd);
+ }
+ if( pMWin->eStart==TK_FOLLOWING ){
+ windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+ if( pMWin->eEnd!=TK_UNBOUNDED ){
+ if( pMWin->eFrmType==TK_RANGE ){
+ int lbl = sqlite3VdbeMakeLabel(pParse);
+ int addrNext = sqlite3VdbeCurrentAddr(v);
+ windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
+ sqlite3VdbeResolveLabel(v, lbl);
+ }else{
+ windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ }
}
+ }else
+ if( pMWin->eEnd==TK_PRECEDING ){
+ int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE);
+ windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
+ if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ if( !bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ }else{
+ int addr = 0;
+ windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+ if( pMWin->eEnd!=TK_UNBOUNDED ){
+ if( pMWin->eFrmType==TK_RANGE ){
+ int lbl = 0;
+ addr = sqlite3VdbeCurrentAddr(v);
+ if( regEnd ){
+ lbl = sqlite3VdbeMakeLabel(pParse);
+ windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
+ }
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ if( regEnd ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
+ sqlite3VdbeResolveLabel(v, lbl);
+ }
+ }else{
+ if( regEnd ){
+ addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1);
+ VdbeCoverage(v);
+ }
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ if( regEnd ) sqlite3VdbeJumpHere(v, addr);
+ }
+ }
+ }
- /* Otherwise, call windowCodeDefaultStep(). */
- if( bCache ){
- VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()"));
- windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
- }else{
- VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()"));
- windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
+ /* End of the main input loop */
+ sqlite3VdbeResolveLabel(v, lblWhereEnd);
+ sqlite3WhereEnd(pWInfo);
+
+ /* Fall through */
+ if( pMWin->pPartition ){
+ addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
+ sqlite3VdbeJumpHere(v, addrGosubFlush);
+ }
+
+ addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
+ VdbeCoverage(v);
+ if( pMWin->eEnd==TK_PRECEDING ){
+ int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE);
+ windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
+ if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
+ }else if( pMWin->eStart==TK_FOLLOWING ){
+ int addrStart;
+ int addrBreak1;
+ int addrBreak2;
+ int addrBreak3;
+ windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+ if( pMWin->eFrmType==TK_RANGE ){
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
+ addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+ }else
+ if( pMWin->eEnd==TK_UNBOUNDED ){
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
+ addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
+ }else{
+ assert( pMWin->eEnd==TK_FOLLOWING );
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
+ addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
+ }
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+ sqlite3VdbeJumpHere(v, addrBreak2);
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+ sqlite3VdbeJumpHere(v, addrBreak1);
+ sqlite3VdbeJumpHere(v, addrBreak3);
+ }else{
+ int addrBreak;
+ int addrStart;
+ windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
+ addrStart = sqlite3VdbeCurrentAddr(v);
+ addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
+ windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
+ sqlite3VdbeJumpHere(v, addrBreak);
+ }
+ sqlite3VdbeJumpHere(v, addrEmpty);
+
+ sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
+ if( pMWin->pPartition ){
+ if( pMWin->regStartRowid ){
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
}
+ sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v));
+ sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
}
}
@@ -145931,6 +148719,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
** input grammar file:
*/
/* #include */
+/* #include */
/************ Begin %include sections from the grammar ************************/
/* #include "sqliteInt.h" */
@@ -146032,19 +148821,15 @@ static void disableLookaside(Parse *pParse){
p->pLeft = p->pRight = 0;
p->x.pList = 0;
p->pAggInfo = 0;
- p->pTab = 0;
+ p->y.pTab = 0;
p->op2 = 0;
p->iTable = 0;
p->iColumn = 0;
-#ifndef SQLITE_OMIT_WINDOWFUNC
- p->pWin = 0;
-#endif
p->u.zToken = (char*)&p[1];
memcpy(p->u.zToken, t.z, t.n);
p->u.zToken[t.n] = 0;
if( sqlite3Isquote(p->u.zToken[0]) ){
- if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
- sqlite3Dequote(p->u.zToken);
+ sqlite3DequoteExpr(p);
}
#if SQLITE_MAX_EXPR_DEPTH>0
p->nHeight = 1;
@@ -146090,6 +148875,10 @@ static void disableLookaside(Parse *pParse){
sqlite3ExprListSetName(pParse, p, pIdToken, 1);
return p;
}
+
+#if TK_SPAN>255
+# error too many tokens in the grammar
+#endif
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols
** in a format understandable to "makeheaders". This section is blank unless
@@ -146153,27 +148942,28 @@ static void disableLookaside(Parse *pParse){
#endif
/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned short int
-#define YYNOCODE 277
+#define YYNOCODE 302
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 91
+#define YYWILDCARD 95
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- Expr* yy18;
- struct TrigEvent yy34;
- IdList* yy48;
- int yy70;
- struct {int value; int mask;} yy111;
- struct FrameBound yy119;
- SrcList* yy135;
- TriggerStep* yy207;
- Window* yy327;
- Upsert* yy340;
- const char* yy392;
- ExprList* yy420;
- With* yy449;
- Select* yy489;
+ TriggerStep* yy11;
+ IdList* yy76;
+ ExprList* yy94;
+ Upsert* yy95;
+ int yy100;
+ Expr* yy102;
+ struct {int value; int mask;} yy199;
+ u8 yy218;
+ With* yy243;
+ struct TrigEvent yy298;
+ Window* yy379;
+ struct FrameBound yy389;
+ Select* yy391;
+ SrcList* yy407;
+ const char* yy528;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -146189,17 +148979,17 @@ typedef union {
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
#define YYFALLBACK 1
-#define YYNSTATE 521
-#define YYNRULE 367
-#define YYNTOKEN 155
-#define YY_MAX_SHIFT 520
-#define YY_MIN_SHIFTREDUCE 756
-#define YY_MAX_SHIFTREDUCE 1122
-#define YY_ERROR_ACTION 1123
-#define YY_ACCEPT_ACTION 1124
-#define YY_NO_ACTION 1125
-#define YY_MIN_REDUCE 1126
-#define YY_MAX_REDUCE 1492
+#define YYNSTATE 540
+#define YYNRULE 376
+#define YYNTOKEN 176
+#define YY_MAX_SHIFT 539
+#define YY_MIN_SHIFTREDUCE 783
+#define YY_MAX_SHIFTREDUCE 1158
+#define YY_ERROR_ACTION 1159
+#define YY_ACCEPT_ACTION 1160
+#define YY_NO_ACTION 1161
+#define YY_MIN_REDUCE 1162
+#define YY_MAX_REDUCE 1537
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
@@ -146266,568 +149056,601 @@ typedef union {
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (2009)
+#define YY_ACTTAB_COUNT (2142)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 368, 105, 102, 197, 105, 102, 197, 515, 1124, 1,
- /* 10 */ 1, 520, 2, 1128, 515, 1192, 1171, 1456, 275, 370,
- /* 20 */ 127, 1389, 1197, 1197, 1192, 1166, 178, 1205, 64, 64,
- /* 30 */ 477, 887, 322, 428, 348, 37, 37, 808, 362, 888,
- /* 40 */ 509, 509, 509, 112, 113, 103, 1100, 1100, 953, 956,
- /* 50 */ 946, 946, 110, 110, 111, 111, 111, 111, 365, 252,
- /* 60 */ 252, 515, 252, 252, 497, 515, 309, 515, 459, 515,
- /* 70 */ 1079, 491, 512, 478, 6, 512, 809, 134, 498, 228,
- /* 80 */ 194, 428, 37, 37, 515, 208, 64, 64, 64, 64,
- /* 90 */ 13, 13, 109, 109, 109, 109, 108, 108, 107, 107,
- /* 100 */ 107, 106, 401, 258, 381, 13, 13, 398, 397, 428,
- /* 110 */ 252, 252, 370, 476, 405, 1104, 1079, 1080, 1081, 386,
- /* 120 */ 1106, 390, 497, 512, 497, 1423, 1419, 304, 1105, 307,
- /* 130 */ 1256, 496, 370, 499, 16, 16, 112, 113, 103, 1100,
- /* 140 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
- /* 150 */ 111, 262, 1107, 495, 1107, 401, 112, 113, 103, 1100,
- /* 160 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
- /* 170 */ 111, 129, 1425, 343, 1420, 339, 1059, 492, 1057, 263,
- /* 180 */ 73, 105, 102, 197, 994, 109, 109, 109, 109, 108,
- /* 190 */ 108, 107, 107, 107, 106, 401, 370, 111, 111, 111,
- /* 200 */ 111, 104, 492, 89, 1432, 109, 109, 109, 109, 108,
- /* 210 */ 108, 107, 107, 107, 106, 401, 111, 111, 111, 111,
- /* 220 */ 112, 113, 103, 1100, 1100, 953, 956, 946, 946, 110,
- /* 230 */ 110, 111, 111, 111, 111, 109, 109, 109, 109, 108,
- /* 240 */ 108, 107, 107, 107, 106, 401, 114, 108, 108, 107,
- /* 250 */ 107, 107, 106, 401, 109, 109, 109, 109, 108, 108,
- /* 260 */ 107, 107, 107, 106, 401, 152, 399, 399, 399, 109,
- /* 270 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401,
- /* 280 */ 178, 493, 1412, 434, 1037, 1486, 1079, 515, 1486, 370,
- /* 290 */ 421, 297, 357, 412, 74, 1079, 109, 109, 109, 109,
- /* 300 */ 108, 108, 107, 107, 107, 106, 401, 1413, 37, 37,
- /* 310 */ 1431, 274, 506, 112, 113, 103, 1100, 1100, 953, 956,
- /* 320 */ 946, 946, 110, 110, 111, 111, 111, 111, 1436, 520,
- /* 330 */ 2, 1128, 1079, 1080, 1081, 430, 275, 1079, 127, 366,
- /* 340 */ 933, 1079, 1080, 1081, 220, 1205, 913, 458, 455, 454,
- /* 350 */ 392, 167, 515, 1035, 152, 445, 924, 453, 152, 874,
- /* 360 */ 923, 289, 109, 109, 109, 109, 108, 108, 107, 107,
- /* 370 */ 107, 106, 401, 13, 13, 261, 853, 252, 252, 227,
- /* 380 */ 106, 401, 370, 1079, 1080, 1081, 311, 388, 1079, 296,
- /* 390 */ 512, 923, 923, 925, 231, 323, 1255, 1388, 1423, 490,
- /* 400 */ 274, 506, 12, 208, 274, 506, 112, 113, 103, 1100,
- /* 410 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111,
- /* 420 */ 111, 1440, 286, 1128, 288, 1079, 1097, 247, 275, 1098,
- /* 430 */ 127, 387, 405, 389, 1079, 1080, 1081, 1205, 159, 238,
- /* 440 */ 255, 321, 461, 316, 460, 225, 790, 105, 102, 197,
- /* 450 */ 513, 314, 842, 842, 445, 109, 109, 109, 109, 108,
- /* 460 */ 108, 107, 107, 107, 106, 401, 515, 514, 515, 252,
- /* 470 */ 252, 1079, 1080, 1081, 435, 370, 1098, 933, 1460, 794,
- /* 480 */ 274, 506, 512, 105, 102, 197, 336, 63, 63, 64,
- /* 490 */ 64, 27, 790, 924, 287, 208, 1354, 923, 515, 112,
- /* 500 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110,
- /* 510 */ 111, 111, 111, 111, 107, 107, 107, 106, 401, 49,
- /* 520 */ 49, 515, 28, 1079, 405, 497, 421, 297, 923, 923,
- /* 530 */ 925, 186, 468, 1079, 467, 999, 999, 442, 515, 1079,
- /* 540 */ 334, 515, 45, 45, 1083, 342, 173, 168, 109, 109,
- /* 550 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 13,
- /* 560 */ 13, 205, 13, 13, 252, 252, 1195, 1195, 370, 1079,
- /* 570 */ 1080, 1081, 787, 265, 5, 359, 494, 512, 469, 1079,
- /* 580 */ 1080, 1081, 398, 397, 1079, 1079, 1080, 1081, 3, 282,
- /* 590 */ 1079, 1083, 112, 113, 103, 1100, 1100, 953, 956, 946,
- /* 600 */ 946, 110, 110, 111, 111, 111, 111, 252, 252, 1015,
- /* 610 */ 220, 1079, 873, 458, 455, 454, 943, 943, 954, 957,
- /* 620 */ 512, 252, 252, 453, 1016, 1079, 445, 1107, 1209, 1107,
- /* 630 */ 1079, 1080, 1081, 515, 512, 426, 1079, 1080, 1081, 1017,
- /* 640 */ 512, 109, 109, 109, 109, 108, 108, 107, 107, 107,
- /* 650 */ 106, 401, 1052, 515, 50, 50, 515, 1079, 1080, 1081,
- /* 660 */ 828, 370, 1051, 379, 411, 1064, 1358, 207, 408, 773,
- /* 670 */ 829, 1079, 1080, 1081, 64, 64, 322, 64, 64, 1302,
- /* 680 */ 947, 411, 410, 1358, 1360, 112, 113, 103, 1100, 1100,
- /* 690 */ 953, 956, 946, 946, 110, 110, 111, 111, 111, 111,
- /* 700 */ 294, 482, 515, 1037, 1487, 515, 434, 1487, 354, 1120,
- /* 710 */ 483, 996, 913, 485, 466, 996, 132, 178, 33, 450,
- /* 720 */ 1203, 136, 406, 64, 64, 479, 64, 64, 419, 369,
- /* 730 */ 283, 1146, 252, 252, 109, 109, 109, 109, 108, 108,
- /* 740 */ 107, 107, 107, 106, 401, 512, 224, 440, 411, 266,
- /* 750 */ 1358, 266, 252, 252, 370, 296, 416, 284, 934, 396,
- /* 760 */ 976, 470, 400, 252, 252, 512, 9, 473, 231, 500,
- /* 770 */ 354, 1036, 1035, 1488, 355, 374, 512, 1121, 112, 113,
- /* 780 */ 103, 1100, 1100, 953, 956, 946, 946, 110, 110, 111,
- /* 790 */ 111, 111, 111, 252, 252, 1015, 515, 1347, 295, 252,
- /* 800 */ 252, 252, 252, 1098, 375, 249, 512, 445, 872, 322,
- /* 810 */ 1016, 480, 512, 195, 512, 434, 273, 15, 15, 515,
- /* 820 */ 314, 515, 95, 515, 93, 1017, 367, 109, 109, 109,
- /* 830 */ 109, 108, 108, 107, 107, 107, 106, 401, 515, 1121,
- /* 840 */ 39, 39, 51, 51, 52, 52, 503, 370, 515, 1204,
- /* 850 */ 1098, 918, 439, 341, 133, 436, 223, 222, 221, 53,
- /* 860 */ 53, 322, 1400, 761, 762, 763, 515, 370, 88, 54,
- /* 870 */ 54, 112, 113, 103, 1100, 1100, 953, 956, 946, 946,
- /* 880 */ 110, 110, 111, 111, 111, 111, 407, 55, 55, 196,
- /* 890 */ 515, 112, 113, 103, 1100, 1100, 953, 956, 946, 946,
- /* 900 */ 110, 110, 111, 111, 111, 111, 135, 264, 1149, 376,
- /* 910 */ 515, 40, 40, 515, 872, 515, 993, 515, 993, 116,
- /* 920 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106,
- /* 930 */ 401, 41, 41, 515, 43, 43, 44, 44, 56, 56,
- /* 940 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106,
- /* 950 */ 401, 515, 379, 515, 57, 57, 515, 799, 515, 379,
- /* 960 */ 515, 445, 200, 515, 323, 515, 1397, 515, 1459, 515,
- /* 970 */ 1287, 817, 58, 58, 14, 14, 515, 59, 59, 118,
- /* 980 */ 118, 60, 60, 515, 46, 46, 61, 61, 62, 62,
- /* 990 */ 47, 47, 515, 190, 189, 91, 515, 140, 140, 515,
- /* 1000 */ 394, 515, 277, 1200, 141, 141, 515, 1115, 515, 992,
- /* 1010 */ 515, 992, 515, 69, 69, 370, 278, 48, 48, 259,
- /* 1020 */ 65, 65, 119, 119, 246, 246, 260, 66, 66, 120,
- /* 1030 */ 120, 121, 121, 117, 117, 370, 515, 512, 383, 112,
- /* 1040 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110,
- /* 1050 */ 111, 111, 111, 111, 515, 872, 515, 139, 139, 112,
- /* 1060 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110,
- /* 1070 */ 111, 111, 111, 111, 1287, 138, 138, 125, 125, 515,
- /* 1080 */ 12, 515, 281, 1287, 515, 445, 131, 1287, 109, 109,
- /* 1090 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515,
- /* 1100 */ 124, 124, 122, 122, 515, 123, 123, 515, 109, 109,
- /* 1110 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515,
- /* 1120 */ 68, 68, 463, 783, 515, 70, 70, 302, 67, 67,
- /* 1130 */ 1032, 253, 253, 356, 1287, 191, 196, 1433, 465, 1301,
- /* 1140 */ 38, 38, 384, 94, 512, 42, 42, 177, 848, 274,
- /* 1150 */ 506, 385, 420, 847, 1356, 441, 508, 376, 377, 153,
- /* 1160 */ 423, 872, 432, 370, 224, 251, 194, 887, 182, 293,
- /* 1170 */ 783, 848, 88, 254, 466, 888, 847, 915, 807, 806,
- /* 1180 */ 230, 1241, 910, 370, 17, 413, 797, 112, 113, 103,
- /* 1190 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111,
- /* 1200 */ 111, 111, 395, 814, 815, 1175, 983, 112, 101, 103,
- /* 1210 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111,
- /* 1220 */ 111, 111, 375, 422, 427, 429, 298, 230, 230, 88,
- /* 1230 */ 1240, 451, 312, 797, 226, 88, 109, 109, 109, 109,
- /* 1240 */ 108, 108, 107, 107, 107, 106, 401, 86, 433, 979,
- /* 1250 */ 927, 881, 226, 983, 230, 415, 109, 109, 109, 109,
- /* 1260 */ 108, 108, 107, 107, 107, 106, 401, 320, 845, 781,
- /* 1270 */ 846, 100, 130, 100, 1403, 290, 370, 319, 1377, 1376,
- /* 1280 */ 437, 1449, 299, 1237, 303, 306, 308, 310, 1188, 1174,
- /* 1290 */ 1173, 1172, 315, 324, 325, 1228, 370, 927, 1249, 271,
- /* 1300 */ 1286, 113, 103, 1100, 1100, 953, 956, 946, 946, 110,
- /* 1310 */ 110, 111, 111, 111, 111, 1224, 1235, 502, 501, 1292,
- /* 1320 */ 1221, 1155, 103, 1100, 1100, 953, 956, 946, 946, 110,
- /* 1330 */ 110, 111, 111, 111, 111, 1148, 1137, 1136, 1138, 1443,
- /* 1340 */ 446, 244, 184, 98, 507, 188, 4, 353, 327, 109,
- /* 1350 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401,
- /* 1360 */ 510, 329, 331, 199, 414, 456, 292, 285, 318, 109,
- /* 1370 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401,
- /* 1380 */ 11, 1271, 1279, 402, 361, 192, 1171, 1351, 431, 505,
- /* 1390 */ 346, 1350, 333, 98, 507, 504, 4, 187, 1446, 1115,
- /* 1400 */ 233, 1396, 155, 1394, 1112, 152, 72, 75, 378, 425,
- /* 1410 */ 510, 165, 149, 157, 933, 1276, 86, 30, 1268, 417,
- /* 1420 */ 96, 96, 8, 160, 161, 162, 163, 97, 418, 402,
- /* 1430 */ 517, 516, 449, 402, 923, 210, 358, 424, 1282, 438,
- /* 1440 */ 169, 214, 360, 1345, 80, 504, 31, 444, 1365, 301,
- /* 1450 */ 245, 274, 506, 216, 174, 305, 488, 447, 217, 462,
- /* 1460 */ 1139, 487, 218, 363, 933, 923, 923, 925, 926, 24,
- /* 1470 */ 96, 96, 1191, 1190, 1189, 391, 1182, 97, 1163, 402,
- /* 1480 */ 517, 516, 799, 364, 923, 1162, 317, 1161, 98, 507,
- /* 1490 */ 1181, 4, 1458, 472, 393, 269, 270, 475, 481, 1232,
- /* 1500 */ 85, 1233, 326, 328, 232, 510, 495, 1231, 330, 98,
- /* 1510 */ 507, 1230, 4, 486, 335, 923, 923, 925, 926, 24,
- /* 1520 */ 1435, 1068, 404, 181, 336, 256, 510, 115, 402, 332,
- /* 1530 */ 352, 352, 351, 241, 349, 1214, 1414, 770, 338, 10,
- /* 1540 */ 504, 340, 272, 92, 1331, 1213, 87, 183, 484, 402,
- /* 1550 */ 201, 488, 280, 239, 344, 345, 489, 1145, 29, 933,
- /* 1560 */ 279, 504, 1074, 518, 240, 96, 96, 242, 243, 519,
- /* 1570 */ 1134, 1129, 97, 154, 402, 517, 516, 372, 373, 923,
- /* 1580 */ 933, 142, 143, 128, 1381, 267, 96, 96, 852, 757,
- /* 1590 */ 203, 144, 403, 97, 1382, 402, 517, 516, 204, 1380,
- /* 1600 */ 923, 146, 1379, 1159, 1158, 71, 1156, 276, 202, 185,
- /* 1610 */ 923, 923, 925, 926, 24, 198, 257, 126, 991, 989,
- /* 1620 */ 907, 98, 507, 156, 4, 145, 158, 206, 831, 209,
- /* 1630 */ 291, 923, 923, 925, 926, 24, 1005, 911, 510, 164,
- /* 1640 */ 147, 380, 371, 382, 166, 76, 77, 274, 506, 148,
- /* 1650 */ 78, 79, 1008, 211, 212, 1004, 137, 213, 18, 300,
- /* 1660 */ 230, 402, 997, 1109, 443, 215, 32, 170, 171, 772,
- /* 1670 */ 409, 448, 319, 504, 219, 172, 452, 81, 19, 457,
- /* 1680 */ 313, 20, 82, 268, 488, 150, 810, 179, 83, 487,
- /* 1690 */ 464, 151, 933, 180, 959, 84, 1040, 34, 96, 96,
- /* 1700 */ 471, 1041, 35, 474, 193, 97, 248, 402, 517, 516,
- /* 1710 */ 1068, 404, 923, 250, 256, 880, 229, 175, 875, 352,
- /* 1720 */ 352, 351, 241, 349, 100, 21, 770, 22, 1054, 1056,
- /* 1730 */ 7, 98, 507, 1045, 4, 337, 1058, 23, 974, 201,
- /* 1740 */ 176, 280, 88, 923, 923, 925, 926, 24, 510, 279,
- /* 1750 */ 960, 958, 962, 1014, 963, 1013, 235, 234, 25, 36,
- /* 1760 */ 99, 90, 507, 928, 4, 511, 350, 782, 26, 841,
- /* 1770 */ 236, 402, 347, 1069, 237, 1125, 1125, 1451, 510, 203,
- /* 1780 */ 1450, 1125, 1125, 504, 1125, 1125, 1125, 204, 1125, 1125,
- /* 1790 */ 146, 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125,
- /* 1800 */ 1125, 402, 933, 1125, 1125, 1125, 1125, 1125, 96, 96,
- /* 1810 */ 1125, 1125, 1125, 504, 1125, 97, 1125, 402, 517, 516,
- /* 1820 */ 1125, 1125, 923, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1830 */ 1125, 371, 933, 1125, 1125, 1125, 274, 506, 96, 96,
- /* 1840 */ 1125, 1125, 1125, 1125, 1125, 97, 1125, 402, 517, 516,
- /* 1850 */ 1125, 1125, 923, 923, 923, 925, 926, 24, 1125, 409,
- /* 1860 */ 1125, 1125, 1125, 256, 1125, 1125, 1125, 1125, 352, 352,
- /* 1870 */ 351, 241, 349, 1125, 1125, 770, 1125, 1125, 1125, 1125,
- /* 1880 */ 1125, 1125, 1125, 923, 923, 925, 926, 24, 201, 1125,
- /* 1890 */ 280, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 279, 1125,
- /* 1900 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1910 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1920 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 203, 1125,
- /* 1930 */ 1125, 1125, 1125, 1125, 1125, 1125, 204, 1125, 1125, 146,
- /* 1940 */ 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125, 1125,
- /* 1950 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1960 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1970 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 1980 */ 371, 1125, 1125, 1125, 1125, 274, 506, 1125, 1125, 1125,
- /* 1990 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
- /* 2000 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 409,
+ /* 0 */ 112, 109, 209, 112, 109, 209, 1160, 1, 1, 539,
+ /* 10 */ 2, 1164, 490, 1193, 1293, 534, 289, 1196, 134, 383,
+ /* 20 */ 1485, 1428, 1164, 1229, 1208, 1242, 1195, 289, 491, 134,
+ /* 30 */ 373, 915, 1229, 443, 16, 16, 1242, 70, 70, 916,
+ /* 40 */ 242, 1292, 296, 119, 120, 110, 1136, 1136, 981, 984,
+ /* 50 */ 974, 974, 117, 117, 118, 118, 118, 118, 264, 264,
+ /* 60 */ 190, 264, 264, 264, 264, 112, 109, 209, 362, 264,
+ /* 70 */ 264, 531, 376, 497, 531, 1134, 531, 1501, 239, 206,
+ /* 80 */ 338, 9, 531, 242, 219, 1203, 118, 118, 118, 118,
+ /* 90 */ 111, 439, 112, 109, 209, 219, 116, 116, 116, 116,
+ /* 100 */ 115, 115, 114, 114, 114, 113, 414, 115, 115, 114,
+ /* 110 */ 114, 114, 113, 414, 418, 12, 383, 400, 1134, 114,
+ /* 120 */ 114, 114, 113, 414, 1115, 418, 1134, 1392, 116, 116,
+ /* 130 */ 116, 116, 115, 115, 114, 114, 114, 113, 414, 961,
+ /* 140 */ 119, 120, 110, 1136, 1136, 981, 984, 974, 974, 117,
+ /* 150 */ 117, 118, 118, 118, 118, 952, 534, 414, 941, 951,
+ /* 160 */ 1481, 539, 2, 1164, 1505, 534, 160, 175, 289, 1134,
+ /* 170 */ 134, 434, 312, 297, 1115, 1116, 1117, 1242, 70, 70,
+ /* 180 */ 1089, 338, 1089, 118, 118, 118, 118, 42, 42, 448,
+ /* 190 */ 951, 951, 953, 116, 116, 116, 116, 115, 115, 114,
+ /* 200 */ 114, 114, 113, 414, 1115, 311, 264, 264, 82, 441,
+ /* 210 */ 264, 264, 190, 383, 284, 12, 288, 525, 407, 531,
+ /* 220 */ 96, 159, 458, 531, 371, 116, 116, 116, 116, 115,
+ /* 230 */ 115, 114, 114, 114, 113, 414, 219, 119, 120, 110,
+ /* 240 */ 1136, 1136, 981, 984, 974, 974, 117, 117, 118, 118,
+ /* 250 */ 118, 118, 511, 1477, 1115, 1116, 1117, 113, 414, 534,
+ /* 260 */ 528, 528, 528, 121, 534, 1427, 418, 116, 116, 116,
+ /* 270 */ 116, 115, 115, 114, 114, 114, 113, 414, 1464, 351,
+ /* 280 */ 270, 42, 42, 383, 187, 1115, 70, 70, 533, 433,
+ /* 290 */ 116, 116, 116, 116, 115, 115, 114, 114, 114, 113,
+ /* 300 */ 414, 534, 1339, 405, 159, 411, 410, 119, 120, 110,
+ /* 310 */ 1136, 1136, 981, 984, 974, 974, 117, 117, 118, 118,
+ /* 320 */ 118, 118, 285, 42, 42, 349, 411, 410, 514, 479,
+ /* 330 */ 1458, 79, 1084, 6, 1140, 1115, 1116, 1117, 480, 1142,
+ /* 340 */ 501, 1115, 1084, 123, 238, 1084, 136, 1141, 1234, 1234,
+ /* 350 */ 1143, 383, 1143, 1115, 167, 426, 80, 447, 512, 1451,
+ /* 360 */ 116, 116, 116, 116, 115, 115, 114, 114, 114, 113,
+ /* 370 */ 414, 1143, 1466, 1143, 350, 119, 120, 110, 1136, 1136,
+ /* 380 */ 981, 984, 974, 974, 117, 117, 118, 118, 118, 118,
+ /* 390 */ 402, 1115, 1116, 1117, 500, 534, 250, 267, 336, 474,
+ /* 400 */ 331, 473, 236, 1115, 1116, 1117, 231, 1115, 329, 471,
+ /* 410 */ 468, 467, 509, 1458, 1464, 505, 6, 70, 70, 466,
+ /* 420 */ 181, 380, 379, 534, 971, 971, 982, 985, 116, 116,
+ /* 430 */ 116, 116, 115, 115, 114, 114, 114, 113, 414, 1115,
+ /* 440 */ 412, 412, 412, 496, 1115, 69, 69, 235, 383, 288,
+ /* 450 */ 525, 273, 326, 516, 337, 458, 1084, 1115, 1116, 1117,
+ /* 460 */ 1232, 1232, 492, 160, 508, 441, 1084, 1067, 1531, 1084,
+ /* 470 */ 207, 1531, 119, 120, 110, 1136, 1136, 981, 984, 974,
+ /* 480 */ 974, 117, 117, 118, 118, 118, 118, 881, 534, 1115,
+ /* 490 */ 1116, 1117, 975, 534, 1115, 1116, 1117, 534, 421, 534,
+ /* 500 */ 141, 534, 176, 356, 517, 1119, 32, 511, 482, 388,
+ /* 510 */ 70, 70, 818, 288, 525, 70, 70, 441, 499, 50,
+ /* 520 */ 50, 70, 70, 70, 70, 116, 116, 116, 116, 115,
+ /* 530 */ 115, 114, 114, 114, 113, 414, 274, 264, 264, 1115,
+ /* 540 */ 1065, 264, 264, 1115, 355, 383, 409, 961, 1439, 822,
+ /* 550 */ 531, 516, 190, 419, 531, 483, 1119, 516, 337, 516,
+ /* 560 */ 518, 1115, 818, 952, 382, 458, 515, 951, 481, 119,
+ /* 570 */ 120, 110, 1136, 1136, 981, 984, 974, 974, 117, 117,
+ /* 580 */ 118, 118, 118, 118, 1338, 278, 1045, 278, 275, 1115,
+ /* 590 */ 1116, 1117, 259, 1115, 1116, 1117, 534, 5, 951, 951,
+ /* 600 */ 953, 1046, 231, 3, 143, 471, 468, 467, 1391, 463,
+ /* 610 */ 1115, 1115, 1116, 1117, 1452, 466, 1047, 836, 70, 70,
+ /* 620 */ 480, 534, 116, 116, 116, 116, 115, 115, 114, 114,
+ /* 630 */ 114, 113, 414, 95, 1115, 287, 235, 856, 902, 420,
+ /* 640 */ 1115, 534, 383, 13, 13, 381, 815, 857, 472, 112,
+ /* 650 */ 109, 209, 1115, 337, 413, 309, 837, 394, 1436, 534,
+ /* 660 */ 1115, 1116, 1117, 54, 54, 291, 119, 120, 110, 1136,
+ /* 670 */ 1136, 981, 984, 974, 974, 117, 117, 118, 118, 118,
+ /* 680 */ 118, 13, 13, 1084, 1115, 1116, 1117, 901, 264, 264,
+ /* 690 */ 1115, 1116, 1117, 1084, 292, 399, 1084, 800, 388, 140,
+ /* 700 */ 295, 531, 1115, 1116, 1117, 403, 447, 532, 534, 870,
+ /* 710 */ 870, 534, 1240, 534, 329, 534, 1185, 389, 534, 116,
+ /* 720 */ 116, 116, 116, 115, 115, 114, 114, 114, 113, 414,
+ /* 730 */ 13, 13, 1024, 13, 13, 13, 13, 13, 13, 383,
+ /* 740 */ 13, 13, 424, 1100, 401, 264, 264, 277, 160, 184,
+ /* 750 */ 1182, 185, 1533, 369, 513, 484, 432, 487, 531, 424,
+ /* 760 */ 423, 1397, 941, 119, 120, 110, 1136, 1136, 981, 984,
+ /* 770 */ 974, 974, 117, 117, 118, 118, 118, 118, 1397, 1399,
+ /* 780 */ 425, 519, 392, 264, 264, 1029, 1029, 455, 264, 264,
+ /* 790 */ 264, 264, 1004, 304, 261, 1278, 531, 900, 288, 525,
+ /* 800 */ 310, 531, 493, 531, 1067, 1532, 458, 387, 1532, 311,
+ /* 810 */ 429, 299, 534, 107, 264, 264, 116, 116, 116, 116,
+ /* 820 */ 115, 115, 114, 114, 114, 113, 414, 531, 424, 1384,
+ /* 830 */ 507, 258, 258, 1246, 55, 55, 383, 1277, 265, 265,
+ /* 840 */ 962, 324, 434, 312, 531, 531, 506, 1397, 1026, 1241,
+ /* 850 */ 298, 531, 1026, 445, 301, 1095, 303, 534, 368, 1156,
+ /* 860 */ 119, 120, 110, 1136, 1136, 981, 984, 974, 974, 117,
+ /* 870 */ 117, 118, 118, 118, 118, 1045, 534, 1065, 534, 15,
+ /* 880 */ 15, 1084, 208, 1324, 453, 452, 534, 1324, 534, 449,
+ /* 890 */ 1046, 1084, 494, 458, 1084, 234, 233, 232, 44, 44,
+ /* 900 */ 56, 56, 319, 1095, 322, 1047, 534, 900, 57, 57,
+ /* 910 */ 58, 58, 534, 116, 116, 116, 116, 115, 115, 114,
+ /* 920 */ 114, 114, 113, 414, 534, 514, 522, 534, 59, 59,
+ /* 930 */ 302, 1157, 534, 383, 60, 60, 1237, 946, 788, 789,
+ /* 940 */ 790, 1459, 1456, 446, 6, 6, 61, 61, 1212, 45,
+ /* 950 */ 45, 534, 396, 383, 46, 46, 397, 119, 120, 110,
+ /* 960 */ 1136, 1136, 981, 984, 974, 974, 117, 117, 118, 118,
+ /* 970 */ 118, 118, 428, 48, 48, 534, 392, 119, 120, 110,
+ /* 980 */ 1136, 1136, 981, 984, 974, 974, 117, 117, 118, 118,
+ /* 990 */ 118, 118, 1324, 368, 1066, 447, 825, 49, 49, 534,
+ /* 1000 */ 458, 357, 534, 353, 534, 138, 534, 337, 1478, 478,
+ /* 1010 */ 116, 116, 116, 116, 115, 115, 114, 114, 114, 113,
+ /* 1020 */ 414, 62, 62, 392, 63, 63, 64, 64, 14, 14,
+ /* 1030 */ 116, 116, 116, 116, 115, 115, 114, 114, 114, 113,
+ /* 1040 */ 414, 534, 810, 317, 271, 534, 1457, 825, 534, 6,
+ /* 1050 */ 534, 1324, 534, 142, 534, 1442, 534, 212, 534, 1324,
+ /* 1060 */ 534, 398, 305, 65, 65, 534, 1157, 125, 125, 476,
+ /* 1070 */ 66, 66, 51, 51, 67, 67, 68, 68, 52, 52,
+ /* 1080 */ 147, 147, 148, 148, 534, 98, 534, 75, 75, 276,
+ /* 1090 */ 534, 272, 534, 810, 534, 876, 534, 527, 389, 534,
+ /* 1100 */ 875, 534, 1151, 202, 534, 383, 53, 53, 71, 71,
+ /* 1110 */ 288, 525, 126, 126, 72, 72, 127, 127, 128, 128,
+ /* 1120 */ 454, 124, 124, 146, 146, 383, 145, 145, 408, 119,
+ /* 1130 */ 120, 110, 1136, 1136, 981, 984, 974, 974, 117, 117,
+ /* 1140 */ 118, 118, 118, 118, 534, 900, 534, 95, 534, 119,
+ /* 1150 */ 120, 110, 1136, 1136, 981, 984, 974, 974, 117, 117,
+ /* 1160 */ 118, 118, 118, 118, 390, 161, 132, 132, 131, 131,
+ /* 1170 */ 129, 129, 534, 915, 534, 1455, 534, 1454, 6, 1416,
+ /* 1180 */ 6, 916, 116, 116, 116, 116, 115, 115, 114, 114,
+ /* 1190 */ 114, 113, 414, 1415, 130, 130, 74, 74, 76, 76,
+ /* 1200 */ 534, 30, 116, 116, 116, 116, 115, 115, 114, 114,
+ /* 1210 */ 114, 113, 414, 534, 263, 206, 534, 1133, 1504, 93,
+ /* 1220 */ 876, 845, 73, 73, 102, 875, 100, 139, 17, 38,
+ /* 1230 */ 208, 1062, 31, 450, 370, 43, 43, 101, 47, 47,
+ /* 1240 */ 827, 216, 436, 308, 943, 440, 95, 241, 241, 442,
+ /* 1250 */ 313, 464, 241, 95, 237, 900, 327, 383, 266, 95,
+ /* 1260 */ 835, 834, 193, 335, 938, 314, 1011, 435, 842, 843,
+ /* 1270 */ 955, 1007, 909, 334, 237, 241, 873, 383, 1023, 107,
+ /* 1280 */ 1023, 119, 120, 110, 1136, 1136, 981, 984, 974, 974,
+ /* 1290 */ 117, 117, 118, 118, 118, 118, 1022, 808, 1022, 1274,
+ /* 1300 */ 137, 119, 108, 110, 1136, 1136, 981, 984, 974, 974,
+ /* 1310 */ 117, 117, 118, 118, 118, 118, 874, 1011, 318, 107,
+ /* 1320 */ 321, 955, 323, 325, 1225, 1211, 197, 1210, 1209, 330,
+ /* 1330 */ 339, 1265, 340, 283, 116, 116, 116, 116, 115, 115,
+ /* 1340 */ 114, 114, 114, 113, 414, 1286, 1323, 1261, 1471, 1272,
+ /* 1350 */ 520, 218, 521, 1329, 116, 116, 116, 116, 115, 115,
+ /* 1360 */ 114, 114, 114, 113, 414, 1192, 1184, 1173, 1172, 1174,
+ /* 1370 */ 1494, 1488, 459, 256, 383, 1258, 342, 199, 367, 344,
+ /* 1380 */ 211, 195, 307, 444, 11, 346, 469, 333, 1308, 1316,
+ /* 1390 */ 375, 427, 203, 360, 383, 1388, 188, 1387, 189, 120,
+ /* 1400 */ 110, 1136, 1136, 981, 984, 974, 974, 117, 117, 118,
+ /* 1410 */ 118, 118, 118, 1208, 1151, 300, 348, 1491, 245, 1148,
+ /* 1420 */ 110, 1136, 1136, 981, 984, 974, 974, 117, 117, 118,
+ /* 1430 */ 118, 118, 118, 198, 1435, 1433, 524, 78, 391, 163,
+ /* 1440 */ 82, 1393, 438, 173, 81, 105, 526, 1313, 4, 35,
+ /* 1450 */ 157, 116, 116, 116, 116, 115, 115, 114, 114, 114,
+ /* 1460 */ 113, 414, 529, 165, 93, 430, 1305, 168, 169, 431,
+ /* 1470 */ 462, 116, 116, 116, 116, 115, 115, 114, 114, 114,
+ /* 1480 */ 113, 414, 170, 171, 221, 415, 372, 437, 1319, 177,
+ /* 1490 */ 374, 36, 451, 225, 1382, 87, 457, 523, 257, 1404,
+ /* 1500 */ 316, 105, 526, 227, 4, 182, 460, 160, 320, 228,
+ /* 1510 */ 377, 1175, 475, 229, 1228, 404, 1227, 1226, 529, 827,
+ /* 1520 */ 961, 1219, 378, 1200, 1199, 406, 103, 103, 1218, 332,
+ /* 1530 */ 8, 281, 1198, 104, 1503, 415, 536, 535, 486, 282,
+ /* 1540 */ 951, 415, 489, 495, 92, 244, 1269, 341, 243, 122,
+ /* 1550 */ 1270, 343, 514, 523, 1268, 1462, 10, 288, 525, 345,
+ /* 1560 */ 1461, 354, 99, 352, 503, 94, 1267, 347, 1251, 502,
+ /* 1570 */ 498, 951, 951, 953, 954, 27, 961, 1250, 194, 358,
+ /* 1580 */ 251, 359, 103, 103, 1181, 34, 537, 1110, 252, 104,
+ /* 1590 */ 254, 415, 536, 535, 255, 1368, 951, 1420, 286, 538,
+ /* 1600 */ 1170, 1165, 1421, 135, 1419, 1418, 149, 150, 279, 784,
+ /* 1610 */ 416, 196, 151, 290, 210, 200, 77, 385, 269, 386,
+ /* 1620 */ 133, 162, 935, 1021, 201, 1019, 153, 951, 951, 953,
+ /* 1630 */ 954, 27, 1480, 1104, 417, 164, 217, 268, 859, 166,
+ /* 1640 */ 306, 1035, 366, 366, 365, 253, 363, 220, 172, 797,
+ /* 1650 */ 939, 155, 105, 526, 393, 4, 395, 174, 156, 83,
+ /* 1660 */ 1038, 84, 213, 85, 294, 222, 86, 223, 1034, 529,
+ /* 1670 */ 144, 18, 293, 224, 315, 456, 241, 1027, 1145, 178,
+ /* 1680 */ 226, 179, 37, 799, 334, 461, 230, 465, 470, 838,
+ /* 1690 */ 180, 88, 415, 19, 280, 328, 20, 89, 90, 158,
+ /* 1700 */ 191, 477, 215, 1097, 523, 204, 192, 987, 91, 1070,
+ /* 1710 */ 152, 39, 485, 154, 1071, 503, 40, 488, 205, 260,
+ /* 1720 */ 504, 262, 105, 526, 214, 4, 908, 961, 183, 240,
+ /* 1730 */ 903, 107, 1086, 103, 103, 21, 22, 1088, 23, 529,
+ /* 1740 */ 104, 24, 415, 536, 535, 1090, 1093, 951, 1094, 25,
+ /* 1750 */ 1074, 33, 7, 26, 510, 1002, 247, 186, 384, 95,
+ /* 1760 */ 988, 986, 415, 288, 525, 990, 1044, 246, 1043, 991,
+ /* 1770 */ 28, 41, 530, 956, 523, 809, 106, 29, 951, 951,
+ /* 1780 */ 953, 954, 27, 869, 361, 503, 422, 248, 364, 1105,
+ /* 1790 */ 502, 249, 1161, 1496, 1495, 1161, 1161, 961, 1161, 1161,
+ /* 1800 */ 1161, 1161, 1161, 103, 103, 1161, 1161, 1161, 1161, 1161,
+ /* 1810 */ 104, 1161, 415, 536, 535, 1104, 417, 951, 1161, 268,
+ /* 1820 */ 1161, 1161, 1161, 1161, 366, 366, 365, 253, 363, 1161,
+ /* 1830 */ 1161, 797, 1161, 1161, 1161, 1161, 105, 526, 1161, 4,
+ /* 1840 */ 1161, 1161, 1161, 1161, 213, 1161, 294, 1161, 951, 951,
+ /* 1850 */ 953, 954, 27, 529, 293, 1161, 1161, 1161, 1161, 1161,
+ /* 1860 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /* 1870 */ 1161, 1161, 1161, 1161, 1161, 1161, 415, 1161, 1161, 1161,
+ /* 1880 */ 1161, 1161, 1161, 1161, 215, 1161, 1161, 1161, 523, 1161,
+ /* 1890 */ 1161, 1161, 152, 1161, 1161, 154, 105, 526, 1161, 4,
+ /* 1900 */ 1161, 1161, 1161, 1161, 1161, 1161, 214, 1161, 1161, 1161,
+ /* 1910 */ 1161, 961, 1161, 529, 1161, 1161, 1161, 103, 103, 880,
+ /* 1920 */ 1161, 1161, 1161, 1161, 104, 1161, 415, 536, 535, 1161,
+ /* 1930 */ 1161, 951, 1161, 1161, 1161, 1161, 415, 1161, 1161, 1161,
+ /* 1940 */ 384, 1161, 1161, 1161, 1161, 288, 525, 1161, 523, 1161,
+ /* 1950 */ 1161, 1161, 1161, 1161, 1161, 1161, 97, 526, 1161, 4,
+ /* 1960 */ 1161, 1161, 951, 951, 953, 954, 27, 1161, 422, 1161,
+ /* 1970 */ 1161, 961, 1161, 529, 1161, 1161, 1161, 103, 103, 1161,
+ /* 1980 */ 1161, 1161, 1161, 1161, 104, 1161, 415, 536, 535, 1161,
+ /* 1990 */ 1161, 951, 268, 1161, 1161, 1161, 415, 366, 366, 365,
+ /* 2000 */ 253, 363, 1161, 1161, 797, 1161, 1161, 1161, 523, 1161,
+ /* 2010 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 213, 1161, 294,
+ /* 2020 */ 1161, 1161, 951, 951, 953, 954, 27, 293, 1161, 1161,
+ /* 2030 */ 1161, 961, 1161, 1161, 1161, 1161, 1161, 103, 103, 1161,
+ /* 2040 */ 1161, 1161, 1161, 1161, 104, 1161, 415, 536, 535, 1161,
+ /* 2050 */ 1161, 951, 1161, 1161, 1161, 1161, 1161, 215, 1161, 1161,
+ /* 2060 */ 1161, 1161, 1161, 1161, 1161, 152, 1161, 1161, 154, 1161,
+ /* 2070 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 214,
+ /* 2080 */ 1161, 1161, 951, 951, 953, 954, 27, 1161, 1161, 1161,
+ /* 2090 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /* 2100 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /* 2110 */ 1161, 1161, 1161, 384, 1161, 1161, 1161, 1161, 288, 525,
+ /* 2120 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /* 2130 */ 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161,
+ /* 2140 */ 1161, 422,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 184, 238, 239, 240, 238, 239, 240, 163, 155, 156,
- /* 10 */ 157, 158, 159, 160, 163, 191, 192, 183, 165, 19,
- /* 20 */ 167, 258, 202, 203, 200, 191, 163, 174, 184, 185,
- /* 30 */ 174, 31, 163, 163, 171, 184, 185, 35, 175, 39,
- /* 40 */ 179, 180, 181, 43, 44, 45, 46, 47, 48, 49,
- /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 184, 206,
- /* 60 */ 207, 163, 206, 207, 220, 163, 16, 163, 66, 163,
- /* 70 */ 59, 270, 219, 229, 273, 219, 74, 208, 174, 223,
- /* 80 */ 224, 163, 184, 185, 163, 232, 184, 185, 184, 185,
- /* 90 */ 184, 185, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 100 */ 100, 101, 102, 233, 198, 184, 185, 96, 97, 163,
- /* 110 */ 206, 207, 19, 163, 261, 104, 105, 106, 107, 198,
- /* 120 */ 109, 119, 220, 219, 220, 274, 275, 77, 117, 79,
- /* 130 */ 187, 229, 19, 229, 184, 185, 43, 44, 45, 46,
- /* 140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 150 */ 57, 233, 141, 134, 143, 102, 43, 44, 45, 46,
- /* 160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 170 */ 57, 152, 274, 216, 276, 218, 83, 163, 85, 233,
- /* 180 */ 67, 238, 239, 240, 11, 92, 93, 94, 95, 96,
- /* 190 */ 97, 98, 99, 100, 101, 102, 19, 54, 55, 56,
- /* 200 */ 57, 58, 163, 26, 163, 92, 93, 94, 95, 96,
- /* 210 */ 97, 98, 99, 100, 101, 102, 54, 55, 56, 57,
- /* 220 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 230 */ 53, 54, 55, 56, 57, 92, 93, 94, 95, 96,
- /* 240 */ 97, 98, 99, 100, 101, 102, 69, 96, 97, 98,
- /* 250 */ 99, 100, 101, 102, 92, 93, 94, 95, 96, 97,
- /* 260 */ 98, 99, 100, 101, 102, 81, 179, 180, 181, 92,
- /* 270 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
- /* 280 */ 163, 267, 268, 163, 22, 23, 59, 163, 26, 19,
- /* 290 */ 117, 118, 175, 109, 24, 59, 92, 93, 94, 95,
- /* 300 */ 96, 97, 98, 99, 100, 101, 102, 268, 184, 185,
- /* 310 */ 269, 127, 128, 43, 44, 45, 46, 47, 48, 49,
- /* 320 */ 50, 51, 52, 53, 54, 55, 56, 57, 157, 158,
- /* 330 */ 159, 160, 105, 106, 107, 163, 165, 59, 167, 184,
- /* 340 */ 90, 105, 106, 107, 108, 174, 73, 111, 112, 113,
- /* 350 */ 19, 22, 163, 91, 81, 163, 106, 121, 81, 132,
- /* 360 */ 110, 16, 92, 93, 94, 95, 96, 97, 98, 99,
- /* 370 */ 100, 101, 102, 184, 185, 255, 98, 206, 207, 26,
- /* 380 */ 101, 102, 19, 105, 106, 107, 23, 198, 59, 116,
- /* 390 */ 219, 141, 142, 143, 24, 163, 187, 205, 274, 275,
- /* 400 */ 127, 128, 182, 232, 127, 128, 43, 44, 45, 46,
- /* 410 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- /* 420 */ 57, 158, 77, 160, 79, 59, 26, 182, 165, 59,
- /* 430 */ 167, 199, 261, 102, 105, 106, 107, 174, 72, 108,
- /* 440 */ 109, 110, 111, 112, 113, 114, 59, 238, 239, 240,
- /* 450 */ 123, 120, 125, 126, 163, 92, 93, 94, 95, 96,
- /* 460 */ 97, 98, 99, 100, 101, 102, 163, 163, 163, 206,
- /* 470 */ 207, 105, 106, 107, 254, 19, 106, 90, 197, 23,
- /* 480 */ 127, 128, 219, 238, 239, 240, 22, 184, 185, 184,
- /* 490 */ 185, 22, 105, 106, 149, 232, 205, 110, 163, 43,
- /* 500 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 510 */ 54, 55, 56, 57, 98, 99, 100, 101, 102, 184,
- /* 520 */ 185, 163, 53, 59, 261, 220, 117, 118, 141, 142,
- /* 530 */ 143, 131, 174, 59, 229, 116, 117, 118, 163, 59,
- /* 540 */ 163, 163, 184, 185, 59, 242, 72, 22, 92, 93,
- /* 550 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 184,
- /* 560 */ 185, 24, 184, 185, 206, 207, 202, 203, 19, 105,
- /* 570 */ 106, 107, 23, 198, 22, 174, 198, 219, 220, 105,
- /* 580 */ 106, 107, 96, 97, 59, 105, 106, 107, 22, 174,
- /* 590 */ 59, 106, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 600 */ 51, 52, 53, 54, 55, 56, 57, 206, 207, 12,
- /* 610 */ 108, 59, 132, 111, 112, 113, 46, 47, 48, 49,
- /* 620 */ 219, 206, 207, 121, 27, 59, 163, 141, 207, 143,
- /* 630 */ 105, 106, 107, 163, 219, 234, 105, 106, 107, 42,
- /* 640 */ 219, 92, 93, 94, 95, 96, 97, 98, 99, 100,
- /* 650 */ 101, 102, 76, 163, 184, 185, 163, 105, 106, 107,
- /* 660 */ 63, 19, 86, 163, 163, 23, 163, 130, 205, 21,
- /* 670 */ 73, 105, 106, 107, 184, 185, 163, 184, 185, 237,
- /* 680 */ 110, 180, 181, 180, 181, 43, 44, 45, 46, 47,
- /* 690 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
- /* 700 */ 174, 163, 163, 22, 23, 163, 163, 26, 22, 23,
- /* 710 */ 220, 29, 73, 220, 272, 33, 22, 163, 24, 19,
- /* 720 */ 174, 208, 259, 184, 185, 19, 184, 185, 80, 175,
- /* 730 */ 230, 174, 206, 207, 92, 93, 94, 95, 96, 97,
- /* 740 */ 98, 99, 100, 101, 102, 219, 46, 65, 247, 195,
- /* 750 */ 247, 197, 206, 207, 19, 116, 117, 118, 23, 220,
- /* 760 */ 112, 174, 220, 206, 207, 219, 22, 174, 24, 174,
- /* 770 */ 22, 23, 91, 264, 265, 168, 219, 91, 43, 44,
- /* 780 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- /* 790 */ 55, 56, 57, 206, 207, 12, 163, 149, 255, 206,
- /* 800 */ 207, 206, 207, 59, 104, 23, 219, 163, 26, 163,
- /* 810 */ 27, 105, 219, 163, 219, 163, 211, 184, 185, 163,
- /* 820 */ 120, 163, 146, 163, 148, 42, 221, 92, 93, 94,
- /* 830 */ 95, 96, 97, 98, 99, 100, 101, 102, 163, 91,
- /* 840 */ 184, 185, 184, 185, 184, 185, 63, 19, 163, 205,
- /* 850 */ 106, 23, 245, 163, 208, 248, 116, 117, 118, 184,
- /* 860 */ 185, 163, 163, 7, 8, 9, 163, 19, 26, 184,
- /* 870 */ 185, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 880 */ 52, 53, 54, 55, 56, 57, 163, 184, 185, 107,
- /* 890 */ 163, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- /* 900 */ 52, 53, 54, 55, 56, 57, 208, 255, 177, 178,
- /* 910 */ 163, 184, 185, 163, 132, 163, 141, 163, 143, 22,
- /* 920 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
- /* 930 */ 102, 184, 185, 163, 184, 185, 184, 185, 184, 185,
- /* 940 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
- /* 950 */ 102, 163, 163, 163, 184, 185, 163, 115, 163, 163,
- /* 960 */ 163, 163, 15, 163, 163, 163, 163, 163, 23, 163,
- /* 970 */ 163, 26, 184, 185, 184, 185, 163, 184, 185, 184,
- /* 980 */ 185, 184, 185, 163, 184, 185, 184, 185, 184, 185,
- /* 990 */ 184, 185, 163, 96, 97, 147, 163, 184, 185, 163,
- /* 1000 */ 199, 163, 163, 205, 184, 185, 163, 60, 163, 141,
- /* 1010 */ 163, 143, 163, 184, 185, 19, 163, 184, 185, 230,
- /* 1020 */ 184, 185, 184, 185, 206, 207, 230, 184, 185, 184,
- /* 1030 */ 185, 184, 185, 184, 185, 19, 163, 219, 231, 43,
- /* 1040 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 1050 */ 54, 55, 56, 57, 163, 26, 163, 184, 185, 43,
- /* 1060 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 1070 */ 54, 55, 56, 57, 163, 184, 185, 184, 185, 163,
- /* 1080 */ 182, 163, 163, 163, 163, 163, 22, 163, 92, 93,
- /* 1090 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163,
- /* 1100 */ 184, 185, 184, 185, 163, 184, 185, 163, 92, 93,
- /* 1110 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163,
- /* 1120 */ 184, 185, 98, 59, 163, 184, 185, 205, 184, 185,
- /* 1130 */ 23, 206, 207, 26, 163, 26, 107, 153, 154, 237,
- /* 1140 */ 184, 185, 231, 147, 219, 184, 185, 249, 124, 127,
- /* 1150 */ 128, 231, 254, 129, 163, 231, 177, 178, 262, 263,
- /* 1160 */ 118, 132, 19, 19, 46, 223, 224, 31, 24, 23,
- /* 1170 */ 106, 124, 26, 22, 272, 39, 129, 23, 109, 110,
- /* 1180 */ 26, 163, 140, 19, 22, 234, 59, 43, 44, 45,
- /* 1190 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 1200 */ 56, 57, 231, 7, 8, 193, 59, 43, 44, 45,
- /* 1210 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
- /* 1220 */ 56, 57, 104, 61, 23, 23, 23, 26, 26, 26,
- /* 1230 */ 163, 23, 23, 106, 26, 26, 92, 93, 94, 95,
- /* 1240 */ 96, 97, 98, 99, 100, 101, 102, 138, 105, 23,
- /* 1250 */ 59, 23, 26, 106, 26, 163, 92, 93, 94, 95,
- /* 1260 */ 96, 97, 98, 99, 100, 101, 102, 110, 23, 23,
- /* 1270 */ 23, 26, 26, 26, 163, 163, 19, 120, 163, 163,
- /* 1280 */ 163, 130, 163, 163, 163, 163, 163, 163, 163, 193,
- /* 1290 */ 193, 163, 163, 163, 163, 225, 19, 106, 163, 222,
- /* 1300 */ 163, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 1310 */ 53, 54, 55, 56, 57, 163, 163, 203, 163, 163,
- /* 1320 */ 222, 163, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 1330 */ 53, 54, 55, 56, 57, 163, 163, 163, 163, 163,
- /* 1340 */ 251, 250, 209, 19, 20, 182, 22, 161, 222, 92,
- /* 1350 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
- /* 1360 */ 36, 222, 222, 260, 226, 188, 256, 226, 187, 92,
- /* 1370 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
- /* 1380 */ 210, 213, 213, 59, 213, 196, 192, 187, 256, 244,
- /* 1390 */ 212, 187, 226, 19, 20, 71, 22, 210, 166, 60,
- /* 1400 */ 130, 170, 260, 170, 38, 81, 257, 257, 170, 104,
- /* 1410 */ 36, 22, 43, 201, 90, 236, 138, 235, 213, 18,
- /* 1420 */ 96, 97, 48, 204, 204, 204, 204, 103, 170, 105,
- /* 1430 */ 106, 107, 18, 59, 110, 169, 213, 213, 201, 170,
- /* 1440 */ 201, 169, 236, 213, 146, 71, 235, 62, 253, 252,
- /* 1450 */ 170, 127, 128, 169, 22, 170, 82, 189, 169, 104,
- /* 1460 */ 170, 87, 169, 189, 90, 141, 142, 143, 144, 145,
- /* 1470 */ 96, 97, 186, 186, 186, 64, 194, 103, 186, 105,
- /* 1480 */ 106, 107, 115, 189, 110, 188, 186, 186, 19, 20,
- /* 1490 */ 194, 22, 186, 189, 102, 246, 246, 189, 133, 228,
- /* 1500 */ 104, 228, 227, 227, 170, 36, 134, 228, 227, 19,
- /* 1510 */ 20, 228, 22, 84, 271, 141, 142, 143, 144, 145,
- /* 1520 */ 0, 1, 2, 216, 22, 5, 36, 137, 59, 227,
- /* 1530 */ 10, 11, 12, 13, 14, 217, 269, 17, 216, 22,
- /* 1540 */ 71, 170, 243, 146, 241, 217, 136, 215, 135, 59,
- /* 1550 */ 30, 82, 32, 25, 214, 213, 87, 173, 26, 90,
- /* 1560 */ 40, 71, 13, 172, 164, 96, 97, 164, 6, 162,
- /* 1570 */ 162, 162, 103, 263, 105, 106, 107, 266, 266, 110,
- /* 1580 */ 90, 176, 176, 190, 182, 190, 96, 97, 98, 4,
- /* 1590 */ 70, 176, 3, 103, 182, 105, 106, 107, 78, 182,
- /* 1600 */ 110, 81, 182, 182, 182, 182, 182, 151, 88, 22,
- /* 1610 */ 141, 142, 143, 144, 145, 15, 89, 16, 23, 23,
- /* 1620 */ 128, 19, 20, 139, 22, 119, 131, 24, 20, 133,
- /* 1630 */ 16, 141, 142, 143, 144, 145, 1, 140, 36, 131,
- /* 1640 */ 119, 61, 122, 37, 139, 53, 53, 127, 128, 119,
- /* 1650 */ 53, 53, 105, 34, 130, 1, 5, 104, 22, 149,
- /* 1660 */ 26, 59, 68, 75, 41, 130, 24, 68, 104, 20,
- /* 1670 */ 150, 19, 120, 71, 114, 22, 67, 22, 22, 67,
- /* 1680 */ 23, 22, 22, 67, 82, 37, 28, 23, 138, 87,
- /* 1690 */ 22, 153, 90, 23, 23, 26, 23, 22, 96, 97,
- /* 1700 */ 24, 23, 22, 24, 130, 103, 23, 105, 106, 107,
- /* 1710 */ 1, 2, 110, 23, 5, 105, 34, 22, 132, 10,
- /* 1720 */ 11, 12, 13, 14, 26, 34, 17, 34, 85, 83,
- /* 1730 */ 44, 19, 20, 23, 22, 24, 75, 34, 23, 30,
- /* 1740 */ 26, 32, 26, 141, 142, 143, 144, 145, 36, 40,
- /* 1750 */ 23, 23, 23, 23, 11, 23, 22, 26, 22, 22,
- /* 1760 */ 22, 19, 20, 23, 22, 26, 15, 23, 22, 124,
- /* 1770 */ 130, 59, 23, 1, 130, 277, 277, 130, 36, 70,
- /* 1780 */ 130, 277, 277, 71, 277, 277, 277, 78, 277, 277,
- /* 1790 */ 81, 277, 277, 277, 277, 277, 277, 88, 277, 277,
- /* 1800 */ 277, 59, 90, 277, 277, 277, 277, 277, 96, 97,
- /* 1810 */ 277, 277, 277, 71, 277, 103, 277, 105, 106, 107,
- /* 1820 */ 277, 277, 110, 277, 277, 277, 277, 277, 277, 277,
- /* 1830 */ 277, 122, 90, 277, 277, 277, 127, 128, 96, 97,
- /* 1840 */ 277, 277, 277, 277, 277, 103, 277, 105, 106, 107,
- /* 1850 */ 277, 277, 110, 141, 142, 143, 144, 145, 277, 150,
- /* 1860 */ 277, 277, 277, 5, 277, 277, 277, 277, 10, 11,
- /* 1870 */ 12, 13, 14, 277, 277, 17, 277, 277, 277, 277,
- /* 1880 */ 277, 277, 277, 141, 142, 143, 144, 145, 30, 277,
- /* 1890 */ 32, 277, 277, 277, 277, 277, 277, 277, 40, 277,
- /* 1900 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1910 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1920 */ 277, 277, 277, 277, 277, 277, 277, 277, 70, 277,
- /* 1930 */ 277, 277, 277, 277, 277, 277, 78, 277, 277, 81,
- /* 1940 */ 277, 277, 277, 277, 277, 277, 88, 277, 277, 277,
- /* 1950 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1960 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1970 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 1980 */ 122, 277, 277, 277, 277, 127, 128, 277, 277, 277,
- /* 1990 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- /* 2000 */ 277, 277, 277, 277, 277, 277, 277, 277, 150, 277,
- /* 2010 */ 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ /* 0 */ 260, 261, 262, 260, 261, 262, 176, 177, 178, 179,
+ /* 10 */ 180, 181, 184, 206, 209, 184, 186, 206, 188, 19,
+ /* 20 */ 179, 281, 181, 213, 214, 195, 206, 186, 195, 188,
+ /* 30 */ 195, 31, 222, 184, 206, 207, 195, 206, 207, 39,
+ /* 40 */ 24, 209, 184, 43, 44, 45, 46, 47, 48, 49,
+ /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 228, 229,
+ /* 60 */ 184, 228, 229, 228, 229, 260, 261, 262, 192, 228,
+ /* 70 */ 229, 241, 196, 242, 241, 59, 241, 205, 245, 246,
+ /* 80 */ 184, 22, 241, 24, 254, 213, 54, 55, 56, 57,
+ /* 90 */ 58, 256, 260, 261, 262, 254, 96, 97, 98, 99,
+ /* 100 */ 100, 101, 102, 103, 104, 105, 106, 100, 101, 102,
+ /* 110 */ 103, 104, 105, 106, 284, 203, 19, 221, 59, 102,
+ /* 120 */ 103, 104, 105, 106, 59, 284, 110, 269, 96, 97,
+ /* 130 */ 98, 99, 100, 101, 102, 103, 104, 105, 106, 94,
+ /* 140 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 150 */ 53, 54, 55, 56, 57, 110, 184, 106, 73, 114,
+ /* 160 */ 178, 179, 180, 181, 219, 184, 81, 22, 186, 110,
+ /* 170 */ 188, 121, 122, 195, 109, 110, 111, 195, 206, 207,
+ /* 180 */ 83, 184, 85, 54, 55, 56, 57, 206, 207, 277,
+ /* 190 */ 145, 146, 147, 96, 97, 98, 99, 100, 101, 102,
+ /* 200 */ 103, 104, 105, 106, 59, 120, 228, 229, 143, 184,
+ /* 210 */ 228, 229, 184, 19, 242, 203, 131, 132, 221, 241,
+ /* 220 */ 26, 184, 184, 241, 196, 96, 97, 98, 99, 100,
+ /* 230 */ 101, 102, 103, 104, 105, 106, 254, 43, 44, 45,
+ /* 240 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ /* 250 */ 56, 57, 184, 184, 109, 110, 111, 105, 106, 184,
+ /* 260 */ 200, 201, 202, 69, 184, 227, 284, 96, 97, 98,
+ /* 270 */ 99, 100, 101, 102, 103, 104, 105, 106, 297, 298,
+ /* 280 */ 255, 206, 207, 19, 272, 59, 206, 207, 184, 277,
+ /* 290 */ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ /* 300 */ 106, 184, 259, 19, 184, 100, 101, 43, 44, 45,
+ /* 310 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ /* 320 */ 56, 57, 242, 206, 207, 184, 100, 101, 138, 292,
+ /* 330 */ 293, 67, 76, 296, 108, 109, 110, 111, 295, 113,
+ /* 340 */ 84, 59, 86, 22, 26, 89, 156, 121, 224, 225,
+ /* 350 */ 145, 19, 147, 59, 72, 256, 24, 184, 290, 291,
+ /* 360 */ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ /* 370 */ 106, 145, 297, 147, 299, 43, 44, 45, 46, 47,
+ /* 380 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ /* 390 */ 106, 109, 110, 111, 138, 184, 112, 113, 114, 115,
+ /* 400 */ 116, 117, 118, 109, 110, 111, 112, 59, 124, 115,
+ /* 410 */ 116, 117, 292, 293, 297, 298, 296, 206, 207, 125,
+ /* 420 */ 72, 100, 101, 184, 46, 47, 48, 49, 96, 97,
+ /* 430 */ 98, 99, 100, 101, 102, 103, 104, 105, 106, 59,
+ /* 440 */ 200, 201, 202, 184, 59, 206, 207, 46, 19, 131,
+ /* 450 */ 132, 278, 23, 242, 184, 184, 76, 109, 110, 111,
+ /* 460 */ 224, 225, 251, 81, 84, 184, 86, 22, 23, 89,
+ /* 470 */ 184, 26, 43, 44, 45, 46, 47, 48, 49, 50,
+ /* 480 */ 51, 52, 53, 54, 55, 56, 57, 102, 184, 109,
+ /* 490 */ 110, 111, 114, 184, 109, 110, 111, 184, 227, 184,
+ /* 500 */ 230, 184, 22, 264, 195, 59, 22, 184, 195, 108,
+ /* 510 */ 206, 207, 59, 131, 132, 206, 207, 184, 138, 206,
+ /* 520 */ 207, 206, 207, 206, 207, 96, 97, 98, 99, 100,
+ /* 530 */ 101, 102, 103, 104, 105, 106, 255, 228, 229, 59,
+ /* 540 */ 95, 228, 229, 59, 184, 19, 242, 94, 184, 23,
+ /* 550 */ 241, 242, 184, 282, 241, 242, 110, 242, 184, 242,
+ /* 560 */ 251, 59, 109, 110, 196, 184, 251, 114, 251, 43,
+ /* 570 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 580 */ 54, 55, 56, 57, 259, 217, 12, 219, 255, 109,
+ /* 590 */ 110, 111, 203, 109, 110, 111, 184, 22, 145, 146,
+ /* 600 */ 147, 27, 112, 22, 230, 115, 116, 117, 227, 19,
+ /* 610 */ 59, 109, 110, 111, 291, 125, 42, 35, 206, 207,
+ /* 620 */ 295, 184, 96, 97, 98, 99, 100, 101, 102, 103,
+ /* 630 */ 104, 105, 106, 26, 59, 233, 46, 63, 136, 184,
+ /* 640 */ 59, 184, 19, 206, 207, 243, 23, 73, 66, 260,
+ /* 650 */ 261, 262, 59, 184, 242, 195, 74, 220, 184, 184,
+ /* 660 */ 109, 110, 111, 206, 207, 184, 43, 44, 45, 46,
+ /* 670 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 680 */ 57, 206, 207, 76, 109, 110, 111, 136, 228, 229,
+ /* 690 */ 109, 110, 111, 86, 184, 220, 89, 21, 108, 230,
+ /* 700 */ 184, 241, 109, 110, 111, 123, 184, 127, 184, 129,
+ /* 710 */ 130, 184, 195, 184, 124, 184, 198, 199, 184, 96,
+ /* 720 */ 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ /* 730 */ 206, 207, 11, 206, 207, 206, 207, 206, 207, 19,
+ /* 740 */ 206, 207, 184, 23, 220, 228, 229, 220, 81, 220,
+ /* 750 */ 195, 220, 287, 288, 220, 195, 80, 195, 241, 201,
+ /* 760 */ 202, 184, 73, 43, 44, 45, 46, 47, 48, 49,
+ /* 770 */ 50, 51, 52, 53, 54, 55, 56, 57, 201, 202,
+ /* 780 */ 113, 195, 184, 228, 229, 120, 121, 122, 228, 229,
+ /* 790 */ 228, 229, 116, 16, 23, 184, 241, 26, 131, 132,
+ /* 800 */ 278, 241, 19, 241, 22, 23, 184, 189, 26, 120,
+ /* 810 */ 121, 122, 184, 26, 228, 229, 96, 97, 98, 99,
+ /* 820 */ 100, 101, 102, 103, 104, 105, 106, 241, 270, 153,
+ /* 830 */ 66, 228, 229, 229, 206, 207, 19, 184, 228, 229,
+ /* 840 */ 23, 16, 121, 122, 241, 241, 82, 270, 29, 227,
+ /* 850 */ 252, 241, 33, 19, 77, 91, 79, 184, 22, 23,
+ /* 860 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 870 */ 53, 54, 55, 56, 57, 12, 184, 95, 184, 206,
+ /* 880 */ 207, 76, 111, 184, 65, 267, 184, 184, 184, 271,
+ /* 890 */ 27, 86, 109, 184, 89, 120, 121, 122, 206, 207,
+ /* 900 */ 206, 207, 77, 139, 79, 42, 184, 136, 206, 207,
+ /* 910 */ 206, 207, 184, 96, 97, 98, 99, 100, 101, 102,
+ /* 920 */ 103, 104, 105, 106, 184, 138, 63, 184, 206, 207,
+ /* 930 */ 153, 95, 184, 19, 206, 207, 227, 23, 7, 8,
+ /* 940 */ 9, 293, 293, 109, 296, 296, 206, 207, 215, 206,
+ /* 950 */ 207, 184, 253, 19, 206, 207, 253, 43, 44, 45,
+ /* 960 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ /* 970 */ 56, 57, 184, 206, 207, 184, 184, 43, 44, 45,
+ /* 980 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ /* 990 */ 56, 57, 184, 22, 23, 184, 59, 206, 207, 184,
+ /* 1000 */ 184, 238, 184, 240, 184, 22, 184, 184, 157, 158,
+ /* 1010 */ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ /* 1020 */ 106, 206, 207, 184, 206, 207, 206, 207, 206, 207,
+ /* 1030 */ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ /* 1040 */ 106, 184, 59, 227, 252, 184, 293, 110, 184, 296,
+ /* 1050 */ 184, 184, 184, 230, 184, 184, 184, 15, 184, 184,
+ /* 1060 */ 184, 253, 184, 206, 207, 184, 95, 206, 207, 102,
+ /* 1070 */ 206, 207, 206, 207, 206, 207, 206, 207, 206, 207,
+ /* 1080 */ 206, 207, 206, 207, 184, 151, 184, 206, 207, 278,
+ /* 1090 */ 184, 252, 184, 110, 184, 128, 184, 198, 199, 184,
+ /* 1100 */ 133, 184, 60, 26, 184, 19, 206, 207, 206, 207,
+ /* 1110 */ 131, 132, 206, 207, 206, 207, 206, 207, 206, 207,
+ /* 1120 */ 253, 206, 207, 206, 207, 19, 206, 207, 253, 43,
+ /* 1130 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 1140 */ 54, 55, 56, 57, 184, 26, 184, 26, 184, 43,
+ /* 1150 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 1160 */ 54, 55, 56, 57, 285, 286, 206, 207, 206, 207,
+ /* 1170 */ 206, 207, 184, 31, 184, 293, 184, 293, 296, 184,
+ /* 1180 */ 296, 39, 96, 97, 98, 99, 100, 101, 102, 103,
+ /* 1190 */ 104, 105, 106, 184, 206, 207, 206, 207, 206, 207,
+ /* 1200 */ 184, 22, 96, 97, 98, 99, 100, 101, 102, 103,
+ /* 1210 */ 104, 105, 106, 184, 245, 246, 184, 26, 23, 142,
+ /* 1220 */ 128, 26, 206, 207, 150, 133, 152, 22, 22, 24,
+ /* 1230 */ 111, 23, 53, 184, 26, 206, 207, 151, 206, 207,
+ /* 1240 */ 119, 24, 122, 23, 23, 23, 26, 26, 26, 23,
+ /* 1250 */ 23, 23, 26, 26, 26, 136, 23, 19, 22, 26,
+ /* 1260 */ 113, 114, 24, 114, 144, 184, 59, 61, 7, 8,
+ /* 1270 */ 59, 23, 23, 124, 26, 26, 23, 19, 145, 26,
+ /* 1280 */ 147, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 1290 */ 52, 53, 54, 55, 56, 57, 145, 23, 147, 184,
+ /* 1300 */ 26, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 1310 */ 52, 53, 54, 55, 56, 57, 23, 110, 184, 26,
+ /* 1320 */ 184, 110, 184, 184, 184, 215, 135, 215, 184, 184,
+ /* 1330 */ 184, 247, 184, 244, 96, 97, 98, 99, 100, 101,
+ /* 1340 */ 102, 103, 104, 105, 106, 184, 184, 184, 301, 184,
+ /* 1350 */ 184, 134, 225, 184, 96, 97, 98, 99, 100, 101,
+ /* 1360 */ 102, 103, 104, 105, 106, 184, 184, 184, 184, 184,
+ /* 1370 */ 134, 184, 274, 273, 19, 244, 244, 204, 182, 244,
+ /* 1380 */ 283, 231, 279, 279, 232, 244, 210, 209, 235, 235,
+ /* 1390 */ 235, 248, 218, 234, 19, 209, 238, 209, 238, 44,
+ /* 1400 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ /* 1410 */ 55, 56, 57, 214, 60, 248, 248, 187, 134, 38,
+ /* 1420 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ /* 1430 */ 55, 56, 57, 232, 191, 191, 266, 280, 191, 283,
+ /* 1440 */ 143, 269, 108, 22, 280, 19, 20, 258, 22, 257,
+ /* 1450 */ 43, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ /* 1460 */ 105, 106, 36, 223, 142, 18, 235, 226, 226, 191,
+ /* 1470 */ 18, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ /* 1480 */ 105, 106, 226, 226, 190, 59, 235, 235, 223, 223,
+ /* 1490 */ 258, 257, 191, 190, 235, 150, 62, 71, 191, 276,
+ /* 1500 */ 275, 19, 20, 190, 22, 22, 211, 81, 191, 190,
+ /* 1510 */ 211, 191, 108, 190, 208, 64, 208, 208, 36, 119,
+ /* 1520 */ 94, 216, 211, 208, 210, 106, 100, 101, 216, 208,
+ /* 1530 */ 48, 268, 208, 107, 208, 109, 110, 111, 211, 268,
+ /* 1540 */ 114, 59, 211, 137, 108, 88, 250, 249, 191, 141,
+ /* 1550 */ 250, 249, 138, 71, 250, 300, 22, 131, 132, 249,
+ /* 1560 */ 300, 191, 150, 238, 82, 140, 250, 249, 239, 87,
+ /* 1570 */ 139, 145, 146, 147, 148, 149, 94, 239, 237, 236,
+ /* 1580 */ 25, 235, 100, 101, 194, 26, 193, 13, 185, 107,
+ /* 1590 */ 185, 109, 110, 111, 6, 263, 114, 203, 265, 183,
+ /* 1600 */ 183, 183, 203, 212, 203, 203, 197, 197, 212, 4,
+ /* 1610 */ 3, 22, 197, 155, 15, 204, 203, 289, 93, 289,
+ /* 1620 */ 16, 286, 132, 23, 204, 23, 123, 145, 146, 147,
+ /* 1630 */ 148, 149, 0, 1, 2, 143, 24, 5, 20, 135,
+ /* 1640 */ 16, 1, 10, 11, 12, 13, 14, 137, 135, 17,
+ /* 1650 */ 144, 123, 19, 20, 61, 22, 37, 143, 123, 53,
+ /* 1660 */ 109, 53, 30, 53, 32, 34, 53, 134, 1, 36,
+ /* 1670 */ 5, 22, 40, 108, 153, 41, 26, 68, 75, 68,
+ /* 1680 */ 134, 108, 24, 20, 124, 19, 118, 67, 67, 28,
+ /* 1690 */ 22, 22, 59, 22, 67, 23, 22, 22, 142, 37,
+ /* 1700 */ 23, 22, 70, 23, 71, 157, 23, 23, 26, 23,
+ /* 1710 */ 78, 22, 24, 81, 23, 82, 22, 24, 134, 23,
+ /* 1720 */ 87, 23, 19, 20, 92, 22, 109, 94, 22, 34,
+ /* 1730 */ 136, 26, 85, 100, 101, 34, 34, 83, 34, 36,
+ /* 1740 */ 107, 34, 109, 110, 111, 75, 90, 114, 75, 34,
+ /* 1750 */ 23, 22, 44, 34, 24, 23, 22, 26, 126, 26,
+ /* 1760 */ 23, 23, 59, 131, 132, 23, 23, 26, 23, 11,
+ /* 1770 */ 22, 22, 26, 23, 71, 23, 22, 22, 145, 146,
+ /* 1780 */ 147, 148, 149, 128, 23, 82, 154, 134, 15, 1,
+ /* 1790 */ 87, 134, 302, 134, 134, 302, 302, 94, 302, 302,
+ /* 1800 */ 302, 302, 302, 100, 101, 302, 302, 302, 302, 302,
+ /* 1810 */ 107, 302, 109, 110, 111, 1, 2, 114, 302, 5,
+ /* 1820 */ 302, 302, 302, 302, 10, 11, 12, 13, 14, 302,
+ /* 1830 */ 302, 17, 302, 302, 302, 302, 19, 20, 302, 22,
+ /* 1840 */ 302, 302, 302, 302, 30, 302, 32, 302, 145, 146,
+ /* 1850 */ 147, 148, 149, 36, 40, 302, 302, 302, 302, 302,
+ /* 1860 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 1870 */ 302, 302, 302, 302, 302, 302, 59, 302, 302, 302,
+ /* 1880 */ 302, 302, 302, 302, 70, 302, 302, 302, 71, 302,
+ /* 1890 */ 302, 302, 78, 302, 302, 81, 19, 20, 302, 22,
+ /* 1900 */ 302, 302, 302, 302, 302, 302, 92, 302, 302, 302,
+ /* 1910 */ 302, 94, 302, 36, 302, 302, 302, 100, 101, 102,
+ /* 1920 */ 302, 302, 302, 302, 107, 302, 109, 110, 111, 302,
+ /* 1930 */ 302, 114, 302, 302, 302, 302, 59, 302, 302, 302,
+ /* 1940 */ 126, 302, 302, 302, 302, 131, 132, 302, 71, 302,
+ /* 1950 */ 302, 302, 302, 302, 302, 302, 19, 20, 302, 22,
+ /* 1960 */ 302, 302, 145, 146, 147, 148, 149, 302, 154, 302,
+ /* 1970 */ 302, 94, 302, 36, 302, 302, 302, 100, 101, 302,
+ /* 1980 */ 302, 302, 302, 302, 107, 302, 109, 110, 111, 302,
+ /* 1990 */ 302, 114, 5, 302, 302, 302, 59, 10, 11, 12,
+ /* 2000 */ 13, 14, 302, 302, 17, 302, 302, 302, 71, 302,
+ /* 2010 */ 302, 302, 302, 302, 302, 302, 302, 30, 302, 32,
+ /* 2020 */ 302, 302, 145, 146, 147, 148, 149, 40, 302, 302,
+ /* 2030 */ 302, 94, 302, 302, 302, 302, 302, 100, 101, 302,
+ /* 2040 */ 302, 302, 302, 302, 107, 302, 109, 110, 111, 302,
+ /* 2050 */ 302, 114, 302, 302, 302, 302, 302, 70, 302, 302,
+ /* 2060 */ 302, 302, 302, 302, 302, 78, 302, 302, 81, 302,
+ /* 2070 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 92,
+ /* 2080 */ 302, 302, 145, 146, 147, 148, 149, 302, 302, 302,
+ /* 2090 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2100 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2110 */ 302, 302, 302, 126, 302, 302, 302, 302, 131, 132,
+ /* 2120 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2130 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2140 */ 302, 154, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2150 */ 302, 302, 302, 302, 302, 302, 302, 302, 302, 302,
+ /* 2160 */ 302, 302, 302, 302, 302, 302, 302, 302, 302,
};
-#define YY_SHIFT_COUNT (520)
+#define YY_SHIFT_COUNT (539)
#define YY_SHIFT_MIN (0)
-#define YY_SHIFT_MAX (1858)
+#define YY_SHIFT_MAX (1987)
static const unsigned short int yy_shift_ofst[] = {
- /* 0 */ 1709, 1520, 1858, 1324, 1324, 277, 1374, 1469, 1602, 1712,
- /* 10 */ 1712, 1712, 273, 0, 0, 113, 1016, 1712, 1712, 1712,
- /* 20 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 11, 11, 236,
- /* 30 */ 184, 277, 277, 277, 277, 277, 277, 93, 177, 270,
- /* 40 */ 363, 456, 549, 642, 735, 828, 848, 996, 1144, 1016,
- /* 50 */ 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016,
- /* 60 */ 1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, 1277,
- /* 70 */ 1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
- /* 80 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
- /* 90 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712,
- /* 100 */ 1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, 1712, 1712,
- /* 110 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 143, 162, 162,
- /* 120 */ 162, 162, 162, 204, 151, 416, 531, 648, 700, 531,
- /* 130 */ 486, 486, 531, 353, 353, 353, 353, 409, 279, 53,
- /* 140 */ 2009, 2009, 331, 331, 331, 329, 366, 329, 329, 597,
- /* 150 */ 597, 464, 474, 262, 681, 531, 531, 531, 531, 531,
- /* 160 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
- /* 170 */ 531, 531, 531, 531, 531, 531, 531, 173, 485, 984,
- /* 180 */ 984, 576, 485, 19, 1022, 2009, 2009, 2009, 387, 250,
- /* 190 */ 250, 525, 502, 278, 552, 227, 480, 566, 531, 531,
- /* 200 */ 531, 531, 531, 531, 531, 531, 531, 531, 639, 531,
- /* 210 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
- /* 220 */ 531, 2, 2, 2, 531, 531, 531, 531, 782, 531,
- /* 230 */ 531, 531, 744, 531, 531, 783, 531, 531, 531, 531,
- /* 240 */ 531, 531, 531, 531, 419, 682, 327, 370, 370, 370,
- /* 250 */ 370, 1029, 327, 327, 1024, 897, 856, 947, 1109, 706,
- /* 260 */ 706, 1143, 1109, 1109, 1143, 842, 945, 1118, 1136, 1136,
- /* 270 */ 1136, 706, 676, 400, 1047, 694, 1339, 1270, 1270, 1366,
- /* 280 */ 1366, 1270, 1305, 1389, 1369, 1278, 1401, 1401, 1401, 1401,
- /* 290 */ 1270, 1414, 1278, 1278, 1305, 1389, 1369, 1369, 1278, 1270,
- /* 300 */ 1414, 1298, 1385, 1270, 1414, 1432, 1270, 1414, 1270, 1414,
- /* 310 */ 1432, 1355, 1355, 1355, 1411, 1432, 1355, 1367, 1355, 1411,
- /* 320 */ 1355, 1355, 1432, 1392, 1392, 1432, 1365, 1396, 1365, 1396,
- /* 330 */ 1365, 1396, 1365, 1396, 1270, 1372, 1429, 1502, 1390, 1372,
- /* 340 */ 1517, 1270, 1397, 1390, 1410, 1413, 1278, 1528, 1532, 1549,
- /* 350 */ 1549, 1562, 1562, 1562, 2009, 2009, 2009, 2009, 2009, 2009,
- /* 360 */ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
- /* 370 */ 570, 345, 686, 748, 50, 740, 1064, 1107, 469, 537,
- /* 380 */ 1042, 1146, 1162, 1154, 1201, 1202, 1203, 1208, 1209, 1127,
- /* 390 */ 1069, 1196, 1157, 1147, 1226, 1228, 1245, 775, 868, 1246,
- /* 400 */ 1247, 1191, 1151, 1585, 1589, 1587, 1456, 1600, 1527, 1601,
- /* 410 */ 1595, 1596, 1492, 1484, 1506, 1603, 1495, 1608, 1496, 1614,
- /* 420 */ 1635, 1508, 1497, 1521, 1580, 1606, 1505, 1592, 1593, 1597,
- /* 430 */ 1598, 1530, 1547, 1619, 1524, 1654, 1651, 1636, 1553, 1510,
- /* 440 */ 1594, 1634, 1599, 1588, 1623, 1535, 1564, 1642, 1649, 1652,
- /* 450 */ 1552, 1560, 1653, 1609, 1655, 1656, 1657, 1659, 1612, 1658,
- /* 460 */ 1660, 1616, 1648, 1664, 1550, 1668, 1538, 1670, 1671, 1669,
- /* 470 */ 1673, 1675, 1676, 1678, 1680, 1679, 1574, 1683, 1690, 1610,
- /* 480 */ 1682, 1695, 1586, 1698, 1691, 1698, 1693, 1643, 1661, 1646,
- /* 490 */ 1686, 1710, 1711, 1714, 1716, 1703, 1715, 1698, 1727, 1728,
- /* 500 */ 1729, 1730, 1731, 1732, 1734, 1743, 1736, 1737, 1740, 1744,
- /* 510 */ 1738, 1746, 1739, 1645, 1640, 1644, 1647, 1650, 1749, 1751,
- /* 520 */ 1772,
+ /* 0 */ 1814, 1632, 1987, 1426, 1426, 382, 1482, 1633, 1703, 1877,
+ /* 10 */ 1877, 1877, 85, 0, 0, 264, 1106, 1877, 1877, 1877,
+ /* 20 */ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /* 30 */ 226, 226, 380, 380, 294, 667, 382, 382, 382, 382,
+ /* 40 */ 382, 382, 97, 194, 332, 429, 526, 623, 720, 817,
+ /* 50 */ 914, 934, 1086, 1238, 1106, 1106, 1106, 1106, 1106, 1106,
+ /* 60 */ 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106,
+ /* 70 */ 1106, 1106, 1258, 1106, 1355, 1375, 1375, 1817, 1877, 1877,
+ /* 80 */ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /* 90 */ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /* 100 */ 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /* 110 */ 1937, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
+ /* 120 */ 1877, 1877, 1877, 1877, 32, 129, 129, 129, 129, 129,
+ /* 130 */ 171, 7, 17, 593, 676, 590, 593, 205, 205, 593,
+ /* 140 */ 318, 318, 318, 318, 50, 152, 51, 2142, 2142, 284,
+ /* 150 */ 284, 284, 65, 145, 282, 145, 145, 574, 574, 256,
+ /* 160 */ 348, 445, 782, 593, 593, 593, 593, 593, 593, 593,
+ /* 170 */ 593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+ /* 180 */ 593, 593, 593, 593, 607, 607, 593, 721, 805, 805,
+ /* 190 */ 446, 851, 851, 446, 190, 979, 2142, 2142, 2142, 453,
+ /* 200 */ 45, 45, 480, 490, 484, 385, 575, 502, 551, 581,
+ /* 210 */ 593, 593, 593, 593, 593, 593, 593, 593, 593, 689,
+ /* 220 */ 593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+ /* 230 */ 593, 593, 582, 582, 582, 593, 593, 593, 593, 771,
+ /* 240 */ 593, 593, 593, 59, 764, 593, 593, 863, 593, 593,
+ /* 250 */ 593, 593, 593, 593, 593, 593, 665, 819, 580, 16,
+ /* 260 */ 16, 16, 16, 1119, 580, 580, 967, 321, 931, 1042,
+ /* 270 */ 1077, 783, 783, 834, 1077, 1077, 834, 1121, 1195, 401,
+ /* 280 */ 1142, 1142, 1142, 783, 787, 787, 1074, 1191, 1092, 1205,
+ /* 290 */ 1354, 1284, 1284, 1381, 1381, 1284, 1297, 1334, 1421, 1407,
+ /* 300 */ 1322, 1447, 1447, 1447, 1447, 1284, 1452, 1322, 1322, 1334,
+ /* 310 */ 1421, 1407, 1407, 1322, 1284, 1452, 1345, 1434, 1284, 1452,
+ /* 320 */ 1483, 1284, 1452, 1284, 1452, 1483, 1404, 1404, 1404, 1451,
+ /* 330 */ 1483, 1404, 1400, 1404, 1451, 1404, 1404, 1483, 1419, 1419,
+ /* 340 */ 1483, 1406, 1436, 1406, 1436, 1406, 1436, 1406, 1436, 1284,
+ /* 350 */ 1457, 1457, 1408, 1414, 1534, 1284, 1412, 1408, 1425, 1431,
+ /* 360 */ 1322, 1555, 1559, 1574, 1574, 1588, 1588, 1588, 2142, 2142,
+ /* 370 */ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142,
+ /* 380 */ 2142, 2142, 2142, 378, 777, 836, 971, 825, 775, 983,
+ /* 390 */ 1208, 1179, 1217, 1120, 1220, 1206, 1221, 1222, 1226, 1227,
+ /* 400 */ 1228, 1233, 937, 1147, 1261, 1149, 1207, 1248, 1249, 1253,
+ /* 410 */ 1133, 1151, 1274, 1293, 1211, 1236, 1605, 1607, 1589, 1458,
+ /* 420 */ 1599, 1525, 1604, 1600, 1602, 1490, 1492, 1503, 1612, 1504,
+ /* 430 */ 1618, 1510, 1624, 1640, 1513, 1506, 1528, 1593, 1619, 1514,
+ /* 440 */ 1606, 1608, 1610, 1613, 1535, 1551, 1631, 1533, 1667, 1665,
+ /* 450 */ 1649, 1565, 1521, 1609, 1650, 1611, 1603, 1634, 1546, 1573,
+ /* 460 */ 1658, 1663, 1666, 1560, 1568, 1668, 1620, 1669, 1671, 1672,
+ /* 470 */ 1674, 1621, 1661, 1675, 1627, 1662, 1677, 1556, 1679, 1680,
+ /* 480 */ 1548, 1683, 1684, 1682, 1686, 1689, 1688, 1691, 1694, 1693,
+ /* 490 */ 1584, 1696, 1698, 1617, 1695, 1706, 1594, 1705, 1701, 1702,
+ /* 500 */ 1704, 1707, 1647, 1670, 1654, 1708, 1673, 1656, 1715, 1727,
+ /* 510 */ 1729, 1730, 1731, 1733, 1719, 1732, 1705, 1737, 1738, 1742,
+ /* 520 */ 1743, 1741, 1745, 1734, 1758, 1748, 1749, 1750, 1752, 1754,
+ /* 530 */ 1755, 1746, 1655, 1653, 1657, 1659, 1660, 1761, 1773, 1788,
};
-#define YY_REDUCE_COUNT (369)
-#define YY_REDUCE_MIN (-237)
-#define YY_REDUCE_MAX (1424)
+#define YY_REDUCE_COUNT (382)
+#define YY_REDUCE_MIN (-260)
+#define YY_REDUCE_MAX (1420)
static const short yy_reduce_ofst[] = {
- /* 0 */ -147, 171, 263, -96, 358, -144, -149, -102, 124, -156,
- /* 10 */ -98, 305, 401, -57, 209, -237, 245, -94, -79, 189,
- /* 20 */ 375, 490, 493, 378, 303, 539, 542, 501, 503, 554,
- /* 30 */ 415, 526, 546, 557, 587, 593, 595, -234, -234, -234,
- /* 40 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
- /* 50 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
- /* 60 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234,
- /* 70 */ -234, -50, 335, 470, 633, 656, 658, 660, 675, 685,
- /* 80 */ 703, 727, 747, 750, 752, 754, 770, 788, 790, 793,
- /* 90 */ 795, 797, 800, 802, 804, 806, 813, 820, 829, 833,
- /* 100 */ 836, 838, 843, 845, 847, 849, 873, 891, 893, 916,
- /* 110 */ 918, 921, 936, 941, 944, 956, 961, -234, -234, -234,
- /* 120 */ -234, -234, -234, -234, -234, -234, 463, 607, -176, 14,
- /* 130 */ -139, 87, -137, 818, 925, 818, 925, 898, -234, -234,
- /* 140 */ -234, -234, -166, -166, -166, -130, -131, -82, -54, -180,
- /* 150 */ 364, 41, 513, 509, 509, 117, 500, 789, 796, 646,
- /* 160 */ 192, 291, 644, 798, 120, 807, 543, 911, 920, 652,
- /* 170 */ 924, 922, 232, 698, 801, 971, 39, 220, 731, 442,
- /* 180 */ 902, -199, 979, -43, 421, 896, 942, 605, -184, -126,
- /* 190 */ 155, 172, 281, 304, 377, 538, 650, 690, 699, 723,
- /* 200 */ 803, 839, 853, 919, 991, 1018, 1067, 1092, 951, 1111,
- /* 210 */ 1112, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1124,
- /* 220 */ 1125, 1012, 1096, 1097, 1128, 1129, 1130, 1131, 1070, 1135,
- /* 230 */ 1137, 1152, 1077, 1153, 1155, 1114, 1156, 304, 1158, 1172,
- /* 240 */ 1173, 1174, 1175, 1176, 1089, 1091, 1133, 1098, 1126, 1139,
- /* 250 */ 1140, 1070, 1133, 1133, 1170, 1163, 1186, 1103, 1168, 1138,
- /* 260 */ 1141, 1110, 1169, 1171, 1132, 1177, 1189, 1194, 1181, 1200,
- /* 270 */ 1204, 1166, 1145, 1178, 1187, 1232, 1142, 1231, 1233, 1149,
- /* 280 */ 1150, 1238, 1179, 1182, 1212, 1205, 1219, 1220, 1221, 1222,
- /* 290 */ 1258, 1266, 1223, 1224, 1206, 1211, 1237, 1239, 1230, 1269,
- /* 300 */ 1272, 1195, 1197, 1280, 1284, 1268, 1285, 1289, 1290, 1293,
- /* 310 */ 1274, 1286, 1287, 1288, 1282, 1294, 1292, 1297, 1300, 1296,
- /* 320 */ 1301, 1306, 1304, 1249, 1250, 1308, 1271, 1275, 1273, 1276,
- /* 330 */ 1279, 1281, 1283, 1302, 1334, 1307, 1243, 1267, 1318, 1322,
- /* 340 */ 1303, 1371, 1299, 1328, 1332, 1340, 1342, 1384, 1391, 1400,
- /* 350 */ 1403, 1407, 1408, 1409, 1311, 1312, 1310, 1405, 1402, 1412,
- /* 360 */ 1417, 1420, 1406, 1393, 1395, 1421, 1422, 1423, 1424, 1415,
+ /* 0 */ -170, -18, -159, 309, 313, -167, -19, 75, 117, 211,
+ /* 10 */ 315, 317, -165, -195, -168, -260, 389, 437, 475, 524,
+ /* 20 */ 527, -169, 529, 531, -28, 80, 534, 239, 304, 412,
+ /* 30 */ 558, 577, 37, 120, 368, -22, 460, 517, 555, 560,
+ /* 40 */ 562, 586, -257, -257, -257, -257, -257, -257, -257, -257,
+ /* 50 */ -257, -257, -257, -257, -257, -257, -257, -257, -257, -257,
+ /* 60 */ -257, -257, -257, -257, -257, -257, -257, -257, -257, -257,
+ /* 70 */ -257, -257, -257, -257, -257, -257, -257, -172, 457, 628,
+ /* 80 */ 673, 692, 694, 702, 704, 722, 728, 740, 743, 748,
+ /* 90 */ 767, 791, 815, 818, 820, 822, 857, 861, 864, 866,
+ /* 100 */ 868, 870, 872, 874, 876, 881, 900, 902, 906, 908,
+ /* 110 */ 910, 912, 915, 917, 920, 960, 962, 964, 988, 990,
+ /* 120 */ 992, 1016, 1029, 1032, -257, -257, -257, -257, -257, -257,
+ /* 130 */ -257, -257, -257, 271, 618, -190, 68, 60, 240, -124,
+ /* 140 */ 603, 610, 603, 610, 12, -257, -257, -257, -257, -128,
+ /* 150 */ -128, -128, -142, 25, 270, 281, 333, 124, 236, 648,
+ /* 160 */ 374, 465, 465, 28, 598, 792, 839, 469, 38, 381,
+ /* 170 */ 622, 709, 173, 699, 522, 703, 808, 811, 867, 816,
+ /* 180 */ -104, 823, -3, 875, 649, 753, 323, -88, 882, 884,
+ /* 190 */ 518, 43, 325, 899, 763, 604, 879, 969, 402, -193,
+ /* 200 */ -189, -180, -151, -55, 69, 104, 141, 259, 286, 360,
+ /* 210 */ 364, 455, 474, 481, 510, 516, 611, 653, 788, 99,
+ /* 220 */ 871, 878, 995, 1009, 1049, 1081, 1115, 1134, 1136, 1138,
+ /* 230 */ 1139, 1140, 733, 1110, 1112, 1144, 1145, 1146, 1148, 1084,
+ /* 240 */ 1161, 1162, 1163, 1089, 1047, 1165, 1166, 1127, 1169, 104,
+ /* 250 */ 1181, 1182, 1183, 1184, 1185, 1187, 1098, 1100, 1150, 1131,
+ /* 260 */ 1132, 1135, 1141, 1084, 1150, 1150, 1152, 1173, 1196, 1097,
+ /* 270 */ 1153, 1143, 1167, 1103, 1154, 1155, 1104, 1176, 1174, 1199,
+ /* 280 */ 1178, 1186, 1188, 1168, 1158, 1160, 1170, 1159, 1201, 1230,
+ /* 290 */ 1156, 1243, 1244, 1157, 1164, 1247, 1172, 1189, 1192, 1240,
+ /* 300 */ 1231, 1241, 1242, 1256, 1257, 1278, 1294, 1251, 1252, 1232,
+ /* 310 */ 1234, 1265, 1266, 1259, 1301, 1303, 1223, 1225, 1307, 1313,
+ /* 320 */ 1295, 1317, 1319, 1320, 1323, 1299, 1306, 1308, 1309, 1305,
+ /* 330 */ 1311, 1315, 1314, 1321, 1312, 1324, 1326, 1327, 1263, 1271,
+ /* 340 */ 1331, 1296, 1298, 1300, 1302, 1304, 1310, 1316, 1318, 1357,
+ /* 350 */ 1255, 1260, 1329, 1325, 1332, 1370, 1333, 1338, 1341, 1343,
+ /* 360 */ 1346, 1390, 1393, 1403, 1405, 1416, 1417, 1418, 1328, 1330,
+ /* 370 */ 1335, 1409, 1394, 1399, 1401, 1402, 1410, 1391, 1396, 1411,
+ /* 380 */ 1420, 1413, 1415,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1492, 1492, 1492, 1340, 1123, 1229, 1123, 1123, 1123, 1340,
- /* 10 */ 1340, 1340, 1123, 1259, 1259, 1391, 1154, 1123, 1123, 1123,
- /* 20 */ 1123, 1123, 1123, 1123, 1339, 1123, 1123, 1123, 1123, 1123,
- /* 30 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1265, 1123,
- /* 40 */ 1123, 1123, 1123, 1123, 1341, 1342, 1123, 1123, 1123, 1390,
- /* 50 */ 1392, 1275, 1274, 1273, 1272, 1373, 1246, 1270, 1263, 1267,
- /* 60 */ 1335, 1336, 1334, 1338, 1342, 1341, 1123, 1266, 1306, 1320,
- /* 70 */ 1305, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 80 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 90 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 100 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 110 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1314, 1319, 1325,
- /* 120 */ 1318, 1315, 1308, 1307, 1309, 1310, 1123, 1144, 1193, 1123,
- /* 130 */ 1123, 1123, 1123, 1409, 1408, 1123, 1123, 1154, 1311, 1312,
- /* 140 */ 1322, 1321, 1398, 1448, 1447, 1123, 1123, 1123, 1123, 1123,
- /* 150 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 160 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 170 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1154, 1150, 1300,
- /* 180 */ 1299, 1418, 1150, 1253, 1123, 1404, 1229, 1220, 1123, 1123,
- /* 190 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 200 */ 1123, 1395, 1393, 1123, 1355, 1123, 1123, 1123, 1123, 1123,
- /* 210 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 220 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 230 */ 1123, 1123, 1225, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 240 */ 1123, 1123, 1123, 1442, 1123, 1368, 1207, 1225, 1225, 1225,
- /* 250 */ 1225, 1227, 1208, 1206, 1219, 1154, 1130, 1484, 1269, 1248,
- /* 260 */ 1248, 1481, 1269, 1269, 1481, 1168, 1462, 1165, 1259, 1259,
- /* 270 */ 1259, 1248, 1337, 1226, 1219, 1123, 1484, 1234, 1234, 1483,
- /* 280 */ 1483, 1234, 1278, 1284, 1196, 1269, 1202, 1202, 1202, 1202,
- /* 290 */ 1234, 1141, 1269, 1269, 1278, 1284, 1196, 1196, 1269, 1234,
- /* 300 */ 1141, 1372, 1478, 1234, 1141, 1348, 1234, 1141, 1234, 1141,
- /* 310 */ 1348, 1194, 1194, 1194, 1183, 1348, 1194, 1168, 1194, 1183,
- /* 320 */ 1194, 1194, 1348, 1352, 1352, 1348, 1252, 1247, 1252, 1247,
- /* 330 */ 1252, 1247, 1252, 1247, 1234, 1253, 1417, 1123, 1264, 1253,
- /* 340 */ 1343, 1234, 1123, 1264, 1262, 1260, 1269, 1147, 1186, 1445,
- /* 350 */ 1445, 1441, 1441, 1441, 1489, 1489, 1404, 1457, 1154, 1154,
- /* 360 */ 1154, 1154, 1457, 1170, 1170, 1154, 1154, 1154, 1154, 1457,
- /* 370 */ 1123, 1123, 1123, 1123, 1123, 1123, 1452, 1123, 1357, 1238,
- /* 380 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 390 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 400 */ 1123, 1123, 1289, 1123, 1126, 1401, 1123, 1123, 1399, 1123,
- /* 410 */ 1123, 1123, 1123, 1123, 1123, 1239, 1123, 1123, 1123, 1123,
- /* 420 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 430 */ 1123, 1123, 1123, 1123, 1480, 1123, 1123, 1123, 1123, 1123,
- /* 440 */ 1123, 1371, 1370, 1123, 1123, 1236, 1123, 1123, 1123, 1123,
- /* 450 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 460 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 470 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 480 */ 1123, 1123, 1123, 1261, 1123, 1416, 1123, 1123, 1123, 1123,
- /* 490 */ 1123, 1123, 1123, 1430, 1254, 1123, 1123, 1471, 1123, 1123,
- /* 500 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123,
- /* 510 */ 1123, 1123, 1466, 1210, 1291, 1123, 1290, 1294, 1123, 1135,
- /* 520 */ 1123,
+ /* 0 */ 1537, 1537, 1537, 1377, 1159, 1266, 1159, 1159, 1159, 1377,
+ /* 10 */ 1377, 1377, 1159, 1296, 1296, 1430, 1190, 1159, 1159, 1159,
+ /* 20 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1376, 1159, 1159,
+ /* 30 */ 1159, 1159, 1460, 1460, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 40 */ 1159, 1159, 1159, 1302, 1159, 1159, 1159, 1159, 1159, 1378,
+ /* 50 */ 1379, 1159, 1159, 1159, 1429, 1431, 1394, 1312, 1311, 1310,
+ /* 60 */ 1309, 1412, 1283, 1307, 1300, 1304, 1372, 1373, 1371, 1375,
+ /* 70 */ 1379, 1378, 1159, 1303, 1343, 1357, 1342, 1159, 1159, 1159,
+ /* 80 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 90 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 100 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 110 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 120 */ 1159, 1159, 1159, 1159, 1351, 1356, 1362, 1355, 1352, 1345,
+ /* 130 */ 1344, 1346, 1347, 1159, 1180, 1230, 1159, 1159, 1159, 1159,
+ /* 140 */ 1448, 1447, 1159, 1159, 1190, 1348, 1349, 1359, 1358, 1437,
+ /* 150 */ 1493, 1492, 1395, 1159, 1159, 1159, 1159, 1159, 1159, 1460,
+ /* 160 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 170 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 180 */ 1159, 1159, 1159, 1159, 1460, 1460, 1159, 1190, 1460, 1460,
+ /* 190 */ 1186, 1337, 1336, 1186, 1290, 1159, 1443, 1266, 1257, 1159,
+ /* 200 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 210 */ 1159, 1159, 1159, 1434, 1432, 1159, 1159, 1159, 1159, 1159,
+ /* 220 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 230 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 240 */ 1159, 1159, 1159, 1262, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 250 */ 1159, 1159, 1159, 1159, 1159, 1487, 1159, 1407, 1244, 1262,
+ /* 260 */ 1262, 1262, 1262, 1264, 1245, 1243, 1256, 1191, 1166, 1529,
+ /* 270 */ 1306, 1285, 1285, 1526, 1306, 1306, 1526, 1205, 1507, 1202,
+ /* 280 */ 1296, 1296, 1296, 1285, 1290, 1290, 1374, 1263, 1256, 1159,
+ /* 290 */ 1529, 1271, 1271, 1528, 1528, 1271, 1395, 1315, 1321, 1233,
+ /* 300 */ 1306, 1239, 1239, 1239, 1239, 1271, 1177, 1306, 1306, 1315,
+ /* 310 */ 1321, 1233, 1233, 1306, 1271, 1177, 1411, 1523, 1271, 1177,
+ /* 320 */ 1385, 1271, 1177, 1271, 1177, 1385, 1231, 1231, 1231, 1220,
+ /* 330 */ 1385, 1231, 1205, 1231, 1220, 1231, 1231, 1385, 1389, 1389,
+ /* 340 */ 1385, 1289, 1284, 1289, 1284, 1289, 1284, 1289, 1284, 1271,
+ /* 350 */ 1470, 1470, 1301, 1290, 1380, 1271, 1159, 1301, 1299, 1297,
+ /* 360 */ 1306, 1183, 1223, 1490, 1490, 1486, 1486, 1486, 1534, 1534,
+ /* 370 */ 1443, 1502, 1190, 1190, 1190, 1190, 1502, 1207, 1207, 1191,
+ /* 380 */ 1191, 1190, 1502, 1159, 1159, 1159, 1159, 1159, 1159, 1497,
+ /* 390 */ 1159, 1396, 1275, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 400 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 410 */ 1159, 1159, 1159, 1159, 1159, 1326, 1159, 1162, 1440, 1159,
+ /* 420 */ 1159, 1438, 1159, 1159, 1159, 1159, 1159, 1159, 1276, 1159,
+ /* 430 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 440 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1525, 1159, 1159,
+ /* 450 */ 1159, 1159, 1159, 1159, 1410, 1409, 1159, 1159, 1273, 1159,
+ /* 460 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 470 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 480 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 490 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1298, 1159, 1159,
+ /* 500 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 510 */ 1159, 1159, 1475, 1291, 1159, 1159, 1516, 1159, 1159, 1159,
+ /* 520 */ 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159, 1159,
+ /* 530 */ 1159, 1511, 1247, 1328, 1159, 1327, 1331, 1159, 1171, 1159,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -146935,6 +149758,10 @@ static const YYCODETYPE yyFallback[] = {
59, /* PRECEDING => ID */
59, /* RANGE => ID */
59, /* UNBOUNDED => ID */
+ 59, /* EXCLUDE => ID */
+ 59, /* GROUPS => ID */
+ 59, /* OTHERS => ID */
+ 59, /* TIES => ID */
59, /* REINDEX => ID */
59, /* RENAME => ID */
59, /* CTIME_KW => ID */
@@ -147113,195 +149940,220 @@ static const char *const yyTokenName[] = {
/* 85 */ "PRECEDING",
/* 86 */ "RANGE",
/* 87 */ "UNBOUNDED",
- /* 88 */ "REINDEX",
- /* 89 */ "RENAME",
- /* 90 */ "CTIME_KW",
- /* 91 */ "ANY",
- /* 92 */ "BITAND",
- /* 93 */ "BITOR",
- /* 94 */ "LSHIFT",
- /* 95 */ "RSHIFT",
- /* 96 */ "PLUS",
- /* 97 */ "MINUS",
- /* 98 */ "STAR",
- /* 99 */ "SLASH",
- /* 100 */ "REM",
- /* 101 */ "CONCAT",
- /* 102 */ "COLLATE",
- /* 103 */ "BITNOT",
- /* 104 */ "ON",
- /* 105 */ "INDEXED",
- /* 106 */ "STRING",
- /* 107 */ "JOIN_KW",
- /* 108 */ "CONSTRAINT",
- /* 109 */ "DEFAULT",
- /* 110 */ "NULL",
- /* 111 */ "PRIMARY",
- /* 112 */ "UNIQUE",
- /* 113 */ "CHECK",
- /* 114 */ "REFERENCES",
- /* 115 */ "AUTOINCR",
- /* 116 */ "INSERT",
- /* 117 */ "DELETE",
- /* 118 */ "UPDATE",
- /* 119 */ "SET",
- /* 120 */ "DEFERRABLE",
- /* 121 */ "FOREIGN",
- /* 122 */ "DROP",
- /* 123 */ "UNION",
- /* 124 */ "ALL",
- /* 125 */ "EXCEPT",
- /* 126 */ "INTERSECT",
- /* 127 */ "SELECT",
- /* 128 */ "VALUES",
- /* 129 */ "DISTINCT",
- /* 130 */ "DOT",
- /* 131 */ "FROM",
- /* 132 */ "JOIN",
- /* 133 */ "USING",
- /* 134 */ "ORDER",
- /* 135 */ "GROUP",
- /* 136 */ "HAVING",
- /* 137 */ "LIMIT",
- /* 138 */ "WHERE",
- /* 139 */ "INTO",
- /* 140 */ "NOTHING",
- /* 141 */ "FLOAT",
- /* 142 */ "BLOB",
- /* 143 */ "INTEGER",
- /* 144 */ "VARIABLE",
- /* 145 */ "CASE",
- /* 146 */ "WHEN",
- /* 147 */ "THEN",
- /* 148 */ "ELSE",
- /* 149 */ "INDEX",
- /* 150 */ "ALTER",
- /* 151 */ "ADD",
- /* 152 */ "WINDOW",
- /* 153 */ "OVER",
- /* 154 */ "FILTER",
- /* 155 */ "input",
- /* 156 */ "cmdlist",
- /* 157 */ "ecmd",
- /* 158 */ "cmdx",
- /* 159 */ "explain",
- /* 160 */ "cmd",
- /* 161 */ "transtype",
- /* 162 */ "trans_opt",
- /* 163 */ "nm",
- /* 164 */ "savepoint_opt",
- /* 165 */ "create_table",
- /* 166 */ "create_table_args",
- /* 167 */ "createkw",
- /* 168 */ "temp",
- /* 169 */ "ifnotexists",
- /* 170 */ "dbnm",
- /* 171 */ "columnlist",
- /* 172 */ "conslist_opt",
- /* 173 */ "table_options",
- /* 174 */ "select",
- /* 175 */ "columnname",
- /* 176 */ "carglist",
- /* 177 */ "typetoken",
- /* 178 */ "typename",
- /* 179 */ "signed",
- /* 180 */ "plus_num",
- /* 181 */ "minus_num",
- /* 182 */ "scanpt",
- /* 183 */ "ccons",
- /* 184 */ "term",
- /* 185 */ "expr",
- /* 186 */ "onconf",
- /* 187 */ "sortorder",
- /* 188 */ "autoinc",
- /* 189 */ "eidlist_opt",
- /* 190 */ "refargs",
- /* 191 */ "defer_subclause",
- /* 192 */ "refarg",
- /* 193 */ "refact",
- /* 194 */ "init_deferred_pred_opt",
- /* 195 */ "conslist",
- /* 196 */ "tconscomma",
- /* 197 */ "tcons",
- /* 198 */ "sortlist",
- /* 199 */ "eidlist",
- /* 200 */ "defer_subclause_opt",
- /* 201 */ "orconf",
- /* 202 */ "resolvetype",
- /* 203 */ "raisetype",
- /* 204 */ "ifexists",
- /* 205 */ "fullname",
- /* 206 */ "selectnowith",
- /* 207 */ "oneselect",
- /* 208 */ "wqlist",
- /* 209 */ "multiselect_op",
- /* 210 */ "distinct",
- /* 211 */ "selcollist",
- /* 212 */ "from",
- /* 213 */ "where_opt",
- /* 214 */ "groupby_opt",
- /* 215 */ "having_opt",
- /* 216 */ "orderby_opt",
- /* 217 */ "limit_opt",
- /* 218 */ "window_clause",
- /* 219 */ "values",
- /* 220 */ "nexprlist",
- /* 221 */ "sclp",
- /* 222 */ "as",
- /* 223 */ "seltablist",
- /* 224 */ "stl_prefix",
- /* 225 */ "joinop",
- /* 226 */ "indexed_opt",
- /* 227 */ "on_opt",
- /* 228 */ "using_opt",
- /* 229 */ "exprlist",
- /* 230 */ "xfullname",
- /* 231 */ "idlist",
- /* 232 */ "with",
- /* 233 */ "setlist",
- /* 234 */ "insert_cmd",
- /* 235 */ "idlist_opt",
- /* 236 */ "upsert",
- /* 237 */ "over_clause",
- /* 238 */ "likeop",
- /* 239 */ "between_op",
- /* 240 */ "in_op",
- /* 241 */ "paren_exprlist",
- /* 242 */ "case_operand",
- /* 243 */ "case_exprlist",
- /* 244 */ "case_else",
- /* 245 */ "uniqueflag",
- /* 246 */ "collate",
- /* 247 */ "nmnum",
- /* 248 */ "trigger_decl",
- /* 249 */ "trigger_cmd_list",
- /* 250 */ "trigger_time",
- /* 251 */ "trigger_event",
- /* 252 */ "foreach_clause",
- /* 253 */ "when_clause",
- /* 254 */ "trigger_cmd",
- /* 255 */ "trnm",
- /* 256 */ "tridxby",
- /* 257 */ "database_kw_opt",
- /* 258 */ "key_opt",
- /* 259 */ "add_column_fullname",
- /* 260 */ "kwcolumn_opt",
- /* 261 */ "create_vtab",
- /* 262 */ "vtabarglist",
- /* 263 */ "vtabarg",
- /* 264 */ "vtabargtoken",
- /* 265 */ "lp",
- /* 266 */ "anylist",
- /* 267 */ "windowdefn_list",
- /* 268 */ "windowdefn",
- /* 269 */ "window",
- /* 270 */ "frame_opt",
- /* 271 */ "part_opt",
- /* 272 */ "filter_opt",
- /* 273 */ "range_or_rows",
- /* 274 */ "frame_bound",
- /* 275 */ "frame_bound_s",
- /* 276 */ "frame_bound_e",
+ /* 88 */ "EXCLUDE",
+ /* 89 */ "GROUPS",
+ /* 90 */ "OTHERS",
+ /* 91 */ "TIES",
+ /* 92 */ "REINDEX",
+ /* 93 */ "RENAME",
+ /* 94 */ "CTIME_KW",
+ /* 95 */ "ANY",
+ /* 96 */ "BITAND",
+ /* 97 */ "BITOR",
+ /* 98 */ "LSHIFT",
+ /* 99 */ "RSHIFT",
+ /* 100 */ "PLUS",
+ /* 101 */ "MINUS",
+ /* 102 */ "STAR",
+ /* 103 */ "SLASH",
+ /* 104 */ "REM",
+ /* 105 */ "CONCAT",
+ /* 106 */ "COLLATE",
+ /* 107 */ "BITNOT",
+ /* 108 */ "ON",
+ /* 109 */ "INDEXED",
+ /* 110 */ "STRING",
+ /* 111 */ "JOIN_KW",
+ /* 112 */ "CONSTRAINT",
+ /* 113 */ "DEFAULT",
+ /* 114 */ "NULL",
+ /* 115 */ "PRIMARY",
+ /* 116 */ "UNIQUE",
+ /* 117 */ "CHECK",
+ /* 118 */ "REFERENCES",
+ /* 119 */ "AUTOINCR",
+ /* 120 */ "INSERT",
+ /* 121 */ "DELETE",
+ /* 122 */ "UPDATE",
+ /* 123 */ "SET",
+ /* 124 */ "DEFERRABLE",
+ /* 125 */ "FOREIGN",
+ /* 126 */ "DROP",
+ /* 127 */ "UNION",
+ /* 128 */ "ALL",
+ /* 129 */ "EXCEPT",
+ /* 130 */ "INTERSECT",
+ /* 131 */ "SELECT",
+ /* 132 */ "VALUES",
+ /* 133 */ "DISTINCT",
+ /* 134 */ "DOT",
+ /* 135 */ "FROM",
+ /* 136 */ "JOIN",
+ /* 137 */ "USING",
+ /* 138 */ "ORDER",
+ /* 139 */ "GROUP",
+ /* 140 */ "HAVING",
+ /* 141 */ "LIMIT",
+ /* 142 */ "WHERE",
+ /* 143 */ "INTO",
+ /* 144 */ "NOTHING",
+ /* 145 */ "FLOAT",
+ /* 146 */ "BLOB",
+ /* 147 */ "INTEGER",
+ /* 148 */ "VARIABLE",
+ /* 149 */ "CASE",
+ /* 150 */ "WHEN",
+ /* 151 */ "THEN",
+ /* 152 */ "ELSE",
+ /* 153 */ "INDEX",
+ /* 154 */ "ALTER",
+ /* 155 */ "ADD",
+ /* 156 */ "WINDOW",
+ /* 157 */ "OVER",
+ /* 158 */ "FILTER",
+ /* 159 */ "TRUEFALSE",
+ /* 160 */ "ISNOT",
+ /* 161 */ "FUNCTION",
+ /* 162 */ "COLUMN",
+ /* 163 */ "AGG_FUNCTION",
+ /* 164 */ "AGG_COLUMN",
+ /* 165 */ "UMINUS",
+ /* 166 */ "UPLUS",
+ /* 167 */ "TRUTH",
+ /* 168 */ "REGISTER",
+ /* 169 */ "VECTOR",
+ /* 170 */ "SELECT_COLUMN",
+ /* 171 */ "IF_NULL_ROW",
+ /* 172 */ "ASTERISK",
+ /* 173 */ "SPAN",
+ /* 174 */ "SPACE",
+ /* 175 */ "ILLEGAL",
+ /* 176 */ "input",
+ /* 177 */ "cmdlist",
+ /* 178 */ "ecmd",
+ /* 179 */ "cmdx",
+ /* 180 */ "explain",
+ /* 181 */ "cmd",
+ /* 182 */ "transtype",
+ /* 183 */ "trans_opt",
+ /* 184 */ "nm",
+ /* 185 */ "savepoint_opt",
+ /* 186 */ "create_table",
+ /* 187 */ "create_table_args",
+ /* 188 */ "createkw",
+ /* 189 */ "temp",
+ /* 190 */ "ifnotexists",
+ /* 191 */ "dbnm",
+ /* 192 */ "columnlist",
+ /* 193 */ "conslist_opt",
+ /* 194 */ "table_options",
+ /* 195 */ "select",
+ /* 196 */ "columnname",
+ /* 197 */ "carglist",
+ /* 198 */ "typetoken",
+ /* 199 */ "typename",
+ /* 200 */ "signed",
+ /* 201 */ "plus_num",
+ /* 202 */ "minus_num",
+ /* 203 */ "scanpt",
+ /* 204 */ "scantok",
+ /* 205 */ "ccons",
+ /* 206 */ "term",
+ /* 207 */ "expr",
+ /* 208 */ "onconf",
+ /* 209 */ "sortorder",
+ /* 210 */ "autoinc",
+ /* 211 */ "eidlist_opt",
+ /* 212 */ "refargs",
+ /* 213 */ "defer_subclause",
+ /* 214 */ "refarg",
+ /* 215 */ "refact",
+ /* 216 */ "init_deferred_pred_opt",
+ /* 217 */ "conslist",
+ /* 218 */ "tconscomma",
+ /* 219 */ "tcons",
+ /* 220 */ "sortlist",
+ /* 221 */ "eidlist",
+ /* 222 */ "defer_subclause_opt",
+ /* 223 */ "orconf",
+ /* 224 */ "resolvetype",
+ /* 225 */ "raisetype",
+ /* 226 */ "ifexists",
+ /* 227 */ "fullname",
+ /* 228 */ "selectnowith",
+ /* 229 */ "oneselect",
+ /* 230 */ "wqlist",
+ /* 231 */ "multiselect_op",
+ /* 232 */ "distinct",
+ /* 233 */ "selcollist",
+ /* 234 */ "from",
+ /* 235 */ "where_opt",
+ /* 236 */ "groupby_opt",
+ /* 237 */ "having_opt",
+ /* 238 */ "orderby_opt",
+ /* 239 */ "limit_opt",
+ /* 240 */ "window_clause",
+ /* 241 */ "values",
+ /* 242 */ "nexprlist",
+ /* 243 */ "sclp",
+ /* 244 */ "as",
+ /* 245 */ "seltablist",
+ /* 246 */ "stl_prefix",
+ /* 247 */ "joinop",
+ /* 248 */ "indexed_opt",
+ /* 249 */ "on_opt",
+ /* 250 */ "using_opt",
+ /* 251 */ "exprlist",
+ /* 252 */ "xfullname",
+ /* 253 */ "idlist",
+ /* 254 */ "with",
+ /* 255 */ "setlist",
+ /* 256 */ "insert_cmd",
+ /* 257 */ "idlist_opt",
+ /* 258 */ "upsert",
+ /* 259 */ "over_clause",
+ /* 260 */ "likeop",
+ /* 261 */ "between_op",
+ /* 262 */ "in_op",
+ /* 263 */ "paren_exprlist",
+ /* 264 */ "case_operand",
+ /* 265 */ "case_exprlist",
+ /* 266 */ "case_else",
+ /* 267 */ "uniqueflag",
+ /* 268 */ "collate",
+ /* 269 */ "vinto",
+ /* 270 */ "nmnum",
+ /* 271 */ "trigger_decl",
+ /* 272 */ "trigger_cmd_list",
+ /* 273 */ "trigger_time",
+ /* 274 */ "trigger_event",
+ /* 275 */ "foreach_clause",
+ /* 276 */ "when_clause",
+ /* 277 */ "trigger_cmd",
+ /* 278 */ "trnm",
+ /* 279 */ "tridxby",
+ /* 280 */ "database_kw_opt",
+ /* 281 */ "key_opt",
+ /* 282 */ "add_column_fullname",
+ /* 283 */ "kwcolumn_opt",
+ /* 284 */ "create_vtab",
+ /* 285 */ "vtabarglist",
+ /* 286 */ "vtabarg",
+ /* 287 */ "vtabargtoken",
+ /* 288 */ "lp",
+ /* 289 */ "anylist",
+ /* 290 */ "windowdefn_list",
+ /* 291 */ "windowdefn",
+ /* 292 */ "window",
+ /* 293 */ "frame_opt",
+ /* 294 */ "part_opt",
+ /* 295 */ "filter_opt",
+ /* 296 */ "range_or_rows",
+ /* 297 */ "frame_bound",
+ /* 298 */ "frame_bound_s",
+ /* 299 */ "frame_bound_e",
+ /* 300 */ "frame_exclude_opt",
+ /* 301 */ "frame_exclude",
};
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
@@ -147338,344 +150190,353 @@ static const char *const yyRuleName[] = {
/* 26 */ "typetoken ::= typename LP signed COMMA signed RP",
/* 27 */ "typename ::= typename ID|STRING",
/* 28 */ "scanpt ::=",
- /* 29 */ "ccons ::= CONSTRAINT nm",
- /* 30 */ "ccons ::= DEFAULT scanpt term scanpt",
- /* 31 */ "ccons ::= DEFAULT LP expr RP",
- /* 32 */ "ccons ::= DEFAULT PLUS term scanpt",
- /* 33 */ "ccons ::= DEFAULT MINUS term scanpt",
- /* 34 */ "ccons ::= DEFAULT scanpt ID|INDEXED",
- /* 35 */ "ccons ::= NOT NULL onconf",
- /* 36 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 37 */ "ccons ::= UNIQUE onconf",
- /* 38 */ "ccons ::= CHECK LP expr RP",
- /* 39 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
- /* 40 */ "ccons ::= defer_subclause",
- /* 41 */ "ccons ::= COLLATE ID|STRING",
- /* 42 */ "autoinc ::=",
- /* 43 */ "autoinc ::= AUTOINCR",
- /* 44 */ "refargs ::=",
- /* 45 */ "refargs ::= refargs refarg",
- /* 46 */ "refarg ::= MATCH nm",
- /* 47 */ "refarg ::= ON INSERT refact",
- /* 48 */ "refarg ::= ON DELETE refact",
- /* 49 */ "refarg ::= ON UPDATE refact",
- /* 50 */ "refact ::= SET NULL",
- /* 51 */ "refact ::= SET DEFAULT",
- /* 52 */ "refact ::= CASCADE",
- /* 53 */ "refact ::= RESTRICT",
- /* 54 */ "refact ::= NO ACTION",
- /* 55 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 56 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 57 */ "init_deferred_pred_opt ::=",
- /* 58 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 59 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 60 */ "conslist_opt ::=",
- /* 61 */ "tconscomma ::= COMMA",
- /* 62 */ "tcons ::= CONSTRAINT nm",
- /* 63 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
- /* 64 */ "tcons ::= UNIQUE LP sortlist RP onconf",
- /* 65 */ "tcons ::= CHECK LP expr RP onconf",
- /* 66 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
- /* 67 */ "defer_subclause_opt ::=",
- /* 68 */ "onconf ::=",
- /* 69 */ "onconf ::= ON CONFLICT resolvetype",
- /* 70 */ "orconf ::=",
- /* 71 */ "orconf ::= OR resolvetype",
- /* 72 */ "resolvetype ::= IGNORE",
- /* 73 */ "resolvetype ::= REPLACE",
- /* 74 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 75 */ "ifexists ::= IF EXISTS",
- /* 76 */ "ifexists ::=",
- /* 77 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
- /* 78 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 79 */ "cmd ::= select",
- /* 80 */ "select ::= WITH wqlist selectnowith",
- /* 81 */ "select ::= WITH RECURSIVE wqlist selectnowith",
- /* 82 */ "select ::= selectnowith",
- /* 83 */ "selectnowith ::= selectnowith multiselect_op oneselect",
- /* 84 */ "multiselect_op ::= UNION",
- /* 85 */ "multiselect_op ::= UNION ALL",
- /* 86 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 87 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
- /* 89 */ "values ::= VALUES LP nexprlist RP",
- /* 90 */ "values ::= values COMMA LP nexprlist RP",
- /* 91 */ "distinct ::= DISTINCT",
- /* 92 */ "distinct ::= ALL",
- /* 93 */ "distinct ::=",
- /* 94 */ "sclp ::=",
- /* 95 */ "selcollist ::= sclp scanpt expr scanpt as",
- /* 96 */ "selcollist ::= sclp scanpt STAR",
- /* 97 */ "selcollist ::= sclp scanpt nm DOT STAR",
- /* 98 */ "as ::= AS nm",
- /* 99 */ "as ::=",
- /* 100 */ "from ::=",
- /* 101 */ "from ::= FROM seltablist",
- /* 102 */ "stl_prefix ::= seltablist joinop",
- /* 103 */ "stl_prefix ::=",
- /* 104 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 105 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
- /* 106 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 107 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 108 */ "dbnm ::=",
- /* 109 */ "dbnm ::= DOT nm",
- /* 110 */ "fullname ::= nm",
- /* 111 */ "fullname ::= nm DOT nm",
- /* 112 */ "xfullname ::= nm",
- /* 113 */ "xfullname ::= nm DOT nm",
- /* 114 */ "xfullname ::= nm DOT nm AS nm",
- /* 115 */ "xfullname ::= nm AS nm",
- /* 116 */ "joinop ::= COMMA|JOIN",
- /* 117 */ "joinop ::= JOIN_KW JOIN",
- /* 118 */ "joinop ::= JOIN_KW nm JOIN",
- /* 119 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 120 */ "on_opt ::= ON expr",
- /* 121 */ "on_opt ::=",
- /* 122 */ "indexed_opt ::=",
- /* 123 */ "indexed_opt ::= INDEXED BY nm",
- /* 124 */ "indexed_opt ::= NOT INDEXED",
- /* 125 */ "using_opt ::= USING LP idlist RP",
- /* 126 */ "using_opt ::=",
- /* 127 */ "orderby_opt ::=",
- /* 128 */ "orderby_opt ::= ORDER BY sortlist",
- /* 129 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 130 */ "sortlist ::= expr sortorder",
- /* 131 */ "sortorder ::= ASC",
- /* 132 */ "sortorder ::= DESC",
- /* 133 */ "sortorder ::=",
- /* 134 */ "groupby_opt ::=",
- /* 135 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 136 */ "having_opt ::=",
- /* 137 */ "having_opt ::= HAVING expr",
- /* 138 */ "limit_opt ::=",
- /* 139 */ "limit_opt ::= LIMIT expr",
- /* 140 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 141 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 142 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt",
- /* 143 */ "where_opt ::=",
- /* 144 */ "where_opt ::= WHERE expr",
- /* 145 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt",
- /* 146 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 147 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
- /* 148 */ "setlist ::= nm EQ expr",
- /* 149 */ "setlist ::= LP idlist RP EQ expr",
- /* 150 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
- /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES",
- /* 152 */ "upsert ::=",
- /* 153 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt",
- /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING",
- /* 155 */ "upsert ::= ON CONFLICT DO NOTHING",
- /* 156 */ "insert_cmd ::= INSERT orconf",
- /* 157 */ "insert_cmd ::= REPLACE",
- /* 158 */ "idlist_opt ::=",
- /* 159 */ "idlist_opt ::= LP idlist RP",
- /* 160 */ "idlist ::= idlist COMMA nm",
- /* 161 */ "idlist ::= nm",
- /* 162 */ "expr ::= LP expr RP",
- /* 163 */ "expr ::= ID|INDEXED",
- /* 164 */ "expr ::= JOIN_KW",
- /* 165 */ "expr ::= nm DOT nm",
- /* 166 */ "expr ::= nm DOT nm DOT nm",
- /* 167 */ "term ::= NULL|FLOAT|BLOB",
- /* 168 */ "term ::= STRING",
- /* 169 */ "term ::= INTEGER",
- /* 170 */ "expr ::= VARIABLE",
- /* 171 */ "expr ::= expr COLLATE ID|STRING",
- /* 172 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 173 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
- /* 174 */ "expr ::= ID|INDEXED LP STAR RP",
- /* 175 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause",
- /* 176 */ "expr ::= ID|INDEXED LP STAR RP over_clause",
- /* 177 */ "term ::= CTIME_KW",
- /* 178 */ "expr ::= LP nexprlist COMMA expr RP",
- /* 179 */ "expr ::= expr AND expr",
- /* 180 */ "expr ::= expr OR expr",
- /* 181 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 182 */ "expr ::= expr EQ|NE expr",
- /* 183 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 184 */ "expr ::= expr PLUS|MINUS expr",
- /* 185 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 186 */ "expr ::= expr CONCAT expr",
- /* 187 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 188 */ "expr ::= expr likeop expr",
- /* 189 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 190 */ "expr ::= expr ISNULL|NOTNULL",
- /* 191 */ "expr ::= expr NOT NULL",
- /* 192 */ "expr ::= expr IS expr",
- /* 193 */ "expr ::= expr IS NOT expr",
- /* 194 */ "expr ::= NOT expr",
- /* 195 */ "expr ::= BITNOT expr",
- /* 196 */ "expr ::= PLUS|MINUS expr",
- /* 197 */ "between_op ::= BETWEEN",
- /* 198 */ "between_op ::= NOT BETWEEN",
- /* 199 */ "expr ::= expr between_op expr AND expr",
- /* 200 */ "in_op ::= IN",
- /* 201 */ "in_op ::= NOT IN",
- /* 202 */ "expr ::= expr in_op LP exprlist RP",
- /* 203 */ "expr ::= LP select RP",
- /* 204 */ "expr ::= expr in_op LP select RP",
- /* 205 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 206 */ "expr ::= EXISTS LP select RP",
- /* 207 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 208 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 209 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 210 */ "case_else ::= ELSE expr",
- /* 211 */ "case_else ::=",
- /* 212 */ "case_operand ::= expr",
- /* 213 */ "case_operand ::=",
- /* 214 */ "exprlist ::=",
- /* 215 */ "nexprlist ::= nexprlist COMMA expr",
- /* 216 */ "nexprlist ::= expr",
- /* 217 */ "paren_exprlist ::=",
- /* 218 */ "paren_exprlist ::= LP exprlist RP",
- /* 219 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 220 */ "uniqueflag ::= UNIQUE",
- /* 221 */ "uniqueflag ::=",
- /* 222 */ "eidlist_opt ::=",
- /* 223 */ "eidlist_opt ::= LP eidlist RP",
- /* 224 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 225 */ "eidlist ::= nm collate sortorder",
- /* 226 */ "collate ::=",
- /* 227 */ "collate ::= COLLATE ID|STRING",
- /* 228 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 229 */ "cmd ::= VACUUM",
- /* 230 */ "cmd ::= VACUUM nm",
- /* 231 */ "cmd ::= PRAGMA nm dbnm",
- /* 232 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 233 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 234 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 235 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 236 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 237 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 238 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 239 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 240 */ "trigger_time ::= BEFORE|AFTER",
- /* 241 */ "trigger_time ::= INSTEAD OF",
- /* 242 */ "trigger_time ::=",
- /* 243 */ "trigger_event ::= DELETE|INSERT",
- /* 244 */ "trigger_event ::= UPDATE",
- /* 245 */ "trigger_event ::= UPDATE OF idlist",
- /* 246 */ "when_clause ::=",
- /* 247 */ "when_clause ::= WHEN expr",
- /* 248 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 249 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 250 */ "trnm ::= nm DOT nm",
- /* 251 */ "tridxby ::= INDEXED BY nm",
- /* 252 */ "tridxby ::= NOT INDEXED",
- /* 253 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
- /* 254 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
- /* 255 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
- /* 256 */ "trigger_cmd ::= scanpt select scanpt",
- /* 257 */ "expr ::= RAISE LP IGNORE RP",
- /* 258 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 259 */ "raisetype ::= ROLLBACK",
- /* 260 */ "raisetype ::= ABORT",
- /* 261 */ "raisetype ::= FAIL",
- /* 262 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 263 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 264 */ "cmd ::= DETACH database_kw_opt expr",
- /* 265 */ "key_opt ::=",
- /* 266 */ "key_opt ::= KEY expr",
- /* 267 */ "cmd ::= REINDEX",
- /* 268 */ "cmd ::= REINDEX nm dbnm",
- /* 269 */ "cmd ::= ANALYZE",
- /* 270 */ "cmd ::= ANALYZE nm dbnm",
- /* 271 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 272 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 273 */ "add_column_fullname ::= fullname",
- /* 274 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
- /* 275 */ "cmd ::= create_vtab",
- /* 276 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 277 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 278 */ "vtabarg ::=",
- /* 279 */ "vtabargtoken ::= ANY",
- /* 280 */ "vtabargtoken ::= lp anylist RP",
- /* 281 */ "lp ::= LP",
- /* 282 */ "with ::= WITH wqlist",
- /* 283 */ "with ::= WITH RECURSIVE wqlist",
- /* 284 */ "wqlist ::= nm eidlist_opt AS LP select RP",
- /* 285 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
- /* 286 */ "windowdefn_list ::= windowdefn",
- /* 287 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
- /* 288 */ "windowdefn ::= nm AS window",
- /* 289 */ "window ::= LP part_opt orderby_opt frame_opt RP",
- /* 290 */ "part_opt ::= PARTITION BY nexprlist",
- /* 291 */ "part_opt ::=",
- /* 292 */ "frame_opt ::=",
- /* 293 */ "frame_opt ::= range_or_rows frame_bound_s",
- /* 294 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e",
- /* 295 */ "range_or_rows ::= RANGE",
- /* 296 */ "range_or_rows ::= ROWS",
- /* 297 */ "frame_bound_s ::= frame_bound",
- /* 298 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
- /* 299 */ "frame_bound_e ::= frame_bound",
- /* 300 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
- /* 301 */ "frame_bound ::= expr PRECEDING",
- /* 302 */ "frame_bound ::= CURRENT ROW",
- /* 303 */ "frame_bound ::= expr FOLLOWING",
- /* 304 */ "window_clause ::= WINDOW windowdefn_list",
- /* 305 */ "over_clause ::= filter_opt OVER window",
- /* 306 */ "over_clause ::= filter_opt OVER nm",
- /* 307 */ "filter_opt ::=",
- /* 308 */ "filter_opt ::= FILTER LP WHERE expr RP",
- /* 309 */ "input ::= cmdlist",
- /* 310 */ "cmdlist ::= cmdlist ecmd",
- /* 311 */ "cmdlist ::= ecmd",
- /* 312 */ "ecmd ::= SEMI",
- /* 313 */ "ecmd ::= cmdx SEMI",
- /* 314 */ "ecmd ::= explain cmdx",
- /* 315 */ "trans_opt ::=",
- /* 316 */ "trans_opt ::= TRANSACTION",
- /* 317 */ "trans_opt ::= TRANSACTION nm",
- /* 318 */ "savepoint_opt ::= SAVEPOINT",
- /* 319 */ "savepoint_opt ::=",
- /* 320 */ "cmd ::= create_table create_table_args",
- /* 321 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 322 */ "columnlist ::= columnname carglist",
- /* 323 */ "nm ::= ID|INDEXED",
- /* 324 */ "nm ::= STRING",
- /* 325 */ "nm ::= JOIN_KW",
- /* 326 */ "typetoken ::= typename",
- /* 327 */ "typename ::= ID|STRING",
- /* 328 */ "signed ::= plus_num",
- /* 329 */ "signed ::= minus_num",
- /* 330 */ "carglist ::= carglist ccons",
- /* 331 */ "carglist ::=",
- /* 332 */ "ccons ::= NULL onconf",
- /* 333 */ "conslist_opt ::= COMMA conslist",
- /* 334 */ "conslist ::= conslist tconscomma tcons",
- /* 335 */ "conslist ::= tcons",
- /* 336 */ "tconscomma ::=",
- /* 337 */ "defer_subclause_opt ::= defer_subclause",
- /* 338 */ "resolvetype ::= raisetype",
- /* 339 */ "selectnowith ::= oneselect",
- /* 340 */ "oneselect ::= values",
- /* 341 */ "sclp ::= selcollist COMMA",
- /* 342 */ "as ::= ID|STRING",
- /* 343 */ "expr ::= term",
- /* 344 */ "likeop ::= LIKE_KW|MATCH",
- /* 345 */ "exprlist ::= nexprlist",
- /* 346 */ "nmnum ::= plus_num",
- /* 347 */ "nmnum ::= nm",
- /* 348 */ "nmnum ::= ON",
- /* 349 */ "nmnum ::= DELETE",
- /* 350 */ "nmnum ::= DEFAULT",
- /* 351 */ "plus_num ::= INTEGER|FLOAT",
- /* 352 */ "foreach_clause ::=",
- /* 353 */ "foreach_clause ::= FOR EACH ROW",
- /* 354 */ "trnm ::= nm",
- /* 355 */ "tridxby ::=",
- /* 356 */ "database_kw_opt ::= DATABASE",
- /* 357 */ "database_kw_opt ::=",
- /* 358 */ "kwcolumn_opt ::=",
- /* 359 */ "kwcolumn_opt ::= COLUMNKW",
- /* 360 */ "vtabarglist ::= vtabarg",
- /* 361 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 362 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 363 */ "anylist ::=",
- /* 364 */ "anylist ::= anylist LP anylist RP",
- /* 365 */ "anylist ::= anylist ANY",
- /* 366 */ "with ::=",
+ /* 29 */ "scantok ::=",
+ /* 30 */ "ccons ::= CONSTRAINT nm",
+ /* 31 */ "ccons ::= DEFAULT scantok term",
+ /* 32 */ "ccons ::= DEFAULT LP expr RP",
+ /* 33 */ "ccons ::= DEFAULT PLUS scantok term",
+ /* 34 */ "ccons ::= DEFAULT MINUS scantok term",
+ /* 35 */ "ccons ::= DEFAULT scantok ID|INDEXED",
+ /* 36 */ "ccons ::= NOT NULL onconf",
+ /* 37 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /* 38 */ "ccons ::= UNIQUE onconf",
+ /* 39 */ "ccons ::= CHECK LP expr RP",
+ /* 40 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
+ /* 41 */ "ccons ::= defer_subclause",
+ /* 42 */ "ccons ::= COLLATE ID|STRING",
+ /* 43 */ "autoinc ::=",
+ /* 44 */ "autoinc ::= AUTOINCR",
+ /* 45 */ "refargs ::=",
+ /* 46 */ "refargs ::= refargs refarg",
+ /* 47 */ "refarg ::= MATCH nm",
+ /* 48 */ "refarg ::= ON INSERT refact",
+ /* 49 */ "refarg ::= ON DELETE refact",
+ /* 50 */ "refarg ::= ON UPDATE refact",
+ /* 51 */ "refact ::= SET NULL",
+ /* 52 */ "refact ::= SET DEFAULT",
+ /* 53 */ "refact ::= CASCADE",
+ /* 54 */ "refact ::= RESTRICT",
+ /* 55 */ "refact ::= NO ACTION",
+ /* 56 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 57 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 58 */ "init_deferred_pred_opt ::=",
+ /* 59 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 60 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 61 */ "conslist_opt ::=",
+ /* 62 */ "tconscomma ::= COMMA",
+ /* 63 */ "tcons ::= CONSTRAINT nm",
+ /* 64 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
+ /* 65 */ "tcons ::= UNIQUE LP sortlist RP onconf",
+ /* 66 */ "tcons ::= CHECK LP expr RP onconf",
+ /* 67 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
+ /* 68 */ "defer_subclause_opt ::=",
+ /* 69 */ "onconf ::=",
+ /* 70 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 71 */ "orconf ::=",
+ /* 72 */ "orconf ::= OR resolvetype",
+ /* 73 */ "resolvetype ::= IGNORE",
+ /* 74 */ "resolvetype ::= REPLACE",
+ /* 75 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 76 */ "ifexists ::= IF EXISTS",
+ /* 77 */ "ifexists ::=",
+ /* 78 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
+ /* 79 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 80 */ "cmd ::= select",
+ /* 81 */ "select ::= WITH wqlist selectnowith",
+ /* 82 */ "select ::= WITH RECURSIVE wqlist selectnowith",
+ /* 83 */ "select ::= selectnowith",
+ /* 84 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+ /* 85 */ "multiselect_op ::= UNION",
+ /* 86 */ "multiselect_op ::= UNION ALL",
+ /* 87 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 89 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt",
+ /* 90 */ "values ::= VALUES LP nexprlist RP",
+ /* 91 */ "values ::= values COMMA LP nexprlist RP",
+ /* 92 */ "distinct ::= DISTINCT",
+ /* 93 */ "distinct ::= ALL",
+ /* 94 */ "distinct ::=",
+ /* 95 */ "sclp ::=",
+ /* 96 */ "selcollist ::= sclp scanpt expr scanpt as",
+ /* 97 */ "selcollist ::= sclp scanpt STAR",
+ /* 98 */ "selcollist ::= sclp scanpt nm DOT STAR",
+ /* 99 */ "as ::= AS nm",
+ /* 100 */ "as ::=",
+ /* 101 */ "from ::=",
+ /* 102 */ "from ::= FROM seltablist",
+ /* 103 */ "stl_prefix ::= seltablist joinop",
+ /* 104 */ "stl_prefix ::=",
+ /* 105 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 106 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+ /* 107 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 108 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 109 */ "dbnm ::=",
+ /* 110 */ "dbnm ::= DOT nm",
+ /* 111 */ "fullname ::= nm",
+ /* 112 */ "fullname ::= nm DOT nm",
+ /* 113 */ "xfullname ::= nm",
+ /* 114 */ "xfullname ::= nm DOT nm",
+ /* 115 */ "xfullname ::= nm DOT nm AS nm",
+ /* 116 */ "xfullname ::= nm AS nm",
+ /* 117 */ "joinop ::= COMMA|JOIN",
+ /* 118 */ "joinop ::= JOIN_KW JOIN",
+ /* 119 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 120 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 121 */ "on_opt ::= ON expr",
+ /* 122 */ "on_opt ::=",
+ /* 123 */ "indexed_opt ::=",
+ /* 124 */ "indexed_opt ::= INDEXED BY nm",
+ /* 125 */ "indexed_opt ::= NOT INDEXED",
+ /* 126 */ "using_opt ::= USING LP idlist RP",
+ /* 127 */ "using_opt ::=",
+ /* 128 */ "orderby_opt ::=",
+ /* 129 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 130 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 131 */ "sortlist ::= expr sortorder",
+ /* 132 */ "sortorder ::= ASC",
+ /* 133 */ "sortorder ::= DESC",
+ /* 134 */ "sortorder ::=",
+ /* 135 */ "groupby_opt ::=",
+ /* 136 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 137 */ "having_opt ::=",
+ /* 138 */ "having_opt ::= HAVING expr",
+ /* 139 */ "limit_opt ::=",
+ /* 140 */ "limit_opt ::= LIMIT expr",
+ /* 141 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 142 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 143 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt",
+ /* 144 */ "where_opt ::=",
+ /* 145 */ "where_opt ::= WHERE expr",
+ /* 146 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt",
+ /* 147 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 148 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+ /* 149 */ "setlist ::= nm EQ expr",
+ /* 150 */ "setlist ::= LP idlist RP EQ expr",
+ /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert",
+ /* 152 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES",
+ /* 153 */ "upsert ::=",
+ /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt",
+ /* 155 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING",
+ /* 156 */ "upsert ::= ON CONFLICT DO NOTHING",
+ /* 157 */ "insert_cmd ::= INSERT orconf",
+ /* 158 */ "insert_cmd ::= REPLACE",
+ /* 159 */ "idlist_opt ::=",
+ /* 160 */ "idlist_opt ::= LP idlist RP",
+ /* 161 */ "idlist ::= idlist COMMA nm",
+ /* 162 */ "idlist ::= nm",
+ /* 163 */ "expr ::= LP expr RP",
+ /* 164 */ "expr ::= ID|INDEXED",
+ /* 165 */ "expr ::= JOIN_KW",
+ /* 166 */ "expr ::= nm DOT nm",
+ /* 167 */ "expr ::= nm DOT nm DOT nm",
+ /* 168 */ "term ::= NULL|FLOAT|BLOB",
+ /* 169 */ "term ::= STRING",
+ /* 170 */ "term ::= INTEGER",
+ /* 171 */ "expr ::= VARIABLE",
+ /* 172 */ "expr ::= expr COLLATE ID|STRING",
+ /* 173 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 174 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 175 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 176 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause",
+ /* 177 */ "expr ::= ID|INDEXED LP STAR RP over_clause",
+ /* 178 */ "term ::= CTIME_KW",
+ /* 179 */ "expr ::= LP nexprlist COMMA expr RP",
+ /* 180 */ "expr ::= expr AND expr",
+ /* 181 */ "expr ::= expr OR expr",
+ /* 182 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 183 */ "expr ::= expr EQ|NE expr",
+ /* 184 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 185 */ "expr ::= expr PLUS|MINUS expr",
+ /* 186 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 187 */ "expr ::= expr CONCAT expr",
+ /* 188 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 189 */ "expr ::= expr likeop expr",
+ /* 190 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 191 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 192 */ "expr ::= expr NOT NULL",
+ /* 193 */ "expr ::= expr IS expr",
+ /* 194 */ "expr ::= expr IS NOT expr",
+ /* 195 */ "expr ::= NOT expr",
+ /* 196 */ "expr ::= BITNOT expr",
+ /* 197 */ "expr ::= PLUS|MINUS expr",
+ /* 198 */ "between_op ::= BETWEEN",
+ /* 199 */ "between_op ::= NOT BETWEEN",
+ /* 200 */ "expr ::= expr between_op expr AND expr",
+ /* 201 */ "in_op ::= IN",
+ /* 202 */ "in_op ::= NOT IN",
+ /* 203 */ "expr ::= expr in_op LP exprlist RP",
+ /* 204 */ "expr ::= LP select RP",
+ /* 205 */ "expr ::= expr in_op LP select RP",
+ /* 206 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 207 */ "expr ::= EXISTS LP select RP",
+ /* 208 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 209 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 210 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 211 */ "case_else ::= ELSE expr",
+ /* 212 */ "case_else ::=",
+ /* 213 */ "case_operand ::= expr",
+ /* 214 */ "case_operand ::=",
+ /* 215 */ "exprlist ::=",
+ /* 216 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 217 */ "nexprlist ::= expr",
+ /* 218 */ "paren_exprlist ::=",
+ /* 219 */ "paren_exprlist ::= LP exprlist RP",
+ /* 220 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 221 */ "uniqueflag ::= UNIQUE",
+ /* 222 */ "uniqueflag ::=",
+ /* 223 */ "eidlist_opt ::=",
+ /* 224 */ "eidlist_opt ::= LP eidlist RP",
+ /* 225 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 226 */ "eidlist ::= nm collate sortorder",
+ /* 227 */ "collate ::=",
+ /* 228 */ "collate ::= COLLATE ID|STRING",
+ /* 229 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 230 */ "cmd ::= VACUUM vinto",
+ /* 231 */ "cmd ::= VACUUM nm vinto",
+ /* 232 */ "vinto ::= INTO expr",
+ /* 233 */ "vinto ::=",
+ /* 234 */ "cmd ::= PRAGMA nm dbnm",
+ /* 235 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 236 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 237 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 238 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 239 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 240 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 241 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 242 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 243 */ "trigger_time ::= BEFORE|AFTER",
+ /* 244 */ "trigger_time ::= INSTEAD OF",
+ /* 245 */ "trigger_time ::=",
+ /* 246 */ "trigger_event ::= DELETE|INSERT",
+ /* 247 */ "trigger_event ::= UPDATE",
+ /* 248 */ "trigger_event ::= UPDATE OF idlist",
+ /* 249 */ "when_clause ::=",
+ /* 250 */ "when_clause ::= WHEN expr",
+ /* 251 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 252 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 253 */ "trnm ::= nm DOT nm",
+ /* 254 */ "tridxby ::= INDEXED BY nm",
+ /* 255 */ "tridxby ::= NOT INDEXED",
+ /* 256 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
+ /* 257 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
+ /* 258 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+ /* 259 */ "trigger_cmd ::= scanpt select scanpt",
+ /* 260 */ "expr ::= RAISE LP IGNORE RP",
+ /* 261 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 262 */ "raisetype ::= ROLLBACK",
+ /* 263 */ "raisetype ::= ABORT",
+ /* 264 */ "raisetype ::= FAIL",
+ /* 265 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 266 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 267 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 268 */ "key_opt ::=",
+ /* 269 */ "key_opt ::= KEY expr",
+ /* 270 */ "cmd ::= REINDEX",
+ /* 271 */ "cmd ::= REINDEX nm dbnm",
+ /* 272 */ "cmd ::= ANALYZE",
+ /* 273 */ "cmd ::= ANALYZE nm dbnm",
+ /* 274 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 275 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 276 */ "add_column_fullname ::= fullname",
+ /* 277 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
+ /* 278 */ "cmd ::= create_vtab",
+ /* 279 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 280 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 281 */ "vtabarg ::=",
+ /* 282 */ "vtabargtoken ::= ANY",
+ /* 283 */ "vtabargtoken ::= lp anylist RP",
+ /* 284 */ "lp ::= LP",
+ /* 285 */ "with ::= WITH wqlist",
+ /* 286 */ "with ::= WITH RECURSIVE wqlist",
+ /* 287 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 288 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 289 */ "windowdefn_list ::= windowdefn",
+ /* 290 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
+ /* 291 */ "windowdefn ::= nm AS LP window RP",
+ /* 292 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 293 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
+ /* 294 */ "window ::= ORDER BY sortlist frame_opt",
+ /* 295 */ "window ::= nm ORDER BY sortlist frame_opt",
+ /* 296 */ "window ::= frame_opt",
+ /* 297 */ "window ::= nm frame_opt",
+ /* 298 */ "frame_opt ::=",
+ /* 299 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
+ /* 300 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
+ /* 301 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
+ /* 302 */ "frame_bound_s ::= frame_bound",
+ /* 303 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
+ /* 304 */ "frame_bound_e ::= frame_bound",
+ /* 305 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
+ /* 306 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
+ /* 307 */ "frame_bound ::= CURRENT ROW",
+ /* 308 */ "frame_exclude_opt ::=",
+ /* 309 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
+ /* 310 */ "frame_exclude ::= NO OTHERS",
+ /* 311 */ "frame_exclude ::= CURRENT ROW",
+ /* 312 */ "frame_exclude ::= GROUP|TIES",
+ /* 313 */ "window_clause ::= WINDOW windowdefn_list",
+ /* 314 */ "over_clause ::= filter_opt OVER LP window RP",
+ /* 315 */ "over_clause ::= filter_opt OVER nm",
+ /* 316 */ "filter_opt ::=",
+ /* 317 */ "filter_opt ::= FILTER LP WHERE expr RP",
+ /* 318 */ "input ::= cmdlist",
+ /* 319 */ "cmdlist ::= cmdlist ecmd",
+ /* 320 */ "cmdlist ::= ecmd",
+ /* 321 */ "ecmd ::= SEMI",
+ /* 322 */ "ecmd ::= cmdx SEMI",
+ /* 323 */ "ecmd ::= explain cmdx",
+ /* 324 */ "trans_opt ::=",
+ /* 325 */ "trans_opt ::= TRANSACTION",
+ /* 326 */ "trans_opt ::= TRANSACTION nm",
+ /* 327 */ "savepoint_opt ::= SAVEPOINT",
+ /* 328 */ "savepoint_opt ::=",
+ /* 329 */ "cmd ::= create_table create_table_args",
+ /* 330 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 331 */ "columnlist ::= columnname carglist",
+ /* 332 */ "nm ::= ID|INDEXED",
+ /* 333 */ "nm ::= STRING",
+ /* 334 */ "nm ::= JOIN_KW",
+ /* 335 */ "typetoken ::= typename",
+ /* 336 */ "typename ::= ID|STRING",
+ /* 337 */ "signed ::= plus_num",
+ /* 338 */ "signed ::= minus_num",
+ /* 339 */ "carglist ::= carglist ccons",
+ /* 340 */ "carglist ::=",
+ /* 341 */ "ccons ::= NULL onconf",
+ /* 342 */ "conslist_opt ::= COMMA conslist",
+ /* 343 */ "conslist ::= conslist tconscomma tcons",
+ /* 344 */ "conslist ::= tcons",
+ /* 345 */ "tconscomma ::=",
+ /* 346 */ "defer_subclause_opt ::= defer_subclause",
+ /* 347 */ "resolvetype ::= raisetype",
+ /* 348 */ "selectnowith ::= oneselect",
+ /* 349 */ "oneselect ::= values",
+ /* 350 */ "sclp ::= selcollist COMMA",
+ /* 351 */ "as ::= ID|STRING",
+ /* 352 */ "expr ::= term",
+ /* 353 */ "likeop ::= LIKE_KW|MATCH",
+ /* 354 */ "exprlist ::= nexprlist",
+ /* 355 */ "nmnum ::= plus_num",
+ /* 356 */ "nmnum ::= nm",
+ /* 357 */ "nmnum ::= ON",
+ /* 358 */ "nmnum ::= DELETE",
+ /* 359 */ "nmnum ::= DEFAULT",
+ /* 360 */ "plus_num ::= INTEGER|FLOAT",
+ /* 361 */ "foreach_clause ::=",
+ /* 362 */ "foreach_clause ::= FOR EACH ROW",
+ /* 363 */ "trnm ::= nm",
+ /* 364 */ "tridxby ::=",
+ /* 365 */ "database_kw_opt ::= DATABASE",
+ /* 366 */ "database_kw_opt ::=",
+ /* 367 */ "kwcolumn_opt ::=",
+ /* 368 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 369 */ "vtabarglist ::= vtabarg",
+ /* 370 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 371 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 372 */ "anylist ::=",
+ /* 373 */ "anylist ::= anylist LP anylist RP",
+ /* 374 */ "anylist ::= anylist ANY",
+ /* 375 */ "with ::=",
};
#endif /* NDEBUG */
@@ -147801,96 +150662,97 @@ static void yy_destructor(
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
- case 174: /* select */
- case 206: /* selectnowith */
- case 207: /* oneselect */
- case 219: /* values */
+ case 195: /* select */
+ case 228: /* selectnowith */
+ case 229: /* oneselect */
+ case 241: /* values */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy489));
+sqlite3SelectDelete(pParse->db, (yypminor->yy391));
}
break;
- case 184: /* term */
- case 185: /* expr */
- case 213: /* where_opt */
- case 215: /* having_opt */
- case 227: /* on_opt */
- case 242: /* case_operand */
- case 244: /* case_else */
- case 253: /* when_clause */
- case 258: /* key_opt */
- case 272: /* filter_opt */
+ case 206: /* term */
+ case 207: /* expr */
+ case 235: /* where_opt */
+ case 237: /* having_opt */
+ case 249: /* on_opt */
+ case 264: /* case_operand */
+ case 266: /* case_else */
+ case 269: /* vinto */
+ case 276: /* when_clause */
+ case 281: /* key_opt */
+ case 295: /* filter_opt */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy18));
+sqlite3ExprDelete(pParse->db, (yypminor->yy102));
}
break;
- case 189: /* eidlist_opt */
- case 198: /* sortlist */
- case 199: /* eidlist */
- case 211: /* selcollist */
- case 214: /* groupby_opt */
- case 216: /* orderby_opt */
- case 220: /* nexprlist */
- case 221: /* sclp */
- case 229: /* exprlist */
- case 233: /* setlist */
- case 241: /* paren_exprlist */
- case 243: /* case_exprlist */
- case 271: /* part_opt */
+ case 211: /* eidlist_opt */
+ case 220: /* sortlist */
+ case 221: /* eidlist */
+ case 233: /* selcollist */
+ case 236: /* groupby_opt */
+ case 238: /* orderby_opt */
+ case 242: /* nexprlist */
+ case 243: /* sclp */
+ case 251: /* exprlist */
+ case 255: /* setlist */
+ case 263: /* paren_exprlist */
+ case 265: /* case_exprlist */
+ case 294: /* part_opt */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy420));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy94));
}
break;
- case 205: /* fullname */
- case 212: /* from */
- case 223: /* seltablist */
- case 224: /* stl_prefix */
- case 230: /* xfullname */
+ case 227: /* fullname */
+ case 234: /* from */
+ case 245: /* seltablist */
+ case 246: /* stl_prefix */
+ case 252: /* xfullname */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy135));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy407));
}
break;
- case 208: /* wqlist */
+ case 230: /* wqlist */
{
-sqlite3WithDelete(pParse->db, (yypminor->yy449));
+sqlite3WithDelete(pParse->db, (yypminor->yy243));
}
break;
- case 218: /* window_clause */
- case 267: /* windowdefn_list */
+ case 240: /* window_clause */
+ case 290: /* windowdefn_list */
{
-sqlite3WindowListDelete(pParse->db, (yypminor->yy327));
+sqlite3WindowListDelete(pParse->db, (yypminor->yy379));
}
break;
- case 228: /* using_opt */
- case 231: /* idlist */
- case 235: /* idlist_opt */
+ case 250: /* using_opt */
+ case 253: /* idlist */
+ case 257: /* idlist_opt */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy48));
+sqlite3IdListDelete(pParse->db, (yypminor->yy76));
}
break;
- case 237: /* over_clause */
- case 268: /* windowdefn */
- case 269: /* window */
- case 270: /* frame_opt */
+ case 259: /* over_clause */
+ case 291: /* windowdefn */
+ case 292: /* window */
+ case 293: /* frame_opt */
{
-sqlite3WindowDelete(pParse->db, (yypminor->yy327));
+sqlite3WindowDelete(pParse->db, (yypminor->yy379));
}
break;
- case 249: /* trigger_cmd_list */
- case 254: /* trigger_cmd */
+ case 272: /* trigger_cmd_list */
+ case 277: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy11));
}
break;
- case 251: /* trigger_event */
+ case 274: /* trigger_event */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy34).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy298).b);
}
break;
- case 274: /* frame_bound */
- case 275: /* frame_bound_s */
- case 276: /* frame_bound_e */
+ case 297: /* frame_bound */
+ case 298: /* frame_bound_s */
+ case 299: /* frame_bound_e */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy389).pExpr);
}
break;
/********* End destructor definitions *****************************************/
@@ -148182,380 +151044,766 @@ static void yy_shift(
yyTraceShift(yypParser, yyNewState, "Shift");
}
-/* The following table contains information about every rule that
-** is used during the reduce.
-*/
-static const struct {
- YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
- signed char nrhs; /* Negative of the number of RHS symbols in the rule */
-} yyRuleInfo[] = {
- { 159, -1 }, /* (0) explain ::= EXPLAIN */
- { 159, -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */
- { 158, -1 }, /* (2) cmdx ::= cmd */
- { 160, -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */
- { 161, 0 }, /* (4) transtype ::= */
- { 161, -1 }, /* (5) transtype ::= DEFERRED */
- { 161, -1 }, /* (6) transtype ::= IMMEDIATE */
- { 161, -1 }, /* (7) transtype ::= EXCLUSIVE */
- { 160, -2 }, /* (8) cmd ::= COMMIT|END trans_opt */
- { 160, -2 }, /* (9) cmd ::= ROLLBACK trans_opt */
- { 160, -2 }, /* (10) cmd ::= SAVEPOINT nm */
- { 160, -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */
- { 160, -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
- { 165, -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
- { 167, -1 }, /* (14) createkw ::= CREATE */
- { 169, 0 }, /* (15) ifnotexists ::= */
- { 169, -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */
- { 168, -1 }, /* (17) temp ::= TEMP */
- { 168, 0 }, /* (18) temp ::= */
- { 166, -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
- { 166, -2 }, /* (20) create_table_args ::= AS select */
- { 173, 0 }, /* (21) table_options ::= */
- { 173, -2 }, /* (22) table_options ::= WITHOUT nm */
- { 175, -2 }, /* (23) columnname ::= nm typetoken */
- { 177, 0 }, /* (24) typetoken ::= */
- { 177, -4 }, /* (25) typetoken ::= typename LP signed RP */
- { 177, -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */
- { 178, -2 }, /* (27) typename ::= typename ID|STRING */
- { 182, 0 }, /* (28) scanpt ::= */
- { 183, -2 }, /* (29) ccons ::= CONSTRAINT nm */
- { 183, -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */
- { 183, -4 }, /* (31) ccons ::= DEFAULT LP expr RP */
- { 183, -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */
- { 183, -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */
- { 183, -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
- { 183, -3 }, /* (35) ccons ::= NOT NULL onconf */
- { 183, -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
- { 183, -2 }, /* (37) ccons ::= UNIQUE onconf */
- { 183, -4 }, /* (38) ccons ::= CHECK LP expr RP */
- { 183, -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
- { 183, -1 }, /* (40) ccons ::= defer_subclause */
- { 183, -2 }, /* (41) ccons ::= COLLATE ID|STRING */
- { 188, 0 }, /* (42) autoinc ::= */
- { 188, -1 }, /* (43) autoinc ::= AUTOINCR */
- { 190, 0 }, /* (44) refargs ::= */
- { 190, -2 }, /* (45) refargs ::= refargs refarg */
- { 192, -2 }, /* (46) refarg ::= MATCH nm */
- { 192, -3 }, /* (47) refarg ::= ON INSERT refact */
- { 192, -3 }, /* (48) refarg ::= ON DELETE refact */
- { 192, -3 }, /* (49) refarg ::= ON UPDATE refact */
- { 193, -2 }, /* (50) refact ::= SET NULL */
- { 193, -2 }, /* (51) refact ::= SET DEFAULT */
- { 193, -1 }, /* (52) refact ::= CASCADE */
- { 193, -1 }, /* (53) refact ::= RESTRICT */
- { 193, -2 }, /* (54) refact ::= NO ACTION */
- { 191, -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- { 191, -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- { 194, 0 }, /* (57) init_deferred_pred_opt ::= */
- { 194, -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
- { 194, -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
- { 172, 0 }, /* (60) conslist_opt ::= */
- { 196, -1 }, /* (61) tconscomma ::= COMMA */
- { 197, -2 }, /* (62) tcons ::= CONSTRAINT nm */
- { 197, -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
- { 197, -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
- { 197, -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */
- { 197, -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
- { 200, 0 }, /* (67) defer_subclause_opt ::= */
- { 186, 0 }, /* (68) onconf ::= */
- { 186, -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */
- { 201, 0 }, /* (70) orconf ::= */
- { 201, -2 }, /* (71) orconf ::= OR resolvetype */
- { 202, -1 }, /* (72) resolvetype ::= IGNORE */
- { 202, -1 }, /* (73) resolvetype ::= REPLACE */
- { 160, -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */
- { 204, -2 }, /* (75) ifexists ::= IF EXISTS */
- { 204, 0 }, /* (76) ifexists ::= */
- { 160, -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
- { 160, -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */
- { 160, -1 }, /* (79) cmd ::= select */
- { 174, -3 }, /* (80) select ::= WITH wqlist selectnowith */
- { 174, -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */
- { 174, -1 }, /* (82) select ::= selectnowith */
- { 206, -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */
- { 209, -1 }, /* (84) multiselect_op ::= UNION */
- { 209, -2 }, /* (85) multiselect_op ::= UNION ALL */
- { 209, -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */
- { 207, -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
- { 207, -10 }, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
- { 219, -4 }, /* (89) values ::= VALUES LP nexprlist RP */
- { 219, -5 }, /* (90) values ::= values COMMA LP nexprlist RP */
- { 210, -1 }, /* (91) distinct ::= DISTINCT */
- { 210, -1 }, /* (92) distinct ::= ALL */
- { 210, 0 }, /* (93) distinct ::= */
- { 221, 0 }, /* (94) sclp ::= */
- { 211, -5 }, /* (95) selcollist ::= sclp scanpt expr scanpt as */
- { 211, -3 }, /* (96) selcollist ::= sclp scanpt STAR */
- { 211, -5 }, /* (97) selcollist ::= sclp scanpt nm DOT STAR */
- { 222, -2 }, /* (98) as ::= AS nm */
- { 222, 0 }, /* (99) as ::= */
- { 212, 0 }, /* (100) from ::= */
- { 212, -2 }, /* (101) from ::= FROM seltablist */
- { 224, -2 }, /* (102) stl_prefix ::= seltablist joinop */
- { 224, 0 }, /* (103) stl_prefix ::= */
- { 223, -7 }, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
- { 223, -9 }, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
- { 223, -7 }, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
- { 223, -7 }, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
- { 170, 0 }, /* (108) dbnm ::= */
- { 170, -2 }, /* (109) dbnm ::= DOT nm */
- { 205, -1 }, /* (110) fullname ::= nm */
- { 205, -3 }, /* (111) fullname ::= nm DOT nm */
- { 230, -1 }, /* (112) xfullname ::= nm */
- { 230, -3 }, /* (113) xfullname ::= nm DOT nm */
- { 230, -5 }, /* (114) xfullname ::= nm DOT nm AS nm */
- { 230, -3 }, /* (115) xfullname ::= nm AS nm */
- { 225, -1 }, /* (116) joinop ::= COMMA|JOIN */
- { 225, -2 }, /* (117) joinop ::= JOIN_KW JOIN */
- { 225, -3 }, /* (118) joinop ::= JOIN_KW nm JOIN */
- { 225, -4 }, /* (119) joinop ::= JOIN_KW nm nm JOIN */
- { 227, -2 }, /* (120) on_opt ::= ON expr */
- { 227, 0 }, /* (121) on_opt ::= */
- { 226, 0 }, /* (122) indexed_opt ::= */
- { 226, -3 }, /* (123) indexed_opt ::= INDEXED BY nm */
- { 226, -2 }, /* (124) indexed_opt ::= NOT INDEXED */
- { 228, -4 }, /* (125) using_opt ::= USING LP idlist RP */
- { 228, 0 }, /* (126) using_opt ::= */
- { 216, 0 }, /* (127) orderby_opt ::= */
- { 216, -3 }, /* (128) orderby_opt ::= ORDER BY sortlist */
- { 198, -4 }, /* (129) sortlist ::= sortlist COMMA expr sortorder */
- { 198, -2 }, /* (130) sortlist ::= expr sortorder */
- { 187, -1 }, /* (131) sortorder ::= ASC */
- { 187, -1 }, /* (132) sortorder ::= DESC */
- { 187, 0 }, /* (133) sortorder ::= */
- { 214, 0 }, /* (134) groupby_opt ::= */
- { 214, -3 }, /* (135) groupby_opt ::= GROUP BY nexprlist */
- { 215, 0 }, /* (136) having_opt ::= */
- { 215, -2 }, /* (137) having_opt ::= HAVING expr */
- { 217, 0 }, /* (138) limit_opt ::= */
- { 217, -2 }, /* (139) limit_opt ::= LIMIT expr */
- { 217, -4 }, /* (140) limit_opt ::= LIMIT expr OFFSET expr */
- { 217, -4 }, /* (141) limit_opt ::= LIMIT expr COMMA expr */
- { 160, -6 }, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
- { 213, 0 }, /* (143) where_opt ::= */
- { 213, -2 }, /* (144) where_opt ::= WHERE expr */
- { 160, -8 }, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
- { 233, -5 }, /* (146) setlist ::= setlist COMMA nm EQ expr */
- { 233, -7 }, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */
- { 233, -3 }, /* (148) setlist ::= nm EQ expr */
- { 233, -5 }, /* (149) setlist ::= LP idlist RP EQ expr */
- { 160, -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
- { 160, -7 }, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
- { 236, 0 }, /* (152) upsert ::= */
- { 236, -11 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
- { 236, -8 }, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
- { 236, -4 }, /* (155) upsert ::= ON CONFLICT DO NOTHING */
- { 234, -2 }, /* (156) insert_cmd ::= INSERT orconf */
- { 234, -1 }, /* (157) insert_cmd ::= REPLACE */
- { 235, 0 }, /* (158) idlist_opt ::= */
- { 235, -3 }, /* (159) idlist_opt ::= LP idlist RP */
- { 231, -3 }, /* (160) idlist ::= idlist COMMA nm */
- { 231, -1 }, /* (161) idlist ::= nm */
- { 185, -3 }, /* (162) expr ::= LP expr RP */
- { 185, -1 }, /* (163) expr ::= ID|INDEXED */
- { 185, -1 }, /* (164) expr ::= JOIN_KW */
- { 185, -3 }, /* (165) expr ::= nm DOT nm */
- { 185, -5 }, /* (166) expr ::= nm DOT nm DOT nm */
- { 184, -1 }, /* (167) term ::= NULL|FLOAT|BLOB */
- { 184, -1 }, /* (168) term ::= STRING */
- { 184, -1 }, /* (169) term ::= INTEGER */
- { 185, -1 }, /* (170) expr ::= VARIABLE */
- { 185, -3 }, /* (171) expr ::= expr COLLATE ID|STRING */
- { 185, -6 }, /* (172) expr ::= CAST LP expr AS typetoken RP */
- { 185, -5 }, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */
- { 185, -4 }, /* (174) expr ::= ID|INDEXED LP STAR RP */
- { 185, -6 }, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
- { 185, -5 }, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */
- { 184, -1 }, /* (177) term ::= CTIME_KW */
- { 185, -5 }, /* (178) expr ::= LP nexprlist COMMA expr RP */
- { 185, -3 }, /* (179) expr ::= expr AND expr */
- { 185, -3 }, /* (180) expr ::= expr OR expr */
- { 185, -3 }, /* (181) expr ::= expr LT|GT|GE|LE expr */
- { 185, -3 }, /* (182) expr ::= expr EQ|NE expr */
- { 185, -3 }, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- { 185, -3 }, /* (184) expr ::= expr PLUS|MINUS expr */
- { 185, -3 }, /* (185) expr ::= expr STAR|SLASH|REM expr */
- { 185, -3 }, /* (186) expr ::= expr CONCAT expr */
- { 238, -2 }, /* (187) likeop ::= NOT LIKE_KW|MATCH */
- { 185, -3 }, /* (188) expr ::= expr likeop expr */
- { 185, -5 }, /* (189) expr ::= expr likeop expr ESCAPE expr */
- { 185, -2 }, /* (190) expr ::= expr ISNULL|NOTNULL */
- { 185, -3 }, /* (191) expr ::= expr NOT NULL */
- { 185, -3 }, /* (192) expr ::= expr IS expr */
- { 185, -4 }, /* (193) expr ::= expr IS NOT expr */
- { 185, -2 }, /* (194) expr ::= NOT expr */
- { 185, -2 }, /* (195) expr ::= BITNOT expr */
- { 185, -2 }, /* (196) expr ::= PLUS|MINUS expr */
- { 239, -1 }, /* (197) between_op ::= BETWEEN */
- { 239, -2 }, /* (198) between_op ::= NOT BETWEEN */
- { 185, -5 }, /* (199) expr ::= expr between_op expr AND expr */
- { 240, -1 }, /* (200) in_op ::= IN */
- { 240, -2 }, /* (201) in_op ::= NOT IN */
- { 185, -5 }, /* (202) expr ::= expr in_op LP exprlist RP */
- { 185, -3 }, /* (203) expr ::= LP select RP */
- { 185, -5 }, /* (204) expr ::= expr in_op LP select RP */
- { 185, -5 }, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */
- { 185, -4 }, /* (206) expr ::= EXISTS LP select RP */
- { 185, -5 }, /* (207) expr ::= CASE case_operand case_exprlist case_else END */
- { 243, -5 }, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */
- { 243, -4 }, /* (209) case_exprlist ::= WHEN expr THEN expr */
- { 244, -2 }, /* (210) case_else ::= ELSE expr */
- { 244, 0 }, /* (211) case_else ::= */
- { 242, -1 }, /* (212) case_operand ::= expr */
- { 242, 0 }, /* (213) case_operand ::= */
- { 229, 0 }, /* (214) exprlist ::= */
- { 220, -3 }, /* (215) nexprlist ::= nexprlist COMMA expr */
- { 220, -1 }, /* (216) nexprlist ::= expr */
- { 241, 0 }, /* (217) paren_exprlist ::= */
- { 241, -3 }, /* (218) paren_exprlist ::= LP exprlist RP */
- { 160, -12 }, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
- { 245, -1 }, /* (220) uniqueflag ::= UNIQUE */
- { 245, 0 }, /* (221) uniqueflag ::= */
- { 189, 0 }, /* (222) eidlist_opt ::= */
- { 189, -3 }, /* (223) eidlist_opt ::= LP eidlist RP */
- { 199, -5 }, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */
- { 199, -3 }, /* (225) eidlist ::= nm collate sortorder */
- { 246, 0 }, /* (226) collate ::= */
- { 246, -2 }, /* (227) collate ::= COLLATE ID|STRING */
- { 160, -4 }, /* (228) cmd ::= DROP INDEX ifexists fullname */
- { 160, -1 }, /* (229) cmd ::= VACUUM */
- { 160, -2 }, /* (230) cmd ::= VACUUM nm */
- { 160, -3 }, /* (231) cmd ::= PRAGMA nm dbnm */
- { 160, -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ nmnum */
- { 160, -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP nmnum RP */
- { 160, -5 }, /* (234) cmd ::= PRAGMA nm dbnm EQ minus_num */
- { 160, -6 }, /* (235) cmd ::= PRAGMA nm dbnm LP minus_num RP */
- { 180, -2 }, /* (236) plus_num ::= PLUS INTEGER|FLOAT */
- { 181, -2 }, /* (237) minus_num ::= MINUS INTEGER|FLOAT */
- { 160, -5 }, /* (238) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
- { 248, -11 }, /* (239) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
- { 250, -1 }, /* (240) trigger_time ::= BEFORE|AFTER */
- { 250, -2 }, /* (241) trigger_time ::= INSTEAD OF */
- { 250, 0 }, /* (242) trigger_time ::= */
- { 251, -1 }, /* (243) trigger_event ::= DELETE|INSERT */
- { 251, -1 }, /* (244) trigger_event ::= UPDATE */
- { 251, -3 }, /* (245) trigger_event ::= UPDATE OF idlist */
- { 253, 0 }, /* (246) when_clause ::= */
- { 253, -2 }, /* (247) when_clause ::= WHEN expr */
- { 249, -3 }, /* (248) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
- { 249, -2 }, /* (249) trigger_cmd_list ::= trigger_cmd SEMI */
- { 255, -3 }, /* (250) trnm ::= nm DOT nm */
- { 256, -3 }, /* (251) tridxby ::= INDEXED BY nm */
- { 256, -2 }, /* (252) tridxby ::= NOT INDEXED */
- { 254, -8 }, /* (253) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
- { 254, -8 }, /* (254) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
- { 254, -6 }, /* (255) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
- { 254, -3 }, /* (256) trigger_cmd ::= scanpt select scanpt */
- { 185, -4 }, /* (257) expr ::= RAISE LP IGNORE RP */
- { 185, -6 }, /* (258) expr ::= RAISE LP raisetype COMMA nm RP */
- { 203, -1 }, /* (259) raisetype ::= ROLLBACK */
- { 203, -1 }, /* (260) raisetype ::= ABORT */
- { 203, -1 }, /* (261) raisetype ::= FAIL */
- { 160, -4 }, /* (262) cmd ::= DROP TRIGGER ifexists fullname */
- { 160, -6 }, /* (263) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
- { 160, -3 }, /* (264) cmd ::= DETACH database_kw_opt expr */
- { 258, 0 }, /* (265) key_opt ::= */
- { 258, -2 }, /* (266) key_opt ::= KEY expr */
- { 160, -1 }, /* (267) cmd ::= REINDEX */
- { 160, -3 }, /* (268) cmd ::= REINDEX nm dbnm */
- { 160, -1 }, /* (269) cmd ::= ANALYZE */
- { 160, -3 }, /* (270) cmd ::= ANALYZE nm dbnm */
- { 160, -6 }, /* (271) cmd ::= ALTER TABLE fullname RENAME TO nm */
- { 160, -7 }, /* (272) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
- { 259, -1 }, /* (273) add_column_fullname ::= fullname */
- { 160, -8 }, /* (274) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
- { 160, -1 }, /* (275) cmd ::= create_vtab */
- { 160, -4 }, /* (276) cmd ::= create_vtab LP vtabarglist RP */
- { 261, -8 }, /* (277) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
- { 263, 0 }, /* (278) vtabarg ::= */
- { 264, -1 }, /* (279) vtabargtoken ::= ANY */
- { 264, -3 }, /* (280) vtabargtoken ::= lp anylist RP */
- { 265, -1 }, /* (281) lp ::= LP */
- { 232, -2 }, /* (282) with ::= WITH wqlist */
- { 232, -3 }, /* (283) with ::= WITH RECURSIVE wqlist */
- { 208, -6 }, /* (284) wqlist ::= nm eidlist_opt AS LP select RP */
- { 208, -8 }, /* (285) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
- { 267, -1 }, /* (286) windowdefn_list ::= windowdefn */
- { 267, -3 }, /* (287) windowdefn_list ::= windowdefn_list COMMA windowdefn */
- { 268, -3 }, /* (288) windowdefn ::= nm AS window */
- { 269, -5 }, /* (289) window ::= LP part_opt orderby_opt frame_opt RP */
- { 271, -3 }, /* (290) part_opt ::= PARTITION BY nexprlist */
- { 271, 0 }, /* (291) part_opt ::= */
- { 270, 0 }, /* (292) frame_opt ::= */
- { 270, -2 }, /* (293) frame_opt ::= range_or_rows frame_bound_s */
- { 270, -5 }, /* (294) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
- { 273, -1 }, /* (295) range_or_rows ::= RANGE */
- { 273, -1 }, /* (296) range_or_rows ::= ROWS */
- { 275, -1 }, /* (297) frame_bound_s ::= frame_bound */
- { 275, -2 }, /* (298) frame_bound_s ::= UNBOUNDED PRECEDING */
- { 276, -1 }, /* (299) frame_bound_e ::= frame_bound */
- { 276, -2 }, /* (300) frame_bound_e ::= UNBOUNDED FOLLOWING */
- { 274, -2 }, /* (301) frame_bound ::= expr PRECEDING */
- { 274, -2 }, /* (302) frame_bound ::= CURRENT ROW */
- { 274, -2 }, /* (303) frame_bound ::= expr FOLLOWING */
- { 218, -2 }, /* (304) window_clause ::= WINDOW windowdefn_list */
- { 237, -3 }, /* (305) over_clause ::= filter_opt OVER window */
- { 237, -3 }, /* (306) over_clause ::= filter_opt OVER nm */
- { 272, 0 }, /* (307) filter_opt ::= */
- { 272, -5 }, /* (308) filter_opt ::= FILTER LP WHERE expr RP */
- { 155, -1 }, /* (309) input ::= cmdlist */
- { 156, -2 }, /* (310) cmdlist ::= cmdlist ecmd */
- { 156, -1 }, /* (311) cmdlist ::= ecmd */
- { 157, -1 }, /* (312) ecmd ::= SEMI */
- { 157, -2 }, /* (313) ecmd ::= cmdx SEMI */
- { 157, -2 }, /* (314) ecmd ::= explain cmdx */
- { 162, 0 }, /* (315) trans_opt ::= */
- { 162, -1 }, /* (316) trans_opt ::= TRANSACTION */
- { 162, -2 }, /* (317) trans_opt ::= TRANSACTION nm */
- { 164, -1 }, /* (318) savepoint_opt ::= SAVEPOINT */
- { 164, 0 }, /* (319) savepoint_opt ::= */
- { 160, -2 }, /* (320) cmd ::= create_table create_table_args */
- { 171, -4 }, /* (321) columnlist ::= columnlist COMMA columnname carglist */
- { 171, -2 }, /* (322) columnlist ::= columnname carglist */
- { 163, -1 }, /* (323) nm ::= ID|INDEXED */
- { 163, -1 }, /* (324) nm ::= STRING */
- { 163, -1 }, /* (325) nm ::= JOIN_KW */
- { 177, -1 }, /* (326) typetoken ::= typename */
- { 178, -1 }, /* (327) typename ::= ID|STRING */
- { 179, -1 }, /* (328) signed ::= plus_num */
- { 179, -1 }, /* (329) signed ::= minus_num */
- { 176, -2 }, /* (330) carglist ::= carglist ccons */
- { 176, 0 }, /* (331) carglist ::= */
- { 183, -2 }, /* (332) ccons ::= NULL onconf */
- { 172, -2 }, /* (333) conslist_opt ::= COMMA conslist */
- { 195, -3 }, /* (334) conslist ::= conslist tconscomma tcons */
- { 195, -1 }, /* (335) conslist ::= tcons */
- { 196, 0 }, /* (336) tconscomma ::= */
- { 200, -1 }, /* (337) defer_subclause_opt ::= defer_subclause */
- { 202, -1 }, /* (338) resolvetype ::= raisetype */
- { 206, -1 }, /* (339) selectnowith ::= oneselect */
- { 207, -1 }, /* (340) oneselect ::= values */
- { 221, -2 }, /* (341) sclp ::= selcollist COMMA */
- { 222, -1 }, /* (342) as ::= ID|STRING */
- { 185, -1 }, /* (343) expr ::= term */
- { 238, -1 }, /* (344) likeop ::= LIKE_KW|MATCH */
- { 229, -1 }, /* (345) exprlist ::= nexprlist */
- { 247, -1 }, /* (346) nmnum ::= plus_num */
- { 247, -1 }, /* (347) nmnum ::= nm */
- { 247, -1 }, /* (348) nmnum ::= ON */
- { 247, -1 }, /* (349) nmnum ::= DELETE */
- { 247, -1 }, /* (350) nmnum ::= DEFAULT */
- { 180, -1 }, /* (351) plus_num ::= INTEGER|FLOAT */
- { 252, 0 }, /* (352) foreach_clause ::= */
- { 252, -3 }, /* (353) foreach_clause ::= FOR EACH ROW */
- { 255, -1 }, /* (354) trnm ::= nm */
- { 256, 0 }, /* (355) tridxby ::= */
- { 257, -1 }, /* (356) database_kw_opt ::= DATABASE */
- { 257, 0 }, /* (357) database_kw_opt ::= */
- { 260, 0 }, /* (358) kwcolumn_opt ::= */
- { 260, -1 }, /* (359) kwcolumn_opt ::= COLUMNKW */
- { 262, -1 }, /* (360) vtabarglist ::= vtabarg */
- { 262, -3 }, /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */
- { 263, -2 }, /* (362) vtabarg ::= vtabarg vtabargtoken */
- { 266, 0 }, /* (363) anylist ::= */
- { 266, -4 }, /* (364) anylist ::= anylist LP anylist RP */
- { 266, -2 }, /* (365) anylist ::= anylist ANY */
- { 232, 0 }, /* (366) with ::= */
+/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
+** of that rule */
+static const YYCODETYPE yyRuleInfoLhs[] = {
+ 180, /* (0) explain ::= EXPLAIN */
+ 180, /* (1) explain ::= EXPLAIN QUERY PLAN */
+ 179, /* (2) cmdx ::= cmd */
+ 181, /* (3) cmd ::= BEGIN transtype trans_opt */
+ 182, /* (4) transtype ::= */
+ 182, /* (5) transtype ::= DEFERRED */
+ 182, /* (6) transtype ::= IMMEDIATE */
+ 182, /* (7) transtype ::= EXCLUSIVE */
+ 181, /* (8) cmd ::= COMMIT|END trans_opt */
+ 181, /* (9) cmd ::= ROLLBACK trans_opt */
+ 181, /* (10) cmd ::= SAVEPOINT nm */
+ 181, /* (11) cmd ::= RELEASE savepoint_opt nm */
+ 181, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ 186, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ 188, /* (14) createkw ::= CREATE */
+ 190, /* (15) ifnotexists ::= */
+ 190, /* (16) ifnotexists ::= IF NOT EXISTS */
+ 189, /* (17) temp ::= TEMP */
+ 189, /* (18) temp ::= */
+ 187, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+ 187, /* (20) create_table_args ::= AS select */
+ 194, /* (21) table_options ::= */
+ 194, /* (22) table_options ::= WITHOUT nm */
+ 196, /* (23) columnname ::= nm typetoken */
+ 198, /* (24) typetoken ::= */
+ 198, /* (25) typetoken ::= typename LP signed RP */
+ 198, /* (26) typetoken ::= typename LP signed COMMA signed RP */
+ 199, /* (27) typename ::= typename ID|STRING */
+ 203, /* (28) scanpt ::= */
+ 204, /* (29) scantok ::= */
+ 205, /* (30) ccons ::= CONSTRAINT nm */
+ 205, /* (31) ccons ::= DEFAULT scantok term */
+ 205, /* (32) ccons ::= DEFAULT LP expr RP */
+ 205, /* (33) ccons ::= DEFAULT PLUS scantok term */
+ 205, /* (34) ccons ::= DEFAULT MINUS scantok term */
+ 205, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */
+ 205, /* (36) ccons ::= NOT NULL onconf */
+ 205, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ 205, /* (38) ccons ::= UNIQUE onconf */
+ 205, /* (39) ccons ::= CHECK LP expr RP */
+ 205, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */
+ 205, /* (41) ccons ::= defer_subclause */
+ 205, /* (42) ccons ::= COLLATE ID|STRING */
+ 210, /* (43) autoinc ::= */
+ 210, /* (44) autoinc ::= AUTOINCR */
+ 212, /* (45) refargs ::= */
+ 212, /* (46) refargs ::= refargs refarg */
+ 214, /* (47) refarg ::= MATCH nm */
+ 214, /* (48) refarg ::= ON INSERT refact */
+ 214, /* (49) refarg ::= ON DELETE refact */
+ 214, /* (50) refarg ::= ON UPDATE refact */
+ 215, /* (51) refact ::= SET NULL */
+ 215, /* (52) refact ::= SET DEFAULT */
+ 215, /* (53) refact ::= CASCADE */
+ 215, /* (54) refact ::= RESTRICT */
+ 215, /* (55) refact ::= NO ACTION */
+ 213, /* (56) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ 213, /* (57) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ 216, /* (58) init_deferred_pred_opt ::= */
+ 216, /* (59) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ 216, /* (60) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ 193, /* (61) conslist_opt ::= */
+ 218, /* (62) tconscomma ::= COMMA */
+ 219, /* (63) tcons ::= CONSTRAINT nm */
+ 219, /* (64) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ 219, /* (65) tcons ::= UNIQUE LP sortlist RP onconf */
+ 219, /* (66) tcons ::= CHECK LP expr RP onconf */
+ 219, /* (67) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ 222, /* (68) defer_subclause_opt ::= */
+ 208, /* (69) onconf ::= */
+ 208, /* (70) onconf ::= ON CONFLICT resolvetype */
+ 223, /* (71) orconf ::= */
+ 223, /* (72) orconf ::= OR resolvetype */
+ 224, /* (73) resolvetype ::= IGNORE */
+ 224, /* (74) resolvetype ::= REPLACE */
+ 181, /* (75) cmd ::= DROP TABLE ifexists fullname */
+ 226, /* (76) ifexists ::= IF EXISTS */
+ 226, /* (77) ifexists ::= */
+ 181, /* (78) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ 181, /* (79) cmd ::= DROP VIEW ifexists fullname */
+ 181, /* (80) cmd ::= select */
+ 195, /* (81) select ::= WITH wqlist selectnowith */
+ 195, /* (82) select ::= WITH RECURSIVE wqlist selectnowith */
+ 195, /* (83) select ::= selectnowith */
+ 228, /* (84) selectnowith ::= selectnowith multiselect_op oneselect */
+ 231, /* (85) multiselect_op ::= UNION */
+ 231, /* (86) multiselect_op ::= UNION ALL */
+ 231, /* (87) multiselect_op ::= EXCEPT|INTERSECT */
+ 229, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ 229, /* (89) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ 241, /* (90) values ::= VALUES LP nexprlist RP */
+ 241, /* (91) values ::= values COMMA LP nexprlist RP */
+ 232, /* (92) distinct ::= DISTINCT */
+ 232, /* (93) distinct ::= ALL */
+ 232, /* (94) distinct ::= */
+ 243, /* (95) sclp ::= */
+ 233, /* (96) selcollist ::= sclp scanpt expr scanpt as */
+ 233, /* (97) selcollist ::= sclp scanpt STAR */
+ 233, /* (98) selcollist ::= sclp scanpt nm DOT STAR */
+ 244, /* (99) as ::= AS nm */
+ 244, /* (100) as ::= */
+ 234, /* (101) from ::= */
+ 234, /* (102) from ::= FROM seltablist */
+ 246, /* (103) stl_prefix ::= seltablist joinop */
+ 246, /* (104) stl_prefix ::= */
+ 245, /* (105) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ 245, /* (106) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ 245, /* (107) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ 245, /* (108) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ 191, /* (109) dbnm ::= */
+ 191, /* (110) dbnm ::= DOT nm */
+ 227, /* (111) fullname ::= nm */
+ 227, /* (112) fullname ::= nm DOT nm */
+ 252, /* (113) xfullname ::= nm */
+ 252, /* (114) xfullname ::= nm DOT nm */
+ 252, /* (115) xfullname ::= nm DOT nm AS nm */
+ 252, /* (116) xfullname ::= nm AS nm */
+ 247, /* (117) joinop ::= COMMA|JOIN */
+ 247, /* (118) joinop ::= JOIN_KW JOIN */
+ 247, /* (119) joinop ::= JOIN_KW nm JOIN */
+ 247, /* (120) joinop ::= JOIN_KW nm nm JOIN */
+ 249, /* (121) on_opt ::= ON expr */
+ 249, /* (122) on_opt ::= */
+ 248, /* (123) indexed_opt ::= */
+ 248, /* (124) indexed_opt ::= INDEXED BY nm */
+ 248, /* (125) indexed_opt ::= NOT INDEXED */
+ 250, /* (126) using_opt ::= USING LP idlist RP */
+ 250, /* (127) using_opt ::= */
+ 238, /* (128) orderby_opt ::= */
+ 238, /* (129) orderby_opt ::= ORDER BY sortlist */
+ 220, /* (130) sortlist ::= sortlist COMMA expr sortorder */
+ 220, /* (131) sortlist ::= expr sortorder */
+ 209, /* (132) sortorder ::= ASC */
+ 209, /* (133) sortorder ::= DESC */
+ 209, /* (134) sortorder ::= */
+ 236, /* (135) groupby_opt ::= */
+ 236, /* (136) groupby_opt ::= GROUP BY nexprlist */
+ 237, /* (137) having_opt ::= */
+ 237, /* (138) having_opt ::= HAVING expr */
+ 239, /* (139) limit_opt ::= */
+ 239, /* (140) limit_opt ::= LIMIT expr */
+ 239, /* (141) limit_opt ::= LIMIT expr OFFSET expr */
+ 239, /* (142) limit_opt ::= LIMIT expr COMMA expr */
+ 181, /* (143) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ 235, /* (144) where_opt ::= */
+ 235, /* (145) where_opt ::= WHERE expr */
+ 181, /* (146) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ 255, /* (147) setlist ::= setlist COMMA nm EQ expr */
+ 255, /* (148) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ 255, /* (149) setlist ::= nm EQ expr */
+ 255, /* (150) setlist ::= LP idlist RP EQ expr */
+ 181, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ 181, /* (152) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ 258, /* (153) upsert ::= */
+ 258, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+ 258, /* (155) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+ 258, /* (156) upsert ::= ON CONFLICT DO NOTHING */
+ 256, /* (157) insert_cmd ::= INSERT orconf */
+ 256, /* (158) insert_cmd ::= REPLACE */
+ 257, /* (159) idlist_opt ::= */
+ 257, /* (160) idlist_opt ::= LP idlist RP */
+ 253, /* (161) idlist ::= idlist COMMA nm */
+ 253, /* (162) idlist ::= nm */
+ 207, /* (163) expr ::= LP expr RP */
+ 207, /* (164) expr ::= ID|INDEXED */
+ 207, /* (165) expr ::= JOIN_KW */
+ 207, /* (166) expr ::= nm DOT nm */
+ 207, /* (167) expr ::= nm DOT nm DOT nm */
+ 206, /* (168) term ::= NULL|FLOAT|BLOB */
+ 206, /* (169) term ::= STRING */
+ 206, /* (170) term ::= INTEGER */
+ 207, /* (171) expr ::= VARIABLE */
+ 207, /* (172) expr ::= expr COLLATE ID|STRING */
+ 207, /* (173) expr ::= CAST LP expr AS typetoken RP */
+ 207, /* (174) expr ::= ID|INDEXED LP distinct exprlist RP */
+ 207, /* (175) expr ::= ID|INDEXED LP STAR RP */
+ 207, /* (176) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ 207, /* (177) expr ::= ID|INDEXED LP STAR RP over_clause */
+ 206, /* (178) term ::= CTIME_KW */
+ 207, /* (179) expr ::= LP nexprlist COMMA expr RP */
+ 207, /* (180) expr ::= expr AND expr */
+ 207, /* (181) expr ::= expr OR expr */
+ 207, /* (182) expr ::= expr LT|GT|GE|LE expr */
+ 207, /* (183) expr ::= expr EQ|NE expr */
+ 207, /* (184) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ 207, /* (185) expr ::= expr PLUS|MINUS expr */
+ 207, /* (186) expr ::= expr STAR|SLASH|REM expr */
+ 207, /* (187) expr ::= expr CONCAT expr */
+ 260, /* (188) likeop ::= NOT LIKE_KW|MATCH */
+ 207, /* (189) expr ::= expr likeop expr */
+ 207, /* (190) expr ::= expr likeop expr ESCAPE expr */
+ 207, /* (191) expr ::= expr ISNULL|NOTNULL */
+ 207, /* (192) expr ::= expr NOT NULL */
+ 207, /* (193) expr ::= expr IS expr */
+ 207, /* (194) expr ::= expr IS NOT expr */
+ 207, /* (195) expr ::= NOT expr */
+ 207, /* (196) expr ::= BITNOT expr */
+ 207, /* (197) expr ::= PLUS|MINUS expr */
+ 261, /* (198) between_op ::= BETWEEN */
+ 261, /* (199) between_op ::= NOT BETWEEN */
+ 207, /* (200) expr ::= expr between_op expr AND expr */
+ 262, /* (201) in_op ::= IN */
+ 262, /* (202) in_op ::= NOT IN */
+ 207, /* (203) expr ::= expr in_op LP exprlist RP */
+ 207, /* (204) expr ::= LP select RP */
+ 207, /* (205) expr ::= expr in_op LP select RP */
+ 207, /* (206) expr ::= expr in_op nm dbnm paren_exprlist */
+ 207, /* (207) expr ::= EXISTS LP select RP */
+ 207, /* (208) expr ::= CASE case_operand case_exprlist case_else END */
+ 265, /* (209) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ 265, /* (210) case_exprlist ::= WHEN expr THEN expr */
+ 266, /* (211) case_else ::= ELSE expr */
+ 266, /* (212) case_else ::= */
+ 264, /* (213) case_operand ::= expr */
+ 264, /* (214) case_operand ::= */
+ 251, /* (215) exprlist ::= */
+ 242, /* (216) nexprlist ::= nexprlist COMMA expr */
+ 242, /* (217) nexprlist ::= expr */
+ 263, /* (218) paren_exprlist ::= */
+ 263, /* (219) paren_exprlist ::= LP exprlist RP */
+ 181, /* (220) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ 267, /* (221) uniqueflag ::= UNIQUE */
+ 267, /* (222) uniqueflag ::= */
+ 211, /* (223) eidlist_opt ::= */
+ 211, /* (224) eidlist_opt ::= LP eidlist RP */
+ 221, /* (225) eidlist ::= eidlist COMMA nm collate sortorder */
+ 221, /* (226) eidlist ::= nm collate sortorder */
+ 268, /* (227) collate ::= */
+ 268, /* (228) collate ::= COLLATE ID|STRING */
+ 181, /* (229) cmd ::= DROP INDEX ifexists fullname */
+ 181, /* (230) cmd ::= VACUUM vinto */
+ 181, /* (231) cmd ::= VACUUM nm vinto */
+ 269, /* (232) vinto ::= INTO expr */
+ 269, /* (233) vinto ::= */
+ 181, /* (234) cmd ::= PRAGMA nm dbnm */
+ 181, /* (235) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ 181, /* (236) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ 181, /* (237) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ 181, /* (238) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ 201, /* (239) plus_num ::= PLUS INTEGER|FLOAT */
+ 202, /* (240) minus_num ::= MINUS INTEGER|FLOAT */
+ 181, /* (241) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ 271, /* (242) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ 273, /* (243) trigger_time ::= BEFORE|AFTER */
+ 273, /* (244) trigger_time ::= INSTEAD OF */
+ 273, /* (245) trigger_time ::= */
+ 274, /* (246) trigger_event ::= DELETE|INSERT */
+ 274, /* (247) trigger_event ::= UPDATE */
+ 274, /* (248) trigger_event ::= UPDATE OF idlist */
+ 276, /* (249) when_clause ::= */
+ 276, /* (250) when_clause ::= WHEN expr */
+ 272, /* (251) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ 272, /* (252) trigger_cmd_list ::= trigger_cmd SEMI */
+ 278, /* (253) trnm ::= nm DOT nm */
+ 279, /* (254) tridxby ::= INDEXED BY nm */
+ 279, /* (255) tridxby ::= NOT INDEXED */
+ 277, /* (256) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+ 277, /* (257) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ 277, /* (258) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ 277, /* (259) trigger_cmd ::= scanpt select scanpt */
+ 207, /* (260) expr ::= RAISE LP IGNORE RP */
+ 207, /* (261) expr ::= RAISE LP raisetype COMMA nm RP */
+ 225, /* (262) raisetype ::= ROLLBACK */
+ 225, /* (263) raisetype ::= ABORT */
+ 225, /* (264) raisetype ::= FAIL */
+ 181, /* (265) cmd ::= DROP TRIGGER ifexists fullname */
+ 181, /* (266) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ 181, /* (267) cmd ::= DETACH database_kw_opt expr */
+ 281, /* (268) key_opt ::= */
+ 281, /* (269) key_opt ::= KEY expr */
+ 181, /* (270) cmd ::= REINDEX */
+ 181, /* (271) cmd ::= REINDEX nm dbnm */
+ 181, /* (272) cmd ::= ANALYZE */
+ 181, /* (273) cmd ::= ANALYZE nm dbnm */
+ 181, /* (274) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ 181, /* (275) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ 282, /* (276) add_column_fullname ::= fullname */
+ 181, /* (277) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ 181, /* (278) cmd ::= create_vtab */
+ 181, /* (279) cmd ::= create_vtab LP vtabarglist RP */
+ 284, /* (280) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 286, /* (281) vtabarg ::= */
+ 287, /* (282) vtabargtoken ::= ANY */
+ 287, /* (283) vtabargtoken ::= lp anylist RP */
+ 288, /* (284) lp ::= LP */
+ 254, /* (285) with ::= WITH wqlist */
+ 254, /* (286) with ::= WITH RECURSIVE wqlist */
+ 230, /* (287) wqlist ::= nm eidlist_opt AS LP select RP */
+ 230, /* (288) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ 290, /* (289) windowdefn_list ::= windowdefn */
+ 290, /* (290) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ 291, /* (291) windowdefn ::= nm AS LP window RP */
+ 292, /* (292) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ 292, /* (293) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ 292, /* (294) window ::= ORDER BY sortlist frame_opt */
+ 292, /* (295) window ::= nm ORDER BY sortlist frame_opt */
+ 292, /* (296) window ::= frame_opt */
+ 292, /* (297) window ::= nm frame_opt */
+ 293, /* (298) frame_opt ::= */
+ 293, /* (299) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ 293, /* (300) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ 296, /* (301) range_or_rows ::= RANGE|ROWS|GROUPS */
+ 298, /* (302) frame_bound_s ::= frame_bound */
+ 298, /* (303) frame_bound_s ::= UNBOUNDED PRECEDING */
+ 299, /* (304) frame_bound_e ::= frame_bound */
+ 299, /* (305) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ 297, /* (306) frame_bound ::= expr PRECEDING|FOLLOWING */
+ 297, /* (307) frame_bound ::= CURRENT ROW */
+ 300, /* (308) frame_exclude_opt ::= */
+ 300, /* (309) frame_exclude_opt ::= EXCLUDE frame_exclude */
+ 301, /* (310) frame_exclude ::= NO OTHERS */
+ 301, /* (311) frame_exclude ::= CURRENT ROW */
+ 301, /* (312) frame_exclude ::= GROUP|TIES */
+ 240, /* (313) window_clause ::= WINDOW windowdefn_list */
+ 259, /* (314) over_clause ::= filter_opt OVER LP window RP */
+ 259, /* (315) over_clause ::= filter_opt OVER nm */
+ 295, /* (316) filter_opt ::= */
+ 295, /* (317) filter_opt ::= FILTER LP WHERE expr RP */
+ 176, /* (318) input ::= cmdlist */
+ 177, /* (319) cmdlist ::= cmdlist ecmd */
+ 177, /* (320) cmdlist ::= ecmd */
+ 178, /* (321) ecmd ::= SEMI */
+ 178, /* (322) ecmd ::= cmdx SEMI */
+ 178, /* (323) ecmd ::= explain cmdx */
+ 183, /* (324) trans_opt ::= */
+ 183, /* (325) trans_opt ::= TRANSACTION */
+ 183, /* (326) trans_opt ::= TRANSACTION nm */
+ 185, /* (327) savepoint_opt ::= SAVEPOINT */
+ 185, /* (328) savepoint_opt ::= */
+ 181, /* (329) cmd ::= create_table create_table_args */
+ 192, /* (330) columnlist ::= columnlist COMMA columnname carglist */
+ 192, /* (331) columnlist ::= columnname carglist */
+ 184, /* (332) nm ::= ID|INDEXED */
+ 184, /* (333) nm ::= STRING */
+ 184, /* (334) nm ::= JOIN_KW */
+ 198, /* (335) typetoken ::= typename */
+ 199, /* (336) typename ::= ID|STRING */
+ 200, /* (337) signed ::= plus_num */
+ 200, /* (338) signed ::= minus_num */
+ 197, /* (339) carglist ::= carglist ccons */
+ 197, /* (340) carglist ::= */
+ 205, /* (341) ccons ::= NULL onconf */
+ 193, /* (342) conslist_opt ::= COMMA conslist */
+ 217, /* (343) conslist ::= conslist tconscomma tcons */
+ 217, /* (344) conslist ::= tcons */
+ 218, /* (345) tconscomma ::= */
+ 222, /* (346) defer_subclause_opt ::= defer_subclause */
+ 224, /* (347) resolvetype ::= raisetype */
+ 228, /* (348) selectnowith ::= oneselect */
+ 229, /* (349) oneselect ::= values */
+ 243, /* (350) sclp ::= selcollist COMMA */
+ 244, /* (351) as ::= ID|STRING */
+ 207, /* (352) expr ::= term */
+ 260, /* (353) likeop ::= LIKE_KW|MATCH */
+ 251, /* (354) exprlist ::= nexprlist */
+ 270, /* (355) nmnum ::= plus_num */
+ 270, /* (356) nmnum ::= nm */
+ 270, /* (357) nmnum ::= ON */
+ 270, /* (358) nmnum ::= DELETE */
+ 270, /* (359) nmnum ::= DEFAULT */
+ 201, /* (360) plus_num ::= INTEGER|FLOAT */
+ 275, /* (361) foreach_clause ::= */
+ 275, /* (362) foreach_clause ::= FOR EACH ROW */
+ 278, /* (363) trnm ::= nm */
+ 279, /* (364) tridxby ::= */
+ 280, /* (365) database_kw_opt ::= DATABASE */
+ 280, /* (366) database_kw_opt ::= */
+ 283, /* (367) kwcolumn_opt ::= */
+ 283, /* (368) kwcolumn_opt ::= COLUMNKW */
+ 285, /* (369) vtabarglist ::= vtabarg */
+ 285, /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */
+ 286, /* (371) vtabarg ::= vtabarg vtabargtoken */
+ 289, /* (372) anylist ::= */
+ 289, /* (373) anylist ::= anylist LP anylist RP */
+ 289, /* (374) anylist ::= anylist ANY */
+ 254, /* (375) with ::= */
+};
+
+/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
+** of symbols on the right-hand side of that rule. */
+static const signed char yyRuleInfoNRhs[] = {
+ -1, /* (0) explain ::= EXPLAIN */
+ -3, /* (1) explain ::= EXPLAIN QUERY PLAN */
+ -1, /* (2) cmdx ::= cmd */
+ -3, /* (3) cmd ::= BEGIN transtype trans_opt */
+ 0, /* (4) transtype ::= */
+ -1, /* (5) transtype ::= DEFERRED */
+ -1, /* (6) transtype ::= IMMEDIATE */
+ -1, /* (7) transtype ::= EXCLUSIVE */
+ -2, /* (8) cmd ::= COMMIT|END trans_opt */
+ -2, /* (9) cmd ::= ROLLBACK trans_opt */
+ -2, /* (10) cmd ::= SAVEPOINT nm */
+ -3, /* (11) cmd ::= RELEASE savepoint_opt nm */
+ -5, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ -6, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ -1, /* (14) createkw ::= CREATE */
+ 0, /* (15) ifnotexists ::= */
+ -3, /* (16) ifnotexists ::= IF NOT EXISTS */
+ -1, /* (17) temp ::= TEMP */
+ 0, /* (18) temp ::= */
+ -5, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+ -2, /* (20) create_table_args ::= AS select */
+ 0, /* (21) table_options ::= */
+ -2, /* (22) table_options ::= WITHOUT nm */
+ -2, /* (23) columnname ::= nm typetoken */
+ 0, /* (24) typetoken ::= */
+ -4, /* (25) typetoken ::= typename LP signed RP */
+ -6, /* (26) typetoken ::= typename LP signed COMMA signed RP */
+ -2, /* (27) typename ::= typename ID|STRING */
+ 0, /* (28) scanpt ::= */
+ 0, /* (29) scantok ::= */
+ -2, /* (30) ccons ::= CONSTRAINT nm */
+ -3, /* (31) ccons ::= DEFAULT scantok term */
+ -4, /* (32) ccons ::= DEFAULT LP expr RP */
+ -4, /* (33) ccons ::= DEFAULT PLUS scantok term */
+ -4, /* (34) ccons ::= DEFAULT MINUS scantok term */
+ -3, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */
+ -3, /* (36) ccons ::= NOT NULL onconf */
+ -5, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ -2, /* (38) ccons ::= UNIQUE onconf */
+ -4, /* (39) ccons ::= CHECK LP expr RP */
+ -4, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */
+ -1, /* (41) ccons ::= defer_subclause */
+ -2, /* (42) ccons ::= COLLATE ID|STRING */
+ 0, /* (43) autoinc ::= */
+ -1, /* (44) autoinc ::= AUTOINCR */
+ 0, /* (45) refargs ::= */
+ -2, /* (46) refargs ::= refargs refarg */
+ -2, /* (47) refarg ::= MATCH nm */
+ -3, /* (48) refarg ::= ON INSERT refact */
+ -3, /* (49) refarg ::= ON DELETE refact */
+ -3, /* (50) refarg ::= ON UPDATE refact */
+ -2, /* (51) refact ::= SET NULL */
+ -2, /* (52) refact ::= SET DEFAULT */
+ -1, /* (53) refact ::= CASCADE */
+ -1, /* (54) refact ::= RESTRICT */
+ -2, /* (55) refact ::= NO ACTION */
+ -3, /* (56) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ -2, /* (57) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ 0, /* (58) init_deferred_pred_opt ::= */
+ -2, /* (59) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ -2, /* (60) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ 0, /* (61) conslist_opt ::= */
+ -1, /* (62) tconscomma ::= COMMA */
+ -2, /* (63) tcons ::= CONSTRAINT nm */
+ -7, /* (64) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ -5, /* (65) tcons ::= UNIQUE LP sortlist RP onconf */
+ -5, /* (66) tcons ::= CHECK LP expr RP onconf */
+ -10, /* (67) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ 0, /* (68) defer_subclause_opt ::= */
+ 0, /* (69) onconf ::= */
+ -3, /* (70) onconf ::= ON CONFLICT resolvetype */
+ 0, /* (71) orconf ::= */
+ -2, /* (72) orconf ::= OR resolvetype */
+ -1, /* (73) resolvetype ::= IGNORE */
+ -1, /* (74) resolvetype ::= REPLACE */
+ -4, /* (75) cmd ::= DROP TABLE ifexists fullname */
+ -2, /* (76) ifexists ::= IF EXISTS */
+ 0, /* (77) ifexists ::= */
+ -9, /* (78) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ -4, /* (79) cmd ::= DROP VIEW ifexists fullname */
+ -1, /* (80) cmd ::= select */
+ -3, /* (81) select ::= WITH wqlist selectnowith */
+ -4, /* (82) select ::= WITH RECURSIVE wqlist selectnowith */
+ -1, /* (83) select ::= selectnowith */
+ -3, /* (84) selectnowith ::= selectnowith multiselect_op oneselect */
+ -1, /* (85) multiselect_op ::= UNION */
+ -2, /* (86) multiselect_op ::= UNION ALL */
+ -1, /* (87) multiselect_op ::= EXCEPT|INTERSECT */
+ -9, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ -10, /* (89) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ -4, /* (90) values ::= VALUES LP nexprlist RP */
+ -5, /* (91) values ::= values COMMA LP nexprlist RP */
+ -1, /* (92) distinct ::= DISTINCT */
+ -1, /* (93) distinct ::= ALL */
+ 0, /* (94) distinct ::= */
+ 0, /* (95) sclp ::= */
+ -5, /* (96) selcollist ::= sclp scanpt expr scanpt as */
+ -3, /* (97) selcollist ::= sclp scanpt STAR */
+ -5, /* (98) selcollist ::= sclp scanpt nm DOT STAR */
+ -2, /* (99) as ::= AS nm */
+ 0, /* (100) as ::= */
+ 0, /* (101) from ::= */
+ -2, /* (102) from ::= FROM seltablist */
+ -2, /* (103) stl_prefix ::= seltablist joinop */
+ 0, /* (104) stl_prefix ::= */
+ -7, /* (105) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ -9, /* (106) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ -7, /* (107) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ -7, /* (108) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ 0, /* (109) dbnm ::= */
+ -2, /* (110) dbnm ::= DOT nm */
+ -1, /* (111) fullname ::= nm */
+ -3, /* (112) fullname ::= nm DOT nm */
+ -1, /* (113) xfullname ::= nm */
+ -3, /* (114) xfullname ::= nm DOT nm */
+ -5, /* (115) xfullname ::= nm DOT nm AS nm */
+ -3, /* (116) xfullname ::= nm AS nm */
+ -1, /* (117) joinop ::= COMMA|JOIN */
+ -2, /* (118) joinop ::= JOIN_KW JOIN */
+ -3, /* (119) joinop ::= JOIN_KW nm JOIN */
+ -4, /* (120) joinop ::= JOIN_KW nm nm JOIN */
+ -2, /* (121) on_opt ::= ON expr */
+ 0, /* (122) on_opt ::= */
+ 0, /* (123) indexed_opt ::= */
+ -3, /* (124) indexed_opt ::= INDEXED BY nm */
+ -2, /* (125) indexed_opt ::= NOT INDEXED */
+ -4, /* (126) using_opt ::= USING LP idlist RP */
+ 0, /* (127) using_opt ::= */
+ 0, /* (128) orderby_opt ::= */
+ -3, /* (129) orderby_opt ::= ORDER BY sortlist */
+ -4, /* (130) sortlist ::= sortlist COMMA expr sortorder */
+ -2, /* (131) sortlist ::= expr sortorder */
+ -1, /* (132) sortorder ::= ASC */
+ -1, /* (133) sortorder ::= DESC */
+ 0, /* (134) sortorder ::= */
+ 0, /* (135) groupby_opt ::= */
+ -3, /* (136) groupby_opt ::= GROUP BY nexprlist */
+ 0, /* (137) having_opt ::= */
+ -2, /* (138) having_opt ::= HAVING expr */
+ 0, /* (139) limit_opt ::= */
+ -2, /* (140) limit_opt ::= LIMIT expr */
+ -4, /* (141) limit_opt ::= LIMIT expr OFFSET expr */
+ -4, /* (142) limit_opt ::= LIMIT expr COMMA expr */
+ -6, /* (143) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ 0, /* (144) where_opt ::= */
+ -2, /* (145) where_opt ::= WHERE expr */
+ -8, /* (146) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ -5, /* (147) setlist ::= setlist COMMA nm EQ expr */
+ -7, /* (148) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ -3, /* (149) setlist ::= nm EQ expr */
+ -5, /* (150) setlist ::= LP idlist RP EQ expr */
+ -7, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ -7, /* (152) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ 0, /* (153) upsert ::= */
+ -11, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+ -8, /* (155) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+ -4, /* (156) upsert ::= ON CONFLICT DO NOTHING */
+ -2, /* (157) insert_cmd ::= INSERT orconf */
+ -1, /* (158) insert_cmd ::= REPLACE */
+ 0, /* (159) idlist_opt ::= */
+ -3, /* (160) idlist_opt ::= LP idlist RP */
+ -3, /* (161) idlist ::= idlist COMMA nm */
+ -1, /* (162) idlist ::= nm */
+ -3, /* (163) expr ::= LP expr RP */
+ -1, /* (164) expr ::= ID|INDEXED */
+ -1, /* (165) expr ::= JOIN_KW */
+ -3, /* (166) expr ::= nm DOT nm */
+ -5, /* (167) expr ::= nm DOT nm DOT nm */
+ -1, /* (168) term ::= NULL|FLOAT|BLOB */
+ -1, /* (169) term ::= STRING */
+ -1, /* (170) term ::= INTEGER */
+ -1, /* (171) expr ::= VARIABLE */
+ -3, /* (172) expr ::= expr COLLATE ID|STRING */
+ -6, /* (173) expr ::= CAST LP expr AS typetoken RP */
+ -5, /* (174) expr ::= ID|INDEXED LP distinct exprlist RP */
+ -4, /* (175) expr ::= ID|INDEXED LP STAR RP */
+ -6, /* (176) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ -5, /* (177) expr ::= ID|INDEXED LP STAR RP over_clause */
+ -1, /* (178) term ::= CTIME_KW */
+ -5, /* (179) expr ::= LP nexprlist COMMA expr RP */
+ -3, /* (180) expr ::= expr AND expr */
+ -3, /* (181) expr ::= expr OR expr */
+ -3, /* (182) expr ::= expr LT|GT|GE|LE expr */
+ -3, /* (183) expr ::= expr EQ|NE expr */
+ -3, /* (184) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ -3, /* (185) expr ::= expr PLUS|MINUS expr */
+ -3, /* (186) expr ::= expr STAR|SLASH|REM expr */
+ -3, /* (187) expr ::= expr CONCAT expr */
+ -2, /* (188) likeop ::= NOT LIKE_KW|MATCH */
+ -3, /* (189) expr ::= expr likeop expr */
+ -5, /* (190) expr ::= expr likeop expr ESCAPE expr */
+ -2, /* (191) expr ::= expr ISNULL|NOTNULL */
+ -3, /* (192) expr ::= expr NOT NULL */
+ -3, /* (193) expr ::= expr IS expr */
+ -4, /* (194) expr ::= expr IS NOT expr */
+ -2, /* (195) expr ::= NOT expr */
+ -2, /* (196) expr ::= BITNOT expr */
+ -2, /* (197) expr ::= PLUS|MINUS expr */
+ -1, /* (198) between_op ::= BETWEEN */
+ -2, /* (199) between_op ::= NOT BETWEEN */
+ -5, /* (200) expr ::= expr between_op expr AND expr */
+ -1, /* (201) in_op ::= IN */
+ -2, /* (202) in_op ::= NOT IN */
+ -5, /* (203) expr ::= expr in_op LP exprlist RP */
+ -3, /* (204) expr ::= LP select RP */
+ -5, /* (205) expr ::= expr in_op LP select RP */
+ -5, /* (206) expr ::= expr in_op nm dbnm paren_exprlist */
+ -4, /* (207) expr ::= EXISTS LP select RP */
+ -5, /* (208) expr ::= CASE case_operand case_exprlist case_else END */
+ -5, /* (209) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ -4, /* (210) case_exprlist ::= WHEN expr THEN expr */
+ -2, /* (211) case_else ::= ELSE expr */
+ 0, /* (212) case_else ::= */
+ -1, /* (213) case_operand ::= expr */
+ 0, /* (214) case_operand ::= */
+ 0, /* (215) exprlist ::= */
+ -3, /* (216) nexprlist ::= nexprlist COMMA expr */
+ -1, /* (217) nexprlist ::= expr */
+ 0, /* (218) paren_exprlist ::= */
+ -3, /* (219) paren_exprlist ::= LP exprlist RP */
+ -12, /* (220) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ -1, /* (221) uniqueflag ::= UNIQUE */
+ 0, /* (222) uniqueflag ::= */
+ 0, /* (223) eidlist_opt ::= */
+ -3, /* (224) eidlist_opt ::= LP eidlist RP */
+ -5, /* (225) eidlist ::= eidlist COMMA nm collate sortorder */
+ -3, /* (226) eidlist ::= nm collate sortorder */
+ 0, /* (227) collate ::= */
+ -2, /* (228) collate ::= COLLATE ID|STRING */
+ -4, /* (229) cmd ::= DROP INDEX ifexists fullname */
+ -2, /* (230) cmd ::= VACUUM vinto */
+ -3, /* (231) cmd ::= VACUUM nm vinto */
+ -2, /* (232) vinto ::= INTO expr */
+ 0, /* (233) vinto ::= */
+ -3, /* (234) cmd ::= PRAGMA nm dbnm */
+ -5, /* (235) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ -6, /* (236) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ -5, /* (237) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ -6, /* (238) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ -2, /* (239) plus_num ::= PLUS INTEGER|FLOAT */
+ -2, /* (240) minus_num ::= MINUS INTEGER|FLOAT */
+ -5, /* (241) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ -11, /* (242) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ -1, /* (243) trigger_time ::= BEFORE|AFTER */
+ -2, /* (244) trigger_time ::= INSTEAD OF */
+ 0, /* (245) trigger_time ::= */
+ -1, /* (246) trigger_event ::= DELETE|INSERT */
+ -1, /* (247) trigger_event ::= UPDATE */
+ -3, /* (248) trigger_event ::= UPDATE OF idlist */
+ 0, /* (249) when_clause ::= */
+ -2, /* (250) when_clause ::= WHEN expr */
+ -3, /* (251) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ -2, /* (252) trigger_cmd_list ::= trigger_cmd SEMI */
+ -3, /* (253) trnm ::= nm DOT nm */
+ -3, /* (254) tridxby ::= INDEXED BY nm */
+ -2, /* (255) tridxby ::= NOT INDEXED */
+ -8, /* (256) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+ -8, /* (257) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ -6, /* (258) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ -3, /* (259) trigger_cmd ::= scanpt select scanpt */
+ -4, /* (260) expr ::= RAISE LP IGNORE RP */
+ -6, /* (261) expr ::= RAISE LP raisetype COMMA nm RP */
+ -1, /* (262) raisetype ::= ROLLBACK */
+ -1, /* (263) raisetype ::= ABORT */
+ -1, /* (264) raisetype ::= FAIL */
+ -4, /* (265) cmd ::= DROP TRIGGER ifexists fullname */
+ -6, /* (266) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ -3, /* (267) cmd ::= DETACH database_kw_opt expr */
+ 0, /* (268) key_opt ::= */
+ -2, /* (269) key_opt ::= KEY expr */
+ -1, /* (270) cmd ::= REINDEX */
+ -3, /* (271) cmd ::= REINDEX nm dbnm */
+ -1, /* (272) cmd ::= ANALYZE */
+ -3, /* (273) cmd ::= ANALYZE nm dbnm */
+ -6, /* (274) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ -7, /* (275) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ -1, /* (276) add_column_fullname ::= fullname */
+ -8, /* (277) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ -1, /* (278) cmd ::= create_vtab */
+ -4, /* (279) cmd ::= create_vtab LP vtabarglist RP */
+ -8, /* (280) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ 0, /* (281) vtabarg ::= */
+ -1, /* (282) vtabargtoken ::= ANY */
+ -3, /* (283) vtabargtoken ::= lp anylist RP */
+ -1, /* (284) lp ::= LP */
+ -2, /* (285) with ::= WITH wqlist */
+ -3, /* (286) with ::= WITH RECURSIVE wqlist */
+ -6, /* (287) wqlist ::= nm eidlist_opt AS LP select RP */
+ -8, /* (288) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ -1, /* (289) windowdefn_list ::= windowdefn */
+ -3, /* (290) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ -5, /* (291) windowdefn ::= nm AS LP window RP */
+ -5, /* (292) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+ -6, /* (293) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+ -4, /* (294) window ::= ORDER BY sortlist frame_opt */
+ -5, /* (295) window ::= nm ORDER BY sortlist frame_opt */
+ -1, /* (296) window ::= frame_opt */
+ -2, /* (297) window ::= nm frame_opt */
+ 0, /* (298) frame_opt ::= */
+ -3, /* (299) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+ -6, /* (300) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+ -1, /* (301) range_or_rows ::= RANGE|ROWS|GROUPS */
+ -1, /* (302) frame_bound_s ::= frame_bound */
+ -2, /* (303) frame_bound_s ::= UNBOUNDED PRECEDING */
+ -1, /* (304) frame_bound_e ::= frame_bound */
+ -2, /* (305) frame_bound_e ::= UNBOUNDED FOLLOWING */
+ -2, /* (306) frame_bound ::= expr PRECEDING|FOLLOWING */
+ -2, /* (307) frame_bound ::= CURRENT ROW */
+ 0, /* (308) frame_exclude_opt ::= */
+ -2, /* (309) frame_exclude_opt ::= EXCLUDE frame_exclude */
+ -2, /* (310) frame_exclude ::= NO OTHERS */
+ -2, /* (311) frame_exclude ::= CURRENT ROW */
+ -1, /* (312) frame_exclude ::= GROUP|TIES */
+ -2, /* (313) window_clause ::= WINDOW windowdefn_list */
+ -5, /* (314) over_clause ::= filter_opt OVER LP window RP */
+ -3, /* (315) over_clause ::= filter_opt OVER nm */
+ 0, /* (316) filter_opt ::= */
+ -5, /* (317) filter_opt ::= FILTER LP WHERE expr RP */
+ -1, /* (318) input ::= cmdlist */
+ -2, /* (319) cmdlist ::= cmdlist ecmd */
+ -1, /* (320) cmdlist ::= ecmd */
+ -1, /* (321) ecmd ::= SEMI */
+ -2, /* (322) ecmd ::= cmdx SEMI */
+ -2, /* (323) ecmd ::= explain cmdx */
+ 0, /* (324) trans_opt ::= */
+ -1, /* (325) trans_opt ::= TRANSACTION */
+ -2, /* (326) trans_opt ::= TRANSACTION nm */
+ -1, /* (327) savepoint_opt ::= SAVEPOINT */
+ 0, /* (328) savepoint_opt ::= */
+ -2, /* (329) cmd ::= create_table create_table_args */
+ -4, /* (330) columnlist ::= columnlist COMMA columnname carglist */
+ -2, /* (331) columnlist ::= columnname carglist */
+ -1, /* (332) nm ::= ID|INDEXED */
+ -1, /* (333) nm ::= STRING */
+ -1, /* (334) nm ::= JOIN_KW */
+ -1, /* (335) typetoken ::= typename */
+ -1, /* (336) typename ::= ID|STRING */
+ -1, /* (337) signed ::= plus_num */
+ -1, /* (338) signed ::= minus_num */
+ -2, /* (339) carglist ::= carglist ccons */
+ 0, /* (340) carglist ::= */
+ -2, /* (341) ccons ::= NULL onconf */
+ -2, /* (342) conslist_opt ::= COMMA conslist */
+ -3, /* (343) conslist ::= conslist tconscomma tcons */
+ -1, /* (344) conslist ::= tcons */
+ 0, /* (345) tconscomma ::= */
+ -1, /* (346) defer_subclause_opt ::= defer_subclause */
+ -1, /* (347) resolvetype ::= raisetype */
+ -1, /* (348) selectnowith ::= oneselect */
+ -1, /* (349) oneselect ::= values */
+ -2, /* (350) sclp ::= selcollist COMMA */
+ -1, /* (351) as ::= ID|STRING */
+ -1, /* (352) expr ::= term */
+ -1, /* (353) likeop ::= LIKE_KW|MATCH */
+ -1, /* (354) exprlist ::= nexprlist */
+ -1, /* (355) nmnum ::= plus_num */
+ -1, /* (356) nmnum ::= nm */
+ -1, /* (357) nmnum ::= ON */
+ -1, /* (358) nmnum ::= DELETE */
+ -1, /* (359) nmnum ::= DEFAULT */
+ -1, /* (360) plus_num ::= INTEGER|FLOAT */
+ 0, /* (361) foreach_clause ::= */
+ -3, /* (362) foreach_clause ::= FOR EACH ROW */
+ -1, /* (363) trnm ::= nm */
+ 0, /* (364) tridxby ::= */
+ -1, /* (365) database_kw_opt ::= DATABASE */
+ 0, /* (366) database_kw_opt ::= */
+ 0, /* (367) kwcolumn_opt ::= */
+ -1, /* (368) kwcolumn_opt ::= COLUMNKW */
+ -1, /* (369) vtabarglist ::= vtabarg */
+ -3, /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */
+ -2, /* (371) vtabarg ::= vtabarg vtabargtoken */
+ 0, /* (372) anylist ::= */
+ -4, /* (373) anylist ::= anylist LP anylist RP */
+ -2, /* (374) anylist ::= anylist ANY */
+ 0, /* (375) with ::= */
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -148587,7 +151835,7 @@ static YYACTIONTYPE yy_reduce(
yymsp = yypParser->yytos;
#ifndef NDEBUG
if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- yysize = yyRuleInfo[yyruleno].nrhs;
+ yysize = yyRuleInfoNRhs[yyruleno];
if( yysize ){
fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
yyTracePrompt,
@@ -148602,7 +151850,7 @@ static YYACTIONTYPE yy_reduce(
/* Check that the stack is large enough to grow by a single entry
** if the RHS of the rule is empty. This ensures that there is room
** enough on the stack to push the LHS value */
- if( yyRuleInfo[yyruleno].nrhs==0 ){
+ if( yyRuleInfoNRhs[yyruleno]==0 ){
#ifdef YYTRACKMAXSTACKDEPTH
if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
yypParser->yyhwm++;
@@ -148652,15 +151900,16 @@ static YYACTIONTYPE yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy100);}
break;
case 4: /* transtype ::= */
-{yymsp[1].minor.yy70 = TK_DEFERRED;}
+{yymsp[1].minor.yy100 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
-{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/}
+ case 301: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==301);
+{yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* cmd ::= COMMIT|END trans_opt */
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
@@ -148683,7 +151932,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.yy70,0,0,yymsp[-2].minor.yy70);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy100,0,0,yymsp[-2].minor.yy100);
}
break;
case 14: /* createkw ::= CREATE */
@@ -148692,38 +151941,38 @@ static YYACTIONTYPE yy_reduce(
case 15: /* ifnotexists ::= */
case 18: /* temp ::= */ yytestcase(yyruleno==18);
case 21: /* table_options ::= */ yytestcase(yyruleno==21);
- case 42: /* autoinc ::= */ yytestcase(yyruleno==42);
- case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
- case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
- case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
- case 93: /* distinct ::= */ yytestcase(yyruleno==93);
- case 226: /* collate ::= */ yytestcase(yyruleno==226);
-{yymsp[1].minor.yy70 = 0;}
+ case 43: /* autoinc ::= */ yytestcase(yyruleno==43);
+ case 58: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==58);
+ case 68: /* defer_subclause_opt ::= */ yytestcase(yyruleno==68);
+ case 77: /* ifexists ::= */ yytestcase(yyruleno==77);
+ case 94: /* distinct ::= */ yytestcase(yyruleno==94);
+ case 227: /* collate ::= */ yytestcase(yyruleno==227);
+{yymsp[1].minor.yy100 = 0;}
break;
case 16: /* ifnotexists ::= IF NOT EXISTS */
-{yymsp[-2].minor.yy70 = 1;}
+{yymsp[-2].minor.yy100 = 1;}
break;
case 17: /* temp ::= TEMP */
- case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
-{yymsp[0].minor.yy70 = 1;}
+ case 44: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==44);
+{yymsp[0].minor.yy100 = 1;}
break;
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy70,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy100,0);
}
break;
case 20: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy391);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy391);
}
break;
case 22: /* table_options ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yymsp[-1].minor.yy70 = TF_WithoutRowid | TF_NoVisibleRowid;
+ yymsp[-1].minor.yy100 = TF_WithoutRowid | TF_NoVisibleRowid;
}else{
- yymsp[-1].minor.yy70 = 0;
+ yymsp[-1].minor.yy100 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -148732,8 +151981,8 @@ static YYACTIONTYPE yy_reduce(
{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 24: /* typetoken ::= */
- case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60);
- case 99: /* as ::= */ yytestcase(yyruleno==99);
+ case 61: /* conslist_opt ::= */ yytestcase(yyruleno==61);
+ case 100: /* as ::= */ yytestcase(yyruleno==100);
{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
break;
case 25: /* typetoken ::= typename LP signed RP */
@@ -148752,29 +152001,35 @@ static YYACTIONTYPE yy_reduce(
case 28: /* scanpt ::= */
{
assert( yyLookahead!=YYNOCODE );
- yymsp[1].minor.yy392 = yyLookaheadToken.z;
+ yymsp[1].minor.yy528 = yyLookaheadToken.z;
+}
+ break;
+ case 29: /* scantok ::= */
+{
+ assert( yyLookahead!=YYNOCODE );
+ yymsp[1].minor.yy0 = yyLookaheadToken;
}
break;
- case 29: /* ccons ::= CONSTRAINT nm */
- case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62);
+ case 30: /* ccons ::= CONSTRAINT nm */
+ case 63: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==63);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
- case 30: /* ccons ::= DEFAULT scanpt term scanpt */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);}
+ case 31: /* ccons ::= DEFAULT scantok term */
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy102,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
- case 31: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
+ case 32: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy102,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
break;
- case 32: /* ccons ::= DEFAULT PLUS term scanpt */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);}
+ case 33: /* ccons ::= DEFAULT PLUS scantok term */
+{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy102,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
- case 33: /* ccons ::= DEFAULT MINUS term scanpt */
+ case 34: /* ccons ::= DEFAULT MINUS scantok term */
{
- Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0);
- sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy102, 0);
+ sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
}
break;
- case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */
+ case 35: /* ccons ::= DEFAULT scantok ID|INDEXED */
{
Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
if( p ){
@@ -148784,171 +152039,171 @@ static YYACTIONTYPE yy_reduce(
sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
}
break;
- case 35: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy70);}
+ case 36: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy100);}
break;
- case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);}
+ case 37: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy100,yymsp[0].minor.yy100,yymsp[-2].minor.yy100);}
break;
- case 37: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0,
+ case 38: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy100,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
- case 38: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);}
+ case 39: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy102);}
break;
- case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);}
+ case 40: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy94,yymsp[0].minor.yy100);}
break;
- case 40: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);}
+ case 41: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy100);}
break;
- case 41: /* ccons ::= COLLATE ID|STRING */
+ case 42: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 44: /* refargs ::= */
-{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */}
+ case 45: /* refargs ::= */
+{ yymsp[1].minor.yy100 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
- case 45: /* refargs ::= refargs refarg */
-{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; }
+ case 46: /* refargs ::= refargs refarg */
+{ yymsp[-1].minor.yy100 = (yymsp[-1].minor.yy100 & ~yymsp[0].minor.yy199.mask) | yymsp[0].minor.yy199.value; }
break;
- case 46: /* refarg ::= MATCH nm */
-{ yymsp[-1].minor.yy111.value = 0; yymsp[-1].minor.yy111.mask = 0x000000; }
+ case 47: /* refarg ::= MATCH nm */
+{ yymsp[-1].minor.yy199.value = 0; yymsp[-1].minor.yy199.mask = 0x000000; }
break;
- case 47: /* refarg ::= ON INSERT refact */
-{ yymsp[-2].minor.yy111.value = 0; yymsp[-2].minor.yy111.mask = 0x000000; }
+ case 48: /* refarg ::= ON INSERT refact */
+{ yymsp[-2].minor.yy199.value = 0; yymsp[-2].minor.yy199.mask = 0x000000; }
break;
- case 48: /* refarg ::= ON DELETE refact */
-{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70; yymsp[-2].minor.yy111.mask = 0x0000ff; }
+ case 49: /* refarg ::= ON DELETE refact */
+{ yymsp[-2].minor.yy199.value = yymsp[0].minor.yy100; yymsp[-2].minor.yy199.mask = 0x0000ff; }
break;
- case 49: /* refarg ::= ON UPDATE refact */
-{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8; yymsp[-2].minor.yy111.mask = 0x00ff00; }
+ case 50: /* refarg ::= ON UPDATE refact */
+{ yymsp[-2].minor.yy199.value = yymsp[0].minor.yy100<<8; yymsp[-2].minor.yy199.mask = 0x00ff00; }
break;
- case 50: /* refact ::= SET NULL */
-{ yymsp[-1].minor.yy70 = OE_SetNull; /* EV: R-33326-45252 */}
+ case 51: /* refact ::= SET NULL */
+{ yymsp[-1].minor.yy100 = OE_SetNull; /* EV: R-33326-45252 */}
break;
- case 51: /* refact ::= SET DEFAULT */
-{ yymsp[-1].minor.yy70 = OE_SetDflt; /* EV: R-33326-45252 */}
+ case 52: /* refact ::= SET DEFAULT */
+{ yymsp[-1].minor.yy100 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
- case 52: /* refact ::= CASCADE */
-{ yymsp[0].minor.yy70 = OE_Cascade; /* EV: R-33326-45252 */}
+ case 53: /* refact ::= CASCADE */
+{ yymsp[0].minor.yy100 = OE_Cascade; /* EV: R-33326-45252 */}
break;
- case 53: /* refact ::= RESTRICT */
-{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */}
+ case 54: /* refact ::= RESTRICT */
+{ yymsp[0].minor.yy100 = OE_Restrict; /* EV: R-33326-45252 */}
break;
- case 54: /* refact ::= NO ACTION */
-{ yymsp[-1].minor.yy70 = OE_None; /* EV: R-33326-45252 */}
+ case 55: /* refact ::= NO ACTION */
+{ yymsp[-1].minor.yy100 = OE_None; /* EV: R-33326-45252 */}
break;
- case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-{yymsp[-2].minor.yy70 = 0;}
+ case 56: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+{yymsp[-2].minor.yy100 = 0;}
break;
- case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
- case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156);
-{yymsp[-1].minor.yy70 = yymsp[0].minor.yy70;}
+ case 57: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 72: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==72);
+ case 157: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==157);
+{yymsp[-1].minor.yy100 = yymsp[0].minor.yy100;}
break;
- case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
- case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
- case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198);
- case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201);
- case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227);
-{yymsp[-1].minor.yy70 = 1;}
+ case 59: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ case 76: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==76);
+ case 199: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==199);
+ case 202: /* in_op ::= NOT IN */ yytestcase(yyruleno==202);
+ case 228: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==228);
+{yymsp[-1].minor.yy100 = 1;}
break;
- case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
-{yymsp[-1].minor.yy70 = 0;}
+ case 60: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+{yymsp[-1].minor.yy100 = 0;}
break;
- case 61: /* tconscomma ::= COMMA */
+ case 62: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
- case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy420,yymsp[0].minor.yy70,yymsp[-2].minor.yy70,0);}
+ case 64: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy94,yymsp[0].minor.yy100,yymsp[-2].minor.yy100,0);}
break;
- case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy420,yymsp[0].minor.yy70,0,0,0,0,
+ case 65: /* tcons ::= UNIQUE LP sortlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy94,yymsp[0].minor.yy100,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
- case 65: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);}
+ case 66: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy102);}
break;
- case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ case 67: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy94, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy94, yymsp[-1].minor.yy100);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy100);
}
break;
- case 68: /* onconf ::= */
- case 70: /* orconf ::= */ yytestcase(yyruleno==70);
-{yymsp[1].minor.yy70 = OE_Default;}
+ case 69: /* onconf ::= */
+ case 71: /* orconf ::= */ yytestcase(yyruleno==71);
+{yymsp[1].minor.yy100 = OE_Default;}
break;
- case 69: /* onconf ::= ON CONFLICT resolvetype */
-{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;}
+ case 70: /* onconf ::= ON CONFLICT resolvetype */
+{yymsp[-2].minor.yy100 = yymsp[0].minor.yy100;}
break;
- case 72: /* resolvetype ::= IGNORE */
-{yymsp[0].minor.yy70 = OE_Ignore;}
+ case 73: /* resolvetype ::= IGNORE */
+{yymsp[0].minor.yy100 = OE_Ignore;}
break;
- case 73: /* resolvetype ::= REPLACE */
- case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157);
-{yymsp[0].minor.yy70 = OE_Replace;}
+ case 74: /* resolvetype ::= REPLACE */
+ case 158: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==158);
+{yymsp[0].minor.yy100 = OE_Replace;}
break;
- case 74: /* cmd ::= DROP TABLE ifexists fullname */
+ case 75: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy407, 0, yymsp[-1].minor.yy100);
}
break;
- case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ case 78: /* 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.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy94, yymsp[0].minor.yy391, yymsp[-7].minor.yy100, yymsp[-5].minor.yy100);
}
break;
- case 78: /* cmd ::= DROP VIEW ifexists fullname */
+ case 79: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy407, 1, yymsp[-1].minor.yy100);
}
break;
- case 79: /* cmd ::= select */
+ case 80: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy489, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489);
+ sqlite3Select(pParse, yymsp[0].minor.yy391, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy391);
}
break;
- case 80: /* select ::= WITH wqlist selectnowith */
+ case 81: /* select ::= WITH wqlist selectnowith */
{
- Select *p = yymsp[0].minor.yy489;
+ Select *p = yymsp[0].minor.yy391;
if( p ){
- p->pWith = yymsp[-1].minor.yy449;
+ p->pWith = yymsp[-1].minor.yy243;
parserDoubleLinkSelect(pParse, p);
}else{
- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy243);
}
- yymsp[-2].minor.yy489 = p;
+ yymsp[-2].minor.yy391 = p;
}
break;
- case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */
+ case 82: /* select ::= WITH RECURSIVE wqlist selectnowith */
{
- Select *p = yymsp[0].minor.yy489;
+ Select *p = yymsp[0].minor.yy391;
if( p ){
- p->pWith = yymsp[-1].minor.yy449;
+ p->pWith = yymsp[-1].minor.yy243;
parserDoubleLinkSelect(pParse, p);
}else{
- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449);
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy243);
}
- yymsp[-3].minor.yy489 = p;
+ yymsp[-3].minor.yy391 = p;
}
break;
- case 82: /* select ::= selectnowith */
+ case 83: /* select ::= selectnowith */
{
- Select *p = yymsp[0].minor.yy489;
+ Select *p = yymsp[0].minor.yy391;
if( p ){
parserDoubleLinkSelect(pParse, p);
}
- yymsp[0].minor.yy489 = p; /*A-overwrites-X*/
+ yymsp[0].minor.yy391 = p; /*A-overwrites-X*/
}
break;
- case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */
+ case 84: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
- Select *pRhs = yymsp[0].minor.yy489;
- Select *pLhs = yymsp[-2].minor.yy489;
+ Select *pRhs = yymsp[0].minor.yy391;
+ Select *pLhs = yymsp[-2].minor.yy391;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
@@ -148958,341 +152213,349 @@ static YYACTIONTYPE yy_reduce(
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
- pRhs->op = (u8)yymsp[-1].minor.yy70;
+ pRhs->op = (u8)yymsp[-1].minor.yy100;
pRhs->pPrior = pLhs;
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
pRhs->selFlags &= ~SF_MultiValue;
- if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1;
+ if( yymsp[-1].minor.yy100!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, pLhs);
}
- yymsp[-2].minor.yy489 = pRhs;
+ yymsp[-2].minor.yy391 = pRhs;
}
break;
- case 84: /* multiselect_op ::= UNION */
- case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86);
-{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/}
+ case 85: /* multiselect_op ::= UNION */
+ case 87: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==87);
+{yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-OP*/}
break;
- case 85: /* multiselect_op ::= UNION ALL */
-{yymsp[-1].minor.yy70 = TK_ALL;}
+ case 86: /* multiselect_op ::= UNION ALL */
+{yymsp[-1].minor.yy100 = TK_ALL;}
break;
- case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
- yymsp[-8].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy420,yymsp[-5].minor.yy135,yymsp[-4].minor.yy18,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[-7].minor.yy70,yymsp[0].minor.yy18);
+ yymsp[-8].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy94,yymsp[-5].minor.yy407,yymsp[-4].minor.yy102,yymsp[-3].minor.yy94,yymsp[-2].minor.yy102,yymsp[-1].minor.yy94,yymsp[-7].minor.yy100,yymsp[0].minor.yy102);
}
break;
- case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
+ case 89: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
{
- yymsp[-9].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy420,yymsp[-6].minor.yy135,yymsp[-5].minor.yy18,yymsp[-4].minor.yy420,yymsp[-3].minor.yy18,yymsp[-1].minor.yy420,yymsp[-8].minor.yy70,yymsp[0].minor.yy18);
- if( yymsp[-9].minor.yy489 ){
- yymsp[-9].minor.yy489->pWinDefn = yymsp[-2].minor.yy327;
+ yymsp[-9].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy94,yymsp[-6].minor.yy407,yymsp[-5].minor.yy102,yymsp[-4].minor.yy94,yymsp[-3].minor.yy102,yymsp[-1].minor.yy94,yymsp[-8].minor.yy100,yymsp[0].minor.yy102);
+ if( yymsp[-9].minor.yy391 ){
+ yymsp[-9].minor.yy391->pWinDefn = yymsp[-2].minor.yy379;
}else{
- sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327);
+ sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy379);
}
}
break;
- case 89: /* values ::= VALUES LP nexprlist RP */
+ case 90: /* values ::= VALUES LP nexprlist RP */
{
- yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0);
+ yymsp[-3].minor.yy391 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy94,0,0,0,0,0,SF_Values,0);
}
break;
- case 90: /* values ::= values COMMA LP nexprlist RP */
+ case 91: /* values ::= values COMMA LP nexprlist RP */
{
- Select *pRight, *pLeft = yymsp[-4].minor.yy489;
- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0);
+ Select *pRight, *pLeft = yymsp[-4].minor.yy391;
+ pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy94,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.yy489 = pRight;
+ yymsp[-4].minor.yy391 = pRight;
}else{
- yymsp[-4].minor.yy489 = pLeft;
+ yymsp[-4].minor.yy391 = pLeft;
}
}
break;
- case 91: /* distinct ::= DISTINCT */
-{yymsp[0].minor.yy70 = SF_Distinct;}
+ case 92: /* distinct ::= DISTINCT */
+{yymsp[0].minor.yy100 = SF_Distinct;}
break;
- case 92: /* distinct ::= ALL */
-{yymsp[0].minor.yy70 = SF_All;}
+ case 93: /* distinct ::= ALL */
+{yymsp[0].minor.yy100 = SF_All;}
break;
- case 94: /* sclp ::= */
- case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127);
- case 134: /* groupby_opt ::= */ yytestcase(yyruleno==134);
- case 214: /* exprlist ::= */ yytestcase(yyruleno==214);
- case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217);
- case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222);
-{yymsp[1].minor.yy420 = 0;}
+ case 95: /* sclp ::= */
+ case 128: /* orderby_opt ::= */ yytestcase(yyruleno==128);
+ case 135: /* groupby_opt ::= */ yytestcase(yyruleno==135);
+ case 215: /* exprlist ::= */ yytestcase(yyruleno==215);
+ case 218: /* paren_exprlist ::= */ yytestcase(yyruleno==218);
+ case 223: /* eidlist_opt ::= */ yytestcase(yyruleno==223);
+{yymsp[1].minor.yy94 = 0;}
break;
- case 95: /* selcollist ::= sclp scanpt expr scanpt as */
+ case 96: /* selcollist ::= sclp scanpt expr scanpt as */
{
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy420,yymsp[-3].minor.yy392,yymsp[-1].minor.yy392);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy94, yymsp[-2].minor.yy102);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy94, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy94,yymsp[-3].minor.yy528,yymsp[-1].minor.yy528);
}
break;
- case 96: /* selcollist ::= sclp scanpt STAR */
+ case 97: /* selcollist ::= sclp scanpt STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
- yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p);
+ yymsp[-2].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy94, p);
}
break;
- case 97: /* selcollist ::= sclp scanpt nm DOT STAR */
+ case 98: /* selcollist ::= sclp scanpt nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, pDot);
}
break;
- case 98: /* as ::= AS nm */
- case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109);
- case 236: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==236);
- case 237: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==237);
+ case 99: /* as ::= AS nm */
+ case 110: /* dbnm ::= DOT nm */ yytestcase(yyruleno==110);
+ case 239: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==239);
+ case 240: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==240);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 100: /* from ::= */
-{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));}
+ case 101: /* from ::= */
+{yymsp[1].minor.yy407 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy407));}
break;
- case 101: /* from ::= FROM seltablist */
+ case 102: /* from ::= FROM seltablist */
{
- yymsp[-1].minor.yy135 = yymsp[0].minor.yy135;
- sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135);
+ yymsp[-1].minor.yy407 = yymsp[0].minor.yy407;
+ sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy407);
}
break;
- case 102: /* stl_prefix ::= seltablist joinop */
+ case 103: /* stl_prefix ::= seltablist joinop */
{
- if( ALWAYS(yymsp[-1].minor.yy135 && yymsp[-1].minor.yy135->nSrc>0) ) yymsp[-1].minor.yy135->a[yymsp[-1].minor.yy135->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy70;
+ if( ALWAYS(yymsp[-1].minor.yy407 && yymsp[-1].minor.yy407->nSrc>0) ) yymsp[-1].minor.yy407->a[yymsp[-1].minor.yy407->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy100;
}
break;
- case 103: /* stl_prefix ::= */
-{yymsp[1].minor.yy135 = 0;}
+ case 104: /* stl_prefix ::= */
+{yymsp[1].minor.yy407 = 0;}
break;
- case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ case 105: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
- yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
- sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-2].minor.yy0);
+ yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy407, &yymsp[-2].minor.yy0);
}
break;
- case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ case 106: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
{
- yymsp[-8].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy135,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
- sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy135, yymsp[-4].minor.yy420);
+ yymsp[-8].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy407,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+ sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy407, yymsp[-4].minor.yy94);
}
break;
- case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ case 107: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
- yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy489,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+ yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy391,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
}
break;
- case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ case 108: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
- if( yymsp[-6].minor.yy135==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy18==0 && yymsp[0].minor.yy48==0 ){
- yymsp[-6].minor.yy135 = yymsp[-4].minor.yy135;
- }else if( yymsp[-4].minor.yy135->nSrc==1 ){
- yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
- if( yymsp[-6].minor.yy135 ){
- struct SrcList_item *pNew = &yymsp[-6].minor.yy135->a[yymsp[-6].minor.yy135->nSrc-1];
- struct SrcList_item *pOld = yymsp[-4].minor.yy135->a;
+ if( yymsp[-6].minor.yy407==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy102==0 && yymsp[0].minor.yy76==0 ){
+ yymsp[-6].minor.yy407 = yymsp[-4].minor.yy407;
+ }else if( yymsp[-4].minor.yy407->nSrc==1 ){
+ yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
+ if( yymsp[-6].minor.yy407 ){
+ struct SrcList_item *pNew = &yymsp[-6].minor.yy407->a[yymsp[-6].minor.yy407->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy407->a;
pNew->zName = pOld->zName;
pNew->zDatabase = pOld->zDatabase;
pNew->pSelect = pOld->pSelect;
+ if( pOld->fg.isTabFunc ){
+ pNew->u1.pFuncArg = pOld->u1.pFuncArg;
+ pOld->u1.pFuncArg = 0;
+ pOld->fg.isTabFunc = 0;
+ pNew->fg.isTabFunc = 1;
+ }
pOld->zName = pOld->zDatabase = 0;
pOld->pSelect = 0;
}
- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135);
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy407);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy135);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy135,0,0,0,0,SF_NestedFrom,0);
- yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy18,yymsp[0].minor.yy48);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy407);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy407,0,0,0,0,SF_NestedFrom,0);
+ yymsp[-6].minor.yy407 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy407,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy102,yymsp[0].minor.yy76);
}
}
break;
- case 108: /* dbnm ::= */
- case 122: /* indexed_opt ::= */ yytestcase(yyruleno==122);
+ case 109: /* dbnm ::= */
+ case 123: /* indexed_opt ::= */ yytestcase(yyruleno==123);
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
break;
- case 110: /* fullname ::= nm */
+ case 111: /* fullname ::= nm */
{
- yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0);
- if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy407 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy407->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[0].minor.yy135 = yylhsminor.yy135;
+ yymsp[0].minor.yy407 = yylhsminor.yy407;
break;
- case 111: /* fullname ::= nm DOT nm */
+ case 112: /* fullname ::= nm DOT nm */
{
- yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
- if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0);
+ yylhsminor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ if( IN_RENAME_OBJECT && yylhsminor.yy407 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy407->a[0].zName, &yymsp[0].minor.yy0);
}
- yymsp[-2].minor.yy135 = yylhsminor.yy135;
+ yymsp[-2].minor.yy407 = yylhsminor.yy407;
break;
- case 112: /* xfullname ::= nm */
-{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
+ case 113: /* xfullname ::= nm */
+{yymsp[0].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
break;
- case 113: /* xfullname ::= nm DOT nm */
-{yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 114: /* xfullname ::= nm DOT nm */
+{yymsp[-2].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 114: /* xfullname ::= nm DOT nm AS nm */
+ case 115: /* xfullname ::= nm DOT nm AS nm */
{
- yymsp[-4].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
- if( yymsp[-4].minor.yy135 ) yymsp[-4].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-4].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
+ if( yymsp[-4].minor.yy407 ) yymsp[-4].minor.yy407->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
- case 115: /* xfullname ::= nm AS nm */
+ case 116: /* xfullname ::= nm AS nm */
{
- yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
- if( yymsp[-2].minor.yy135 ) yymsp[-2].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
+ yymsp[-2].minor.yy407 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
+ if( yymsp[-2].minor.yy407 ) yymsp[-2].minor.yy407->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
- case 116: /* joinop ::= COMMA|JOIN */
-{ yymsp[0].minor.yy70 = JT_INNER; }
+ case 117: /* joinop ::= COMMA|JOIN */
+{ yymsp[0].minor.yy100 = JT_INNER; }
break;
- case 117: /* joinop ::= JOIN_KW JOIN */
-{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
+ case 118: /* joinop ::= JOIN_KW JOIN */
+{yymsp[-1].minor.yy100 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
break;
- case 118: /* joinop ::= JOIN_KW nm JOIN */
-{yymsp[-2].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
+ case 119: /* joinop ::= JOIN_KW nm JOIN */
+{yymsp[-2].minor.yy100 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
break;
- case 119: /* joinop ::= JOIN_KW nm nm JOIN */
-{yymsp[-3].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+ case 120: /* joinop ::= JOIN_KW nm nm JOIN */
+{yymsp[-3].minor.yy100 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
break;
- case 120: /* on_opt ::= ON expr */
- case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137);
- case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144);
- case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210);
-{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;}
+ case 121: /* on_opt ::= ON expr */
+ case 138: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==138);
+ case 145: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==145);
+ case 211: /* case_else ::= ELSE expr */ yytestcase(yyruleno==211);
+ case 232: /* vinto ::= INTO expr */ yytestcase(yyruleno==232);
+{yymsp[-1].minor.yy102 = yymsp[0].minor.yy102;}
break;
- case 121: /* on_opt ::= */
- case 136: /* having_opt ::= */ yytestcase(yyruleno==136);
- case 138: /* limit_opt ::= */ yytestcase(yyruleno==138);
- case 143: /* where_opt ::= */ yytestcase(yyruleno==143);
- case 211: /* case_else ::= */ yytestcase(yyruleno==211);
- case 213: /* case_operand ::= */ yytestcase(yyruleno==213);
-{yymsp[1].minor.yy18 = 0;}
+ case 122: /* on_opt ::= */
+ case 137: /* having_opt ::= */ yytestcase(yyruleno==137);
+ case 139: /* limit_opt ::= */ yytestcase(yyruleno==139);
+ case 144: /* where_opt ::= */ yytestcase(yyruleno==144);
+ case 212: /* case_else ::= */ yytestcase(yyruleno==212);
+ case 214: /* case_operand ::= */ yytestcase(yyruleno==214);
+ case 233: /* vinto ::= */ yytestcase(yyruleno==233);
+{yymsp[1].minor.yy102 = 0;}
break;
- case 123: /* indexed_opt ::= INDEXED BY nm */
+ case 124: /* indexed_opt ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 124: /* indexed_opt ::= NOT INDEXED */
+ case 125: /* indexed_opt ::= NOT INDEXED */
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
- case 125: /* using_opt ::= USING LP idlist RP */
-{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;}
+ case 126: /* using_opt ::= USING LP idlist RP */
+{yymsp[-3].minor.yy76 = yymsp[-1].minor.yy76;}
break;
- case 126: /* using_opt ::= */
- case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158);
-{yymsp[1].minor.yy48 = 0;}
+ case 127: /* using_opt ::= */
+ case 159: /* idlist_opt ::= */ yytestcase(yyruleno==159);
+{yymsp[1].minor.yy76 = 0;}
break;
- case 128: /* orderby_opt ::= ORDER BY sortlist */
- case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135);
-{yymsp[-2].minor.yy420 = yymsp[0].minor.yy420;}
+ case 129: /* orderby_opt ::= ORDER BY sortlist */
+ case 136: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==136);
+{yymsp[-2].minor.yy94 = yymsp[0].minor.yy94;}
break;
- case 129: /* sortlist ::= sortlist COMMA expr sortorder */
+ case 130: /* sortlist ::= sortlist COMMA expr sortorder */
{
- yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18);
- sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70);
+ yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy94,yymsp[-1].minor.yy102);
+ sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy94,yymsp[0].minor.yy100);
}
break;
- case 130: /* sortlist ::= expr sortorder */
+ case 131: /* sortlist ::= expr sortorder */
{
- yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/
- sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70);
+ yymsp[-1].minor.yy94 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy102); /*A-overwrites-Y*/
+ sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy94,yymsp[0].minor.yy100);
}
break;
- case 131: /* sortorder ::= ASC */
-{yymsp[0].minor.yy70 = SQLITE_SO_ASC;}
+ case 132: /* sortorder ::= ASC */
+{yymsp[0].minor.yy100 = SQLITE_SO_ASC;}
break;
- case 132: /* sortorder ::= DESC */
-{yymsp[0].minor.yy70 = SQLITE_SO_DESC;}
+ case 133: /* sortorder ::= DESC */
+{yymsp[0].minor.yy100 = SQLITE_SO_DESC;}
break;
- case 133: /* sortorder ::= */
-{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;}
+ case 134: /* sortorder ::= */
+{yymsp[1].minor.yy100 = SQLITE_SO_UNDEFINED;}
break;
- case 139: /* limit_opt ::= LIMIT expr */
-{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);}
+ case 140: /* limit_opt ::= LIMIT expr */
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy102,0);}
break;
- case 140: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+ case 141: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
break;
- case 141: /* limit_opt ::= LIMIT expr COMMA expr */
-{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);}
+ case 142: /* limit_opt ::= LIMIT expr COMMA expr */
+{yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy102,yymsp[-2].minor.yy102);}
break;
- case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
+ case 143: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy135, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy135,yymsp[0].minor.yy18,0,0);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy407, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy407,yymsp[0].minor.yy102,0,0);
}
break;
- case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
+ case 146: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy135, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy420,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy135,yymsp[-1].minor.yy420,yymsp[0].minor.yy18,yymsp[-5].minor.yy70,0,0,0);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy407, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy94,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy407,yymsp[-1].minor.yy94,yymsp[0].minor.yy102,yymsp[-5].minor.yy100,0,0,0);
}
break;
- case 146: /* setlist ::= setlist COMMA nm EQ expr */
+ case 147: /* setlist ::= setlist COMMA nm EQ expr */
{
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, 1);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy94, yymsp[0].minor.yy102);
+ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy94, &yymsp[-2].minor.yy0, 1);
}
break;
- case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+ case 148: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
{
- yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+ yymsp[-6].minor.yy94 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy94, yymsp[-3].minor.yy76, yymsp[0].minor.yy102);
}
break;
- case 148: /* setlist ::= nm EQ expr */
+ case 149: /* setlist ::= nm EQ expr */
{
- yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18);
- sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1);
+ yylhsminor.yy94 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy102);
+ sqlite3ExprListSetName(pParse, yylhsminor.yy94, &yymsp[-2].minor.yy0, 1);
}
- yymsp[-2].minor.yy420 = yylhsminor.yy420;
+ yymsp[-2].minor.yy94 = yylhsminor.yy94;
break;
- case 149: /* setlist ::= LP idlist RP EQ expr */
+ case 150: /* setlist ::= LP idlist RP EQ expr */
{
- yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy76, yymsp[0].minor.yy102);
}
break;
- case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
+ case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
{
- sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy407, yymsp[-1].minor.yy391, yymsp[-2].minor.yy76, yymsp[-5].minor.yy100, yymsp[0].minor.yy95);
}
break;
- case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
+ case 152: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */
{
- sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy407, 0, yymsp[-2].minor.yy76, yymsp[-5].minor.yy100, 0);
}
break;
- case 152: /* upsert ::= */
-{ yymsp[1].minor.yy340 = 0; }
+ case 153: /* upsert ::= */
+{ yymsp[1].minor.yy95 = 0; }
break;
- case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
-{ yymsp[-10].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy420,yymsp[-5].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);}
+ case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */
+{ yymsp[-10].minor.yy95 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy94,yymsp[-5].minor.yy102,yymsp[-1].minor.yy94,yymsp[0].minor.yy102);}
break;
- case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
-{ yymsp[-7].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy420,yymsp[-2].minor.yy18,0,0); }
+ case 155: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */
+{ yymsp[-7].minor.yy95 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy94,yymsp[-2].minor.yy102,0,0); }
break;
- case 155: /* upsert ::= ON CONFLICT DO NOTHING */
-{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
+ case 156: /* upsert ::= ON CONFLICT DO NOTHING */
+{ yymsp[-3].minor.yy95 = sqlite3UpsertNew(pParse->db,0,0,0,0); }
break;
- case 159: /* idlist_opt ::= LP idlist RP */
-{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;}
+ case 160: /* idlist_opt ::= LP idlist RP */
+{yymsp[-2].minor.yy76 = yymsp[-1].minor.yy76;}
break;
- case 160: /* idlist ::= idlist COMMA nm */
-{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);}
+ case 161: /* idlist ::= idlist COMMA nm */
+{yymsp[-2].minor.yy76 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy76,&yymsp[0].minor.yy0);}
break;
- case 161: /* idlist ::= nm */
-{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+ case 162: /* idlist ::= nm */
+{yymsp[0].minor.yy76 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
- case 162: /* expr ::= LP expr RP */
-{yymsp[-2].minor.yy18 = yymsp[-1].minor.yy18;}
+ case 163: /* expr ::= LP expr RP */
+{yymsp[-2].minor.yy102 = yymsp[-1].minor.yy102;}
break;
- case 163: /* expr ::= ID|INDEXED */
- case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164);
-{yymsp[0].minor.yy18=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 164: /* expr ::= ID|INDEXED */
+ case 165: /* expr ::= JOIN_KW */ yytestcase(yyruleno==165);
+{yymsp[0].minor.yy102=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 165: /* expr ::= nm DOT nm */
+ case 166: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
@@ -149300,11 +152563,11 @@ static YYACTIONTYPE yy_reduce(
sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0);
sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0);
}
- yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ yylhsminor.yy102 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
- yymsp[-2].minor.yy18 = yylhsminor.yy18;
+ yymsp[-2].minor.yy102 = yylhsminor.yy102;
break;
- case 166: /* expr ::= nm DOT nm DOT nm */
+ case 167: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
@@ -149314,26 +152577,26 @@ static YYACTIONTYPE yy_reduce(
sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0);
sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0);
}
- yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ yylhsminor.yy102 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
- yymsp[-4].minor.yy18 = yylhsminor.yy18;
+ yymsp[-4].minor.yy102 = yylhsminor.yy102;
break;
- case 167: /* term ::= NULL|FLOAT|BLOB */
- case 168: /* term ::= STRING */ yytestcase(yyruleno==168);
-{yymsp[0].minor.yy18=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 168: /* term ::= NULL|FLOAT|BLOB */
+ case 169: /* term ::= STRING */ yytestcase(yyruleno==169);
+{yymsp[0].minor.yy102=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 169: /* term ::= INTEGER */
+ case 170: /* term ::= INTEGER */
{
- yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+ yylhsminor.yy102 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
}
- yymsp[0].minor.yy18 = yylhsminor.yy18;
+ yymsp[0].minor.yy102 = yylhsminor.yy102;
break;
- case 170: /* expr ::= VARIABLE */
+ case 171: /* 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.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n);
+ yymsp[0].minor.yy102 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy102, 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
@@ -149342,154 +152605,156 @@ static YYACTIONTYPE yy_reduce(
assert( t.n>=2 );
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
- yymsp[0].minor.yy18 = 0;
+ yymsp[0].minor.yy102 = 0;
}else{
- yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
- if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable);
+ yymsp[0].minor.yy102 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+ if( yymsp[0].minor.yy102 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy102->iTable);
}
}
}
break;
- case 171: /* expr ::= expr COLLATE ID|STRING */
+ case 172: /* expr ::= expr COLLATE ID|STRING */
{
- yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1);
+ yymsp[-2].minor.yy102 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy102, &yymsp[0].minor.yy0, 1);
}
break;
- case 172: /* expr ::= CAST LP expr AS typetoken RP */
+ case 173: /* expr ::= CAST LP expr AS typetoken RP */
{
- yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy18, yymsp[-3].minor.yy18, 0);
+ yymsp[-5].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy102, yymsp[-3].minor.yy102, 0);
}
break;
- case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ case 174: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy94, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy100);
}
- yymsp[-4].minor.yy18 = yylhsminor.yy18;
+ yymsp[-4].minor.yy102 = yylhsminor.yy102;
break;
- case 174: /* expr ::= ID|INDEXED LP STAR RP */
+ case 175: /* expr ::= ID|INDEXED LP STAR RP */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
- yymsp[-3].minor.yy18 = yylhsminor.yy18;
+ yymsp[-3].minor.yy102 = yylhsminor.yy102;
break;
- case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
+ case 176: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70);
- sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy94, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy100);
+ sqlite3WindowAttach(pParse, yylhsminor.yy102, yymsp[0].minor.yy379);
}
- yymsp[-5].minor.yy18 = yylhsminor.yy18;
+ yymsp[-5].minor.yy102 = yylhsminor.yy102;
break;
- case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */
+ case 177: /* expr ::= ID|INDEXED LP STAR RP over_clause */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
- sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
+ sqlite3WindowAttach(pParse, yylhsminor.yy102, yymsp[0].minor.yy379);
}
- yymsp[-4].minor.yy18 = yylhsminor.yy18;
+ yymsp[-4].minor.yy102 = yylhsminor.yy102;
break;
- case 177: /* term ::= CTIME_KW */
+ case 178: /* term ::= CTIME_KW */
{
- yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
+ yylhsminor.yy102 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
}
- yymsp[0].minor.yy18 = yylhsminor.yy18;
+ yymsp[0].minor.yy102 = yylhsminor.yy102;
break;
- case 178: /* expr ::= LP nexprlist COMMA expr RP */
+ case 179: /* expr ::= LP nexprlist COMMA expr RP */
{
- ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy420, yymsp[-1].minor.yy18);
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
- if( yymsp[-4].minor.yy18 ){
- yymsp[-4].minor.yy18->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy94, yymsp[-1].minor.yy102);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( yymsp[-4].minor.yy102 ){
+ yymsp[-4].minor.yy102->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
break;
- case 179: /* expr ::= expr AND expr */
- case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180);
- case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181);
- case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182);
- case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183);
- case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184);
- case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185);
- case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186);
-{yymsp[-2].minor.yy18=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);}
+ case 180: /* expr ::= expr AND expr */
+{yymsp[-2].minor.yy102=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
+ break;
+ case 181: /* expr ::= expr OR expr */
+ case 182: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==182);
+ case 183: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==183);
+ case 184: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==184);
+ case 185: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==185);
+ case 186: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==186);
+ case 187: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==187);
+{yymsp[-2].minor.yy102=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);}
break;
- case 187: /* likeop ::= NOT LIKE_KW|MATCH */
+ case 188: /* 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 188: /* expr ::= expr likeop expr */
+ case 189: /* 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.yy18);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy18);
- yymsp[-2].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
- if( bNot ) yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy18, 0);
- if( yymsp[-2].minor.yy18 ) yymsp[-2].minor.yy18->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy102);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy102);
+ yymsp[-2].minor.yy102 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
+ if( bNot ) yymsp[-2].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy102, 0);
+ if( yymsp[-2].minor.yy102 ) yymsp[-2].minor.yy102->flags |= EP_InfixFunc;
}
break;
- case 189: /* expr ::= expr likeop expr ESCAPE expr */
+ case 190: /* 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.yy18);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy18);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
- yymsp[-4].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
- if( bNot ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
- if( yymsp[-4].minor.yy18 ) yymsp[-4].minor.yy18->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy102);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy102);
+ yymsp[-4].minor.yy102 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
+ if( bNot ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
+ if( yymsp[-4].minor.yy102 ) yymsp[-4].minor.yy102->flags |= EP_InfixFunc;
}
break;
- case 190: /* expr ::= expr ISNULL|NOTNULL */
-{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);}
+ case 191: /* expr ::= expr ISNULL|NOTNULL */
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy102,0);}
break;
- case 191: /* expr ::= expr NOT NULL */
-{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);}
+ case 192: /* expr ::= expr NOT NULL */
+{yymsp[-2].minor.yy102 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy102,0);}
break;
- case 192: /* expr ::= expr IS expr */
+ case 193: /* expr ::= expr IS expr */
{
- yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-2].minor.yy18, TK_ISNULL);
+ yymsp[-2].minor.yy102 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy102,yymsp[0].minor.yy102);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy102, yymsp[-2].minor.yy102, TK_ISNULL);
}
break;
- case 193: /* expr ::= expr IS NOT expr */
+ case 194: /* expr ::= expr IS NOT expr */
{
- yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy18,yymsp[0].minor.yy18);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-3].minor.yy18, TK_NOTNULL);
+ yymsp[-3].minor.yy102 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy102,yymsp[0].minor.yy102);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy102, yymsp[-3].minor.yy102, TK_NOTNULL);
}
break;
- case 194: /* expr ::= NOT expr */
- case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195);
-{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy18, 0);/*A-overwrites-B*/}
+ case 195: /* expr ::= NOT expr */
+ case 196: /* expr ::= BITNOT expr */ yytestcase(yyruleno==196);
+{yymsp[-1].minor.yy102 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy102, 0);/*A-overwrites-B*/}
break;
- case 196: /* expr ::= PLUS|MINUS expr */
+ case 197: /* expr ::= PLUS|MINUS expr */
{
- yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0);
+ yymsp[-1].minor.yy102 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy102, 0);
/*A-overwrites-B*/
}
break;
- case 197: /* between_op ::= BETWEEN */
- case 200: /* in_op ::= IN */ yytestcase(yyruleno==200);
-{yymsp[0].minor.yy70 = 0;}
+ case 198: /* between_op ::= BETWEEN */
+ case 201: /* in_op ::= IN */ yytestcase(yyruleno==201);
+{yymsp[0].minor.yy100 = 0;}
break;
- case 199: /* expr ::= expr between_op expr AND expr */
+ case 200: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18);
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy18, 0);
- if( yymsp[-4].minor.yy18 ){
- yymsp[-4].minor.yy18->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy102);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy102, 0);
+ if( yymsp[-4].minor.yy102 ){
+ yymsp[-4].minor.yy102->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
}
break;
- case 202: /* expr ::= expr in_op LP exprlist RP */
+ case 203: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy420==0 ){
+ if( yymsp[-1].minor.yy94==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -149498,9 +152763,9 @@ static YYACTIONTYPE yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy18);
- yymsp[-4].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy70],1);
- }else if( yymsp[-1].minor.yy420->nExpr==1 ){
+ sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy102);
+ yymsp[-4].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy100],1);
+ }else if( yymsp[-1].minor.yy94->nExpr==1 ){
/* Expressions of the form:
**
** expr1 IN (?1)
@@ -149517,199 +152782,199 @@ static YYACTIONTYPE yy_reduce(
** affinity or the collating sequence to use for comparison. Otherwise,
** the semantics would be subtly different from IN or NOT IN.
*/
- Expr *pRHS = yymsp[-1].minor.yy420->a[0].pExpr;
- yymsp[-1].minor.yy420->a[0].pExpr = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+ Expr *pRHS = yymsp[-1].minor.yy94->a[0].pExpr;
+ yymsp[-1].minor.yy94->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy94);
/* pRHS cannot be NULL because a malloc error would have been detected
** before now and control would have never reached this point */
if( ALWAYS(pRHS) ){
pRHS->flags &= ~EP_Collate;
pRHS->flags |= EP_Generic;
}
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, yymsp[-3].minor.yy100 ? TK_NE : TK_EQ, yymsp[-4].minor.yy102, pRHS);
}else{
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
- if( yymsp[-4].minor.yy18 ){
- yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy420;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+ if( yymsp[-4].minor.yy102 ){
+ yymsp[-4].minor.yy102->x.pList = yymsp[-1].minor.yy94;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy102);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy94);
}
- if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
}
}
break;
- case 203: /* expr ::= LP select RP */
+ case 204: /* expr ::= LP select RP */
{
- yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489);
+ yymsp[-2].minor.yy102 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy102, yymsp[-1].minor.yy391);
}
break;
- case 204: /* expr ::= expr in_op LP select RP */
+ case 205: /* expr ::= expr in_op LP select RP */
{
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, yymsp[-1].minor.yy489);
- if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy102, yymsp[-1].minor.yy391);
+ if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
}
break;
- case 205: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ case 206: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
- SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
+ 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.yy420 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy420);
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0);
- sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, pSelect);
- if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0);
+ if( yymsp[0].minor.yy94 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy94);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy102, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy102, pSelect);
+ if( yymsp[-3].minor.yy100 ) yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy102, 0);
}
break;
- case 206: /* expr ::= EXISTS LP select RP */
+ case 207: /* expr ::= EXISTS LP select RP */
{
Expr *p;
- p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489);
+ p = yymsp[-3].minor.yy102 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy391);
}
break;
- case 207: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 208: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy18, 0);
- if( yymsp[-4].minor.yy18 ){
- yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy18 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[-1].minor.yy18) : yymsp[-2].minor.yy420;
- sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18);
+ yymsp[-4].minor.yy102 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy102, 0);
+ if( yymsp[-4].minor.yy102 ){
+ yymsp[-4].minor.yy102->x.pList = yymsp[-1].minor.yy102 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy94,yymsp[-1].minor.yy102) : yymsp[-2].minor.yy94;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy102);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy94);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy102);
}
}
break;
- case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 209: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[-2].minor.yy18);
- yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[0].minor.yy18);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, yymsp[-2].minor.yy102);
+ yymsp[-4].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy94, yymsp[0].minor.yy102);
}
break;
- case 209: /* case_exprlist ::= WHEN expr THEN expr */
+ case 210: /* case_exprlist ::= WHEN expr THEN expr */
{
- yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18);
- yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420, yymsp[0].minor.yy18);
+ yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy102);
+ yymsp[-3].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy94, yymsp[0].minor.yy102);
}
break;
- case 212: /* case_operand ::= expr */
-{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/}
+ case 213: /* case_operand ::= expr */
+{yymsp[0].minor.yy102 = yymsp[0].minor.yy102; /*A-overwrites-X*/}
break;
- case 215: /* nexprlist ::= nexprlist COMMA expr */
-{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);}
+ case 216: /* nexprlist ::= nexprlist COMMA expr */
+{yymsp[-2].minor.yy94 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy94,yymsp[0].minor.yy102);}
break;
- case 216: /* nexprlist ::= expr */
-{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/}
+ case 217: /* nexprlist ::= expr */
+{yymsp[0].minor.yy94 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy102); /*A-overwrites-Y*/}
break;
- case 218: /* paren_exprlist ::= LP exprlist RP */
- case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223);
-{yymsp[-2].minor.yy420 = yymsp[-1].minor.yy420;}
+ case 219: /* paren_exprlist ::= LP exprlist RP */
+ case 224: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==224);
+{yymsp[-2].minor.yy94 = yymsp[-1].minor.yy94;}
break;
- case 219: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ case 220: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
- sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy420, yymsp[-10].minor.yy70,
- &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF);
+ sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy94, yymsp[-10].minor.yy100,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy102, SQLITE_SO_ASC, yymsp[-8].minor.yy100, SQLITE_IDXTYPE_APPDEF);
if( IN_RENAME_OBJECT && pParse->pNewIndex ){
sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
}
}
break;
- case 220: /* uniqueflag ::= UNIQUE */
- case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260);
-{yymsp[0].minor.yy70 = OE_Abort;}
+ case 221: /* uniqueflag ::= UNIQUE */
+ case 263: /* raisetype ::= ABORT */ yytestcase(yyruleno==263);
+{yymsp[0].minor.yy100 = OE_Abort;}
break;
- case 221: /* uniqueflag ::= */
-{yymsp[1].minor.yy70 = OE_None;}
+ case 222: /* uniqueflag ::= */
+{yymsp[1].minor.yy100 = OE_None;}
break;
- case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ case 225: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
- yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70);
+ yymsp[-4].minor.yy94 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy94, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy100, yymsp[0].minor.yy100);
}
break;
- case 225: /* eidlist ::= nm collate sortorder */
+ case 226: /* eidlist ::= nm collate sortorder */
{
- yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/
+ yymsp[-2].minor.yy94 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy100, yymsp[0].minor.yy100); /*A-overwrites-Y*/
}
break;
- case 228: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);}
+ case 229: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy407, yymsp[-1].minor.yy100);}
break;
- case 229: /* cmd ::= VACUUM */
-{sqlite3Vacuum(pParse,0);}
+ case 230: /* cmd ::= VACUUM vinto */
+{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy102);}
break;
- case 230: /* cmd ::= VACUUM nm */
-{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
+ case 231: /* cmd ::= VACUUM nm vinto */
+{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy102);}
break;
- case 231: /* cmd ::= PRAGMA nm dbnm */
+ case 234: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 235: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 236: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 237: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 235: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 238: /* 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 238: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 241: /* 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.yy207, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy11, &all);
}
break;
- case 239: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 242: /* 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.yy70, yymsp[-4].minor.yy34.a, yymsp[-4].minor.yy34.b, yymsp[-2].minor.yy135, yymsp[0].minor.yy18, yymsp[-10].minor.yy70, yymsp[-8].minor.yy70);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy100, yymsp[-4].minor.yy298.a, yymsp[-4].minor.yy298.b, yymsp[-2].minor.yy407, yymsp[0].minor.yy102, yymsp[-10].minor.yy100, yymsp[-8].minor.yy100);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 240: /* trigger_time ::= BEFORE|AFTER */
-{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ }
+ case 243: /* trigger_time ::= BEFORE|AFTER */
+{ yymsp[0].minor.yy100 = yymsp[0].major; /*A-overwrites-X*/ }
break;
- case 241: /* trigger_time ::= INSTEAD OF */
-{ yymsp[-1].minor.yy70 = TK_INSTEAD;}
+ case 244: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy100 = TK_INSTEAD;}
break;
- case 242: /* trigger_time ::= */
-{ yymsp[1].minor.yy70 = TK_BEFORE; }
+ case 245: /* trigger_time ::= */
+{ yymsp[1].minor.yy100 = TK_BEFORE; }
break;
- case 243: /* trigger_event ::= DELETE|INSERT */
- case 244: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==244);
-{yymsp[0].minor.yy34.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy34.b = 0;}
+ case 246: /* trigger_event ::= DELETE|INSERT */
+ case 247: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==247);
+{yymsp[0].minor.yy298.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy298.b = 0;}
break;
- case 245: /* trigger_event ::= UPDATE OF idlist */
-{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;}
+ case 248: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy298.a = TK_UPDATE; yymsp[-2].minor.yy298.b = yymsp[0].minor.yy76;}
break;
- case 246: /* when_clause ::= */
- case 265: /* key_opt ::= */ yytestcase(yyruleno==265);
- case 307: /* filter_opt ::= */ yytestcase(yyruleno==307);
-{ yymsp[1].minor.yy18 = 0; }
+ case 249: /* when_clause ::= */
+ case 268: /* key_opt ::= */ yytestcase(yyruleno==268);
+ case 316: /* filter_opt ::= */ yytestcase(yyruleno==316);
+{ yymsp[1].minor.yy102 = 0; }
break;
- case 247: /* when_clause ::= WHEN expr */
- case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266);
-{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; }
+ case 250: /* when_clause ::= WHEN expr */
+ case 269: /* key_opt ::= KEY expr */ yytestcase(yyruleno==269);
+{ yymsp[-1].minor.yy102 = yymsp[0].minor.yy102; }
break;
- case 248: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 251: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
- assert( yymsp[-2].minor.yy207!=0 );
- yymsp[-2].minor.yy207->pLast->pNext = yymsp[-1].minor.yy207;
- yymsp[-2].minor.yy207->pLast = yymsp[-1].minor.yy207;
+ assert( yymsp[-2].minor.yy11!=0 );
+ yymsp[-2].minor.yy11->pLast->pNext = yymsp[-1].minor.yy11;
+ yymsp[-2].minor.yy11->pLast = yymsp[-1].minor.yy11;
}
break;
- case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 252: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy207!=0 );
- yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207;
+ assert( yymsp[-1].minor.yy11!=0 );
+ yymsp[-1].minor.yy11->pLast = yymsp[-1].minor.yy11;
}
break;
- case 250: /* trnm ::= nm DOT nm */
+ case 253: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -149717,312 +152982,334 @@ static YYACTIONTYPE yy_reduce(
"statements within triggers");
}
break;
- case 251: /* tridxby ::= INDEXED BY nm */
+ case 254: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 252: /* tridxby ::= NOT INDEXED */
+ case 255: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 253: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
-{yylhsminor.yy207 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy18, yymsp[-6].minor.yy70, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy392);}
- yymsp[-7].minor.yy207 = yylhsminor.yy207;
+ case 256: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+{yylhsminor.yy11 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy94, yymsp[-1].minor.yy102, yymsp[-6].minor.yy100, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy528);}
+ yymsp[-7].minor.yy11 = yylhsminor.yy11;
break;
- case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+ case 257: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
{
- yylhsminor.yy207 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy48,yymsp[-2].minor.yy489,yymsp[-6].minor.yy70,yymsp[-1].minor.yy340,yymsp[-7].minor.yy392,yymsp[0].minor.yy392);/*yylhsminor.yy207-overwrites-yymsp[-6].minor.yy70*/
+ yylhsminor.yy11 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy76,yymsp[-2].minor.yy391,yymsp[-6].minor.yy100,yymsp[-1].minor.yy95,yymsp[-7].minor.yy528,yymsp[0].minor.yy528);/*yylhsminor.yy11-overwrites-yymsp[-6].minor.yy100*/
}
- yymsp[-7].minor.yy207 = yylhsminor.yy207;
+ yymsp[-7].minor.yy11 = yylhsminor.yy11;
break;
- case 255: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
-{yylhsminor.yy207 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy18, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy392);}
- yymsp[-5].minor.yy207 = yylhsminor.yy207;
+ case 258: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+{yylhsminor.yy11 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy102, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy528);}
+ yymsp[-5].minor.yy11 = yylhsminor.yy11;
break;
- case 256: /* trigger_cmd ::= scanpt select scanpt */
-{yylhsminor.yy207 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy489, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); /*yylhsminor.yy207-overwrites-yymsp[-1].minor.yy489*/}
- yymsp[-2].minor.yy207 = yylhsminor.yy207;
+ case 259: /* trigger_cmd ::= scanpt select scanpt */
+{yylhsminor.yy11 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy391, yymsp[-2].minor.yy528, yymsp[0].minor.yy528); /*yylhsminor.yy11-overwrites-yymsp[-1].minor.yy391*/}
+ yymsp[-2].minor.yy11 = yylhsminor.yy11;
break;
- case 257: /* expr ::= RAISE LP IGNORE RP */
+ case 260: /* expr ::= RAISE LP IGNORE RP */
{
- yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
- if( yymsp[-3].minor.yy18 ){
- yymsp[-3].minor.yy18->affinity = OE_Ignore;
+ yymsp[-3].minor.yy102 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
+ if( yymsp[-3].minor.yy102 ){
+ yymsp[-3].minor.yy102->affinity = OE_Ignore;
}
}
break;
- case 258: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 261: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
- yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
- if( yymsp[-5].minor.yy18 ) {
- yymsp[-5].minor.yy18->affinity = (char)yymsp[-3].minor.yy70;
+ yymsp[-5].minor.yy102 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
+ if( yymsp[-5].minor.yy102 ) {
+ yymsp[-5].minor.yy102->affinity = (char)yymsp[-3].minor.yy100;
}
}
break;
- case 259: /* raisetype ::= ROLLBACK */
-{yymsp[0].minor.yy70 = OE_Rollback;}
+ case 262: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy100 = OE_Rollback;}
break;
- case 261: /* raisetype ::= FAIL */
-{yymsp[0].minor.yy70 = OE_Fail;}
+ case 264: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy100 = OE_Fail;}
break;
- case 262: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 265: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy407,yymsp[-1].minor.yy100);
}
break;
- case 263: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 266: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy102, yymsp[-1].minor.yy102, yymsp[0].minor.yy102);
}
break;
- case 264: /* cmd ::= DETACH database_kw_opt expr */
+ case 267: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy18);
+ sqlite3Detach(pParse, yymsp[0].minor.yy102);
}
break;
- case 267: /* cmd ::= REINDEX */
+ case 270: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 268: /* cmd ::= REINDEX nm dbnm */
+ case 271: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 269: /* cmd ::= ANALYZE */
+ case 272: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 270: /* cmd ::= ANALYZE nm dbnm */
+ case 273: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 274: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy407,&yymsp[0].minor.yy0);
}
break;
- case 272: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 275: /* 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 273: /* add_column_fullname ::= fullname */
+ case 276: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy407);
}
break;
- case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+ case 277: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
- sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
+ sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy407, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 275: /* cmd ::= create_vtab */
+ case 278: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 276: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 279: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 277: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 280: /* 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.yy70);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy100);
}
break;
- case 278: /* vtabarg ::= */
+ case 281: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 279: /* vtabargtoken ::= ANY */
- case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280);
- case 281: /* lp ::= LP */ yytestcase(yyruleno==281);
+ case 282: /* vtabargtoken ::= ANY */
+ case 283: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==283);
+ case 284: /* lp ::= LP */ yytestcase(yyruleno==284);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 282: /* with ::= WITH wqlist */
- case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283);
-{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); }
+ case 285: /* with ::= WITH wqlist */
+ case 286: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==286);
+{ sqlite3WithPush(pParse, yymsp[0].minor.yy243, 1); }
break;
- case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ case 287: /* wqlist ::= nm eidlist_opt AS LP select RP */
{
- yymsp[-5].minor.yy449 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); /*A-overwrites-X*/
+ yymsp[-5].minor.yy243 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy94, yymsp[-1].minor.yy391); /*A-overwrites-X*/
}
break;
- case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ case 288: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
{
- yymsp[-7].minor.yy449 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy449, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489);
+ yymsp[-7].minor.yy243 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy243, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy94, yymsp[-1].minor.yy391);
}
break;
- case 286: /* windowdefn_list ::= windowdefn */
-{ yylhsminor.yy327 = yymsp[0].minor.yy327; }
- yymsp[0].minor.yy327 = yylhsminor.yy327;
+ case 289: /* windowdefn_list ::= windowdefn */
+{ yylhsminor.yy379 = yymsp[0].minor.yy379; }
+ yymsp[0].minor.yy379 = yylhsminor.yy379;
break;
- case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+ case 290: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
- assert( yymsp[0].minor.yy327!=0 );
- yymsp[0].minor.yy327->pNextWin = yymsp[-2].minor.yy327;
- yylhsminor.yy327 = yymsp[0].minor.yy327;
+ assert( yymsp[0].minor.yy379!=0 );
+ sqlite3WindowChain(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy379);
+ yymsp[0].minor.yy379->pNextWin = yymsp[-2].minor.yy379;
+ yylhsminor.yy379 = yymsp[0].minor.yy379;
}
- yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ yymsp[-2].minor.yy379 = yylhsminor.yy379;
break;
- case 288: /* windowdefn ::= nm AS window */
+ case 291: /* windowdefn ::= nm AS LP window RP */
{
- if( ALWAYS(yymsp[0].minor.yy327) ){
- yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n);
+ if( ALWAYS(yymsp[-1].minor.yy379) ){
+ yymsp[-1].minor.yy379->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
}
- yylhsminor.yy327 = yymsp[0].minor.yy327;
+ yylhsminor.yy379 = yymsp[-1].minor.yy379;
}
- yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ yymsp[-4].minor.yy379 = yylhsminor.yy379;
break;
- case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */
+ case 292: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
{
- yymsp[-4].minor.yy327 = yymsp[-1].minor.yy327;
- if( ALWAYS(yymsp[-4].minor.yy327) ){
- yymsp[-4].minor.yy327->pPartition = yymsp[-3].minor.yy420;
- yymsp[-4].minor.yy327->pOrderBy = yymsp[-2].minor.yy420;
- }
+ yymsp[-4].minor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy94, yymsp[-1].minor.yy94, 0);
}
break;
- case 290: /* part_opt ::= PARTITION BY nexprlist */
-{ yymsp[-2].minor.yy420 = yymsp[0].minor.yy420; }
+ case 293: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+{
+ yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, yymsp[-2].minor.yy94, yymsp[-1].minor.yy94, &yymsp[-5].minor.yy0);
+}
+ yymsp[-5].minor.yy379 = yylhsminor.yy379;
break;
- case 291: /* part_opt ::= */
-{ yymsp[1].minor.yy420 = 0; }
+ case 294: /* window ::= ORDER BY sortlist frame_opt */
+{
+ yymsp[-3].minor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, yymsp[-1].minor.yy94, 0);
+}
break;
- case 292: /* frame_opt ::= */
+ case 295: /* window ::= nm ORDER BY sortlist frame_opt */
+{
+ yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, yymsp[-1].minor.yy94, &yymsp[-4].minor.yy0);
+}
+ yymsp[-4].minor.yy379 = yylhsminor.yy379;
+ break;
+ case 296: /* window ::= frame_opt */
+{
+ yylhsminor.yy379 = yymsp[0].minor.yy379;
+}
+ yymsp[0].minor.yy379 = yylhsminor.yy379;
+ break;
+ case 297: /* window ::= nm frame_opt */
+{
+ yylhsminor.yy379 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy379, 0, 0, &yymsp[-1].minor.yy0);
+}
+ yymsp[-1].minor.yy379 = yylhsminor.yy379;
+ break;
+ case 298: /* frame_opt ::= */
{
- yymsp[1].minor.yy327 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
+ yymsp[1].minor.yy379 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
break;
- case 293: /* frame_opt ::= range_or_rows frame_bound_s */
+ case 299: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
{
- yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy70, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr, TK_CURRENT, 0);
+ yylhsminor.yy379 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy100, yymsp[-1].minor.yy389.eType, yymsp[-1].minor.yy389.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy218);
}
- yymsp[-1].minor.yy327 = yylhsminor.yy327;
+ yymsp[-2].minor.yy379 = yylhsminor.yy379;
break;
- case 294: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */
+ case 300: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
{
- yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy119.eType, yymsp[-2].minor.yy119.pExpr, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr);
+ yylhsminor.yy379 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy100, yymsp[-3].minor.yy389.eType, yymsp[-3].minor.yy389.pExpr, yymsp[-1].minor.yy389.eType, yymsp[-1].minor.yy389.pExpr, yymsp[0].minor.yy218);
}
- yymsp[-4].minor.yy327 = yylhsminor.yy327;
+ yymsp[-5].minor.yy379 = yylhsminor.yy379;
break;
- case 295: /* range_or_rows ::= RANGE */
-{ yymsp[0].minor.yy70 = TK_RANGE; }
+ case 302: /* frame_bound_s ::= frame_bound */
+ case 304: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==304);
+{yylhsminor.yy389 = yymsp[0].minor.yy389;}
+ yymsp[0].minor.yy389 = yylhsminor.yy389;
break;
- case 296: /* range_or_rows ::= ROWS */
-{ yymsp[0].minor.yy70 = TK_ROWS; }
+ case 303: /* frame_bound_s ::= UNBOUNDED PRECEDING */
+ case 305: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==305);
+ case 307: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==307);
+{yylhsminor.yy389.eType = yymsp[-1].major; yylhsminor.yy389.pExpr = 0;}
+ yymsp[-1].minor.yy389 = yylhsminor.yy389;
break;
- case 297: /* frame_bound_s ::= frame_bound */
- case 299: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==299);
-{ yylhsminor.yy119 = yymsp[0].minor.yy119; }
- yymsp[0].minor.yy119 = yylhsminor.yy119;
+ case 306: /* frame_bound ::= expr PRECEDING|FOLLOWING */
+{yylhsminor.yy389.eType = yymsp[0].major; yylhsminor.yy389.pExpr = yymsp[-1].minor.yy102;}
+ yymsp[-1].minor.yy389 = yylhsminor.yy389;
break;
- case 298: /* frame_bound_s ::= UNBOUNDED PRECEDING */
- case 300: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==300);
-{yymsp[-1].minor.yy119.eType = TK_UNBOUNDED; yymsp[-1].minor.yy119.pExpr = 0;}
+ case 308: /* frame_exclude_opt ::= */
+{yymsp[1].minor.yy218 = 0;}
break;
- case 301: /* frame_bound ::= expr PRECEDING */
-{ yylhsminor.yy119.eType = TK_PRECEDING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
- yymsp[-1].minor.yy119 = yylhsminor.yy119;
+ case 309: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
+{yymsp[-1].minor.yy218 = yymsp[0].minor.yy218;}
break;
- case 302: /* frame_bound ::= CURRENT ROW */
-{ yymsp[-1].minor.yy119.eType = TK_CURRENT ; yymsp[-1].minor.yy119.pExpr = 0; }
+ case 310: /* frame_exclude ::= NO OTHERS */
+ case 311: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==311);
+{yymsp[-1].minor.yy218 = yymsp[-1].major; /*A-overwrites-X*/}
break;
- case 303: /* frame_bound ::= expr FOLLOWING */
-{ yylhsminor.yy119.eType = TK_FOLLOWING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; }
- yymsp[-1].minor.yy119 = yylhsminor.yy119;
+ case 312: /* frame_exclude ::= GROUP|TIES */
+{yymsp[0].minor.yy218 = yymsp[0].major; /*A-overwrites-X*/}
break;
- case 304: /* window_clause ::= WINDOW windowdefn_list */
-{ yymsp[-1].minor.yy327 = yymsp[0].minor.yy327; }
+ case 313: /* window_clause ::= WINDOW windowdefn_list */
+{ yymsp[-1].minor.yy379 = yymsp[0].minor.yy379; }
break;
- case 305: /* over_clause ::= filter_opt OVER window */
+ case 314: /* over_clause ::= filter_opt OVER LP window RP */
{
- yylhsminor.yy327 = yymsp[0].minor.yy327;
- assert( yylhsminor.yy327!=0 );
- yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
+ yylhsminor.yy379 = yymsp[-1].minor.yy379;
+ assert( yylhsminor.yy379!=0 );
+ yylhsminor.yy379->pFilter = yymsp[-4].minor.yy102;
}
- yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ yymsp[-4].minor.yy379 = yylhsminor.yy379;
break;
- case 306: /* over_clause ::= filter_opt OVER nm */
+ case 315: /* over_clause ::= filter_opt OVER nm */
{
- yylhsminor.yy327 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
- if( yylhsminor.yy327 ){
- yylhsminor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
- yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18;
+ yylhsminor.yy379 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
+ if( yylhsminor.yy379 ){
+ yylhsminor.yy379->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
+ yylhsminor.yy379->pFilter = yymsp[-2].minor.yy102;
}else{
- sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18);
+ sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy102);
}
}
- yymsp[-2].minor.yy327 = yylhsminor.yy327;
+ yymsp[-2].minor.yy379 = yylhsminor.yy379;
break;
- case 308: /* filter_opt ::= FILTER LP WHERE expr RP */
-{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; }
+ case 317: /* filter_opt ::= FILTER LP WHERE expr RP */
+{ yymsp[-4].minor.yy102 = yymsp[-1].minor.yy102; }
break;
default:
- /* (309) input ::= cmdlist */ yytestcase(yyruleno==309);
- /* (310) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==310);
- /* (311) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=311);
- /* (312) ecmd ::= SEMI */ yytestcase(yyruleno==312);
- /* (313) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==313);
- /* (314) ecmd ::= explain cmdx */ yytestcase(yyruleno==314);
- /* (315) trans_opt ::= */ yytestcase(yyruleno==315);
- /* (316) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==316);
- /* (317) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==317);
- /* (318) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==318);
- /* (319) savepoint_opt ::= */ yytestcase(yyruleno==319);
- /* (320) cmd ::= create_table create_table_args */ yytestcase(yyruleno==320);
- /* (321) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==321);
- /* (322) columnlist ::= columnname carglist */ yytestcase(yyruleno==322);
- /* (323) nm ::= ID|INDEXED */ yytestcase(yyruleno==323);
- /* (324) nm ::= STRING */ yytestcase(yyruleno==324);
- /* (325) nm ::= JOIN_KW */ yytestcase(yyruleno==325);
- /* (326) typetoken ::= typename */ yytestcase(yyruleno==326);
- /* (327) typename ::= ID|STRING */ yytestcase(yyruleno==327);
- /* (328) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=328);
- /* (329) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=329);
- /* (330) carglist ::= carglist ccons */ yytestcase(yyruleno==330);
- /* (331) carglist ::= */ yytestcase(yyruleno==331);
- /* (332) ccons ::= NULL onconf */ yytestcase(yyruleno==332);
- /* (333) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==333);
- /* (334) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==334);
- /* (335) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=335);
- /* (336) tconscomma ::= */ yytestcase(yyruleno==336);
- /* (337) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=337);
- /* (338) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=338);
- /* (339) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=339);
- /* (340) oneselect ::= values */ yytestcase(yyruleno==340);
- /* (341) sclp ::= selcollist COMMA */ yytestcase(yyruleno==341);
- /* (342) as ::= ID|STRING */ yytestcase(yyruleno==342);
- /* (343) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=343);
- /* (344) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==344);
- /* (345) exprlist ::= nexprlist */ yytestcase(yyruleno==345);
- /* (346) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=346);
- /* (347) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=347);
- /* (348) nmnum ::= ON */ yytestcase(yyruleno==348);
- /* (349) nmnum ::= DELETE */ yytestcase(yyruleno==349);
- /* (350) nmnum ::= DEFAULT */ yytestcase(yyruleno==350);
- /* (351) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==351);
- /* (352) foreach_clause ::= */ yytestcase(yyruleno==352);
- /* (353) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==353);
- /* (354) trnm ::= nm */ yytestcase(yyruleno==354);
- /* (355) tridxby ::= */ yytestcase(yyruleno==355);
- /* (356) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==356);
- /* (357) database_kw_opt ::= */ yytestcase(yyruleno==357);
- /* (358) kwcolumn_opt ::= */ yytestcase(yyruleno==358);
- /* (359) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==359);
- /* (360) vtabarglist ::= vtabarg */ yytestcase(yyruleno==360);
- /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==361);
- /* (362) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==362);
- /* (363) anylist ::= */ yytestcase(yyruleno==363);
- /* (364) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==364);
- /* (365) anylist ::= anylist ANY */ yytestcase(yyruleno==365);
- /* (366) with ::= */ yytestcase(yyruleno==366);
+ /* (318) input ::= cmdlist */ yytestcase(yyruleno==318);
+ /* (319) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==319);
+ /* (320) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=320);
+ /* (321) ecmd ::= SEMI */ yytestcase(yyruleno==321);
+ /* (322) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==322);
+ /* (323) ecmd ::= explain cmdx */ yytestcase(yyruleno==323);
+ /* (324) trans_opt ::= */ yytestcase(yyruleno==324);
+ /* (325) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==325);
+ /* (326) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==326);
+ /* (327) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==327);
+ /* (328) savepoint_opt ::= */ yytestcase(yyruleno==328);
+ /* (329) cmd ::= create_table create_table_args */ yytestcase(yyruleno==329);
+ /* (330) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==330);
+ /* (331) columnlist ::= columnname carglist */ yytestcase(yyruleno==331);
+ /* (332) nm ::= ID|INDEXED */ yytestcase(yyruleno==332);
+ /* (333) nm ::= STRING */ yytestcase(yyruleno==333);
+ /* (334) nm ::= JOIN_KW */ yytestcase(yyruleno==334);
+ /* (335) typetoken ::= typename */ yytestcase(yyruleno==335);
+ /* (336) typename ::= ID|STRING */ yytestcase(yyruleno==336);
+ /* (337) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=337);
+ /* (338) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=338);
+ /* (339) carglist ::= carglist ccons */ yytestcase(yyruleno==339);
+ /* (340) carglist ::= */ yytestcase(yyruleno==340);
+ /* (341) ccons ::= NULL onconf */ yytestcase(yyruleno==341);
+ /* (342) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==342);
+ /* (343) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==343);
+ /* (344) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=344);
+ /* (345) tconscomma ::= */ yytestcase(yyruleno==345);
+ /* (346) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=346);
+ /* (347) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=347);
+ /* (348) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=348);
+ /* (349) oneselect ::= values */ yytestcase(yyruleno==349);
+ /* (350) sclp ::= selcollist COMMA */ yytestcase(yyruleno==350);
+ /* (351) as ::= ID|STRING */ yytestcase(yyruleno==351);
+ /* (352) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=352);
+ /* (353) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==353);
+ /* (354) exprlist ::= nexprlist */ yytestcase(yyruleno==354);
+ /* (355) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=355);
+ /* (356) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=356);
+ /* (357) nmnum ::= ON */ yytestcase(yyruleno==357);
+ /* (358) nmnum ::= DELETE */ yytestcase(yyruleno==358);
+ /* (359) nmnum ::= DEFAULT */ yytestcase(yyruleno==359);
+ /* (360) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==360);
+ /* (361) foreach_clause ::= */ yytestcase(yyruleno==361);
+ /* (362) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==362);
+ /* (363) trnm ::= nm */ yytestcase(yyruleno==363);
+ /* (364) tridxby ::= */ yytestcase(yyruleno==364);
+ /* (365) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==365);
+ /* (366) database_kw_opt ::= */ yytestcase(yyruleno==366);
+ /* (367) kwcolumn_opt ::= */ yytestcase(yyruleno==367);
+ /* (368) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==368);
+ /* (369) vtabarglist ::= vtabarg */ yytestcase(yyruleno==369);
+ /* (370) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==370);
+ /* (371) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==371);
+ /* (372) anylist ::= */ yytestcase(yyruleno==372);
+ /* (373) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==373);
+ /* (374) anylist ::= anylist ANY */ yytestcase(yyruleno==374);
+ /* (375) with ::= */ yytestcase(yyruleno==375);
break;
/********** End reduce actions ************************************************/
};
- assert( yyrulenoyytos >= yypParser->yystack
- && yymx != YYERRORSYMBOL
&& (yyact = yy_find_reduce_action(
yypParser->yytos->stateno,
- YYERRORSYMBOL)) >= YY_MIN_REDUCE
+ YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
){
yy_pop_parser_stack(yypParser);
}
@@ -150480,144 +153766,144 @@ const unsigned char ebcdicToAscii[] = {
** is substantially reduced. This is important for embedded applications
** on platforms with limited memory.
*/
-/* Hash score: 208 */
-/* zKWText[] encodes 923 bytes of keyword text in 614 bytes */
+/* Hash score: 214 */
+/* zKWText[] encodes 950 bytes of keyword text in 629 bytes */
/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
-/* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */
-/* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */
-/* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERANGEBETWEEN */
-/* OTHINGLOBYCASCADELETECASECOLLATECREATECURRENT_DATEDETACH */
-/* IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMIT */
-/* WHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULTAUTOINCREMENTCAST */
-/* COLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMPARTITIONDEFERRED */
-/* ISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWINGFROMFULLIFISNULL */
-/* ORDERESTRICTOVERIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEW */
-/* INDOWINITIALLYPRIMARY */
-static const char zKWText[613] = {
+/* ABLEFTHENDEFERRABLELSEXCLUDELETEMPORARYCONSTRAINTERSECTIES */
+/* AVEPOINTOFFSETRANSACTIONATURALTERAISEXCEPTRIGGEREFERENCES */
+/* UNIQUERYWITHOUTERELEASEXCLUSIVEXISTSATTACHAVINGLOBEGINNERANGE */
+/* BETWEENOTHINGROUPSCASCADETACHCASECOLLATECREATECURRENT_DATE */
+/* IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTUPDATEVALUES */
+/* VIRTUALIMITWHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULT */
+/* AUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMP */
+/* ARTITIONDEFERREDISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWING */
+/* FROMFULLIFISNULLORDERESTRICTOTHERSOVERIGHTROLLBACKROWS */
+/* UNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBYINITIALLYPRIMARY */
+static const char zKWText[628] = {
'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
- 'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N',
- 'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I',
- 'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E',
- 'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E',
- 'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T',
- 'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
- 'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
- 'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
- 'T','E','B','E','G','I','N','N','E','R','A','N','G','E','B','E','T','W',
- 'E','E','N','O','T','H','I','N','G','L','O','B','Y','C','A','S','C','A',
- 'D','E','L','E','T','E','C','A','S','E','C','O','L','L','A','T','E','C',
- 'R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E','D',
- 'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N',
- 'S','E','R','T','L','I','K','E','M','A','T','C','H','P','L','A','N','A',
- 'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U',
- 'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','O',
- 'T','N','U','L','L','W','H','E','R','E','C','U','R','S','I','V','E','A',
- 'F','T','E','R','E','N','A','M','E','A','N','D','E','F','A','U','L','T',
- 'A','U','T','O','I','N','C','R','E','M','E','N','T','C','A','S','T','C',
- 'O','L','U','M','N','C','O','M','M','I','T','C','O','N','F','L','I','C',
- 'T','C','R','O','S','S','C','U','R','R','E','N','T','_','T','I','M','E',
- 'S','T','A','M','P','A','R','T','I','T','I','O','N','D','E','F','E','R',
- 'R','E','D','I','S','T','I','N','C','T','D','R','O','P','R','E','C','E',
- 'D','I','N','G','F','A','I','L','F','I','L','T','E','R','E','P','L','A',
- 'C','E','F','O','L','L','O','W','I','N','G','F','R','O','M','F','U','L',
- 'L','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T','R',
- 'I','C','T','O','V','E','R','I','G','H','T','R','O','L','L','B','A','C',
- 'K','R','O','W','S','U','N','B','O','U','N','D','E','D','U','N','I','O',
- 'N','U','S','I','N','G','V','A','C','U','U','M','V','I','E','W','I','N',
- 'D','O','W','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R',
- 'Y',
+ 'E','R','R','A','B','L','E','L','S','E','X','C','L','U','D','E','L','E',
+ 'T','E','M','P','O','R','A','R','Y','C','O','N','S','T','R','A','I','N',
+ 'T','E','R','S','E','C','T','I','E','S','A','V','E','P','O','I','N','T',
+ 'O','F','F','S','E','T','R','A','N','S','A','C','T','I','O','N','A','T',
+ 'U','R','A','L','T','E','R','A','I','S','E','X','C','E','P','T','R','I',
+ 'G','G','E','R','E','F','E','R','E','N','C','E','S','U','N','I','Q','U',
+ 'E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S','E',
+ 'X','C','L','U','S','I','V','E','X','I','S','T','S','A','T','T','A','C',
+ 'H','A','V','I','N','G','L','O','B','E','G','I','N','N','E','R','A','N',
+ 'G','E','B','E','T','W','E','E','N','O','T','H','I','N','G','R','O','U',
+ 'P','S','C','A','S','C','A','D','E','T','A','C','H','C','A','S','E','C',
+ 'O','L','L','A','T','E','C','R','E','A','T','E','C','U','R','R','E','N',
+ 'T','_','D','A','T','E','I','M','M','E','D','I','A','T','E','J','O','I',
+ 'N','S','E','R','T','L','I','K','E','M','A','T','C','H','P','L','A','N',
+ 'A','L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','U','P','D',
+ 'A','T','E','V','A','L','U','E','S','V','I','R','T','U','A','L','I','M',
+ 'I','T','W','H','E','N','O','T','N','U','L','L','W','H','E','R','E','C',
+ 'U','R','S','I','V','E','A','F','T','E','R','E','N','A','M','E','A','N',
+ 'D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E','M','E',
+ 'N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M','I','T',
+ 'C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R','R','E',
+ 'N','T','_','T','I','M','E','S','T','A','M','P','A','R','T','I','T','I',
+ 'O','N','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D',
+ 'R','O','P','R','E','C','E','D','I','N','G','F','A','I','L','F','I','L',
+ 'T','E','R','E','P','L','A','C','E','F','O','L','L','O','W','I','N','G',
+ 'F','R','O','M','F','U','L','L','I','F','I','S','N','U','L','L','O','R',
+ 'D','E','R','E','S','T','R','I','C','T','O','T','H','E','R','S','O','V',
+ 'E','R','I','G','H','T','R','O','L','L','B','A','C','K','R','O','W','S',
+ 'U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S','I','N',
+ 'G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W','B','Y',
+ 'I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y',
};
/* aKWHash[i] is the hash value for the i-th keyword */
static const unsigned char aKWHash[127] = {
- 74, 109, 124, 72, 106, 45, 0, 0, 81, 0, 76, 61, 0,
- 42, 12, 77, 15, 0, 123, 84, 54, 118, 125, 19, 0, 0,
- 130, 0, 128, 121, 0, 22, 96, 0, 9, 0, 0, 115, 69,
- 0, 67, 6, 0, 48, 93, 136, 0, 126, 104, 0, 0, 44,
- 0, 107, 24, 0, 17, 0, 131, 53, 23, 0, 5, 62, 132,
- 99, 0, 0, 135, 110, 60, 134, 57, 113, 55, 0, 94, 0,
- 103, 26, 0, 102, 0, 0, 0, 98, 95, 100, 105, 117, 14,
- 39, 116, 0, 80, 0, 133, 114, 92, 59, 0, 129, 79, 119,
- 86, 46, 83, 0, 0, 97, 40, 122, 120, 0, 127, 0, 0,
- 29, 0, 89, 87, 88, 0, 20, 85, 111, 56,
+ 75, 111, 127, 73, 108, 29, 0, 0, 83, 0, 77, 63, 0,
+ 37, 33, 78, 15, 0, 126, 86, 57, 120, 128, 19, 0, 0,
+ 133, 0, 131, 123, 0, 22, 98, 0, 9, 0, 0, 117, 71,
+ 0, 69, 6, 0, 49, 95, 140, 0, 129, 106, 0, 0, 54,
+ 0, 109, 24, 0, 17, 0, 134, 56, 23, 26, 5, 58, 135,
+ 101, 0, 0, 139, 112, 62, 138, 59, 115, 65, 0, 96, 0,
+ 105, 45, 0, 104, 0, 0, 0, 100, 97, 102, 107, 119, 14,
+ 31, 118, 0, 81, 0, 136, 116, 137, 61, 124, 132, 80, 121,
+ 88, 30, 85, 0, 0, 99, 35, 125, 122, 0, 130, 0, 0,
+ 41, 0, 91, 89, 90, 0, 20, 87, 113, 82,
};
/* aKWNext[] forms the hash collision chain. If aKWHash[i]==0
** then the i-th keyword has no more hash collisions. Otherwise,
** the next keyword with the same hash is aKWHash[i]-1. */
-static const unsigned char aKWNext[136] = {
+static const unsigned char aKWNext[140] = {
0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
- 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 50,
- 0, 43, 3, 47, 0, 0, 32, 0, 0, 0, 0, 0, 0,
- 0, 1, 64, 0, 0, 65, 0, 41, 0, 38, 0, 0, 0,
- 0, 0, 49, 75, 0, 0, 30, 0, 58, 0, 0, 0, 31,
- 63, 16, 34, 10, 0, 0, 0, 0, 0, 0, 0, 11, 70,
- 91, 0, 0, 8, 0, 108, 0, 101, 28, 52, 68, 0, 112,
- 0, 73, 51, 0, 90, 27, 37, 0, 71, 36, 82, 0, 35,
- 66, 25, 18, 0, 0, 78,
+ 0, 0, 0, 21, 0, 0, 12, 0, 0, 0, 0, 0, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 51, 28, 0, 0, 38, 0, 0, 0, 44, 0, 0, 0, 3,
+ 0, 0, 67, 1, 66, 0, 0, 0, 36, 0, 47, 0, 0,
+ 0, 0, 0, 48, 50, 76, 0, 0, 42, 0, 60, 0, 0,
+ 0, 43, 0, 16, 55, 10, 0, 0, 0, 0, 0, 0, 0,
+ 11, 72, 93, 0, 0, 8, 0, 110, 0, 103, 40, 53, 70,
+ 0, 114, 0, 74, 52, 0, 0, 92, 39, 46, 0, 68, 32,
+ 84, 0, 34, 27, 25, 18, 94, 0, 64, 79,
};
/* aKWLen[i] is the length (in bytes) of the i-th keyword */
-static const unsigned char aKWLen[136] = {
+static const unsigned char aKWLen[140] = {
7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6,
- 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6,
- 11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10,
- 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 4, 5, 7,
- 6, 6, 5, 6, 5, 5, 5, 7, 7, 4, 2, 7, 3,
- 6, 4, 7, 6, 12, 6, 9, 4, 6, 4, 5, 4, 7,
- 6, 5, 6, 7, 5, 4, 7, 3, 2, 4, 5, 9, 5,
- 6, 3, 7, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12,
- 7, 9, 8, 8, 2, 4, 9, 4, 6, 7, 9, 4, 4,
- 2, 6, 5, 8, 4, 5, 8, 4, 3, 9, 5, 5, 6,
- 4, 6, 2, 9, 3, 7,
+ 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7,
+ 6, 9, 4, 2, 10, 9, 4, 9, 4, 6, 2, 3, 11,
+ 6, 2, 7, 5, 5, 6, 7, 10, 6, 5, 7, 4, 5,
+ 7, 9, 6, 6, 6, 4, 5, 5, 5, 7, 7, 6, 5,
+ 7, 3, 6, 4, 7, 6, 12, 9, 4, 6, 4, 5, 4,
+ 7, 6, 5, 6, 6, 7, 5, 4, 7, 3, 2, 4, 5,
+ 9, 5, 6, 3, 7, 13, 2, 2, 4, 6, 6, 8, 5,
+ 17, 12, 7, 9, 8, 8, 2, 4, 9, 4, 6, 7, 9,
+ 4, 4, 2, 6, 5, 8, 6, 4, 5, 8, 4, 3, 9,
+ 5, 5, 6, 4, 6, 2, 2, 9, 3, 7,
};
/* aKWOffset[i] is the index into zKWText[] of the start of
** the text for the i-th keyword. */
-static const unsigned short int aKWOffset[136] = {
+static const unsigned short int aKWOffset[140] = {
0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
- 86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
- 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192,
- 199, 204, 209, 212, 218, 221, 225, 230, 236, 242, 245, 247, 248,
- 252, 258, 262, 269, 275, 287, 293, 302, 304, 310, 314, 319, 321,
- 328, 333, 338, 344, 350, 355, 358, 358, 358, 361, 365, 368, 377,
- 381, 387, 389, 396, 398, 400, 409, 413, 419, 425, 433, 438, 438,
- 438, 454, 463, 470, 471, 478, 481, 490, 494, 499, 506, 515, 519,
- 523, 525, 531, 535, 543, 546, 551, 559, 559, 563, 572, 577, 582,
- 588, 591, 594, 597, 602, 606,
+ 86, 90, 90, 94, 99, 106, 114, 117, 123, 126, 126, 129, 131,
+ 136, 140, 141, 146, 150, 154, 159, 165, 175, 178, 183, 183, 187,
+ 191, 197, 205, 211, 216, 221, 224, 227, 231, 236, 242, 248, 248,
+ 254, 255, 259, 265, 269, 276, 282, 294, 303, 305, 311, 315, 320,
+ 322, 329, 334, 339, 345, 351, 357, 362, 365, 365, 365, 368, 372,
+ 375, 384, 388, 394, 396, 403, 405, 407, 416, 420, 426, 432, 440,
+ 445, 445, 445, 461, 470, 477, 478, 485, 488, 497, 501, 506, 513,
+ 522, 526, 530, 532, 538, 542, 550, 556, 559, 564, 572, 572, 576,
+ 585, 590, 595, 601, 604, 607, 610, 612, 617, 621,
};
/* aKWCode[i] is the parser symbol code for the i-th keyword */
-static const unsigned char aKWCode[136] = {
+static const unsigned char aKWCode[140] = {
TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD,
TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE,
TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE,
- TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW,
- TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT,
- TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO,
- TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP,
- TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH,
- TK_JOIN_KW, TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP,
- TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RANGE, TK_BETWEEN,
- TK_NOTHING, TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC,
- TK_DELETE, TK_CASE, TK_COLLATE, TK_CREATE, TK_CTIME_KW,
- TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_LIKE_KW,
- TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT,
- TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, TK_NOTNULL,
- TK_NOT, TK_NO, TK_NULL, TK_WHERE, TK_RECURSIVE,
- TK_AFTER, TK_RENAME, TK_AND, TK_DEFAULT, TK_AUTOINCR,
- TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, TK_COMMIT,
- TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_CURRENT,
- TK_PARTITION, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP,
- TK_PRECEDING, TK_FAIL, TK_FILTER, TK_REPLACE, TK_FOLLOWING,
- TK_FROM, TK_JOIN_KW, TK_IF, TK_ISNULL, TK_ORDER,
- TK_RESTRICT, TK_OVER, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS,
- TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM,
- TK_VIEW, TK_WINDOW, TK_DO, TK_INITIALLY, TK_ALL,
- TK_PRIMARY,
+ TK_EXCLUDE, TK_DELETE, TK_TEMP, TK_TEMP, TK_OR,
+ TK_CONSTRAINT, TK_INTERSECT, TK_TIES, TK_SAVEPOINT, TK_INTO,
+ TK_OFFSET, TK_OF, TK_SET, TK_TRANSACTION,TK_ACTION,
+ TK_ON, TK_JOIN_KW, TK_ALTER, TK_RAISE, TK_EXCEPT,
+ TK_TRIGGER, TK_REFERENCES, TK_UNIQUE, TK_QUERY, TK_WITHOUT,
+ TK_WITH, TK_JOIN_KW, TK_RELEASE, TK_EXCLUSIVE, TK_EXISTS,
+ TK_ATTACH, TK_HAVING, TK_LIKE_KW, TK_BEGIN, TK_JOIN_KW,
+ TK_RANGE, TK_BETWEEN, TK_NOTHING, TK_GROUPS, TK_GROUP,
+ TK_CASCADE, TK_ASC, TK_DETACH, TK_CASE, TK_COLLATE,
+ TK_CREATE, TK_CTIME_KW, TK_IMMEDIATE, TK_JOIN, TK_INSERT,
+ TK_LIKE_KW, TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA,
+ TK_ABORT, TK_UPDATE, TK_VALUES, TK_VIRTUAL, TK_LIMIT,
+ TK_WHEN, TK_NOTNULL, TK_NOT, TK_NO, TK_NULL,
+ TK_WHERE, TK_RECURSIVE, TK_AFTER, TK_RENAME, TK_AND,
+ TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, TK_CAST,
+ TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW,
+ TK_CTIME_KW, TK_CURRENT, TK_PARTITION, TK_DEFERRED, TK_DISTINCT,
+ TK_IS, TK_DROP, TK_PRECEDING, TK_FAIL, TK_FILTER,
+ TK_REPLACE, TK_FOLLOWING, TK_FROM, TK_JOIN_KW, TK_IF,
+ TK_ISNULL, TK_ORDER, TK_RESTRICT, TK_OTHERS, TK_OVER,
+ TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, TK_ROW, TK_UNBOUNDED,
+ TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_WINDOW,
+ TK_DO, TK_BY, TK_INITIALLY, TK_ALL, TK_PRIMARY,
};
/* Check to see if z[0..n-1] is a keyword. If it is, write the
** parser symbol code for that keyword into *pType. Always
@@ -150663,117 +153949,121 @@ static int keywordCode(const char *z, int n, int *pType){
testcase( i==22 ); /* END */
testcase( i==23 ); /* DEFERRABLE */
testcase( i==24 ); /* ELSE */
- testcase( i==25 ); /* EXCEPT */
- testcase( i==26 ); /* TRANSACTION */
- testcase( i==27 ); /* ACTION */
- testcase( i==28 ); /* ON */
- testcase( i==29 ); /* NATURAL */
- testcase( i==30 ); /* ALTER */
- testcase( i==31 ); /* RAISE */
- testcase( i==32 ); /* EXCLUSIVE */
- testcase( i==33 ); /* EXISTS */
- testcase( i==34 ); /* SAVEPOINT */
- testcase( i==35 ); /* INTERSECT */
- testcase( i==36 ); /* TRIGGER */
- testcase( i==37 ); /* REFERENCES */
- testcase( i==38 ); /* CONSTRAINT */
- testcase( i==39 ); /* INTO */
- testcase( i==40 ); /* OFFSET */
- testcase( i==41 ); /* OF */
- testcase( i==42 ); /* SET */
- testcase( i==43 ); /* TEMPORARY */
- testcase( i==44 ); /* TEMP */
- testcase( i==45 ); /* OR */
- testcase( i==46 ); /* UNIQUE */
- testcase( i==47 ); /* QUERY */
- testcase( i==48 ); /* WITHOUT */
- testcase( i==49 ); /* WITH */
- testcase( i==50 ); /* OUTER */
- testcase( i==51 ); /* RELEASE */
- testcase( i==52 ); /* ATTACH */
- testcase( i==53 ); /* HAVING */
- testcase( i==54 ); /* GROUP */
- testcase( i==55 ); /* UPDATE */
- testcase( i==56 ); /* BEGIN */
- testcase( i==57 ); /* INNER */
- testcase( i==58 ); /* RANGE */
- testcase( i==59 ); /* BETWEEN */
- testcase( i==60 ); /* NOTHING */
- testcase( i==61 ); /* GLOB */
- testcase( i==62 ); /* BY */
- testcase( i==63 ); /* CASCADE */
- testcase( i==64 ); /* ASC */
- testcase( i==65 ); /* DELETE */
- testcase( i==66 ); /* CASE */
- testcase( i==67 ); /* COLLATE */
- testcase( i==68 ); /* CREATE */
- testcase( i==69 ); /* CURRENT_DATE */
- testcase( i==70 ); /* DETACH */
- testcase( i==71 ); /* IMMEDIATE */
- testcase( i==72 ); /* JOIN */
- testcase( i==73 ); /* INSERT */
- testcase( i==74 ); /* LIKE */
- testcase( i==75 ); /* MATCH */
- testcase( i==76 ); /* PLAN */
- testcase( i==77 ); /* ANALYZE */
- testcase( i==78 ); /* PRAGMA */
- testcase( i==79 ); /* ABORT */
- testcase( i==80 ); /* VALUES */
- testcase( i==81 ); /* VIRTUAL */
- testcase( i==82 ); /* LIMIT */
- testcase( i==83 ); /* WHEN */
- testcase( i==84 ); /* NOTNULL */
- testcase( i==85 ); /* NOT */
- testcase( i==86 ); /* NO */
- testcase( i==87 ); /* NULL */
- testcase( i==88 ); /* WHERE */
- testcase( i==89 ); /* RECURSIVE */
- testcase( i==90 ); /* AFTER */
- testcase( i==91 ); /* RENAME */
- testcase( i==92 ); /* AND */
- testcase( i==93 ); /* DEFAULT */
- testcase( i==94 ); /* AUTOINCREMENT */
- testcase( i==95 ); /* TO */
- testcase( i==96 ); /* IN */
- testcase( i==97 ); /* CAST */
- testcase( i==98 ); /* COLUMN */
- testcase( i==99 ); /* COMMIT */
- testcase( i==100 ); /* CONFLICT */
- testcase( i==101 ); /* CROSS */
- testcase( i==102 ); /* CURRENT_TIMESTAMP */
- testcase( i==103 ); /* CURRENT_TIME */
- testcase( i==104 ); /* CURRENT */
- testcase( i==105 ); /* PARTITION */
- testcase( i==106 ); /* DEFERRED */
- testcase( i==107 ); /* DISTINCT */
- testcase( i==108 ); /* IS */
- testcase( i==109 ); /* DROP */
- testcase( i==110 ); /* PRECEDING */
- testcase( i==111 ); /* FAIL */
- testcase( i==112 ); /* FILTER */
- testcase( i==113 ); /* REPLACE */
- testcase( i==114 ); /* FOLLOWING */
- testcase( i==115 ); /* FROM */
- testcase( i==116 ); /* FULL */
- testcase( i==117 ); /* IF */
- testcase( i==118 ); /* ISNULL */
- testcase( i==119 ); /* ORDER */
- testcase( i==120 ); /* RESTRICT */
- testcase( i==121 ); /* OVER */
- testcase( i==122 ); /* RIGHT */
- testcase( i==123 ); /* ROLLBACK */
- testcase( i==124 ); /* ROWS */
- testcase( i==125 ); /* ROW */
- testcase( i==126 ); /* UNBOUNDED */
- testcase( i==127 ); /* UNION */
- testcase( i==128 ); /* USING */
- testcase( i==129 ); /* VACUUM */
- testcase( i==130 ); /* VIEW */
- testcase( i==131 ); /* WINDOW */
- testcase( i==132 ); /* DO */
- testcase( i==133 ); /* INITIALLY */
- testcase( i==134 ); /* ALL */
- testcase( i==135 ); /* PRIMARY */
+ testcase( i==25 ); /* EXCLUDE */
+ testcase( i==26 ); /* DELETE */
+ testcase( i==27 ); /* TEMPORARY */
+ testcase( i==28 ); /* TEMP */
+ testcase( i==29 ); /* OR */
+ testcase( i==30 ); /* CONSTRAINT */
+ testcase( i==31 ); /* INTERSECT */
+ testcase( i==32 ); /* TIES */
+ testcase( i==33 ); /* SAVEPOINT */
+ testcase( i==34 ); /* INTO */
+ testcase( i==35 ); /* OFFSET */
+ testcase( i==36 ); /* OF */
+ testcase( i==37 ); /* SET */
+ testcase( i==38 ); /* TRANSACTION */
+ testcase( i==39 ); /* ACTION */
+ testcase( i==40 ); /* ON */
+ testcase( i==41 ); /* NATURAL */
+ testcase( i==42 ); /* ALTER */
+ testcase( i==43 ); /* RAISE */
+ testcase( i==44 ); /* EXCEPT */
+ testcase( i==45 ); /* TRIGGER */
+ testcase( i==46 ); /* REFERENCES */
+ testcase( i==47 ); /* UNIQUE */
+ testcase( i==48 ); /* QUERY */
+ testcase( i==49 ); /* WITHOUT */
+ testcase( i==50 ); /* WITH */
+ testcase( i==51 ); /* OUTER */
+ testcase( i==52 ); /* RELEASE */
+ testcase( i==53 ); /* EXCLUSIVE */
+ testcase( i==54 ); /* EXISTS */
+ testcase( i==55 ); /* ATTACH */
+ testcase( i==56 ); /* HAVING */
+ testcase( i==57 ); /* GLOB */
+ testcase( i==58 ); /* BEGIN */
+ testcase( i==59 ); /* INNER */
+ testcase( i==60 ); /* RANGE */
+ testcase( i==61 ); /* BETWEEN */
+ testcase( i==62 ); /* NOTHING */
+ testcase( i==63 ); /* GROUPS */
+ testcase( i==64 ); /* GROUP */
+ testcase( i==65 ); /* CASCADE */
+ testcase( i==66 ); /* ASC */
+ testcase( i==67 ); /* DETACH */
+ testcase( i==68 ); /* CASE */
+ testcase( i==69 ); /* COLLATE */
+ testcase( i==70 ); /* CREATE */
+ testcase( i==71 ); /* CURRENT_DATE */
+ testcase( i==72 ); /* IMMEDIATE */
+ testcase( i==73 ); /* JOIN */
+ testcase( i==74 ); /* INSERT */
+ testcase( i==75 ); /* LIKE */
+ testcase( i==76 ); /* MATCH */
+ testcase( i==77 ); /* PLAN */
+ testcase( i==78 ); /* ANALYZE */
+ testcase( i==79 ); /* PRAGMA */
+ testcase( i==80 ); /* ABORT */
+ testcase( i==81 ); /* UPDATE */
+ testcase( i==82 ); /* VALUES */
+ testcase( i==83 ); /* VIRTUAL */
+ testcase( i==84 ); /* LIMIT */
+ testcase( i==85 ); /* WHEN */
+ testcase( i==86 ); /* NOTNULL */
+ testcase( i==87 ); /* NOT */
+ testcase( i==88 ); /* NO */
+ testcase( i==89 ); /* NULL */
+ testcase( i==90 ); /* WHERE */
+ testcase( i==91 ); /* RECURSIVE */
+ testcase( i==92 ); /* AFTER */
+ testcase( i==93 ); /* RENAME */
+ testcase( i==94 ); /* AND */
+ testcase( i==95 ); /* DEFAULT */
+ testcase( i==96 ); /* AUTOINCREMENT */
+ testcase( i==97 ); /* TO */
+ testcase( i==98 ); /* IN */
+ testcase( i==99 ); /* CAST */
+ testcase( i==100 ); /* COLUMN */
+ testcase( i==101 ); /* COMMIT */
+ testcase( i==102 ); /* CONFLICT */
+ testcase( i==103 ); /* CROSS */
+ testcase( i==104 ); /* CURRENT_TIMESTAMP */
+ testcase( i==105 ); /* CURRENT_TIME */
+ testcase( i==106 ); /* CURRENT */
+ testcase( i==107 ); /* PARTITION */
+ testcase( i==108 ); /* DEFERRED */
+ testcase( i==109 ); /* DISTINCT */
+ testcase( i==110 ); /* IS */
+ testcase( i==111 ); /* DROP */
+ testcase( i==112 ); /* PRECEDING */
+ testcase( i==113 ); /* FAIL */
+ testcase( i==114 ); /* FILTER */
+ testcase( i==115 ); /* REPLACE */
+ testcase( i==116 ); /* FOLLOWING */
+ testcase( i==117 ); /* FROM */
+ testcase( i==118 ); /* FULL */
+ testcase( i==119 ); /* IF */
+ testcase( i==120 ); /* ISNULL */
+ testcase( i==121 ); /* ORDER */
+ testcase( i==122 ); /* RESTRICT */
+ testcase( i==123 ); /* OTHERS */
+ testcase( i==124 ); /* OVER */
+ testcase( i==125 ); /* RIGHT */
+ testcase( i==126 ); /* ROLLBACK */
+ testcase( i==127 ); /* ROWS */
+ testcase( i==128 ); /* ROW */
+ testcase( i==129 ); /* UNBOUNDED */
+ testcase( i==130 ); /* UNION */
+ testcase( i==131 ); /* USING */
+ testcase( i==132 ); /* VACUUM */
+ testcase( i==133 ); /* VIEW */
+ testcase( i==134 ); /* WINDOW */
+ testcase( i==135 ); /* DO */
+ testcase( i==136 ); /* BY */
+ testcase( i==137 ); /* INITIALLY */
+ testcase( i==138 ); /* ALL */
+ testcase( i==139 ); /* PRIMARY */
*pType = aKWCode[i];
break;
}
@@ -150785,7 +154075,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
keywordCode((char*)z, n, &id);
return id;
}
-#define SQLITE_N_KEYWORD 136
+#define SQLITE_N_KEYWORD 140
SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){
if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR;
*pzName = zKWText + aKWOffset[i];
@@ -151218,6 +154508,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
#endif
+ VVA_ONLY( u8 startedWithOom = db->mallocFailed );
assert( zSql!=0 );
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
@@ -151227,7 +154518,14 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
assert( pzErrMsg!=0 );
- /* sqlite3ParserTrace(stdout, "parser: "); */
+#ifdef SQLITE_DEBUG
+ if( db->flags & SQLITE_ParserTrace ){
+ printf("parser: [[[%s]]]\n", zSql);
+ sqlite3ParserTrace(stdout, "parser: ");
+ }else{
+ sqlite3ParserTrace(0, 0);
+ }
+#endif
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
pEngine = &sEngine;
sqlite3ParserInit(pEngine, pParse);
@@ -151242,6 +154540,8 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
assert( pParse->pVList==0 );
+ pParse->pParentParse = db->pParse;
+ db->pParse = pParse;
while( 1 ){
n = sqlite3GetToken((u8*)zSql, &tokenType);
mxSqlLen -= n;
@@ -151298,7 +154598,8 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
lastTokenParsed = tokenType;
zSql += n;
- if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
+ assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom );
+ if( pParse->rc!=SQLITE_OK ) break;
}
assert( nErr==0 );
#ifdef YYTRACKMAXSTACKDEPTH
@@ -151366,10 +154667,147 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
pParse->pZombieTab = p->pNextZombie;
sqlite3DeleteTable(db, p);
}
+ db->pParse = pParse->pParentParse;
+ pParse->pParentParse = 0;
assert( nErr==0 || pParse->rc!=SQLITE_OK );
return nErr;
}
+
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Insert a single space character into pStr if the current string
+** ends with an identifier
+*/
+static void addSpaceSeparator(sqlite3_str *pStr){
+ if( pStr->nChar && sqlite3IsIdChar(pStr->zText[pStr->nChar-1]) ){
+ sqlite3_str_append(pStr, " ", 1);
+ }
+}
+
+/*
+** Compute a normalization of the SQL given by zSql[0..nSql-1]. Return
+** the normalization in space obtained from sqlite3DbMalloc(). Or return
+** NULL if anything goes wrong or if zSql is NULL.
+*/
+SQLITE_PRIVATE char *sqlite3Normalize(
+ Vdbe *pVdbe, /* VM being reprepared */
+ const char *zSql /* The original SQL string */
+){
+ sqlite3 *db; /* The database connection */
+ int i; /* Next unread byte of zSql[] */
+ int n; /* length of current token */
+ int tokenType; /* type of current token */
+ int prevType = 0; /* Previous non-whitespace token */
+ int nParen; /* Number of nested levels of parentheses */
+ int iStartIN; /* Start of RHS of IN operator in z[] */
+ int nParenAtIN; /* Value of nParent at start of RHS of IN operator */
+ int j; /* Bytes of normalized SQL generated so far */
+ sqlite3_str *pStr; /* The normalized SQL string under construction */
+
+ db = sqlite3VdbeDb(pVdbe);
+ tokenType = -1;
+ nParen = iStartIN = nParenAtIN = 0;
+ pStr = sqlite3_str_new(db);
+ assert( pStr!=0 ); /* sqlite3_str_new() never returns NULL */
+ for(i=0; zSql[i] && pStr->accError==0; i+=n){
+ if( tokenType!=TK_SPACE ){
+ prevType = tokenType;
+ }
+ n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType);
+ if( NEVER(n<=0) ) break;
+ switch( tokenType ){
+ case TK_SPACE: {
+ break;
+ }
+ case TK_NULL: {
+ if( prevType==TK_IS || prevType==TK_NOT ){
+ sqlite3_str_append(pStr, " NULL", 5);
+ break;
+ }
+ /* Fall through */
+ }
+ case TK_STRING:
+ case TK_INTEGER:
+ case TK_FLOAT:
+ case TK_VARIABLE:
+ case TK_BLOB: {
+ sqlite3_str_append(pStr, "?", 1);
+ break;
+ }
+ case TK_LP: {
+ nParen++;
+ if( prevType==TK_IN ){
+ iStartIN = pStr->nChar;
+ nParenAtIN = nParen;
+ }
+ sqlite3_str_append(pStr, "(", 1);
+ break;
+ }
+ case TK_RP: {
+ if( iStartIN>0 && nParen==nParenAtIN ){
+ assert( pStr->nChar>=iStartIN );
+ pStr->nChar = iStartIN+1;
+ sqlite3_str_append(pStr, "?,?,?", 5);
+ iStartIN = 0;
+ }
+ nParen--;
+ sqlite3_str_append(pStr, ")", 1);
+ break;
+ }
+ case TK_ID: {
+ iStartIN = 0;
+ j = pStr->nChar;
+ if( sqlite3Isquote(zSql[i]) ){
+ char *zId = sqlite3DbStrNDup(db, zSql+i, n);
+ int nId;
+ int eType = 0;
+ if( zId==0 ) break;
+ sqlite3Dequote(zId);
+ if( zSql[i]=='"' && sqlite3VdbeUsesDoubleQuotedString(pVdbe, zId) ){
+ sqlite3_str_append(pStr, "?", 1);
+ sqlite3DbFree(db, zId);
+ break;
+ }
+ nId = sqlite3Strlen30(zId);
+ if( sqlite3GetToken((u8*)zId, &eType)==nId && eType==TK_ID ){
+ addSpaceSeparator(pStr);
+ sqlite3_str_append(pStr, zId, nId);
+ }else{
+ sqlite3_str_appendf(pStr, "\"%w\"", zId);
+ }
+ sqlite3DbFree(db, zId);
+ }else{
+ addSpaceSeparator(pStr);
+ sqlite3_str_append(pStr, zSql+i, n);
+ }
+ while( jnChar ){
+ pStr->zText[j] = sqlite3Tolower(pStr->zText[j]);
+ j++;
+ }
+ break;
+ }
+ case TK_SELECT: {
+ iStartIN = 0;
+ /* fall through */
+ }
+ default: {
+ if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr);
+ j = pStr->nChar;
+ sqlite3_str_append(pStr, zSql+i, n);
+ while( jnChar ){
+ pStr->zText[j] = sqlite3Toupper(pStr->zText[j]);
+ j++;
+ }
+ break;
+ }
+ }
+ }
+ if( tokenType!=TK_SEMI ) sqlite3_str_append(pStr, ";", 1);
+ return sqlite3_str_finish(pStr);
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
+
/************** End of tokenize.c ********************************************/
/************** Begin file complete.c ****************************************/
/*
@@ -152415,6 +155853,13 @@ SQLITE_API int sqlite3_config(int op, ...){
}
#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
+#ifdef SQLITE_ENABLE_DESERIALIZE
+ case SQLITE_CONFIG_MEMDB_MAXSIZE: {
+ sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64);
+ break;
+ }
+#endif /* SQLITE_ENABLE_DESERIALIZE */
+
default: {
rc = SQLITE_ERROR;
break;
@@ -152460,7 +155905,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
pStart = 0;
}else if( pBuf==0 ){
sqlite3BeginBenignMalloc();
- pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */
+ pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt ); /* IMP: R-61949-35727 */
sqlite3EndBenignMalloc();
if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
}else{
@@ -152597,6 +156042,12 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
{ SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
{ SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
+ { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
+ { SQLITE_DBCONFIG_WRITABLE_SCHEMA, SQLITE_WriteSchema|
+ SQLITE_NoSchemaError },
+ { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter },
+ { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL },
+ { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -152604,11 +156055,11 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
if( aFlagOp[i].op==op ){
int onoff = va_arg(ap, int);
int *pRes = va_arg(ap, int*);
- u32 oldFlags = db->flags;
+ u64 oldFlags = db->flags;
if( onoff>0 ){
db->flags |= aFlagOp[i].mask;
}else if( onoff==0 ){
- db->flags &= ~aFlagOp[i].mask;
+ db->flags &= ~(u64)aFlagOp[i].mask;
}
if( oldFlags!=db->flags ){
sqlite3ExpirePreparedStatements(db, 0);
@@ -152627,28 +156078,17 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
return rc;
}
-
-/*
-** Return true if the buffer z[0..n-1] contains all spaces.
-*/
-static int allSpaces(const char *z, int n){
- while( n>0 && z[n-1]==' ' ){ n--; }
- return n==0;
-}
-
/*
** This is the default collating function named "BINARY" which is always
** available.
-**
-** If the padFlag argument is not NULL then space padding at the end
-** of strings is ignored. This implements the RTRIM collation.
*/
static int binCollFunc(
- void *padFlag,
+ void *NotUsed,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
int rc, n;
+ UNUSED_PARAMETER(NotUsed);
n = nKey1xCmp!=binCollFunc || p->pUser!=0
- || strcmp(p->zName,"BINARY")==0 );
- return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
+ assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 );
+ return p==0 || p->xCmp==binCollFunc;
}
/*
@@ -153071,7 +156515,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
/* Any deferred constraint violations have now been resolved. */
db->nDeferredCons = 0;
db->nDeferredImmCons = 0;
- db->flags &= ~SQLITE_DeferFKs;
+ db->flags &= ~(u64)SQLITE_DeferFKs;
/* If one has been configured, invoke the rollback-hook callback */
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
@@ -153813,6 +157257,8 @@ SQLITE_API void *sqlite3_profile(
pOld = db->pProfileArg;
db->xProfile = xProfile;
db->pProfileArg = pArg;
+ db->mTrace &= SQLITE_TRACE_NONLEGACY_MASK;
+ if( db->xProfile ) db->mTrace |= SQLITE_TRACE_XPROFILE;
sqlite3_mutex_leave(db->mutex);
return pOld;
}
@@ -154164,7 +157610,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
}else{
testcase( db->pErr==0 );
- z = (char*)sqlite3_value_text(db->pErr);
+ z = db->errCode ? (char*)sqlite3_value_text(db->pErr) : 0;
assert( !db->mallocFailed );
if( z==0 ){
z = sqlite3ErrStr(db->errCode);
@@ -154694,6 +158140,40 @@ SQLITE_PRIVATE int sqlite3ParseUri(
return rc;
}
+#if defined(SQLITE_HAS_CODEC)
+/*
+** Process URI filename query parameters relevant to the SQLite Encryption
+** Extension. Return true if any of the relevant query parameters are
+** seen and return false if not.
+*/
+SQLITE_PRIVATE int sqlite3CodecQueryParameters(
+ sqlite3 *db, /* Database connection */
+ const char *zDb, /* Which schema is being created/attached */
+ const char *zUri /* URI filename */
+){
+ const char *zKey;
+ if( (zKey = sqlite3_uri_parameter(zUri, "hexkey"))!=0 && zKey[0] ){
+ u8 iByte;
+ int i;
+ char zDecoded[40];
+ for(i=0, iByte=0; iszMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->nMaxSorterMmap = 0x7FFFFFFF;
- db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
+ db->flags |= SQLITE_ShortColNames
+ | SQLITE_EnableTrigger
+ | SQLITE_CacheSpill
+
+/* The SQLITE_DQS compile-time option determines the default settings
+** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
+**
+** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML
+** ---------- ----------------------- -----------------------
+** undefined on on
+** 3 on on
+** 2 on off
+** 1 off on
+** 0 off off
+**
+** Legacy behavior is 3 (double-quoted string literals are allowed anywhere)
+** and so that is the default. But developers are encouranged to use
+** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible.
+*/
+#if !defined(SQLITE_DQS)
+# define SQLITE_DQS 3
+#endif
+#if (SQLITE_DQS&1)==1
+ | SQLITE_DqsDML
+#endif
+#if (SQLITE_DQS&2)==2
+ | SQLITE_DqsDDL
+#endif
+
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
@@ -154823,6 +158331,9 @@ static int openDatabase(
#endif
#if defined(SQLITE_ENABLE_QPSG)
| SQLITE_EnableQPSG
+#endif
+#if defined(SQLITE_DEFAULT_DEFENSIVE)
+ | SQLITE_Defensive
#endif
;
sqlite3HashInit(&db->aCollSeq);
@@ -154841,7 +158352,7 @@ static int openDatabase(
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
- createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
+ createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
if( db->mallocFailed ){
goto opendb_out;
}
@@ -155036,26 +158547,13 @@ static int openDatabase(
}
#endif
#if defined(SQLITE_HAS_CODEC)
- if( rc==SQLITE_OK ){
- const char *zKey;
- if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){
- u8 iByte;
- int i;
- char zDecoded[40];
- for(i=0, iByte=0; i=0 );
return 5;
@@ -157901,13 +161449,18 @@ static int fts3DestroyMethod(sqlite3_vtab *pVtab){
sqlite3 *db = p->db; /* Database handle */
/* Drop the shadow tables */
- if( p->zContentTbl==0 ){
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
- }
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);
+ fts3DbExec(&rc, db,
+ "DROP TABLE IF EXISTS %Q.'%q_segments';"
+ "DROP TABLE IF EXISTS %Q.'%q_segdir';"
+ "DROP TABLE IF EXISTS %Q.'%q_docsize';"
+ "DROP TABLE IF EXISTS %Q.'%q_stat';"
+ "%s DROP TABLE IF EXISTS %Q.'%q_content';",
+ zDb, p->zName,
+ zDb, p->zName,
+ zDb, p->zName,
+ zDb, p->zName,
+ (p->zContentTbl ? "--" : ""), zDb,p->zName
+ );
/* If everything has worked, invoke fts3DisconnectMethod() to free the
** memory associated with the Fts3Table structure and return SQLITE_OK.
@@ -158139,10 +161692,10 @@ static void fts3Appendf(
** memory.
*/
static char *fts3QuoteId(char const *zInput){
- int nRet;
+ sqlite3_int64 nRet;
char *zRet;
nRet = 2 + (int)strlen(zInput)*2 + 1;
- zRet = sqlite3_malloc(nRet);
+ zRet = sqlite3_malloc64(nRet);
if( zRet ){
int i;
char *z = zRet;
@@ -158323,7 +161876,7 @@ static int fts3PrefixParameter(
}
}
- aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
+ aIndex = sqlite3_malloc64(sizeof(struct Fts3Index) * nIndex);
*apIndex = aIndex;
if( !aIndex ){
return SQLITE_NOMEM;
@@ -158402,7 +161955,7 @@ static int fts3ContentColumns(
if( rc==SQLITE_OK ){
const char **azCol; /* Output array */
- int nStr = 0; /* Size of all column names (incl. 0x00) */
+ sqlite3_int64 nStr = 0; /* Size of all column names (incl. 0x00) */
int nCol; /* Number of table columns */
int i; /* Used to iterate through columns */
@@ -158412,11 +161965,11 @@ static int fts3ContentColumns(
nCol = sqlite3_column_count(pStmt);
for(i=0; i=0 && nSuffix>=0 );
- if( &zCsr[nSuffix]>zEnd ){
+ if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr || nSuffix==0 ){
rc = FTS_CORRUPT_VTAB;
goto finish_scan;
}
- if( nPrefix+nSuffix>nAlloc ){
+ if( (i64)nPrefix+nSuffix>nAlloc ){
char *zNew;
- nAlloc = (nPrefix+nSuffix) * 2;
- zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
+ nAlloc = ((i64)nPrefix+nSuffix) * 2;
+ zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc);
if( !zNew ){
rc = SQLITE_NOMEM;
goto finish_scan;
@@ -159475,7 +163028,7 @@ static int fts3PutColNumber(char **pp, int iCol){
** updated appropriately. The caller is responsible for insuring
** that there is enough space in *pp to hold the complete output.
*/
-static void fts3PoslistMerge(
+static int fts3PoslistMerge(
char **pp, /* Output buffer */
char **pp1, /* Left input list */
char **pp2 /* Right input list */
@@ -159488,11 +163041,17 @@ static void fts3PoslistMerge(
int iCol1; /* The current column index in pp1 */
int iCol2; /* The current column index in pp2 */
- if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1);
+ if( *p1==POS_COLUMN ){
+ fts3GetVarint32(&p1[1], &iCol1);
+ if( iCol1==0 ) return FTS_CORRUPT_VTAB;
+ }
else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
else iCol1 = 0;
- if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2);
+ if( *p2==POS_COLUMN ){
+ fts3GetVarint32(&p2[1], &iCol2);
+ if( iCol2==0 ) return FTS_CORRUPT_VTAB;
+ }
else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
else iCol2 = 0;
@@ -159540,6 +163099,7 @@ static void fts3PoslistMerge(
*pp = p;
*pp1 = p1 + 1;
*pp2 = p2 + 1;
+ return SQLITE_OK;
}
/*
@@ -159604,10 +163164,9 @@ static int fts3PoslistPhraseMerge(
p += sqlite3Fts3PutVarint(p, iCol1);
}
- assert( *p1!=POS_END && *p1!=POS_COLUMN );
- assert( *p2!=POS_END && *p2!=POS_COLUMN );
fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2;
fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
+ if( iPos1<0 || iPos2<0 ) break;
while( 1 ){
if( iPos2==iPos1+nToken
@@ -159833,6 +163392,7 @@ static int fts3DoclistOrMerge(
char *a2, int n2, /* Second doclist */
char **paOut, int *pnOut /* OUT: Malloc'd doclist */
){
+ int rc = SQLITE_OK;
sqlite3_int64 i1 = 0;
sqlite3_int64 i2 = 0;
sqlite3_int64 iPrev = 0;
@@ -159876,7 +163436,7 @@ static int fts3DoclistOrMerge(
** A symetric argument may be made if the doclists are in descending
** order.
*/
- aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1);
+ aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING);
if( !aOut ) return SQLITE_NOMEM;
p = aOut;
@@ -159887,7 +163447,8 @@ static int fts3DoclistOrMerge(
if( p2 && p1 && iDiff==0 ){
fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1);
- fts3PoslistMerge(&p, &p1, &p2);
+ rc = fts3PoslistMerge(&p, &p1, &p2);
+ if( rc ) break;
fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
}else if( !p2 || (p1 && iDiff<0) ){
@@ -159901,10 +163462,16 @@ static int fts3DoclistOrMerge(
}
}
+ if( rc!=SQLITE_OK ){
+ sqlite3_free(aOut);
+ p = aOut = 0;
+ }else{
+ assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 );
+ memset(&aOut[(p-aOut)], 0, FTS3_BUFFER_PADDING);
+ }
*paOut = aOut;
*pnOut = (int)(p-aOut);
- assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 );
- return SQLITE_OK;
+ return rc;
}
/*
@@ -159939,7 +163506,7 @@ static int fts3DoclistPhraseMerge(
assert( nDist>0 );
if( bDescDoclist ){
- aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX);
+ aOut = sqlite3_malloc64((sqlite3_int64)*pnRight + FTS3_VARINT_MAX);
if( aOut==0 ) return SQLITE_NOMEM;
}else{
aOut = aRight;
@@ -160123,6 +163690,7 @@ static int fts3TermSelectMerge(
pTS->anOutput[0] = nDoclist;
if( pTS->aaOutput[0] ){
memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
+ memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX);
}else{
return SQLITE_NOMEM;
}
@@ -160174,8 +163742,8 @@ static int fts3SegReaderCursorAppend(
){
if( (pCsr->nSegment%16)==0 ){
Fts3SegReader **apNew;
- int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
- apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte);
+ sqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
+ apNew = (Fts3SegReader **)sqlite3_realloc64(pCsr->apSegment, nByte);
if( !apNew ){
sqlite3Fts3SegReaderFree(pNew);
return SQLITE_NOMEM;
@@ -160239,7 +163807,7 @@ static int fts3SegReaderCursor(
/* If zTerm is not NULL, and this segment is not stored entirely on its
** root node, the range of leaves scanned can be reduced. Do this. */
- if( iStartBlock && zTerm ){
+ if( iStartBlock && zTerm && zRoot ){
sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0);
rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi);
if( rc!=SQLITE_OK ) goto finished;
@@ -161181,14 +164749,28 @@ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
Fts3Table *p = (Fts3Table*)pVtab;
UNUSED_PARAMETER(iSavepoint);
assert( p->inTransaction );
- assert( p->mxSavepoint >= iSavepoint );
TESTONLY( p->mxSavepoint = iSavepoint );
sqlite3Fts3PendingTermsClear(p);
return SQLITE_OK;
}
+/*
+** Return true if zName is the extension on one of the shadow tables used
+** by this module.
+*/
+static int fts3ShadowName(const char *zName){
+ static const char *azName[] = {
+ "content", "docsize", "segdir", "segments", "stat",
+ };
+ unsigned int i;
+ for(i=0; inToken-1].nList;
- char *aDoclist = sqlite3_malloc(nByte+1);
+ char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING);
if( !aDoclist ) return SQLITE_NOMEM;
memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
+ memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING);
for(i=0; i<(p->nToken-1); i++){
if( a[i].bIgnore==0 ){
@@ -162331,7 +165917,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
Fts3TokenAndCost *aTC;
Fts3Expr **apOr;
- aTC = (Fts3TokenAndCost *)sqlite3_malloc(
+ aTC = (Fts3TokenAndCost *)sqlite3_malloc64(
sizeof(Fts3TokenAndCost) * nToken
+ sizeof(Fts3Expr *) * nOr * 2
);
@@ -162642,7 +166228,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
&& (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
){
Fts3Expr *p;
- int nTmp = 0; /* Bytes of temp space */
+ sqlite3_int64 nTmp = 0; /* Bytes of temp space */
char *aTmp; /* Temp space for PoslistNearMerge() */
/* Allocate temporary working space. */
@@ -162651,7 +166237,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
nTmp += p->pRight->pPhrase->doclist.nList;
}
nTmp += p->pPhrase->doclist.nList;
- aTmp = sqlite3_malloc(nTmp*2);
+ aTmp = sqlite3_malloc64(nTmp*2);
if( !aTmp ){
*pRc = SQLITE_NOMEM;
res = 0;
@@ -162921,15 +166507,14 @@ static void fts3EvalRestart(
** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase
** expression nodes.
*/
-static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
+static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){
if( pExpr ){
Fts3Phrase *pPhrase = pExpr->pPhrase;
if( pPhrase && pPhrase->doclist.pList ){
int iCol = 0;
char *p = pPhrase->doclist.pList;
- assert( *p );
- while( 1 ){
+ do{
u8 c = 0;
int iCnt = 0;
while( 0xFE & (*p | c) ){
@@ -162945,11 +166530,11 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
if( *p==0x00 ) break;
p++;
p += fts3GetVarint32(p, &iCol);
- }
+ }while( iColpLeft);
- fts3EvalUpdateCounts(pExpr->pRight);
+ fts3EvalUpdateCounts(pExpr->pLeft, nCol);
+ fts3EvalUpdateCounts(pExpr->pRight, nCol);
}
}
@@ -162993,7 +166578,7 @@ static int fts3EvalGatherStats(
for(p=pRoot; p; p=p->pLeft){
Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight);
assert( pE->aMI==0 );
- pE->aMI = (u32 *)sqlite3_malloc(pTab->nColumn * 3 * sizeof(u32));
+ pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32));
if( !pE->aMI ) return SQLITE_NOMEM;
memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32));
}
@@ -163019,7 +166604,7 @@ static int fts3EvalGatherStats(
);
if( rc==SQLITE_OK && pCsr->isEof==0 ){
- fts3EvalUpdateCounts(pRoot);
+ fts3EvalUpdateCounts(pRoot, pTab->nColumn);
}
}
@@ -163369,7 +166954,7 @@ static int fts3auxConnectMethod(
char const *zFts3; /* Name of fts3 table */
int nDb; /* Result of strlen(zDb) */
int nFts3; /* Result of strlen(zFts3) */
- int nByte; /* Bytes of space to allocate here */
+ sqlite3_int64 nByte; /* Bytes of space to allocate here */
int rc; /* value returned by declare_vtab() */
Fts3auxTable *p; /* Virtual table object to return */
@@ -163401,7 +166986,7 @@ static int fts3auxConnectMethod(
if( rc!=SQLITE_OK ) return rc;
nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
- p = (Fts3auxTable *)sqlite3_malloc(nByte);
+ p = (Fts3auxTable *)sqlite3_malloc64(nByte);
if( !p ) return SQLITE_NOMEM;
memset(p, 0, nByte);
@@ -163551,7 +167136,7 @@ static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){
static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){
if( nSize>pCsr->nStat ){
struct Fts3auxColstats *aNew;
- aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat,
+ aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat,
sizeof(struct Fts3auxColstats) * nSize
);
if( aNew==0 ) return SQLITE_NOMEM;
@@ -163719,15 +167304,15 @@ static int fts3auxFilterMethod(
assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) );
if( zStr ){
pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr);
- pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]);
if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM;
+ pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm);
}
}
if( iLe>=0 ){
pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe]));
- pCsr->nStop = sqlite3_value_bytes(apVal[iLe]);
if( pCsr->zStop==0 ) return SQLITE_NOMEM;
+ pCsr->nStop = (int)strlen(pCsr->zStop);
}
if( iLangid>=0 ){
@@ -163842,7 +167427,8 @@ SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
+ 0 /* xShadowName */
};
int rc; /* Return code */
@@ -163978,8 +167564,8 @@ static int fts3isspace(char c){
** zero the memory before returning a pointer to it. If unsuccessful,
** return NULL.
*/
-static void *fts3MallocZero(int nByte){
- void *pRet = sqlite3_malloc(nByte);
+static void *fts3MallocZero(sqlite3_int64 nByte){
+ void *pRet = sqlite3_malloc64(nByte);
if( pRet ) memset(pRet, 0, nByte);
return pRet;
}
@@ -164054,7 +167640,7 @@ static int getNextToken(
if( rc==SQLITE_OK ){
const char *zToken;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
- int nByte; /* total space to allocate */
+ sqlite3_int64 nByte; /* total space to allocate */
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
if( rc==SQLITE_OK ){
@@ -164108,8 +167694,8 @@ static int getNextToken(
** Enlarge a memory allocation. If an out-of-memory allocation occurs,
** then free the old allocation.
*/
-static void *fts3ReallocOrFree(void *pOrig, int nNew){
- void *pRet = sqlite3_realloc(pOrig, nNew);
+static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){
+ void *pRet = sqlite3_realloc64(pOrig, nNew);
if( !pRet ){
sqlite3_free(pOrig);
}
@@ -164353,7 +167939,6 @@ static int getNextNode(
int nConsumed = 0;
pParse->nNest++;
rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
- if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; }
*pnConsumed = (int)(zInput - z) + 1 + nConsumed;
return rc;
}else if( *zInput==')' ){
@@ -164652,7 +168237,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){
if( rc==SQLITE_OK ){
if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
Fts3Expr **apLeaf;
- apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
+ apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth);
if( 0==apLeaf ){
rc = SQLITE_NOMEM;
}else{
@@ -165072,7 +168657,7 @@ static void fts3ExprTestCommon(
zExpr = (const char *)sqlite3_value_text(argv[1]);
nExpr = sqlite3_value_bytes(argv[1]);
nCol = argc-2;
- azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
+ azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *));
if( !azCol ){
sqlite3_result_error_nomem(context);
goto exprtest_out;
@@ -165186,8 +168771,8 @@ SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash
/*
** Malloc and Free functions
*/
-static void *fts3HashMalloc(int n){
- void *p = sqlite3_malloc(n);
+static void *fts3HashMalloc(sqlite3_int64 n){
+ void *p = sqlite3_malloc64(n);
if( p ){
memset(p, 0, n);
}
@@ -166281,7 +169866,7 @@ static void fts3TokenizerFunc(
nName = sqlite3_value_bytes(argv[0])+1;
if( argc==2 ){
- if( fts3TokenizerEnabled(context) ){
+ if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){
void *pOld;
int n = sqlite3_value_bytes(argv[1]);
if( zName==0 || n!=sizeof(pPtr) ){
@@ -166308,7 +169893,9 @@ static void fts3TokenizerFunc(
return;
}
}
- sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
+ if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[0]) ){
+ sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
+ }
}
SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){
@@ -166396,8 +169983,8 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
int iArg = 0;
z = &z[n+1];
while( zzInput = sqlite3_malloc(nByte+1);
+ pCsr->zInput = sqlite3_malloc64(nByte+1);
if( pCsr->zInput==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -167401,7 +170988,8 @@ SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
+ 0 /* xShadowName */
};
int rc; /* Return code */
@@ -167811,10 +171399,12 @@ static int fts3SqlStmt(
pStmt = p->aStmt[eStmt];
if( !pStmt ){
+ int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
char *zSql;
if( eStmt==SQL_CONTENT_INSERT ){
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
}else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
+ f &= ~SQLITE_PREPARE_NO_VTAB;
zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
}else{
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
@@ -167822,8 +171412,7 @@ static int fts3SqlStmt(
if( !zSql ){
rc = SQLITE_NOMEM;
}else{
- rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
- &pStmt, NULL);
+ rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL);
sqlite3_free(zSql);
assert( rc==SQLITE_OK || pStmt==0 );
p->aStmt[eStmt] = pStmt;
@@ -167981,7 +171570,7 @@ static sqlite3_int64 getAbsoluteLevel(
int iLevel /* Level of segments */
){
sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */
- assert( iLangid>=0 );
+ assert_fts3_nc( iLangid>=0 );
assert( p->nIndex>0 );
assert( iIndex>=0 && iIndexnIndex );
@@ -168762,7 +172351,9 @@ static int fts3SegReaderNext(
/* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf
** blocks have already been traversed. */
- assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock );
+#ifdef CORRUPT_DB
+ assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock || CORRUPT_DB );
+#endif
if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){
return SQLITE_OK;
}
@@ -168789,15 +172380,19 @@ static int fts3SegReaderNext(
** safe (no risk of overread) even if the node data is corrupted. */
pNext += fts3GetVarint32(pNext, &nPrefix);
pNext += fts3GetVarint32(pNext, &nSuffix);
- if( nPrefix<0 || nSuffix<=0
- || &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
+ if( nSuffix<=0
+ || (&pReader->aNode[pReader->nNode] - pNext)pReader->nTermAlloc
){
return FTS_CORRUPT_VTAB;
}
- if( nPrefix+nSuffix>pReader->nTermAlloc ){
- int nNew = (nPrefix+nSuffix)*2;
- char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
+ /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are
+ ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer
+ ** overflow - hence the (i64) casts. */
+ if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){
+ i64 nNew = ((i64)nPrefix+nSuffix)*2;
+ char *zNew = sqlite3_realloc64(pReader->zTerm, nNew);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -168819,7 +172414,7 @@ static int fts3SegReaderNext(
** b-tree node. And that the final byte of the doclist is 0x00. If either
** of these statements is untrue, then the data structure is corrupt.
*/
- if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
+ if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
){
return FTS_CORRUPT_VTAB;
@@ -169019,8 +172614,13 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
Fts3SegReader *pReader; /* Newly allocated SegReader object */
int nExtra = 0; /* Bytes to allocate segment root node */
- assert( iStartLeaf<=iEndLeaf );
+ assert( zRoot!=0 || nRoot==0 );
+#ifdef CORRUPT_DB
+ assert( zRoot!=0 || CORRUPT_DB );
+#endif
+
if( iStartLeaf==0 ){
+ if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB;
nExtra = nRoot + FTS3_NODE_PADDING;
}
@@ -169040,7 +172640,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
pReader->aNode = (char *)&pReader[1];
pReader->rootOnly = 1;
pReader->nNode = nRoot;
- memcpy(pReader->aNode, zRoot, nRoot);
+ if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot);
memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
}else{
pReader->iCurrentBlock = iStartLeaf-1;
@@ -169155,8 +172755,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending(
}
if( nElem>0 ){
- int nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *);
- pReader = (Fts3SegReader *)sqlite3_malloc(nByte);
+ sqlite3_int64 nByte;
+ nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *);
+ pReader = (Fts3SegReader *)sqlite3_malloc64(nByte);
if( !pReader ){
rc = SQLITE_NOMEM;
}else{
@@ -169660,6 +173261,11 @@ static int fts3SegWriterAdd(
nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm);
nSuffix = nTerm-nPrefix;
+ /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of
+ ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when
+ ** compared with BINARY collation. This indicates corruption. */
+ if( nSuffix<=0 ) return FTS_CORRUPT_VTAB;
+
/* Figure out how many bytes are required by this new entry */
nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */
sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */
@@ -170016,14 +173622,14 @@ static void fts3ColumnFilter(
nList -= (int)(p - pList);
pList = p;
- if( nList==0 ){
+ if( nList<=0 ){
break;
}
p = &pList[1];
p += fts3GetVarint32(p, &iCurrent);
}
- if( bZero && &pList[nList]!=pEnd ){
+ if( bZero && (pEnd - &pList[nList])>0){
memset(&pList[nList], 0, pEnd - &pList[nList]);
}
*ppList = pList;
@@ -170367,7 +173973,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
}else{
iDelta = iDocid - iPrev;
}
- assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) );
+ if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){
+ return FTS_CORRUPT_VTAB;
+ }
assert( nDoclist>0 || iDelta==iDocid );
nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
@@ -170633,8 +174241,10 @@ static int fts3SegmentMerge(
if( rc!=SQLITE_OK ) goto finished;
assert( csr.nSegment>0 );
- assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) );
- assert( iNewLevel=getAbsoluteLevel(p, iLangid, iIndex, 0) );
+ assert_fts3_nc(
+ iNewLevelnColumn );
+ pBlob = sqlite3_malloc64( 10*(sqlite3_int64)p->nColumn );
if( pBlob==0 ){
*pRC = SQLITE_NOMEM;
return;
@@ -170809,7 +174421,7 @@ static void fts3UpdateDocTotals(
const int nStat = p->nColumn+2;
if( *pRC ) return;
- a = sqlite3_malloc( (sizeof(u32)+10)*nStat );
+ a = sqlite3_malloc64( (sizeof(u32)+10)*(sqlite3_int64)nStat );
if( a==0 ){
*pRC = SQLITE_NOMEM;
return;
@@ -170930,8 +174542,8 @@ static int fts3DoRebuild(Fts3Table *p){
}
if( rc==SQLITE_OK ){
- int nByte = sizeof(u32) * (p->nColumn+1)*3;
- aSz = (u32 *)sqlite3_malloc(nByte);
+ sqlite3_int64 nByte = sizeof(u32) * ((sqlite3_int64)p->nColumn+1)*3;
+ aSz = (u32 *)sqlite3_malloc64(nByte);
if( aSz==0 ){
rc = SQLITE_NOMEM;
}else{
@@ -170997,12 +174609,12 @@ static int fts3IncrmergeCsr(
){
int rc; /* Return Code */
sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */
- int nByte; /* Bytes allocated at pCsr->apSegment[] */
+ sqlite3_int64 nByte; /* Bytes allocated at pCsr->apSegment[] */
/* Allocate space for the Fts3MultiSegReader.aCsr[] array */
memset(pCsr, 0, sizeof(*pCsr));
nByte = sizeof(Fts3SegReader *) * nSeg;
- pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc(nByte);
+ pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc64(nByte);
if( pCsr->apSegment==0 ){
rc = SQLITE_NOMEM;
@@ -171145,6 +174757,9 @@ static int nodeReaderNext(NodeReader *p){
}
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
+ if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
+ return FTS_CORRUPT_VTAB;
+ }
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
if( rc==SQLITE_OK ){
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
@@ -171152,14 +174767,16 @@ static int nodeReaderNext(NodeReader *p){
p->iOff += nSuffix;
if( p->iChild==0 ){
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
+ if( (p->nNode-p->iOff)nDoclist ){
+ return FTS_CORRUPT_VTAB;
+ }
p->aDoclist = &p->aNode[p->iOff];
p->iOff += p->nDoclist;
}
}
}
- assert( p->iOff<=p->nNode );
-
+ assert_fts3_nc( p->iOff<=p->nNode );
return rc;
}
@@ -171320,7 +174937,7 @@ static int fts3AppendToNode(
/* Node must have already been started. There must be a doclist for a
** leaf node, and there must not be a doclist for an internal node. */
assert( pNode->n>0 );
- assert( (pNode->a[0]=='\0')==(aDoclist!=0) );
+ assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) );
blobGrowBuffer(pPrev, nTerm, &rc);
if( rc!=SQLITE_OK ) return rc;
@@ -171536,7 +175153,7 @@ static int fts3TermCmp(
int nCmp = MIN(nLhs, nRhs);
int res;
- res = memcmp(zLhs, zRhs, nCmp);
+ res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0);
if( res==0 ) res = nLhs - nRhs;
return res;
@@ -171668,10 +175285,13 @@ static int fts3IncrmergeLoad(
pNode = &pWriter->aNodeWriter[nHeight];
pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight;
- blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc);
+ blobGrowBuffer(&pNode->block,
+ MAX(nRoot, p->nNodeSize)+FTS3_NODE_PADDING, &rc
+ );
if( rc==SQLITE_OK ){
memcpy(pNode->block.a, aRoot, nRoot);
pNode->block.n = nRoot;
+ memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
}
for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
@@ -171679,23 +175299,28 @@ static int fts3IncrmergeLoad(
pNode = &pWriter->aNodeWriter[i];
rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
- while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
- blobGrowBuffer(&pNode->key, reader.term.n, &rc);
- if( rc==SQLITE_OK ){
- memcpy(pNode->key.a, reader.term.a, reader.term.n);
- pNode->key.n = reader.term.n;
- if( i>0 ){
- char *aBlock = 0;
- int nBlock = 0;
- pNode = &pWriter->aNodeWriter[i-1];
- pNode->iBlock = reader.iChild;
- rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
- blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize), &rc);
- if( rc==SQLITE_OK ){
- memcpy(pNode->block.a, aBlock, nBlock);
- pNode->block.n = nBlock;
+ if( reader.aNode ){
+ while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
+ blobGrowBuffer(&pNode->key, reader.term.n, &rc);
+ if( rc==SQLITE_OK ){
+ memcpy(pNode->key.a, reader.term.a, reader.term.n);
+ pNode->key.n = reader.term.n;
+ if( i>0 ){
+ char *aBlock = 0;
+ int nBlock = 0;
+ pNode = &pWriter->aNodeWriter[i-1];
+ pNode->iBlock = reader.iChild;
+ rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
+ blobGrowBuffer(&pNode->block,
+ MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc
+ );
+ if( rc==SQLITE_OK ){
+ memcpy(pNode->block.a, aBlock, nBlock);
+ pNode->block.n = nBlock;
+ memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING);
+ }
+ sqlite3_free(aBlock);
}
- sqlite3_free(aBlock);
}
}
nodeReaderRelease(&reader);
@@ -171938,7 +175563,10 @@ static int fts3TruncateNode(
NodeReader reader; /* Reader object */
Blob prev = {0, 0, 0}; /* Previous term written to new node */
int rc = SQLITE_OK; /* Return code */
- int bLeaf = aNode[0]=='\0'; /* True for a leaf node */
+ int bLeaf; /* True for a leaf node */
+
+ if( nNode<1 ) return FTS_CORRUPT_VTAB;
+ bLeaf = aNode[0]=='\0';
/* Allocate required output space */
blobGrowBuffer(pNew, nNode, &rc);
@@ -172977,7 +176605,7 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
}
/* Allocate space to hold the change in document sizes */
- aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
+ aSzDel = sqlite3_malloc64(sizeof(aSzDel[0])*((sqlite3_int64)p->nColumn+1)*2);
if( aSzDel==0 ){
rc = SQLITE_NOMEM;
goto update_out;
@@ -173231,17 +176859,19 @@ struct StrBuffer {
/*
** Allocate a two-slot MatchinfoBuffer object.
*/
-static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
+static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
MatchinfoBuffer *pRet;
- int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
- int nStr = (int)strlen(zMatchinfo);
+ sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
+ + sizeof(MatchinfoBuffer);
+ sqlite3_int64 nStr = strlen(zMatchinfo);
- pRet = sqlite3_malloc(nByte + nStr+1);
+ pRet = sqlite3_malloc64(nByte + nStr+1);
if( pRet ){
memset(pRet, 0, nByte);
pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
- pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
- pRet->nElem = nElem;
+ pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
+ + sizeof(u32)*((int)nElem+1);
+ pRet->nElem = (int)nElem;
pRet->zMatchinfo = ((char*)pRet) + nByte;
memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
pRet->aRef[0] = 1;
@@ -173281,7 +176911,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
aOut = &p->aMatchinfo[p->nElem+2];
xRet = fts3MIBufferFree;
}else{
- aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
+ aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32));
if( aOut ){
xRet = sqlite3_free;
if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
@@ -173532,11 +177162,12 @@ static void fts3SnippetDetails(
char *pCsr = pPhrase->pTail;
int iCsr = pPhrase->iTail;
- while( iCsr<(iStart+pIter->nSnippet) ){
+ while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){
int j;
u64 mPhrase = (u64)1 << i;
u64 mPos = (u64)1 << (iCsr - iStart);
- assert( iCsr>=iStart );
+ assert( iCsr>=iStart && (iCsr - iStart)<=64 );
+ assert( i>=0 && i<=64 );
if( (mCover|mCovered)&mPhrase ){
iScore++;
}else{
@@ -173578,11 +177209,14 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
int iFirst = 0;
pPhrase->pList = pCsr;
fts3GetDeltaPosition(&pCsr, &iFirst);
- assert( iFirst>=0 );
- pPhrase->pHead = pCsr;
- pPhrase->pTail = pCsr;
- pPhrase->iHead = iFirst;
- pPhrase->iTail = iFirst;
+ if( iFirst<0 ){
+ rc = FTS_CORRUPT_VTAB;
+ }else{
+ pPhrase->pHead = pCsr;
+ pPhrase->pTail = pCsr;
+ pPhrase->iHead = iFirst;
+ pPhrase->iTail = iFirst;
+ }
}else{
assert( rc!=SQLITE_OK || (
pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0
@@ -173619,7 +177253,7 @@ static int fts3BestSnippet(
int rc; /* Return Code */
int nList; /* Number of phrases in expression */
SnippetIter sIter; /* Iterates through snippet candidates */
- int nByte; /* Number of bytes of space to allocate */
+ sqlite3_int64 nByte; /* Number of bytes of space to allocate */
int iBestScore = -1; /* Best snippet score found so far */
int i; /* Loop counter */
@@ -173637,7 +177271,7 @@ static int fts3BestSnippet(
** the required space using malloc().
*/
nByte = sizeof(SnippetPhrase) * nList;
- sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte);
+ sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte);
if( !sIter.aPhrase ){
return SQLITE_NOMEM;
}
@@ -173707,8 +177341,8 @@ static int fts3StringAppend(
** appended data.
*/
if( pStr->n+nAppend+1>=pStr->nAlloc ){
- int nAlloc = pStr->nAlloc+nAppend+100;
- char *zNew = sqlite3_realloc(pStr->z, nAlloc);
+ sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100;
+ char *zNew = sqlite3_realloc64(pStr->z, nAlloc);
if( !zNew ){
return SQLITE_NOMEM;
}
@@ -173763,6 +177397,7 @@ static int fts3SnippetShift(
for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++);
for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++);
+ assert( (nSnippet-1-nRight)<=63 && (nSnippet-1-nRight)>=0 );
nDesired = (nLeft-nRight)/2;
/* Ideally, the start of the snippet should be pushed forward in the
@@ -173955,7 +177590,7 @@ static int fts3ColumnlistCount(char **ppCollist){
/*
** This function gathers 'y' or 'b' data for a single phrase.
*/
-static void fts3ExprLHits(
+static int fts3ExprLHits(
Fts3Expr *pExpr, /* Phrase expression node */
MatchInfo *p /* Matchinfo context */
){
@@ -173985,25 +177620,29 @@ static void fts3ExprLHits(
if( *pIter!=0x01 ) break;
pIter++;
pIter += fts3GetVarint32(pIter, &iCol);
+ if( iCol>=p->nCol ) return FTS_CORRUPT_VTAB;
}
+ return SQLITE_OK;
}
/*
** Gather the results for matchinfo directives 'y' and 'b'.
*/
-static void fts3ExprLHitGather(
+static int fts3ExprLHitGather(
Fts3Expr *pExpr,
MatchInfo *p
){
+ int rc = SQLITE_OK;
assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
if( pExpr->pLeft ){
- fts3ExprLHitGather(pExpr->pLeft, p);
- fts3ExprLHitGather(pExpr->pRight, p);
+ rc = fts3ExprLHitGather(pExpr->pLeft, p);
+ if( rc==SQLITE_OK ) rc = fts3ExprLHitGather(pExpr->pRight, p);
}else{
- fts3ExprLHits(pExpr, p);
+ rc = fts3ExprLHits(pExpr, p);
}
}
+ return rc;
}
/*
@@ -174093,8 +177732,8 @@ static int fts3MatchinfoCheck(
return SQLITE_ERROR;
}
-static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
- int nVal; /* Number of integers output by cArg */
+static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
+ size_t nVal; /* Number of integers output by cArg */
switch( cArg ){
case FTS3_MATCHINFO_NDOC:
@@ -174220,11 +177859,12 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
int i;
int iCol;
int nToken = 0;
+ int rc = SQLITE_OK;
/* Allocate and populate the array of LcsIterator objects. The array
** contains one element for each matchable phrase in the query.
**/
- aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase);
+ aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase);
if( !aIter ) return SQLITE_NOMEM;
memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
(void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
@@ -174240,13 +177880,16 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
int nLive = 0; /* Number of iterators in aIter not at EOF */
for(i=0; inPhrase; i++){
- int rc;
LcsIterator *pIt = &aIter[i];
rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead);
- if( rc!=SQLITE_OK ) return rc;
+ if( rc!=SQLITE_OK ) goto matchinfo_lcs_out;
if( pIt->pRead ){
pIt->iPos = pIt->iPosOffset;
- fts3LcsIteratorAdvance(&aIter[i]);
+ fts3LcsIteratorAdvance(pIt);
+ if( pIt->pRead==0 ){
+ rc = FTS_CORRUPT_VTAB;
+ goto matchinfo_lcs_out;
+ }
nLive++;
}
}
@@ -174278,8 +177921,9 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
pInfo->aMatchinfo[iCol] = nLcs;
}
+ matchinfo_lcs_out:
sqlite3_free(aIter);
- return SQLITE_OK;
+ return rc;
}
/*
@@ -174373,9 +178017,9 @@ static int fts3MatchinfoValues(
case FTS3_MATCHINFO_LHITS_BM:
case FTS3_MATCHINFO_LHITS: {
- int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
+ size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
memset(pInfo->aMatchinfo, 0, nZero);
- fts3ExprLHitGather(pCsr->pExpr, pInfo);
+ rc = fts3ExprLHitGather(pCsr->pExpr, pInfo);
break;
}
@@ -174442,7 +178086,7 @@ static void fts3GetMatchinfo(
** initialize those elements that are constant for every row.
*/
if( pCsr->pMIBuffer==0 ){
- int nMatchinfo = 0; /* Number of u32 elements in match-info */
+ size_t nMatchinfo = 0; /* Number of u32 elements in match-info */
int i; /* Used to iterate through zArg */
/* Determine the number of phrases in the query */
@@ -174527,6 +178171,10 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet(
return;
}
+ /* Limit the snippet length to 64 tokens. */
+ if( nToken<-64 ) nToken = -64;
+ if( nToken>+64 ) nToken = +64;
+
for(nSnippet=1; 1; nSnippet++){
int iSnip; /* Loop counter 0..nSnippet-1 */
@@ -174628,7 +178276,7 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
nTerm = pExpr->pPhrase->nToken;
if( pList ){
fts3GetDeltaPosition(&pList, &iPos);
- assert( iPos>=0 );
+ assert_fts3_nc( iPos>=0 );
}
for(iTerm=0; iTermpList) ){
pTerm->pList = 0;
}else{
@@ -174894,7 +178542,7 @@ typedef struct unicode_cursor unicode_cursor;
struct unicode_tokenizer {
sqlite3_tokenizer base;
- int bRemoveDiacritic;
+ int eRemoveDiacritic;
int nException;
int *aiException;
};
@@ -174967,7 +178615,7 @@ static int unicodeAddExceptions(
int *aNew; /* New aiException[] array */
int nNew; /* Number of valid entries in array aNew[] */
- aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
+ aNew = sqlite3_realloc64(p->aiException,(p->nException+nEntry)*sizeof(int));
if( aNew==0 ) return SQLITE_NOMEM;
nNew = p->nException;
@@ -175039,17 +178687,20 @@ static int unicodeCreate(
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
if( pNew==NULL ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(unicode_tokenizer));
- pNew->bRemoveDiacritic = 1;
+ pNew->eRemoveDiacritic = 1;
for(i=0; rc==SQLITE_OK && ibRemoveDiacritic = 1;
+ pNew->eRemoveDiacritic = 1;
}
else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
- pNew->bRemoveDiacritic = 0;
+ pNew->eRemoveDiacritic = 0;
+ }
+ else if( n==19 && memcmp("remove_diacritics=2", z, 19)==0 ){
+ pNew->eRemoveDiacritic = 2;
}
else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){
rc = unicodeAddExceptions(pNew, 1, &z[11], n-11);
@@ -175153,7 +178804,7 @@ static int unicodeNext(
/* Grow the output buffer if required. */
if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
- char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
+ char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64);
if( !zNew ) return SQLITE_NOMEM;
zOut = &zNew[zOut - pCsr->zToken];
pCsr->zToken = zNew;
@@ -175162,7 +178813,7 @@ static int unicodeNext(
/* Write the folded case of the last character read to the output */
zEnd = z;
- iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
+ iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic);
if( iOut ){
WRITE_UTF8(zOut, iOut);
}
@@ -175207,7 +178858,7 @@ SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const *
/************** End of fts3_unicode.c ****************************************/
/************** Begin file fts3_unicode2.c ***********************************/
/*
-** 2012 May 25
+** 2012-05-25
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -175367,32 +179018,48 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
** E"). The resuls of passing a codepoint that corresponds to an
** uppercase letter are undefined.
*/
-static int remove_diacritic(int c){
+static int remove_diacritic(int c, int bComplex){
unsigned short aDia[] = {
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
- 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
- 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
- 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
- 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
- 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
- 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
- 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
- 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
- 62924, 63050, 63082, 63274, 63390,
+ 3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896,
+ 3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106,
+ 4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344,
+ 4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198,
+ 6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468,
+ 61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704,
+ 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914,
+ 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218,
+ 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554,
+ 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766,
+ 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118,
+ 63182, 63242, 63274, 63310, 63368, 63390,
};
- char aChar[] = {
- '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
- 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
- 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
- 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
- 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
- '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
- 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
- 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
- 'e', 'i', 'o', 'u', 'y',
+#define HIBIT ((unsigned char)0x80)
+ unsigned char aChar[] = {
+ '\0', 'a', 'c', 'e', 'i', 'n',
+ 'o', 'u', 'y', 'y', 'a', 'c',
+ 'd', 'e', 'e', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'n', 'o', 'r',
+ 's', 't', 'u', 'u', 'w', 'y',
+ 'z', 'o', 'u', 'a', 'i', 'o',
+ 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o',
+ 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a',
+ 'e', 'i', 'o', 'r', 'u', 's',
+ 't', 'h', 'a', 'e', 'o'|HIBIT, 'o',
+ 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0',
+ '\0', '\0', '\0', '\0', 'a', 'b',
+ 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT,
+ 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT,
+ 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n',
+ 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's',
+ 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w',
+ 'w', 'x', 'y', 'z', 'h', 't',
+ 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT,
+ 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT,
+ 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y',
};
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -175409,7 +179076,8 @@ static int remove_diacritic(int c){
}
}
assert( key>=aDia[iRes] );
- return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
+ if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
+ return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
}
@@ -175422,8 +179090,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
return (c < 768+32) ?
- (mask0 & (1 << (c-768))) :
- (mask1 & (1 << (c-768-32)));
+ (mask0 & ((unsigned int)1 << (c-768))) :
+ (mask1 & ((unsigned int)1 << (c-768-32)));
}
@@ -175436,7 +179104,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
** The results are undefined if the value passed to this function
** is less than zero.
*/
-SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
+SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
@@ -175559,7 +179227,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
assert( ret>0 );
}
- if( bRemoveDiacritic ) ret = remove_diacritic(ret);
+ if( eRemoveDiacritic ){
+ ret = remove_diacritic(ret, eRemoveDiacritic==2);
+ }
}
else if( c>=66560 && c<66600 ){
@@ -176266,7 +179936,7 @@ static JSON_NOINLINE int jsonParseAddNodeExpand(
assert( pParse->nNode>=pParse->nAlloc );
if( pParse->oom ) return -1;
nNew = pParse->nAlloc*2 + 10;
- pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
+ pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew);
if( pNew==0 ){
pParse->oom = 1;
return -1;
@@ -176540,7 +180210,7 @@ static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){
static int jsonParseFindParents(JsonParse *pParse){
u32 *aUp;
assert( pParse->aUp==0 );
- aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode );
+ aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode );
if( aUp==0 ){
pParse->oom = 1;
return SQLITE_NOMEM;
@@ -176602,7 +180272,7 @@ static JsonParse *jsonParseCached(
pMatch->iHold = iMaxHold+1;
return pMatch;
}
- p = sqlite3_malloc( sizeof(*p) + nJson + 1 );
+ p = sqlite3_malloc64( sizeof(*p) + nJson + 1 );
if( p==0 ){
sqlite3_result_error_nomem(pCtx);
return 0;
@@ -176698,7 +180368,7 @@ static JsonNode *jsonLookupStep(
u32 iStart, iLabel;
JsonNode *pNode;
iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
- iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
+ iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
zPath += i;
pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
if( pParse->oom ) return 0;
@@ -177569,6 +181239,9 @@ static int jsonEachConnect(
#define JEACH_PARENT 5
#define JEACH_FULLKEY 6
#define JEACH_PATH 7
+/* The xBestIndex method assumes that the JSON and ROOT columns are
+** the last two columns in the table. Should this ever changes, be
+** sure to update the xBestIndex method. */
#define JEACH_JSON 8
#define JEACH_ROOT 9
@@ -177826,35 +181499,54 @@ static int jsonEachBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
- int i;
- int jsonIdx = -1;
- int rootIdx = -1;
+ int i; /* Loop counter or computed array index */
+ int aIdx[2]; /* Index of constraints for JSON and ROOT */
+ int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */
+ int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */
const struct sqlite3_index_constraint *pConstraint;
+ /* This implementation assumes that JSON and ROOT are the last two
+ ** columns in the table */
+ assert( JEACH_ROOT == JEACH_JSON+1 );
UNUSED_PARAM(tab);
+ aIdx[0] = aIdx[1] = -1;
pConstraint = pIdxInfo->aConstraint;
for(i=0; inConstraint; i++, pConstraint++){
- if( pConstraint->usable==0 ) continue;
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
- switch( pConstraint->iColumn ){
- case JEACH_JSON: jsonIdx = i; break;
- case JEACH_ROOT: rootIdx = i; break;
- default: /* no-op */ break;
- }
- }
- if( jsonIdx<0 ){
+ int iCol;
+ int iMask;
+ if( pConstraint->iColumn < JEACH_JSON ) continue;
+ iCol = pConstraint->iColumn - JEACH_JSON;
+ assert( iCol==0 || iCol==1 );
+ iMask = 1 << iCol;
+ if( pConstraint->usable==0 ){
+ unusableMask |= iMask;
+ }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ aIdx[iCol] = i;
+ idxMask |= iMask;
+ }
+ }
+ if( (unusableMask & ~idxMask)!=0 ){
+ /* If there are any unusable constraints on JSON or ROOT, then reject
+ ** this entire plan */
+ return SQLITE_CONSTRAINT;
+ }
+ if( aIdx[0]<0 ){
+ /* No JSON input. Leave estimatedCost at the huge value that it was
+ ** initialized to to discourage the query planner from selecting this
+ ** plan. */
pIdxInfo->idxNum = 0;
- pIdxInfo->estimatedCost = 1e99;
}else{
pIdxInfo->estimatedCost = 1.0;
- pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
- pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
- if( rootIdx<0 ){
- pIdxInfo->idxNum = 1;
+ i = aIdx[0];
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ if( aIdx[1]<0 ){
+ pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */
}else{
- pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
- pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
- pIdxInfo->idxNum = 3;
+ i = aIdx[1];
+ pIdxInfo->aConstraintUsage[i].argvIndex = 2;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */
}
}
return SQLITE_OK;
@@ -177963,7 +181655,8 @@ static sqlite3_module jsonEachModule = {
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
+ 0 /* xShadowName */
};
/* The methods of the json_tree virtual table. */
@@ -177990,7 +181683,8 @@ static sqlite3_module jsonTreeModule = {
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
+ 0 /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -178158,10 +181852,6 @@ SQLITE_API int sqlite3_json_init(
/* #include "sqlite3.h" */
#endif
-/* #include */
-/* #include */
-/* #include */
-
#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
@@ -178169,8 +181859,18 @@ typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+# define NDEBUG 1
+#endif
+#if defined(NDEBUG) && defined(SQLITE_DEBUG)
+# undef NDEBUG
+#endif
#endif
+/* #include */
+/* #include */
+/* #include */
+
/* The following macro is used to suppress compiler warnings.
*/
#ifndef UNUSED_PARAMETER
@@ -178223,6 +181923,9 @@ struct Rtree {
u8 inWrTrans; /* True if inside write transaction */
u8 nAux; /* # of auxiliary columns in %_rowid */
u8 nAuxNotNull; /* Number of initial not-null aux columns */
+#ifdef SQLITE_DEBUG
+ u8 bCorrupt; /* Shadow table corruption detected */
+#endif
int iDepth; /* Current depth of the r-tree structure */
char *zDb; /* Name of database containing r-tree table */
char *zName; /* Name of r-tree table */
@@ -178282,6 +181985,15 @@ struct Rtree {
# define RTREE_ZERO 0.0
#endif
+/*
+** Set the Rtree.bCorrupt flag
+*/
+#ifdef SQLITE_DEBUG
+# define RTREE_IS_CORRUPT(X) ((X)->bCorrupt = 1)
+#else
+# define RTREE_IS_CORRUPT(X)
+#endif
+
/*
** When doing a search of an r-tree, instances of the following structure
** record intermediate results from the tree walk.
@@ -178648,8 +182360,8 @@ static void nodeZero(Rtree *pRtree, RtreeNode *p){
** Given a node number iNode, return the corresponding key to use
** in the Rtree.aHash table.
*/
-static int nodeHash(i64 iNode){
- return iNode % HASHSIZE;
+static unsigned int nodeHash(i64 iNode){
+ return ((unsigned)iNode) % HASHSIZE;
}
/*
@@ -178694,7 +182406,7 @@ static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){
*/
static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
RtreeNode *pNode;
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
+ pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode) + pRtree->iNodeSize);
if( pNode ){
memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
pNode->zData = (u8 *)&pNode[1];
@@ -178718,6 +182430,18 @@ static void nodeBlobReset(Rtree *pRtree){
}
}
+/*
+** Check to see if pNode is the same as pParent or any of the parents
+** of pParent.
+*/
+static int nodeInParentChain(const RtreeNode *pNode, const RtreeNode *pParent){
+ do{
+ if( pNode==pParent ) return 1;
+ pParent = pParent->pParent;
+ }while( pParent );
+ return 0;
+}
+
/*
** Obtain a reference to an r-tree node.
*/
@@ -178736,6 +182460,10 @@ static int nodeAcquire(
if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
if( pParent && !pNode->pParent ){
+ if( nodeInParentChain(pNode, pParent) ){
+ RTREE_IS_CORRUPT(pRtree);
+ return SQLITE_CORRUPT_VTAB;
+ }
pParent->nRef++;
pNode->pParent = pParent;
}
@@ -178766,9 +182494,12 @@ static int nodeAcquire(
*ppNode = 0;
/* If unable to open an sqlite3_blob on the desired row, that can only
** be because the shadow tables hold erroneous data. */
- if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB;
+ if( rc==SQLITE_ERROR ){
+ rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
+ }
}else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
+ pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize);
if( !pNode ){
rc = SQLITE_NOMEM;
}else{
@@ -178781,7 +182512,6 @@ static int nodeAcquire(
pNode->pNext = 0;
rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData,
pRtree->iNodeSize, 0);
- nodeReference(pParent);
}
}
@@ -178795,6 +182525,7 @@ static int nodeAcquire(
pRtree->iDepth = readInt16(pNode->zData);
if( pRtree->iDepth>RTREE_MAX_DEPTH ){
rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
}
}
@@ -178805,14 +182536,17 @@ static int nodeAcquire(
if( pNode && rc==SQLITE_OK ){
if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
}
}
if( rc==SQLITE_OK ){
if( pNode!=0 ){
+ nodeReference(pParent);
nodeHashInsert(pRtree, pNode);
}else{
rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
}
*ppNode = pNode;
}else{
@@ -179038,7 +182772,7 @@ static void rtreeRelease(Rtree *pRtree){
pRtree->inWrTrans = 0;
assert( pRtree->nCursor==0 );
nodeBlobReset(pRtree);
- assert( pRtree->nNodeRef==0 );
+ assert( pRtree->nNodeRef==0 || pRtree->bCorrupt );
sqlite3_finalize(pRtree->pWriteNode);
sqlite3_finalize(pRtree->pDeleteNode);
sqlite3_finalize(pRtree->pReadRowid);
@@ -179097,7 +182831,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
Rtree *pRtree = (Rtree *)pVTab;
RtreeCursor *pCsr;
- pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
+ pCsr = (RtreeCursor *)sqlite3_malloc64(sizeof(RtreeCursor));
if( pCsr ){
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = pVTab;
@@ -179370,6 +183104,7 @@ static int nodeRowidIndex(
return SQLITE_OK;
}
}
+ RTREE_IS_CORRUPT(pRtree);
return SQLITE_CORRUPT_VTAB;
}
@@ -179463,7 +183198,7 @@ static RtreeSearchPoint *rtreeEnqueue(
RtreeSearchPoint *pNew;
if( pCur->nPoint>=pCur->nPointAlloc ){
int nNew = pCur->nPointAlloc*2 + 8;
- pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0]));
+ pNew = sqlite3_realloc64(pCur->aPoint, nNew*sizeof(pCur->aPoint[0]));
if( pNew==0 ) return 0;
pCur->aPoint = pNew;
pCur->nPointAlloc = nNew;
@@ -179865,7 +183600,7 @@ static int rtreeFilter(
*/
rc = nodeAcquire(pRtree, 1, 0, &pRoot);
if( rc==SQLITE_OK && argc>0 ){
- pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
+ pCsr->aConstraint = sqlite3_malloc64(sizeof(RtreeConstraint)*argc);
pCsr->nConstraint = argc;
if( !pCsr->aConstraint ){
rc = SQLITE_NOMEM;
@@ -180010,20 +183745,20 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
){
u8 op;
switch( p->op ){
- case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
- case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
- case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
- case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
- case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
- default:
- assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
- op = RTREE_MATCH;
- break;
+ case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
+ case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
+ case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
+ case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
+ case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
+ case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break;
+ default: op = 0; break;
+ }
+ if( op ){
+ zIdxStr[iIdx++] = op;
+ zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
+ pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
+ pIdxInfo->aConstraintUsage[ii].omit = 1;
}
- zIdxStr[iIdx++] = op;
- zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
- pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
- pIdxInfo->aConstraintUsage[ii].omit = 1;
}
}
@@ -180059,11 +183794,11 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
#endif
{
switch( pRtree->nDim ){
- case 5: area = p->aCoord[9].i - p->aCoord[8].i;
- case 4: area *= p->aCoord[7].i - p->aCoord[6].i;
- case 3: area *= p->aCoord[5].i - p->aCoord[4].i;
- case 2: area *= p->aCoord[3].i - p->aCoord[2].i;
- default: area *= p->aCoord[1].i - p->aCoord[0].i;
+ case 5: area = (i64)p->aCoord[9].i - (i64)p->aCoord[8].i;
+ case 4: area *= (i64)p->aCoord[7].i - (i64)p->aCoord[6].i;
+ case 3: area *= (i64)p->aCoord[5].i - (i64)p->aCoord[4].i;
+ case 2: area *= (i64)p->aCoord[3].i - (i64)p->aCoord[2].i;
+ default: area *= (i64)p->aCoord[1].i - (i64)p->aCoord[0].i;
}
}
return area;
@@ -180232,12 +183967,14 @@ static int AdjustTree(
RtreeCell *pCell /* This cell was just inserted */
){
RtreeNode *p = pNode;
+ int cnt = 0;
while( p->pParent ){
RtreeNode *pParent = p->pParent;
RtreeCell cell;
int iCell;
- if( nodeParentIndex(pRtree, p, &iCell) ){
+ if( (++cnt)>1000 || nodeParentIndex(pRtree, p, &iCell) ){
+ RTREE_IS_CORRUPT(pRtree);
return SQLITE_CORRUPT_VTAB;
}
@@ -180434,9 +184171,9 @@ static int splitNodeStartree(
int iBestSplit = 0;
RtreeDValue fBestMargin = RTREE_ZERO;
- int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
+ sqlite3_int64 nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
- aaSorted = (int **)sqlite3_malloc(nByte);
+ aaSorted = (int **)sqlite3_malloc64(nByte);
if( !aaSorted ){
return SQLITE_NOMEM;
}
@@ -180557,7 +184294,7 @@ static int SplitNode(
/* Allocate an array and populate it with a copy of pCell and
** all cells from node pLeft. Then zero the original node.
*/
- aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
+ aCell = sqlite3_malloc64((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
if( !aCell ){
rc = SQLITE_NOMEM;
goto splitnode_out;
@@ -180705,7 +184442,10 @@ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
}
rc = sqlite3_reset(pRtree->pReadParent);
if( rc==SQLITE_OK ) rc = rc2;
- if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB;
+ if( rc==SQLITE_OK && !pChild->pParent ){
+ RTREE_IS_CORRUPT(pRtree);
+ rc = SQLITE_CORRUPT_VTAB;
+ }
pChild = pChild->pParent;
}
return rc;
@@ -180845,7 +184585,7 @@ static int Reinsert(
/* Allocate the buffers used by this operation. The allocation is
** relinquished before this function returns.
*/
- aCell = (RtreeCell *)sqlite3_malloc(n * (
+ aCell = (RtreeCell *)sqlite3_malloc64(n * (
sizeof(RtreeCell) + /* aCell array */
sizeof(int) + /* aOrder array */
sizeof(int) + /* aSpare array */
@@ -181019,8 +184759,12 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
rc = findLeafNode(pRtree, iDelete, &pLeaf, 0);
}
+#ifdef CORRUPT_DB
+ assert( pLeaf!=0 || rc!=SQLITE_OK || CORRUPT_DB );
+#endif
+
/* Delete the cell in question from the leaf node. */
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK && pLeaf ){
int rc2;
rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell);
if( rc==SQLITE_OK ){
@@ -181292,7 +185036,7 @@ static int rtreeUpdate(
rc = rc2;
}
}
- if( pRtree->nAux ){
+ if( rc==SQLITE_OK && pRtree->nAux ){
sqlite3_stmt *pUp = pRtree->pWriteAux;
int jj;
sqlite3_bind_int64(pUp, 1, *pRowid);
@@ -181420,8 +185164,24 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
return rc;
}
+
+/*
+** Return true if zName is the extension on one of the shadow tables used
+** by this module.
+*/
+static int rtreeShadowName(const char *zName){
+ static const char *azName[] = {
+ "node", "parent", "rowid"
+ };
+ unsigned int i;
+ for(i=0; idb = db;
@@ -181529,8 +185291,7 @@ static int rtreeSqlInit(
}
zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
if( zSql ){
- rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
- appStmt[i], 0);
+ rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0);
}else{
rc = SQLITE_NOMEM;
}
@@ -181560,8 +185321,7 @@ static int rtreeSqlInit(
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
- rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
- &pRtree->pWriteAux, 0);
+ rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0);
sqlite3_free(zSql);
}
}
@@ -181637,6 +185397,7 @@ static int getNodeSize(
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
}else if( pRtree->iNodeSize<(512-64) ){
rc = SQLITE_CORRUPT_VTAB;
+ RTREE_IS_CORRUPT(pRtree);
*pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
pRtree->zName);
}
@@ -181692,7 +185453,7 @@ static int rtreeInit(
/* Allocate the sqlite3_vtab structure */
nDb = (int)strlen(argv[1]);
nName = (int)strlen(argv[2]);
- pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
+ pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2);
if( !pRtree ){
return SQLITE_NOMEM;
}
@@ -181789,49 +185550,45 @@ static int rtreeInit(
** *2 coordinates.
*/
static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
- char *zText = 0;
RtreeNode node;
Rtree tree;
int ii;
+ int nData;
+ int errCode;
+ sqlite3_str *pOut;
UNUSED_PARAMETER(nArg);
memset(&node, 0, sizeof(RtreeNode));
memset(&tree, 0, sizeof(Rtree));
tree.nDim = (u8)sqlite3_value_int(apArg[0]);
+ if( tree.nDim<1 || tree.nDim>5 ) return;
tree.nDim2 = tree.nDim*2;
tree.nBytesPerCell = 8 + 8 * tree.nDim;
node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
+ nData = sqlite3_value_bytes(apArg[1]);
+ if( nData<4 ) return;
+ if( nData0 ) sqlite3_str_append(pOut, " ", 1);
+ sqlite3_str_appendf(pOut, "{%lld", cell.iRowid);
for(jj=0; jjrc==SQLITE_OK );
- if( pCheck->pGetNode==0 ){
+ if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){
pCheck->pGetNode = rtreeCheckPrepare(pCheck,
"SELECT data FROM %Q.'%q_node' WHERE nodeno=?",
pCheck->zDb, pCheck->zTab
@@ -181973,7 +185729,7 @@ static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){
int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0);
const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0);
- pRet = sqlite3_malloc(nNode);
+ pRet = sqlite3_malloc64(nNode);
if( pRet==0 ){
pCheck->rc = SQLITE_NOMEM;
}else{
@@ -182434,14 +186190,32 @@ typedef float GeoCoord;
**
** encoding (1 byte) 0=big-endian, 1=little-endian
** nvertex (3 bytes) Number of vertexes as a big-endian integer
+**
+** Enough space is allocated for 4 coordinates, to work around over-zealous
+** warnings coming from some compiler (notably, clang). In reality, the size
+** of each GeoPoly memory allocate is adjusted as necessary so that the
+** GeoPoly.a[] array at the end is the appropriate size.
*/
typedef struct GeoPoly GeoPoly;
struct GeoPoly {
int nVertex; /* Number of vertexes */
unsigned char hdr[4]; /* Header for on-disk representation */
- GeoCoord a[2]; /* 2*nVertex values. X (longitude) first, then Y */
+ GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */
};
+/* The size of a memory allocation needed for a GeoPoly object sufficient
+** to hold N coordinate pairs.
+*/
+#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
+
+/* Macros to access coordinates of a GeoPoly.
+** We have to use these macros, rather than just say p->a[i] in order
+** to silence (incorrect) UBSAN warnings if the array index is too large.
+*/
+#define GeoX(P,I) (((GeoCoord*)(P)->a)[(I)*2])
+#define GeoY(P,I) (((GeoCoord*)(P)->a)[(I)*2+1])
+
+
/*
** State of a parse of a GeoJSON input.
*/
@@ -182466,7 +186240,7 @@ static void geopolySwab32(unsigned char *a){
/* Skip whitespace. Return the next non-whitespace character. */
static char geopolySkipSpace(GeoParse *p){
- while( p->z[0] && safe_isspace(p->z[0]) ) p->z++;
+ while( safe_isspace(p->z[0]) ) p->z++;
return p->z[0];
}
@@ -182486,7 +186260,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
for(;; j++){
c = z[j];
- if( c>='0' && c<='9' ) continue;
+ if( safe_isdigit(c) ) continue;
if( c=='.' ){
if( z[j-1]=='-' ) return 0;
if( seenDP ) return 0;
@@ -182508,7 +186282,17 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
break;
}
if( z[j-1]<'0' ) return 0;
- if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z);
+ if( pVal ){
+#ifdef SQLITE_AMALGAMATION
+ /* The sqlite3AtoF() routine is much much faster than atof(), if it
+ ** is available */
+ double r;
+ (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
+ *pVal = r;
+#else
+ *pVal = (GeoCoord)atof((const char*)p->z);
+#endif
+ }
p->z += j;
return 1;
}
@@ -182566,12 +186350,10 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){
&& s.a[1]==s.a[s.nVertex*2-1]
&& (s.z++, geopolySkipSpace(&s)==0)
){
- int nByte;
GeoPoly *pOut;
int x = 1;
s.nVertex--; /* Remove the redundant vertex at the end */
- nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
- pOut = sqlite3_malloc64( nByte );
+ pOut = sqlite3_malloc64( GEOPOLY_SZ((sqlite3_int64)s.nVertex) );
x = 1;
if( pOut==0 ) goto parse_json_err;
pOut->nVertex = s.nVertex;
@@ -182626,8 +186408,9 @@ static GeoPoly *geopolyFuncParam(
memcpy(p->hdr, a, nByte);
if( a[0] != *(unsigned char*)&x ){
int ii;
- for(ii=0; iia[ii]);
+ for(ii=0; iihdr[0] ^= 1;
}
@@ -182686,9 +186469,9 @@ static void geopolyJsonFunc(
int i;
sqlite3_str_append(x, "[", 1);
for(i=0; inVertex; i++){
- sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]);
+ sqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i));
}
- sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]);
+ sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0));
sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
sqlite3_free(p);
}
@@ -182705,7 +186488,9 @@ static void geopolySvgFunc(
int argc,
sqlite3_value **argv
){
- GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ GeoPoly *p;
+ if( argc<1 ) return;
+ p = geopolyFuncParam(context, argv[0], 0);
if( p ){
sqlite3 *db = sqlite3_context_db_handle(context);
sqlite3_str *x = sqlite3_str_new(db);
@@ -182713,10 +186498,10 @@ static void geopolySvgFunc(
char cSep = '\'';
sqlite3_str_appendf(x, "a[i*2], p->a[i*2+1]);
+ sqlite3_str_appendf(x, "%c%g,%g", cSep, GeoX(p,i), GeoY(p,i));
cSep = ' ';
}
- sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]);
+ sqlite3_str_appendf(x, " %g,%g'", GeoX(p,0), GeoY(p,0));
for(i=1; inVertex; ii++){
- x0 = p->a[ii*2];
- y0 = p->a[ii*2+1];
+ x0 = GeoX(p,ii);
+ y0 = GeoY(p,ii);
x1 = (GeoCoord)(A*x0 + B*y0 + E);
y1 = (GeoCoord)(C*x0 + D*y0 + F);
- p->a[ii*2] = x1;
- p->a[ii*2+1] = y1;
+ GeoX(p,ii) = x1;
+ GeoY(p,ii) = y1;
}
sqlite3_result_blob(context, p->hdr,
4+8*p->nVertex, SQLITE_TRANSIENT);
@@ -182774,6 +186559,27 @@ static void geopolyXformFunc(
}
}
+/*
+** Compute the area enclosed by the polygon.
+**
+** This routine can also be used to detect polygons that rotate in
+** the wrong direction. Polygons are suppose to be counter-clockwise (CCW).
+** This routine returns a negative value for clockwise (CW) polygons.
+*/
+static double geopolyArea(GeoPoly *p){
+ double rArea = 0.0;
+ int ii;
+ for(ii=0; iinVertex-1; ii++){
+ rArea += (GeoX(p,ii) - GeoX(p,ii+1)) /* (x0 - x1) */
+ * (GeoY(p,ii) + GeoY(p,ii+1)) /* (y0 + y1) */
+ * 0.5;
+ }
+ rArea += (GeoX(p,ii) - GeoX(p,0)) /* (xN - x0) */
+ * (GeoY(p,ii) + GeoY(p,0)) /* (yN + y0) */
+ * 0.5;
+ return rArea;
+}
+
/*
** Implementation of the geopoly_area(X) function.
**
@@ -182789,21 +186595,106 @@ static void geopolyAreaFunc(
){
GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
if( p ){
- double rArea = 0.0;
- int ii;
- for(ii=0; iinVertex-1; ii++){
- rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
- * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
- * 0.5;
- }
- rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
- * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
- * 0.5;
- sqlite3_result_double(context, rArea);
+ sqlite3_result_double(context, geopolyArea(p));
sqlite3_free(p);
}
}
+/*
+** Implementation of the geopoly_ccw(X) function.
+**
+** If the rotation of polygon X is clockwise (incorrect) instead of
+** counter-clockwise (the correct winding order according to RFC7946)
+** then reverse the order of the vertexes in polygon X.
+**
+** In other words, this routine returns a CCW polygon regardless of the
+** winding order of its input.
+**
+** Use this routine to sanitize historical inputs that that sometimes
+** contain polygons that wind in the wrong direction.
+*/
+static void geopolyCcwFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ if( p ){
+ if( geopolyArea(p)<0.0 ){
+ int ii, jj;
+ for(ii=1, jj=p->nVertex-1; iihdr,
+ 4+8*p->nVertex, SQLITE_TRANSIENT);
+ sqlite3_free(p);
+ }
+}
+
+#define GEOPOLY_PI 3.1415926535897932385
+
+/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
+*/
+static double geopolySine(double r){
+ assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
+ if( r>=1.5*GEOPOLY_PI ){
+ r -= 2.0*GEOPOLY_PI;
+ }
+ if( r>=0.5*GEOPOLY_PI ){
+ return -geopolySine(r-GEOPOLY_PI);
+ }else{
+ double r2 = r*r;
+ double r3 = r2*r;
+ double r5 = r3*r2;
+ return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
+ }
+}
+
+/*
+** Function: geopoly_regular(X,Y,R,N)
+**
+** Construct a simple, convex, regular polygon centered at X, Y
+** with circumradius R and with N sides.
+*/
+static void geopolyRegularFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ double x = sqlite3_value_double(argv[0]);
+ double y = sqlite3_value_double(argv[1]);
+ double r = sqlite3_value_double(argv[2]);
+ int n = sqlite3_value_int(argv[3]);
+ int i;
+ GeoPoly *p;
+
+ if( n<3 || r<=0.0 ) return;
+ if( n>1000 ) n = 1000;
+ p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
+ if( p==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }
+ i = 1;
+ p->hdr[0] = *(unsigned char*)&i;
+ p->hdr[1] = 0;
+ p->hdr[2] = (n>>8)&0xff;
+ p->hdr[3] = n&0xff;
+ for(i=0; ihdr, 4+8*n, SQLITE_TRANSIENT);
+ sqlite3_free(p);
+}
+
/*
** If pPoly is a polygon, compute its bounding box. Then:
**
@@ -182835,20 +186726,20 @@ static GeoPoly *geopolyBBox(
}
if( p ){
int ii;
- mnX = mxX = p->a[0];
- mnY = mxY = p->a[1];
+ mnX = mxX = GeoX(p,0);
+ mnY = mxY = GeoY(p,0);
for(ii=1; iinVertex; ii++){
- double r = p->a[ii*2];
+ double r = GeoX(p,ii);
if( rmxX ) mxX = (float)r;
- r = p->a[ii*2+1];
+ r = GeoY(p,ii);
if( rmxY ) mxY = (float)r;
}
if( pRc ) *pRc = SQLITE_OK;
if( aCoord==0 ){
geopolyBboxFill:
- pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6);
+ pOut = sqlite3_realloc64(p, GEOPOLY_SZ(4));
if( pOut==0 ){
sqlite3_free(p);
if( context ) sqlite3_result_error_nomem(context);
@@ -182861,14 +186752,14 @@ static GeoPoly *geopolyBBox(
pOut->hdr[1] = 0;
pOut->hdr[2] = 0;
pOut->hdr[3] = 4;
- pOut->a[0] = mnX;
- pOut->a[1] = mnY;
- pOut->a[2] = mxX;
- pOut->a[3] = mnY;
- pOut->a[4] = mxX;
- pOut->a[5] = mxY;
- pOut->a[6] = mnX;
- pOut->a[7] = mxY;
+ GeoX(pOut,0) = mnX;
+ GeoY(pOut,0) = mnY;
+ GeoX(pOut,1) = mxX;
+ GeoY(pOut,1) = mnY;
+ GeoX(pOut,2) = mxX;
+ GeoY(pOut,2) = mxY;
+ GeoX(pOut,3) = mnX;
+ GeoY(pOut,3) = mxY;
}else{
sqlite3_free(p);
aCoord[0].f = mnX;
@@ -183006,14 +186897,14 @@ static void geopolyContainsPointFunc(
int ii;
if( p1==0 ) return;
for(ii=0; iinVertex-1; ii++){
- v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
- p1->a[ii*2+2],p1->a[ii*2+3]);
+ v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
+ GeoX(p1,ii+1),GeoY(p1,ii+1));
if( v==2 ) break;
cnt += v;
}
if( v!=2 ){
- v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
- p1->a[0],p1->a[1]);
+ v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
+ GeoX(p1,0), GeoY(p1,0));
}
if( v==2 ){
sqlite3_result_int(context, 1);
@@ -183135,10 +187026,10 @@ static void geopolyAddSegments(
unsigned int i;
GeoCoord *x;
for(i=0; i<(unsigned)pPoly->nVertex-1; i++){
- x = pPoly->a + (i*2);
+ x = &GeoX(pPoly,i);
geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i);
}
- x = pPoly->a + (i*2);
+ x = &GeoX(pPoly,i);
geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i);
}
@@ -183244,9 +187135,9 @@ static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){
** Determine the overlap between two polygons
*/
static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
- int nVertex = p1->nVertex + p2->nVertex + 2;
+ sqlite3_int64 nVertex = p1->nVertex + p2->nVertex + 2;
GeoOverlap *p;
- int nByte;
+ sqlite3_int64 nByte;
GeoEvent *pThisEvent;
double rX;
int rc = 0;
@@ -183258,7 +187149,7 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
nByte = sizeof(GeoEvent)*nVertex*2
+ sizeof(GeoSegment)*nVertex
+ sizeof(GeoOverlap);
- p = sqlite3_malloc( nByte );
+ p = sqlite3_malloc64( nByte );
if( p==0 ) return -1;
p->aEvent = (GeoEvent*)&p[1];
p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2];
@@ -183417,8 +187308,8 @@ static int geopolyInit(
){
int rc = SQLITE_OK;
Rtree *pRtree;
- int nDb; /* Length of string argv[1] */
- int nName; /* Length of string argv[2] */
+ sqlite3_int64 nDb; /* Length of string argv[1] */
+ sqlite3_int64 nName; /* Length of string argv[2] */
sqlite3_str *pSql;
char *zSql;
int ii;
@@ -183426,9 +187317,9 @@ static int geopolyInit(
sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
/* Allocate the sqlite3_vtab structure */
- nDb = (int)strlen(argv[1]);
- nName = (int)strlen(argv[2]);
- pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
+ nDb = strlen(argv[1]);
+ nName = strlen(argv[2]);
+ pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2);
if( !pRtree ){
return SQLITE_NOMEM;
}
@@ -183876,7 +187767,16 @@ static int geopolyUpdate(
if( sqlite3_value_nochange(aData[2]) ){
sqlite3_bind_null(pUp, 2);
}else{
- sqlite3_bind_value(pUp, 2, aData[2]);
+ GeoPoly *p = 0;
+ if( sqlite3_value_type(aData[2])==SQLITE_TEXT
+ && (p = geopolyFuncParam(0, aData[2], &rc))!=0
+ && rc==SQLITE_OK
+ ){
+ sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_bind_value(pUp, 2, aData[2]);
+ }
+ sqlite3_free(p);
nChange = 1;
}
for(jj=1; jjnAux; jj++){
@@ -183920,7 +187820,7 @@ static int geopolyFindFunction(
static sqlite3_module geopolyModule = {
- 2, /* iVersion */
+ 3, /* iVersion */
geopolyCreate, /* xCreate - create a table */
geopolyConnect, /* xConnect - connect to an existing table */
geopolyBestIndex, /* xBestIndex - Determine search strategy */
@@ -183943,25 +187843,29 @@ static sqlite3_module geopolyModule = {
rtreeSavepoint, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
+ rtreeShadowName /* xShadowName */
};
static int sqlite3_geopoly_init(sqlite3 *db){
int rc = SQLITE_OK;
static const struct {
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
- int nArg;
+ signed char nArg;
+ unsigned char bPure;
const char *zName;
} aFunc[] = {
- { geopolyAreaFunc, 1, "geopoly_area" },
- { geopolyBlobFunc, 1, "geopoly_blob" },
- { geopolyJsonFunc, 1, "geopoly_json" },
- { geopolySvgFunc, -1, "geopoly_svg" },
- { geopolyWithinFunc, 2, "geopoly_within" },
- { geopolyContainsPointFunc, 3, "geopoly_contains_point" },
- { geopolyOverlapFunc, 2, "geopoly_overlap" },
- { geopolyDebugFunc, 1, "geopoly_debug" },
- { geopolyBBoxFunc, 1, "geopoly_bbox" },
- { geopolyXformFunc, 7, "geopoly_xform" },
+ { geopolyAreaFunc, 1, 1, "geopoly_area" },
+ { geopolyBlobFunc, 1, 1, "geopoly_blob" },
+ { geopolyJsonFunc, 1, 1, "geopoly_json" },
+ { geopolySvgFunc, -1, 1, "geopoly_svg" },
+ { geopolyWithinFunc, 2, 1, "geopoly_within" },
+ { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" },
+ { geopolyOverlapFunc, 2, 1, "geopoly_overlap" },
+ { geopolyDebugFunc, 1, 0, "geopoly_debug" },
+ { geopolyBBoxFunc, 1, 1, "geopoly_bbox" },
+ { geopolyXformFunc, 7, 1, "geopoly_xform" },
+ { geopolyRegularFunc, 4, 1, "geopoly_regular" },
+ { geopolyCcwFunc, 1, 1, "geopoly_ccw" },
};
static const struct {
void (*xStep)(sqlite3_context*,int,sqlite3_value**);
@@ -183972,8 +187876,9 @@ static int sqlite3_geopoly_init(sqlite3 *db){
};
int i;
for(i=0; i0 ){
n = strlen(argv[0])+1;
}
- p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n);
+ p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n);
if( !p ){
return SQLITE_NOMEM;
}
@@ -184842,7 +188747,7 @@ static int icuOpen(
nInput = strlen(zInput);
}
nChar = nInput+1;
- pCsr = (IcuCursor *)sqlite3_malloc(
+ pCsr = (IcuCursor *)sqlite3_malloc64(
sizeof(IcuCursor) + /* IcuCursor */
((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */
(nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */
@@ -185414,7 +189319,11 @@ SQLITE_API sqlite3rbu *sqlite3rbu_open(
** name of the state database is "-vacuum", where
** is the name of the target database file. In this case, on UNIX, if the
** state database is not already present in the file-system, it is created
-** with the same permissions as the target db is made.
+** with the same permissions as the target db is made.
+**
+** With an RBU vacuum, it is an SQLITE_MISUSE error if the name of the
+** state database ends with "-vactmp". This name is reserved for internal
+** use.
**
** This function does not delete the state database after an RBU vacuum
** is completed, even if it created it. However, if the call to
@@ -185835,6 +189744,11 @@ struct RbuUpdateStmt {
** it points to an array of flags nTblCol elements in size. The flag is
** set for each column that is either a part of the PK or a part of an
** index. Or clear otherwise.
+**
+** If there are one or more partial indexes on the table, all fields of
+** this array set set to 1. This is because in that case, the module has
+** no way to tell which fields will be required to add and remove entries
+** from the partial indexes.
**
*/
struct RbuObjIter {
@@ -186000,7 +189914,8 @@ struct rbu_vfs {
sqlite3_vfs *pRealVfs; /* Underlying VFS */
sqlite3_mutex *mutex; /* Mutex to protect pMain */
sqlite3rbu *pRbu; /* Owner RBU object */
- rbu_file *pMain; /* Linked list of main db files */
+ rbu_file *pMain; /* List of main db files */
+ rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */
};
/*
@@ -186029,6 +189944,7 @@ struct rbu_file {
const char *zWal; /* Wal filename for this main db file */
rbu_file *pWalFd; /* Wal file descriptor for this main db */
rbu_file *pMainNext; /* Next MAIN_DB file */
+ rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */
};
/*
@@ -186277,6 +190193,7 @@ static void rbuFossilDeltaFunc(
}else{
nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut);
if( nOut2!=nOut ){
+ sqlite3_free(aOut);
sqlite3_result_error(context, "corrupt fossil delta", -1);
}else{
sqlite3_result_blob(context, aOut, nOut, sqlite3_free);
@@ -186517,7 +190434,8 @@ static void rbuTargetNameFunc(
zIn = (const char*)sqlite3_value_text(argv[0]);
if( zIn ){
if( rbuIsVacuum(p) ){
- if( argc==1 || 0==sqlite3_value_int(argv[1]) ){
+ assert( argc==2 );
+ if( 0==sqlite3_value_int(argv[1]) ){
sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC);
}
}else{
@@ -186627,7 +190545,7 @@ static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){
** immediately without attempting the allocation or modifying the stored
** error code.
*/
-static void *rbuMalloc(sqlite3rbu *p, int nByte){
+static void *rbuMalloc(sqlite3rbu *p, sqlite3_int64 nByte){
void *pRet = 0;
if( p->rc==SQLITE_OK ){
assert( nByte>0 );
@@ -186648,7 +190566,7 @@ static void *rbuMalloc(sqlite3rbu *p, int nByte){
** error code in the RBU handle passed as the first argument.
*/
static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){
- int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
+ sqlite3_int64 nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
char **azNew;
azNew = (char**)rbuMalloc(p, nByte);
@@ -186842,8 +190760,12 @@ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){
pIter->nIndex = 0;
while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
+ int bPartial = sqlite3_column_int(pList, 4);
sqlite3_stmt *pXInfo = 0;
if( zIdx==0 ) break;
+ if( bPartial ){
+ memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol);
+ }
p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
);
@@ -186964,7 +190886,8 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){
}
pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc);
- pIter->abTblPk[iOrder] = (iPk!=0);
+ assert( iPk>=0 );
+ pIter->abTblPk[iOrder] = (u8)iPk;
pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
iOrder++;
}
@@ -186999,6 +190922,213 @@ static char *rbuObjIterGetCollist(
return zList;
}
+/*
+** Return a comma separated list of the quoted PRIMARY KEY column names,
+** in order, for the current table. Before each column name, add the text
+** zPre. After each column name, add the zPost text. Use zSeparator as
+** the separator text (usually ", ").
+*/
+static char *rbuObjIterGetPkList(
+ sqlite3rbu *p, /* RBU object */
+ RbuObjIter *pIter, /* Object iterator for column names */
+ const char *zPre, /* Before each quoted column name */
+ const char *zSeparator, /* Separator to use between columns */
+ const char *zPost /* After each quoted column name */
+){
+ int iPk = 1;
+ char *zRet = 0;
+ const char *zSep = "";
+ while( 1 ){
+ int i;
+ for(i=0; inTblCol; i++){
+ if( (int)pIter->abTblPk[i]==iPk ){
+ const char *zCol = pIter->azTblCol[i];
+ zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost);
+ zSep = zSeparator;
+ break;
+ }
+ }
+ if( i==pIter->nTblCol ) break;
+ iPk++;
+ }
+ return zRet;
+}
+
+/*
+** This function is called as part of restarting an RBU vacuum within
+** stage 1 of the process (while the *-oal file is being built) while
+** updating a table (not an index). The table may be a rowid table or
+** a WITHOUT ROWID table. It queries the target database to find the
+** largest key that has already been written to the target table and
+** constructs a WHERE clause that can be used to extract the remaining
+** rows from the source table. For a rowid table, the WHERE clause
+** is of the form:
+**
+** "WHERE _rowid_ > ?"
+**
+** and for WITHOUT ROWID tables:
+**
+** "WHERE (key1, key2) > (?, ?)"
+**
+** Instead of "?" placeholders, the actual WHERE clauses created by
+** this function contain literal SQL values.
+*/
+static char *rbuVacuumTableStart(
+ sqlite3rbu *p, /* RBU handle */
+ RbuObjIter *pIter, /* RBU iterator object */
+ int bRowid, /* True for a rowid table */
+ const char *zWrite /* Target table name prefix */
+){
+ sqlite3_stmt *pMax = 0;
+ char *zRet = 0;
+ if( bRowid ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
+ sqlite3_mprintf(
+ "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl
+ )
+ );
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
+ sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0);
+ zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax);
+ }
+ rbuFinalize(p, pMax);
+ }else{
+ char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC");
+ char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")");
+ char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", "");
+
+ if( p->rc==SQLITE_OK ){
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg,
+ sqlite3_mprintf(
+ "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1",
+ zSelect, zWrite, pIter->zTbl, zOrder
+ )
+ );
+ if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
+ const char *zVal = (const char*)sqlite3_column_text(pMax, 0);
+ zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal);
+ }
+ rbuFinalize(p, pMax);
+ }
+
+ sqlite3_free(zOrder);
+ sqlite3_free(zSelect);
+ sqlite3_free(zList);
+ }
+ return zRet;
+}
+
+/*
+** This function is called as part of restating an RBU vacuum when the
+** current operation is writing content to an index. If possible, it
+** queries the target index b-tree for the largest key already written to
+** it, then composes and returns an expression that can be used in a WHERE
+** clause to select the remaining required rows from the source table.
+** It is only possible to return such an expression if:
+**
+** * The index contains no DESC columns, and
+** * The last key written to the index before the operation was
+** suspended does not contain any NULL values.
+**
+** The expression is of the form:
+**
+** (index-field1, index-field2, ...) > (?, ?, ...)
+**
+** except that the "?" placeholders are replaced with literal values.
+**
+** If the expression cannot be created, NULL is returned. In this case,
+** the caller has to use an OFFSET clause to extract only the required
+** rows from the sourct table, just as it does for an RBU update operation.
+*/
+char *rbuVacuumIndexStart(
+ sqlite3rbu *p, /* RBU handle */
+ RbuObjIter *pIter /* RBU iterator object */
+){
+ char *zOrder = 0;
+ char *zLhs = 0;
+ char *zSelect = 0;
+ char *zVector = 0;
+ char *zRet = 0;
+ int bFailed = 0;
+ const char *zSep = "";
+ int iCol = 0;
+ sqlite3_stmt *pXInfo = 0;
+
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
+ );
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
+ int iCid = sqlite3_column_int(pXInfo, 1);
+ const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
+ const char *zCol;
+ if( sqlite3_column_int(pXInfo, 3) ){
+ bFailed = 1;
+ break;
+ }
+
+ if( iCid<0 ){
+ if( pIter->eType==RBU_PK_IPK ){
+ int i;
+ for(i=0; pIter->abTblPk[i]==0; i++);
+ assert( i
|