Version History
1.0.90.0 - December XX, 2013 (release scheduled)
+ - Updated to SQLite 3.8.2.
- Add experimental support for the native regexp extension.
- Never create a new connection wrapper in the SQLiteConnection.Shutdown method. ** Potentially Incompatible Change **
- Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.
- Add memory leak detection to the test project for the .NET Compact Framework.
- Add SQLITE_ENABLE_MEMORY_MANAGEMENT compile-time option to the interop assembly.
Index: SQLite.Interop/props/sqlite3.props
==================================================================
--- SQLite.Interop/props/sqlite3.props
+++ SQLite.Interop/props/sqlite3.props
@@ -7,12 +7,12 @@
* Released to the public domain, use at your own risk!
*
-->
- 3.8.1
- 3,8,1
+ 3.8.2
+ 3,8,2
_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT4=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1;SQLITE_ENABLE_MEMORY_MANAGEMENT=1
SQLITE_HAS_CODEC=1
SQLITE_OMIT_WAL=1
SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1;SQLITE_ENABLE_EXPENSIVE_ASSERT=1
SQLITE_WIN32_MALLOC=1
Index: SQLite.Interop/props/sqlite3.vsprops
==================================================================
--- SQLite.Interop/props/sqlite3.vsprops
+++ SQLite.Interop/props/sqlite3.vsprops
@@ -12,16 +12,16 @@
Version="8.00"
Name="sqlite3"
>
[[SQLITE_FCNTL_TRACE]]
+** The [SQLITE_FCNTL_TRACE] file control provides advisory information
+** to the VFS about what the higher layers of the SQLite stack are doing.
+** This file control is used by some VFS activity tracing [shims].
+** The argument is a zero-terminated string. Higher layers in the
+** SQLite stack may generate instances of this file control if
+** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
+**
**
*/
#define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_GET_LOCKPROXYFILE 2
#define SQLITE_SET_LOCKPROXYFILE 3
@@ -957,10 +966,11 @@
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
#define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
#define SQLITE_FCNTL_MMAP_SIZE 18
+#define SQLITE_FCNTL_TRACE 19
/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
@@ -1803,23 +1813,25 @@
SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
**
-** ^Each entry in an SQLite table has a unique 64-bit signed
+** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
+** has a unique 64-bit signed
** integer key called the [ROWID | "rowid"]. ^The rowid is always available
** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
** names are not also used by explicitly declared columns. ^If
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^This routine returns the [rowid] of the most recent
-** successful [INSERT] into the database from the [database connection]
-** in the first argument. ^As of SQLite version 3.7.7, this routines
-** records the last insert rowid of both ordinary tables and [virtual tables].
-** ^If no successful [INSERT]s
-** have ever occurred on that database connection, zero is returned.
+** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
+** most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D.
+** ^Inserts into [WITHOUT ROWID] tables are not recorded.
+** ^If no successful [INSERT]s into rowid tables
+** have ever occurred on the database connection D,
+** then sqlite3_last_insert_rowid(D) returns zero.
**
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
** row as long as the trigger or virtual table method is running.
** But once the trigger or virtual table method ends, the value returned
@@ -4832,16 +4844,17 @@
/*
** CAPI3REF: Data Change Notification Callbacks
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
+** to be invoked whenever a row is updated, inserted or deleted in
+** a rowid table.
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
** ^The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
+** row is updated, inserted or deleted in a rowid table.
** ^The first argument to the callback is a copy of the third argument
** to sqlite3_update_hook().
** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
** or [SQLITE_UPDATE], depending on the operation that caused the callback
** to be invoked.
@@ -4850,10 +4863,11 @@
** ^The final callback parameter is the [rowid] of the row.
** ^In the case of an update, this is the [rowid] after the update takes place.
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^
+** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when duplication rows are deleted because of an
** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
** invoked when rows are deleted using the [truncate optimization].
@@ -5307,14 +5321,26 @@
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
-** ^The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
+** ^The estimatedCost value is an estimate of the cost of a particular
+** strategy. A cost of N indicates that the cost of the strategy is similar
+** to a linear scan of an SQLite table with N rows. A cost of log(N)
+** indicates that the expense of the operation is similar to that of a
+** binary search on a unique indexed field of an SQLite table with N rows.
+**
+** ^The estimatedRows value is an estimate of the number of rows that
+** will be returned by the strategy.
+**
+** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+** structure for SQLite version 3.8.2. If a virtual table extension is
+** used with an SQLite version earlier than 3.8.2, the results of attempting
+** to read or write the estimatedRows field are undefined (but are likely
+** to included crashing the application). The estimatedRows field should
+** therefore only be used if [sqlite3_libversion_number()] returns a
+** value greater than or equal to 3008002.
*/
struct sqlite3_index_info {
/* Inputs */
int nConstraint; /* Number of entries in aConstraint */
struct sqlite3_index_constraint {
@@ -5335,11 +5361,12 @@
} *aConstraintUsage;
int idxNum; /* Number used to identify the index */
char *idxStr; /* String, possibly obtained from sqlite3_malloc */
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
+ double estimatedCost; /* Estimated cost of using this index */
+ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
};
/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
@@ -5539,10 +5566,13 @@
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob. ^The size of a blob may not be changed by this
** interface. Use the [UPDATE] SQL command to change the size of a
** blob.
**
+** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
+** table. Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
+**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
** this interface.
**
@@ -7756,10 +7786,17 @@
#endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
# undef NDEBUG
#endif
+/*
+** Enable SQLITE_ENABLE_EXPLAIN_COMMENTS if SQLITE_DEBUG is turned on.
+*/
+#if !defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) && defined(SQLITE_DEBUG)
+# define SQLITE_ENABLE_EXPLAIN_COMMENTS 1
+#endif
+
/*
** The testcase() macro is used to aid in coverage testing. When
** doing coverage testing, the condition inside the argument to
** testcase() must be evaluated both true and false in order to
** get full branch coverage. The testcase() macro is inserted
@@ -7972,143 +8009,144 @@
#define TK_EXISTS 20
#define TK_TEMP 21
#define TK_LP 22
#define TK_RP 23
#define TK_AS 24
-#define TK_COMMA 25
-#define TK_ID 26
-#define TK_INDEXED 27
-#define TK_ABORT 28
-#define TK_ACTION 29
-#define TK_AFTER 30
-#define TK_ANALYZE 31
-#define TK_ASC 32
-#define TK_ATTACH 33
-#define TK_BEFORE 34
-#define TK_BY 35
-#define TK_CASCADE 36
-#define TK_CAST 37
-#define TK_COLUMNKW 38
-#define TK_CONFLICT 39
-#define TK_DATABASE 40
-#define TK_DESC 41
-#define TK_DETACH 42
-#define TK_EACH 43
-#define TK_FAIL 44
-#define TK_FOR 45
-#define TK_IGNORE 46
-#define TK_INITIALLY 47
-#define TK_INSTEAD 48
-#define TK_LIKE_KW 49
-#define TK_MATCH 50
-#define TK_NO 51
-#define TK_KEY 52
-#define TK_OF 53
-#define TK_OFFSET 54
-#define TK_PRAGMA 55
-#define TK_RAISE 56
-#define TK_REPLACE 57
-#define TK_RESTRICT 58
-#define TK_ROW 59
-#define TK_TRIGGER 60
-#define TK_VACUUM 61
-#define TK_VIEW 62
-#define TK_VIRTUAL 63
-#define TK_REINDEX 64
-#define TK_RENAME 65
-#define TK_CTIME_KW 66
-#define TK_ANY 67
-#define TK_OR 68
-#define TK_AND 69
-#define TK_IS 70
-#define TK_BETWEEN 71
-#define TK_IN 72
-#define TK_ISNULL 73
-#define TK_NOTNULL 74
-#define TK_NE 75
-#define TK_EQ 76
-#define TK_GT 77
-#define TK_LE 78
-#define TK_LT 79
-#define TK_GE 80
-#define TK_ESCAPE 81
-#define TK_BITAND 82
-#define TK_BITOR 83
-#define TK_LSHIFT 84
-#define TK_RSHIFT 85
-#define TK_PLUS 86
-#define TK_MINUS 87
-#define TK_STAR 88
-#define TK_SLASH 89
-#define TK_REM 90
-#define TK_CONCAT 91
-#define TK_COLLATE 92
-#define TK_BITNOT 93
-#define TK_STRING 94
-#define TK_JOIN_KW 95
-#define TK_CONSTRAINT 96
-#define TK_DEFAULT 97
-#define TK_NULL 98
-#define TK_PRIMARY 99
-#define TK_UNIQUE 100
-#define TK_CHECK 101
-#define TK_REFERENCES 102
-#define TK_AUTOINCR 103
-#define TK_ON 104
-#define TK_INSERT 105
-#define TK_DELETE 106
-#define TK_UPDATE 107
-#define TK_SET 108
-#define TK_DEFERRABLE 109
-#define TK_FOREIGN 110
-#define TK_DROP 111
-#define TK_UNION 112
-#define TK_ALL 113
-#define TK_EXCEPT 114
-#define TK_INTERSECT 115
-#define TK_SELECT 116
-#define TK_DISTINCT 117
-#define TK_DOT 118
-#define TK_FROM 119
-#define TK_JOIN 120
-#define TK_USING 121
-#define TK_ORDER 122
-#define TK_GROUP 123
-#define TK_HAVING 124
-#define TK_LIMIT 125
-#define TK_WHERE 126
-#define TK_INTO 127
-#define TK_VALUES 128
-#define TK_INTEGER 129
-#define TK_FLOAT 130
-#define TK_BLOB 131
-#define TK_REGISTER 132
-#define TK_VARIABLE 133
-#define TK_CASE 134
-#define TK_WHEN 135
-#define TK_THEN 136
-#define TK_ELSE 137
-#define TK_INDEX 138
-#define TK_ALTER 139
-#define TK_ADD 140
-#define TK_TO_TEXT 141
-#define TK_TO_BLOB 142
-#define TK_TO_NUMERIC 143
-#define TK_TO_INT 144
-#define TK_TO_REAL 145
-#define TK_ISNOT 146
-#define TK_END_OF_FILE 147
-#define TK_ILLEGAL 148
-#define TK_SPACE 149
-#define TK_UNCLOSED_STRING 150
-#define TK_FUNCTION 151
-#define TK_COLUMN 152
-#define TK_AGG_FUNCTION 153
-#define TK_AGG_COLUMN 154
-#define TK_CONST_FUNC 155
-#define TK_UMINUS 156
-#define TK_UPLUS 157
+#define TK_WITHOUT 25
+#define TK_COMMA 26
+#define TK_ID 27
+#define TK_INDEXED 28
+#define TK_ABORT 29
+#define TK_ACTION 30
+#define TK_AFTER 31
+#define TK_ANALYZE 32
+#define TK_ASC 33
+#define TK_ATTACH 34
+#define TK_BEFORE 35
+#define TK_BY 36
+#define TK_CASCADE 37
+#define TK_CAST 38
+#define TK_COLUMNKW 39
+#define TK_CONFLICT 40
+#define TK_DATABASE 41
+#define TK_DESC 42
+#define TK_DETACH 43
+#define TK_EACH 44
+#define TK_FAIL 45
+#define TK_FOR 46
+#define TK_IGNORE 47
+#define TK_INITIALLY 48
+#define TK_INSTEAD 49
+#define TK_LIKE_KW 50
+#define TK_MATCH 51
+#define TK_NO 52
+#define TK_KEY 53
+#define TK_OF 54
+#define TK_OFFSET 55
+#define TK_PRAGMA 56
+#define TK_RAISE 57
+#define TK_REPLACE 58
+#define TK_RESTRICT 59
+#define TK_ROW 60
+#define TK_TRIGGER 61
+#define TK_VACUUM 62
+#define TK_VIEW 63
+#define TK_VIRTUAL 64
+#define TK_REINDEX 65
+#define TK_RENAME 66
+#define TK_CTIME_KW 67
+#define TK_ANY 68
+#define TK_OR 69
+#define TK_AND 70
+#define TK_IS 71
+#define TK_BETWEEN 72
+#define TK_IN 73
+#define TK_ISNULL 74
+#define TK_NOTNULL 75
+#define TK_NE 76
+#define TK_EQ 77
+#define TK_GT 78
+#define TK_LE 79
+#define TK_LT 80
+#define TK_GE 81
+#define TK_ESCAPE 82
+#define TK_BITAND 83
+#define TK_BITOR 84
+#define TK_LSHIFT 85
+#define TK_RSHIFT 86
+#define TK_PLUS 87
+#define TK_MINUS 88
+#define TK_STAR 89
+#define TK_SLASH 90
+#define TK_REM 91
+#define TK_CONCAT 92
+#define TK_COLLATE 93
+#define TK_BITNOT 94
+#define TK_STRING 95
+#define TK_JOIN_KW 96
+#define TK_CONSTRAINT 97
+#define TK_DEFAULT 98
+#define TK_NULL 99
+#define TK_PRIMARY 100
+#define TK_UNIQUE 101
+#define TK_CHECK 102
+#define TK_REFERENCES 103
+#define TK_AUTOINCR 104
+#define TK_ON 105
+#define TK_INSERT 106
+#define TK_DELETE 107
+#define TK_UPDATE 108
+#define TK_SET 109
+#define TK_DEFERRABLE 110
+#define TK_FOREIGN 111
+#define TK_DROP 112
+#define TK_UNION 113
+#define TK_ALL 114
+#define TK_EXCEPT 115
+#define TK_INTERSECT 116
+#define TK_SELECT 117
+#define TK_DISTINCT 118
+#define TK_DOT 119
+#define TK_FROM 120
+#define TK_JOIN 121
+#define TK_USING 122
+#define TK_ORDER 123
+#define TK_GROUP 124
+#define TK_HAVING 125
+#define TK_LIMIT 126
+#define TK_WHERE 127
+#define TK_INTO 128
+#define TK_VALUES 129
+#define TK_INTEGER 130
+#define TK_FLOAT 131
+#define TK_BLOB 132
+#define TK_REGISTER 133
+#define TK_VARIABLE 134
+#define TK_CASE 135
+#define TK_WHEN 136
+#define TK_THEN 137
+#define TK_ELSE 138
+#define TK_INDEX 139
+#define TK_ALTER 140
+#define TK_ADD 141
+#define TK_TO_TEXT 142
+#define TK_TO_BLOB 143
+#define TK_TO_NUMERIC 144
+#define TK_TO_INT 145
+#define TK_TO_REAL 146
+#define TK_ISNOT 147
+#define TK_END_OF_FILE 148
+#define TK_ILLEGAL 149
+#define TK_SPACE 150
+#define TK_UNCLOSED_STRING 151
+#define TK_FUNCTION 152
+#define TK_COLUMN 153
+#define TK_AGG_FUNCTION 154
+#define TK_AGG_COLUMN 155
+#define TK_CONST_FUNC 156
+#define TK_UMINUS 157
+#define TK_UPLUS 158
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
#include
#include
@@ -8881,11 +8919,11 @@
KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
int *ai; /* Used when p4type is P4_INTARRAY */
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
int (*xAdvance)(BtCursor *, int *);
} p4;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
char *zComment; /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
int cnt; /* Number of times this instruction was executed */
u64 cycles; /* Total time spent executing this instruction */
@@ -8937,19 +8975,15 @@
#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */
#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */
#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
-/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
-** is made. That copy is freed when the Vdbe is finalized. But if the
-** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used. It still
-** gets freed when the Vdbe is finalized so it still should be obtained
-** from a single sqliteMalloc(). But no copy is made and the calling
-** function should *not* try to free the KeyInfo.
-*/
-#define P4_KEYINFO_HANDOFF (-16)
-#define P4_KEYINFO_STATIC (-17)
+/* Error message codes for OP_Halt */
+#define P5_ConstraintNotNull 1
+#define P5_ConstraintUnique 2
+#define P5_ConstraintCheck 3
+#define P5_ConstraintFK 4
/*
** The Vdbe.aColName array contains 5n Mem structures, where n is the
** number of columns of data returned by the statement.
*/
@@ -8982,160 +9016,160 @@
*/
/************** Include opcodes.h in the middle of vdbe.h ********************/
/************** Begin file opcodes.h *****************************************/
/* Automatically generated. Do not edit */
/* See the mkopcodeh.awk script for details */
-#define OP_Function 1
-#define OP_Savepoint 2
-#define OP_AutoCommit 3
-#define OP_Transaction 4
-#define OP_SorterNext 5
-#define OP_Prev 6
-#define OP_Next 7
-#define OP_AggStep 8
-#define OP_Checkpoint 9
-#define OP_JournalMode 10
-#define OP_Vacuum 11
-#define OP_VFilter 12
-#define OP_VUpdate 13
-#define OP_Goto 14
-#define OP_Gosub 15
-#define OP_Return 16
-#define OP_Yield 17
-#define OP_HaltIfNull 18
-#define OP_Not 19 /* same as TK_NOT */
-#define OP_Halt 20
-#define OP_Integer 21
-#define OP_Int64 22
-#define OP_String 23
-#define OP_Null 24
-#define OP_Blob 25
-#define OP_Variable 26
-#define OP_Move 27
-#define OP_Copy 28
-#define OP_SCopy 29
-#define OP_ResultRow 30
-#define OP_CollSeq 31
-#define OP_AddImm 32
-#define OP_MustBeInt 33
-#define OP_RealAffinity 34
-#define OP_Permutation 35
-#define OP_Compare 36
-#define OP_Jump 37
-#define OP_Once 38
-#define OP_If 39
-#define OP_IfNot 40
-#define OP_Column 41
-#define OP_Affinity 42
-#define OP_MakeRecord 43
-#define OP_Count 44
-#define OP_ReadCookie 45
-#define OP_SetCookie 46
-#define OP_VerifyCookie 47
-#define OP_OpenRead 48
-#define OP_OpenWrite 49
-#define OP_OpenAutoindex 50
-#define OP_OpenEphemeral 51
-#define OP_SorterOpen 52
-#define OP_OpenPseudo 53
-#define OP_Close 54
-#define OP_SeekLt 55
-#define OP_SeekLe 56
-#define OP_SeekGe 57
-#define OP_SeekGt 58
-#define OP_Seek 59
-#define OP_NotFound 60
-#define OP_Found 61
-#define OP_IsUnique 62
-#define OP_NotExists 63
-#define OP_Sequence 64
-#define OP_NewRowid 65
-#define OP_Insert 66
-#define OP_InsertInt 67
-#define OP_Or 68 /* same as TK_OR */
-#define OP_And 69 /* same as TK_AND */
-#define OP_Delete 70
-#define OP_ResetCount 71
-#define OP_SorterCompare 72
-#define OP_IsNull 73 /* same as TK_ISNULL */
-#define OP_NotNull 74 /* same as TK_NOTNULL */
-#define OP_Ne 75 /* same as TK_NE */
-#define OP_Eq 76 /* same as TK_EQ */
-#define OP_Gt 77 /* same as TK_GT */
-#define OP_Le 78 /* same as TK_LE */
-#define OP_Lt 79 /* same as TK_LT */
-#define OP_Ge 80 /* same as TK_GE */
-#define OP_SorterData 81
-#define OP_BitAnd 82 /* same as TK_BITAND */
-#define OP_BitOr 83 /* same as TK_BITOR */
-#define OP_ShiftLeft 84 /* same as TK_LSHIFT */
-#define OP_ShiftRight 85 /* same as TK_RSHIFT */
-#define OP_Add 86 /* same as TK_PLUS */
-#define OP_Subtract 87 /* same as TK_MINUS */
-#define OP_Multiply 88 /* same as TK_STAR */
-#define OP_Divide 89 /* same as TK_SLASH */
-#define OP_Remainder 90 /* same as TK_REM */
-#define OP_Concat 91 /* same as TK_CONCAT */
-#define OP_RowKey 92
-#define OP_BitNot 93 /* same as TK_BITNOT */
-#define OP_String8 94 /* same as TK_STRING */
-#define OP_RowData 95
-#define OP_Rowid 96
-#define OP_NullRow 97
-#define OP_Last 98
-#define OP_SorterSort 99
-#define OP_Sort 100
-#define OP_Rewind 101
-#define OP_SorterInsert 102
-#define OP_IdxInsert 103
-#define OP_IdxDelete 104
-#define OP_IdxRowid 105
-#define OP_IdxLT 106
-#define OP_IdxGE 107
-#define OP_Destroy 108
-#define OP_Clear 109
-#define OP_CreateIndex 110
-#define OP_CreateTable 111
-#define OP_ParseSchema 112
-#define OP_LoadAnalysis 113
-#define OP_DropTable 114
-#define OP_DropIndex 115
-#define OP_DropTrigger 116
-#define OP_IntegrityCk 117
-#define OP_RowSetAdd 118
-#define OP_RowSetRead 119
-#define OP_RowSetTest 120
-#define OP_Program 121
-#define OP_Param 122
-#define OP_FkCounter 123
-#define OP_FkIfZero 124
-#define OP_MemMax 125
-#define OP_IfPos 126
-#define OP_IfNeg 127
-#define OP_IfZero 128
-#define OP_AggFinal 129
-#define OP_Real 130 /* same as TK_FLOAT */
-#define OP_IncrVacuum 131
-#define OP_Expire 132
-#define OP_TableLock 133
-#define OP_VBegin 134
-#define OP_VCreate 135
-#define OP_VDestroy 136
-#define OP_VOpen 137
-#define OP_VColumn 138
-#define OP_VNext 139
-#define OP_VRename 140
-#define OP_ToText 141 /* same as TK_TO_TEXT */
-#define OP_ToBlob 142 /* same as TK_TO_BLOB */
-#define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/
-#define OP_ToInt 144 /* same as TK_TO_INT */
-#define OP_ToReal 145 /* same as TK_TO_REAL */
-#define OP_Pagecount 146
-#define OP_MaxPgcnt 147
-#define OP_Trace 148
-#define OP_Noop 149
-#define OP_Explain 150
+#define OP_Function 1 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Savepoint 2
+#define OP_AutoCommit 3
+#define OP_Transaction 4
+#define OP_SorterNext 5
+#define OP_Prev 6
+#define OP_Next 7
+#define OP_AggStep 8 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_Checkpoint 9
+#define OP_JournalMode 10
+#define OP_Vacuum 11
+#define OP_VFilter 12 /* synopsis: iPlan=r[P3] zPlan='P4' */
+#define OP_VUpdate 13 /* synopsis: data=r[P3@P2] */
+#define OP_Goto 14
+#define OP_Gosub 15
+#define OP_Return 16
+#define OP_Yield 17
+#define OP_HaltIfNull 18 /* synopsis: if r[P3] null then halt */
+#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
+#define OP_Halt 20
+#define OP_Integer 21 /* synopsis: r[P2]=P1 */
+#define OP_Int64 22 /* synopsis: r[P2]=P4 */
+#define OP_String 23 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 24 /* synopsis: r[P2..P3]=NULL */
+#define OP_Blob 25 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 26 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 27 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 28 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_SCopy 29 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 30 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 31
+#define OP_AddImm 32 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_MustBeInt 33
+#define OP_RealAffinity 34
+#define OP_Permutation 35
+#define OP_Compare 36
+#define OP_Jump 37
+#define OP_Once 38
+#define OP_If 39
+#define OP_IfNot 40
+#define OP_Column 41 /* synopsis: r[P3]=PX */
+#define OP_Affinity 42 /* synopsis: affinity(r[P1@P2]) */
+#define OP_MakeRecord 43 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 44 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 45
+#define OP_SetCookie 46
+#define OP_VerifyCookie 47
+#define OP_OpenRead 48 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 49 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenAutoindex 50 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 51 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 52
+#define OP_OpenPseudo 53 /* synopsis: content in r[P2@P3] */
+#define OP_Close 54
+#define OP_SeekLt 55 /* synopsis: key=r[P3@P4] */
+#define OP_SeekLe 56 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGe 57 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGt 58 /* synopsis: key=r[P3@P4] */
+#define OP_Seek 59 /* synopsis: intkey=r[P2] */
+#define OP_NoConflict 60 /* synopsis: key=r[P3@P4] */
+#define OP_NotFound 61 /* synopsis: key=r[P3@P4] */
+#define OP_Found 62 /* synopsis: key=r[P3@P4] */
+#define OP_NotExists 63 /* synopsis: intkey=r[P3] */
+#define OP_Sequence 64 /* synopsis: r[P2]=rowid */
+#define OP_NewRowid 65 /* synopsis: r[P2]=rowid */
+#define OP_Insert 66 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_InsertInt 67 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 68
+#define OP_Or 69 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And 70 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_ResetCount 71
+#define OP_SorterCompare 72 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */
+#define OP_SorterData 73 /* synopsis: r[P2]=data */
+#define OP_IsNull 74 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 75 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 76 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
+#define OP_Eq 77 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
+#define OP_Gt 78 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
+#define OP_Le 79 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
+#define OP_Lt 80 /* same as TK_LT, synopsis: if r[P1]=r[P3] goto P2 */
+#define OP_RowKey 82 /* synopsis: r[P2]=key */
+#define OP_BitAnd 83 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 84 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 85 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */
+#define OP_Add 87 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 88 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 89 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 90 /* same as TK_SLASH, synopsis: r[P3]=r[P1]/r[P2] */
+#define OP_Remainder 91 /* same as TK_REM, synopsis: r[P3]=r[P1]%r[P2] */
+#define OP_Concat 92 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_RowData 93 /* synopsis: r[P2]=data */
+#define OP_BitNot 94 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+#define OP_String8 95 /* same as TK_STRING, synopsis: r[P2]='P4' */
+#define OP_Rowid 96 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 97
+#define OP_Last 98
+#define OP_SorterSort 99
+#define OP_Sort 100
+#define OP_Rewind 101
+#define OP_SorterInsert 102
+#define OP_IdxInsert 103 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 104 /* synopsis: key=r[P2@P3] */
+#define OP_IdxRowid 105 /* synopsis: r[P2]=rowid */
+#define OP_IdxLT 106 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGE 107 /* synopsis: key=r[P3@P4] */
+#define OP_Destroy 108
+#define OP_Clear 109
+#define OP_CreateIndex 110 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_CreateTable 111 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_ParseSchema 112
+#define OP_LoadAnalysis 113
+#define OP_DropTable 114
+#define OP_DropIndex 115
+#define OP_DropTrigger 116
+#define OP_IntegrityCk 117
+#define OP_RowSetAdd 118 /* synopsis: rowset(P1)=r[P2] */
+#define OP_RowSetRead 119 /* synopsis: r[P3]=rowset(P1) */
+#define OP_RowSetTest 120 /* synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Program 121
+#define OP_Param 122
+#define OP_FkCounter 123 /* synopsis: fkctr[P1]+=P2 */
+#define OP_FkIfZero 124 /* synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_MemMax 125 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_IfPos 126 /* synopsis: if r[P1]>0 goto P2 */
+#define OP_IfNeg 127 /* synopsis: if r[P1]<0 goto P2 */
+#define OP_IfZero 128 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */
+#define OP_AggFinal 129 /* synopsis: accum=r[P1] N=P2 */
+#define OP_IncrVacuum 130
+#define OP_Real 131 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
+#define OP_Expire 132
+#define OP_TableLock 133 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 134
+#define OP_VCreate 135
+#define OP_VDestroy 136
+#define OP_VOpen 137
+#define OP_VColumn 138 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VNext 139
+#define OP_VRename 140
+#define OP_Pagecount 141
+#define OP_ToText 142 /* same as TK_TO_TEXT */
+#define OP_ToBlob 143 /* same as TK_TO_BLOB */
+#define OP_ToNumeric 144 /* same as TK_TO_NUMERIC */
+#define OP_ToInt 145 /* same as TK_TO_INT */
+#define OP_ToReal 146 /* same as TK_TO_REAL */
+#define OP_MaxPgcnt 147
+#define OP_Trace 148
+#define OP_Noop 149
+#define OP_Explain 150
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
** are encoded into bitvectors as follows:
@@ -9149,26 +9183,26 @@
#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
/* 8 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x01,\
/* 16 */ 0x04, 0x04, 0x10, 0x24, 0x00, 0x02, 0x02, 0x02,\
-/* 24 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x24, 0x00, 0x00,\
+/* 24 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00,\
/* 32 */ 0x04, 0x05, 0x04, 0x00, 0x00, 0x01, 0x01, 0x05,\
/* 40 */ 0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\
/* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,\
/* 56 */ 0x11, 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11,\
-/* 64 */ 0x02, 0x02, 0x00, 0x00, 0x4c, 0x4c, 0x00, 0x00,\
-/* 72 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
-/* 80 */ 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
-/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02, 0x00,\
+/* 64 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x4c, 0x00,\
+/* 72 */ 0x00, 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15,\
+/* 80 */ 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
+/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02,\
/* 96 */ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08,\
/* 104 */ 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02, 0x02,\
/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\
/* 120 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x08, 0x05, 0x05,\
-/* 128 */ 0x05, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,\
-/* 136 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x04, 0x04,\
-/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}
+/* 128 */ 0x05, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00,\
+/* 136 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x04, 0x04,\
+/* 144 */ 0x04, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
/*
@@ -9189,10 +9223,11 @@
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
+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 void sqlite3VdbeRunOnlyOnce(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
@@ -9227,19 +9262,31 @@
#ifndef SQLITE_OMIT_TRIGGER
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif
-
-#ifndef NDEBUG
+/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
+** each VDBE opcode.
+**
+** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op
+** comments in VDBE programs that show key decision points in the code
+** generator.
+*/
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X) sqlite3VdbeComment X
SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...);
# define VdbeNoopComment(X) sqlite3VdbeNoopComment X
+# ifdef SQLITE_ENABLE_MODULE_COMMENTS
+# define VdbeModuleComment(X) sqlite3VdbeNoopComment X
+# else
+# define VdbeModuleComment(X)
+# endif
#else
# define VdbeComment(X)
# define VdbeNoopComment(X)
+# define VdbeModuleComment(X)
#endif
#endif
/************** End of vdbe.h ************************************************/
@@ -10631,10 +10678,11 @@
#define TF_Readonly 0x01 /* Read-only system table */
#define TF_Ephemeral 0x02 /* An ephemeral table */
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
#define TF_Virtual 0x10 /* Is a virtual table */
+#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
/*
** Test to see whether or not a table is a virtual table. This is
** done as a macro so that it will be optimized out when virtual
@@ -10646,10 +10694,13 @@
#else
# define IsVirtual(X) 0
# define IsHiddenColumn(X) 0
#endif
+/* Does the table have a rowid */
+#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
+
/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables. The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
@@ -10660,30 +10711,39 @@
** a INTEGER PRIMARY KEY,
** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x)
** );
**
** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
+** Equivalent names:
+**
+** from-table == child-table
+** to-table == parent-table
**
** Each REFERENCES clause generates an instance of the following structure
** which is attached to the from-table. The to-table need not exist when
** the from-table is created. The existence of the to-table is not checked.
+**
+** The list of all parents for child Table X is held at X.pFKey.
+**
+** A list of all children for a table named Z (which might not even exist)
+** is held in Schema.fkeyHash with a hash key of Z.
*/
struct FKey {
Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */
- FKey *pNextFrom; /* Next foreign key in pFrom */
+ FKey *pNextFrom; /* Next FKey with the same in pFrom. Next parent of pFrom */
char *zTo; /* Name of table that the key points to (aka: Parent) */
- FKey *pNextTo; /* Next foreign key on table named zTo */
- FKey *pPrevTo; /* Previous foreign key on table named zTo */
+ FKey *pNextTo; /* Next with the same zTo. Next child of zTo. */
+ FKey *pPrevTo; /* Previous with the same zTo */
int nCol; /* Number of columns in this key */
/* EV: R-30323-21917 */
- u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
- u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */
- Trigger *apTrigger[2]; /* Triggers for aAction[] actions */
- struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
- int iFrom; /* Index of column in pFrom */
- char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */
- } aCol[1]; /* One entry for each of nCol column s */
+ u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
+ u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */
+ Trigger *apTrigger[2];/* Triggers for aAction[] actions */
+ struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
+ int iFrom; /* Index of column in pFrom */
+ char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */
+ } aCol[1]; /* One entry for each of nCol columns */
};
/*
** SQLite supports many different ways to resolve a constraint
** error. ROLLBACK processing means that a constraint violation
@@ -10732,13 +10792,15 @@
** Note that aSortOrder[] and aColl[] have nField+1 slots. There
** are nField slots for the columns of an index then one extra slot
** for the rowid at the end.
*/
struct KeyInfo {
- sqlite3 *db; /* The database connection */
+ u32 nRef; /* Number of references to this KeyInfo object */
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
- u16 nField; /* Maximum index for aColl[] and aSortOrder[] */
+ u16 nField; /* Number of key columns in the index */
+ u16 nXField; /* Number of columns beyond the key columns */
+ sqlite3 *db; /* The database connection */
u8 *aSortOrder; /* Sort order for each column. */
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
};
/*
@@ -10757,20 +10819,18 @@
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
u8 flags; /* Boolean settings. UNPACKED_... below */
- i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */
Mem *aMem; /* Values */
};
/*
** Allowed values of UnpackedRecord.flags
*/
#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */
#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */
-#define UNPACKED_PREFIX_SEARCH 0x04 /* Ignore final (rowid) field */
/*
** Each SQL index is represented in memory by an
** instance of the following structure.
**
@@ -10796,26 +10856,30 @@
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
*/
struct Index {
char *zName; /* Name of this index */
- int *aiColumn; /* Which columns are used by this index. 1st is 0 */
+ i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */
tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
Table *pTable; /* The SQL table being indexed */
char *zColAff; /* String defining the affinity of each column */
Index *pNext; /* The next index associated with the same table */
Schema *pSchema; /* Schema containing this index */
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
char **azColl; /* Array of collation sequence names for index */
Expr *pPartIdxWhere; /* WHERE clause for partial indices */
+ KeyInfo *pKeyInfo; /* A KeyInfo object suitable for this index */
int tnum; /* DB Page containing root of this index */
LogEst szIdxRow; /* Estimated average row size in bytes */
- u16 nColumn; /* Number of columns in table used by this 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 autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
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 */
+ unsigned isCovering:1; /* True if this is a covering index */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
IndexSample *aSample; /* Samples of the left-most key */
@@ -11490,10 +11554,12 @@
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
/* Information used while coding trigger programs. */
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
+ int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
+ int addrSkipPK; /* Address of instruction to skip PRIMARY KEY index */
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
u32 newmask; /* Mask of new.* columns referenced */
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
@@ -11502,10 +11568,11 @@
/* Above is constant between recursions. Below is reset before and after
** each recursion */
int nVar; /* Number of '?' variables seen in the SQL so far */
int nzVar; /* Number of available slots in azVar[] */
+ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
u8 explain; /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
int nVtabLock; /* Number of virtual tables to lock */
#endif
@@ -11515,11 +11582,10 @@
int iSelectId; /* ID of current select for EXPLAIN output */
int iNextSelectId; /* Next available select ID for EXPLAIN output */
#endif
char **azVar; /* Pointers to names of parameters */
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
- int *aAlias; /* Register used to hold aliased result */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
Token sNameToken; /* Token with unqualified schema object name */
@@ -11984,19 +12050,21 @@
SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*);
SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int);
SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*);
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*);
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
+SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*);
+SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index*, i16);
SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*);
SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
-SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*);
+SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
sqlite3_vfs**,char**,char **);
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
SQLITE_PRIVATE int sqlite3CodeOnce(Parse *);
@@ -12045,10 +12113,11 @@
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
+SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Expr*, int, int);
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
@@ -12067,11 +12136,11 @@
SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
-SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
@@ -12121,21 +12190,23 @@
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
-SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
-SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
+SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
+SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
-SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
- int*,int,int,int,int,int*);
-SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
-SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
+SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
+ u8,u8,int,int*);
+SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
+SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, int*, int*);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
-SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, int);
+SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8);
+SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*);
+SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*);
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
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);
@@ -12349,12 +12420,17 @@
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
SQLITE_PRIVATE void sqlite3SchemaClear(void *);
SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
-SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int);
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
+SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
+#endif
SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
void (*)(sqlite3_context*,int,sqlite3_value **),
void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
FuncDestructor *pDestructor
);
@@ -13350,12 +13426,11 @@
i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
- /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or
- ** OP_IsUnique opcode on this cursor. */
+ /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists */
int seekResult;
/* Cached information about the header for the data record that the
** cursor is currently pointing to. Only valid if cacheStatus matches
** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -13716,11 +13791,11 @@
SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
-SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
+SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*);
#else
@@ -22794,163 +22869,168 @@
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
/* See the mkopcodec.awk script for details. */
-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+#if !defined(SQLITE_OMIT_EXPLAIN) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)
+# define OpHelp(X) "\0" X
+#else
+# define OpHelp(X)
+#endif
SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
static const char *const azName[] = { "?",
- /* 1 */ "Function",
- /* 2 */ "Savepoint",
- /* 3 */ "AutoCommit",
- /* 4 */ "Transaction",
- /* 5 */ "SorterNext",
- /* 6 */ "Prev",
- /* 7 */ "Next",
- /* 8 */ "AggStep",
- /* 9 */ "Checkpoint",
- /* 10 */ "JournalMode",
- /* 11 */ "Vacuum",
- /* 12 */ "VFilter",
- /* 13 */ "VUpdate",
- /* 14 */ "Goto",
- /* 15 */ "Gosub",
- /* 16 */ "Return",
- /* 17 */ "Yield",
- /* 18 */ "HaltIfNull",
- /* 19 */ "Not",
- /* 20 */ "Halt",
- /* 21 */ "Integer",
- /* 22 */ "Int64",
- /* 23 */ "String",
- /* 24 */ "Null",
- /* 25 */ "Blob",
- /* 26 */ "Variable",
- /* 27 */ "Move",
- /* 28 */ "Copy",
- /* 29 */ "SCopy",
- /* 30 */ "ResultRow",
- /* 31 */ "CollSeq",
- /* 32 */ "AddImm",
- /* 33 */ "MustBeInt",
- /* 34 */ "RealAffinity",
- /* 35 */ "Permutation",
- /* 36 */ "Compare",
- /* 37 */ "Jump",
- /* 38 */ "Once",
- /* 39 */ "If",
- /* 40 */ "IfNot",
- /* 41 */ "Column",
- /* 42 */ "Affinity",
- /* 43 */ "MakeRecord",
- /* 44 */ "Count",
- /* 45 */ "ReadCookie",
- /* 46 */ "SetCookie",
- /* 47 */ "VerifyCookie",
- /* 48 */ "OpenRead",
- /* 49 */ "OpenWrite",
- /* 50 */ "OpenAutoindex",
- /* 51 */ "OpenEphemeral",
- /* 52 */ "SorterOpen",
- /* 53 */ "OpenPseudo",
- /* 54 */ "Close",
- /* 55 */ "SeekLt",
- /* 56 */ "SeekLe",
- /* 57 */ "SeekGe",
- /* 58 */ "SeekGt",
- /* 59 */ "Seek",
- /* 60 */ "NotFound",
- /* 61 */ "Found",
- /* 62 */ "IsUnique",
- /* 63 */ "NotExists",
- /* 64 */ "Sequence",
- /* 65 */ "NewRowid",
- /* 66 */ "Insert",
- /* 67 */ "InsertInt",
- /* 68 */ "Or",
- /* 69 */ "And",
- /* 70 */ "Delete",
- /* 71 */ "ResetCount",
- /* 72 */ "SorterCompare",
- /* 73 */ "IsNull",
- /* 74 */ "NotNull",
- /* 75 */ "Ne",
- /* 76 */ "Eq",
- /* 77 */ "Gt",
- /* 78 */ "Le",
- /* 79 */ "Lt",
- /* 80 */ "Ge",
- /* 81 */ "SorterData",
- /* 82 */ "BitAnd",
- /* 83 */ "BitOr",
- /* 84 */ "ShiftLeft",
- /* 85 */ "ShiftRight",
- /* 86 */ "Add",
- /* 87 */ "Subtract",
- /* 88 */ "Multiply",
- /* 89 */ "Divide",
- /* 90 */ "Remainder",
- /* 91 */ "Concat",
- /* 92 */ "RowKey",
- /* 93 */ "BitNot",
- /* 94 */ "String8",
- /* 95 */ "RowData",
- /* 96 */ "Rowid",
- /* 97 */ "NullRow",
- /* 98 */ "Last",
- /* 99 */ "SorterSort",
- /* 100 */ "Sort",
- /* 101 */ "Rewind",
- /* 102 */ "SorterInsert",
- /* 103 */ "IdxInsert",
- /* 104 */ "IdxDelete",
- /* 105 */ "IdxRowid",
- /* 106 */ "IdxLT",
- /* 107 */ "IdxGE",
- /* 108 */ "Destroy",
- /* 109 */ "Clear",
- /* 110 */ "CreateIndex",
- /* 111 */ "CreateTable",
- /* 112 */ "ParseSchema",
- /* 113 */ "LoadAnalysis",
- /* 114 */ "DropTable",
- /* 115 */ "DropIndex",
- /* 116 */ "DropTrigger",
- /* 117 */ "IntegrityCk",
- /* 118 */ "RowSetAdd",
- /* 119 */ "RowSetRead",
- /* 120 */ "RowSetTest",
- /* 121 */ "Program",
- /* 122 */ "Param",
- /* 123 */ "FkCounter",
- /* 124 */ "FkIfZero",
- /* 125 */ "MemMax",
- /* 126 */ "IfPos",
- /* 127 */ "IfNeg",
- /* 128 */ "IfZero",
- /* 129 */ "AggFinal",
- /* 130 */ "Real",
- /* 131 */ "IncrVacuum",
- /* 132 */ "Expire",
- /* 133 */ "TableLock",
- /* 134 */ "VBegin",
- /* 135 */ "VCreate",
- /* 136 */ "VDestroy",
- /* 137 */ "VOpen",
- /* 138 */ "VColumn",
- /* 139 */ "VNext",
- /* 140 */ "VRename",
- /* 141 */ "ToText",
- /* 142 */ "ToBlob",
- /* 143 */ "ToNumeric",
- /* 144 */ "ToInt",
- /* 145 */ "ToReal",
- /* 146 */ "Pagecount",
- /* 147 */ "MaxPgcnt",
- /* 148 */ "Trace",
- /* 149 */ "Noop",
- /* 150 */ "Explain",
+ /* 1 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 2 */ "Savepoint" OpHelp(""),
+ /* 3 */ "AutoCommit" OpHelp(""),
+ /* 4 */ "Transaction" OpHelp(""),
+ /* 5 */ "SorterNext" OpHelp(""),
+ /* 6 */ "Prev" OpHelp(""),
+ /* 7 */ "Next" OpHelp(""),
+ /* 8 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 9 */ "Checkpoint" OpHelp(""),
+ /* 10 */ "JournalMode" OpHelp(""),
+ /* 11 */ "Vacuum" OpHelp(""),
+ /* 12 */ "VFilter" OpHelp("iPlan=r[P3] zPlan='P4'"),
+ /* 13 */ "VUpdate" OpHelp("data=r[P3@P2]"),
+ /* 14 */ "Goto" OpHelp(""),
+ /* 15 */ "Gosub" OpHelp(""),
+ /* 16 */ "Return" OpHelp(""),
+ /* 17 */ "Yield" OpHelp(""),
+ /* 18 */ "HaltIfNull" OpHelp("if r[P3] null then halt"),
+ /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
+ /* 20 */ "Halt" OpHelp(""),
+ /* 21 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 22 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 23 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 24 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 25 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 26 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 27 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 28 */ "Copy" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 29 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 30 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 31 */ "CollSeq" OpHelp(""),
+ /* 32 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 33 */ "MustBeInt" OpHelp(""),
+ /* 34 */ "RealAffinity" OpHelp(""),
+ /* 35 */ "Permutation" OpHelp(""),
+ /* 36 */ "Compare" OpHelp(""),
+ /* 37 */ "Jump" OpHelp(""),
+ /* 38 */ "Once" OpHelp(""),
+ /* 39 */ "If" OpHelp(""),
+ /* 40 */ "IfNot" OpHelp(""),
+ /* 41 */ "Column" OpHelp("r[P3]=PX"),
+ /* 42 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 43 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 44 */ "Count" OpHelp("r[P2]=count()"),
+ /* 45 */ "ReadCookie" OpHelp(""),
+ /* 46 */ "SetCookie" OpHelp(""),
+ /* 47 */ "VerifyCookie" OpHelp(""),
+ /* 48 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 49 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 50 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 51 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 52 */ "SorterOpen" OpHelp(""),
+ /* 53 */ "OpenPseudo" OpHelp("content in r[P2@P3]"),
+ /* 54 */ "Close" OpHelp(""),
+ /* 55 */ "SeekLt" OpHelp("key=r[P3@P4]"),
+ /* 56 */ "SeekLe" OpHelp("key=r[P3@P4]"),
+ /* 57 */ "SeekGe" OpHelp("key=r[P3@P4]"),
+ /* 58 */ "SeekGt" OpHelp("key=r[P3@P4]"),
+ /* 59 */ "Seek" OpHelp("intkey=r[P2]"),
+ /* 60 */ "NoConflict" OpHelp("key=r[P3@P4]"),
+ /* 61 */ "NotFound" OpHelp("key=r[P3@P4]"),
+ /* 62 */ "Found" OpHelp("key=r[P3@P4]"),
+ /* 63 */ "NotExists" OpHelp("intkey=r[P3]"),
+ /* 64 */ "Sequence" OpHelp("r[P2]=rowid"),
+ /* 65 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 66 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 67 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 68 */ "Delete" OpHelp(""),
+ /* 69 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
+ /* 70 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
+ /* 71 */ "ResetCount" OpHelp(""),
+ /* 72 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"),
+ /* 73 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 74 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 75 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 76 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"),
+ /* 77 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"),
+ /* 78 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"),
+ /* 79 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"),
+ /* 80 */ "Lt" OpHelp("if r[P1]=r[P3] goto P2"),
+ /* 82 */ "RowKey" OpHelp("r[P2]=key"),
+ /* 83 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 84 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 85 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"),
+ /* 87 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 88 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 89 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 90 */ "Divide" OpHelp("r[P3]=r[P1]/r[P2]"),
+ /* 91 */ "Remainder" OpHelp("r[P3]=r[P1]%r[P2]"),
+ /* 92 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 93 */ "RowData" OpHelp("r[P2]=data"),
+ /* 94 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
+ /* 95 */ "String8" OpHelp("r[P2]='P4'"),
+ /* 96 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 97 */ "NullRow" OpHelp(""),
+ /* 98 */ "Last" OpHelp(""),
+ /* 99 */ "SorterSort" OpHelp(""),
+ /* 100 */ "Sort" OpHelp(""),
+ /* 101 */ "Rewind" OpHelp(""),
+ /* 102 */ "SorterInsert" OpHelp(""),
+ /* 103 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 104 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 105 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 106 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 107 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 108 */ "Destroy" OpHelp(""),
+ /* 109 */ "Clear" OpHelp(""),
+ /* 110 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
+ /* 111 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
+ /* 112 */ "ParseSchema" OpHelp(""),
+ /* 113 */ "LoadAnalysis" OpHelp(""),
+ /* 114 */ "DropTable" OpHelp(""),
+ /* 115 */ "DropIndex" OpHelp(""),
+ /* 116 */ "DropTrigger" OpHelp(""),
+ /* 117 */ "IntegrityCk" OpHelp(""),
+ /* 118 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 119 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 120 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 121 */ "Program" OpHelp(""),
+ /* 122 */ "Param" OpHelp(""),
+ /* 123 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 124 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 125 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 126 */ "IfPos" OpHelp("if r[P1]>0 goto P2"),
+ /* 127 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"),
+ /* 128 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"),
+ /* 129 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 130 */ "IncrVacuum" OpHelp(""),
+ /* 131 */ "Real" OpHelp("r[P2]=P4"),
+ /* 132 */ "Expire" OpHelp(""),
+ /* 133 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 134 */ "VBegin" OpHelp(""),
+ /* 135 */ "VCreate" OpHelp(""),
+ /* 136 */ "VDestroy" OpHelp(""),
+ /* 137 */ "VOpen" OpHelp(""),
+ /* 138 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 139 */ "VNext" OpHelp(""),
+ /* 140 */ "VRename" OpHelp(""),
+ /* 141 */ "Pagecount" OpHelp(""),
+ /* 142 */ "ToText" OpHelp(""),
+ /* 143 */ "ToBlob" OpHelp(""),
+ /* 144 */ "ToNumeric" OpHelp(""),
+ /* 145 */ "ToInt" OpHelp(""),
+ /* 146 */ "ToReal" OpHelp(""),
+ /* 147 */ "MaxPgcnt" OpHelp(""),
+ /* 148 */ "Trace" OpHelp(""),
+ /* 149 */ "Noop" OpHelp(""),
+ /* 150 */ "Explain" OpHelp(""),
};
return azName[i];
}
#endif
@@ -25053,11 +25133,13 @@
**
** If the locking level of the file descriptor is already at or below
** the requested locking level, this routine is a no-op.
*/
static int unixUnlock(sqlite3_file *id, int eFileLock){
+#if SQLITE_MAX_MMAP_SIZE>0
assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
+#endif
return posixUnlock(id, eFileLock, 0);
}
#if SQLITE_MAX_MMAP_SIZE>0
static int unixMapfile(unixFile *pFd, i64 nByte);
@@ -30878,38 +30960,52 @@
#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE)
# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\
must be defined."
#endif
+/*
+** This constant should already be defined (in the "WinDef.h" SDK file).
+*/
+#ifndef MAX_PATH
+# define MAX_PATH (260)
+#endif
+
/*
** Maximum pathname length (in chars) for Win32. This should normally be
** MAX_PATH.
*/
#ifndef SQLITE_WIN32_MAX_PATH_CHARS
# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH)
#endif
+/*
+** This constant should already be defined (in the "WinNT.h" SDK file).
+*/
+#ifndef UNICODE_STRING_MAX_CHARS
+# define UNICODE_STRING_MAX_CHARS (32767)
+#endif
+
/*
** Maximum pathname length (in chars) for WinNT. This should normally be
-** 32767.
+** UNICODE_STRING_MAX_CHARS.
*/
#ifndef SQLITE_WINNT_MAX_PATH_CHARS
-# define SQLITE_WINNT_MAX_PATH_CHARS (32767)
+# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS)
#endif
/*
** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in
-** characters, so we allocate 3 bytes per character assuming worst-case of
+** characters, so we allocate 4 bytes per character assuming worst-case of
** 4-bytes-per-character for UTF8.
*/
#ifndef SQLITE_WIN32_MAX_PATH_BYTES
# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4)
#endif
/*
** Maximum pathname length (in bytes) for WinNT. This should normally be
-** 32767 * sizeof(WCHAR).
+** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR).
*/
#ifndef SQLITE_WINNT_MAX_PATH_BYTES
# define SQLITE_WINNT_MAX_PATH_BYTES \
(sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS)
#endif
@@ -30936,18 +31032,14 @@
#ifndef UNUSED_VARIABLE_VALUE
# define UNUSED_VARIABLE_VALUE(x) (void)(x)
#endif
/*
-** Returns the string that should be used as the directory separator.
+** Returns the character that should be used as the directory separator.
*/
-#ifndef winGetDirDep
-# ifdef __CYGWIN__
-# define winGetDirDep() "/"
-# else
-# define winGetDirDep() "\\"
-# endif
+#ifndef winGetDirSep
+# define winGetDirSep() '\\'
#endif
/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
@@ -31135,34 +31227,45 @@
** sqlite3_mem_methods implementation.
*/
typedef struct winMemData winMemData;
struct winMemData {
#ifndef NDEBUG
- u32 magic; /* Magic number to detect structure corruption. */
+ u32 magic1; /* Magic number to detect structure corruption. */
#endif
HANDLE hHeap; /* The handle to our heap. */
BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */
+#ifndef NDEBUG
+ u32 magic2; /* Magic number to detect structure corruption. */
+#endif
};
#ifndef NDEBUG
-#define WINMEM_MAGIC 0x42b2830b
+#define WINMEM_MAGIC1 0x42b2830b
+#define WINMEM_MAGIC2 0xbd4d7cf4
#endif
static struct winMemData win_mem_data = {
#ifndef NDEBUG
- WINMEM_MAGIC,
+ WINMEM_MAGIC1,
#endif
NULL, FALSE
+#ifndef NDEBUG
+ ,WINMEM_MAGIC2
+#endif
};
#ifndef NDEBUG
-#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
+#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 )
+#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 )
+#define winMemAssertMagic() winMemAssertMagic1(); winMemAssertMagic2();
#else
#define winMemAssertMagic()
#endif
-#define winMemGetHeap() win_mem_data.hHeap
+#define winMemGetDataPtr() &win_mem_data
+#define winMemGetHeap() win_mem_data.hHeap
+#define winMemGetOwned() win_mem_data.bOwned
static void *winMemMalloc(int nBytes);
static void winMemFree(void *pPrior);
static void *winMemRealloc(void *pPrior, int nBytes);
static int winMemSize(void *p);
@@ -31555,44 +31658,52 @@
#endif
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[42].pCurrent)
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+ { "HeapCompact", (SYSCALL)HeapCompact, 0 },
+#else
+ { "HeapCompact", (SYSCALL)0, 0 },
+#endif
+
+#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
+
#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
#else
{ "LoadLibraryA", (SYSCALL)0, 0 },
#endif
-#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[43].pCurrent)
+#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 },
#else
{ "LoadLibraryW", (SYSCALL)0, 0 },
#endif
-#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[44].pCurrent)
+#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
#if !SQLITE_OS_WINRT
{ "LocalFree", (SYSCALL)LocalFree, 0 },
#else
{ "LocalFree", (SYSCALL)0, 0 },
#endif
-#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[45].pCurrent)
+#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "LockFile", (SYSCALL)LockFile, 0 },
#else
{ "LockFile", (SYSCALL)0, 0 },
#endif
#ifndef osLockFile
#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[46].pCurrent)
+ DWORD))aSyscall[47].pCurrent)
#endif
#if !SQLITE_OS_WINCE
{ "LockFileEx", (SYSCALL)LockFileEx, 0 },
#else
@@ -31599,218 +31710,218 @@
{ "LockFileEx", (SYSCALL)0, 0 },
#endif
#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[47].pCurrent)
+ LPOVERLAPPED))aSyscall[48].pCurrent)
#endif
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
{ "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 },
#else
{ "MapViewOfFile", (SYSCALL)0, 0 },
#endif
#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- SIZE_T))aSyscall[48].pCurrent)
+ SIZE_T))aSyscall[49].pCurrent)
{ "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
- int))aSyscall[49].pCurrent)
+ int))aSyscall[50].pCurrent)
{ "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
- LARGE_INTEGER*))aSyscall[50].pCurrent)
+ LARGE_INTEGER*))aSyscall[51].pCurrent)
{ "ReadFile", (SYSCALL)ReadFile, 0 },
#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[51].pCurrent)
+ LPOVERLAPPED))aSyscall[52].pCurrent)
{ "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
-#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[52].pCurrent)
+#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
#if !SQLITE_OS_WINRT
{ "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
#else
{ "SetFilePointer", (SYSCALL)0, 0 },
#endif
#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
- DWORD))aSyscall[53].pCurrent)
+ DWORD))aSyscall[54].pCurrent)
#if !SQLITE_OS_WINRT
{ "Sleep", (SYSCALL)Sleep, 0 },
#else
{ "Sleep", (SYSCALL)0, 0 },
#endif
-#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[54].pCurrent)
+#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
{ "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
- LPFILETIME))aSyscall[55].pCurrent)
+ LPFILETIME))aSyscall[56].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "UnlockFile", (SYSCALL)UnlockFile, 0 },
#else
{ "UnlockFile", (SYSCALL)0, 0 },
#endif
#ifndef osUnlockFile
#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[56].pCurrent)
+ DWORD))aSyscall[57].pCurrent)
#endif
#if !SQLITE_OS_WINCE
{ "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 },
#else
{ "UnlockFileEx", (SYSCALL)0, 0 },
#endif
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[57].pCurrent)
+ LPOVERLAPPED))aSyscall[58].pCurrent)
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
#else
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
#endif
-#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[58].pCurrent)
+#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
{ "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
- LPCSTR,LPBOOL))aSyscall[59].pCurrent)
+ LPCSTR,LPBOOL))aSyscall[60].pCurrent)
{ "WriteFile", (SYSCALL)WriteFile, 0 },
#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[60].pCurrent)
+ LPOVERLAPPED))aSyscall[61].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
#else
{ "CreateEventExW", (SYSCALL)0, 0 },
#endif
#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
- DWORD,DWORD))aSyscall[61].pCurrent)
+ DWORD,DWORD))aSyscall[62].pCurrent)
#if !SQLITE_OS_WINRT
{ "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
#else
{ "WaitForSingleObject", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
- DWORD))aSyscall[62].pCurrent)
+ DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
#else
{ "WaitForSingleObjectEx", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
- BOOL))aSyscall[63].pCurrent)
+ BOOL))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
#else
{ "SetFilePointerEx", (SYSCALL)0, 0 },
#endif
#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
- PLARGE_INTEGER,DWORD))aSyscall[64].pCurrent)
+ PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
#if SQLITE_OS_WINRT
{ "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
#else
{ "GetFileInformationByHandleEx", (SYSCALL)0, 0 },
#endif
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
- FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[65].pCurrent)
+ FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
#else
{ "MapViewOfFileFromApp", (SYSCALL)0, 0 },
#endif
#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
- SIZE_T))aSyscall[66].pCurrent)
+ SIZE_T))aSyscall[67].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFile2", (SYSCALL)CreateFile2, 0 },
#else
{ "CreateFile2", (SYSCALL)0, 0 },
#endif
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
- LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[67].pCurrent)
+ LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
#else
{ "LoadPackagedLibrary", (SYSCALL)0, 0 },
#endif
#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
- DWORD))aSyscall[68].pCurrent)
+ DWORD))aSyscall[69].pCurrent)
#if SQLITE_OS_WINRT
{ "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
#else
{ "GetTickCount64", (SYSCALL)0, 0 },
#endif
-#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[69].pCurrent)
+#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
#if SQLITE_OS_WINRT
{ "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
#else
{ "GetNativeSystemInfo", (SYSCALL)0, 0 },
#endif
#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
- LPSYSTEM_INFO))aSyscall[70].pCurrent)
+ LPSYSTEM_INFO))aSyscall[71].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
#else
{ "OutputDebugStringA", (SYSCALL)0, 0 },
#endif
-#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[71].pCurrent)
+#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
#else
{ "OutputDebugStringW", (SYSCALL)0, 0 },
#endif
-#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[72].pCurrent)
+#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
{ "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
-#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[73].pCurrent)
+#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
{ "CreateFileMappingFromApp", (SYSCALL)0, 0 },
#endif
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
- LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[74].pCurrent)
+ LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
}; /* End of the overrideable system calls */
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
@@ -31893,10 +32004,98 @@
if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
}
return 0;
}
+#ifdef SQLITE_WIN32_MALLOC
+/*
+** If a Win32 native heap has been configured, this function will attempt to
+** compact it. Upon success, SQLITE_OK will be returned. Upon failure, one
+** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned. The
+** "pnLargest" argument, if non-zero, will be used to return the size of the
+** largest committed free block in the heap, in bytes.
+*/
+SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
+ int rc = SQLITE_OK;
+ UINT nLargest = 0;
+ HANDLE hHeap;
+
+ winMemAssertMagic();
+ hHeap = winMemGetHeap();
+ assert( hHeap!=0 );
+ assert( hHeap!=INVALID_HANDLE_VALUE );
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+#endif
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+ if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
+ DWORD lastErrno = osGetLastError();
+ if( lastErrno==NO_ERROR ){
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
+ (void*)hHeap);
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
+ osGetLastError(), (void*)hHeap);
+ rc = SQLITE_ERROR;
+ }
+ }
+#else
+ sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
+ (void*)hHeap);
+ rc = SQLITE_NOTFOUND;
+#endif
+ if( pnLargest ) *pnLargest = nLargest;
+ return rc;
+}
+
+/*
+** If a Win32 native heap has been configured, this function will attempt to
+** destroy and recreate it. If the Win32 native heap is not isolated and/or
+** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
+** be returned and no changes will be made to the Win32 native heap.
+*/
+SQLITE_API int sqlite3_win32_reset_heap(){
+ int rc;
+ MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
+ MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
+ MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
+ MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
+ sqlite3_mutex_enter(pMaster);
+ sqlite3_mutex_enter(pMem);
+ winMemAssertMagic();
+ if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
+ /*
+ ** At this point, there should be no outstanding memory allocations on
+ ** the heap. Also, since both the master and memsys locks are currently
+ ** being held by us, no other function (i.e. from another thread) should
+ ** be able to even access the heap. Attempt to destroy and recreate our
+ ** isolated Win32 native heap now.
+ */
+ assert( winMemGetHeap()!=NULL );
+ assert( winMemGetOwned() );
+ assert( sqlite3_memory_used()==0 );
+ winMemShutdown(winMemGetDataPtr());
+ assert( winMemGetHeap()==NULL );
+ assert( !winMemGetOwned() );
+ assert( sqlite3_memory_used()==0 );
+ rc = winMemInit(winMemGetDataPtr());
+ assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
+ assert( rc!=SQLITE_OK || winMemGetOwned() );
+ assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
+ }else{
+ /*
+ ** The Win32 native heap cannot be modified because it may be in use.
+ */
+ rc = SQLITE_BUSY;
+ }
+ sqlite3_mutex_leave(pMem);
+ sqlite3_mutex_leave(pMaster);
+ return rc;
+}
+#endif /* SQLITE_WIN32_MALLOC */
+
/*
** This function outputs the specified (ANSI) string to the Win32 debugger
** (if available).
*/
@@ -32001,11 +32200,11 @@
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
assert( nBytes>=0 );
p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
if( !p ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
@@ -32023,11 +32222,11 @@
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
pPrior, osGetLastError(), (void*)hHeap);
@@ -32044,11 +32243,11 @@
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
assert( nBytes>=0 );
if( !pPrior ){
p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
}else{
@@ -32072,11 +32271,11 @@
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
#endif
if( !p ) return 0;
n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
if( n==(SIZE_T)-1 ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
@@ -32098,11 +32297,12 @@
*/
static int winMemInit(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return SQLITE_ERROR;
- assert( pWinMemData->magic==WINMEM_MAGIC );
+ assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+ assert( pWinMemData->magic2==WINMEM_MAGIC2 );
#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
if( !pWinMemData->hHeap ){
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE,
@@ -32140,10 +32340,13 @@
*/
static void winMemShutdown(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return;
+ assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+ assert( pWinMemData->magic2==WINMEM_MAGIC2 );
+
if( pWinMemData->hHeap ){
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
@@ -34809,16 +35012,25 @@
return zConverted;
}
/*
** This function returns non-zero if the specified UTF-8 string buffer
-** ends with a directory separator character.
+** ends with a directory separator character or one was successfully
+** added to it.
*/
-static int winEndsInDirSep(char *zBuf){
+static int winMakeEndInDirSep(int nBuf, char *zBuf){
if( zBuf ){
int nLen = sqlite3Strlen30(zBuf);
- return nLen>0 && winIsDirSep(zBuf[nLen-1]);
+ if( nLen>0 ){
+ if( winIsDirSep(zBuf[nLen-1]) ){
+ return 1;
+ }else if( nLen+1mxPathname;
- zBuf = sqlite3MallocZero( nBuf+2 );
+ nMax = pVfs->mxPathname; nBuf = nMax + 2;
+ zBuf = sqlite3MallocZero( nBuf );
if( !zBuf ){
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM;
}
/* Figure out the effective temporary directory. First, check if one
** has been explicitly set by the application; otherwise, use the one
** configured by the operating system.
*/
- assert( nBuf>30 );
+ nDir = nMax - (nPre + 15);
+ assert( nDir>0 );
if( sqlite3_temp_directory ){
- sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory,
- winEndsInDirSep(sqlite3_temp_directory) ? "" :
- winGetDirDep());
+ int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
+ if( nDirLen>0 ){
+ if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
+ nDirLen++;
+ }
+ if( nDirLen>nDir ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
+ }
+ sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
+ }
}
#if defined(__CYGWIN__)
else{
static const char *azDirs[] = {
0, /* getenv("SQLITE_TMPDIR") */
@@ -34885,41 +35108,41 @@
for(i=0; i/etilqs_XXXXXXXXXXXXXXX\0\0"
+ **
+ ** If not, return SQLITE_ERROR. The number 17 is used here in order to
+ ** account for the space used by the 15 character random suffix and the
+ ** two trailing NUL characters. The final directory separator character
+ ** has already added if it was not already present.
*/
nLen = sqlite3Strlen30(zBuf);
-
- if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
+ if( (nLen + nPre + 17) > nBuf ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
- return winLogError(SQLITE_ERROR, 0, "winGetTempname3", 0);
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
}
- sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
+ sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
j = sqlite3Strlen30(zBuf);
sqlite3_randomness(15, &zBuf[j]);
for(i=0; i<15; i++, j++){
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
@@ -35066,11 +35307,11 @@
sqlite3_file *id, /* Write the SQLite file handle here */
int flags, /* Open mode flags */
int *pOutFlags /* Status return flags */
){
HANDLE h;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
DWORD dwDesiredAccess;
DWORD dwShareMode;
DWORD dwCreationDisposition;
DWORD dwFlagsAndAttributes = 0;
#if SQLITE_OS_WINCE
@@ -35357,11 +35598,11 @@
int syncDir /* Not used on win32 */
){
int cnt = 0;
int rc;
DWORD attr;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
SimulateIOError(return SQLITE_IOERR_DELETE);
@@ -35465,11 +35706,11 @@
int flags, /* Type of test to make on this file */
int *pResOut /* OUT: Result */
){
DWORD attr;
int rc = 0;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
SimulateIOError( return SQLITE_IOERR_ACCESS; );
OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
@@ -35611,12 +35852,12 @@
pVfs->mxPathname+1)<0 ){
sqlite3_free(zOut);
return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
"winFullPathname1", zRelative);
}
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
- sqlite3_data_directory, winGetDirDep(), zOut);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zOut);
sqlite3_free(zOut);
}else{
if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
"winFullPathname2", zRelative);
@@ -35634,12 +35875,12 @@
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
- sqlite3_data_directory, winGetDirDep(), zRelative);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zRelative);
}else{
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
}
return SQLITE_OK;
#endif
@@ -35667,12 +35908,12 @@
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s",
- sqlite3_data_directory, winGetDirDep(), zRelative);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zRelative);
return SQLITE_OK;
}
zConverted = winConvertFromUtf8Filename(zRelative);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
@@ -36006,11 +36247,11 @@
};
#endif
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==75 );
+ assert( ArraySize(aSyscall)==76 );
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
osGetNativeSystemInfo(&winSysInfo);
@@ -50676,11 +50917,11 @@
int bias, /* Bias search to the high end */
int *pRes /* Write search results here */
){
int rc; /* Status code */
UnpackedRecord *pIdxKey; /* Unpacked index key */
- char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */
+ char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */
char *pFree = 0;
if( pKey ){
assert( nKey==(i64)(int)nKey );
pIdxKey = sqlite3VdbeAllocUnpackedRecord(
@@ -60294,19 +60535,19 @@
if( pRec==0 ){
Index *pIdx = p->pIdx; /* Index being probed */
int nByte; /* Bytes of space to allocate */
int i; /* Counter variable */
- int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */
+ int nCol = pIdx->nColumn; /* Number of index columns including rowid */
nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord);
pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
if( pRec ){
- pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx);
+ pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
if( pRec->pKeyInfo ){
- assert( pRec->pKeyInfo->nField+1==nCol );
- pRec->pKeyInfo->enc = ENC(db);
+ assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
+ assert( pRec->pKeyInfo->enc==ENC(db) );
pRec->flags = UNPACKED_PREFIX_MATCH;
pRec->aMem = (Mem *)&pRec[1];
for(i=0; iaMem[i].flags = MEM_Null;
pRec->aMem[i].type = SQLITE_NULL;
@@ -60625,17 +60866,17 @@
** the object.
*/
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
if( pRec ){
int i;
- int nCol = pRec->pKeyInfo->nField+1;
+ int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
Mem *aMem = pRec->aMem;
sqlite3 *db = aMem[0].db;
for(i=0; ipKeyInfo);
+ sqlite3KeyInfoUnref(pRec->pKeyInfo);
sqlite3DbFree(db, pRec);
}
}
#endif /* ifdef SQLITE_ENABLE_STAT4 */
@@ -60784,10 +61025,21 @@
p->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
}
+#ifdef SQLITE_DEBUG
+/* This routine is just a convenient place to set a breakpoint that will
+** fire after each opcode is inserted and displayed using
+** "PRAGMA vdbe_addoptrace=on".
+*/
+static void test_addop_breakpoint(void){
+ static int n = 0;
+ n++;
+}
+#endif
+
/*
** Add a new instruction to the list of instructions current in the
** VDBE. Return the address of the new instruction.
**
** Parameters:
@@ -60821,14 +61073,17 @@
pOp->p1 = p1;
pOp->p2 = p2;
pOp->p3 = p3;
pOp->p4.p = 0;
pOp->p4type = P4_NOTUSED;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
pOp->zComment = 0;
+#endif
+#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
sqlite3VdbePrintOp(0, i, &p->aOp[i]);
+ test_addop_breakpoint();
}
#endif
#ifdef VDBE_PROFILE
pOp->cycles = 0;
pOp->cnt = 0;
@@ -61200,21 +61455,24 @@
for(i=0; ip2;
VdbeOp *pOut = &p->aOp[i+addr];
pOut->opcode = pIn->opcode;
pOut->p1 = pIn->p1;
- if( p2<0 && (sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP)!=0 ){
+ if( p2<0 ){
+ assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
pOut->p2 = addr + ADDR(p2);
}else{
pOut->p2 = p2;
}
pOut->p3 = pIn->p3;
pOut->p4type = P4_NOTUSED;
pOut->p4.p = 0;
pOut->p5 = 0;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
pOut->zComment = 0;
+#endif
+#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
}
#endif
}
@@ -61298,15 +61556,17 @@
assert( db );
switch( p4type ){
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
- case P4_KEYINFO:
- case P4_INTARRAY:
- case P4_KEYINFO_HANDOFF: {
+ case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
+ }
+ case P4_KEYINFO: {
+ if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
+ break;
}
case P4_MPRINTF: {
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break;
}
@@ -61340,11 +61600,11 @@
static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
if( aOp ){
Op *pOp;
for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
freeP4(db, pOp->p4type, pOp->p4.p);
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
sqlite3DbFree(db, pOp->zComment);
#endif
}
}
sqlite3DbFree(db, aOp);
@@ -61368,10 +61628,11 @@
VdbeOp *pOp = &p->aOp[addr];
sqlite3 *db = p->db;
freeP4(db, pOp->p4type, pOp->p4.p);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
+ if( addr==p->nOp-1 ) p->nOp--;
}
}
/*
** Change the value of the P4 operand for a specific instruction.
@@ -61381,18 +61642,10 @@
**
** If n>=0 then the P4 operand is dynamic, meaning that a copy of
** the string is made into memory obtained from sqlite3_malloc().
** A value of n==0 means copy bytes of zP4 up to and including the
** first null byte. If n>0 then copy n+1 bytes of zP4.
-**
-** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
-** A copy is made of the KeyInfo structure into memory obtained from
-** sqlite3_malloc, to be freed when the Vdbe is finalized.
-** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
-** stored in memory that the caller has obtained from sqlite3_malloc. The
-** caller should not free the allocation, it will be freed when the Vdbe is
-** finalized.
**
** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
** to a string or structure that is guaranteed to exist for the lifetime of
** the Vdbe. In these cases we can just copy the pointer.
**
@@ -61403,11 +61656,11 @@
sqlite3 *db;
assert( p!=0 );
db = p->db;
assert( p->magic==VDBE_MAGIC_INIT );
if( p->aOp==0 || db->mallocFailed ){
- if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
+ if( n!=P4_VTAB ){
freeP4(db, n, (void*)*(char**)&zP4);
}
return;
}
assert( p->nOp>0 );
@@ -61426,23 +61679,10 @@
pOp->p4type = P4_INT32;
}else if( zP4==0 ){
pOp->p4.p = 0;
pOp->p4type = P4_NOTUSED;
}else if( n==P4_KEYINFO ){
- KeyInfo *pOrig, *pNew;
-
- pOrig = (KeyInfo*)zP4;
- pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField);
- if( pNew ){
- memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0]));
- memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField);
- pOp->p4type = P4_KEYINFO;
- }else{
- p->db->mallocFailed = 1;
- pOp->p4type = P4_NOTUSED;
- }
- }else if( n==P4_KEYINFO_HANDOFF ){
pOp->p4.p = (void*)zP4;
pOp->p4type = P4_KEYINFO;
}else if( n==P4_VTAB ){
pOp->p4.p = (void*)zP4;
pOp->p4type = P4_VTAB;
@@ -61456,11 +61696,23 @@
pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
pOp->p4type = P4_DYNAMIC;
}
}
-#ifndef NDEBUG
+/*
+** Set the P4 on the most recently added opcode to the KeyInfo for the
+** index given.
+*/
+SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
+ Vdbe *v = pParse->pVdbe;
+ assert( v!=0 );
+ assert( pIdx!=0 );
+ sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx),
+ P4_KEYINFO);
+}
+
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
** Change the comment on the most recently coded instruction. Or
** insert a No-op and add the comment to that new instruction. This
** makes the code easier to read during debugging. None of this happens
** in a production build.
@@ -61530,10 +61782,85 @@
return (VdbeOp*)&dummy;
}else{
return &p->aOp[addr];
}
}
+
+#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
+/*
+** Return an integer value for one of the parameters to the opcode pOp
+** determined by character c.
+*/
+static int translateP(char c, const Op *pOp){
+ if( c=='1' ) return pOp->p1;
+ if( c=='2' ) return pOp->p2;
+ if( c=='3' ) return pOp->p3;
+ if( c=='4' ) return pOp->p4.i;
+ return pOp->p5;
+}
+
+/*
+** Compute a string for the "comment" field of a VDBE opcode listing
+*/
+static int displayComment(
+ const Op *pOp, /* The opcode to be commented */
+ const char *zP4, /* Previously obtained value for P4 */
+ char *zTemp, /* Write result here */
+ int nTemp /* Space available in zTemp[] */
+){
+ const char *zOpName;
+ const char *zSynopsis;
+ int nOpName;
+ int ii, jj;
+ zOpName = sqlite3OpcodeName(pOp->opcode);
+ nOpName = sqlite3Strlen30(zOpName);
+ if( zOpName[nOpName+1] ){
+ int seenCom = 0;
+ char c;
+ zSynopsis = zOpName += nOpName + 1;
+ for(ii=jj=0; jjzComment);
+ seenCom = 1;
+ }else{
+ int v1 = translateP(c, pOp);
+ int v2;
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1);
+ if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
+ ii += 3;
+ jj += sqlite3Strlen30(zTemp+jj);
+ v2 = translateP(zSynopsis[ii], pOp);
+ if( v2>1 ) sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
+ }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
+ ii += 4;
+ }
+ }
+ jj += sqlite3Strlen30(zTemp+jj);
+ }else{
+ zTemp[jj++] = c;
+ }
+ }
+ if( !seenCom && jjzComment ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment);
+ jj += sqlite3Strlen30(zTemp+jj);
+ }
+ if( jjzComment ){
+ sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment);
+ jj = sqlite3Strlen30(zTemp);
+ }else{
+ zTemp[0] = 0;
+ jj = 0;
+ }
+ return jj;
+}
+#endif /* SQLITE_DEBUG */
+
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
** Compute a string that describes the P4 parameter for an opcode.
@@ -61541,21 +61868,24 @@
*/
static char *displayP4(Op *pOp, char *zTemp, int nTemp){
char *zP4 = zTemp;
assert( nTemp>=20 );
switch( pOp->p4type ){
- case P4_KEYINFO_STATIC:
case P4_KEYINFO: {
int i, j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortOrder!=0 );
- sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
+ sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField);
i = sqlite3Strlen30(zTemp);
for(j=0; jnField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
const char *zColl = pColl ? pColl->zName : "nil";
int n = sqlite3Strlen30(zColl);
+ if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
+ zColl = "B";
+ n = 1;
+ }
if( i+n>nTemp-6 ){
memcpy(&zTemp[i],",...",4);
break;
}
zTemp[i++] = ',';
@@ -61724,20 +62054,22 @@
** Print a single opcode. This routine is used for debugging only.
*/
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
char *zP4;
char zPtr[50];
- static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n";
+ char zCom[100];
+ static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
if( pOut==0 ) pOut = stdout;
zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ displayComment(pOp, zP4, zCom, sizeof(zCom));
+#else
+ zCom[0] = 0
+#endif
fprintf(pOut, zFormat1, pc,
sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
-#ifdef SQLITE_DEBUG
- pOp->zComment ? pOp->zComment : ""
-#else
- ""
-#endif
+ zCom
);
fflush(pOut);
}
#endif
@@ -61879,11 +62211,11 @@
}else if( db->u1.isInterrupted ){
p->rc = SQLITE_INTERRUPT;
rc = SQLITE_ERROR;
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
}else{
- char *z;
+ char *zP4;
Op *pOp;
if( inOp ){
/* The output line number is small enough that we are still in the
** main program. */
pOp = &p->aOp[i];
@@ -61902,11 +62234,11 @@
pMem->type = SQLITE_INTEGER;
pMem->u.i = i; /* Program counter */
pMem++;
pMem->flags = MEM_Static|MEM_Str|MEM_Term;
- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
+ pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30(pMem->z);
pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8;
pMem++;
@@ -61949,13 +62281,13 @@
if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
- z = displayP4(pOp, pMem->z, 32);
- if( z!=pMem->z ){
- sqlite3VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, 0);
+ zP4 = displayP4(pOp, pMem->z, 32);
+ if( zP4!=pMem->z ){
+ sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
}else{
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
}
@@ -61972,23 +62304,23 @@
sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8;
pMem++;
-#ifdef SQLITE_DEBUG
- if( pOp->zComment ){
- pMem->flags = MEM_Str|MEM_Term;
- pMem->z = pOp->zComment;
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem->type = SQLITE_TEXT;
- }else
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ if( sqlite3VdbeMemGrow(pMem, 500, 0) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
+ }
+ pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
+ pMem->n = displayComment(pOp, zP4, pMem->z, 500);
+ pMem->type = SQLITE_TEXT;
+ pMem->enc = SQLITE_UTF8;
+#else
+ pMem->flags = MEM_Null; /* Comment */
+ pMem->type = SQLITE_NULL;
#endif
- {
- pMem->flags = MEM_Null; /* Comment */
- pMem->type = SQLITE_NULL;
- }
}
p->nResColumn = 8 - 4*(p->explain-1);
p->pResultSet = &p->aMem[1];
p->rc = SQLITE_OK;
@@ -62775,11 +63107,11 @@
if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
|| (!deferred && p->nFkConstraint>0)
){
p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
p->errorAction = OE_Abort;
- sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
+ sqlite3SetString(&p->zErrMsg, db, "FOREIGN KEY constraint failed");
return SQLITE_ERROR;
}
return SQLITE_OK;
}
#endif
@@ -63706,11 +64038,11 @@
*/
/* mem1.u.i = 0; // not needed, here to silence compiler warning */
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
- assert( pKeyInfo->nField+1>=pPKey2->nField );
+ assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField );
assert( pKeyInfo->aSortOrder!=0 );
while( idx1nField ){
u32 serial_type1;
/* Read the serial types for the next element in each key. */
@@ -63735,28 +64067,13 @@
/* Do the comparison
*/
rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
if( rc!=0 ){
assert( mem1.zMalloc==0 ); /* See comment below */
-
- /* Invert the result if we are using DESC sort order. */
if( pKeyInfo->aSortOrder[i] ){
- rc = -rc;
- }
-
- /* If the PREFIX_SEARCH flag is set and all fields except the final
- ** rowid field were equal, then clear the PREFIX_SEARCH flag and set
- ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
- ** This is used by the OP_IsUnique opcode.
- */
- if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){
- assert( idx1==szHdr1 && rc );
- assert( mem1.flags & MEM_Int );
- pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH;
- pPKey2->rowid = mem1.u.i;
- }
-
+ rc = -rc; /* Invert the result for DESC sort order. */
+ }
return rc;
}
i++;
}
@@ -66271,77 +66588,81 @@
*/
union vdbeExecUnion {
struct OP_Yield_stack_vars {
int pcDest;
} aa;
+ struct OP_Halt_stack_vars {
+ const char *zType;
+ const char *zLogFmt;
+ } ab;
struct OP_Null_stack_vars {
int cnt;
u16 nullFlag;
- } ab;
+ } ac;
struct OP_Variable_stack_vars {
Mem *pVar; /* Value being transferred */
- } ac;
+ } ad;
struct OP_Move_stack_vars {
char *zMalloc; /* Holding variable for allocated memory */
int n; /* Number of registers left to copy */
int p1; /* Register to copy from */
int p2; /* Register to copy to */
- } ad;
+ } ae;
struct OP_Copy_stack_vars {
int n;
- } ae;
+ } af;
struct OP_ResultRow_stack_vars {
Mem *pMem;
int i;
- } af;
+ } ag;
struct OP_Concat_stack_vars {
i64 nByte;
- } ag;
+ } ah;
struct OP_Remainder_stack_vars {
char bIntint; /* Started out as two integer operands */
int flags; /* Combined MEM_* flags from both inputs */
i64 iA; /* Integer value of left operand */
i64 iB; /* Integer value of right operand */
double rA; /* Real value of left operand */
double rB; /* Real value of right operand */
- } ah;
+ } ai;
struct OP_Function_stack_vars {
int i;
Mem *pArg;
sqlite3_context ctx;
sqlite3_value **apVal;
int n;
- } ai;
+ } aj;
struct OP_ShiftRight_stack_vars {
i64 iA;
u64 uA;
i64 iB;
u8 op;
- } aj;
+ } ak;
struct OP_Ge_stack_vars {
int res; /* Result of the comparison of pIn1 against pIn3 */
char affinity; /* Affinity to use for comparison */
u16 flags1; /* Copy of initial value of pIn1->flags */
u16 flags3; /* Copy of initial value of pIn3->flags */
- } ak;
+ } al;
struct OP_Compare_stack_vars {
int n;
int i;
int p1;
int p2;
const KeyInfo *pKeyInfo;
int idx;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
- } al;
+ } am;
struct OP_Or_stack_vars {
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- } am;
+ } an;
struct OP_IfNot_stack_vars {
int c;
- } an;
+ } ao;
struct OP_Column_stack_vars {
u32 payloadSize; /* Number of bytes in the record */
i64 payloadSize64; /* Number of bytes in the record */
int p1; /* P1 value of the opcode */
int p2; /* column number to retrieve */
@@ -66362,15 +66683,15 @@
u32 szField; /* Number of bytes in the content of a field */
int szHdr; /* Size of the header size field at start of record */
int avail; /* Number of bytes of available data */
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
- } ao;
+ } ap;
struct OP_Affinity_stack_vars {
const char *zAffinity; /* The affinity to be applied */
char cAff; /* A single character of affinity */
- } ap;
+ } aq;
struct OP_MakeRecord_stack_vars {
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
@@ -66383,93 +66704,86 @@
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
int i; /* Space used in zNewRecord[] */
int len; /* Length of a field */
- } aq;
+ } ar;
struct OP_Count_stack_vars {
i64 nEntry;
BtCursor *pCrsr;
- } ar;
+ } as;
struct OP_Savepoint_stack_vars {
int p1; /* Value of P1 operand */
char *zName; /* Name of savepoint */
int nName;
Savepoint *pNew;
Savepoint *pSavepoint;
Savepoint *pTmp;
int iSavepoint;
int ii;
- } as;
+ } at;
struct OP_AutoCommit_stack_vars {
int desiredAutoCommit;
int iRollback;
int turnOnAC;
- } at;
+ } au;
struct OP_Transaction_stack_vars {
Btree *pBt;
- } au;
+ } av;
struct OP_ReadCookie_stack_vars {
int iMeta;
int iDb;
int iCookie;
- } av;
+ } aw;
struct OP_SetCookie_stack_vars {
Db *pDb;
- } aw;
+ } ax;
struct OP_VerifyCookie_stack_vars {
int iMeta;
int iGen;
Btree *pBt;
- } ax;
+ } ay;
struct OP_OpenWrite_stack_vars {
int nField;
KeyInfo *pKeyInfo;
int p2;
int iDb;
int wrFlag;
Btree *pX;
VdbeCursor *pCur;
Db *pDb;
- } ay;
+ } az;
struct OP_OpenEphemeral_stack_vars {
VdbeCursor *pCx;
- } az;
+ KeyInfo *pKeyInfo;
+ } ba;
struct OP_SorterOpen_stack_vars {
VdbeCursor *pCx;
- } ba;
+ } bb;
struct OP_OpenPseudo_stack_vars {
VdbeCursor *pCx;
- } bb;
+ } bc;
struct OP_SeekGt_stack_vars {
int res;
int oc;
VdbeCursor *pC;
UnpackedRecord r;
int nField;
i64 iKey; /* The rowid we are to seek to */
- } bc;
+ } bd;
struct OP_Seek_stack_vars {
VdbeCursor *pC;
- } bd;
+ } be;
struct OP_Found_stack_vars {
int alreadyExists;
+ int ii;
VdbeCursor *pC;
int res;
char *pFree;
UnpackedRecord *pIdxKey;
UnpackedRecord r;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
- } be;
- struct OP_IsUnique_stack_vars {
- u16 ii;
- VdbeCursor *pCx;
- BtCursor *pCrsr;
- u16 nField;
- Mem *aMx;
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
+ char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
} bf;
struct OP_NotExists_stack_vars {
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
@@ -66499,10 +66813,11 @@
VdbeCursor *pC;
} bj;
struct OP_SorterCompare_stack_vars {
VdbeCursor *pC;
int res;
+ int nIgnore;
} bk;
struct OP_SorterData_stack_vars {
VdbeCursor *pC;
} bl;
struct OP_RowData_stack_vars {
@@ -66939,23 +67254,25 @@
REGISTER_TRACE(pOp->p1, pIn1);
pc = u.aa.pcDest;
break;
}
-/* Opcode: HaltIfNull P1 P2 P3 P4 *
+/* Opcode: HaltIfNull P1 P2 P3 P4 P5
+** Synopsis: if r[P3] null then halt
**
** Check the value in register P3. If it is NULL then Halt using
** parameter P1, P2, and P4 as if this were a Halt instruction. If the
** value in register P3 is not NULL, then this routine is a no-op.
+** The P5 parameter should be 1.
*/
case OP_HaltIfNull: { /* in3 */
pIn3 = &aMem[pOp->p3];
if( (pIn3->flags & MEM_Null)==0 ) break;
/* Fall through into OP_Halt */
}
-/* Opcode: Halt P1 P2 * P4 *
+/* Opcode: Halt P1 P2 * P4 P5
**
** Exit immediately. All open cursors, etc are closed
** automatically.
**
** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
@@ -66965,26 +67282,42 @@
** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort,
** then back out all changes that have occurred during this execution of the
** VDBE, but do not rollback the transaction.
**
** If P4 is not null then it is an error message string.
+**
+** P5 is a value between 0 and 4, inclusive, that modifies the P4 string.
+**
+** 0: (no change)
+** 1: NOT NULL contraint failed: P4
+** 2: UNIQUE constraint failed: P4
+** 3: CHECK constraint failed: P4
+** 4: FOREIGN KEY constraint failed: P4
+**
+** If P5 is not zero and P4 is NULL, then everything after the ":" is
+** omitted.
**
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program. So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {
+#if 0 /* local variables moved into u.ab */
+ const char *zType;
+ const char *zLogFmt;
+#endif /* local variables moved into u.ab */
+
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
VdbeFrame *pFrame = p->pFrame;
p->pFrame = pFrame->pParent;
p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange);
pc = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
- /* Instruction pc is the OP_Program that invoked the sub-program
+ /* Instruction pc is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
** instruction is set to OE_Ignore, then the sub-program is throwing
** an IGNORE exception. In this case jump to the address specified
** as the p2 of the calling OP_Program. */
pc = p->aOp[pc].p2-1;
@@ -66991,22 +67324,37 @@
}
aOp = p->aOp;
aMem = p->aMem;
break;
}
-
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
p->pc = pc;
- if( pOp->p4.z ){
- assert( p->rc!=SQLITE_OK );
- sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pc, p->zSql, pOp->p4.z);
- }else if( p->rc ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(pOp->p1, "constraint failed at %d in [%s]", pc, p->zSql);
+ if( p->rc ){
+ if( pOp->p5 ){
+ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
+ "FOREIGN KEY" };
+ assert( pOp->p5>=1 && pOp->p5<=4 );
+ testcase( pOp->p5==1 );
+ testcase( pOp->p5==2 );
+ testcase( pOp->p5==3 );
+ testcase( pOp->p5==4 );
+ u.ab.zType = azType[pOp->p5-1];
+ }else{
+ u.ab.zType = 0;
+ }
+ assert( u.ab.zType!=0 || pOp->p4.z!=0 );
+ u.ab.zLogFmt = "abort at %d in [%s]: %s";
+ if( u.ab.zType && pOp->p4.z ){
+ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
+ u.ab.zType, pOp->p4.z);
+ }else if( pOp->p4.z ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
+ }else{
+ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", u.ab.zType);
+ }
+ sqlite3_log(pOp->p1, u.ab.zLogFmt, pc, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
if( rc==SQLITE_BUSY ){
p->rc = rc = SQLITE_BUSY;
@@ -67017,19 +67365,21 @@
}
goto vdbe_return;
}
/* Opcode: Integer P1 P2 * * *
+** Synopsis: r[P2]=P1
**
** The 32-bit integer value P1 is written into register P2.
*/
case OP_Integer: { /* out2-prerelease */
pOut->u.i = pOp->p1;
break;
}
/* Opcode: Int64 * P2 * P4 *
+** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
*/
case OP_Int64: { /* out2-prerelease */
@@ -67038,10 +67388,11 @@
break;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
/* Opcode: Real * P2 * P4 *
+** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2.
*/
case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
@@ -67051,10 +67402,11 @@
break;
}
#endif
/* Opcode: String8 * P2 * P4 *
+** Synopsis: r[P2]='P4'
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
** into an OP_String before it is executed for the first time.
*/
case OP_String8: { /* same as TK_STRING, out2-prerelease */
@@ -67085,10 +67437,11 @@
}
/* Fall through to the next case, OP_String */
}
/* Opcode: String P1 P2 * P4 *
+** Synopsis: r[P2]='P4' (len=P1)
**
** The string value P4 of length P1 (bytes) is stored in register P2.
*/
case OP_String: { /* out2-prerelease */
assert( pOp->p4.z!=0 );
@@ -67099,10 +67452,11 @@
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Null P1 P2 P3 * *
+** Synopsis: r[P2..P3]=NULL
**
** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and every register in between P2 and P3. If P3
** is less than P2 (typically P3 is zero) then only register P2 is
** set to NULL.
@@ -67110,29 +67464,30 @@
** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
case OP_Null: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ab */
+#if 0 /* local variables moved into u.ac */
int cnt;
u16 nullFlag;
-#endif /* local variables moved into u.ab */
- u.ab.cnt = pOp->p3-pOp->p2;
+#endif /* local variables moved into u.ac */
+ u.ac.cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) );
- pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
- while( u.ab.cnt>0 ){
+ pOut->flags = u.ac.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
+ while( u.ac.cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
- pOut->flags = u.ab.nullFlag;
- u.ab.cnt--;
+ pOut->flags = u.ac.nullFlag;
+ u.ac.cnt--;
}
break;
}
/* Opcode: Blob P1 P2 * P4
+** Synopsis: r[P2]=P4 (len=P1)
**
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
*/
case OP_Blob: { /* out2-prerelease */
@@ -67142,107 +67497,111 @@
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Variable P1 P2 * P4 *
+** Synopsis: r[P2]=parameter(P1,P4)
**
** Transfer the values of bound parameter P1 into register P2
**
** If the parameter is named, then its name appears in P4 and P3==1.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ac */
+#if 0 /* local variables moved into u.ad */
Mem *pVar; /* Value being transferred */
-#endif /* local variables moved into u.ac */
+#endif /* local variables moved into u.ad */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
- u.ac.pVar = &p->aVar[pOp->p1 - 1];
- if( sqlite3VdbeMemTooBig(u.ac.pVar) ){
+ u.ad.pVar = &p->aVar[pOp->p1 - 1];
+ if( sqlite3VdbeMemTooBig(u.ad.pVar) ){
goto too_big;
}
- sqlite3VdbeMemShallowCopy(pOut, u.ac.pVar, MEM_Static);
+ sqlite3VdbeMemShallowCopy(pOut, u.ad.pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Move P1 P2 P3 * *
+** Synopsis: r[P2@P3]=r[P1@P3]
**
** Move the values in register P1..P1+P3 over into
** registers P2..P2+P3. Registers P1..P1+P3 are
** left holding a NULL. It is an error for register ranges
** P1..P1+P3 and P2..P2+P3 to overlap.
*/
case OP_Move: {
-#if 0 /* local variables moved into u.ad */
+#if 0 /* local variables moved into u.ae */
char *zMalloc; /* Holding variable for allocated memory */
int n; /* Number of registers left to copy */
int p1; /* Register to copy from */
int p2; /* Register to copy to */
-#endif /* local variables moved into u.ad */
-
- u.ad.n = pOp->p3 + 1;
- u.ad.p1 = pOp->p1;
- u.ad.p2 = pOp->p2;
- assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 );
- assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 );
-
- pIn1 = &aMem[u.ad.p1];
- pOut = &aMem[u.ad.p2];
- while( u.ad.n-- ){
+#endif /* local variables moved into u.ae */
+
+ u.ae.n = pOp->p3 + 1;
+ u.ae.p1 = pOp->p1;
+ u.ae.p2 = pOp->p2;
+ assert( u.ae.n>0 && u.ae.p1>0 && u.ae.p2>0 );
+ assert( u.ae.p1+u.ae.n<=u.ae.p2 || u.ae.p2+u.ae.n<=u.ae.p1 );
+
+ pIn1 = &aMem[u.ae.p1];
+ pOut = &aMem[u.ae.p2];
+ while( u.ae.n-- ){
assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
- u.ad.zMalloc = pOut->zMalloc;
+ u.ae.zMalloc = pOut->zMalloc;
pOut->zMalloc = 0;
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom>=&aMem[u.ad.p1] && pOut->pScopyFrom<&aMem[u.ad.p1+pOp->p3] ){
- pOut->pScopyFrom += u.ad.p1 - pOp->p2;
+ if( pOut->pScopyFrom>=&aMem[u.ae.p1] && pOut->pScopyFrom<&aMem[u.ae.p1+pOp->p3] ){
+ pOut->pScopyFrom += u.ae.p1 - pOp->p2;
}
#endif
- pIn1->zMalloc = u.ad.zMalloc;
- REGISTER_TRACE(u.ad.p2++, pOut);
+ pIn1->zMalloc = u.ae.zMalloc;
+ REGISTER_TRACE(u.ae.p2++, pOut);
pIn1++;
pOut++;
}
break;
}
/* Opcode: Copy P1 P2 P3 * *
+** Synopsis: r[P2@P3]=r[P1@P3]
**
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
** This instruction makes a deep copy of the value. A duplicate
** is made of any string or blob constant. See also OP_SCopy.
*/
case OP_Copy: {
-#if 0 /* local variables moved into u.ae */
+#if 0 /* local variables moved into u.af */
int n;
-#endif /* local variables moved into u.ae */
+#endif /* local variables moved into u.af */
- u.ae.n = pOp->p3;
+ u.af.n = pOp->p3;
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
while( 1 ){
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
Deephemeralize(pOut);
#ifdef SQLITE_DEBUG
pOut->pScopyFrom = 0;
#endif
- REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
- if( (u.ae.n--)==0 ) break;
+ REGISTER_TRACE(pOp->p2+pOp->p3-u.af.n, pOut);
+ if( (u.af.n--)==0 ) break;
pOut++;
pIn1++;
}
break;
}
/* Opcode: SCopy P1 P2 * * *
+** Synopsis: r[P2]=r[P1]
**
** Make a shallow copy of register P1 into register P2.
**
** This instruction makes a shallow copy of the value. If the value
** is a string or blob, then the copy is only a pointer to the
@@ -67250,35 +67609,35 @@
** Worse, if the original is deallocated, the copy becomes invalid.
** Thus the program must guarantee that the original will not change
** during the lifetime of the copy. Use OP_Copy to make a complete
** copy.
*/
-case OP_SCopy: { /* in1, out2 */
+case OP_SCopy: { /* out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
#endif
- REGISTER_TRACE(pOp->p2, pOut);
break;
}
/* Opcode: ResultRow P1 P2 * * *
+** Synopsis: output=r[P1@P2]
**
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
** structure to provide access to the top P1 values as the result
** row.
*/
case OP_ResultRow: {
-#if 0 /* local variables moved into u.af */
+#if 0 /* local variables moved into u.ag */
Mem *pMem;
int i;
-#endif /* local variables moved into u.af */
+#endif /* local variables moved into u.ag */
assert( p->nResColumn==pOp->p2 );
assert( pOp->p1>0 );
assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 );
/* If this statement has violated immediate foreign key constraints, do
@@ -67316,19 +67675,19 @@
/* Make sure the results of the current row are \000 terminated
** and have an assigned type. The results are de-ephemeralized as
** a side effect.
*/
- u.af.pMem = p->pResultSet = &aMem[pOp->p1];
- for(u.af.i=0; u.af.ip2; u.af.i++){
- assert( memIsValid(&u.af.pMem[u.af.i]) );
- Deephemeralize(&u.af.pMem[u.af.i]);
- assert( (u.af.pMem[u.af.i].flags & MEM_Ephem)==0
- || (u.af.pMem[u.af.i].flags & (MEM_Str|MEM_Blob))==0 );
- sqlite3VdbeMemNulTerminate(&u.af.pMem[u.af.i]);
- sqlite3VdbeMemStoreType(&u.af.pMem[u.af.i]);
- REGISTER_TRACE(pOp->p1+u.af.i, &u.af.pMem[u.af.i]);
+ u.ag.pMem = p->pResultSet = &aMem[pOp->p1];
+ for(u.ag.i=0; u.ag.ip2; u.ag.i++){
+ assert( memIsValid(&u.ag.pMem[u.ag.i]) );
+ Deephemeralize(&u.ag.pMem[u.ag.i]);
+ assert( (u.ag.pMem[u.ag.i].flags & MEM_Ephem)==0
+ || (u.ag.pMem[u.ag.i].flags & (MEM_Str|MEM_Blob))==0 );
+ sqlite3VdbeMemNulTerminate(&u.ag.pMem[u.ag.i]);
+ sqlite3VdbeMemStoreType(&u.ag.pMem[u.ag.i]);
+ REGISTER_TRACE(pOp->p1+u.ag.i, &u.ag.pMem[u.ag.i]);
}
if( db->mallocFailed ) goto no_mem;
/* Return SQLITE_ROW
*/
@@ -67336,10 +67695,11 @@
rc = SQLITE_ROW;
goto vdbe_return;
}
/* Opcode: Concat P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]+r[P1]
**
** Add the text in register P1 onto the end of the text in
** register P2 and store the result in register P3.
** If either the P1 or P2 text are NULL then store NULL in P3.
**
@@ -67348,13 +67708,13 @@
** It is illegal for P1 and P3 to be the same register. Sometimes,
** if P3 is the same register as P2, the implementation is able
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
-#if 0 /* local variables moved into u.ag */
+#if 0 /* local variables moved into u.ah */
i64 nByte;
-#endif /* local variables moved into u.ag */
+#endif /* local variables moved into u.ah */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
assert( pIn1!=pOut );
@@ -67363,58 +67723,63 @@
break;
}
if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
Stringify(pIn1, encoding);
Stringify(pIn2, encoding);
- u.ag.nByte = pIn1->n + pIn2->n;
- if( u.ag.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ u.ah.nByte = pIn1->n + pIn2->n;
+ if( u.ah.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
MemSetTypeFlag(pOut, MEM_Str);
- if( sqlite3VdbeMemGrow(pOut, (int)u.ag.nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)u.ah.nByte+2, pOut==pIn2) ){
goto no_mem;
}
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
- pOut->z[u.ag.nByte] = 0;
- pOut->z[u.ag.nByte+1] = 0;
+ pOut->z[u.ah.nByte]=0;
+ pOut->z[u.ah.nByte+1] = 0;
pOut->flags |= MEM_Term;
- pOut->n = (int)u.ag.nByte;
+ pOut->n = (int)u.ah.nByte;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Add P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]+r[P2]
**
** Add the value in register P1 to the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Multiply P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]*r[P2]
**
**
** Multiply the value in register P1 by the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Subtract P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]-r[P1]
**
** Subtract the value in register P1 from the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Divide P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]/r[P2]
**
** Divide the value in register P1 by the value in register P2
** and store the result in register P3 (P3=P2/P1). If the value in
** register P1 is zero, then the result is NULL. If either input is
** NULL, the result is NULL.
*/
/* Opcode: Remainder P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]%r[P2]
**
** Compute the remainder after integer division of the value in
** register P1 by the value in register P2 and store the result in P3.
** If the value in register P2 is zero the result is NULL.
** If either operand is NULL, the result is NULL.
@@ -67422,83 +67787,83 @@
case OP_Add: /* same as TK_PLUS, in1, in2, out3 */
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 */
-#if 0 /* local variables moved into u.ah */
+#if 0 /* local variables moved into u.ai */
char bIntint; /* Started out as two integer operands */
int flags; /* Combined MEM_* flags from both inputs */
i64 iA; /* Integer value of left operand */
i64 iB; /* Integer value of right operand */
double rA; /* Real value of left operand */
double rB; /* Real value of right operand */
-#endif /* local variables moved into u.ah */
+#endif /* local variables moved into u.ai */
pIn1 = &aMem[pOp->p1];
applyNumericAffinity(pIn1);
pIn2 = &aMem[pOp->p2];
applyNumericAffinity(pIn2);
pOut = &aMem[pOp->p3];
- u.ah.flags = pIn1->flags | pIn2->flags;
- if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
+ u.ai.flags = pIn1->flags | pIn2->flags;
+ if( (u.ai.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
- u.ah.iA = pIn1->u.i;
- u.ah.iB = pIn2->u.i;
- u.ah.bIntint = 1;
+ u.ai.iA = pIn1->u.i;
+ u.ai.iB = pIn2->u.i;
+ u.ai.bIntint = 1;
switch( pOp->opcode ){
- case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
- case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
- case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
+ case OP_Add: if( sqlite3AddInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
+ case OP_Subtract: if( sqlite3SubInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
+ case OP_Multiply: if( sqlite3MulInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
case OP_Divide: {
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 && u.ah.iB==SMALLEST_INT64 ) goto fp_math;
- u.ah.iB /= u.ah.iA;
+ if( u.ai.iA==0 ) goto arithmetic_result_is_null;
+ if( u.ai.iA==-1 && u.ai.iB==SMALLEST_INT64 ) goto fp_math;
+ u.ai.iB /= u.ai.iA;
break;
}
default: {
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 ) u.ah.iA = 1;
- u.ah.iB %= u.ah.iA;
+ if( u.ai.iA==0 ) goto arithmetic_result_is_null;
+ if( u.ai.iA==-1 ) u.ai.iA = 1;
+ u.ai.iB %= u.ai.iA;
break;
}
}
- pOut->u.i = u.ah.iB;
+ pOut->u.i = u.ai.iB;
MemSetTypeFlag(pOut, MEM_Int);
}else{
- u.ah.bIntint = 0;
+ u.ai.bIntint = 0;
fp_math:
- u.ah.rA = sqlite3VdbeRealValue(pIn1);
- u.ah.rB = sqlite3VdbeRealValue(pIn2);
+ u.ai.rA = sqlite3VdbeRealValue(pIn1);
+ u.ai.rB = sqlite3VdbeRealValue(pIn2);
switch( pOp->opcode ){
- case OP_Add: u.ah.rB += u.ah.rA; break;
- case OP_Subtract: u.ah.rB -= u.ah.rA; break;
- case OP_Multiply: u.ah.rB *= u.ah.rA; break;
+ case OP_Add: u.ai.rB += u.ai.rA; break;
+ case OP_Subtract: u.ai.rB -= u.ai.rA; break;
+ case OP_Multiply: u.ai.rB *= u.ai.rA; break;
case OP_Divide: {
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- if( u.ah.rA==(double)0 ) goto arithmetic_result_is_null;
- u.ah.rB /= u.ah.rA;
+ if( u.ai.rA==(double)0 ) goto arithmetic_result_is_null;
+ u.ai.rB /= u.ai.rA;
break;
}
default: {
- u.ah.iA = (i64)u.ah.rA;
- u.ah.iB = (i64)u.ah.rB;
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 ) u.ah.iA = 1;
- u.ah.rB = (double)(u.ah.iB % u.ah.iA);
+ u.ai.iA = (i64)u.ai.rA;
+ u.ai.iB = (i64)u.ai.rB;
+ if( u.ai.iA==0 ) goto arithmetic_result_is_null;
+ if( u.ai.iA==-1 ) u.ai.iA = 1;
+ u.ai.rB = (double)(u.ai.iB % u.ai.iA);
break;
}
}
#ifdef SQLITE_OMIT_FLOATING_POINT
- pOut->u.i = u.ah.rB;
+ pOut->u.i = u.ai.rB;
MemSetTypeFlag(pOut, MEM_Int);
#else
- if( sqlite3IsNaN(u.ah.rB) ){
+ if( sqlite3IsNaN(u.ai.rB) ){
goto arithmetic_result_is_null;
}
- pOut->r = u.ah.rB;
+ pOut->r = u.ai.rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
+ if( (u.ai.flags & MEM_Real)==0 && !u.ai.bIntint ){
sqlite3VdbeIntegerAffinity(pOut);
}
#endif
}
break;
@@ -67530,10 +67895,11 @@
}
break;
}
/* Opcode: Function P1 P2 P3 P4 P5
+** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to a Function structure that
** defines the function) with P5 arguments taken from register P2 and
** successors. The result of the function is stored in register P3.
** Register P3 must not be one of the function inputs.
@@ -67546,85 +67912,85 @@
** invocation of this opcode.
**
** See also: AggStep and AggFinal
*/
case OP_Function: {
-#if 0 /* local variables moved into u.ai */
+#if 0 /* local variables moved into u.aj */
int i;
Mem *pArg;
sqlite3_context ctx;
sqlite3_value **apVal;
int n;
-#endif /* local variables moved into u.ai */
+#endif /* local variables moved into u.aj */
- u.ai.n = pOp->p5;
- u.ai.apVal = p->apArg;
- assert( u.ai.apVal || u.ai.n==0 );
+ u.aj.n = pOp->p5;
+ u.aj.apVal = p->apArg;
+ assert( u.aj.apVal || u.aj.n==0 );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
pOut = &aMem[pOp->p3];
memAboutToChange(p, pOut);
- assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=(p->nMem-p->nCursor)+1) );
- assert( pOp->p3p2 || pOp->p3>=pOp->p2+u.ai.n );
- u.ai.pArg = &aMem[pOp->p2];
- for(u.ai.i=0; u.ai.ip2+u.ai.i, u.ai.pArg);
+ assert( u.aj.n==0 || (pOp->p2>0 && pOp->p2+u.aj.n<=(p->nMem-p->nCursor)+1) );
+ assert( pOp->p3p2 || pOp->p3>=pOp->p2+u.aj.n );
+ u.aj.pArg = &aMem[pOp->p2];
+ for(u.aj.i=0; u.aj.ip2+u.aj.i, u.aj.pArg);
}
assert( pOp->p4type==P4_FUNCDEF );
- u.ai.ctx.pFunc = pOp->p4.pFunc;
- u.ai.ctx.s.flags = MEM_Null;
- u.ai.ctx.s.db = db;
- u.ai.ctx.s.xDel = 0;
- u.ai.ctx.s.zMalloc = 0;
- u.ai.ctx.iOp = pc;
- u.ai.ctx.pVdbe = p;
+ u.aj.ctx.pFunc = pOp->p4.pFunc;
+ u.aj.ctx.s.flags = MEM_Null;
+ u.aj.ctx.s.db = db;
+ u.aj.ctx.s.xDel = 0;
+ u.aj.ctx.s.zMalloc = 0;
+ u.aj.ctx.iOp = pc;
+ u.aj.ctx.pVdbe = p;
/* The output cell may already have a buffer allocated. Move
- ** the pointer to u.ai.ctx.s so in case the user-function can use
+ ** the pointer to u.aj.ctx.s so in case the user-function can use
** the already allocated buffer instead of allocating a new one.
*/
- sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
- MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);
+ sqlite3VdbeMemMove(&u.aj.ctx.s, pOut);
+ MemSetTypeFlag(&u.aj.ctx.s, MEM_Null);
- u.ai.ctx.fErrorOrAux = 0;
- if( u.ai.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
+ u.aj.ctx.fErrorOrAux = 0;
+ if( u.aj.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
- u.ai.ctx.pColl = pOp[-1].p4.pColl;
+ u.aj.ctx.pColl = pOp[-1].p4.pColl;
}
db->lastRowid = lastRowid;
- (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */
+ (*u.aj.ctx.pFunc->xFunc)(&u.aj.ctx, u.aj.n, u.aj.apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid;
if( db->mallocFailed ){
/* Even though a malloc() has failed, the implementation of the
** user function may have called an sqlite3_result_XXX() function
** to return a value. The following call releases any resources
** associated with such a value.
*/
- sqlite3VdbeMemRelease(&u.ai.ctx.s);
+ sqlite3VdbeMemRelease(&u.aj.ctx.s);
goto no_mem;
}
/* If the function returned an error, throw an exception */
- if( u.ai.ctx.fErrorOrAux ){
- if( u.ai.ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
- rc = u.ai.ctx.isError;
+ if( u.aj.ctx.fErrorOrAux ){
+ if( u.aj.ctx.isError ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.aj.ctx.s));
+ rc = u.aj.ctx.isError;
}
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
}
/* Copy the result of the function into register P3 */
- sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding);
- sqlite3VdbeMemMove(pOut, &u.ai.ctx.s);
+ sqlite3VdbeChangeEncoding(&u.aj.ctx.s, encoding);
+ sqlite3VdbeMemMove(pOut, &u.aj.ctx.s);
if( sqlite3VdbeMemTooBig(pOut) ){
goto too_big;
}
#if 0
@@ -67639,29 +68005,33 @@
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: BitAnd P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]&r[P2]
**
** Take the bit-wise AND of the values in register P1 and P2 and
** store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: BitOr P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]|r[P2]
**
** Take the bit-wise OR of the values in register P1 and P2 and
** store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftLeft P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]<>r[P1]
**
** Shift the integer value in register P2 to the right by the
** number of bits specified by the integer in register P1.
** Store the result in register P3.
** If either input is NULL, the result is NULL.
@@ -67668,61 +68038,62 @@
*/
case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
-#if 0 /* local variables moved into u.aj */
+#if 0 /* local variables moved into u.ak */
i64 iA;
u64 uA;
i64 iB;
u8 op;
-#endif /* local variables moved into u.aj */
+#endif /* local variables moved into u.ak */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
sqlite3VdbeMemSetNull(pOut);
break;
}
- u.aj.iA = sqlite3VdbeIntValue(pIn2);
- u.aj.iB = sqlite3VdbeIntValue(pIn1);
- u.aj.op = pOp->opcode;
- if( u.aj.op==OP_BitAnd ){
- u.aj.iA &= u.aj.iB;
- }else if( u.aj.op==OP_BitOr ){
- u.aj.iA |= u.aj.iB;
- }else if( u.aj.iB!=0 ){
- assert( u.aj.op==OP_ShiftRight || u.aj.op==OP_ShiftLeft );
+ u.ak.iA = sqlite3VdbeIntValue(pIn2);
+ u.ak.iB = sqlite3VdbeIntValue(pIn1);
+ u.ak.op = pOp->opcode;
+ if( u.ak.op==OP_BitAnd ){
+ u.ak.iA &= u.ak.iB;
+ }else if( u.ak.op==OP_BitOr ){
+ u.ak.iA |= u.ak.iB;
+ }else if( u.ak.iB!=0 ){
+ assert( u.ak.op==OP_ShiftRight || u.ak.op==OP_ShiftLeft );
/* If shifting by a negative amount, shift in the other direction */
- if( u.aj.iB<0 ){
+ if( u.ak.iB<0 ){
assert( OP_ShiftRight==OP_ShiftLeft+1 );
- u.aj.op = 2*OP_ShiftLeft + 1 - u.aj.op;
- u.aj.iB = u.aj.iB>(-64) ? -u.aj.iB : 64;
+ u.ak.op = 2*OP_ShiftLeft + 1 - u.ak.op;
+ u.ak.iB = u.ak.iB>(-64) ? -u.ak.iB : 64;
}
- if( u.aj.iB>=64 ){
- u.aj.iA = (u.aj.iA>=0 || u.aj.op==OP_ShiftLeft) ? 0 : -1;
- }else{
- memcpy(&u.aj.uA, &u.aj.iA, sizeof(u.aj.uA));
- if( u.aj.op==OP_ShiftLeft ){
- u.aj.uA <<= u.aj.iB;
- }else{
- u.aj.uA >>= u.aj.iB;
+ if( u.ak.iB>=64 ){
+ u.ak.iA = (u.ak.iA>=0 || u.ak.op==OP_ShiftLeft) ? 0 : -1;
+ }else{
+ memcpy(&u.ak.uA, &u.ak.iA, sizeof(u.ak.uA));
+ if( u.ak.op==OP_ShiftLeft ){
+ u.ak.uA <<= u.ak.iB;
+ }else{
+ u.ak.uA >>= u.ak.iB;
/* Sign-extend on a right shift of a negative number */
- if( u.aj.iA<0 ) u.aj.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.aj.iB);
+ if( u.ak.iA<0 ) u.ak.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ak.iB);
}
- memcpy(&u.aj.iA, &u.aj.uA, sizeof(u.aj.iA));
+ memcpy(&u.ak.iA, &u.ak.uA, sizeof(u.ak.iA));
}
}
- pOut->u.i = u.aj.iA;
+ pOut->u.i = u.ak.iA;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
/* Opcode: AddImm P1 P2 * * *
+** Synopsis: r[P1]=r[P1]+P2
**
** Add the constant P2 to the value in register P1.
** The result is always an integer.
**
** To force any register to be an integer, just add 0.
@@ -67877,10 +68248,11 @@
break;
}
#endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */
/* Opcode: Lt P1 P2 P3 P4 P5
+** Synopsis: if r[P1]r[P3] goto P2
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is greater than the content of
** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Ge P1 P2 P3 P4 P5
+** Synopsis: if r[P1]>=r[P3] goto P2
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is greater than or equal to the content of
** register P1. See the Lt opcode for additional information.
*/
@@ -67958,37 +68335,37 @@
case OP_Ne: /* same as TK_NE, jump, in1, in3 */
case OP_Lt: /* same as TK_LT, jump, in1, in3 */
case OP_Le: /* same as TK_LE, jump, in1, in3 */
case OP_Gt: /* same as TK_GT, jump, in1, in3 */
case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
-#if 0 /* local variables moved into u.ak */
+#if 0 /* local variables moved into u.al */
int res; /* Result of the comparison of pIn1 against pIn3 */
char affinity; /* Affinity to use for comparison */
u16 flags1; /* Copy of initial value of pIn1->flags */
u16 flags3; /* Copy of initial value of pIn3->flags */
-#endif /* local variables moved into u.ak */
+#endif /* local variables moved into u.al */
pIn1 = &aMem[pOp->p1];
pIn3 = &aMem[pOp->p3];
- u.ak.flags1 = pIn1->flags;
- u.ak.flags3 = pIn3->flags;
- if( (u.ak.flags1 | u.ak.flags3)&MEM_Null ){
+ u.al.flags1 = pIn1->flags;
+ u.al.flags3 = pIn3->flags;
+ if( (u.al.flags1 | u.al.flags3)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
/* If SQLITE_NULLEQ is set (which will only happen if the operator is
** 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( (u.ak.flags1 & MEM_Cleared)==0 );
- if( (u.ak.flags1&MEM_Null)!=0
- && (u.ak.flags3&MEM_Null)!=0
- && (u.ak.flags3&MEM_Cleared)==0
+ assert( (u.al.flags1 & MEM_Cleared)==0 );
+ if( (u.al.flags1&MEM_Null)!=0
+ && (u.al.flags3&MEM_Null)!=0
+ && (u.al.flags3&MEM_Cleared)==0
){
- u.ak.res = 0; /* Results are equal */
+ u.al.res = 0; /* Results are equal */
}else{
- u.ak.res = 1; /* Results are not equal */
+ u.al.res = 1; /* Results are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
** then the result is always NULL.
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
@@ -68002,44 +68379,44 @@
}
break;
}
}else{
/* Neither operand is NULL. Do a comparison. */
- u.ak.affinity = pOp->p5 & SQLITE_AFF_MASK;
- if( u.ak.affinity ){
- applyAffinity(pIn1, u.ak.affinity, encoding);
- applyAffinity(pIn3, u.ak.affinity, encoding);
+ u.al.affinity = pOp->p5 & SQLITE_AFF_MASK;
+ if( u.al.affinity ){
+ applyAffinity(pIn1, u.al.affinity, encoding);
+ applyAffinity(pIn3, u.al.affinity, encoding);
if( db->mallocFailed ) goto no_mem;
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
ExpandBlob(pIn1);
ExpandBlob(pIn3);
- u.ak.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+ u.al.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
switch( pOp->opcode ){
- case OP_Eq: u.ak.res = u.ak.res==0; break;
- case OP_Ne: u.ak.res = u.ak.res!=0; break;
- case OP_Lt: u.ak.res = u.ak.res<0; break;
- case OP_Le: u.ak.res = u.ak.res<=0; break;
- case OP_Gt: u.ak.res = u.ak.res>0; break;
- default: u.ak.res = u.ak.res>=0; break;
+ case OP_Eq: u.al.res = u.al.res==0; break;
+ case OP_Ne: u.al.res = u.al.res!=0; break;
+ case OP_Lt: u.al.res = u.al.res<0; break;
+ case OP_Le: u.al.res = u.al.res<=0; break;
+ case OP_Gt: u.al.res = u.al.res>0; break;
+ default: u.al.res = u.al.res>=0; break;
}
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.ak.res;
+ pOut->u.i = u.al.res;
REGISTER_TRACE(pOp->p2, pOut);
- }else if( u.ak.res ){
+ }else if( u.al.res ){
pc = pOp->p2-1;
}
/* Undo any changes made by applyAffinity() to the input registers. */
- pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.ak.flags1&MEM_TypeMask);
- pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.ak.flags3&MEM_TypeMask);
+ pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.al.flags1&MEM_TypeMask);
+ pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.al.flags3&MEM_TypeMask);
break;
}
/* Opcode: Permutation * * * P4 *
**
@@ -68075,51 +68452,51 @@
** The comparison is a sort comparison, so NULLs compare equal,
** NULLs are less than numbers, numbers are less than strings,
** and strings are less than blobs.
*/
case OP_Compare: {
-#if 0 /* local variables moved into u.al */
+#if 0 /* local variables moved into u.am */
int n;
int i;
int p1;
int p2;
const KeyInfo *pKeyInfo;
int idx;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
-#endif /* local variables moved into u.al */
+#endif /* local variables moved into u.am */
if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
- u.al.n = pOp->p3;
- u.al.pKeyInfo = pOp->p4.pKeyInfo;
- assert( u.al.n>0 );
- assert( u.al.pKeyInfo!=0 );
- u.al.p1 = pOp->p1;
- u.al.p2 = pOp->p2;
+ u.am.n = pOp->p3;
+ u.am.pKeyInfo = pOp->p4.pKeyInfo;
+ assert( u.am.n>0 );
+ assert( u.am.pKeyInfo!=0 );
+ u.am.p1 = pOp->p1;
+ u.am.p2 = pOp->p2;
#if SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
- for(k=0; kmx ) mx = aPermute[k];
- assert( u.al.p1>0 && u.al.p1+mx<=(p->nMem-p->nCursor)+1 );
- assert( u.al.p2>0 && u.al.p2+mx<=(p->nMem-p->nCursor)+1 );
+ for(k=0; kmx ) mx = aPermute[k];
+ assert( u.am.p1>0 && u.am.p1+mx<=(p->nMem-p->nCursor)+1 );
+ assert( u.am.p2>0 && u.am.p2+mx<=(p->nMem-p->nCursor)+1 );
}else{
- assert( u.al.p1>0 && u.al.p1+u.al.n<=(p->nMem-p->nCursor)+1 );
- assert( u.al.p2>0 && u.al.p2+u.al.n<=(p->nMem-p->nCursor)+1 );
+ assert( u.am.p1>0 && u.am.p1+u.am.n<=(p->nMem-p->nCursor)+1 );
+ assert( u.am.p2>0 && u.am.p2+u.am.n<=(p->nMem-p->nCursor)+1 );
}
#endif /* SQLITE_DEBUG */
- for(u.al.i=0; u.al.inField );
- u.al.pColl = u.al.pKeyInfo->aColl[u.al.i];
- u.al.bRev = u.al.pKeyInfo->aSortOrder[u.al.i];
- iCompare = sqlite3MemCompare(&aMem[u.al.p1+u.al.idx], &aMem[u.al.p2+u.al.idx], u.al.pColl);
+ for(u.am.i=0; u.am.inField );
+ u.am.pColl = u.am.pKeyInfo->aColl[u.am.i];
+ u.am.bRev = u.am.pKeyInfo->aSortOrder[u.am.i];
+ iCompare = sqlite3MemCompare(&aMem[u.am.p1+u.am.idx], &aMem[u.am.p2+u.am.idx], u.am.pColl);
if( iCompare ){
- if( u.al.bRev ) iCompare = -iCompare;
+ if( u.am.bRev ) iCompare = -iCompare;
break;
}
}
aPermute = 0;
break;
@@ -68141,19 +68518,21 @@
}
break;
}
/* Opcode: And P1 P2 P3 * *
+** Synopsis: r[P3]=(r[P1] && r[P2])
**
** Take the logical AND of the values in registers P1 and P2 and
** write the result into register P3.
**
** If either P1 or P2 is 0 (false) then the result is 0 even if
** the other input is NULL. A NULL and true or two NULLs give
** a NULL output.
*/
/* Opcode: Or P1 P2 P3 * *
+** Synopsis: r[P3]=(r[P1] || r[P2])
**
** Take the logical OR of the values in register P1 and P2 and
** store the answer in register P3.
**
** If either P1 or P2 is nonzero (true) then the result is 1 (true)
@@ -68160,45 +68539,46 @@
** even if the other input is NULL. A NULL and false or two NULLs
** give a NULL output.
*/
case OP_And: /* same as TK_AND, in1, in2, out3 */
case OP_Or: { /* same as TK_OR, in1, in2, out3 */
-#if 0 /* local variables moved into u.am */
+#if 0 /* local variables moved into u.an */
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
-#endif /* local variables moved into u.am */
+#endif /* local variables moved into u.an */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
- u.am.v1 = 2;
+ u.an.v1 = 2;
}else{
- u.am.v1 = sqlite3VdbeIntValue(pIn1)!=0;
+ u.an.v1 = sqlite3VdbeIntValue(pIn1)!=0;
}
pIn2 = &aMem[pOp->p2];
if( pIn2->flags & MEM_Null ){
- u.am.v2 = 2;
+ u.an.v2 = 2;
}else{
- u.am.v2 = sqlite3VdbeIntValue(pIn2)!=0;
+ u.an.v2 = sqlite3VdbeIntValue(pIn2)!=0;
}
if( pOp->opcode==OP_And ){
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
- u.am.v1 = and_logic[u.am.v1*3+u.am.v2];
+ u.an.v1 = and_logic[u.an.v1*3+u.an.v2];
}else{
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
- u.am.v1 = or_logic[u.am.v1*3+u.am.v2];
+ u.an.v1 = or_logic[u.an.v1*3+u.an.v2];
}
pOut = &aMem[pOp->p3];
- if( u.am.v1==2 ){
+ if( u.an.v1==2 ){
MemSetTypeFlag(pOut, MEM_Null);
}else{
- pOut->u.i = u.am.v1;
+ pOut->u.i = u.an.v1;
MemSetTypeFlag(pOut, MEM_Int);
}
break;
}
/* Opcode: Not P1 P2 * * *
+** Synopsis: r[P2]= !r[P1]
**
** Interpret the value in register P1 as a boolean value. Store the
** boolean complement in register P2. If the value in register P1 is
** NULL, then a NULL is stored in P2.
*/
@@ -68212,10 +68592,11 @@
}
break;
}
/* Opcode: BitNot P1 P2 * * *
+** Synopsis: r[P1]= ~r[P1]
**
** Interpret the content of register P1 as an integer. Store the
** ones-complement of the P1 value into register P2. If P1 holds
** a NULL then store a NULL in P2.
*/
@@ -68257,31 +68638,32 @@
** is considered false if it has a numeric value of zero. If the value
** in P1 is NULL then take the jump if P3 is zero.
*/
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
-#if 0 /* local variables moved into u.an */
+#if 0 /* local variables moved into u.ao */
int c;
-#endif /* local variables moved into u.an */
+#endif /* local variables moved into u.ao */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
- u.an.c = pOp->p3;
+ u.ao.c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
- u.an.c = sqlite3VdbeIntValue(pIn1)!=0;
+ u.ao.c = sqlite3VdbeIntValue(pIn1)!=0;
#else
- u.an.c = sqlite3VdbeRealValue(pIn1)!=0.0;
+ u.ao.c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
- if( pOp->opcode==OP_IfNot ) u.an.c = !u.an.c;
+ if( pOp->opcode==OP_IfNot ) u.ao.c = !u.ao.c;
}
- if( u.an.c ){
+ if( u.ao.c ){
pc = pOp->p2-1;
}
break;
}
/* Opcode: IsNull P1 P2 * * *
+** Synopsis: if r[P1]==NULL goto P2
**
** Jump to P2 if the value in register P1 is NULL.
*/
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
@@ -68290,10 +68672,11 @@
}
break;
}
/* Opcode: NotNull P1 P2 * * *
+** Synopsis: if r[P1]!=NULL goto P2
**
** Jump to P2 if the value in register P1 is not NULL.
*/
case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
@@ -68302,10 +68685,11 @@
}
break;
}
/* Opcode: Column P1 P2 P3 P4 P5
+** Synopsis: r[P3]=PX
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
** information about the format of the data.) Extract the P2-th column
** from this record. If there are less that (P2+1)
@@ -68326,11 +68710,11 @@
** the result is guaranteed to only be used as the argument of a length()
** or typeof() function, respectively. The loading of large blobs can be
** skipped for length() and all content loading can be skipped for typeof().
*/
case OP_Column: {
-#if 0 /* local variables moved into u.ao */
+#if 0 /* local variables moved into u.ap */
u32 payloadSize; /* Number of bytes in the record */
i64 payloadSize64; /* Number of bytes in the record */
int p1; /* P1 value of the opcode */
int p2; /* column number to retrieve */
VdbeCursor *pC; /* The VDBE cursor */
@@ -68350,135 +68734,133 @@
u32 szField; /* Number of bytes in the content of a field */
int szHdr; /* Size of the header size field at start of record */
int avail; /* Number of bytes of available data */
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
-#endif /* local variables moved into u.ao */
+#endif /* local variables moved into u.ap */
- u.ao.p1 = pOp->p1;
- u.ao.p2 = pOp->p2;
- u.ao.pC = 0;
- memset(&u.ao.sMem, 0, sizeof(u.ao.sMem));
- assert( u.ao.p1nCursor );
+ u.ap.p1 = pOp->p1;
+ u.ap.p2 = pOp->p2;
+ u.ap.pC = 0;
+ memset(&u.ap.sMem, 0, sizeof(u.ap.sMem));
+ assert( u.ap.p1nCursor );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- u.ao.pDest = &aMem[pOp->p3];
- memAboutToChange(p, u.ao.pDest);
- u.ao.zRec = 0;
+ u.ap.pDest = &aMem[pOp->p3];
+ memAboutToChange(p, u.ap.pDest);
+ u.ap.zRec = 0;
- /* This block sets the variable u.ao.payloadSize to be the total number of
+ /* This block sets the variable u.ap.payloadSize to be the total number of
** bytes in the record.
**
- ** u.ao.zRec is set to be the complete text of the record if it is available.
+ ** u.ap.zRec is set to be the complete text of the record if it is available.
** The complete record text is always available for pseudo-tables
** If the record is stored in a cursor, the complete record text
- ** might be available in the u.ao.pC->aRow cache. Or it might not be.
- ** If the data is unavailable, u.ao.zRec is set to NULL.
+ ** might be available in the u.ap.pC->aRow cache. Or it might not be.
+ ** If the data is unavailable, u.ap.zRec is set to NULL.
**
** We also compute the number of columns in the record. For cursors,
** the number of columns is stored in the VdbeCursor.nField element.
*/
- u.ao.pC = p->apCsr[u.ao.p1];
- assert( u.ao.pC!=0 );
+ u.ap.pC = p->apCsr[u.ap.p1];
+ assert( u.ap.pC!=0 );
#ifndef SQLITE_OMIT_VIRTUALTABLE
- assert( u.ao.pC->pVtabCursor==0 );
+ assert( u.ap.pC->pVtabCursor==0 );
#endif
- u.ao.pCrsr = u.ao.pC->pCursor;
- if( u.ao.pCrsr!=0 ){
+ u.ap.pCrsr = u.ap.pC->pCursor;
+ if( u.ap.pCrsr!=0 ){
/* The record is stored in a B-Tree */
- rc = sqlite3VdbeCursorMoveto(u.ao.pC);
+ rc = sqlite3VdbeCursorMoveto(u.ap.pC);
if( rc ) goto abort_due_to_error;
- if( u.ao.pC->nullRow ){
- u.ao.payloadSize = 0;
- }else if( u.ao.pC->cacheStatus==p->cacheCtr ){
- u.ao.payloadSize = u.ao.pC->payloadSize;
- u.ao.zRec = (char*)u.ao.pC->aRow;
- }else if( u.ao.pC->isIndex ){
- assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ao.pCrsr, &u.ao.payloadSize64);
+ if( u.ap.pC->nullRow ){
+ u.ap.payloadSize = 0;
+ }else if( u.ap.pC->cacheStatus==p->cacheCtr ){
+ u.ap.payloadSize = u.ap.pC->payloadSize;
+ u.ap.zRec = (char*)u.ap.pC->aRow;
+ }else if( u.ap.pC->isIndex ){
+ assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) );
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ap.pCrsr, &u.ap.payloadSize64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
/* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
- ** payload size, so it is impossible for u.ao.payloadSize64 to be
+ ** payload size, so it is impossible for u.ap.payloadSize64 to be
** larger than 32 bits. */
- assert( (u.ao.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ao.payloadSize64 );
- u.ao.payloadSize = (u32)u.ao.payloadSize64;
+ assert( (u.ap.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ap.payloadSize64 );
+ u.ap.payloadSize = (u32)u.ap.payloadSize64;
}else{
- assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ao.pCrsr, &u.ao.payloadSize);
+ assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) );
+ VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ap.pCrsr, &u.ap.payloadSize);
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
}
- }else if( ALWAYS(u.ao.pC->pseudoTableReg>0) ){
- u.ao.pReg = &aMem[u.ao.pC->pseudoTableReg];
- if( u.ao.pC->multiPseudo ){
- sqlite3VdbeMemShallowCopy(u.ao.pDest, u.ao.pReg+u.ao.p2, MEM_Ephem);
- Deephemeralize(u.ao.pDest);
+ }else{
+ assert( u.ap.pC->pseudoTableReg>0 );
+ u.ap.pReg = &aMem[u.ap.pC->pseudoTableReg];
+ if( u.ap.pC->multiPseudo ){
+ sqlite3VdbeMemShallowCopy(u.ap.pDest, u.ap.pReg+u.ap.p2, MEM_Ephem);
+ Deephemeralize(u.ap.pDest);
goto op_column_out;
}
- assert( u.ao.pReg->flags & MEM_Blob );
- assert( memIsValid(u.ao.pReg) );
- u.ao.payloadSize = u.ao.pReg->n;
- u.ao.zRec = u.ao.pReg->z;
- u.ao.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
- assert( u.ao.payloadSize==0 || u.ao.zRec!=0 );
- }else{
- /* Consider the row to be NULL */
- u.ao.payloadSize = 0;
+ assert( u.ap.pReg->flags & MEM_Blob );
+ assert( memIsValid(u.ap.pReg) );
+ u.ap.payloadSize = u.ap.pReg->n;
+ u.ap.zRec = u.ap.pReg->z;
+ u.ap.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
+ assert( u.ap.payloadSize==0 || u.ap.zRec!=0 );
}
- /* If u.ao.payloadSize is 0, then just store a NULL. This can happen because of
+ /* If u.ap.payloadSize is 0, then just store a NULL. This can happen because of
** nullRow or because of a corrupt database. */
- if( u.ao.payloadSize==0 ){
- MemSetTypeFlag(u.ao.pDest, MEM_Null);
+ if( u.ap.payloadSize==0 ){
+ MemSetTypeFlag(u.ap.pDest, MEM_Null);
goto op_column_out;
}
assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
- if( u.ao.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( u.ap.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- u.ao.nField = u.ao.pC->nField;
- assert( u.ao.p2nField;
+ assert( u.ap.p2aType;
- if( u.ao.pC->cacheStatus==p->cacheCtr ){
- u.ao.aOffset = u.ao.pC->aOffset;
+ u.ap.aType = u.ap.pC->aType;
+ if( u.ap.pC->cacheStatus==p->cacheCtr ){
+ u.ap.aOffset = u.ap.pC->aOffset;
}else{
- assert(u.ao.aType);
- u.ao.avail = 0;
- u.ao.pC->aOffset = u.ao.aOffset = &u.ao.aType[u.ao.nField];
- u.ao.pC->payloadSize = u.ao.payloadSize;
- u.ao.pC->cacheStatus = p->cacheCtr;
+ assert(u.ap.aType);
+ u.ap.avail = 0;
+ u.ap.pC->aOffset = u.ap.aOffset = &u.ap.aType[u.ap.nField];
+ u.ap.pC->payloadSize = u.ap.payloadSize;
+ u.ap.pC->cacheStatus = p->cacheCtr;
/* Figure out how many bytes are in the header */
- if( u.ao.zRec ){
- u.ao.zData = u.ao.zRec;
+ if( u.ap.zRec ){
+ u.ap.zData = u.ap.zRec;
}else{
- if( u.ao.pC->isIndex ){
- u.ao.zData = (char*)sqlite3BtreeKeyFetch(u.ao.pCrsr, &u.ao.avail);
+ if( u.ap.pC->isIndex ){
+ u.ap.zData = (char*)sqlite3BtreeKeyFetch(u.ap.pCrsr, &u.ap.avail);
}else{
- u.ao.zData = (char*)sqlite3BtreeDataFetch(u.ao.pCrsr, &u.ao.avail);
+ u.ap.zData = (char*)sqlite3BtreeDataFetch(u.ap.pCrsr, &u.ap.avail);
}
/* If KeyFetch()/DataFetch() managed to get the entire payload,
- ** save the payload in the u.ao.pC->aRow cache. That will save us from
+ ** save the payload in the u.ap.pC->aRow cache. That will save us from
** having to make additional calls to fetch the content portion of
** the record.
*/
- assert( u.ao.avail>=0 );
- if( u.ao.payloadSize <= (u32)u.ao.avail ){
- u.ao.zRec = u.ao.zData;
- u.ao.pC->aRow = (u8*)u.ao.zData;
+ assert( u.ap.avail>=0 );
+ if( u.ap.payloadSize <= (u32)u.ap.avail ){
+ u.ap.zRec = u.ap.zData;
+ u.ap.pC->aRow = (u8*)u.ap.zData;
}else{
- u.ao.pC->aRow = 0;
+ u.ap.pC->aRow = 0;
}
}
/* The following assert is true in all cases except when
** the database file has been corrupted externally.
- ** assert( u.ao.zRec!=0 || u.ao.avail>=u.ao.payloadSize || u.ao.avail>=9 ); */
- u.ao.szHdr = getVarint32((u8*)u.ao.zData, u.ao.offset);
+ ** assert( u.ap.zRec!=0 || u.ap.avail>=u.ap.payloadSize || u.ap.avail>=9 ); */
+ u.ap.szHdr = getVarint32((u8*)u.ap.zData, u.ap.offset);
/* Make sure a corrupt database has not given us an oversize header.
** Do this now to avoid an oversize memory allocation.
**
** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
@@ -68485,193 +68867,195 @@
** types use so much data space that there can only be 4096 and 32 of
** them, respectively. So the maximum header length results from a
** 3-byte type for each of the maximum of 32768 columns plus three
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
*/
- if( u.ao.offset > 98307 ){
+ if( u.ap.offset > 98307 ){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_out;
}
- /* Compute in u.ao.len the number of bytes of data we need to read in order
- ** to get u.ao.nField type values. u.ao.offset is an upper bound on this. But
- ** u.ao.nField might be significantly less than the true number of columns
- ** in the table, and in that case, 5*u.ao.nField+3 might be smaller than u.ao.offset.
- ** We want to minimize u.ao.len in order to limit the size of the memory
- ** allocation, especially if a corrupt database file has caused u.ao.offset
+ /* Compute in u.ap.len the number of bytes of data we need to read in order
+ ** to get u.ap.nField type values. u.ap.offset is an upper bound on this. But
+ ** u.ap.nField might be significantly less than the true number of columns
+ ** in the table, and in that case, 5*u.ap.nField+3 might be smaller than u.ap.offset.
+ ** We want to minimize u.ap.len in order to limit the size of the memory
+ ** allocation, especially if a corrupt database file has caused u.ap.offset
** to be oversized. Offset is limited to 98307 above. But 98307 might
** still exceed Robson memory allocation limits on some configurations.
- ** On systems that cannot tolerate large memory allocations, u.ao.nField*5+3
- ** will likely be much smaller since u.ao.nField will likely be less than
+ ** On systems that cannot tolerate large memory allocations, u.ap.nField*5+3
+ ** will likely be much smaller since u.ap.nField will likely be less than
** 20 or so. This insures that Robson memory allocation limits are
** not exceeded even for corrupt database files.
*/
- u.ao.len = u.ao.nField*5 + 3;
- if( u.ao.len > (int)u.ao.offset ) u.ao.len = (int)u.ao.offset;
+ u.ap.len = u.ap.nField*5 + 3;
+ if( u.ap.len > (int)u.ap.offset ) u.ap.len = (int)u.ap.offset;
/* The KeyFetch() or DataFetch() above are fast and will get the entire
** record header in most cases. But they will fail to get the complete
** record header if the record header does not fit on a single page
** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to
** acquire the complete header text.
*/
- if( !u.ao.zRec && u.ao.availisIndex, &u.ao.sMem);
+ if( !u.ap.zRec && u.ap.availisIndex, &u.ap.sMem);
if( rc!=SQLITE_OK ){
goto op_column_out;
}
- u.ao.zData = u.ao.sMem.z;
- }
- u.ao.zEndHdr = (u8 *)&u.ao.zData[u.ao.len];
- u.ao.zIdx = (u8 *)&u.ao.zData[u.ao.szHdr];
-
- /* Scan the header and use it to fill in the u.ao.aType[] and u.ao.aOffset[]
- ** arrays. u.ao.aType[u.ao.i] will contain the type integer for the u.ao.i-th
- ** column and u.ao.aOffset[u.ao.i] will contain the u.ao.offset from the beginning
- ** of the record to the start of the data for the u.ao.i-th column
- */
- for(u.ao.i=0; u.ao.i u.ao.zEndHdr) || (u.ao.offset > u.ao.payloadSize)
- || (u.ao.zIdx==u.ao.zEndHdr && u.ao.offset!=u.ao.payloadSize) ){
+ if( (u.ap.zIdx > u.ap.zEndHdr) || (u.ap.offset > u.ap.payloadSize)
+ || (u.ap.zIdx==u.ap.zEndHdr && u.ap.offset!=u.ap.payloadSize) ){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_out;
}
}
- /* Get the column information. If u.ao.aOffset[u.ao.p2] is non-zero, then
- ** deserialize the value from the record. If u.ao.aOffset[u.ao.p2] is zero,
+ /* Get the column information. If u.ap.aOffset[u.ap.p2] is non-zero, then
+ ** deserialize the value from the record. If u.ap.aOffset[u.ap.p2] is zero,
** then there are not enough fields in the record to satisfy the
** request. In this case, set the value NULL or to P4 if P4 is
** a pointer to a Mem object.
*/
- if( u.ao.aOffset[u.ao.p2] ){
+ if( u.ap.aOffset[u.ap.p2] ){
assert( rc==SQLITE_OK );
- if( u.ao.zRec ){
+ if( u.ap.zRec ){
/* This is the common case where the whole row fits on a single page */
- VdbeMemRelease(u.ao.pDest);
- sqlite3VdbeSerialGet((u8 *)&u.ao.zRec[u.ao.aOffset[u.ao.p2]], u.ao.aType[u.ao.p2], u.ao.pDest);
+ VdbeMemRelease(u.ap.pDest);
+ sqlite3VdbeSerialGet((u8 *)&u.ap.zRec[u.ap.aOffset[u.ap.p2]], u.ap.aType[u.ap.p2], u.ap.pDest);
}else{
/* This branch happens only when the row overflows onto multiple pages */
- u.ao.t = u.ao.aType[u.ao.p2];
+ u.ap.t = u.ap.aType[u.ap.p2];
if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
- && ((u.ao.t>=12 && (u.ao.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
+ && ((u.ap.t>=12 && (u.ap.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
){
/* Content is irrelevant for the typeof() function and for
** the length(X) function if X is a blob. So we might as well use
** bogus content rather than reading content from disk. NULL works
- ** for text and blob and whatever is in the u.ao.payloadSize64 variable
+ ** for text and blob and whatever is in the u.ap.payloadSize64 variable
** will work for everything else. */
- u.ao.zData = u.ao.t<12 ? (char*)&u.ao.payloadSize64 : 0;
+ u.ap.zData = u.ap.t<12 ? (char*)&u.ap.payloadSize64 : 0;
}else{
- u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.t);
- sqlite3VdbeMemMove(&u.ao.sMem, u.ao.pDest);
- rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, u.ao.aOffset[u.ao.p2], u.ao.len, u.ao.pC->isIndex,
- &u.ao.sMem);
+ u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.t);
+ sqlite3VdbeMemMove(&u.ap.sMem, u.ap.pDest);
+ rc = sqlite3VdbeMemFromBtree(u.ap.pCrsr, u.ap.aOffset[u.ap.p2], u.ap.len, u.ap.pC->isIndex,
+ &u.ap.sMem);
if( rc!=SQLITE_OK ){
goto op_column_out;
}
- u.ao.zData = u.ao.sMem.z;
+ u.ap.zData = u.ap.sMem.z;
}
- sqlite3VdbeSerialGet((u8*)u.ao.zData, u.ao.t, u.ao.pDest);
+ sqlite3VdbeSerialGet((u8*)u.ap.zData, u.ap.t, u.ap.pDest);
}
- u.ao.pDest->enc = encoding;
+ u.ap.pDest->enc = encoding;
}else{
if( pOp->p4type==P4_MEM ){
- sqlite3VdbeMemShallowCopy(u.ao.pDest, pOp->p4.pMem, MEM_Static);
+ sqlite3VdbeMemShallowCopy(u.ap.pDest, pOp->p4.pMem, MEM_Static);
}else{
- MemSetTypeFlag(u.ao.pDest, MEM_Null);
+ MemSetTypeFlag(u.ap.pDest, MEM_Null);
}
}
/* If we dynamically allocated space to hold the data (in the
** sqlite3VdbeMemFromBtree() call above) then transfer control of that
- ** dynamically allocated space over to the u.ao.pDest structure.
+ ** dynamically allocated space over to the u.ap.pDest structure.
** This prevents a memory copy.
*/
- if( u.ao.sMem.zMalloc ){
- assert( u.ao.sMem.z==u.ao.sMem.zMalloc );
- assert( !(u.ao.pDest->flags & MEM_Dyn) );
- assert( !(u.ao.pDest->flags & (MEM_Blob|MEM_Str)) || u.ao.pDest->z==u.ao.sMem.z );
- u.ao.pDest->flags &= ~(MEM_Ephem|MEM_Static);
- u.ao.pDest->flags |= MEM_Term;
- u.ao.pDest->z = u.ao.sMem.z;
- u.ao.pDest->zMalloc = u.ao.sMem.zMalloc;
+ if( u.ap.sMem.zMalloc ){
+ assert( u.ap.sMem.z==u.ap.sMem.zMalloc );
+ assert( !(u.ap.pDest->flags & MEM_Dyn) );
+ assert( !(u.ap.pDest->flags & (MEM_Blob|MEM_Str)) || u.ap.pDest->z==u.ap.sMem.z );
+ u.ap.pDest->flags &= ~(MEM_Ephem|MEM_Static);
+ u.ap.pDest->flags |= MEM_Term;
+ u.ap.pDest->z = u.ap.sMem.z;
+ u.ap.pDest->zMalloc = u.ap.sMem.zMalloc;
}
- rc = sqlite3VdbeMemMakeWriteable(u.ao.pDest);
+ rc = sqlite3VdbeMemMakeWriteable(u.ap.pDest);
op_column_out:
- UPDATE_MAX_BLOBSIZE(u.ao.pDest);
- REGISTER_TRACE(pOp->p3, u.ao.pDest);
+ UPDATE_MAX_BLOBSIZE(u.ap.pDest);
+ REGISTER_TRACE(pOp->p3, u.ap.pDest);
break;
}
/* Opcode: Affinity P1 P2 * P4 *
+** Synopsis: affinity(r[P1@P2])
**
** Apply affinities to a range of P2 registers starting with P1.
**
** P4 is a string that is P2 characters long. The nth character of the
** string indicates the column affinity that should be used for the nth
** memory cell in the range.
*/
case OP_Affinity: {
-#if 0 /* local variables moved into u.ap */
+#if 0 /* local variables moved into u.aq */
const char *zAffinity; /* The affinity to be applied */
char cAff; /* A single character of affinity */
-#endif /* local variables moved into u.ap */
+#endif /* local variables moved into u.aq */
- u.ap.zAffinity = pOp->p4.z;
- assert( u.ap.zAffinity!=0 );
- assert( u.ap.zAffinity[pOp->p2]==0 );
+ u.aq.zAffinity = pOp->p4.z;
+ assert( u.aq.zAffinity!=0 );
+ assert( u.aq.zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
- while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){
+ while( (u.aq.cAff = *(u.aq.zAffinity++))!=0 ){
assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
ExpandBlob(pIn1);
- applyAffinity(pIn1, u.ap.cAff, encoding);
+ applyAffinity(pIn1, u.aq.cAff, encoding);
pIn1++;
}
break;
}
/* Opcode: MakeRecord P1 P2 P3 P4 *
+** Synopsis: r[P3]=mkrec(r[P1@P2])
**
** Convert P2 registers beginning with P1 into the [record format]
** use as a data record in a database table or as a key
** in an index. The OP_Column opcode can decode the record later.
**
@@ -68683,11 +69067,11 @@
** macros defined in sqliteInt.h.
**
** If P4 is NULL then all index fields have the affinity NONE.
*/
case OP_MakeRecord: {
-#if 0 /* local variables moved into u.aq */
+#if 0 /* local variables moved into u.ar */
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
int nHdr; /* Number of bytes of header space */
i64 nByte; /* Data space required for this record */
@@ -68699,11 +69083,11 @@
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
int i; /* Space used in zNewRecord[] */
int len; /* Length of a field */
-#endif /* local variables moved into u.aq */
+#endif /* local variables moved into u.ar */
/* Assuming the record contains N fields, the record format looks
** like this:
**
** ------------------------------------------------------------------------
@@ -68716,114 +69100,112 @@
** Each type field is a varint representing the serial type of the
** corresponding data element (see sqlite3VdbeSerialType()). The
** hdr-size field is also a varint which is the offset from the beginning
** of the record to data0.
*/
- u.aq.nData = 0; /* Number of bytes of data space */
- u.aq.nHdr = 0; /* Number of bytes of header space */
- u.aq.nZero = 0; /* Number of zero bytes at the end of the record */
- u.aq.nField = pOp->p1;
- u.aq.zAffinity = pOp->p4.z;
- assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=(p->nMem-p->nCursor)+1 );
- u.aq.pData0 = &aMem[u.aq.nField];
- u.aq.nField = pOp->p2;
- u.aq.pLast = &u.aq.pData0[u.aq.nField-1];
- u.aq.file_format = p->minWriteFileFormat;
+ u.ar.nData = 0; /* Number of bytes of data space */
+ u.ar.nHdr = 0; /* Number of bytes of header space */
+ u.ar.nZero = 0; /* Number of zero bytes at the end of the record */
+ u.ar.nField = pOp->p1;
+ u.ar.zAffinity = pOp->p4.z;
+ assert( u.ar.nField>0 && pOp->p2>0 && pOp->p2+u.ar.nField<=(p->nMem-p->nCursor)+1 );
+ u.ar.pData0 = &aMem[u.ar.nField];
+ u.ar.nField = pOp->p2;
+ u.ar.pLast = &u.ar.pData0[u.ar.nField-1];
+ u.ar.file_format = p->minWriteFileFormat;
/* Identify the output register */
assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 );
pOut = &aMem[pOp->p3];
memAboutToChange(p, pOut);
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record.
*/
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
- assert( memIsValid(u.aq.pRec) );
- if( u.aq.zAffinity ){
- applyAffinity(u.aq.pRec, u.aq.zAffinity[u.aq.pRec-u.aq.pData0], encoding);
- }
- if( u.aq.pRec->flags&MEM_Zero && u.aq.pRec->n>0 ){
- sqlite3VdbeMemExpandBlob(u.aq.pRec);
- }
- u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
- u.aq.len = sqlite3VdbeSerialTypeLen(u.aq.serial_type);
- u.aq.nData += u.aq.len;
- u.aq.nHdr += sqlite3VarintLen(u.aq.serial_type);
- if( u.aq.pRec->flags & MEM_Zero ){
+ for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){
+ assert( memIsValid(u.ar.pRec) );
+ if( u.ar.zAffinity ){
+ applyAffinity(u.ar.pRec, u.ar.zAffinity[u.ar.pRec-u.ar.pData0], encoding);
+ }
+ if( u.ar.pRec->flags&MEM_Zero && u.ar.pRec->n>0 ){
+ sqlite3VdbeMemExpandBlob(u.ar.pRec);
+ }
+ u.ar.serial_type = sqlite3VdbeSerialType(u.ar.pRec, u.ar.file_format);
+ u.ar.len = sqlite3VdbeSerialTypeLen(u.ar.serial_type);
+ u.ar.nData += u.ar.len;
+ u.ar.nHdr += sqlite3VarintLen(u.ar.serial_type);
+ if( u.ar.pRec->flags & MEM_Zero ){
/* Only pure zero-filled BLOBs can be input to this Opcode.
** We do not allow blobs with a prefix and a zero-filled tail. */
- u.aq.nZero += u.aq.pRec->u.nZero;
- }else if( u.aq.len ){
- u.aq.nZero = 0;
+ u.ar.nZero += u.ar.pRec->u.nZero;
+ }else if( u.ar.len ){
+ u.ar.nZero = 0;
}
}
/* Add the initial header varint and total the size */
- u.aq.nHdr += u.aq.nVarint = sqlite3VarintLen(u.aq.nHdr);
- if( u.aq.nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){
+ u.ar.nByte = u.ar.nHdr+u.ar.nData-u.ar.nZero;
+ if( u.ar.nByte>db->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
** sqlite3VdbeMemGrow() could clobber the value before it is used).
*/
- if( sqlite3VdbeMemGrow(pOut, (int)u.aq.nByte, 0) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)u.ar.nByte, 0) ){
goto no_mem;
}
- u.aq.zNewRecord = (u8 *)pOut->z;
+ u.ar.zNewRecord = (u8 *)pOut->z;
/* Write the record */
- u.aq.i = putVarint32(u.aq.zNewRecord, u.aq.nHdr);
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
- u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
- u.aq.i += putVarint32(&u.aq.zNewRecord[u.aq.i], u.aq.serial_type); /* serial type */
- }
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */
- u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format);
- }
- assert( u.aq.i==u.aq.nByte );
+ u.ar.i = putVarint32(u.ar.zNewRecord, u.ar.nHdr);
+ for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){
+ u.ar.serial_type = sqlite3VdbeSerialType(u.ar.pRec, u.ar.file_format);
+ u.ar.i += putVarint32(&u.ar.zNewRecord[u.ar.i], u.ar.serial_type); /* serial type */
+ }
+ for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){ /* serial data */
+ u.ar.i += sqlite3VdbeSerialPut(&u.ar.zNewRecord[u.ar.i], (int)(u.ar.nByte-u.ar.i), u.ar.pRec,u.ar.file_format);
+ }
+ assert( u.ar.i==u.ar.nByte );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- pOut->n = (int)u.aq.nByte;
+ pOut->n = (int)u.ar.nByte;
pOut->flags = MEM_Blob | MEM_Dyn;
pOut->xDel = 0;
- if( u.aq.nZero ){
- pOut->u.nZero = u.aq.nZero;
+ if( u.ar.nZero ){
+ pOut->u.nZero = u.ar.nZero;
pOut->flags |= MEM_Zero;
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
REGISTER_TRACE(pOp->p3, pOut);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Count P1 P2 * * *
+** Synopsis: r[P2]=count()
**
** Store the number of entries (an integer value) in the table or index
** opened by cursor P1 in register P2
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ar */
+#if 0 /* local variables moved into u.as */
i64 nEntry;
BtCursor *pCrsr;
-#endif /* local variables moved into u.ar */
-
- u.ar.pCrsr = p->apCsr[pOp->p1]->pCursor;
- if( ALWAYS(u.ar.pCrsr) ){
- rc = sqlite3BtreeCount(u.ar.pCrsr, &u.ar.nEntry);
- }else{
- u.ar.nEntry = 0;
- }
- pOut->u.i = u.ar.nEntry;
+#endif /* local variables moved into u.as */
+
+ u.as.pCrsr = p->apCsr[pOp->p1]->pCursor;
+ assert( u.as.pCrsr );
+ rc = sqlite3BtreeCount(u.as.pCrsr, &u.as.nEntry);
+ pOut->u.i = u.as.nEntry;
break;
}
#endif
/* Opcode: Savepoint P1 * * P4 *
@@ -68831,43 +69213,43 @@
** 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.
*/
case OP_Savepoint: {
-#if 0 /* local variables moved into u.as */
+#if 0 /* local variables moved into u.at */
int p1; /* Value of P1 operand */
char *zName; /* Name of savepoint */
int nName;
Savepoint *pNew;
Savepoint *pSavepoint;
Savepoint *pTmp;
int iSavepoint;
int ii;
-#endif /* local variables moved into u.as */
+#endif /* local variables moved into u.at */
- u.as.p1 = pOp->p1;
- u.as.zName = pOp->p4.z;
+ u.at.p1 = pOp->p1;
+ u.at.zName = pOp->p4.z;
- /* Assert that the u.as.p1 parameter is valid. Also that if there is no open
+ /* Assert that the u.at.p1 parameter is valid. Also that if there is no open
** transaction, then there cannot be any savepoints.
*/
assert( db->pSavepoint==0 || db->autoCommit==0 );
- assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK );
+ assert( u.at.p1==SAVEPOINT_BEGIN||u.at.p1==SAVEPOINT_RELEASE||u.at.p1==SAVEPOINT_ROLLBACK );
assert( db->pSavepoint || db->isTransactionSavepoint==0 );
assert( checkSavepointCount(db) );
assert( p->bIsReader );
- if( u.as.p1==SAVEPOINT_BEGIN ){
+ if( u.at.p1==SAVEPOINT_BEGIN ){
if( db->nVdbeWrite>0 ){
/* A new savepoint cannot be created if there are active write
** statements (i.e. open read/write incremental blob handles).
*/
sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else{
- u.as.nName = sqlite3Strlen30(u.as.zName);
+ u.at.nName = sqlite3Strlen30(u.at.zName);
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* This call is Ok even if this savepoint is actually a transaction
** savepoint (and therefore should not prompt xSavepoint()) callbacks.
** If this is a transaction savepoint being opened, it is guaranteed
@@ -68877,14 +69259,14 @@
db->nStatement+db->nSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
#endif
/* Create a new savepoint structure. */
- u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1);
- if( u.as.pNew ){
- u.as.pNew->zName = (char *)&u.as.pNew[1];
- memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1);
+ u.at.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.at.nName+1);
+ if( u.at.pNew ){
+ u.at.pNew->zName = (char *)&u.at.pNew[1];
+ memcpy(u.at.pNew->zName, u.at.zName, u.at.nName+1);
/* If there is no open transaction, then mark this as a special
** "transaction savepoint". */
if( db->autoCommit ){
db->autoCommit = 0;
@@ -68892,32 +69274,32 @@
}else{
db->nSavepoint++;
}
/* Link the new savepoint into the database handle's list. */
- u.as.pNew->pNext = db->pSavepoint;
- db->pSavepoint = u.as.pNew;
- u.as.pNew->nDeferredCons = db->nDeferredCons;
- u.as.pNew->nDeferredImmCons = db->nDeferredImmCons;
+ u.at.pNew->pNext = db->pSavepoint;
+ db->pSavepoint = u.at.pNew;
+ u.at.pNew->nDeferredCons = db->nDeferredCons;
+ u.at.pNew->nDeferredImmCons = db->nDeferredImmCons;
}
}
}else{
- u.as.iSavepoint = 0;
+ u.at.iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
** an error is returned to the user. */
for(
- u.as.pSavepoint = db->pSavepoint;
- u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName);
- u.as.pSavepoint = u.as.pSavepoint->pNext
+ u.at.pSavepoint = db->pSavepoint;
+ u.at.pSavepoint && sqlite3StrICmp(u.at.pSavepoint->zName, u.at.zName);
+ u.at.pSavepoint = u.at.pSavepoint->pNext
){
- u.as.iSavepoint++;
+ u.at.iSavepoint++;
}
- if( !u.as.pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName);
+ if( !u.at.pSavepoint ){
+ sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.at.zName);
rc = SQLITE_ERROR;
- }else if( db->nVdbeWrite>0 && u.as.p1==SAVEPOINT_RELEASE ){
+ }else if( db->nVdbeWrite>0 && u.at.p1==SAVEPOINT_RELEASE ){
/* It is not possible to release (commit) a savepoint if there are
** active write statements.
*/
sqlite3SetString(&p->zErrMsg, db,
"cannot release savepoint - SQL statements in progress"
@@ -68927,12 +69309,12 @@
/* Determine whether or not this is a transaction savepoint. If so,
** and this is a RELEASE command, then the current transaction
** is committed.
*/
- int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint;
- if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){
+ int isTransaction = u.at.pSavepoint->pNext==0 && db->isTransactionSavepoint;
+ if( isTransaction && u.at.p1==SAVEPOINT_RELEASE ){
if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
@@ -68942,56 +69324,56 @@
goto vdbe_return;
}
db->isTransactionSavepoint = 0;
rc = p->rc;
}else{
- u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1;
- if( u.as.p1==SAVEPOINT_ROLLBACK ){
- for(u.as.ii=0; u.as.iinDb; u.as.ii++){
- sqlite3BtreeTripAllCursors(db->aDb[u.as.ii].pBt, SQLITE_ABORT);
+ u.at.iSavepoint = db->nSavepoint - u.at.iSavepoint - 1;
+ if( u.at.p1==SAVEPOINT_ROLLBACK ){
+ for(u.at.ii=0; u.at.iinDb; u.at.ii++){
+ sqlite3BtreeTripAllCursors(db->aDb[u.at.ii].pBt, SQLITE_ABORT);
}
}
- for(u.as.ii=0; u.as.iinDb; u.as.ii++){
- rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint);
+ for(u.at.ii=0; u.at.iinDb; u.at.ii++){
+ rc = sqlite3BtreeSavepoint(db->aDb[u.at.ii].pBt, u.at.p1, u.at.iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
- if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
+ if( u.at.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
db->flags = (db->flags | SQLITE_InternChanges);
}
}
/* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
** savepoints nested inside of the savepoint being operated on. */
- while( db->pSavepoint!=u.as.pSavepoint ){
- u.as.pTmp = db->pSavepoint;
- db->pSavepoint = u.as.pTmp->pNext;
- sqlite3DbFree(db, u.as.pTmp);
+ while( db->pSavepoint!=u.at.pSavepoint ){
+ u.at.pTmp = db->pSavepoint;
+ db->pSavepoint = u.at.pTmp->pNext;
+ sqlite3DbFree(db, u.at.pTmp);
db->nSavepoint--;
}
/* If it is a RELEASE, then destroy the savepoint being operated on
** too. If it is a ROLLBACK TO, then set the number of deferred
** constraint violations present in the database to the value stored
** when the savepoint was created. */
- if( u.as.p1==SAVEPOINT_RELEASE ){
- assert( u.as.pSavepoint==db->pSavepoint );
- db->pSavepoint = u.as.pSavepoint->pNext;
- sqlite3DbFree(db, u.as.pSavepoint);
+ if( u.at.p1==SAVEPOINT_RELEASE ){
+ assert( u.at.pSavepoint==db->pSavepoint );
+ db->pSavepoint = u.at.pSavepoint->pNext;
+ sqlite3DbFree(db, u.at.pSavepoint);
if( !isTransaction ){
db->nSavepoint--;
}
}else{
- db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
- db->nDeferredImmCons = u.as.pSavepoint->nDeferredImmCons;
+ db->nDeferredCons = u.at.pSavepoint->nDeferredCons;
+ db->nDeferredImmCons = u.at.pSavepoint->nDeferredImmCons;
}
if( !isTransaction ){
- rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
+ rc = sqlite3VtabSavepoint(db, u.at.p1, u.at.iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}
}
@@ -69006,54 +69388,54 @@
** there are active writing VMs or active VMs that use shared cache.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
-#if 0 /* local variables moved into u.at */
+#if 0 /* local variables moved into u.au */
int desiredAutoCommit;
int iRollback;
int turnOnAC;
-#endif /* local variables moved into u.at */
+#endif /* local variables moved into u.au */
- u.at.desiredAutoCommit = pOp->p1;
- u.at.iRollback = pOp->p2;
- u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit;
- assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 );
- assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 );
+ u.au.desiredAutoCommit = pOp->p1;
+ u.au.iRollback = pOp->p2;
+ u.au.turnOnAC = u.au.desiredAutoCommit && !db->autoCommit;
+ assert( u.au.desiredAutoCommit==1 || u.au.desiredAutoCommit==0 );
+ assert( u.au.desiredAutoCommit==1 || u.au.iRollback==0 );
assert( db->nVdbeActive>0 ); /* At least this one VM is active */
assert( p->bIsReader );
#if 0
- if( u.at.turnOnAC && u.at.iRollback && db->nVdbeActive>1 ){
+ if( u.au.turnOnAC && u.au.iRollback && db->nVdbeActive>1 ){
/* If this instruction implements a ROLLBACK and other VMs are
** still running, and a transaction is active, return an error indicating
** that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else
#endif
- if( u.at.turnOnAC && !u.at.iRollback && db->nVdbeWrite>0 ){
+ if( u.au.turnOnAC && !u.au.iRollback && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing
** return an error indicating that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
- }else if( u.at.desiredAutoCommit!=db->autoCommit ){
- if( u.at.iRollback ){
- assert( u.at.desiredAutoCommit==1 );
+ }else if( u.au.desiredAutoCommit!=db->autoCommit ){
+ if( u.au.iRollback ){
+ assert( u.au.desiredAutoCommit==1 );
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
db->autoCommit = 1;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
- db->autoCommit = (u8)u.at.desiredAutoCommit;
+ db->autoCommit = (u8)u.au.desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc;
- db->autoCommit = (u8)(1-u.at.desiredAutoCommit);
+ db->autoCommit = (u8)(1-u.au.desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
}
assert( db->nStatement==0 );
@@ -69064,12 +69446,12 @@
rc = SQLITE_ERROR;
}
goto vdbe_return;
}else{
sqlite3SetString(&p->zErrMsg, db,
- (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":(
- (u.at.iRollback)?"cannot rollback - no transaction is active":
+ (!u.au.desiredAutoCommit)?"cannot start a transaction within a transaction":(
+ (u.au.iRollback)?"cannot rollback - no transaction is active":
"cannot commit - no transaction is active"));
rc = SQLITE_ERROR;
}
break;
@@ -69105,26 +69487,26 @@
** will automatically commit when the VDBE halts.
**
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
-#if 0 /* local variables moved into u.au */
+#if 0 /* local variables moved into u.av */
Btree *pBt;
-#endif /* local variables moved into u.au */
+#endif /* local variables moved into u.av */
assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p1>=0 && pOp->p1nDb );
assert( (p->btreeMask & (((yDbMask)1)<p1))!=0 );
if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
rc = SQLITE_READONLY;
goto abort_due_to_error;
}
- u.au.pBt = db->aDb[pOp->p1].pBt;
+ u.av.pBt = db->aDb[pOp->p1].pBt;
- if( u.au.pBt ){
- rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
+ if( u.av.pBt ){
+ rc = sqlite3BtreeBeginTrans(u.av.pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
p->pc = pc;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
@@ -69133,20 +69515,20 @@
}
if( pOp->p2 && p->usesStmtJournal
&& (db->autoCommit==0 || db->nVdbeRead>1)
){
- assert( sqlite3BtreeIsInTrans(u.au.pBt) );
+ assert( sqlite3BtreeIsInTrans(u.av.pBt) );
if( p->iStatement==0 ){
assert( db->nStatement>=0 && db->nSavepoint>=0 );
db->nStatement++;
p->iStatement = db->nSavepoint + db->nStatement;
}
rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginStmt(u.au.pBt, p->iStatement);
+ rc = sqlite3BtreeBeginStmt(u.av.pBt, p->iStatement);
}
/* Store the current value of the database handles deferred constraint
** counter. If the statement transaction needs to be rolled back,
** the value of this counter needs to be restored too. */
@@ -69168,26 +69550,26 @@
** There must be a read-lock on the database (either a transaction
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: { /* out2-prerelease */
-#if 0 /* local variables moved into u.av */
+#if 0 /* local variables moved into u.aw */
int iMeta;
int iDb;
int iCookie;
-#endif /* local variables moved into u.av */
+#endif /* local variables moved into u.aw */
assert( p->bIsReader );
- u.av.iDb = pOp->p1;
- u.av.iCookie = pOp->p3;
+ u.aw.iDb = pOp->p1;
+ u.aw.iCookie = pOp->p3;
assert( pOp->p3=0 && u.av.iDbnDb );
- assert( db->aDb[u.av.iDb].pBt!=0 );
- assert( (p->btreeMask & (((yDbMask)1)<=0 && u.aw.iDbnDb );
+ assert( db->aDb[u.aw.iDb].pBt!=0 );
+ assert( (p->btreeMask & (((yDbMask)1)<aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta);
- pOut->u.i = u.av.iMeta;
+ sqlite3BtreeGetMeta(db->aDb[u.aw.iDb].pBt, u.aw.iCookie, (u32 *)&u.aw.iMeta);
+ pOut->u.i = u.aw.iMeta;
break;
}
/* Opcode: SetCookie P1 P2 P3 * *
**
@@ -69198,31 +69580,31 @@
** database file used to store temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: { /* in3 */
-#if 0 /* local variables moved into u.aw */
+#if 0 /* local variables moved into u.ax */
Db *pDb;
-#endif /* local variables moved into u.aw */
+#endif /* local variables moved into u.ax */
assert( pOp->p2p1>=0 && pOp->p1nDb );
assert( (p->btreeMask & (((yDbMask)1)<p1))!=0 );
assert( p->readOnly==0 );
- u.aw.pDb = &db->aDb[pOp->p1];
- assert( u.aw.pDb->pBt!=0 );
+ u.ax.pDb = &db->aDb[pOp->p1];
+ assert( u.ax.pDb->pBt!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
pIn3 = &aMem[pOp->p3];
sqlite3VdbeMemIntegerify(pIn3);
/* See note about index shifting on OP_ReadCookie */
- rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i);
+ rc = sqlite3BtreeUpdateMeta(u.ax.pDb->pBt, pOp->p2, (int)pIn3->u.i);
if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
- u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
+ u.ax.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
db->flags |= SQLITE_InternChanges;
}else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
- u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i;
+ u.ax.pDb->pSchema->file_format = (u8)pIn3->u.i;
}
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
** schema is changed. Ticket #1644 */
sqlite3ExpirePreparedStatements(db);
@@ -69248,28 +69630,28 @@
** Either a transaction needs to have been started or an OP_Open needs
** to be executed (to establish a read lock) before this opcode is
** invoked.
*/
case OP_VerifyCookie: {
-#if 0 /* local variables moved into u.ax */
+#if 0 /* local variables moved into u.ay */
int iMeta;
int iGen;
Btree *pBt;
-#endif /* local variables moved into u.ax */
+#endif /* local variables moved into u.ay */
assert( pOp->p1>=0 && pOp->p1nDb );
assert( (p->btreeMask & (((yDbMask)1)<p1))!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
assert( p->bIsReader );
- u.ax.pBt = db->aDb[pOp->p1].pBt;
- if( u.ax.pBt ){
- sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta);
- u.ax.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
+ u.ay.pBt = db->aDb[pOp->p1].pBt;
+ if( u.ay.pBt ){
+ sqlite3BtreeGetMeta(u.ay.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ay.iMeta);
+ u.ay.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
}else{
- u.ax.iGen = u.ax.iMeta = 0;
+ u.ay.iGen = u.ay.iMeta = 0;
}
- if( u.ax.iMeta!=pOp->p2 || u.ax.iGen!=pOp->p3 ){
+ if( u.ay.iMeta!=pOp->p2 || u.ay.iGen!=pOp->p3 ){
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
/* If the schema-cookie from the database file matches the cookie
** stored with the in-memory representation of the schema, do
** not reload the schema from the database file.
@@ -69281,11 +69663,11 @@
** discard the database schema, as the user code implementing the
** v-table would have to be ready for the sqlite3_vtab structure itself
** to be invalidated whenever sqlite3_step() is called from within
** a v-table method.
*/
- if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){
+ if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ay.iMeta ){
sqlite3ResetOneSchema(db, pOp->p1);
}
p->expired = 1;
rc = SQLITE_SCHEMA;
@@ -69292,10 +69674,11 @@
}
break;
}
/* Opcode: OpenRead P1 P2 P3 P4 P5
+** Synopsis: root=P2 iDb=P3
**
** Open a read-only cursor for the database table whose root page is
** P2 in a database file. The database file is determined by P3.
** P3==0 means the main database, P3==1 means the database used for
** temporary tables, and P3>1 means used the corresponding attached
@@ -69322,10 +69705,11 @@
** value, it is set to the number of columns in the table.
**
** See also OpenWrite.
*/
/* Opcode: OpenWrite P1 P2 P3 P4 P5
+** Synopsis: root=P2 iDb=P3
**
** Open a read/write cursor named P1 on the table or index whose root
** page is P2. Or if P5!=0 use the content of register P2 to find the
** root page.
**
@@ -69342,20 +69726,20 @@
**
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {
-#if 0 /* local variables moved into u.ay */
+#if 0 /* local variables moved into u.az */
int nField;
KeyInfo *pKeyInfo;
int p2;
int iDb;
int wrFlag;
Btree *pX;
VdbeCursor *pCur;
Db *pDb;
-#endif /* local variables moved into u.ay */
+#endif /* local variables moved into u.az */
assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
assert( p->bIsReader );
assert( pOp->opcode==OP_OpenRead || p->readOnly==0 );
@@ -69363,76 +69747,78 @@
if( p->expired ){
rc = SQLITE_ABORT;
break;
}
- u.ay.nField = 0;
- u.ay.pKeyInfo = 0;
- u.ay.p2 = pOp->p2;
- u.ay.iDb = pOp->p3;
- assert( u.ay.iDb>=0 && u.ay.iDbnDb );
- assert( (p->btreeMask & (((yDbMask)1)<aDb[u.ay.iDb];
- u.ay.pX = u.ay.pDb->pBt;
- assert( u.ay.pX!=0 );
+ u.az.nField = 0;
+ u.az.pKeyInfo = 0;
+ u.az.p2 = pOp->p2;
+ u.az.iDb = pOp->p3;
+ assert( u.az.iDb>=0 && u.az.iDbnDb );
+ assert( (p->btreeMask & (((yDbMask)1)<aDb[u.az.iDb];
+ u.az.pX = u.az.pDb->pBt;
+ assert( u.az.pX!=0 );
if( pOp->opcode==OP_OpenWrite ){
- u.ay.wrFlag = 1;
- assert( sqlite3SchemaMutexHeld(db, u.ay.iDb, 0) );
- if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){
- p->minWriteFileFormat = u.ay.pDb->pSchema->file_format;
+ u.az.wrFlag = 1;
+ assert( sqlite3SchemaMutexHeld(db, u.az.iDb, 0) );
+ if( u.az.pDb->pSchema->file_format < p->minWriteFileFormat ){
+ p->minWriteFileFormat = u.az.pDb->pSchema->file_format;
}
}else{
- u.ay.wrFlag = 0;
+ u.az.wrFlag = 0;
}
if( pOp->p5 & OPFLAG_P2ISREG ){
- assert( u.ay.p2>0 );
- assert( u.ay.p2<=(p->nMem-p->nCursor) );
- pIn2 = &aMem[u.ay.p2];
+ assert( u.az.p2>0 );
+ assert( u.az.p2<=(p->nMem-p->nCursor) );
+ pIn2 = &aMem[u.az.p2];
assert( memIsValid(pIn2) );
assert( (pIn2->flags & MEM_Int)!=0 );
sqlite3VdbeMemIntegerify(pIn2);
- u.ay.p2 = (int)pIn2->u.i;
- /* The u.ay.p2 value always comes from a prior OP_CreateTable opcode and
- ** that opcode will always set the u.ay.p2 value to 2 or more or else fail.
+ u.az.p2 = (int)pIn2->u.i;
+ /* The u.az.p2 value always comes from a prior OP_CreateTable opcode and
+ ** that opcode will always set the u.az.p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
- if( NEVER(u.ay.p2<2) ) {
+ if( NEVER(u.az.p2<2) ) {
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
}
if( pOp->p4type==P4_KEYINFO ){
- u.ay.pKeyInfo = pOp->p4.pKeyInfo;
- u.ay.pKeyInfo->enc = ENC(p->db);
- u.ay.nField = u.ay.pKeyInfo->nField+1;
+ u.az.pKeyInfo = pOp->p4.pKeyInfo;
+ assert( u.az.pKeyInfo->enc==ENC(db) );
+ assert( u.az.pKeyInfo->db==db );
+ u.az.nField = u.az.pKeyInfo->nField+u.az.pKeyInfo->nXField;
}else if( pOp->p4type==P4_INT32 ){
- u.ay.nField = pOp->p4.i;
+ u.az.nField = pOp->p4.i;
}
assert( pOp->p1>=0 );
- u.ay.pCur = allocateCursor(p, pOp->p1, u.ay.nField, u.ay.iDb, 1);
- if( u.ay.pCur==0 ) goto no_mem;
- u.ay.pCur->nullRow = 1;
- u.ay.pCur->isOrdered = 1;
- rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor);
- u.ay.pCur->pKeyInfo = u.ay.pKeyInfo;
+ u.az.pCur = allocateCursor(p, pOp->p1, u.az.nField, u.az.iDb, 1);
+ if( u.az.pCur==0 ) goto no_mem;
+ u.az.pCur->nullRow = 1;
+ u.az.pCur->isOrdered = 1;
+ rc = sqlite3BtreeCursor(u.az.pX, u.az.p2, u.az.wrFlag, u.az.pKeyInfo, u.az.pCur->pCursor);
+ u.az.pCur->pKeyInfo = u.az.pKeyInfo;
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
- sqlite3BtreeCursorHints(u.ay.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
+ sqlite3BtreeCursorHints(u.az.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
/* Since it performs no memory allocation or IO, the only value that
** sqlite3BtreeCursor() may return is SQLITE_OK. */
assert( rc==SQLITE_OK );
/* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
** SQLite used to check if the root-page flags were sane at this point
** and report database corruption if they were not, but this check has
** since moved into the btree layer. */
- u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO;
- u.ay.pCur->isIndex = !u.ay.pCur->isTable;
+ u.az.pCur->isTable = pOp->p4type!=P4_KEYINFO;
+ u.az.pCur->isIndex = !u.az.pCur->isTable;
break;
}
/* Opcode: OpenEphemeral P1 P2 * P4 P5
+** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if
** the main database is read-only. The ephemeral
** table is deleted automatically when the cursor is closed.
@@ -69440,98 +69826,96 @@
** 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
** that defines the format of keys in the index.
**
-** This opcode was once called OpenTemp. But that created
-** confusion because the term "temp table", might refer either
-** to a TEMP table at the SQL level, or to a table opened by
-** this opcode. Then this opcode was call OpenVirtual. But
-** that created confusion with the whole virtual-table idea.
-**
** The P5 parameter can be a mask of the BTREE_* flags defined
** in btree.h. These flags control aspects of the operation of
** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are
** added automatically.
*/
/* Opcode: OpenAutoindex P1 P2 * P4 *
+** Synopsis: nColumn=P2
**
** This opcode works the same as OP_OpenEphemeral. It has a
** different name to distinguish its use. Tables created using
** by this opcode will be used for automatically created transient
** indices in joins.
*/
case OP_OpenAutoindex:
case OP_OpenEphemeral: {
-#if 0 /* local variables moved into u.az */
+#if 0 /* local variables moved into u.ba */
VdbeCursor *pCx;
-#endif /* local variables moved into u.az */
+ KeyInfo *pKeyInfo;
+#endif /* local variables moved into u.ba */
+
static const int vfsFlags =
SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE |
SQLITE_OPEN_EXCLUSIVE |
SQLITE_OPEN_DELETEONCLOSE |
SQLITE_OPEN_TRANSIENT_DB;
-
assert( pOp->p1>=0 );
- u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.az.pCx==0 ) goto no_mem;
- u.az.pCx->nullRow = 1;
- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.az.pCx->pBt,
+ u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
+ if( u.ba.pCx==0 ) goto no_mem;
+ u.ba.pCx->nullRow = 1;
+ rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ba.pCx->pBt,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1);
+ rc = sqlite3BtreeBeginTrans(u.ba.pCx->pBt, 1);
}
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( pOp->p4.pKeyInfo ){
+ if( (u.ba.pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
+ rc = sqlite3BtreeCreateTable(u.ba.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
if( rc==SQLITE_OK ){
assert( pgno==MASTER_ROOT+1 );
- rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1,
- (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor);
- u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo;
- u.az.pCx->pKeyInfo->enc = ENC(p->db);
- }
- u.az.pCx->isTable = 0;
- }else{
- rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor);
- u.az.pCx->isTable = 1;
+ assert( u.ba.pKeyInfo->db==db );
+ assert( u.ba.pKeyInfo->enc==ENC(db) );
+ u.ba.pCx->pKeyInfo = u.ba.pKeyInfo;
+ rc = sqlite3BtreeCursor(u.ba.pCx->pBt, pgno, 1, u.ba.pKeyInfo, u.ba.pCx->pCursor);
+ }
+ u.ba.pCx->isTable = 0;
+ }else{
+ rc = sqlite3BtreeCursor(u.ba.pCx->pBt, MASTER_ROOT, 1, 0, u.ba.pCx->pCursor);
+ u.ba.pCx->isTable = 1;
}
}
- u.az.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
- u.az.pCx->isIndex = !u.az.pCx->isTable;
+ u.ba.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
+ u.ba.pCx->isIndex = !u.ba.pCx->isTable;
break;
}
-/* Opcode: SorterOpen P1 P2 * P4 *
+/* Opcode: SorterOpen P1 * * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
*/
case OP_SorterOpen: {
-#if 0 /* local variables moved into u.ba */
+#if 0 /* local variables moved into u.bb */
VdbeCursor *pCx;
-#endif /* local variables moved into u.ba */
-
- u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.ba.pCx==0 ) goto no_mem;
- u.ba.pCx->pKeyInfo = pOp->p4.pKeyInfo;
- u.ba.pCx->pKeyInfo->enc = ENC(p->db);
- u.ba.pCx->isSorter = 1;
- rc = sqlite3VdbeSorterInit(db, u.ba.pCx);
+#endif /* local variables moved into u.bb */
+
+ u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
+ if( u.bb.pCx==0 ) goto no_mem;
+ u.bb.pCx->pKeyInfo = pOp->p4.pKeyInfo;
+ assert( u.bb.pCx->pKeyInfo->db==db );
+ assert( u.bb.pCx->pKeyInfo->enc==ENC(db) );
+ u.bb.pCx->isSorter = 1;
+ rc = sqlite3VdbeSorterInit(db, u.bb.pCx);
break;
}
/* Opcode: OpenPseudo P1 P2 P3 * P5
+** Synopsis: content in r[P2@P3]
**
** Open a new cursor that points to a fake table that contains a single
** row of data. The content of that one row in the content of memory
** register P2 when P5==0. In other words, cursor P1 becomes an alias for the
** MEM_Blob content contained in register P2. When P5==1, then the
@@ -69544,22 +69928,22 @@
**
** P3 is the number of fields in the records that will be stored by
** the pseudo-table.
*/
case OP_OpenPseudo: {
-#if 0 /* local variables moved into u.bb */
+#if 0 /* local variables moved into u.bc */
VdbeCursor *pCx;
-#endif /* local variables moved into u.bb */
+#endif /* local variables moved into u.bc */
assert( pOp->p1>=0 );
- u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
- if( u.bb.pCx==0 ) goto no_mem;
- u.bb.pCx->nullRow = 1;
- u.bb.pCx->pseudoTableReg = pOp->p2;
- u.bb.pCx->isTable = 1;
- u.bb.pCx->isIndex = 0;
- u.bb.pCx->multiPseudo = pOp->p5;
+ u.bc.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
+ if( u.bc.pCx==0 ) goto no_mem;
+ u.bc.pCx->nullRow = 1;
+ u.bc.pCx->pseudoTableReg = pOp->p2;
+ u.bc.pCx->isTable = 1;
+ u.bc.pCx->isIndex = 0;
+ u.bc.pCx->multiPseudo = pOp->p5;
break;
}
/* Opcode: Close P1 * * * *
**
@@ -69572,10 +69956,11 @@
p->apCsr[pOp->p1] = 0;
break;
}
/* Opcode: SeekGe P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as the key. If cursor P1 refers
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
@@ -69585,10 +69970,11 @@
** greater than or equal to the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe
*/
/* Opcode: SeekGt P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
@@ -69598,10 +69984,11 @@
** the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe
*/
/* Opcode: SeekLt P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
@@ -69611,10 +69998,11 @@
** the key and P2 is not zero, then jump to P2.
**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe
*/
/* Opcode: SeekLe P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
@@ -69627,200 +70015,197 @@
*/
case OP_SeekLt: /* jump, in3 */
case OP_SeekLe: /* jump, in3 */
case OP_SeekGe: /* jump, in3 */
case OP_SeekGt: { /* jump, in3 */
-#if 0 /* local variables moved into u.bc */
+#if 0 /* local variables moved into u.bd */
int res;
int oc;
VdbeCursor *pC;
UnpackedRecord r;
int nField;
i64 iKey; /* The rowid we are to seek to */
-#endif /* local variables moved into u.bc */
+#endif /* local variables moved into u.bd */
assert( pOp->p1>=0 && pOp->p1nCursor );
assert( pOp->p2!=0 );
- u.bc.pC = p->apCsr[pOp->p1];
- assert( u.bc.pC!=0 );
- assert( u.bc.pC->pseudoTableReg==0 );
+ u.bd.pC = p->apCsr[pOp->p1];
+ assert( u.bd.pC!=0 );
+ assert( u.bd.pC->pseudoTableReg==0 );
assert( OP_SeekLe == OP_SeekLt+1 );
assert( OP_SeekGe == OP_SeekLt+2 );
assert( OP_SeekGt == OP_SeekLt+3 );
- assert( u.bc.pC->isOrdered );
- if( ALWAYS(u.bc.pC->pCursor!=0) ){
- u.bc.oc = pOp->opcode;
- u.bc.pC->nullRow = 0;
- if( u.bc.pC->isTable ){
- /* The input value in P3 might be of any type: integer, real, string,
- ** blob, or NULL. But it needs to be an integer before we can do
- ** the seek, so covert it. */
- pIn3 = &aMem[pOp->p3];
- applyNumericAffinity(pIn3);
- u.bc.iKey = sqlite3VdbeIntValue(pIn3);
- u.bc.pC->rowidIsValid = 0;
-
- /* If the P3 value could not be converted into an integer without
- ** loss of information, then special processing is required... */
- if( (pIn3->flags & MEM_Int)==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 */
- pc = pOp->p2 - 1;
- break;
- }
- /* If we reach this point, then the P3 value must be a floating
- ** point number. */
- assert( (pIn3->flags & MEM_Real)!=0 );
-
- if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){
- /* The P3 value is too large in magnitude to be expressed as an
- ** integer. */
- u.bc.res = 1;
- if( pIn3->r<0 ){
- if( u.bc.oc>=OP_SeekGe ){ assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
- rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }else{
- if( u.bc.oc<=OP_SeekLe ){ assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
- rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }
- if( u.bc.res ){
- pc = pOp->p2 - 1;
- }
- break;
- }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){
- /* Use the ceiling() function to convert real->int */
- if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++;
- }else{
- /* Use the floor() function to convert real->int */
- assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt );
- if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--;
- }
- }
- rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( u.bc.res==0 ){
- u.bc.pC->rowidIsValid = 1;
- u.bc.pC->lastRowid = u.bc.iKey;
- }
- }else{
- u.bc.nField = pOp->p4.i;
- assert( pOp->p4type==P4_INT32 );
- assert( u.bc.nField>0 );
- u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo;
- u.bc.r.nField = (u16)u.bc.nField;
-
- /* The next line of code computes as follows, only faster:
- ** if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){
- ** u.bc.r.flags = UNPACKED_INCRKEY;
- ** }else{
- ** u.bc.r.flags = 0;
- ** }
- */
- u.bc.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bc.oc - OP_SeekLt)));
- assert( u.bc.oc!=OP_SeekGt || u.bc.r.flags==UNPACKED_INCRKEY );
- assert( u.bc.oc!=OP_SeekLe || u.bc.r.flags==UNPACKED_INCRKEY );
- assert( u.bc.oc!=OP_SeekGe || u.bc.r.flags==0 );
- assert( u.bc.oc!=OP_SeekLt || u.bc.r.flags==0 );
-
- u.bc.r.aMem = &aMem[pOp->p3];
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; ipCursor, &u.bc.r, 0, 0, &u.bc.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- u.bc.pC->rowidIsValid = 0;
- }
- u.bc.pC->deferredMoveto = 0;
- u.bc.pC->cacheStatus = CACHE_STALE;
-#ifdef SQLITE_TEST
- sqlite3_search_count++;
-#endif
- if( u.bc.oc>=OP_SeekGe ){ assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
- if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){
- rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.bc.pC->rowidIsValid = 0;
- }else{
- u.bc.res = 0;
- }
- }else{
- assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
- if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){
- rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.bc.pC->rowidIsValid = 0;
- }else{
- /* u.bc.res might be negative because the table is empty. Check to
- ** see if this is the case.
- */
- u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor);
- }
- }
- assert( pOp->p2>0 );
- if( u.bc.res ){
- pc = pOp->p2 - 1;
- }
- }else{
- /* This happens when attempting to open the sqlite3_master table
- ** for read access returns SQLITE_EMPTY. In this case always
- ** take the jump (since there are no records in the table).
- */
+ assert( u.bd.pC->isOrdered );
+ assert( u.bd.pC->pCursor!=0 );
+ u.bd.oc = pOp->opcode;
+ u.bd.pC->nullRow = 0;
+ if( u.bd.pC->isTable ){
+ /* The input value in P3 might be of any type: integer, real, string,
+ ** blob, or NULL. But it needs to be an integer before we can do
+ ** the seek, so covert it. */
+ pIn3 = &aMem[pOp->p3];
+ applyNumericAffinity(pIn3);
+ u.bd.iKey = sqlite3VdbeIntValue(pIn3);
+ u.bd.pC->rowidIsValid = 0;
+
+ /* 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_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 */
+ pc = pOp->p2 - 1;
+ break;
+ }
+ /* If we reach this point, then the P3 value must be a floating
+ ** point number. */
+ assert( (pIn3->flags & MEM_Real)!=0 );
+
+ if( u.bd.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bd.iKey || pIn3->r>0) ){
+ /* The P3 value is too large in magnitude to be expressed as an
+ ** integer. */
+ u.bd.res = 1;
+ if( pIn3->r<0 ){
+ if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
+ rc = sqlite3BtreeFirst(u.bd.pC->pCursor, &u.bd.res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ }
+ }else{
+ if( u.bd.oc<=OP_SeekLe ){ assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
+ rc = sqlite3BtreeLast(u.bd.pC->pCursor, &u.bd.res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ }
+ }
+ if( u.bd.res ){
+ pc = pOp->p2 - 1;
+ }
+ break;
+ }else if( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekGe ){
+ /* Use the ceiling() function to convert real->int */
+ if( pIn3->r > (double)u.bd.iKey ) u.bd.iKey++;
+ }else{
+ /* Use the floor() function to convert real->int */
+ assert( u.bd.oc==OP_SeekLe || u.bd.oc==OP_SeekGt );
+ if( pIn3->r < (double)u.bd.iKey ) u.bd.iKey--;
+ }
+ }
+ rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ if( u.bd.res==0 ){
+ u.bd.pC->rowidIsValid = 1;
+ u.bd.pC->lastRowid = u.bd.iKey;
+ }
+ }else{
+ u.bd.nField = pOp->p4.i;
+ assert( pOp->p4type==P4_INT32 );
+ assert( u.bd.nField>0 );
+ u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo;
+ u.bd.r.nField = (u16)u.bd.nField;
+
+ /* The next line of code computes as follows, only faster:
+ ** if( u.bd.oc==OP_SeekGt || u.bd.oc==OP_SeekLe ){
+ ** u.bd.r.flags = UNPACKED_INCRKEY;
+ ** }else{
+ ** u.bd.r.flags = 0;
+ ** }
+ */
+ u.bd.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bd.oc - OP_SeekLt)));
+ assert( u.bd.oc!=OP_SeekGt || u.bd.r.flags==UNPACKED_INCRKEY );
+ assert( u.bd.oc!=OP_SeekLe || u.bd.r.flags==UNPACKED_INCRKEY );
+ assert( u.bd.oc!=OP_SeekGe || u.bd.r.flags==0 );
+ assert( u.bd.oc!=OP_SeekLt || u.bd.r.flags==0 );
+
+ u.bd.r.aMem = &aMem[pOp->p3];
+#ifdef SQLITE_DEBUG
+ { int i; for(i=0; ipCursor, &u.bd.r, 0, 0, &u.bd.res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ u.bd.pC->rowidIsValid = 0;
+ }
+ u.bd.pC->deferredMoveto = 0;
+ u.bd.pC->cacheStatus = CACHE_STALE;
+#ifdef SQLITE_TEST
+ sqlite3_search_count++;
+#endif
+ if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
+ if( u.bd.res<0 || (u.bd.res==0 && u.bd.oc==OP_SeekGt) ){
+ rc = sqlite3BtreeNext(u.bd.pC->pCursor, &u.bd.res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ u.bd.pC->rowidIsValid = 0;
+ }else{
+ u.bd.res = 0;
+ }
+ }else{
+ assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
+ if( u.bd.res>0 || (u.bd.res==0 && u.bd.oc==OP_SeekLt) ){
+ rc = sqlite3BtreePrevious(u.bd.pC->pCursor, &u.bd.res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ u.bd.pC->rowidIsValid = 0;
+ }else{
+ /* u.bd.res might be negative because the table is empty. Check to
+ ** see if this is the case.
+ */
+ u.bd.res = sqlite3BtreeEof(u.bd.pC->pCursor);
+ }
+ }
+ assert( pOp->p2>0 );
+ if( u.bd.res ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: Seek P1 P2 * * *
+** Synopsis: intkey=r[P2]
**
** P1 is an open table cursor and P2 is a rowid integer. Arrange
** for P1 to move so that it points to the rowid given by P2.
**
** This is actually a deferred seek. Nothing actually happens until
** the cursor is used to read a record. That way, if no reads
** occur, no unnecessary I/O happens.
*/
case OP_Seek: { /* in2 */
-#if 0 /* local variables moved into u.bd */
+#if 0 /* local variables moved into u.be */
VdbeCursor *pC;
-#endif /* local variables moved into u.bd */
+#endif /* local variables moved into u.be */
assert( pOp->p1>=0 && pOp->p1nCursor );
- u.bd.pC = p->apCsr[pOp->p1];
- assert( u.bd.pC!=0 );
- if( ALWAYS(u.bd.pC->pCursor!=0) ){
- assert( u.bd.pC->isTable );
- u.bd.pC->nullRow = 0;
- pIn2 = &aMem[pOp->p2];
- u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
- u.bd.pC->rowidIsValid = 0;
- u.bd.pC->deferredMoveto = 1;
- }
+ u.be.pC = p->apCsr[pOp->p1];
+ assert( u.be.pC!=0 );
+ assert( u.be.pC->pCursor!=0 );
+ assert( u.be.pC->isTable );
+ u.be.pC->nullRow = 0;
+ pIn2 = &aMem[pOp->p2];
+ u.be.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
+ u.be.pC->rowidIsValid = 0;
+ u.be.pC->deferredMoveto = 1;
break;
}
/* Opcode: Found P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If P4==0 then register P3 holds a blob constructed by MakeRecord. If
** P4>0 then register P3 is the first of P4 registers that form an unpacked
** record.
**
** Cursor P1 is on an index btree. If the record identified by P3 and P4
** is a prefix of any entry in P1 then a jump is made to P2 and
** P1 is left pointing at the matching entry.
+**
+** See also: NotFound, NoConflict, NotExists. SeekGe
*/
/* Opcode: NotFound P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If P4==0 then register P3 holds a blob constructed by MakeRecord. If
** P4>0 then register P3 is the first of P4 registers that form an unpacked
** record.
**
@@ -69828,177 +70213,126 @@
** is not the prefix of any entry in P1 then a jump is made to P2. If P1
** does contain an entry whose prefix matches the P3/P4 record then control
** falls through to the next instruction and P1 is left pointing at the
** matching entry.
**
-** See also: Found, NotExists, IsUnique
+** See also: Found, NotExists, NoConflict
*/
+/* Opcode: NoConflict P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
+**
+** If P4==0 then register P3 holds a blob constructed by MakeRecord. If
+** P4>0 then register P3 is the first of P4 registers that form an unpacked
+** record.
+**
+** Cursor P1 is on an index btree. If the record identified by P3 and P4
+** contains any NULL value, jump immediately to P2. If all terms of the
+** record are not-NULL then a check is done to determine if any row in the
+** P1 index btree has a matching key prefix. If there are no matches, jump
+** immediately to P2. If there is a match, fall through and leave the P1
+** cursor pointing to the matching row.
+**
+** This opcode is similar to OP_NotFound with the exceptions that the
+** branch is always taken if any part of the search key input is NULL.
+**
+** See also: NotFound, Found, NotExists
+*/
+case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
-#if 0 /* local variables moved into u.be */
+#if 0 /* local variables moved into u.bf */
int alreadyExists;
+ int ii;
VdbeCursor *pC;
int res;
char *pFree;
UnpackedRecord *pIdxKey;
UnpackedRecord r;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
-#endif /* local variables moved into u.be */
-
-#ifdef SQLITE_TEST
- sqlite3_found_count++;
-#endif
-
- u.be.alreadyExists = 0;
- assert( pOp->p1>=0 && pOp->p1nCursor );
- assert( pOp->p4type==P4_INT32 );
- u.be.pC = p->apCsr[pOp->p1];
- assert( u.be.pC!=0 );
- pIn3 = &aMem[pOp->p3];
- if( ALWAYS(u.be.pC->pCursor!=0) ){
-
- assert( u.be.pC->isTable==0 );
- if( pOp->p4.i>0 ){
- u.be.r.pKeyInfo = u.be.pC->pKeyInfo;
- u.be.r.nField = (u16)pOp->p4.i;
- u.be.r.aMem = pIn3;
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; ipKeyInfo, u.be.aTempRec, sizeof(u.be.aTempRec), &u.be.pFree
- );
- if( u.be.pIdxKey==0 ) goto no_mem;
- assert( pIn3->flags & MEM_Blob );
- assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
- sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z, u.be.pIdxKey);
- u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
- }
- rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res);
- if( pOp->p4.i==0 ){
- sqlite3DbFree(db, u.be.pFree);
- }
- if( rc!=SQLITE_OK ){
- break;
- }
- u.be.alreadyExists = (u.be.res==0);
- u.be.pC->deferredMoveto = 0;
- u.be.pC->cacheStatus = CACHE_STALE;
- }
- if( pOp->opcode==OP_Found ){
- if( u.be.alreadyExists ) pc = pOp->p2 - 1;
- }else{
- if( !u.be.alreadyExists ) pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: IsUnique P1 P2 P3 P4 *
-**
-** Cursor P1 is open on an index b-tree - that is to say, a btree which
-** no data and where the key are records generated by OP_MakeRecord with
-** the list field being the integer ROWID of the entry that the index
-** entry refers to.
-**
-** The P3 register contains an integer record number. Call this record
-** number R. Register P4 is the first in a set of N contiguous registers
-** that make up an unpacked index key that can be used with cursor P1.
-** The value of N can be inferred from the cursor. N includes the rowid
-** value appended to the end of the index record. This rowid value may
-** or may not be the same as R.
-**
-** If any of the N registers beginning with register P4 contains a NULL
-** value, jump immediately to P2.
-**
-** Otherwise, this instruction checks if cursor P1 contains an entry
-** where the first (N-1) fields match but the rowid value at the end
-** of the index entry is not R. If there is no such entry, control jumps
-** to instruction P2. Otherwise, the rowid of the conflicting index
-** entry is copied to register P3 and control falls through to the next
-** instruction.
-**
-** See also: NotFound, NotExists, Found
-*/
-case OP_IsUnique: { /* jump, in3 */
-#if 0 /* local variables moved into u.bf */
- u16 ii;
- VdbeCursor *pCx;
- BtCursor *pCrsr;
- u16 nField;
- Mem *aMx;
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
-#endif /* local variables moved into u.bf */
-
- pIn3 = &aMem[pOp->p3];
- u.bf.aMx = &aMem[pOp->p4.i];
- /* Assert that the values of parameters P1 and P4 are in range. */
- assert( pOp->p4type==P4_INT32 );
- assert( pOp->p4.i>0 && pOp->p4.i<=(p->nMem-p->nCursor) );
- assert( pOp->p1>=0 && pOp->p1nCursor );
-
- /* Find the index cursor. */
- u.bf.pCx = p->apCsr[pOp->p1];
- assert( u.bf.pCx->deferredMoveto==0 );
- u.bf.pCx->seekResult = 0;
- u.bf.pCx->cacheStatus = CACHE_STALE;
- u.bf.pCrsr = u.bf.pCx->pCursor;
-
- /* If any of the values are NULL, take the jump. */
- u.bf.nField = u.bf.pCx->pKeyInfo->nField;
- for(u.bf.ii=0; u.bf.iip2 - 1;
- u.bf.pCrsr = 0;
- break;
- }
- }
- assert( (u.bf.aMx[u.bf.nField].flags & MEM_Null)==0 );
-
- if( u.bf.pCrsr!=0 ){
- /* Populate the index search key. */
- u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo;
- u.bf.r.nField = u.bf.nField + 1;
- u.bf.r.flags = UNPACKED_PREFIX_SEARCH;
- u.bf.r.aMem = u.bf.aMx;
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; iu.i;
-
- /* Search the B-Tree index. If no conflicting record is found, jump
- ** to P2. Otherwise, copy the rowid of the conflicting record to
- ** register P3 and fall through to the next instruction. */
- rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult);
- if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){
- pc = pOp->p2 - 1;
- }else{
- pIn3->u.i = u.bf.r.rowid;
- }
+ char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
+#endif /* local variables moved into u.bf */
+
+#ifdef SQLITE_TEST
+ if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
+#endif
+
+ u.bf.alreadyExists = 0;
+ assert( pOp->p1>=0 && pOp->p1nCursor );
+ assert( pOp->p4type==P4_INT32 );
+ u.bf.pC = p->apCsr[pOp->p1];
+ assert( u.bf.pC!=0 );
+ pIn3 = &aMem[pOp->p3];
+ assert( u.bf.pC->pCursor!=0 );
+ assert( u.bf.pC->isTable==0 );
+ if( pOp->p4.i>0 ){
+ u.bf.r.pKeyInfo = u.bf.pC->pKeyInfo;
+ u.bf.r.nField = (u16)pOp->p4.i;
+ u.bf.r.aMem = pIn3;
+#ifdef SQLITE_DEBUG
+ {
+ int i;
+ for(i=0; ip3+i, &u.bf.r.aMem[i]);
+ }
+ }
+#endif
+ u.bf.r.flags = UNPACKED_PREFIX_MATCH;
+ u.bf.pIdxKey = &u.bf.r;
+ }else{
+ u.bf.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
+ u.bf.pC->pKeyInfo, u.bf.aTempRec, sizeof(u.bf.aTempRec), &u.bf.pFree
+ );
+ if( u.bf.pIdxKey==0 ) goto no_mem;
+ assert( pIn3->flags & MEM_Blob );
+ assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
+ sqlite3VdbeRecordUnpack(u.bf.pC->pKeyInfo, pIn3->n, pIn3->z, u.bf.pIdxKey);
+ u.bf.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
+ }
+ if( pOp->opcode==OP_NoConflict ){
+ /* For the OP_NoConflict opcode, take the jump if any of the
+ ** input fields are NULL, since any key with a NULL will not
+ ** conflict */
+ for(u.bf.ii=0; u.bf.iip2 - 1;
+ break;
+ }
+ }
+ }
+ rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, u.bf.pIdxKey, 0, 0, &u.bf.res);
+ if( pOp->p4.i==0 ){
+ sqlite3DbFree(db, u.bf.pFree);
+ }
+ if( rc!=SQLITE_OK ){
+ break;
+ }
+ u.bf.pC->seekResult = u.bf.res;
+ u.bf.alreadyExists = (u.bf.res==0);
+ u.bf.pC->nullRow = 1-u.bf.alreadyExists;
+ u.bf.pC->deferredMoveto = 0;
+ u.bf.pC->cacheStatus = CACHE_STALE;
+ if( pOp->opcode==OP_Found ){
+ if( u.bf.alreadyExists ) pc = pOp->p2 - 1;
+ }else{
+ if( !u.bf.alreadyExists ) pc = pOp->p2 - 1;
}
break;
}
/* Opcode: NotExists P1 P2 P3 * *
-**
-** Use the content of register P3 as an integer key. If a record
-** with that key does not exist in table of P1, then jump to P2.
-** If the record does exist, then fall through. The cursor is left
-** pointing to the record if it exists.
-**
-** The difference between this operation and NotFound is that this
-** operation assumes the key is an integer and that P1 is a table whereas
-** NotFound assumes key is a blob constructed from MakeRecord and
-** P1 is an index.
-**
-** See also: Found, NotFound, IsUnique
+** Synopsis: intkey=r[P3]
+**
+** P1 is the index of a cursor open on an SQL table btree (with integer
+** keys). P3 is an integer rowid. If P1 does not contain a record with
+** rowid P3 then jump immediately to P2. If P1 does contain a record
+** with rowid P3 then leave the cursor pointing at that record and fall
+** through to the next instruction.
+**
+** The OP_NotFound opcode performs the same operation on index btrees
+** (with arbitrary multi-value keys).
+**
+** See also: Found, NotFound, NoConflict
*/
case OP_NotExists: { /* jump, in3 */
#if 0 /* local variables moved into u.bg */
VdbeCursor *pC;
BtCursor *pCrsr;
@@ -70012,36 +70346,29 @@
u.bg.pC = p->apCsr[pOp->p1];
assert( u.bg.pC!=0 );
assert( u.bg.pC->isTable );
assert( u.bg.pC->pseudoTableReg==0 );
u.bg.pCrsr = u.bg.pC->pCursor;
- if( ALWAYS(u.bg.pCrsr!=0) ){
- u.bg.res = 0;
- u.bg.iKey = pIn3->u.i;
- rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
- u.bg.pC->lastRowid = pIn3->u.i;
- u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
- u.bg.pC->nullRow = 0;
- u.bg.pC->cacheStatus = CACHE_STALE;
- u.bg.pC->deferredMoveto = 0;
- if( u.bg.res!=0 ){
- pc = pOp->p2 - 1;
- assert( u.bg.pC->rowidIsValid==0 );
- }
- u.bg.pC->seekResult = u.bg.res;
- }else{
- /* This happens when an attempt to open a read cursor on the
- ** sqlite_master table returns SQLITE_EMPTY.
- */
- pc = pOp->p2 - 1;
- assert( u.bg.pC->rowidIsValid==0 );
- u.bg.pC->seekResult = 0;
- }
+ assert( u.bg.pCrsr!=0 );
+ u.bg.res = 0;
+ u.bg.iKey = pIn3->u.i;
+ rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
+ u.bg.pC->lastRowid = pIn3->u.i;
+ u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
+ u.bg.pC->nullRow = 0;
+ u.bg.pC->cacheStatus = CACHE_STALE;
+ u.bg.pC->deferredMoveto = 0;
+ if( u.bg.res!=0 ){
+ pc = pOp->p2 - 1;
+ assert( u.bg.pC->rowidIsValid==0 );
+ }
+ u.bg.pC->seekResult = u.bg.res;
break;
}
/* Opcode: Sequence P1 P2 * * *
+** Synopsis: r[P2]=rowid
**
** Find the next available sequence number for cursor P1.
** Write the sequence number into register P2.
** The sequence number on the cursor is incremented after this
** instruction.
@@ -70053,10 +70380,11 @@
break;
}
/* Opcode: NewRowid P1 P2 P3 * *
+** Synopsis: r[P2]=rowid
**
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
** The record number is not previously used as a key in the database
** table that cursor P1 points to. The new record number is written
** written to register P2.
@@ -70204,10 +70532,11 @@
pOut->u.i = u.bh.v;
break;
}
/* Opcode: Insert P1 P2 P3 P4 P5
+** Synopsis: intkey=r[P3] data=r[P2]
**
** Write an entry into the table of cursor P1. A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten. The data is the value MEM_Blob stored in register
** number P2. The key is stored in register P3. The key must
@@ -70243,10 +70572,11 @@
**
** 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:
@@ -70396,34 +70726,46 @@
sqlite3VdbeSetChanges(db, p->nChange);
p->nChange = 0;
break;
}
-/* Opcode: SorterCompare P1 P2 P3
+/* Opcode: SorterCompare P1 P2 P3 P4
+** Synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2
**
-** P1 is a sorter cursor. This instruction compares the record blob in
-** register P3 with the entry that the sorter cursor currently points to.
-** If, excluding the rowid fields at the end, the two records are a match,
-** fall through to the next instruction. Otherwise, jump to instruction P2.
+** P1 is a sorter cursor. This instruction compares a prefix of the
+** the record blob in register P3 against a prefix of the entry that
+** the sorter cursor currently points to. The final P4 fields of both
+** the P3 and sorter record are ignored.
+**
+** If either P3 or the sorter contains a NULL in one of their significant
+** fields (not counting the P4 fields at the end which are ignored) then
+** the comparison is assumed to be equal.
+**
+** Fall through to next instruction if the two records compare equal to
+** each other. Jump to P2 if they are different.
*/
case OP_SorterCompare: {
#if 0 /* local variables moved into u.bk */
VdbeCursor *pC;
int res;
+ int nIgnore;
#endif /* local variables moved into u.bk */
u.bk.pC = p->apCsr[pOp->p1];
assert( isSorter(u.bk.pC) );
+ assert( pOp->p4type==P4_INT32 );
pIn3 = &aMem[pOp->p3];
- rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, &u.bk.res);
+ u.bk.nIgnore = pOp->p4.i;
+ rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, u.bk.nIgnore, &u.bk.res);
if( u.bk.res ){
pc = pOp->p2-1;
}
break;
};
/* Opcode: SorterData P1 P2 * * *
+** Synopsis: r[P2]=data
**
** Write into register P2 the current sorter data for sorter cursor P1.
*/
case OP_SorterData: {
#if 0 /* local variables moved into u.bl */
@@ -70436,10 +70778,11 @@
rc = sqlite3VdbeSorterRowkey(u.bl.pC, pOut);
break;
}
/* Opcode: RowData P1 P2 * * *
+** Synopsis: r[P2]=data
**
** Write into register P2 the complete row data for cursor P1.
** There is no interpretation of the data.
** It is just copied onto the P2 register exactly as
** it is found in the database file.
@@ -70446,10 +70789,11 @@
**
** If the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
*/
/* Opcode: RowKey P1 P2 * * *
+** Synopsis: r[P2]=key
**
** Write into register P2 the complete row key for cursor P1.
** There is no interpretation of the data.
** The key is copied onto the P3 register exactly as
** it is found in the database file.
@@ -70516,14 +70860,16 @@
}else{
rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z);
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
+ REGISTER_TRACE(pOp->p2, pOut);
break;
}
/* Opcode: Rowid P1 P2 * * *
+** Synopsis: r[P2]=rowid
**
** Store in register P2 an integer which is the key of the table entry that
** P1 is currently point to.
**
** P1 can be either an ordinary table or a virtual table. There used to
@@ -70611,13 +70957,12 @@
assert( pOp->p1>=0 && pOp->p1nCursor );
u.bp.pC = p->apCsr[pOp->p1];
assert( u.bp.pC!=0 );
u.bp.pCrsr = u.bp.pC->pCursor;
u.bp.res = 0;
- if( ALWAYS(u.bp.pCrsr!=0) ){
- rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
- }
+ assert( u.bp.pCrsr!=0 );
+ rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
u.bp.pC->nullRow = (u8)u.bp.res;
u.bp.pC->deferredMoveto = 0;
u.bp.pC->rowidIsValid = 0;
u.bp.pC->cacheStatus = CACHE_STALE;
if( pOp->p2>0 && u.bp.res ){
@@ -70685,11 +71030,11 @@
pc = pOp->p2 - 1;
}
break;
}
-/* Opcode: Next P1 P2 * P4 P5
+/* Opcode: Next P1 P2 * * P5
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index. If there are no more key/value pairs then fall through
** to the following instruction. But if the cursor advance was successful,
** jump immediately to P2.
@@ -70757,10 +71102,11 @@
u.br.pC->rowidIsValid = 0;
goto check_for_interrupt;
}
/* Opcode: IdxInsert P1 P2 P3 * P5
+** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions. This opcode writes that key
** into the index P1. Data for the entry is nil.
**
@@ -70784,31 +71130,32 @@
assert( u.bs.pC!=0 );
assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
pIn2 = &aMem[pOp->p2];
assert( pIn2->flags & MEM_Blob );
u.bs.pCrsr = u.bs.pC->pCursor;
- if( ALWAYS(u.bs.pCrsr!=0) ){
- assert( u.bs.pC->isTable==0 );
- rc = ExpandBlob(pIn2);
- if( rc==SQLITE_OK ){
- if( isSorter(u.bs.pC) ){
- rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
- }else{
- u.bs.nKey = pIn2->n;
- u.bs.zKey = pIn2->z;
- rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
- );
- assert( u.bs.pC->deferredMoveto==0 );
- u.bs.pC->cacheStatus = CACHE_STALE;
- }
+ if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+ assert( u.bs.pCrsr!=0 );
+ assert( u.bs.pC->isTable==0 );
+ rc = ExpandBlob(pIn2);
+ if( rc==SQLITE_OK ){
+ if( isSorter(u.bs.pC) ){
+ rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
+ }else{
+ u.bs.nKey = pIn2->n;
+ u.bs.zKey = pIn2->z;
+ rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
+ );
+ assert( u.bs.pC->deferredMoveto==0 );
+ u.bs.pC->cacheStatus = CACHE_STALE;
}
}
break;
}
/* Opcode: IdxDelete P1 P2 P3 * *
+** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the
** index opened by cursor P1.
*/
@@ -70824,29 +71171,30 @@
assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 );
assert( pOp->p1>=0 && pOp->p1nCursor );
u.bt.pC = p->apCsr[pOp->p1];
assert( u.bt.pC!=0 );
u.bt.pCrsr = u.bt.pC->pCursor;
- if( ALWAYS(u.bt.pCrsr!=0) ){
- u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
- u.bt.r.nField = (u16)pOp->p3;
- u.bt.r.flags = 0;
- u.bt.r.aMem = &aMem[pOp->p2];
+ assert( u.bt.pCrsr!=0 );
+ assert( pOp->p5==0 );
+ u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
+ u.bt.r.nField = (u16)pOp->p3;
+ u.bt.r.flags = UNPACKED_PREFIX_MATCH;
+ u.bt.r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; ideferredMoveto==0 );
- u.bt.pC->cacheStatus = CACHE_STALE;
+ rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
+ if( rc==SQLITE_OK && u.bt.res==0 ){
+ rc = sqlite3BtreeDelete(u.bt.pCrsr);
}
+ assert( u.bt.pC->deferredMoveto==0 );
+ u.bt.pC->cacheStatus = CACHE_STALE;
break;
}
/* Opcode: IdxRowid P1 P2 * * *
+** Synopsis: r[P2]=rowid
**
** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1. This integer should be
** the rowid of the table entry to which this index entry points.
**
@@ -70861,29 +71209,29 @@
assert( pOp->p1>=0 && pOp->p1nCursor );
u.bu.pC = p->apCsr[pOp->p1];
assert( u.bu.pC!=0 );
u.bu.pCrsr = u.bu.pC->pCursor;
+ assert( u.bu.pCrsr!=0 );
pOut->flags = MEM_Null;
- if( ALWAYS(u.bu.pCrsr!=0) ){
- rc = sqlite3VdbeCursorMoveto(u.bu.pC);
- if( NEVER(rc) ) goto abort_due_to_error;
- assert( u.bu.pC->deferredMoveto==0 );
- assert( u.bu.pC->isTable==0 );
- if( !u.bu.pC->nullRow ){
- rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- pOut->u.i = u.bu.rowid;
- pOut->flags = MEM_Int;
- }
+ rc = sqlite3VdbeCursorMoveto(u.bu.pC);
+ if( NEVER(rc) ) goto abort_due_to_error;
+ assert( u.bu.pC->deferredMoveto==0 );
+ assert( u.bu.pC->isTable==0 );
+ if( !u.bu.pC->nullRow ){
+ rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ pOut->u.i = u.bu.rowid;
+ pOut->flags = MEM_Int;
}
break;
}
/* Opcode: IdxGE P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
** key that omits the ROWID. Compare this key value against the index
** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
**
@@ -70894,10 +71242,11 @@
** prior to the comparison. This make the opcode work like IdxGT except
** that if the key from register P3 is a prefix of the key in the cursor,
** the result is false whereas it would be true with IdxGT.
*/
/* Opcode: IdxLT P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
** key that omits the ROWID. Compare this key value against the index
** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
**
@@ -70917,35 +71266,34 @@
assert( pOp->p1>=0 && pOp->p1nCursor );
u.bv.pC = p->apCsr[pOp->p1];
assert( u.bv.pC!=0 );
assert( u.bv.pC->isOrdered );
- if( ALWAYS(u.bv.pC->pCursor!=0) ){
- assert( u.bv.pC->deferredMoveto==0 );
- assert( pOp->p5==0 || pOp->p5==1 );
- assert( pOp->p4type==P4_INT32 );
- u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
- u.bv.r.nField = (u16)pOp->p4.i;
- if( pOp->p5 ){
- u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
- }else{
- u.bv.r.flags = UNPACKED_PREFIX_MATCH;
- }
- u.bv.r.aMem = &aMem[pOp->p3];
+ assert( u.bv.pC->pCursor!=0);
+ assert( u.bv.pC->deferredMoveto==0 );
+ assert( pOp->p5==0 || pOp->p5==1 );
+ assert( pOp->p4type==P4_INT32 );
+ u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
+ u.bv.r.nField = (u16)pOp->p4.i;
+ if( pOp->p5 ){
+ u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
+ }else{
+ u.bv.r.flags = UNPACKED_PREFIX_MATCH;
+ }
+ u.bv.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; iopcode==OP_IdxLT ){
- u.bv.res = -u.bv.res;
- }else{
- assert( pOp->opcode==OP_IdxGE );
- u.bv.res++;
- }
- if( u.bv.res>0 ){
- pc = pOp->p2 - 1 ;
- }
+ rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
+ if( pOp->opcode==OP_IdxLT ){
+ u.bv.res = -u.bv.res;
+ }else{
+ assert( pOp->opcode==OP_IdxGE );
+ u.bv.res++;
+ }
+ if( u.bv.res>0 ){
+ pc = pOp->p2 - 1 ;
}
break;
}
/* Opcode: Destroy P1 P2 P3 * *
@@ -71052,10 +71400,11 @@
}
break;
}
/* Opcode: CreateTable P1 P2 * * *
+** Synopsis: r[P2]=root iDb=P1
**
** Allocate a new table in the main database file if P1==0 or in the
** auxiliary database file if P1==1 or in an attached database if
** P1>1. Write the root page number of the new table into
** register P2
@@ -71065,10 +71414,11 @@
** has an arbitrary key but no data.
**
** See also: CreateIndex
*/
/* Opcode: CreateIndex P1 P2 * * *
+** Synopsis: r[P2]=root iDb=P1
**
** Allocate a new index in the main database file if P1==0 or in the
** auxiliary database file if P1==1 or in an attached database if
** P1>1. Write the root page number of the new table into
** register P2.
@@ -71272,10 +71622,11 @@
break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/* Opcode: RowSetAdd P1 P2 * * *
+** Synopsis: rowset(P1)=r[P2]
**
** Insert the integer value held by register P2 into a boolean index
** held in register P1.
**
** An assertion fails if P2 is not an integer.
@@ -71291,10 +71642,11 @@
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
break;
}
/* Opcode: RowSetRead P1 P2 P3 * *
+** Synopsis: r[P3]=rowset(P1)
**
** Extract the smallest value from boolean index P1 and put that value into
** register P3. Or, if boolean index P1 is initially empty, leave P3
** unchanged and jump to instruction P2.
*/
@@ -71316,10 +71668,11 @@
}
goto check_for_interrupt;
}
/* Opcode: RowSetTest P1 P2 P3 P4
+** Synopsis: if r[P3] in rowset(P1) goto P2
**
** Register P3 is assumed to hold a 64-bit integer value. If register P1
** contains a RowSet object and that RowSet object contains
** the value held in P3, jump to register P2. Otherwise, insert the
** integer in P3 into the RowSet and continue on to the
@@ -71525,10 +71878,11 @@
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Opcode: FkCounter P1 P2 * * *
+** Synopsis: fkctr[P1]+=P2
**
** Increment a "constraint counter" by P2 (P2 may be negative or positive).
** If P1 is non-zero, the database constraint counter is incremented
** (deferred foreign key constraints). Otherwise, if P1 is zero, the
** statement counter is incremented (immediate foreign key constraints).
@@ -71543,10 +71897,11 @@
}
break;
}
/* Opcode: FkIfZero P1 P2 * * *
+** Synopsis: if fkctr[P1]==0 goto P2
**
** This opcode tests if a foreign key constraint-counter is currently zero.
** If so, jump to instruction P2. Otherwise, fall through to the next
** instruction.
**
@@ -71565,10 +71920,11 @@
}
#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Opcode: MemMax P1 P2 * * *
+** Synopsis: r[P1]=max(r[P1],r[P2])
**
** P1 is a register in the root frame of this VM (the root frame is
** different from the current frame if this instruction is being executed
** within a sub-program). Set the value of register P1 to the maximum of
** its current value and the value in register P2.
@@ -71597,10 +71953,11 @@
break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */
/* Opcode: IfPos P1 P2 * * *
+** Synopsis: if r[P1]>0 goto P2
**
** If the value of register P1 is 1 or greater, jump to P2.
**
** It is illegal to use this instruction on a register that does
** not contain an integer. An assertion fault will result if you try.
@@ -71613,10 +71970,11 @@
}
break;
}
/* Opcode: IfNeg P1 P2 * * *
+** Synopsis: if r[P1]<0 goto P2
**
** If the value of register P1 is less than zero, jump to P2.
**
** It is illegal to use this instruction on a register that does
** not contain an integer. An assertion fault will result if you try.
@@ -71629,10 +71987,11 @@
}
break;
}
/* Opcode: IfZero P1 P2 P3 * *
+** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2
**
** The register P1 must contain an integer. Add literal P3 to the
** value in register P1. If the result is exactly 0, jump to P2.
**
** It is illegal to use this instruction on a register that does
@@ -71647,10 +72006,11 @@
}
break;
}
/* Opcode: AggStep * P2 P3 P4 P5
+** Synopsis: accum=r[P3] step(r[P2@P5])
**
** Execute the step function for an aggregate. The
** function has P5 arguments. P4 is a pointer to the FuncDef
** structure that specifies the function. Use register
** P3 as the accumulator.
@@ -71712,10 +72072,11 @@
break;
}
/* Opcode: AggFinal P1 P2 * P4 *
+** Synopsis: accum=r[P1] N=P2
**
** Execute the finalizer function for an aggregate. P1 is
** the memory location that is the accumulator for the aggregate.
**
** P2 is the number of arguments that the step function takes and
@@ -71947,10 +72308,11 @@
break;
}
#ifndef SQLITE_OMIT_SHARED_CACHE
/* Opcode: TableLock P1 P2 P3 P4 *
+** Synopsis: iDb=P1 root=P2 write=P3
**
** Obtain a lock on a particular table. This instruction is only used when
** the shared-cache feature is enabled.
**
** P1 is the index of the database in sqlite3.aDb[] of the database
@@ -72067,10 +72429,11 @@
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VFilter P1 P2 P3 P4 *
+** Synopsis: iPlan=r[P3] zPlan='P4'
**
** P1 is a cursor opened using VOpen. P2 is an address to jump to if
** the filtered result set is empty.
**
** P4 is either NULL or a string that was generated by the xBestIndex
@@ -72143,10 +72506,11 @@
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 * *
+** Synopsis: r[P3]=vcolumn(P2)
**
** Store the value of the P2-th column of
** the row of the virtual-table that the
** P1 cursor is pointing to into register P3.
*/
@@ -72282,10 +72646,11 @@
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VUpdate P1 P2 P3 P4 *
+** Synopsis: data=r[P3@P2]
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
** This opcode invokes the corresponding xUpdate method. P2 values
** are contiguous memory cells starting at P3 to pass to the xUpdate
** invocation. The value in register (P3+P2-1) corresponds to the
@@ -72413,10 +72778,20 @@
){
u.cs.z = sqlite3VdbeExpandSql(p, u.cs.zTrace);
db->xTrace(db->pTraceArg, u.cs.z);
sqlite3DbFree(db, u.cs.z);
}
+#ifdef SQLITE_USE_FCNTL_TRACE
+ u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
+ if( u.cs.zTrace ){
+ int i;
+ for(i=0; inDb; i++){
+ if( ((1<btreeMask)==0 ) continue;
+ sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, u.cs.zTrace);
+ }
+ }
+#endif /* SQLITE_USE_FCNTL_TRACE */
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0
&& (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
sqlite3DebugPrintf("SQL-trace: %s\n", u.cs.zTrace);
@@ -72727,10 +73102,14 @@
pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
if( pTab && IsVirtual(pTab) ){
pTab = 0;
sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
}
+ if( pTab && !HasRowid(pTab) ){
+ pTab = 0;
+ sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable);
+ }
#ifndef SQLITE_OMIT_VIEW
if( pTab && pTab->pSelect ){
pTab = 0;
sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable);
}
@@ -72784,11 +73163,11 @@
}
}
#endif
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int j;
- for(j=0; jnColumn; j++){
+ for(j=0; jnKeyCol; j++){
if( pIdx->aiColumn[j]==iCol ){
zFault = "indexed";
}
}
}
@@ -73405,11 +73784,11 @@
** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace
** has been allocated and contains an unpacked record that is used as key2.
*/
static void vdbeSorterCompare(
const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */
- int bOmitRowid, /* Ignore rowid field at end of keys */
+ int nIgnore, /* Ignore the last nIgnore fields */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2, /* Right side of comparison */
int *pRes /* OUT: Result of comparison */
){
KeyInfo *pKeyInfo = pCsr->pKeyInfo;
@@ -73419,12 +73798,12 @@
if( pKey2 ){
sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2);
}
- if( bOmitRowid ){
- r2->nField = pKeyInfo->nField;
+ if( nIgnore ){
+ r2->nField = pKeyInfo->nField - nIgnore;
assert( r2->nField>0 );
for(i=0; inField; i++){
if( r2->aMem[i].flags & MEM_Null ){
*pRes = -1;
return;
@@ -74046,17 +74425,18 @@
** key.
*/
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal, /* Value to compare to current sorter key */
+ int nIgnore, /* Ignore this many fields at the end */
int *pRes /* OUT: Result of comparison */
){
VdbeSorter *pSorter = pCsr->pSorter;
void *pKey; int nKey; /* Sorter key to compare pVal with */
pKey = vdbeSorterRowkey(pSorter, &nKey);
- vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
+ vdbeSorterCompare(pCsr, nIgnore, pVal->z, pVal->n, pKey, nKey, pRes);
return SQLITE_OK;
}
/************** End of vdbesort.c ********************************************/
/************** Begin file journal.c *****************************************/
@@ -74955,11 +75335,13 @@
sqlite3 *db = pParse->db; /* The database connection */
struct SrcList_item *pItem; /* Use for looping over pSrcList items */
struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
NameContext *pTopNC = pNC; /* First namecontext in the list */
Schema *pSchema = 0; /* Schema of the expression */
- int isTrigger = 0;
+ int isTrigger = 0; /* True if resolved to a trigger column */
+ Table *pTab = 0; /* Table hold the row */
+ Column *pCol; /* A column of pTab */
assert( pNC ); /* the name context cannot be NULL. */
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
@@ -74996,13 +75378,10 @@
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
if( pSrcList ){
for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){
- Table *pTab;
- Column *pCol;
-
pTab = pItem->pTab;
assert( pTab!=0 && pTab->zName!=0 );
assert( pTab->nCol>0 );
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
int hit = 0;
@@ -75058,13 +75437,12 @@
#ifndef SQLITE_OMIT_TRIGGER
/* If we have not already resolved the name, then maybe
** it is a new.* or old.* trigger argument reference
*/
- if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){
+ if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){
int op = pParse->eTriggerOp;
- Table *pTab = 0;
assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
pExpr->iTable = 1;
pTab = pParse->pTriggerTab;
}else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
@@ -75074,20 +75452,19 @@
if( pTab ){
int iCol;
pSchema = pTab->pSchema;
cntTab++;
- for(iCol=0; iColnCol; iCol++){
- Column *pCol = &pTab->aCol[iCol];
+ for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
if( iCol==pTab->iPKey ){
iCol = -1;
}
break;
}
}
- if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) ){
+ if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
iCol = -1; /* IMP: R-44911-55124 */
}
if( iColnCol ){
cnt++;
if( iCol<0 ){
@@ -75110,11 +75487,12 @@
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
/*
** Perhaps the name is a reference to the ROWID
*/
- if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
+ assert( pTab!=0 || cntTab==0 );
+ if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
cnt = 1;
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
pExpr->affinity = SQLITE_AFF_INTEGER;
}
@@ -77714,20 +78092,20 @@
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table . */
Expr *pExpr; /* Expression */
- int iCol; /* Index of column */
- int iDb; /* Database idx for pTab */
+ i16 iCol; /* Index of column */
+ i16 iDb; /* Database idx for pTab */
assert( p ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
pTab = p->pSrc->a[0].pTab;
pExpr = p->pEList->a[0].pExpr;
- iCol = pExpr->iColumn;
+ iCol = (i16)pExpr->iColumn;
/* Code an OP_VerifyCookie and OP_TableLock for . */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
@@ -77761,20 +78139,15 @@
int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity);
for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
if( (pIdx->aiColumn[0]==iCol)
&& sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
- && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
+ && (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None))
){
- int iAddr;
- char *pKey;
-
- pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
- iAddr = sqlite3CodeOnce(pParse);
-
- sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
- pKey,P4_KEYINFO_HANDOFF);
+ int iAddr = sqlite3CodeOnce(pParse);
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
sqlite3VdbeJumpHere(v, iAddr);
@@ -77910,11 +78283,11 @@
** is used.
*/
pExpr->iTable = pParse->nTab++;
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
- pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);
+ pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* Case 1: expr IN (SELECT ...)
**
** Generate code to write the results of the select into the temporary
@@ -77928,17 +78301,18 @@
dest.affSdst = (u8)affinity;
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
pExpr->x.pSelect->iLimit = 0;
testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
- sqlite3DbFree(pParse->db, pKeyInfo);
+ sqlite3KeyInfoUnref(pKeyInfo);
return 0;
}
pEList = pExpr->x.pSelect->pEList;
assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
assert( pEList!=0 );
assert( pEList->nExpr>0 );
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
pEList->a[0].pExpr);
}else if( ALWAYS(pExpr->x.pList!=0) ){
/* Case 2: expr IN (exprlist)
**
@@ -77954,10 +78328,11 @@
if( !affinity ){
affinity = SQLITE_AFF_NONE;
}
if( pKeyInfo ){
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
}
/* Loop through each expression in . */
r1 = sqlite3GetTempReg(pParse);
@@ -77995,11 +78370,11 @@
}
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempReg(pParse, r2);
}
if( pKeyInfo ){
- sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
}
break;
}
case TK_EXISTS:
@@ -78396,19 +78771,23 @@
** Generate code to extract the value of the iCol-th column of a table.
*/
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
Vdbe *v, /* The VDBE under construction */
Table *pTab, /* The table containing the value */
- int iTabCur, /* The cursor for this table */
+ int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */
int iCol, /* Index of the column to extract */
- int regOut /* Extract the valud into this register */
+ int regOut /* Extract the value into this register */
){
if( iCol<0 || iCol==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
}else{
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
- sqlite3VdbeAddOp3(v, op, iTabCur, iCol, regOut);
+ int x = iCol;
+ if( !HasRowid(pTab) ){
+ x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
+ }
+ sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
}
if( iCol>=0 ){
sqlite3ColumnDefault(v, pTab, iCol, regOut);
}
}
@@ -79150,11 +79529,11 @@
if( pExpr->affinity==OE_Ignore ){
sqlite3VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
}else{
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
- pExpr->affinity, pExpr->u.zToken, 0);
+ pExpr->affinity, pExpr->u.zToken, 0, 0);
}
break;
}
#endif
@@ -81526,12 +81905,11 @@
}
/* Open the sqlite_stat[134] tables for writing. */
for(i=0; aTable[i].zCols; i++){
assert( inRowid ){
+ sqlite3DbFree(db, p->u.aRowid);
+ p->nRowid = 0;
+ }
+}
+#endif
+
+/* Initialize the BLOB value of a ROWID
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
+ assert( db!=0 );
+ if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
+ p->u.aRowid = sqlite3DbMallocRaw(db, n);
+ if( p->u.aRowid ){
+ p->nRowid = n;
+ memcpy(p->u.aRowid, pData, n);
+ }else{
+ p->nRowid = 0;
+ }
+}
+#endif
+
+/* Initialize the INTEGER value of a ROWID.
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
+ assert( db!=0 );
+ if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
+ p->nRowid = 0;
+ p->u.iRowid = iRowid;
+}
+#endif
+
+
+/*
+** Copy the contents of object (*pFrom) into (*pTo).
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
+ pTo->isPSample = pFrom->isPSample;
+ pTo->iCol = pFrom->iCol;
+ pTo->iHash = pFrom->iHash;
+ memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
+ memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
+ memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol);
+ if( pFrom->nRowid ){
+ sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid);
+ }else{
+ sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid);
+ }
+}
+#endif
+
+/*
+** Reclaim all memory of a Stat4Accum structure.
+*/
+static void stat4Destructor(void *pOld){
+ Stat4Accum *p = (Stat4Accum*)pOld;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int i;
+ for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i);
+ for(i=0; imxSample; i++) sampleClear(p->db, p->a+i);
+ sampleClear(p->db, &p->current);
+#endif
+ sqlite3DbFree(p->db, p);
+}
/*
** Implementation of the stat_init(N,C) SQL function. The two parameters
** are the number of rows in the table or index (C) and the number of columns
** in the index (N). The second argument (C) is only used for STAT3 and STAT4.
@@ -81589,10 +82045,11 @@
){
Stat4Accum *p;
int nCol; /* Number of columns in index being sampled */
int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */
+ sqlite3 *db; /* Database connection */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int mxSample = SQLITE_STAT4_SAMPLES;
#endif
/* Decode the three function arguments */
@@ -81605,20 +82062,22 @@
n = sizeof(*p)
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
- + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
#endif
;
- p = sqlite3MallocZero(n);
+ db = sqlite3_context_db_handle(context);
+ p = sqlite3DbMallocZero(db, n);
if( p==0 ){
sqlite3_result_error_nomem(context);
return;
}
+ p->db = db;
p->nRow = 0;
p->nCol = nCol;
p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nColUp];
@@ -81649,11 +82108,11 @@
}
}
#endif
/* Return a pointer to the allocated object to the caller */
- sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
+ sqlite3_result_blob(context, p, sizeof(p), stat4Destructor);
}
static const FuncDef statInitFuncdef = {
1+IsStat34, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
@@ -81723,29 +82182,16 @@
#else
return (nEqNew==nEqOld && pNew->iHash>pOld->iHash);
#endif
}
-/*
-** Copy the contents of object (*pFrom) into (*pTo).
-*/
-static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
- pTo->iRowid = pFrom->iRowid;
- pTo->isPSample = pFrom->isPSample;
- pTo->iCol = pFrom->iCol;
- pTo->iHash = pFrom->iHash;
- memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
- memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
- memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol);
-}
-
/*
** Copy the contents of sample *pNew into the p->a[] array. If necessary,
** remove the least desirable sample from p->a[] to make room.
*/
static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
- Stat4Sample *pSample;
+ Stat4Sample *pSample = 0;
int i;
assert( IsStat4 || nEqZero==0 );
#ifdef SQLITE_ENABLE_STAT4
@@ -81781,12 +82227,14 @@
if( p->nSample>=p->mxSample ){
Stat4Sample *pMin = &p->a[p->iMin];
tRowcnt *anEq = pMin->anEq;
tRowcnt *anLt = pMin->anLt;
tRowcnt *anDLt = pMin->anDLt;
+ sampleClear(p->db, pMin);
memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1));
pSample = &p->a[p->nSample-1];
+ pSample->nRowid = 0;
pSample->anEq = anEq;
pSample->anDLt = anDLt;
pSample->anLt = anLt;
p->nSample = p->mxSample-1;
}
@@ -81879,20 +82327,21 @@
UNUSED_PARAMETER( iChng );
#endif
}
/*
-** Implementation of the stat_push SQL function: stat_push(P,R,C)
+** Implementation of the stat_push SQL function: stat_push(P,C,R)
** Arguments:
**
** P Pointer to the Stat4Accum object created by stat_init()
** C Index of left-most column to differ from previous row
-** R Rowid for the current row
+** R Rowid for the current row. Might be a key record for
+** WITHOUT ROWID tables.
**
** The SQL function always returns NULL.
**
-** The R parameter is only used for STAT3 and STAT4.
+** The R parameter is only used for STAT3 and STAT4
*/
static void statPush(
sqlite3_context *context,
int argc,
sqlite3_value **argv
@@ -81928,11 +82377,16 @@
p->current.anEq[i] = 1;
}
}
p->nRow++;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
- p->current.iRowid = sqlite3_value_int64(argv[2]);
+ if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
+ sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
+ }else{
+ sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
+ sqlite3_value_blob(argv[2]));
+ }
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
#endif
#ifdef SQLITE_ENABLE_STAT4
{
@@ -82052,11 +82506,17 @@
if( p->iGet<0 ){
samplePushPrevious(p, 0);
p->iGet = 0;
}
if( p->iGetnSample ){
- sqlite3_result_int64(context, p->a[p->iGet].iRowid);
+ Stat4Sample *pS = p->a + p->iGet;
+ if( pS->nRowid==0 ){
+ sqlite3_result_int64(context, pS->u.iRowid);
+ }else{
+ sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid,
+ SQLITE_TRANSIENT);
+ }
}
}else{
tRowcnt *aCnt = 0;
assert( p->iGetnSample );
@@ -82189,26 +82649,30 @@
sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int nCol; /* Number of columns indexed by pIdx */
- KeyInfo *pKey; /* KeyInfo structure for pIdx */
int *aGotoChng; /* Array of jump instruction addresses */
int addrRewind; /* Address of "OP_Rewind iIdxCur" */
int addrGotoChng0; /* Address of "Goto addr_chng_0" */
int addrNextRow; /* Address of "next_row:" */
+ const char *zIdxName; /* Name of the index */
if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
- nCol = pIdx->nColumn;
+ nCol = pIdx->nKeyCol;
aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1));
if( aGotoChng==0 ) continue;
- pKey = sqlite3IndexKeyinfo(pParse, pIdx);
/* Populate the register containing the index name. */
- sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
+ if( pIdx->autoIndex==2 && !HasRowid(pTab) ){
+ zIdxName = pTab->zName;
+ }else{
+ zIdxName = pIdx->zName;
+ }
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0);
/*
** Pseudo-code for loop that calls stat_push():
**
** Rewind csr
@@ -82247,11 +82711,11 @@
pParse->nMem = MAX(pParse->nMem, regPrev+nCol);
/* Open a read-only cursor on the index being analyzed. */
assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
/* Invoke the stat_init() function. The arguments are:
**
** (1) the number of columns in the index including the rowid,
@@ -82321,12 +82785,25 @@
** Next csr
** if !eof(csr) goto next_row;
*/
sqlite3VdbeJumpHere(v, aGotoChng[nCol]);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
- sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
assert( regRowid==(regStat4+2) );
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+ int j, k, regKey;
+ regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+ for(j=0; jnKeyCol; j++){
+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
+ VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
+ sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
+ }
#endif
assert( regChng==(regStat4+1) );
sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, 2+IsStat34);
@@ -82348,26 +82825,27 @@
int regSample = regStat1+3;
int regCol = regStat1+4;
int regSampleRowid = regCol + nCol;
int addrNext;
int addrIsNull;
+ u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
pParse->nMem = MAX(pParse->nMem, regCol+nCol+1);
addrNext = sqlite3VdbeCurrentAddr(v);
callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
- sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid);
+ sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
#ifdef SQLITE_ENABLE_STAT3
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
pIdx->aiColumn[0], regSample);
#else
for(i=0; iaiColumn[i];
+ i16 iCol = pIdx->aiColumn[i];
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
#endif
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0);
@@ -82619,11 +83097,11 @@
pIndex = 0;
}
z = argv[2];
if( pIndex ){
- decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst, pIndex);
+ decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex);
if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0];
}else{
Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow;
decodeIntArray((char*)z, 1, &pTable->nRowEst, &fakeIdx);
@@ -82665,11 +83143,11 @@
static void initAvgEq(Index *pIdx){
if( pIdx ){
IndexSample *aSample = pIdx->aSample;
IndexSample *pFinal = &aSample[pIdx->nSample-1];
int iCol;
- for(iCol=0; iColnColumn; iCol++){
+ for(iCol=0; iColnKeyCol; iCol++){
int i; /* Used to iterate through samples */
tRowcnt sumEq = 0; /* Sum of the nEq values */
tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
tRowcnt avgEq = 0;
tRowcnt nDLt = pFinal->anDLt[iCol];
@@ -82692,10 +83170,27 @@
pIdx->aAvgEq[iCol] = avgEq;
if( pIdx->nSampleCol==1 ) break;
}
}
}
+
+/*
+** Look up an index by name. Or, if the name of a WITHOUT ROWID table
+** is supplied instead, find the PRIMARY KEY index for that table.
+*/
+static Index *findIndexOrPrimaryKey(
+ sqlite3 *db,
+ const char *zName,
+ const char *zDb
+){
+ Index *pIdx = sqlite3FindIndex(db, zName, zDb);
+ if( pIdx==0 ){
+ Table *pTab = sqlite3FindTable(db, zName, zDb);
+ if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
+ }
+ return pIdx;
+}
/*
** Load the content from either the sqlite_stat4 or sqlite_stat3 table
** into the relevant Index.aSample[] arrays.
**
@@ -82742,18 +83237,18 @@
tRowcnt *pSpace;
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
nSample = sqlite3_column_int(pStmt, 1);
- pIdx = sqlite3FindIndex(db, zIndex, zDb);
+ pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
/* Index.nSample is non-zero at this point if data has already been
** loaded from the stat4 table. In this case ignore stat3 data. */
if( pIdx==0 || pIdx->nSample ) continue;
if( bStat3==0 ){
- nIdxCol = pIdx->nColumn+1;
- nAvgCol = pIdx->nColumn;
+ nIdxCol = pIdx->nKeyCol+1;
+ nAvgCol = pIdx->nKeyCol;
}
pIdx->nSampleCol = nIdxCol;
nByte = sizeof(IndexSample) * nSample;
nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
@@ -82788,11 +83283,11 @@
Index *pIdx; /* Pointer to the index object */
int nCol = 1; /* Number of columns in index */
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
- pIdx = sqlite3FindIndex(db, zIndex, zDb);
+ pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
if( pIdx==0 ) continue;
/* This next condition is true if data has already been loaded from
** the sqlite_stat4 table. In this case ignore stat3 data. */
nCol = pIdx->nSampleCol;
if( bStat3 && nCol>1 ) continue;
@@ -84144,12 +84639,14 @@
*/
static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
sqlite3DeleteIndexSamples(db, p);
#endif
+ if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
sqlite3ExprDelete(db, p->pPartIdxWhere);
sqlite3DbFree(db, p->zColAff);
+ if( p->isResized ) sqlite3DbFree(db, p->azColl);
sqlite3DbFree(db, p);
}
/*
** For the index called zIdxName which is found in the database iDb,
@@ -84403,12 +84900,11 @@
** writing. The table is opened using cursor 0.
*/
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){
Vdbe *v = sqlite3GetVdbe(p);
sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
- sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb);
- sqlite3VdbeChangeP4(v, -1, (char *)5, P4_INT32); /* 5 column table */
+ sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
if( p->nTab==0 ){
p->nTab = 1;
}
}
@@ -84508,10 +85004,31 @@
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
return SQLITE_ERROR;
}
return SQLITE_OK;
}
+
+/*
+** Return the PRIMARY KEY index of a table
+*/
+SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){
+ Index *p;
+ for(p=pTab->pIndex; p && p->autoIndex!=2; p=p->pNext){}
+ return p;
+}
+
+/*
+** Return the column of index pIdx that corresponds to table
+** column iCol. Return -1 if not found.
+*/
+SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
+ int i;
+ for(i=0; inColumn; i++){
+ if( iCol==pIdx->aiColumn[i] ) return i;
+ }
+ return -1;
+}
/*
** Begin constructing a new table representation in memory. This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement. In particular, this routine is called
@@ -84708,11 +85225,11 @@
if( isView || isVirtual ){
sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2);
}else
#endif
{
- sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
+ pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
}
sqlite3OpenMasterTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
sqlite3VdbeAddOp2(v, OP_Null, 0, reg3);
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
@@ -84976,10 +85493,11 @@
int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */
){
Table *pTab = pParse->pNewTable;
char *zType = 0;
int iCol = -1, i;
+ int nTerm;
if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
if( pTab->tabFlags & TF_HasPrimaryKey ){
sqlite3ErrorMsg(pParse,
"table \"%s\" has more than one primary key", pTab->zName);
goto primary_key_exit;
@@ -84986,43 +85504,47 @@
}
pTab->tabFlags |= TF_HasPrimaryKey;
if( pList==0 ){
iCol = pTab->nCol - 1;
pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
+ zType = pTab->aCol[iCol].zType;
+ nTerm = 1;
}else{
- for(i=0; inExpr; i++){
+ nTerm = pList->nExpr;
+ for(i=0; inCol; iCol++){
if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
+ pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
+ zType = pTab->aCol[iCol].zType;
break;
}
}
- if( iColnCol ){
- pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
- }
- }
- if( pList->nExpr>1 ) iCol = -1;
- }
- if( iCol>=0 && iColnCol ){
- zType = pTab->aCol[iCol].zType;
- }
- if( zType && sqlite3StrICmp(zType, "INTEGER")==0
- && sortOrder==SQLITE_SO_ASC ){
+ }
+ }
+ if( nTerm==1
+ && zType && sqlite3StrICmp(zType, "INTEGER")==0
+ && sortOrder==SQLITE_SO_ASC
+ ){
pTab->iPKey = iCol;
pTab->keyConf = (u8)onError;
assert( autoInc==0 || autoInc==1 );
pTab->tabFlags |= autoInc*TF_Autoincrement;
+ if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
}else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
"INTEGER PRIMARY KEY");
#endif
}else{
+ Vdbe *v = pParse->pVdbe;
Index *p;
+ if( v ) pParse->addrSkipPK = sqlite3VdbeAddOp0(v, OP_Noop);
p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
0, sortOrder, 0);
if( p ){
p->autoIndex = 2;
+ if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK);
}
pList = 0;
}
primary_key_exit:
@@ -85075,11 +85597,11 @@
/* If the column is declared as " PRIMARY KEY COLLATE ",
** then an index may have been created on this column before the
** collation type was added. Correct this if it is the case.
*/
for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
- assert( pIdx->nColumn==1 );
+ assert( pIdx->nKeyCol==1 );
if( pIdx->aiColumn[0]==i ){
pIdx->azColl[0] = p->aCol[i].zColl;
}
}
}else{
@@ -85266,10 +85788,35 @@
assert( k<=n );
}
sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
return zStmt;
}
+
+/*
+** Resize an Index object to hold N columns total. Return SQLITE_OK
+** on success and SQLITE_NOMEM on an OOM error.
+*/
+static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
+ char *zExtra;
+ int nByte;
+ if( pIdx->nColumn>=N ) return SQLITE_OK;
+ assert( pIdx->isResized==0 );
+ nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
+ zExtra = sqlite3DbMallocZero(db, nByte);
+ if( zExtra==0 ) return SQLITE_NOMEM;
+ memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
+ pIdx->azColl = (char**)zExtra;
+ zExtra += sizeof(char*)*N;
+ memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
+ pIdx->aiColumn = (i16*)zExtra;
+ zExtra += sizeof(i16)*N;
+ memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn);
+ pIdx->aSortOrder = (u8*)zExtra;
+ pIdx->nColumn = N;
+ pIdx->isResized = 1;
+ return SQLITE_OK;
+}
/*
** Estimate the total row width for a table.
*/
static void estimateTableWidth(Table *pTab){
@@ -85285,19 +85832,151 @@
/*
** Estimate the average size of a row for an index.
*/
static void estimateIndexWidth(Index *pIdx){
- unsigned wIndex = 1;
+ unsigned wIndex = 0;
int i;
const Column *aCol = pIdx->pTable->aCol;
for(i=0; inColumn; i++){
- assert( pIdx->aiColumn[i]>=0 && pIdx->aiColumn[i]pTable->nCol );
- wIndex += aCol[pIdx->aiColumn[i]].szEst;
+ i16 x = pIdx->aiColumn[i];
+ assert( xpTable->nCol );
+ wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
}
pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
}
+
+/* Return true if value x is found any of the first nCol entries of aiCol[]
+*/
+static int hasColumn(const i16 *aiCol, int nCol, int x){
+ while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
+ return 0;
+}
+
+/*
+** This routine runs at the end of parsing a CREATE TABLE statement that
+** has a WITHOUT ROWID clause. The job of this routine is to convert both
+** internal schema data structures and the generated VDBE code so that they
+** are appropriate for a WITHOUT ROWID table instead of a rowid table.
+** Changes include:
+**
+** (1) Convert the OP_CreateTable into an OP_CreateIndex. There is
+** no rowid btree for a WITHOUT ROWID. Instead, the canonical
+** data storage is a covering index btree.
+** (2) Bypass the creation of the sqlite_master table entry
+** for the PRIMARY KEY as the the primary key index is now
+** identified by the sqlite_master table entry of the table itself.
+** (3) Set the Index.tnum of the PRIMARY KEY Index object in the
+** schema to the rootpage from the main table.
+** (4) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
+** (5) Add all table columns to the PRIMARY KEY Index object
+** so that the PRIMARY KEY is a covering index. The surplus
+** columns are part of KeyInfo.nXField and are not used for
+** sorting or lookup or uniqueness checks.
+** (6) Replace the rowid tail on all automatically generated UNIQUE
+** indices with the PRIMARY KEY columns.
+*/
+static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
+ Index *pIdx;
+ Index *pPk;
+ int nPk;
+ int i, j;
+ sqlite3 *db = pParse->db;
+ Vdbe *v = pParse->pVdbe;
+
+ /* Convert the OP_CreateTable opcode that would normally create the
+ ** root-page for the table into a OP_CreateIndex opcode. The index
+ ** created will become the PRIMARY KEY index.
+ */
+ if( pParse->addrCrTab ){
+ assert( v );
+ sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
+ }
+
+ /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
+ ** table entry.
+ */
+ if( pParse->addrSkipPK ){
+ assert( v );
+ sqlite3VdbeGetOp(v, pParse->addrSkipPK)->opcode = OP_Goto;
+ }
+
+ /* Locate the PRIMARY KEY index. Or, if this table was originally
+ ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
+ */
+ if( pTab->iPKey>=0 ){
+ ExprList *pList;
+ pList = sqlite3ExprListAppend(pParse, 0, 0);
+ if( pList==0 ) return;
+ pList->a[0].zName = sqlite3DbStrDup(pParse->db,
+ pTab->aCol[pTab->iPKey].zName);
+ pList->a[0].sortOrder = pParse->iPkSortOrder;
+ assert( pParse->pNewTable==pTab );
+ pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
+ if( pPk==0 ) return;
+ pPk->autoIndex = 2;
+ pTab->iPKey = -1;
+ }else{
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ }
+ pPk->isCovering = 1;
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+
+ /* Make sure every column of the PRIMARY KEY is NOT NULL */
+ for(i=0; iaCol[pPk->aiColumn[i]].notNull = 1;
+ }
+ pPk->uniqNotNull = 1;
+
+ /* The root page of the PRIMARY KEY is the table root page */
+ pPk->tnum = pTab->tnum;
+
+ /* Update the in-memory representation of all UNIQUE indices by converting
+ ** the final rowid column into one or more columns of the PRIMARY KEY.
+ */
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int n;
+ if( pIdx->autoIndex==2 ) continue;
+ for(i=n=0; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
+ }
+ if( n==0 ){
+ /* This index is a superset of the primary key */
+ pIdx->nColumn = pIdx->nKeyCol;
+ continue;
+ }
+ if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
+ for(i=0, j=pIdx->nKeyCol; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
+ pIdx->aiColumn[j] = pPk->aiColumn[i];
+ pIdx->azColl[j] = pPk->azColl[i];
+ j++;
+ }
+ }
+ assert( pIdx->nColumn>=pIdx->nKeyCol+n );
+ assert( pIdx->nColumn>=j );
+ }
+
+ /* Add all table columns to the PRIMARY KEY index
+ */
+ if( nPknCol ){
+ if( resizeIndexObject(db, pPk, pTab->nCol) ) return;
+ for(i=0, j=nPk; inCol; i++){
+ if( !hasColumn(pPk->aiColumn, j, i) ){
+ assert( jnColumn );
+ pPk->aiColumn[j] = i;
+ pPk->azColl[j] = "BINARY";
+ j++;
+ }
+ }
+ assert( pPk->nColumn==j );
+ assert( pTab->nCol==j );
+ }else{
+ pPk->nColumn = pTab->nCol;
+ }
+}
/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
@@ -85318,11 +85997,12 @@
** the new table will match the result set of the SELECT.
*/
SQLITE_PRIVATE void sqlite3EndTable(
Parse *pParse, /* Parse context */
Token *pCons, /* The ',' token after the last column defn. */
- Token *pEnd, /* The final ')' token in the CREATE TABLE */
+ Token *pEnd, /* The ')' before options in the CREATE TABLE */
+ u8 tabOpts, /* Extra table options. Usually 0. */
Select *pSelect /* Select from a "CREATE ... AS SELECT" */
){
Table *p; /* The new table */
sqlite3 *db = pParse->db; /* The database connection */
int iDb; /* Database in which the table lives */
@@ -85333,10 +86013,35 @@
}
p = pParse->pNewTable;
if( p==0 ) return;
assert( !db->init.busy || !pSelect );
+
+ /* 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
+ ** for the table from the db->init.newTnum field. (The page number
+ ** should have been put there by the sqliteOpenCb routine.)
+ */
+ if( db->init.busy ){
+ p->tnum = db->init.newTnum;
+ }
+
+ /* Special processing for WITHOUT ROWID Tables */
+ if( tabOpts & TF_WithoutRowid ){
+ if( (p->tabFlags & TF_Autoincrement) ){
+ sqlite3ErrorMsg(pParse,
+ "AUTOINCREMENT not allowed on WITHOUT ROWID tables");
+ return;
+ }
+ if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
+ sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
+ }else{
+ p->tabFlags |= TF_WithoutRowid;
+ convertToWithoutRowidTable(pParse, p);
+ }
+ }
iDb = sqlite3SchemaToIndex(db, p->pSchema);
#ifndef SQLITE_OMIT_CHECK
/* Resolve names in all CHECK constraint expressions.
@@ -85350,20 +86055,10 @@
estimateTableWidth(p);
for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
estimateIndexWidth(pIdx);
}
- /* 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
- ** for the table from the db->init.newTnum field. (The page number
- ** should have been put there by the sqliteOpenCb routine.)
- */
- if( db->init.busy ){
- p->tnum = db->init.newTnum;
- }
-
/* If not initializing, then create a record for the new table
** in the SQLITE_MASTER table of the database.
**
** If this is a TEMPORARY table, write the entry into the auxiliary
** file instead of into the main database file.
@@ -85433,11 +86128,13 @@
/* Compute the complete text of the CREATE statement */
if( pSelect ){
zStmt = createTableStmt(db, p);
}else{
- n = (int)(pEnd->z - pParse->sNameToken.z) + 1;
+ Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd;
+ n = (int)(pEnd2->z - pParse->sNameToken.z);
+ if( pEnd2->z[0]!=';' ) n += pEnd2->n;
zStmt = sqlite3MPrintf(db,
"CREATE %s %.*s", zType2, n, pParse->sNameToken.z
);
}
@@ -85476,11 +86173,11 @@
}
#endif
/* Reparse everything to update our internal data structures */
sqlite3VdbeAddParseSchemaOp(v, iDb,
- sqlite3MPrintf(db, "tbl_name='%q'", p->zName));
+ sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName));
}
/* Add the table to the in-memory representation of the database.
*/
@@ -85581,11 +86278,11 @@
while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; }
sEnd.z = &z[n-1];
sEnd.n = 1;
/* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
- sqlite3EndTable(pParse, 0, &sEnd, 0);
+ sqlite3EndTable(pParse, 0, &sEnd, 0, 0);
return;
}
#endif /* SQLITE_OMIT_VIEW */
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
@@ -86036,12 +86733,12 @@
/*
** This routine is called to create a new foreign key on the table
** currently under construction. pFromCol determines which columns
** in the current table point to the foreign key. If pFromCol==0 then
** connect the key to the last column inserted. pTo is the name of
-** the table referred to. pToCol is a list of tables in the other
-** pTo table that the foreign key points to. flags contains all
+** the table referred to (a.k.a the "parent" table). pToCol is a list
+** of tables in the parent pTo table. flags contains all
** information about the conflict resolution algorithms specified
** in the ON DELETE, ON UPDATE and ON INSERT clauses.
**
** An FKey structure is created and added to the table currently
** under construction in the pParse->pNewTable field.
@@ -86220,41 +86917,43 @@
if( v==0 ) return;
if( memRootPage>=0 ){
tnum = memRootPage;
}else{
tnum = pIndex->tnum;
- sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
}
- pKey = sqlite3IndexKeyinfo(pParse, pIndex);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
- (char *)pKey, P4_KEYINFO_HANDOFF);
- sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
+ pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
- sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
+ sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)
+ sqlite3KeyInfoRef(pKey), P4_KEYINFO);
/* Open the table. Loop through all rows of the table, inserting index
** records into the sorter. */
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
regRecord = sqlite3GetTempReg(pParse);
- sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel);
+ sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 0, &iPartIdxLabel);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
sqlite3VdbeJumpHere(v, addr1);
+ if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
+ sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
+ (char *)pKey, P4_KEYINFO);
+ sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
+
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
- if( pIndex->onError!=OE_None ){
+ assert( pKey!=0 || db->mallocFailed || pParse->nErr );
+ if( pIndex->onError!=OE_None && pKey!=0 ){
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
- OE_Abort, "indexed columns are not unique", P4_STATIC
- );
+ sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
+ pKey->nField - pIndex->nKeyCol);
+ sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
@@ -86265,10 +86964,45 @@
sqlite3VdbeAddOp1(v, OP_Close, iTab);
sqlite3VdbeAddOp1(v, OP_Close, iIdx);
sqlite3VdbeAddOp1(v, OP_Close, iSorter);
}
+
+/*
+** Allocate heap space to hold an Index object with nCol columns.
+**
+** Increase the allocation size to provide an extra nExtra bytes
+** of 8-byte aligned space after the Index object and return a
+** pointer to this extra space in *ppExtra.
+*/
+SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(
+ sqlite3 *db, /* Database connection */
+ i16 nCol, /* Total number of columns in the index */
+ int nExtra, /* Number of bytes of extra space to alloc */
+ char **ppExtra /* Pointer to the "extra" space */
+){
+ Index *p; /* Allocated index object */
+ int nByte; /* Bytes of space for Index object + arrays */
+
+ nByte = ROUND8(sizeof(Index)) + /* Index structure */
+ ROUND8(sizeof(char*)*nCol) + /* Index.azColl */
+ ROUND8(sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */
+ sizeof(i16)*nCol + /* Index.aiColumn */
+ sizeof(u8)*nCol); /* Index.aSortOrder */
+ p = sqlite3DbMallocZero(db, nByte + nExtra);
+ if( p ){
+ char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
+ p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
+ p->aiRowEst = (tRowcnt*)pExtra; pExtra += sizeof(tRowcnt)*(nCol+1);
+ p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
+ p->aSortOrder = (u8*)pExtra;
+ p->nColumn = nCol;
+ p->nKeyCol = nCol - 1;
+ *ppExtra = ((char*)p) + nByte;
+ }
+ return p;
+}
/*
** Create a new index for an SQL table. pName1.pName2 is the name of the index
** and pTblList is the name of the table that is to be indexed. Both will
** be NULL for a primary key or an index that is created to satisfy a
@@ -86300,22 +87034,22 @@
Table *pTab = 0; /* Table to be indexed */
Index *pIndex = 0; /* The index to be created */
char *zName = 0; /* Name of the index */
int nName; /* Number of characters in zName */
int i, j;
- Token nullId; /* Fake token for an empty ID list */
DbFixer sFix; /* For assigning database names to pTable */
int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */
sqlite3 *db = pParse->db;
Db *pDb; /* The specific table containing the indexed database */
int iDb; /* Index of the database that is being written */
Token *pName = 0; /* Unqualified name of the index to create */
struct ExprList_item *pListItem; /* For looping over pList */
const Column *pTabCol; /* A column in the table */
- int nCol; /* Number of columns */
int nExtra = 0; /* Space allocated for zExtra[] */
+ int nExtraCol; /* Number of extra columns needed */
char *zExtra; /* Extra space after the Index object */
+ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
assert( pParse->nErr==0 ); /* Never called with prior errors */
if( db->mallocFailed || IN_DECLARE_VTAB ){
goto exit_create_index;
}
@@ -86363,10 +87097,11 @@
sqlite3ErrorMsg(pParse,
"cannot create a TEMP index on non-TEMP table \"%s\"",
pTab->zName);
goto exit_create_index;
}
+ if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab);
}else{
assert( pName==0 );
assert( pStart==0 );
pTab = pParse->pNewTable;
if( !pTab ) goto exit_create_index;
@@ -86458,15 +87193,14 @@
/* If pList==0, it means this routine was called to make a primary
** key out of the last column added to the table under construction.
** So create a fake list to simulate this.
*/
if( pList==0 ){
- nullId.z = pTab->aCol[pTab->nCol-1].zName;
- nullId.n = sqlite3Strlen30((char*)nullId.z);
pList = sqlite3ExprListAppend(pParse, 0, 0);
if( pList==0 ) goto exit_create_index;
- sqlite3ExprListSetName(pParse, pList, &nullId, 0);
+ pList->a[0].zName = sqlite3DbStrDup(pParse->db,
+ pTab->aCol[pTab->nCol-1].zName);
pList->a[0].sortOrder = (u8)sortOrder;
}
/* Figure out how many bytes of space are required to store explicitly
** specified collation sequence names.
@@ -86481,40 +87215,27 @@
/*
** Allocate the index structure.
*/
nName = sqlite3Strlen30(zName);
- nCol = pList->nExpr;
- pIndex = sqlite3DbMallocZero(db,
- ROUND8(sizeof(Index)) + /* Index structure */
- ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */
- sizeof(char *)*nCol + /* Index.azColl */
- sizeof(int)*nCol + /* Index.aiColumn */
- sizeof(u8)*nCol + /* Index.aSortOrder */
- nName + 1 + /* Index.zName */
- nExtra /* Collation sequence names */
- );
+ nExtraCol = pPk ? pPk->nKeyCol : 1;
+ pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol,
+ nName + nExtra + 1, &zExtra);
if( db->mallocFailed ){
goto exit_create_index;
}
- zExtra = (char*)pIndex;
- pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))];
- pIndex->azColl = (char**)
- ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
- pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
- pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
- pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
- zExtra = (char *)(&pIndex->zName[nName+1]);
+ pIndex->zName = zExtra;
+ zExtra += nName + 1;
memcpy(pIndex->zName, zName, nName+1);
pIndex->pTable = pTab;
- pIndex->nColumn = pList->nExpr;
pIndex->onError = (u8)onError;
- pIndex->uniqNotNull = onError==OE_Abort;
+ pIndex->uniqNotNull = onError!=OE_None;
pIndex->autoIndex = (u8)(pName==0);
pIndex->pSchema = db->aDb[iDb].pSchema;
+ pIndex->nKeyCol = pList->nExpr;
if( pPIWhere ){
sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
pIndex->pPartIdxWhere = pPIWhere;
pPIWhere = 0;
}
@@ -86550,11 +87271,12 @@
sqlite3ErrorMsg(pParse, "table %s has no column named %s",
pTab->zName, zColName);
pParse->checkSchema = 1;
goto exit_create_index;
}
- pIndex->aiColumn[i] = j;
+ assert( pTab->nCol<=0x7fff && j<=0x7fff );
+ pIndex->aiColumn[i] = (i16)j;
if( pListItem->pExpr ){
int nColl;
assert( pListItem->pExpr->op==TK_COLLATE );
zColl = pListItem->pExpr->u.zToken;
nColl = sqlite3Strlen30(zColl) + 1;
@@ -86573,10 +87295,27 @@
pIndex->azColl[i] = zColl;
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0;
}
+ if( pPk ){
+ for(j=0; jnKeyCol; j++){
+ int x = pPk->aiColumn[j];
+ if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
+ pIndex->nColumn--;
+ }else{
+ pIndex->aiColumn[i] = x;
+ pIndex->azColl[i] = pPk->azColl[j];
+ pIndex->aSortOrder[i] = pPk->aSortOrder[j];
+ i++;
+ }
+ }
+ assert( i==pIndex->nColumn );
+ }else{
+ pIndex->aiColumn[i] = -1;
+ pIndex->azColl[i] = "BINARY";
+ }
sqlite3DefaultRowEst(pIndex);
if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
if( pTab==pParse->pNewTable ){
/* This routine has been called to create an automatic index as a
@@ -86605,20 +87344,20 @@
int k;
assert( pIdx->onError!=OE_None );
assert( pIdx->autoIndex );
assert( pIndex->onError!=OE_None );
- if( pIdx->nColumn!=pIndex->nColumn ) continue;
- for(k=0; knColumn; k++){
+ if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue;
+ for(k=0; knKeyCol; k++){
const char *z1;
const char *z2;
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
z1 = pIdx->azColl[k];
z2 = pIndex->azColl[k];
if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
}
- if( k==pIdx->nColumn ){
+ if( k==pIdx->nKeyCol ){
if( pIdx->onError!=pIndex->onError ){
/* This constraint creates the same index as a previous
** constraint specified somewhere in the CREATE TABLE statement.
** However the ON CONFLICT clauses are different. If both this
** constraint and the previous equivalent constraint have explicit
@@ -86656,26 +87395,24 @@
if( pTblName!=0 ){
pIndex->tnum = db->init.newTnum;
}
}
- /* If the db->init.busy is 0 then create the index on disk. This
- ** involves writing the index into the master table and filling in the
- ** index with the current table contents.
- **
- ** The db->init.busy is 0 when the user first enters a CREATE INDEX
- ** command. db->init.busy is 1 when a database is opened and
- ** CREATE INDEX statements are read out of the master table. In
- ** the latter case the index already exists on disk, which is why
- ** we don't want to recreate it.
- **
- ** If pTblName==0 it means this index is generated as a primary key
- ** or UNIQUE constraint of a CREATE TABLE statement. Since the table
+ /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
+ ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
+ ** emit code to allocate the index rootpage on disk and make an entry for
+ ** the index in the sqlite_master table and populate the index with
+ ** content. But, do not do this if we are simply reading the sqlite_master
+ ** table to parse the schema, or if this index is the PRIMARY KEY index
+ ** of a WITHOUT ROWID table.
+ **
+ ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
+ ** or UNIQUE index in a CREATE TABLE statement. Since the table
** has just been created, it contains no data and the index initialization
** step can be skipped.
*/
- else if( pParse->nErr==0 ){
+ else if( pParse->nErr==0 && (HasRowid(pTab) || pTblName!=0) ){
Vdbe *v;
char *zStmt;
int iMem = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
@@ -86783,16 +87520,16 @@
tRowcnt n;
assert( a!=0 );
a[0] = pIdx->pTable->nRowEst;
if( a[0]<10 ) a[0] = 10;
n = 10;
- for(i=1; i<=pIdx->nColumn; i++){
+ for(i=1; i<=pIdx->nKeyCol; i++){
a[i] = n;
if( n>5 ) n--;
}
if( pIdx->onError!=OE_None ){
- a[pIdx->nColumn] = 1;
+ a[pIdx->nKeyCol] = 1;
}
}
/*
** This routine will drop an existing named index. This routine
@@ -87476,18 +88213,71 @@
SQLITE_PRIVATE void sqlite3HaltConstraint(
Parse *pParse, /* Parsing context */
int errCode, /* extended error code */
int onError, /* Constraint type */
char *p4, /* Error message */
- int p4type /* P4_STATIC or P4_TRANSIENT */
+ i8 p4type, /* P4_STATIC or P4_TRANSIENT */
+ u8 p5Errmsg /* P5_ErrMsg type */
){
Vdbe *v = sqlite3GetVdbe(pParse);
assert( (errCode&0xff)==SQLITE_CONSTRAINT );
if( onError==OE_Abort ){
sqlite3MayAbort(pParse);
}
sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
+ if( p5Errmsg ) sqlite3VdbeChangeP5(v, p5Errmsg);
+}
+
+/*
+** Code an OP_Halt due to UNIQUE or PRIMARY KEY constraint violation.
+*/
+SQLITE_PRIVATE void sqlite3UniqueConstraint(
+ Parse *pParse, /* Parsing context */
+ int onError, /* Constraint type */
+ Index *pIdx /* The index that triggers the constraint */
+){
+ char *zErr;
+ int j;
+ StrAccum errMsg;
+ Table *pTab = pIdx->pTable;
+
+ sqlite3StrAccumInit(&errMsg, 0, 0, 200);
+ errMsg.db = pParse->db;
+ for(j=0; jnKeyCol; j++){
+ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+ if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
+ sqlite3StrAccumAppend(&errMsg, pTab->zName, -1);
+ sqlite3StrAccumAppend(&errMsg, ".", 1);
+ sqlite3StrAccumAppend(&errMsg, zCol, -1);
+ }
+ zErr = sqlite3StrAccumFinish(&errMsg);
+ sqlite3HaltConstraint(pParse,
+ (pIdx->autoIndex==2)?SQLITE_CONSTRAINT_PRIMARYKEY:SQLITE_CONSTRAINT_UNIQUE,
+ onError, zErr, P4_DYNAMIC, P5_ConstraintUnique);
+}
+
+
+/*
+** Code an OP_Halt due to non-unique rowid.
+*/
+SQLITE_PRIVATE void sqlite3RowidConstraint(
+ Parse *pParse, /* Parsing context */
+ int onError, /* Conflict resolution algorithm */
+ Table *pTab /* The table with the non-unique rowid */
+){
+ char *zMsg;
+ int rc;
+ if( pTab->iPKey>=0 ){
+ zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName,
+ pTab->aCol[pTab->iPKey].zName);
+ rc = SQLITE_CONSTRAINT_PRIMARYKEY;
+ }else{
+ zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName);
+ rc = SQLITE_CONSTRAINT_ROWID;
+ }
+ sqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC,
+ P5_ConstraintUnique);
}
/*
** Check to see if pIndex uses the collating sequence pColl. Return
** true if it does and false if it does not.
@@ -87496,12 +88286,12 @@
static int collationMatch(const char *zColl, Index *pIndex){
int i;
assert( zColl!=0 );
for(i=0; inColumn; i++){
const char *z = pIndex->azColl[i];
- assert( z!=0 );
- if( 0==sqlite3StrICmp(z, zColl) ){
+ assert( z!=0 || pIndex->aiColumn[i]<0 );
+ if( pIndex->aiColumn[i]>=0 && 0==sqlite3StrICmp(z, zColl) ){
return 1;
}
}
return 0;
}
@@ -87616,39 +88406,53 @@
sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
}
#endif
/*
-** Return a dynamicly allocated KeyInfo structure that can be used
-** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
-**
-** If successful, a pointer to the new structure is returned. In this case
-** the caller is responsible for calling sqlite3DbFree(db, ) on the returned
-** pointer. If an error occurs (out of memory or missing collation
-** sequence), NULL is returned and the state of pParse updated to reflect
-** the error.
-*/
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
- int i;
- int nCol = pIdx->nColumn;
- KeyInfo *pKey;
-
- pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
- if( pKey ){
- for(i=0; iazColl[i];
- assert( zColl );
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
- pKey->aSortOrder[i] = pIdx->aSortOrder[i];
- }
- }
-
- if( pParse->nErr ){
- sqlite3DbFree(pParse->db, pKey);
- pKey = 0;
- }
- return pKey;
+** Return a KeyInfo structure that is appropriate for the given Index.
+**
+** The KeyInfo structure for an index is cached in the Index object.
+** So there might be multiple references to the returned pointer. The
+** caller should not try to modify the KeyInfo object.
+**
+** The caller should invoke sqlite3KeyInfoUnref() on the returned object
+** when it has finished using it.
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
+ if( pParse->nErr ) return 0;
+#ifndef SQLITE_OMIT_SHARED_CACHE
+ if( pIdx->pKeyInfo && pIdx->pKeyInfo->db!=pParse->db ){
+ sqlite3KeyInfoUnref(pIdx->pKeyInfo);
+ pIdx->pKeyInfo = 0;
+ }
+#endif
+ if( pIdx->pKeyInfo==0 ){
+ int i;
+ int nCol = pIdx->nColumn;
+ int nKey = pIdx->nKeyCol;
+ KeyInfo *pKey;
+ if( pIdx->uniqNotNull ){
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
+ }else{
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
+ }
+ if( pKey ){
+ assert( sqlite3KeyInfoIsWriteable(pKey) );
+ for(i=0; iazColl[i];
+ if( NEVER(zColl==0) ) zColl = "BINARY";
+ pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
+ pKey->aSortOrder[i] = pIdx->aSortOrder[i];
+ }
+ if( pParse->nErr ){
+ sqlite3KeyInfoUnref(pKey);
+ }else{
+ pIdx->pKeyInfo = pKey;
+ }
+ }
+ }
+ return sqlite3KeyInfoRef(pIdx->pKeyInfo);
}
/************** End of build.c ***********************************************/
/************** Begin file callback.c ****************************************/
/*
@@ -88264,11 +89068,11 @@
SrcList *pSrc, /* the FROM clause -- which tables to scan */
Expr *pWhere, /* The WHERE clause. May be null */
ExprList *pOrderBy, /* The ORDER BY clause. May be null */
Expr *pLimit, /* The LIMIT clause. May be null */
Expr *pOffset, /* The OFFSET clause. May be null */
- char *zStmtType /* Either DELETE or UPDATE. For error messages. */
+ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */
){
Expr *pWhereRowid = NULL; /* WHERE rowid .. */
Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
Expr *pSelectRowid = NULL; /* SELECT rowid ... */
ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */
@@ -88339,11 +89143,12 @@
sqlite3ExprListDelete(pParse->db, pOrderBy);
sqlite3ExprDelete(pParse->db, pLimit);
sqlite3ExprDelete(pParse->db, pOffset);
return 0;
}
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
+#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
+ /* && !defined(SQLITE_OMIT_SUBQUERY) */
/*
** Generate code for a DELETE FROM statement.
**
** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
@@ -88360,11 +89165,13 @@
const char *zDb; /* Name of database holding pTab */
int end, addr = 0; /* A couple addresses of generated code */
int i; /* Loop counter */
WhereInfo *pWInfo; /* Information about the WHERE clause */
Index *pIdx; /* For looping over indices of the table */
- int iCur; /* VDBE Cursor number for pTab */
+ int iTabCur; /* Cursor number for the table */
+ int iDataCur; /* VDBE cursor for the canonical data source */
+ int iIdxCur; /* Cursor number of the first index */
sqlite3 *db; /* Main database structure */
AuthContext sContext; /* Authorization context */
NameContext sNC; /* Name context to resolve expressions in */
int iDb; /* Database number */
int memCnt = -1; /* Memory cell used for change counting */
@@ -88425,11 +89232,11 @@
assert(!isView || pTrigger);
/* Assign cursor number to the table and all its indices.
*/
assert( pTabList->nSrc==1 );
- iCur = pTabList->a[0].iCursor = pParse->nTab++;
+ iTabCur = pTabList->a[0].iCursor = pParse->nTab++;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
pParse->nTab++;
}
/* Start the view context
@@ -88450,11 +89257,12 @@
/* If we are trying to delete from a view, realize that view into
** a ephemeral table.
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
+ sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur);
+ iDataCur = iIdxCur = iTabCur;
}
#endif
/* Resolve the column names in the WHERE clause.
*/
@@ -88481,22 +89289,78 @@
if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab)
&& 0==sqlite3FkRequired(pParse, pTab, 0, 0)
){
assert( !isView );
sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
- sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
- pTab->zName, P4_STATIC);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
+ pTab->zName, P4_STATIC);
+ }
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
assert( pIdx->pSchema==pTab->pSchema );
sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
}
}else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
- /* The usual case: There is a WHERE clause so we have to scan through
- ** the table and pick which records to delete.
- */
- {
+ if( !HasRowid(pTab) ){
+ /* There is a WHERE clause on a WITHOUT ROWID table.
+ */
+ Index *pPk; /* The PRIMARY KEY index on the table */
+ int iPk; /* First of nPk memory cells holding PRIMARY KEY value */
+ int iEph; /* Ephemeral table holding all primary key values */
+ int iKey; /* Key value inserting into iEph */
+ i16 nPk; /* Number of components of the PRIMARY KEY */
+
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+ iPk = pParse->nMem+1;
+ pParse->nMem += nPk;
+ iKey = ++pParse->nMem;
+ iEph = pParse->nTab++;
+
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 0, 0);
+ if( pWInfo==0 ) goto delete_from_cleanup;
+ for(i=0; iaiColumn[i],iPk+i);
+ }
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
+ sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, iKey);
+ if( db->flags & SQLITE_CountRows ){
+ sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
+ }
+ sqlite3WhereEnd(pWInfo);
+
+ /* Open cursors for all indices of the table.
+ */
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite,
+ iTabCur, &iDataCur, &iIdxCur);
+
+ /* Loop over the primary keys to be deleted. */
+ addr = sqlite3VdbeAddOp1(v, OP_Rewind, iEph);
+ sqlite3VdbeAddOp2(v, OP_RowKey, iEph, iPk);
+
+ /* Delete the row */
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ iPk, 0, 1, OE_Default, 0);
+
+ /* End of the delete loop */
+ sqlite3VdbeAddOp2(v, OP_Next, iEph, addr+1);
+ sqlite3VdbeJumpHere(v, addr);
+
+ /* Close the cursors open on the table and its indexes. */
+ assert( iDataCur>=iIdxCur );
+ for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ sqlite3VdbeAddOp1(v, OP_Close, iIdxCur+i);
+ }
+ }else{
+ /* There is a WHERE clause on a rowid table. Run a loop that extracts
+ ** all rowids to be deleted into a RowSet.
+ */
int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */
int iRowid = ++pParse->nMem; /* Used for storing rowid values. */
int regRowid; /* Actual register containing rowids */
/* Collect rowids of every row to be deleted.
@@ -88504,11 +89368,11 @@
sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
pWInfo = sqlite3WhereBegin(
pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0
);
if( pWInfo==0 ) goto delete_from_cleanup;
- regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0);
+ regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iRowid, 0);
sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid);
if( db->flags & SQLITE_CountRows ){
sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
}
sqlite3WhereEnd(pWInfo);
@@ -88521,11 +89385,14 @@
/* Unless this is a view, open cursors for the table we are
** deleting from and all its indices. If this is a view, then the
** only effect this statement has is to fire the INSTEAD OF
** triggers. */
if( !isView ){
- sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur,
+ &iDataCur, &iIdxCur);
+ assert( iDataCur==iTabCur );
+ assert( iIdxCur==iDataCur+1 );
}
addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
/* Delete the row */
@@ -88538,23 +89405,24 @@
sqlite3MayAbort(pParse);
}else
#endif
{
int count = (pParse->nested==0); /* True to count changes */
- sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ iRowid, 1, count, OE_Default, 0);
}
/* End of the delete loop */
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
sqlite3VdbeResolveLabel(v, end);
/* Close the cursors open on the table and its indexes. */
if( !isView && !IsVirtual(pTab) ){
- for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
+ sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
+ for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i);
}
- sqlite3VdbeAddOp1(v, OP_Close, iCur);
}
}
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
@@ -88590,48 +89458,56 @@
#undef pTrigger
#endif
/*
** This routine generates VDBE code that causes a single row of a
-** single table to be deleted.
+** single table to be deleted. Both the original table entry and
+** all indices are removed.
**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
+** Preconditions:
**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number $iCur.
+** 1. iDataCur is an open cursor on the btree that is the canonical data
+** store for the table. (This will be either the table itself,
+** in the case of a rowid table, or the PRIMARY KEY index in the case
+** of a WITHOUT ROWID table.)
**
** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number base+i for the i-th index.
+** cursor number iIdxCur+i for the i-th index.
**
-** 3. The record number of the row to be deleted must be stored in
-** memory cell iRowid.
-**
-** This routine generates code to remove both the table record and all
-** index entries that point to that record.
+** 3. The primary key for the row to be deleted must be stored in a
+** sequence of nPk memory cells starting at iPk. If nPk==0 that means
+** that a search record formed from OP_MakeRecord is contained in the
+** single memory location iPk.
*/
SQLITE_PRIVATE void sqlite3GenerateRowDelete(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table containing the row to be deleted */
- int iCur, /* Cursor number for the table */
- int iRowid, /* Memory cell that contains the rowid to delete */
- int count, /* If non-zero, increment the row change counter */
Trigger *pTrigger, /* List of triggers to (potentially) fire */
- int onconf /* Default ON CONFLICT policy for triggers */
+ int iDataCur, /* Cursor from which column data is extracted */
+ int iIdxCur, /* First index cursor */
+ int iPk, /* First memory cell containing the PRIMARY KEY */
+ i16 nPk, /* Number of PRIMARY KEY memory cells */
+ u8 count, /* If non-zero, increment the row change counter */
+ u8 onconf, /* Default ON CONFLICT policy for triggers */
+ u8 bNoSeek /* iDataCur is already pointing to the row to delete */
){
Vdbe *v = pParse->pVdbe; /* Vdbe */
int iOld = 0; /* First register in OLD.* array */
int iLabel; /* Label resolved to end of generated code */
+ u8 opSeek; /* Seek opcode */
/* Vdbe is guaranteed to have been allocated by this stage. */
assert( v );
+ VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",
+ iDataCur, iIdxCur, iPk, (int)nPk));
/* 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);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
+ opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+ if( !bNoSeek ) sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
/* If there are any triggers to fire, allocate a range of registers to
** use for the old.* references in the triggers. */
if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
u32 mask; /* Mask of OLD.* columns in use */
@@ -88646,14 +89522,14 @@
iOld = pParse->nMem+1;
pParse->nMem += (1 + pTab->nCol);
/* Populate the OLD.* pseudo-table register array. These values will be
** used by any BEFORE and AFTER triggers that exist. */
- sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld);
+ sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
for(iCol=0; iColnCol; iCol++){
if( mask==0xffffffff || mask&(1<pSelect==0 ){
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
if( count ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
}
}
@@ -88695,53 +89571,65 @@
/* Jump here if the row had already been deleted before any BEFORE
** trigger programs were invoked. Or if a trigger program throws a
** RAISE(IGNORE) exception. */
sqlite3VdbeResolveLabel(v, iLabel);
+ VdbeModuleComment((v, "END: GenRowDel()"));
}
/*
** This routine generates VDBE code that causes the deletion of all
-** index entries associated with a single row of a single table.
+** index entries associated with a single row of a single table, pTab
**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
+** Preconditions:
**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number "iCur".
+** 1. A read/write cursor "iDataCur" must be open on the canonical storage
+** btree for the table pTab. (This will be either the table itself
+** for rowid tables or to the primary key index for WITHOUT ROWID
+** tables.)
**
** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number iCur+i for the i-th index.
+** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex
+** index is the 0-th index.)
**
-** 3. The "iCur" cursor must be pointing to the row that is to be
-** deleted.
+** 3. The "iDataCur" cursor must be already be positioned on the row
+** that is to be deleted.
*/
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
Parse *pParse, /* Parsing and code generating context */
Table *pTab, /* Table containing the row to be deleted */
- int iCur, /* Cursor number for the table */
+ int iDataCur, /* Cursor of table holding data. */
+ int iIdxCur, /* First index cursor */
int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){
- int i;
- Index *pIdx;
- int r1;
- int iPartIdxLabel;
- Vdbe *v = pParse->pVdbe;
-
- for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
- sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
+ int i; /* Index loop counter */
+ int r1; /* Register holding an index key */
+ int iPartIdxLabel; /* Jump destination for skipping partial index entries */
+ Index *pIdx; /* Current index */
+ Vdbe *v; /* The prepared statement under construction */
+ Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */
+
+ v = pParse->pVdbe;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ assert( iIdxCur+i!=iDataCur || pPk==pIdx );
+ if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
+ if( pIdx==pPk ) continue;
+ VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel);
+ sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
+ pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
}
}
/*
-** Generate code that will assemble an index key and put it in register
+** Generate code that will assemble an index key and stores it in register
** regOut. The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
-** the entry that needs indexing.
+** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then
+** iCur must be the cursor of the PRIMARY KEY index.
**
** Return a register number which is the first in a block of
** registers that holds the elements of the index key. The
** block of registers has already been deallocated by the time
** this routine returns.
@@ -88754,56 +89642,58 @@
** sqlite3VdbeResolveLabel().
*/
SQLITE_PRIVATE int sqlite3GenerateIndexKey(
Parse *pParse, /* Parsing context */
Index *pIdx, /* The index for which to generate a key */
- int iCur, /* Cursor number for the pIdx->pTable table */
- int regOut, /* Write the new index key to this register */
- int doMakeRec, /* Run the OP_MakeRecord instruction if true */
+ int iDataCur, /* Cursor number from which to take column data */
+ int regOut, /* Put the new key into this register if not 0 */
+ int prefixOnly, /* Compute only a unique prefix of the key */
int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */
){
Vdbe *v = pParse->pVdbe;
int j;
Table *pTab = pIdx->pTable;
int regBase;
int nCol;
+ Index *pPk;
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
*piPartIdxLabel = sqlite3VdbeMakeLabel(v);
- pParse->iPartIdxTab = iCur;
+ pParse->iPartIdxTab = iDataCur;
sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
SQLITE_JUMPIFNULL);
}else{
*piPartIdxLabel = 0;
}
}
- nCol = pIdx->nColumn;
- regBase = sqlite3GetTempRange(pParse, nCol+1);
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
+ nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
+ regBase = sqlite3GetTempRange(pParse, nCol);
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
for(j=0; jaiColumn[j];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
+ i16 idx = pIdx->aiColumn[j];
+ if( pPk ) idx = sqlite3ColumnOfIndex(pPk, idx);
+ if( idx<0 || idx==pTab->iPKey ){
+ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regBase+j);
}else{
- sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
- sqlite3ColumnDefault(v, pTab, idx, -1);
+ sqlite3VdbeAddOp3(v, OP_Column, iDataCur, idx, regBase+j);
+ sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[j], -1);
}
}
- if( doMakeRec ){
+ if( regOut ){
const char *zAff;
if( pTab->pSelect
|| OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
){
zAff = 0;
}else{
zAff = sqlite3IndexAffinityStr(v, pIdx);
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
}
- sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
+ sqlite3ReleaseTempRange(pParse, regBase, nCol);
return regBase;
}
/************** End of delete.c **********************************************/
/************** Begin file func.c ********************************************/
@@ -88943,12 +89833,12 @@
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_INTEGER: {
i64 iVal = sqlite3_value_int64(argv[0]);
if( iVal<0 ){
if( (iVal<<1)==0 ){
- /* IMP: R-35460-15084 If X is the integer -9223372036854775807 then
- ** abs(X) throws an integer overflow error since there is no
+ /* IMP: R-31676-45509 If X is the integer -9223372036854775808
+ ** then abs(X) throws an integer overflow error since there is no
** equivalent positive 64-bit two complement value. */
sqlite3_result_error(context, "integer overflow", -1);
return;
}
iVal = -iVal;
@@ -90755,11 +91645,11 @@
if( !aiCol ) return 1;
*paiCol = aiCol;
}
for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){
+ if( pIdx->nKeyCol==nCol && pIdx->onError!=OE_None ){
/* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
** of columns. If each indexed column corresponds to a foreign key
** column of pFKey, then this index is a winner. */
if( zKey==0 ){
@@ -90778,11 +91668,11 @@
** map to an explicit list of columns in table pParent. Check if this
** index matches those columns. Also, check that the index uses
** the default collation sequences for each column. */
int i, j;
for(i=0; iaiColumn[i]; /* Index of column in parent tbl */
+ i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
char *zDfltColl; /* Def. collation for column */
char *zIdxCol; /* Name of indexed column */
/* If the index uses a collation sequence that is different from
** the default collation sequence for the column, this index is
@@ -90909,14 +91799,13 @@
sqlite3ReleaseTempReg(pParse, regTemp);
}else{
int nCol = pFKey->nCol;
int regTemp = sqlite3GetTempRange(pParse, nCol);
int regRec = sqlite3GetTempReg(pParse);
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
for(i=0; i0 && pFKey->isDeferred==0 ){
sqlite3ParseToplevel(pParse)->mayAbort = 1;
}
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
@@ -90975,10 +91863,66 @@
sqlite3VdbeResolveLabel(v, iOk);
sqlite3VdbeAddOp1(v, OP_Close, iCur);
}
+
+/*
+** Return an Expr object that refers to a memory register corresponding
+** to column iCol of table pTab.
+**
+** regBase is the first of an array of register that contains the data
+** for pTab. regBase itself holds the rowid. regBase+1 holds the first
+** column. regBase+2 holds the second column, and so forth.
+*/
+static Expr *exprTableRegister(
+ Parse *pParse, /* Parsing and code generating context */
+ Table *pTab, /* The table whose content is at r[regBase]... */
+ int regBase, /* Contents of table pTab */
+ i16 iCol /* Which column of pTab is desired */
+){
+ Expr *pExpr;
+ Column *pCol;
+ const char *zColl;
+ sqlite3 *db = pParse->db;
+
+ pExpr = sqlite3Expr(db, TK_REGISTER, 0);
+ if( pExpr ){
+ if( iCol>=0 && iCol!=pTab->iPKey ){
+ pCol = &pTab->aCol[iCol];
+ pExpr->iTable = regBase + iCol + 1;
+ pExpr->affinity = pCol->affinity;
+ zColl = pCol->zColl;
+ if( zColl==0 ) zColl = db->pDfltColl->zName;
+ pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl);
+ }else{
+ pExpr->iTable = regBase;
+ pExpr->affinity = SQLITE_AFF_INTEGER;
+ }
+ }
+ return pExpr;
+}
+
+/*
+** Return an Expr object that refers to column iCol of table pTab which
+** has cursor iCur.
+*/
+static Expr *exprTableColumn(
+ sqlite3 *db, /* The database connection */
+ Table *pTab, /* The table whose column is desired */
+ int iCursor, /* The open cursor on the table */
+ i16 iCol /* The column that is wanted */
+){
+ Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
+ if( pExpr ){
+ pExpr->pTab = pTab;
+ pExpr->iTable = iCursor;
+ pExpr->iColumn = iCol;
+ }
+ return pExpr;
+}
+
/*
** This function is called to generate code executed when a row is deleted
** from the parent table of foreign key constraint pFKey and, if pFKey is
** deferred, when a row is inserted into the same table. When generating
** code for an SQL UPDATE operation, this function may be called twice -
@@ -90990,31 +91934,31 @@
**
** Operation | FK type | Action taken
** --------------------------------------------------------------------------
** DELETE immediate Increment the "immediate constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-** throw a "foreign key constraint failed" exception.
+** throw a "FOREIGN KEY constraint failed" exception.
**
** INSERT immediate Decrement the "immediate constraint counter".
**
** DELETE deferred Increment the "deferred constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-** throw a "foreign key constraint failed" exception.
+** throw a "FOREIGN KEY constraint failed" exception.
**
** INSERT deferred Decrement the "deferred constraint counter".
**
** These operations are identified in the comment at the top of this file
** (fkey.c) as "I.2" and "D.2".
*/
static void fkScanChildren(
Parse *pParse, /* Parse context */
- SrcList *pSrc, /* SrcList containing the table to scan */
- Table *pTab,
- Index *pIdx, /* Foreign key index */
- FKey *pFKey, /* Foreign key relationship */
+ SrcList *pSrc, /* The child table to be scanned */
+ Table *pTab, /* The parent table */
+ Index *pIdx, /* Index on parent covering the foreign key */
+ FKey *pFKey, /* The foreign key linking pSrc to pTab */
int *aiCol, /* Map from pIdx cols to child table cols */
- int regData, /* Referenced table data starts here */
+ int regData, /* Parent row data starts here */
int nIncr /* Amount to increment deferred counter by */
){
sqlite3 *db = pParse->db; /* Database handle */
int i; /* Iterator variable */
Expr *pWhere = 0; /* WHERE clause to scan with */
@@ -91021,11 +91965,13 @@
NameContext sNameContext; /* Context used to resolve WHERE clause */
WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */
int iFkIfZero = 0; /* Address of OP_FkIfZero */
Vdbe *v = sqlite3GetVdbe(pParse);
- assert( !pIdx || pIdx->pTable==pTab );
+ assert( pIdx==0 || pIdx->pTable==pTab );
+ assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol );
+ assert( pIdx!=0 || pFKey->nCol==1 );
if( nIncr<0 ){
iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
}
@@ -91039,59 +91985,55 @@
*/
for(i=0; inCol; i++){
Expr *pLeft; /* Value from parent table row */
Expr *pRight; /* Column ref to child table */
Expr *pEq; /* Expression (pLeft = pRight) */
- int iCol; /* Index of column in child table */
+ i16 iCol; /* Index of column in child table */
const char *zCol; /* Name of column in child table */
- pLeft = sqlite3Expr(db, TK_REGISTER, 0);
- if( pLeft ){
- /* Set the collation sequence and affinity of the LHS of each TK_EQ
- ** expression to the parent key column defaults. */
- if( pIdx ){
- Column *pCol;
- const char *zColl;
- iCol = pIdx->aiColumn[i];
- pCol = &pTab->aCol[iCol];
- if( pTab->iPKey==iCol ) iCol = -1;
- pLeft->iTable = regData+iCol+1;
- pLeft->affinity = pCol->affinity;
- zColl = pCol->zColl;
- if( zColl==0 ) zColl = db->pDfltColl->zName;
- pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
- }else{
- pLeft->iTable = regData;
- pLeft->affinity = SQLITE_AFF_INTEGER;
- }
- }
+ iCol = pIdx ? pIdx->aiColumn[i] : -1;
+ pLeft = exprTableRegister(pParse, pTab, regData, iCol);
iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iCol>=0 );
zCol = pFKey->pFrom->aCol[iCol].zName;
pRight = sqlite3Expr(db, TK_ID, zCol);
pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
}
- /* If the child table is the same as the parent table, and this scan
- ** is taking place as part of a DELETE operation (operation D.2), omit the
- ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE
- ** clause, where $rowid is the rowid of the row being deleted. */
+ /* If the child table is the same as the parent table, then add terms
+ ** to the WHERE clause that prevent this entry from being scanned.
+ ** The added WHERE clause terms are like this:
+ **
+ ** $current_rowid!=rowid
+ ** 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,...)
+ */
if( pTab==pFKey->pFrom && nIncr>0 ){
- Expr *pEq; /* Expression (pLeft = pRight) */
+ Expr *pNe; /* Expression (pLeft != pRight) */
Expr *pLeft; /* Value from parent table row */
Expr *pRight; /* Column ref to child table */
- pLeft = sqlite3Expr(db, TK_REGISTER, 0);
- pRight = sqlite3Expr(db, TK_COLUMN, 0);
- if( pLeft && pRight ){
- pLeft->iTable = regData;
- pLeft->affinity = SQLITE_AFF_INTEGER;
- pRight->iTable = pSrc->a[0].iCursor;
- pRight->iColumn = -1;
- }
- pEq = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+ if( HasRowid(pTab) ){
+ pLeft = exprTableRegister(pParse, pTab, regData, -1);
+ pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
+ pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
+ }else{
+ Expr *pEq, *pAll = 0;
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ for(i=0; inKeyCol; i++){
+ i16 iCol = pIdx->aiColumn[i];
+ pLeft = exprTableRegister(pParse, pTab, regData, iCol);
+ pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
+ pAll = sqlite3ExprAnd(db, pAll, pEq);
+ }
+ pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0);
+ }
+ pWhere = sqlite3ExprAnd(db, pWhere, pNe);
}
/* Resolve the references in the WHERE clause. */
memset(&sNameContext, 0, sizeof(NameContext));
sNameContext.pSrcList = pSrc;
@@ -91117,12 +92059,12 @@
sqlite3VdbeJumpHere(v, iFkIfZero);
}
}
/*
-** This function returns a pointer to the head of a linked list of FK
-** constraints for which table pTab is the parent table. For example,
+** This function returns a linked list of FKey objects (connected by
+** FKey.pNextTo) holding all children of table pTab. For example,
** given the following schema:
**
** CREATE TABLE t1(a PRIMARY KEY);
** CREATE TABLE t2(b REFERENCES t1(a);
**
@@ -91209,12 +92151,11 @@
** constraints are violated.
*/
if( (db->flags & SQLITE_DeferFKs)==0 ){
sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
- OE_Abort, "foreign key constraint failed", P4_STATIC
- );
+ OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
}
if( iSkip ){
sqlite3VdbeResolveLabel(v, iSkip);
}
@@ -91420,11 +92361,12 @@
}
sqlite3DbFree(db, aiFree);
}
- /* Loop through all the foreign key constraints that refer to this table */
+ /* Loop through all the foreign key constraints that refer to this table.
+ ** (the "child" constraints) */
for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
Index *pIdx = 0; /* Foreign key index for pFKey */
SrcList *pSrc;
int *aiCol = 0;
@@ -91445,13 +92387,12 @@
if( !isIgnoreErrors || db->mallocFailed ) return;
continue;
}
assert( aiCol || pFKey->nCol==1 );
- /* Create a SrcList structure containing a single table (the table
- ** the foreign key that refers to this table is attached to). This
- ** is required for the sqlite3WhereXXX() interface. */
+ /* Create a SrcList structure containing the child table. We need the
+ ** child table as a SrcList for sqlite3WhereBegin() */
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
struct SrcList_item *pItem = pSrc->a;
pItem->pTab = pFKey->pFrom;
pItem->zName = pFKey->pFrom->zName;
@@ -91496,11 +92437,11 @@
}
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
Index *pIdx = 0;
sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
if( pIdx ){
- for(i=0; inColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
+ for(i=0; inKeyCol; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
}
}
}
return mask;
}
@@ -91688,11 +92629,11 @@
Token tFrom;
Expr *pRaise;
tFrom.z = zFrom;
tFrom.n = nFrom;
- pRaise = sqlite3Expr(db, TK_RAISE, "foreign key constraint failed");
+ pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
if( pRaise ){
pRaise->affinity = OE_Abort;
}
pSelect = sqlite3SelectNew(pParse,
sqlite3ExprListAppend(pParse, 0, pRaise),
@@ -91852,27 +92793,42 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
*/
/*
-** Generate code that will open a table for reading.
+** Generate code that will
+**
+** (1) acquire a lock for table pTab then
+** (2) open pTab as cursor iCur.
+**
+** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index
+** for that table that is actually opened.
*/
SQLITE_PRIVATE void sqlite3OpenTable(
- Parse *p, /* Generate code into this VDBE */
+ Parse *pParse, /* Generate code into this VDBE */
int iCur, /* The cursor number of the table */
int iDb, /* The database index in sqlite3.aDb[] */
Table *pTab, /* The table to be opened */
int opcode /* OP_OpenRead or OP_OpenWrite */
){
Vdbe *v;
assert( !IsVirtual(pTab) );
- v = sqlite3GetVdbe(p);
+ v = sqlite3GetVdbe(pParse);
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
- sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
- sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
- VdbeComment((v, "%s", pTab->zName));
+ sqlite3TableLock(pParse, iDb, pTab->tnum,
+ (opcode==OP_OpenWrite)?1:0, pTab->zName);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
+ VdbeComment((v, "%s", pTab->zName));
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ assert( pPk->tnum=pTab->tnum );
+ sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ VdbeComment((v, "%s", pTab->zName));
+ }
}
/*
** Return a pointer to the column affinity string associated with index
** pIdx. A column affinity string has one character for each column in
@@ -91904,19 +92860,19 @@
** up.
*/
int n;
Table *pTab = pIdx->pTable;
sqlite3 *db = sqlite3VdbeDb(v);
- pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
+ pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
if( !pIdx->zColAff ){
db->mallocFailed = 1;
return 0;
}
for(n=0; nnColumn; n++){
- pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
+ i16 x = pIdx->aiColumn[n];
+ pIdx->zColAff[n] = x<0 ? SQLITE_AFF_INTEGER : pTab->aCol[x].affinity;
}
- pIdx->zColAff[n++] = SQLITE_AFF_INTEGER;
pIdx->zColAff[n] = 0;
}
return pIdx->zColAff;
}
@@ -92258,11 +93214,11 @@
int onError, /* How to handle constraint errors */
int iDbDest /* The database of pDest */
);
/*
-** This routine is call to handle SQL of the following forms:
+** This routine is called to handle SQL of the following forms:
**
** insert into TABLE (IDLIST) values(EXPRLIST)
** insert into TABLE (IDLIST) select
**
** The IDLIST following the table name is always optional. If omitted,
@@ -92273,16 +93229,16 @@
** statement above, and pSelect is NULL. For the second form, pList is
** NULL and pSelect is a pointer to the select statement used to generate
** data for the insert.
**
** The code generated follows one of four templates. For a simple
-** select with data coming from a VALUES clause, the code executes
+** insert with data coming from a VALUES clause, the code executes
** once straight down through. Pseudo-code follows (we call this
** the "1st template"):
**
** open write cursor to and its indices
-** puts VALUES clause expressions onto the stack
+** put VALUES clause expressions into registers
** write the resulting record into
** cleanup
**
** The three remaining templates assume the statement is of the form
**
@@ -92376,12 +93332,13 @@
int i, j, idx; /* Loop counters */
Vdbe *v; /* Generate code into this virtual machine */
Index *pIdx; /* For looping over indices of the table */
int nColumn; /* Number of columns in the data */
int nHidden = 0; /* Number of hidden columns if TABLE is virtual */
- int baseCur = 0; /* VDBE Cursor number for pTab */
- int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
+ int iDataCur = 0; /* VDBE cursor that is the main data repository */
+ int iIdxCur = 0; /* First index cursor */
+ int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
int endOfLoop; /* Label for the end of the insertion loop */
int useTempTable = 0; /* Store SELECT results in intermediate table */
int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
int addrInsTop = 0; /* Jump to label "D" */
int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */
@@ -92388,10 +93345,11 @@
int addrSelect = 0; /* Address of coroutine that implements the SELECT */
SelectDest dest; /* Destination for SELECT on rhs of INSERT */
int iDb; /* Index of database holding TABLE */
Db *pDb; /* The database containing table being inserted into */
int appendFlag = 0; /* True if the insert is likely to be an append */
+ int withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */
int regRowCount = 0; /* Memory cell used for the row counter */
@@ -92427,10 +93385,11 @@
pDb = &db->aDb[iDb];
zDb = pDb->zName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
goto insert_cleanup;
}
+ withoutRowid = !HasRowid(pTab);
/* Figure out if we have any triggers and if the table being
** inserted into is a view
*/
#ifndef SQLITE_OMIT_TRIGGER
@@ -92446,20 +93405,17 @@
# define isView 0
#endif
assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
/* If pTab is really a view, make sure it has been initialized.
- ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual
- ** module table).
+ ** ViewGetColumnNames() is a no-op if pTab is not a view.
*/
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
goto insert_cleanup;
}
- /* Ensure that:
- * (a) the table is not read-only,
- * (b) that if it is a view then ON INSERT triggers exist
+ /* Cannot insert into a read-only table.
*/
if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
goto insert_cleanup;
}
@@ -92496,12 +93452,11 @@
** is coming from a SELECT statement, then generate a co-routine that
** produces a single row of the SELECT on each invocation. The
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
- /* Data is coming from a SELECT. Generate a co-routine to run that
- ** SELECT. */
+ /* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest);
if( rc ) goto insert_cleanup;
regEof = dest.iSDParm + 1;
regFromSelect = dest.iSdst;
@@ -92509,11 +93464,11 @@
nColumn = pSelect->pEList->nExpr;
assert( dest.nSdst==nColumn );
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
- ** FALSE if each* row of the SELECT can be written directly into
+ ** FALSE if each output row of the SELECT can be written directly into
** the destination table (template 3).
**
** A temp table must be used if the table being updated is also one
** of the tables being read by the SELECT statement. Also use a
** temp table in the case of row triggers.
@@ -92592,15 +93547,15 @@
/* If the INSERT statement included an IDLIST term, then make sure
** all elements of the IDLIST really are columns of the table and
** remember the column indices.
**
** If the table has an INTEGER PRIMARY KEY column and that column
- ** is named in the IDLIST, then record in the keyColumn variable
- ** the index into IDLIST of the primary key column. keyColumn is
+ ** is named in the IDLIST, then record in the ipkColumn variable
+ ** the index into IDLIST of the primary key column. ipkColumn is
** the index of the primary key as it appears in IDLIST, not as
- ** is appears in the original table. (The index of the primary
- ** key in the original table is pTab->iPKey.)
+ ** is appears in the original table. (The index of the INTEGER
+ ** PRIMARY KEY in the original table is pTab->iPKey.)
*/
if( pColumn ){
for(i=0; inId; i++){
pColumn->a[i].idx = -1;
}
@@ -92607,18 +93562,18 @@
for(i=0; inId; i++){
for(j=0; jnCol; j++){
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
pColumn->a[i].idx = j;
if( j==pTab->iPKey ){
- keyColumn = i;
+ ipkColumn = i; assert( !withoutRowid );
}
break;
}
}
if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pColumn->a[i].zName) ){
- keyColumn = i;
+ if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
+ ipkColumn = i;
}else{
sqlite3ErrorMsg(pParse, "table %S has no column named %s",
pTabList, 0, pColumn->a[i].zName);
pParse->checkSchema = 1;
goto insert_cleanup;
@@ -92626,15 +93581,15 @@
}
}
}
/* If there is no IDLIST term but the table has an integer primary
- ** key, the set the keyColumn variable to the primary key column index
- ** in the original table definition.
+ ** key, the set the ipkColumn variable to the integer primary key
+ ** column index in the original table definition.
*/
if( pColumn==0 && nColumn>0 ){
- keyColumn = pTab->iPKey;
+ ipkColumn = pTab->iPKey;
}
/* Initialize the count of rows to be inserted
*/
if( db->flags & SQLITE_CountRows ){
@@ -92643,13 +93598,12 @@
}
/* If this is not a view, open the table and and all indices */
if( !isView ){
int nIdx;
-
- baseCur = pParse->nTab;
- nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite);
+ nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1,
+ &iDataCur, &iIdxCur);
aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
if( aRegIdx==0 ){
goto insert_cleanup;
}
for(i=0; ia[keyColumn].pExpr, regCols);
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
}
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
@@ -92763,33 +93718,31 @@
pTab, regCols-pTab->nCol-1, onError, endOfLoop);
sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
}
- /* Push the record number for the new entry onto the stack. The
- ** record number is a randomly generate integer created by NewRowid
- ** except when the table has an INTEGER PRIMARY KEY column, in which
- ** case the record number is the same as that column.
+ /* Compute the content of the next row to insert into a range of
+ ** registers beginning at regIns.
*/
if( !isView ){
if( IsVirtual(pTab) ){
/* The row that the VUpdate opcode will delete: none */
sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
}
- if( keyColumn>=0 ){
+ if( ipkColumn>=0 ){
if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid);
+ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+ipkColumn, regRowid);
}else{
VdbeOp *pOp;
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
pOp = sqlite3VdbeGetOp(v, -1);
if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
appendFlag = 1;
pOp->opcode = OP_NewRowid;
- pOp->p1 = baseCur;
+ pOp->p1 = iDataCur;
pOp->p2 = regRowid;
pOp->p3 = regAutoinc;
}
}
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
@@ -92797,36 +93750,36 @@
*/
if( !appendFlag ){
int j1;
if( !IsVirtual(pTab) ){
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
sqlite3VdbeJumpHere(v, j1);
}else{
j1 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
}
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
}
- }else if( IsVirtual(pTab) ){
+ }else if( IsVirtual(pTab) || withoutRowid ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
}else{
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
appendFlag = 1;
}
autoIncStep(pParse, regAutoinc, regRowid);
- /* Push onto the stack, data for all columns of the new entry, beginning
+ /* Compute data for all columns of the new entry, beginning
** with the first column.
*/
nHidden = 0;
for(i=0; inCol; i++){
int iRegStore = regRowid+1+i;
if( i==pTab->iPKey ){
/* The value of the INTEGER PRIMARY KEY column is always a NULL.
- ** Whenever this column is read, the record number will be substituted
- ** in its place. So will fill this column with a NULL to avoid
+ ** Whenever this column is read, the rowid will be substituted
+ ** in its place. Hence, fill this column with a NULL to avoid
** taking up data space with information that will never be used. */
sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore);
continue;
}
if( pColumn==0 ){
@@ -92865,17 +93818,16 @@
sqlite3MayAbort(pParse);
}else
#endif
{
int isReplace; /* Set to true if constraints may cause a replace */
- sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx,
- keyColumn>=0, 0, onError, endOfLoop, &isReplace
+ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+ regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace
);
sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
- sqlite3CompleteInsertion(
- pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0
- );
+ sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+ regIns, aRegIdx, 0, appendFlag, isReplace==0);
}
}
/* Update the count of rows that are inserted
*/
@@ -92902,13 +93854,13 @@
sqlite3VdbeJumpHere(v, addrInsTop);
}
if( !IsVirtual(pTab) && !isView ){
/* Close all tables opened */
- sqlite3VdbeAddOp1(v, OP_Close, baseCur);
- for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
- sqlite3VdbeAddOp1(v, OP_Close, idx+baseCur);
+ if( iDataCurpIndex; pIdx; pIdx=pIdx->pNext, idx++){
+ sqlite3VdbeAddOp1(v, OP_Close, idx+iIdxCur);
}
}
insert_end:
/* Update the sqlite_sequence table by storing the content of the
@@ -92949,65 +93901,78 @@
#endif
#ifdef tmask
#undef tmask
#endif
-
/*
-** Generate code to do constraint checks prior to an INSERT or an UPDATE.
-**
-** The input is a range of consecutive registers as follows:
-**
-** 1. The rowid of the row after the update.
-**
-** 2. The data in the first column of the entry after the update.
-**
-** i. Data from middle columns...
-**
-** N. The data in the last column of the entry after the update.
-**
-** The regRowid parameter is the index of the register containing (1).
-**
-** If isUpdate is true and rowidChng is non-zero, then rowidChng contains
-** the address of a register containing the rowid before the update takes
-** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate
-** is false, indicating an INSERT statement, then a non-zero rowidChng
-** indicates that the rowid was explicitly specified as part of the
-** INSERT statement. If rowidChng is false, it means that the rowid is
-** computed automatically in an insert or that the rowid value is not
-** modified by an update.
-**
-** The code generated by this routine store new index entries into
+** Generate code to do constraint checks prior to an INSERT or an UPDATE
+** on table pTab.
+**
+** The regNewData parameter is the first register in a range that contains
+** the data to be inserted or the data after the update. There will be
+** pTab->nCol+1 registers in this range. The first register (the one
+** that regNewData points to) will contain the new rowid, or NULL in the
+** case of a WITHOUT ROWID table. The second register in the range will
+** contain the content of the first table column. The third register will
+** contain the content of the second table column. And so forth.
+**
+** The regOldData parameter is similar to regNewData except that it contains
+** the data prior to an UPDATE rather than afterwards. regOldData is zero
+** for an INSERT. This routine can distinguish between UPDATE and INSERT by
+** checking regOldData for zero.
+**
+** For an UPDATE, the pkChng boolean is true if the true primary key (the
+** rowid for a normal table or the PRIMARY KEY for a WITHOUT ROWID table)
+** might be modified by the UPDATE. If pkChng is false, then the key of
+** the iDataCur content table is guaranteed to be unchanged by the UPDATE.
+**
+** For an INSERT, the pkChng boolean indicates whether or not the rowid
+** was explicitly specified as part of the INSERT statement. If pkChng
+** is zero, it means that the either rowid is computed automatically or
+** that the table is a WITHOUT ROWID table and has no rowid. On an INSERT,
+** pkChng will only be true if the INSERT statement provides an integer
+** value for either the rowid column or its INTEGER PRIMARY KEY alias.
+**
+** The code generated by this routine will store new index entries into
** registers identified by aRegIdx[]. No index entry is created for
** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
** the same as the order of indices on the linked list of indices
-** attached to the table.
+** at pTab->pIndex.
+**
+** 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
+** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
+** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor
+** for the first index in the pTab->pIndex list. Cursors for other indices
+** are at iIdxCur+N for the N-th element of the pTab->pIndex list.
**
** This routine also generates code to check constraints. NOT NULL,
** CHECK, and UNIQUE constraints are all checked. If a constraint fails,
** then the appropriate action is performed. There are five possible
** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
**
** Constraint type Action What Happens
** --------------- ---------- ----------------------------------------
** any ROLLBACK The current transaction is rolled back and
-** sqlite3_exec() returns immediately with a
+** sqlite3_step() returns immediately with a
** return code of SQLITE_CONSTRAINT.
**
** any ABORT Back out changes from the current command
** only (do not do a complete rollback) then
-** cause sqlite3_exec() to return immediately
+** cause sqlite3_step() to return immediately
** with SQLITE_CONSTRAINT.
**
-** any FAIL Sqlite3_exec() returns immediately with a
+** any FAIL Sqlite3_step() returns immediately with a
** return code of SQLITE_CONSTRAINT. The
** transaction is not rolled back and any
-** prior changes are retained.
+** changes to prior rows are retained.
**
-** any IGNORE The record number and data is popped from
-** the stack and there is an immediate jump
-** to label ignoreDest.
+** any IGNORE The attempt in insert or update the current
+** row is skipped, without throwing an error.
+** Processing continues with the next row.
+** (There is an immediate jump to ignoreDest.)
**
** NOT NULL REPLACE The NULL value is replace by the default
** value for that column. If the default value
** is NULL, the action is the same as ABORT.
**
@@ -93018,48 +93983,61 @@
**
** Which action to take is determined by the overrideError parameter.
** Or if overrideError==OE_Default, then the pParse->onError parameter
** is used. Or if pParse->onError==OE_Default then the onError value
** for the constraint is used.
-**
-** The calling routine must open a read/write cursor for pTab with
-** cursor number "baseCur". All indices of pTab must also have open
-** read/write cursors with cursor number baseCur+i for the i-th cursor.
-** Except, if there is no possibility of a REPLACE action then
-** cursors do not need to be open for indices where aRegIdx[i]==0.
*/
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
- Parse *pParse, /* The parser context */
- Table *pTab, /* the table into which we are inserting */
- int baseCur, /* Index of a read/write cursor pointing at pTab */
- int regRowid, /* Index of the range of input registers */
- int *aRegIdx, /* Register used by each index. 0 for unused indices */
- int rowidChng, /* True if the rowid might collide with existing entry */
- int isUpdate, /* True for UPDATE, False for INSERT */
- int overrideError, /* Override onError to this if not OE_Default */
- int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
- int *pbMayReplace /* OUT: Set to true if constraint may cause a replace */
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* The table being inserted or updated */
+ int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */
+ int iDataCur, /* Canonical data cursor (main table or PK index) */
+ int iIdxCur, /* First index cursor */
+ int regNewData, /* First register in a range holding values to insert */
+ int regOldData, /* Previous content. 0 for INSERTs */
+ u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */
+ u8 overrideError, /* Override onError to this if not OE_Default */
+ int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
+ int *pbMayReplace /* OUT: Set to true if constraint may cause a replace */
){
- int i; /* loop counter */
- Vdbe *v; /* VDBE under constrution */
- int nCol; /* Number of columns */
- int onError; /* Conflict resolution strategy */
- int j1; /* Addresss of jump instruction */
- int j2 = 0, j3; /* Addresses of jump instructions */
- int regData; /* Register containing first data column */
- int iCur; /* Table cursor number */
+ Vdbe *v; /* VDBE under constrution */
Index *pIdx; /* Pointer to one of the indices */
+ Index *pPk = 0; /* The PRIMARY KEY index */
sqlite3 *db; /* Database connection */
+ int i; /* loop counter */
+ int ix; /* Index loop counter */
+ int nCol; /* Number of columns */
+ int onError; /* Conflict resolution strategy */
+ int j1; /* Addresss of jump instruction */
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
- int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid;
+ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
+ int ipkTop = 0; /* Top of the rowid change constraint check */
+ int ipkBottom = 0; /* Bottom of the rowid change constraint check */
+ u8 isUpdate; /* True if this is an UPDATE operation */
+ isUpdate = regOldData!=0;
db = pParse->db;
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
nCol = pTab->nCol;
- regData = regRowid + 1;
+
+ /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for
+ ** normal rowid tables. nPkField is the number of key fields in the
+ ** pPk index or 1 for a rowid table. In other words, nPkField is the
+ ** number of fields in the true primary key of the table. */
+ if( HasRowid(pTab) ){
+ pPk = 0;
+ nPkField = 1;
+ }else{
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ nPkField = pPk->nKeyCol;
+ }
+
+ /* Record that this module has started */
+ VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
+ iDataCur, iIdxCur, regNewData, regOldData, pkChng));
/* Test all NOT NULL constraints.
*/
for(i=0; iiPKey ){
@@ -93078,28 +94056,28 @@
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|| onError==OE_Ignore || onError==OE_Replace );
switch( onError ){
case OE_Abort:
sqlite3MayAbort(pParse);
+ /* Fall through */
case OE_Rollback:
case OE_Fail: {
- char *zMsg;
- sqlite3VdbeAddOp3(v, OP_HaltIfNull,
- SQLITE_CONSTRAINT_NOTNULL, onError, regData+i);
- zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
- pTab->zName, pTab->aCol[i].zName);
- sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
+ char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
+ pTab->aCol[i].zName);
+ sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
+ regNewData+1+i, zMsg, P4_DYNAMIC);
+ sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
break;
}
case OE_Ignore: {
- sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
break;
}
default: {
assert( onError==OE_Replace );
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);
+ j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
sqlite3VdbeJumpHere(v, j1);
break;
}
}
}
@@ -93107,59 +94085,79 @@
/* Test all CHECK constraints
*/
#ifndef SQLITE_OMIT_CHECK
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
ExprList *pCheck = pTab->pCheck;
- pParse->ckBase = regData;
+ pParse->ckBase = regNewData+1;
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; inExpr; i++){
int allOk = sqlite3VdbeMakeLabel(v);
sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
}else{
- char *zConsName = pCheck->a[i].zName;
+ char *zName = pCheck->a[i].zName;
+ if( zName==0 ) zName = pTab->zName;
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
- if( zConsName ){
- zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
- }else{
- zConsName = 0;
- }
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
- onError, zConsName, P4_DYNAMIC);
+ onError, zName, P4_TRANSIENT,
+ P5_ConstraintCheck);
}
sqlite3VdbeResolveLabel(v, allOk);
}
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
- /* If we have an INTEGER PRIMARY KEY, make sure the primary key
- ** of the new record does not previously exist. Except, if this
- ** is an UPDATE and the primary key is not changing, that is OK.
+ /* If rowid is changing, make sure the new rowid does not previously
+ ** exist in the table.
*/
- if( rowidChng ){
+ if( pkChng && pPk==0 ){
+ int addrRowidOk = sqlite3VdbeMakeLabel(v);
+
+ /* Figure out what action to take in case of a rowid collision */
onError = pTab->keyConf;
if( overrideError!=OE_Default ){
onError = overrideError;
}else if( onError==OE_Default ){
onError = OE_Abort;
}
-
+
if( isUpdate ){
- j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
+ /* pkChng!=0 does not mean that the rowid has change, only that
+ ** it might have changed. Skip the conflict logic below if the rowid
+ ** is unchanged. */
+ sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
}
- j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
+
+ /* If the response to a rowid conflict is REPLACE but the response
+ ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
+ ** to defer the running of the rowid conflict checking until after
+ ** the UNIQUE constraints have run.
+ */
+ if( onError==OE_Replace && overrideError!=OE_Replace ){
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){
+ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto);
+ break;
+ }
+ }
+ }
+
+ /* Check to see if the new rowid already exists in the table. Skip
+ ** the following conflict logic if it does not. */
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
+
+ /* Generate code that deals with a rowid collision */
switch( onError ){
default: {
onError = OE_Abort;
/* Fall thru into the next case */
}
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
- onError, "PRIMARY KEY must be unique", P4_STATIC);
+ sqlite3RowidConstraint(pParse, onError, pTab);
break;
}
case OE_Replace: {
/* If there are DELETE triggers on this table and the
** recursive-triggers flag is set, call GenerateRowDelete() to
@@ -93187,123 +94185,162 @@
if( db->flags&SQLITE_RecTriggers ){
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
}
if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
sqlite3MultiWrite(pParse);
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
- );
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ regNewData, 1, 0, OE_Replace, 1);
}else if( pTab->pIndex ){
sqlite3MultiWrite(pParse);
- sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
}
seenReplace = 1;
break;
}
case OE_Ignore: {
- assert( seenReplace==0 );
+ /*assert( seenReplace==0 );*/
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
break;
}
}
- sqlite3VdbeJumpHere(v, j3);
- if( isUpdate ){
- sqlite3VdbeJumpHere(v, j2);
+ sqlite3VdbeResolveLabel(v, addrRowidOk);
+ if( ipkTop ){
+ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
+ sqlite3VdbeJumpHere(v, ipkTop);
}
}
/* Test all UNIQUE constraints by creating entries for each UNIQUE
** index and making sure that duplicate entries do not already exist.
- ** Add the new records to the indices as we go.
+ ** Compute the revised record entries for indices as we go.
+ **
+ ** This loop also handles the case of the PRIMARY KEY index for a
+ ** WITHOUT ROWID table.
*/
- for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
- int regIdx;
- int regR;
- int addrSkipRow = 0;
+ for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){
+ int regIdx; /* Range of registers hold conent for pIdx */
+ int regR; /* Range of registers holding conflicting PK */
+ int iThisCur; /* Cursor for this UNIQUE index */
+ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
- if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
+ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
+ iThisCur = iIdxCur+ix;
+ addrUniqueOk = sqlite3VdbeMakeLabel(v);
+ /* Skip partial indices for which the WHERE clause is not true */
if( pIdx->pPartIdxWhere ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
- addrSkipRow = sqlite3VdbeMakeLabel(v);
- pParse->ckBase = regData;
- sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
+ sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
+ pParse->ckBase = regNewData+1;
+ sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
SQLITE_JUMPIFNULL);
pParse->ckBase = 0;
}
- /* Create a key for accessing the index entry */
- regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
+ /* Create a record for this index entry as it should appear after
+ ** the insert or update. Store that record in the aRegIdx[ix] register
+ */
+ regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
for(i=0; inColumn; i++){
- int idx = pIdx->aiColumn[i];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
+ int iField = pIdx->aiColumn[i];
+ int x;
+ if( iField<0 || iField==pTab->iPKey ){
+ x = regNewData;
}else{
- sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
+ x = iField + regNewData + 1;
}
+ sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
+ VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
- sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
+ VdbeComment((v, "for %s", pIdx->zName));
+ sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
- /* Find out what action to take in case there is an indexing conflict */
+ /* In an UPDATE operation, if this index is the PRIMARY KEY index
+ ** of a WITHOUT ROWID table and there has been no change the
+ ** primary key, then no collision is possible. The collision detection
+ ** logic below can all be skipped. */
+ if( isUpdate && pPk==pIdx && pkChng==0 ){
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ continue;
+ }
+
+ /* Find out what action to take in case there is a uniqueness conflict */
onError = pIdx->onError;
if( onError==OE_None ){
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
- sqlite3VdbeResolveLabel(v, addrSkipRow);
+ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
continue; /* pIdx is not a UNIQUE index */
}
if( overrideError!=OE_Default ){
onError = overrideError;
}else if( onError==OE_Default ){
onError = OE_Abort;
}
- if( seenReplace ){
- if( onError==OE_Ignore ) onError = OE_Replace;
- else if( onError==OE_Fail ) onError = OE_Abort;
- }
/* Check to see if the new index entry will be unique */
- regR = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR);
- j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
- regR, SQLITE_INT_TO_PTR(regIdx),
- P4_INT32);
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
+ sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
+ regIdx, pIdx->nKeyCol);
+
+ /* Generate code to handle collisions */
+ regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
+ /* Conflict only if the rowid of the existing index entry
+ ** is different from old-rowid */
+ if( isUpdate ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
+ }
+ }else{
+ int x;
+ /* Extract the PRIMARY KEY from the end of the index entry and
+ ** store it in registers regR..regR+nPk-1 */
+ if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){
+ for(i=0; inKeyCol; i++){
+ x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
+ VdbeComment((v, "%s.%s", pTab->zName,
+ pTab->aCol[pPk->aiColumn[i]].zName));
+ }
+ }
+ if( isUpdate ){
+ /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
+ ** table, only conflict if the new PRIMARY KEY values are actually
+ ** different from the old.
+ **
+ ** For a UNIQUE index, only conflict if the PRIMARY KEY values
+ ** of the matched index row are different from the original PRIMARY
+ ** KEY values of this row before the update. */
+ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
+ int op = OP_Ne;
+ int regCmp = (pIdx->autoIndex==2 ? regIdx : regR);
+
+ for(i=0; inKeyCol; i++){
+ char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
+ x = pPk->aiColumn[i];
+ if( i==(pPk->nKeyCol-1) ){
+ addrJump = addrUniqueOk;
+ op = OP_Eq;
+ }
+ sqlite3VdbeAddOp4(v, op,
+ regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
+ );
+ }
+ }
+ }
/* Generate code that executes if the new index entry is not unique */
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|| onError==OE_Ignore || onError==OE_Replace );
switch( onError ){
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
- int j;
- StrAccum errMsg;
- const char *zSep;
- char *zErr;
-
- sqlite3StrAccumInit(&errMsg, 0, 0, 200);
- errMsg.db = db;
- zSep = pIdx->nColumn>1 ? "columns " : "column ";
- for(j=0; jnColumn; j++){
- char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
- sqlite3StrAccumAppend(&errMsg, zSep, -1);
- zSep = ", ";
- sqlite3StrAccumAppend(&errMsg, zCol, -1);
- }
- sqlite3StrAccumAppend(&errMsg,
- pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
- zErr = sqlite3StrAccumFinish(&errMsg);
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
- onError, zErr, 0);
- sqlite3DbFree(errMsg.db, zErr);
+ sqlite3UniqueConstraint(pParse, onError, pIdx);
break;
}
case OE_Ignore: {
- assert( seenReplace==0 );
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
break;
}
default: {
Trigger *pTrigger = 0;
@@ -93310,67 +94347,75 @@
assert( onError==OE_Replace );
sqlite3MultiWrite(pParse);
if( db->flags&SQLITE_RecTriggers ){
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
}
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
- );
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ regR, nPkField, 0, OE_Replace, pIdx==pPk);
seenReplace = 1;
break;
}
}
- sqlite3VdbeJumpHere(v, j3);
- sqlite3VdbeResolveLabel(v, addrSkipRow);
- sqlite3ReleaseTempReg(pParse, regR);
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+ if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
+ }
+ if( ipkTop ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
+ sqlite3VdbeJumpHere(v, ipkBottom);
}
- if( pbMayReplace ){
- *pbMayReplace = seenReplace;
- }
+ *pbMayReplace = seenReplace;
+ VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
-** A consecutive range of registers starting at regRowid contains the
+** A consecutive range of registers starting at regNewData contains the
** rowid and the content to be inserted.
**
** The arguments to this routine should be the same as the first six
** arguments to sqlite3GenerateConstraintChecks.
*/
SQLITE_PRIVATE void sqlite3CompleteInsertion(
Parse *pParse, /* The parser context */
Table *pTab, /* the table into which we are inserting */
- int baseCur, /* Index of a read/write cursor pointing at pTab */
- int regRowid, /* Range of content */
+ int iDataCur, /* Cursor of the canonical data source */
+ int iIdxCur, /* First index cursor */
+ int regNewData, /* Range of content */
int *aRegIdx, /* Register used by each index. 0 for unused indices */
int isUpdate, /* True for UPDATE, False for INSERT */
int appendBias, /* True if this is likely to be an append */
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
- int i;
- Vdbe *v;
- Index *pIdx;
- u8 pik_flags;
- int regData;
- int regRec;
+ 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 assemblied record for the table */
+ int i; /* Loop counter */
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
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;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
}
- sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
- if( useSeekResult ){
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
+ pik_flags = 0;
+ if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT;
+ if( pIdx->autoIndex==2 && !HasRowid(pTab) ){
+ assert( pParse->nested==0 );
+ pik_flags |= OPFLAG_NCHANGE;
}
+ if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags);
}
- regData = regRowid + 1;
+ if( !HasRowid(pTab) ) return;
+ regData = regNewData + 1;
regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
sqlite3TableAffinityStr(v, pTab);
sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
if( pParse->nested ){
@@ -93383,51 +94428,75 @@
pik_flags |= OPFLAG_APPEND;
}
if( useSeekResult ){
pik_flags |= OPFLAG_USESEEKRESULT;
}
- sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
if( !pParse->nested ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
}
sqlite3VdbeChangeP5(v, pik_flags);
}
/*
-** Generate code that will open cursors for a table and for all
-** indices of that table. The "baseCur" parameter is the cursor number used
-** for the table. Indices are opened on subsequent cursors.
+** Allocate cursors for the pTab table and all its indices and generate
+** code to open and initialized those cursors.
**
-** Return the number of indices on the table.
+** The cursor for the object that contains the complete data (normally
+** the table itself, but the PRIMARY KEY index in the case of a WITHOUT
+** ROWID table) is returned in *piDataCur. The first index cursor is
+** returned in *piIdxCur. The number of indices is returned.
+**
+** Use iBase as the first cursor (either the *piDataCur for rowid tables
+** or the first index for WITHOUT ROWID tables) if it is non-negative.
+** If iBase is negative, then allocate the next available cursor.
+**
+** For a rowid table, *piDataCur will be exactly one less than *piIdxCur.
+** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
+** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
+** pTab->pIndex list.
*/
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table to be opened */
- int baseCur, /* Cursor number assigned to the table */
- int op /* OP_OpenRead or OP_OpenWrite */
+ int op, /* OP_OpenRead or OP_OpenWrite */
+ int iBase, /* Use this for the table cursor, if there is one */
+ int *piDataCur, /* Write the database source cursor number here */
+ int *piIdxCur /* Write the first index cursor number here */
){
int i;
int iDb;
Index *pIdx;
Vdbe *v;
- if( IsVirtual(pTab) ) return 0;
+ assert( op==OP_OpenRead || op==OP_OpenWrite );
+ if( IsVirtual(pTab) ){
+ *piDataCur = 0;
+ *piIdxCur = 1;
+ return 0;
+ }
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
- sqlite3OpenTable(pParse, baseCur, iDb, pTab, op);
- for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
+ if( iBase<0 ) iBase = pParse->nTab;
+ if( HasRowid(pTab) ){
+ *piDataCur = iBase++;
+ sqlite3OpenTable(pParse, *piDataCur, iDb, pTab, op);
+ }else{
+ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName);
+ }
+ *piIdxCur = iBase;
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ int iIdxCur = iBase++;
assert( pIdx->pSchema==pTab->pSchema );
- sqlite3VdbeAddOp4(v, op, i+baseCur, pIdx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
+ if( pIdx->autoIndex==2 && !HasRowid(pTab) ) *piDataCur = iIdxCur;
+ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
}
- if( pParse->nTabnTab = baseCur+i;
- }
- return i-1;
+ if( iBase>pParse->nTab ) pParse->nTab = iBase;
+ return i;
}
#ifdef SQLITE_TEST
/*
@@ -93468,17 +94537,17 @@
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
assert( pDest && pSrc );
assert( pDest->pTable!=pSrc->pTable );
- if( pDest->nColumn!=pSrc->nColumn ){
+ if( pDest->nKeyCol!=pSrc->nKeyCol ){
return 0; /* Different number of columns */
}
if( pDest->onError!=pSrc->onError ){
return 0; /* Different conflict resolution strategies */
}
- for(i=0; inColumn; i++){
+ for(i=0; inKeyCol; i++){
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
return 0; /* Different columns indexed */
}
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
@@ -93533,14 +94602,13 @@
struct SrcList_item *pItem; /* An element of pSelect->pSrc */
int i; /* Loop counter */
int iDbSrc; /* The database of pSrc */
int iSrc, iDest; /* Cursors from source and destination */
int addr1, addr2; /* Loop addresses */
- int emptyDestTest; /* Address of test for empty pDest */
- int emptySrcTest; /* Address of test for empty pSrc */
+ int emptyDestTest = 0; /* Address of test for empty pDest */
+ int emptySrcTest = 0; /* Address of test for empty pSrc */
Vdbe *v; /* The VDBE we are building */
- KeyInfo *pKey; /* Key information for an index */
int regAutoinc; /* Memory register used by AUTOINC */
int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
int regData, regRowid; /* Registers holding data and rowid */
if( pSelect==0 ){
@@ -93606,10 +94674,13 @@
return 0; /* FROM clause does not contain a real table */
}
if( pSrc==pDest ){
return 0; /* tab1 and tab2 may not be the same table */
}
+ if( HasRowid(pDest)!=HasRowid(pSrc) ){
+ return 0; /* source and destination must both be WITHOUT ROWID or not */
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pSrc->tabFlags & TF_Virtual ){
return 0; /* tab2 must not be a virtual table */
}
#endif
@@ -93676,11 +94747,14 @@
v = sqlite3GetVdbe(pParse);
sqlite3CodeVerifySchema(pParse, iDbSrc);
iSrc = pParse->nTab++;
iDest = pParse->nTab++;
regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
+ regData = sqlite3GetTempReg(pParse);
+ regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
+ assert( HasRowid(pDest) || destHasUniqueIdx );
if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
){
/* In some circumstances, we are able to run the xfer optimization
@@ -93698,62 +94772,60 @@
** (3) onError is something other than OE_Abort and OE_Rollback.
*/
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0);
emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
sqlite3VdbeJumpHere(v, addr1);
- }else{
- emptyDestTest = 0;
- }
- sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
- emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
- regData = sqlite3GetTempReg(pParse);
- regRowid = sqlite3GetTempReg(pParse);
- if( pDest->iPKey>=0 ){
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
- onError, "PRIMARY KEY must be unique", P4_STATIC);
- sqlite3VdbeJumpHere(v, addr2);
- autoIncStep(pParse, regAutoinc, regRowid);
- }else if( pDest->pIndex==0 ){
- addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
- }else{
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- assert( (pDest->tabFlags & TF_Autoincrement)==0 );
- }
- sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
- sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
- sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
+ }
+ if( HasRowid(pSrc) ){
+ sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
+ emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
+ if( pDest->iPKey>=0 ){
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+ addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
+ sqlite3RowidConstraint(pParse, onError, pDest);
+ sqlite3VdbeJumpHere(v, addr2);
+ autoIncStep(pParse, regAutoinc, regRowid);
+ }else if( pDest->pIndex==0 ){
+ addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
+ }else{
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+ assert( (pDest->tabFlags & TF_Autoincrement)==0 );
+ }
+ sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
+ sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
+ sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
+ sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
+ sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
+ sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
+ }else{
+ sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
+ sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
+ }
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
assert( pSrcIdx );
- sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
- pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
- sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc,
- (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
+ sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
VdbeComment((v, "%s", pSrcIdx->zName));
- pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
- (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
+ sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}
sqlite3VdbeJumpHere(v, emptySrcTest);
sqlite3ReleaseTempReg(pParse, regRowid);
sqlite3ReleaseTempReg(pParse, regData);
- sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
if( emptyDestTest ){
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
sqlite3VdbeJumpHere(v, emptyDestTest);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
return 0;
@@ -95251,15 +96323,17 @@
{ /* zName: */ "auto_vacuum",
/* ePragTyp: */ PragTyp_AUTO_VACUUM,
/* ePragFlag: */ PragFlag_NeedSchema,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
{ /* zName: */ "automatic_index",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_AutoIndex },
+#endif
#endif
{ /* zName: */ "busy_timeout",
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
@@ -95267,22 +96341,26 @@
{ /* zName: */ "cache_size",
/* ePragTyp: */ PragTyp_CACHE_SIZE,
/* ePragFlag: */ PragFlag_NeedSchema,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "cache_spill",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_CacheSpill },
+#endif
{ /* zName: */ "case_sensitive_like",
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "checkpoint_fullfsync",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_CkptFullFSync },
+#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{ /* zName: */ "collation_list",
/* ePragTyp: */ PragTyp_COLLATION_LIST,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
@@ -95291,14 +96369,16 @@
{ /* zName: */ "compile_options",
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "count_changes",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_CountRows },
+#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
{ /* zName: */ "data_store_directory",
/* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
@@ -95313,20 +96393,24 @@
{ /* zName: */ "default_cache_size",
/* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
/* ePragFlag: */ PragFlag_NeedSchema,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
{ /* zName: */ "defer_foreign_keys",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_DeferFKs },
#endif
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "empty_result_callbacks",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_NullCallback },
+#endif
#if !defined(SQLITE_OMIT_UTF16)
{ /* zName: */ "encoding",
/* ePragTyp: */ PragTyp_ENCODING,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
@@ -95341,30 +96425,34 @@
{ /* zName: */ "foreign_key_list",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
/* ePragFlag: */ PragFlag_NeedSchema,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
{ /* zName: */ "foreign_keys",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_ForeignKeys },
+#endif
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{ /* zName: */ "freelist_count",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "full_column_names",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_FullColNames },
{ /* zName: */ "fullfsync",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_FullFSync },
+#endif
#if defined(SQLITE_HAS_CODEC)
{ /* zName: */ "hexkey",
/* ePragTyp: */ PragTyp_HEXKEY,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
@@ -95371,15 +96459,17 @@
{ /* zName: */ "hexrekey",
/* ePragTyp: */ PragTyp_HEXKEY,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_CHECK)
{ /* zName: */ "ignore_check_constraints",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_IgnoreChecks },
+#endif
#endif
#if !defined(SQLITE_OMIT_AUTOVACUUM)
{ /* zName: */ "incremental_vacuum",
/* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
/* ePragFlag: */ PragFlag_NeedSchema,
@@ -95415,14 +96505,16 @@
{ /* zName: */ "key",
/* ePragTyp: */ PragTyp_KEY,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "legacy_file_format",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_LegacyFileFmt },
+#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
{ /* zName: */ "lock_proxy_file",
/* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
@@ -95459,38 +96551,44 @@
{ /* zName: */ "parser_trace",
/* ePragTyp: */ PragTyp_PARSER_TRACE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "query_only",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_QueryOnly },
+#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
{ /* zName: */ "quick_check",
/* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
/* ePragFlag: */ PragFlag_NeedSchema,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "read_uncommitted",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_ReadUncommitted },
{ /* zName: */ "recursive_triggers",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_RecTriggers },
+#endif
#if defined(SQLITE_HAS_CODEC)
{ /* zName: */ "rekey",
/* ePragTyp: */ PragTyp_REKEY,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "reverse_unordered_selects",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_ReverseOrder },
+#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
{ /* zName: */ "schema_version",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
@@ -95499,27 +96597,31 @@
{ /* zName: */ "secure_delete",
/* ePragTyp: */ PragTyp_SECURE_DELETE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "short_column_names",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_ShortColNames },
+#endif
{ /* zName: */ "shrink_memory",
/* ePragTyp: */ PragTyp_SHRINK_MEMORY,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
{ /* zName: */ "soft_heap_limit",
/* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if defined(SQLITE_DEBUG)
{ /* zName: */ "sql_trace",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_SqlTrace },
+#endif
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{ /* zName: */ "stats",
/* ePragTyp: */ PragTyp_STATS,
/* ePragFlag: */ PragFlag_NeedSchema,
@@ -95551,10 +96653,11 @@
{ /* zName: */ "user_version",
/* ePragTyp: */ PragTyp_HEADER_VALUE,
/* ePragFlag: */ 0,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if defined(SQLITE_DEBUG)
{ /* zName: */ "vdbe_addoptrace",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_VdbeAddopTrace },
@@ -95568,10 +96671,11 @@
/* iArg: */ SQLITE_VdbeListing },
{ /* zName: */ "vdbe_trace",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_VdbeTrace },
+#endif
#endif
#if !defined(SQLITE_OMIT_WAL)
{ /* zName: */ "wal_autocheckpoint",
/* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
/* ePragFlag: */ 0,
@@ -95579,14 +96683,16 @@
{ /* zName: */ "wal_checkpoint",
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
/* ePragFlag: */ PragFlag_NeedSchema,
/* iArg: */ 0 },
#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{ /* zName: */ "writable_schema",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlag: */ 0,
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
+#endif
};
/* Number of pragmas: 56 on by default, 68 total. */
/* End of the automatically generated pragma table.
***************************************************************************/
@@ -96548,12 +97654,11 @@
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
int i, k;
int nHidden = 0;
Column *pCol;
- Index *pPk;
- for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
sqlite3VdbeSetNumCols(v, 6);
pParse->nMem = 6;
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
@@ -96632,12 +97737,12 @@
pParse->nMem = 3;
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
- for(i=0; inColumn; i++){
- int cnum = pIdx->aiColumn[i];
+ for(i=0; inKeyCol; i++){
+ i16 cnum = pIdx->aiColumn[i];
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
assert( pTab->nCol>cnum );
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
@@ -96804,13 +97909,12 @@
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
if( x==0 ){
if( pIdx==0 ){
sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
}else{
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
}
}else{
k = 0;
break;
}
@@ -96970,20 +98074,24 @@
assert( sqlite3SchemaMutexHeld(db, i, 0) );
pTbls = &db->aDb[i].pSchema->tblHash;
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx;
- sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
- cnt++;
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
+ VdbeComment((v, "%s", pTab->zName));
+ cnt++;
+ }
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
+ VdbeComment((v, "%s", pIdx->zName));
cnt++;
}
}
/* Make sure sufficient number of registers have been allocated */
- pParse->nMem = MAX( pParse->nMem, cnt+7 );
+ pParse->nMem = MAX( pParse->nMem, cnt+8 );
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
sqlite3VdbeChangeP5(v, (u8)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
@@ -96997,62 +98105,64 @@
/* Make sure all the indices are constructed correctly.
*/
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
- Index *pIdx;
+ Index *pIdx, *pPk;
int loopTop;
+ int iDataCur, iIdxCur;
if( pTab->pIndex==0 ) continue;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
sqlite3ExprCacheClear(pParse);
- sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */
- }
- pParse->nMem = MAX(pParse->nMem, 7+j);
- loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0) + 1;
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- int jmp2, jmp3;
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead,
+ 1, &iDataCur, &iIdxCur);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
+ }
+ pParse->nMem = MAX(pParse->nMem, 8+j);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0);
+ loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ int jmp2, jmp3, jmp4;
int r1;
- static const VdbeOpList idxErr[] = {
- { OP_AddImm, 1, -1, 0},
- { OP_String8, 0, 3, 0}, /* 1 */
- { OP_Rowid, 1, 4, 0},
- { OP_String8, 0, 5, 0}, /* 3 */
- { OP_String8, 0, 6, 0}, /* 4 */
- { OP_Concat, 4, 3, 3},
- { OP_Concat, 5, 3, 3},
- { OP_Concat, 6, 3, 3},
- { OP_ResultRow, 3, 1, 0},
- { OP_IfPos, 1, 0, 0}, /* 9 */
- { OP_Halt, 0, 0, 0},
- };
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
- sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1); /* increment entry count */
- jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
- addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
- sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
- sqlite3VdbeJumpHere(v, addr+9);
+ if( pPk==pIdx ) continue;
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
+ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1,
+ pIdx->nColumn);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
+ sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, " missing from index ",
+ P4_STATIC);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+ jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
+ sqlite3VdbeAddOp0(v, OP_Halt);
+ sqlite3VdbeJumpHere(v, jmp4);
sqlite3VdbeJumpHere(v, jmp2);
sqlite3VdbeResolveLabel(v, jmp3);
}
- sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop);
+ sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
"wrong # of entries in index ", P4_STATIC);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( pPk==pIdx ) continue;
addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeAddOp2(v, OP_Count, j+2, 3);
- sqlite3VdbeAddOp3(v, OP_Eq, 7+j, addr+8, 3);
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
+ sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
}
@@ -99096,28 +100206,61 @@
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
}
}
/*
-** Allocate a KeyInfo object sufficient for an index of N columns.
-**
-** Actually, always allocate one extra column for the rowid at the end
-** of the index. So the KeyInfo returned will have space sufficient for
-** N+1 columns.
+** Allocate a KeyInfo object sufficient for an index of N key columns and
+** X extra columns.
*/
-SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
- KeyInfo *p = sqlite3DbMallocZero(db,
- sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
+ KeyInfo *p = sqlite3DbMallocZero(0,
+ sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1));
if( p ){
- p->aSortOrder = (u8*)&p->aColl[N+1];
+ p->aSortOrder = (u8*)&p->aColl[N+X];
p->nField = (u16)N;
+ p->nXField = (u16)X;
p->enc = ENC(db);
p->db = db;
+ p->nRef = 1;
+ }else{
+ db->mallocFailed = 1;
+ }
+ return p;
+}
+
+/*
+** Deallocate a KeyInfo object
+*/
+SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){
+ if( p ){
+ assert( p->nRef>0 );
+ p->nRef--;
+ if( p->nRef==0 ) sqlite3DbFree(0, p);
+ }
+}
+
+/*
+** Make a new pointer to a KeyInfo object
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){
+ if( p ){
+ assert( p->nRef>0 );
+ p->nRef++;
}
return p;
}
+#ifdef SQLITE_DEBUG
+/*
+** Return TRUE if a KeyInfo object can be change. The KeyInfo object
+** can only be changed if this is just a single reference to the object.
+**
+** This routine is used only inside of assert() statements.
+*/
+SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; }
+#endif /* SQLITE_DEBUG */
+
/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
**
** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
@@ -99126,23 +100269,23 @@
** then the KeyInfo structure is appropriate for initializing a virtual
** index to implement a DISTINCT test.
**
** Space to hold the KeyInfo structure is obtain from malloc. The calling
** function is responsible for seeing that this structure is eventually
-** freed. Add the KeyInfo structure to the P4 field of an opcode using
-** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
+** freed.
*/
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
int nExpr;
KeyInfo *pInfo;
struct ExprList_item *pItem;
sqlite3 *db = pParse->db;
int i;
nExpr = pList->nExpr;
- pInfo = sqlite3KeyInfoAlloc(db, nExpr);
+ pInfo = sqlite3KeyInfoAlloc(db, nExpr, 1);
if( pInfo ){
+ assert( sqlite3KeyInfoIsWriteable(pInfo) );
for(i=0, pItem=pList->a; ipExpr);
if( !pColl ) pColl = db->pDfltColl;
pInfo->aColl[i] = pColl;
@@ -100281,11 +101424,11 @@
CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
int nCol; /* Number of columns in result set */
assert( p->pRightmost==p );
nCol = p->pEList->nExpr;
- pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);
+ pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
if( !pKeyInfo ){
rc = SQLITE_NOMEM;
goto multi_select_end;
}
for(i=0, apColl=pKeyInfo->aColl; iaddrOpenEphm[1]<0 );
break;
}
sqlite3VdbeChangeP2(v, addr, nCol);
- sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo),
+ P4_KEYINFO);
pLoop->addrOpenEphm[i] = -1;
}
}
- sqlite3DbFree(db, pKeyInfo);
+ sqlite3KeyInfoUnref(pKeyInfo);
}
multi_select_end:
pDest->iSdst = dest.iSdst;
pDest->nSdst = dest.nSdst;
@@ -100346,11 +101490,10 @@
SelectDest *pIn, /* Coroutine supplying data */
SelectDest *pDest, /* Where to send the data */
int regReturn, /* The return address register */
int regPrev, /* Previous result register. No uniqueness if 0 */
KeyInfo *pKeyInfo, /* For comparing with previous entry */
- int p4type, /* The p4 type for pKeyInfo */
int iBreak /* Jump here if we hit the LIMIT */
){
Vdbe *v = pParse->pVdbe;
int iContinue;
int addr;
@@ -100362,11 +101505,11 @@
*/
if( regPrev ){
int j1, j2;
j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
- (char*)pKeyInfo, p4type);
+ (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
}
@@ -100660,11 +101803,11 @@
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; iiOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->iOrderByCol - 1;
}
- pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);
+ pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1);
if( pKeyMerge ){
for(i=0; ia[i].pExpr;
if( pTerm->flags & EP_Collate ){
@@ -100673,10 +101816,11 @@
pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
if( pColl==0 ) pColl = db->pDfltColl;
pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
}
+ assert( sqlite3KeyInfoIsWriteable(pKeyMerge) );
pKeyMerge->aColl[i] = pColl;
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
}
}
}else{
@@ -100698,12 +101842,13 @@
int nExpr = p->pEList->nExpr;
assert( nOrderBy>=nExpr || db->mallocFailed );
regPrev = pParse->nMem+1;
pParse->nMem += nExpr+1;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
- pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);
+ pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1);
if( pKeyDup ){
+ assert( sqlite3KeyInfoIsWriteable(pKeyDup) );
for(i=0; iaColl[i] = multiSelectCollSeq(pParse, p, i);
pKeyDup->aSortOrder[i] = 0;
}
}
@@ -100781,21 +101926,22 @@
** select as the next output row of the compound select.
*/
VdbeNoopComment((v, "Output routine for A"));
addrOutA = generateOutputSubroutine(pParse,
p, &destA, pDest, regOutA,
- regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
+ regPrev, pKeyDup, labelEnd);
/* Generate a subroutine that outputs the current row of the B
** select as the next output row of the compound select.
*/
if( op==TK_ALL || op==TK_UNION ){
VdbeNoopComment((v, "Output routine for B"));
addrOutB = generateOutputSubroutine(pParse,
p, &destB, pDest, regOutB,
- regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
+ regPrev, pKeyDup, labelEnd);
}
+ sqlite3KeyInfoUnref(pKeyDup);
/* Generate a subroutine to run when the results from select A
** are exhausted and only data in select B remains.
*/
VdbeNoopComment((v, "eof-A subroutine"));
@@ -100870,11 +102016,11 @@
/* Implement the main merge loop
*/
sqlite3VdbeResolveLabel(v, labelCmpr);
sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
- (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
+ (char*)pKeyMerge, P4_KEYINFO);
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
/* Jump to the this point in order to terminate the query.
*/
@@ -102096,11 +103242,11 @@
"argument");
pFunc->iDistinct = -1;
}else{
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ (char*)pKeyInfo, P4_KEYINFO);
}
}
}
}
@@ -102551,11 +103697,11 @@
pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
pOrderBy->iECursor = pParse->nTab++;
p->addrOpenEphm[2] = addrSortIndex =
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ (char*)pKeyInfo, P4_KEYINFO);
}else{
addrSortIndex = -1;
}
/* If the output is destined for a temporary table, open that table.
@@ -102579,11 +103725,11 @@
if( p->selFlags & SF_Distinct ){
sDistinct.tabTnct = pParse->nTab++;
sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
sDistinct.tabTnct, 0, 0,
(char*)keyInfoFromExprList(pParse, p->pEList),
- P4_KEYINFO_HANDOFF);
+ P4_KEYINFO);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
}else{
sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
}
@@ -102703,11 +103849,11 @@
*/
sAggInfo.sortingIdx = pParse->nTab++;
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
- 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ 0, (char*)pKeyInfo, P4_KEYINFO);
/* Initialize memory locations used by GROUP BY aggregate processing
*/
iUseFlag = ++pParse->nMem;
iAbortFlag = ++pParse->nMem;
@@ -102817,11 +103963,11 @@
sAggInfo.directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
}
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
- (char*)pKeyInfo, P4_KEYINFO);
+ (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
j1 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
/* Generate code that runs whenever the GROUP BY changes.
** Changes in the GROUP BY are detected by the previous code
@@ -102943,17 +104089,17 @@
pBest = pIdx;
}
}
if( pBest ){
iRoot = pBest->tnum;
- pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest);
+ pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
}
/* Open a read-only cursor, execute the OP_Count, close the cursor. */
- sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb);
+ sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1);
if( pKeyInfo ){
- sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
}
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
explainSimpleCount(pParse, pTab, pBest);
}else
@@ -104155,11 +105301,11 @@
}
return 0;
}
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
** This function is used to add VdbeComment() annotations to a VDBE
** program. It is not used in production code, only for debugging.
*/
static const char *onErrorText(int onError){
@@ -104603,44 +105749,54 @@
Expr *pWhere, /* The WHERE clause. May be null */
int onError /* How to handle constraint errors */
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
- int addr = 0; /* VDBE instruction address of the start of the loop */
+ int addrTop = 0; /* VDBE instruction address of the start of the loop */
WhereInfo *pWInfo; /* Information about the WHERE clause */
Vdbe *v; /* The virtual database engine */
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 iCur; /* VDBE Cursor number of pTab */
+ int iDataCur; /* Cursor for the canonical data btree */
+ int iIdxCur; /* Cursor for the first index */
sqlite3 *db; /* The database structure */
int *aRegIdx = 0; /* One register assigned to each index to be updated */
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. */
- int chngRowid; /* True if the record number is being changed */
+ u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */
+ u8 chngRowid; /* Rowid changed in a normal table */
+ u8 chngKey; /* Either chngPk or chngRowid */
Expr *pRowidExpr = 0; /* Expression defining the new record number */
int openAll = 0; /* True if all indices need to be opened */
AuthContext sContext; /* The authorization context */
NameContext sNC; /* The name-context to resolve expressions in */
int iDb; /* Database containing the table being updated */
int okOnePass; /* True for one-pass algorithm without the FIFO */
int hasFK; /* True if foreign key processing is required */
+ int labelBreak; /* Jump here to break out of UPDATE loop */
+ int labelContinue; /* Jump here to continue next step of UPDATE loop */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True when updating a view (INSTEAD OF trigger) */
Trigger *pTrigger; /* List of triggers on pTab, if required */
int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
#endif
int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */
+ int iEph = 0; /* Ephemeral table holding all primary key values */
+ int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */
+ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
/* Register Allocations */
int regRowCount = 0; /* A count of rows changed */
int regOldRowid; /* The old rowid */
int regNewRowid; /* The new rowid */
int regNew; /* Content of the NEW.* table in triggers */
int regOld = 0; /* Content of OLD.* table in triggers */
int regRowSet = 0; /* Rowset of rows to be updated */
+ int regKey = 0; /* composite PRIMARY KEY value */
memset(&sContext, 0, sizeof(sContext));
db = pParse->db;
if( pParse->nErr || db->mallocFailed ){
goto update_cleanup;
@@ -104683,12 +105839,18 @@
/* Allocate a cursors for the main database table and for all indices.
** The index cursors might not be used, but if they are used they
** need to occur right after the database cursor. So go ahead and
** allocate enough space, just in case.
*/
- pTabList->a[0].iCursor = iCur = pParse->nTab++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ pTabList->a[0].iCursor = iDataCur = pParse->nTab++;
+ iIdxCur = iDataCur+1;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
+ if( pIdx->autoIndex==2 && pPk!=0 ){
+ iDataCur = pParse->nTab;
+ pTabList->a[0].iCursor = iDataCur;
+ }
pParse->nTab++;
}
/* Initialize the name-context */
memset(&sNC, 0, sizeof(sNC));
@@ -104699,27 +105861,29 @@
** of the UPDATE statement. Also find the column index
** for each column to be updated in the pChanges array. For each
** column to be updated, make sure we have authorization to change
** that column.
*/
- chngRowid = 0;
+ chngRowid = chngPk = 0;
for(i=0; inExpr; i++){
if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
goto update_cleanup;
}
for(j=0; jnCol; j++){
if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
if( j==pTab->iPKey ){
chngRowid = 1;
pRowidExpr = pChanges->a[i].pExpr;
+ }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){
+ chngPk = 1;
}
aXRef[j] = i;
break;
}
}
if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pChanges->a[i].zName) ){
+ if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){
j = -1;
chngRowid = 1;
pRowidExpr = pChanges->a[i].pExpr;
}else{
sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
@@ -104739,30 +105903,33 @@
aXRef[j] = -1;
}
}
#endif
}
+ assert( (chngRowid & chngPk)==0 );
+ assert( chngRowid==0 || chngRowid==1 );
+ assert( chngPk==0 || chngPk==1 );
+ chngKey = chngRowid + chngPk;
- hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngRowid);
+ hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
/* Allocate memory for the array aRegIdx[]. There is one entry in the
** array for each index associated with table being updated. Fill in
** the value with a register number for indices that are to be used
** and with zero for unused indices.
*/
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
if( nIdx>0 ){
aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
if( aRegIdx==0 ) goto update_cleanup;
}
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
- if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
+ if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
reg = ++pParse->nMem;
}else{
reg = 0;
- for(i=0; inColumn; i++){
+ for(i=0; inKeyCol; i++){
if( aXRef[pIdx->aiColumn[i]]>=0 ){
reg = ++pParse->nMem;
break;
}
}
@@ -104788,15 +105955,15 @@
#endif
/* Allocate required registers. */
regRowSet = ++pParse->nMem;
regOldRowid = regNewRowid = ++pParse->nMem;
- if( pTrigger || hasFK ){
+ if( chngPk || pTrigger || hasFK ){
regOld = pParse->nMem + 1;
pParse->nMem += pTab->nCol;
}
- if( chngRowid || pTrigger || hasFK ){
+ if( chngKey || pTrigger || hasFK ){
regNewRowid = ++pParse->nMem;
}
regNew = pParse->nMem + 1;
pParse->nMem += pTab->nCol;
@@ -104808,11 +105975,11 @@
/* If we are trying to update a view, realize that view into
** a ephemeral table.
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
+ sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur);
}
#endif
/* Resolve the column names in all the expressions in the
** WHERE clause.
@@ -104821,43 +105988,81 @@
goto update_cleanup;
}
/* Begin the database scan
*/
- sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
- pWInfo = sqlite3WhereBegin(
- pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, 0
- );
- if( pWInfo==0 ) goto update_cleanup;
- okOnePass = sqlite3WhereOkOnePass(pWInfo);
-
- /* Remember the rowid of every item to be updated.
- */
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid);
- if( !okOnePass ){
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
- }
-
- /* End the database scan loop.
- */
- sqlite3WhereEnd(pWInfo);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
+ pWInfo = sqlite3WhereBegin(
+ pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur
+ );
+ if( pWInfo==0 ) goto update_cleanup;
+ okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+
+ /* Remember the rowid of every item to be updated.
+ */
+ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
+ if( !okOnePass ){
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
+ }
+
+ /* End the database scan loop.
+ */
+ sqlite3WhereEnd(pWInfo);
+ }else{
+ int iPk; /* First of nPk memory cells holding PRIMARY KEY value */
+ i16 nPk; /* Number of components of the PRIMARY KEY */
+ int addrOpen; /* Address of the OpenEphemeral instruction */
+
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+ iPk = pParse->nMem+1;
+ pParse->nMem += nPk;
+ regKey = ++pParse->nMem;
+ iEph = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
+ addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
+ WHERE_ONEPASS_DESIRED, iIdxCur);
+ if( pWInfo==0 ) goto update_cleanup;
+ okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ for(i=0; iaiColumn[i],
+ iPk+i);
+ }
+ if( okOnePass ){
+ sqlite3VdbeChangeToNoop(v, addrOpen);
+ nKey = nPk;
+ regKey = iPk;
+ }else{
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
+ sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
+ }
+ sqlite3WhereEnd(pWInfo);
+ }
/* Initialize the count of updated rows
*/
if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
regRowCount = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
}
+ labelBreak = sqlite3VdbeMakeLabel(v);
if( !isView ){
/*
** Open every index that needs updating. Note that if any
** index could potentially invoke a REPLACE conflict resolution
** action, then we need to open all indices because we might need
** to be deleting some records.
*/
- if( !okOnePass ) sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite);
+ if( !okOnePass && HasRowid(pTab) ){
+ sqlite3OpenTable(pParse, iDataCur, iDb, pTab, OP_OpenWrite);
+ }
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
if( onError==OE_Replace ){
openAll = 1;
}else{
openAll = 0;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -104866,59 +106071,71 @@
break;
}
}
}
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ int iThisCur = iIdxCur+i;
assert( aRegIdx );
- if( openAll || aRegIdx[i]>0 ){
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- assert( pParse->nTab>iCur+i+1 );
+ if( (openAll || aRegIdx[i]>0)
+ && iThisCur!=aiCurOnePass[1]
+ ){
+ assert( iThisCur!=aiCurOnePass[0] );
+ sqlite3VdbeAddOp3(v, OP_OpenWrite, iThisCur, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ assert( pParse->nTab>iThisCur );
+ VdbeComment((v, "%s", pIdx->zName));
+ if( okOnePass && pPk && iThisCur==iDataCur ){
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak,
+ regKey, nKey);
+ }
}
}
}
/* Top of the update loop */
if( okOnePass ){
- int a1 = sqlite3VdbeAddOp1(v, OP_NotNull, regOldRowid);
- addr = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, a1);
+ labelContinue = labelBreak;
+ sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+ }else if( pPk ){
+ labelContinue = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak);
+ addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
}else{
- addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid);
+ labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
+ regOldRowid);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
}
- /* Make cursor iCur point to the record that is being updated. If
- ** this record does not exist for some reason (deleted by a trigger,
- ** for example, then jump to the next iteration of the RowSet loop. */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
-
/* If the record number will change, set register regNewRowid to
** contain the new value. If the record number is not being modified,
** then regNewRowid is the same register as regOldRowid, which is
** already populated. */
- assert( chngRowid || pTrigger || hasFK || regOldRowid==regNewRowid );
+ assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
if( chngRowid ){
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
}
- /* If there are triggers on this table, populate an array of registers
- ** with the required old.* column data. */
- if( hasFK || pTrigger ){
+ /* Compute the old pre-UPDATE content of the row being changed, if that
+ ** information is needed */
+ if( chngPk || hasFK || pTrigger ){
u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0);
oldmask |= sqlite3TriggerColmask(pParse,
pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
);
for(i=0; inCol; i++){
- if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
+ ){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
}
}
- if( chngRowid==0 ){
+ if( chngRowid==0 && pPk==0 ){
sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
}
}
/* Populate the array of registers beginning at regNew with the new
@@ -104951,12 +106168,11 @@
** if there are one or more BEFORE triggers that use this value via
** a new.* reference in a trigger program.
*/
testcase( i==31 );
testcase( i==32 );
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
- sqlite3ColumnDefault(v, pTab, i, regNew+i);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
}
}
}
/* Fire any BEFORE UPDATE triggers. This happens before constraints are
@@ -104964,67 +106180,85 @@
*/
if( tmask&TRIGGER_BEFORE ){
sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
sqlite3TableAffinityStr(v, pTab);
sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_BEFORE, pTab, regOldRowid, onError, addr);
+ TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue);
/* The row-trigger may have deleted the row being updated. In this
** case, jump to the next row. No updates or AFTER triggers are
** required. This behavior - what happens when the row being updated
** is deleted or renamed by a BEFORE trigger - is left undefined in the
** documentation.
*/
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
+ if( pPk ){
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ }
/* If it did not delete it, the row-trigger may still have modified
** some of the columns of the row being updated. Load the values for
** all columns not modified by the update statement into their
** registers in case this has happened.
*/
for(i=0; inCol; i++){
if( aXRef[i]<0 && i!=pTab->iPKey ){
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
- sqlite3ColumnDefault(v, pTab, i, regNew+i);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
}
}
}
if( !isView ){
- int j1; /* Address of jump instruction */
+ int j1 = 0; /* Address of jump instruction */
+ int bReplace = 0; /* True if REPLACE conflict resolution might happen */
/* Do constraint checks. */
- sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
- aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);
+ assert( regOldRowid>0 );
+ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+ regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace);
/* Do FK constraint checks. */
if( hasFK ){
- sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngRowid);
+ sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
}
/* Delete the index entries associated with the current record. */
- j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
+ if( bReplace || chngKey ){
+ if( pPk ){
+ j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
+ }else{
+ j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
+ }
+ }
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
/* If changing the record number, delete the old record. */
- if( hasFK || chngRowid ){
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
+ if( hasFK || chngKey || pPk!=0 ){
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
}
- sqlite3VdbeJumpHere(v, j1);
+ if( bReplace || chngKey ){
+ if( sqlite3VdbeCurrentAddr(v)==j1+1 ){
+ sqlite3VdbeChangeToNoop(v, j1);
+ }else{
+ sqlite3VdbeJumpHere(v, j1);
+ }
+ }
if( hasFK ){
- sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngRowid);
+ sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);
}
/* Insert the new index entries and the new record. */
- sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0);
+ sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+ regNewRowid, aRegIdx, 1, 0, 0);
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
** handle rows (possibly in other tables) that refer via a foreign key
** to the row just updated. */
if( hasFK ){
- sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngRowid);
+ sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey);
}
}
/* Increment the row counter
*/
@@ -105031,26 +106265,33 @@
if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
}
sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_AFTER, pTab, regOldRowid, onError, addr);
+ TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue);
/* Repeat the above with the next record to be updated, until
** all record selected by the WHERE clause have been updated.
*/
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
- sqlite3VdbeJumpHere(v, addr);
+ if( okOnePass ){
+ /* Nothing to do at end-of-loop for a single-pass */
+ }else if( pPk ){
+ sqlite3VdbeResolveLabel(v, labelContinue);
+ sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
+ }
+ sqlite3VdbeResolveLabel(v, labelBreak);
/* Close all tables */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
assert( aRegIdx );
if( openAll || aRegIdx[i]>0 ){
- sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0);
}
}
- sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
+ if( iDataCur0"
+ " AND coalesce(rootpage,1)>0"
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = execExecSql(db, pzErrMsg,
"SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
" FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
@@ -105439,11 +106680,11 @@
rc = execExecSql(db, pzErrMsg,
"SELECT 'INSERT INTO vacuum_db.' || quote(name) "
"|| ' SELECT * FROM main.' || quote(name) || ';'"
"FROM main.sqlite_master "
"WHERE type = 'table' AND name!='sqlite_sequence' "
- " AND rootpage>0"
+ " AND coalesce(rootpage,1)>0"
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy over the sequence table
*/
@@ -107062,10 +108303,11 @@
u8 nLevel; /* Number of nested loop */
int iTop; /* The very beginning of the WHERE loop */
int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */
int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
+ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
WhereClause sWC; /* Decomposition of the WHERE clause */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
};
@@ -107154,12 +108396,23 @@
/*
** Return TRUE if an UPDATE or DELETE statement can operate directly on
** the rowids returned by a WHERE clause. Return FALSE if doing an
** UPDATE or DELETE might change subsequent WHERE clause results.
+**
+** If the ONEPASS optimization is used (if this routine returns true)
+** then also write the indices of open cursors used by ONEPASS
+** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data
+** table and iaCur[1] gets the cursor used by an auxiliary index.
+** Either value may be -1, indicating that cursor is not used.
+** Any cursors returned will have been opened for writing.
+**
+** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is
+** unable to use the ONEPASS optimization.
*/
-SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo){
+SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){
+ memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);
return pWInfo->okOnePass;
}
/*
** Move the content of pSrc into pDest
@@ -107531,11 +108784,14 @@
while( pScan->iEquiv<=pScan->nEquiv ){
iCur = pScan->aEquiv[pScan->iEquiv-2];
iColumn = pScan->aEquiv[pScan->iEquiv-1];
while( (pWC = pScan->pWC)!=0 ){
for(pTerm=pWC->a+k; knTerm; k++, pTerm++){
- if( pTerm->leftCursor==iCur && pTerm->u.leftColumn==iColumn ){
+ if( pTerm->leftCursor==iCur
+ && pTerm->u.leftColumn==iColumn
+ && (pScan->iEquiv<=2 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+ ){
if( (pTerm->eOperator & WO_EQUIV)!=0
&& pScan->nEquivaEquiv)
){
int j;
pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
@@ -107621,11 +108877,11 @@
pScan->pOrigWC = pWC;
pScan->pWC = pWC;
if( pIdx && iColumn>=0 ){
pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
- if( NEVER(j>=pIdx->nColumn) ) return 0;
+ if( NEVER(j>=pIdx->nKeyCol) ) return 0;
}
pScan->zCollName = pIdx->azColl[j];
}else{
pScan->idxaff = 0;
pScan->zCollName = 0;
@@ -108551,20 +109807,20 @@
** 3. All of those index columns for which the WHERE clause does not
** contain a "col=X" term are subject to a NOT NULL constraint.
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None ) continue;
- for(i=0; inColumn; i++){
- int iCol = pIdx->aiColumn[i];
+ for(i=0; inKeyCol; i++){
+ i16 iCol = pIdx->aiColumn[i];
if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
- if( iIdxCol<0 || pTab->aCol[pIdx->aiColumn[i]].notNull==0 ){
+ if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){
break;
}
}
}
- if( i==pIdx->nColumn ){
+ if( i==pIdx->nKeyCol ){
/* This index implies that the DISTINCT qualifier is redundant. */
return 1;
}
}
@@ -108616,10 +109872,11 @@
}
sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum);
sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr);
sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed);
sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost);
+ sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows);
}
#else
#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif
@@ -108658,26 +109915,25 @@
WhereClause *pWC, /* The WHERE clause */
struct SrcList_item *pSrc, /* The FROM clause term to get the next index */
Bitmask notReady, /* Mask of cursors that are not available */
WhereLevel *pLevel /* Write new index here */
){
- int nColumn; /* Number of columns in the constructed index */
+ int nKeyCol; /* Number of columns in the constructed index */
WhereTerm *pTerm; /* A single term of the WHERE clause */
WhereTerm *pWCEnd; /* End of pWC->a[] */
- int nByte; /* Byte of memory needed for pIdx */
Index *pIdx; /* Object describing the transient index */
Vdbe *v; /* Prepared statement under construction */
int addrInit; /* Address of the initialization bypass jump */
Table *pTable; /* The table being indexed */
- KeyInfo *pKeyinfo; /* Key information for the index */
int addrTop; /* Top of the index fill loop */
int regRecord; /* Register holding an index record */
int n; /* Column counter */
int i; /* Loop counter */
int mxBitCol; /* Maximum column in pSrc->colUsed */
CollSeq *pColl; /* Collating sequence to on a column */
WhereLoop *pLoop; /* The Loop object */
+ char *zNotUsed; /* Extra space on the end of pIdx */
Bitmask idxCols; /* Bitmap of columns used for indexing */
Bitmask extraCols; /* Bitmap of additional columns */
u8 sentWarning = 0; /* True if a warnning has been issued */
/* Generate code to skip over the creation and initialization of the
@@ -108686,11 +109942,11 @@
assert( v!=0 );
addrInit = sqlite3CodeOnce(pParse);
/* Count the number of columns that will be added to the index
** and used to match WHERE clause constraints */
- nColumn = 0;
+ nKeyCol = 0;
pTable = pSrc->pTab;
pWCEnd = &pWC->a[pWC->nTerm];
pLoop = pLevel->pWLoop;
idxCols = 0;
for(pTerm=pWC->a; pTermzName,
pTable->aCol[iCol].zName);
sentWarning = 1;
}
if( (idxCols & cMask)==0 ){
- if( whereLoopResize(pParse->db, pLoop, nColumn+1) ) return;
- pLoop->aLTerm[nColumn++] = pTerm;
+ if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ) return;
+ pLoop->aLTerm[nKeyCol++] = pTerm;
idxCols |= cMask;
}
}
}
- assert( nColumn>0 );
- pLoop->u.btree.nEq = pLoop->nLTerm = nColumn;
+ assert( nKeyCol>0 );
+ pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol;
pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
| WHERE_AUTO_INDEX;
/* Count the number of additional columns needed to create a
** covering index. A "covering index" is an index that contains all
@@ -108728,30 +109984,22 @@
extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol;
testcase( pTable->nCol==BMS-1 );
testcase( pTable->nCol==BMS-2 );
for(i=0; icolUsed & MASKBIT(BMS-1) ){
- nColumn += pTable->nCol - BMS + 1;
+ nKeyCol += pTable->nCol - BMS + 1;
}
pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;
/* Construct the Index object to describe this index */
- nByte = sizeof(Index);
- nByte += nColumn*sizeof(int); /* Index.aiColumn */
- nByte += nColumn*sizeof(char*); /* Index.azColl */
- nByte += nColumn; /* Index.aSortOrder */
- pIdx = sqlite3DbMallocZero(pParse->db, nByte);
+ pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
if( pIdx==0 ) return;
pLoop->u.btree.pIndex = pIdx;
- pIdx->azColl = (char**)&pIdx[1];
- pIdx->aiColumn = (int*)&pIdx->azColl[nColumn];
- pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn];
pIdx->zName = "auto-index";
- pIdx->nColumn = nColumn;
pIdx->pTable = pTable;
n = 0;
idxCols = 0;
for(pTerm=pWC->a; pTermaiColumn[n] = i;
pIdx->azColl[n] = "BINARY";
n++;
}
}
- assert( n==nColumn );
+ assert( n==nKeyCol );
+ pIdx->aiColumn[n] = -1;
+ pIdx->azColl[n] = "BINARY";
/* Create the automatic index */
- pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx);
assert( pLevel->iIdxCur>=0 );
pLevel->iIdxCur = pParse->nTab++;
- sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
- (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
regRecord = sqlite3GetTempReg(pParse);
- sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0);
+ sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite3VdbeJumpHere(v, addrTop);
@@ -109045,11 +110294,11 @@
iUpper = aSample[0].anLt[iCol];
}else{
iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol];
iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
}
- aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 1);
+ aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1);
if( iLower>=iUpper ){
iGap = 0;
}else{
iGap = iUpper - iLower;
}
@@ -109145,11 +110394,11 @@
** of iUpper are requested of whereKeyStats() and the smaller used.
*/
tRowcnt iLower;
tRowcnt iUpper;
- if( nEq==p->nColumn ){
+ if( nEq==p->nKeyCol ){
aff = SQLITE_AFF_INTEGER;
}else{
aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
}
/* Determine iLower and iUpper using ($P) only. */
@@ -109203,11 +110452,11 @@
}
if( nNewnOut = (LogEst)nOut;
- WHERETRACE(0x100, ("range scan regions: %u..%u est=%d\n",
+ WHERETRACE(0x10, ("range scan regions: %u..%u est=%d\n",
(u32)iLower, (u32)iUpper, nOut));
return SQLITE_OK;
}
}
#else
@@ -109263,11 +110512,11 @@
int rc; /* Subfunction return code */
tRowcnt a[2]; /* Statistics */
int bOk;
assert( nEq>=1 );
- assert( nEq<=(p->nColumn+1) );
+ assert( nEq<=(p->nKeyCol+1) );
assert( p->aSample!=0 );
assert( p->nSample>0 );
assert( pBuilder->nRecValidp->nColumn ){
+ if( nEq>p->nKeyCol ){
*pnRow = 1;
return SQLITE_OK;
}
aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity;
@@ -109289,11 +110538,11 @@
if( rc!=SQLITE_OK ) return rc;
if( bOk==0 ) return SQLITE_NOTFOUND;
pBuilder->nRecValid = nEq;
whereKeyStats(pParse, p, pRec, 0, a);
- WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1]));
+ WHERETRACE(0x10,("equality scan regions: %d\n", (int)a[1]));
*pnRow = a[1];
return rc;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
@@ -109337,11 +110586,11 @@
}
if( rc==SQLITE_OK ){
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
*pnRow = nRowEst;
- WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst));
+ WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst));
}
assert( pBuilder->nRecValid==nRecValid );
return rc;
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
@@ -109663,31 +110912,31 @@
static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
Index *pIndex = pLoop->u.btree.pIndex;
int nEq = pLoop->u.btree.nEq;
int i, j;
Column *aCol = pTab->aCol;
- int *aiColumn = pIndex->aiColumn;
+ i16 *aiColumn = pIndex->aiColumn;
StrAccum txt;
if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
return 0;
}
sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
txt.db = db;
sqlite3StrAccumAppend(&txt, " (", 2);
for(i=0; inColumn ) ? "rowid" : aCol[aiColumn[i]].zName;
+ char *z = (i==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[i]].zName;
explainAppendTerm(&txt, i, z, "=");
}
j = i;
if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
- char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
+ char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
explainAppendTerm(&txt, i++, z, ">");
}
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
- char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
+ char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
explainAppendTerm(&txt, i, z, "<");
}
sqlite3StrAccumAppend(&txt, ")", 1);
return sqlite3StrAccumFinish(&txt);
}
@@ -109810,11 +111059,11 @@
iCur = pTabItem->iCursor;
pLevel->notReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
bRev = (pWInfo->revMask>>iLevel)&1;
omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
&& (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
- VdbeNoopComment((v, "Begin Join Loop %d", iLevel));
+ VdbeNoopComment((v, "Begin WHERE-Loop %d: %s", iLevel,pTabItem->pTab->zName));
/* Create labels for the "break" and "continue" instructions
** for the current loop. Jump to addrBrk to break out of a loop.
** Jump to cont to go immediately to the next iteration of the
** loop.
@@ -110067,11 +111316,11 @@
** the first one after the nEq equality constraints in the index,
** this requires some special handling.
*/
if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
&& (pWInfo->bOBSat!=0)
- && (pIdx->nColumn>nEq)
+ && (pIdx->nKeyCol>nEq)
){
/* assert( pOrderBy->nExpr==1 ); */
/* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
isMinQuery = 1;
nExtraReg = 1;
@@ -110100,12 +111349,12 @@
/* If we are doing a reverse order scan on an ascending index, or
** a forward order scan on a descending index, interchange the
** start and end terms (pRangeStart and pRangeEnd).
*/
- if( (nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
- || (bRev && pIdx->nColumn==nEq)
+ if( (nEqnKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
+ || (bRev && pIdx->nKeyCol==nEq)
){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
}
testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
@@ -110210,15 +111459,26 @@
sqlite3ReleaseTempReg(pParse, r1);
/* Seek the table cursor, if required */
disableTerm(pLevel, pRangeStart);
disableTerm(pLevel, pRangeEnd);
- if( !omitTable ){
+ if( omitTable ){
+ /* pIdx is a covering index. No need to access the main table. */
+ }else if( HasRowid(pIdx->pTable) ){
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+ iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+ for(j=0; jnKeyCol; j++){
+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
+ }
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
+ iRowidReg, pPk->nKeyCol);
}
/* Record the instruction used to terminate the loop. Disable
** WHERE clause terms made redundant by the index range scan.
*/
@@ -110541,27 +111801,43 @@
}
sqlite3ReleaseTempReg(pParse, iReleaseReg);
return pLevel->notReady;
}
+
+#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
+/*
+** Generate "Explanation" text for a WhereTerm.
+*/
+static void whereExplainTerm(Vdbe *v, WhereTerm *pTerm){
+ char zType[4];
+ memcpy(zType, "...", 4);
+ if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
+ if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
+ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
+ sqlite3ExplainPrintf(v, "%s ", zType);
+ sqlite3ExplainExpr(v, pTerm->pExpr);
+}
+#endif /* WHERETRACE_ENABLED && SQLITE_ENABLE_TREE_EXPLAIN */
+
#ifdef WHERETRACE_ENABLED
/*
** Print a WhereLoop object for debugging purposes
*/
-static void whereLoopPrint(WhereLoop *p, SrcList *pTabList){
- int nb = 1+(pTabList->nSrc+7)/8;
- struct SrcList_item *pItem = pTabList->a + p->iTab;
+static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
+ WhereInfo *pWInfo = pWC->pWInfo;
+ int nb = 1+(pWInfo->pTabList->nSrc+7)/8;
+ struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
Table *pTab = pItem->pTab;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
p->iTab, nb, p->maskSelf, nb, p->prereq);
sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
- if( p->u.btree.pIndex ){
- const char *zName = p->u.btree.pIndex->zName;
- if( zName==0 ) zName = "ipk";
+ const char *zName;
+ if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
int i = sqlite3Strlen30(zName) - 1;
while( zName[i]!='_' ) i--;
zName += i;
}
@@ -110580,10 +111856,30 @@
sqlite3DebugPrintf(" %-19s", z);
sqlite3_free(z);
}
sqlite3DebugPrintf(" f %04x N %d", p->wsFlags, p->nLTerm);
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
+#ifdef SQLITE_ENABLE_TREE_EXPLAIN
+ /* If the 0x100 bit of wheretracing is set, then show all of the constraint
+ ** expressions in the WhereLoop.aLTerm[] array.
+ */
+ if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ /* WHERETRACE 0x100 */
+ int i;
+ Vdbe *v = pWInfo->pParse->pVdbe;
+ sqlite3ExplainBegin(v);
+ for(i=0; inLTerm; i++){
+ WhereTerm *pTerm = p->aLTerm[i];
+ sqlite3ExplainPrintf(v, " (%d) #%-2d ", i+1, (int)(pTerm-pWC->a));
+ sqlite3ExplainPush(v);
+ whereExplainTerm(v, pTerm);
+ sqlite3ExplainPop(v);
+ sqlite3ExplainNL(v);
+ }
+ sqlite3ExplainFinish(v);
+ sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
+ }
+#endif
}
#endif
/*
** Convert bulk memory into a valid WhereLoop that can be passed
@@ -110605,10 +111901,11 @@
sqlite3_free(p->u.vtab.idxStr);
p->u.vtab.needFree = 0;
p->u.vtab.idxStr = 0;
}else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
+ sqlite3KeyInfoUnref(p->u.btree.pIndex->pKeyInfo);
sqlite3DbFree(db, p->u.btree.pIndex);
p->u.btree.pIndex = 0;
}
}
}
@@ -110719,14 +112016,14 @@
u16 n = pBuilder->pOrSet->n;
int x =
#endif
whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
pTemplate->nOut);
-#if WHERETRACE_ENABLED
+#if WHERETRACE_ENABLED /* 0x8 */
if( sqlite3WhereTrace & 0x8 ){
sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
- whereLoopPrint(pTemplate, pWInfo->pTabList);
+ whereLoopPrint(pTemplate, pBuilder->pWC);
}
#endif
return SQLITE_OK;
}
@@ -110792,18 +112089,18 @@
/* If we reach this point it means that either p[] should be overwritten
** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
** WhereLoop and insert it.
*/
-#if WHERETRACE_ENABLED
+#if WHERETRACE_ENABLED /* 0x8 */
if( sqlite3WhereTrace & 0x8 ){
if( p!=0 ){
sqlite3DebugPrintf("ins-del: ");
- whereLoopPrint(p, pWInfo->pTabList);
+ whereLoopPrint(p, pBuilder->pWC);
}
sqlite3DebugPrintf("ins-new: ");
- whereLoopPrint(pTemplate, pWInfo->pTabList);
+ whereLoopPrint(pTemplate, pBuilder->pWC);
}
#endif
if( p==0 ){
p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
if( p==0 ) return SQLITE_NOMEM;
@@ -110820,14 +112117,14 @@
}
return SQLITE_OK;
/* Jump here if the insert is a no-op */
whereLoopInsert_noop:
-#if WHERETRACE_ENABLED
+#if WHERETRACE_ENABLED /* 0x8 */
if( sqlite3WhereTrace & 0x8 ){
sqlite3DebugPrintf("ins-noop: ");
- whereLoopPrint(pTemplate, pWInfo->pTabList);
+ whereLoopPrint(pTemplate, pBuilder->pWC);
}
#endif
return SQLITE_OK;
}
@@ -110904,12 +112201,12 @@
}else{
opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
}
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
- assert( pNew->u.btree.nEq<=pProbe->nColumn );
- if( pNew->u.btree.nEq < pProbe->nColumn ){
+ assert( pNew->u.btree.nEq<=pProbe->nKeyCol );
+ if( pNew->u.btree.nEq < pProbe->nKeyCol ){
iCol = pProbe->aiColumn[pNew->u.btree.nEq];
nRowEst = sqlite3LogEst(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1;
}else{
iCol = -1;
@@ -110962,11 +112259,11 @@
assert( (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0
|| nInMul==0 );
pNew->wsFlags |= WHERE_COLUMN_EQ;
if( iCol<0
|| (pProbe->onError!=OE_None && nInMul==0
- && pNew->u.btree.nEq==pProbe->nColumn-1)
+ && pNew->u.btree.nEq==pProbe->nKeyCol-1)
){
assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
pNew->wsFlags |= WHERE_ONEROW;
}
pNew->u.btree.nEq++;
@@ -111028,11 +112325,11 @@
/* Step cost for each output row */
pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut);
whereLoopOutputAdjust(pBuilder->pWC, pNew);
rc = whereLoopInsert(pBuilder, pNew);
if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
- && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0))
+ && pNew->u.btree.nEq<(pProbe->nKeyCol + (pProbe->zName!=0))
){
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
}
pNew->nOut = saved_nOut;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -111067,11 +112364,11 @@
if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
for(ii=0; iinExpr; ii++){
Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
if( pExpr->op!=TK_COLUMN ) return 0;
if( pExpr->iTable==iCursor ){
- for(jj=0; jjnColumn; jj++){
+ for(jj=0; jjnKeyCol; jj++){
if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
}
}
}
return 0;
@@ -111084,14 +112381,15 @@
static Bitmask columnsInIndex(Index *pIdx){
Bitmask m = 0;
int j;
for(j=pIdx->nColumn-1; j>=0; j--){
int x = pIdx->aiColumn[j];
- assert( x>=0 );
- testcase( x==BMS-1 );
- testcase( x==BMS-2 );
- if( x=0 ){
+ testcase( x==BMS-1 );
+ testcase( x==BMS-2 );
+ if( xpTab) );
if( pSrc->pIndex ){
/* An INDEXED BY clause specifies a particular index to use */
pProbe = pSrc->pIndex;
+ }else if( !HasRowid(pTab) ){
+ pProbe = pTab->pIndex;
}else{
/* There is no INDEXED BY clause. Create a fake Index object in local
** variable sPk to represent the rowid primary key index. Make this
** fake index the first in a chain of Index objects with all of the real
** indices to follow */
Index *pFirst; /* First of real indices on the table */
memset(&sPk, 0, sizeof(Index));
- sPk.nColumn = 1;
+ sPk.nKeyCol = 1;
sPk.aiColumn = &aiColumnPk;
sPk.aiRowEst = aiRowEstPk;
sPk.onError = OE_Replace;
sPk.pTable = pTab;
aiRowEstPk[0] = pTab->nRowEst;
@@ -111172,10 +112472,11 @@
if( !pBuilder->pOrSet
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
&& pSrc->pIndex==0
&& !pSrc->viaCoroutine
&& !pSrc->notIndexed
+ && HasRowid(pTab)
&& !pSrc->isCorrelated
){
/* Generate auto-index WhereLoops */
WhereTerm *pTerm;
WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
@@ -111234,18 +112535,25 @@
whereLoopOutputAdjust(pWC, pNew);
rc = whereLoopInsert(pBuilder, pNew);
pNew->nOut = rSize;
if( rc ) break;
}else{
- Bitmask m = pSrc->colUsed & ~columnsInIndex(pProbe);
- pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
+ Bitmask m;
+ if( pProbe->isCovering ){
+ pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
+ m = 0;
+ }else{
+ m = pSrc->colUsed & ~columnsInIndex(pProbe);
+ pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
+ }
/* Full scan via index */
if( b
+ || !HasRowid(pTab)
|| ( m==0
&& pProbe->bUnordered==0
- && pProbe->szIdxRowszTabRow
+ && (pProbe->szIdxRowszTabRow)
&& (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
&& sqlite3GlobalConfig.bUseCis
&& OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
)
){
@@ -111257,11 +112565,10 @@
** is smaller for smaller indices, thus favoring them.
*/
pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 +
(15*pProbe->szIdxRow)/pTab->szTabRow;
}else{
- assert( b!=0 );
/* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)
** which we will simplify to just N*log2(N) */
pNew->rRun = rSize + rLogSize;
}
whereLoopOutputAdjust(pWC, pNew);
@@ -111375,10 +112682,11 @@
pIdxInfo->idxStr = 0;
pIdxInfo->idxNum = 0;
pIdxInfo->needToFreeIdxStr = 0;
pIdxInfo->orderByConsumed = 0;
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
+ pIdxInfo->estimatedRows = 25;
rc = vtabBestIndex(pParse, pTab, pIdxInfo);
if( rc ) goto whereLoopAddVtab_exit;
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
pNew->prereq = 0;
mxTerm = -1;
@@ -111434,12 +112742,11 @@
pNew->u.vtab.idxStr = pIdxInfo->idxStr;
pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0)
&& pIdxInfo->orderByConsumed);
pNew->rSetup = 0;
pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
- /* TUNING: Every virtual table query returns 25 rows */
- pNew->nOut = 46; assert( 46==sqlite3LogEst(25) );
+ pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
whereLoopInsert(pBuilder, pNew);
if( pNew->u.vtab.needFree ){
sqlite3_free(pNew->u.vtab.idxStr);
pNew->u.vtab.needFree = 0;
}
@@ -111473,10 +112780,11 @@
if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
pWCEnd = pWC->a + pWC->nTerm;
pNew = pBuilder->pNew;
memset(&sSum, 0, sizeof(sSum));
pItem = pWInfo->pTabList->a + pNew->iTab;
+ if( !HasRowid(pItem->pTab) ) return SQLITE_OK;
iCur = pItem->iCursor;
for(pTerm=pWC->a; pTermeOperator & WO_OR)!=0
&& (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
@@ -111622,11 +112930,12 @@
u8 rev; /* Composite sort order */
u8 revIdx; /* Index sort order */
u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */
u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */
u8 isMatch; /* iColumn matches a term of the ORDER BY clause */
- u16 nColumn; /* Number of columns in pIndex */
+ u16 nKeyCol; /* Number of key columns in pIndex */
+ u16 nColumn; /* Total number of ordered columns in the index */
u16 nOrderBy; /* Number terms in the ORDER BY clause */
int iLoop; /* Index of WhereLoop in pPath being processed */
int i, j; /* Loop counters */
int iCur; /* Cursor number for current WhereLoop */
int iColumn; /* A column number within table iCur */
@@ -111714,24 +113023,28 @@
}
if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
if( pLoop->wsFlags & WHERE_IPK ){
pIndex = 0;
- nColumn = 0;
+ nKeyCol = 0;
+ nColumn = 1;
}else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
return 0;
}else{
+ nKeyCol = pIndex->nKeyCol;
nColumn = pIndex->nColumn;
+ assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
+ assert( pIndex->aiColumn[nColumn-1]==(-1) || !HasRowid(pIndex->pTable));
isOrderDistinct = pIndex->onError!=OE_None;
}
/* Loop through all columns of the index and deal with the ones
** that are not constrained by == or IN.
*/
rev = revSet = 0;
distinctColumns = 0;
- for(j=0; j<=nColumn; j++){
+ for(j=0; ju.btree.nEq
&& ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
@@ -111744,24 +113057,21 @@
}
/* Get the column number in the table (iColumn) and sort order
** (revIdx) for the j-th column of the index.
*/
- if( jaiColumn[j];
revIdx = pIndex->aSortOrder[j];
if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
}else{
- /* The ROWID column at the end */
- assert( j==nColumn );
iColumn = -1;
revIdx = 0;
}
/* An unconstrained column that might be NULL means that this
- ** WhereLoop is not well-ordered
+ ** WhereLoop is not well-ordered
*/
if( isOrderDistinct
&& iColumn>=0
&& j>=pLoop->u.btree.nEq
&& pIndex->pTable->aCol[iColumn].notNull==0
@@ -111808,11 +113118,11 @@
revSet = 1;
}
}
}else{
/* No match found */
- if( j==0 || j=nTo ){
if( nTo>=mxChoice && rCost>=mxCost ){
-#ifdef WHERETRACE_ENABLED
+#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
}
@@ -111999,20 +113309,20 @@
}else{
/* New path replaces the prior worst to keep count below mxChoice */
jj = mxI;
}
pTo = &aTo[jj];
-#ifdef WHERETRACE_ENABLED
+#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf("New %s cost=%-3d,%3d order=%c\n",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
}
#endif
}else{
if( pTo->rCost<=rCost && pTo->nRow<=nOut ){
-#ifdef WHERETRACE_ENABLED
+#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf(
"Skip %s cost=%-3d,%3d order=%c",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
@@ -112024,11 +113334,11 @@
testcase( pTo->rCost==rCost );
continue;
}
testcase( pTo->rCost==rCost+1 );
/* A new and better score for a previously created equivalent path */
-#ifdef WHERETRACE_ENABLED
+#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf(
"Update %s cost=%-3d,%3d order=%c",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
@@ -112060,11 +113370,11 @@
}
}
}
}
-#ifdef WHERETRACE_ENABLED
+#ifdef WHERETRACE_ENABLED /* >=2 */
if( sqlite3WhereTrace>=2 ){
sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
for(ii=0, pTo=aTo; iirCost, pTo->nRow,
@@ -112174,20 +113484,20 @@
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
assert( pLoop->aLTermSpace==pLoop->aLTerm );
assert( ArraySize(pLoop->aLTermSpace)==4 );
if( pIdx->onError==OE_None
|| pIdx->pPartIdxWhere!=0
- || pIdx->nColumn>ArraySize(pLoop->aLTermSpace)
+ || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
) continue;
- for(j=0; jnColumn; j++){
+ for(j=0; jnKeyCol; j++){
pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
if( pTerm==0 ) break;
pLoop->aLTerm[j] = pTerm;
}
- if( j!=pIdx->nColumn ) continue;
+ if( j!=pIdx->nKeyCol ) continue;
pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
- if( (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
+ if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
pLoop->wsFlags |= WHERE_IDX_ONLY;
}
pLoop->nLTerm = j;
pLoop->u.btree.nEq = j;
pLoop->u.btree.pIndex = pIdx;
@@ -112291,10 +113601,18 @@
**
** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause
** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement
** if there is one. If there is no ORDER BY clause or if this routine
** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
+**
+** The iIdxCur parameter is the cursor number of an index. If
+** WHERE_ONETABLE_ONLY is set, iIdxCur is the cursor number of an index
+** to use for OR clause processing. The WHERE clause should use this
+** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is
+** the first cursor in an array of cursors for all indices. iIdxCur should
+** be used to compute the appropriate cursor depending on which index is
+** used.
*/
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
Parse *pParse, /* The parser context */
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
@@ -112356,10 +113674,11 @@
if( db->mallocFailed ){
sqlite3DbFree(db, pWInfo);
pWInfo = 0;
goto whereBeginError;
}
+ pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
pWInfo->nLevel = nTabList;
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->pOrderBy = pOrderBy;
pWInfo->pResultSet = pResultSet;
@@ -112469,24 +113788,41 @@
}
}
/* Construct the WhereLoop objects */
WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
+ /* Display all terms of the WHERE clause */
+#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
+ if( sqlite3WhereTrace & 0x100 ){
+ int i;
+ Vdbe *v = pParse->pVdbe;
+ sqlite3ExplainBegin(v);
+ for(i=0; inTerm; i++){
+ sqlite3ExplainPrintf(v, "#%-2d ", i);
+ sqlite3ExplainPush(v);
+ whereExplainTerm(v, &sWLB.pWC->a[i]);
+ sqlite3ExplainPop(v);
+ sqlite3ExplainNL(v);
+ }
+ sqlite3ExplainFinish(v);
+ sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
+ }
+#endif
if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
rc = whereLoopAddAll(&sWLB);
if( rc ) goto whereBeginError;
/* Display all of the WhereLoop objects if wheretrace is enabled */
-#ifdef WHERETRACE_ENABLED
+#ifdef WHERETRACE_ENABLED /* !=0 */
if( sqlite3WhereTrace ){
WhereLoop *p;
int i;
static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
"ABCDEFGHIJKLMNOPQRSTUVWYXZ";
for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
p->cId = zLabel[i%sizeof(zLabel)];
- whereLoopPrint(p, pTabList);
+ whereLoopPrint(p, sWLB.pWC);
}
}
#endif
wherePathSolver(pWInfo, 0);
@@ -112500,11 +113836,11 @@
pWInfo->revMask = (Bitmask)(-1);
}
if( pParse->nErr || NEVER(db->mallocFailed) ){
goto whereBeginError;
}
-#ifdef WHERETRACE_ENABLED
+#ifdef WHERETRACE_ENABLED /* !=0 */
if( sqlite3WhereTrace ){
int ii;
sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
if( pWInfo->bOBSat ){
sqlite3DebugPrintf(" ORDERBY=0x%llx", pWInfo->revMask);
@@ -112523,11 +113859,11 @@
break;
}
}
sqlite3DebugPrintf("\n");
for(ii=0; iinLevel; ii++){
- whereLoopPrint(pWInfo->a[ii].pWLoop, pTabList);
+ whereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
}
}
#endif
/* Attempt to omit tables from the join that do not effect the result */
if( pWInfo->nLevel>=2
@@ -112570,11 +113906,13 @@
*/
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0
&& (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){
pWInfo->okOnePass = 1;
- pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
+ if( HasRowid(pTabList->a[0].pTab) ){
+ pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
+ }
}
/* Open all tables in the pTabList and any indices selected for
** searching those tables.
*/
@@ -112600,15 +113938,20 @@
/* noop */
}else
#endif
if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
&& (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
- int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
+ int op = OP_OpenRead;
+ if( pWInfo->okOnePass ){
+ op = OP_OpenWrite;
+ pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
+ };
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
+ assert( pTabItem->iCursor==pLevel->iTabCur );
testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
- if( !pWInfo->okOnePass && pTab->nColokOnePass && pTab->nColcolUsed;
int n = 0;
for(; b; b=b>>1, n++){}
sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1,
SQLITE_INT_TO_PTR(n), P4_INT32);
@@ -112617,17 +113960,34 @@
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
}
if( pLoop->wsFlags & WHERE_INDEXED ){
Index *pIx = pLoop->u.btree.pIndex;
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
- /* FIXME: As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
- int iIndexCur = pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
+ int iIndexCur;
+ int op = OP_OpenRead;
+ /* iIdxCur is always set if to a positive value if ONEPASS is possible */
+ assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+ if( pWInfo->okOnePass ){
+ Index *pJ = pTabItem->pTab->pIndex;
+ iIndexCur = iIdxCur;
+ assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
+ while( ALWAYS(pJ) && pJ!=pIx ){
+ iIndexCur++;
+ pJ = pJ->pNext;
+ }
+ op = OP_OpenWrite;
+ pWInfo->aiCurOnePass[1] = iIndexCur;
+ }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
+ iIndexCur = iIdxCur;
+ }else{
+ iIndexCur = pParse->nTab++;
+ }
+ pLevel->iIdxCur = iIndexCur;
assert( pIx->pSchema==pTab->pSchema );
assert( iIndexCur>=0 );
- sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIx);
VdbeComment((v, "%s", pIx->zName));
}
sqlite3CodeVerifySchema(pParse, iDb);
notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
}
@@ -112718,35 +114078,44 @@
}else{
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
}
sqlite3VdbeJumpHere(v, addr);
}
+ VdbeNoopComment((v, "End WHERE-Loop %d: %s", i,
+ pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
}
/* The "break" point is here, just past the end of the outer loop.
** Set it.
*/
sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
- /* Close all of the cursors that were opened by sqlite3WhereBegin.
- */
assert( pWInfo->nLevel<=pTabList->nSrc );
for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){
Index *pIdx = 0;
struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
Table *pTab = pTabItem->pTab;
assert( pTab!=0 );
pLoop = pLevel->pWLoop;
+
+ /* Close all of the cursors that were opened by sqlite3WhereBegin.
+ ** Except, do not close cursors that will be reused by the OR optimization
+ ** (WHERE_OMIT_OPEN_CLOSE). 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_OMIT_OPEN_CLOSE)==0
){
int ws = pLoop->wsFlags;
if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
}
- if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 ){
+ if( (ws & WHERE_INDEXED)!=0
+ && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
+ && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
+ ){
sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
}
}
/* If this scan uses an index, make VDBE code substitutions to read data
@@ -112764,27 +114133,31 @@
pIdx = pLoop->u.btree.pIndex;
}else if( pLoop->wsFlags & WHERE_MULTI_OR ){
pIdx = pLevel->u.pCovidx;
}
if( pIdx && !db->mallocFailed ){
- int k, j, last;
+ int k, last;
VdbeOp *pOp;
last = sqlite3VdbeCurrentAddr(v);
k = pLevel->addrBody;
pOp = sqlite3VdbeGetOp(v, k);
for(; kp1!=pLevel->iTabCur ) continue;
if( pOp->opcode==OP_Column ){
- for(j=0; jnColumn; j++){
- if( pOp->p2==pIdx->aiColumn[j] ){
- pOp->p2 = j;
- pOp->p1 = pLevel->iIdxCur;
- break;
- }
- }
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || jnColumn );
+ int x = pOp->p2;
+ assert( pIdx->pTable==pTab );
+ if( !HasRowid(pTab) ){
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ x = pPk->aiColumn[x];
+ }
+ x = sqlite3ColumnOfIndex(pIdx, x);
+ if( x>=0 ){
+ pOp->p2 = x;
+ pOp->p1 = pLevel->iIdxCur;
+ }
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 );
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
pOp->opcode = OP_IdxRowid;
}
}
@@ -112988,42 +114361,42 @@
** YYNRULE the number of rules in the grammar
** YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
*/
#define YYCODETYPE unsigned char
-#define YYNOCODE 251
+#define YYNOCODE 253
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 67
+#define YYWILDCARD 68
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- struct LimitVal yy64;
- Expr* yy122;
- Select* yy159;
- IdList* yy180;
- struct {int value; int mask;} yy207;
- u8 yy258;
- u16 yy305;
- struct LikeOp yy318;
- TriggerStep* yy327;
- ExprSpan yy342;
- SrcList* yy347;
- int yy392;
- struct TrigEvent yy410;
- ExprList* yy442;
- struct ValueList yy487;
+ int yy4;
+ struct TrigEvent yy90;
+ ExprSpan yy118;
+ u16 yy177;
+ TriggerStep* yy203;
+ u8 yy210;
+ struct {int value; int mask;} yy215;
+ SrcList* yy259;
+ struct ValueList yy260;
+ struct LimitVal yy292;
+ Expr* yy314;
+ ExprList* yy322;
+ struct LikeOp yy342;
+ IdList* yy384;
+ Select* yy387;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
#define sqlite3ParserARG_SDECL Parse *pParse;
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 628
-#define YYNRULE 327
+#define YYNSTATE 631
+#define YYNRULE 329
#define YYFALLBACK 1
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
@@ -113089,478 +114462,484 @@
** shifting terminals.
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
-#define YY_ACTTAB_COUNT (1564)
+#define YY_ACTTAB_COUNT (1582)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 310, 956, 184, 418, 2, 171, 625, 595, 56, 56,
- /* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
- /* 20 */ 52, 52, 51, 233, 621, 620, 299, 621, 620, 234,
- /* 30 */ 588, 582, 56, 56, 56, 56, 19, 54, 54, 54,
- /* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 606, 57,
- /* 50 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
- /* 60 */ 56, 56, 542, 54, 54, 54, 54, 53, 53, 52,
- /* 70 */ 52, 52, 51, 233, 310, 595, 326, 196, 195, 194,
- /* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 90 */ 51, 233, 618, 617, 165, 618, 617, 381, 378, 377,
- /* 100 */ 408, 533, 577, 577, 588, 582, 304, 423, 376, 59,
- /* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
- /* 120 */ 575, 546, 65, 57, 58, 48, 580, 579, 581, 581,
- /* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
- /* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 223,
- /* 150 */ 540, 421, 170, 176, 138, 281, 384, 276, 383, 168,
- /* 160 */ 490, 552, 410, 669, 621, 620, 272, 439, 410, 439,
- /* 170 */ 551, 605, 67, 483, 508, 619, 600, 413, 588, 582,
- /* 180 */ 601, 484, 619, 413, 619, 599, 91, 440, 441, 440,
- /* 190 */ 336, 599, 73, 670, 222, 267, 481, 57, 58, 48,
- /* 200 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
- /* 210 */ 671, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 220 */ 51, 233, 310, 280, 232, 231, 1, 132, 200, 386,
- /* 230 */ 621, 620, 618, 617, 279, 436, 290, 564, 175, 263,
- /* 240 */ 410, 265, 438, 498, 437, 166, 442, 569, 337, 569,
- /* 250 */ 201, 538, 588, 582, 600, 413, 165, 595, 601, 381,
- /* 260 */ 378, 377, 598, 599, 92, 524, 619, 570, 570, 593,
- /* 270 */ 376, 57, 58, 48, 580, 579, 581, 581, 55, 55,
- /* 280 */ 56, 56, 56, 56, 598, 54, 54, 54, 54, 53,
- /* 290 */ 53, 52, 52, 52, 51, 233, 310, 464, 618, 617,
- /* 300 */ 591, 591, 591, 174, 273, 397, 410, 273, 410, 549,
- /* 310 */ 398, 621, 620, 68, 327, 621, 620, 621, 620, 619,
- /* 320 */ 547, 413, 619, 413, 472, 595, 588, 582, 473, 599,
- /* 330 */ 92, 599, 92, 52, 52, 52, 51, 233, 514, 513,
- /* 340 */ 206, 323, 364, 465, 221, 57, 58, 48, 580, 579,
- /* 350 */ 581, 581, 55, 55, 56, 56, 56, 56, 530, 54,
- /* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 370 */ 310, 397, 410, 397, 598, 373, 387, 531, 348, 618,
- /* 380 */ 617, 576, 202, 618, 617, 618, 617, 413, 621, 620,
- /* 390 */ 145, 255, 347, 254, 578, 599, 74, 352, 45, 490,
- /* 400 */ 588, 582, 235, 189, 465, 545, 167, 297, 187, 470,
- /* 410 */ 480, 67, 62, 39, 619, 547, 598, 346, 574, 57,
- /* 420 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
- /* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
- /* 440 */ 52, 52, 51, 233, 310, 563, 559, 408, 529, 577,
- /* 450 */ 577, 345, 255, 347, 254, 182, 618, 617, 504, 505,
- /* 460 */ 315, 410, 558, 235, 166, 272, 410, 353, 565, 181,
- /* 470 */ 408, 547, 577, 577, 588, 582, 413, 538, 557, 562,
- /* 480 */ 518, 413, 619, 249, 599, 16, 7, 36, 468, 599,
- /* 490 */ 92, 517, 619, 57, 58, 48, 580, 579, 581, 581,
- /* 500 */ 55, 55, 56, 56, 56, 56, 542, 54, 54, 54,
- /* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 328,
- /* 520 */ 573, 572, 526, 559, 561, 395, 872, 246, 410, 248,
- /* 530 */ 171, 393, 595, 219, 408, 410, 577, 577, 503, 558,
- /* 540 */ 365, 145, 511, 413, 408, 229, 577, 577, 588, 582,
- /* 550 */ 413, 599, 92, 382, 270, 557, 166, 401, 599, 69,
- /* 560 */ 502, 420, 946, 199, 946, 198, 547, 57, 58, 48,
- /* 570 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
- /* 580 */ 569, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 590 */ 51, 233, 310, 318, 420, 945, 509, 945, 309, 598,
- /* 600 */ 595, 566, 491, 212, 173, 247, 424, 616, 615, 614,
- /* 610 */ 324, 197, 143, 406, 573, 572, 490, 66, 50, 47,
- /* 620 */ 146, 595, 588, 582, 232, 231, 560, 428, 67, 556,
- /* 630 */ 15, 619, 186, 544, 304, 422, 35, 206, 433, 424,
- /* 640 */ 553, 57, 58, 48, 580, 579, 581, 581, 55, 55,
- /* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
- /* 660 */ 53, 52, 52, 52, 51, 233, 310, 570, 570, 261,
- /* 670 */ 269, 598, 12, 374, 569, 166, 410, 314, 410, 421,
- /* 680 */ 410, 474, 474, 366, 619, 50, 47, 146, 598, 595,
- /* 690 */ 256, 413, 166, 413, 352, 413, 588, 582, 32, 599,
- /* 700 */ 94, 599, 97, 599, 95, 628, 626, 330, 142, 50,
- /* 710 */ 47, 146, 334, 350, 359, 57, 58, 48, 580, 579,
- /* 720 */ 581, 581, 55, 55, 56, 56, 56, 56, 410, 54,
- /* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 740 */ 310, 410, 389, 413, 410, 22, 566, 405, 212, 363,
- /* 750 */ 390, 599, 104, 360, 410, 156, 413, 410, 604, 413,
- /* 760 */ 538, 332, 570, 570, 599, 103, 494, 599, 105, 413,
- /* 770 */ 588, 582, 413, 261, 550, 619, 11, 599, 106, 522,
- /* 780 */ 599, 133, 169, 458, 457, 170, 35, 602, 619, 57,
- /* 790 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
- /* 800 */ 56, 56, 410, 54, 54, 54, 54, 53, 53, 52,
- /* 810 */ 52, 52, 51, 233, 310, 410, 260, 413, 410, 50,
- /* 820 */ 47, 146, 358, 319, 356, 599, 134, 528, 353, 338,
- /* 830 */ 413, 410, 357, 413, 358, 410, 358, 619, 599, 98,
- /* 840 */ 129, 599, 102, 619, 588, 582, 413, 21, 235, 619,
- /* 850 */ 413, 619, 211, 143, 599, 101, 30, 167, 599, 93,
- /* 860 */ 351, 536, 203, 57, 58, 48, 580, 579, 581, 581,
- /* 870 */ 55, 55, 56, 56, 56, 56, 410, 54, 54, 54,
- /* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 410,
- /* 890 */ 527, 413, 410, 426, 215, 306, 598, 552, 141, 599,
- /* 900 */ 100, 40, 410, 38, 413, 410, 551, 413, 410, 228,
- /* 910 */ 220, 315, 599, 77, 501, 599, 96, 413, 588, 582,
- /* 920 */ 413, 339, 253, 413, 218, 599, 137, 380, 599, 136,
- /* 930 */ 28, 599, 135, 271, 716, 210, 482, 57, 58, 48,
- /* 940 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
- /* 950 */ 410, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 960 */ 51, 233, 310, 410, 273, 413, 410, 316, 147, 598,
- /* 970 */ 273, 627, 2, 599, 76, 209, 410, 127, 413, 619,
- /* 980 */ 126, 413, 410, 622, 235, 619, 599, 90, 375, 599,
- /* 990 */ 89, 413, 588, 582, 27, 261, 351, 413, 619, 599,
- /* 1000 */ 75, 322, 542, 542, 125, 599, 88, 321, 279, 598,
- /* 1010 */ 619, 57, 46, 48, 580, 579, 581, 581, 55, 55,
- /* 1020 */ 56, 56, 56, 56, 410, 54, 54, 54, 54, 53,
- /* 1030 */ 53, 52, 52, 52, 51, 233, 310, 410, 451, 413,
- /* 1040 */ 164, 285, 283, 273, 610, 425, 305, 599, 87, 371,
- /* 1050 */ 410, 478, 413, 410, 609, 410, 608, 603, 619, 619,
- /* 1060 */ 599, 99, 587, 586, 122, 413, 588, 582, 413, 619,
- /* 1070 */ 413, 619, 619, 599, 86, 367, 599, 17, 599, 85,
- /* 1080 */ 320, 185, 520, 519, 584, 583, 58, 48, 580, 579,
- /* 1090 */ 581, 581, 55, 55, 56, 56, 56, 56, 410, 54,
- /* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 1110 */ 310, 585, 410, 413, 410, 261, 261, 261, 409, 592,
- /* 1120 */ 475, 599, 84, 170, 410, 467, 519, 413, 121, 413,
- /* 1130 */ 619, 619, 619, 619, 619, 599, 83, 599, 72, 413,
- /* 1140 */ 588, 582, 51, 233, 626, 330, 471, 599, 71, 258,
- /* 1150 */ 159, 120, 14, 463, 157, 158, 117, 261, 449, 448,
- /* 1160 */ 447, 48, 580, 579, 581, 581, 55, 55, 56, 56,
- /* 1170 */ 56, 56, 619, 54, 54, 54, 54, 53, 53, 52,
- /* 1180 */ 52, 52, 51, 233, 44, 404, 261, 3, 410, 460,
- /* 1190 */ 261, 414, 620, 118, 399, 10, 25, 24, 555, 349,
- /* 1200 */ 217, 619, 407, 413, 410, 619, 4, 44, 404, 619,
- /* 1210 */ 3, 599, 82, 619, 414, 620, 456, 543, 115, 413,
- /* 1220 */ 539, 402, 537, 275, 507, 407, 251, 599, 81, 216,
- /* 1230 */ 274, 564, 619, 243, 454, 619, 154, 619, 619, 619,
- /* 1240 */ 450, 417, 624, 110, 402, 619, 410, 236, 64, 123,
- /* 1250 */ 488, 41, 42, 532, 564, 204, 410, 268, 43, 412,
- /* 1260 */ 411, 413, 266, 593, 108, 619, 107, 435, 333, 599,
- /* 1270 */ 80, 413, 619, 264, 41, 42, 444, 619, 410, 599,
- /* 1280 */ 70, 43, 412, 411, 434, 262, 593, 149, 619, 598,
- /* 1290 */ 257, 237, 188, 413, 591, 591, 591, 590, 589, 13,
- /* 1300 */ 619, 599, 18, 329, 235, 619, 44, 404, 361, 3,
- /* 1310 */ 419, 462, 340, 414, 620, 227, 124, 591, 591, 591,
- /* 1320 */ 590, 589, 13, 619, 407, 410, 619, 410, 139, 34,
- /* 1330 */ 404, 388, 3, 148, 623, 313, 414, 620, 312, 331,
- /* 1340 */ 413, 461, 413, 402, 180, 354, 413, 407, 599, 79,
- /* 1350 */ 599, 78, 250, 564, 599, 9, 619, 613, 612, 611,
- /* 1360 */ 619, 8, 453, 443, 242, 416, 402, 619, 239, 235,
- /* 1370 */ 179, 238, 429, 41, 42, 289, 564, 619, 619, 619,
- /* 1380 */ 43, 412, 411, 619, 144, 593, 619, 619, 177, 61,
- /* 1390 */ 619, 597, 392, 621, 620, 288, 41, 42, 415, 619,
- /* 1400 */ 294, 30, 394, 43, 412, 411, 293, 619, 593, 31,
- /* 1410 */ 619, 396, 292, 60, 230, 37, 591, 591, 591, 590,
- /* 1420 */ 589, 13, 214, 554, 183, 291, 172, 302, 301, 300,
- /* 1430 */ 178, 298, 596, 564, 452, 29, 286, 391, 541, 591,
- /* 1440 */ 591, 591, 590, 589, 13, 284, 521, 535, 150, 534,
- /* 1450 */ 241, 282, 385, 192, 191, 325, 516, 515, 277, 240,
- /* 1460 */ 511, 524, 308, 512, 128, 593, 510, 225, 226, 487,
- /* 1470 */ 486, 224, 152, 492, 465, 307, 485, 163, 153, 372,
- /* 1480 */ 479, 151, 162, 259, 370, 161, 368, 208, 476, 477,
- /* 1490 */ 26, 160, 469, 466, 362, 140, 591, 591, 591, 116,
- /* 1500 */ 119, 455, 344, 155, 114, 343, 113, 112, 446, 111,
- /* 1510 */ 131, 109, 432, 317, 130, 431, 23, 20, 430, 427,
- /* 1520 */ 190, 63, 255, 342, 244, 607, 295, 287, 311, 594,
- /* 1530 */ 278, 508, 496, 235, 493, 571, 497, 568, 495, 403,
- /* 1540 */ 459, 379, 355, 245, 193, 303, 567, 296, 341, 5,
- /* 1550 */ 445, 548, 506, 207, 525, 500, 335, 489, 252, 369,
- /* 1560 */ 400, 499, 523, 233,
+ /* 0 */ 312, 961, 185, 420, 2, 171, 516, 515, 597, 56,
+ /* 10 */ 56, 56, 56, 49, 54, 54, 54, 54, 53, 53,
+ /* 20 */ 52, 52, 52, 51, 234, 197, 196, 195, 624, 623,
+ /* 30 */ 301, 590, 584, 56, 56, 56, 56, 156, 54, 54,
+ /* 40 */ 54, 54, 53, 53, 52, 52, 52, 51, 234, 628,
+ /* 50 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 60 */ 56, 56, 56, 466, 54, 54, 54, 54, 53, 53,
+ /* 70 */ 52, 52, 52, 51, 234, 312, 597, 52, 52, 52,
+ /* 80 */ 51, 234, 33, 54, 54, 54, 54, 53, 53, 52,
+ /* 90 */ 52, 52, 51, 234, 624, 623, 621, 620, 165, 624,
+ /* 100 */ 623, 383, 380, 379, 214, 328, 590, 584, 624, 623,
+ /* 110 */ 467, 59, 378, 619, 618, 617, 53, 53, 52, 52,
+ /* 120 */ 52, 51, 234, 506, 507, 57, 58, 48, 582, 581,
+ /* 130 */ 583, 583, 55, 55, 56, 56, 56, 56, 30, 54,
+ /* 140 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 150 */ 312, 50, 47, 146, 233, 232, 207, 474, 256, 349,
+ /* 160 */ 255, 475, 621, 620, 554, 438, 298, 621, 620, 236,
+ /* 170 */ 674, 435, 440, 553, 439, 366, 621, 620, 540, 224,
+ /* 180 */ 551, 590, 584, 176, 138, 282, 386, 277, 385, 168,
+ /* 190 */ 600, 422, 951, 548, 622, 951, 273, 572, 572, 566,
+ /* 200 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 210 */ 56, 56, 56, 354, 54, 54, 54, 54, 53, 53,
+ /* 220 */ 52, 52, 52, 51, 234, 312, 561, 526, 62, 675,
+ /* 230 */ 132, 595, 410, 348, 579, 579, 492, 426, 577, 419,
+ /* 240 */ 627, 65, 329, 560, 441, 237, 676, 123, 607, 67,
+ /* 250 */ 542, 532, 622, 170, 205, 500, 590, 584, 166, 559,
+ /* 260 */ 622, 403, 593, 593, 593, 442, 443, 271, 422, 950,
+ /* 270 */ 166, 223, 950, 483, 190, 57, 58, 48, 582, 581,
+ /* 280 */ 583, 583, 55, 55, 56, 56, 56, 56, 600, 54,
+ /* 290 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 300 */ 312, 441, 412, 376, 175, 165, 166, 391, 383, 380,
+ /* 310 */ 379, 342, 412, 203, 426, 66, 392, 622, 415, 378,
+ /* 320 */ 597, 166, 442, 338, 444, 571, 601, 74, 415, 624,
+ /* 330 */ 623, 590, 584, 624, 623, 174, 601, 92, 333, 171,
+ /* 340 */ 1, 410, 597, 579, 579, 624, 623, 600, 306, 425,
+ /* 350 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 360 */ 56, 56, 56, 580, 54, 54, 54, 54, 53, 53,
+ /* 370 */ 52, 52, 52, 51, 234, 312, 472, 262, 399, 68,
+ /* 380 */ 412, 339, 571, 389, 624, 623, 578, 602, 597, 589,
+ /* 390 */ 588, 603, 412, 622, 423, 533, 415, 621, 620, 513,
+ /* 400 */ 257, 621, 620, 166, 601, 91, 590, 584, 415, 45,
+ /* 410 */ 597, 586, 585, 621, 620, 250, 601, 92, 39, 347,
+ /* 420 */ 576, 336, 597, 547, 567, 57, 58, 48, 582, 581,
+ /* 430 */ 583, 583, 55, 55, 56, 56, 56, 56, 587, 54,
+ /* 440 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 450 */ 312, 561, 621, 620, 531, 291, 470, 188, 399, 375,
+ /* 460 */ 247, 492, 249, 350, 412, 476, 476, 368, 560, 299,
+ /* 470 */ 334, 412, 281, 482, 67, 565, 410, 622, 579, 579,
+ /* 480 */ 415, 590, 584, 280, 559, 467, 520, 415, 601, 92,
+ /* 490 */ 597, 167, 544, 36, 877, 601, 16, 519, 564, 6,
+ /* 500 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 510 */ 56, 56, 56, 200, 54, 54, 54, 54, 53, 53,
+ /* 520 */ 52, 52, 52, 51, 234, 312, 183, 412, 236, 528,
+ /* 530 */ 395, 535, 358, 256, 349, 255, 397, 412, 248, 182,
+ /* 540 */ 353, 359, 549, 415, 236, 317, 563, 50, 47, 146,
+ /* 550 */ 273, 601, 73, 415, 7, 311, 590, 584, 568, 493,
+ /* 560 */ 213, 601, 92, 233, 232, 410, 173, 579, 579, 330,
+ /* 570 */ 575, 574, 631, 629, 332, 57, 58, 48, 582, 581,
+ /* 580 */ 583, 583, 55, 55, 56, 56, 56, 56, 199, 54,
+ /* 590 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 600 */ 312, 492, 340, 320, 511, 505, 572, 572, 460, 562,
+ /* 610 */ 549, 170, 145, 430, 67, 558, 410, 622, 579, 579,
+ /* 620 */ 384, 236, 600, 412, 408, 575, 574, 504, 572, 572,
+ /* 630 */ 571, 590, 584, 353, 198, 143, 268, 549, 316, 415,
+ /* 640 */ 306, 424, 207, 50, 47, 146, 167, 601, 69, 546,
+ /* 650 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 660 */ 56, 56, 56, 555, 54, 54, 54, 54, 53, 53,
+ /* 670 */ 52, 52, 52, 51, 234, 312, 600, 326, 412, 270,
+ /* 680 */ 145, 264, 274, 266, 459, 571, 423, 35, 412, 568,
+ /* 690 */ 407, 213, 428, 388, 415, 308, 212, 143, 622, 354,
+ /* 700 */ 317, 12, 601, 94, 415, 549, 590, 584, 50, 47,
+ /* 710 */ 146, 365, 601, 97, 552, 362, 318, 147, 602, 361,
+ /* 720 */ 325, 15, 603, 187, 206, 57, 58, 48, 582, 581,
+ /* 730 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
+ /* 740 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 750 */ 312, 412, 35, 412, 415, 22, 630, 2, 600, 50,
+ /* 760 */ 47, 146, 601, 95, 412, 485, 510, 415, 412, 415,
+ /* 770 */ 412, 11, 235, 486, 412, 601, 104, 601, 103, 19,
+ /* 780 */ 415, 590, 584, 352, 415, 40, 415, 38, 601, 105,
+ /* 790 */ 415, 32, 601, 106, 601, 133, 544, 169, 601, 134,
+ /* 800 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 810 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
+ /* 820 */ 52, 52, 52, 51, 234, 312, 412, 274, 412, 415,
+ /* 830 */ 412, 274, 274, 274, 201, 230, 721, 601, 98, 484,
+ /* 840 */ 427, 307, 415, 622, 415, 540, 415, 622, 622, 622,
+ /* 850 */ 601, 102, 601, 101, 601, 93, 590, 584, 262, 21,
+ /* 860 */ 129, 622, 522, 521, 554, 222, 469, 521, 600, 324,
+ /* 870 */ 323, 322, 211, 553, 622, 57, 58, 48, 582, 581,
+ /* 880 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
+ /* 890 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 900 */ 312, 412, 261, 412, 415, 412, 600, 210, 625, 367,
+ /* 910 */ 51, 234, 601, 100, 538, 606, 142, 415, 355, 415,
+ /* 920 */ 412, 415, 412, 496, 622, 601, 77, 601, 96, 601,
+ /* 930 */ 137, 590, 584, 530, 622, 529, 415, 141, 415, 28,
+ /* 940 */ 524, 600, 229, 544, 601, 136, 601, 135, 604, 204,
+ /* 950 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 960 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
+ /* 970 */ 52, 52, 52, 51, 234, 312, 412, 360, 412, 415,
+ /* 980 */ 412, 360, 286, 600, 503, 220, 127, 601, 76, 629,
+ /* 990 */ 332, 382, 415, 622, 415, 540, 415, 622, 412, 613,
+ /* 1000 */ 601, 90, 601, 89, 601, 75, 590, 584, 341, 272,
+ /* 1010 */ 377, 622, 126, 27, 415, 622, 164, 544, 125, 280,
+ /* 1020 */ 373, 122, 601, 88, 480, 57, 46, 48, 582, 581,
+ /* 1030 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
+ /* 1040 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 1050 */ 312, 412, 360, 412, 415, 412, 284, 186, 369, 321,
+ /* 1060 */ 477, 170, 601, 87, 121, 473, 221, 415, 622, 415,
+ /* 1070 */ 254, 415, 412, 355, 412, 601, 99, 601, 86, 601,
+ /* 1080 */ 17, 590, 584, 259, 612, 120, 159, 158, 415, 622,
+ /* 1090 */ 415, 14, 465, 157, 462, 25, 601, 85, 601, 84,
+ /* 1100 */ 622, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 1110 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
+ /* 1120 */ 52, 52, 52, 51, 234, 312, 412, 262, 412, 415,
+ /* 1130 */ 412, 262, 118, 611, 117, 24, 10, 601, 83, 351,
+ /* 1140 */ 216, 219, 415, 622, 415, 608, 415, 622, 412, 622,
+ /* 1150 */ 601, 72, 601, 71, 601, 82, 590, 584, 262, 4,
+ /* 1160 */ 605, 622, 458, 115, 415, 456, 252, 154, 452, 110,
+ /* 1170 */ 108, 453, 601, 81, 622, 451, 622, 48, 582, 581,
+ /* 1180 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
+ /* 1190 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 1200 */ 44, 406, 450, 3, 415, 412, 262, 107, 416, 623,
+ /* 1210 */ 446, 437, 601, 80, 436, 335, 238, 189, 411, 409,
+ /* 1220 */ 594, 415, 622, 44, 406, 401, 3, 412, 557, 601,
+ /* 1230 */ 70, 416, 623, 412, 622, 149, 622, 421, 404, 64,
+ /* 1240 */ 412, 622, 409, 415, 622, 331, 139, 148, 566, 415,
+ /* 1250 */ 449, 601, 18, 228, 124, 626, 415, 601, 79, 315,
+ /* 1260 */ 181, 404, 412, 545, 601, 78, 262, 541, 41, 42,
+ /* 1270 */ 534, 566, 390, 202, 262, 43, 414, 413, 415, 622,
+ /* 1280 */ 595, 314, 622, 622, 180, 539, 601, 92, 415, 276,
+ /* 1290 */ 622, 41, 42, 509, 616, 615, 601, 9, 43, 414,
+ /* 1300 */ 413, 622, 418, 595, 262, 622, 275, 600, 614, 622,
+ /* 1310 */ 218, 593, 593, 593, 592, 591, 13, 178, 217, 417,
+ /* 1320 */ 622, 236, 622, 44, 406, 490, 3, 269, 399, 267,
+ /* 1330 */ 609, 416, 623, 400, 593, 593, 593, 592, 591, 13,
+ /* 1340 */ 265, 622, 409, 622, 263, 622, 34, 406, 244, 3,
+ /* 1350 */ 258, 363, 464, 463, 416, 623, 622, 356, 251, 8,
+ /* 1360 */ 622, 404, 177, 599, 455, 409, 622, 622, 622, 622,
+ /* 1370 */ 445, 566, 243, 622, 622, 236, 295, 240, 31, 239,
+ /* 1380 */ 622, 431, 30, 396, 404, 290, 622, 294, 622, 293,
+ /* 1390 */ 144, 41, 42, 622, 566, 622, 394, 622, 43, 414,
+ /* 1400 */ 413, 622, 289, 595, 398, 60, 622, 292, 37, 231,
+ /* 1410 */ 598, 172, 622, 29, 41, 42, 393, 523, 622, 556,
+ /* 1420 */ 184, 43, 414, 413, 287, 387, 595, 543, 285, 518,
+ /* 1430 */ 537, 536, 517, 327, 593, 593, 593, 592, 591, 13,
+ /* 1440 */ 215, 283, 278, 514, 513, 304, 303, 302, 179, 300,
+ /* 1450 */ 512, 310, 454, 128, 227, 226, 309, 593, 593, 593,
+ /* 1460 */ 592, 591, 13, 494, 489, 225, 488, 150, 487, 242,
+ /* 1470 */ 163, 61, 374, 481, 162, 161, 624, 623, 241, 372,
+ /* 1480 */ 209, 479, 370, 260, 26, 160, 478, 364, 468, 471,
+ /* 1490 */ 140, 152, 119, 467, 131, 116, 155, 153, 345, 457,
+ /* 1500 */ 151, 346, 130, 114, 113, 112, 111, 448, 319, 23,
+ /* 1510 */ 109, 434, 20, 433, 432, 429, 566, 610, 573, 596,
+ /* 1520 */ 63, 405, 191, 279, 510, 296, 498, 288, 570, 495,
+ /* 1530 */ 499, 497, 461, 194, 5, 305, 193, 192, 381, 569,
+ /* 1540 */ 357, 256, 344, 245, 526, 246, 253, 313, 595, 343,
+ /* 1550 */ 447, 297, 236, 402, 550, 491, 508, 502, 501, 527,
+ /* 1560 */ 234, 208, 525, 962, 962, 962, 371, 962, 962, 962,
+ /* 1570 */ 962, 962, 962, 962, 962, 337, 962, 962, 962, 593,
+ /* 1580 */ 593, 593,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
+ /* 0 */ 19, 143, 144, 145, 146, 24, 7, 8, 27, 78,
/* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
- /* 30 */ 49, 50, 77, 78, 79, 80, 204, 82, 83, 84,
- /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 23, 68,
+ /* 20 */ 89, 90, 91, 92, 93, 106, 107, 108, 27, 28,
+ /* 30 */ 15, 50, 51, 78, 79, 80, 81, 26, 83, 84,
+ /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 1,
/* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 60 */ 79, 80, 166, 82, 83, 84, 85, 86, 87, 88,
- /* 70 */ 89, 90, 91, 92, 19, 94, 19, 105, 106, 107,
- /* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 90 */ 91, 92, 94, 95, 96, 94, 95, 99, 100, 101,
- /* 100 */ 112, 205, 114, 115, 49, 50, 22, 23, 110, 54,
- /* 110 */ 86, 87, 88, 89, 90, 91, 92, 221, 222, 223,
- /* 120 */ 23, 120, 25, 68, 69, 70, 71, 72, 73, 74,
- /* 130 */ 75, 76, 77, 78, 79, 80, 22, 82, 83, 84,
- /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 92,
- /* 150 */ 23, 67, 25, 96, 97, 98, 99, 100, 101, 102,
- /* 160 */ 150, 32, 150, 118, 26, 27, 109, 150, 150, 150,
- /* 170 */ 41, 161, 162, 180, 181, 165, 113, 165, 49, 50,
- /* 180 */ 117, 188, 165, 165, 165, 173, 174, 170, 171, 170,
- /* 190 */ 171, 173, 174, 118, 184, 16, 186, 68, 69, 70,
- /* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 210 */ 118, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 220 */ 91, 92, 19, 98, 86, 87, 22, 24, 160, 88,
- /* 230 */ 26, 27, 94, 95, 109, 97, 224, 66, 118, 60,
- /* 240 */ 150, 62, 104, 23, 106, 25, 229, 230, 229, 230,
- /* 250 */ 160, 150, 49, 50, 113, 165, 96, 26, 117, 99,
- /* 260 */ 100, 101, 194, 173, 174, 94, 165, 129, 130, 98,
- /* 270 */ 110, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 280 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86,
- /* 290 */ 87, 88, 89, 90, 91, 92, 19, 11, 94, 95,
- /* 300 */ 129, 130, 131, 118, 150, 215, 150, 150, 150, 25,
- /* 310 */ 220, 26, 27, 22, 213, 26, 27, 26, 27, 165,
- /* 320 */ 25, 165, 165, 165, 30, 94, 49, 50, 34, 173,
- /* 330 */ 174, 173, 174, 88, 89, 90, 91, 92, 7, 8,
- /* 340 */ 160, 187, 48, 57, 187, 68, 69, 70, 71, 72,
- /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 23, 82,
- /* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 370 */ 19, 215, 150, 215, 194, 19, 220, 88, 220, 94,
- /* 380 */ 95, 23, 160, 94, 95, 94, 95, 165, 26, 27,
- /* 390 */ 95, 105, 106, 107, 113, 173, 174, 217, 22, 150,
- /* 400 */ 49, 50, 116, 119, 57, 120, 50, 158, 22, 21,
- /* 410 */ 161, 162, 232, 136, 165, 120, 194, 237, 23, 68,
- /* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 430 */ 79, 80, 22, 82, 83, 84, 85, 86, 87, 88,
- /* 440 */ 89, 90, 91, 92, 19, 23, 12, 112, 23, 114,
- /* 450 */ 115, 63, 105, 106, 107, 23, 94, 95, 97, 98,
- /* 460 */ 104, 150, 28, 116, 25, 109, 150, 150, 23, 23,
- /* 470 */ 112, 25, 114, 115, 49, 50, 165, 150, 44, 11,
- /* 480 */ 46, 165, 165, 16, 173, 174, 76, 136, 100, 173,
- /* 490 */ 174, 57, 165, 68, 69, 70, 71, 72, 73, 74,
- /* 500 */ 75, 76, 77, 78, 79, 80, 166, 82, 83, 84,
- /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 169,
- /* 520 */ 170, 171, 23, 12, 23, 214, 138, 60, 150, 62,
- /* 530 */ 24, 215, 26, 216, 112, 150, 114, 115, 36, 28,
- /* 540 */ 213, 95, 103, 165, 112, 205, 114, 115, 49, 50,
- /* 550 */ 165, 173, 174, 51, 23, 44, 25, 46, 173, 174,
- /* 560 */ 58, 22, 23, 22, 25, 160, 120, 68, 69, 70,
- /* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 580 */ 230, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 590 */ 91, 92, 19, 215, 22, 23, 23, 25, 163, 194,
- /* 600 */ 94, 166, 167, 168, 25, 138, 67, 7, 8, 9,
- /* 610 */ 108, 206, 207, 169, 170, 171, 150, 22, 221, 222,
- /* 620 */ 223, 26, 49, 50, 86, 87, 23, 161, 162, 23,
- /* 630 */ 22, 165, 24, 120, 22, 23, 25, 160, 241, 67,
- /* 640 */ 176, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 650 */ 77, 78, 79, 80, 160, 82, 83, 84, 85, 86,
- /* 660 */ 87, 88, 89, 90, 91, 92, 19, 129, 130, 150,
- /* 670 */ 23, 194, 35, 23, 230, 25, 150, 155, 150, 67,
- /* 680 */ 150, 105, 106, 107, 165, 221, 222, 223, 194, 94,
- /* 690 */ 23, 165, 25, 165, 217, 165, 49, 50, 25, 173,
- /* 700 */ 174, 173, 174, 173, 174, 0, 1, 2, 118, 221,
- /* 710 */ 222, 223, 193, 219, 237, 68, 69, 70, 71, 72,
- /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
- /* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 740 */ 19, 150, 19, 165, 150, 24, 166, 167, 168, 227,
- /* 750 */ 27, 173, 174, 231, 150, 25, 165, 150, 172, 165,
- /* 760 */ 150, 242, 129, 130, 173, 174, 180, 173, 174, 165,
- /* 770 */ 49, 50, 165, 150, 176, 165, 35, 173, 174, 165,
- /* 780 */ 173, 174, 35, 23, 23, 25, 25, 173, 165, 68,
- /* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88,
- /* 810 */ 89, 90, 91, 92, 19, 150, 193, 165, 150, 221,
- /* 820 */ 222, 223, 150, 213, 19, 173, 174, 23, 150, 97,
- /* 830 */ 165, 150, 27, 165, 150, 150, 150, 165, 173, 174,
- /* 840 */ 22, 173, 174, 165, 49, 50, 165, 52, 116, 165,
- /* 850 */ 165, 165, 206, 207, 173, 174, 126, 50, 173, 174,
- /* 860 */ 128, 27, 160, 68, 69, 70, 71, 72, 73, 74,
- /* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84,
- /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150,
- /* 890 */ 23, 165, 150, 23, 216, 25, 194, 32, 39, 173,
- /* 900 */ 174, 135, 150, 137, 165, 150, 41, 165, 150, 52,
- /* 910 */ 238, 104, 173, 174, 29, 173, 174, 165, 49, 50,
- /* 920 */ 165, 219, 238, 165, 238, 173, 174, 52, 173, 174,
- /* 930 */ 22, 173, 174, 23, 23, 160, 25, 68, 69, 70,
- /* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 960 */ 91, 92, 19, 150, 150, 165, 150, 245, 246, 194,
- /* 970 */ 150, 144, 145, 173, 174, 160, 150, 22, 165, 165,
- /* 980 */ 22, 165, 150, 150, 116, 165, 173, 174, 52, 173,
- /* 990 */ 174, 165, 49, 50, 22, 150, 128, 165, 165, 173,
- /* 1000 */ 174, 187, 166, 166, 22, 173, 174, 187, 109, 194,
- /* 1010 */ 165, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86,
- /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 150, 193, 165,
- /* 1040 */ 102, 205, 205, 150, 150, 247, 248, 173, 174, 19,
- /* 1050 */ 150, 20, 165, 150, 150, 150, 150, 150, 165, 165,
- /* 1060 */ 173, 174, 49, 50, 104, 165, 49, 50, 165, 165,
- /* 1070 */ 165, 165, 165, 173, 174, 43, 173, 174, 173, 174,
- /* 1080 */ 187, 24, 190, 191, 71, 72, 69, 70, 71, 72,
- /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
- /* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 1110 */ 19, 98, 150, 165, 150, 150, 150, 150, 150, 150,
- /* 1120 */ 59, 173, 174, 25, 150, 190, 191, 165, 53, 165,
- /* 1130 */ 165, 165, 165, 165, 165, 173, 174, 173, 174, 165,
- /* 1140 */ 49, 50, 91, 92, 1, 2, 53, 173, 174, 138,
- /* 1150 */ 104, 22, 5, 1, 35, 118, 127, 150, 193, 193,
- /* 1160 */ 193, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 1170 */ 79, 80, 165, 82, 83, 84, 85, 86, 87, 88,
- /* 1180 */ 89, 90, 91, 92, 19, 20, 150, 22, 150, 27,
- /* 1190 */ 150, 26, 27, 108, 150, 22, 76, 76, 150, 25,
- /* 1200 */ 193, 165, 37, 165, 150, 165, 22, 19, 20, 165,
- /* 1210 */ 22, 173, 174, 165, 26, 27, 23, 150, 119, 165,
- /* 1220 */ 150, 56, 150, 150, 150, 37, 16, 173, 174, 193,
- /* 1230 */ 150, 66, 165, 193, 1, 165, 121, 165, 165, 165,
- /* 1240 */ 20, 146, 147, 119, 56, 165, 150, 152, 16, 154,
- /* 1250 */ 150, 86, 87, 88, 66, 160, 150, 150, 93, 94,
- /* 1260 */ 95, 165, 150, 98, 108, 165, 127, 23, 65, 173,
- /* 1270 */ 174, 165, 165, 150, 86, 87, 128, 165, 150, 173,
- /* 1280 */ 174, 93, 94, 95, 23, 150, 98, 15, 165, 194,
- /* 1290 */ 150, 140, 22, 165, 129, 130, 131, 132, 133, 134,
- /* 1300 */ 165, 173, 174, 3, 116, 165, 19, 20, 150, 22,
- /* 1310 */ 4, 150, 217, 26, 27, 179, 179, 129, 130, 131,
- /* 1320 */ 132, 133, 134, 165, 37, 150, 165, 150, 164, 19,
- /* 1330 */ 20, 150, 22, 246, 149, 249, 26, 27, 249, 244,
- /* 1340 */ 165, 150, 165, 56, 6, 150, 165, 37, 173, 174,
- /* 1350 */ 173, 174, 150, 66, 173, 174, 165, 149, 149, 13,
- /* 1360 */ 165, 25, 150, 150, 150, 149, 56, 165, 150, 116,
- /* 1370 */ 151, 150, 150, 86, 87, 150, 66, 165, 165, 165,
- /* 1380 */ 93, 94, 95, 165, 150, 98, 165, 165, 151, 22,
- /* 1390 */ 165, 194, 150, 26, 27, 150, 86, 87, 159, 165,
- /* 1400 */ 199, 126, 123, 93, 94, 95, 200, 165, 98, 124,
- /* 1410 */ 165, 122, 201, 125, 225, 135, 129, 130, 131, 132,
- /* 1420 */ 133, 134, 5, 157, 157, 202, 118, 10, 11, 12,
- /* 1430 */ 13, 14, 203, 66, 17, 104, 210, 121, 211, 129,
- /* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
- /* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
- /* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
- /* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
- /* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
- /* 1490 */ 135, 156, 199, 189, 157, 68, 129, 130, 131, 22,
- /* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
- /* 1510 */ 218, 189, 40, 157, 218, 157, 240, 240, 157, 38,
- /* 1520 */ 196, 243, 105, 106, 107, 153, 198, 209, 111, 166,
- /* 1530 */ 176, 181, 166, 116, 166, 230, 176, 230, 176, 226,
- /* 1540 */ 199, 177, 239, 209, 185, 148, 166, 195, 209, 196,
- /* 1550 */ 199, 208, 182, 233, 173, 182, 139, 186, 239, 234,
- /* 1560 */ 191, 182, 173, 92,
-};
-#define YY_SHIFT_USE_DFLT (-70)
-#define YY_SHIFT_COUNT (417)
-#define YY_SHIFT_MIN (-69)
-#define YY_SHIFT_MAX (1487)
+ /* 60 */ 79, 80, 81, 11, 83, 84, 85, 86, 87, 88,
+ /* 70 */ 89, 90, 91, 92, 93, 19, 95, 89, 90, 91,
+ /* 80 */ 92, 93, 26, 83, 84, 85, 86, 87, 88, 89,
+ /* 90 */ 90, 91, 92, 93, 27, 28, 95, 96, 97, 27,
+ /* 100 */ 28, 100, 101, 102, 22, 19, 50, 51, 27, 28,
+ /* 110 */ 58, 55, 111, 7, 8, 9, 87, 88, 89, 90,
+ /* 120 */ 91, 92, 93, 98, 99, 69, 70, 71, 72, 73,
+ /* 130 */ 74, 75, 76, 77, 78, 79, 80, 81, 127, 83,
+ /* 140 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 150 */ 19, 223, 224, 225, 87, 88, 162, 31, 106, 107,
+ /* 160 */ 108, 35, 95, 96, 33, 98, 23, 95, 96, 117,
+ /* 170 */ 119, 243, 105, 42, 107, 49, 95, 96, 151, 93,
+ /* 180 */ 26, 50, 51, 97, 98, 99, 100, 101, 102, 103,
+ /* 190 */ 196, 22, 23, 121, 167, 26, 110, 130, 131, 67,
+ /* 200 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 210 */ 79, 80, 81, 219, 83, 84, 85, 86, 87, 88,
+ /* 220 */ 89, 90, 91, 92, 93, 19, 12, 95, 234, 119,
+ /* 230 */ 24, 99, 113, 239, 115, 116, 151, 68, 23, 147,
+ /* 240 */ 148, 26, 215, 29, 151, 153, 119, 155, 163, 164,
+ /* 250 */ 23, 23, 167, 26, 162, 23, 50, 51, 26, 45,
+ /* 260 */ 167, 47, 130, 131, 132, 172, 173, 23, 22, 23,
+ /* 270 */ 26, 186, 26, 188, 120, 69, 70, 71, 72, 73,
+ /* 280 */ 74, 75, 76, 77, 78, 79, 80, 81, 196, 83,
+ /* 290 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 300 */ 19, 151, 151, 23, 119, 97, 26, 19, 100, 101,
+ /* 310 */ 102, 219, 151, 162, 68, 22, 28, 167, 167, 111,
+ /* 320 */ 27, 26, 172, 173, 231, 232, 175, 176, 167, 27,
+ /* 330 */ 28, 50, 51, 27, 28, 119, 175, 176, 246, 24,
+ /* 340 */ 22, 113, 27, 115, 116, 27, 28, 196, 22, 23,
+ /* 350 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 360 */ 79, 80, 81, 114, 83, 84, 85, 86, 87, 88,
+ /* 370 */ 89, 90, 91, 92, 93, 19, 21, 151, 217, 22,
+ /* 380 */ 151, 231, 232, 222, 27, 28, 23, 114, 95, 50,
+ /* 390 */ 51, 118, 151, 167, 68, 89, 167, 95, 96, 104,
+ /* 400 */ 23, 95, 96, 26, 175, 176, 50, 51, 167, 22,
+ /* 410 */ 95, 72, 73, 95, 96, 16, 175, 176, 137, 64,
+ /* 420 */ 23, 195, 27, 121, 23, 69, 70, 71, 72, 73,
+ /* 430 */ 74, 75, 76, 77, 78, 79, 80, 81, 99, 83,
+ /* 440 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 450 */ 19, 12, 95, 96, 23, 226, 101, 22, 217, 19,
+ /* 460 */ 61, 151, 63, 222, 151, 106, 107, 108, 29, 159,
+ /* 470 */ 244, 151, 99, 163, 164, 23, 113, 167, 115, 116,
+ /* 480 */ 167, 50, 51, 110, 45, 58, 47, 167, 175, 176,
+ /* 490 */ 95, 51, 168, 137, 139, 175, 176, 58, 11, 22,
+ /* 500 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 510 */ 79, 80, 81, 22, 83, 84, 85, 86, 87, 88,
+ /* 520 */ 89, 90, 91, 92, 93, 19, 23, 151, 117, 23,
+ /* 530 */ 217, 207, 19, 106, 107, 108, 216, 151, 139, 23,
+ /* 540 */ 129, 28, 26, 167, 117, 105, 23, 223, 224, 225,
+ /* 550 */ 110, 175, 176, 167, 77, 165, 50, 51, 168, 169,
+ /* 560 */ 170, 175, 176, 87, 88, 113, 26, 115, 116, 171,
+ /* 570 */ 172, 173, 0, 1, 2, 69, 70, 71, 72, 73,
+ /* 580 */ 74, 75, 76, 77, 78, 79, 80, 81, 162, 83,
+ /* 590 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 600 */ 19, 151, 98, 217, 23, 37, 130, 131, 23, 23,
+ /* 610 */ 26, 26, 96, 163, 164, 23, 113, 167, 115, 116,
+ /* 620 */ 52, 117, 196, 151, 171, 172, 173, 59, 130, 131,
+ /* 630 */ 232, 50, 51, 129, 208, 209, 16, 121, 156, 167,
+ /* 640 */ 22, 23, 162, 223, 224, 225, 51, 175, 176, 121,
+ /* 650 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 660 */ 79, 80, 81, 178, 83, 84, 85, 86, 87, 88,
+ /* 670 */ 89, 90, 91, 92, 93, 19, 196, 109, 151, 23,
+ /* 680 */ 96, 61, 151, 63, 23, 232, 68, 26, 151, 168,
+ /* 690 */ 169, 170, 23, 89, 167, 26, 208, 209, 167, 219,
+ /* 700 */ 105, 36, 175, 176, 167, 121, 50, 51, 223, 224,
+ /* 710 */ 225, 229, 175, 176, 178, 233, 247, 248, 114, 239,
+ /* 720 */ 189, 22, 118, 24, 162, 69, 70, 71, 72, 73,
+ /* 730 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
+ /* 740 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 750 */ 19, 151, 26, 151, 167, 24, 145, 146, 196, 223,
+ /* 760 */ 224, 225, 175, 176, 151, 182, 183, 167, 151, 167,
+ /* 770 */ 151, 36, 199, 190, 151, 175, 176, 175, 176, 206,
+ /* 780 */ 167, 50, 51, 221, 167, 136, 167, 138, 175, 176,
+ /* 790 */ 167, 26, 175, 176, 175, 176, 168, 36, 175, 176,
+ /* 800 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 810 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
+ /* 820 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
+ /* 830 */ 151, 151, 151, 151, 162, 207, 23, 175, 176, 26,
+ /* 840 */ 249, 250, 167, 167, 167, 151, 167, 167, 167, 167,
+ /* 850 */ 175, 176, 175, 176, 175, 176, 50, 51, 151, 53,
+ /* 860 */ 22, 167, 192, 193, 33, 189, 192, 193, 196, 189,
+ /* 870 */ 189, 189, 162, 42, 167, 69, 70, 71, 72, 73,
+ /* 880 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
+ /* 890 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 900 */ 19, 151, 195, 151, 167, 151, 196, 162, 151, 215,
+ /* 910 */ 92, 93, 175, 176, 28, 174, 119, 167, 151, 167,
+ /* 920 */ 151, 167, 151, 182, 167, 175, 176, 175, 176, 175,
+ /* 930 */ 176, 50, 51, 23, 167, 23, 167, 40, 167, 22,
+ /* 940 */ 167, 196, 53, 168, 175, 176, 175, 176, 175, 162,
+ /* 950 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 960 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
+ /* 970 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
+ /* 980 */ 151, 151, 207, 196, 30, 218, 22, 175, 176, 1,
+ /* 990 */ 2, 53, 167, 167, 167, 151, 167, 167, 151, 151,
+ /* 1000 */ 175, 176, 175, 176, 175, 176, 50, 51, 221, 23,
+ /* 1010 */ 53, 167, 22, 22, 167, 167, 103, 168, 22, 110,
+ /* 1020 */ 19, 105, 175, 176, 20, 69, 70, 71, 72, 73,
+ /* 1030 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
+ /* 1040 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 1050 */ 19, 151, 151, 151, 167, 151, 207, 24, 44, 215,
+ /* 1060 */ 60, 26, 175, 176, 54, 54, 240, 167, 167, 167,
+ /* 1070 */ 240, 167, 151, 151, 151, 175, 176, 175, 176, 175,
+ /* 1080 */ 176, 50, 51, 139, 151, 22, 105, 119, 167, 167,
+ /* 1090 */ 167, 5, 1, 36, 28, 77, 175, 176, 175, 176,
+ /* 1100 */ 167, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 1110 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
+ /* 1120 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
+ /* 1130 */ 151, 151, 109, 151, 128, 77, 22, 175, 176, 26,
+ /* 1140 */ 218, 240, 167, 167, 167, 151, 167, 167, 151, 167,
+ /* 1150 */ 175, 176, 175, 176, 175, 176, 50, 51, 151, 22,
+ /* 1160 */ 151, 167, 23, 120, 167, 1, 16, 122, 20, 120,
+ /* 1170 */ 109, 195, 175, 176, 167, 195, 167, 71, 72, 73,
+ /* 1180 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
+ /* 1190 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 1200 */ 19, 20, 195, 22, 167, 151, 151, 128, 27, 28,
+ /* 1210 */ 129, 23, 175, 176, 23, 66, 141, 22, 151, 38,
+ /* 1220 */ 151, 167, 167, 19, 20, 151, 22, 151, 151, 175,
+ /* 1230 */ 176, 27, 28, 151, 167, 15, 167, 4, 57, 16,
+ /* 1240 */ 151, 167, 38, 167, 167, 3, 166, 248, 67, 167,
+ /* 1250 */ 195, 175, 176, 181, 181, 150, 167, 175, 176, 251,
+ /* 1260 */ 6, 57, 151, 151, 175, 176, 151, 151, 87, 88,
+ /* 1270 */ 89, 67, 151, 162, 151, 94, 95, 96, 167, 167,
+ /* 1280 */ 99, 251, 167, 167, 152, 151, 175, 176, 167, 151,
+ /* 1290 */ 167, 87, 88, 151, 150, 150, 175, 176, 94, 95,
+ /* 1300 */ 96, 167, 150, 99, 151, 167, 151, 196, 13, 167,
+ /* 1310 */ 195, 130, 131, 132, 133, 134, 135, 152, 195, 160,
+ /* 1320 */ 167, 117, 167, 19, 20, 151, 22, 151, 217, 151,
+ /* 1330 */ 161, 27, 28, 222, 130, 131, 132, 133, 134, 135,
+ /* 1340 */ 151, 167, 38, 167, 151, 167, 19, 20, 195, 22,
+ /* 1350 */ 151, 151, 151, 151, 27, 28, 167, 151, 151, 26,
+ /* 1360 */ 167, 57, 25, 196, 151, 38, 167, 167, 167, 167,
+ /* 1370 */ 151, 67, 151, 167, 167, 117, 201, 151, 125, 151,
+ /* 1380 */ 167, 151, 127, 124, 57, 151, 167, 202, 167, 203,
+ /* 1390 */ 151, 87, 88, 167, 67, 167, 151, 167, 94, 95,
+ /* 1400 */ 96, 167, 151, 99, 123, 126, 167, 204, 136, 227,
+ /* 1410 */ 205, 119, 167, 105, 87, 88, 122, 177, 167, 158,
+ /* 1420 */ 158, 94, 95, 96, 212, 105, 99, 213, 212, 177,
+ /* 1430 */ 213, 213, 185, 48, 130, 131, 132, 133, 134, 135,
+ /* 1440 */ 5, 212, 177, 179, 104, 10, 11, 12, 13, 14,
+ /* 1450 */ 177, 180, 17, 22, 230, 93, 180, 130, 131, 132,
+ /* 1460 */ 133, 134, 135, 185, 177, 230, 177, 32, 177, 34,
+ /* 1470 */ 157, 22, 18, 158, 157, 157, 27, 28, 43, 158,
+ /* 1480 */ 158, 158, 46, 237, 136, 157, 238, 158, 191, 201,
+ /* 1490 */ 69, 56, 191, 58, 220, 22, 157, 62, 18, 201,
+ /* 1500 */ 65, 158, 220, 194, 194, 194, 194, 201, 158, 242,
+ /* 1510 */ 191, 41, 242, 158, 158, 39, 67, 154, 232, 168,
+ /* 1520 */ 245, 228, 198, 178, 183, 200, 168, 211, 232, 168,
+ /* 1530 */ 178, 178, 201, 187, 198, 149, 87, 88, 179, 168,
+ /* 1540 */ 241, 106, 107, 108, 95, 211, 241, 112, 99, 211,
+ /* 1550 */ 201, 197, 117, 193, 210, 188, 184, 184, 184, 175,
+ /* 1560 */ 93, 235, 175, 252, 252, 252, 236, 252, 252, 252,
+ /* 1570 */ 252, 252, 252, 252, 252, 140, 252, 252, 252, 130,
+ /* 1580 */ 131, 132,
+};
+#define YY_SHIFT_USE_DFLT (-82)
+#define YY_SHIFT_COUNT (419)
+#define YY_SHIFT_MIN (-81)
+#define YY_SHIFT_MAX (1480)
static const short yy_shift_ofst[] = {
- /* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
- /* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
- /* 20 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 30 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 40 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287,
- /* 50 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 60 */ 1287, 1287, 286, 362, 362, 538, 538, 231, 1253, 55,
- /* 70 */ 721, 647, 573, 499, 425, 351, 277, 203, 869, 869,
- /* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
- /* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
- /* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
- /* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
- /* 130 */ 732, 868, 231, 1051, 1471, -70, -70, -70, 1367, 57,
- /* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
- /* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
- /* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
- /* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
- /* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
- /* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
- /* 230 */ 766, 633, 633, 231, 284, 63, 608, 1481, 1308, 1308,
- /* 240 */ 1472, 1472, 1308, 1477, 1427, 1275, 1487, 1487, 1487, 1487,
- /* 250 */ 1308, 1461, 1275, 1477, 1427, 1427, 1275, 1308, 1461, 1355,
- /* 260 */ 1441, 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348,
- /* 270 */ 1348, 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408,
- /* 280 */ 1348, 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308,
- /* 290 */ 1280, 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346,
- /* 300 */ 1338, 1338, 1338, 1338, -70, -70, -70, -70, -70, -70,
- /* 310 */ 1013, 467, 612, 84, 179, -28, 870, 410, 761, 760,
- /* 320 */ 667, 650, 531, 220, 361, 331, 125, 127, 97, 1306,
- /* 330 */ 1300, 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174,
- /* 340 */ 1139, 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184,
- /* 350 */ 1174, 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152,
- /* 360 */ 1147, 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960,
- /* 370 */ 1057, 1031, 1030, 899, 938, 982, 936, 972, 958, 910,
- /* 380 */ 955, 875, 885, 908, 857, 859, 867, 804, 590, 834,
- /* 390 */ 747, 818, 513, 611, 741, 673, 637, 611, 606, 603,
- /* 400 */ 579, 501, 541, 468, 386, 445, 395, 376, 281, 185,
- /* 410 */ 120, 92, 75, 45, 114, 25, 11, 5,
+ /* 0 */ 988, 1204, 1435, 1204, 1304, 1304, 67, 67, 1, -19,
+ /* 10 */ 1304, 1304, 1304, 1304, 427, 81, 131, 131, 806, 1181,
+ /* 20 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
+ /* 30 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
+ /* 40 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1327, 1304,
+ /* 50 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
+ /* 60 */ 1304, 1304, 52, 81, 81, 476, 476, 395, 1258, 56,
+ /* 70 */ 731, 656, 581, 506, 431, 356, 281, 206, 881, 881,
+ /* 80 */ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ /* 90 */ 881, 881, 881, 956, 881, 1031, 1106, 1106, -69, -45,
+ /* 100 */ -45, -45, -45, -45, 0, 29, -12, 81, 81, 81,
+ /* 110 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ /* 120 */ 81, 81, 81, 355, 440, 81, 81, 81, 81, 81,
+ /* 130 */ 504, 411, 395, 818, 1467, -82, -82, -82, 1449, 86,
+ /* 140 */ 439, 439, 306, 357, 302, 72, 318, 246, 169, 81,
+ /* 150 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ /* 160 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ /* 170 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ /* 180 */ 81, 81, 315, 315, 315, 572, 1258, 1258, 1258, -82,
+ /* 190 */ -82, -82, 132, 132, 208, 568, 568, 568, 516, 503,
+ /* 200 */ 214, 452, 363, 228, 119, 119, 119, 119, 359, 126,
+ /* 210 */ 119, 119, 584, 293, 604, 106, 11, 288, 288, 513,
+ /* 220 */ 11, 513, 295, 813, 395, 831, 395, 831, 595, 831,
+ /* 230 */ 288, 649, 498, 498, 395, 154, 273, 699, 1476, 1292,
+ /* 240 */ 1292, 1470, 1470, 1292, 1473, 1421, 1255, 1480, 1480, 1480,
+ /* 250 */ 1480, 1292, 1454, 1255, 1473, 1421, 1421, 1255, 1292, 1454,
+ /* 260 */ 1348, 1436, 1292, 1292, 1454, 1292, 1454, 1292, 1454, 1431,
+ /* 270 */ 1320, 1320, 1320, 1385, 1362, 1362, 1431, 1320, 1340, 1320,
+ /* 280 */ 1385, 1320, 1320, 1294, 1308, 1294, 1308, 1294, 1308, 1292,
+ /* 290 */ 1292, 1272, 1279, 1281, 1253, 1259, 1255, 1258, 1337, 1333,
+ /* 300 */ 1295, 1295, 1254, 1254, 1254, 1254, -82, -82, -82, -82,
+ /* 310 */ -82, -82, 339, 399, 618, 326, 620, -81, 669, 477,
+ /* 320 */ 661, 585, 377, 280, 244, 232, 25, -1, 373, 227,
+ /* 330 */ 215, 1233, 1242, 1195, 1075, 1220, 1149, 1223, 1191, 1188,
+ /* 340 */ 1081, 1113, 1079, 1061, 1049, 1148, 1045, 1150, 1164, 1043,
+ /* 350 */ 1139, 1137, 1113, 1114, 1006, 1058, 1018, 1023, 1066, 1057,
+ /* 360 */ 968, 1091, 1086, 1063, 981, 944, 1011, 1035, 1010, 1000,
+ /* 370 */ 1014, 916, 1033, 1004, 1001, 909, 913, 996, 957, 991,
+ /* 380 */ 990, 986, 964, 938, 954, 917, 889, 897, 912, 910,
+ /* 390 */ 797, 886, 761, 838, 528, 726, 735, 765, 665, 726,
+ /* 400 */ 592, 586, 540, 523, 491, 487, 435, 401, 397, 387,
+ /* 410 */ 249, 216, 185, 127, 110, 51, 82, 143, 15, 48,
};
-#define YY_REDUCE_USE_DFLT (-169)
-#define YY_REDUCE_COUNT (309)
-#define YY_REDUCE_MIN (-168)
-#define YY_REDUCE_MAX (1397)
+#define YY_REDUCE_USE_DFLT (-143)
+#define YY_REDUCE_COUNT (311)
+#define YY_REDUCE_MIN (-142)
+#define YY_REDUCE_MAX (1387)
static const short yy_reduce_ofst[] = {
- /* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
- /* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
- /* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
- /* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
- /* 40 */ 800, 758, 755, 752, 742, 739, 726, 685, 681, 668,
- /* 50 */ 665, 652, 607, 604, 594, 591, 578, 530, 528, 526,
- /* 60 */ 385, 18, 477, 466, 519, 444, 350, 435, 405, 488,
- /* 70 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 80 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 90 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 100 */ 488, 488, 488, 488, 488, 488, 488, 1040, 678, 1036,
- /* 110 */ 1007, 967, 966, 965, 845, 686, 610, 684, 317, 672,
- /* 120 */ 893, 327, 623, 522, -7, 820, 814, 157, 154, 101,
- /* 130 */ 702, 494, 580, 488, 488, 488, 488, 488, 614, 586,
- /* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
- /* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
- /* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
- /* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
- /* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
- /* 190 */ -168, 1389, 1381, 1371, 1379, 1373, 1370, 1343, 1352, 1369,
- /* 200 */ 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1325, 1320, 1352,
- /* 210 */ 1352, 1343, 1380, 1353, 1397, 1351, 1339, 1334, 1319, 1341,
- /* 220 */ 1303, 1364, 1359, 1368, 1362, 1366, 1360, 1350, 1354, 1318,
- /* 230 */ 1313, 1307, 1305, 1363, 1328, 1324, 1372, 1278, 1361, 1358,
- /* 240 */ 1277, 1276, 1356, 1296, 1322, 1309, 1317, 1315, 1314, 1312,
- /* 250 */ 1345, 1347, 1302, 1292, 1311, 1304, 1293, 1337, 1335, 1252,
- /* 260 */ 1248, 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301,
- /* 270 */ 1295, 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274,
- /* 280 */ 1281, 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266,
- /* 290 */ 1189, 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219,
- /* 300 */ 1216, 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
+ /* 0 */ -142, 1111, 92, 151, 241, 161, 150, 93, 85, 324,
+ /* 10 */ 386, 313, 320, 229, -6, 310, 536, 485, -72, 1121,
+ /* 20 */ 1089, 1082, 1076, 1054, 1037, 997, 979, 977, 975, 962,
+ /* 30 */ 923, 921, 904, 902, 900, 887, 847, 829, 827, 825,
+ /* 40 */ 812, 771, 769, 754, 752, 750, 737, 679, 677, 675,
+ /* 50 */ 662, 623, 619, 617, 613, 602, 600, 587, 537, 527,
+ /* 60 */ 472, 376, 480, 450, 226, 453, 398, 390, 426, 420,
+ /* 70 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
+ /* 80 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
+ /* 90 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
+ /* 100 */ 420, 420, 420, 420, 420, 420, 420, 1153, 922, 1123,
+ /* 110 */ 1115, 1055, 1007, 980, 976, 901, 844, 830, 767, 826,
+ /* 120 */ 682, 694, 707, 482, 583, 681, 680, 676, 531, 27,
+ /* 130 */ 787, 562, 521, 420, 420, 420, 420, 420, 773, 741,
+ /* 140 */ 674, 670, 1067, 1251, 1245, 1239, 1234, 591, 591, 1230,
+ /* 150 */ 1228, 1226, 1221, 1219, 1213, 1207, 1206, 1202, 1201, 1200,
+ /* 160 */ 1199, 1193, 1189, 1178, 1176, 1174, 1155, 1142, 1138, 1134,
+ /* 170 */ 1116, 1112, 1077, 1074, 1069, 1067, 1009, 994, 982, 933,
+ /* 180 */ 848, 757, 849, 775, 628, 611, 745, 710, 672, 469,
+ /* 190 */ 488, 573, 1387, 1384, 1367, 1374, 1373, 1372, 1344, 1354,
+ /* 200 */ 1360, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1330, 1326,
+ /* 210 */ 1354, 1354, 1344, 1371, 1336, 1386, 1349, 1338, 1334, 1305,
+ /* 220 */ 1331, 1299, 1359, 1346, 1361, 1353, 1358, 1352, 1341, 1345,
+ /* 230 */ 1316, 1293, 1296, 1286, 1351, 1325, 1324, 1363, 1275, 1356,
+ /* 240 */ 1355, 1270, 1267, 1350, 1282, 1319, 1306, 1312, 1311, 1310,
+ /* 250 */ 1309, 1343, 1339, 1298, 1274, 1301, 1297, 1288, 1329, 1328,
+ /* 260 */ 1248, 1246, 1323, 1322, 1318, 1321, 1317, 1315, 1313, 1276,
+ /* 270 */ 1291, 1289, 1287, 1278, 1235, 1224, 1271, 1273, 1264, 1265,
+ /* 280 */ 1247, 1252, 1240, 1218, 1229, 1217, 1216, 1214, 1212, 1262,
+ /* 290 */ 1261, 1182, 1205, 1203, 1186, 1185, 1175, 1167, 1169, 1159,
+ /* 300 */ 1165, 1132, 1152, 1145, 1144, 1105, 1030, 1008, 999, 1073,
+ /* 310 */ 1072, 1080,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 633, 867, 955, 955, 867, 867, 955, 955, 955, 757,
- /* 10 */ 955, 955, 955, 865, 955, 955, 785, 785, 929, 955,
- /* 20 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 30 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 40 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 50 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 60 */ 955, 955, 955, 955, 955, 955, 955, 672, 761, 791,
- /* 70 */ 955, 955, 955, 955, 955, 955, 955, 955, 928, 930,
- /* 80 */ 799, 798, 908, 772, 796, 789, 793, 868, 861, 862,
- /* 90 */ 860, 864, 869, 955, 792, 828, 845, 827, 839, 844,
- /* 100 */ 851, 843, 840, 830, 829, 831, 832, 955, 955, 955,
- /* 110 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 120 */ 955, 955, 955, 659, 726, 955, 955, 955, 955, 955,
- /* 130 */ 955, 955, 955, 833, 834, 848, 847, 846, 955, 664,
- /* 140 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 150 */ 935, 933, 955, 880, 955, 955, 955, 955, 955, 955,
- /* 160 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 170 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 180 */ 639, 757, 757, 757, 633, 955, 955, 955, 947, 761,
- /* 190 */ 751, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 200 */ 955, 955, 955, 801, 740, 918, 920, 955, 901, 738,
- /* 210 */ 661, 759, 674, 749, 641, 795, 774, 774, 913, 795,
- /* 220 */ 913, 697, 720, 955, 785, 955, 785, 694, 785, 774,
- /* 230 */ 863, 955, 955, 955, 758, 749, 955, 940, 765, 765,
- /* 240 */ 932, 932, 765, 807, 730, 795, 737, 737, 737, 737,
- /* 250 */ 765, 656, 795, 807, 730, 730, 795, 765, 656, 907,
- /* 260 */ 905, 765, 765, 656, 765, 656, 765, 656, 873, 728,
- /* 270 */ 728, 728, 712, 877, 877, 873, 728, 697, 728, 712,
- /* 280 */ 728, 728, 778, 773, 778, 773, 778, 773, 765, 765,
- /* 290 */ 955, 790, 779, 788, 786, 795, 955, 715, 649, 649,
- /* 300 */ 638, 638, 638, 638, 952, 952, 947, 699, 699, 682,
- /* 310 */ 955, 955, 955, 955, 955, 955, 955, 882, 955, 955,
- /* 320 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 330 */ 634, 942, 955, 955, 939, 955, 955, 955, 955, 800,
- /* 340 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 350 */ 917, 955, 955, 955, 955, 955, 955, 955, 911, 955,
- /* 360 */ 955, 955, 955, 955, 955, 904, 903, 955, 955, 955,
- /* 370 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 380 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
- /* 390 */ 955, 955, 955, 787, 955, 780, 955, 866, 955, 955,
- /* 400 */ 955, 955, 955, 955, 955, 955, 955, 955, 743, 816,
- /* 410 */ 955, 815, 819, 814, 666, 955, 647, 955, 630, 635,
- /* 420 */ 951, 954, 953, 950, 949, 948, 943, 941, 938, 937,
- /* 430 */ 936, 934, 931, 927, 886, 884, 891, 890, 889, 888,
- /* 440 */ 887, 885, 883, 881, 802, 797, 794, 926, 879, 739,
- /* 450 */ 736, 735, 655, 944, 910, 919, 806, 805, 808, 916,
- /* 460 */ 915, 914, 912, 909, 896, 804, 803, 731, 871, 870,
- /* 470 */ 658, 900, 899, 898, 902, 906, 897, 767, 657, 654,
- /* 480 */ 663, 718, 719, 727, 725, 724, 723, 722, 721, 717,
- /* 490 */ 665, 673, 711, 696, 695, 876, 878, 875, 874, 704,
- /* 500 */ 703, 709, 708, 707, 706, 705, 702, 701, 700, 693,
- /* 510 */ 692, 698, 691, 714, 713, 710, 690, 734, 733, 732,
- /* 520 */ 729, 689, 688, 687, 819, 686, 685, 825, 824, 812,
- /* 530 */ 855, 754, 753, 752, 764, 763, 776, 775, 810, 809,
- /* 540 */ 777, 762, 756, 755, 771, 770, 769, 768, 760, 750,
- /* 550 */ 782, 784, 783, 781, 857, 766, 854, 925, 924, 923,
- /* 560 */ 922, 921, 859, 858, 826, 823, 677, 678, 894, 893,
- /* 570 */ 895, 892, 680, 679, 676, 675, 856, 745, 744, 852,
- /* 580 */ 849, 841, 837, 853, 850, 842, 838, 836, 835, 821,
- /* 590 */ 820, 818, 817, 813, 822, 668, 746, 742, 741, 811,
- /* 600 */ 748, 747, 684, 683, 681, 662, 660, 653, 651, 650,
- /* 610 */ 652, 648, 646, 645, 644, 643, 642, 671, 670, 669,
- /* 620 */ 667, 666, 640, 637, 636, 632, 631, 629,
+ /* 0 */ 636, 872, 960, 960, 872, 872, 960, 960, 960, 762,
+ /* 10 */ 960, 960, 960, 870, 960, 960, 790, 790, 934, 960,
+ /* 20 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 30 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 40 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 50 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 60 */ 960, 960, 960, 960, 960, 960, 960, 677, 766, 796,
+ /* 70 */ 960, 960, 960, 960, 960, 960, 960, 960, 933, 935,
+ /* 80 */ 804, 803, 913, 777, 801, 794, 798, 873, 866, 867,
+ /* 90 */ 865, 869, 874, 960, 797, 833, 850, 832, 844, 849,
+ /* 100 */ 856, 848, 845, 835, 834, 836, 837, 960, 960, 960,
+ /* 110 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 120 */ 960, 960, 960, 662, 731, 960, 960, 960, 960, 960,
+ /* 130 */ 960, 960, 960, 838, 839, 853, 852, 851, 960, 669,
+ /* 140 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 150 */ 940, 938, 960, 885, 960, 960, 960, 960, 960, 960,
+ /* 160 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 170 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 180 */ 960, 642, 762, 762, 762, 636, 960, 960, 960, 952,
+ /* 190 */ 766, 756, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 200 */ 960, 960, 960, 960, 806, 745, 923, 925, 960, 906,
+ /* 210 */ 743, 664, 764, 679, 754, 644, 800, 779, 779, 918,
+ /* 220 */ 800, 918, 702, 725, 960, 790, 960, 790, 699, 790,
+ /* 230 */ 779, 868, 960, 960, 960, 763, 754, 960, 945, 770,
+ /* 240 */ 770, 937, 937, 770, 812, 735, 800, 742, 742, 742,
+ /* 250 */ 742, 770, 659, 800, 812, 735, 735, 800, 770, 659,
+ /* 260 */ 912, 910, 770, 770, 659, 770, 659, 770, 659, 878,
+ /* 270 */ 733, 733, 733, 717, 882, 882, 878, 733, 702, 733,
+ /* 280 */ 717, 733, 733, 783, 778, 783, 778, 783, 778, 770,
+ /* 290 */ 770, 960, 795, 784, 793, 791, 800, 960, 665, 720,
+ /* 300 */ 652, 652, 641, 641, 641, 641, 957, 957, 952, 704,
+ /* 310 */ 704, 687, 960, 960, 960, 960, 960, 960, 960, 887,
+ /* 320 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 330 */ 960, 960, 637, 947, 960, 960, 944, 960, 960, 960,
+ /* 340 */ 960, 805, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 350 */ 960, 960, 922, 960, 960, 960, 960, 960, 960, 960,
+ /* 360 */ 916, 960, 960, 960, 960, 960, 960, 909, 908, 960,
+ /* 370 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 380 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 390 */ 960, 960, 960, 960, 960, 792, 960, 785, 960, 871,
+ /* 400 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 410 */ 748, 821, 960, 820, 824, 819, 671, 960, 650, 960,
+ /* 420 */ 633, 638, 956, 959, 958, 955, 954, 953, 948, 946,
+ /* 430 */ 943, 942, 941, 939, 936, 932, 891, 889, 896, 895,
+ /* 440 */ 894, 893, 892, 890, 888, 886, 807, 802, 799, 931,
+ /* 450 */ 884, 744, 741, 740, 658, 949, 915, 924, 811, 810,
+ /* 460 */ 813, 921, 920, 919, 917, 914, 901, 809, 808, 736,
+ /* 470 */ 876, 875, 661, 905, 904, 903, 907, 911, 902, 772,
+ /* 480 */ 660, 657, 668, 723, 724, 732, 730, 729, 728, 727,
+ /* 490 */ 726, 722, 670, 678, 716, 701, 700, 881, 883, 880,
+ /* 500 */ 879, 709, 708, 714, 713, 712, 711, 710, 707, 706,
+ /* 510 */ 705, 698, 697, 703, 696, 719, 718, 715, 695, 739,
+ /* 520 */ 738, 737, 734, 694, 693, 692, 824, 691, 690, 830,
+ /* 530 */ 829, 817, 860, 759, 758, 757, 769, 768, 781, 780,
+ /* 540 */ 815, 814, 782, 767, 761, 760, 776, 775, 774, 773,
+ /* 550 */ 765, 755, 787, 789, 788, 786, 862, 771, 859, 930,
+ /* 560 */ 929, 928, 927, 926, 864, 863, 831, 828, 682, 683,
+ /* 570 */ 899, 898, 900, 897, 685, 684, 681, 680, 861, 750,
+ /* 580 */ 749, 857, 854, 846, 842, 858, 855, 847, 843, 841,
+ /* 590 */ 840, 826, 825, 823, 822, 818, 827, 673, 751, 747,
+ /* 600 */ 746, 816, 753, 752, 689, 688, 686, 667, 666, 663,
+ /* 610 */ 656, 654, 653, 655, 651, 649, 648, 647, 646, 645,
+ /* 620 */ 676, 675, 674, 672, 671, 643, 640, 639, 635, 634,
+ /* 630 */ 632,
};
/* The next table maps tokens into fallback tokens. If a construct
** like the following:
**
@@ -113573,75 +114952,76 @@
*/
#ifdef YYFALLBACK
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 26, /* EXPLAIN => ID */
- 26, /* QUERY => ID */
- 26, /* PLAN => ID */
- 26, /* BEGIN => ID */
+ 27, /* EXPLAIN => ID */
+ 27, /* QUERY => ID */
+ 27, /* PLAN => ID */
+ 27, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 26, /* DEFERRED => ID */
- 26, /* IMMEDIATE => ID */
- 26, /* EXCLUSIVE => ID */
+ 27, /* DEFERRED => ID */
+ 27, /* IMMEDIATE => ID */
+ 27, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
- 26, /* END => ID */
- 26, /* ROLLBACK => ID */
- 26, /* SAVEPOINT => ID */
- 26, /* RELEASE => ID */
+ 27, /* END => ID */
+ 27, /* ROLLBACK => ID */
+ 27, /* SAVEPOINT => ID */
+ 27, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 26, /* IF => ID */
+ 27, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 26, /* TEMP => ID */
+ 27, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
+ 27, /* WITHOUT => ID */
0, /* COMMA => nothing */
0, /* ID => nothing */
0, /* INDEXED => nothing */
- 26, /* ABORT => ID */
- 26, /* ACTION => ID */
- 26, /* AFTER => ID */
- 26, /* ANALYZE => ID */
- 26, /* ASC => ID */
- 26, /* ATTACH => ID */
- 26, /* BEFORE => ID */
- 26, /* BY => ID */
- 26, /* CASCADE => ID */
- 26, /* CAST => ID */
- 26, /* COLUMNKW => ID */
- 26, /* CONFLICT => ID */
- 26, /* DATABASE => ID */
- 26, /* DESC => ID */
- 26, /* DETACH => ID */
- 26, /* EACH => ID */
- 26, /* FAIL => ID */
- 26, /* FOR => ID */
- 26, /* IGNORE => ID */
- 26, /* INITIALLY => ID */
- 26, /* INSTEAD => ID */
- 26, /* LIKE_KW => ID */
- 26, /* MATCH => ID */
- 26, /* NO => ID */
- 26, /* KEY => ID */
- 26, /* OF => ID */
- 26, /* OFFSET => ID */
- 26, /* PRAGMA => ID */
- 26, /* RAISE => ID */
- 26, /* REPLACE => ID */
- 26, /* RESTRICT => ID */
- 26, /* ROW => ID */
- 26, /* TRIGGER => ID */
- 26, /* VACUUM => ID */
- 26, /* VIEW => ID */
- 26, /* VIRTUAL => ID */
- 26, /* REINDEX => ID */
- 26, /* RENAME => ID */
- 26, /* CTIME_KW => ID */
+ 27, /* ABORT => ID */
+ 27, /* ACTION => ID */
+ 27, /* AFTER => ID */
+ 27, /* ANALYZE => ID */
+ 27, /* ASC => ID */
+ 27, /* ATTACH => ID */
+ 27, /* BEFORE => ID */
+ 27, /* BY => ID */
+ 27, /* CASCADE => ID */
+ 27, /* CAST => ID */
+ 27, /* COLUMNKW => ID */
+ 27, /* CONFLICT => ID */
+ 27, /* DATABASE => ID */
+ 27, /* DESC => ID */
+ 27, /* DETACH => ID */
+ 27, /* EACH => ID */
+ 27, /* FAIL => ID */
+ 27, /* FOR => ID */
+ 27, /* IGNORE => ID */
+ 27, /* INITIALLY => ID */
+ 27, /* INSTEAD => ID */
+ 27, /* LIKE_KW => ID */
+ 27, /* MATCH => ID */
+ 27, /* NO => ID */
+ 27, /* KEY => ID */
+ 27, /* OF => ID */
+ 27, /* OFFSET => ID */
+ 27, /* PRAGMA => ID */
+ 27, /* RAISE => ID */
+ 27, /* REPLACE => ID */
+ 27, /* RESTRICT => ID */
+ 27, /* ROW => ID */
+ 27, /* TRIGGER => ID */
+ 27, /* VACUUM => ID */
+ 27, /* VIEW => ID */
+ 27, /* VIRTUAL => ID */
+ 27, /* REINDEX => ID */
+ 27, /* RENAME => ID */
+ 27, /* CTIME_KW => ID */
};
#endif /* YYFALLBACK */
/* The following structure represents a single element of the
** parser's stack. Information stored includes:
@@ -113722,67 +115102,67 @@
"PLAN", "BEGIN", "TRANSACTION", "DEFERRED",
"IMMEDIATE", "EXCLUSIVE", "COMMIT", "END",
"ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
"TABLE", "CREATE", "IF", "NOT",
"EXISTS", "TEMP", "LP", "RP",
- "AS", "COMMA", "ID", "INDEXED",
- "ABORT", "ACTION", "AFTER", "ANALYZE",
- "ASC", "ATTACH", "BEFORE", "BY",
- "CASCADE", "CAST", "COLUMNKW", "CONFLICT",
- "DATABASE", "DESC", "DETACH", "EACH",
- "FAIL", "FOR", "IGNORE", "INITIALLY",
- "INSTEAD", "LIKE_KW", "MATCH", "NO",
- "KEY", "OF", "OFFSET", "PRAGMA",
- "RAISE", "REPLACE", "RESTRICT", "ROW",
- "TRIGGER", "VACUUM", "VIEW", "VIRTUAL",
- "REINDEX", "RENAME", "CTIME_KW", "ANY",
- "OR", "AND", "IS", "BETWEEN",
- "IN", "ISNULL", "NOTNULL", "NE",
- "EQ", "GT", "LE", "LT",
- "GE", "ESCAPE", "BITAND", "BITOR",
- "LSHIFT", "RSHIFT", "PLUS", "MINUS",
- "STAR", "SLASH", "REM", "CONCAT",
- "COLLATE", "BITNOT", "STRING", "JOIN_KW",
- "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY",
- "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR",
- "ON", "INSERT", "DELETE", "UPDATE",
- "SET", "DEFERRABLE", "FOREIGN", "DROP",
- "UNION", "ALL", "EXCEPT", "INTERSECT",
- "SELECT", "DISTINCT", "DOT", "FROM",
- "JOIN", "USING", "ORDER", "GROUP",
- "HAVING", "LIMIT", "WHERE", "INTO",
- "VALUES", "INTEGER", "FLOAT", "BLOB",
- "REGISTER", "VARIABLE", "CASE", "WHEN",
- "THEN", "ELSE", "INDEX", "ALTER",
- "ADD", "error", "input", "cmdlist",
- "ecmd", "explain", "cmdx", "cmd",
- "transtype", "trans_opt", "nm", "savepoint_opt",
- "create_table", "create_table_args", "createkw", "temp",
- "ifnotexists", "dbnm", "columnlist", "conslist_opt",
- "select", "column", "columnid", "type",
- "carglist", "id", "ids", "typetoken",
- "typename", "signed", "plus_num", "minus_num",
- "ccons", "term", "expr", "onconf",
- "sortorder", "autoinc", "idxlist_opt", "refargs",
- "defer_subclause", "refarg", "refact", "init_deferred_pred_opt",
- "conslist", "tconscomma", "tcons", "idxlist",
- "defer_subclause_opt", "orconf", "resolvetype", "raisetype",
- "ifexists", "fullname", "oneselect", "multiselect_op",
- "distinct", "selcollist", "from", "where_opt",
- "groupby_opt", "having_opt", "orderby_opt", "limit_opt",
- "sclp", "as", "seltablist", "stl_prefix",
- "joinop", "indexed_opt", "on_opt", "using_opt",
- "joinop2", "inscollist", "sortlist", "nexprlist",
- "setlist", "insert_cmd", "inscollist_opt", "valuelist",
- "exprlist", "likeop", "between_op", "in_op",
- "case_operand", "case_exprlist", "case_else", "uniqueflag",
- "collate", "nmnum", "number", "trigger_decl",
- "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause",
- "when_clause", "trigger_cmd", "trnm", "tridxby",
- "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt",
- "create_vtab", "vtabarglist", "vtabarg", "vtabargtoken",
- "lp", "anylist",
+ "AS", "WITHOUT", "COMMA", "ID",
+ "INDEXED", "ABORT", "ACTION", "AFTER",
+ "ANALYZE", "ASC", "ATTACH", "BEFORE",
+ "BY", "CASCADE", "CAST", "COLUMNKW",
+ "CONFLICT", "DATABASE", "DESC", "DETACH",
+ "EACH", "FAIL", "FOR", "IGNORE",
+ "INITIALLY", "INSTEAD", "LIKE_KW", "MATCH",
+ "NO", "KEY", "OF", "OFFSET",
+ "PRAGMA", "RAISE", "REPLACE", "RESTRICT",
+ "ROW", "TRIGGER", "VACUUM", "VIEW",
+ "VIRTUAL", "REINDEX", "RENAME", "CTIME_KW",
+ "ANY", "OR", "AND", "IS",
+ "BETWEEN", "IN", "ISNULL", "NOTNULL",
+ "NE", "EQ", "GT", "LE",
+ "LT", "GE", "ESCAPE", "BITAND",
+ "BITOR", "LSHIFT", "RSHIFT", "PLUS",
+ "MINUS", "STAR", "SLASH", "REM",
+ "CONCAT", "COLLATE", "BITNOT", "STRING",
+ "JOIN_KW", "CONSTRAINT", "DEFAULT", "NULL",
+ "PRIMARY", "UNIQUE", "CHECK", "REFERENCES",
+ "AUTOINCR", "ON", "INSERT", "DELETE",
+ "UPDATE", "SET", "DEFERRABLE", "FOREIGN",
+ "DROP", "UNION", "ALL", "EXCEPT",
+ "INTERSECT", "SELECT", "DISTINCT", "DOT",
+ "FROM", "JOIN", "USING", "ORDER",
+ "GROUP", "HAVING", "LIMIT", "WHERE",
+ "INTO", "VALUES", "INTEGER", "FLOAT",
+ "BLOB", "REGISTER", "VARIABLE", "CASE",
+ "WHEN", "THEN", "ELSE", "INDEX",
+ "ALTER", "ADD", "error", "input",
+ "cmdlist", "ecmd", "explain", "cmdx",
+ "cmd", "transtype", "trans_opt", "nm",
+ "savepoint_opt", "create_table", "create_table_args", "createkw",
+ "temp", "ifnotexists", "dbnm", "columnlist",
+ "conslist_opt", "table_options", "select", "column",
+ "columnid", "type", "carglist", "id",
+ "ids", "typetoken", "typename", "signed",
+ "plus_num", "minus_num", "ccons", "term",
+ "expr", "onconf", "sortorder", "autoinc",
+ "idxlist_opt", "refargs", "defer_subclause", "refarg",
+ "refact", "init_deferred_pred_opt", "conslist", "tconscomma",
+ "tcons", "idxlist", "defer_subclause_opt", "orconf",
+ "resolvetype", "raisetype", "ifexists", "fullname",
+ "oneselect", "multiselect_op", "distinct", "selcollist",
+ "from", "where_opt", "groupby_opt", "having_opt",
+ "orderby_opt", "limit_opt", "sclp", "as",
+ "seltablist", "stl_prefix", "joinop", "indexed_opt",
+ "on_opt", "using_opt", "joinop2", "idlist",
+ "sortlist", "nexprlist", "setlist", "insert_cmd",
+ "inscollist_opt", "valuelist", "exprlist", "likeop",
+ "between_op", "in_op", "case_operand", "case_exprlist",
+ "case_else", "uniqueflag", "collate", "nmnum",
+ "number", "trigger_decl", "trigger_cmd_list", "trigger_time",
+ "trigger_event", "foreach_clause", "when_clause", "trigger_cmd",
+ "trnm", "tridxby", "database_kw_opt", "key_opt",
+ "add_column_fullname", "kwcolumn_opt", "create_vtab", "vtabarglist",
+ "vtabarg", "vtabargtoken", "lp", "anylist",
};
#endif /* NDEBUG */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
@@ -113818,305 +115198,307 @@
/* 27 */ "createkw ::= CREATE",
/* 28 */ "ifnotexists ::=",
/* 29 */ "ifnotexists ::= IF NOT EXISTS",
/* 30 */ "temp ::= TEMP",
/* 31 */ "temp ::=",
- /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP",
+ /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP table_options",
/* 33 */ "create_table_args ::= AS select",
- /* 34 */ "columnlist ::= columnlist COMMA column",
- /* 35 */ "columnlist ::= column",
- /* 36 */ "column ::= columnid type carglist",
- /* 37 */ "columnid ::= nm",
- /* 38 */ "id ::= ID",
- /* 39 */ "id ::= INDEXED",
- /* 40 */ "ids ::= ID|STRING",
- /* 41 */ "nm ::= id",
- /* 42 */ "nm ::= STRING",
- /* 43 */ "nm ::= JOIN_KW",
- /* 44 */ "type ::=",
- /* 45 */ "type ::= typetoken",
- /* 46 */ "typetoken ::= typename",
- /* 47 */ "typetoken ::= typename LP signed RP",
- /* 48 */ "typetoken ::= typename LP signed COMMA signed RP",
- /* 49 */ "typename ::= ids",
- /* 50 */ "typename ::= typename ids",
- /* 51 */ "signed ::= plus_num",
- /* 52 */ "signed ::= minus_num",
- /* 53 */ "carglist ::= carglist ccons",
- /* 54 */ "carglist ::=",
- /* 55 */ "ccons ::= CONSTRAINT nm",
- /* 56 */ "ccons ::= DEFAULT term",
- /* 57 */ "ccons ::= DEFAULT LP expr RP",
- /* 58 */ "ccons ::= DEFAULT PLUS term",
- /* 59 */ "ccons ::= DEFAULT MINUS term",
- /* 60 */ "ccons ::= DEFAULT id",
- /* 61 */ "ccons ::= NULL onconf",
- /* 62 */ "ccons ::= NOT NULL onconf",
- /* 63 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 64 */ "ccons ::= UNIQUE onconf",
- /* 65 */ "ccons ::= CHECK LP expr RP",
- /* 66 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
- /* 67 */ "ccons ::= defer_subclause",
- /* 68 */ "ccons ::= COLLATE ids",
- /* 69 */ "autoinc ::=",
- /* 70 */ "autoinc ::= AUTOINCR",
- /* 71 */ "refargs ::=",
- /* 72 */ "refargs ::= refargs refarg",
- /* 73 */ "refarg ::= MATCH nm",
- /* 74 */ "refarg ::= ON INSERT refact",
- /* 75 */ "refarg ::= ON DELETE refact",
- /* 76 */ "refarg ::= ON UPDATE refact",
- /* 77 */ "refact ::= SET NULL",
- /* 78 */ "refact ::= SET DEFAULT",
- /* 79 */ "refact ::= CASCADE",
- /* 80 */ "refact ::= RESTRICT",
- /* 81 */ "refact ::= NO ACTION",
- /* 82 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 83 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 84 */ "init_deferred_pred_opt ::=",
- /* 85 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 86 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 87 */ "conslist_opt ::=",
- /* 88 */ "conslist_opt ::= COMMA conslist",
- /* 89 */ "conslist ::= conslist tconscomma tcons",
- /* 90 */ "conslist ::= tcons",
- /* 91 */ "tconscomma ::= COMMA",
- /* 92 */ "tconscomma ::=",
- /* 93 */ "tcons ::= CONSTRAINT nm",
- /* 94 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
- /* 95 */ "tcons ::= UNIQUE LP idxlist RP onconf",
- /* 96 */ "tcons ::= CHECK LP expr RP onconf",
- /* 97 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
- /* 98 */ "defer_subclause_opt ::=",
- /* 99 */ "defer_subclause_opt ::= defer_subclause",
- /* 100 */ "onconf ::=",
- /* 101 */ "onconf ::= ON CONFLICT resolvetype",
- /* 102 */ "orconf ::=",
- /* 103 */ "orconf ::= OR resolvetype",
- /* 104 */ "resolvetype ::= raisetype",
- /* 105 */ "resolvetype ::= IGNORE",
- /* 106 */ "resolvetype ::= REPLACE",
- /* 107 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 108 */ "ifexists ::= IF EXISTS",
- /* 109 */ "ifexists ::=",
- /* 110 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
- /* 111 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 112 */ "cmd ::= select",
- /* 113 */ "select ::= oneselect",
- /* 114 */ "select ::= select multiselect_op oneselect",
- /* 115 */ "multiselect_op ::= UNION",
- /* 116 */ "multiselect_op ::= UNION ALL",
- /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 119 */ "distinct ::= DISTINCT",
- /* 120 */ "distinct ::= ALL",
- /* 121 */ "distinct ::=",
- /* 122 */ "sclp ::= selcollist COMMA",
- /* 123 */ "sclp ::=",
- /* 124 */ "selcollist ::= sclp expr as",
- /* 125 */ "selcollist ::= sclp STAR",
- /* 126 */ "selcollist ::= sclp nm DOT STAR",
- /* 127 */ "as ::= AS nm",
- /* 128 */ "as ::= ids",
- /* 129 */ "as ::=",
- /* 130 */ "from ::=",
- /* 131 */ "from ::= FROM seltablist",
- /* 132 */ "stl_prefix ::= seltablist joinop",
- /* 133 */ "stl_prefix ::=",
- /* 134 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 135 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 136 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 137 */ "dbnm ::=",
- /* 138 */ "dbnm ::= DOT nm",
- /* 139 */ "fullname ::= nm dbnm",
- /* 140 */ "joinop ::= COMMA|JOIN",
- /* 141 */ "joinop ::= JOIN_KW JOIN",
- /* 142 */ "joinop ::= JOIN_KW nm JOIN",
- /* 143 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 144 */ "on_opt ::= ON expr",
- /* 145 */ "on_opt ::=",
- /* 146 */ "indexed_opt ::=",
- /* 147 */ "indexed_opt ::= INDEXED BY nm",
- /* 148 */ "indexed_opt ::= NOT INDEXED",
- /* 149 */ "using_opt ::= USING LP inscollist RP",
- /* 150 */ "using_opt ::=",
- /* 151 */ "orderby_opt ::=",
- /* 152 */ "orderby_opt ::= ORDER BY sortlist",
- /* 153 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 154 */ "sortlist ::= expr sortorder",
- /* 155 */ "sortorder ::= ASC",
- /* 156 */ "sortorder ::= DESC",
- /* 157 */ "sortorder ::=",
- /* 158 */ "groupby_opt ::=",
- /* 159 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 160 */ "having_opt ::=",
- /* 161 */ "having_opt ::= HAVING expr",
- /* 162 */ "limit_opt ::=",
- /* 163 */ "limit_opt ::= LIMIT expr",
- /* 164 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 165 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 166 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
- /* 167 */ "where_opt ::=",
- /* 168 */ "where_opt ::= WHERE expr",
- /* 169 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 170 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 171 */ "setlist ::= nm EQ expr",
- /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist",
- /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
- /* 175 */ "insert_cmd ::= INSERT orconf",
- /* 176 */ "insert_cmd ::= REPLACE",
- /* 177 */ "valuelist ::= VALUES LP nexprlist RP",
- /* 178 */ "valuelist ::= valuelist COMMA LP exprlist RP",
- /* 179 */ "inscollist_opt ::=",
- /* 180 */ "inscollist_opt ::= LP inscollist RP",
- /* 181 */ "inscollist ::= inscollist COMMA nm",
- /* 182 */ "inscollist ::= nm",
- /* 183 */ "expr ::= term",
- /* 184 */ "expr ::= LP expr RP",
- /* 185 */ "term ::= NULL",
- /* 186 */ "expr ::= id",
- /* 187 */ "expr ::= JOIN_KW",
- /* 188 */ "expr ::= nm DOT nm",
- /* 189 */ "expr ::= nm DOT nm DOT nm",
- /* 190 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 191 */ "term ::= STRING",
- /* 192 */ "expr ::= REGISTER",
- /* 193 */ "expr ::= VARIABLE",
- /* 194 */ "expr ::= expr COLLATE ids",
- /* 195 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 196 */ "expr ::= ID LP distinct exprlist RP",
- /* 197 */ "expr ::= ID LP STAR RP",
- /* 198 */ "term ::= CTIME_KW",
- /* 199 */ "expr ::= expr AND expr",
- /* 200 */ "expr ::= expr OR expr",
- /* 201 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 202 */ "expr ::= expr EQ|NE expr",
- /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 204 */ "expr ::= expr PLUS|MINUS expr",
- /* 205 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 206 */ "expr ::= expr CONCAT expr",
- /* 207 */ "likeop ::= LIKE_KW",
- /* 208 */ "likeop ::= NOT LIKE_KW",
- /* 209 */ "likeop ::= MATCH",
- /* 210 */ "likeop ::= NOT MATCH",
- /* 211 */ "expr ::= expr likeop expr",
- /* 212 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 213 */ "expr ::= expr ISNULL|NOTNULL",
- /* 214 */ "expr ::= expr NOT NULL",
- /* 215 */ "expr ::= expr IS expr",
- /* 216 */ "expr ::= expr IS NOT expr",
- /* 217 */ "expr ::= NOT expr",
- /* 218 */ "expr ::= BITNOT expr",
- /* 219 */ "expr ::= MINUS expr",
- /* 220 */ "expr ::= PLUS expr",
- /* 221 */ "between_op ::= BETWEEN",
- /* 222 */ "between_op ::= NOT BETWEEN",
- /* 223 */ "expr ::= expr between_op expr AND expr",
- /* 224 */ "in_op ::= IN",
- /* 225 */ "in_op ::= NOT IN",
- /* 226 */ "expr ::= expr in_op LP exprlist RP",
- /* 227 */ "expr ::= LP select RP",
- /* 228 */ "expr ::= expr in_op LP select RP",
- /* 229 */ "expr ::= expr in_op nm dbnm",
- /* 230 */ "expr ::= EXISTS LP select RP",
- /* 231 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 232 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 233 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 234 */ "case_else ::= ELSE expr",
- /* 235 */ "case_else ::=",
- /* 236 */ "case_operand ::= expr",
- /* 237 */ "case_operand ::=",
- /* 238 */ "exprlist ::= nexprlist",
- /* 239 */ "exprlist ::=",
- /* 240 */ "nexprlist ::= nexprlist COMMA expr",
- /* 241 */ "nexprlist ::= expr",
- /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
- /* 243 */ "uniqueflag ::= UNIQUE",
- /* 244 */ "uniqueflag ::=",
- /* 245 */ "idxlist_opt ::=",
- /* 246 */ "idxlist_opt ::= LP idxlist RP",
- /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder",
- /* 248 */ "idxlist ::= nm collate sortorder",
- /* 249 */ "collate ::=",
- /* 250 */ "collate ::= COLLATE ids",
- /* 251 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 252 */ "cmd ::= VACUUM",
- /* 253 */ "cmd ::= VACUUM nm",
- /* 254 */ "cmd ::= PRAGMA nm dbnm",
- /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 256 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 257 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 258 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 259 */ "nmnum ::= plus_num",
- /* 260 */ "nmnum ::= nm",
- /* 261 */ "nmnum ::= ON",
- /* 262 */ "nmnum ::= DELETE",
- /* 263 */ "nmnum ::= DEFAULT",
- /* 264 */ "plus_num ::= PLUS number",
- /* 265 */ "plus_num ::= number",
- /* 266 */ "minus_num ::= MINUS number",
- /* 267 */ "number ::= INTEGER|FLOAT",
- /* 268 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 269 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 270 */ "trigger_time ::= BEFORE",
- /* 271 */ "trigger_time ::= AFTER",
- /* 272 */ "trigger_time ::= INSTEAD OF",
- /* 273 */ "trigger_time ::=",
- /* 274 */ "trigger_event ::= DELETE|INSERT",
- /* 275 */ "trigger_event ::= UPDATE",
- /* 276 */ "trigger_event ::= UPDATE OF inscollist",
- /* 277 */ "foreach_clause ::=",
- /* 278 */ "foreach_clause ::= FOR EACH ROW",
- /* 279 */ "when_clause ::=",
- /* 280 */ "when_clause ::= WHEN expr",
- /* 281 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 283 */ "trnm ::= nm",
- /* 284 */ "trnm ::= nm DOT nm",
- /* 285 */ "tridxby ::=",
- /* 286 */ "tridxby ::= INDEXED BY nm",
- /* 287 */ "tridxby ::= NOT INDEXED",
- /* 288 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 289 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist",
- /* 290 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
- /* 291 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 292 */ "trigger_cmd ::= select",
- /* 293 */ "expr ::= RAISE LP IGNORE RP",
- /* 294 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 295 */ "raisetype ::= ROLLBACK",
- /* 296 */ "raisetype ::= ABORT",
- /* 297 */ "raisetype ::= FAIL",
- /* 298 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 299 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 300 */ "cmd ::= DETACH database_kw_opt expr",
- /* 301 */ "key_opt ::=",
- /* 302 */ "key_opt ::= KEY expr",
- /* 303 */ "database_kw_opt ::= DATABASE",
- /* 304 */ "database_kw_opt ::=",
- /* 305 */ "cmd ::= REINDEX",
- /* 306 */ "cmd ::= REINDEX nm dbnm",
- /* 307 */ "cmd ::= ANALYZE",
- /* 308 */ "cmd ::= ANALYZE nm dbnm",
- /* 309 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 310 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 311 */ "add_column_fullname ::= fullname",
- /* 312 */ "kwcolumn_opt ::=",
- /* 313 */ "kwcolumn_opt ::= COLUMNKW",
- /* 314 */ "cmd ::= create_vtab",
- /* 315 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 316 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 317 */ "vtabarglist ::= vtabarg",
- /* 318 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 319 */ "vtabarg ::=",
- /* 320 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 321 */ "vtabargtoken ::= ANY",
- /* 322 */ "vtabargtoken ::= lp anylist RP",
- /* 323 */ "lp ::= LP",
- /* 324 */ "anylist ::=",
- /* 325 */ "anylist ::= anylist LP anylist RP",
- /* 326 */ "anylist ::= anylist ANY",
+ /* 34 */ "table_options ::=",
+ /* 35 */ "table_options ::= WITHOUT nm",
+ /* 36 */ "columnlist ::= columnlist COMMA column",
+ /* 37 */ "columnlist ::= column",
+ /* 38 */ "column ::= columnid type carglist",
+ /* 39 */ "columnid ::= nm",
+ /* 40 */ "id ::= ID",
+ /* 41 */ "id ::= INDEXED",
+ /* 42 */ "ids ::= ID|STRING",
+ /* 43 */ "nm ::= id",
+ /* 44 */ "nm ::= STRING",
+ /* 45 */ "nm ::= JOIN_KW",
+ /* 46 */ "type ::=",
+ /* 47 */ "type ::= typetoken",
+ /* 48 */ "typetoken ::= typename",
+ /* 49 */ "typetoken ::= typename LP signed RP",
+ /* 50 */ "typetoken ::= typename LP signed COMMA signed RP",
+ /* 51 */ "typename ::= ids",
+ /* 52 */ "typename ::= typename ids",
+ /* 53 */ "signed ::= plus_num",
+ /* 54 */ "signed ::= minus_num",
+ /* 55 */ "carglist ::= carglist ccons",
+ /* 56 */ "carglist ::=",
+ /* 57 */ "ccons ::= CONSTRAINT nm",
+ /* 58 */ "ccons ::= DEFAULT term",
+ /* 59 */ "ccons ::= DEFAULT LP expr RP",
+ /* 60 */ "ccons ::= DEFAULT PLUS term",
+ /* 61 */ "ccons ::= DEFAULT MINUS term",
+ /* 62 */ "ccons ::= DEFAULT id",
+ /* 63 */ "ccons ::= NULL onconf",
+ /* 64 */ "ccons ::= NOT NULL onconf",
+ /* 65 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /* 66 */ "ccons ::= UNIQUE onconf",
+ /* 67 */ "ccons ::= CHECK LP expr RP",
+ /* 68 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
+ /* 69 */ "ccons ::= defer_subclause",
+ /* 70 */ "ccons ::= COLLATE ids",
+ /* 71 */ "autoinc ::=",
+ /* 72 */ "autoinc ::= AUTOINCR",
+ /* 73 */ "refargs ::=",
+ /* 74 */ "refargs ::= refargs refarg",
+ /* 75 */ "refarg ::= MATCH nm",
+ /* 76 */ "refarg ::= ON INSERT refact",
+ /* 77 */ "refarg ::= ON DELETE refact",
+ /* 78 */ "refarg ::= ON UPDATE refact",
+ /* 79 */ "refact ::= SET NULL",
+ /* 80 */ "refact ::= SET DEFAULT",
+ /* 81 */ "refact ::= CASCADE",
+ /* 82 */ "refact ::= RESTRICT",
+ /* 83 */ "refact ::= NO ACTION",
+ /* 84 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 85 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 86 */ "init_deferred_pred_opt ::=",
+ /* 87 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 88 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 89 */ "conslist_opt ::=",
+ /* 90 */ "conslist_opt ::= COMMA conslist",
+ /* 91 */ "conslist ::= conslist tconscomma tcons",
+ /* 92 */ "conslist ::= tcons",
+ /* 93 */ "tconscomma ::= COMMA",
+ /* 94 */ "tconscomma ::=",
+ /* 95 */ "tcons ::= CONSTRAINT nm",
+ /* 96 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
+ /* 97 */ "tcons ::= UNIQUE LP idxlist RP onconf",
+ /* 98 */ "tcons ::= CHECK LP expr RP onconf",
+ /* 99 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
+ /* 100 */ "defer_subclause_opt ::=",
+ /* 101 */ "defer_subclause_opt ::= defer_subclause",
+ /* 102 */ "onconf ::=",
+ /* 103 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 104 */ "orconf ::=",
+ /* 105 */ "orconf ::= OR resolvetype",
+ /* 106 */ "resolvetype ::= raisetype",
+ /* 107 */ "resolvetype ::= IGNORE",
+ /* 108 */ "resolvetype ::= REPLACE",
+ /* 109 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 110 */ "ifexists ::= IF EXISTS",
+ /* 111 */ "ifexists ::=",
+ /* 112 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
+ /* 113 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 114 */ "cmd ::= select",
+ /* 115 */ "select ::= oneselect",
+ /* 116 */ "select ::= select multiselect_op oneselect",
+ /* 117 */ "multiselect_op ::= UNION",
+ /* 118 */ "multiselect_op ::= UNION ALL",
+ /* 119 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 120 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 121 */ "distinct ::= DISTINCT",
+ /* 122 */ "distinct ::= ALL",
+ /* 123 */ "distinct ::=",
+ /* 124 */ "sclp ::= selcollist COMMA",
+ /* 125 */ "sclp ::=",
+ /* 126 */ "selcollist ::= sclp expr as",
+ /* 127 */ "selcollist ::= sclp STAR",
+ /* 128 */ "selcollist ::= sclp nm DOT STAR",
+ /* 129 */ "as ::= AS nm",
+ /* 130 */ "as ::= ids",
+ /* 131 */ "as ::=",
+ /* 132 */ "from ::=",
+ /* 133 */ "from ::= FROM seltablist",
+ /* 134 */ "stl_prefix ::= seltablist joinop",
+ /* 135 */ "stl_prefix ::=",
+ /* 136 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 137 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 138 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 139 */ "dbnm ::=",
+ /* 140 */ "dbnm ::= DOT nm",
+ /* 141 */ "fullname ::= nm dbnm",
+ /* 142 */ "joinop ::= COMMA|JOIN",
+ /* 143 */ "joinop ::= JOIN_KW JOIN",
+ /* 144 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 145 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 146 */ "on_opt ::= ON expr",
+ /* 147 */ "on_opt ::=",
+ /* 148 */ "indexed_opt ::=",
+ /* 149 */ "indexed_opt ::= INDEXED BY nm",
+ /* 150 */ "indexed_opt ::= NOT INDEXED",
+ /* 151 */ "using_opt ::= USING LP idlist RP",
+ /* 152 */ "using_opt ::=",
+ /* 153 */ "orderby_opt ::=",
+ /* 154 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 155 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 156 */ "sortlist ::= expr sortorder",
+ /* 157 */ "sortorder ::= ASC",
+ /* 158 */ "sortorder ::= DESC",
+ /* 159 */ "sortorder ::=",
+ /* 160 */ "groupby_opt ::=",
+ /* 161 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 162 */ "having_opt ::=",
+ /* 163 */ "having_opt ::= HAVING expr",
+ /* 164 */ "limit_opt ::=",
+ /* 165 */ "limit_opt ::= LIMIT expr",
+ /* 166 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 167 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 168 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
+ /* 169 */ "where_opt ::=",
+ /* 170 */ "where_opt ::= WHERE expr",
+ /* 171 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
+ /* 172 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 173 */ "setlist ::= nm EQ expr",
+ /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist",
+ /* 175 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
+ /* 176 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
+ /* 177 */ "insert_cmd ::= INSERT orconf",
+ /* 178 */ "insert_cmd ::= REPLACE",
+ /* 179 */ "valuelist ::= VALUES LP nexprlist RP",
+ /* 180 */ "valuelist ::= valuelist COMMA LP exprlist RP",
+ /* 181 */ "inscollist_opt ::=",
+ /* 182 */ "inscollist_opt ::= LP idlist RP",
+ /* 183 */ "idlist ::= idlist COMMA nm",
+ /* 184 */ "idlist ::= nm",
+ /* 185 */ "expr ::= term",
+ /* 186 */ "expr ::= LP expr RP",
+ /* 187 */ "term ::= NULL",
+ /* 188 */ "expr ::= id",
+ /* 189 */ "expr ::= JOIN_KW",
+ /* 190 */ "expr ::= nm DOT nm",
+ /* 191 */ "expr ::= nm DOT nm DOT nm",
+ /* 192 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 193 */ "term ::= STRING",
+ /* 194 */ "expr ::= REGISTER",
+ /* 195 */ "expr ::= VARIABLE",
+ /* 196 */ "expr ::= expr COLLATE ids",
+ /* 197 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 198 */ "expr ::= ID LP distinct exprlist RP",
+ /* 199 */ "expr ::= ID LP STAR RP",
+ /* 200 */ "term ::= CTIME_KW",
+ /* 201 */ "expr ::= expr AND expr",
+ /* 202 */ "expr ::= expr OR expr",
+ /* 203 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 204 */ "expr ::= expr EQ|NE expr",
+ /* 205 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 206 */ "expr ::= expr PLUS|MINUS expr",
+ /* 207 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 208 */ "expr ::= expr CONCAT expr",
+ /* 209 */ "likeop ::= LIKE_KW",
+ /* 210 */ "likeop ::= NOT LIKE_KW",
+ /* 211 */ "likeop ::= MATCH",
+ /* 212 */ "likeop ::= NOT MATCH",
+ /* 213 */ "expr ::= expr likeop expr",
+ /* 214 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 215 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 216 */ "expr ::= expr NOT NULL",
+ /* 217 */ "expr ::= expr IS expr",
+ /* 218 */ "expr ::= expr IS NOT expr",
+ /* 219 */ "expr ::= NOT expr",
+ /* 220 */ "expr ::= BITNOT expr",
+ /* 221 */ "expr ::= MINUS expr",
+ /* 222 */ "expr ::= PLUS expr",
+ /* 223 */ "between_op ::= BETWEEN",
+ /* 224 */ "between_op ::= NOT BETWEEN",
+ /* 225 */ "expr ::= expr between_op expr AND expr",
+ /* 226 */ "in_op ::= IN",
+ /* 227 */ "in_op ::= NOT IN",
+ /* 228 */ "expr ::= expr in_op LP exprlist RP",
+ /* 229 */ "expr ::= LP select RP",
+ /* 230 */ "expr ::= expr in_op LP select RP",
+ /* 231 */ "expr ::= expr in_op nm dbnm",
+ /* 232 */ "expr ::= EXISTS LP select RP",
+ /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 235 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 236 */ "case_else ::= ELSE expr",
+ /* 237 */ "case_else ::=",
+ /* 238 */ "case_operand ::= expr",
+ /* 239 */ "case_operand ::=",
+ /* 240 */ "exprlist ::= nexprlist",
+ /* 241 */ "exprlist ::=",
+ /* 242 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 243 */ "nexprlist ::= expr",
+ /* 244 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
+ /* 245 */ "uniqueflag ::= UNIQUE",
+ /* 246 */ "uniqueflag ::=",
+ /* 247 */ "idxlist_opt ::=",
+ /* 248 */ "idxlist_opt ::= LP idxlist RP",
+ /* 249 */ "idxlist ::= idxlist COMMA nm collate sortorder",
+ /* 250 */ "idxlist ::= nm collate sortorder",
+ /* 251 */ "collate ::=",
+ /* 252 */ "collate ::= COLLATE ids",
+ /* 253 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 254 */ "cmd ::= VACUUM",
+ /* 255 */ "cmd ::= VACUUM nm",
+ /* 256 */ "cmd ::= PRAGMA nm dbnm",
+ /* 257 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 258 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 259 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 260 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 261 */ "nmnum ::= plus_num",
+ /* 262 */ "nmnum ::= nm",
+ /* 263 */ "nmnum ::= ON",
+ /* 264 */ "nmnum ::= DELETE",
+ /* 265 */ "nmnum ::= DEFAULT",
+ /* 266 */ "plus_num ::= PLUS number",
+ /* 267 */ "plus_num ::= number",
+ /* 268 */ "minus_num ::= MINUS number",
+ /* 269 */ "number ::= INTEGER|FLOAT",
+ /* 270 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 271 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 272 */ "trigger_time ::= BEFORE",
+ /* 273 */ "trigger_time ::= AFTER",
+ /* 274 */ "trigger_time ::= INSTEAD OF",
+ /* 275 */ "trigger_time ::=",
+ /* 276 */ "trigger_event ::= DELETE|INSERT",
+ /* 277 */ "trigger_event ::= UPDATE",
+ /* 278 */ "trigger_event ::= UPDATE OF idlist",
+ /* 279 */ "foreach_clause ::=",
+ /* 280 */ "foreach_clause ::= FOR EACH ROW",
+ /* 281 */ "when_clause ::=",
+ /* 282 */ "when_clause ::= WHEN expr",
+ /* 283 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 284 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 285 */ "trnm ::= nm",
+ /* 286 */ "trnm ::= nm DOT nm",
+ /* 287 */ "tridxby ::=",
+ /* 288 */ "tridxby ::= INDEXED BY nm",
+ /* 289 */ "tridxby ::= NOT INDEXED",
+ /* 290 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 291 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist",
+ /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
+ /* 293 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 294 */ "trigger_cmd ::= select",
+ /* 295 */ "expr ::= RAISE LP IGNORE RP",
+ /* 296 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 297 */ "raisetype ::= ROLLBACK",
+ /* 298 */ "raisetype ::= ABORT",
+ /* 299 */ "raisetype ::= FAIL",
+ /* 300 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 301 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 302 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 303 */ "key_opt ::=",
+ /* 304 */ "key_opt ::= KEY expr",
+ /* 305 */ "database_kw_opt ::= DATABASE",
+ /* 306 */ "database_kw_opt ::=",
+ /* 307 */ "cmd ::= REINDEX",
+ /* 308 */ "cmd ::= REINDEX nm dbnm",
+ /* 309 */ "cmd ::= ANALYZE",
+ /* 310 */ "cmd ::= ANALYZE nm dbnm",
+ /* 311 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 312 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 313 */ "add_column_fullname ::= fullname",
+ /* 314 */ "kwcolumn_opt ::=",
+ /* 315 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 316 */ "cmd ::= create_vtab",
+ /* 317 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 318 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 319 */ "vtabarglist ::= vtabarg",
+ /* 320 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 321 */ "vtabarg ::=",
+ /* 322 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 323 */ "vtabargtoken ::= ANY",
+ /* 324 */ "vtabargtoken ::= lp anylist RP",
+ /* 325 */ "lp ::= LP",
+ /* 326 */ "anylist ::=",
+ /* 327 */ "anylist ::= anylist LP anylist RP",
+ /* 328 */ "anylist ::= anylist ANY",
};
#endif /* NDEBUG */
#if YYSTACKDEPTH<=0
@@ -114191,80 +115573,80 @@
**
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are not used
** inside the C code.
*/
- case 160: /* select */
- case 194: /* oneselect */
-{
-sqlite3SelectDelete(pParse->db, (yypminor->yy159));
-}
- break;
- case 173: /* term */
- case 174: /* expr */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy342).pExpr);
-}
- break;
- case 178: /* idxlist_opt */
- case 187: /* idxlist */
- case 197: /* selcollist */
- case 200: /* groupby_opt */
- case 202: /* orderby_opt */
- case 204: /* sclp */
- case 214: /* sortlist */
- case 215: /* nexprlist */
- case 216: /* setlist */
- case 220: /* exprlist */
- case 225: /* case_exprlist */
-{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy442));
-}
- break;
- case 193: /* fullname */
- case 198: /* from */
- case 206: /* seltablist */
- case 207: /* stl_prefix */
-{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy347));
-}
- break;
- case 199: /* where_opt */
- case 201: /* having_opt */
- case 210: /* on_opt */
- case 224: /* case_operand */
- case 226: /* case_else */
- case 236: /* when_clause */
- case 241: /* key_opt */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy122));
-}
- break;
- case 211: /* using_opt */
- case 213: /* inscollist */
- case 218: /* inscollist_opt */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy180));
-}
- break;
- case 219: /* valuelist */
-{
-
- sqlite3ExprListDelete(pParse->db, (yypminor->yy487).pList);
- sqlite3SelectDelete(pParse->db, (yypminor->yy487).pSelect);
-
-}
- break;
- case 232: /* trigger_cmd_list */
- case 237: /* trigger_cmd */
-{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy327));
-}
- break;
- case 234: /* trigger_event */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy410).b);
+ case 162: /* select */
+ case 196: /* oneselect */
+{
+sqlite3SelectDelete(pParse->db, (yypminor->yy387));
+}
+ break;
+ case 175: /* term */
+ case 176: /* expr */
+{
+sqlite3ExprDelete(pParse->db, (yypminor->yy118).pExpr);
+}
+ break;
+ case 180: /* idxlist_opt */
+ case 189: /* idxlist */
+ case 199: /* selcollist */
+ case 202: /* groupby_opt */
+ case 204: /* orderby_opt */
+ case 206: /* sclp */
+ case 216: /* sortlist */
+ case 217: /* nexprlist */
+ case 218: /* setlist */
+ case 222: /* exprlist */
+ case 227: /* case_exprlist */
+{
+sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
+}
+ break;
+ case 195: /* fullname */
+ case 200: /* from */
+ case 208: /* seltablist */
+ case 209: /* stl_prefix */
+{
+sqlite3SrcListDelete(pParse->db, (yypminor->yy259));
+}
+ break;
+ case 201: /* where_opt */
+ case 203: /* having_opt */
+ case 212: /* on_opt */
+ case 226: /* case_operand */
+ case 228: /* case_else */
+ case 238: /* when_clause */
+ case 243: /* key_opt */
+{
+sqlite3ExprDelete(pParse->db, (yypminor->yy314));
+}
+ break;
+ case 213: /* using_opt */
+ case 215: /* idlist */
+ case 220: /* inscollist_opt */
+{
+sqlite3IdListDelete(pParse->db, (yypminor->yy384));
+}
+ break;
+ case 221: /* valuelist */
+{
+
+ sqlite3ExprListDelete(pParse->db, (yypminor->yy260).pList);
+ sqlite3SelectDelete(pParse->db, (yypminor->yy260).pSelect);
+
+}
+ break;
+ case 234: /* trigger_cmd_list */
+ case 239: /* trigger_cmd */
+{
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203));
+}
+ break;
+ case 236: /* trigger_event */
+{
+sqlite3IdListDelete(pParse->db, (yypminor->yy90).b);
}
break;
default: break; /* If no destructor action specified: do nothing */
}
}
@@ -114505,337 +115887,339 @@
*/
static const struct {
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
- { 142, 1 },
- { 143, 2 },
- { 143, 1 },
- { 144, 1 },
- { 144, 3 },
- { 145, 0 },
- { 145, 1 },
- { 145, 3 },
- { 146, 1 },
- { 147, 3 },
- { 149, 0 },
- { 149, 1 },
- { 149, 2 },
- { 148, 0 },
- { 148, 1 },
- { 148, 1 },
- { 148, 1 },
- { 147, 2 },
- { 147, 2 },
- { 147, 2 },
- { 151, 1 },
- { 151, 0 },
- { 147, 2 },
- { 147, 3 },
- { 147, 5 },
- { 147, 2 },
- { 152, 6 },
- { 154, 1 },
- { 156, 0 },
- { 156, 3 },
- { 155, 1 },
- { 155, 0 },
- { 153, 4 },
- { 153, 2 },
- { 158, 3 },
- { 158, 1 },
- { 161, 3 },
- { 162, 1 },
- { 165, 1 },
- { 165, 1 },
- { 166, 1 },
- { 150, 1 },
- { 150, 1 },
- { 150, 1 },
- { 163, 0 },
- { 163, 1 },
- { 167, 1 },
- { 167, 4 },
- { 167, 6 },
- { 168, 1 },
- { 168, 2 },
- { 169, 1 },
- { 169, 1 },
- { 164, 2 },
- { 164, 0 },
- { 172, 2 },
- { 172, 2 },
- { 172, 4 },
- { 172, 3 },
- { 172, 3 },
- { 172, 2 },
- { 172, 2 },
- { 172, 3 },
- { 172, 5 },
- { 172, 2 },
- { 172, 4 },
- { 172, 4 },
- { 172, 1 },
- { 172, 2 },
- { 177, 0 },
- { 177, 1 },
- { 179, 0 },
- { 179, 2 },
- { 181, 2 },
- { 181, 3 },
- { 181, 3 },
- { 181, 3 },
- { 182, 2 },
- { 182, 2 },
- { 182, 1 },
- { 182, 1 },
- { 182, 2 },
- { 180, 3 },
- { 180, 2 },
- { 183, 0 },
- { 183, 2 },
- { 183, 2 },
- { 159, 0 },
- { 159, 2 },
- { 184, 3 },
- { 184, 1 },
- { 185, 1 },
- { 185, 0 },
- { 186, 2 },
- { 186, 7 },
- { 186, 5 },
- { 186, 5 },
- { 186, 10 },
- { 188, 0 },
- { 188, 1 },
- { 175, 0 },
- { 175, 3 },
- { 189, 0 },
- { 189, 2 },
- { 190, 1 },
- { 190, 1 },
- { 190, 1 },
- { 147, 4 },
- { 192, 2 },
- { 192, 0 },
- { 147, 8 },
- { 147, 4 },
- { 147, 1 },
- { 160, 1 },
- { 160, 3 },
- { 195, 1 },
- { 195, 2 },
- { 195, 1 },
- { 194, 9 },
- { 196, 1 },
- { 196, 1 },
- { 196, 0 },
- { 204, 2 },
- { 204, 0 },
- { 197, 3 },
- { 197, 2 },
- { 197, 4 },
- { 205, 2 },
- { 205, 1 },
- { 205, 0 },
- { 198, 0 },
- { 198, 2 },
- { 207, 2 },
- { 207, 0 },
- { 206, 7 },
- { 206, 7 },
- { 206, 7 },
- { 157, 0 },
- { 157, 2 },
- { 193, 2 },
- { 208, 1 },
- { 208, 2 },
- { 208, 3 },
- { 208, 4 },
- { 210, 2 },
- { 210, 0 },
- { 209, 0 },
- { 209, 3 },
- { 209, 2 },
- { 211, 4 },
- { 211, 0 },
- { 202, 0 },
- { 202, 3 },
- { 214, 4 },
- { 214, 2 },
- { 176, 1 },
- { 176, 1 },
- { 176, 0 },
- { 200, 0 },
- { 200, 3 },
- { 201, 0 },
- { 201, 2 },
- { 203, 0 },
- { 203, 2 },
- { 203, 4 },
- { 203, 4 },
- { 147, 5 },
- { 199, 0 },
- { 199, 2 },
- { 147, 7 },
- { 216, 5 },
- { 216, 3 },
- { 147, 5 },
- { 147, 5 },
- { 147, 6 },
- { 217, 2 },
- { 217, 1 },
- { 219, 4 },
- { 219, 5 },
- { 218, 0 },
- { 218, 3 },
- { 213, 3 },
- { 213, 1 },
- { 174, 1 },
- { 174, 3 },
- { 173, 1 },
- { 174, 1 },
- { 174, 1 },
- { 174, 3 },
- { 174, 5 },
- { 173, 1 },
- { 173, 1 },
- { 174, 1 },
- { 174, 1 },
- { 174, 3 },
- { 174, 6 },
- { 174, 5 },
- { 174, 4 },
- { 173, 1 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 221, 1 },
- { 221, 2 },
- { 221, 1 },
- { 221, 2 },
- { 174, 3 },
- { 174, 5 },
- { 174, 2 },
- { 174, 3 },
- { 174, 3 },
- { 174, 4 },
- { 174, 2 },
- { 174, 2 },
- { 174, 2 },
- { 174, 2 },
- { 222, 1 },
- { 222, 2 },
- { 174, 5 },
- { 223, 1 },
- { 223, 2 },
- { 174, 5 },
- { 174, 3 },
- { 174, 5 },
- { 174, 4 },
- { 174, 4 },
- { 174, 5 },
- { 225, 5 },
- { 225, 4 },
- { 226, 2 },
- { 226, 0 },
- { 224, 1 },
- { 224, 0 },
- { 220, 1 },
- { 220, 0 },
- { 215, 3 },
- { 215, 1 },
- { 147, 12 },
- { 227, 1 },
- { 227, 0 },
- { 178, 0 },
- { 178, 3 },
- { 187, 5 },
- { 187, 3 },
- { 228, 0 },
- { 228, 2 },
- { 147, 4 },
- { 147, 1 },
- { 147, 2 },
- { 147, 3 },
- { 147, 5 },
- { 147, 6 },
- { 147, 5 },
- { 147, 6 },
- { 229, 1 },
- { 229, 1 },
- { 229, 1 },
- { 229, 1 },
- { 229, 1 },
- { 170, 2 },
- { 170, 1 },
- { 171, 2 },
- { 230, 1 },
- { 147, 5 },
- { 231, 11 },
- { 233, 1 },
- { 233, 1 },
- { 233, 2 },
- { 233, 0 },
- { 234, 1 },
- { 234, 1 },
- { 234, 3 },
- { 235, 0 },
- { 235, 3 },
- { 236, 0 },
- { 236, 2 },
- { 232, 3 },
- { 232, 2 },
- { 238, 1 },
- { 238, 3 },
- { 239, 0 },
- { 239, 3 },
- { 239, 2 },
- { 237, 7 },
- { 237, 5 },
- { 237, 5 },
- { 237, 5 },
- { 237, 1 },
- { 174, 4 },
- { 174, 6 },
- { 191, 1 },
- { 191, 1 },
- { 191, 1 },
- { 147, 4 },
- { 147, 6 },
- { 147, 3 },
- { 241, 0 },
- { 241, 2 },
- { 240, 1 },
- { 240, 0 },
- { 147, 1 },
- { 147, 3 },
- { 147, 1 },
- { 147, 3 },
- { 147, 6 },
- { 147, 6 },
- { 242, 1 },
- { 243, 0 },
- { 243, 1 },
- { 147, 1 },
- { 147, 4 },
- { 244, 8 },
- { 245, 1 },
- { 245, 3 },
- { 246, 0 },
- { 246, 2 },
- { 247, 1 },
- { 247, 3 },
- { 248, 1 },
- { 249, 0 },
- { 249, 4 },
- { 249, 2 },
+ { 143, 1 },
+ { 144, 2 },
+ { 144, 1 },
+ { 145, 1 },
+ { 145, 3 },
+ { 146, 0 },
+ { 146, 1 },
+ { 146, 3 },
+ { 147, 1 },
+ { 148, 3 },
+ { 150, 0 },
+ { 150, 1 },
+ { 150, 2 },
+ { 149, 0 },
+ { 149, 1 },
+ { 149, 1 },
+ { 149, 1 },
+ { 148, 2 },
+ { 148, 2 },
+ { 148, 2 },
+ { 152, 1 },
+ { 152, 0 },
+ { 148, 2 },
+ { 148, 3 },
+ { 148, 5 },
+ { 148, 2 },
+ { 153, 6 },
+ { 155, 1 },
+ { 157, 0 },
+ { 157, 3 },
+ { 156, 1 },
+ { 156, 0 },
+ { 154, 5 },
+ { 154, 2 },
+ { 161, 0 },
+ { 161, 2 },
+ { 159, 3 },
+ { 159, 1 },
+ { 163, 3 },
+ { 164, 1 },
+ { 167, 1 },
+ { 167, 1 },
+ { 168, 1 },
+ { 151, 1 },
+ { 151, 1 },
+ { 151, 1 },
+ { 165, 0 },
+ { 165, 1 },
+ { 169, 1 },
+ { 169, 4 },
+ { 169, 6 },
+ { 170, 1 },
+ { 170, 2 },
+ { 171, 1 },
+ { 171, 1 },
+ { 166, 2 },
+ { 166, 0 },
+ { 174, 2 },
+ { 174, 2 },
+ { 174, 4 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 2 },
+ { 174, 2 },
+ { 174, 3 },
+ { 174, 5 },
+ { 174, 2 },
+ { 174, 4 },
+ { 174, 4 },
+ { 174, 1 },
+ { 174, 2 },
+ { 179, 0 },
+ { 179, 1 },
+ { 181, 0 },
+ { 181, 2 },
+ { 183, 2 },
+ { 183, 3 },
+ { 183, 3 },
+ { 183, 3 },
+ { 184, 2 },
+ { 184, 2 },
+ { 184, 1 },
+ { 184, 1 },
+ { 184, 2 },
+ { 182, 3 },
+ { 182, 2 },
+ { 185, 0 },
+ { 185, 2 },
+ { 185, 2 },
+ { 160, 0 },
+ { 160, 2 },
+ { 186, 3 },
+ { 186, 1 },
+ { 187, 1 },
+ { 187, 0 },
+ { 188, 2 },
+ { 188, 7 },
+ { 188, 5 },
+ { 188, 5 },
+ { 188, 10 },
+ { 190, 0 },
+ { 190, 1 },
+ { 177, 0 },
+ { 177, 3 },
+ { 191, 0 },
+ { 191, 2 },
+ { 192, 1 },
+ { 192, 1 },
+ { 192, 1 },
+ { 148, 4 },
+ { 194, 2 },
+ { 194, 0 },
+ { 148, 8 },
+ { 148, 4 },
+ { 148, 1 },
+ { 162, 1 },
+ { 162, 3 },
+ { 197, 1 },
+ { 197, 2 },
+ { 197, 1 },
+ { 196, 9 },
+ { 198, 1 },
+ { 198, 1 },
+ { 198, 0 },
+ { 206, 2 },
+ { 206, 0 },
+ { 199, 3 },
+ { 199, 2 },
+ { 199, 4 },
+ { 207, 2 },
+ { 207, 1 },
+ { 207, 0 },
+ { 200, 0 },
+ { 200, 2 },
+ { 209, 2 },
+ { 209, 0 },
+ { 208, 7 },
+ { 208, 7 },
+ { 208, 7 },
+ { 158, 0 },
+ { 158, 2 },
+ { 195, 2 },
+ { 210, 1 },
+ { 210, 2 },
+ { 210, 3 },
+ { 210, 4 },
+ { 212, 2 },
+ { 212, 0 },
+ { 211, 0 },
+ { 211, 3 },
+ { 211, 2 },
+ { 213, 4 },
+ { 213, 0 },
+ { 204, 0 },
+ { 204, 3 },
+ { 216, 4 },
+ { 216, 2 },
+ { 178, 1 },
+ { 178, 1 },
+ { 178, 0 },
+ { 202, 0 },
+ { 202, 3 },
+ { 203, 0 },
+ { 203, 2 },
+ { 205, 0 },
+ { 205, 2 },
+ { 205, 4 },
+ { 205, 4 },
+ { 148, 5 },
+ { 201, 0 },
+ { 201, 2 },
+ { 148, 7 },
+ { 218, 5 },
+ { 218, 3 },
+ { 148, 5 },
+ { 148, 5 },
+ { 148, 6 },
+ { 219, 2 },
+ { 219, 1 },
+ { 221, 4 },
+ { 221, 5 },
+ { 220, 0 },
+ { 220, 3 },
+ { 215, 3 },
+ { 215, 1 },
+ { 176, 1 },
+ { 176, 3 },
+ { 175, 1 },
+ { 176, 1 },
+ { 176, 1 },
+ { 176, 3 },
+ { 176, 5 },
+ { 175, 1 },
+ { 175, 1 },
+ { 176, 1 },
+ { 176, 1 },
+ { 176, 3 },
+ { 176, 6 },
+ { 176, 5 },
+ { 176, 4 },
+ { 175, 1 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 223, 1 },
+ { 223, 2 },
+ { 223, 1 },
+ { 223, 2 },
+ { 176, 3 },
+ { 176, 5 },
+ { 176, 2 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 4 },
+ { 176, 2 },
+ { 176, 2 },
+ { 176, 2 },
+ { 176, 2 },
+ { 224, 1 },
+ { 224, 2 },
+ { 176, 5 },
+ { 225, 1 },
+ { 225, 2 },
+ { 176, 5 },
+ { 176, 3 },
+ { 176, 5 },
+ { 176, 4 },
+ { 176, 4 },
+ { 176, 5 },
+ { 227, 5 },
+ { 227, 4 },
+ { 228, 2 },
+ { 228, 0 },
+ { 226, 1 },
+ { 226, 0 },
+ { 222, 1 },
+ { 222, 0 },
+ { 217, 3 },
+ { 217, 1 },
+ { 148, 12 },
+ { 229, 1 },
+ { 229, 0 },
+ { 180, 0 },
+ { 180, 3 },
+ { 189, 5 },
+ { 189, 3 },
+ { 230, 0 },
+ { 230, 2 },
+ { 148, 4 },
+ { 148, 1 },
+ { 148, 2 },
+ { 148, 3 },
+ { 148, 5 },
+ { 148, 6 },
+ { 148, 5 },
+ { 148, 6 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
+ { 172, 2 },
+ { 172, 1 },
+ { 173, 2 },
+ { 232, 1 },
+ { 148, 5 },
+ { 233, 11 },
+ { 235, 1 },
+ { 235, 1 },
+ { 235, 2 },
+ { 235, 0 },
+ { 236, 1 },
+ { 236, 1 },
+ { 236, 3 },
+ { 237, 0 },
+ { 237, 3 },
+ { 238, 0 },
+ { 238, 2 },
+ { 234, 3 },
+ { 234, 2 },
+ { 240, 1 },
+ { 240, 3 },
+ { 241, 0 },
+ { 241, 3 },
+ { 241, 2 },
+ { 239, 7 },
+ { 239, 5 },
+ { 239, 5 },
+ { 239, 5 },
+ { 239, 1 },
+ { 176, 4 },
+ { 176, 6 },
+ { 193, 1 },
+ { 193, 1 },
+ { 193, 1 },
+ { 148, 4 },
+ { 148, 6 },
+ { 148, 3 },
+ { 243, 0 },
+ { 243, 2 },
+ { 242, 1 },
+ { 242, 0 },
+ { 148, 1 },
+ { 148, 3 },
+ { 148, 1 },
+ { 148, 3 },
+ { 148, 6 },
+ { 148, 6 },
+ { 244, 1 },
+ { 245, 0 },
+ { 245, 1 },
+ { 148, 1 },
+ { 148, 4 },
+ { 246, 8 },
+ { 247, 1 },
+ { 247, 3 },
+ { 248, 0 },
+ { 248, 2 },
+ { 249, 1 },
+ { 249, 3 },
+ { 250, 1 },
+ { 251, 0 },
+ { 251, 4 },
+ { 251, 2 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
/*
@@ -114899,21 +116283,21 @@
break;
case 8: /* cmdx ::= cmd */
{ sqlite3FinishCoding(pParse); }
break;
case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy392);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);}
break;
case 13: /* transtype ::= */
-{yygotominor.yy392 = TK_DEFERRED;}
+{yygotominor.yy4 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
- case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
- case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
-{yygotominor.yy392 = yymsp[0].major;}
+ case 117: /* multiselect_op ::= UNION */ yytestcase(yyruleno==117);
+ case 119: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==119);
+{yygotominor.yy4 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
{sqlite3CommitTransaction(pParse);}
break;
@@ -114935,11 +116319,11 @@
sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
}
break;
case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy392,0,0,yymsp[-2].minor.yy392);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4);
}
break;
case 27: /* createkw ::= CREATE */
{
pParse->db->lookaside.bEnabled = 0;
@@ -114946,1051 +116330,1064 @@
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 28: /* ifnotexists ::= */
case 31: /* temp ::= */ yytestcase(yyruleno==31);
- case 69: /* autoinc ::= */ yytestcase(yyruleno==69);
- case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
- case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
- case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
- case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
- case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
- case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
- case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
-{yygotominor.yy392 = 0;}
+ case 71: /* autoinc ::= */ yytestcase(yyruleno==71);
+ case 84: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==84);
+ case 86: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==86);
+ case 88: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==88);
+ case 100: /* defer_subclause_opt ::= */ yytestcase(yyruleno==100);
+ case 111: /* ifexists ::= */ yytestcase(yyruleno==111);
+ case 223: /* between_op ::= BETWEEN */ yytestcase(yyruleno==223);
+ case 226: /* in_op ::= IN */ yytestcase(yyruleno==226);
+{yygotominor.yy4 = 0;}
break;
case 29: /* ifnotexists ::= IF NOT EXISTS */
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
- case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
- case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
- case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
- case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
- case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
-{yygotominor.yy392 = 1;}
+ case 72: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==72);
+ case 87: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==87);
+ case 110: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==110);
+ case 224: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==224);
+ case 227: /* in_op ::= NOT IN */ yytestcase(yyruleno==227);
+{yygotominor.yy4 = 1;}
break;
- case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
+ case 32: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy210,0);
}
break;
case 33: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy159);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
}
break;
- case 36: /* column ::= columnid type carglist */
+ case 34: /* table_options ::= */
+{yygotominor.yy210 = 0;}
+ break;
+ case 35: /* table_options ::= WITHOUT nm */
+{
+ if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
+ yygotominor.yy210 = TF_WithoutRowid;
+ }else{
+ yygotominor.yy210 = 0;
+ sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
+ }
+}
+ break;
+ case 38: /* column ::= columnid type carglist */
{
yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
}
break;
- case 37: /* columnid ::= nm */
+ case 39: /* columnid ::= nm */
{
sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
yygotominor.yy0 = yymsp[0].minor.yy0;
pParse->constraintName.n = 0;
}
break;
- case 38: /* id ::= ID */
- case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
- case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
- case 41: /* nm ::= id */ yytestcase(yyruleno==41);
- case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
- case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
- case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
- case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
- case 127: /* as ::= AS nm */ yytestcase(yyruleno==127);
- case 128: /* as ::= ids */ yytestcase(yyruleno==128);
- case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138);
- case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147);
- case 250: /* collate ::= COLLATE ids */ yytestcase(yyruleno==250);
- case 259: /* nmnum ::= plus_num */ yytestcase(yyruleno==259);
- case 260: /* nmnum ::= nm */ yytestcase(yyruleno==260);
- case 261: /* nmnum ::= ON */ yytestcase(yyruleno==261);
- case 262: /* nmnum ::= DELETE */ yytestcase(yyruleno==262);
- case 263: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==263);
- case 264: /* plus_num ::= PLUS number */ yytestcase(yyruleno==264);
- case 265: /* plus_num ::= number */ yytestcase(yyruleno==265);
- case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266);
- case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267);
- case 283: /* trnm ::= nm */ yytestcase(yyruleno==283);
+ case 40: /* id ::= ID */
+ case 41: /* id ::= INDEXED */ yytestcase(yyruleno==41);
+ case 42: /* ids ::= ID|STRING */ yytestcase(yyruleno==42);
+ case 43: /* nm ::= id */ yytestcase(yyruleno==43);
+ case 44: /* nm ::= STRING */ yytestcase(yyruleno==44);
+ case 45: /* nm ::= JOIN_KW */ yytestcase(yyruleno==45);
+ case 48: /* typetoken ::= typename */ yytestcase(yyruleno==48);
+ case 51: /* typename ::= ids */ yytestcase(yyruleno==51);
+ case 129: /* as ::= AS nm */ yytestcase(yyruleno==129);
+ case 130: /* as ::= ids */ yytestcase(yyruleno==130);
+ case 140: /* dbnm ::= DOT nm */ yytestcase(yyruleno==140);
+ case 149: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==149);
+ case 252: /* collate ::= COLLATE ids */ yytestcase(yyruleno==252);
+ case 261: /* nmnum ::= plus_num */ yytestcase(yyruleno==261);
+ case 262: /* nmnum ::= nm */ yytestcase(yyruleno==262);
+ case 263: /* nmnum ::= ON */ yytestcase(yyruleno==263);
+ case 264: /* nmnum ::= DELETE */ yytestcase(yyruleno==264);
+ case 265: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==265);
+ case 266: /* plus_num ::= PLUS number */ yytestcase(yyruleno==266);
+ case 267: /* plus_num ::= number */ yytestcase(yyruleno==267);
+ case 268: /* minus_num ::= MINUS number */ yytestcase(yyruleno==268);
+ case 269: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==269);
+ case 285: /* trnm ::= nm */ yytestcase(yyruleno==285);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
- case 45: /* type ::= typetoken */
+ case 47: /* type ::= typetoken */
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
- case 47: /* typetoken ::= typename LP signed RP */
+ case 49: /* typetoken ::= typename LP signed RP */
{
yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
}
break;
- case 48: /* typetoken ::= typename LP signed COMMA signed RP */
+ case 50: /* typetoken ::= typename LP signed COMMA signed RP */
{
yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
}
break;
- case 50: /* typename ::= typename ids */
+ case 52: /* typename ::= typename ids */
{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
- case 55: /* ccons ::= CONSTRAINT nm */
- case 93: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93);
+ case 57: /* ccons ::= CONSTRAINT nm */
+ case 95: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==95);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
- case 56: /* ccons ::= DEFAULT term */
- case 58: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==58);
-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy342);}
- break;
- case 57: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);}
- break;
- case 59: /* ccons ::= DEFAULT MINUS term */
+ case 58: /* ccons ::= DEFAULT term */
+ case 60: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==60);
+{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy118);}
+ break;
+ case 59: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy118);}
+ break;
+ case 61: /* ccons ::= DEFAULT MINUS term */
{
ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy342.pExpr, 0, 0);
+ v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy118.pExpr, 0, 0);
v.zStart = yymsp[-1].minor.yy0.z;
- v.zEnd = yymsp[0].minor.yy342.zEnd;
+ v.zEnd = yymsp[0].minor.yy118.zEnd;
sqlite3AddDefaultValue(pParse,&v);
}
break;
- case 60: /* ccons ::= DEFAULT id */
+ case 62: /* ccons ::= DEFAULT id */
{
ExprSpan v;
spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
sqlite3AddDefaultValue(pParse,&v);
}
break;
- case 62: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy392);}
- break;
- case 63: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);}
- break;
- case 64: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);}
- break;
- case 65: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy342.pExpr);}
- break;
- case 66: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy442,yymsp[0].minor.yy392);}
- break;
- case 67: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);}
- break;
- case 68: /* ccons ::= COLLATE ids */
+ case 64: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);}
+ break;
+ case 65: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);}
+ break;
+ case 66: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0);}
+ break;
+ case 67: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy118.pExpr);}
+ break;
+ case 68: /* ccons ::= REFERENCES nm idxlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);}
+ break;
+ case 69: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);}
+ break;
+ case 70: /* ccons ::= COLLATE ids */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 71: /* refargs ::= */
-{ yygotominor.yy392 = OE_None*0x0101; /* EV: R-19803-45884 */}
- break;
- case 72: /* refargs ::= refargs refarg */
-{ yygotominor.yy392 = (yymsp[-1].minor.yy392 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
- break;
- case 73: /* refarg ::= MATCH nm */
- case 74: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==74);
-{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; }
- break;
- case 75: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392; yygotominor.yy207.mask = 0x0000ff; }
- break;
- case 76: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392<<8; yygotominor.yy207.mask = 0x00ff00; }
- break;
- case 77: /* refact ::= SET NULL */
-{ yygotominor.yy392 = OE_SetNull; /* EV: R-33326-45252 */}
- break;
- case 78: /* refact ::= SET DEFAULT */
-{ yygotominor.yy392 = OE_SetDflt; /* EV: R-33326-45252 */}
- break;
- case 79: /* refact ::= CASCADE */
-{ yygotominor.yy392 = OE_Cascade; /* EV: R-33326-45252 */}
- break;
- case 80: /* refact ::= RESTRICT */
-{ yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */}
- break;
- case 81: /* refact ::= NO ACTION */
-{ yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */}
- break;
- case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99);
- case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101);
- case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104);
-{yygotominor.yy392 = yymsp[0].minor.yy392;}
- break;
- case 87: /* conslist_opt ::= */
+ case 73: /* refargs ::= */
+{ yygotominor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */}
+ break;
+ case 74: /* refargs ::= refargs refarg */
+{ yygotominor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; }
+ break;
+ case 75: /* refarg ::= MATCH nm */
+ case 76: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==76);
+{ yygotominor.yy215.value = 0; yygotominor.yy215.mask = 0x000000; }
+ break;
+ case 77: /* refarg ::= ON DELETE refact */
+{ yygotominor.yy215.value = yymsp[0].minor.yy4; yygotominor.yy215.mask = 0x0000ff; }
+ break;
+ case 78: /* refarg ::= ON UPDATE refact */
+{ yygotominor.yy215.value = yymsp[0].minor.yy4<<8; yygotominor.yy215.mask = 0x00ff00; }
+ break;
+ case 79: /* refact ::= SET NULL */
+{ yygotominor.yy4 = OE_SetNull; /* EV: R-33326-45252 */}
+ break;
+ case 80: /* refact ::= SET DEFAULT */
+{ yygotominor.yy4 = OE_SetDflt; /* EV: R-33326-45252 */}
+ break;
+ case 81: /* refact ::= CASCADE */
+{ yygotominor.yy4 = OE_Cascade; /* EV: R-33326-45252 */}
+ break;
+ case 82: /* refact ::= RESTRICT */
+{ yygotominor.yy4 = OE_Restrict; /* EV: R-33326-45252 */}
+ break;
+ case 83: /* refact ::= NO ACTION */
+{ yygotominor.yy4 = OE_None; /* EV: R-33326-45252 */}
+ break;
+ case 85: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 101: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==101);
+ case 103: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==103);
+ case 106: /* resolvetype ::= raisetype */ yytestcase(yyruleno==106);
+{yygotominor.yy4 = yymsp[0].minor.yy4;}
+ break;
+ case 89: /* conslist_opt ::= */
{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
break;
- case 88: /* conslist_opt ::= COMMA conslist */
+ case 90: /* conslist_opt ::= COMMA conslist */
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
- case 91: /* tconscomma ::= COMMA */
+ case 93: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
- case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);}
- break;
- case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);}
- break;
- case 96: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);}
- break;
- case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
-{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392);
-}
- break;
- case 100: /* onconf ::= */
-{yygotominor.yy392 = OE_Default;}
- break;
- case 102: /* orconf ::= */
-{yygotominor.yy258 = OE_Default;}
- break;
- case 103: /* orconf ::= OR resolvetype */
-{yygotominor.yy258 = (u8)yymsp[0].minor.yy392;}
- break;
- case 105: /* resolvetype ::= IGNORE */
-{yygotominor.yy392 = OE_Ignore;}
- break;
- case 106: /* resolvetype ::= REPLACE */
-{yygotominor.yy392 = OE_Replace;}
- break;
- case 107: /* cmd ::= DROP TABLE ifexists fullname */
-{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392);
-}
- break;
- case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
-{
- sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy159, yymsp[-6].minor.yy392, yymsp[-4].minor.yy392);
-}
- break;
- case 111: /* cmd ::= DROP VIEW ifexists fullname */
-{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392);
-}
- break;
- case 112: /* cmd ::= select */
+ case 96: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);}
+ break;
+ case 97: /* tcons ::= UNIQUE LP idxlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0);}
+ break;
+ case 98: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy118.pExpr);}
+ break;
+ case 99: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
+{
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4);
+}
+ break;
+ case 102: /* onconf ::= */
+{yygotominor.yy4 = OE_Default;}
+ break;
+ case 104: /* orconf ::= */
+{yygotominor.yy210 = OE_Default;}
+ break;
+ case 105: /* orconf ::= OR resolvetype */
+{yygotominor.yy210 = (u8)yymsp[0].minor.yy4;}
+ break;
+ case 107: /* resolvetype ::= IGNORE */
+{yygotominor.yy4 = OE_Ignore;}
+ break;
+ case 108: /* resolvetype ::= REPLACE */
+{yygotominor.yy4 = OE_Replace;}
+ break;
+ case 109: /* cmd ::= DROP TABLE ifexists fullname */
+{
+ sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4);
+}
+ break;
+ case 112: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
+{
+ sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy387, yymsp[-6].minor.yy4, yymsp[-4].minor.yy4);
+}
+ break;
+ case 113: /* cmd ::= DROP VIEW ifexists fullname */
+{
+ sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4);
+}
+ break;
+ case 114: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy159, &dest);
+ sqlite3Select(pParse, yymsp[0].minor.yy387, &dest);
sqlite3ExplainBegin(pParse->pVdbe);
- sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy159);
+ sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy387);
sqlite3ExplainFinish(pParse->pVdbe);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
-}
- break;
- case 113: /* select ::= oneselect */
-{yygotominor.yy159 = yymsp[0].minor.yy159;}
- break;
- case 114: /* select ::= select multiselect_op oneselect */
-{
- if( yymsp[0].minor.yy159 ){
- yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
- yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
- if( yymsp[-1].minor.yy392!=TK_ALL ) pParse->hasCompound = 1;
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
- }
- yygotominor.yy159 = yymsp[0].minor.yy159;
-}
- break;
- case 116: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy392 = TK_ALL;}
- break;
- case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
-{
- yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy305,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
-}
- break;
- case 119: /* distinct ::= DISTINCT */
-{yygotominor.yy305 = SF_Distinct;}
- break;
- case 120: /* distinct ::= ALL */
- case 121: /* distinct ::= */ yytestcase(yyruleno==121);
-{yygotominor.yy305 = 0;}
- break;
- case 122: /* sclp ::= selcollist COMMA */
- case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
-{yygotominor.yy442 = yymsp[-1].minor.yy442;}
- break;
- case 123: /* sclp ::= */
- case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151);
- case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158);
- case 239: /* exprlist ::= */ yytestcase(yyruleno==239);
- case 245: /* idxlist_opt ::= */ yytestcase(yyruleno==245);
-{yygotominor.yy442 = 0;}
- break;
- case 124: /* selcollist ::= sclp expr as */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy442, yymsp[-1].minor.yy342.pExpr);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yygotominor.yy442,&yymsp[-1].minor.yy342);
-}
- break;
- case 125: /* selcollist ::= sclp STAR */
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
+}
+ break;
+ case 115: /* select ::= oneselect */
+{yygotominor.yy387 = yymsp[0].minor.yy387;}
+ break;
+ case 116: /* select ::= select multiselect_op oneselect */
+{
+ if( yymsp[0].minor.yy387 ){
+ yymsp[0].minor.yy387->op = (u8)yymsp[-1].minor.yy4;
+ yymsp[0].minor.yy387->pPrior = yymsp[-2].minor.yy387;
+ if( yymsp[-1].minor.yy4!=TK_ALL ) pParse->hasCompound = 1;
+ }else{
+ sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy387);
+ }
+ yygotominor.yy387 = yymsp[0].minor.yy387;
+}
+ break;
+ case 118: /* multiselect_op ::= UNION ALL */
+{yygotominor.yy4 = TK_ALL;}
+ break;
+ case 120: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+{
+ yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy177,yymsp[0].minor.yy292.pLimit,yymsp[0].minor.yy292.pOffset);
+}
+ break;
+ case 121: /* distinct ::= DISTINCT */
+{yygotominor.yy177 = SF_Distinct;}
+ break;
+ case 122: /* distinct ::= ALL */
+ case 123: /* distinct ::= */ yytestcase(yyruleno==123);
+{yygotominor.yy177 = 0;}
+ break;
+ case 124: /* sclp ::= selcollist COMMA */
+ case 248: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==248);
+{yygotominor.yy322 = yymsp[-1].minor.yy322;}
+ break;
+ case 125: /* sclp ::= */
+ case 153: /* orderby_opt ::= */ yytestcase(yyruleno==153);
+ case 160: /* groupby_opt ::= */ yytestcase(yyruleno==160);
+ case 241: /* exprlist ::= */ yytestcase(yyruleno==241);
+ case 247: /* idxlist_opt ::= */ yytestcase(yyruleno==247);
+{yygotominor.yy322 = 0;}
+ break;
+ case 126: /* selcollist ::= sclp expr as */
+{
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, yymsp[-1].minor.yy118.pExpr);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yygotominor.yy322,&yymsp[-1].minor.yy118);
+}
+ break;
+ case 127: /* selcollist ::= sclp STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy322, p);
}
break;
- case 126: /* selcollist ::= sclp nm DOT STAR */
+ case 128: /* selcollist ::= sclp nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, pDot);
}
break;
- case 129: /* as ::= */
+ case 131: /* as ::= */
{yygotominor.yy0.n = 0;}
break;
- case 130: /* from ::= */
-{yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));}
- break;
- case 131: /* from ::= FROM seltablist */
-{
- yygotominor.yy347 = yymsp[0].minor.yy347;
- sqlite3SrcListShiftJoinType(yygotominor.yy347);
-}
- break;
- case 132: /* stl_prefix ::= seltablist joinop */
-{
- yygotominor.yy347 = yymsp[-1].minor.yy347;
- if( ALWAYS(yygotominor.yy347 && yygotominor.yy347->nSrc>0) ) yygotominor.yy347->a[yygotominor.yy347->nSrc-1].jointype = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 133: /* stl_prefix ::= */
-{yygotominor.yy347 = 0;}
- break;
- case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
-{
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- sqlite3SrcListIndexedBy(pParse, yygotominor.yy347, &yymsp[-2].minor.yy0);
-}
- break;
- case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
-{
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- }
- break;
- case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
-{
- if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
- yygotominor.yy347 = yymsp[-4].minor.yy347;
- }else if( yymsp[-4].minor.yy347->nSrc==1 ){
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- if( yygotominor.yy347 ){
- struct SrcList_item *pNew = &yygotominor.yy347->a[yygotominor.yy347->nSrc-1];
- struct SrcList_item *pOld = yymsp[-4].minor.yy347->a;
+ case 132: /* from ::= */
+{yygotominor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy259));}
+ break;
+ case 133: /* from ::= FROM seltablist */
+{
+ yygotominor.yy259 = yymsp[0].minor.yy259;
+ sqlite3SrcListShiftJoinType(yygotominor.yy259);
+}
+ break;
+ case 134: /* stl_prefix ::= seltablist joinop */
+{
+ yygotominor.yy259 = yymsp[-1].minor.yy259;
+ if( ALWAYS(yygotominor.yy259 && yygotominor.yy259->nSrc>0) ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].jointype = (u8)yymsp[0].minor.yy4;
+}
+ break;
+ case 135: /* stl_prefix ::= */
+{yygotominor.yy259 = 0;}
+ break;
+ case 136: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+{
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ sqlite3SrcListIndexedBy(pParse, yygotominor.yy259, &yymsp[-2].minor.yy0);
+}
+ break;
+ case 137: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+{
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ }
+ break;
+ case 138: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+{
+ if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){
+ yygotominor.yy259 = yymsp[-4].minor.yy259;
+ }else if( yymsp[-4].minor.yy259->nSrc==1 ){
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ if( yygotominor.yy259 ){
+ struct SrcList_item *pNew = &yygotominor.yy259->a[yygotominor.yy259->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy259->a;
pNew->zName = pOld->zName;
pNew->zDatabase = pOld->zDatabase;
pNew->pSelect = pOld->pSelect;
pOld->zName = pOld->zDatabase = 0;
pOld->pSelect = 0;
}
- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy347);
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy259);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,SF_NestedFrom,0,0);
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,SF_NestedFrom,0,0);
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
}
}
break;
- case 137: /* dbnm ::= */
- case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146);
+ case 139: /* dbnm ::= */
+ case 148: /* indexed_opt ::= */ yytestcase(yyruleno==148);
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
- case 139: /* fullname ::= nm dbnm */
-{yygotominor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
- break;
- case 140: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy392 = JT_INNER; }
- break;
- case 141: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
- break;
- case 142: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
- break;
- case 143: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
- break;
- case 144: /* on_opt ::= ON expr */
- case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161);
- case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168);
- case 234: /* case_else ::= ELSE expr */ yytestcase(yyruleno==234);
- case 236: /* case_operand ::= expr */ yytestcase(yyruleno==236);
-{yygotominor.yy122 = yymsp[0].minor.yy342.pExpr;}
- break;
- case 145: /* on_opt ::= */
- case 160: /* having_opt ::= */ yytestcase(yyruleno==160);
- case 167: /* where_opt ::= */ yytestcase(yyruleno==167);
- case 235: /* case_else ::= */ yytestcase(yyruleno==235);
- case 237: /* case_operand ::= */ yytestcase(yyruleno==237);
-{yygotominor.yy122 = 0;}
- break;
- case 148: /* indexed_opt ::= NOT INDEXED */
+ case 141: /* fullname ::= nm dbnm */
+{yygotominor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
+ break;
+ case 142: /* joinop ::= COMMA|JOIN */
+{ yygotominor.yy4 = JT_INNER; }
+ break;
+ case 143: /* joinop ::= JOIN_KW JOIN */
+{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+ break;
+ case 144: /* joinop ::= JOIN_KW nm JOIN */
+{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
+ break;
+ case 145: /* joinop ::= JOIN_KW nm nm JOIN */
+{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
+ break;
+ case 146: /* on_opt ::= ON expr */
+ case 163: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==163);
+ case 170: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==170);
+ case 236: /* case_else ::= ELSE expr */ yytestcase(yyruleno==236);
+ case 238: /* case_operand ::= expr */ yytestcase(yyruleno==238);
+{yygotominor.yy314 = yymsp[0].minor.yy118.pExpr;}
+ break;
+ case 147: /* on_opt ::= */
+ case 162: /* having_opt ::= */ yytestcase(yyruleno==162);
+ case 169: /* where_opt ::= */ yytestcase(yyruleno==169);
+ case 237: /* case_else ::= */ yytestcase(yyruleno==237);
+ case 239: /* case_operand ::= */ yytestcase(yyruleno==239);
+{yygotominor.yy314 = 0;}
+ break;
+ case 150: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
- case 149: /* using_opt ::= USING LP inscollist RP */
- case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180);
-{yygotominor.yy180 = yymsp[-1].minor.yy180;}
- break;
- case 150: /* using_opt ::= */
- case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
-{yygotominor.yy180 = 0;}
- break;
- case 152: /* orderby_opt ::= ORDER BY sortlist */
- case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159);
- case 238: /* exprlist ::= nexprlist */ yytestcase(yyruleno==238);
-{yygotominor.yy442 = yymsp[0].minor.yy442;}
- break;
- case 153: /* sortlist ::= sortlist COMMA expr sortorder */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy342.pExpr);
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 154: /* sortlist ::= expr sortorder */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy342.pExpr);
- if( yygotominor.yy442 && ALWAYS(yygotominor.yy442->a) ) yygotominor.yy442->a[0].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 155: /* sortorder ::= ASC */
- case 157: /* sortorder ::= */ yytestcase(yyruleno==157);
-{yygotominor.yy392 = SQLITE_SO_ASC;}
- break;
- case 156: /* sortorder ::= DESC */
-{yygotominor.yy392 = SQLITE_SO_DESC;}
- break;
- case 162: /* limit_opt ::= */
-{yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;}
- break;
- case 163: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yygotominor.yy64.pOffset = 0;}
- break;
- case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy64.pLimit = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pOffset = yymsp[0].minor.yy342.pExpr;}
- break;
- case 165: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy64.pOffset = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr;}
- break;
- case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
-{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy347, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy347,yymsp[0].minor.yy122);
-}
- break;
- case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
-{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy442,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy347,yymsp[-1].minor.yy442,yymsp[0].minor.yy122,yymsp[-5].minor.yy258);
-}
- break;
- case 170: /* setlist ::= setlist COMMA nm EQ expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
-}
- break;
- case 171: /* setlist ::= nm EQ expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
-}
- break;
- case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy347, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
- break;
- case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy347, 0, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
- break;
- case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
-{sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy258);}
- break;
- case 175: /* insert_cmd ::= INSERT orconf */
-{yygotominor.yy258 = yymsp[0].minor.yy258;}
- break;
- case 176: /* insert_cmd ::= REPLACE */
-{yygotominor.yy258 = OE_Replace;}
- break;
- case 177: /* valuelist ::= VALUES LP nexprlist RP */
-{
- yygotominor.yy487.pList = yymsp[-1].minor.yy442;
- yygotominor.yy487.pSelect = 0;
-}
- break;
- case 178: /* valuelist ::= valuelist COMMA LP exprlist RP */
-{
- Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy442, 0, 0, 0, 0, 0, 0, 0, 0);
- if( yymsp[-4].minor.yy487.pList ){
- yymsp[-4].minor.yy487.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy487.pList, 0, 0, 0, 0, 0, 0, 0, 0);
- yymsp[-4].minor.yy487.pList = 0;
- }
- yygotominor.yy487.pList = 0;
- if( yymsp[-4].minor.yy487.pSelect==0 || pRight==0 ){
+ case 151: /* using_opt ::= USING LP idlist RP */
+ case 182: /* inscollist_opt ::= LP idlist RP */ yytestcase(yyruleno==182);
+{yygotominor.yy384 = yymsp[-1].minor.yy384;}
+ break;
+ case 152: /* using_opt ::= */
+ case 181: /* inscollist_opt ::= */ yytestcase(yyruleno==181);
+{yygotominor.yy384 = 0;}
+ break;
+ case 154: /* orderby_opt ::= ORDER BY sortlist */
+ case 161: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==161);
+ case 240: /* exprlist ::= nexprlist */ yytestcase(yyruleno==240);
+{yygotominor.yy322 = yymsp[0].minor.yy322;}
+ break;
+ case 155: /* sortlist ::= sortlist COMMA expr sortorder */
+{
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy118.pExpr);
+ if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
+}
+ break;
+ case 156: /* sortlist ::= expr sortorder */
+{
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy118.pExpr);
+ if( yygotominor.yy322 && ALWAYS(yygotominor.yy322->a) ) yygotominor.yy322->a[0].sortOrder = (u8)yymsp[0].minor.yy4;
+}
+ break;
+ case 157: /* sortorder ::= ASC */
+ case 159: /* sortorder ::= */ yytestcase(yyruleno==159);
+{yygotominor.yy4 = SQLITE_SO_ASC;}
+ break;
+ case 158: /* sortorder ::= DESC */
+{yygotominor.yy4 = SQLITE_SO_DESC;}
+ break;
+ case 164: /* limit_opt ::= */
+{yygotominor.yy292.pLimit = 0; yygotominor.yy292.pOffset = 0;}
+ break;
+ case 165: /* limit_opt ::= LIMIT expr */
+{yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr; yygotominor.yy292.pOffset = 0;}
+ break;
+ case 166: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yygotominor.yy292.pLimit = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pOffset = yymsp[0].minor.yy118.pExpr;}
+ break;
+ case 167: /* limit_opt ::= LIMIT expr COMMA expr */
+{yygotominor.yy292.pOffset = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr;}
+ break;
+ case 168: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
+{
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314);
+}
+ break;
+ case 171: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
+{
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy210);
+}
+ break;
+ case 172: /* setlist ::= setlist COMMA nm EQ expr */
+{
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy118.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
+}
+ break;
+ case 173: /* setlist ::= nm EQ expr */
+{
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy118.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
+}
+ break;
+ case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */
+{sqlite3Insert(pParse, yymsp[-2].minor.yy259, yymsp[0].minor.yy260.pList, yymsp[0].minor.yy260.pSelect, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);}
+ break;
+ case 175: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
+{sqlite3Insert(pParse, yymsp[-2].minor.yy259, 0, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);}
+ break;
+ case 176: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
+{sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy210);}
+ break;
+ case 177: /* insert_cmd ::= INSERT orconf */
+{yygotominor.yy210 = yymsp[0].minor.yy210;}
+ break;
+ case 178: /* insert_cmd ::= REPLACE */
+{yygotominor.yy210 = OE_Replace;}
+ break;
+ case 179: /* valuelist ::= VALUES LP nexprlist RP */
+{
+ yygotominor.yy260.pList = yymsp[-1].minor.yy322;
+ yygotominor.yy260.pSelect = 0;
+}
+ break;
+ case 180: /* valuelist ::= valuelist COMMA LP exprlist RP */
+{
+ Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy322, 0, 0, 0, 0, 0, 0, 0, 0);
+ if( yymsp[-4].minor.yy260.pList ){
+ yymsp[-4].minor.yy260.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy260.pList, 0, 0, 0, 0, 0, 0, 0, 0);
+ yymsp[-4].minor.yy260.pList = 0;
+ }
+ yygotominor.yy260.pList = 0;
+ if( yymsp[-4].minor.yy260.pSelect==0 || pRight==0 ){
sqlite3SelectDelete(pParse->db, pRight);
- sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy487.pSelect);
- yygotominor.yy487.pSelect = 0;
+ sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy260.pSelect);
+ yygotominor.yy260.pSelect = 0;
}else{
pRight->op = TK_ALL;
- pRight->pPrior = yymsp[-4].minor.yy487.pSelect;
+ pRight->pPrior = yymsp[-4].minor.yy260.pSelect;
pRight->selFlags |= SF_Values;
pRight->pPrior->selFlags |= SF_Values;
- yygotominor.yy487.pSelect = pRight;
- }
-}
- break;
- case 181: /* inscollist ::= inscollist COMMA nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);}
- break;
- case 182: /* inscollist ::= nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
- break;
- case 183: /* expr ::= term */
-{yygotominor.yy342 = yymsp[0].minor.yy342;}
- break;
- case 184: /* expr ::= LP expr RP */
-{yygotominor.yy342.pExpr = yymsp[-1].minor.yy342.pExpr; spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
- break;
- case 185: /* term ::= NULL */
- case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
- case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
-{spanExpr(&yygotominor.yy342, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
- break;
- case 186: /* expr ::= id */
- case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
-{spanExpr(&yygotominor.yy342, pParse, TK_ID, &yymsp[0].minor.yy0);}
- break;
- case 188: /* expr ::= nm DOT nm */
+ yygotominor.yy260.pSelect = pRight;
+ }
+}
+ break;
+ case 183: /* idlist ::= idlist COMMA nm */
+{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);}
+ break;
+ case 184: /* idlist ::= nm */
+{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
+ break;
+ case 185: /* expr ::= term */
+{yygotominor.yy118 = yymsp[0].minor.yy118;}
+ break;
+ case 186: /* expr ::= LP expr RP */
+{yygotominor.yy118.pExpr = yymsp[-1].minor.yy118.pExpr; spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
+ break;
+ case 187: /* term ::= NULL */
+ case 192: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==192);
+ case 193: /* term ::= STRING */ yytestcase(yyruleno==193);
+{spanExpr(&yygotominor.yy118, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
+ break;
+ case 188: /* expr ::= id */
+ case 189: /* expr ::= JOIN_KW */ yytestcase(yyruleno==189);
+{spanExpr(&yygotominor.yy118, pParse, TK_ID, &yymsp[0].minor.yy0);}
+ break;
+ case 190: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
- spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 189: /* expr ::= nm DOT nm DOT nm */
+ case 191: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
- spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 192: /* expr ::= REGISTER */
+ case 194: /* expr ::= REGISTER */
{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = 0;
- }else{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
- if( yygotominor.yy342.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy342.pExpr->iTable);
- }
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 193: /* expr ::= VARIABLE */
-{
- spanExpr(&yygotominor.yy342, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yygotominor.yy342.pExpr);
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 194: /* expr ::= expr COLLATE ids */
-{
- yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
- yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 195: /* expr ::= CAST LP expr AS typetoken RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 196: /* expr ::= ID LP distinct exprlist RP */
-{
- if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+ yygotominor.yy118.pExpr = 0;
+ }else{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
+ if( yygotominor.yy118.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy118.pExpr->iTable);
+ }
+ spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+}
+ break;
+ case 195: /* expr ::= VARIABLE */
+{
+ spanExpr(&yygotominor.yy118, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yygotominor.yy118.pExpr);
+ spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+}
+ break;
+ case 196: /* expr ::= expr COLLATE ids */
+{
+ yygotominor.yy118.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy118.pExpr, &yymsp[0].minor.yy0);
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+}
+ break;
+ case 197: /* expr ::= CAST LP expr AS typetoken RP */
+{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy118.pExpr, 0, &yymsp[-1].minor.yy0);
+ spanSet(&yygotominor.yy118,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+}
+ break;
+ case 198: /* expr ::= ID LP distinct exprlist RP */
+{
+ if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy305 && yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->flags |= EP_Distinct;
- }
-}
- break;
- case 197: /* expr ::= ID LP STAR RP */
-{
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 198: /* term ::= CTIME_KW */
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
+ spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ if( yymsp[-2].minor.yy177 && yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->flags |= EP_Distinct;
+ }
+}
+ break;
+ case 199: /* expr ::= ID LP STAR RP */
+{
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+ spanSet(&yygotominor.yy118,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+}
+ break;
+ case 200: /* term ::= CTIME_KW */
{
/* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
** treated as functions that return constants */
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->op = TK_CONST_FUNC;
- }
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 199: /* expr ::= expr AND expr */
- case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
- case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
- case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
- case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
- case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
- case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
- case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
-{spanBinaryExpr(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);}
- break;
- case 207: /* likeop ::= LIKE_KW */
- case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209);
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 0;}
- break;
- case 208: /* likeop ::= NOT LIKE_KW */
- case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210);
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 1;}
- break;
- case 211: /* expr ::= expr likeop expr */
-{
- ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy318.eOperator);
- if( yymsp[-1].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
- if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
-}
- break;
- case 212: /* expr ::= expr likeop expr ESCAPE expr */
-{
- ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy318.eOperator);
- if( yymsp[-3].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
- if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
-}
- break;
- case 213: /* expr ::= expr ISNULL|NOTNULL */
-{spanUnaryPostfix(&yygotominor.yy342,pParse,yymsp[0].major,&yymsp[-1].minor.yy342,&yymsp[0].minor.yy0);}
- break;
- case 214: /* expr ::= expr NOT NULL */
-{spanUnaryPostfix(&yygotominor.yy342,pParse,TK_NOTNULL,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy0);}
- break;
- case 215: /* expr ::= expr IS expr */
-{
- spanBinaryExpr(&yygotominor.yy342,pParse,TK_IS,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_ISNULL);
-}
- break;
- case 216: /* expr ::= expr IS NOT expr */
-{
- spanBinaryExpr(&yygotominor.yy342,pParse,TK_ISNOT,&yymsp[-3].minor.yy342,&yymsp[0].minor.yy342);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_NOTNULL);
-}
- break;
- case 217: /* expr ::= NOT expr */
- case 218: /* expr ::= BITNOT expr */ yytestcase(yyruleno==218);
-{spanUnaryPrefix(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
- break;
- case 219: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
- break;
- case 220: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
- break;
- case 223: /* expr ::= expr between_op expr AND expr */
-{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = pList;
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->op = TK_CONST_FUNC;
+ }
+ spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+}
+ break;
+ case 201: /* expr ::= expr AND expr */
+ case 202: /* expr ::= expr OR expr */ yytestcase(yyruleno==202);
+ case 203: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==203);
+ case 204: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==204);
+ case 205: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==205);
+ case 206: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==206);
+ case 207: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==207);
+ case 208: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==208);
+{spanBinaryExpr(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);}
+ break;
+ case 209: /* likeop ::= LIKE_KW */
+ case 211: /* likeop ::= MATCH */ yytestcase(yyruleno==211);
+{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 0;}
+ break;
+ case 210: /* likeop ::= NOT LIKE_KW */
+ case 212: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==212);
+{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 1;}
+ break;
+ case 213: /* expr ::= expr likeop expr */
+{
+ ExprList *pList;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy342.eOperator);
+ if( yymsp[-1].minor.yy342.bNot ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+ if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
+}
+ break;
+ case 214: /* expr ::= expr likeop expr ESCAPE expr */
+{
+ ExprList *pList;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy342.eOperator);
+ if( yymsp[-3].minor.yy342.bNot ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+ if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
+}
+ break;
+ case 215: /* expr ::= expr ISNULL|NOTNULL */
+{spanUnaryPostfix(&yygotominor.yy118,pParse,yymsp[0].major,&yymsp[-1].minor.yy118,&yymsp[0].minor.yy0);}
+ break;
+ case 216: /* expr ::= expr NOT NULL */
+{spanUnaryPostfix(&yygotominor.yy118,pParse,TK_NOTNULL,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy0);}
+ break;
+ case 217: /* expr ::= expr IS expr */
+{
+ spanBinaryExpr(&yygotominor.yy118,pParse,TK_IS,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_ISNULL);
+}
+ break;
+ case 218: /* expr ::= expr IS NOT expr */
+{
+ spanBinaryExpr(&yygotominor.yy118,pParse,TK_ISNOT,&yymsp[-3].minor.yy118,&yymsp[0].minor.yy118);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_NOTNULL);
+}
+ break;
+ case 219: /* expr ::= NOT expr */
+ case 220: /* expr ::= BITNOT expr */ yytestcase(yyruleno==220);
+{spanUnaryPrefix(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+ break;
+ case 221: /* expr ::= MINUS expr */
+{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UMINUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+ break;
+ case 222: /* expr ::= PLUS expr */
+{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UPLUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+ break;
+ case 225: /* expr ::= expr between_op expr AND expr */
+{
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
-}
- break;
- case 226: /* expr ::= expr in_op LP exprlist RP */
-{
- if( yymsp[-1].minor.yy442==0 ){
+ if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+}
+ break;
+ case 228: /* expr ::= expr in_op LP exprlist RP */
+{
+ if( yymsp[-1].minor.yy322==0 ){
/* Expressions of the form
**
** expr1 IN ()
** expr1 NOT IN ()
**
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy392]);
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy342.pExpr);
- }else{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = yymsp[-1].minor.yy442;
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
- }
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- }
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 227: /* expr ::= LP select RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- yygotominor.yy342.zStart = yymsp[-2].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 228: /* expr ::= expr in_op LP select RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 229: /* expr ::= expr in_op nm dbnm */
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy4]);
+ sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy118.pExpr);
+ }else{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy322;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ }else{
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
+ }
+ if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ }
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ }
+ break;
+ case 229: /* expr ::= LP select RP */
+{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ }else{
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
+ }
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ }
+ break;
+ case 230: /* expr ::= expr in_op LP select RP */
+{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ }else{
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
+ }
+ if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ }
+ break;
+ case 231: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
- if( yymsp[-2].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-3].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
- }
- break;
- case 230: /* expr ::= EXISTS LP select RP */
-{
- Expr *p = yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ if( yymsp[-2].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
+ }
+ break;
+ case 232: /* expr ::= EXISTS LP select RP */
+{
+ Expr *p = yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
- p->x.pSelect = yymsp[-1].minor.yy159;
+ p->x.pSelect = yymsp[-1].minor.yy387;
ExprSetProperty(p, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, p);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 231: /* expr ::= CASE case_operand case_exprlist case_else END */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = yymsp[-1].minor.yy122 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[-1].minor.yy122) : yymsp[-2].minor.yy442;
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy122);
- }
- yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 232: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
-}
- break;
- case 233: /* case_exprlist ::= WHEN expr THEN expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
-}
- break;
- case 240: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
- break;
- case 241: /* nexprlist ::= expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
- break;
- case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
+ }
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ }
+ break;
+ case 233: /* expr ::= CASE case_operand case_exprlist case_else END */
+{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy314 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy314) : yymsp[-2].minor.yy322;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ }else{
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy314);
+ }
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+}
+ break;
+ case 234: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+{
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
+}
+ break;
+ case 235: /* case_exprlist ::= WHEN expr THEN expr */
+{
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
+}
+ break;
+ case 242: /* nexprlist ::= nexprlist COMMA expr */
+{yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy118.pExpr);}
+ break;
+ case 243: /* nexprlist ::= expr */
+{yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy118.pExpr);}
+ break;
+ case 244: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist 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.yy442, yymsp[-10].minor.yy392,
- &yymsp[-11].minor.yy0, yymsp[0].minor.yy122, SQLITE_SO_ASC, yymsp[-8].minor.yy392);
-}
- break;
- case 243: /* uniqueflag ::= UNIQUE */
- case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
-{yygotominor.yy392 = OE_Abort;}
- break;
- case 244: /* uniqueflag ::= */
-{yygotominor.yy392 = OE_None;}
- break;
- case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
-{
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
- sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 248: /* idxlist ::= nm collate sortorder */
-{
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 249: /* collate ::= */
+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy4,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy314, SQLITE_SO_ASC, yymsp[-8].minor.yy4);
+}
+ break;
+ case 245: /* uniqueflag ::= UNIQUE */
+ case 298: /* raisetype ::= ABORT */ yytestcase(yyruleno==298);
+{yygotominor.yy4 = OE_Abort;}
+ break;
+ case 246: /* uniqueflag ::= */
+{yygotominor.yy4 = OE_None;}
+ break;
+ case 249: /* idxlist ::= idxlist COMMA nm collate sortorder */
+{
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, p);
+ sqlite3ExprListSetName(pParse,yygotominor.yy322,&yymsp[-2].minor.yy0,1);
+ sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index");
+ if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
+}
+ break;
+ case 250: /* idxlist ::= nm collate sortorder */
+{
+ Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, p);
+ sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
+ sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index");
+ if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
+}
+ break;
+ case 251: /* collate ::= */
{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
break;
- case 251: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);}
+ case 253: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);}
break;
- case 252: /* cmd ::= VACUUM */
- case 253: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==253);
+ case 254: /* cmd ::= VACUUM */
+ case 255: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==255);
{sqlite3Vacuum(pParse);}
break;
- case 254: /* cmd ::= PRAGMA nm dbnm */
+ case 256: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 255: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 257: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 256: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 258: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 257: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 259: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 258: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 260: /* 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 268: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 270: /* 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.yy327, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all);
}
break;
- case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 271: /* 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.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4);
yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
}
break;
- case 270: /* trigger_time ::= BEFORE */
- case 273: /* trigger_time ::= */ yytestcase(yyruleno==273);
-{ yygotominor.yy392 = TK_BEFORE; }
- break;
- case 271: /* trigger_time ::= AFTER */
-{ yygotominor.yy392 = TK_AFTER; }
- break;
- case 272: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy392 = TK_INSTEAD;}
- break;
- case 274: /* trigger_event ::= DELETE|INSERT */
- case 275: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==275);
-{yygotominor.yy410.a = yymsp[0].major; yygotominor.yy410.b = 0;}
- break;
- case 276: /* trigger_event ::= UPDATE OF inscollist */
-{yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;}
- break;
- case 279: /* when_clause ::= */
- case 301: /* key_opt ::= */ yytestcase(yyruleno==301);
-{ yygotominor.yy122 = 0; }
- break;
- case 280: /* when_clause ::= WHEN expr */
- case 302: /* key_opt ::= KEY expr */ yytestcase(yyruleno==302);
-{ yygotominor.yy122 = yymsp[0].minor.yy342.pExpr; }
- break;
- case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
-{
- assert( yymsp[-2].minor.yy327!=0 );
- yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327;
- yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327;
- yygotominor.yy327 = yymsp[-2].minor.yy327;
-}
- break;
- case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */
-{
- assert( yymsp[-1].minor.yy327!=0 );
- yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327;
- yygotominor.yy327 = yymsp[-1].minor.yy327;
-}
- break;
- case 284: /* trnm ::= nm DOT nm */
+ case 272: /* trigger_time ::= BEFORE */
+ case 275: /* trigger_time ::= */ yytestcase(yyruleno==275);
+{ yygotominor.yy4 = TK_BEFORE; }
+ break;
+ case 273: /* trigger_time ::= AFTER */
+{ yygotominor.yy4 = TK_AFTER; }
+ break;
+ case 274: /* trigger_time ::= INSTEAD OF */
+{ yygotominor.yy4 = TK_INSTEAD;}
+ break;
+ case 276: /* trigger_event ::= DELETE|INSERT */
+ case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277);
+{yygotominor.yy90.a = yymsp[0].major; yygotominor.yy90.b = 0;}
+ break;
+ case 278: /* trigger_event ::= UPDATE OF idlist */
+{yygotominor.yy90.a = TK_UPDATE; yygotominor.yy90.b = yymsp[0].minor.yy384;}
+ break;
+ case 281: /* when_clause ::= */
+ case 303: /* key_opt ::= */ yytestcase(yyruleno==303);
+{ yygotominor.yy314 = 0; }
+ break;
+ case 282: /* when_clause ::= WHEN expr */
+ case 304: /* key_opt ::= KEY expr */ yytestcase(yyruleno==304);
+{ yygotominor.yy314 = yymsp[0].minor.yy118.pExpr; }
+ break;
+ case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+{
+ assert( yymsp[-2].minor.yy203!=0 );
+ yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203;
+ yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203;
+ yygotominor.yy203 = yymsp[-2].minor.yy203;
+}
+ break;
+ case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */
+{
+ assert( yymsp[-1].minor.yy203!=0 );
+ yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203;
+ yygotominor.yy203 = yymsp[-1].minor.yy203;
+}
+ break;
+ case 286: /* trnm ::= nm DOT nm */
{
yygotominor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
"statements within triggers");
}
break;
- case 286: /* tridxby ::= INDEXED BY nm */
+ case 288: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 287: /* tridxby ::= NOT INDEXED */
+ case 289: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 288: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
-{ yygotominor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-5].minor.yy258); }
- break;
- case 289: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */
-{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-4].minor.yy258);}
- break;
- case 290: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
-{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, 0, yymsp[0].minor.yy159, yymsp[-4].minor.yy258);}
- break;
- case 291: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);}
- break;
- case 292: /* trigger_cmd ::= select */
-{yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); }
- break;
- case 293: /* expr ::= RAISE LP IGNORE RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->affinity = OE_Ignore;
- }
- yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 294: /* expr ::= RAISE LP raisetype COMMA nm RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
- if( yygotominor.yy342.pExpr ) {
- yygotominor.yy342.pExpr->affinity = (char)yymsp[-3].minor.yy392;
- }
- yygotominor.yy342.zStart = yymsp[-5].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 295: /* raisetype ::= ROLLBACK */
-{yygotominor.yy392 = OE_Rollback;}
- break;
- case 297: /* raisetype ::= FAIL */
-{yygotominor.yy392 = OE_Fail;}
- break;
- case 298: /* cmd ::= DROP TRIGGER ifexists fullname */
-{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392);
-}
- break;
- case 299: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
-{
- sqlite3Attach(pParse, yymsp[-3].minor.yy342.pExpr, yymsp[-1].minor.yy342.pExpr, yymsp[0].minor.yy122);
-}
- break;
- case 300: /* cmd ::= DETACH database_kw_opt expr */
-{
- sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr);
-}
- break;
- case 305: /* cmd ::= REINDEX */
+ case 290: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+{ yygotominor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy314, yymsp[-5].minor.yy210); }
+ break;
+ case 291: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */
+{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, yymsp[0].minor.yy260.pList, yymsp[0].minor.yy260.pSelect, yymsp[-4].minor.yy210);}
+ break;
+ case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
+{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, 0, yymsp[0].minor.yy387, yymsp[-4].minor.yy210);}
+ break;
+ case 293: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+{yygotominor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy314);}
+ break;
+ case 294: /* trigger_cmd ::= select */
+{yygotominor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy387); }
+ break;
+ case 295: /* expr ::= RAISE LP IGNORE RP */
+{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->affinity = OE_Ignore;
+ }
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+}
+ break;
+ case 296: /* expr ::= RAISE LP raisetype COMMA nm RP */
+{
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+ if( yygotominor.yy118.pExpr ) {
+ yygotominor.yy118.pExpr->affinity = (char)yymsp[-3].minor.yy4;
+ }
+ yygotominor.yy118.zStart = yymsp[-5].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+}
+ break;
+ case 297: /* raisetype ::= ROLLBACK */
+{yygotominor.yy4 = OE_Rollback;}
+ break;
+ case 299: /* raisetype ::= FAIL */
+{yygotominor.yy4 = OE_Fail;}
+ break;
+ case 300: /* cmd ::= DROP TRIGGER ifexists fullname */
+{
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4);
+}
+ break;
+ case 301: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+{
+ sqlite3Attach(pParse, yymsp[-3].minor.yy118.pExpr, yymsp[-1].minor.yy118.pExpr, yymsp[0].minor.yy314);
+}
+ break;
+ case 302: /* cmd ::= DETACH database_kw_opt expr */
+{
+ sqlite3Detach(pParse, yymsp[0].minor.yy118.pExpr);
+}
+ break;
+ case 307: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 306: /* cmd ::= REINDEX nm dbnm */
+ case 308: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 307: /* cmd ::= ANALYZE */
+ case 309: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 308: /* cmd ::= ANALYZE nm dbnm */
+ case 310: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 309: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 311: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0);
}
break;
- case 310: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
+ case 312: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
- case 311: /* add_column_fullname ::= fullname */
+ case 313: /* add_column_fullname ::= fullname */
{
pParse->db->lookaside.bEnabled = 0;
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259);
}
break;
- case 314: /* cmd ::= create_vtab */
+ case 316: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 315: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 317: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 316: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 318: /* 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.yy392);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy4);
}
break;
- case 319: /* vtabarg ::= */
+ case 321: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 321: /* vtabargtoken ::= ANY */
- case 322: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==322);
- case 323: /* lp ::= LP */ yytestcase(yyruleno==323);
+ case 323: /* vtabargtoken ::= ANY */
+ case 324: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==324);
+ case 325: /* lp ::= LP */ yytestcase(yyruleno==325);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
default:
/* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
/* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
@@ -116001,34 +117398,34 @@
/* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
/* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
/* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
/* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
/* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
- /* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34);
- /* (35) columnlist ::= column */ yytestcase(yyruleno==35);
- /* (44) type ::= */ yytestcase(yyruleno==44);
- /* (51) signed ::= plus_num */ yytestcase(yyruleno==51);
- /* (52) signed ::= minus_num */ yytestcase(yyruleno==52);
- /* (53) carglist ::= carglist ccons */ yytestcase(yyruleno==53);
- /* (54) carglist ::= */ yytestcase(yyruleno==54);
- /* (61) ccons ::= NULL onconf */ yytestcase(yyruleno==61);
- /* (89) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==89);
- /* (90) conslist ::= tcons */ yytestcase(yyruleno==90);
- /* (92) tconscomma ::= */ yytestcase(yyruleno==92);
- /* (277) foreach_clause ::= */ yytestcase(yyruleno==277);
- /* (278) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==278);
- /* (285) tridxby ::= */ yytestcase(yyruleno==285);
- /* (303) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==303);
- /* (304) database_kw_opt ::= */ yytestcase(yyruleno==304);
- /* (312) kwcolumn_opt ::= */ yytestcase(yyruleno==312);
- /* (313) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==313);
- /* (317) vtabarglist ::= vtabarg */ yytestcase(yyruleno==317);
- /* (318) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==318);
- /* (320) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==320);
- /* (324) anylist ::= */ yytestcase(yyruleno==324);
- /* (325) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==325);
- /* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326);
+ /* (36) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==36);
+ /* (37) columnlist ::= column */ yytestcase(yyruleno==37);
+ /* (46) type ::= */ yytestcase(yyruleno==46);
+ /* (53) signed ::= plus_num */ yytestcase(yyruleno==53);
+ /* (54) signed ::= minus_num */ yytestcase(yyruleno==54);
+ /* (55) carglist ::= carglist ccons */ yytestcase(yyruleno==55);
+ /* (56) carglist ::= */ yytestcase(yyruleno==56);
+ /* (63) ccons ::= NULL onconf */ yytestcase(yyruleno==63);
+ /* (91) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==91);
+ /* (92) conslist ::= tcons */ yytestcase(yyruleno==92);
+ /* (94) tconscomma ::= */ yytestcase(yyruleno==94);
+ /* (279) foreach_clause ::= */ yytestcase(yyruleno==279);
+ /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280);
+ /* (287) tridxby ::= */ yytestcase(yyruleno==287);
+ /* (305) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==305);
+ /* (306) database_kw_opt ::= */ yytestcase(yyruleno==306);
+ /* (314) kwcolumn_opt ::= */ yytestcase(yyruleno==314);
+ /* (315) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==315);
+ /* (319) vtabarglist ::= vtabarg */ yytestcase(yyruleno==319);
+ /* (320) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==320);
+ /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322);
+ /* (326) anylist ::= */ yytestcase(yyruleno==326);
+ /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327);
+ /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328);
break;
};
assert( yyruleno>=0 && yyrulenopNewTrigger);
for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
sqlite3DbFree(db, pParse->azVar);
- sqlite3DbFree(db, pParse->aAlias);
while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc;
pParse->pAinc = p->pNext;
sqlite3DbFree(db, p);
}
@@ -118594,10 +119992,11 @@
case SQLITE_CONSTRAINT_COMMITHOOK:
zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break;
case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break;
case SQLITE_CONSTRAINT_FUNCTION:
zName = "SQLITE_CONSTRAINT_FUNCTION"; break;
+ case SQLITE_CONSTRAINT_ROWID: zName = "SQLITE_CONSTRAINT_ROWID"; break;
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
case SQLITE_AUTH: zName = "SQLITE_AUTH"; break;
case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break;
@@ -119408,10 +120807,36 @@
** function.
*/
SQLITE_API const char *sqlite3_errstr(int rc){
return sqlite3ErrStr(rc);
}
+
+/*
+** Invalidate all cached KeyInfo objects for database connection "db"
+*/
+static void invalidateCachedKeyInfo(sqlite3 *db){
+ Db *pDb; /* A single database */
+ int iDb; /* The database index number */
+ HashElem *k; /* For looping over tables in pDb */
+ Table *pTab; /* A table in the database */
+ Index *pIdx; /* Each index */
+
+ for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){
+ if( pDb->pBt==0 ) continue;
+ sqlite3BtreeEnter(pDb->pBt);
+ for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
+ pTab = (Table*)sqliteHashData(k);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->pKeyInfo && pIdx->pKeyInfo->db==db ){
+ sqlite3KeyInfoUnref(pIdx->pKeyInfo);
+ pIdx->pKeyInfo = 0;
+ }
+ }
+ }
+ sqlite3BtreeLeave(pDb->pBt);
+ }
+}
/*
** Create a new collating function for database "db". The name is zName
** and the encoding is enc.
*/
@@ -119453,10 +120878,11 @@
sqlite3Error(db, SQLITE_BUSY,
"unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY;
}
sqlite3ExpirePreparedStatements(db);
+ invalidateCachedKeyInfo(db);
/* If collation sequence pColl was created directly by a call to
** sqlite3_create_collation, and not generated by synthCollSeq(),
** then any copies made by synthCollSeq() need to be invalidated.
** Also, collation destructor - CollSeq.xDel() - function may need
@@ -128435,10 +129861,15 @@
}
*ppCsr = pCsr;
return rc;
}
+/*
+** Function getNextNode(), which is called by fts3ExprParse(), may itself
+** call fts3ExprParse(). So this forward declaration is required.
+*/
+static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
/*
** Extract the next token from buffer z (length n) using the tokenizer
** and other information (column names etc.) in pParse. Create an Fts3Expr
** structure of type FTSQUERY_PHRASE containing a phrase consisting of this
@@ -128469,11 +129900,35 @@
const char *zToken;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
int nByte; /* total space to allocate */
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
- if( rc==SQLITE_OK ){
+
+ if( (rc==SQLITE_OK || rc==SQLITE_DONE) && sqlite3_fts3_enable_parentheses ){
+ int i;
+ if( rc==SQLITE_DONE ) iStart = n;
+ for(i=0; inNest++;
+ rc = fts3ExprParse(pParse, &z[i+1], n-i-1, &pRet, &nConsumed);
+ if( rc==SQLITE_OK && !pRet ){
+ rc = SQLITE_DONE;
+ }
+ nConsumed = (int)(i + 1 + nConsumed);
+ break;
+ }
+
+ if( z[i]==')' ){
+ rc = SQLITE_DONE;
+ pParse->nNest--;
+ nConsumed = i+1;
+ break;
+ }
+ }
+ }
+
+ if( nConsumed==0 && rc==SQLITE_OK ){
nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
pRet = (Fts3Expr *)fts3MallocZero(nByte);
if( !pRet ){
rc = SQLITE_NOMEM;
}else{
@@ -128649,16 +130104,10 @@
sqlite3_free(p);
*ppExpr = 0;
return SQLITE_NOMEM;
}
-/*
-** Function getNextNode(), which is called by fts3ExprParse(), may itself
-** call fts3ExprParse(). So this forward declaration is required.
-*/
-static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
-
/*
** The output variable *ppExpr is populated with an allocated Fts3Expr
** structure, or set to 0 if the end of the input buffer is reached.
**
** Returns an SQLite error code. SQLITE_OK if everything works, SQLITE_NOMEM
@@ -128751,31 +130200,10 @@
** user has supplied a token such as "ORacle". Continue.
*/
}
}
- /* Check for an open bracket. */
- if( sqlite3_fts3_enable_parentheses ){
- if( *zInput=='(' ){
- int nConsumed;
- 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;
- }
-
- /* Check for a close bracket. */
- if( *zInput==')' ){
- pParse->nNest--;
- *pnConsumed = (int)((zInput - z) + 1);
- return SQLITE_DONE;
- }
- }
-
/* See if we are dealing with a quoted phrase. If this is the case, then
** search for the closing quote and pass the whole string to getNextString()
** for processing. This is easy to do, as fts3 has no syntax for escaping
** a quote character embedded in a string.
*/
@@ -139614,10 +141042,20 @@
** ever contain very many entries, so a fixed number of buckets is
** used.
*/
#define HASHSIZE 128
+/* The xBestIndex method of this virtual table requires an estimate of
+** the number of rows in the virtual table to calculate the costs of
+** various strategies. If possible, this estimate is loaded from the
+** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum).
+** Otherwise, if no sqlite_stat1 entry is available, use
+** RTREE_DEFAULT_ROWEST.
+*/
+#define RTREE_DEFAULT_ROWEST 1048576
+#define RTREE_MIN_ROWEST 100
+
/*
** An rtree virtual-table object.
*/
struct Rtree {
sqlite3_vtab base;
@@ -139628,10 +141066,11 @@
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 */
RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */
int nBusy; /* Current number of users of this structure */
+ i64 nRowEst; /* Estimated number of rows in this table */
/* List of nodes removed during a CondenseTree operation. List is
** linked together via the pointer normally used for hash chains -
** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree
** headed by the node (leaf nodes have RtreeNode.iNode==0).
@@ -140819,10 +142258,23 @@
}
rtreeRelease(pRtree);
return rc;
}
+
+/*
+** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support estimatedRows. In that case this function is a no-op.
+*/
+static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
+#if SQLITE_VERSION_NUMBER>=3008002
+ if( sqlite3_libversion_number()>=3008002 ){
+ pIdxInfo->estimatedRows = nRow;
+ }
+#endif
+}
/*
** Rtree virtual table module xBestIndex method. There are three
** table scan strategies to choose from (in order from most to
** least desirable):
@@ -140855,17 +142307,18 @@
** The second of each pair of bytes identifies the coordinate column
** to which the constraint applies. The leftmost coordinate column
** is 'a', the second from the left 'b' etc.
*/
static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ Rtree *pRtree = (Rtree*)tab;
int rc = SQLITE_OK;
int ii;
+ i64 nRow; /* Estimated rows returned by this scan */
int iIdx = 0;
char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
memset(zIdxStr, 0, sizeof(zIdxStr));
- UNUSED_PARAMETER(tab);
assert( pIdxInfo->idxStr==0 );
for(ii=0; iinConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
@@ -140881,13 +142334,15 @@
pIdxInfo->aConstraintUsage[jj].omit = 1;
/* This strategy involves a two rowid lookups on an B-Tree structures
** and then a linear search of an R-Tree node. This should be
** considered almost as quick as a direct rowid lookup (for which
- ** sqlite uses an internal cost of 0.0).
+ ** sqlite uses an internal cost of 0.0). It is expected to return
+ ** a single row.
*/
- pIdxInfo->estimatedCost = 10.0;
+ pIdxInfo->estimatedCost = 30.0;
+ setEstimatedRows(pIdxInfo, 1);
return SQLITE_OK;
}
if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
u8 op;
@@ -140912,12 +142367,15 @@
pIdxInfo->idxNum = 2;
pIdxInfo->needToFreeIdxStr = 1;
if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
return SQLITE_NOMEM;
}
- assert( iIdx>=0 );
- pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));
+
+ nRow = pRtree->nRowEst / (iIdx + 1);
+ pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
+ setEstimatedRows(pIdxInfo, nRow);
+
return rc;
}
/*
** Return the N-dimensional volumn of the cell stored in *p.
@@ -142387,10 +143845,41 @@
rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
sqlite3_free(zSql);
}
return rc;
}
+
+/*
+** This function populates the pRtree->nRowEst variable with an estimate
+** of the number of rows in the virtual table. If possible, this is based
+** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
+*/
+static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
+ const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'";
+ sqlite3_stmt *p;
+ int rc;
+ i64 nRow = 0;
+
+ rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC);
+ if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
+ rc = sqlite3_finalize(p);
+ }else if( rc!=SQLITE_NOMEM ){
+ rc = SQLITE_OK;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( nRow==0 ){
+ pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
+ }else{
+ pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
+ }
+ }
+
+ return rc;
+}
static sqlite3_module rtreeModule = {
0, /* iVersion */
rtreeCreate, /* xCreate - create a table */
rtreeConnect, /* xConnect - connect to an existing table */
@@ -142473,10 +143962,11 @@
appStmt[5] = &pRtree->pDeleteRowid;
appStmt[6] = &pRtree->pReadParent;
appStmt[7] = &pRtree->pWriteParent;
appStmt[8] = &pRtree->pDeleteParent;
+ rc = rtreeQueryStat1(db, pRtree);
for(i=0; i[[SQLITE_FCNTL_TRACE]]
+** The [SQLITE_FCNTL_TRACE] file control provides advisory information
+** to the VFS about what the higher layers of the SQLite stack are doing.
+** This file control is used by some VFS activity tracing [shims].
+** The argument is a zero-terminated string. Higher layers in the
+** SQLite stack may generate instances of this file control if
+** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
+**
**
*/
#define SQLITE_FCNTL_LOCKSTATE 1
#define SQLITE_GET_LOCKPROXYFILE 2
#define SQLITE_SET_LOCKPROXYFILE 3
@@ -929,10 +938,11 @@
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
#define SQLITE_FCNTL_PRAGMA 14
#define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
#define SQLITE_FCNTL_MMAP_SIZE 18
+#define SQLITE_FCNTL_TRACE 19
/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
@@ -1775,23 +1785,25 @@
SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
**
-** ^Each entry in an SQLite table has a unique 64-bit signed
+** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
+** has a unique 64-bit signed
** integer key called the [ROWID | "rowid"]. ^The rowid is always available
** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
** names are not also used by explicitly declared columns. ^If
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^This routine returns the [rowid] of the most recent
-** successful [INSERT] into the database from the [database connection]
-** in the first argument. ^As of SQLite version 3.7.7, this routines
-** records the last insert rowid of both ordinary tables and [virtual tables].
-** ^If no successful [INSERT]s
-** have ever occurred on that database connection, zero is returned.
+** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
+** most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D.
+** ^Inserts into [WITHOUT ROWID] tables are not recorded.
+** ^If no successful [INSERT]s into rowid tables
+** have ever occurred on the database connection D,
+** then sqlite3_last_insert_rowid(D) returns zero.
**
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
** row as long as the trigger or virtual table method is running.
** But once the trigger or virtual table method ends, the value returned
@@ -4804,16 +4816,17 @@
/*
** CAPI3REF: Data Change Notification Callbacks
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
+** to be invoked whenever a row is updated, inserted or deleted in
+** a rowid table.
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
** ^The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
+** row is updated, inserted or deleted in a rowid table.
** ^The first argument to the callback is a copy of the third argument
** to sqlite3_update_hook().
** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
** or [SQLITE_UPDATE], depending on the operation that caused the callback
** to be invoked.
@@ -4822,10 +4835,11 @@
** ^The final callback parameter is the [rowid] of the row.
** ^In the case of an update, this is the [rowid] after the update takes place.
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^
+** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when duplication rows are deleted because of an
** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
** invoked when rows are deleted using the [truncate optimization].
@@ -5279,14 +5293,26 @@
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
-** ^The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
+** ^The estimatedCost value is an estimate of the cost of a particular
+** strategy. A cost of N indicates that the cost of the strategy is similar
+** to a linear scan of an SQLite table with N rows. A cost of log(N)
+** indicates that the expense of the operation is similar to that of a
+** binary search on a unique indexed field of an SQLite table with N rows.
+**
+** ^The estimatedRows value is an estimate of the number of rows that
+** will be returned by the strategy.
+**
+** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+** structure for SQLite version 3.8.2. If a virtual table extension is
+** used with an SQLite version earlier than 3.8.2, the results of attempting
+** to read or write the estimatedRows field are undefined (but are likely
+** to included crashing the application). The estimatedRows field should
+** therefore only be used if [sqlite3_libversion_number()] returns a
+** value greater than or equal to 3008002.
*/
struct sqlite3_index_info {
/* Inputs */
int nConstraint; /* Number of entries in aConstraint */
struct sqlite3_index_constraint {
@@ -5307,11 +5333,12 @@
} *aConstraintUsage;
int idxNum; /* Number used to identify the index */
char *idxStr; /* String, possibly obtained from sqlite3_malloc */
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
+ double estimatedCost; /* Estimated cost of using this index */
+ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
};
/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
@@ -5511,10 +5538,13 @@
** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
** the opened blob. ^The size of a blob may not be changed by this
** interface. Use the [UPDATE] SQL command to change the size of a
** blob.
**
+** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
+** table. Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
+**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
** this interface.
**
Index: SQLite.Interop/src/win/interop.c
==================================================================
--- SQLite.Interop/src/win/interop.c
+++ SQLite.Interop/src/win/interop.c
@@ -56,32 +56,32 @@
typedef void (*SQLITEFUNCFINAL)(sqlite3_context *);
#if defined(INTEROP_DEBUG) || defined(INTEROP_LOG)
SQLITE_PRIVATE void sqlite3InteropDebug(const char *zFormat, ...){
va_list ap; /* Vararg list */
- StrAccum acc; /* String accumulator */
+ StrAccum acc; /* String accumulator */
char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
- va_start(ap, zFormat);
- sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
- acc.useMalloc = 0;
- sqlite3VXPrintf(&acc, 0, zFormat, ap);
- va_end(ap);
+ va_start(ap, zFormat);
+ sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
+ acc.useMalloc = 0;
+ sqlite3VXPrintf(&acc, 0, zFormat, ap);
+ va_end(ap);
#if SQLITE_VERSION_NUMBER >= 3007013
- sqlite3_win32_write_debug(sqlite3StrAccumFinish(&acc), -1);
-#elif defined(SQLITE_WIN32_HAS_ANSI)
- OutputDebugStringA(sqlite3StrAccumFinish(&acc));
-#elif defined(SQLITE_WIN32_HAS_WIDE)
- {
- LPWSTR zWideMsg = utf8ToUnicode(sqlite3StrAccumFinish(&acc));
- if( zWideMsg ){
- OutputDebugStringW(zWideMsg);
- sqlite3_free(zWideMsg);
- }
- }
-#else
- fprintf(stderr, "%s", sqlite3StrAccumFinish(&acc));
-#endif
+ sqlite3_win32_write_debug(sqlite3StrAccumFinish(&acc), -1);
+#elif defined(SQLITE_WIN32_HAS_ANSI)
+ OutputDebugStringA(sqlite3StrAccumFinish(&acc));
+#elif defined(SQLITE_WIN32_HAS_WIDE)
+ {
+ LPWSTR zWideMsg = utf8ToUnicode(sqlite3StrAccumFinish(&acc));
+ if( zWideMsg ){
+ OutputDebugStringW(zWideMsg);
+ sqlite3_free(zWideMsg);
+ }
+ }
+#else
+ fprintf(stderr, "%s", sqlite3StrAccumFinish(&acc));
+#endif
}
#endif
#if defined(INTEROP_LOG)
SQLITE_PRIVATE int logConfigured = 0;
@@ -740,17 +740,17 @@
{
Index *pIdx;
Table *pTab;
int n;
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeEnterAll(db);
+ sqlite3_mutex_enter(db->mutex);
+ sqlite3BtreeEnterAll(db);
pIdx = sqlite3FindIndex(db, zIndexName, zDb);
- sqlite3BtreeLeaveAll(db);
- sqlite3_mutex_leave(db->mutex);
+ sqlite3BtreeLeaveAll(db);
+ sqlite3_mutex_leave(db->mutex);
if (!pIdx) return SQLITE_ERROR;
pTab = pIdx->pTable;
for (n = 0; n < pIdx->nColumn; n++)
Index: System.Data.SQLite/SQLite3.cs
==================================================================
--- System.Data.SQLite/SQLite3.cs
+++ System.Data.SQLite/SQLite3.cs
@@ -514,21 +514,72 @@
///
/// Attempts to free N bytes of heap memory by deallocating non-essential memory
/// allocations held by the database library. Memory used to cache database pages
/// to improve performance is an example of non-essential memory. This is a no-op
/// returning zero if the SQLite core library was not compiled with the compile-time
- /// option SQLITE_ENABLE_MEMORY_MANAGEMENT.
+ /// option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or
+ /// compact the Win32 native heap, if applicable.
///
///
/// The requested number of bytes to free.
///
- ///
+ ///
+ /// Non-zero to attempt a heap reset.
+ ///
+ ///
+ /// Non-zero to attempt heap compaction.
+ ///
+ ///
/// The number of bytes actually freed. This value may be zero.
+ ///
+ ///
+ /// This value will be non-zero if the heap reset was successful.
+ ///
+ ///
+ /// The size of the largest committed free block in the heap, in bytes.
+ /// This value will be zero unless heap compaction is enabled.
+ ///
+ ///
+ /// A standard SQLite return code (i.e. zero for success and non-zero
+ /// for failure).
///
- internal static int StaticReleaseMemory(int nBytes)
+ internal static SQLiteErrorCode StaticReleaseMemory(
+ int nBytes,
+ bool reset,
+ bool compact,
+ ref int nFree,
+ ref bool resetOk,
+ ref uint nLargest
+ )
{
- return UnsafeNativeMethods.sqlite3_release_memory(nBytes);
+ SQLiteErrorCode rc = SQLiteErrorCode.Ok;
+
+ int nFreeLocal = UnsafeNativeMethods.sqlite3_release_memory(nBytes);
+ uint nLargestLocal = 0;
+ bool resetOkLocal = false;
+
+#if !DEBUG && WINDOWS // NOTE: Should be "WIN32HEAP && !MEMDEBUG && WINDOWS"
+ if ((rc == SQLiteErrorCode.Ok) && reset)
+ {
+ rc = UnsafeNativeMethods.sqlite3_win32_reset_heap();
+
+ if (rc == SQLiteErrorCode.Ok)
+ resetOkLocal = true;
+ }
+
+ if ((rc == SQLiteErrorCode.Ok) && compact)
+ rc = UnsafeNativeMethods.sqlite3_win32_compact_heap(ref nLargestLocal);
+#else
+ if (reset || compact)
+ rc = SQLiteErrorCode.NotFound;
+#endif
+
+ nFree = nFreeLocal;
+ nLargest = nLargestLocal;
+ resetOk = resetOkLocal;
+
+ return rc;
}
///
/// Shutdown the SQLite engine so that it can be restarted with different
/// configuration options. We depend on auto initialization to recover.
@@ -564,11 +615,11 @@
if (rc == SQLiteErrorCode.Ok)
rc = UnsafeNativeMethods.sqlite3_win32_set_directory(2, null);
#else
#if !NET_COMPACT_20 && TRACE_CONNECTION
Trace.WriteLine(
- "Shutdown: Cannot reset directories on this operating system.");
+ "Shutdown: Cannot reset directories on this platform.");
#endif
#endif
}
if (rc == SQLiteErrorCode.Ok)
Index: System.Data.SQLite/SQLiteConnection.cs
==================================================================
--- System.Data.SQLite/SQLiteConnection.cs
+++ System.Data.SQLite/SQLiteConnection.cs
@@ -2508,21 +2508,47 @@
///
/// Attempts to free N bytes of heap memory by deallocating non-essential memory
/// allocations held by the database library. Memory used to cache database pages
/// to improve performance is an example of non-essential memory. This is a no-op
/// returning zero if the SQLite core library was not compiled with the compile-time
- /// option SQLITE_ENABLE_MEMORY_MANAGEMENT.
+ /// option SQLITE_ENABLE_MEMORY_MANAGEMENT. Optionally, attempts to reset and/or
+ /// compact the Win32 native heap, if applicable.
///
///
/// The requested number of bytes to free.
///
- ///
+ ///
+ /// Non-zero to attempt a heap reset.
+ ///
+ ///
+ /// Non-zero to attempt heap compaction.
+ ///
+ ///
/// The number of bytes actually freed. This value may be zero.
+ ///
+ ///
+ /// This value will be non-zero if the heap reset was successful.
+ ///
+ ///
+ /// The size of the largest committed free block in the heap, in bytes.
+ /// This value will be zero unless heap compaction is enabled.
+ ///
+ ///
+ /// A standard SQLite return code (i.e. zero for success and non-zero
+ /// for failure).
///
- public static int ReleaseMemory(int nBytes)
+ public static SQLiteErrorCode ReleaseMemory(
+ int nBytes,
+ bool reset,
+ bool compact,
+ ref int nFree,
+ ref bool resetOk,
+ ref uint nLargest
+ )
{
- return SQLite3.StaticReleaseMemory(nBytes);
+ return SQLite3.StaticReleaseMemory(
+ nBytes, reset, compact, ref nFree, ref resetOk, ref nLargest);
}
///
/// Sets the status of the memory usage tracking subsystem in the SQLite core library. By default, this is enabled.
/// If this is disabled, memory usage tracking will not be performed. This is not really a per-connection value, it is
@@ -2686,11 +2712,11 @@
_sql.Close(true); /* NOTE: MUST be closed before shutdown. */
SQLiteErrorCode rc = _sql.Shutdown();
#if !NET_COMPACT_20 && TRACE_CONNECTION
if (rc != SQLiteErrorCode.Ok)
- Trace.WriteLine(String.Format("Shutdown (Instance) Failed: {0}", rc));
+ System.Diagnostics.Trace.WriteLine(String.Format("Shutdown (Instance) Failed: {0}", rc));
#endif
return rc;
}
@@ -2714,11 +2740,11 @@
SQLiteErrorCode rc = SQLite3.StaticShutdown(directories);
if (rc != SQLiteErrorCode.Ok)
{
#if !NET_COMPACT_20 && TRACE_CONNECTION
- Trace.WriteLine(String.Format("Shutdown (Static) Failed: {0}", rc));
+ System.Diagnostics.Trace.WriteLine(String.Format("Shutdown (Static) Failed: {0}", rc));
#endif
if (!noThrow)
throw new SQLiteException(rc, null);
}
Index: System.Data.SQLite/SQLiteModule.cs
==================================================================
--- System.Data.SQLite/SQLiteModule.cs
+++ System.Data.SQLite/SQLiteModule.cs
@@ -963,10 +963,28 @@
}
#endregion
///////////////////////////////////////////////////////////////////////
+ ///
+ /// Determines if the native estimatedRows field can be used, based on
+ /// the available version of the SQLite core library.
+ ///
+ ///
+ /// Non-zero if the property is supported
+ /// by the SQLite core library.
+ ///
+ public bool CanUseEstimatedRows()
+ {
+ if (UnsafeNativeMethods.sqlite3_libversion_number() >= 3008002)
+ return true;
+
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
#region Public Properties
private SQLiteIndexConstraintUsage[] constraintUsages;
///
/// An array of object
/// instances, each containing information to be supplied to the SQLite
@@ -1040,10 +1058,23 @@
public double? EstimatedCost
{
get { return estimatedCost; }
set { estimatedCost = value; }
}
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private long? estimatedRows;
+ ///
+ /// Estimated number of rows returned. Using a null value here
+ /// indicates that a default estimated rows value should be used.
+ ///
+ public long? EstimatedRows
+ {
+ get { return estimatedRows; }
+ set { estimatedRows = value; }
+ }
#endregion
}
#endregion
///////////////////////////////////////////////////////////////////////////
@@ -1053,20 +1084,10 @@
/// This class represents the various inputs and outputs used with the
/// method.
///
public sealed class SQLiteIndex
{
- #region Private Constants
- ///
- /// The default estimated cost for use with the
- /// method.
- ///
- internal static readonly double DefaultEstimatedCost = double.MaxValue;
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
#region Internal Constructors
///
/// Constructs an instance of this class.
///
///
@@ -1267,12 +1288,22 @@
index.Outputs.OrderByConsumed);
offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int),
sizeof(double));
- SQLiteMarshal.WriteDouble(pIndex, offset,
- index.Outputs.EstimatedCost.GetValueOrDefault());
+ if (index.Outputs.EstimatedCost.HasValue)
+ {
+ SQLiteMarshal.WriteDouble(pIndex, offset,
+ index.Outputs.EstimatedCost.GetValueOrDefault());
+ }
+
+ if (index.Outputs.CanUseEstimatedRows() &&
+ index.Outputs.EstimatedRows.HasValue)
+ {
+ SQLiteMarshal.WriteInt64(pIndex, offset,
+ index.Outputs.EstimatedRows.GetValueOrDefault());
+ }
}
#endregion
///////////////////////////////////////////////////////////////////////
@@ -4413,10 +4444,40 @@
#endif
}
///////////////////////////////////////////////////////////////////////
+ ///
+ /// Writes an value to the specified memory
+ /// location.
+ ///
+ ///
+ /// The object instance representing the base
+ /// memory location.
+ ///
+ ///
+ /// The integer offset from the base memory location where the
+ /// value to be written is located.
+ ///
+ ///
+ /// The value to write.
+ ///
+ public static void WriteInt64(
+ IntPtr pointer,
+ int offset,
+ long value
+ )
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ Marshal.WriteInt64(pointer, offset, value);
+#else
+ Marshal.WriteInt64(IntPtrForOffset(pointer, offset), value);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
///
/// Writes a value to the specified memory
/// location.
///
///
@@ -6839,18 +6900,19 @@
///
///
/// The object instance to modify.
///
///
- /// The estimated cost value to use.
+ /// The estimated cost value to use. Using a null value means that the
+ /// default value provided by the SQLite core library should be used.
///
///
/// Non-zero upon success.
///
protected virtual bool SetEstimatedCost(
SQLiteIndex index,
- double estimatedCost
+ double? estimatedCost
)
{
if ((index == null) || (index.Outputs == null))
return false;
@@ -6872,11 +6934,58 @@
///
protected virtual bool SetEstimatedCost(
SQLiteIndex index
)
{
- return SetEstimatedCost(index, SQLiteIndex.DefaultEstimatedCost);
+ return SetEstimatedCost(index, null);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Modifies the specified object instance
+ /// to contain the specified estimated rows.
+ ///
+ ///
+ /// The object instance to modify.
+ ///
+ ///
+ /// The estimated rows value to use. Using a null value means that the
+ /// default value provided by the SQLite core library should be used.
+ ///
+ ///
+ /// Non-zero upon success.
+ ///
+ protected virtual bool SetEstimatedRows(
+ SQLiteIndex index,
+ long? estimatedRows
+ )
+ {
+ if ((index == null) || (index.Outputs == null))
+ return false;
+
+ index.Outputs.EstimatedRows = estimatedRows;
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ ///
+ /// Modifies the specified object instance
+ /// to contain the default estimated rows.
+ ///
+ ///
+ /// The object instance to modify.
+ ///
+ ///
+ /// Non-zero upon success.
+ ///
+ protected virtual bool SetEstimatedRows(
+ SQLiteIndex index
+ )
+ {
+ return SetEstimatedRows(index, null);
}
#endregion
#endregion
///////////////////////////////////////////////////////////////////////
Index: System.Data.SQLite/UnsafeNativeMethods.cs
==================================================================
--- System.Data.SQLite/UnsafeNativeMethods.cs
+++ System.Data.SQLite/UnsafeNativeMethods.cs
@@ -1053,11 +1053,45 @@
#if !PLATFORM_COMPACTFRAMEWORK
[DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
#else
[DllImport(SQLITE_DLL, CharSet = CharSet.Unicode)]
#endif
+ //
+ // NOTE: The "sqlite3_win32_set_directory" SQLite core library function is
+ // only supported on Windows.
+ //
internal static extern SQLiteErrorCode sqlite3_win32_set_directory(uint type, string value);
+
+#if !DEBUG // NOTE: Should be "WIN32HEAP && !MEMDEBUG"
+#if !PLATFORM_COMPACTFRAMEWORK
+ [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
+#else
+ [DllImport(SQLITE_DLL)]
+#endif
+ //
+ // NOTE: The "sqlite3_win32_reset_heap" SQLite core library function is
+ // only supported on Windows when the Win32 native allocator is in
+ // use (i.e. by default, in "Release" builds of System.Data.SQLite
+ // only). By default, in "Debug" builds of System.Data.SQLite, the
+ // MEMDEBUG allocator is used.
+ //
+ internal static extern SQLiteErrorCode sqlite3_win32_reset_heap();
+
+#if !PLATFORM_COMPACTFRAMEWORK
+ [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
+#else
+ [DllImport(SQLITE_DLL)]
+#endif
+ //
+ // NOTE: The "sqlite3_win32_compact_heap" SQLite core library function is
+ // only supported on Windows when the Win32 native allocator is in
+ // use (i.e. by default, in "Release" builds of System.Data.SQLite
+ // only). By default, in "Debug" builds of System.Data.SQLite, the
+ // MEMDEBUG allocator is used.
+ //
+ internal static extern SQLiteErrorCode sqlite3_win32_compact_heap(ref uint largest);
+#endif
#endif
#if !PLATFORM_COMPACTFRAMEWORK
[DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
Index: Tests/basic.eagle
==================================================================
--- Tests/basic.eagle
+++ Tests/basic.eagle
@@ -2613,10 +2613,65 @@
unset -nocomplain db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{0 1 1 {unmatched '('} 0 1 1 {unmatched '('} 0 0 1 {unmatched '('} 0 0 1\
{unmatched '('}}}
+
+###############################################################################
+
+reportSQLiteResources $test_channel
+
+###############################################################################
+
+runTest {test data-1.54 {SQLiteConnection.ReleaseMemory method} -setup {
+ setupDb [set fileName data-1.54.db]
+} -body {
+ set result [list]
+
+ set nFree 0; set resetOk false; set nLargest 0
+ set code [object invoke \
+ System.Data.SQLite.SQLiteConnection ReleaseMemory \
+ -1 true true nFree resetOk nLargest]
+
+ lappend result [list $code $nFree $resetOk $nLargest]
+
+ sql execute $db "CREATE TABLE t1(x);"
+ sql execute $db "INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576));"
+
+ set nFree 0; set resetOk false; set nLargest 0
+ set code [object invoke \
+ System.Data.SQLite.SQLiteConnection ReleaseMemory \
+ -1 true true nFree resetOk nLargest]
+
+ tputs $test_channel [appendArgs \
+ "---- memory released by SQLite... " $nFree " bytes\n"]
+
+ lappend result [list $code $nFree $resetOk $nLargest]
+
+ cleanupDb $fileName
+ checkForSQLiteDirectories $test_channel true
+
+ set nFree 0; set resetOk false; set nLargest 0
+ set code [object invoke \
+ System.Data.SQLite.SQLiteConnection ReleaseMemory \
+ -1 true true nFree resetOk nLargest]
+
+ tputs $test_channel [appendArgs \
+ "---- largest free SQLite heap block... " $nLargest " bytes\n"]
+
+ lappend result [list $code $nFree $resetOk $nLargest]
+} -cleanup {
+ cleanupDb $fileName
+
+ unset -nocomplain nLargest resetOk nFree code result db fileName
+} -constraints {eagle monoBug28 configuration.Release command.sql compile.DATA\
+SQLite System.Data.SQLite} -match regexp -result {^\{Busy 0 False 0\} \{Busy\
+\d+ False 0\} \{Ok 0 True \d+\}$}}
+
+###############################################################################
+
+reportSQLiteResources $test_channel
###############################################################################
unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \
testExeFile testLinqExeFile northwindEfDbFile testLinqOutFile
Index: Tests/tkt-ccfa69fc32.eagle
==================================================================
--- Tests/tkt-ccfa69fc32.eagle
+++ Tests/tkt-ccfa69fc32.eagle
@@ -83,11 +83,11 @@
unset -nocomplain code output error result add
} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll testExec\
file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} -match \
glob -result {0 {1581 1730 1833 2116 2139} 0 {System.Data.UpdateException: *\
---> System.Data.SQLite.SQLiteException: constraint failed
-PRIMARY KEY must be unique
+UNIQUE constraint failed: Territories.TerritoryID
*} 0 {1 2 3 4 5 6 7 8 9 10 1576 1577 1578 1579 1580 1581 1730 1833 2116 2139}}}
###############################################################################
unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \
Index: Tests/tkt-e06c4caff3.eagle
==================================================================
--- Tests/tkt-e06c4caff3.eagle
+++ Tests/tkt-e06c4caff3.eagle
@@ -33,11 +33,11 @@
unset -nocomplain NaN db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-returnCodes 1 -match regexp -result [string map [list \n \r\n] \
{^System\.Data\.SQLite\.SQLiteException \(0x80004005\): constraint failed
-t1\.x may not be NULL
+NOT NULL constraint failed: t1\.x
.*$}]}
###############################################################################
runTest {test tkt-e06c4caff3-1.2 {NaN to NULL} -setup {
Index: Tests/version.eagle
==================================================================
--- Tests/version.eagle
+++ Tests/version.eagle
@@ -200,13 +200,17 @@
} -constraints {eagle System.Data.SQLite} -result $version(full)}
###############################################################################
runTest {test version-1.16 {ProviderSourceId} -body {
+ #
+ # NOTE: The ProviderSourceId property value may be null, which
+ # would result in an empty string being returned here.
+ #
object invoke System.Data.SQLite.SQLiteConnection ProviderSourceId
} -constraints {eagle System.Data.SQLite} -match regexp -result \
-{^[0-9a-f]{40} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} UTC$}}
+{^(?:|[0-9a-f]{40} \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} UTC)$}}
###############################################################################
set patterns [list \
[appendArgs Version= [string map [list . \\.] $version(full)] ,] \
Index: readme.htm
==================================================================
--- readme.htm
+++ readme.htm
@@ -4,11 +4,11 @@
ADO.NET SQLite Data Provider
Version 1.0.90.0 December XX, 2013 (release scheduled)
-Using SQLite 3.8.1
+Using SQLite 3.8.2
Originally written by Robert Simpson
Released to the public domain, use at your own risk!
Official provider website: http://system.data.sqlite.org/
Legacy versions: http://sqlite.phxsoftware.com/
@@ -188,10 +188,11 @@
1.0.90.0 - December XX, 2013 (release scheduled)
+ - Updated to SQLite 3.8.2.
- Add experimental support for the native regexp extension.
- Never create a new connection wrapper in the SQLiteConnection.Shutdown method. ** Potentially Incompatible Change **
- Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.
- Add memory leak detection to the test project for the .NET Compact Framework.
- Add SQLITE_ENABLE_MEMORY_MANAGEMENT compile-time option to the interop assembly.
Index: www/news.wiki
==================================================================
--- www/news.wiki
+++ www/news.wiki
@@ -4,10 +4,11 @@
1.0.90.0 - December XX, 2013 (release scheduled)
+ - Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.8.2].
- Add experimental support for the native regexp extension.
- Never create a new connection wrapper in the SQLiteConnection.Shutdown method. ** Potentially Incompatible Change **
- Add experimental GetMemoryStatistics, ReleaseMemory, and Shutdown methods to the SQLiteConnection class.
- Add memory leak detection to the test project for the .NET Compact Framework.
- Add SQLITE_ENABLE_MEMORY_MANAGEMENT compile-time option to the interop assembly.