| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.8.2. By combining all the individual C code files into this |
| 3 | +** version 3.8.3. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -133,13 +133,13 @@ |
| 133 | 133 | ** |
| 134 | 134 | ** See also: [sqlite3_libversion()], |
| 135 | 135 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 136 | 136 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 137 | 137 | */ |
| 138 | | -#define SQLITE_VERSION "3.8.2" |
| 139 | | -#define SQLITE_VERSION_NUMBER 3008002 |
| 140 | | -#define SQLITE_SOURCE_ID "2013-11-11 16:55:52 924d63b283a3d059838114c95d42c6feaf913529" |
| 138 | +#define SQLITE_VERSION "3.8.3" |
| 139 | +#define SQLITE_VERSION_NUMBER 3008003 |
| 140 | +#define SQLITE_SOURCE_ID "2013-12-11 12:02:55 3e1d55f0bd84810a035bd6c54583eb373784a9a3" |
| 141 | 141 | |
| 142 | 142 | /* |
| 143 | 143 | ** CAPI3REF: Run-Time Library Version Numbers |
| 144 | 144 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 145 | 145 | ** |
| | @@ -396,11 +396,11 @@ |
| 396 | 396 | ** Restrictions: |
| 397 | 397 | ** |
| 398 | 398 | ** <ul> |
| 399 | 399 | ** <li> The application must insure that the 1st parameter to sqlite3_exec() |
| 400 | 400 | ** is a valid and open [database connection]. |
| 401 | | -** <li> The application must not close [database connection] specified by |
| 401 | +** <li> The application must not close the [database connection] specified by |
| 402 | 402 | ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. |
| 403 | 403 | ** <li> The application must not modify the SQL statement text passed into |
| 404 | 404 | ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. |
| 405 | 405 | ** </ul> |
| 406 | 406 | */ |
| | @@ -473,11 +473,11 @@ |
| 473 | 473 | ** about errors. The extended result codes are enabled or disabled |
| 474 | 474 | ** on a per database connection basis using the |
| 475 | 475 | ** [sqlite3_extended_result_codes()] API. |
| 476 | 476 | ** |
| 477 | 477 | ** Some of the available extended result codes are listed here. |
| 478 | | -** One may expect the number of extended result codes will be expand |
| 478 | +** One may expect the number of extended result codes will increase |
| 479 | 479 | ** over time. Software that uses extended result codes should expect |
| 480 | 480 | ** to see new result codes in future releases of SQLite. |
| 481 | 481 | ** |
| 482 | 482 | ** The SQLITE_OK result code will never be extended. It will always |
| 483 | 483 | ** be exactly zero. |
| | @@ -517,10 +517,11 @@ |
| 517 | 517 | #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) |
| 518 | 518 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 519 | 519 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 520 | 520 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 521 | 521 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 522 | +#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) |
| 522 | 523 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| 523 | 524 | #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) |
| 524 | 525 | #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) |
| 525 | 526 | #define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) |
| 526 | 527 | #define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) |
| | @@ -584,11 +585,12 @@ |
| 584 | 585 | ** information is written to disk in the same order as calls |
| 585 | 586 | ** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that |
| 586 | 587 | ** after reboot following a crash or power loss, the only bytes in a |
| 587 | 588 | ** file that were written at the application level might have changed |
| 588 | 589 | ** and that adjacent bytes, even bytes within the same sector are |
| 589 | | -** guaranteed to be unchanged. |
| 590 | +** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
| 591 | +** flag indicate that a file cannot be deleted when open. |
| 590 | 592 | */ |
| 591 | 593 | #define SQLITE_IOCAP_ATOMIC 0x00000001 |
| 592 | 594 | #define SQLITE_IOCAP_ATOMIC512 0x00000002 |
| 593 | 595 | #define SQLITE_IOCAP_ATOMIC1K 0x00000004 |
| 594 | 596 | #define SQLITE_IOCAP_ATOMIC2K 0x00000008 |
| | @@ -947,10 +949,16 @@ |
| 947 | 949 | ** This file control is used by some VFS activity tracing [shims]. |
| 948 | 950 | ** The argument is a zero-terminated string. Higher layers in the |
| 949 | 951 | ** SQLite stack may generate instances of this file control if |
| 950 | 952 | ** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled. |
| 951 | 953 | ** |
| 954 | +** <li>[[SQLITE_FCNTL_HAS_MOVED]] |
| 955 | +** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a |
| 956 | +** pointer to an integer and it writes a boolean into that integer depending |
| 957 | +** on whether or not the file has been renamed, moved, or deleted since it |
| 958 | +** was first opened. |
| 959 | +** |
| 952 | 960 | ** </ul> |
| 953 | 961 | */ |
| 954 | 962 | #define SQLITE_FCNTL_LOCKSTATE 1 |
| 955 | 963 | #define SQLITE_GET_LOCKPROXYFILE 2 |
| 956 | 964 | #define SQLITE_SET_LOCKPROXYFILE 3 |
| | @@ -967,10 +975,11 @@ |
| 967 | 975 | #define SQLITE_FCNTL_PRAGMA 14 |
| 968 | 976 | #define SQLITE_FCNTL_BUSYHANDLER 15 |
| 969 | 977 | #define SQLITE_FCNTL_TEMPFILENAME 16 |
| 970 | 978 | #define SQLITE_FCNTL_MMAP_SIZE 18 |
| 971 | 979 | #define SQLITE_FCNTL_TRACE 19 |
| 980 | +#define SQLITE_FCNTL_HAS_MOVED 20 |
| 972 | 981 | |
| 973 | 982 | /* |
| 974 | 983 | ** CAPI3REF: Mutex Handle |
| 975 | 984 | ** |
| 976 | 985 | ** The mutex module within SQLite defines [sqlite3_mutex] to be an |
| | @@ -1411,11 +1420,11 @@ |
| 1411 | 1420 | ** of 8. Some allocators round up to a larger multiple or to a power of 2. |
| 1412 | 1421 | ** Every memory allocation request coming in through [sqlite3_malloc()] |
| 1413 | 1422 | ** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, |
| 1414 | 1423 | ** that causes the corresponding memory allocation to fail. |
| 1415 | 1424 | ** |
| 1416 | | -** The xInit method initializes the memory allocator. (For example, |
| 1425 | +** The xInit method initializes the memory allocator. For example, |
| 1417 | 1426 | ** it might allocate any require mutexes or initialize internal data |
| 1418 | 1427 | ** structures. The xShutdown method is invoked (indirectly) by |
| 1419 | 1428 | ** [sqlite3_shutdown()] and should deallocate any resources acquired |
| 1420 | 1429 | ** by xInit. The pAppData pointer is used as the only parameter to |
| 1421 | 1430 | ** xInit and xShutdown. |
| | @@ -1713,10 +1722,17 @@ |
| 1713 | 1722 | ** cannot be changed at run-time. Nor may the maximum allowed mmap size |
| 1714 | 1723 | ** exceed the compile-time maximum mmap size set by the |
| 1715 | 1724 | ** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ |
| 1716 | 1725 | ** ^If either argument to this option is negative, then that argument is |
| 1717 | 1726 | ** changed to its compile-time default. |
| 1727 | +** |
| 1728 | +** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] |
| 1729 | +** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE |
| 1730 | +** <dd>^This option is only available if SQLite is compiled for Windows |
| 1731 | +** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. |
| 1732 | +** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value |
| 1733 | +** that specifies the maximum size of the created heap. |
| 1718 | 1734 | ** </dl> |
| 1719 | 1735 | */ |
| 1720 | 1736 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 1721 | 1737 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| 1722 | 1738 | #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ |
| | @@ -1737,10 +1753,11 @@ |
| 1737 | 1753 | #define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ |
| 1738 | 1754 | #define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ |
| 1739 | 1755 | #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ |
| 1740 | 1756 | #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ |
| 1741 | 1757 | #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ |
| 1758 | +#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ |
| 1742 | 1759 | |
| 1743 | 1760 | /* |
| 1744 | 1761 | ** CAPI3REF: Database Connection Configuration Options |
| 1745 | 1762 | ** |
| 1746 | 1763 | ** These constants are the available integer configuration options that |
| | @@ -3137,11 +3154,10 @@ |
| 3137 | 3154 | ** to the [sqlite3_bind_text | bindings] of that [parameter]. |
| 3138 | 3155 | ** ^The specific value of WHERE-clause [parameter] might influence the |
| 3139 | 3156 | ** choice of query plan if the parameter is the left-hand side of a [LIKE] |
| 3140 | 3157 | ** or [GLOB] operator or if the parameter is compared to an indexed column |
| 3141 | 3158 | ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. |
| 3142 | | -** the |
| 3143 | 3159 | ** </li> |
| 3144 | 3160 | ** </ol> |
| 3145 | 3161 | */ |
| 3146 | 3162 | SQLITE_API int sqlite3_prepare( |
| 3147 | 3163 | sqlite3 *db, /* Database handle */ |
| | @@ -3799,23 +3815,23 @@ |
| 3799 | 3815 | ** <table border="1"> |
| 3800 | 3816 | ** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion |
| 3801 | 3817 | ** |
| 3802 | 3818 | ** <tr><td> NULL <td> INTEGER <td> Result is 0 |
| 3803 | 3819 | ** <tr><td> NULL <td> FLOAT <td> Result is 0.0 |
| 3804 | | -** <tr><td> NULL <td> TEXT <td> Result is NULL pointer |
| 3805 | | -** <tr><td> NULL <td> BLOB <td> Result is NULL pointer |
| 3820 | +** <tr><td> NULL <td> TEXT <td> Result is a NULL pointer |
| 3821 | +** <tr><td> NULL <td> BLOB <td> Result is a NULL pointer |
| 3806 | 3822 | ** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float |
| 3807 | 3823 | ** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer |
| 3808 | 3824 | ** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT |
| 3809 | | -** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer |
| 3825 | +** <tr><td> FLOAT <td> INTEGER <td> [CAST] to INTEGER |
| 3810 | 3826 | ** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float |
| 3811 | | -** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT |
| 3812 | | -** <tr><td> TEXT <td> INTEGER <td> Use atoi() |
| 3813 | | -** <tr><td> TEXT <td> FLOAT <td> Use atof() |
| 3827 | +** <tr><td> FLOAT <td> BLOB <td> [CAST] to BLOB |
| 3828 | +** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER |
| 3829 | +** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL |
| 3814 | 3830 | ** <tr><td> TEXT <td> BLOB <td> No change |
| 3815 | | -** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi() |
| 3816 | | -** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof() |
| 3831 | +** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER |
| 3832 | +** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL |
| 3817 | 3833 | ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed |
| 3818 | 3834 | ** </table> |
| 3819 | 3835 | ** </blockquote>)^ |
| 3820 | 3836 | ** |
| 3821 | 3837 | ** The table above makes reference to standard C library functions atoi() |
| | @@ -3867,11 +3883,11 @@ |
| 3867 | 3883 | ** |
| 3868 | 3884 | ** ^The pointers returned are valid until a type conversion occurs as |
| 3869 | 3885 | ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or |
| 3870 | 3886 | ** [sqlite3_finalize()] is called. ^The memory space used to hold strings |
| 3871 | 3887 | ** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned |
| 3872 | | -** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into |
| 3888 | +** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into |
| 3873 | 3889 | ** [sqlite3_free()]. |
| 3874 | 3890 | ** |
| 3875 | 3891 | ** ^(If a memory allocation error occurs during the evaluation of any |
| 3876 | 3892 | ** of these routines, a default value is returned. The default value |
| 3877 | 3893 | ** is either the integer 0, the floating point number 0.0, or a NULL |
| | @@ -4945,12 +4961,12 @@ |
| 4945 | 4961 | /* |
| 4946 | 4962 | ** CAPI3REF: Free Memory Used By A Database Connection |
| 4947 | 4963 | ** |
| 4948 | 4964 | ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap |
| 4949 | 4965 | ** memory as possible from database connection D. Unlike the |
| 4950 | | -** [sqlite3_release_memory()] interface, this interface is effect even |
| 4951 | | -** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is |
| 4966 | +** [sqlite3_release_memory()] interface, this interface is in effect even |
| 4967 | +** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is |
| 4952 | 4968 | ** omitted. |
| 4953 | 4969 | ** |
| 4954 | 4970 | ** See also: [sqlite3_release_memory()] |
| 4955 | 4971 | */ |
| 4956 | 4972 | SQLITE_API int sqlite3_db_release_memory(sqlite3*); |
| | @@ -5321,14 +5337,26 @@ |
| 5321 | 5337 | ** |
| 5322 | 5338 | ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in |
| 5323 | 5339 | ** the correct order to satisfy the ORDER BY clause so that no separate |
| 5324 | 5340 | ** sorting step is required. |
| 5325 | 5341 | ** |
| 5326 | | -** ^The estimatedCost value is an estimate of the cost of doing the |
| 5327 | | -** particular lookup. A full scan of a table with N entries should have |
| 5328 | | -** a cost of N. A binary search of a table of N entries should have a |
| 5329 | | -** cost of approximately log(N). |
| 5342 | +** ^The estimatedCost value is an estimate of the cost of a particular |
| 5343 | +** strategy. A cost of N indicates that the cost of the strategy is similar |
| 5344 | +** to a linear scan of an SQLite table with N rows. A cost of log(N) |
| 5345 | +** indicates that the expense of the operation is similar to that of a |
| 5346 | +** binary search on a unique indexed field of an SQLite table with N rows. |
| 5347 | +** |
| 5348 | +** ^The estimatedRows value is an estimate of the number of rows that |
| 5349 | +** will be returned by the strategy. |
| 5350 | +** |
| 5351 | +** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info |
| 5352 | +** structure for SQLite version 3.8.2. If a virtual table extension is |
| 5353 | +** used with an SQLite version earlier than 3.8.2, the results of attempting |
| 5354 | +** to read or write the estimatedRows field are undefined (but are likely |
| 5355 | +** to included crashing the application). The estimatedRows field should |
| 5356 | +** therefore only be used if [sqlite3_libversion_number()] returns a |
| 5357 | +** value greater than or equal to 3008002. |
| 5330 | 5358 | */ |
| 5331 | 5359 | struct sqlite3_index_info { |
| 5332 | 5360 | /* Inputs */ |
| 5333 | 5361 | int nConstraint; /* Number of entries in aConstraint */ |
| 5334 | 5362 | struct sqlite3_index_constraint { |
| | @@ -5349,11 +5377,13 @@ |
| 5349 | 5377 | } *aConstraintUsage; |
| 5350 | 5378 | int idxNum; /* Number used to identify the index */ |
| 5351 | 5379 | char *idxStr; /* String, possibly obtained from sqlite3_malloc */ |
| 5352 | 5380 | int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ |
| 5353 | 5381 | int orderByConsumed; /* True if output is already ordered */ |
| 5354 | | - double estimatedCost; /* Estimated cost of using this index */ |
| 5382 | + double estimatedCost; /* Estimated cost of using this index */ |
| 5383 | + /* Fields below are only available in SQLite 3.8.2 and later */ |
| 5384 | + sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ |
| 5355 | 5385 | }; |
| 5356 | 5386 | |
| 5357 | 5387 | /* |
| 5358 | 5388 | ** CAPI3REF: Virtual Table Constraint Operator Codes |
| 5359 | 5389 | ** |
| | @@ -6079,11 +6109,12 @@ |
| 6079 | 6109 | #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 |
| 6080 | 6110 | #define SQLITE_TESTCTRL_ISKEYWORD 16 |
| 6081 | 6111 | #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 |
| 6082 | 6112 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 |
| 6083 | 6113 | #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 |
| 6084 | | -#define SQLITE_TESTCTRL_LAST 19 |
| 6114 | +#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 |
| 6115 | +#define SQLITE_TESTCTRL_LAST 20 |
| 6085 | 6116 | |
| 6086 | 6117 | /* |
| 6087 | 6118 | ** CAPI3REF: SQLite Runtime Status |
| 6088 | 6119 | ** |
| 6089 | 6120 | ** ^This interface is used to retrieve runtime status information |
| | @@ -8127,13 +8158,12 @@ |
| 8127 | 8158 | #define TK_UNCLOSED_STRING 151 |
| 8128 | 8159 | #define TK_FUNCTION 152 |
| 8129 | 8160 | #define TK_COLUMN 153 |
| 8130 | 8161 | #define TK_AGG_FUNCTION 154 |
| 8131 | 8162 | #define TK_AGG_COLUMN 155 |
| 8132 | | -#define TK_CONST_FUNC 156 |
| 8133 | | -#define TK_UMINUS 157 |
| 8134 | | -#define TK_UPLUS 158 |
| 8163 | +#define TK_UMINUS 156 |
| 8164 | +#define TK_UPLUS 157 |
| 8135 | 8165 | |
| 8136 | 8166 | /************** End of parse.h ***********************************************/ |
| 8137 | 8167 | /************** Continuing where we left off in sqliteInt.h ******************/ |
| 8138 | 8168 | #include <stdio.h> |
| 8139 | 8169 | #include <stdlib.h> |
| | @@ -8765,12 +8795,12 @@ |
| 8765 | 8795 | SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes); |
| 8766 | 8796 | SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); |
| 8767 | 8797 | SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes); |
| 8768 | 8798 | SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); |
| 8769 | 8799 | SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); |
| 8770 | | -SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt); |
| 8771 | | -SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt); |
| 8800 | +SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt); |
| 8801 | +SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt); |
| 8772 | 8802 | SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); |
| 8773 | 8803 | SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); |
| 8774 | 8804 | SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64); |
| 8775 | 8805 | SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*); |
| 8776 | 8806 | |
| | @@ -9008,155 +9038,157 @@ |
| 9008 | 9038 | #define OP_Function 1 /* synopsis: r[P3]=func(r[P2@P5]) */ |
| 9009 | 9039 | #define OP_Savepoint 2 |
| 9010 | 9040 | #define OP_AutoCommit 3 |
| 9011 | 9041 | #define OP_Transaction 4 |
| 9012 | 9042 | #define OP_SorterNext 5 |
| 9013 | | -#define OP_Prev 6 |
| 9014 | | -#define OP_Next 7 |
| 9015 | | -#define OP_AggStep 8 /* synopsis: accum=r[P3] step(r[P2@P5]) */ |
| 9016 | | -#define OP_Checkpoint 9 |
| 9017 | | -#define OP_JournalMode 10 |
| 9018 | | -#define OP_Vacuum 11 |
| 9019 | | -#define OP_VFilter 12 /* synopsis: iPlan=r[P3] zPlan='P4' */ |
| 9020 | | -#define OP_VUpdate 13 /* synopsis: data=r[P3@P2] */ |
| 9021 | | -#define OP_Goto 14 |
| 9022 | | -#define OP_Gosub 15 |
| 9023 | | -#define OP_Return 16 |
| 9024 | | -#define OP_Yield 17 |
| 9025 | | -#define OP_HaltIfNull 18 /* synopsis: if r[P3] null then halt */ |
| 9043 | +#define OP_PrevIfOpen 6 |
| 9044 | +#define OP_NextIfOpen 7 |
| 9045 | +#define OP_Prev 8 |
| 9046 | +#define OP_Next 9 |
| 9047 | +#define OP_AggStep 10 /* synopsis: accum=r[P3] step(r[P2@P5]) */ |
| 9048 | +#define OP_Checkpoint 11 |
| 9049 | +#define OP_JournalMode 12 |
| 9050 | +#define OP_Vacuum 13 |
| 9051 | +#define OP_VFilter 14 /* synopsis: iPlan=r[P3] zPlan='P4' */ |
| 9052 | +#define OP_VUpdate 15 /* synopsis: data=r[P3@P2] */ |
| 9053 | +#define OP_Goto 16 |
| 9054 | +#define OP_Gosub 17 |
| 9055 | +#define OP_Return 18 |
| 9026 | 9056 | #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ |
| 9027 | | -#define OP_Halt 20 |
| 9028 | | -#define OP_Integer 21 /* synopsis: r[P2]=P1 */ |
| 9029 | | -#define OP_Int64 22 /* synopsis: r[P2]=P4 */ |
| 9030 | | -#define OP_String 23 /* synopsis: r[P2]='P4' (len=P1) */ |
| 9031 | | -#define OP_Null 24 /* synopsis: r[P2..P3]=NULL */ |
| 9032 | | -#define OP_Blob 25 /* synopsis: r[P2]=P4 (len=P1) */ |
| 9033 | | -#define OP_Variable 26 /* synopsis: r[P2]=parameter(P1,P4) */ |
| 9034 | | -#define OP_Move 27 /* synopsis: r[P2@P3]=r[P1@P3] */ |
| 9035 | | -#define OP_Copy 28 /* synopsis: r[P2@P3]=r[P1@P3] */ |
| 9036 | | -#define OP_SCopy 29 /* synopsis: r[P2]=r[P1] */ |
| 9037 | | -#define OP_ResultRow 30 /* synopsis: output=r[P1@P2] */ |
| 9038 | | -#define OP_CollSeq 31 |
| 9039 | | -#define OP_AddImm 32 /* synopsis: r[P1]=r[P1]+P2 */ |
| 9040 | | -#define OP_MustBeInt 33 |
| 9041 | | -#define OP_RealAffinity 34 |
| 9042 | | -#define OP_Permutation 35 |
| 9043 | | -#define OP_Compare 36 |
| 9044 | | -#define OP_Jump 37 |
| 9045 | | -#define OP_Once 38 |
| 9046 | | -#define OP_If 39 |
| 9047 | | -#define OP_IfNot 40 |
| 9048 | | -#define OP_Column 41 /* synopsis: r[P3]=PX */ |
| 9049 | | -#define OP_Affinity 42 /* synopsis: affinity(r[P1@P2]) */ |
| 9050 | | -#define OP_MakeRecord 43 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9051 | | -#define OP_Count 44 /* synopsis: r[P2]=count() */ |
| 9052 | | -#define OP_ReadCookie 45 |
| 9053 | | -#define OP_SetCookie 46 |
| 9054 | | -#define OP_VerifyCookie 47 |
| 9055 | | -#define OP_OpenRead 48 /* synopsis: root=P2 iDb=P3 */ |
| 9056 | | -#define OP_OpenWrite 49 /* synopsis: root=P2 iDb=P3 */ |
| 9057 | | -#define OP_OpenAutoindex 50 /* synopsis: nColumn=P2 */ |
| 9058 | | -#define OP_OpenEphemeral 51 /* synopsis: nColumn=P2 */ |
| 9059 | | -#define OP_SorterOpen 52 |
| 9060 | | -#define OP_OpenPseudo 53 /* synopsis: content in r[P2@P3] */ |
| 9061 | | -#define OP_Close 54 |
| 9062 | | -#define OP_SeekLt 55 /* synopsis: key=r[P3@P4] */ |
| 9063 | | -#define OP_SeekLe 56 /* synopsis: key=r[P3@P4] */ |
| 9064 | | -#define OP_SeekGe 57 /* synopsis: key=r[P3@P4] */ |
| 9065 | | -#define OP_SeekGt 58 /* synopsis: key=r[P3@P4] */ |
| 9066 | | -#define OP_Seek 59 /* synopsis: intkey=r[P2] */ |
| 9067 | | -#define OP_NoConflict 60 /* synopsis: key=r[P3@P4] */ |
| 9068 | | -#define OP_NotFound 61 /* synopsis: key=r[P3@P4] */ |
| 9069 | | -#define OP_Found 62 /* synopsis: key=r[P3@P4] */ |
| 9070 | | -#define OP_NotExists 63 /* synopsis: intkey=r[P3] */ |
| 9071 | | -#define OP_Sequence 64 /* synopsis: r[P2]=rowid */ |
| 9072 | | -#define OP_NewRowid 65 /* synopsis: r[P2]=rowid */ |
| 9073 | | -#define OP_Insert 66 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9074 | | -#define OP_InsertInt 67 /* synopsis: intkey=P3 data=r[P2] */ |
| 9075 | | -#define OP_Delete 68 |
| 9057 | +#define OP_Yield 20 |
| 9058 | +#define OP_HaltIfNull 21 /* synopsis: if r[P3] null then halt */ |
| 9059 | +#define OP_Halt 22 |
| 9060 | +#define OP_Integer 23 /* synopsis: r[P2]=P1 */ |
| 9061 | +#define OP_Int64 24 /* synopsis: r[P2]=P4 */ |
| 9062 | +#define OP_String 25 /* synopsis: r[P2]='P4' (len=P1) */ |
| 9063 | +#define OP_Null 26 /* synopsis: r[P2..P3]=NULL */ |
| 9064 | +#define OP_Blob 27 /* synopsis: r[P2]=P4 (len=P1) */ |
| 9065 | +#define OP_Variable 28 /* synopsis: r[P2]=parameter(P1,P4) */ |
| 9066 | +#define OP_Move 29 /* synopsis: r[P2@P3]=r[P1@P3] */ |
| 9067 | +#define OP_Copy 30 /* synopsis: r[P2@P3]=r[P1@P3] */ |
| 9068 | +#define OP_SCopy 31 /* synopsis: r[P2]=r[P1] */ |
| 9069 | +#define OP_ResultRow 32 /* synopsis: output=r[P1@P2] */ |
| 9070 | +#define OP_CollSeq 33 |
| 9071 | +#define OP_AddImm 34 /* synopsis: r[P1]=r[P1]+P2 */ |
| 9072 | +#define OP_MustBeInt 35 |
| 9073 | +#define OP_RealAffinity 36 |
| 9074 | +#define OP_Permutation 37 |
| 9075 | +#define OP_Compare 38 |
| 9076 | +#define OP_Jump 39 |
| 9077 | +#define OP_Once 40 |
| 9078 | +#define OP_If 41 |
| 9079 | +#define OP_IfNot 42 |
| 9080 | +#define OP_Column 43 /* synopsis: r[P3]=PX */ |
| 9081 | +#define OP_Affinity 44 /* synopsis: affinity(r[P1@P2]) */ |
| 9082 | +#define OP_MakeRecord 45 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ |
| 9083 | +#define OP_Count 46 /* synopsis: r[P2]=count() */ |
| 9084 | +#define OP_ReadCookie 47 |
| 9085 | +#define OP_SetCookie 48 |
| 9086 | +#define OP_VerifyCookie 49 |
| 9087 | +#define OP_OpenRead 50 /* synopsis: root=P2 iDb=P3 */ |
| 9088 | +#define OP_OpenWrite 51 /* synopsis: root=P2 iDb=P3 */ |
| 9089 | +#define OP_OpenAutoindex 52 /* synopsis: nColumn=P2 */ |
| 9090 | +#define OP_OpenEphemeral 53 /* synopsis: nColumn=P2 */ |
| 9091 | +#define OP_SorterOpen 54 |
| 9092 | +#define OP_OpenPseudo 55 /* synopsis: content in r[P2@P3] */ |
| 9093 | +#define OP_Close 56 |
| 9094 | +#define OP_SeekLt 57 /* synopsis: key=r[P3@P4] */ |
| 9095 | +#define OP_SeekLe 58 /* synopsis: key=r[P3@P4] */ |
| 9096 | +#define OP_SeekGe 59 /* synopsis: key=r[P3@P4] */ |
| 9097 | +#define OP_SeekGt 60 /* synopsis: key=r[P3@P4] */ |
| 9098 | +#define OP_Seek 61 /* synopsis: intkey=r[P2] */ |
| 9099 | +#define OP_NoConflict 62 /* synopsis: key=r[P3@P4] */ |
| 9100 | +#define OP_NotFound 63 /* synopsis: key=r[P3@P4] */ |
| 9101 | +#define OP_Found 64 /* synopsis: key=r[P3@P4] */ |
| 9102 | +#define OP_NotExists 65 /* synopsis: intkey=r[P3] */ |
| 9103 | +#define OP_Sequence 66 /* synopsis: r[P2]=rowid */ |
| 9104 | +#define OP_NewRowid 67 /* synopsis: r[P2]=rowid */ |
| 9105 | +#define OP_Insert 68 /* synopsis: intkey=r[P3] data=r[P2] */ |
| 9076 | 9106 | #define OP_Or 69 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 9077 | 9107 | #define OP_And 70 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 9078 | | -#define OP_ResetCount 71 |
| 9079 | | -#define OP_SorterCompare 72 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */ |
| 9080 | | -#define OP_SorterData 73 /* synopsis: r[P2]=data */ |
| 9108 | +#define OP_InsertInt 71 /* synopsis: intkey=P3 data=r[P2] */ |
| 9109 | +#define OP_Delete 72 |
| 9110 | +#define OP_ResetCount 73 |
| 9081 | 9111 | #define OP_IsNull 74 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 9082 | 9112 | #define OP_NotNull 75 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 9083 | 9113 | #define OP_Ne 76 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */ |
| 9084 | 9114 | #define OP_Eq 77 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */ |
| 9085 | 9115 | #define OP_Gt 78 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */ |
| 9086 | 9116 | #define OP_Le 79 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */ |
| 9087 | | -#define OP_Lt 80 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P3 */ |
| 9117 | +#define OP_Lt 80 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */ |
| 9088 | 9118 | #define OP_Ge 81 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */ |
| 9089 | | -#define OP_RowKey 82 /* synopsis: r[P2]=key */ |
| 9119 | +#define OP_SorterCompare 82 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */ |
| 9090 | 9120 | #define OP_BitAnd 83 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ |
| 9091 | 9121 | #define OP_BitOr 84 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ |
| 9092 | 9122 | #define OP_ShiftLeft 85 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ |
| 9093 | 9123 | #define OP_ShiftRight 86 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ |
| 9094 | 9124 | #define OP_Add 87 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ |
| 9095 | 9125 | #define OP_Subtract 88 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ |
| 9096 | 9126 | #define OP_Multiply 89 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ |
| 9097 | | -#define OP_Divide 90 /* same as TK_SLASH, synopsis: r[P3]=r[P1]/r[P2] */ |
| 9098 | | -#define OP_Remainder 91 /* same as TK_REM, synopsis: r[P3]=r[P1]%r[P2] */ |
| 9127 | +#define OP_Divide 90 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ |
| 9128 | +#define OP_Remainder 91 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ |
| 9099 | 9129 | #define OP_Concat 92 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ |
| 9100 | | -#define OP_RowData 93 /* synopsis: r[P2]=data */ |
| 9130 | +#define OP_SorterData 93 /* synopsis: r[P2]=data */ |
| 9101 | 9131 | #define OP_BitNot 94 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ |
| 9102 | 9132 | #define OP_String8 95 /* same as TK_STRING, synopsis: r[P2]='P4' */ |
| 9103 | | -#define OP_Rowid 96 /* synopsis: r[P2]=rowid */ |
| 9104 | | -#define OP_NullRow 97 |
| 9105 | | -#define OP_Last 98 |
| 9106 | | -#define OP_SorterSort 99 |
| 9107 | | -#define OP_Sort 100 |
| 9108 | | -#define OP_Rewind 101 |
| 9109 | | -#define OP_SorterInsert 102 |
| 9110 | | -#define OP_IdxInsert 103 /* synopsis: key=r[P2] */ |
| 9111 | | -#define OP_IdxDelete 104 /* synopsis: key=r[P2@P3] */ |
| 9112 | | -#define OP_IdxRowid 105 /* synopsis: r[P2]=rowid */ |
| 9113 | | -#define OP_IdxLT 106 /* synopsis: key=r[P3@P4] */ |
| 9114 | | -#define OP_IdxGE 107 /* synopsis: key=r[P3@P4] */ |
| 9115 | | -#define OP_Destroy 108 |
| 9116 | | -#define OP_Clear 109 |
| 9117 | | -#define OP_CreateIndex 110 /* synopsis: r[P2]=root iDb=P1 */ |
| 9118 | | -#define OP_CreateTable 111 /* synopsis: r[P2]=root iDb=P1 */ |
| 9119 | | -#define OP_ParseSchema 112 |
| 9120 | | -#define OP_LoadAnalysis 113 |
| 9121 | | -#define OP_DropTable 114 |
| 9122 | | -#define OP_DropIndex 115 |
| 9123 | | -#define OP_DropTrigger 116 |
| 9124 | | -#define OP_IntegrityCk 117 |
| 9125 | | -#define OP_RowSetAdd 118 /* synopsis: rowset(P1)=r[P2] */ |
| 9126 | | -#define OP_RowSetRead 119 /* synopsis: r[P3]=rowset(P1) */ |
| 9127 | | -#define OP_RowSetTest 120 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9128 | | -#define OP_Program 121 |
| 9129 | | -#define OP_Param 122 |
| 9130 | | -#define OP_FkCounter 123 /* synopsis: fkctr[P1]+=P2 */ |
| 9131 | | -#define OP_FkIfZero 124 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9132 | | -#define OP_MemMax 125 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9133 | | -#define OP_IfPos 126 /* synopsis: if r[P1]>0 goto P2 */ |
| 9134 | | -#define OP_IfNeg 127 /* synopsis: if r[P1]<0 goto P2 */ |
| 9135 | | -#define OP_IfZero 128 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9136 | | -#define OP_AggFinal 129 /* synopsis: accum=r[P1] N=P2 */ |
| 9137 | | -#define OP_IncrVacuum 130 |
| 9133 | +#define OP_RowKey 96 /* synopsis: r[P2]=key */ |
| 9134 | +#define OP_RowData 97 /* synopsis: r[P2]=data */ |
| 9135 | +#define OP_Rowid 98 /* synopsis: r[P2]=rowid */ |
| 9136 | +#define OP_NullRow 99 |
| 9137 | +#define OP_Last 100 |
| 9138 | +#define OP_SorterSort 101 |
| 9139 | +#define OP_Sort 102 |
| 9140 | +#define OP_Rewind 103 |
| 9141 | +#define OP_SorterInsert 104 |
| 9142 | +#define OP_IdxInsert 105 /* synopsis: key=r[P2] */ |
| 9143 | +#define OP_IdxDelete 106 /* synopsis: key=r[P2@P3] */ |
| 9144 | +#define OP_IdxRowid 107 /* synopsis: r[P2]=rowid */ |
| 9145 | +#define OP_IdxLT 108 /* synopsis: key=r[P3@P4] */ |
| 9146 | +#define OP_IdxGE 109 /* synopsis: key=r[P3@P4] */ |
| 9147 | +#define OP_Destroy 110 |
| 9148 | +#define OP_Clear 111 |
| 9149 | +#define OP_CreateIndex 112 /* synopsis: r[P2]=root iDb=P1 */ |
| 9150 | +#define OP_CreateTable 113 /* synopsis: r[P2]=root iDb=P1 */ |
| 9151 | +#define OP_ParseSchema 114 |
| 9152 | +#define OP_LoadAnalysis 115 |
| 9153 | +#define OP_DropTable 116 |
| 9154 | +#define OP_DropIndex 117 |
| 9155 | +#define OP_DropTrigger 118 |
| 9156 | +#define OP_IntegrityCk 119 |
| 9157 | +#define OP_RowSetAdd 120 /* synopsis: rowset(P1)=r[P2] */ |
| 9158 | +#define OP_RowSetRead 121 /* synopsis: r[P3]=rowset(P1) */ |
| 9159 | +#define OP_RowSetTest 122 /* synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 9160 | +#define OP_Program 123 |
| 9161 | +#define OP_Param 124 |
| 9162 | +#define OP_FkCounter 125 /* synopsis: fkctr[P1]+=P2 */ |
| 9163 | +#define OP_FkIfZero 126 /* synopsis: if fkctr[P1]==0 goto P2 */ |
| 9164 | +#define OP_MemMax 127 /* synopsis: r[P1]=max(r[P1],r[P2]) */ |
| 9165 | +#define OP_IfPos 128 /* synopsis: if r[P1]>0 goto P2 */ |
| 9166 | +#define OP_IfNeg 129 /* synopsis: if r[P1]<0 goto P2 */ |
| 9167 | +#define OP_IfZero 130 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */ |
| 9138 | 9168 | #define OP_Real 131 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ |
| 9139 | | -#define OP_Expire 132 |
| 9140 | | -#define OP_TableLock 133 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9141 | | -#define OP_VBegin 134 |
| 9142 | | -#define OP_VCreate 135 |
| 9143 | | -#define OP_VDestroy 136 |
| 9144 | | -#define OP_VOpen 137 |
| 9145 | | -#define OP_VColumn 138 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9146 | | -#define OP_VNext 139 |
| 9147 | | -#define OP_VRename 140 |
| 9148 | | -#define OP_Pagecount 141 |
| 9169 | +#define OP_AggFinal 132 /* synopsis: accum=r[P1] N=P2 */ |
| 9170 | +#define OP_IncrVacuum 133 |
| 9171 | +#define OP_Expire 134 |
| 9172 | +#define OP_TableLock 135 /* synopsis: iDb=P1 root=P2 write=P3 */ |
| 9173 | +#define OP_VBegin 136 |
| 9174 | +#define OP_VCreate 137 |
| 9175 | +#define OP_VDestroy 138 |
| 9176 | +#define OP_VOpen 139 |
| 9177 | +#define OP_VColumn 140 /* synopsis: r[P3]=vcolumn(P2) */ |
| 9178 | +#define OP_VNext 141 |
| 9149 | 9179 | #define OP_ToText 142 /* same as TK_TO_TEXT */ |
| 9150 | 9180 | #define OP_ToBlob 143 /* same as TK_TO_BLOB */ |
| 9151 | 9181 | #define OP_ToNumeric 144 /* same as TK_TO_NUMERIC */ |
| 9152 | 9182 | #define OP_ToInt 145 /* same as TK_TO_INT */ |
| 9153 | 9183 | #define OP_ToReal 146 /* same as TK_TO_REAL */ |
| 9154 | | -#define OP_MaxPgcnt 147 |
| 9155 | | -#define OP_Trace 148 |
| 9156 | | -#define OP_Noop 149 |
| 9157 | | -#define OP_Explain 150 |
| 9184 | +#define OP_VRename 147 |
| 9185 | +#define OP_Pagecount 148 |
| 9186 | +#define OP_MaxPgcnt 149 |
| 9187 | +#define OP_Trace 150 |
| 9188 | +#define OP_Noop 151 |
| 9189 | +#define OP_Explain 152 |
| 9158 | 9190 | |
| 9159 | 9191 | |
| 9160 | 9192 | /* Properties such as "out2" or "jump" that are specified in |
| 9161 | 9193 | ** comments following the "case" for each opcode in the vdbe.c |
| 9162 | 9194 | ** are encoded into bitvectors as follows: |
| | @@ -9168,28 +9200,29 @@ |
| 9168 | 9200 | #define OPFLG_IN3 0x0010 /* in3: P3 is an input */ |
| 9169 | 9201 | #define OPFLG_OUT2 0x0020 /* out2: P2 is an output */ |
| 9170 | 9202 | #define OPFLG_OUT3 0x0040 /* out3: P3 is an output */ |
| 9171 | 9203 | #define OPFLG_INITIALIZER {\ |
| 9172 | 9204 | /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\ |
| 9173 | | -/* 8 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x01,\ |
| 9174 | | -/* 16 */ 0x04, 0x04, 0x10, 0x24, 0x00, 0x02, 0x02, 0x02,\ |
| 9175 | | -/* 24 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00,\ |
| 9176 | | -/* 32 */ 0x04, 0x05, 0x04, 0x00, 0x00, 0x01, 0x01, 0x05,\ |
| 9177 | | -/* 40 */ 0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\ |
| 9178 | | -/* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,\ |
| 9179 | | -/* 56 */ 0x11, 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11,\ |
| 9180 | | -/* 64 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x4c, 0x00,\ |
| 9205 | +/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\ |
| 9206 | +/* 16 */ 0x01, 0x01, 0x04, 0x24, 0x04, 0x10, 0x00, 0x02,\ |
| 9207 | +/* 24 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x20,\ |
| 9208 | +/* 32 */ 0x00, 0x00, 0x04, 0x05, 0x04, 0x00, 0x00, 0x01,\ |
| 9209 | +/* 40 */ 0x01, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x02,\ |
| 9210 | +/* 48 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 9211 | +/* 56 */ 0x00, 0x11, 0x11, 0x11, 0x11, 0x08, 0x11, 0x11,\ |
| 9212 | +/* 64 */ 0x11, 0x11, 0x02, 0x02, 0x00, 0x4c, 0x4c, 0x00,\ |
| 9181 | 9213 | /* 72 */ 0x00, 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15,\ |
| 9182 | 9214 | /* 80 */ 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\ |
| 9183 | 9215 | /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02,\ |
| 9184 | | -/* 96 */ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08,\ |
| 9185 | | -/* 104 */ 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02, 0x02,\ |
| 9186 | | -/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\ |
| 9187 | | -/* 120 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x08, 0x05, 0x05,\ |
| 9188 | | -/* 128 */ 0x05, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00,\ |
| 9189 | | -/* 136 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x04, 0x04,\ |
| 9190 | | -/* 144 */ 0x04, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00,} |
| 9216 | +/* 96 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,\ |
| 9217 | +/* 104 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\ |
| 9218 | +/* 112 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 9219 | +/* 120 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\ |
| 9220 | +/* 128 */ 0x05, 0x05, 0x05, 0x02, 0x00, 0x01, 0x00, 0x00,\ |
| 9221 | +/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x04,\ |
| 9222 | +/* 144 */ 0x04, 0x04, 0x04, 0x00, 0x02, 0x02, 0x00, 0x00,\ |
| 9223 | +/* 152 */ 0x00,} |
| 9191 | 9224 | |
| 9192 | 9225 | /************** End of opcodes.h *********************************************/ |
| 9193 | 9226 | /************** Continuing where we left off in vdbe.h ***********************/ |
| 9194 | 9227 | |
| 9195 | 9228 | /* |
| | @@ -9223,11 +9256,10 @@ |
| 9223 | 9256 | SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); |
| 9224 | 9257 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); |
| 9225 | 9258 | SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); |
| 9226 | 9259 | #ifdef SQLITE_DEBUG |
| 9227 | 9260 | SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); |
| 9228 | | -SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); |
| 9229 | 9261 | #endif |
| 9230 | 9262 | SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); |
| 9231 | 9263 | SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); |
| 9232 | 9264 | SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); |
| 9233 | 9265 | SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); |
| | @@ -10290,10 +10322,11 @@ |
| 10290 | 10322 | #define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ |
| 10291 | 10323 | #define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ |
| 10292 | 10324 | #define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */ |
| 10293 | 10325 | #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ |
| 10294 | 10326 | #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ |
| 10327 | +#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ |
| 10295 | 10328 | |
| 10296 | 10329 | |
| 10297 | 10330 | /* |
| 10298 | 10331 | ** Bits of the sqlite3.dbOptFlags field that are used by the |
| 10299 | 10332 | ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to |
| | @@ -10323,10 +10356,17 @@ |
| 10323 | 10356 | #else |
| 10324 | 10357 | #define OptimizationDisabled(db, mask) 0 |
| 10325 | 10358 | #define OptimizationEnabled(db, mask) 1 |
| 10326 | 10359 | #endif |
| 10327 | 10360 | |
| 10361 | +/* |
| 10362 | +** Return true if it OK to factor constant expressions into the initialization |
| 10363 | +** code. The argument is a Parse object for the code generator. |
| 10364 | +*/ |
| 10365 | +#define ConstFactorOk(P) \ |
| 10366 | + ((P)->cookieGoto>0 && OptimizationEnabled((P)->db,SQLITE_FactorOutConst)) |
| 10367 | + |
| 10328 | 10368 | /* |
| 10329 | 10369 | ** Possible values for the sqlite.magic field. |
| 10330 | 10370 | ** The numbers are obtained at random and have no special meaning, other |
| 10331 | 10371 | ** than being distinct from one another. |
| 10332 | 10372 | */ |
| | @@ -10389,10 +10429,11 @@ |
| 10389 | 10429 | #define SQLITE_FUNC_LENGTH 0x040 /* Built-in length() function */ |
| 10390 | 10430 | #define SQLITE_FUNC_TYPEOF 0x080 /* Built-in typeof() function */ |
| 10391 | 10431 | #define SQLITE_FUNC_COUNT 0x100 /* Built-in count(*) aggregate */ |
| 10392 | 10432 | #define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */ |
| 10393 | 10433 | #define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */ |
| 10434 | +#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */ |
| 10394 | 10435 | |
| 10395 | 10436 | /* |
| 10396 | 10437 | ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are |
| 10397 | 10438 | ** used to create the initializers for the FuncDef structures. |
| 10398 | 10439 | ** |
| | @@ -10401,10 +10442,13 @@ |
| 10401 | 10442 | ** implemented by C function xFunc that accepts nArg arguments. The |
| 10402 | 10443 | ** value passed as iArg is cast to a (void*) and made available |
| 10403 | 10444 | ** as the user-data (sqlite3_user_data()) for the function. If |
| 10404 | 10445 | ** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. |
| 10405 | 10446 | ** |
| 10447 | +** VFUNCTION(zName, nArg, iArg, bNC, xFunc) |
| 10448 | +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. |
| 10449 | +** |
| 10406 | 10450 | ** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) |
| 10407 | 10451 | ** Used to create an aggregate function definition implemented by |
| 10408 | 10452 | ** the C functions xStep and xFinal. The first four parameters |
| 10409 | 10453 | ** are interpreted in the same way as the first 4 parameters to |
| 10410 | 10454 | ** FUNCTION(). |
| | @@ -10416,20 +10460,24 @@ |
| 10416 | 10460 | ** available as the function user-data (sqlite3_user_data()). The |
| 10417 | 10461 | ** FuncDef.flags variable is set to the value passed as the flags |
| 10418 | 10462 | ** parameter. |
| 10419 | 10463 | */ |
| 10420 | 10464 | #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ |
| 10465 | + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ |
| 10466 | + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} |
| 10467 | +#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ |
| 10421 | 10468 | {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ |
| 10422 | 10469 | SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} |
| 10423 | 10470 | #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ |
| 10424 | | - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ |
| 10471 | + {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ |
| 10425 | 10472 | SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} |
| 10426 | 10473 | #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ |
| 10427 | | - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ |
| 10474 | + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ |
| 10428 | 10475 | pArg, 0, xFunc, 0, 0, #zName, 0, 0} |
| 10429 | 10476 | #define LIKEFUNC(zName, nArg, arg, flags) \ |
| 10430 | | - {nArg, SQLITE_UTF8|flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} |
| 10477 | + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ |
| 10478 | + (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} |
| 10431 | 10479 | #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ |
| 10432 | 10480 | {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ |
| 10433 | 10481 | SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} |
| 10434 | 10482 | |
| 10435 | 10483 | /* |
| | @@ -11075,20 +11123,21 @@ |
| 11075 | 11123 | #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ |
| 11076 | 11124 | #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ |
| 11077 | 11125 | #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ |
| 11078 | 11126 | #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ |
| 11079 | 11127 | #define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */ |
| 11080 | | -#define EP_FixedDest 0x000200 /* Result needed in a specific register */ |
| 11128 | + /* unused 0x000200 */ |
| 11081 | 11129 | #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ |
| 11082 | 11130 | #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ |
| 11083 | 11131 | #define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */ |
| 11084 | 11132 | #define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ |
| 11085 | 11133 | #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ |
| 11086 | 11134 | #define EP_Static 0x008000 /* Held in memory not obtained from malloc() */ |
| 11087 | 11135 | #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ |
| 11088 | 11136 | #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ |
| 11089 | 11137 | #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ |
| 11138 | +#define EP_Constant 0x080000 /* Node is a constant */ |
| 11090 | 11139 | |
| 11091 | 11140 | /* |
| 11092 | 11141 | ** These macros can be used to test, set, or clear bits in the |
| 11093 | 11142 | ** Expr.flags field. |
| 11094 | 11143 | */ |
| | @@ -11146,12 +11195,18 @@ |
| 11146 | 11195 | char *zName; /* Token associated with this expression */ |
| 11147 | 11196 | char *zSpan; /* Original text of the expression */ |
| 11148 | 11197 | u8 sortOrder; /* 1 for DESC or 0 for ASC */ |
| 11149 | 11198 | unsigned done :1; /* A flag to indicate when processing is finished */ |
| 11150 | 11199 | unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ |
| 11151 | | - u16 iOrderByCol; /* For ORDER BY, column number in result set */ |
| 11152 | | - u16 iAlias; /* Index into Parse.aAlias[] for zName */ |
| 11200 | + unsigned reusable :1; /* Constant expression is reusable */ |
| 11201 | + union { |
| 11202 | + struct { |
| 11203 | + u16 iOrderByCol; /* For ORDER BY, column number in result set */ |
| 11204 | + u16 iAlias; /* Index into Parse.aAlias[] for zName */ |
| 11205 | + } x; |
| 11206 | + int iConstExprReg; /* Register in which Expr value is cached */ |
| 11207 | + } u; |
| 11153 | 11208 | } *a; /* Alloc a power of two greater or equal to nExpr */ |
| 11154 | 11209 | }; |
| 11155 | 11210 | |
| 11156 | 11211 | /* |
| 11157 | 11212 | ** An instance of this structure is used by the parser to record both |
| | @@ -11524,10 +11579,11 @@ |
| 11524 | 11579 | u8 tempReg; /* iReg is a temp register that needs to be freed */ |
| 11525 | 11580 | int iLevel; /* Nesting level */ |
| 11526 | 11581 | int iReg; /* Reg with value of this column. 0 means none. */ |
| 11527 | 11582 | int lru; /* Least recently used entry has the smallest value */ |
| 11528 | 11583 | } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ |
| 11584 | + ExprList *pConstExpr;/* Constant expressions */ |
| 11529 | 11585 | yDbMask writeMask; /* Start a write transaction on these databases */ |
| 11530 | 11586 | yDbMask cookieMask; /* Bitmask of schema verified databases */ |
| 11531 | 11587 | int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ |
| 11532 | 11588 | int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ |
| 11533 | 11589 | int regRowid; /* Register holding rowid of CREATE TABLE entry */ |
| | @@ -11761,10 +11817,11 @@ |
| 11761 | 11817 | int bCoreMutex; /* True to enable core mutexing */ |
| 11762 | 11818 | int bFullMutex; /* True to enable full mutexing */ |
| 11763 | 11819 | int bOpenUri; /* True to interpret filenames as URIs */ |
| 11764 | 11820 | int bUseCis; /* Use covering indices for full-scans */ |
| 11765 | 11821 | int mxStrlen; /* Maximum string length */ |
| 11822 | + int neverCorrupt; /* Database is always well-formed */ |
| 11766 | 11823 | int szLookaside; /* Default lookaside buffer size */ |
| 11767 | 11824 | int nLookaside; /* Default lookaside buffer count */ |
| 11768 | 11825 | sqlite3_mem_methods m; /* Low-level memory allocation interface */ |
| 11769 | 11826 | sqlite3_mutex_methods mutex; /* Low-level mutex interface */ |
| 11770 | 11827 | sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ |
| | @@ -11797,10 +11854,28 @@ |
| 11797 | 11854 | void(*xSqllog)(void*,sqlite3*,const char*, int); |
| 11798 | 11855 | void *pSqllogArg; |
| 11799 | 11856 | #endif |
| 11800 | 11857 | }; |
| 11801 | 11858 | |
| 11859 | +/* |
| 11860 | +** This macro is used inside of assert() statements to indicate that |
| 11861 | +** the assert is only valid on a well-formed database. Instead of: |
| 11862 | +** |
| 11863 | +** assert( X ); |
| 11864 | +** |
| 11865 | +** One writes: |
| 11866 | +** |
| 11867 | +** assert( X || CORRUPT_DB ); |
| 11868 | +** |
| 11869 | +** CORRUPT_DB is true during normal operation. CORRUPT_DB does not indicate |
| 11870 | +** that the database is definitely corrupt, only that it might be corrupt. |
| 11871 | +** For most test cases, CORRUPT_DB is set to false using a special |
| 11872 | +** sqlite3_test_control(). This enables assert() statements to prove |
| 11873 | +** things that are always true for well-formed databases. |
| 11874 | +*/ |
| 11875 | +#define CORRUPT_DB (sqlite3Config.neverCorrupt==0) |
| 11876 | + |
| 11802 | 11877 | /* |
| 11803 | 11878 | ** Context pointer passed down through the tree-walk. |
| 11804 | 11879 | */ |
| 11805 | 11880 | struct Walker { |
| 11806 | 11881 | int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ |
| | @@ -12134,15 +12209,17 @@ |
| 12134 | 12209 | SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int); |
| 12135 | 12210 | SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); |
| 12136 | 12211 | SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); |
| 12137 | 12212 | SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); |
| 12138 | 12213 | SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int); |
| 12214 | +SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); |
| 12139 | 12215 | SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); |
| 12140 | 12216 | SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); |
| 12141 | 12217 | SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse*, Expr*, int); |
| 12142 | | -SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse*, Expr*); |
| 12143 | | -SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int); |
| 12218 | +SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8); |
| 12219 | +#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ |
| 12220 | +#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ |
| 12144 | 12221 | SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int); |
| 12145 | 12222 | SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int); |
| 12146 | 12223 | SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); |
| 12147 | 12224 | SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*); |
| 12148 | 12225 | SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *); |
| | @@ -12183,11 +12260,11 @@ |
| 12183 | 12260 | SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*); |
| 12184 | 12261 | SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*); |
| 12185 | 12262 | SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, |
| 12186 | 12263 | u8,u8,int,int*); |
| 12187 | 12264 | SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); |
| 12188 | | -SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, int*, int*); |
| 12265 | +SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*); |
| 12189 | 12266 | SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); |
| 12190 | 12267 | SQLITE_PRIVATE void sqlite3MultiWrite(Parse*); |
| 12191 | 12268 | SQLITE_PRIVATE void sqlite3MayAbort(Parse*); |
| 12192 | 12269 | SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8); |
| 12193 | 12270 | SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*); |
| | @@ -12424,10 +12501,11 @@ |
| 12424 | 12501 | SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); |
| 12425 | 12502 | SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); |
| 12426 | 12503 | |
| 12427 | 12504 | SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int); |
| 12428 | 12505 | SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int); |
| 12506 | +SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*); |
| 12429 | 12507 | SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int); |
| 12430 | 12508 | SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); |
| 12431 | 12509 | SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*); |
| 12432 | 12510 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); |
| 12433 | 12511 | SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); |
| | @@ -12505,10 +12583,11 @@ |
| 12505 | 12583 | SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); |
| 12506 | 12584 | SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); |
| 12507 | 12585 | SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); |
| 12508 | 12586 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); |
| 12509 | 12587 | SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); |
| 12588 | +SQLITE_PRIVATE void sqlite3ParserReset(Parse*); |
| 12510 | 12589 | SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); |
| 12511 | 12590 | SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); |
| 12512 | 12591 | SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); |
| 12513 | 12592 | SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); |
| 12514 | 12593 | SQLITE_PRIVATE const char *sqlite3JournalModename(int); |
| | @@ -12821,10 +12900,11 @@ |
| 12821 | 12900 | 1, /* bCoreMutex */ |
| 12822 | 12901 | SQLITE_THREADSAFE==1, /* bFullMutex */ |
| 12823 | 12902 | SQLITE_USE_URI, /* bOpenUri */ |
| 12824 | 12903 | SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ |
| 12825 | 12904 | 0x7ffffffe, /* mxStrlen */ |
| 12905 | + 0, /* neverCorrupt */ |
| 12826 | 12906 | 128, /* szLookaside */ |
| 12827 | 12907 | 500, /* nLookaside */ |
| 12828 | 12908 | {0,0,0,0,0,0,0,0}, /* m */ |
| 12829 | 12909 | {0,0,0,0,0,0,0,0,0}, /* mutex */ |
| 12830 | 12910 | {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ |
| | @@ -12855,11 +12935,10 @@ |
| 12855 | 12935 | #ifdef SQLITE_ENABLE_SQLLOG |
| 12856 | 12936 | 0, /* xSqllog */ |
| 12857 | 12937 | 0 /* pSqllogArg */ |
| 12858 | 12938 | #endif |
| 12859 | 12939 | }; |
| 12860 | | - |
| 12861 | 12940 | |
| 12862 | 12941 | /* |
| 12863 | 12942 | ** Hash table for global functions - functions common to all |
| 12864 | 12943 | ** database connections. After initialization, this table is |
| 12865 | 12944 | ** read-only. |
| | @@ -13253,10 +13332,13 @@ |
| 13253 | 13332 | "SMALL_STACK", |
| 13254 | 13333 | #endif |
| 13255 | 13334 | #ifdef SQLITE_SOUNDEX |
| 13256 | 13335 | "SOUNDEX", |
| 13257 | 13336 | #endif |
| 13337 | +#ifdef SQLITE_SYSTEM_MALLOC |
| 13338 | + "SYSTEM_MALLOC", |
| 13339 | +#endif |
| 13258 | 13340 | #ifdef SQLITE_TCL |
| 13259 | 13341 | "TCL", |
| 13260 | 13342 | #endif |
| 13261 | 13343 | #if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc) |
| 13262 | 13344 | "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), |
| | @@ -13267,10 +13349,13 @@ |
| 13267 | 13349 | #if defined(SQLITE_THREADSAFE) |
| 13268 | 13350 | "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), |
| 13269 | 13351 | #endif |
| 13270 | 13352 | #ifdef SQLITE_USE_ALLOCA |
| 13271 | 13353 | "USE_ALLOCA", |
| 13354 | +#endif |
| 13355 | +#ifdef SQLITE_WIN32_MALLOC |
| 13356 | + "WIN32_MALLOC", |
| 13272 | 13357 | #endif |
| 13273 | 13358 | #ifdef SQLITE_ZERO_MALLOC |
| 13274 | 13359 | "ZERO_MALLOC" |
| 13275 | 13360 | #endif |
| 13276 | 13361 | }; |
| | @@ -13367,11 +13452,11 @@ |
| 13367 | 13452 | typedef struct VdbeOp Op; |
| 13368 | 13453 | |
| 13369 | 13454 | /* |
| 13370 | 13455 | ** Boolean values |
| 13371 | 13456 | */ |
| 13372 | | -typedef unsigned char Bool; |
| 13457 | +typedef unsigned Bool; |
| 13373 | 13458 | |
| 13374 | 13459 | /* Opaque type used by code in vdbesort.c */ |
| 13375 | 13460 | typedef struct VdbeSorter VdbeSorter; |
| 13376 | 13461 | |
| 13377 | 13462 | /* Opaque type used by the explainer */ |
| | @@ -13384,42 +13469,39 @@ |
| 13384 | 13469 | ** A cursor is a pointer into a single BTree within a database file. |
| 13385 | 13470 | ** The cursor can seek to a BTree entry with a particular key, or |
| 13386 | 13471 | ** loop over all entries of the Btree. You can also insert new BTree |
| 13387 | 13472 | ** entries or retrieve the key or data from the entry that the cursor |
| 13388 | 13473 | ** is currently pointing to. |
| 13474 | +** |
| 13475 | +** Cursors can also point to virtual tables, sorters, or "pseudo-tables". |
| 13476 | +** A pseudo-table is a single-row table implemented by registers. |
| 13389 | 13477 | ** |
| 13390 | 13478 | ** Every cursor that the virtual machine has open is represented by an |
| 13391 | 13479 | ** instance of the following structure. |
| 13392 | 13480 | */ |
| 13393 | 13481 | struct VdbeCursor { |
| 13394 | 13482 | BtCursor *pCursor; /* The cursor structure of the backend */ |
| 13395 | 13483 | Btree *pBt; /* Separate file holding temporary table */ |
| 13396 | 13484 | KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ |
| 13397 | | - int iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13485 | + int seekResult; /* Result of previous sqlite3BtreeMoveto() */ |
| 13398 | 13486 | int pseudoTableReg; /* Register holding pseudotable content. */ |
| 13399 | | - int nField; /* Number of fields in the header */ |
| 13400 | | - Bool zeroed; /* True if zeroed out and ready for reuse */ |
| 13401 | | - Bool rowidIsValid; /* True if lastRowid is valid */ |
| 13402 | | - Bool atFirst; /* True if pointing to first entry */ |
| 13403 | | - Bool useRandomRowid; /* Generate new record numbers semi-randomly */ |
| 13404 | | - Bool nullRow; /* True if pointing to a row with no data */ |
| 13405 | | - Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13406 | | - Bool isTable; /* True if a table requiring integer keys */ |
| 13407 | | - Bool isIndex; /* True if an index containing keys only - no data */ |
| 13408 | | - Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ |
| 13409 | | - Bool isSorter; /* True if a new-style sorter */ |
| 13410 | | - Bool multiPseudo; /* Multi-register pseudo-cursor */ |
| 13487 | + i16 nField; /* Number of fields in the header */ |
| 13488 | + u16 nHdrParsed; /* Number of header fields parsed so far */ |
| 13489 | + i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 13490 | + u8 nullRow; /* True if pointing to a row with no data */ |
| 13491 | + u8 rowidIsValid; /* True if lastRowid is valid */ |
| 13492 | + u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 13493 | + Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ |
| 13494 | + Bool isTable:1; /* True if a table requiring integer keys */ |
| 13495 | + Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ |
| 13496 | + Bool multiPseudo:1; /* Multi-register pseudo-cursor */ |
| 13411 | 13497 | sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ |
| 13412 | | - const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ |
| 13413 | 13498 | i64 seqCount; /* Sequence counter */ |
| 13414 | 13499 | i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ |
| 13415 | | - i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ |
| 13500 | + i64 lastRowid; /* Rowid being deleted by OP_Delete */ |
| 13416 | 13501 | VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ |
| 13417 | 13502 | |
| 13418 | | - /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists */ |
| 13419 | | - int seekResult; |
| 13420 | | - |
| 13421 | 13503 | /* Cached information about the header for the data record that the |
| 13422 | 13504 | ** cursor is currently pointing to. Only valid if cacheStatus matches |
| 13423 | 13505 | ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of |
| 13424 | 13506 | ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that |
| 13425 | 13507 | ** the cache is out of date. |
| | @@ -13426,14 +13508,18 @@ |
| 13426 | 13508 | ** |
| 13427 | 13509 | ** aRow might point to (ephemeral) data for the current row, or it might |
| 13428 | 13510 | ** be NULL. |
| 13429 | 13511 | */ |
| 13430 | 13512 | u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ |
| 13431 | | - int payloadSize; /* Total number of bytes in the record */ |
| 13432 | | - u32 *aType; /* Type values for all entries in the record */ |
| 13433 | | - u32 *aOffset; /* Cached offsets to the start of each columns data */ |
| 13434 | | - u8 *aRow; /* Data for the current row, if all on one page */ |
| 13513 | + u32 payloadSize; /* Total number of bytes in the record */ |
| 13514 | + u32 szRow; /* Byte available in aRow */ |
| 13515 | + u32 iHdrOffset; /* Offset to next unparsed byte of the header */ |
| 13516 | + const u8 *aRow; /* Data for the current row, if all on one page */ |
| 13517 | + u32 aType[1]; /* Type values for all entries in the record */ |
| 13518 | + /* 2*nField extra array elements allocated for aType[], beyond the one |
| 13519 | + ** static element declared in the structure. nField total array slots for |
| 13520 | + ** aType[] and nField+1 array slots for aOffset[] */ |
| 13435 | 13521 | }; |
| 13436 | 13522 | typedef struct VdbeCursor VdbeCursor; |
| 13437 | 13523 | |
| 13438 | 13524 | /* |
| 13439 | 13525 | ** When a sub-program is executed (OP_Program), a structure of this type |
| | @@ -13686,13 +13772,10 @@ |
| 13686 | 13772 | i64 nFkConstraint; /* Number of imm. FK constraints this VM */ |
| 13687 | 13773 | i64 nStmtDefCons; /* Number of def. constraints when stmt started */ |
| 13688 | 13774 | i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ |
| 13689 | 13775 | char *zSql; /* Text of the SQL statement that generated this */ |
| 13690 | 13776 | void *pFree; /* Free this when deleting the vdbe */ |
| 13691 | | -#ifdef SQLITE_DEBUG |
| 13692 | | - FILE *trace; /* Write an execution trace here, if not NULL */ |
| 13693 | | -#endif |
| 13694 | 13777 | #ifdef SQLITE_ENABLE_TREE_EXPLAIN |
| 13695 | 13778 | Explain *pExplain; /* The explainer */ |
| 13696 | 13779 | char *zExplain; /* Explanation of data structures */ |
| 13697 | 13780 | #endif |
| 13698 | 13781 | VdbeFrame *pFrame; /* Parent frame */ |
| | @@ -13722,11 +13805,11 @@ |
| 13722 | 13805 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 13723 | 13806 | SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); |
| 13724 | 13807 | #endif |
| 13725 | 13808 | SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); |
| 13726 | 13809 | SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); |
| 13727 | | -SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); |
| 13810 | +SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); |
| 13728 | 13811 | SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); |
| 13729 | 13812 | SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); |
| 13730 | 13813 | |
| 13731 | 13814 | int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); |
| 13732 | 13815 | SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); |
| | @@ -13757,11 +13840,11 @@ |
| 13757 | 13840 | SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); |
| 13758 | 13841 | SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); |
| 13759 | 13842 | SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); |
| 13760 | 13843 | SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); |
| 13761 | 13844 | SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); |
| 13762 | | -SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); |
| 13845 | +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); |
| 13763 | 13846 | SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); |
| 13764 | 13847 | SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p); |
| 13765 | 13848 | #define VdbeMemRelease(X) \ |
| 13766 | 13849 | if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \ |
| 13767 | 13850 | sqlite3VdbeMemReleaseExternal(X); |
| | @@ -15782,20 +15865,10 @@ |
| 15782 | 15865 | ** This version of the memory allocator is the default. It is |
| 15783 | 15866 | ** used when no other memory allocator is specified using compile-time |
| 15784 | 15867 | ** macros. |
| 15785 | 15868 | */ |
| 15786 | 15869 | #ifdef SQLITE_SYSTEM_MALLOC |
| 15787 | | - |
| 15788 | | -/* |
| 15789 | | -** The MSVCRT has malloc_usable_size() but it is called _msize(). |
| 15790 | | -** The use of _msize() is automatic, but can be disabled by compiling |
| 15791 | | -** with -DSQLITE_WITHOUT_MSIZE |
| 15792 | | -*/ |
| 15793 | | -#if defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE) |
| 15794 | | -# define SQLITE_MALLOCSIZE _msize |
| 15795 | | -#endif |
| 15796 | | - |
| 15797 | 15870 | #if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) |
| 15798 | 15871 | |
| 15799 | 15872 | /* |
| 15800 | 15873 | ** Use the zone allocator available on apple products unless the |
| 15801 | 15874 | ** SQLITE_WITHOUT_ZONEMALLOC symbol is defined. |
| | @@ -15814,25 +15887,51 @@ |
| 15814 | 15887 | |
| 15815 | 15888 | /* |
| 15816 | 15889 | ** Use standard C library malloc and free on non-Apple systems. |
| 15817 | 15890 | ** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined. |
| 15818 | 15891 | */ |
| 15819 | | -#define SQLITE_MALLOC(x) malloc(x) |
| 15820 | | -#define SQLITE_FREE(x) free(x) |
| 15821 | | -#define SQLITE_REALLOC(x,y) realloc((x),(y)) |
| 15822 | | - |
| 15823 | | -#if (defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)) \ |
| 15824 | | - || (defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE)) |
| 15825 | | -# include <malloc.h> /* Needed for malloc_usable_size on linux */ |
| 15826 | | -#endif |
| 15827 | | -#ifdef HAVE_MALLOC_USABLE_SIZE |
| 15828 | | -# ifndef SQLITE_MALLOCSIZE |
| 15829 | | -# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) |
| 15830 | | -# endif |
| 15831 | | -#else |
| 15832 | | -# undef SQLITE_MALLOCSIZE |
| 15833 | | -#endif |
| 15892 | +#define SQLITE_MALLOC(x) malloc(x) |
| 15893 | +#define SQLITE_FREE(x) free(x) |
| 15894 | +#define SQLITE_REALLOC(x,y) realloc((x),(y)) |
| 15895 | + |
| 15896 | +/* |
| 15897 | +** The malloc.h header file is needed for malloc_usable_size() function |
| 15898 | +** on some systems (e.g. Linux). |
| 15899 | +*/ |
| 15900 | +#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE) |
| 15901 | +# define SQLITE_USE_MALLOC_H |
| 15902 | +# define SQLITE_USE_MALLOC_USABLE_SIZE |
| 15903 | +/* |
| 15904 | +** The MSVCRT has malloc_usable_size(), but it is called _msize(). The |
| 15905 | +** use of _msize() is automatic, but can be disabled by compiling with |
| 15906 | +** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires |
| 15907 | +** the malloc.h header file. |
| 15908 | +*/ |
| 15909 | +#elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE) |
| 15910 | +# define SQLITE_USE_MALLOC_H |
| 15911 | +# define SQLITE_USE_MSIZE |
| 15912 | +#endif |
| 15913 | + |
| 15914 | +/* |
| 15915 | +** Include the malloc.h header file, if necessary. Also set define macro |
| 15916 | +** SQLITE_MALLOCSIZE to the appropriate function name, which is _msize() |
| 15917 | +** for MSVC and malloc_usable_size() for most other systems (e.g. Linux). |
| 15918 | +** The memory size function can always be overridden manually by defining |
| 15919 | +** the macro SQLITE_MALLOCSIZE to the desired function name. |
| 15920 | +*/ |
| 15921 | +#if defined(SQLITE_USE_MALLOC_H) |
| 15922 | +# include <malloc.h> |
| 15923 | +# if defined(SQLITE_USE_MALLOC_USABLE_SIZE) |
| 15924 | +# if !defined(SQLITE_MALLOCSIZE) |
| 15925 | +# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) |
| 15926 | +# endif |
| 15927 | +# elif defined(SQLITE_USE_MSIZE) |
| 15928 | +# if !defined(SQLITE_MALLOCSIZE) |
| 15929 | +# define SQLITE_MALLOCSIZE _msize |
| 15930 | +# endif |
| 15931 | +# endif |
| 15932 | +#endif /* defined(SQLITE_USE_MALLOC_H) */ |
| 15834 | 15933 | |
| 15835 | 15934 | #endif /* __APPLE__ or not __APPLE__ */ |
| 15836 | 15935 | |
| 15837 | 15936 | /* |
| 15838 | 15937 | ** Like malloc(), but remember the size of the allocation |
| | @@ -17435,36 +17534,17 @@ |
| 17435 | 17534 | ** works for chunks that are currently checked out. |
| 17436 | 17535 | */ |
| 17437 | 17536 | static int memsys5Size(void *p){ |
| 17438 | 17537 | int iSize = 0; |
| 17439 | 17538 | if( p ){ |
| 17440 | | - int i = ((u8 *)p-mem5.zPool)/mem5.szAtom; |
| 17539 | + int i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom); |
| 17441 | 17540 | assert( i>=0 && i<mem5.nBlock ); |
| 17442 | 17541 | iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE)); |
| 17443 | 17542 | } |
| 17444 | 17543 | return iSize; |
| 17445 | 17544 | } |
| 17446 | 17545 | |
| 17447 | | -/* |
| 17448 | | -** Find the first entry on the freelist iLogsize. Unlink that |
| 17449 | | -** entry and return its index. |
| 17450 | | -*/ |
| 17451 | | -static int memsys5UnlinkFirst(int iLogsize){ |
| 17452 | | - int i; |
| 17453 | | - int iFirst; |
| 17454 | | - |
| 17455 | | - assert( iLogsize>=0 && iLogsize<=LOGMAX ); |
| 17456 | | - i = iFirst = mem5.aiFreelist[iLogsize]; |
| 17457 | | - assert( iFirst>=0 ); |
| 17458 | | - while( i>0 ){ |
| 17459 | | - if( i<iFirst ) iFirst = i; |
| 17460 | | - i = MEM5LINK(i)->next; |
| 17461 | | - } |
| 17462 | | - memsys5Unlink(iFirst, iLogsize); |
| 17463 | | - return iFirst; |
| 17464 | | -} |
| 17465 | | - |
| 17466 | 17546 | /* |
| 17467 | 17547 | ** Return a block of memory of at least nBytes in size. |
| 17468 | 17548 | ** Return NULL if unable. Return NULL if nBytes==0. |
| 17469 | 17549 | ** |
| 17470 | 17550 | ** The caller guarantees that nByte is positive. |
| | @@ -17506,11 +17586,12 @@ |
| 17506 | 17586 | if( iBin>LOGMAX ){ |
| 17507 | 17587 | testcase( sqlite3GlobalConfig.xLog!=0 ); |
| 17508 | 17588 | sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); |
| 17509 | 17589 | return 0; |
| 17510 | 17590 | } |
| 17511 | | - i = memsys5UnlinkFirst(iBin); |
| 17591 | + i = mem5.aiFreelist[iBin]; |
| 17592 | + memsys5Unlink(i, iBin); |
| 17512 | 17593 | while( iBin>iLogsize ){ |
| 17513 | 17594 | int newSize; |
| 17514 | 17595 | |
| 17515 | 17596 | iBin--; |
| 17516 | 17597 | newSize = 1 << iBin; |
| | @@ -17540,11 +17621,11 @@ |
| 17540 | 17621 | int iBlock; |
| 17541 | 17622 | |
| 17542 | 17623 | /* Set iBlock to the index of the block pointed to by pOld in |
| 17543 | 17624 | ** the array of mem5.szAtom byte blocks pointed to by mem5.zPool. |
| 17544 | 17625 | */ |
| 17545 | | - iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom; |
| 17626 | + iBlock = (int)(((u8 *)pOld-mem5.zPool)/mem5.szAtom); |
| 17546 | 17627 | |
| 17547 | 17628 | /* Check that the pointer pOld points to a valid, non-free block. */ |
| 17548 | 17629 | assert( iBlock>=0 && iBlock<mem5.nBlock ); |
| 17549 | 17630 | assert( ((u8 *)pOld-mem5.zPool)%mem5.szAtom==0 ); |
| 17550 | 17631 | assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 ); |
| | @@ -19309,11 +19390,11 @@ |
| 19309 | 19390 | /* |
| 19310 | 19391 | ** TRUE if p is a lookaside memory allocation from db |
| 19311 | 19392 | */ |
| 19312 | 19393 | #ifndef SQLITE_OMIT_LOOKASIDE |
| 19313 | 19394 | static int isLookaside(sqlite3 *db, void *p){ |
| 19314 | | - return p && p>=db->lookaside.pStart && p<db->lookaside.pEnd; |
| 19395 | + return p>=db->lookaside.pStart && p<db->lookaside.pEnd; |
| 19315 | 19396 | } |
| 19316 | 19397 | #else |
| 19317 | 19398 | #define isLookaside(A,B) 0 |
| 19318 | 19399 | #endif |
| 19319 | 19400 | |
| | @@ -19325,12 +19406,13 @@ |
| 19325 | 19406 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 19326 | 19407 | assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); |
| 19327 | 19408 | return sqlite3GlobalConfig.m.xSize(p); |
| 19328 | 19409 | } |
| 19329 | 19410 | SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ |
| 19330 | | - assert( db==0 || sqlite3_mutex_held(db->mutex) ); |
| 19331 | | - if( db && isLookaside(db, p) ){ |
| 19411 | + assert( db!=0 ); |
| 19412 | + assert( sqlite3_mutex_held(db->mutex) ); |
| 19413 | + if( isLookaside(db, p) ){ |
| 19332 | 19414 | return db->lookaside.sz; |
| 19333 | 19415 | }else{ |
| 19334 | 19416 | assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); |
| 19335 | 19417 | assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); |
| 19336 | 19418 | assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); |
| | @@ -19808,10 +19890,18 @@ |
| 19808 | 19890 | } |
| 19809 | 19891 | if( N>0 ){ |
| 19810 | 19892 | sqlite3StrAccumAppend(pAccum, zSpaces, N); |
| 19811 | 19893 | } |
| 19812 | 19894 | } |
| 19895 | + |
| 19896 | +/* |
| 19897 | +** Set the StrAccum object to an error mode. |
| 19898 | +*/ |
| 19899 | +void setStrAccumError(StrAccum *p, u8 eError){ |
| 19900 | + p->accError = eError; |
| 19901 | + p->nAlloc = 0; |
| 19902 | +} |
| 19813 | 19903 | |
| 19814 | 19904 | /* |
| 19815 | 19905 | ** On machines with a small stack size, you can redefine the |
| 19816 | 19906 | ** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired. |
| 19817 | 19907 | */ |
| | @@ -20020,11 +20110,11 @@ |
| 20020 | 20110 | zOut = buf; |
| 20021 | 20111 | }else{ |
| 20022 | 20112 | nOut = precision + 10; |
| 20023 | 20113 | zOut = zExtra = sqlite3Malloc( nOut ); |
| 20024 | 20114 | if( zOut==0 ){ |
| 20025 | | - pAccum->accError = STRACCUM_NOMEM; |
| 20115 | + setStrAccumError(pAccum, STRACCUM_NOMEM); |
| 20026 | 20116 | return; |
| 20027 | 20117 | } |
| 20028 | 20118 | } |
| 20029 | 20119 | bufpt = &zOut[nOut-1]; |
| 20030 | 20120 | if( xtype==etORDINAL ){ |
| | @@ -20132,11 +20222,11 @@ |
| 20132 | 20222 | e2 = exp; |
| 20133 | 20223 | } |
| 20134 | 20224 | if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){ |
| 20135 | 20225 | bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 ); |
| 20136 | 20226 | if( bufpt==0 ){ |
| 20137 | | - pAccum->accError = STRACCUM_NOMEM; |
| 20227 | + setStrAccumError(pAccum, STRACCUM_NOMEM); |
| 20138 | 20228 | return; |
| 20139 | 20229 | } |
| 20140 | 20230 | } |
| 20141 | 20231 | zOut = bufpt; |
| 20142 | 20232 | nsd = 16 + flag_altform2*10; |
| | @@ -20267,11 +20357,11 @@ |
| 20267 | 20357 | needQuote = !isnull && xtype==etSQLESCAPE2; |
| 20268 | 20358 | n += i + 1 + needQuote*2; |
| 20269 | 20359 | if( n>etBUFSIZE ){ |
| 20270 | 20360 | bufpt = zExtra = sqlite3Malloc( n ); |
| 20271 | 20361 | if( bufpt==0 ){ |
| 20272 | | - pAccum->accError = STRACCUM_NOMEM; |
| 20362 | + setStrAccumError(pAccum, STRACCUM_NOMEM); |
| 20273 | 20363 | return; |
| 20274 | 20364 | } |
| 20275 | 20365 | }else{ |
| 20276 | 20366 | bufpt = buf; |
| 20277 | 20367 | } |
| | @@ -20290,11 +20380,11 @@ |
| 20290 | 20380 | ** if( precision>=0 && precision<length ) length = precision; */ |
| 20291 | 20381 | break; |
| 20292 | 20382 | } |
| 20293 | 20383 | case etTOKEN: { |
| 20294 | 20384 | Token *pToken = va_arg(ap, Token*); |
| 20295 | | - if( pToken ){ |
| 20385 | + if( pToken && pToken->n ){ |
| 20296 | 20386 | sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n); |
| 20297 | 20387 | } |
| 20298 | 20388 | length = width = 0; |
| 20299 | 20389 | break; |
| 20300 | 20390 | } |
| | @@ -20302,14 +20392,14 @@ |
| 20302 | 20392 | SrcList *pSrc = va_arg(ap, SrcList*); |
| 20303 | 20393 | int k = va_arg(ap, int); |
| 20304 | 20394 | struct SrcList_item *pItem = &pSrc->a[k]; |
| 20305 | 20395 | assert( k>=0 && k<pSrc->nSrc ); |
| 20306 | 20396 | if( pItem->zDatabase ){ |
| 20307 | | - sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1); |
| 20397 | + sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase); |
| 20308 | 20398 | sqlite3StrAccumAppend(pAccum, ".", 1); |
| 20309 | 20399 | } |
| 20310 | | - sqlite3StrAccumAppend(pAccum, pItem->zName, -1); |
| 20400 | + sqlite3StrAccumAppendAll(pAccum, pItem->zName); |
| 20311 | 20401 | length = width = 0; |
| 20312 | 20402 | break; |
| 20313 | 20403 | } |
| 20314 | 20404 | default: { |
| 20315 | 20405 | assert( xtype==etINVALID ); |
| | @@ -20344,36 +20434,34 @@ |
| 20344 | 20434 | |
| 20345 | 20435 | /* |
| 20346 | 20436 | ** Append N bytes of text from z to the StrAccum object. |
| 20347 | 20437 | */ |
| 20348 | 20438 | SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ |
| 20349 | | - assert( z!=0 || N==0 ); |
| 20350 | | - if( p->accError ){ |
| 20351 | | - testcase(p->accError==STRACCUM_TOOBIG); |
| 20352 | | - testcase(p->accError==STRACCUM_NOMEM); |
| 20353 | | - return; |
| 20354 | | - } |
| 20355 | | - assert( p->zText!=0 || p->nChar==0 ); |
| 20356 | | - if( N<=0 ){ |
| 20357 | | - if( N==0 || z[0]==0 ) return; |
| 20358 | | - N = sqlite3Strlen30(z); |
| 20359 | | - } |
| 20439 | + assert( z!=0 ); |
| 20440 | + assert( p->zText!=0 || p->nChar==0 || p->accError ); |
| 20441 | + assert( N>=0 ); |
| 20442 | + assert( p->accError==0 || p->nAlloc==0 ); |
| 20360 | 20443 | if( p->nChar+N >= p->nAlloc ){ |
| 20361 | 20444 | char *zNew; |
| 20445 | + if( p->accError ){ |
| 20446 | + testcase(p->accError==STRACCUM_TOOBIG); |
| 20447 | + testcase(p->accError==STRACCUM_NOMEM); |
| 20448 | + return; |
| 20449 | + } |
| 20362 | 20450 | if( !p->useMalloc ){ |
| 20363 | | - p->accError = STRACCUM_TOOBIG; |
| 20364 | 20451 | N = p->nAlloc - p->nChar - 1; |
| 20452 | + setStrAccumError(p, STRACCUM_TOOBIG); |
| 20365 | 20453 | if( N<=0 ){ |
| 20366 | 20454 | return; |
| 20367 | 20455 | } |
| 20368 | 20456 | }else{ |
| 20369 | 20457 | char *zOld = (p->zText==p->zBase ? 0 : p->zText); |
| 20370 | 20458 | i64 szNew = p->nChar; |
| 20371 | 20459 | szNew += N + 1; |
| 20372 | 20460 | if( szNew > p->mxAlloc ){ |
| 20373 | 20461 | sqlite3StrAccumReset(p); |
| 20374 | | - p->accError = STRACCUM_TOOBIG; |
| 20462 | + setStrAccumError(p, STRACCUM_TOOBIG); |
| 20375 | 20463 | return; |
| 20376 | 20464 | }else{ |
| 20377 | 20465 | p->nAlloc = (int)szNew; |
| 20378 | 20466 | } |
| 20379 | 20467 | if( p->useMalloc==1 ){ |
| | @@ -20383,20 +20471,28 @@ |
| 20383 | 20471 | } |
| 20384 | 20472 | if( zNew ){ |
| 20385 | 20473 | if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); |
| 20386 | 20474 | p->zText = zNew; |
| 20387 | 20475 | }else{ |
| 20388 | | - p->accError = STRACCUM_NOMEM; |
| 20389 | 20476 | sqlite3StrAccumReset(p); |
| 20477 | + setStrAccumError(p, STRACCUM_NOMEM); |
| 20390 | 20478 | return; |
| 20391 | 20479 | } |
| 20392 | 20480 | } |
| 20393 | 20481 | } |
| 20394 | 20482 | assert( p->zText ); |
| 20395 | 20483 | memcpy(&p->zText[p->nChar], z, N); |
| 20396 | 20484 | p->nChar += N; |
| 20397 | 20485 | } |
| 20486 | + |
| 20487 | +/* |
| 20488 | +** Append the complete text of zero-terminated string z[] to the p string. |
| 20489 | +*/ |
| 20490 | +SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ |
| 20491 | + sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z)); |
| 20492 | +} |
| 20493 | + |
| 20398 | 20494 | |
| 20399 | 20495 | /* |
| 20400 | 20496 | ** Finish off a string by making sure it is zero-terminated. |
| 20401 | 20497 | ** Return a pointer to the resulting string. Return a NULL |
| 20402 | 20498 | ** pointer if any kind of error was encountered. |
| | @@ -20411,11 +20507,11 @@ |
| 20411 | 20507 | p->zText = sqlite3_malloc(p->nChar+1); |
| 20412 | 20508 | } |
| 20413 | 20509 | if( p->zText ){ |
| 20414 | 20510 | memcpy(p->zText, p->zBase, p->nChar+1); |
| 20415 | 20511 | }else{ |
| 20416 | | - p->accError = STRACCUM_NOMEM; |
| 20512 | + setStrAccumError(p, STRACCUM_NOMEM); |
| 20417 | 20513 | } |
| 20418 | 20514 | } |
| 20419 | 20515 | } |
| 20420 | 20516 | return p->zText; |
| 20421 | 20517 | } |
| | @@ -21748,16 +21844,16 @@ |
| 21748 | 21844 | ** Convert zNum to a 64-bit signed integer. |
| 21749 | 21845 | ** |
| 21750 | 21846 | ** If the zNum value is representable as a 64-bit twos-complement |
| 21751 | 21847 | ** integer, then write that value into *pNum and return 0. |
| 21752 | 21848 | ** |
| 21753 | | -** If zNum is exactly 9223372036854665808, return 2. This special |
| 21754 | | -** case is broken out because while 9223372036854665808 cannot be a |
| 21755 | | -** signed 64-bit integer, its negative -9223372036854665808 can be. |
| 21849 | +** If zNum is exactly 9223372036854775808, return 2. This special |
| 21850 | +** case is broken out because while 9223372036854775808 cannot be a |
| 21851 | +** signed 64-bit integer, its negative -9223372036854775808 can be. |
| 21756 | 21852 | ** |
| 21757 | 21853 | ** If zNum is too big for a 64-bit integer and is not |
| 21758 | | -** 9223372036854665808 or if zNum contains any non-numeric text, |
| 21854 | +** 9223372036854775808 or if zNum contains any non-numeric text, |
| 21759 | 21855 | ** then return 1. |
| 21760 | 21856 | ** |
| 21761 | 21857 | ** length is the number of bytes in the string (bytes, not characters). |
| 21762 | 21858 | ** The string is not necessarily zero-terminated. The encoding is |
| 21763 | 21859 | ** given by enc. |
| | @@ -21795,11 +21891,11 @@ |
| 21795 | 21891 | while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */ |
| 21796 | 21892 | for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){ |
| 21797 | 21893 | u = u*10 + c - '0'; |
| 21798 | 21894 | } |
| 21799 | 21895 | if( u>LARGEST_INT64 ){ |
| 21800 | | - *pNum = SMALLEST_INT64; |
| 21896 | + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; |
| 21801 | 21897 | }else if( neg ){ |
| 21802 | 21898 | *pNum = -(i64)u; |
| 21803 | 21899 | }else{ |
| 21804 | 21900 | *pNum = (i64)u; |
| 21805 | 21901 | } |
| | @@ -21826,11 +21922,10 @@ |
| 21826 | 21922 | return 1; |
| 21827 | 21923 | }else{ |
| 21828 | 21924 | /* zNum is exactly 9223372036854775808. Fits if negative. The |
| 21829 | 21925 | ** special case 2 overflow if positive */ |
| 21830 | 21926 | assert( u-1==LARGEST_INT64 ); |
| 21831 | | - assert( (*pNum)==SMALLEST_INT64 ); |
| 21832 | 21927 | return neg ? 0 : 2; |
| 21833 | 21928 | } |
| 21834 | 21929 | } |
| 21835 | 21930 | } |
| 21836 | 21931 | |
| | @@ -22565,11 +22660,13 @@ |
| 22565 | 22660 | if( x<10 ) return 1; |
| 22566 | 22661 | n = x%10; |
| 22567 | 22662 | x /= 10; |
| 22568 | 22663 | if( n>=5 ) n -= 2; |
| 22569 | 22664 | else if( n>=1 ) n -= 1; |
| 22570 | | - if( x>=3 ) return (n+8)<<(x-3); |
| 22665 | + if( x>=3 ){ |
| 22666 | + return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3); |
| 22667 | + } |
| 22571 | 22668 | return (n+8)>>(3-x); |
| 22572 | 22669 | } |
| 22573 | 22670 | |
| 22574 | 22671 | /************** End of util.c ************************************************/ |
| 22575 | 22672 | /************** Begin file hash.c ********************************************/ |
| | @@ -22869,155 +22966,157 @@ |
| 22869 | 22966 | /* 1 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), |
| 22870 | 22967 | /* 2 */ "Savepoint" OpHelp(""), |
| 22871 | 22968 | /* 3 */ "AutoCommit" OpHelp(""), |
| 22872 | 22969 | /* 4 */ "Transaction" OpHelp(""), |
| 22873 | 22970 | /* 5 */ "SorterNext" OpHelp(""), |
| 22874 | | - /* 6 */ "Prev" OpHelp(""), |
| 22875 | | - /* 7 */ "Next" OpHelp(""), |
| 22876 | | - /* 8 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), |
| 22877 | | - /* 9 */ "Checkpoint" OpHelp(""), |
| 22878 | | - /* 10 */ "JournalMode" OpHelp(""), |
| 22879 | | - /* 11 */ "Vacuum" OpHelp(""), |
| 22880 | | - /* 12 */ "VFilter" OpHelp("iPlan=r[P3] zPlan='P4'"), |
| 22881 | | - /* 13 */ "VUpdate" OpHelp("data=r[P3@P2]"), |
| 22882 | | - /* 14 */ "Goto" OpHelp(""), |
| 22883 | | - /* 15 */ "Gosub" OpHelp(""), |
| 22884 | | - /* 16 */ "Return" OpHelp(""), |
| 22885 | | - /* 17 */ "Yield" OpHelp(""), |
| 22886 | | - /* 18 */ "HaltIfNull" OpHelp("if r[P3] null then halt"), |
| 22971 | + /* 6 */ "PrevIfOpen" OpHelp(""), |
| 22972 | + /* 7 */ "NextIfOpen" OpHelp(""), |
| 22973 | + /* 8 */ "Prev" OpHelp(""), |
| 22974 | + /* 9 */ "Next" OpHelp(""), |
| 22975 | + /* 10 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), |
| 22976 | + /* 11 */ "Checkpoint" OpHelp(""), |
| 22977 | + /* 12 */ "JournalMode" OpHelp(""), |
| 22978 | + /* 13 */ "Vacuum" OpHelp(""), |
| 22979 | + /* 14 */ "VFilter" OpHelp("iPlan=r[P3] zPlan='P4'"), |
| 22980 | + /* 15 */ "VUpdate" OpHelp("data=r[P3@P2]"), |
| 22981 | + /* 16 */ "Goto" OpHelp(""), |
| 22982 | + /* 17 */ "Gosub" OpHelp(""), |
| 22983 | + /* 18 */ "Return" OpHelp(""), |
| 22887 | 22984 | /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), |
| 22888 | | - /* 20 */ "Halt" OpHelp(""), |
| 22889 | | - /* 21 */ "Integer" OpHelp("r[P2]=P1"), |
| 22890 | | - /* 22 */ "Int64" OpHelp("r[P2]=P4"), |
| 22891 | | - /* 23 */ "String" OpHelp("r[P2]='P4' (len=P1)"), |
| 22892 | | - /* 24 */ "Null" OpHelp("r[P2..P3]=NULL"), |
| 22893 | | - /* 25 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), |
| 22894 | | - /* 26 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), |
| 22895 | | - /* 27 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), |
| 22896 | | - /* 28 */ "Copy" OpHelp("r[P2@P3]=r[P1@P3]"), |
| 22897 | | - /* 29 */ "SCopy" OpHelp("r[P2]=r[P1]"), |
| 22898 | | - /* 30 */ "ResultRow" OpHelp("output=r[P1@P2]"), |
| 22899 | | - /* 31 */ "CollSeq" OpHelp(""), |
| 22900 | | - /* 32 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), |
| 22901 | | - /* 33 */ "MustBeInt" OpHelp(""), |
| 22902 | | - /* 34 */ "RealAffinity" OpHelp(""), |
| 22903 | | - /* 35 */ "Permutation" OpHelp(""), |
| 22904 | | - /* 36 */ "Compare" OpHelp(""), |
| 22905 | | - /* 37 */ "Jump" OpHelp(""), |
| 22906 | | - /* 38 */ "Once" OpHelp(""), |
| 22907 | | - /* 39 */ "If" OpHelp(""), |
| 22908 | | - /* 40 */ "IfNot" OpHelp(""), |
| 22909 | | - /* 41 */ "Column" OpHelp("r[P3]=PX"), |
| 22910 | | - /* 42 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 22911 | | - /* 43 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 22912 | | - /* 44 */ "Count" OpHelp("r[P2]=count()"), |
| 22913 | | - /* 45 */ "ReadCookie" OpHelp(""), |
| 22914 | | - /* 46 */ "SetCookie" OpHelp(""), |
| 22915 | | - /* 47 */ "VerifyCookie" OpHelp(""), |
| 22916 | | - /* 48 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 22917 | | - /* 49 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 22918 | | - /* 50 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 22919 | | - /* 51 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 22920 | | - /* 52 */ "SorterOpen" OpHelp(""), |
| 22921 | | - /* 53 */ "OpenPseudo" OpHelp("content in r[P2@P3]"), |
| 22922 | | - /* 54 */ "Close" OpHelp(""), |
| 22923 | | - /* 55 */ "SeekLt" OpHelp("key=r[P3@P4]"), |
| 22924 | | - /* 56 */ "SeekLe" OpHelp("key=r[P3@P4]"), |
| 22925 | | - /* 57 */ "SeekGe" OpHelp("key=r[P3@P4]"), |
| 22926 | | - /* 58 */ "SeekGt" OpHelp("key=r[P3@P4]"), |
| 22927 | | - /* 59 */ "Seek" OpHelp("intkey=r[P2]"), |
| 22928 | | - /* 60 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 22929 | | - /* 61 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 22930 | | - /* 62 */ "Found" OpHelp("key=r[P3@P4]"), |
| 22931 | | - /* 63 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 22932 | | - /* 64 */ "Sequence" OpHelp("r[P2]=rowid"), |
| 22933 | | - /* 65 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 22934 | | - /* 66 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 22935 | | - /* 67 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| 22936 | | - /* 68 */ "Delete" OpHelp(""), |
| 22985 | + /* 20 */ "Yield" OpHelp(""), |
| 22986 | + /* 21 */ "HaltIfNull" OpHelp("if r[P3] null then halt"), |
| 22987 | + /* 22 */ "Halt" OpHelp(""), |
| 22988 | + /* 23 */ "Integer" OpHelp("r[P2]=P1"), |
| 22989 | + /* 24 */ "Int64" OpHelp("r[P2]=P4"), |
| 22990 | + /* 25 */ "String" OpHelp("r[P2]='P4' (len=P1)"), |
| 22991 | + /* 26 */ "Null" OpHelp("r[P2..P3]=NULL"), |
| 22992 | + /* 27 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), |
| 22993 | + /* 28 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), |
| 22994 | + /* 29 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), |
| 22995 | + /* 30 */ "Copy" OpHelp("r[P2@P3]=r[P1@P3]"), |
| 22996 | + /* 31 */ "SCopy" OpHelp("r[P2]=r[P1]"), |
| 22997 | + /* 32 */ "ResultRow" OpHelp("output=r[P1@P2]"), |
| 22998 | + /* 33 */ "CollSeq" OpHelp(""), |
| 22999 | + /* 34 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), |
| 23000 | + /* 35 */ "MustBeInt" OpHelp(""), |
| 23001 | + /* 36 */ "RealAffinity" OpHelp(""), |
| 23002 | + /* 37 */ "Permutation" OpHelp(""), |
| 23003 | + /* 38 */ "Compare" OpHelp(""), |
| 23004 | + /* 39 */ "Jump" OpHelp(""), |
| 23005 | + /* 40 */ "Once" OpHelp(""), |
| 23006 | + /* 41 */ "If" OpHelp(""), |
| 23007 | + /* 42 */ "IfNot" OpHelp(""), |
| 23008 | + /* 43 */ "Column" OpHelp("r[P3]=PX"), |
| 23009 | + /* 44 */ "Affinity" OpHelp("affinity(r[P1@P2])"), |
| 23010 | + /* 45 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), |
| 23011 | + /* 46 */ "Count" OpHelp("r[P2]=count()"), |
| 23012 | + /* 47 */ "ReadCookie" OpHelp(""), |
| 23013 | + /* 48 */ "SetCookie" OpHelp(""), |
| 23014 | + /* 49 */ "VerifyCookie" OpHelp(""), |
| 23015 | + /* 50 */ "OpenRead" OpHelp("root=P2 iDb=P3"), |
| 23016 | + /* 51 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), |
| 23017 | + /* 52 */ "OpenAutoindex" OpHelp("nColumn=P2"), |
| 23018 | + /* 53 */ "OpenEphemeral" OpHelp("nColumn=P2"), |
| 23019 | + /* 54 */ "SorterOpen" OpHelp(""), |
| 23020 | + /* 55 */ "OpenPseudo" OpHelp("content in r[P2@P3]"), |
| 23021 | + /* 56 */ "Close" OpHelp(""), |
| 23022 | + /* 57 */ "SeekLt" OpHelp("key=r[P3@P4]"), |
| 23023 | + /* 58 */ "SeekLe" OpHelp("key=r[P3@P4]"), |
| 23024 | + /* 59 */ "SeekGe" OpHelp("key=r[P3@P4]"), |
| 23025 | + /* 60 */ "SeekGt" OpHelp("key=r[P3@P4]"), |
| 23026 | + /* 61 */ "Seek" OpHelp("intkey=r[P2]"), |
| 23027 | + /* 62 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 23028 | + /* 63 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 23029 | + /* 64 */ "Found" OpHelp("key=r[P3@P4]"), |
| 23030 | + /* 65 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 23031 | + /* 66 */ "Sequence" OpHelp("r[P2]=rowid"), |
| 23032 | + /* 67 */ "NewRowid" OpHelp("r[P2]=rowid"), |
| 23033 | + /* 68 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), |
| 22937 | 23034 | /* 69 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 22938 | 23035 | /* 70 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 22939 | | - /* 71 */ "ResetCount" OpHelp(""), |
| 22940 | | - /* 72 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"), |
| 22941 | | - /* 73 */ "SorterData" OpHelp("r[P2]=data"), |
| 23036 | + /* 71 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), |
| 23037 | + /* 72 */ "Delete" OpHelp(""), |
| 23038 | + /* 73 */ "ResetCount" OpHelp(""), |
| 22942 | 23039 | /* 74 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 22943 | 23040 | /* 75 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 22944 | 23041 | /* 76 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"), |
| 22945 | 23042 | /* 77 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"), |
| 22946 | 23043 | /* 78 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"), |
| 22947 | 23044 | /* 79 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"), |
| 22948 | | - /* 80 */ "Lt" OpHelp("if r[P1]<r[P3] goto P3"), |
| 23045 | + /* 80 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"), |
| 22949 | 23046 | /* 81 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"), |
| 22950 | | - /* 82 */ "RowKey" OpHelp("r[P2]=key"), |
| 23047 | + /* 82 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"), |
| 22951 | 23048 | /* 83 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), |
| 22952 | 23049 | /* 84 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), |
| 22953 | 23050 | /* 85 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), |
| 22954 | 23051 | /* 86 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), |
| 22955 | 23052 | /* 87 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), |
| 22956 | 23053 | /* 88 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), |
| 22957 | 23054 | /* 89 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), |
| 22958 | | - /* 90 */ "Divide" OpHelp("r[P3]=r[P1]/r[P2]"), |
| 22959 | | - /* 91 */ "Remainder" OpHelp("r[P3]=r[P1]%r[P2]"), |
| 23055 | + /* 90 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), |
| 23056 | + /* 91 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), |
| 22960 | 23057 | /* 92 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), |
| 22961 | | - /* 93 */ "RowData" OpHelp("r[P2]=data"), |
| 23058 | + /* 93 */ "SorterData" OpHelp("r[P2]=data"), |
| 22962 | 23059 | /* 94 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), |
| 22963 | 23060 | /* 95 */ "String8" OpHelp("r[P2]='P4'"), |
| 22964 | | - /* 96 */ "Rowid" OpHelp("r[P2]=rowid"), |
| 22965 | | - /* 97 */ "NullRow" OpHelp(""), |
| 22966 | | - /* 98 */ "Last" OpHelp(""), |
| 22967 | | - /* 99 */ "SorterSort" OpHelp(""), |
| 22968 | | - /* 100 */ "Sort" OpHelp(""), |
| 22969 | | - /* 101 */ "Rewind" OpHelp(""), |
| 22970 | | - /* 102 */ "SorterInsert" OpHelp(""), |
| 22971 | | - /* 103 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 22972 | | - /* 104 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 22973 | | - /* 105 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 22974 | | - /* 106 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 22975 | | - /* 107 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 22976 | | - /* 108 */ "Destroy" OpHelp(""), |
| 22977 | | - /* 109 */ "Clear" OpHelp(""), |
| 22978 | | - /* 110 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 22979 | | - /* 111 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 22980 | | - /* 112 */ "ParseSchema" OpHelp(""), |
| 22981 | | - /* 113 */ "LoadAnalysis" OpHelp(""), |
| 22982 | | - /* 114 */ "DropTable" OpHelp(""), |
| 22983 | | - /* 115 */ "DropIndex" OpHelp(""), |
| 22984 | | - /* 116 */ "DropTrigger" OpHelp(""), |
| 22985 | | - /* 117 */ "IntegrityCk" OpHelp(""), |
| 22986 | | - /* 118 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 22987 | | - /* 119 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 22988 | | - /* 120 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 22989 | | - /* 121 */ "Program" OpHelp(""), |
| 22990 | | - /* 122 */ "Param" OpHelp(""), |
| 22991 | | - /* 123 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 22992 | | - /* 124 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 22993 | | - /* 125 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 22994 | | - /* 126 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 22995 | | - /* 127 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 22996 | | - /* 128 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 22997 | | - /* 129 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 22998 | | - /* 130 */ "IncrVacuum" OpHelp(""), |
| 23061 | + /* 96 */ "RowKey" OpHelp("r[P2]=key"), |
| 23062 | + /* 97 */ "RowData" OpHelp("r[P2]=data"), |
| 23063 | + /* 98 */ "Rowid" OpHelp("r[P2]=rowid"), |
| 23064 | + /* 99 */ "NullRow" OpHelp(""), |
| 23065 | + /* 100 */ "Last" OpHelp(""), |
| 23066 | + /* 101 */ "SorterSort" OpHelp(""), |
| 23067 | + /* 102 */ "Sort" OpHelp(""), |
| 23068 | + /* 103 */ "Rewind" OpHelp(""), |
| 23069 | + /* 104 */ "SorterInsert" OpHelp(""), |
| 23070 | + /* 105 */ "IdxInsert" OpHelp("key=r[P2]"), |
| 23071 | + /* 106 */ "IdxDelete" OpHelp("key=r[P2@P3]"), |
| 23072 | + /* 107 */ "IdxRowid" OpHelp("r[P2]=rowid"), |
| 23073 | + /* 108 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 23074 | + /* 109 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 23075 | + /* 110 */ "Destroy" OpHelp(""), |
| 23076 | + /* 111 */ "Clear" OpHelp(""), |
| 23077 | + /* 112 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"), |
| 23078 | + /* 113 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"), |
| 23079 | + /* 114 */ "ParseSchema" OpHelp(""), |
| 23080 | + /* 115 */ "LoadAnalysis" OpHelp(""), |
| 23081 | + /* 116 */ "DropTable" OpHelp(""), |
| 23082 | + /* 117 */ "DropIndex" OpHelp(""), |
| 23083 | + /* 118 */ "DropTrigger" OpHelp(""), |
| 23084 | + /* 119 */ "IntegrityCk" OpHelp(""), |
| 23085 | + /* 120 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), |
| 23086 | + /* 121 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 23087 | + /* 122 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 23088 | + /* 123 */ "Program" OpHelp(""), |
| 23089 | + /* 124 */ "Param" OpHelp(""), |
| 23090 | + /* 125 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), |
| 23091 | + /* 126 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 23092 | + /* 127 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), |
| 23093 | + /* 128 */ "IfPos" OpHelp("if r[P1]>0 goto P2"), |
| 23094 | + /* 129 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"), |
| 23095 | + /* 130 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"), |
| 22999 | 23096 | /* 131 */ "Real" OpHelp("r[P2]=P4"), |
| 23000 | | - /* 132 */ "Expire" OpHelp(""), |
| 23001 | | - /* 133 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 23002 | | - /* 134 */ "VBegin" OpHelp(""), |
| 23003 | | - /* 135 */ "VCreate" OpHelp(""), |
| 23004 | | - /* 136 */ "VDestroy" OpHelp(""), |
| 23005 | | - /* 137 */ "VOpen" OpHelp(""), |
| 23006 | | - /* 138 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 23007 | | - /* 139 */ "VNext" OpHelp(""), |
| 23008 | | - /* 140 */ "VRename" OpHelp(""), |
| 23009 | | - /* 141 */ "Pagecount" OpHelp(""), |
| 23097 | + /* 132 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), |
| 23098 | + /* 133 */ "IncrVacuum" OpHelp(""), |
| 23099 | + /* 134 */ "Expire" OpHelp(""), |
| 23100 | + /* 135 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), |
| 23101 | + /* 136 */ "VBegin" OpHelp(""), |
| 23102 | + /* 137 */ "VCreate" OpHelp(""), |
| 23103 | + /* 138 */ "VDestroy" OpHelp(""), |
| 23104 | + /* 139 */ "VOpen" OpHelp(""), |
| 23105 | + /* 140 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), |
| 23106 | + /* 141 */ "VNext" OpHelp(""), |
| 23010 | 23107 | /* 142 */ "ToText" OpHelp(""), |
| 23011 | 23108 | /* 143 */ "ToBlob" OpHelp(""), |
| 23012 | 23109 | /* 144 */ "ToNumeric" OpHelp(""), |
| 23013 | 23110 | /* 145 */ "ToInt" OpHelp(""), |
| 23014 | 23111 | /* 146 */ "ToReal" OpHelp(""), |
| 23015 | | - /* 147 */ "MaxPgcnt" OpHelp(""), |
| 23016 | | - /* 148 */ "Trace" OpHelp(""), |
| 23017 | | - /* 149 */ "Noop" OpHelp(""), |
| 23018 | | - /* 150 */ "Explain" OpHelp(""), |
| 23112 | + /* 147 */ "VRename" OpHelp(""), |
| 23113 | + /* 148 */ "Pagecount" OpHelp(""), |
| 23114 | + /* 149 */ "MaxPgcnt" OpHelp(""), |
| 23115 | + /* 150 */ "Trace" OpHelp(""), |
| 23116 | + /* 151 */ "Noop" OpHelp(""), |
| 23117 | + /* 152 */ "Explain" OpHelp(""), |
| 23019 | 23118 | }; |
| 23020 | 23119 | return azName[i]; |
| 23021 | 23120 | } |
| 23022 | 23121 | #endif |
| 23023 | 23122 | |
| | @@ -24545,10 +24644,19 @@ |
| 24545 | 24644 | } |
| 24546 | 24645 | *ppInode = pInode; |
| 24547 | 24646 | return SQLITE_OK; |
| 24548 | 24647 | } |
| 24549 | 24648 | |
| 24649 | +/* |
| 24650 | +** Return TRUE if pFile has been renamed or unlinked since it was first opened. |
| 24651 | +*/ |
| 24652 | +static int fileHasMoved(unixFile *pFile){ |
| 24653 | + struct stat buf; |
| 24654 | + return pFile->pInode!=0 && |
| 24655 | + (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino); |
| 24656 | +} |
| 24657 | + |
| 24550 | 24658 | |
| 24551 | 24659 | /* |
| 24552 | 24660 | ** Check a unixFile that is a database. Verify the following: |
| 24553 | 24661 | ** |
| 24554 | 24662 | ** (1) There is exactly one hard link on the file |
| | @@ -24579,14 +24687,11 @@ |
| 24579 | 24687 | if( buf.st_nlink>1 ){ |
| 24580 | 24688 | sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); |
| 24581 | 24689 | pFile->ctrlFlags |= UNIXFILE_WARNED; |
| 24582 | 24690 | return; |
| 24583 | 24691 | } |
| 24584 | | - if( pFile->pInode!=0 |
| 24585 | | - && ((rc = osStat(pFile->zPath, &buf))!=0 |
| 24586 | | - || buf.st_ino!=pFile->pInode->fileId.ino) |
| 24587 | | - ){ |
| 24692 | + if( fileHasMoved(pFile) ){ |
| 24588 | 24693 | sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); |
| 24589 | 24694 | pFile->ctrlFlags |= UNIXFILE_WARNED; |
| 24590 | 24695 | return; |
| 24591 | 24696 | } |
| 24592 | 24697 | } |
| | @@ -27030,10 +27135,14 @@ |
| 27030 | 27135 | if( zTFile ){ |
| 27031 | 27136 | unixGetTempname(pFile->pVfs->mxPathname, zTFile); |
| 27032 | 27137 | *(char**)pArg = zTFile; |
| 27033 | 27138 | } |
| 27034 | 27139 | return SQLITE_OK; |
| 27140 | + } |
| 27141 | + case SQLITE_FCNTL_HAS_MOVED: { |
| 27142 | + *(int*)pArg = fileHasMoved(pFile); |
| 27143 | + return SQLITE_OK; |
| 27035 | 27144 | } |
| 27036 | 27145 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 27037 | 27146 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 27038 | 27147 | i64 newLimit = *(i64*)pArg; |
| 27039 | 27148 | int rc = SQLITE_OK; |
| | @@ -27311,11 +27420,11 @@ |
| 27311 | 27420 | |
| 27312 | 27421 | /* Update the global lock state and do debug tracing */ |
| 27313 | 27422 | #ifdef SQLITE_DEBUG |
| 27314 | 27423 | { u16 mask; |
| 27315 | 27424 | OSTRACE(("SHM-LOCK ")); |
| 27316 | | - mask = (1<<(ofst+n)) - (1<<ofst); |
| 27425 | + mask = ofst>31 ? 0xffffffff : (1<<(ofst+n)) - (1<<ofst); |
| 27317 | 27426 | if( rc==SQLITE_OK ){ |
| 27318 | 27427 | if( lockType==F_UNLCK ){ |
| 27319 | 27428 | OSTRACE(("unlock %d ok", ofst)); |
| 27320 | 27429 | pShmNode->exclMask &= ~mask; |
| 27321 | 27430 | pShmNode->sharedMask &= ~mask; |
| | @@ -30947,10 +31056,38 @@ |
| 30947 | 31056 | #if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) |
| 30948 | 31057 | # error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ |
| 30949 | 31058 | must be defined." |
| 30950 | 31059 | #endif |
| 30951 | 31060 | |
| 31061 | +/* |
| 31062 | +** Define the required Windows SDK version constants if they are not |
| 31063 | +** already available. |
| 31064 | +*/ |
| 31065 | +#ifndef NTDDI_WIN8 |
| 31066 | +# define NTDDI_WIN8 0x06020000 |
| 31067 | +#endif |
| 31068 | + |
| 31069 | +#ifndef NTDDI_WINBLUE |
| 31070 | +# define NTDDI_WINBLUE 0x06030000 |
| 31071 | +#endif |
| 31072 | + |
| 31073 | +/* |
| 31074 | +** Check if the GetVersionEx[AW] functions should be considered deprecated |
| 31075 | +** and avoid using them in that case. It should be noted here that if the |
| 31076 | +** value of the SQLITE_WIN32_GETVERSIONEX pre-processor macro is zero |
| 31077 | +** (whether via this block or via being manually specified), that implies |
| 31078 | +** the underlying operating system will always be based on the Windows NT |
| 31079 | +** Kernel. |
| 31080 | +*/ |
| 31081 | +#ifndef SQLITE_WIN32_GETVERSIONEX |
| 31082 | +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE |
| 31083 | +# define SQLITE_WIN32_GETVERSIONEX 0 |
| 31084 | +# else |
| 31085 | +# define SQLITE_WIN32_GETVERSIONEX 1 |
| 31086 | +# endif |
| 31087 | +#endif |
| 31088 | + |
| 30952 | 31089 | /* |
| 30953 | 31090 | ** This constant should already be defined (in the "WinDef.h" SDK file). |
| 30954 | 31091 | */ |
| 30955 | 31092 | #ifndef MAX_PATH |
| 30956 | 31093 | # define MAX_PATH (260) |
| | @@ -31582,20 +31719,22 @@ |
| 31582 | 31719 | { "GetTickCount", (SYSCALL)0, 0 }, |
| 31583 | 31720 | #endif |
| 31584 | 31721 | |
| 31585 | 31722 | #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) |
| 31586 | 31723 | |
| 31587 | | -#if defined(SQLITE_WIN32_HAS_ANSI) |
| 31724 | +#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \ |
| 31725 | + SQLITE_WIN32_GETVERSIONEX |
| 31588 | 31726 | { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, |
| 31589 | 31727 | #else |
| 31590 | 31728 | { "GetVersionExA", (SYSCALL)0, 0 }, |
| 31591 | 31729 | #endif |
| 31592 | 31730 | |
| 31593 | 31731 | #define osGetVersionExA ((BOOL(WINAPI*)( \ |
| 31594 | 31732 | LPOSVERSIONINFOA))aSyscall[34].pCurrent) |
| 31595 | 31733 | |
| 31596 | | -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 31734 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ |
| 31735 | + defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX |
| 31597 | 31736 | { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, |
| 31598 | 31737 | #else |
| 31599 | 31738 | { "GetVersionExW", (SYSCALL)0, 0 }, |
| 31600 | 31739 | #endif |
| 31601 | 31740 | |
| | @@ -32148,15 +32287,14 @@ |
| 32148 | 32287 | ** API as long as we don't call it when running Win95/98/ME. A call to |
| 32149 | 32288 | ** this routine is used to determine if the host is Win95/98/ME or |
| 32150 | 32289 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 32151 | 32290 | ** the LockFileEx() API. |
| 32152 | 32291 | */ |
| 32153 | | -#ifndef NTDDI_WIN8 |
| 32154 | | -# define NTDDI_WIN8 0x06020000 |
| 32155 | | -#endif |
| 32156 | 32292 | |
| 32157 | | -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 32293 | +#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX |
| 32294 | +# define osIsNT() (1) |
| 32295 | +#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 32158 | 32296 | # define osIsNT() (1) |
| 32159 | 32297 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 32160 | 32298 | # define osIsNT() (0) |
| 32161 | 32299 | #else |
| 32162 | 32300 | static int osIsNT(void){ |
| | @@ -32289,18 +32427,24 @@ |
| 32289 | 32427 | assert( pWinMemData->magic1==WINMEM_MAGIC1 ); |
| 32290 | 32428 | assert( pWinMemData->magic2==WINMEM_MAGIC2 ); |
| 32291 | 32429 | |
| 32292 | 32430 | #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE |
| 32293 | 32431 | if( !pWinMemData->hHeap ){ |
| 32432 | + DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; |
| 32433 | + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; |
| 32434 | + if( dwMaximumSize==0 ){ |
| 32435 | + dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; |
| 32436 | + }else if( dwInitialSize>dwMaximumSize ){ |
| 32437 | + dwInitialSize = dwMaximumSize; |
| 32438 | + } |
| 32294 | 32439 | pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, |
| 32295 | | - SQLITE_WIN32_HEAP_INIT_SIZE, |
| 32296 | | - SQLITE_WIN32_HEAP_MAX_SIZE); |
| 32440 | + dwInitialSize, dwMaximumSize); |
| 32297 | 32441 | if( !pWinMemData->hHeap ){ |
| 32298 | 32442 | sqlite3_log(SQLITE_NOMEM, |
| 32299 | | - "failed to HeapCreate (%lu), flags=%u, initSize=%u, maxSize=%u", |
| 32300 | | - osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, |
| 32301 | | - SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); |
| 32443 | + "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", |
| 32444 | + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, |
| 32445 | + dwMaximumSize); |
| 32302 | 32446 | return SQLITE_NOMEM; |
| 32303 | 32447 | } |
| 32304 | 32448 | pWinMemData->bOwned = TRUE; |
| 32305 | 32449 | assert( pWinMemData->bOwned ); |
| 32306 | 32450 | } |
| | @@ -33972,11 +34116,11 @@ |
| 33972 | 34116 | winModeBit(pFile, WINFILE_PSOW, (int*)pArg); |
| 33973 | 34117 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33974 | 34118 | return SQLITE_OK; |
| 33975 | 34119 | } |
| 33976 | 34120 | case SQLITE_FCNTL_VFSNAME: { |
| 33977 | | - *(char**)pArg = sqlite3_mprintf("win32"); |
| 34121 | + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); |
| 33978 | 34122 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33979 | 34123 | return SQLITE_OK; |
| 33980 | 34124 | } |
| 33981 | 34125 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33982 | 34126 | int *a = (int*)pArg; |
| | @@ -34956,11 +35100,11 @@ |
| 34956 | 35100 | ** |
| 34957 | 35101 | ** This division contains the implementation of methods on the |
| 34958 | 35102 | ** sqlite3_vfs object. |
| 34959 | 35103 | */ |
| 34960 | 35104 | |
| 34961 | | -#if 0 |
| 35105 | +#if defined(__CYGWIN__) |
| 34962 | 35106 | /* |
| 34963 | 35107 | ** Convert a filename from whatever the underlying operating system |
| 34964 | 35108 | ** supports for filenames into UTF-8. Space to hold the result is |
| 34965 | 35109 | ** obtained from malloc and must be freed by the calling function. |
| 34966 | 35110 | */ |
| | @@ -35132,27 +35276,21 @@ |
| 35132 | 35276 | if( winIsDir(zConverted) ){ |
| 35133 | 35277 | /* At this point, we know the candidate directory exists and should |
| 35134 | 35278 | ** be used. However, we may need to convert the string containing |
| 35135 | 35279 | ** its name into UTF-8 (i.e. if it is UTF-16 right now). |
| 35136 | 35280 | */ |
| 35137 | | - if( osIsNT() ){ |
| 35138 | | - char *zUtf8 = winUnicodeToUtf8(zConverted); |
| 35139 | | - if( !zUtf8 ){ |
| 35140 | | - sqlite3_free(zConverted); |
| 35141 | | - sqlite3_free(zBuf); |
| 35142 | | - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 35143 | | - return SQLITE_IOERR_NOMEM; |
| 35144 | | - } |
| 35145 | | - sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); |
| 35146 | | - sqlite3_free(zUtf8); |
| 35147 | | - sqlite3_free(zConverted); |
| 35148 | | - break; |
| 35149 | | - }else{ |
| 35150 | | - sqlite3_snprintf(nMax, zBuf, "%s", zConverted); |
| 35151 | | - sqlite3_free(zConverted); |
| 35152 | | - break; |
| 35153 | | - } |
| 35281 | + char *zUtf8 = winConvertToUtf8Filename(zConverted); |
| 35282 | + if( !zUtf8 ){ |
| 35283 | + sqlite3_free(zConverted); |
| 35284 | + sqlite3_free(zBuf); |
| 35285 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 35286 | + return SQLITE_IOERR_NOMEM; |
| 35287 | + } |
| 35288 | + sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); |
| 35289 | + sqlite3_free(zUtf8); |
| 35290 | + sqlite3_free(zConverted); |
| 35291 | + break; |
| 35154 | 35292 | } |
| 35155 | 35293 | sqlite3_free(zConverted); |
| 35156 | 35294 | } |
| 35157 | 35295 | } |
| 35158 | 35296 | } |
| | @@ -35833,23 +35971,47 @@ |
| 35833 | 35971 | */ |
| 35834 | 35972 | char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35835 | 35973 | if( !zOut ){ |
| 35836 | 35974 | return SQLITE_IOERR_NOMEM; |
| 35837 | 35975 | } |
| 35838 | | - if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35839 | | - pVfs->mxPathname+1)<0 ){ |
| 35976 | + if( cygwin_conv_path( |
| 35977 | + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | |
| 35978 | + CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ |
| 35840 | 35979 | sqlite3_free(zOut); |
| 35841 | 35980 | return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 35842 | 35981 | "winFullPathname1", zRelative); |
| 35982 | + }else{ |
| 35983 | + char *zUtf8 = winConvertToUtf8Filename(zOut); |
| 35984 | + if( !zUtf8 ){ |
| 35985 | + sqlite3_free(zOut); |
| 35986 | + return SQLITE_IOERR_NOMEM; |
| 35987 | + } |
| 35988 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 35989 | + sqlite3_data_directory, winGetDirSep(), zUtf8); |
| 35990 | + sqlite3_free(zUtf8); |
| 35991 | + sqlite3_free(zOut); |
| 35843 | 35992 | } |
| 35844 | | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 35845 | | - sqlite3_data_directory, winGetDirSep(), zOut); |
| 35846 | | - sqlite3_free(zOut); |
| 35847 | 35993 | }else{ |
| 35848 | | - if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35994 | + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35995 | + if( !zOut ){ |
| 35996 | + return SQLITE_IOERR_NOMEM; |
| 35997 | + } |
| 35998 | + if( cygwin_conv_path( |
| 35999 | + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), |
| 36000 | + zRelative, zOut, pVfs->mxPathname+1)<0 ){ |
| 36001 | + sqlite3_free(zOut); |
| 35849 | 36002 | return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 35850 | 36003 | "winFullPathname2", zRelative); |
| 36004 | + }else{ |
| 36005 | + char *zUtf8 = winConvertToUtf8Filename(zOut); |
| 36006 | + if( !zUtf8 ){ |
| 36007 | + sqlite3_free(zOut); |
| 36008 | + return SQLITE_IOERR_NOMEM; |
| 36009 | + } |
| 36010 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); |
| 36011 | + sqlite3_free(zUtf8); |
| 36012 | + sqlite3_free(zOut); |
| 35851 | 36013 | } |
| 35852 | 36014 | } |
| 35853 | 36015 | return SQLITE_OK; |
| 35854 | 36016 | #endif |
| 35855 | 36017 | |
| | @@ -43770,10 +43932,34 @@ |
| 43770 | 43932 | *ppPager = pPager; |
| 43771 | 43933 | return SQLITE_OK; |
| 43772 | 43934 | } |
| 43773 | 43935 | |
| 43774 | 43936 | |
| 43937 | +/* Verify that the database file has not be deleted or renamed out from |
| 43938 | +** under the pager. Return SQLITE_OK if the database is still were it ought |
| 43939 | +** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error |
| 43940 | +** code from sqlite3OsAccess()) if the database has gone missing. |
| 43941 | +*/ |
| 43942 | +static int databaseIsUnmoved(Pager *pPager){ |
| 43943 | + int bHasMoved = 0; |
| 43944 | + int rc; |
| 43945 | + |
| 43946 | + if( pPager->tempFile ) return SQLITE_OK; |
| 43947 | + if( pPager->dbSize==0 ) return SQLITE_OK; |
| 43948 | + assert( pPager->zFilename && pPager->zFilename[0] ); |
| 43949 | + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); |
| 43950 | + if( rc==SQLITE_NOTFOUND ){ |
| 43951 | + /* If the HAS_MOVED file-control is unimplemented, assume that the file |
| 43952 | + ** has not been moved. That is the historical behavior of SQLite: prior to |
| 43953 | + ** version 3.8.3, it never checked */ |
| 43954 | + rc = SQLITE_OK; |
| 43955 | + }else if( rc==SQLITE_OK && bHasMoved ){ |
| 43956 | + rc = SQLITE_READONLY_DBMOVED; |
| 43957 | + } |
| 43958 | + return rc; |
| 43959 | +} |
| 43960 | + |
| 43775 | 43961 | |
| 43776 | 43962 | /* |
| 43777 | 43963 | ** This function is called after transitioning from PAGER_UNLOCK to |
| 43778 | 43964 | ** PAGER_SHARED state. It tests if there is a hot journal present in |
| 43779 | 43965 | ** the file-system for the given pager. A hot journal is one that |
| | @@ -44241,11 +44427,11 @@ |
| 44241 | 44427 | if( bMmapOk && pagerUseWal(pPager) ){ |
| 44242 | 44428 | rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); |
| 44243 | 44429 | if( rc!=SQLITE_OK ) goto pager_acquire_err; |
| 44244 | 44430 | } |
| 44245 | 44431 | |
| 44246 | | - if( iFrame==0 && bMmapOk ){ |
| 44432 | + if( bMmapOk && iFrame==0 ){ |
| 44247 | 44433 | void *pData = 0; |
| 44248 | 44434 | |
| 44249 | 44435 | rc = sqlite3OsFetch(pPager->fd, |
| 44250 | 44436 | (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData |
| 44251 | 44437 | ); |
| | @@ -44446,17 +44632,23 @@ |
| 44446 | 44632 | SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| |
| 44447 | 44633 | (pPager->tempFile ? |
| 44448 | 44634 | (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): |
| 44449 | 44635 | (SQLITE_OPEN_MAIN_JOURNAL) |
| 44450 | 44636 | ); |
| 44451 | | - #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 44452 | | - rc = sqlite3JournalOpen( |
| 44453 | | - pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) |
| 44454 | | - ); |
| 44455 | | - #else |
| 44456 | | - rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); |
| 44457 | | - #endif |
| 44637 | + |
| 44638 | + /* Verify that the database still has the same name as it did when |
| 44639 | + ** it was originally opened. */ |
| 44640 | + rc = databaseIsUnmoved(pPager); |
| 44641 | + if( rc==SQLITE_OK ){ |
| 44642 | +#ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 44643 | + rc = sqlite3JournalOpen( |
| 44644 | + pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager) |
| 44645 | + ); |
| 44646 | +#else |
| 44647 | + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); |
| 44648 | +#endif |
| 44649 | + } |
| 44458 | 44650 | } |
| 44459 | 44651 | assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); |
| 44460 | 44652 | } |
| 44461 | 44653 | |
| 44462 | 44654 | |
| | @@ -44586,18 +44778,12 @@ |
| 44586 | 44778 | assert( pPager->eState==PAGER_WRITER_LOCKED |
| 44587 | 44779 | || pPager->eState==PAGER_WRITER_CACHEMOD |
| 44588 | 44780 | || pPager->eState==PAGER_WRITER_DBMOD |
| 44589 | 44781 | ); |
| 44590 | 44782 | assert( assert_pager_state(pPager) ); |
| 44591 | | - |
| 44592 | | - /* If an error has been previously detected, report the same error |
| 44593 | | - ** again. This should not happen, but the check provides robustness. */ |
| 44594 | | - if( NEVER(pPager->errCode) ) return pPager->errCode; |
| 44595 | | - |
| 44596 | | - /* Higher-level routines never call this function if database is not |
| 44597 | | - ** writable. But check anyway, just for robustness. */ |
| 44598 | | - if( NEVER(pPager->readOnly) ) return SQLITE_PERM; |
| 44783 | + assert( pPager->errCode==0 ); |
| 44784 | + assert( pPager->readOnly==0 ); |
| 44599 | 44785 | |
| 44600 | 44786 | CHECK_PAGE(pPg); |
| 44601 | 44787 | |
| 44602 | 44788 | /* The journal file needs to be opened. Higher level routines have already |
| 44603 | 44789 | ** obtained the necessary locks to begin the write-transaction, but the |
| | @@ -44722,23 +44908,23 @@ |
| 44722 | 44908 | SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ |
| 44723 | 44909 | int rc = SQLITE_OK; |
| 44724 | 44910 | |
| 44725 | 44911 | PgHdr *pPg = pDbPage; |
| 44726 | 44912 | Pager *pPager = pPg->pPager; |
| 44727 | | - Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
| 44728 | 44913 | |
| 44729 | 44914 | assert( (pPg->flags & PGHDR_MMAP)==0 ); |
| 44730 | 44915 | assert( pPager->eState>=PAGER_WRITER_LOCKED ); |
| 44731 | 44916 | assert( pPager->eState!=PAGER_ERROR ); |
| 44732 | 44917 | assert( assert_pager_state(pPager) ); |
| 44733 | 44918 | |
| 44734 | | - if( nPagePerSector>1 ){ |
| 44919 | + if( pPager->sectorSize > (u32)pPager->pageSize ){ |
| 44735 | 44920 | Pgno nPageCount; /* Total number of pages in database file */ |
| 44736 | 44921 | Pgno pg1; /* First page of the sector pPg is located on. */ |
| 44737 | 44922 | int nPage = 0; /* Number of pages starting at pg1 to journal */ |
| 44738 | 44923 | int ii; /* Loop counter */ |
| 44739 | 44924 | int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ |
| 44925 | + Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
| 44740 | 44926 | |
| 44741 | 44927 | /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow |
| 44742 | 44928 | ** a journal header to be written between the pages journaled by |
| 44743 | 44929 | ** this function. |
| 44744 | 44930 | */ |
| | @@ -50914,10 +51100,14 @@ |
| 50914 | 51100 | pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 50915 | 51101 | pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree |
| 50916 | 51102 | ); |
| 50917 | 51103 | if( pIdxKey==0 ) return SQLITE_NOMEM; |
| 50918 | 51104 | sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); |
| 51105 | + if( pIdxKey->nField==0 ){ |
| 51106 | + sqlite3DbFree(pCur->pKeyInfo->db, pFree); |
| 51107 | + return SQLITE_CORRUPT_BKPT; |
| 51108 | + } |
| 50919 | 51109 | }else{ |
| 50920 | 51110 | pIdxKey = 0; |
| 50921 | 51111 | } |
| 50922 | 51112 | rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); |
| 50923 | 51113 | if( pFree ){ |
| | @@ -51868,11 +52058,11 @@ |
| 51868 | 52058 | |
| 51869 | 52059 | if( pgno>btreePagecount(pBt) ){ |
| 51870 | 52060 | rc = SQLITE_CORRUPT_BKPT; |
| 51871 | 52061 | }else{ |
| 51872 | 52062 | rc = btreeGetPage(pBt, pgno, ppPage, bReadonly); |
| 51873 | | - if( rc==SQLITE_OK ){ |
| 52063 | + if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){ |
| 51874 | 52064 | rc = btreeInitPage(*ppPage); |
| 51875 | 52065 | if( rc!=SQLITE_OK ){ |
| 51876 | 52066 | releasePage(*ppPage); |
| 51877 | 52067 | } |
| 51878 | 52068 | } |
| | @@ -54408,14 +54598,14 @@ |
| 54408 | 54598 | } |
| 54409 | 54599 | |
| 54410 | 54600 | /* |
| 54411 | 54601 | ** Return a pointer to payload information from the entry that the |
| 54412 | 54602 | ** pCur cursor is pointing to. The pointer is to the beginning of |
| 54413 | | -** the key if skipKey==0 and it points to the beginning of data if |
| 54414 | | -** skipKey==1. The number of bytes of available key/data is written |
| 54415 | | -** into *pAmt. If *pAmt==0, then the value returned will not be |
| 54416 | | -** a valid pointer. |
| 54603 | +** the key if index btrees (pPage->intKey==0) and is the data for |
| 54604 | +** table btrees (pPage->intKey==1). The number of bytes of available |
| 54605 | +** key/data is written into *pAmt. If *pAmt==0, then the value |
| 54606 | +** returned will not be a valid pointer. |
| 54417 | 54607 | ** |
| 54418 | 54608 | ** This routine is an optimization. It is common for the entire key |
| 54419 | 54609 | ** and data to fit on the local page and for there to be no overflow |
| 54420 | 54610 | ** pages. When that is so, this routine can be used to access the |
| 54421 | 54611 | ** key and data without making a copy. If the key and/or data spills |
| | @@ -54424,45 +54614,25 @@ |
| 54424 | 54614 | ** |
| 54425 | 54615 | ** The pointer returned by this routine looks directly into the cached |
| 54426 | 54616 | ** page of the database. The data might change or move the next time |
| 54427 | 54617 | ** any btree routine is called. |
| 54428 | 54618 | */ |
| 54429 | | -static const unsigned char *fetchPayload( |
| 54619 | +static const void *fetchPayload( |
| 54430 | 54620 | BtCursor *pCur, /* Cursor pointing to entry to read from */ |
| 54431 | | - int *pAmt, /* Write the number of available bytes here */ |
| 54432 | | - int skipKey /* read beginning at data if this is true */ |
| 54621 | + u32 *pAmt /* Write the number of available bytes here */ |
| 54433 | 54622 | ){ |
| 54434 | | - unsigned char *aPayload; |
| 54435 | | - MemPage *pPage; |
| 54436 | | - u32 nKey; |
| 54437 | | - u32 nLocal; |
| 54438 | | - |
| 54439 | 54623 | assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); |
| 54440 | 54624 | assert( pCur->eState==CURSOR_VALID ); |
| 54625 | + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 54441 | 54626 | assert( cursorHoldsMutex(pCur) ); |
| 54442 | | - pPage = pCur->apPage[pCur->iPage]; |
| 54443 | | - assert( pCur->aiIdx[pCur->iPage]<pPage->nCell ); |
| 54444 | | - if( NEVER(pCur->info.nSize==0) ){ |
| 54627 | + assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); |
| 54628 | + if( pCur->info.nSize==0 ){ |
| 54445 | 54629 | btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], |
| 54446 | 54630 | &pCur->info); |
| 54447 | 54631 | } |
| 54448 | | - aPayload = pCur->info.pCell; |
| 54449 | | - aPayload += pCur->info.nHeader; |
| 54450 | | - if( pPage->intKey ){ |
| 54451 | | - nKey = 0; |
| 54452 | | - }else{ |
| 54453 | | - nKey = (int)pCur->info.nKey; |
| 54454 | | - } |
| 54455 | | - if( skipKey ){ |
| 54456 | | - aPayload += nKey; |
| 54457 | | - nLocal = pCur->info.nLocal - nKey; |
| 54458 | | - }else{ |
| 54459 | | - nLocal = pCur->info.nLocal; |
| 54460 | | - assert( nLocal<=nKey ); |
| 54461 | | - } |
| 54462 | | - *pAmt = nLocal; |
| 54463 | | - return aPayload; |
| 54632 | + *pAmt = pCur->info.nLocal; |
| 54633 | + return (void*)(pCur->info.pCell + pCur->info.nHeader); |
| 54464 | 54634 | } |
| 54465 | 54635 | |
| 54466 | 54636 | |
| 54467 | 54637 | /* |
| 54468 | 54638 | ** For the entry that cursor pCur is point to, return as |
| | @@ -54476,27 +54646,15 @@ |
| 54476 | 54646 | ** this routine. |
| 54477 | 54647 | ** |
| 54478 | 54648 | ** These routines is used to get quick access to key and data |
| 54479 | 54649 | ** in the common case where no overflow pages are used. |
| 54480 | 54650 | */ |
| 54481 | | -SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){ |
| 54482 | | - const void *p = 0; |
| 54483 | | - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 54484 | | - assert( cursorHoldsMutex(pCur) ); |
| 54485 | | - if( ALWAYS(pCur->eState==CURSOR_VALID) ){ |
| 54486 | | - p = (const void*)fetchPayload(pCur, pAmt, 0); |
| 54487 | | - } |
| 54488 | | - return p; |
| 54489 | | -} |
| 54490 | | -SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){ |
| 54491 | | - const void *p = 0; |
| 54492 | | - assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 54493 | | - assert( cursorHoldsMutex(pCur) ); |
| 54494 | | - if( ALWAYS(pCur->eState==CURSOR_VALID) ){ |
| 54495 | | - p = (const void*)fetchPayload(pCur, pAmt, 1); |
| 54496 | | - } |
| 54497 | | - return p; |
| 54651 | +SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){ |
| 54652 | + return fetchPayload(pCur, pAmt); |
| 54653 | +} |
| 54654 | +SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){ |
| 54655 | + return fetchPayload(pCur, pAmt); |
| 54498 | 54656 | } |
| 54499 | 54657 | |
| 54500 | 54658 | |
| 54501 | 54659 | /* |
| 54502 | 54660 | ** Move the cursor down to a new child page. The newPgno argument is the |
| | @@ -54611,12 +54769,10 @@ |
| 54611 | 54769 | ** b-tree). |
| 54612 | 54770 | */ |
| 54613 | 54771 | static int moveToRoot(BtCursor *pCur){ |
| 54614 | 54772 | MemPage *pRoot; |
| 54615 | 54773 | int rc = SQLITE_OK; |
| 54616 | | - Btree *p = pCur->pBtree; |
| 54617 | | - BtShared *pBt = p->pBt; |
| 54618 | 54774 | |
| 54619 | 54775 | assert( cursorHoldsMutex(pCur) ); |
| 54620 | 54776 | assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); |
| 54621 | 54777 | assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); |
| 54622 | 54778 | assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); |
| | @@ -54627,20 +54783,16 @@ |
| 54627 | 54783 | } |
| 54628 | 54784 | sqlite3BtreeClearCursor(pCur); |
| 54629 | 54785 | } |
| 54630 | 54786 | |
| 54631 | 54787 | if( pCur->iPage>=0 ){ |
| 54632 | | - int i; |
| 54633 | | - for(i=1; i<=pCur->iPage; i++){ |
| 54634 | | - releasePage(pCur->apPage[i]); |
| 54635 | | - } |
| 54636 | | - pCur->iPage = 0; |
| 54788 | + while( pCur->iPage ) releasePage(pCur->apPage[pCur->iPage--]); |
| 54637 | 54789 | }else if( pCur->pgnoRoot==0 ){ |
| 54638 | 54790 | pCur->eState = CURSOR_INVALID; |
| 54639 | 54791 | return SQLITE_OK; |
| 54640 | 54792 | }else{ |
| 54641 | | - rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], |
| 54793 | + rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], |
| 54642 | 54794 | pCur->wrFlag==0 ? PAGER_GET_READONLY : 0); |
| 54643 | 54795 | if( rc!=SQLITE_OK ){ |
| 54644 | 54796 | pCur->eState = CURSOR_INVALID; |
| 54645 | 54797 | return rc; |
| 54646 | 54798 | } |
| | @@ -54669,18 +54821,20 @@ |
| 54669 | 54821 | pCur->aiIdx[0] = 0; |
| 54670 | 54822 | pCur->info.nSize = 0; |
| 54671 | 54823 | pCur->atLast = 0; |
| 54672 | 54824 | pCur->validNKey = 0; |
| 54673 | 54825 | |
| 54674 | | - if( pRoot->nCell==0 && !pRoot->leaf ){ |
| 54826 | + if( pRoot->nCell>0 ){ |
| 54827 | + pCur->eState = CURSOR_VALID; |
| 54828 | + }else if( !pRoot->leaf ){ |
| 54675 | 54829 | Pgno subpage; |
| 54676 | 54830 | if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; |
| 54677 | 54831 | subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); |
| 54678 | 54832 | pCur->eState = CURSOR_VALID; |
| 54679 | 54833 | rc = moveToChild(pCur, subpage); |
| 54680 | 54834 | }else{ |
| 54681 | | - pCur->eState = ((pRoot->nCell>0)?CURSOR_VALID:CURSOR_INVALID); |
| 54835 | + pCur->eState = CURSOR_INVALID; |
| 54682 | 54836 | } |
| 54683 | 54837 | return rc; |
| 54684 | 54838 | } |
| 54685 | 54839 | |
| 54686 | 54840 | /* |
| | @@ -54867,14 +55021,14 @@ |
| 54867 | 55021 | assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); |
| 54868 | 55022 | return SQLITE_OK; |
| 54869 | 55023 | } |
| 54870 | 55024 | assert( pCur->apPage[0]->intKey || pIdxKey ); |
| 54871 | 55025 | for(;;){ |
| 54872 | | - int lwr, upr, idx; |
| 55026 | + int lwr, upr, idx, c; |
| 54873 | 55027 | Pgno chldPg; |
| 54874 | 55028 | MemPage *pPage = pCur->apPage[pCur->iPage]; |
| 54875 | | - int c; |
| 55029 | + u8 *pCell; /* Pointer to current cell in pPage */ |
| 54876 | 55030 | |
| 54877 | 55031 | /* pPage->nCell must be greater than zero. If this is the root-page |
| 54878 | 55032 | ** the cursor would have been INVALID above and this for(;;) loop |
| 54879 | 55033 | ** not run. If this is not the root-page, then the moveToChild() routine |
| 54880 | 55034 | ** would have already detected db corruption. Similarly, pPage must |
| | @@ -54882,59 +55036,68 @@ |
| 54882 | 55036 | ** a moveToChild() or moveToRoot() call would have detected corruption. */ |
| 54883 | 55037 | assert( pPage->nCell>0 ); |
| 54884 | 55038 | assert( pPage->intKey==(pIdxKey==0) ); |
| 54885 | 55039 | lwr = 0; |
| 54886 | 55040 | upr = pPage->nCell-1; |
| 54887 | | - if( biasRight ){ |
| 54888 | | - pCur->aiIdx[pCur->iPage] = (u16)(idx = upr); |
| 54889 | | - }else{ |
| 54890 | | - pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2); |
| 54891 | | - } |
| 54892 | | - for(;;){ |
| 54893 | | - u8 *pCell; /* Pointer to current cell in pPage */ |
| 54894 | | - |
| 54895 | | - assert( idx==pCur->aiIdx[pCur->iPage] ); |
| 54896 | | - pCur->info.nSize = 0; |
| 54897 | | - pCell = findCell(pPage, idx) + pPage->childPtrSize; |
| 54898 | | - if( pPage->intKey ){ |
| 55041 | + assert( biasRight==0 || biasRight==1 ); |
| 55042 | + idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ |
| 55043 | + pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 55044 | + if( pPage->intKey ){ |
| 55045 | + for(;;){ |
| 54899 | 55046 | i64 nCellKey; |
| 55047 | + pCell = findCell(pPage, idx) + pPage->childPtrSize; |
| 54900 | 55048 | if( pPage->hasData ){ |
| 54901 | | - u32 dummy; |
| 54902 | | - pCell += getVarint32(pCell, dummy); |
| 55049 | + while( 0x80 <= *(pCell++) ){ |
| 55050 | + if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT; |
| 55051 | + } |
| 54903 | 55052 | } |
| 54904 | 55053 | getVarint(pCell, (u64*)&nCellKey); |
| 54905 | | - if( nCellKey==intKey ){ |
| 54906 | | - c = 0; |
| 54907 | | - }else if( nCellKey<intKey ){ |
| 54908 | | - c = -1; |
| 54909 | | - }else{ |
| 54910 | | - assert( nCellKey>intKey ); |
| 54911 | | - c = +1; |
| 54912 | | - } |
| 54913 | | - pCur->validNKey = 1; |
| 54914 | | - pCur->info.nKey = nCellKey; |
| 54915 | | - }else{ |
| 55054 | + if( nCellKey<intKey ){ |
| 55055 | + lwr = idx+1; |
| 55056 | + if( lwr>upr ){ c = -1; break; } |
| 55057 | + }else if( nCellKey>intKey ){ |
| 55058 | + upr = idx-1; |
| 55059 | + if( lwr>upr ){ c = +1; break; } |
| 55060 | + }else{ |
| 55061 | + assert( nCellKey==intKey ); |
| 55062 | + pCur->validNKey = 1; |
| 55063 | + pCur->info.nKey = nCellKey; |
| 55064 | + pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 55065 | + if( !pPage->leaf ){ |
| 55066 | + lwr = idx; |
| 55067 | + goto moveto_next_layer; |
| 55068 | + }else{ |
| 55069 | + *pRes = 0; |
| 55070 | + rc = SQLITE_OK; |
| 55071 | + goto moveto_finish; |
| 55072 | + } |
| 55073 | + } |
| 55074 | + assert( lwr+upr>=0 ); |
| 55075 | + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */ |
| 55076 | + } |
| 55077 | + }else{ |
| 55078 | + for(;;){ |
| 55079 | + int nCell; |
| 55080 | + pCell = findCell(pPage, idx) + pPage->childPtrSize; |
| 55081 | + |
| 54916 | 55082 | /* The maximum supported page-size is 65536 bytes. This means that |
| 54917 | 55083 | ** the maximum number of record bytes stored on an index B-Tree |
| 54918 | 55084 | ** page is less than 16384 bytes and may be stored as a 2-byte |
| 54919 | 55085 | ** varint. This information is used to attempt to avoid parsing |
| 54920 | 55086 | ** the entire cell by checking for the cases where the record is |
| 54921 | 55087 | ** stored entirely within the b-tree page by inspecting the first |
| 54922 | 55088 | ** 2 bytes of the cell. |
| 54923 | 55089 | */ |
| 54924 | | - int nCell = pCell[0]; |
| 54925 | | - if( nCell<=pPage->max1bytePayload |
| 54926 | | - /* && (pCell+nCell)<pPage->aDataEnd */ |
| 54927 | | - ){ |
| 55090 | + nCell = pCell[0]; |
| 55091 | + if( nCell<=pPage->max1bytePayload ){ |
| 54928 | 55092 | /* This branch runs if the record-size field of the cell is a |
| 54929 | 55093 | ** single byte varint and the record fits entirely on the main |
| 54930 | 55094 | ** b-tree page. */ |
| 54931 | 55095 | testcase( pCell+nCell+1==pPage->aDataEnd ); |
| 54932 | 55096 | c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey); |
| 54933 | 55097 | }else if( !(pCell[1] & 0x80) |
| 54934 | 55098 | && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal |
| 54935 | | - /* && (pCell+nCell+2)<=pPage->aDataEnd */ |
| 54936 | 55099 | ){ |
| 54937 | 55100 | /* The record-size field is a 2 byte varint and the record |
| 54938 | 55101 | ** fits entirely on the main b-tree page. */ |
| 54939 | 55102 | testcase( pCell+nCell+2==pPage->aDataEnd ); |
| 54940 | 55103 | c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey); |
| | @@ -54950,61 +55113,57 @@ |
| 54950 | 55113 | pCellKey = sqlite3Malloc( nCell ); |
| 54951 | 55114 | if( pCellKey==0 ){ |
| 54952 | 55115 | rc = SQLITE_NOMEM; |
| 54953 | 55116 | goto moveto_finish; |
| 54954 | 55117 | } |
| 55118 | + pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 54955 | 55119 | rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); |
| 54956 | 55120 | if( rc ){ |
| 54957 | 55121 | sqlite3_free(pCellKey); |
| 54958 | 55122 | goto moveto_finish; |
| 54959 | 55123 | } |
| 54960 | 55124 | c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); |
| 54961 | 55125 | sqlite3_free(pCellKey); |
| 54962 | 55126 | } |
| 54963 | | - } |
| 54964 | | - if( c==0 ){ |
| 54965 | | - if( pPage->intKey && !pPage->leaf ){ |
| 54966 | | - lwr = idx; |
| 54967 | | - break; |
| 55127 | + if( c<0 ){ |
| 55128 | + lwr = idx+1; |
| 55129 | + }else if( c>0 ){ |
| 55130 | + upr = idx-1; |
| 54968 | 55131 | }else{ |
| 55132 | + assert( c==0 ); |
| 54969 | 55133 | *pRes = 0; |
| 54970 | 55134 | rc = SQLITE_OK; |
| 55135 | + pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 54971 | 55136 | goto moveto_finish; |
| 54972 | 55137 | } |
| 54973 | | - } |
| 54974 | | - if( c<0 ){ |
| 54975 | | - lwr = idx+1; |
| 54976 | | - }else{ |
| 54977 | | - upr = idx-1; |
| 54978 | | - } |
| 54979 | | - if( lwr>upr ){ |
| 54980 | | - break; |
| 54981 | | - } |
| 54982 | | - pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); |
| 55138 | + if( lwr>upr ) break; |
| 55139 | + assert( lwr+upr>=0 ); |
| 55140 | + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ |
| 55141 | + } |
| 54983 | 55142 | } |
| 54984 | 55143 | assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); |
| 54985 | 55144 | assert( pPage->isInit ); |
| 54986 | 55145 | if( pPage->leaf ){ |
| 54987 | | - chldPg = 0; |
| 54988 | | - }else if( lwr>=pPage->nCell ){ |
| 54989 | | - chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); |
| 54990 | | - }else{ |
| 54991 | | - chldPg = get4byte(findCell(pPage, lwr)); |
| 54992 | | - } |
| 54993 | | - if( chldPg==0 ){ |
| 54994 | 55146 | assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell ); |
| 55147 | + pCur->aiIdx[pCur->iPage] = (u16)idx; |
| 54995 | 55148 | *pRes = c; |
| 54996 | 55149 | rc = SQLITE_OK; |
| 54997 | 55150 | goto moveto_finish; |
| 54998 | 55151 | } |
| 55152 | +moveto_next_layer: |
| 55153 | + if( lwr>=pPage->nCell ){ |
| 55154 | + chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); |
| 55155 | + }else{ |
| 55156 | + chldPg = get4byte(findCell(pPage, lwr)); |
| 55157 | + } |
| 54999 | 55158 | pCur->aiIdx[pCur->iPage] = (u16)lwr; |
| 55000 | | - pCur->info.nSize = 0; |
| 55001 | | - pCur->validNKey = 0; |
| 55002 | 55159 | rc = moveToChild(pCur, chldPg); |
| 55003 | | - if( rc ) goto moveto_finish; |
| 55160 | + if( rc ) break; |
| 55004 | 55161 | } |
| 55005 | 55162 | moveto_finish: |
| 55163 | + pCur->info.nSize = 0; |
| 55164 | + pCur->validNKey = 0; |
| 55006 | 55165 | return rc; |
| 55007 | 55166 | } |
| 55008 | 55167 | |
| 55009 | 55168 | |
| 55010 | 55169 | /* |
| | @@ -55758,11 +55917,11 @@ |
| 55758 | 55917 | nHeader = 0; |
| 55759 | 55918 | if( !pPage->leaf ){ |
| 55760 | 55919 | nHeader += 4; |
| 55761 | 55920 | } |
| 55762 | 55921 | if( pPage->hasData ){ |
| 55763 | | - nHeader += putVarint(&pCell[nHeader], nData+nZero); |
| 55922 | + nHeader += putVarint32(&pCell[nHeader], nData+nZero); |
| 55764 | 55923 | }else{ |
| 55765 | 55924 | nData = nZero = 0; |
| 55766 | 55925 | } |
| 55767 | 55926 | nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey); |
| 55768 | 55927 | btreeParseCellPtr(pPage, pCell, &info); |
| | @@ -55886,11 +56045,10 @@ |
| 55886 | 56045 | */ |
| 55887 | 56046 | static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ |
| 55888 | 56047 | u32 pc; /* Offset to cell content of cell being deleted */ |
| 55889 | 56048 | u8 *data; /* pPage->aData */ |
| 55890 | 56049 | u8 *ptr; /* Used to move bytes around within data[] */ |
| 55891 | | - u8 *endPtr; /* End of loop */ |
| 55892 | 56050 | int rc; /* The return code */ |
| 55893 | 56051 | int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ |
| 55894 | 56052 | |
| 55895 | 56053 | if( *pRC ) return; |
| 55896 | 56054 | |
| | @@ -55911,17 +56069,12 @@ |
| 55911 | 56069 | rc = freeSpace(pPage, pc, sz); |
| 55912 | 56070 | if( rc ){ |
| 55913 | 56071 | *pRC = rc; |
| 55914 | 56072 | return; |
| 55915 | 56073 | } |
| 55916 | | - endPtr = &pPage->aCellIdx[2*pPage->nCell - 2]; |
| 55917 | | - assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ |
| 55918 | | - while( ptr<endPtr ){ |
| 55919 | | - *(u16*)ptr = *(u16*)&ptr[2]; |
| 55920 | | - ptr += 2; |
| 55921 | | - } |
| 55922 | 56074 | pPage->nCell--; |
| 56075 | + memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); |
| 55923 | 56076 | put2byte(&data[hdr+3], pPage->nCell); |
| 55924 | 56077 | pPage->nFree += 2; |
| 55925 | 56078 | } |
| 55926 | 56079 | |
| 55927 | 56080 | /* |
| | @@ -55954,13 +56107,10 @@ |
| 55954 | 56107 | int j; /* Loop counter */ |
| 55955 | 56108 | int end; /* First byte past the last cell pointer in data[] */ |
| 55956 | 56109 | int ins; /* Index in data[] where new cell pointer is inserted */ |
| 55957 | 56110 | int cellOffset; /* Address of first cell pointer in data[] */ |
| 55958 | 56111 | u8 *data; /* The content of the whole page */ |
| 55959 | | - u8 *ptr; /* Used for moving information around in data[] */ |
| 55960 | | - u8 *endPtr; /* End of the loop */ |
| 55961 | | - |
| 55962 | 56112 | int nSkip = (iChild ? 4 : 0); |
| 55963 | 56113 | |
| 55964 | 56114 | if( *pRC ) return; |
| 55965 | 56115 | |
| 55966 | 56116 | assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); |
| | @@ -56007,17 +56157,11 @@ |
| 56007 | 56157 | pPage->nFree -= (u16)(2 + sz); |
| 56008 | 56158 | memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); |
| 56009 | 56159 | if( iChild ){ |
| 56010 | 56160 | put4byte(&data[idx], iChild); |
| 56011 | 56161 | } |
| 56012 | | - ptr = &data[end]; |
| 56013 | | - endPtr = &data[ins]; |
| 56014 | | - assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */ |
| 56015 | | - while( ptr>endPtr ){ |
| 56016 | | - *(u16*)ptr = *(u16*)&ptr[-2]; |
| 56017 | | - ptr -= 2; |
| 56018 | | - } |
| 56162 | + memmove(&data[ins+2], &data[ins], end-ins); |
| 56019 | 56163 | put2byte(&data[ins], idx); |
| 56020 | 56164 | put2byte(&data[pPage->hdrOffset+3], pPage->nCell); |
| 56021 | 56165 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 56022 | 56166 | if( pPage->pBt->autoVacuum ){ |
| 56023 | 56167 | /* The cell may contain a pointer to an overflow page. If so, write |
| | @@ -57975,11 +58119,11 @@ |
| 57975 | 58119 | va_start(ap, zFormat); |
| 57976 | 58120 | if( pCheck->errMsg.nChar ){ |
| 57977 | 58121 | sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); |
| 57978 | 58122 | } |
| 57979 | 58123 | if( zMsg1 ){ |
| 57980 | | - sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1); |
| 58124 | + sqlite3StrAccumAppendAll(&pCheck->errMsg, zMsg1); |
| 57981 | 58125 | } |
| 57982 | 58126 | sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); |
| 57983 | 58127 | va_end(ap); |
| 57984 | 58128 | if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ |
| 57985 | 58129 | pCheck->mallocFailed = 1; |
| | @@ -58839,10 +58983,11 @@ |
| 58839 | 58983 | if( sqlite3OpenTempDatabase(pParse) ){ |
| 58840 | 58984 | sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg); |
| 58841 | 58985 | rc = SQLITE_ERROR; |
| 58842 | 58986 | } |
| 58843 | 58987 | sqlite3DbFree(pErrorDb, pParse->zErrMsg); |
| 58988 | + sqlite3ParserReset(pParse); |
| 58844 | 58989 | sqlite3StackFree(pErrorDb, pParse); |
| 58845 | 58990 | } |
| 58846 | 58991 | if( rc ){ |
| 58847 | 58992 | return 0; |
| 58848 | 58993 | } |
| | @@ -59550,61 +59695,59 @@ |
| 59550 | 59695 | #endif |
| 59551 | 59696 | } |
| 59552 | 59697 | |
| 59553 | 59698 | /* |
| 59554 | 59699 | ** Make sure pMem->z points to a writable allocation of at least |
| 59555 | | -** n bytes. |
| 59556 | | -** |
| 59557 | | -** If the third argument passed to this function is true, then memory |
| 59558 | | -** cell pMem must contain a string or blob. In this case the content is |
| 59559 | | -** preserved. Otherwise, if the third parameter to this function is false, |
| 59560 | | -** any current string or blob value may be discarded. |
| 59561 | | -** |
| 59562 | | -** This function sets the MEM_Dyn flag and clears any xDel callback. |
| 59563 | | -** It also clears MEM_Ephem and MEM_Static. If the preserve flag is |
| 59564 | | -** not set, Mem.n is zeroed. |
| 59565 | | -*/ |
| 59566 | | -SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){ |
| 59700 | +** min(n,32) bytes. |
| 59701 | +** |
| 59702 | +** If the bPreserve argument is true, then copy of the content of |
| 59703 | +** pMem->z into the new allocation. pMem must be either a string or |
| 59704 | +** blob if bPreserve is true. If bPreserve is false, any prior content |
| 59705 | +** in pMem->z is discarded. |
| 59706 | +*/ |
| 59707 | +SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ |
| 59567 | 59708 | assert( 1 >= |
| 59568 | 59709 | ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) + |
| 59569 | 59710 | (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) + |
| 59570 | 59711 | ((pMem->flags&MEM_Ephem) ? 1 : 0) + |
| 59571 | 59712 | ((pMem->flags&MEM_Static) ? 1 : 0) |
| 59572 | 59713 | ); |
| 59573 | 59714 | assert( (pMem->flags&MEM_RowSet)==0 ); |
| 59574 | 59715 | |
| 59575 | | - /* If the preserve flag is set to true, then the memory cell must already |
| 59716 | + /* If the bPreserve flag is set to true, then the memory cell must already |
| 59576 | 59717 | ** contain a valid string or blob value. */ |
| 59577 | | - assert( preserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); |
| 59718 | + assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); |
| 59719 | + testcase( bPreserve && pMem->z==0 ); |
| 59578 | 59720 | |
| 59579 | | - if( n<32 ) n = 32; |
| 59580 | | - if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){ |
| 59581 | | - if( preserve && pMem->z==pMem->zMalloc ){ |
| 59721 | + if( pMem->zMalloc==0 || sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){ |
| 59722 | + if( n<32 ) n = 32; |
| 59723 | + if( bPreserve && pMem->z==pMem->zMalloc ){ |
| 59582 | 59724 | pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); |
| 59583 | | - preserve = 0; |
| 59725 | + bPreserve = 0; |
| 59584 | 59726 | }else{ |
| 59585 | 59727 | sqlite3DbFree(pMem->db, pMem->zMalloc); |
| 59586 | 59728 | pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); |
| 59587 | 59729 | } |
| 59730 | + if( pMem->zMalloc==0 ){ |
| 59731 | + sqlite3VdbeMemRelease(pMem); |
| 59732 | + pMem->flags = MEM_Null; |
| 59733 | + return SQLITE_NOMEM; |
| 59734 | + } |
| 59588 | 59735 | } |
| 59589 | 59736 | |
| 59590 | | - if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ |
| 59737 | + if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){ |
| 59591 | 59738 | memcpy(pMem->zMalloc, pMem->z, pMem->n); |
| 59592 | 59739 | } |
| 59593 | | - if( pMem->flags&MEM_Dyn && pMem->xDel ){ |
| 59740 | + if( (pMem->flags&MEM_Dyn)!=0 && pMem->xDel ){ |
| 59594 | 59741 | assert( pMem->xDel!=SQLITE_DYNAMIC ); |
| 59595 | 59742 | pMem->xDel((void *)(pMem->z)); |
| 59596 | 59743 | } |
| 59597 | 59744 | |
| 59598 | 59745 | pMem->z = pMem->zMalloc; |
| 59599 | | - if( pMem->z==0 ){ |
| 59600 | | - pMem->flags = MEM_Null; |
| 59601 | | - }else{ |
| 59602 | | - pMem->flags &= ~(MEM_Ephem|MEM_Static); |
| 59603 | | - } |
| 59746 | + pMem->flags &= ~(MEM_Ephem|MEM_Static); |
| 59604 | 59747 | pMem->xDel = 0; |
| 59605 | | - return (pMem->z ? SQLITE_OK : SQLITE_NOMEM); |
| 59748 | + return SQLITE_OK; |
| 59606 | 59749 | } |
| 59607 | 59750 | |
| 59608 | 59751 | /* |
| 59609 | 59752 | ** Make the given Mem object MEM_Dyn. In other words, make it so |
| 59610 | 59753 | ** that any TEXT or BLOB content is stored in memory obtained from |
| | @@ -59786,27 +59929,22 @@ |
| 59786 | 59929 | ** inconsistent state, for example with (Mem.z==0) and |
| 59787 | 59930 | ** (Mem.type==SQLITE_TEXT). |
| 59788 | 59931 | */ |
| 59789 | 59932 | SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ |
| 59790 | 59933 | VdbeMemRelease(p); |
| 59791 | | - sqlite3DbFree(p->db, p->zMalloc); |
| 59934 | + if( p->zMalloc ){ |
| 59935 | + sqlite3DbFree(p->db, p->zMalloc); |
| 59936 | + p->zMalloc = 0; |
| 59937 | + } |
| 59792 | 59938 | p->z = 0; |
| 59793 | | - p->zMalloc = 0; |
| 59794 | | - p->xDel = 0; |
| 59939 | + assert( p->xDel==0 ); /* Zeroed by VdbeMemRelease() above */ |
| 59795 | 59940 | } |
| 59796 | 59941 | |
| 59797 | 59942 | /* |
| 59798 | 59943 | ** Convert a 64-bit IEEE double into a 64-bit signed integer. |
| 59799 | | -** If the double is too large, return 0x8000000000000000. |
| 59800 | | -** |
| 59801 | | -** Most systems appear to do this simply by assigning |
| 59802 | | -** variables and without the extra range tests. But |
| 59803 | | -** there are reports that windows throws an expection |
| 59804 | | -** if the floating point value is out of range. (See ticket #2880.) |
| 59805 | | -** Because we do not completely understand the problem, we will |
| 59806 | | -** take the conservative approach and always do range tests |
| 59807 | | -** before attempting the conversion. |
| 59944 | +** If the double is out of range of a 64-bit signed integer then |
| 59945 | +** return the closest available 64-bit signed integer. |
| 59808 | 59946 | */ |
| 59809 | 59947 | static i64 doubleToInt64(double r){ |
| 59810 | 59948 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 59811 | 59949 | /* When floating-point is omitted, double and int64 are the same thing */ |
| 59812 | 59950 | return r; |
| | @@ -59819,18 +59957,14 @@ |
| 59819 | 59957 | ** larger than a 32-bit integer constant. |
| 59820 | 59958 | */ |
| 59821 | 59959 | static const i64 maxInt = LARGEST_INT64; |
| 59822 | 59960 | static const i64 minInt = SMALLEST_INT64; |
| 59823 | 59961 | |
| 59824 | | - if( r<(double)minInt ){ |
| 59825 | | - return minInt; |
| 59826 | | - }else if( r>(double)maxInt ){ |
| 59827 | | - /* minInt is correct here - not maxInt. It turns out that assigning |
| 59828 | | - ** a very large positive number to an integer results in a very large |
| 59829 | | - ** negative integer. This makes no sense, but it is what x86 hardware |
| 59830 | | - ** does so for compatibility we will do the same in software. */ |
| 59831 | | - return minInt; |
| 59962 | + if( r<=(double)minInt ){ |
| 59963 | + return minInt; |
| 59964 | + }else if( r>=(double)maxInt ){ |
| 59965 | + return maxInt; |
| 59832 | 59966 | }else{ |
| 59833 | 59967 | return (i64)r; |
| 59834 | 59968 | } |
| 59835 | 59969 | #endif |
| 59836 | 59970 | } |
| | @@ -59908,21 +60042,15 @@ |
| 59908 | 60042 | ** (2) The integer is neither the largest nor the smallest |
| 59909 | 60043 | ** possible integer (ticket #3922) |
| 59910 | 60044 | ** |
| 59911 | 60045 | ** The second and third terms in the following conditional enforces |
| 59912 | 60046 | ** the second condition under the assumption that addition overflow causes |
| 59913 | | - ** values to wrap around. On x86 hardware, the third term is always |
| 59914 | | - ** true and could be omitted. But we leave it in because other |
| 59915 | | - ** architectures might behave differently. |
| 60047 | + ** values to wrap around. |
| 59916 | 60048 | */ |
| 59917 | 60049 | if( pMem->r==(double)pMem->u.i |
| 59918 | 60050 | && pMem->u.i>SMALLEST_INT64 |
| 59919 | | -#if defined(__i486__) || defined(__x86_64__) |
| 59920 | | - && ALWAYS(pMem->u.i<LARGEST_INT64) |
| 59921 | | -#else |
| 59922 | 60051 | && pMem->u.i<LARGEST_INT64 |
| 59923 | | -#endif |
| 59924 | 60052 | ){ |
| 59925 | 60053 | pMem->flags |= MEM_Int; |
| 59926 | 60054 | } |
| 59927 | 60055 | } |
| 59928 | 60056 | |
| | @@ -60387,17 +60515,17 @@ |
| 60387 | 60515 | ** If this routine fails for any reason (malloc returns NULL or unable |
| 60388 | 60516 | ** to read from the disk) then the pMem is left in an inconsistent state. |
| 60389 | 60517 | */ |
| 60390 | 60518 | SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( |
| 60391 | 60519 | BtCursor *pCur, /* Cursor pointing at record to retrieve. */ |
| 60392 | | - int offset, /* Offset from the start of data to return bytes from. */ |
| 60393 | | - int amt, /* Number of bytes to return. */ |
| 60520 | + u32 offset, /* Offset from the start of data to return bytes from. */ |
| 60521 | + u32 amt, /* Number of bytes to return. */ |
| 60394 | 60522 | int key, /* If true, retrieve from the btree key, not data. */ |
| 60395 | 60523 | Mem *pMem /* OUT: Return data in this Mem structure. */ |
| 60396 | 60524 | ){ |
| 60397 | 60525 | char *zData; /* Data from the btree layer */ |
| 60398 | | - int available = 0; /* Number of bytes available on the local btree page */ |
| 60526 | + u32 available = 0; /* Number of bytes available on the local btree page */ |
| 60399 | 60527 | int rc = SQLITE_OK; /* Return code */ |
| 60400 | 60528 | |
| 60401 | 60529 | assert( sqlite3BtreeCursorIsValid(pCur) ); |
| 60402 | 60530 | |
| 60403 | 60531 | /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() |
| | @@ -60408,11 +60536,11 @@ |
| 60408 | 60536 | }else{ |
| 60409 | 60537 | zData = (char *)sqlite3BtreeDataFetch(pCur, &available); |
| 60410 | 60538 | } |
| 60411 | 60539 | assert( zData!=0 ); |
| 60412 | 60540 | |
| 60413 | | - if( offset+amt<=available && (pMem->flags&MEM_Dyn)==0 ){ |
| 60541 | + if( offset+amt<=available ){ |
| 60414 | 60542 | sqlite3VdbeMemRelease(pMem); |
| 60415 | 60543 | pMem->z = &zData[offset]; |
| 60416 | 60544 | pMem->flags = MEM_Blob|MEM_Ephem; |
| 60417 | 60545 | }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){ |
| 60418 | 60546 | pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term; |
| | @@ -60427,11 +60555,11 @@ |
| 60427 | 60555 | pMem->z[amt+1] = 0; |
| 60428 | 60556 | if( rc!=SQLITE_OK ){ |
| 60429 | 60557 | sqlite3VdbeMemRelease(pMem); |
| 60430 | 60558 | } |
| 60431 | 60559 | } |
| 60432 | | - pMem->n = amt; |
| 60560 | + pMem->n = (int)amt; |
| 60433 | 60561 | |
| 60434 | 60562 | return rc; |
| 60435 | 60563 | } |
| 60436 | 60564 | |
| 60437 | 60565 | /* This function is only available internally, it is not part of the |
| | @@ -60524,19 +60652,19 @@ |
| 60524 | 60652 | Index *pIdx = p->pIdx; /* Index being probed */ |
| 60525 | 60653 | int nByte; /* Bytes of space to allocate */ |
| 60526 | 60654 | int i; /* Counter variable */ |
| 60527 | 60655 | int nCol = pIdx->nColumn; /* Number of index columns including rowid */ |
| 60528 | 60656 | |
| 60529 | | - nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord); |
| 60657 | + nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord)); |
| 60530 | 60658 | pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); |
| 60531 | 60659 | if( pRec ){ |
| 60532 | 60660 | pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx); |
| 60533 | 60661 | if( pRec->pKeyInfo ){ |
| 60534 | 60662 | assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol ); |
| 60535 | 60663 | assert( pRec->pKeyInfo->enc==ENC(db) ); |
| 60536 | 60664 | pRec->flags = UNPACKED_PREFIX_MATCH; |
| 60537 | | - pRec->aMem = (Mem *)&pRec[1]; |
| 60665 | + pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); |
| 60538 | 60666 | for(i=0; i<nCol; i++){ |
| 60539 | 60667 | pRec->aMem[i].flags = MEM_Null; |
| 60540 | 60668 | pRec->aMem[i].type = SQLITE_NULL; |
| 60541 | 60669 | pRec->aMem[i].db = db; |
| 60542 | 60670 | } |
| | @@ -60586,20 +60714,11 @@ |
| 60586 | 60714 | if( !pExpr ){ |
| 60587 | 60715 | *ppVal = 0; |
| 60588 | 60716 | return SQLITE_OK; |
| 60589 | 60717 | } |
| 60590 | 60718 | op = pExpr->op; |
| 60591 | | - |
| 60592 | | - /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT4. |
| 60593 | | - ** The ifdef here is to enable us to achieve 100% branch test coverage even |
| 60594 | | - ** when SQLITE_ENABLE_STAT4 is omitted. |
| 60595 | | - */ |
| 60596 | | -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60597 | | - if( op==TK_REGISTER ) op = pExpr->op2; |
| 60598 | | -#else |
| 60599 | 60719 | if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
| 60600 | | -#endif |
| 60601 | 60720 | |
| 60602 | 60721 | /* Handle negative integers in a single step. This is needed in the |
| 60603 | 60722 | ** case when the value is -9223372036854775808. |
| 60604 | 60723 | */ |
| 60605 | 60724 | if( op==TK_UMINUS |
| | @@ -60736,11 +60855,11 @@ |
| 60736 | 60855 | if( aRet==0 ){ |
| 60737 | 60856 | sqlite3_result_error_nomem(context); |
| 60738 | 60857 | }else{ |
| 60739 | 60858 | aRet[0] = nSerial+1; |
| 60740 | 60859 | sqlite3PutVarint(&aRet[1], iSerial); |
| 60741 | | - sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format); |
| 60860 | + sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial); |
| 60742 | 60861 | sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); |
| 60743 | 60862 | sqlite3DbFree(db, aRet); |
| 60744 | 60863 | } |
| 60745 | 60864 | } |
| 60746 | 60865 | |
| | @@ -60814,14 +60933,13 @@ |
| 60814 | 60933 | |
| 60815 | 60934 | if( !pExpr ){ |
| 60816 | 60935 | pVal = valueNew(db, &alloc); |
| 60817 | 60936 | if( pVal ){ |
| 60818 | 60937 | sqlite3VdbeMemSetNull((Mem*)pVal); |
| 60819 | | - *pbOk = 1; |
| 60820 | 60938 | } |
| 60821 | 60939 | }else if( pExpr->op==TK_VARIABLE |
| 60822 | | - || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) |
| 60940 | + || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) |
| 60823 | 60941 | ){ |
| 60824 | 60942 | Vdbe *v; |
| 60825 | 60943 | int iBindVar = pExpr->iColumn; |
| 60826 | 60944 | sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); |
| 60827 | 60945 | if( (v = pParse->pReprepare)!=0 ){ |
| | @@ -60830,20 +60948,17 @@ |
| 60830 | 60948 | rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); |
| 60831 | 60949 | if( rc==SQLITE_OK ){ |
| 60832 | 60950 | sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); |
| 60833 | 60951 | } |
| 60834 | 60952 | pVal->db = pParse->db; |
| 60835 | | - *pbOk = 1; |
| 60836 | 60953 | sqlite3VdbeMemStoreType((Mem*)pVal); |
| 60837 | 60954 | } |
| 60838 | | - }else{ |
| 60839 | | - *pbOk = 0; |
| 60840 | 60955 | } |
| 60841 | 60956 | }else{ |
| 60842 | 60957 | rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc); |
| 60843 | | - *pbOk = (pVal!=0); |
| 60844 | 60958 | } |
| 60959 | + *pbOk = (pVal!=0); |
| 60845 | 60960 | |
| 60846 | 60961 | assert( pVal==0 || pVal->db==db ); |
| 60847 | 60962 | return rc; |
| 60848 | 60963 | } |
| 60849 | 60964 | |
| | @@ -60983,19 +61098,10 @@ |
| 60983 | 61098 | pA->zSql = pB->zSql; |
| 60984 | 61099 | pB->zSql = zTmp; |
| 60985 | 61100 | pB->isPrepareV2 = pA->isPrepareV2; |
| 60986 | 61101 | } |
| 60987 | 61102 | |
| 60988 | | -#ifdef SQLITE_DEBUG |
| 60989 | | -/* |
| 60990 | | -** Turn tracing on or off |
| 60991 | | -*/ |
| 60992 | | -SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe *p, FILE *trace){ |
| 60993 | | - p->trace = trace; |
| 60994 | | -} |
| 60995 | | -#endif |
| 60996 | | - |
| 60997 | 61103 | /* |
| 60998 | 61104 | ** Resize the Vdbe.aOp array so that it is at least one op larger than |
| 60999 | 61105 | ** it was. |
| 61000 | 61106 | ** |
| 61001 | 61107 | ** If an out-of-memory error occurs while resizing the array, return |
| | @@ -61367,16 +61473,18 @@ |
| 61367 | 61473 | if( n>nMaxArgs ) nMaxArgs = n; |
| 61368 | 61474 | break; |
| 61369 | 61475 | } |
| 61370 | 61476 | #endif |
| 61371 | 61477 | case OP_Next: |
| 61478 | + case OP_NextIfOpen: |
| 61372 | 61479 | case OP_SorterNext: { |
| 61373 | 61480 | pOp->p4.xAdvance = sqlite3BtreeNext; |
| 61374 | 61481 | pOp->p4type = P4_ADVANCE; |
| 61375 | 61482 | break; |
| 61376 | 61483 | } |
| 61377 | | - case OP_Prev: { |
| 61484 | + case OP_Prev: |
| 61485 | + case OP_PrevIfOpen: { |
| 61378 | 61486 | pOp->p4.xAdvance = sqlite3BtreePrevious; |
| 61379 | 61487 | pOp->p4type = P4_ADVANCE; |
| 61380 | 61488 | break; |
| 61381 | 61489 | } |
| 61382 | 61490 | } |
| | @@ -61887,11 +61995,11 @@ |
| 61887 | 61995 | assert( i<nTemp ); |
| 61888 | 61996 | break; |
| 61889 | 61997 | } |
| 61890 | 61998 | case P4_COLLSEQ: { |
| 61891 | 61999 | CollSeq *pColl = pOp->p4.pColl; |
| 61892 | | - sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName); |
| 62000 | + sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName); |
| 61893 | 62001 | break; |
| 61894 | 62002 | } |
| 61895 | 62003 | case P4_FUNCDEF: { |
| 61896 | 62004 | FuncDef *pDef = pOp->p4.pFunc; |
| 61897 | 62005 | sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); |
| | @@ -62320,19 +62428,21 @@ |
| 62320 | 62428 | #ifdef SQLITE_DEBUG |
| 62321 | 62429 | /* |
| 62322 | 62430 | ** Print the SQL that was used to generate a VDBE program. |
| 62323 | 62431 | */ |
| 62324 | 62432 | SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){ |
| 62325 | | - int nOp = p->nOp; |
| 62326 | | - VdbeOp *pOp; |
| 62327 | | - if( nOp<1 ) return; |
| 62328 | | - pOp = &p->aOp[0]; |
| 62329 | | - if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){ |
| 62330 | | - const char *z = pOp->p4.z; |
| 62331 | | - while( sqlite3Isspace(*z) ) z++; |
| 62332 | | - printf("SQL: [%s]\n", z); |
| 62333 | | - } |
| 62433 | + const char *z = 0; |
| 62434 | + if( p->zSql ){ |
| 62435 | + z = p->zSql; |
| 62436 | + }else if( p->nOp>=1 ){ |
| 62437 | + const VdbeOp *pOp = &p->aOp[0]; |
| 62438 | + if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){ |
| 62439 | + z = pOp->p4.z; |
| 62440 | + while( sqlite3Isspace(*z) ) z++; |
| 62441 | + } |
| 62442 | + } |
| 62443 | + if( z ) printf("SQL: [%s]\n", z); |
| 62334 | 62444 | } |
| 62335 | 62445 | #endif |
| 62336 | 62446 | |
| 62337 | 62447 | #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) |
| 62338 | 62448 | /* |
| | @@ -62586,11 +62696,11 @@ |
| 62586 | 62696 | sqlite3BtreeCloseCursor(pCx->pCursor); |
| 62587 | 62697 | } |
| 62588 | 62698 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 62589 | 62699 | if( pCx->pVtabCursor ){ |
| 62590 | 62700 | sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; |
| 62591 | | - const sqlite3_module *pModule = pCx->pModule; |
| 62701 | + const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; |
| 62592 | 62702 | p->inVtabMethod = 1; |
| 62593 | 62703 | pModule->xClose(pVtabCursor); |
| 62594 | 62704 | p->inVtabMethod = 0; |
| 62595 | 62705 | } |
| 62596 | 62706 | #endif |
| | @@ -63570,11 +63680,11 @@ |
| 63570 | 63680 | #ifdef SQLITE_TEST |
| 63571 | 63681 | sqlite3_search_count++; |
| 63572 | 63682 | #endif |
| 63573 | 63683 | p->deferredMoveto = 0; |
| 63574 | 63684 | p->cacheStatus = CACHE_STALE; |
| 63575 | | - }else if( ALWAYS(p->pCursor) ){ |
| 63685 | + }else if( p->pCursor ){ |
| 63576 | 63686 | int hasMoved; |
| 63577 | 63687 | int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved); |
| 63578 | 63688 | if( rc ) return rc; |
| 63579 | 63689 | if( hasMoved ){ |
| 63580 | 63690 | p->cacheStatus = CACHE_STALE; |
| | @@ -63737,25 +63847,19 @@ |
| 63737 | 63847 | /* |
| 63738 | 63848 | ** Write the serialized data blob for the value stored in pMem into |
| 63739 | 63849 | ** buf. It is assumed that the caller has allocated sufficient space. |
| 63740 | 63850 | ** Return the number of bytes written. |
| 63741 | 63851 | ** |
| 63742 | | -** nBuf is the amount of space left in buf[]. nBuf must always be |
| 63743 | | -** large enough to hold the entire field. Except, if the field is |
| 63744 | | -** a blob with a zero-filled tail, then buf[] might be just the right |
| 63745 | | -** size to hold everything except for the zero-filled tail. If buf[] |
| 63746 | | -** is only big enough to hold the non-zero prefix, then only write that |
| 63747 | | -** prefix into buf[]. But if buf[] is large enough to hold both the |
| 63748 | | -** prefix and the tail then write the prefix and set the tail to all |
| 63749 | | -** zeros. |
| 63852 | +** nBuf is the amount of space left in buf[]. The caller is responsible |
| 63853 | +** for allocating enough space to buf[] to hold the entire field, exclusive |
| 63854 | +** of the pMem->u.nZero bytes for a MEM_Zero value. |
| 63750 | 63855 | ** |
| 63751 | 63856 | ** Return the number of bytes actually written into buf[]. The number |
| 63752 | 63857 | ** of bytes in the zero-filled tail is included in the return value only |
| 63753 | 63858 | ** if those bytes were zeroed in buf[]. |
| 63754 | 63859 | */ |
| 63755 | | -SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){ |
| 63756 | | - u32 serial_type = sqlite3VdbeSerialType(pMem, file_format); |
| 63860 | +SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ |
| 63757 | 63861 | u32 len; |
| 63758 | 63862 | |
| 63759 | 63863 | /* Integer and Real */ |
| 63760 | 63864 | if( serial_type<=7 && serial_type>0 ){ |
| 63761 | 63865 | u64 v; |
| | @@ -63766,11 +63870,10 @@ |
| 63766 | 63870 | swapMixedEndianFloat(v); |
| 63767 | 63871 | }else{ |
| 63768 | 63872 | v = pMem->u.i; |
| 63769 | 63873 | } |
| 63770 | 63874 | len = i = sqlite3VdbeSerialTypeLen(serial_type); |
| 63771 | | - assert( len<=(u32)nBuf ); |
| 63772 | 63875 | while( i-- ){ |
| 63773 | 63876 | buf[i] = (u8)(v&0xFF); |
| 63774 | 63877 | v >>= 8; |
| 63775 | 63878 | } |
| 63776 | 63879 | return len; |
| | @@ -63778,21 +63881,12 @@ |
| 63778 | 63881 | |
| 63779 | 63882 | /* String or blob */ |
| 63780 | 63883 | if( serial_type>=12 ){ |
| 63781 | 63884 | assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0) |
| 63782 | 63885 | == (int)sqlite3VdbeSerialTypeLen(serial_type) ); |
| 63783 | | - assert( pMem->n<=nBuf ); |
| 63784 | 63886 | len = pMem->n; |
| 63785 | 63887 | memcpy(buf, pMem->z, len); |
| 63786 | | - if( pMem->flags & MEM_Zero ){ |
| 63787 | | - len += pMem->u.nZero; |
| 63788 | | - assert( nBuf>=0 ); |
| 63789 | | - if( len > (u32)nBuf ){ |
| 63790 | | - len = (u32)nBuf; |
| 63791 | | - } |
| 63792 | | - memset(&buf[pMem->n], 0, len-pMem->n); |
| 63793 | | - } |
| 63794 | 63888 | return len; |
| 63795 | 63889 | } |
| 63796 | 63890 | |
| 63797 | 63891 | /* NULL or constants 0 or 1 */ |
| 63798 | 63892 | return 0; |
| | @@ -63878,19 +63972,16 @@ |
| 63878 | 63972 | pMem->u.i = serial_type-8; |
| 63879 | 63973 | pMem->flags = MEM_Int; |
| 63880 | 63974 | return 0; |
| 63881 | 63975 | } |
| 63882 | 63976 | default: { |
| 63977 | + static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; |
| 63883 | 63978 | u32 len = (serial_type-12)/2; |
| 63884 | 63979 | pMem->z = (char *)buf; |
| 63885 | 63980 | pMem->n = len; |
| 63886 | 63981 | pMem->xDel = 0; |
| 63887 | | - if( serial_type&0x01 ){ |
| 63888 | | - pMem->flags = MEM_Str | MEM_Ephem; |
| 63889 | | - }else{ |
| 63890 | | - pMem->flags = MEM_Blob | MEM_Ephem; |
| 63891 | | - } |
| 63982 | + pMem->flags = aFlag[serial_type&1]; |
| 63892 | 63983 | return len; |
| 63893 | 63984 | } |
| 63894 | 63985 | } |
| 63895 | 63986 | return 0; |
| 63896 | 63987 | } |
| | @@ -64025,13 +64116,15 @@ |
| 64025 | 64116 | */ |
| 64026 | 64117 | /* mem1.u.i = 0; // not needed, here to silence compiler warning */ |
| 64027 | 64118 | |
| 64028 | 64119 | idx1 = getVarint32(aKey1, szHdr1); |
| 64029 | 64120 | d1 = szHdr1; |
| 64030 | | - assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField ); |
| 64121 | + assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB ); |
| 64031 | 64122 | assert( pKeyInfo->aSortOrder!=0 ); |
| 64032 | | - while( idx1<szHdr1 && i<pPKey2->nField ){ |
| 64123 | + assert( pKeyInfo->nField>0 ); |
| 64124 | + assert( idx1<=szHdr1 || CORRUPT_DB ); |
| 64125 | + do{ |
| 64033 | 64126 | u32 serial_type1; |
| 64034 | 64127 | |
| 64035 | 64128 | /* Read the serial types for the next element in each key. */ |
| 64036 | 64129 | idx1 += getVarint32( aKey1+idx1, serial_type1 ); |
| 64037 | 64130 | |
| | @@ -64060,11 +64153,11 @@ |
| 64060 | 64153 | rc = -rc; /* Invert the result for DESC sort order. */ |
| 64061 | 64154 | } |
| 64062 | 64155 | return rc; |
| 64063 | 64156 | } |
| 64064 | 64157 | i++; |
| 64065 | | - } |
| 64158 | + }while( idx1<szHdr1 && i<pPKey2->nField ); |
| 64066 | 64159 | |
| 64067 | 64160 | /* No memory allocation is ever used on mem1. Prove this using |
| 64068 | 64161 | ** the following assert(). If the assert() fails, it indicates a |
| 64069 | 64162 | ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). |
| 64070 | 64163 | */ |
| | @@ -64118,11 +64211,11 @@ |
| 64118 | 64211 | assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */ |
| 64119 | 64212 | assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); |
| 64120 | 64213 | |
| 64121 | 64214 | /* Read in the complete content of the index entry */ |
| 64122 | 64215 | memset(&m, 0, sizeof(m)); |
| 64123 | | - rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m); |
| 64216 | + rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); |
| 64124 | 64217 | if( rc ){ |
| 64125 | 64218 | return rc; |
| 64126 | 64219 | } |
| 64127 | 64220 | |
| 64128 | 64221 | /* The index entry must begin with a header size */ |
| | @@ -64196,11 +64289,11 @@ |
| 64196 | 64289 | if( nCellKey<=0 || nCellKey>0x7fffffff ){ |
| 64197 | 64290 | *res = 0; |
| 64198 | 64291 | return SQLITE_CORRUPT_BKPT; |
| 64199 | 64292 | } |
| 64200 | 64293 | memset(&m, 0, sizeof(m)); |
| 64201 | | - rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m); |
| 64294 | + rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (u32)nCellKey, 1, &m); |
| 64202 | 64295 | if( rc ){ |
| 64203 | 64296 | return rc; |
| 64204 | 64297 | } |
| 64205 | 64298 | assert( pUnpacked->flags & UNPACKED_PREFIX_MATCH ); |
| 64206 | 64299 | *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); |
| | @@ -65715,10 +65808,11 @@ |
| 65715 | 65808 | if( db->nVdbeExec>1 ){ |
| 65716 | 65809 | while( *zRawSql ){ |
| 65717 | 65810 | const char *zStart = zRawSql; |
| 65718 | 65811 | while( *(zRawSql++)!='\n' && *zRawSql ); |
| 65719 | 65812 | sqlite3StrAccumAppend(&out, "-- ", 3); |
| 65813 | + assert( (zRawSql - zStart) > 0 ); |
| 65720 | 65814 | sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart)); |
| 65721 | 65815 | } |
| 65722 | 65816 | }else{ |
| 65723 | 65817 | while( zRawSql[0] ){ |
| 65724 | 65818 | n = findNextHostParameter(zRawSql, &nToken); |
| | @@ -66131,13 +66225,12 @@ |
| 66131 | 66225 | Mem *pMem = &p->aMem[p->nMem-iCur]; |
| 66132 | 66226 | |
| 66133 | 66227 | int nByte; |
| 66134 | 66228 | VdbeCursor *pCx = 0; |
| 66135 | 66229 | nByte = |
| 66136 | | - ROUND8(sizeof(VdbeCursor)) + |
| 66137 | | - (isBtreeCursor?sqlite3BtreeCursorSize():0) + |
| 66138 | | - 2*nField*sizeof(u32); |
| 66230 | + ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + |
| 66231 | + (isBtreeCursor?sqlite3BtreeCursorSize():0); |
| 66139 | 66232 | |
| 66140 | 66233 | assert( iCur<p->nCursor ); |
| 66141 | 66234 | if( p->apCsr[iCur] ){ |
| 66142 | 66235 | sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); |
| 66143 | 66236 | p->apCsr[iCur] = 0; |
| | @@ -66145,16 +66238,13 @@ |
| 66145 | 66238 | if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){ |
| 66146 | 66239 | p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; |
| 66147 | 66240 | memset(pCx, 0, sizeof(VdbeCursor)); |
| 66148 | 66241 | pCx->iDb = iDb; |
| 66149 | 66242 | pCx->nField = nField; |
| 66150 | | - if( nField ){ |
| 66151 | | - pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))]; |
| 66152 | | - } |
| 66153 | 66243 | if( isBtreeCursor ){ |
| 66154 | 66244 | pCx->pCursor = (BtCursor*) |
| 66155 | | - &pMem->z[ROUND8(sizeof(VdbeCursor))+2*nField*sizeof(u32)]; |
| 66245 | + &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; |
| 66156 | 66246 | sqlite3BtreeCursorZero(pCx->pCursor); |
| 66157 | 66247 | } |
| 66158 | 66248 | } |
| 66159 | 66249 | return pCx; |
| 66160 | 66250 | } |
| | @@ -66336,41 +66426,40 @@ |
| 66336 | 66426 | |
| 66337 | 66427 | #ifdef SQLITE_DEBUG |
| 66338 | 66428 | /* |
| 66339 | 66429 | ** Print the value of a register for tracing purposes: |
| 66340 | 66430 | */ |
| 66341 | | -static void memTracePrint(FILE *out, Mem *p){ |
| 66431 | +static void memTracePrint(Mem *p){ |
| 66342 | 66432 | if( p->flags & MEM_Invalid ){ |
| 66343 | | - fprintf(out, " undefined"); |
| 66433 | + printf(" undefined"); |
| 66344 | 66434 | }else if( p->flags & MEM_Null ){ |
| 66345 | | - fprintf(out, " NULL"); |
| 66435 | + printf(" NULL"); |
| 66346 | 66436 | }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ |
| 66347 | | - fprintf(out, " si:%lld", p->u.i); |
| 66437 | + printf(" si:%lld", p->u.i); |
| 66348 | 66438 | }else if( p->flags & MEM_Int ){ |
| 66349 | | - fprintf(out, " i:%lld", p->u.i); |
| 66439 | + printf(" i:%lld", p->u.i); |
| 66350 | 66440 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 66351 | 66441 | }else if( p->flags & MEM_Real ){ |
| 66352 | | - fprintf(out, " r:%g", p->r); |
| 66442 | + printf(" r:%g", p->r); |
| 66353 | 66443 | #endif |
| 66354 | 66444 | }else if( p->flags & MEM_RowSet ){ |
| 66355 | | - fprintf(out, " (rowset)"); |
| 66445 | + printf(" (rowset)"); |
| 66356 | 66446 | }else{ |
| 66357 | 66447 | char zBuf[200]; |
| 66358 | 66448 | sqlite3VdbeMemPrettyPrint(p, zBuf); |
| 66359 | | - fprintf(out, " "); |
| 66360 | | - fprintf(out, "%s", zBuf); |
| 66449 | + printf(" %s", zBuf); |
| 66361 | 66450 | } |
| 66362 | 66451 | } |
| 66363 | | -static void registerTrace(FILE *out, int iReg, Mem *p){ |
| 66364 | | - fprintf(out, "REG[%d] = ", iReg); |
| 66365 | | - memTracePrint(out, p); |
| 66366 | | - fprintf(out, "\n"); |
| 66452 | +static void registerTrace(int iReg, Mem *p){ |
| 66453 | + printf("REG[%d] = ", iReg); |
| 66454 | + memTracePrint(p); |
| 66455 | + printf("\n"); |
| 66367 | 66456 | } |
| 66368 | 66457 | #endif |
| 66369 | 66458 | |
| 66370 | 66459 | #ifdef SQLITE_DEBUG |
| 66371 | | -# define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M) |
| 66460 | +# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) |
| 66372 | 66461 | #else |
| 66373 | 66462 | # define REGISTER_TRACE(R,M) |
| 66374 | 66463 | #endif |
| 66375 | 66464 | |
| 66376 | 66465 | |
| | @@ -66563,438 +66652,11 @@ |
| 66563 | 66652 | i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */ |
| 66564 | 66653 | #ifdef VDBE_PROFILE |
| 66565 | 66654 | u64 start; /* CPU clock count at start of opcode */ |
| 66566 | 66655 | int origPc; /* Program counter at start of opcode */ |
| 66567 | 66656 | #endif |
| 66568 | | - /******************************************************************** |
| 66569 | | - ** Automatically generated code |
| 66570 | | - ** |
| 66571 | | - ** The following union is automatically generated by the |
| 66572 | | - ** vdbe-compress.tcl script. The purpose of this union is to |
| 66573 | | - ** reduce the amount of stack space required by this function. |
| 66574 | | - ** See comments in the vdbe-compress.tcl script for details. |
| 66575 | | - */ |
| 66576 | | - union vdbeExecUnion { |
| 66577 | | - struct OP_Yield_stack_vars { |
| 66578 | | - int pcDest; |
| 66579 | | - } aa; |
| 66580 | | - struct OP_Halt_stack_vars { |
| 66581 | | - const char *zType; |
| 66582 | | - const char *zLogFmt; |
| 66583 | | - } ab; |
| 66584 | | - struct OP_Null_stack_vars { |
| 66585 | | - int cnt; |
| 66586 | | - u16 nullFlag; |
| 66587 | | - } ac; |
| 66588 | | - struct OP_Variable_stack_vars { |
| 66589 | | - Mem *pVar; /* Value being transferred */ |
| 66590 | | - } ad; |
| 66591 | | - struct OP_Move_stack_vars { |
| 66592 | | - char *zMalloc; /* Holding variable for allocated memory */ |
| 66593 | | - int n; /* Number of registers left to copy */ |
| 66594 | | - int p1; /* Register to copy from */ |
| 66595 | | - int p2; /* Register to copy to */ |
| 66596 | | - } ae; |
| 66597 | | - struct OP_Copy_stack_vars { |
| 66598 | | - int n; |
| 66599 | | - } af; |
| 66600 | | - struct OP_ResultRow_stack_vars { |
| 66601 | | - Mem *pMem; |
| 66602 | | - int i; |
| 66603 | | - } ag; |
| 66604 | | - struct OP_Concat_stack_vars { |
| 66605 | | - i64 nByte; |
| 66606 | | - } ah; |
| 66607 | | - struct OP_Remainder_stack_vars { |
| 66608 | | - char bIntint; /* Started out as two integer operands */ |
| 66609 | | - int flags; /* Combined MEM_* flags from both inputs */ |
| 66610 | | - i64 iA; /* Integer value of left operand */ |
| 66611 | | - i64 iB; /* Integer value of right operand */ |
| 66612 | | - double rA; /* Real value of left operand */ |
| 66613 | | - double rB; /* Real value of right operand */ |
| 66614 | | - } ai; |
| 66615 | | - struct OP_Function_stack_vars { |
| 66616 | | - int i; |
| 66617 | | - Mem *pArg; |
| 66618 | | - sqlite3_context ctx; |
| 66619 | | - sqlite3_value **apVal; |
| 66620 | | - int n; |
| 66621 | | - } aj; |
| 66622 | | - struct OP_ShiftRight_stack_vars { |
| 66623 | | - i64 iA; |
| 66624 | | - u64 uA; |
| 66625 | | - i64 iB; |
| 66626 | | - u8 op; |
| 66627 | | - } ak; |
| 66628 | | - struct OP_Ge_stack_vars { |
| 66629 | | - int res; /* Result of the comparison of pIn1 against pIn3 */ |
| 66630 | | - char affinity; /* Affinity to use for comparison */ |
| 66631 | | - u16 flags1; /* Copy of initial value of pIn1->flags */ |
| 66632 | | - u16 flags3; /* Copy of initial value of pIn3->flags */ |
| 66633 | | - } al; |
| 66634 | | - struct OP_Compare_stack_vars { |
| 66635 | | - int n; |
| 66636 | | - int i; |
| 66637 | | - int p1; |
| 66638 | | - int p2; |
| 66639 | | - const KeyInfo *pKeyInfo; |
| 66640 | | - int idx; |
| 66641 | | - CollSeq *pColl; /* Collating sequence to use on this term */ |
| 66642 | | - int bRev; /* True for DESCENDING sort order */ |
| 66643 | | - } am; |
| 66644 | | - struct OP_Or_stack_vars { |
| 66645 | | - int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
| 66646 | | - int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
| 66647 | | - } an; |
| 66648 | | - struct OP_IfNot_stack_vars { |
| 66649 | | - int c; |
| 66650 | | - } ao; |
| 66651 | | - struct OP_Column_stack_vars { |
| 66652 | | - u32 payloadSize; /* Number of bytes in the record */ |
| 66653 | | - i64 payloadSize64; /* Number of bytes in the record */ |
| 66654 | | - int p1; /* P1 value of the opcode */ |
| 66655 | | - int p2; /* column number to retrieve */ |
| 66656 | | - VdbeCursor *pC; /* The VDBE cursor */ |
| 66657 | | - char *zRec; /* Pointer to complete record-data */ |
| 66658 | | - BtCursor *pCrsr; /* The BTree cursor */ |
| 66659 | | - u32 *aType; /* aType[i] holds the numeric type of the i-th column */ |
| 66660 | | - u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ |
| 66661 | | - int nField; /* number of fields in the record */ |
| 66662 | | - int len; /* The length of the serialized data for the column */ |
| 66663 | | - int i; /* Loop counter */ |
| 66664 | | - char *zData; /* Part of the record being decoded */ |
| 66665 | | - Mem *pDest; /* Where to write the extracted value */ |
| 66666 | | - Mem sMem; /* For storing the record being decoded */ |
| 66667 | | - u8 *zIdx; /* Index into header */ |
| 66668 | | - u8 *zEndHdr; /* Pointer to first byte after the header */ |
| 66669 | | - u32 offset; /* Offset into the data */ |
| 66670 | | - u32 szField; /* Number of bytes in the content of a field */ |
| 66671 | | - int szHdr; /* Size of the header size field at start of record */ |
| 66672 | | - int avail; /* Number of bytes of available data */ |
| 66673 | | - u32 t; /* A type code from the record header */ |
| 66674 | | - Mem *pReg; /* PseudoTable input register */ |
| 66675 | | - } ap; |
| 66676 | | - struct OP_Affinity_stack_vars { |
| 66677 | | - const char *zAffinity; /* The affinity to be applied */ |
| 66678 | | - char cAff; /* A single character of affinity */ |
| 66679 | | - } aq; |
| 66680 | | - struct OP_MakeRecord_stack_vars { |
| 66681 | | - u8 *zNewRecord; /* A buffer to hold the data for the new record */ |
| 66682 | | - Mem *pRec; /* The new record */ |
| 66683 | | - u64 nData; /* Number of bytes of data space */ |
| 66684 | | - int nHdr; /* Number of bytes of header space */ |
| 66685 | | - i64 nByte; /* Data space required for this record */ |
| 66686 | | - int nZero; /* Number of zero bytes at the end of the record */ |
| 66687 | | - int nVarint; /* Number of bytes in a varint */ |
| 66688 | | - u32 serial_type; /* Type field */ |
| 66689 | | - Mem *pData0; /* First field to be combined into the record */ |
| 66690 | | - Mem *pLast; /* Last field of the record */ |
| 66691 | | - int nField; /* Number of fields in the record */ |
| 66692 | | - char *zAffinity; /* The affinity string for the record */ |
| 66693 | | - int file_format; /* File format to use for encoding */ |
| 66694 | | - int i; /* Space used in zNewRecord[] */ |
| 66695 | | - int len; /* Length of a field */ |
| 66696 | | - } ar; |
| 66697 | | - struct OP_Count_stack_vars { |
| 66698 | | - i64 nEntry; |
| 66699 | | - BtCursor *pCrsr; |
| 66700 | | - } as; |
| 66701 | | - struct OP_Savepoint_stack_vars { |
| 66702 | | - int p1; /* Value of P1 operand */ |
| 66703 | | - char *zName; /* Name of savepoint */ |
| 66704 | | - int nName; |
| 66705 | | - Savepoint *pNew; |
| 66706 | | - Savepoint *pSavepoint; |
| 66707 | | - Savepoint *pTmp; |
| 66708 | | - int iSavepoint; |
| 66709 | | - int ii; |
| 66710 | | - } at; |
| 66711 | | - struct OP_AutoCommit_stack_vars { |
| 66712 | | - int desiredAutoCommit; |
| 66713 | | - int iRollback; |
| 66714 | | - int turnOnAC; |
| 66715 | | - } au; |
| 66716 | | - struct OP_Transaction_stack_vars { |
| 66717 | | - Btree *pBt; |
| 66718 | | - } av; |
| 66719 | | - struct OP_ReadCookie_stack_vars { |
| 66720 | | - int iMeta; |
| 66721 | | - int iDb; |
| 66722 | | - int iCookie; |
| 66723 | | - } aw; |
| 66724 | | - struct OP_SetCookie_stack_vars { |
| 66725 | | - Db *pDb; |
| 66726 | | - } ax; |
| 66727 | | - struct OP_VerifyCookie_stack_vars { |
| 66728 | | - int iMeta; |
| 66729 | | - int iGen; |
| 66730 | | - Btree *pBt; |
| 66731 | | - } ay; |
| 66732 | | - struct OP_OpenWrite_stack_vars { |
| 66733 | | - int nField; |
| 66734 | | - KeyInfo *pKeyInfo; |
| 66735 | | - int p2; |
| 66736 | | - int iDb; |
| 66737 | | - int wrFlag; |
| 66738 | | - Btree *pX; |
| 66739 | | - VdbeCursor *pCur; |
| 66740 | | - Db *pDb; |
| 66741 | | - } az; |
| 66742 | | - struct OP_OpenEphemeral_stack_vars { |
| 66743 | | - VdbeCursor *pCx; |
| 66744 | | - KeyInfo *pKeyInfo; |
| 66745 | | - } ba; |
| 66746 | | - struct OP_SorterOpen_stack_vars { |
| 66747 | | - VdbeCursor *pCx; |
| 66748 | | - } bb; |
| 66749 | | - struct OP_OpenPseudo_stack_vars { |
| 66750 | | - VdbeCursor *pCx; |
| 66751 | | - } bc; |
| 66752 | | - struct OP_SeekGt_stack_vars { |
| 66753 | | - int res; |
| 66754 | | - int oc; |
| 66755 | | - VdbeCursor *pC; |
| 66756 | | - UnpackedRecord r; |
| 66757 | | - int nField; |
| 66758 | | - i64 iKey; /* The rowid we are to seek to */ |
| 66759 | | - } bd; |
| 66760 | | - struct OP_Seek_stack_vars { |
| 66761 | | - VdbeCursor *pC; |
| 66762 | | - } be; |
| 66763 | | - struct OP_Found_stack_vars { |
| 66764 | | - int alreadyExists; |
| 66765 | | - int ii; |
| 66766 | | - VdbeCursor *pC; |
| 66767 | | - int res; |
| 66768 | | - char *pFree; |
| 66769 | | - UnpackedRecord *pIdxKey; |
| 66770 | | - UnpackedRecord r; |
| 66771 | | - char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7]; |
| 66772 | | - } bf; |
| 66773 | | - struct OP_NotExists_stack_vars { |
| 66774 | | - VdbeCursor *pC; |
| 66775 | | - BtCursor *pCrsr; |
| 66776 | | - int res; |
| 66777 | | - u64 iKey; |
| 66778 | | - } bg; |
| 66779 | | - struct OP_NewRowid_stack_vars { |
| 66780 | | - i64 v; /* The new rowid */ |
| 66781 | | - VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 66782 | | - int res; /* Result of an sqlite3BtreeLast() */ |
| 66783 | | - int cnt; /* Counter to limit the number of searches */ |
| 66784 | | - Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 66785 | | - VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 66786 | | - } bh; |
| 66787 | | - struct OP_InsertInt_stack_vars { |
| 66788 | | - Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 66789 | | - Mem *pKey; /* MEM cell holding key for the record */ |
| 66790 | | - i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 66791 | | - VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| 66792 | | - int nZero; /* Number of zero-bytes to append */ |
| 66793 | | - int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 66794 | | - const char *zDb; /* database name - used by the update hook */ |
| 66795 | | - const char *zTbl; /* Table name - used by the opdate hook */ |
| 66796 | | - int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 66797 | | - } bi; |
| 66798 | | - struct OP_Delete_stack_vars { |
| 66799 | | - i64 iKey; |
| 66800 | | - VdbeCursor *pC; |
| 66801 | | - } bj; |
| 66802 | | - struct OP_SorterCompare_stack_vars { |
| 66803 | | - VdbeCursor *pC; |
| 66804 | | - int res; |
| 66805 | | - int nIgnore; |
| 66806 | | - } bk; |
| 66807 | | - struct OP_SorterData_stack_vars { |
| 66808 | | - VdbeCursor *pC; |
| 66809 | | - } bl; |
| 66810 | | - struct OP_RowData_stack_vars { |
| 66811 | | - VdbeCursor *pC; |
| 66812 | | - BtCursor *pCrsr; |
| 66813 | | - u32 n; |
| 66814 | | - i64 n64; |
| 66815 | | - } bm; |
| 66816 | | - struct OP_Rowid_stack_vars { |
| 66817 | | - VdbeCursor *pC; |
| 66818 | | - i64 v; |
| 66819 | | - sqlite3_vtab *pVtab; |
| 66820 | | - const sqlite3_module *pModule; |
| 66821 | | - } bn; |
| 66822 | | - struct OP_NullRow_stack_vars { |
| 66823 | | - VdbeCursor *pC; |
| 66824 | | - } bo; |
| 66825 | | - struct OP_Last_stack_vars { |
| 66826 | | - VdbeCursor *pC; |
| 66827 | | - BtCursor *pCrsr; |
| 66828 | | - int res; |
| 66829 | | - } bp; |
| 66830 | | - struct OP_Rewind_stack_vars { |
| 66831 | | - VdbeCursor *pC; |
| 66832 | | - BtCursor *pCrsr; |
| 66833 | | - int res; |
| 66834 | | - } bq; |
| 66835 | | - struct OP_Next_stack_vars { |
| 66836 | | - VdbeCursor *pC; |
| 66837 | | - int res; |
| 66838 | | - } br; |
| 66839 | | - struct OP_IdxInsert_stack_vars { |
| 66840 | | - VdbeCursor *pC; |
| 66841 | | - BtCursor *pCrsr; |
| 66842 | | - int nKey; |
| 66843 | | - const char *zKey; |
| 66844 | | - } bs; |
| 66845 | | - struct OP_IdxDelete_stack_vars { |
| 66846 | | - VdbeCursor *pC; |
| 66847 | | - BtCursor *pCrsr; |
| 66848 | | - int res; |
| 66849 | | - UnpackedRecord r; |
| 66850 | | - } bt; |
| 66851 | | - struct OP_IdxRowid_stack_vars { |
| 66852 | | - BtCursor *pCrsr; |
| 66853 | | - VdbeCursor *pC; |
| 66854 | | - i64 rowid; |
| 66855 | | - } bu; |
| 66856 | | - struct OP_IdxGE_stack_vars { |
| 66857 | | - VdbeCursor *pC; |
| 66858 | | - int res; |
| 66859 | | - UnpackedRecord r; |
| 66860 | | - } bv; |
| 66861 | | - struct OP_Destroy_stack_vars { |
| 66862 | | - int iMoved; |
| 66863 | | - int iCnt; |
| 66864 | | - Vdbe *pVdbe; |
| 66865 | | - int iDb; |
| 66866 | | - } bw; |
| 66867 | | - struct OP_Clear_stack_vars { |
| 66868 | | - int nChange; |
| 66869 | | - } bx; |
| 66870 | | - struct OP_CreateTable_stack_vars { |
| 66871 | | - int pgno; |
| 66872 | | - int flags; |
| 66873 | | - Db *pDb; |
| 66874 | | - } by; |
| 66875 | | - struct OP_ParseSchema_stack_vars { |
| 66876 | | - int iDb; |
| 66877 | | - const char *zMaster; |
| 66878 | | - char *zSql; |
| 66879 | | - InitData initData; |
| 66880 | | - } bz; |
| 66881 | | - struct OP_IntegrityCk_stack_vars { |
| 66882 | | - int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 66883 | | - int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 66884 | | - int j; /* Loop counter */ |
| 66885 | | - int nErr; /* Number of errors reported */ |
| 66886 | | - char *z; /* Text of the error report */ |
| 66887 | | - Mem *pnErr; /* Register keeping track of errors remaining */ |
| 66888 | | - } ca; |
| 66889 | | - struct OP_RowSetRead_stack_vars { |
| 66890 | | - i64 val; |
| 66891 | | - } cb; |
| 66892 | | - struct OP_RowSetTest_stack_vars { |
| 66893 | | - int iSet; |
| 66894 | | - int exists; |
| 66895 | | - } cc; |
| 66896 | | - struct OP_Program_stack_vars { |
| 66897 | | - int nMem; /* Number of memory registers for sub-program */ |
| 66898 | | - int nByte; /* Bytes of runtime space required for sub-program */ |
| 66899 | | - Mem *pRt; /* Register to allocate runtime space */ |
| 66900 | | - Mem *pMem; /* Used to iterate through memory cells */ |
| 66901 | | - Mem *pEnd; /* Last memory cell in new array */ |
| 66902 | | - VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 66903 | | - SubProgram *pProgram; /* Sub-program to execute */ |
| 66904 | | - void *t; /* Token identifying trigger */ |
| 66905 | | - } cd; |
| 66906 | | - struct OP_Param_stack_vars { |
| 66907 | | - VdbeFrame *pFrame; |
| 66908 | | - Mem *pIn; |
| 66909 | | - } ce; |
| 66910 | | - struct OP_MemMax_stack_vars { |
| 66911 | | - Mem *pIn1; |
| 66912 | | - VdbeFrame *pFrame; |
| 66913 | | - } cf; |
| 66914 | | - struct OP_AggStep_stack_vars { |
| 66915 | | - int n; |
| 66916 | | - int i; |
| 66917 | | - Mem *pMem; |
| 66918 | | - Mem *pRec; |
| 66919 | | - sqlite3_context ctx; |
| 66920 | | - sqlite3_value **apVal; |
| 66921 | | - } cg; |
| 66922 | | - struct OP_AggFinal_stack_vars { |
| 66923 | | - Mem *pMem; |
| 66924 | | - } ch; |
| 66925 | | - struct OP_Checkpoint_stack_vars { |
| 66926 | | - int i; /* Loop counter */ |
| 66927 | | - int aRes[3]; /* Results */ |
| 66928 | | - Mem *pMem; /* Write results here */ |
| 66929 | | - } ci; |
| 66930 | | - struct OP_JournalMode_stack_vars { |
| 66931 | | - Btree *pBt; /* Btree to change journal mode of */ |
| 66932 | | - Pager *pPager; /* Pager associated with pBt */ |
| 66933 | | - int eNew; /* New journal mode */ |
| 66934 | | - int eOld; /* The old journal mode */ |
| 66935 | | -#ifndef SQLITE_OMIT_WAL |
| 66936 | | - const char *zFilename; /* Name of database file for pPager */ |
| 66937 | | -#endif |
| 66938 | | - } cj; |
| 66939 | | - struct OP_IncrVacuum_stack_vars { |
| 66940 | | - Btree *pBt; |
| 66941 | | - } ck; |
| 66942 | | - struct OP_VBegin_stack_vars { |
| 66943 | | - VTable *pVTab; |
| 66944 | | - } cl; |
| 66945 | | - struct OP_VOpen_stack_vars { |
| 66946 | | - VdbeCursor *pCur; |
| 66947 | | - sqlite3_vtab_cursor *pVtabCursor; |
| 66948 | | - sqlite3_vtab *pVtab; |
| 66949 | | - sqlite3_module *pModule; |
| 66950 | | - } cm; |
| 66951 | | - struct OP_VFilter_stack_vars { |
| 66952 | | - int nArg; |
| 66953 | | - int iQuery; |
| 66954 | | - const sqlite3_module *pModule; |
| 66955 | | - Mem *pQuery; |
| 66956 | | - Mem *pArgc; |
| 66957 | | - sqlite3_vtab_cursor *pVtabCursor; |
| 66958 | | - sqlite3_vtab *pVtab; |
| 66959 | | - VdbeCursor *pCur; |
| 66960 | | - int res; |
| 66961 | | - int i; |
| 66962 | | - Mem **apArg; |
| 66963 | | - } cn; |
| 66964 | | - struct OP_VColumn_stack_vars { |
| 66965 | | - sqlite3_vtab *pVtab; |
| 66966 | | - const sqlite3_module *pModule; |
| 66967 | | - Mem *pDest; |
| 66968 | | - sqlite3_context sContext; |
| 66969 | | - } co; |
| 66970 | | - struct OP_VNext_stack_vars { |
| 66971 | | - sqlite3_vtab *pVtab; |
| 66972 | | - const sqlite3_module *pModule; |
| 66973 | | - int res; |
| 66974 | | - VdbeCursor *pCur; |
| 66975 | | - } cp; |
| 66976 | | - struct OP_VRename_stack_vars { |
| 66977 | | - sqlite3_vtab *pVtab; |
| 66978 | | - Mem *pName; |
| 66979 | | - } cq; |
| 66980 | | - struct OP_VUpdate_stack_vars { |
| 66981 | | - sqlite3_vtab *pVtab; |
| 66982 | | - sqlite3_module *pModule; |
| 66983 | | - int nArg; |
| 66984 | | - int i; |
| 66985 | | - sqlite_int64 rowid; |
| 66986 | | - Mem **apArg; |
| 66987 | | - Mem *pX; |
| 66988 | | - } cr; |
| 66989 | | - struct OP_Trace_stack_vars { |
| 66990 | | - char *zTrace; |
| 66991 | | - char *z; |
| 66992 | | - } cs; |
| 66993 | | - } u; |
| 66994 | | - /* End automatically generated code |
| 66995 | | - ********************************************************************/ |
| 66657 | + /*** INSERT STACK UNION HERE ***/ |
| 66996 | 66658 | |
| 66997 | 66659 | assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ |
| 66998 | 66660 | sqlite3VdbeEnter(p); |
| 66999 | 66661 | if( p->rc==SQLITE_NOMEM ){ |
| 67000 | 66662 | /* This happens if a malloc() inside a call to sqlite3_column_text() or |
| | @@ -67021,17 +66683,32 @@ |
| 67021 | 66683 | } |
| 67022 | 66684 | } |
| 67023 | 66685 | #endif |
| 67024 | 66686 | #ifdef SQLITE_DEBUG |
| 67025 | 66687 | sqlite3BeginBenignMalloc(); |
| 67026 | | - if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){ |
| 66688 | + if( p->pc==0 |
| 66689 | + && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0 |
| 66690 | + ){ |
| 67027 | 66691 | int i; |
| 67028 | | - printf("VDBE Program Listing:\n"); |
| 66692 | + int once = 1; |
| 67029 | 66693 | sqlite3VdbePrintSql(p); |
| 67030 | | - for(i=0; i<p->nOp; i++){ |
| 67031 | | - sqlite3VdbePrintOp(stdout, i, &aOp[i]); |
| 66694 | + if( p->db->flags & SQLITE_VdbeListing ){ |
| 66695 | + printf("VDBE Program Listing:\n"); |
| 66696 | + for(i=0; i<p->nOp; i++){ |
| 66697 | + sqlite3VdbePrintOp(stdout, i, &aOp[i]); |
| 66698 | + } |
| 67032 | 66699 | } |
| 66700 | + if( p->db->flags & SQLITE_VdbeEQP ){ |
| 66701 | + for(i=0; i<p->nOp; i++){ |
| 66702 | + if( aOp[i].opcode==OP_Explain ){ |
| 66703 | + if( once ) printf("VDBE Query Plan:\n"); |
| 66704 | + printf("%s\n", aOp[i].p4.z); |
| 66705 | + once = 0; |
| 66706 | + } |
| 66707 | + } |
| 66708 | + } |
| 66709 | + if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); |
| 67033 | 66710 | } |
| 67034 | 66711 | sqlite3EndBenignMalloc(); |
| 67035 | 66712 | #endif |
| 67036 | 66713 | for(pc=p->pc; rc==SQLITE_OK; pc++){ |
| 67037 | 66714 | assert( pc>=0 && pc<p->nOp ); |
| | @@ -67044,16 +66721,12 @@ |
| 67044 | 66721 | pOp = &aOp[pc]; |
| 67045 | 66722 | |
| 67046 | 66723 | /* Only allow tracing if SQLITE_DEBUG is defined. |
| 67047 | 66724 | */ |
| 67048 | 66725 | #ifdef SQLITE_DEBUG |
| 67049 | | - if( p->trace ){ |
| 67050 | | - if( pc==0 ){ |
| 67051 | | - printf("VDBE Execution Trace:\n"); |
| 67052 | | - sqlite3VdbePrintSql(p); |
| 67053 | | - } |
| 67054 | | - sqlite3VdbePrintOp(p->trace, pc, pOp); |
| 66726 | + if( db->flags & SQLITE_VdbeTrace ){ |
| 66727 | + sqlite3VdbePrintOp(stdout, pc, pOp); |
| 67055 | 66728 | } |
| 67056 | 66729 | #endif |
| 67057 | 66730 | |
| 67058 | 66731 | |
| 67059 | 66732 | /* Check to see if we need to simulate an interrupt. This only happens |
| | @@ -67180,19 +66853,16 @@ |
| 67180 | 66853 | ** sqlite3VdbeExec() or since last time the progress callback was called). |
| 67181 | 66854 | ** If the progress callback returns non-zero, exit the virtual machine with |
| 67182 | 66855 | ** a return code SQLITE_ABORT. |
| 67183 | 66856 | */ |
| 67184 | 66857 | if( db->xProgress!=0 && nVmStep>=nProgressLimit ){ |
| 67185 | | - int prc; |
| 67186 | | - prc = db->xProgress(db->pProgressArg); |
| 67187 | | - if( prc!=0 ){ |
| 66858 | + assert( db->nProgressOps!=0 ); |
| 66859 | + nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); |
| 66860 | + if( db->xProgress(db->pProgressArg) ){ |
| 67188 | 66861 | rc = SQLITE_INTERRUPT; |
| 67189 | 66862 | goto vdbe_error_halt; |
| 67190 | 66863 | } |
| 67191 | | - if( db->xProgress!=0 ){ |
| 67192 | | - nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps); |
| 67193 | | - } |
| 67194 | 66864 | } |
| 67195 | 66865 | #endif |
| 67196 | 66866 | |
| 67197 | 66867 | break; |
| 67198 | 66868 | } |
| | @@ -67228,20 +66898,18 @@ |
| 67228 | 66898 | /* Opcode: Yield P1 * * * * |
| 67229 | 66899 | ** |
| 67230 | 66900 | ** Swap the program counter with the value in register P1. |
| 67231 | 66901 | */ |
| 67232 | 66902 | case OP_Yield: { /* in1 */ |
| 67233 | | -#if 0 /* local variables moved into u.aa */ |
| 67234 | 66903 | int pcDest; |
| 67235 | | -#endif /* local variables moved into u.aa */ |
| 67236 | 66904 | pIn1 = &aMem[pOp->p1]; |
| 67237 | 66905 | assert( (pIn1->flags & MEM_Dyn)==0 ); |
| 67238 | 66906 | pIn1->flags = MEM_Int; |
| 67239 | | - u.aa.pcDest = (int)pIn1->u.i; |
| 66907 | + pcDest = (int)pIn1->u.i; |
| 67240 | 66908 | pIn1->u.i = pc; |
| 67241 | 66909 | REGISTER_TRACE(pOp->p1, pIn1); |
| 67242 | | - pc = u.aa.pcDest; |
| 66910 | + pc = pcDest; |
| 67243 | 66911 | break; |
| 67244 | 66912 | } |
| 67245 | 66913 | |
| 67246 | 66914 | /* Opcode: HaltIfNull P1 P2 P3 P4 P5 |
| 67247 | 66915 | ** Synopsis: if r[P3] null then halt |
| | @@ -67286,14 +66954,12 @@ |
| 67286 | 66954 | ** There is an implied "Halt 0 0 0" instruction inserted at the very end of |
| 67287 | 66955 | ** every program. So a jump past the last instruction of the program |
| 67288 | 66956 | ** is the same as executing Halt. |
| 67289 | 66957 | */ |
| 67290 | 66958 | case OP_Halt: { |
| 67291 | | -#if 0 /* local variables moved into u.ab */ |
| 67292 | 66959 | const char *zType; |
| 67293 | 66960 | const char *zLogFmt; |
| 67294 | | -#endif /* local variables moved into u.ab */ |
| 67295 | 66961 | |
| 67296 | 66962 | if( pOp->p1==SQLITE_OK && p->pFrame ){ |
| 67297 | 66963 | /* Halt the sub-program. Return control to the parent frame. */ |
| 67298 | 66964 | VdbeFrame *pFrame = p->pFrame; |
| 67299 | 66965 | p->pFrame = pFrame->pParent; |
| | @@ -67300,11 +66966,11 @@ |
| 67300 | 66966 | p->nFrame--; |
| 67301 | 66967 | sqlite3VdbeSetChanges(db, p->nChange); |
| 67302 | 66968 | pc = sqlite3VdbeFrameRestore(pFrame); |
| 67303 | 66969 | lastRowid = db->lastRowid; |
| 67304 | 66970 | if( pOp->p2==OE_Ignore ){ |
| 67305 | | - /* Instruction pc is the OP_Program that invoked the sub-program |
| 66971 | + /* Instruction pc is the OP_Program that invoked the sub-program |
| 67306 | 66972 | ** currently being halted. If the p2 instruction of this OP_Halt |
| 67307 | 66973 | ** instruction is set to OE_Ignore, then the sub-program is throwing |
| 67308 | 66974 | ** an IGNORE exception. In this case jump to the address specified |
| 67309 | 66975 | ** as the p2 of the calling OP_Program. */ |
| 67310 | 66976 | pc = p->aOp[pc].p2-1; |
| | @@ -67323,25 +66989,25 @@ |
| 67323 | 66989 | assert( pOp->p5>=1 && pOp->p5<=4 ); |
| 67324 | 66990 | testcase( pOp->p5==1 ); |
| 67325 | 66991 | testcase( pOp->p5==2 ); |
| 67326 | 66992 | testcase( pOp->p5==3 ); |
| 67327 | 66993 | testcase( pOp->p5==4 ); |
| 67328 | | - u.ab.zType = azType[pOp->p5-1]; |
| 66994 | + zType = azType[pOp->p5-1]; |
| 67329 | 66995 | }else{ |
| 67330 | | - u.ab.zType = 0; |
| 66996 | + zType = 0; |
| 67331 | 66997 | } |
| 67332 | | - assert( u.ab.zType!=0 || pOp->p4.z!=0 ); |
| 67333 | | - u.ab.zLogFmt = "abort at %d in [%s]: %s"; |
| 67334 | | - if( u.ab.zType && pOp->p4.z ){ |
| 67335 | | - sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s", |
| 67336 | | - u.ab.zType, pOp->p4.z); |
| 66998 | + assert( zType!=0 || pOp->p4.z!=0 ); |
| 66999 | + zLogFmt = "abort at %d in [%s]: %s"; |
| 67000 | + if( zType && pOp->p4.z ){ |
| 67001 | + sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s", |
| 67002 | + zType, pOp->p4.z); |
| 67337 | 67003 | }else if( pOp->p4.z ){ |
| 67338 | 67004 | sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); |
| 67339 | 67005 | }else{ |
| 67340 | | - sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", u.ab.zType); |
| 67006 | + sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType); |
| 67341 | 67007 | } |
| 67342 | | - sqlite3_log(pOp->p1, u.ab.zLogFmt, pc, p->zSql, p->zErrMsg); |
| 67008 | + sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg); |
| 67343 | 67009 | } |
| 67344 | 67010 | rc = sqlite3VdbeHalt(p); |
| 67345 | 67011 | assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); |
| 67346 | 67012 | if( rc==SQLITE_BUSY ){ |
| 67347 | 67013 | p->rc = rc = SQLITE_BUSY; |
| | @@ -67451,23 +67117,21 @@ |
| 67451 | 67117 | ** If the P1 value is non-zero, then also set the MEM_Cleared flag so that |
| 67452 | 67118 | ** NULL values will not compare equal even if SQLITE_NULLEQ is set on |
| 67453 | 67119 | ** OP_Ne or OP_Eq. |
| 67454 | 67120 | */ |
| 67455 | 67121 | case OP_Null: { /* out2-prerelease */ |
| 67456 | | -#if 0 /* local variables moved into u.ac */ |
| 67457 | 67122 | int cnt; |
| 67458 | 67123 | u16 nullFlag; |
| 67459 | | -#endif /* local variables moved into u.ac */ |
| 67460 | | - u.ac.cnt = pOp->p3-pOp->p2; |
| 67124 | + cnt = pOp->p3-pOp->p2; |
| 67461 | 67125 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 67462 | | - pOut->flags = u.ac.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 67463 | | - while( u.ac.cnt>0 ){ |
| 67126 | + pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 67127 | + while( cnt>0 ){ |
| 67464 | 67128 | pOut++; |
| 67465 | 67129 | memAboutToChange(p, pOut); |
| 67466 | 67130 | VdbeMemRelease(pOut); |
| 67467 | | - pOut->flags = u.ac.nullFlag; |
| 67468 | | - u.ac.cnt--; |
| 67131 | + pOut->flags = nullFlag; |
| 67132 | + cnt--; |
| 67469 | 67133 | } |
| 67470 | 67134 | break; |
| 67471 | 67135 | } |
| 67472 | 67136 | |
| 67473 | 67137 | |
| | @@ -67492,21 +67156,19 @@ |
| 67492 | 67156 | ** |
| 67493 | 67157 | ** If the parameter is named, then its name appears in P4 and P3==1. |
| 67494 | 67158 | ** The P4 value is used by sqlite3_bind_parameter_name(). |
| 67495 | 67159 | */ |
| 67496 | 67160 | case OP_Variable: { /* out2-prerelease */ |
| 67497 | | -#if 0 /* local variables moved into u.ad */ |
| 67498 | 67161 | Mem *pVar; /* Value being transferred */ |
| 67499 | | -#endif /* local variables moved into u.ad */ |
| 67500 | 67162 | |
| 67501 | 67163 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 67502 | 67164 | assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); |
| 67503 | | - u.ad.pVar = &p->aVar[pOp->p1 - 1]; |
| 67504 | | - if( sqlite3VdbeMemTooBig(u.ad.pVar) ){ |
| 67165 | + pVar = &p->aVar[pOp->p1 - 1]; |
| 67166 | + if( sqlite3VdbeMemTooBig(pVar) ){ |
| 67505 | 67167 | goto too_big; |
| 67506 | 67168 | } |
| 67507 | | - sqlite3VdbeMemShallowCopy(pOut, u.ad.pVar, MEM_Static); |
| 67169 | + sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static); |
| 67508 | 67170 | UPDATE_MAX_BLOBSIZE(pOut); |
| 67509 | 67171 | break; |
| 67510 | 67172 | } |
| 67511 | 67173 | |
| 67512 | 67174 | /* Opcode: Move P1 P2 P3 * * |
| | @@ -67516,43 +67178,41 @@ |
| 67516 | 67178 | ** registers P2..P2+P3. Registers P1..P1+P3 are |
| 67517 | 67179 | ** left holding a NULL. It is an error for register ranges |
| 67518 | 67180 | ** P1..P1+P3 and P2..P2+P3 to overlap. |
| 67519 | 67181 | */ |
| 67520 | 67182 | case OP_Move: { |
| 67521 | | -#if 0 /* local variables moved into u.ae */ |
| 67522 | 67183 | char *zMalloc; /* Holding variable for allocated memory */ |
| 67523 | 67184 | int n; /* Number of registers left to copy */ |
| 67524 | 67185 | int p1; /* Register to copy from */ |
| 67525 | 67186 | int p2; /* Register to copy to */ |
| 67526 | | -#endif /* local variables moved into u.ae */ |
| 67527 | | - |
| 67528 | | - u.ae.n = pOp->p3 + 1; |
| 67529 | | - u.ae.p1 = pOp->p1; |
| 67530 | | - u.ae.p2 = pOp->p2; |
| 67531 | | - assert( u.ae.n>0 && u.ae.p1>0 && u.ae.p2>0 ); |
| 67532 | | - assert( u.ae.p1+u.ae.n<=u.ae.p2 || u.ae.p2+u.ae.n<=u.ae.p1 ); |
| 67533 | | - |
| 67534 | | - pIn1 = &aMem[u.ae.p1]; |
| 67535 | | - pOut = &aMem[u.ae.p2]; |
| 67536 | | - while( u.ae.n-- ){ |
| 67187 | + |
| 67188 | + n = pOp->p3; |
| 67189 | + p1 = pOp->p1; |
| 67190 | + p2 = pOp->p2; |
| 67191 | + assert( n>=0 && p1>0 && p2>0 ); |
| 67192 | + assert( p1+n<=p2 || p2+n<=p1 ); |
| 67193 | + |
| 67194 | + pIn1 = &aMem[p1]; |
| 67195 | + pOut = &aMem[p2]; |
| 67196 | + do{ |
| 67537 | 67197 | assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); |
| 67538 | 67198 | assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); |
| 67539 | 67199 | assert( memIsValid(pIn1) ); |
| 67540 | 67200 | memAboutToChange(p, pOut); |
| 67541 | | - u.ae.zMalloc = pOut->zMalloc; |
| 67201 | + zMalloc = pOut->zMalloc; |
| 67542 | 67202 | pOut->zMalloc = 0; |
| 67543 | 67203 | sqlite3VdbeMemMove(pOut, pIn1); |
| 67544 | 67204 | #ifdef SQLITE_DEBUG |
| 67545 | | - if( pOut->pScopyFrom>=&aMem[u.ae.p1] && pOut->pScopyFrom<&aMem[u.ae.p1+pOp->p3] ){ |
| 67546 | | - pOut->pScopyFrom += u.ae.p1 - pOp->p2; |
| 67205 | + if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){ |
| 67206 | + pOut->pScopyFrom += p1 - pOp->p2; |
| 67547 | 67207 | } |
| 67548 | 67208 | #endif |
| 67549 | | - pIn1->zMalloc = u.ae.zMalloc; |
| 67550 | | - REGISTER_TRACE(u.ae.p2++, pOut); |
| 67209 | + pIn1->zMalloc = zMalloc; |
| 67210 | + REGISTER_TRACE(p2++, pOut); |
| 67551 | 67211 | pIn1++; |
| 67552 | 67212 | pOut++; |
| 67553 | | - } |
| 67213 | + }while( n-- ); |
| 67554 | 67214 | break; |
| 67555 | 67215 | } |
| 67556 | 67216 | |
| 67557 | 67217 | /* Opcode: Copy P1 P2 P3 * * |
| 67558 | 67218 | ** Synopsis: r[P2@P3]=r[P1@P3] |
| | @@ -67561,26 +67221,24 @@ |
| 67561 | 67221 | ** |
| 67562 | 67222 | ** This instruction makes a deep copy of the value. A duplicate |
| 67563 | 67223 | ** is made of any string or blob constant. See also OP_SCopy. |
| 67564 | 67224 | */ |
| 67565 | 67225 | case OP_Copy: { |
| 67566 | | -#if 0 /* local variables moved into u.af */ |
| 67567 | 67226 | int n; |
| 67568 | | -#endif /* local variables moved into u.af */ |
| 67569 | 67227 | |
| 67570 | | - u.af.n = pOp->p3; |
| 67228 | + n = pOp->p3; |
| 67571 | 67229 | pIn1 = &aMem[pOp->p1]; |
| 67572 | 67230 | pOut = &aMem[pOp->p2]; |
| 67573 | 67231 | assert( pOut!=pIn1 ); |
| 67574 | 67232 | while( 1 ){ |
| 67575 | 67233 | sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); |
| 67576 | 67234 | Deephemeralize(pOut); |
| 67577 | 67235 | #ifdef SQLITE_DEBUG |
| 67578 | 67236 | pOut->pScopyFrom = 0; |
| 67579 | 67237 | #endif |
| 67580 | | - REGISTER_TRACE(pOp->p2+pOp->p3-u.af.n, pOut); |
| 67581 | | - if( (u.af.n--)==0 ) break; |
| 67238 | + REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); |
| 67239 | + if( (n--)==0 ) break; |
| 67582 | 67240 | pOut++; |
| 67583 | 67241 | pIn1++; |
| 67584 | 67242 | } |
| 67585 | 67243 | break; |
| 67586 | 67244 | } |
| | @@ -67617,17 +67275,27 @@ |
| 67617 | 67275 | ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt |
| 67618 | 67276 | ** structure to provide access to the top P1 values as the result |
| 67619 | 67277 | ** row. |
| 67620 | 67278 | */ |
| 67621 | 67279 | case OP_ResultRow: { |
| 67622 | | -#if 0 /* local variables moved into u.ag */ |
| 67623 | 67280 | Mem *pMem; |
| 67624 | 67281 | int i; |
| 67625 | | -#endif /* local variables moved into u.ag */ |
| 67626 | 67282 | assert( p->nResColumn==pOp->p2 ); |
| 67627 | 67283 | assert( pOp->p1>0 ); |
| 67628 | 67284 | assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); |
| 67285 | + |
| 67286 | +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 67287 | + /* Run the progress counter just before returning. |
| 67288 | + */ |
| 67289 | + if( db->xProgress!=0 |
| 67290 | + && nVmStep>=nProgressLimit |
| 67291 | + && db->xProgress(db->pProgressArg)!=0 |
| 67292 | + ){ |
| 67293 | + rc = SQLITE_INTERRUPT; |
| 67294 | + goto vdbe_error_halt; |
| 67295 | + } |
| 67296 | +#endif |
| 67629 | 67297 | |
| 67630 | 67298 | /* If this statement has violated immediate foreign key constraints, do |
| 67631 | 67299 | ** not return the number of rows modified. And do not RELEASE the statement |
| 67632 | 67300 | ** transaction. It needs to be rolled back. */ |
| 67633 | 67301 | if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ |
| | @@ -67634,12 +67302,12 @@ |
| 67634 | 67302 | assert( db->flags&SQLITE_CountRows ); |
| 67635 | 67303 | assert( p->usesStmtJournal ); |
| 67636 | 67304 | break; |
| 67637 | 67305 | } |
| 67638 | 67306 | |
| 67639 | | - /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then |
| 67640 | | - ** DML statements invoke this opcode to return the number of rows |
| 67307 | + /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then |
| 67308 | + ** DML statements invoke this opcode to return the number of rows |
| 67641 | 67309 | ** modified to the user. This is the only way that a VM that |
| 67642 | 67310 | ** opens a statement transaction may invoke this opcode. |
| 67643 | 67311 | ** |
| 67644 | 67312 | ** In case this is such a statement, close any statement transaction |
| 67645 | 67313 | ** opened by this VM before returning control to the user. This is to |
| | @@ -67662,19 +67330,19 @@ |
| 67662 | 67330 | |
| 67663 | 67331 | /* Make sure the results of the current row are \000 terminated |
| 67664 | 67332 | ** and have an assigned type. The results are de-ephemeralized as |
| 67665 | 67333 | ** a side effect. |
| 67666 | 67334 | */ |
| 67667 | | - u.ag.pMem = p->pResultSet = &aMem[pOp->p1]; |
| 67668 | | - for(u.ag.i=0; u.ag.i<pOp->p2; u.ag.i++){ |
| 67669 | | - assert( memIsValid(&u.ag.pMem[u.ag.i]) ); |
| 67670 | | - Deephemeralize(&u.ag.pMem[u.ag.i]); |
| 67671 | | - assert( (u.ag.pMem[u.ag.i].flags & MEM_Ephem)==0 |
| 67672 | | - || (u.ag.pMem[u.ag.i].flags & (MEM_Str|MEM_Blob))==0 ); |
| 67673 | | - sqlite3VdbeMemNulTerminate(&u.ag.pMem[u.ag.i]); |
| 67674 | | - sqlite3VdbeMemStoreType(&u.ag.pMem[u.ag.i]); |
| 67675 | | - REGISTER_TRACE(pOp->p1+u.ag.i, &u.ag.pMem[u.ag.i]); |
| 67335 | + pMem = p->pResultSet = &aMem[pOp->p1]; |
| 67336 | + for(i=0; i<pOp->p2; i++){ |
| 67337 | + assert( memIsValid(&pMem[i]) ); |
| 67338 | + Deephemeralize(&pMem[i]); |
| 67339 | + assert( (pMem[i].flags & MEM_Ephem)==0 |
| 67340 | + || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 ); |
| 67341 | + sqlite3VdbeMemNulTerminate(&pMem[i]); |
| 67342 | + sqlite3VdbeMemStoreType(&pMem[i]); |
| 67343 | + REGISTER_TRACE(pOp->p1+i, &pMem[i]); |
| 67676 | 67344 | } |
| 67677 | 67345 | if( db->mallocFailed ) goto no_mem; |
| 67678 | 67346 | |
| 67679 | 67347 | /* Return SQLITE_ROW |
| 67680 | 67348 | */ |
| | @@ -67695,13 +67363,11 @@ |
| 67695 | 67363 | ** It is illegal for P1 and P3 to be the same register. Sometimes, |
| 67696 | 67364 | ** if P3 is the same register as P2, the implementation is able |
| 67697 | 67365 | ** to avoid a memcpy(). |
| 67698 | 67366 | */ |
| 67699 | 67367 | case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ |
| 67700 | | -#if 0 /* local variables moved into u.ah */ |
| 67701 | 67368 | i64 nByte; |
| 67702 | | -#endif /* local variables moved into u.ah */ |
| 67703 | 67369 | |
| 67704 | 67370 | pIn1 = &aMem[pOp->p1]; |
| 67705 | 67371 | pIn2 = &aMem[pOp->p2]; |
| 67706 | 67372 | pOut = &aMem[pOp->p3]; |
| 67707 | 67373 | assert( pIn1!=pOut ); |
| | @@ -67710,26 +67376,26 @@ |
| 67710 | 67376 | break; |
| 67711 | 67377 | } |
| 67712 | 67378 | if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem; |
| 67713 | 67379 | Stringify(pIn1, encoding); |
| 67714 | 67380 | Stringify(pIn2, encoding); |
| 67715 | | - u.ah.nByte = pIn1->n + pIn2->n; |
| 67716 | | - if( u.ah.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67381 | + nByte = pIn1->n + pIn2->n; |
| 67382 | + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 67717 | 67383 | goto too_big; |
| 67718 | 67384 | } |
| 67719 | 67385 | MemSetTypeFlag(pOut, MEM_Str); |
| 67720 | | - if( sqlite3VdbeMemGrow(pOut, (int)u.ah.nByte+2, pOut==pIn2) ){ |
| 67386 | + if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){ |
| 67721 | 67387 | goto no_mem; |
| 67722 | 67388 | } |
| 67723 | 67389 | if( pOut!=pIn2 ){ |
| 67724 | 67390 | memcpy(pOut->z, pIn2->z, pIn2->n); |
| 67725 | 67391 | } |
| 67726 | 67392 | memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); |
| 67727 | | - pOut->z[u.ah.nByte]=0; |
| 67728 | | - pOut->z[u.ah.nByte+1] = 0; |
| 67393 | + pOut->z[nByte]=0; |
| 67394 | + pOut->z[nByte+1] = 0; |
| 67729 | 67395 | pOut->flags |= MEM_Term; |
| 67730 | | - pOut->n = (int)u.ah.nByte; |
| 67396 | + pOut->n = (int)nByte; |
| 67731 | 67397 | pOut->enc = encoding; |
| 67732 | 67398 | UPDATE_MAX_BLOBSIZE(pOut); |
| 67733 | 67399 | break; |
| 67734 | 67400 | } |
| 67735 | 67401 | |
| | @@ -67754,103 +67420,101 @@ |
| 67754 | 67420 | ** Subtract the value in register P1 from the value in register P2 |
| 67755 | 67421 | ** and store the result in register P3. |
| 67756 | 67422 | ** If either input is NULL, the result is NULL. |
| 67757 | 67423 | */ |
| 67758 | 67424 | /* Opcode: Divide P1 P2 P3 * * |
| 67759 | | -** Synopsis: r[P3]=r[P1]/r[P2] |
| 67425 | +** Synopsis: r[P3]=r[P2]/r[P1] |
| 67760 | 67426 | ** |
| 67761 | 67427 | ** Divide the value in register P1 by the value in register P2 |
| 67762 | 67428 | ** and store the result in register P3 (P3=P2/P1). If the value in |
| 67763 | 67429 | ** register P1 is zero, then the result is NULL. If either input is |
| 67764 | 67430 | ** NULL, the result is NULL. |
| 67765 | 67431 | */ |
| 67766 | 67432 | /* Opcode: Remainder P1 P2 P3 * * |
| 67767 | | -** Synopsis: r[P3]=r[P1]%r[P2] |
| 67433 | +** Synopsis: r[P3]=r[P2]%r[P1] |
| 67768 | 67434 | ** |
| 67769 | | -** Compute the remainder after integer division of the value in |
| 67770 | | -** register P1 by the value in register P2 and store the result in P3. |
| 67771 | | -** If the value in register P2 is zero the result is NULL. |
| 67435 | +** Compute the remainder after integer register P2 is divided by |
| 67436 | +** register P1 and store the result in register P3. |
| 67437 | +** If the value in register P1 is zero the result is NULL. |
| 67772 | 67438 | ** If either operand is NULL, the result is NULL. |
| 67773 | 67439 | */ |
| 67774 | 67440 | case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ |
| 67775 | 67441 | case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ |
| 67776 | 67442 | case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ |
| 67777 | 67443 | case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ |
| 67778 | 67444 | case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ |
| 67779 | | -#if 0 /* local variables moved into u.ai */ |
| 67780 | 67445 | char bIntint; /* Started out as two integer operands */ |
| 67781 | 67446 | int flags; /* Combined MEM_* flags from both inputs */ |
| 67782 | 67447 | i64 iA; /* Integer value of left operand */ |
| 67783 | 67448 | i64 iB; /* Integer value of right operand */ |
| 67784 | 67449 | double rA; /* Real value of left operand */ |
| 67785 | 67450 | double rB; /* Real value of right operand */ |
| 67786 | | -#endif /* local variables moved into u.ai */ |
| 67787 | 67451 | |
| 67788 | 67452 | pIn1 = &aMem[pOp->p1]; |
| 67789 | 67453 | applyNumericAffinity(pIn1); |
| 67790 | 67454 | pIn2 = &aMem[pOp->p2]; |
| 67791 | 67455 | applyNumericAffinity(pIn2); |
| 67792 | 67456 | pOut = &aMem[pOp->p3]; |
| 67793 | | - u.ai.flags = pIn1->flags | pIn2->flags; |
| 67794 | | - if( (u.ai.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; |
| 67457 | + flags = pIn1->flags | pIn2->flags; |
| 67458 | + if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null; |
| 67795 | 67459 | if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){ |
| 67796 | | - u.ai.iA = pIn1->u.i; |
| 67797 | | - u.ai.iB = pIn2->u.i; |
| 67798 | | - u.ai.bIntint = 1; |
| 67460 | + iA = pIn1->u.i; |
| 67461 | + iB = pIn2->u.i; |
| 67462 | + bIntint = 1; |
| 67799 | 67463 | switch( pOp->opcode ){ |
| 67800 | | - case OP_Add: if( sqlite3AddInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break; |
| 67801 | | - case OP_Subtract: if( sqlite3SubInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break; |
| 67802 | | - case OP_Multiply: if( sqlite3MulInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break; |
| 67464 | + case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; |
| 67465 | + case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; |
| 67466 | + case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; |
| 67803 | 67467 | case OP_Divide: { |
| 67804 | | - if( u.ai.iA==0 ) goto arithmetic_result_is_null; |
| 67805 | | - if( u.ai.iA==-1 && u.ai.iB==SMALLEST_INT64 ) goto fp_math; |
| 67806 | | - u.ai.iB /= u.ai.iA; |
| 67468 | + if( iA==0 ) goto arithmetic_result_is_null; |
| 67469 | + if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; |
| 67470 | + iB /= iA; |
| 67807 | 67471 | break; |
| 67808 | 67472 | } |
| 67809 | 67473 | default: { |
| 67810 | | - if( u.ai.iA==0 ) goto arithmetic_result_is_null; |
| 67811 | | - if( u.ai.iA==-1 ) u.ai.iA = 1; |
| 67812 | | - u.ai.iB %= u.ai.iA; |
| 67474 | + if( iA==0 ) goto arithmetic_result_is_null; |
| 67475 | + if( iA==-1 ) iA = 1; |
| 67476 | + iB %= iA; |
| 67813 | 67477 | break; |
| 67814 | 67478 | } |
| 67815 | 67479 | } |
| 67816 | | - pOut->u.i = u.ai.iB; |
| 67480 | + pOut->u.i = iB; |
| 67817 | 67481 | MemSetTypeFlag(pOut, MEM_Int); |
| 67818 | 67482 | }else{ |
| 67819 | | - u.ai.bIntint = 0; |
| 67483 | + bIntint = 0; |
| 67820 | 67484 | fp_math: |
| 67821 | | - u.ai.rA = sqlite3VdbeRealValue(pIn1); |
| 67822 | | - u.ai.rB = sqlite3VdbeRealValue(pIn2); |
| 67485 | + rA = sqlite3VdbeRealValue(pIn1); |
| 67486 | + rB = sqlite3VdbeRealValue(pIn2); |
| 67823 | 67487 | switch( pOp->opcode ){ |
| 67824 | | - case OP_Add: u.ai.rB += u.ai.rA; break; |
| 67825 | | - case OP_Subtract: u.ai.rB -= u.ai.rA; break; |
| 67826 | | - case OP_Multiply: u.ai.rB *= u.ai.rA; break; |
| 67488 | + case OP_Add: rB += rA; break; |
| 67489 | + case OP_Subtract: rB -= rA; break; |
| 67490 | + case OP_Multiply: rB *= rA; break; |
| 67827 | 67491 | case OP_Divide: { |
| 67828 | 67492 | /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ |
| 67829 | | - if( u.ai.rA==(double)0 ) goto arithmetic_result_is_null; |
| 67830 | | - u.ai.rB /= u.ai.rA; |
| 67493 | + if( rA==(double)0 ) goto arithmetic_result_is_null; |
| 67494 | + rB /= rA; |
| 67831 | 67495 | break; |
| 67832 | 67496 | } |
| 67833 | 67497 | default: { |
| 67834 | | - u.ai.iA = (i64)u.ai.rA; |
| 67835 | | - u.ai.iB = (i64)u.ai.rB; |
| 67836 | | - if( u.ai.iA==0 ) goto arithmetic_result_is_null; |
| 67837 | | - if( u.ai.iA==-1 ) u.ai.iA = 1; |
| 67838 | | - u.ai.rB = (double)(u.ai.iB % u.ai.iA); |
| 67498 | + iA = (i64)rA; |
| 67499 | + iB = (i64)rB; |
| 67500 | + if( iA==0 ) goto arithmetic_result_is_null; |
| 67501 | + if( iA==-1 ) iA = 1; |
| 67502 | + rB = (double)(iB % iA); |
| 67839 | 67503 | break; |
| 67840 | 67504 | } |
| 67841 | 67505 | } |
| 67842 | 67506 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 67843 | | - pOut->u.i = u.ai.rB; |
| 67507 | + pOut->u.i = rB; |
| 67844 | 67508 | MemSetTypeFlag(pOut, MEM_Int); |
| 67845 | 67509 | #else |
| 67846 | | - if( sqlite3IsNaN(u.ai.rB) ){ |
| 67510 | + if( sqlite3IsNaN(rB) ){ |
| 67847 | 67511 | goto arithmetic_result_is_null; |
| 67848 | 67512 | } |
| 67849 | | - pOut->r = u.ai.rB; |
| 67513 | + pOut->r = rB; |
| 67850 | 67514 | MemSetTypeFlag(pOut, MEM_Real); |
| 67851 | | - if( (u.ai.flags & MEM_Real)==0 && !u.ai.bIntint ){ |
| 67515 | + if( (flags & MEM_Real)==0 && !bIntint ){ |
| 67852 | 67516 | sqlite3VdbeIntegerAffinity(pOut); |
| 67853 | 67517 | } |
| 67854 | 67518 | #endif |
| 67855 | 67519 | } |
| 67856 | 67520 | break; |
| | @@ -67899,85 +67563,83 @@ |
| 67899 | 67563 | ** invocation of this opcode. |
| 67900 | 67564 | ** |
| 67901 | 67565 | ** See also: AggStep and AggFinal |
| 67902 | 67566 | */ |
| 67903 | 67567 | case OP_Function: { |
| 67904 | | -#if 0 /* local variables moved into u.aj */ |
| 67905 | 67568 | int i; |
| 67906 | 67569 | Mem *pArg; |
| 67907 | 67570 | sqlite3_context ctx; |
| 67908 | 67571 | sqlite3_value **apVal; |
| 67909 | 67572 | int n; |
| 67910 | | -#endif /* local variables moved into u.aj */ |
| 67911 | 67573 | |
| 67912 | | - u.aj.n = pOp->p5; |
| 67913 | | - u.aj.apVal = p->apArg; |
| 67914 | | - assert( u.aj.apVal || u.aj.n==0 ); |
| 67574 | + n = pOp->p5; |
| 67575 | + apVal = p->apArg; |
| 67576 | + assert( apVal || n==0 ); |
| 67915 | 67577 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 67916 | 67578 | pOut = &aMem[pOp->p3]; |
| 67917 | 67579 | memAboutToChange(p, pOut); |
| 67918 | 67580 | |
| 67919 | | - assert( u.aj.n==0 || (pOp->p2>0 && pOp->p2+u.aj.n<=(p->nMem-p->nCursor)+1) ); |
| 67920 | | - assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.aj.n ); |
| 67921 | | - u.aj.pArg = &aMem[pOp->p2]; |
| 67922 | | - for(u.aj.i=0; u.aj.i<u.aj.n; u.aj.i++, u.aj.pArg++){ |
| 67923 | | - assert( memIsValid(u.aj.pArg) ); |
| 67924 | | - u.aj.apVal[u.aj.i] = u.aj.pArg; |
| 67925 | | - Deephemeralize(u.aj.pArg); |
| 67926 | | - sqlite3VdbeMemStoreType(u.aj.pArg); |
| 67927 | | - REGISTER_TRACE(pOp->p2+u.aj.i, u.aj.pArg); |
| 67581 | + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); |
| 67582 | + assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 67583 | + pArg = &aMem[pOp->p2]; |
| 67584 | + for(i=0; i<n; i++, pArg++){ |
| 67585 | + assert( memIsValid(pArg) ); |
| 67586 | + apVal[i] = pArg; |
| 67587 | + Deephemeralize(pArg); |
| 67588 | + sqlite3VdbeMemStoreType(pArg); |
| 67589 | + REGISTER_TRACE(pOp->p2+i, pArg); |
| 67928 | 67590 | } |
| 67929 | 67591 | |
| 67930 | 67592 | assert( pOp->p4type==P4_FUNCDEF ); |
| 67931 | | - u.aj.ctx.pFunc = pOp->p4.pFunc; |
| 67932 | | - u.aj.ctx.s.flags = MEM_Null; |
| 67933 | | - u.aj.ctx.s.db = db; |
| 67934 | | - u.aj.ctx.s.xDel = 0; |
| 67935 | | - u.aj.ctx.s.zMalloc = 0; |
| 67936 | | - u.aj.ctx.iOp = pc; |
| 67937 | | - u.aj.ctx.pVdbe = p; |
| 67593 | + ctx.pFunc = pOp->p4.pFunc; |
| 67594 | + ctx.iOp = pc; |
| 67595 | + ctx.pVdbe = p; |
| 67938 | 67596 | |
| 67939 | 67597 | /* The output cell may already have a buffer allocated. Move |
| 67940 | | - ** the pointer to u.aj.ctx.s so in case the user-function can use |
| 67598 | + ** the pointer to ctx.s so in case the user-function can use |
| 67941 | 67599 | ** the already allocated buffer instead of allocating a new one. |
| 67942 | 67600 | */ |
| 67943 | | - sqlite3VdbeMemMove(&u.aj.ctx.s, pOut); |
| 67944 | | - MemSetTypeFlag(&u.aj.ctx.s, MEM_Null); |
| 67601 | + memcpy(&ctx.s, pOut, sizeof(Mem)); |
| 67602 | + pOut->flags = MEM_Null; |
| 67603 | + pOut->xDel = 0; |
| 67604 | + pOut->zMalloc = 0; |
| 67605 | + MemSetTypeFlag(&ctx.s, MEM_Null); |
| 67945 | 67606 | |
| 67946 | | - u.aj.ctx.fErrorOrAux = 0; |
| 67947 | | - if( u.aj.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 67607 | + ctx.fErrorOrAux = 0; |
| 67608 | + if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 67948 | 67609 | assert( pOp>aOp ); |
| 67949 | 67610 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 67950 | 67611 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 67951 | | - u.aj.ctx.pColl = pOp[-1].p4.pColl; |
| 67612 | + ctx.pColl = pOp[-1].p4.pColl; |
| 67952 | 67613 | } |
| 67953 | 67614 | db->lastRowid = lastRowid; |
| 67954 | | - (*u.aj.ctx.pFunc->xFunc)(&u.aj.ctx, u.aj.n, u.aj.apVal); /* IMP: R-24505-23230 */ |
| 67615 | + (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ |
| 67955 | 67616 | lastRowid = db->lastRowid; |
| 67956 | 67617 | |
| 67957 | 67618 | if( db->mallocFailed ){ |
| 67958 | 67619 | /* Even though a malloc() has failed, the implementation of the |
| 67959 | 67620 | ** user function may have called an sqlite3_result_XXX() function |
| 67960 | 67621 | ** to return a value. The following call releases any resources |
| 67961 | 67622 | ** associated with such a value. |
| 67962 | 67623 | */ |
| 67963 | | - sqlite3VdbeMemRelease(&u.aj.ctx.s); |
| 67624 | + sqlite3VdbeMemRelease(&ctx.s); |
| 67964 | 67625 | goto no_mem; |
| 67965 | 67626 | } |
| 67966 | 67627 | |
| 67967 | 67628 | /* If the function returned an error, throw an exception */ |
| 67968 | | - if( u.aj.ctx.fErrorOrAux ){ |
| 67969 | | - if( u.aj.ctx.isError ){ |
| 67970 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.aj.ctx.s)); |
| 67971 | | - rc = u.aj.ctx.isError; |
| 67629 | + if( ctx.fErrorOrAux ){ |
| 67630 | + if( ctx.isError ){ |
| 67631 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s)); |
| 67632 | + rc = ctx.isError; |
| 67972 | 67633 | } |
| 67973 | 67634 | sqlite3VdbeDeleteAuxData(p, pc, pOp->p1); |
| 67974 | 67635 | } |
| 67975 | 67636 | |
| 67976 | 67637 | /* Copy the result of the function into register P3 */ |
| 67977 | | - sqlite3VdbeChangeEncoding(&u.aj.ctx.s, encoding); |
| 67978 | | - sqlite3VdbeMemMove(pOut, &u.aj.ctx.s); |
| 67638 | + sqlite3VdbeChangeEncoding(&ctx.s, encoding); |
| 67639 | + assert( pOut->flags==MEM_Null ); |
| 67640 | + memcpy(pOut, &ctx.s, sizeof(Mem)); |
| 67979 | 67641 | if( sqlite3VdbeMemTooBig(pOut) ){ |
| 67980 | 67642 | goto too_big; |
| 67981 | 67643 | } |
| 67982 | 67644 | |
| 67983 | 67645 | #if 0 |
| | @@ -68025,56 +67687,54 @@ |
| 68025 | 67687 | */ |
| 68026 | 67688 | case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ |
| 68027 | 67689 | case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ |
| 68028 | 67690 | case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ |
| 68029 | 67691 | case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ |
| 68030 | | -#if 0 /* local variables moved into u.ak */ |
| 68031 | 67692 | i64 iA; |
| 68032 | 67693 | u64 uA; |
| 68033 | 67694 | i64 iB; |
| 68034 | 67695 | u8 op; |
| 68035 | | -#endif /* local variables moved into u.ak */ |
| 68036 | 67696 | |
| 68037 | 67697 | pIn1 = &aMem[pOp->p1]; |
| 68038 | 67698 | pIn2 = &aMem[pOp->p2]; |
| 68039 | 67699 | pOut = &aMem[pOp->p3]; |
| 68040 | 67700 | if( (pIn1->flags | pIn2->flags) & MEM_Null ){ |
| 68041 | 67701 | sqlite3VdbeMemSetNull(pOut); |
| 68042 | 67702 | break; |
| 68043 | 67703 | } |
| 68044 | | - u.ak.iA = sqlite3VdbeIntValue(pIn2); |
| 68045 | | - u.ak.iB = sqlite3VdbeIntValue(pIn1); |
| 68046 | | - u.ak.op = pOp->opcode; |
| 68047 | | - if( u.ak.op==OP_BitAnd ){ |
| 68048 | | - u.ak.iA &= u.ak.iB; |
| 68049 | | - }else if( u.ak.op==OP_BitOr ){ |
| 68050 | | - u.ak.iA |= u.ak.iB; |
| 68051 | | - }else if( u.ak.iB!=0 ){ |
| 68052 | | - assert( u.ak.op==OP_ShiftRight || u.ak.op==OP_ShiftLeft ); |
| 67704 | + iA = sqlite3VdbeIntValue(pIn2); |
| 67705 | + iB = sqlite3VdbeIntValue(pIn1); |
| 67706 | + op = pOp->opcode; |
| 67707 | + if( op==OP_BitAnd ){ |
| 67708 | + iA &= iB; |
| 67709 | + }else if( op==OP_BitOr ){ |
| 67710 | + iA |= iB; |
| 67711 | + }else if( iB!=0 ){ |
| 67712 | + assert( op==OP_ShiftRight || op==OP_ShiftLeft ); |
| 68053 | 67713 | |
| 68054 | 67714 | /* If shifting by a negative amount, shift in the other direction */ |
| 68055 | | - if( u.ak.iB<0 ){ |
| 67715 | + if( iB<0 ){ |
| 68056 | 67716 | assert( OP_ShiftRight==OP_ShiftLeft+1 ); |
| 68057 | | - u.ak.op = 2*OP_ShiftLeft + 1 - u.ak.op; |
| 68058 | | - u.ak.iB = u.ak.iB>(-64) ? -u.ak.iB : 64; |
| 67717 | + op = 2*OP_ShiftLeft + 1 - op; |
| 67718 | + iB = iB>(-64) ? -iB : 64; |
| 68059 | 67719 | } |
| 68060 | 67720 | |
| 68061 | | - if( u.ak.iB>=64 ){ |
| 68062 | | - u.ak.iA = (u.ak.iA>=0 || u.ak.op==OP_ShiftLeft) ? 0 : -1; |
| 68063 | | - }else{ |
| 68064 | | - memcpy(&u.ak.uA, &u.ak.iA, sizeof(u.ak.uA)); |
| 68065 | | - if( u.ak.op==OP_ShiftLeft ){ |
| 68066 | | - u.ak.uA <<= u.ak.iB; |
| 68067 | | - }else{ |
| 68068 | | - u.ak.uA >>= u.ak.iB; |
| 67721 | + if( iB>=64 ){ |
| 67722 | + iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1; |
| 67723 | + }else{ |
| 67724 | + memcpy(&uA, &iA, sizeof(uA)); |
| 67725 | + if( op==OP_ShiftLeft ){ |
| 67726 | + uA <<= iB; |
| 67727 | + }else{ |
| 67728 | + uA >>= iB; |
| 68069 | 67729 | /* Sign-extend on a right shift of a negative number */ |
| 68070 | | - if( u.ak.iA<0 ) u.ak.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ak.iB); |
| 67730 | + if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB); |
| 68071 | 67731 | } |
| 68072 | | - memcpy(&u.ak.iA, &u.ak.uA, sizeof(u.ak.iA)); |
| 67732 | + memcpy(&iA, &uA, sizeof(iA)); |
| 68073 | 67733 | } |
| 68074 | 67734 | } |
| 68075 | | - pOut->u.i = u.ak.iA; |
| 67735 | + pOut->u.i = iA; |
| 68076 | 67736 | MemSetTypeFlag(pOut, MEM_Int); |
| 68077 | 67737 | break; |
| 68078 | 67738 | } |
| 68079 | 67739 | |
| 68080 | 67740 | /* Opcode: AddImm P1 P2 * * * |
| | @@ -68100,21 +67760,23 @@ |
| 68100 | 67760 | ** without data loss, then jump immediately to P2, or if P2==0 |
| 68101 | 67761 | ** raise an SQLITE_MISMATCH exception. |
| 68102 | 67762 | */ |
| 68103 | 67763 | case OP_MustBeInt: { /* jump, in1 */ |
| 68104 | 67764 | pIn1 = &aMem[pOp->p1]; |
| 68105 | | - applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); |
| 68106 | 67765 | if( (pIn1->flags & MEM_Int)==0 ){ |
| 68107 | | - if( pOp->p2==0 ){ |
| 68108 | | - rc = SQLITE_MISMATCH; |
| 68109 | | - goto abort_due_to_error; |
| 68110 | | - }else{ |
| 68111 | | - pc = pOp->p2 - 1; |
| 68112 | | - } |
| 68113 | | - }else{ |
| 68114 | | - MemSetTypeFlag(pIn1, MEM_Int); |
| 68115 | | - } |
| 67766 | + applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); |
| 67767 | + if( (pIn1->flags & MEM_Int)==0 ){ |
| 67768 | + if( pOp->p2==0 ){ |
| 67769 | + rc = SQLITE_MISMATCH; |
| 67770 | + goto abort_due_to_error; |
| 67771 | + }else{ |
| 67772 | + pc = pOp->p2 - 1; |
| 67773 | + break; |
| 67774 | + } |
| 67775 | + } |
| 67776 | + } |
| 67777 | + MemSetTypeFlag(pIn1, MEM_Int); |
| 68116 | 67778 | break; |
| 68117 | 67779 | } |
| 68118 | 67780 | |
| 68119 | 67781 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 68120 | 67782 | /* Opcode: RealAffinity P1 * * * * |
| | @@ -68235,11 +67897,11 @@ |
| 68235 | 67897 | break; |
| 68236 | 67898 | } |
| 68237 | 67899 | #endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */ |
| 68238 | 67900 | |
| 68239 | 67901 | /* Opcode: Lt P1 P2 P3 P4 P5 |
| 68240 | | -** Synopsis: if r[P1]<r[P3] goto P3 |
| 67902 | +** Synopsis: if r[P1]<r[P3] goto P2 |
| 68241 | 67903 | ** |
| 68242 | 67904 | ** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then |
| 68243 | 67905 | ** jump to address P2. |
| 68244 | 67906 | ** |
| 68245 | 67907 | ** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or |
| | @@ -68322,37 +67984,35 @@ |
| 68322 | 67984 | case OP_Ne: /* same as TK_NE, jump, in1, in3 */ |
| 68323 | 67985 | case OP_Lt: /* same as TK_LT, jump, in1, in3 */ |
| 68324 | 67986 | case OP_Le: /* same as TK_LE, jump, in1, in3 */ |
| 68325 | 67987 | case OP_Gt: /* same as TK_GT, jump, in1, in3 */ |
| 68326 | 67988 | case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ |
| 68327 | | -#if 0 /* local variables moved into u.al */ |
| 68328 | 67989 | int res; /* Result of the comparison of pIn1 against pIn3 */ |
| 68329 | 67990 | char affinity; /* Affinity to use for comparison */ |
| 68330 | 67991 | u16 flags1; /* Copy of initial value of pIn1->flags */ |
| 68331 | 67992 | u16 flags3; /* Copy of initial value of pIn3->flags */ |
| 68332 | | -#endif /* local variables moved into u.al */ |
| 68333 | 67993 | |
| 68334 | 67994 | pIn1 = &aMem[pOp->p1]; |
| 68335 | 67995 | pIn3 = &aMem[pOp->p3]; |
| 68336 | | - u.al.flags1 = pIn1->flags; |
| 68337 | | - u.al.flags3 = pIn3->flags; |
| 68338 | | - if( (u.al.flags1 | u.al.flags3)&MEM_Null ){ |
| 67996 | + flags1 = pIn1->flags; |
| 67997 | + flags3 = pIn3->flags; |
| 67998 | + if( (flags1 | flags3)&MEM_Null ){ |
| 68339 | 67999 | /* One or both operands are NULL */ |
| 68340 | 68000 | if( pOp->p5 & SQLITE_NULLEQ ){ |
| 68341 | 68001 | /* If SQLITE_NULLEQ is set (which will only happen if the operator is |
| 68342 | 68002 | ** OP_Eq or OP_Ne) then take the jump or not depending on whether |
| 68343 | 68003 | ** or not both operands are null. |
| 68344 | 68004 | */ |
| 68345 | 68005 | assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); |
| 68346 | | - assert( (u.al.flags1 & MEM_Cleared)==0 ); |
| 68347 | | - if( (u.al.flags1&MEM_Null)!=0 |
| 68348 | | - && (u.al.flags3&MEM_Null)!=0 |
| 68349 | | - && (u.al.flags3&MEM_Cleared)==0 |
| 68006 | + assert( (flags1 & MEM_Cleared)==0 ); |
| 68007 | + if( (flags1&MEM_Null)!=0 |
| 68008 | + && (flags3&MEM_Null)!=0 |
| 68009 | + && (flags3&MEM_Cleared)==0 |
| 68350 | 68010 | ){ |
| 68351 | | - u.al.res = 0; /* Results are equal */ |
| 68011 | + res = 0; /* Results are equal */ |
| 68352 | 68012 | }else{ |
| 68353 | | - u.al.res = 1; /* Results are not equal */ |
| 68013 | + res = 1; /* Results are not equal */ |
| 68354 | 68014 | } |
| 68355 | 68015 | }else{ |
| 68356 | 68016 | /* SQLITE_NULLEQ is clear and at least one operand is NULL, |
| 68357 | 68017 | ** then the result is always NULL. |
| 68358 | 68018 | ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. |
| | @@ -68366,44 +68026,44 @@ |
| 68366 | 68026 | } |
| 68367 | 68027 | break; |
| 68368 | 68028 | } |
| 68369 | 68029 | }else{ |
| 68370 | 68030 | /* Neither operand is NULL. Do a comparison. */ |
| 68371 | | - u.al.affinity = pOp->p5 & SQLITE_AFF_MASK; |
| 68372 | | - if( u.al.affinity ){ |
| 68373 | | - applyAffinity(pIn1, u.al.affinity, encoding); |
| 68374 | | - applyAffinity(pIn3, u.al.affinity, encoding); |
| 68031 | + affinity = pOp->p5 & SQLITE_AFF_MASK; |
| 68032 | + if( affinity ){ |
| 68033 | + applyAffinity(pIn1, affinity, encoding); |
| 68034 | + applyAffinity(pIn3, affinity, encoding); |
| 68375 | 68035 | if( db->mallocFailed ) goto no_mem; |
| 68376 | 68036 | } |
| 68377 | 68037 | |
| 68378 | 68038 | assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); |
| 68379 | 68039 | ExpandBlob(pIn1); |
| 68380 | 68040 | ExpandBlob(pIn3); |
| 68381 | | - u.al.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); |
| 68041 | + res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); |
| 68382 | 68042 | } |
| 68383 | 68043 | switch( pOp->opcode ){ |
| 68384 | | - case OP_Eq: u.al.res = u.al.res==0; break; |
| 68385 | | - case OP_Ne: u.al.res = u.al.res!=0; break; |
| 68386 | | - case OP_Lt: u.al.res = u.al.res<0; break; |
| 68387 | | - case OP_Le: u.al.res = u.al.res<=0; break; |
| 68388 | | - case OP_Gt: u.al.res = u.al.res>0; break; |
| 68389 | | - default: u.al.res = u.al.res>=0; break; |
| 68044 | + case OP_Eq: res = res==0; break; |
| 68045 | + case OP_Ne: res = res!=0; break; |
| 68046 | + case OP_Lt: res = res<0; break; |
| 68047 | + case OP_Le: res = res<=0; break; |
| 68048 | + case OP_Gt: res = res>0; break; |
| 68049 | + default: res = res>=0; break; |
| 68390 | 68050 | } |
| 68391 | 68051 | |
| 68392 | 68052 | if( pOp->p5 & SQLITE_STOREP2 ){ |
| 68393 | 68053 | pOut = &aMem[pOp->p2]; |
| 68394 | 68054 | memAboutToChange(p, pOut); |
| 68395 | 68055 | MemSetTypeFlag(pOut, MEM_Int); |
| 68396 | | - pOut->u.i = u.al.res; |
| 68056 | + pOut->u.i = res; |
| 68397 | 68057 | REGISTER_TRACE(pOp->p2, pOut); |
| 68398 | | - }else if( u.al.res ){ |
| 68058 | + }else if( res ){ |
| 68399 | 68059 | pc = pOp->p2-1; |
| 68400 | 68060 | } |
| 68401 | 68061 | |
| 68402 | 68062 | /* Undo any changes made by applyAffinity() to the input registers. */ |
| 68403 | | - pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.al.flags1&MEM_TypeMask); |
| 68404 | | - pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.al.flags3&MEM_TypeMask); |
| 68063 | + pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask); |
| 68064 | + pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask); |
| 68405 | 68065 | break; |
| 68406 | 68066 | } |
| 68407 | 68067 | |
| 68408 | 68068 | /* Opcode: Permutation * * * P4 * |
| 68409 | 68069 | ** |
| | @@ -68439,51 +68099,49 @@ |
| 68439 | 68099 | ** The comparison is a sort comparison, so NULLs compare equal, |
| 68440 | 68100 | ** NULLs are less than numbers, numbers are less than strings, |
| 68441 | 68101 | ** and strings are less than blobs. |
| 68442 | 68102 | */ |
| 68443 | 68103 | case OP_Compare: { |
| 68444 | | -#if 0 /* local variables moved into u.am */ |
| 68445 | 68104 | int n; |
| 68446 | 68105 | int i; |
| 68447 | 68106 | int p1; |
| 68448 | 68107 | int p2; |
| 68449 | 68108 | const KeyInfo *pKeyInfo; |
| 68450 | 68109 | int idx; |
| 68451 | 68110 | CollSeq *pColl; /* Collating sequence to use on this term */ |
| 68452 | 68111 | int bRev; /* True for DESCENDING sort order */ |
| 68453 | | -#endif /* local variables moved into u.am */ |
| 68454 | 68112 | |
| 68455 | 68113 | if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0; |
| 68456 | | - u.am.n = pOp->p3; |
| 68457 | | - u.am.pKeyInfo = pOp->p4.pKeyInfo; |
| 68458 | | - assert( u.am.n>0 ); |
| 68459 | | - assert( u.am.pKeyInfo!=0 ); |
| 68460 | | - u.am.p1 = pOp->p1; |
| 68461 | | - u.am.p2 = pOp->p2; |
| 68114 | + n = pOp->p3; |
| 68115 | + pKeyInfo = pOp->p4.pKeyInfo; |
| 68116 | + assert( n>0 ); |
| 68117 | + assert( pKeyInfo!=0 ); |
| 68118 | + p1 = pOp->p1; |
| 68119 | + p2 = pOp->p2; |
| 68462 | 68120 | #if SQLITE_DEBUG |
| 68463 | 68121 | if( aPermute ){ |
| 68464 | 68122 | int k, mx = 0; |
| 68465 | | - for(k=0; k<u.am.n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 68466 | | - assert( u.am.p1>0 && u.am.p1+mx<=(p->nMem-p->nCursor)+1 ); |
| 68467 | | - assert( u.am.p2>0 && u.am.p2+mx<=(p->nMem-p->nCursor)+1 ); |
| 68123 | + for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 68124 | + assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 ); |
| 68125 | + assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 ); |
| 68468 | 68126 | }else{ |
| 68469 | | - assert( u.am.p1>0 && u.am.p1+u.am.n<=(p->nMem-p->nCursor)+1 ); |
| 68470 | | - assert( u.am.p2>0 && u.am.p2+u.am.n<=(p->nMem-p->nCursor)+1 ); |
| 68127 | + assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 ); |
| 68128 | + assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 ); |
| 68471 | 68129 | } |
| 68472 | 68130 | #endif /* SQLITE_DEBUG */ |
| 68473 | | - for(u.am.i=0; u.am.i<u.am.n; u.am.i++){ |
| 68474 | | - u.am.idx = aPermute ? aPermute[u.am.i] : u.am.i; |
| 68475 | | - assert( memIsValid(&aMem[u.am.p1+u.am.idx]) ); |
| 68476 | | - assert( memIsValid(&aMem[u.am.p2+u.am.idx]) ); |
| 68477 | | - REGISTER_TRACE(u.am.p1+u.am.idx, &aMem[u.am.p1+u.am.idx]); |
| 68478 | | - REGISTER_TRACE(u.am.p2+u.am.idx, &aMem[u.am.p2+u.am.idx]); |
| 68479 | | - assert( u.am.i<u.am.pKeyInfo->nField ); |
| 68480 | | - u.am.pColl = u.am.pKeyInfo->aColl[u.am.i]; |
| 68481 | | - u.am.bRev = u.am.pKeyInfo->aSortOrder[u.am.i]; |
| 68482 | | - iCompare = sqlite3MemCompare(&aMem[u.am.p1+u.am.idx], &aMem[u.am.p2+u.am.idx], u.am.pColl); |
| 68131 | + for(i=0; i<n; i++){ |
| 68132 | + idx = aPermute ? aPermute[i] : i; |
| 68133 | + assert( memIsValid(&aMem[p1+idx]) ); |
| 68134 | + assert( memIsValid(&aMem[p2+idx]) ); |
| 68135 | + REGISTER_TRACE(p1+idx, &aMem[p1+idx]); |
| 68136 | + REGISTER_TRACE(p2+idx, &aMem[p2+idx]); |
| 68137 | + assert( i<pKeyInfo->nField ); |
| 68138 | + pColl = pKeyInfo->aColl[i]; |
| 68139 | + bRev = pKeyInfo->aSortOrder[i]; |
| 68140 | + iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); |
| 68483 | 68141 | if( iCompare ){ |
| 68484 | | - if( u.am.bRev ) iCompare = -iCompare; |
| 68142 | + if( bRev ) iCompare = -iCompare; |
| 68485 | 68143 | break; |
| 68486 | 68144 | } |
| 68487 | 68145 | } |
| 68488 | 68146 | aPermute = 0; |
| 68489 | 68147 | break; |
| | @@ -68526,39 +68184,37 @@ |
| 68526 | 68184 | ** even if the other input is NULL. A NULL and false or two NULLs |
| 68527 | 68185 | ** give a NULL output. |
| 68528 | 68186 | */ |
| 68529 | 68187 | case OP_And: /* same as TK_AND, in1, in2, out3 */ |
| 68530 | 68188 | case OP_Or: { /* same as TK_OR, in1, in2, out3 */ |
| 68531 | | -#if 0 /* local variables moved into u.an */ |
| 68532 | 68189 | int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
| 68533 | 68190 | int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
| 68534 | | -#endif /* local variables moved into u.an */ |
| 68535 | 68191 | |
| 68536 | 68192 | pIn1 = &aMem[pOp->p1]; |
| 68537 | 68193 | if( pIn1->flags & MEM_Null ){ |
| 68538 | | - u.an.v1 = 2; |
| 68194 | + v1 = 2; |
| 68539 | 68195 | }else{ |
| 68540 | | - u.an.v1 = sqlite3VdbeIntValue(pIn1)!=0; |
| 68196 | + v1 = sqlite3VdbeIntValue(pIn1)!=0; |
| 68541 | 68197 | } |
| 68542 | 68198 | pIn2 = &aMem[pOp->p2]; |
| 68543 | 68199 | if( pIn2->flags & MEM_Null ){ |
| 68544 | | - u.an.v2 = 2; |
| 68200 | + v2 = 2; |
| 68545 | 68201 | }else{ |
| 68546 | | - u.an.v2 = sqlite3VdbeIntValue(pIn2)!=0; |
| 68202 | + v2 = sqlite3VdbeIntValue(pIn2)!=0; |
| 68547 | 68203 | } |
| 68548 | 68204 | if( pOp->opcode==OP_And ){ |
| 68549 | 68205 | static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; |
| 68550 | | - u.an.v1 = and_logic[u.an.v1*3+u.an.v2]; |
| 68206 | + v1 = and_logic[v1*3+v2]; |
| 68551 | 68207 | }else{ |
| 68552 | 68208 | static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; |
| 68553 | | - u.an.v1 = or_logic[u.an.v1*3+u.an.v2]; |
| 68209 | + v1 = or_logic[v1*3+v2]; |
| 68554 | 68210 | } |
| 68555 | 68211 | pOut = &aMem[pOp->p3]; |
| 68556 | | - if( u.an.v1==2 ){ |
| 68212 | + if( v1==2 ){ |
| 68557 | 68213 | MemSetTypeFlag(pOut, MEM_Null); |
| 68558 | 68214 | }else{ |
| 68559 | | - pOut->u.i = u.an.v1; |
| 68215 | + pOut->u.i = v1; |
| 68560 | 68216 | MemSetTypeFlag(pOut, MEM_Int); |
| 68561 | 68217 | } |
| 68562 | 68218 | break; |
| 68563 | 68219 | } |
| 68564 | 68220 | |
| | @@ -68625,25 +68281,23 @@ |
| 68625 | 68281 | ** is considered false if it has a numeric value of zero. If the value |
| 68626 | 68282 | ** in P1 is NULL then take the jump if P3 is zero. |
| 68627 | 68283 | */ |
| 68628 | 68284 | case OP_If: /* jump, in1 */ |
| 68629 | 68285 | case OP_IfNot: { /* jump, in1 */ |
| 68630 | | -#if 0 /* local variables moved into u.ao */ |
| 68631 | 68286 | int c; |
| 68632 | | -#endif /* local variables moved into u.ao */ |
| 68633 | 68287 | pIn1 = &aMem[pOp->p1]; |
| 68634 | 68288 | if( pIn1->flags & MEM_Null ){ |
| 68635 | | - u.ao.c = pOp->p3; |
| 68289 | + c = pOp->p3; |
| 68636 | 68290 | }else{ |
| 68637 | 68291 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 68638 | | - u.ao.c = sqlite3VdbeIntValue(pIn1)!=0; |
| 68292 | + c = sqlite3VdbeIntValue(pIn1)!=0; |
| 68639 | 68293 | #else |
| 68640 | | - u.ao.c = sqlite3VdbeRealValue(pIn1)!=0.0; |
| 68294 | + c = sqlite3VdbeRealValue(pIn1)!=0.0; |
| 68641 | 68295 | #endif |
| 68642 | | - if( pOp->opcode==OP_IfNot ) u.ao.c = !u.ao.c; |
| 68296 | + if( pOp->opcode==OP_IfNot ) c = !c; |
| 68643 | 68297 | } |
| 68644 | | - if( u.ao.c ){ |
| 68298 | + if( c ){ |
| 68645 | 68299 | pc = pOp->p2-1; |
| 68646 | 68300 | } |
| 68647 | 68301 | break; |
| 68648 | 68302 | } |
| 68649 | 68303 | |
| | @@ -68697,157 +68351,107 @@ |
| 68697 | 68351 | ** the result is guaranteed to only be used as the argument of a length() |
| 68698 | 68352 | ** or typeof() function, respectively. The loading of large blobs can be |
| 68699 | 68353 | ** skipped for length() and all content loading can be skipped for typeof(). |
| 68700 | 68354 | */ |
| 68701 | 68355 | case OP_Column: { |
| 68702 | | -#if 0 /* local variables moved into u.ap */ |
| 68703 | | - u32 payloadSize; /* Number of bytes in the record */ |
| 68704 | 68356 | i64 payloadSize64; /* Number of bytes in the record */ |
| 68705 | | - int p1; /* P1 value of the opcode */ |
| 68706 | 68357 | int p2; /* column number to retrieve */ |
| 68707 | 68358 | VdbeCursor *pC; /* The VDBE cursor */ |
| 68708 | | - char *zRec; /* Pointer to complete record-data */ |
| 68709 | 68359 | BtCursor *pCrsr; /* The BTree cursor */ |
| 68710 | 68360 | u32 *aType; /* aType[i] holds the numeric type of the i-th column */ |
| 68711 | 68361 | u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ |
| 68712 | | - int nField; /* number of fields in the record */ |
| 68713 | 68362 | int len; /* The length of the serialized data for the column */ |
| 68714 | 68363 | int i; /* Loop counter */ |
| 68715 | | - char *zData; /* Part of the record being decoded */ |
| 68716 | 68364 | Mem *pDest; /* Where to write the extracted value */ |
| 68717 | 68365 | Mem sMem; /* For storing the record being decoded */ |
| 68718 | | - u8 *zIdx; /* Index into header */ |
| 68719 | | - u8 *zEndHdr; /* Pointer to first byte after the header */ |
| 68366 | + const u8 *zData; /* Part of the record being decoded */ |
| 68367 | + const u8 *zHdr; /* Next unparsed byte of the header */ |
| 68368 | + const u8 *zEndHdr; /* Pointer to first byte after the header */ |
| 68720 | 68369 | u32 offset; /* Offset into the data */ |
| 68721 | 68370 | u32 szField; /* Number of bytes in the content of a field */ |
| 68722 | | - int szHdr; /* Size of the header size field at start of record */ |
| 68723 | | - int avail; /* Number of bytes of available data */ |
| 68371 | + u32 avail; /* Number of bytes of available data */ |
| 68724 | 68372 | u32 t; /* A type code from the record header */ |
| 68725 | 68373 | Mem *pReg; /* PseudoTable input register */ |
| 68726 | | -#endif /* local variables moved into u.ap */ |
| 68727 | | - |
| 68728 | | - |
| 68729 | | - u.ap.p1 = pOp->p1; |
| 68730 | | - u.ap.p2 = pOp->p2; |
| 68731 | | - u.ap.pC = 0; |
| 68732 | | - memset(&u.ap.sMem, 0, sizeof(u.ap.sMem)); |
| 68733 | | - assert( u.ap.p1<p->nCursor ); |
| 68374 | + |
| 68375 | + p2 = pOp->p2; |
| 68734 | 68376 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 68735 | | - u.ap.pDest = &aMem[pOp->p3]; |
| 68736 | | - memAboutToChange(p, u.ap.pDest); |
| 68737 | | - u.ap.zRec = 0; |
| 68738 | | - |
| 68739 | | - /* This block sets the variable u.ap.payloadSize to be the total number of |
| 68740 | | - ** bytes in the record. |
| 68741 | | - ** |
| 68742 | | - ** u.ap.zRec is set to be the complete text of the record if it is available. |
| 68743 | | - ** The complete record text is always available for pseudo-tables |
| 68744 | | - ** If the record is stored in a cursor, the complete record text |
| 68745 | | - ** might be available in the u.ap.pC->aRow cache. Or it might not be. |
| 68746 | | - ** If the data is unavailable, u.ap.zRec is set to NULL. |
| 68747 | | - ** |
| 68748 | | - ** We also compute the number of columns in the record. For cursors, |
| 68749 | | - ** the number of columns is stored in the VdbeCursor.nField element. |
| 68750 | | - */ |
| 68751 | | - u.ap.pC = p->apCsr[u.ap.p1]; |
| 68752 | | - assert( u.ap.pC!=0 ); |
| 68377 | + pDest = &aMem[pOp->p3]; |
| 68378 | + memAboutToChange(p, pDest); |
| 68379 | + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 68380 | + pC = p->apCsr[pOp->p1]; |
| 68381 | + assert( pC!=0 ); |
| 68382 | + assert( p2<pC->nField ); |
| 68383 | + aType = pC->aType; |
| 68384 | + aOffset = aType + pC->nField; |
| 68753 | 68385 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 68754 | | - assert( u.ap.pC->pVtabCursor==0 ); |
| 68755 | | -#endif |
| 68756 | | - u.ap.pCrsr = u.ap.pC->pCursor; |
| 68757 | | - if( u.ap.pCrsr!=0 ){ |
| 68758 | | - /* The record is stored in a B-Tree */ |
| 68759 | | - rc = sqlite3VdbeCursorMoveto(u.ap.pC); |
| 68760 | | - if( rc ) goto abort_due_to_error; |
| 68761 | | - if( u.ap.pC->nullRow ){ |
| 68762 | | - u.ap.payloadSize = 0; |
| 68763 | | - }else if( u.ap.pC->cacheStatus==p->cacheCtr ){ |
| 68764 | | - u.ap.payloadSize = u.ap.pC->payloadSize; |
| 68765 | | - u.ap.zRec = (char*)u.ap.pC->aRow; |
| 68766 | | - }else if( u.ap.pC->isIndex ){ |
| 68767 | | - assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) ); |
| 68768 | | - VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ap.pCrsr, &u.ap.payloadSize64); |
| 68769 | | - assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 68770 | | - /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the |
| 68771 | | - ** payload size, so it is impossible for u.ap.payloadSize64 to be |
| 68772 | | - ** larger than 32 bits. */ |
| 68773 | | - assert( (u.ap.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ap.payloadSize64 ); |
| 68774 | | - u.ap.payloadSize = (u32)u.ap.payloadSize64; |
| 68775 | | - }else{ |
| 68776 | | - assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) ); |
| 68777 | | - VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ap.pCrsr, &u.ap.payloadSize); |
| 68778 | | - assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 68779 | | - } |
| 68780 | | - }else{ |
| 68781 | | - assert( u.ap.pC->pseudoTableReg>0 ); |
| 68782 | | - u.ap.pReg = &aMem[u.ap.pC->pseudoTableReg]; |
| 68783 | | - if( u.ap.pC->multiPseudo ){ |
| 68784 | | - sqlite3VdbeMemShallowCopy(u.ap.pDest, u.ap.pReg+u.ap.p2, MEM_Ephem); |
| 68785 | | - Deephemeralize(u.ap.pDest); |
| 68786 | | - goto op_column_out; |
| 68787 | | - } |
| 68788 | | - assert( u.ap.pReg->flags & MEM_Blob ); |
| 68789 | | - assert( memIsValid(u.ap.pReg) ); |
| 68790 | | - u.ap.payloadSize = u.ap.pReg->n; |
| 68791 | | - u.ap.zRec = u.ap.pReg->z; |
| 68792 | | - u.ap.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; |
| 68793 | | - assert( u.ap.payloadSize==0 || u.ap.zRec!=0 ); |
| 68794 | | - } |
| 68795 | | - |
| 68796 | | - /* If u.ap.payloadSize is 0, then just store a NULL. This can happen because of |
| 68797 | | - ** nullRow or because of a corrupt database. */ |
| 68798 | | - if( u.ap.payloadSize==0 ){ |
| 68799 | | - MemSetTypeFlag(u.ap.pDest, MEM_Null); |
| 68800 | | - goto op_column_out; |
| 68801 | | - } |
| 68802 | | - assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 ); |
| 68803 | | - if( u.ap.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 68804 | | - goto too_big; |
| 68805 | | - } |
| 68806 | | - |
| 68807 | | - u.ap.nField = u.ap.pC->nField; |
| 68808 | | - assert( u.ap.p2<u.ap.nField ); |
| 68809 | | - |
| 68810 | | - /* Read and parse the table header. Store the results of the parse |
| 68811 | | - ** into the record header cache fields of the cursor. |
| 68812 | | - */ |
| 68813 | | - u.ap.aType = u.ap.pC->aType; |
| 68814 | | - if( u.ap.pC->cacheStatus==p->cacheCtr ){ |
| 68815 | | - u.ap.aOffset = u.ap.pC->aOffset; |
| 68816 | | - }else{ |
| 68817 | | - assert(u.ap.aType); |
| 68818 | | - u.ap.avail = 0; |
| 68819 | | - u.ap.pC->aOffset = u.ap.aOffset = &u.ap.aType[u.ap.nField]; |
| 68820 | | - u.ap.pC->payloadSize = u.ap.payloadSize; |
| 68821 | | - u.ap.pC->cacheStatus = p->cacheCtr; |
| 68822 | | - |
| 68823 | | - /* Figure out how many bytes are in the header */ |
| 68824 | | - if( u.ap.zRec ){ |
| 68825 | | - u.ap.zData = u.ap.zRec; |
| 68826 | | - }else{ |
| 68827 | | - if( u.ap.pC->isIndex ){ |
| 68828 | | - u.ap.zData = (char*)sqlite3BtreeKeyFetch(u.ap.pCrsr, &u.ap.avail); |
| 68829 | | - }else{ |
| 68830 | | - u.ap.zData = (char*)sqlite3BtreeDataFetch(u.ap.pCrsr, &u.ap.avail); |
| 68831 | | - } |
| 68832 | | - /* If KeyFetch()/DataFetch() managed to get the entire payload, |
| 68833 | | - ** save the payload in the u.ap.pC->aRow cache. That will save us from |
| 68834 | | - ** having to make additional calls to fetch the content portion of |
| 68835 | | - ** the record. |
| 68836 | | - */ |
| 68837 | | - assert( u.ap.avail>=0 ); |
| 68838 | | - if( u.ap.payloadSize <= (u32)u.ap.avail ){ |
| 68839 | | - u.ap.zRec = u.ap.zData; |
| 68840 | | - u.ap.pC->aRow = (u8*)u.ap.zData; |
| 68841 | | - }else{ |
| 68842 | | - u.ap.pC->aRow = 0; |
| 68843 | | - } |
| 68844 | | - } |
| 68845 | | - /* The following assert is true in all cases except when |
| 68846 | | - ** the database file has been corrupted externally. |
| 68847 | | - ** assert( u.ap.zRec!=0 || u.ap.avail>=u.ap.payloadSize || u.ap.avail>=9 ); */ |
| 68848 | | - u.ap.szHdr = getVarint32((u8*)u.ap.zData, u.ap.offset); |
| 68386 | + assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ |
| 68387 | +#endif |
| 68388 | + pCrsr = pC->pCursor; |
| 68389 | + assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */ |
| 68390 | + assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */ |
| 68391 | + |
| 68392 | + /* If the cursor cache is stale, bring it up-to-date */ |
| 68393 | + rc = sqlite3VdbeCursorMoveto(pC); |
| 68394 | + if( rc ) goto abort_due_to_error; |
| 68395 | + if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){ |
| 68396 | + if( pC->nullRow ){ |
| 68397 | + if( pCrsr==0 ){ |
| 68398 | + assert( pC->pseudoTableReg>0 ); |
| 68399 | + pReg = &aMem[pC->pseudoTableReg]; |
| 68400 | + if( pC->multiPseudo ){ |
| 68401 | + sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem); |
| 68402 | + Deephemeralize(pDest); |
| 68403 | + goto op_column_out; |
| 68404 | + } |
| 68405 | + assert( pReg->flags & MEM_Blob ); |
| 68406 | + assert( memIsValid(pReg) ); |
| 68407 | + pC->payloadSize = pC->szRow = avail = pReg->n; |
| 68408 | + pC->aRow = (u8*)pReg->z; |
| 68409 | + }else{ |
| 68410 | + MemSetTypeFlag(pDest, MEM_Null); |
| 68411 | + goto op_column_out; |
| 68412 | + } |
| 68413 | + }else{ |
| 68414 | + assert( pCrsr ); |
| 68415 | + if( pC->isTable==0 ){ |
| 68416 | + assert( sqlite3BtreeCursorIsValid(pCrsr) ); |
| 68417 | + VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); |
| 68418 | + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 68419 | + /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the |
| 68420 | + ** payload size, so it is impossible for payloadSize64 to be |
| 68421 | + ** larger than 32 bits. */ |
| 68422 | + assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 ); |
| 68423 | + pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail); |
| 68424 | + pC->payloadSize = (u32)payloadSize64; |
| 68425 | + }else{ |
| 68426 | + assert( sqlite3BtreeCursorIsValid(pCrsr) ); |
| 68427 | + VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize); |
| 68428 | + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 68429 | + pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail); |
| 68430 | + } |
| 68431 | + assert( avail<=65536 ); /* Maximum page size is 64KiB */ |
| 68432 | + if( pC->payloadSize <= (u32)avail ){ |
| 68433 | + pC->szRow = pC->payloadSize; |
| 68434 | + }else{ |
| 68435 | + pC->szRow = avail; |
| 68436 | + } |
| 68437 | + if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 68438 | + goto too_big; |
| 68439 | + } |
| 68440 | + } |
| 68441 | + pC->cacheStatus = p->cacheCtr; |
| 68442 | + pC->iHdrOffset = getVarint32(pC->aRow, offset); |
| 68443 | + pC->nHdrParsed = 0; |
| 68444 | + aOffset[0] = offset; |
| 68445 | + if( avail<offset ){ |
| 68446 | + /* pC->aRow does not have to hold the entire row, but it does at least |
| 68447 | + ** need to cover the header of the record. If pC->aRow does not contain |
| 68448 | + ** the complete header, then set it to zero, forcing the header to be |
| 68449 | + ** dynamically allocated. */ |
| 68450 | + pC->aRow = 0; |
| 68451 | + pC->szRow = 0; |
| 68452 | + } |
| 68849 | 68453 | |
| 68850 | 68454 | /* Make sure a corrupt database has not given us an oversize header. |
| 68851 | 68455 | ** Do this now to avoid an oversize memory allocation. |
| 68852 | 68456 | ** |
| 68853 | 68457 | ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte |
| | @@ -68854,161 +68458,154 @@ |
| 68854 | 68458 | ** types use so much data space that there can only be 4096 and 32 of |
| 68855 | 68459 | ** them, respectively. So the maximum header length results from a |
| 68856 | 68460 | ** 3-byte type for each of the maximum of 32768 columns plus three |
| 68857 | 68461 | ** extra bytes for the header length itself. 32768*3 + 3 = 98307. |
| 68858 | 68462 | */ |
| 68859 | | - if( u.ap.offset > 98307 ){ |
| 68860 | | - rc = SQLITE_CORRUPT_BKPT; |
| 68861 | | - goto op_column_out; |
| 68862 | | - } |
| 68863 | | - |
| 68864 | | - /* Compute in u.ap.len the number of bytes of data we need to read in order |
| 68865 | | - ** to get u.ap.nField type values. u.ap.offset is an upper bound on this. But |
| 68866 | | - ** u.ap.nField might be significantly less than the true number of columns |
| 68867 | | - ** in the table, and in that case, 5*u.ap.nField+3 might be smaller than u.ap.offset. |
| 68868 | | - ** We want to minimize u.ap.len in order to limit the size of the memory |
| 68869 | | - ** allocation, especially if a corrupt database file has caused u.ap.offset |
| 68870 | | - ** to be oversized. Offset is limited to 98307 above. But 98307 might |
| 68871 | | - ** still exceed Robson memory allocation limits on some configurations. |
| 68872 | | - ** On systems that cannot tolerate large memory allocations, u.ap.nField*5+3 |
| 68873 | | - ** will likely be much smaller since u.ap.nField will likely be less than |
| 68874 | | - ** 20 or so. This insures that Robson memory allocation limits are |
| 68875 | | - ** not exceeded even for corrupt database files. |
| 68876 | | - */ |
| 68877 | | - u.ap.len = u.ap.nField*5 + 3; |
| 68878 | | - if( u.ap.len > (int)u.ap.offset ) u.ap.len = (int)u.ap.offset; |
| 68879 | | - |
| 68880 | | - /* The KeyFetch() or DataFetch() above are fast and will get the entire |
| 68881 | | - ** record header in most cases. But they will fail to get the complete |
| 68882 | | - ** record header if the record header does not fit on a single page |
| 68883 | | - ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to |
| 68884 | | - ** acquire the complete header text. |
| 68885 | | - */ |
| 68886 | | - if( !u.ap.zRec && u.ap.avail<u.ap.len ){ |
| 68887 | | - u.ap.sMem.flags = 0; |
| 68888 | | - u.ap.sMem.db = 0; |
| 68889 | | - rc = sqlite3VdbeMemFromBtree(u.ap.pCrsr, 0, u.ap.len, u.ap.pC->isIndex, &u.ap.sMem); |
| 68890 | | - if( rc!=SQLITE_OK ){ |
| 68891 | | - goto op_column_out; |
| 68892 | | - } |
| 68893 | | - u.ap.zData = u.ap.sMem.z; |
| 68894 | | - } |
| 68895 | | - u.ap.zEndHdr = (u8 *)&u.ap.zData[u.ap.len]; |
| 68896 | | - u.ap.zIdx = (u8 *)&u.ap.zData[u.ap.szHdr]; |
| 68897 | | - |
| 68898 | | - /* Scan the header and use it to fill in the u.ap.aType[] and u.ap.aOffset[] |
| 68899 | | - ** arrays. u.ap.aType[u.ap.i] will contain the type integer for the u.ap.i-th |
| 68900 | | - ** column and u.ap.aOffset[u.ap.i] will contain the u.ap.offset from the beginning |
| 68901 | | - ** of the record to the start of the data for the u.ap.i-th column |
| 68902 | | - */ |
| 68903 | | - for(u.ap.i=0; u.ap.i<u.ap.nField; u.ap.i++){ |
| 68904 | | - if( u.ap.zIdx<u.ap.zEndHdr ){ |
| 68905 | | - u.ap.aOffset[u.ap.i] = u.ap.offset; |
| 68906 | | - if( u.ap.zIdx[0]<0x80 ){ |
| 68907 | | - u.ap.t = u.ap.zIdx[0]; |
| 68908 | | - u.ap.zIdx++; |
| 68909 | | - }else{ |
| 68910 | | - u.ap.zIdx += sqlite3GetVarint32(u.ap.zIdx, &u.ap.t); |
| 68911 | | - } |
| 68912 | | - u.ap.aType[u.ap.i] = u.ap.t; |
| 68913 | | - u.ap.szField = sqlite3VdbeSerialTypeLen(u.ap.t); |
| 68914 | | - u.ap.offset += u.ap.szField; |
| 68915 | | - if( u.ap.offset<u.ap.szField ){ /* True if u.ap.offset overflows */ |
| 68916 | | - u.ap.zIdx = &u.ap.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ |
| 68917 | | - break; |
| 68918 | | - } |
| 68919 | | - }else{ |
| 68920 | | - /* If u.ap.i is less that u.ap.nField, then there are fewer fields in this |
| 68921 | | - ** record than SetNumColumns indicated there are columns in the |
| 68922 | | - ** table. Set the u.ap.offset for any extra columns not present in |
| 68923 | | - ** the record to 0. This tells code below to store the default value |
| 68924 | | - ** for the column instead of deserializing a value from the record. |
| 68925 | | - */ |
| 68926 | | - u.ap.aOffset[u.ap.i] = 0; |
| 68927 | | - } |
| 68928 | | - } |
| 68929 | | - sqlite3VdbeMemRelease(&u.ap.sMem); |
| 68930 | | - u.ap.sMem.flags = MEM_Null; |
| 68931 | | - |
| 68932 | | - /* If we have read more header data than was contained in the header, |
| 68933 | | - ** or if the end of the last field appears to be past the end of the |
| 68934 | | - ** record, or if the end of the last field appears to be before the end |
| 68935 | | - ** of the record (when all fields present), then we must be dealing |
| 68936 | | - ** with a corrupt database. |
| 68937 | | - */ |
| 68938 | | - if( (u.ap.zIdx > u.ap.zEndHdr) || (u.ap.offset > u.ap.payloadSize) |
| 68939 | | - || (u.ap.zIdx==u.ap.zEndHdr && u.ap.offset!=u.ap.payloadSize) ){ |
| 68940 | | - rc = SQLITE_CORRUPT_BKPT; |
| 68941 | | - goto op_column_out; |
| 68942 | | - } |
| 68943 | | - } |
| 68944 | | - |
| 68945 | | - /* Get the column information. If u.ap.aOffset[u.ap.p2] is non-zero, then |
| 68946 | | - ** deserialize the value from the record. If u.ap.aOffset[u.ap.p2] is zero, |
| 68947 | | - ** then there are not enough fields in the record to satisfy the |
| 68948 | | - ** request. In this case, set the value NULL or to P4 if P4 is |
| 68949 | | - ** a pointer to a Mem object. |
| 68950 | | - */ |
| 68951 | | - if( u.ap.aOffset[u.ap.p2] ){ |
| 68952 | | - assert( rc==SQLITE_OK ); |
| 68953 | | - if( u.ap.zRec ){ |
| 68954 | | - /* This is the common case where the whole row fits on a single page */ |
| 68955 | | - VdbeMemRelease(u.ap.pDest); |
| 68956 | | - sqlite3VdbeSerialGet((u8 *)&u.ap.zRec[u.ap.aOffset[u.ap.p2]], u.ap.aType[u.ap.p2], u.ap.pDest); |
| 68957 | | - }else{ |
| 68958 | | - /* This branch happens only when the row overflows onto multiple pages */ |
| 68959 | | - u.ap.t = u.ap.aType[u.ap.p2]; |
| 68960 | | - if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 |
| 68961 | | - && ((u.ap.t>=12 && (u.ap.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0) |
| 68962 | | - ){ |
| 68963 | | - /* Content is irrelevant for the typeof() function and for |
| 68964 | | - ** the length(X) function if X is a blob. So we might as well use |
| 68965 | | - ** bogus content rather than reading content from disk. NULL works |
| 68966 | | - ** for text and blob and whatever is in the u.ap.payloadSize64 variable |
| 68967 | | - ** will work for everything else. */ |
| 68968 | | - u.ap.zData = u.ap.t<12 ? (char*)&u.ap.payloadSize64 : 0; |
| 68969 | | - }else{ |
| 68970 | | - u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.t); |
| 68971 | | - sqlite3VdbeMemMove(&u.ap.sMem, u.ap.pDest); |
| 68972 | | - rc = sqlite3VdbeMemFromBtree(u.ap.pCrsr, u.ap.aOffset[u.ap.p2], u.ap.len, u.ap.pC->isIndex, |
| 68973 | | - &u.ap.sMem); |
| 68974 | | - if( rc!=SQLITE_OK ){ |
| 68975 | | - goto op_column_out; |
| 68976 | | - } |
| 68977 | | - u.ap.zData = u.ap.sMem.z; |
| 68978 | | - } |
| 68979 | | - sqlite3VdbeSerialGet((u8*)u.ap.zData, u.ap.t, u.ap.pDest); |
| 68980 | | - } |
| 68981 | | - u.ap.pDest->enc = encoding; |
| 68982 | | - }else{ |
| 68983 | | - if( pOp->p4type==P4_MEM ){ |
| 68984 | | - sqlite3VdbeMemShallowCopy(u.ap.pDest, pOp->p4.pMem, MEM_Static); |
| 68985 | | - }else{ |
| 68986 | | - MemSetTypeFlag(u.ap.pDest, MEM_Null); |
| 68987 | | - } |
| 68988 | | - } |
| 68989 | | - |
| 68990 | | - /* If we dynamically allocated space to hold the data (in the |
| 68991 | | - ** sqlite3VdbeMemFromBtree() call above) then transfer control of that |
| 68992 | | - ** dynamically allocated space over to the u.ap.pDest structure. |
| 68993 | | - ** This prevents a memory copy. |
| 68994 | | - */ |
| 68995 | | - if( u.ap.sMem.zMalloc ){ |
| 68996 | | - assert( u.ap.sMem.z==u.ap.sMem.zMalloc ); |
| 68997 | | - assert( !(u.ap.pDest->flags & MEM_Dyn) ); |
| 68998 | | - assert( !(u.ap.pDest->flags & (MEM_Blob|MEM_Str)) || u.ap.pDest->z==u.ap.sMem.z ); |
| 68999 | | - u.ap.pDest->flags &= ~(MEM_Ephem|MEM_Static); |
| 69000 | | - u.ap.pDest->flags |= MEM_Term; |
| 69001 | | - u.ap.pDest->z = u.ap.sMem.z; |
| 69002 | | - u.ap.pDest->zMalloc = u.ap.sMem.zMalloc; |
| 69003 | | - } |
| 69004 | | - |
| 69005 | | - rc = sqlite3VdbeMemMakeWriteable(u.ap.pDest); |
| 69006 | | - |
| 69007 | | -op_column_out: |
| 69008 | | - UPDATE_MAX_BLOBSIZE(u.ap.pDest); |
| 69009 | | - REGISTER_TRACE(pOp->p3, u.ap.pDest); |
| 68463 | + if( offset > 98307 || offset > pC->payloadSize ){ |
| 68464 | + rc = SQLITE_CORRUPT_BKPT; |
| 68465 | + goto op_column_error; |
| 68466 | + } |
| 68467 | + } |
| 68468 | + |
| 68469 | + /* Make sure at least the first p2+1 entries of the header have been |
| 68470 | + ** parsed and valid information is in aOffset[] and aType[]. |
| 68471 | + */ |
| 68472 | + if( pC->nHdrParsed<=p2 ){ |
| 68473 | + /* If there is more header available for parsing in the record, try |
| 68474 | + ** to extract additional fields up through the p2+1-th field |
| 68475 | + */ |
| 68476 | + if( pC->iHdrOffset<aOffset[0] ){ |
| 68477 | + /* Make sure zData points to enough of the record to cover the header. */ |
| 68478 | + if( pC->aRow==0 ){ |
| 68479 | + memset(&sMem, 0, sizeof(sMem)); |
| 68480 | + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], |
| 68481 | + !pC->isTable, &sMem); |
| 68482 | + if( rc!=SQLITE_OK ){ |
| 68483 | + goto op_column_error; |
| 68484 | + } |
| 68485 | + zData = (u8*)sMem.z; |
| 68486 | + }else{ |
| 68487 | + zData = pC->aRow; |
| 68488 | + } |
| 68489 | + |
| 68490 | + /* Fill in aType[i] and aOffset[i] values through the p2-th field. */ |
| 68491 | + i = pC->nHdrParsed; |
| 68492 | + offset = aOffset[i]; |
| 68493 | + zHdr = zData + pC->iHdrOffset; |
| 68494 | + zEndHdr = zData + aOffset[0]; |
| 68495 | + assert( i<=p2 && zHdr<zEndHdr ); |
| 68496 | + do{ |
| 68497 | + if( zHdr[0]<0x80 ){ |
| 68498 | + t = zHdr[0]; |
| 68499 | + zHdr++; |
| 68500 | + }else{ |
| 68501 | + zHdr += sqlite3GetVarint32(zHdr, &t); |
| 68502 | + } |
| 68503 | + aType[i] = t; |
| 68504 | + szField = sqlite3VdbeSerialTypeLen(t); |
| 68505 | + offset += szField; |
| 68506 | + if( offset<szField ){ /* True if offset overflows */ |
| 68507 | + zHdr = &zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */ |
| 68508 | + break; |
| 68509 | + } |
| 68510 | + i++; |
| 68511 | + aOffset[i] = offset; |
| 68512 | + }while( i<=p2 && zHdr<zEndHdr ); |
| 68513 | + pC->nHdrParsed = i; |
| 68514 | + pC->iHdrOffset = (u32)(zHdr - zData); |
| 68515 | + if( pC->aRow==0 ){ |
| 68516 | + sqlite3VdbeMemRelease(&sMem); |
| 68517 | + sMem.flags = MEM_Null; |
| 68518 | + } |
| 68519 | + |
| 68520 | + /* If we have read more header data than was contained in the header, |
| 68521 | + ** or if the end of the last field appears to be past the end of the |
| 68522 | + ** record, or if the end of the last field appears to be before the end |
| 68523 | + ** of the record (when all fields present), then we must be dealing |
| 68524 | + ** with a corrupt database. |
| 68525 | + */ |
| 68526 | + if( (zHdr > zEndHdr) |
| 68527 | + || (offset > pC->payloadSize) |
| 68528 | + || (zHdr==zEndHdr && offset!=pC->payloadSize) |
| 68529 | + ){ |
| 68530 | + rc = SQLITE_CORRUPT_BKPT; |
| 68531 | + goto op_column_error; |
| 68532 | + } |
| 68533 | + } |
| 68534 | + |
| 68535 | + /* If after trying to extra new entries from the header, nHdrParsed is |
| 68536 | + ** still not up to p2, that means that the record has fewer than p2 |
| 68537 | + ** columns. So the result will be either the default value or a NULL. |
| 68538 | + */ |
| 68539 | + if( pC->nHdrParsed<=p2 ){ |
| 68540 | + if( pOp->p4type==P4_MEM ){ |
| 68541 | + sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); |
| 68542 | + }else{ |
| 68543 | + MemSetTypeFlag(pDest, MEM_Null); |
| 68544 | + } |
| 68545 | + goto op_column_out; |
| 68546 | + } |
| 68547 | + } |
| 68548 | + |
| 68549 | + /* Extract the content for the p2+1-th column. Control can only |
| 68550 | + ** reach this point if aOffset[p2], aOffset[p2+1], and aType[p2] are |
| 68551 | + ** all valid. |
| 68552 | + */ |
| 68553 | + assert( p2<pC->nHdrParsed ); |
| 68554 | + assert( rc==SQLITE_OK ); |
| 68555 | + if( pC->szRow>=aOffset[p2+1] ){ |
| 68556 | + /* This is the common case where the desired content fits on the original |
| 68557 | + ** page - where the content is not on an overflow page */ |
| 68558 | + VdbeMemRelease(pDest); |
| 68559 | + sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); |
| 68560 | + }else{ |
| 68561 | + /* This branch happens only when content is on overflow pages */ |
| 68562 | + t = aType[p2]; |
| 68563 | + if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 |
| 68564 | + && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) |
| 68565 | + || (len = sqlite3VdbeSerialTypeLen(t))==0 |
| 68566 | + ){ |
| 68567 | + /* Content is irrelevant for the typeof() function and for |
| 68568 | + ** the length(X) function if X is a blob. So we might as well use |
| 68569 | + ** bogus content rather than reading content from disk. NULL works |
| 68570 | + ** for text and blob and whatever is in the payloadSize64 variable |
| 68571 | + ** will work for everything else. Content is also irrelevant if |
| 68572 | + ** the content length is 0. */ |
| 68573 | + zData = t<=13 ? (u8*)&payloadSize64 : 0; |
| 68574 | + sMem.zMalloc = 0; |
| 68575 | + }else{ |
| 68576 | + memset(&sMem, 0, sizeof(sMem)); |
| 68577 | + sqlite3VdbeMemMove(&sMem, pDest); |
| 68578 | + rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable, |
| 68579 | + &sMem); |
| 68580 | + if( rc!=SQLITE_OK ){ |
| 68581 | + goto op_column_error; |
| 68582 | + } |
| 68583 | + zData = (u8*)sMem.z; |
| 68584 | + } |
| 68585 | + sqlite3VdbeSerialGet(zData, t, pDest); |
| 68586 | + /* If we dynamically allocated space to hold the data (in the |
| 68587 | + ** sqlite3VdbeMemFromBtree() call above) then transfer control of that |
| 68588 | + ** dynamically allocated space over to the pDest structure. |
| 68589 | + ** This prevents a memory copy. */ |
| 68590 | + if( sMem.zMalloc ){ |
| 68591 | + assert( sMem.z==sMem.zMalloc ); |
| 68592 | + assert( !(pDest->flags & MEM_Dyn) ); |
| 68593 | + assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z ); |
| 68594 | + pDest->flags &= ~(MEM_Ephem|MEM_Static); |
| 68595 | + pDest->flags |= MEM_Term; |
| 68596 | + pDest->z = sMem.z; |
| 68597 | + pDest->zMalloc = sMem.zMalloc; |
| 68598 | + } |
| 68599 | + } |
| 68600 | + pDest->enc = encoding; |
| 68601 | + |
| 68602 | +op_column_out: |
| 68603 | + Deephemeralize(pDest); |
| 68604 | +op_column_error: |
| 68605 | + UPDATE_MAX_BLOBSIZE(pDest); |
| 68606 | + REGISTER_TRACE(pOp->p3, pDest); |
| 69010 | 68607 | break; |
| 69011 | 68608 | } |
| 69012 | 68609 | |
| 69013 | 68610 | /* Opcode: Affinity P1 P2 * P4 * |
| 69014 | 68611 | ** Synopsis: affinity(r[P1@P2]) |
| | @@ -69018,24 +68615,22 @@ |
| 69018 | 68615 | ** P4 is a string that is P2 characters long. The nth character of the |
| 69019 | 68616 | ** string indicates the column affinity that should be used for the nth |
| 69020 | 68617 | ** memory cell in the range. |
| 69021 | 68618 | */ |
| 69022 | 68619 | case OP_Affinity: { |
| 69023 | | -#if 0 /* local variables moved into u.aq */ |
| 69024 | 68620 | const char *zAffinity; /* The affinity to be applied */ |
| 69025 | 68621 | char cAff; /* A single character of affinity */ |
| 69026 | | -#endif /* local variables moved into u.aq */ |
| 69027 | 68622 | |
| 69028 | | - u.aq.zAffinity = pOp->p4.z; |
| 69029 | | - assert( u.aq.zAffinity!=0 ); |
| 69030 | | - assert( u.aq.zAffinity[pOp->p2]==0 ); |
| 68623 | + zAffinity = pOp->p4.z; |
| 68624 | + assert( zAffinity!=0 ); |
| 68625 | + assert( zAffinity[pOp->p2]==0 ); |
| 69031 | 68626 | pIn1 = &aMem[pOp->p1]; |
| 69032 | | - while( (u.aq.cAff = *(u.aq.zAffinity++))!=0 ){ |
| 68627 | + while( (cAff = *(zAffinity++))!=0 ){ |
| 69033 | 68628 | assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); |
| 69034 | 68629 | assert( memIsValid(pIn1) ); |
| 69035 | 68630 | ExpandBlob(pIn1); |
| 69036 | | - applyAffinity(pIn1, u.aq.cAff, encoding); |
| 68631 | + applyAffinity(pIn1, cAff, encoding); |
| 69037 | 68632 | pIn1++; |
| 69038 | 68633 | } |
| 69039 | 68634 | break; |
| 69040 | 68635 | } |
| 69041 | 68636 | |
| | @@ -69054,11 +68649,10 @@ |
| 69054 | 68649 | ** macros defined in sqliteInt.h. |
| 69055 | 68650 | ** |
| 69056 | 68651 | ** If P4 is NULL then all index fields have the affinity NONE. |
| 69057 | 68652 | */ |
| 69058 | 68653 | case OP_MakeRecord: { |
| 69059 | | -#if 0 /* local variables moved into u.ar */ |
| 69060 | 68654 | u8 *zNewRecord; /* A buffer to hold the data for the new record */ |
| 69061 | 68655 | Mem *pRec; /* The new record */ |
| 69062 | 68656 | u64 nData; /* Number of bytes of data space */ |
| 69063 | 68657 | int nHdr; /* Number of bytes of header space */ |
| 69064 | 68658 | i64 nByte; /* Data space required for this record */ |
| | @@ -69068,106 +68662,123 @@ |
| 69068 | 68662 | Mem *pData0; /* First field to be combined into the record */ |
| 69069 | 68663 | Mem *pLast; /* Last field of the record */ |
| 69070 | 68664 | int nField; /* Number of fields in the record */ |
| 69071 | 68665 | char *zAffinity; /* The affinity string for the record */ |
| 69072 | 68666 | int file_format; /* File format to use for encoding */ |
| 69073 | | - int i; /* Space used in zNewRecord[] */ |
| 68667 | + int i; /* Space used in zNewRecord[] header */ |
| 68668 | + int j; /* Space used in zNewRecord[] content */ |
| 69074 | 68669 | int len; /* Length of a field */ |
| 69075 | | -#endif /* local variables moved into u.ar */ |
| 69076 | 68670 | |
| 69077 | 68671 | /* Assuming the record contains N fields, the record format looks |
| 69078 | 68672 | ** like this: |
| 69079 | 68673 | ** |
| 69080 | 68674 | ** ------------------------------------------------------------------------ |
| 69081 | | - ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | |
| 68675 | + ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | |
| 69082 | 68676 | ** ------------------------------------------------------------------------ |
| 69083 | 68677 | ** |
| 69084 | 68678 | ** Data(0) is taken from register P1. Data(1) comes from register P1+1 |
| 69085 | 68679 | ** and so froth. |
| 69086 | 68680 | ** |
| 69087 | | - ** Each type field is a varint representing the serial type of the |
| 68681 | + ** Each type field is a varint representing the serial type of the |
| 69088 | 68682 | ** corresponding data element (see sqlite3VdbeSerialType()). The |
| 69089 | 68683 | ** hdr-size field is also a varint which is the offset from the beginning |
| 69090 | 68684 | ** of the record to data0. |
| 69091 | 68685 | */ |
| 69092 | | - u.ar.nData = 0; /* Number of bytes of data space */ |
| 69093 | | - u.ar.nHdr = 0; /* Number of bytes of header space */ |
| 69094 | | - u.ar.nZero = 0; /* Number of zero bytes at the end of the record */ |
| 69095 | | - u.ar.nField = pOp->p1; |
| 69096 | | - u.ar.zAffinity = pOp->p4.z; |
| 69097 | | - assert( u.ar.nField>0 && pOp->p2>0 && pOp->p2+u.ar.nField<=(p->nMem-p->nCursor)+1 ); |
| 69098 | | - u.ar.pData0 = &aMem[u.ar.nField]; |
| 69099 | | - u.ar.nField = pOp->p2; |
| 69100 | | - u.ar.pLast = &u.ar.pData0[u.ar.nField-1]; |
| 69101 | | - u.ar.file_format = p->minWriteFileFormat; |
| 68686 | + nData = 0; /* Number of bytes of data space */ |
| 68687 | + nHdr = 0; /* Number of bytes of header space */ |
| 68688 | + nZero = 0; /* Number of zero bytes at the end of the record */ |
| 68689 | + nField = pOp->p1; |
| 68690 | + zAffinity = pOp->p4.z; |
| 68691 | + assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 ); |
| 68692 | + pData0 = &aMem[nField]; |
| 68693 | + nField = pOp->p2; |
| 68694 | + pLast = &pData0[nField-1]; |
| 68695 | + file_format = p->minWriteFileFormat; |
| 69102 | 68696 | |
| 69103 | 68697 | /* Identify the output register */ |
| 69104 | 68698 | assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 ); |
| 69105 | 68699 | pOut = &aMem[pOp->p3]; |
| 69106 | 68700 | memAboutToChange(p, pOut); |
| 68701 | + |
| 68702 | + /* Apply the requested affinity to all inputs |
| 68703 | + */ |
| 68704 | + assert( pData0<=pLast ); |
| 68705 | + if( zAffinity ){ |
| 68706 | + pRec = pData0; |
| 68707 | + do{ |
| 68708 | + applyAffinity(pRec, *(zAffinity++), encoding); |
| 68709 | + }while( (++pRec)<=pLast ); |
| 68710 | + } |
| 69107 | 68711 | |
| 69108 | 68712 | /* Loop through the elements that will make up the record to figure |
| 69109 | 68713 | ** out how much space is required for the new record. |
| 69110 | 68714 | */ |
| 69111 | | - for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){ |
| 69112 | | - assert( memIsValid(u.ar.pRec) ); |
| 69113 | | - if( u.ar.zAffinity ){ |
| 69114 | | - applyAffinity(u.ar.pRec, u.ar.zAffinity[u.ar.pRec-u.ar.pData0], encoding); |
| 69115 | | - } |
| 69116 | | - if( u.ar.pRec->flags&MEM_Zero && u.ar.pRec->n>0 ){ |
| 69117 | | - sqlite3VdbeMemExpandBlob(u.ar.pRec); |
| 69118 | | - } |
| 69119 | | - u.ar.serial_type = sqlite3VdbeSerialType(u.ar.pRec, u.ar.file_format); |
| 69120 | | - u.ar.len = sqlite3VdbeSerialTypeLen(u.ar.serial_type); |
| 69121 | | - u.ar.nData += u.ar.len; |
| 69122 | | - u.ar.nHdr += sqlite3VarintLen(u.ar.serial_type); |
| 69123 | | - if( u.ar.pRec->flags & MEM_Zero ){ |
| 69124 | | - /* Only pure zero-filled BLOBs can be input to this Opcode. |
| 69125 | | - ** We do not allow blobs with a prefix and a zero-filled tail. */ |
| 69126 | | - u.ar.nZero += u.ar.pRec->u.nZero; |
| 69127 | | - }else if( u.ar.len ){ |
| 69128 | | - u.ar.nZero = 0; |
| 69129 | | - } |
| 69130 | | - } |
| 68715 | + pRec = pLast; |
| 68716 | + do{ |
| 68717 | + assert( memIsValid(pRec) ); |
| 68718 | + serial_type = sqlite3VdbeSerialType(pRec, file_format); |
| 68719 | + len = sqlite3VdbeSerialTypeLen(serial_type); |
| 68720 | + if( pRec->flags & MEM_Zero ){ |
| 68721 | + if( nData ){ |
| 68722 | + sqlite3VdbeMemExpandBlob(pRec); |
| 68723 | + }else{ |
| 68724 | + nZero += pRec->u.nZero; |
| 68725 | + len -= pRec->u.nZero; |
| 68726 | + } |
| 68727 | + } |
| 68728 | + nData += len; |
| 68729 | + testcase( serial_type==127 ); |
| 68730 | + testcase( serial_type==128 ); |
| 68731 | + nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); |
| 68732 | + }while( (--pRec)>=pData0 ); |
| 69131 | 68733 | |
| 69132 | 68734 | /* Add the initial header varint and total the size */ |
| 69133 | | - u.ar.nHdr += u.ar.nVarint = sqlite3VarintLen(u.ar.nHdr); |
| 69134 | | - if( u.ar.nVarint<sqlite3VarintLen(u.ar.nHdr) ){ |
| 69135 | | - u.ar.nHdr++; |
| 68735 | + testcase( nHdr==126 ); |
| 68736 | + testcase( nHdr==127 ); |
| 68737 | + if( nHdr<=126 ){ |
| 68738 | + /* The common case */ |
| 68739 | + nHdr += 1; |
| 68740 | + }else{ |
| 68741 | + /* Rare case of a really large header */ |
| 68742 | + nVarint = sqlite3VarintLen(nHdr); |
| 68743 | + nHdr += nVarint; |
| 68744 | + if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++; |
| 69136 | 68745 | } |
| 69137 | | - u.ar.nByte = u.ar.nHdr+u.ar.nData-u.ar.nZero; |
| 69138 | | - if( u.ar.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 68746 | + nByte = nHdr+nData; |
| 68747 | + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 69139 | 68748 | goto too_big; |
| 69140 | 68749 | } |
| 69141 | 68750 | |
| 69142 | | - /* Make sure the output register has a buffer large enough to store |
| 68751 | + /* Make sure the output register has a buffer large enough to store |
| 69143 | 68752 | ** the new record. The output register (pOp->p3) is not allowed to |
| 69144 | 68753 | ** be one of the input registers (because the following call to |
| 69145 | 68754 | ** sqlite3VdbeMemGrow() could clobber the value before it is used). |
| 69146 | 68755 | */ |
| 69147 | | - if( sqlite3VdbeMemGrow(pOut, (int)u.ar.nByte, 0) ){ |
| 68756 | + if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){ |
| 69148 | 68757 | goto no_mem; |
| 69149 | 68758 | } |
| 69150 | | - u.ar.zNewRecord = (u8 *)pOut->z; |
| 68759 | + zNewRecord = (u8 *)pOut->z; |
| 69151 | 68760 | |
| 69152 | 68761 | /* Write the record */ |
| 69153 | | - u.ar.i = putVarint32(u.ar.zNewRecord, u.ar.nHdr); |
| 69154 | | - for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){ |
| 69155 | | - u.ar.serial_type = sqlite3VdbeSerialType(u.ar.pRec, u.ar.file_format); |
| 69156 | | - u.ar.i += putVarint32(&u.ar.zNewRecord[u.ar.i], u.ar.serial_type); /* serial type */ |
| 69157 | | - } |
| 69158 | | - for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){ /* serial data */ |
| 69159 | | - u.ar.i += sqlite3VdbeSerialPut(&u.ar.zNewRecord[u.ar.i], (int)(u.ar.nByte-u.ar.i), u.ar.pRec,u.ar.file_format); |
| 69160 | | - } |
| 69161 | | - assert( u.ar.i==u.ar.nByte ); |
| 68762 | + i = putVarint32(zNewRecord, nHdr); |
| 68763 | + j = nHdr; |
| 68764 | + assert( pData0<=pLast ); |
| 68765 | + pRec = pData0; |
| 68766 | + do{ |
| 68767 | + serial_type = sqlite3VdbeSerialType(pRec, file_format); |
| 68768 | + i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ |
| 68769 | + j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ |
| 68770 | + }while( (++pRec)<=pLast ); |
| 68771 | + assert( i==nHdr ); |
| 68772 | + assert( j==nByte ); |
| 69162 | 68773 | |
| 69163 | 68774 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 69164 | | - pOut->n = (int)u.ar.nByte; |
| 68775 | + pOut->n = (int)nByte; |
| 69165 | 68776 | pOut->flags = MEM_Blob | MEM_Dyn; |
| 69166 | 68777 | pOut->xDel = 0; |
| 69167 | | - if( u.ar.nZero ){ |
| 69168 | | - pOut->u.nZero = u.ar.nZero; |
| 68778 | + if( nZero ){ |
| 68779 | + pOut->u.nZero = nZero; |
| 69169 | 68780 | pOut->flags |= MEM_Zero; |
| 69170 | 68781 | } |
| 69171 | 68782 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ |
| 69172 | 68783 | REGISTER_TRACE(pOp->p3, pOut); |
| 69173 | 68784 | UPDATE_MAX_BLOBSIZE(pOut); |
| | @@ -69180,19 +68791,18 @@ |
| 69180 | 68791 | ** Store the number of entries (an integer value) in the table or index |
| 69181 | 68792 | ** opened by cursor P1 in register P2 |
| 69182 | 68793 | */ |
| 69183 | 68794 | #ifndef SQLITE_OMIT_BTREECOUNT |
| 69184 | 68795 | case OP_Count: { /* out2-prerelease */ |
| 69185 | | -#if 0 /* local variables moved into u.as */ |
| 69186 | 68796 | i64 nEntry; |
| 69187 | 68797 | BtCursor *pCrsr; |
| 69188 | | -#endif /* local variables moved into u.as */ |
| 69189 | 68798 | |
| 69190 | | - u.as.pCrsr = p->apCsr[pOp->p1]->pCursor; |
| 69191 | | - assert( u.as.pCrsr ); |
| 69192 | | - rc = sqlite3BtreeCount(u.as.pCrsr, &u.as.nEntry); |
| 69193 | | - pOut->u.i = u.as.nEntry; |
| 68799 | + pCrsr = p->apCsr[pOp->p1]->pCursor; |
| 68800 | + assert( pCrsr ); |
| 68801 | + nEntry = 0; /* Not needed. Only used to silence a warning. */ |
| 68802 | + rc = sqlite3BtreeCount(pCrsr, &nEntry); |
| 68803 | + pOut->u.i = nEntry; |
| 69194 | 68804 | break; |
| 69195 | 68805 | } |
| 69196 | 68806 | #endif |
| 69197 | 68807 | |
| 69198 | 68808 | /* Opcode: Savepoint P1 * * P4 * |
| | @@ -69200,43 +68810,41 @@ |
| 69200 | 68810 | ** Open, release or rollback the savepoint named by parameter P4, depending |
| 69201 | 68811 | ** on the value of P1. To open a new savepoint, P1==0. To release (commit) an |
| 69202 | 68812 | ** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. |
| 69203 | 68813 | */ |
| 69204 | 68814 | case OP_Savepoint: { |
| 69205 | | -#if 0 /* local variables moved into u.at */ |
| 69206 | 68815 | int p1; /* Value of P1 operand */ |
| 69207 | 68816 | char *zName; /* Name of savepoint */ |
| 69208 | 68817 | int nName; |
| 69209 | 68818 | Savepoint *pNew; |
| 69210 | 68819 | Savepoint *pSavepoint; |
| 69211 | 68820 | Savepoint *pTmp; |
| 69212 | 68821 | int iSavepoint; |
| 69213 | 68822 | int ii; |
| 69214 | | -#endif /* local variables moved into u.at */ |
| 69215 | 68823 | |
| 69216 | | - u.at.p1 = pOp->p1; |
| 69217 | | - u.at.zName = pOp->p4.z; |
| 68824 | + p1 = pOp->p1; |
| 68825 | + zName = pOp->p4.z; |
| 69218 | 68826 | |
| 69219 | | - /* Assert that the u.at.p1 parameter is valid. Also that if there is no open |
| 69220 | | - ** transaction, then there cannot be any savepoints. |
| 68827 | + /* Assert that the p1 parameter is valid. Also that if there is no open |
| 68828 | + ** transaction, then there cannot be any savepoints. |
| 69221 | 68829 | */ |
| 69222 | 68830 | assert( db->pSavepoint==0 || db->autoCommit==0 ); |
| 69223 | | - assert( u.at.p1==SAVEPOINT_BEGIN||u.at.p1==SAVEPOINT_RELEASE||u.at.p1==SAVEPOINT_ROLLBACK ); |
| 68831 | + assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); |
| 69224 | 68832 | assert( db->pSavepoint || db->isTransactionSavepoint==0 ); |
| 69225 | 68833 | assert( checkSavepointCount(db) ); |
| 69226 | 68834 | assert( p->bIsReader ); |
| 69227 | 68835 | |
| 69228 | | - if( u.at.p1==SAVEPOINT_BEGIN ){ |
| 68836 | + if( p1==SAVEPOINT_BEGIN ){ |
| 69229 | 68837 | if( db->nVdbeWrite>0 ){ |
| 69230 | | - /* A new savepoint cannot be created if there are active write |
| 68838 | + /* A new savepoint cannot be created if there are active write |
| 69231 | 68839 | ** statements (i.e. open read/write incremental blob handles). |
| 69232 | 68840 | */ |
| 69233 | 68841 | sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - " |
| 69234 | 68842 | "SQL statements in progress"); |
| 69235 | 68843 | rc = SQLITE_BUSY; |
| 69236 | 68844 | }else{ |
| 69237 | | - u.at.nName = sqlite3Strlen30(u.at.zName); |
| 68845 | + nName = sqlite3Strlen30(zName); |
| 69238 | 68846 | |
| 69239 | 68847 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 69240 | 68848 | /* This call is Ok even if this savepoint is actually a transaction |
| 69241 | 68849 | ** savepoint (and therefore should not prompt xSavepoint()) callbacks. |
| 69242 | 68850 | ** If this is a transaction savepoint being opened, it is guaranteed |
| | @@ -69246,62 +68854,62 @@ |
| 69246 | 68854 | db->nStatement+db->nSavepoint); |
| 69247 | 68855 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 69248 | 68856 | #endif |
| 69249 | 68857 | |
| 69250 | 68858 | /* Create a new savepoint structure. */ |
| 69251 | | - u.at.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.at.nName+1); |
| 69252 | | - if( u.at.pNew ){ |
| 69253 | | - u.at.pNew->zName = (char *)&u.at.pNew[1]; |
| 69254 | | - memcpy(u.at.pNew->zName, u.at.zName, u.at.nName+1); |
| 69255 | | - |
| 68859 | + pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1); |
| 68860 | + if( pNew ){ |
| 68861 | + pNew->zName = (char *)&pNew[1]; |
| 68862 | + memcpy(pNew->zName, zName, nName+1); |
| 68863 | + |
| 69256 | 68864 | /* If there is no open transaction, then mark this as a special |
| 69257 | 68865 | ** "transaction savepoint". */ |
| 69258 | 68866 | if( db->autoCommit ){ |
| 69259 | 68867 | db->autoCommit = 0; |
| 69260 | 68868 | db->isTransactionSavepoint = 1; |
| 69261 | 68869 | }else{ |
| 69262 | 68870 | db->nSavepoint++; |
| 69263 | 68871 | } |
| 69264 | | - |
| 68872 | + |
| 69265 | 68873 | /* Link the new savepoint into the database handle's list. */ |
| 69266 | | - u.at.pNew->pNext = db->pSavepoint; |
| 69267 | | - db->pSavepoint = u.at.pNew; |
| 69268 | | - u.at.pNew->nDeferredCons = db->nDeferredCons; |
| 69269 | | - u.at.pNew->nDeferredImmCons = db->nDeferredImmCons; |
| 68874 | + pNew->pNext = db->pSavepoint; |
| 68875 | + db->pSavepoint = pNew; |
| 68876 | + pNew->nDeferredCons = db->nDeferredCons; |
| 68877 | + pNew->nDeferredImmCons = db->nDeferredImmCons; |
| 69270 | 68878 | } |
| 69271 | 68879 | } |
| 69272 | 68880 | }else{ |
| 69273 | | - u.at.iSavepoint = 0; |
| 68881 | + iSavepoint = 0; |
| 69274 | 68882 | |
| 69275 | 68883 | /* Find the named savepoint. If there is no such savepoint, then an |
| 69276 | 68884 | ** an error is returned to the user. */ |
| 69277 | 68885 | for( |
| 69278 | | - u.at.pSavepoint = db->pSavepoint; |
| 69279 | | - u.at.pSavepoint && sqlite3StrICmp(u.at.pSavepoint->zName, u.at.zName); |
| 69280 | | - u.at.pSavepoint = u.at.pSavepoint->pNext |
| 68886 | + pSavepoint = db->pSavepoint; |
| 68887 | + pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName); |
| 68888 | + pSavepoint = pSavepoint->pNext |
| 69281 | 68889 | ){ |
| 69282 | | - u.at.iSavepoint++; |
| 68890 | + iSavepoint++; |
| 69283 | 68891 | } |
| 69284 | | - if( !u.at.pSavepoint ){ |
| 69285 | | - sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.at.zName); |
| 68892 | + if( !pSavepoint ){ |
| 68893 | + sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName); |
| 69286 | 68894 | rc = SQLITE_ERROR; |
| 69287 | | - }else if( db->nVdbeWrite>0 && u.at.p1==SAVEPOINT_RELEASE ){ |
| 69288 | | - /* It is not possible to release (commit) a savepoint if there are |
| 68895 | + }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){ |
| 68896 | + /* It is not possible to release (commit) a savepoint if there are |
| 69289 | 68897 | ** active write statements. |
| 69290 | 68898 | */ |
| 69291 | | - sqlite3SetString(&p->zErrMsg, db, |
| 68899 | + sqlite3SetString(&p->zErrMsg, db, |
| 69292 | 68900 | "cannot release savepoint - SQL statements in progress" |
| 69293 | 68901 | ); |
| 69294 | 68902 | rc = SQLITE_BUSY; |
| 69295 | 68903 | }else{ |
| 69296 | 68904 | |
| 69297 | 68905 | /* Determine whether or not this is a transaction savepoint. If so, |
| 69298 | | - ** and this is a RELEASE command, then the current transaction |
| 69299 | | - ** is committed. |
| 68906 | + ** and this is a RELEASE command, then the current transaction |
| 68907 | + ** is committed. |
| 69300 | 68908 | */ |
| 69301 | | - int isTransaction = u.at.pSavepoint->pNext==0 && db->isTransactionSavepoint; |
| 69302 | | - if( isTransaction && u.at.p1==SAVEPOINT_RELEASE ){ |
| 68909 | + int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; |
| 68910 | + if( isTransaction && p1==SAVEPOINT_RELEASE ){ |
| 69303 | 68911 | if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ |
| 69304 | 68912 | goto vdbe_return; |
| 69305 | 68913 | } |
| 69306 | 68914 | db->autoCommit = 1; |
| 69307 | 68915 | if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ |
| | @@ -69311,56 +68919,56 @@ |
| 69311 | 68919 | goto vdbe_return; |
| 69312 | 68920 | } |
| 69313 | 68921 | db->isTransactionSavepoint = 0; |
| 69314 | 68922 | rc = p->rc; |
| 69315 | 68923 | }else{ |
| 69316 | | - u.at.iSavepoint = db->nSavepoint - u.at.iSavepoint - 1; |
| 69317 | | - if( u.at.p1==SAVEPOINT_ROLLBACK ){ |
| 69318 | | - for(u.at.ii=0; u.at.ii<db->nDb; u.at.ii++){ |
| 69319 | | - sqlite3BtreeTripAllCursors(db->aDb[u.at.ii].pBt, SQLITE_ABORT); |
| 68924 | + iSavepoint = db->nSavepoint - iSavepoint - 1; |
| 68925 | + if( p1==SAVEPOINT_ROLLBACK ){ |
| 68926 | + for(ii=0; ii<db->nDb; ii++){ |
| 68927 | + sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT); |
| 69320 | 68928 | } |
| 69321 | 68929 | } |
| 69322 | | - for(u.at.ii=0; u.at.ii<db->nDb; u.at.ii++){ |
| 69323 | | - rc = sqlite3BtreeSavepoint(db->aDb[u.at.ii].pBt, u.at.p1, u.at.iSavepoint); |
| 68930 | + for(ii=0; ii<db->nDb; ii++){ |
| 68931 | + rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); |
| 69324 | 68932 | if( rc!=SQLITE_OK ){ |
| 69325 | 68933 | goto abort_due_to_error; |
| 69326 | 68934 | } |
| 69327 | 68935 | } |
| 69328 | | - if( u.at.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ |
| 68936 | + if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ |
| 69329 | 68937 | sqlite3ExpirePreparedStatements(db); |
| 69330 | 68938 | sqlite3ResetAllSchemasOfConnection(db); |
| 69331 | 68939 | db->flags = (db->flags | SQLITE_InternChanges); |
| 69332 | 68940 | } |
| 69333 | 68941 | } |
| 69334 | | - |
| 69335 | | - /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all |
| 68942 | + |
| 68943 | + /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all |
| 69336 | 68944 | ** savepoints nested inside of the savepoint being operated on. */ |
| 69337 | | - while( db->pSavepoint!=u.at.pSavepoint ){ |
| 69338 | | - u.at.pTmp = db->pSavepoint; |
| 69339 | | - db->pSavepoint = u.at.pTmp->pNext; |
| 69340 | | - sqlite3DbFree(db, u.at.pTmp); |
| 68945 | + while( db->pSavepoint!=pSavepoint ){ |
| 68946 | + pTmp = db->pSavepoint; |
| 68947 | + db->pSavepoint = pTmp->pNext; |
| 68948 | + sqlite3DbFree(db, pTmp); |
| 69341 | 68949 | db->nSavepoint--; |
| 69342 | 68950 | } |
| 69343 | 68951 | |
| 69344 | | - /* If it is a RELEASE, then destroy the savepoint being operated on |
| 69345 | | - ** too. If it is a ROLLBACK TO, then set the number of deferred |
| 68952 | + /* If it is a RELEASE, then destroy the savepoint being operated on |
| 68953 | + ** too. If it is a ROLLBACK TO, then set the number of deferred |
| 69346 | 68954 | ** constraint violations present in the database to the value stored |
| 69347 | 68955 | ** when the savepoint was created. */ |
| 69348 | | - if( u.at.p1==SAVEPOINT_RELEASE ){ |
| 69349 | | - assert( u.at.pSavepoint==db->pSavepoint ); |
| 69350 | | - db->pSavepoint = u.at.pSavepoint->pNext; |
| 69351 | | - sqlite3DbFree(db, u.at.pSavepoint); |
| 68956 | + if( p1==SAVEPOINT_RELEASE ){ |
| 68957 | + assert( pSavepoint==db->pSavepoint ); |
| 68958 | + db->pSavepoint = pSavepoint->pNext; |
| 68959 | + sqlite3DbFree(db, pSavepoint); |
| 69352 | 68960 | if( !isTransaction ){ |
| 69353 | 68961 | db->nSavepoint--; |
| 69354 | 68962 | } |
| 69355 | 68963 | }else{ |
| 69356 | | - db->nDeferredCons = u.at.pSavepoint->nDeferredCons; |
| 69357 | | - db->nDeferredImmCons = u.at.pSavepoint->nDeferredImmCons; |
| 68964 | + db->nDeferredCons = pSavepoint->nDeferredCons; |
| 68965 | + db->nDeferredImmCons = pSavepoint->nDeferredImmCons; |
| 69358 | 68966 | } |
| 69359 | 68967 | |
| 69360 | 68968 | if( !isTransaction ){ |
| 69361 | | - rc = sqlite3VtabSavepoint(db, u.at.p1, u.at.iSavepoint); |
| 68969 | + rc = sqlite3VtabSavepoint(db, p1, iSavepoint); |
| 69362 | 68970 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 69363 | 68971 | } |
| 69364 | 68972 | } |
| 69365 | 68973 | } |
| 69366 | 68974 | |
| | @@ -69375,54 +68983,52 @@ |
| 69375 | 68983 | ** there are active writing VMs or active VMs that use shared cache. |
| 69376 | 68984 | ** |
| 69377 | 68985 | ** This instruction causes the VM to halt. |
| 69378 | 68986 | */ |
| 69379 | 68987 | case OP_AutoCommit: { |
| 69380 | | -#if 0 /* local variables moved into u.au */ |
| 69381 | 68988 | int desiredAutoCommit; |
| 69382 | 68989 | int iRollback; |
| 69383 | 68990 | int turnOnAC; |
| 69384 | | -#endif /* local variables moved into u.au */ |
| 69385 | 68991 | |
| 69386 | | - u.au.desiredAutoCommit = pOp->p1; |
| 69387 | | - u.au.iRollback = pOp->p2; |
| 69388 | | - u.au.turnOnAC = u.au.desiredAutoCommit && !db->autoCommit; |
| 69389 | | - assert( u.au.desiredAutoCommit==1 || u.au.desiredAutoCommit==0 ); |
| 69390 | | - assert( u.au.desiredAutoCommit==1 || u.au.iRollback==0 ); |
| 68992 | + desiredAutoCommit = pOp->p1; |
| 68993 | + iRollback = pOp->p2; |
| 68994 | + turnOnAC = desiredAutoCommit && !db->autoCommit; |
| 68995 | + assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); |
| 68996 | + assert( desiredAutoCommit==1 || iRollback==0 ); |
| 69391 | 68997 | assert( db->nVdbeActive>0 ); /* At least this one VM is active */ |
| 69392 | 68998 | assert( p->bIsReader ); |
| 69393 | 68999 | |
| 69394 | 69000 | #if 0 |
| 69395 | | - if( u.au.turnOnAC && u.au.iRollback && db->nVdbeActive>1 ){ |
| 69001 | + if( turnOnAC && iRollback && db->nVdbeActive>1 ){ |
| 69396 | 69002 | /* If this instruction implements a ROLLBACK and other VMs are |
| 69397 | 69003 | ** still running, and a transaction is active, return an error indicating |
| 69398 | | - ** that the other VMs must complete first. |
| 69004 | + ** that the other VMs must complete first. |
| 69399 | 69005 | */ |
| 69400 | 69006 | sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " |
| 69401 | 69007 | "SQL statements in progress"); |
| 69402 | 69008 | rc = SQLITE_BUSY; |
| 69403 | 69009 | }else |
| 69404 | 69010 | #endif |
| 69405 | | - if( u.au.turnOnAC && !u.au.iRollback && db->nVdbeWrite>0 ){ |
| 69011 | + if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){ |
| 69406 | 69012 | /* If this instruction implements a COMMIT and other VMs are writing |
| 69407 | | - ** return an error indicating that the other VMs must complete first. |
| 69013 | + ** return an error indicating that the other VMs must complete first. |
| 69408 | 69014 | */ |
| 69409 | 69015 | sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - " |
| 69410 | 69016 | "SQL statements in progress"); |
| 69411 | 69017 | rc = SQLITE_BUSY; |
| 69412 | | - }else if( u.au.desiredAutoCommit!=db->autoCommit ){ |
| 69413 | | - if( u.au.iRollback ){ |
| 69414 | | - assert( u.au.desiredAutoCommit==1 ); |
| 69018 | + }else if( desiredAutoCommit!=db->autoCommit ){ |
| 69019 | + if( iRollback ){ |
| 69020 | + assert( desiredAutoCommit==1 ); |
| 69415 | 69021 | sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); |
| 69416 | 69022 | db->autoCommit = 1; |
| 69417 | 69023 | }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ |
| 69418 | 69024 | goto vdbe_return; |
| 69419 | 69025 | }else{ |
| 69420 | | - db->autoCommit = (u8)u.au.desiredAutoCommit; |
| 69026 | + db->autoCommit = (u8)desiredAutoCommit; |
| 69421 | 69027 | if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ |
| 69422 | 69028 | p->pc = pc; |
| 69423 | | - db->autoCommit = (u8)(1-u.au.desiredAutoCommit); |
| 69029 | + db->autoCommit = (u8)(1-desiredAutoCommit); |
| 69424 | 69030 | p->rc = rc = SQLITE_BUSY; |
| 69425 | 69031 | goto vdbe_return; |
| 69426 | 69032 | } |
| 69427 | 69033 | } |
| 69428 | 69034 | assert( db->nStatement==0 ); |
| | @@ -69433,14 +69039,14 @@ |
| 69433 | 69039 | rc = SQLITE_ERROR; |
| 69434 | 69040 | } |
| 69435 | 69041 | goto vdbe_return; |
| 69436 | 69042 | }else{ |
| 69437 | 69043 | sqlite3SetString(&p->zErrMsg, db, |
| 69438 | | - (!u.au.desiredAutoCommit)?"cannot start a transaction within a transaction":( |
| 69439 | | - (u.au.iRollback)?"cannot rollback - no transaction is active": |
| 69044 | + (!desiredAutoCommit)?"cannot start a transaction within a transaction":( |
| 69045 | + (iRollback)?"cannot rollback - no transaction is active": |
| 69440 | 69046 | "cannot commit - no transaction is active")); |
| 69441 | | - |
| 69047 | + |
| 69442 | 69048 | rc = SQLITE_ERROR; |
| 69443 | 69049 | } |
| 69444 | 69050 | break; |
| 69445 | 69051 | } |
| 69446 | 69052 | |
| | @@ -69474,48 +69080,46 @@ |
| 69474 | 69080 | ** will automatically commit when the VDBE halts. |
| 69475 | 69081 | ** |
| 69476 | 69082 | ** If P2 is zero, then a read-lock is obtained on the database file. |
| 69477 | 69083 | */ |
| 69478 | 69084 | case OP_Transaction: { |
| 69479 | | -#if 0 /* local variables moved into u.av */ |
| 69480 | 69085 | Btree *pBt; |
| 69481 | | -#endif /* local variables moved into u.av */ |
| 69482 | 69086 | |
| 69483 | 69087 | assert( p->bIsReader ); |
| 69484 | 69088 | assert( p->readOnly==0 || pOp->p2==0 ); |
| 69485 | 69089 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69486 | 69090 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 69487 | 69091 | if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ |
| 69488 | 69092 | rc = SQLITE_READONLY; |
| 69489 | 69093 | goto abort_due_to_error; |
| 69490 | 69094 | } |
| 69491 | | - u.av.pBt = db->aDb[pOp->p1].pBt; |
| 69095 | + pBt = db->aDb[pOp->p1].pBt; |
| 69492 | 69096 | |
| 69493 | | - if( u.av.pBt ){ |
| 69494 | | - rc = sqlite3BtreeBeginTrans(u.av.pBt, pOp->p2); |
| 69097 | + if( pBt ){ |
| 69098 | + rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); |
| 69495 | 69099 | if( rc==SQLITE_BUSY ){ |
| 69496 | 69100 | p->pc = pc; |
| 69497 | 69101 | p->rc = rc = SQLITE_BUSY; |
| 69498 | 69102 | goto vdbe_return; |
| 69499 | 69103 | } |
| 69500 | 69104 | if( rc!=SQLITE_OK ){ |
| 69501 | 69105 | goto abort_due_to_error; |
| 69502 | 69106 | } |
| 69503 | 69107 | |
| 69504 | | - if( pOp->p2 && p->usesStmtJournal |
| 69505 | | - && (db->autoCommit==0 || db->nVdbeRead>1) |
| 69108 | + if( pOp->p2 && p->usesStmtJournal |
| 69109 | + && (db->autoCommit==0 || db->nVdbeRead>1) |
| 69506 | 69110 | ){ |
| 69507 | | - assert( sqlite3BtreeIsInTrans(u.av.pBt) ); |
| 69111 | + assert( sqlite3BtreeIsInTrans(pBt) ); |
| 69508 | 69112 | if( p->iStatement==0 ){ |
| 69509 | 69113 | assert( db->nStatement>=0 && db->nSavepoint>=0 ); |
| 69510 | | - db->nStatement++; |
| 69114 | + db->nStatement++; |
| 69511 | 69115 | p->iStatement = db->nSavepoint + db->nStatement; |
| 69512 | 69116 | } |
| 69513 | 69117 | |
| 69514 | 69118 | rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); |
| 69515 | 69119 | if( rc==SQLITE_OK ){ |
| 69516 | | - rc = sqlite3BtreeBeginStmt(u.av.pBt, p->iStatement); |
| 69120 | + rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); |
| 69517 | 69121 | } |
| 69518 | 69122 | |
| 69519 | 69123 | /* Store the current value of the database handles deferred constraint |
| 69520 | 69124 | ** counter. If the statement transaction needs to be rolled back, |
| 69521 | 69125 | ** the value of this counter needs to be restored too. */ |
| | @@ -69537,26 +69141,24 @@ |
| 69537 | 69141 | ** There must be a read-lock on the database (either a transaction |
| 69538 | 69142 | ** must be started or there must be an open cursor) before |
| 69539 | 69143 | ** executing this instruction. |
| 69540 | 69144 | */ |
| 69541 | 69145 | case OP_ReadCookie: { /* out2-prerelease */ |
| 69542 | | -#if 0 /* local variables moved into u.aw */ |
| 69543 | 69146 | int iMeta; |
| 69544 | 69147 | int iDb; |
| 69545 | 69148 | int iCookie; |
| 69546 | | -#endif /* local variables moved into u.aw */ |
| 69547 | 69149 | |
| 69548 | 69150 | assert( p->bIsReader ); |
| 69549 | | - u.aw.iDb = pOp->p1; |
| 69550 | | - u.aw.iCookie = pOp->p3; |
| 69151 | + iDb = pOp->p1; |
| 69152 | + iCookie = pOp->p3; |
| 69551 | 69153 | assert( pOp->p3<SQLITE_N_BTREE_META ); |
| 69552 | | - assert( u.aw.iDb>=0 && u.aw.iDb<db->nDb ); |
| 69553 | | - assert( db->aDb[u.aw.iDb].pBt!=0 ); |
| 69554 | | - assert( (p->btreeMask & (((yDbMask)1)<<u.aw.iDb))!=0 ); |
| 69154 | + assert( iDb>=0 && iDb<db->nDb ); |
| 69155 | + assert( db->aDb[iDb].pBt!=0 ); |
| 69156 | + assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 69555 | 69157 | |
| 69556 | | - sqlite3BtreeGetMeta(db->aDb[u.aw.iDb].pBt, u.aw.iCookie, (u32 *)&u.aw.iMeta); |
| 69557 | | - pOut->u.i = u.aw.iMeta; |
| 69158 | + sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); |
| 69159 | + pOut->u.i = iMeta; |
| 69558 | 69160 | break; |
| 69559 | 69161 | } |
| 69560 | 69162 | |
| 69561 | 69163 | /* Opcode: SetCookie P1 P2 P3 * * |
| 69562 | 69164 | ** |
| | @@ -69567,31 +69169,29 @@ |
| 69567 | 69169 | ** database file used to store temporary tables. |
| 69568 | 69170 | ** |
| 69569 | 69171 | ** A transaction must be started before executing this opcode. |
| 69570 | 69172 | */ |
| 69571 | 69173 | case OP_SetCookie: { /* in3 */ |
| 69572 | | -#if 0 /* local variables moved into u.ax */ |
| 69573 | 69174 | Db *pDb; |
| 69574 | | -#endif /* local variables moved into u.ax */ |
| 69575 | 69175 | assert( pOp->p2<SQLITE_N_BTREE_META ); |
| 69576 | 69176 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69577 | 69177 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 69578 | 69178 | assert( p->readOnly==0 ); |
| 69579 | | - u.ax.pDb = &db->aDb[pOp->p1]; |
| 69580 | | - assert( u.ax.pDb->pBt!=0 ); |
| 69179 | + pDb = &db->aDb[pOp->p1]; |
| 69180 | + assert( pDb->pBt!=0 ); |
| 69581 | 69181 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 69582 | 69182 | pIn3 = &aMem[pOp->p3]; |
| 69583 | 69183 | sqlite3VdbeMemIntegerify(pIn3); |
| 69584 | 69184 | /* See note about index shifting on OP_ReadCookie */ |
| 69585 | | - rc = sqlite3BtreeUpdateMeta(u.ax.pDb->pBt, pOp->p2, (int)pIn3->u.i); |
| 69185 | + rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i); |
| 69586 | 69186 | if( pOp->p2==BTREE_SCHEMA_VERSION ){ |
| 69587 | 69187 | /* When the schema cookie changes, record the new cookie internally */ |
| 69588 | | - u.ax.pDb->pSchema->schema_cookie = (int)pIn3->u.i; |
| 69188 | + pDb->pSchema->schema_cookie = (int)pIn3->u.i; |
| 69589 | 69189 | db->flags |= SQLITE_InternChanges; |
| 69590 | 69190 | }else if( pOp->p2==BTREE_FILE_FORMAT ){ |
| 69591 | 69191 | /* Record changes in the file format */ |
| 69592 | | - u.ax.pDb->pSchema->file_format = (u8)pIn3->u.i; |
| 69192 | + pDb->pSchema->file_format = (u8)pIn3->u.i; |
| 69593 | 69193 | } |
| 69594 | 69194 | if( pOp->p1==1 ){ |
| 69595 | 69195 | /* Invalidate all prepared statements whenever the TEMP database |
| 69596 | 69196 | ** schema is changed. Ticket #1644 */ |
| 69597 | 69197 | sqlite3ExpirePreparedStatements(db); |
| | @@ -69617,44 +69217,42 @@ |
| 69617 | 69217 | ** Either a transaction needs to have been started or an OP_Open needs |
| 69618 | 69218 | ** to be executed (to establish a read lock) before this opcode is |
| 69619 | 69219 | ** invoked. |
| 69620 | 69220 | */ |
| 69621 | 69221 | case OP_VerifyCookie: { |
| 69622 | | -#if 0 /* local variables moved into u.ay */ |
| 69623 | 69222 | int iMeta; |
| 69624 | 69223 | int iGen; |
| 69625 | 69224 | Btree *pBt; |
| 69626 | | -#endif /* local variables moved into u.ay */ |
| 69627 | 69225 | |
| 69628 | 69226 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 69629 | 69227 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 69630 | 69228 | assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); |
| 69631 | 69229 | assert( p->bIsReader ); |
| 69632 | | - u.ay.pBt = db->aDb[pOp->p1].pBt; |
| 69633 | | - if( u.ay.pBt ){ |
| 69634 | | - sqlite3BtreeGetMeta(u.ay.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ay.iMeta); |
| 69635 | | - u.ay.iGen = db->aDb[pOp->p1].pSchema->iGeneration; |
| 69230 | + pBt = db->aDb[pOp->p1].pBt; |
| 69231 | + if( pBt ){ |
| 69232 | + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); |
| 69233 | + iGen = db->aDb[pOp->p1].pSchema->iGeneration; |
| 69636 | 69234 | }else{ |
| 69637 | | - u.ay.iGen = u.ay.iMeta = 0; |
| 69235 | + iGen = iMeta = 0; |
| 69638 | 69236 | } |
| 69639 | | - if( u.ay.iMeta!=pOp->p2 || u.ay.iGen!=pOp->p3 ){ |
| 69237 | + if( iMeta!=pOp->p2 || iGen!=pOp->p3 ){ |
| 69640 | 69238 | sqlite3DbFree(db, p->zErrMsg); |
| 69641 | 69239 | p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); |
| 69642 | | - /* If the schema-cookie from the database file matches the cookie |
| 69240 | + /* If the schema-cookie from the database file matches the cookie |
| 69643 | 69241 | ** stored with the in-memory representation of the schema, do |
| 69644 | 69242 | ** not reload the schema from the database file. |
| 69645 | 69243 | ** |
| 69646 | 69244 | ** If virtual-tables are in use, this is not just an optimization. |
| 69647 | 69245 | ** Often, v-tables store their data in other SQLite tables, which |
| 69648 | 69246 | ** are queried from within xNext() and other v-table methods using |
| 69649 | 69247 | ** prepared queries. If such a query is out-of-date, we do not want to |
| 69650 | 69248 | ** discard the database schema, as the user code implementing the |
| 69651 | 69249 | ** v-table would have to be ready for the sqlite3_vtab structure itself |
| 69652 | | - ** to be invalidated whenever sqlite3_step() is called from within |
| 69250 | + ** to be invalidated whenever sqlite3_step() is called from within |
| 69653 | 69251 | ** a v-table method. |
| 69654 | 69252 | */ |
| 69655 | | - if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ay.iMeta ){ |
| 69253 | + if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ |
| 69656 | 69254 | sqlite3ResetOneSchema(db, pOp->p1); |
| 69657 | 69255 | } |
| 69658 | 69256 | |
| 69659 | 69257 | p->expired = 1; |
| 69660 | 69258 | rc = SQLITE_SCHEMA; |
| | @@ -69713,20 +69311,18 @@ |
| 69713 | 69311 | ** |
| 69714 | 69312 | ** See also OpenRead. |
| 69715 | 69313 | */ |
| 69716 | 69314 | case OP_OpenRead: |
| 69717 | 69315 | case OP_OpenWrite: { |
| 69718 | | -#if 0 /* local variables moved into u.az */ |
| 69719 | 69316 | int nField; |
| 69720 | 69317 | KeyInfo *pKeyInfo; |
| 69721 | 69318 | int p2; |
| 69722 | 69319 | int iDb; |
| 69723 | 69320 | int wrFlag; |
| 69724 | 69321 | Btree *pX; |
| 69725 | 69322 | VdbeCursor *pCur; |
| 69726 | 69323 | Db *pDb; |
| 69727 | | -#endif /* local variables moved into u.az */ |
| 69728 | 69324 | |
| 69729 | 69325 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 69730 | 69326 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 69731 | 69327 | assert( p->bIsReader ); |
| 69732 | 69328 | assert( pOp->opcode==OP_OpenRead || p->readOnly==0 ); |
| | @@ -69734,73 +69330,74 @@ |
| 69734 | 69330 | if( p->expired ){ |
| 69735 | 69331 | rc = SQLITE_ABORT; |
| 69736 | 69332 | break; |
| 69737 | 69333 | } |
| 69738 | 69334 | |
| 69739 | | - u.az.nField = 0; |
| 69740 | | - u.az.pKeyInfo = 0; |
| 69741 | | - u.az.p2 = pOp->p2; |
| 69742 | | - u.az.iDb = pOp->p3; |
| 69743 | | - assert( u.az.iDb>=0 && u.az.iDb<db->nDb ); |
| 69744 | | - assert( (p->btreeMask & (((yDbMask)1)<<u.az.iDb))!=0 ); |
| 69745 | | - u.az.pDb = &db->aDb[u.az.iDb]; |
| 69746 | | - u.az.pX = u.az.pDb->pBt; |
| 69747 | | - assert( u.az.pX!=0 ); |
| 69335 | + nField = 0; |
| 69336 | + pKeyInfo = 0; |
| 69337 | + p2 = pOp->p2; |
| 69338 | + iDb = pOp->p3; |
| 69339 | + assert( iDb>=0 && iDb<db->nDb ); |
| 69340 | + assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 69341 | + pDb = &db->aDb[iDb]; |
| 69342 | + pX = pDb->pBt; |
| 69343 | + assert( pX!=0 ); |
| 69748 | 69344 | if( pOp->opcode==OP_OpenWrite ){ |
| 69749 | | - u.az.wrFlag = 1; |
| 69750 | | - assert( sqlite3SchemaMutexHeld(db, u.az.iDb, 0) ); |
| 69751 | | - if( u.az.pDb->pSchema->file_format < p->minWriteFileFormat ){ |
| 69752 | | - p->minWriteFileFormat = u.az.pDb->pSchema->file_format; |
| 69345 | + wrFlag = 1; |
| 69346 | + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 69347 | + if( pDb->pSchema->file_format < p->minWriteFileFormat ){ |
| 69348 | + p->minWriteFileFormat = pDb->pSchema->file_format; |
| 69753 | 69349 | } |
| 69754 | 69350 | }else{ |
| 69755 | | - u.az.wrFlag = 0; |
| 69351 | + wrFlag = 0; |
| 69756 | 69352 | } |
| 69757 | 69353 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 69758 | | - assert( u.az.p2>0 ); |
| 69759 | | - assert( u.az.p2<=(p->nMem-p->nCursor) ); |
| 69760 | | - pIn2 = &aMem[u.az.p2]; |
| 69354 | + assert( p2>0 ); |
| 69355 | + assert( p2<=(p->nMem-p->nCursor) ); |
| 69356 | + pIn2 = &aMem[p2]; |
| 69761 | 69357 | assert( memIsValid(pIn2) ); |
| 69762 | 69358 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 69763 | 69359 | sqlite3VdbeMemIntegerify(pIn2); |
| 69764 | | - u.az.p2 = (int)pIn2->u.i; |
| 69765 | | - /* The u.az.p2 value always comes from a prior OP_CreateTable opcode and |
| 69766 | | - ** that opcode will always set the u.az.p2 value to 2 or more or else fail. |
| 69360 | + p2 = (int)pIn2->u.i; |
| 69361 | + /* The p2 value always comes from a prior OP_CreateTable opcode and |
| 69362 | + ** that opcode will always set the p2 value to 2 or more or else fail. |
| 69767 | 69363 | ** If there were a failure, the prepared statement would have halted |
| 69768 | 69364 | ** before reaching this instruction. */ |
| 69769 | | - if( NEVER(u.az.p2<2) ) { |
| 69365 | + if( NEVER(p2<2) ) { |
| 69770 | 69366 | rc = SQLITE_CORRUPT_BKPT; |
| 69771 | 69367 | goto abort_due_to_error; |
| 69772 | 69368 | } |
| 69773 | 69369 | } |
| 69774 | 69370 | if( pOp->p4type==P4_KEYINFO ){ |
| 69775 | | - u.az.pKeyInfo = pOp->p4.pKeyInfo; |
| 69776 | | - assert( u.az.pKeyInfo->enc==ENC(db) ); |
| 69777 | | - assert( u.az.pKeyInfo->db==db ); |
| 69778 | | - u.az.nField = u.az.pKeyInfo->nField+u.az.pKeyInfo->nXField; |
| 69371 | + pKeyInfo = pOp->p4.pKeyInfo; |
| 69372 | + assert( pKeyInfo->enc==ENC(db) ); |
| 69373 | + assert( pKeyInfo->db==db ); |
| 69374 | + nField = pKeyInfo->nField+pKeyInfo->nXField; |
| 69779 | 69375 | }else if( pOp->p4type==P4_INT32 ){ |
| 69780 | | - u.az.nField = pOp->p4.i; |
| 69376 | + nField = pOp->p4.i; |
| 69781 | 69377 | } |
| 69782 | 69378 | assert( pOp->p1>=0 ); |
| 69783 | | - u.az.pCur = allocateCursor(p, pOp->p1, u.az.nField, u.az.iDb, 1); |
| 69784 | | - if( u.az.pCur==0 ) goto no_mem; |
| 69785 | | - u.az.pCur->nullRow = 1; |
| 69786 | | - u.az.pCur->isOrdered = 1; |
| 69787 | | - rc = sqlite3BtreeCursor(u.az.pX, u.az.p2, u.az.wrFlag, u.az.pKeyInfo, u.az.pCur->pCursor); |
| 69788 | | - u.az.pCur->pKeyInfo = u.az.pKeyInfo; |
| 69379 | + assert( nField>=0 ); |
| 69380 | + testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ |
| 69381 | + pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); |
| 69382 | + if( pCur==0 ) goto no_mem; |
| 69383 | + pCur->nullRow = 1; |
| 69384 | + pCur->isOrdered = 1; |
| 69385 | + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); |
| 69386 | + pCur->pKeyInfo = pKeyInfo; |
| 69789 | 69387 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 69790 | | - sqlite3BtreeCursorHints(u.az.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 69388 | + sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 69791 | 69389 | |
| 69792 | 69390 | /* Since it performs no memory allocation or IO, the only value that |
| 69793 | 69391 | ** sqlite3BtreeCursor() may return is SQLITE_OK. */ |
| 69794 | 69392 | assert( rc==SQLITE_OK ); |
| 69795 | 69393 | |
| 69796 | | - /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of |
| 69394 | + /* Set the VdbeCursor.isTable variable. Previous versions of |
| 69797 | 69395 | ** SQLite used to check if the root-page flags were sane at this point |
| 69798 | 69396 | ** and report database corruption if they were not, but this check has |
| 69799 | | - ** since moved into the btree layer. */ |
| 69800 | | - u.az.pCur->isTable = pOp->p4type!=P4_KEYINFO; |
| 69801 | | - u.az.pCur->isIndex = !u.az.pCur->isTable; |
| 69397 | + ** since moved into the btree layer. */ |
| 69398 | + pCur->isTable = pOp->p4type!=P4_KEYINFO; |
| 69802 | 69399 | break; |
| 69803 | 69400 | } |
| 69804 | 69401 | |
| 69805 | 69402 | /* Opcode: OpenEphemeral P1 P2 * P4 P5 |
| 69806 | 69403 | ** Synopsis: nColumn=P2 |
| | @@ -69828,55 +69425,53 @@ |
| 69828 | 69425 | ** by this opcode will be used for automatically created transient |
| 69829 | 69426 | ** indices in joins. |
| 69830 | 69427 | */ |
| 69831 | 69428 | case OP_OpenAutoindex: |
| 69832 | 69429 | case OP_OpenEphemeral: { |
| 69833 | | -#if 0 /* local variables moved into u.ba */ |
| 69834 | 69430 | VdbeCursor *pCx; |
| 69835 | 69431 | KeyInfo *pKeyInfo; |
| 69836 | | -#endif /* local variables moved into u.ba */ |
| 69837 | 69432 | |
| 69838 | | - static const int vfsFlags = |
| 69433 | + static const int vfsFlags = |
| 69839 | 69434 | SQLITE_OPEN_READWRITE | |
| 69840 | 69435 | SQLITE_OPEN_CREATE | |
| 69841 | 69436 | SQLITE_OPEN_EXCLUSIVE | |
| 69842 | 69437 | SQLITE_OPEN_DELETEONCLOSE | |
| 69843 | 69438 | SQLITE_OPEN_TRANSIENT_DB; |
| 69844 | 69439 | assert( pOp->p1>=0 ); |
| 69845 | | - u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 69846 | | - if( u.ba.pCx==0 ) goto no_mem; |
| 69847 | | - u.ba.pCx->nullRow = 1; |
| 69848 | | - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ba.pCx->pBt, |
| 69440 | + assert( pOp->p2>=0 ); |
| 69441 | + pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 69442 | + if( pCx==0 ) goto no_mem; |
| 69443 | + pCx->nullRow = 1; |
| 69444 | + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, |
| 69849 | 69445 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); |
| 69850 | 69446 | if( rc==SQLITE_OK ){ |
| 69851 | | - rc = sqlite3BtreeBeginTrans(u.ba.pCx->pBt, 1); |
| 69447 | + rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); |
| 69852 | 69448 | } |
| 69853 | 69449 | if( rc==SQLITE_OK ){ |
| 69854 | 69450 | /* If a transient index is required, create it by calling |
| 69855 | 69451 | ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before |
| 69856 | 69452 | ** opening it. If a transient table is required, just use the |
| 69857 | 69453 | ** automatically created table with root-page 1 (an BLOB_INTKEY table). |
| 69858 | 69454 | */ |
| 69859 | | - if( (u.ba.pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ |
| 69455 | + if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ |
| 69860 | 69456 | int pgno; |
| 69861 | 69457 | assert( pOp->p4type==P4_KEYINFO ); |
| 69862 | | - rc = sqlite3BtreeCreateTable(u.ba.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); |
| 69458 | + rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); |
| 69863 | 69459 | if( rc==SQLITE_OK ){ |
| 69864 | 69460 | assert( pgno==MASTER_ROOT+1 ); |
| 69865 | | - assert( u.ba.pKeyInfo->db==db ); |
| 69866 | | - assert( u.ba.pKeyInfo->enc==ENC(db) ); |
| 69867 | | - u.ba.pCx->pKeyInfo = u.ba.pKeyInfo; |
| 69868 | | - rc = sqlite3BtreeCursor(u.ba.pCx->pBt, pgno, 1, u.ba.pKeyInfo, u.ba.pCx->pCursor); |
| 69869 | | - } |
| 69870 | | - u.ba.pCx->isTable = 0; |
| 69871 | | - }else{ |
| 69872 | | - rc = sqlite3BtreeCursor(u.ba.pCx->pBt, MASTER_ROOT, 1, 0, u.ba.pCx->pCursor); |
| 69873 | | - u.ba.pCx->isTable = 1; |
| 69461 | + assert( pKeyInfo->db==db ); |
| 69462 | + assert( pKeyInfo->enc==ENC(db) ); |
| 69463 | + pCx->pKeyInfo = pKeyInfo; |
| 69464 | + rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor); |
| 69465 | + } |
| 69466 | + pCx->isTable = 0; |
| 69467 | + }else{ |
| 69468 | + rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor); |
| 69469 | + pCx->isTable = 1; |
| 69874 | 69470 | } |
| 69875 | 69471 | } |
| 69876 | | - u.ba.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 69877 | | - u.ba.pCx->isIndex = !u.ba.pCx->isTable; |
| 69472 | + pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 69878 | 69473 | break; |
| 69879 | 69474 | } |
| 69880 | 69475 | |
| 69881 | 69476 | /* Opcode: SorterOpen P1 * * P4 * |
| 69882 | 69477 | ** |
| | @@ -69883,21 +69478,20 @@ |
| 69883 | 69478 | ** This opcode works like OP_OpenEphemeral except that it opens |
| 69884 | 69479 | ** a transient index that is specifically designed to sort large |
| 69885 | 69480 | ** tables using an external merge-sort algorithm. |
| 69886 | 69481 | */ |
| 69887 | 69482 | case OP_SorterOpen: { |
| 69888 | | -#if 0 /* local variables moved into u.bb */ |
| 69889 | 69483 | VdbeCursor *pCx; |
| 69890 | | -#endif /* local variables moved into u.bb */ |
| 69891 | | - |
| 69892 | | - u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 69893 | | - if( u.bb.pCx==0 ) goto no_mem; |
| 69894 | | - u.bb.pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 69895 | | - assert( u.bb.pCx->pKeyInfo->db==db ); |
| 69896 | | - assert( u.bb.pCx->pKeyInfo->enc==ENC(db) ); |
| 69897 | | - u.bb.pCx->isSorter = 1; |
| 69898 | | - rc = sqlite3VdbeSorterInit(db, u.bb.pCx); |
| 69484 | + |
| 69485 | + assert( pOp->p1>=0 ); |
| 69486 | + assert( pOp->p2>=0 ); |
| 69487 | + pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); |
| 69488 | + if( pCx==0 ) goto no_mem; |
| 69489 | + pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 69490 | + assert( pCx->pKeyInfo->db==db ); |
| 69491 | + assert( pCx->pKeyInfo->enc==ENC(db) ); |
| 69492 | + rc = sqlite3VdbeSorterInit(db, pCx); |
| 69899 | 69493 | break; |
| 69900 | 69494 | } |
| 69901 | 69495 | |
| 69902 | 69496 | /* Opcode: OpenPseudo P1 P2 P3 * P5 |
| 69903 | 69497 | ** Synopsis: content in r[P2@P3] |
| | @@ -69915,22 +69509,20 @@ |
| 69915 | 69509 | ** |
| 69916 | 69510 | ** P3 is the number of fields in the records that will be stored by |
| 69917 | 69511 | ** the pseudo-table. |
| 69918 | 69512 | */ |
| 69919 | 69513 | case OP_OpenPseudo: { |
| 69920 | | -#if 0 /* local variables moved into u.bc */ |
| 69921 | 69514 | VdbeCursor *pCx; |
| 69922 | | -#endif /* local variables moved into u.bc */ |
| 69923 | 69515 | |
| 69924 | 69516 | assert( pOp->p1>=0 ); |
| 69925 | | - u.bc.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); |
| 69926 | | - if( u.bc.pCx==0 ) goto no_mem; |
| 69927 | | - u.bc.pCx->nullRow = 1; |
| 69928 | | - u.bc.pCx->pseudoTableReg = pOp->p2; |
| 69929 | | - u.bc.pCx->isTable = 1; |
| 69930 | | - u.bc.pCx->isIndex = 0; |
| 69931 | | - u.bc.pCx->multiPseudo = pOp->p5; |
| 69517 | + assert( pOp->p3>=0 ); |
| 69518 | + pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); |
| 69519 | + if( pCx==0 ) goto no_mem; |
| 69520 | + pCx->nullRow = 1; |
| 69521 | + pCx->pseudoTableReg = pOp->p2; |
| 69522 | + pCx->isTable = 1; |
| 69523 | + pCx->multiPseudo = pOp->p5; |
| 69932 | 69524 | break; |
| 69933 | 69525 | } |
| 69934 | 69526 | |
| 69935 | 69527 | /* Opcode: Close P1 * * * * |
| 69936 | 69528 | ** |
| | @@ -70002,39 +69594,37 @@ |
| 70002 | 69594 | */ |
| 70003 | 69595 | case OP_SeekLt: /* jump, in3 */ |
| 70004 | 69596 | case OP_SeekLe: /* jump, in3 */ |
| 70005 | 69597 | case OP_SeekGe: /* jump, in3 */ |
| 70006 | 69598 | case OP_SeekGt: { /* jump, in3 */ |
| 70007 | | -#if 0 /* local variables moved into u.bd */ |
| 70008 | 69599 | int res; |
| 70009 | 69600 | int oc; |
| 70010 | 69601 | VdbeCursor *pC; |
| 70011 | 69602 | UnpackedRecord r; |
| 70012 | 69603 | int nField; |
| 70013 | 69604 | i64 iKey; /* The rowid we are to seek to */ |
| 70014 | | -#endif /* local variables moved into u.bd */ |
| 70015 | 69605 | |
| 70016 | 69606 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70017 | 69607 | assert( pOp->p2!=0 ); |
| 70018 | | - u.bd.pC = p->apCsr[pOp->p1]; |
| 70019 | | - assert( u.bd.pC!=0 ); |
| 70020 | | - assert( u.bd.pC->pseudoTableReg==0 ); |
| 69608 | + pC = p->apCsr[pOp->p1]; |
| 69609 | + assert( pC!=0 ); |
| 69610 | + assert( pC->pseudoTableReg==0 ); |
| 70021 | 69611 | assert( OP_SeekLe == OP_SeekLt+1 ); |
| 70022 | 69612 | assert( OP_SeekGe == OP_SeekLt+2 ); |
| 70023 | 69613 | assert( OP_SeekGt == OP_SeekLt+3 ); |
| 70024 | | - assert( u.bd.pC->isOrdered ); |
| 70025 | | - assert( u.bd.pC->pCursor!=0 ); |
| 70026 | | - u.bd.oc = pOp->opcode; |
| 70027 | | - u.bd.pC->nullRow = 0; |
| 70028 | | - if( u.bd.pC->isTable ){ |
| 69614 | + assert( pC->isOrdered ); |
| 69615 | + assert( pC->pCursor!=0 ); |
| 69616 | + oc = pOp->opcode; |
| 69617 | + pC->nullRow = 0; |
| 69618 | + if( pC->isTable ){ |
| 70029 | 69619 | /* The input value in P3 might be of any type: integer, real, string, |
| 70030 | 69620 | ** blob, or NULL. But it needs to be an integer before we can do |
| 70031 | 69621 | ** the seek, so covert it. */ |
| 70032 | 69622 | pIn3 = &aMem[pOp->p3]; |
| 70033 | 69623 | applyNumericAffinity(pIn3); |
| 70034 | | - u.bd.iKey = sqlite3VdbeIntValue(pIn3); |
| 70035 | | - u.bd.pC->rowidIsValid = 0; |
| 69624 | + iKey = sqlite3VdbeIntValue(pIn3); |
| 69625 | + pC->rowidIsValid = 0; |
| 70036 | 69626 | |
| 70037 | 69627 | /* If the P3 value could not be converted into an integer without |
| 70038 | 69628 | ** loss of information, then special processing is required... */ |
| 70039 | 69629 | if( (pIn3->flags & MEM_Int)==0 ){ |
| 70040 | 69630 | if( (pIn3->flags & MEM_Real)==0 ){ |
| | @@ -70041,109 +69631,101 @@ |
| 70041 | 69631 | /* If the P3 value cannot be converted into any kind of a number, |
| 70042 | 69632 | ** then the seek is not possible, so jump to P2 */ |
| 70043 | 69633 | pc = pOp->p2 - 1; |
| 70044 | 69634 | break; |
| 70045 | 69635 | } |
| 70046 | | - /* If we reach this point, then the P3 value must be a floating |
| 70047 | | - ** point number. */ |
| 70048 | | - assert( (pIn3->flags & MEM_Real)!=0 ); |
| 70049 | | - |
| 70050 | | - if( u.bd.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bd.iKey || pIn3->r>0) ){ |
| 70051 | | - /* The P3 value is too large in magnitude to be expressed as an |
| 70052 | | - ** integer. */ |
| 70053 | | - u.bd.res = 1; |
| 70054 | | - if( pIn3->r<0 ){ |
| 70055 | | - if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt ); |
| 70056 | | - rc = sqlite3BtreeFirst(u.bd.pC->pCursor, &u.bd.res); |
| 70057 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 70058 | | - } |
| 70059 | | - }else{ |
| 70060 | | - if( u.bd.oc<=OP_SeekLe ){ assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe ); |
| 70061 | | - rc = sqlite3BtreeLast(u.bd.pC->pCursor, &u.bd.res); |
| 70062 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 70063 | | - } |
| 70064 | | - } |
| 70065 | | - if( u.bd.res ){ |
| 70066 | | - pc = pOp->p2 - 1; |
| 70067 | | - } |
| 70068 | | - break; |
| 70069 | | - }else if( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekGe ){ |
| 70070 | | - /* Use the ceiling() function to convert real->int */ |
| 70071 | | - if( pIn3->r > (double)u.bd.iKey ) u.bd.iKey++; |
| 70072 | | - }else{ |
| 70073 | | - /* Use the floor() function to convert real->int */ |
| 70074 | | - assert( u.bd.oc==OP_SeekLe || u.bd.oc==OP_SeekGt ); |
| 70075 | | - if( pIn3->r < (double)u.bd.iKey ) u.bd.iKey--; |
| 70076 | | - } |
| 70077 | | - } |
| 70078 | | - rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res); |
| 70079 | | - if( rc!=SQLITE_OK ){ |
| 70080 | | - goto abort_due_to_error; |
| 70081 | | - } |
| 70082 | | - if( u.bd.res==0 ){ |
| 70083 | | - u.bd.pC->rowidIsValid = 1; |
| 70084 | | - u.bd.pC->lastRowid = u.bd.iKey; |
| 70085 | | - } |
| 70086 | | - }else{ |
| 70087 | | - u.bd.nField = pOp->p4.i; |
| 70088 | | - assert( pOp->p4type==P4_INT32 ); |
| 70089 | | - assert( u.bd.nField>0 ); |
| 70090 | | - u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo; |
| 70091 | | - u.bd.r.nField = (u16)u.bd.nField; |
| 70092 | | - |
| 70093 | | - /* The next line of code computes as follows, only faster: |
| 70094 | | - ** if( u.bd.oc==OP_SeekGt || u.bd.oc==OP_SeekLe ){ |
| 70095 | | - ** u.bd.r.flags = UNPACKED_INCRKEY; |
| 70096 | | - ** }else{ |
| 70097 | | - ** u.bd.r.flags = 0; |
| 70098 | | - ** } |
| 70099 | | - */ |
| 70100 | | - u.bd.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bd.oc - OP_SeekLt))); |
| 70101 | | - assert( u.bd.oc!=OP_SeekGt || u.bd.r.flags==UNPACKED_INCRKEY ); |
| 70102 | | - assert( u.bd.oc!=OP_SeekLe || u.bd.r.flags==UNPACKED_INCRKEY ); |
| 70103 | | - assert( u.bd.oc!=OP_SeekGe || u.bd.r.flags==0 ); |
| 70104 | | - assert( u.bd.oc!=OP_SeekLt || u.bd.r.flags==0 ); |
| 70105 | | - |
| 70106 | | - u.bd.r.aMem = &aMem[pOp->p3]; |
| 70107 | | -#ifdef SQLITE_DEBUG |
| 70108 | | - { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); } |
| 70109 | | -#endif |
| 70110 | | - ExpandBlob(u.bd.r.aMem); |
| 70111 | | - rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, &u.bd.r, 0, 0, &u.bd.res); |
| 70112 | | - if( rc!=SQLITE_OK ){ |
| 70113 | | - goto abort_due_to_error; |
| 70114 | | - } |
| 70115 | | - u.bd.pC->rowidIsValid = 0; |
| 70116 | | - } |
| 70117 | | - u.bd.pC->deferredMoveto = 0; |
| 70118 | | - u.bd.pC->cacheStatus = CACHE_STALE; |
| 70119 | | -#ifdef SQLITE_TEST |
| 70120 | | - sqlite3_search_count++; |
| 70121 | | -#endif |
| 70122 | | - if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt ); |
| 70123 | | - if( u.bd.res<0 || (u.bd.res==0 && u.bd.oc==OP_SeekGt) ){ |
| 70124 | | - rc = sqlite3BtreeNext(u.bd.pC->pCursor, &u.bd.res); |
| 70125 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 70126 | | - u.bd.pC->rowidIsValid = 0; |
| 70127 | | - }else{ |
| 70128 | | - u.bd.res = 0; |
| 70129 | | - } |
| 70130 | | - }else{ |
| 70131 | | - assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe ); |
| 70132 | | - if( u.bd.res>0 || (u.bd.res==0 && u.bd.oc==OP_SeekLt) ){ |
| 70133 | | - rc = sqlite3BtreePrevious(u.bd.pC->pCursor, &u.bd.res); |
| 70134 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 70135 | | - u.bd.pC->rowidIsValid = 0; |
| 70136 | | - }else{ |
| 70137 | | - /* u.bd.res might be negative because the table is empty. Check to |
| 70138 | | - ** see if this is the case. |
| 70139 | | - */ |
| 70140 | | - u.bd.res = sqlite3BtreeEof(u.bd.pC->pCursor); |
| 70141 | | - } |
| 70142 | | - } |
| 70143 | | - assert( pOp->p2>0 ); |
| 70144 | | - if( u.bd.res ){ |
| 69636 | + |
| 69637 | + /* If the approximation iKey is larger than the actual real search |
| 69638 | + ** term, substitute >= for > and < for <=. e.g. if the search term |
| 69639 | + ** is 4.9 and the integer approximation 5: |
| 69640 | + ** |
| 69641 | + ** (x > 4.9) -> (x >= 5) |
| 69642 | + ** (x <= 4.9) -> (x < 5) |
| 69643 | + */ |
| 69644 | + if( pIn3->r<(double)iKey ){ |
| 69645 | + assert( OP_SeekGe==(OP_SeekGt-1) ); |
| 69646 | + assert( OP_SeekLt==(OP_SeekLe-1) ); |
| 69647 | + assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) ); |
| 69648 | + if( (oc & 0x0001)==(OP_SeekGt & 0x0001) ) oc--; |
| 69649 | + } |
| 69650 | + |
| 69651 | + /* If the approximation iKey is smaller than the actual real search |
| 69652 | + ** term, substitute <= for < and > for >=. */ |
| 69653 | + else if( pIn3->r>(double)iKey ){ |
| 69654 | + assert( OP_SeekLe==(OP_SeekLt+1) ); |
| 69655 | + assert( OP_SeekGt==(OP_SeekGe+1) ); |
| 69656 | + assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) ); |
| 69657 | + if( (oc & 0x0001)==(OP_SeekLt & 0x0001) ) oc++; |
| 69658 | + } |
| 69659 | + } |
| 69660 | + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); |
| 69661 | + if( rc!=SQLITE_OK ){ |
| 69662 | + goto abort_due_to_error; |
| 69663 | + } |
| 69664 | + if( res==0 ){ |
| 69665 | + pC->rowidIsValid = 1; |
| 69666 | + pC->lastRowid = iKey; |
| 69667 | + } |
| 69668 | + }else{ |
| 69669 | + nField = pOp->p4.i; |
| 69670 | + assert( pOp->p4type==P4_INT32 ); |
| 69671 | + assert( nField>0 ); |
| 69672 | + r.pKeyInfo = pC->pKeyInfo; |
| 69673 | + r.nField = (u16)nField; |
| 69674 | + |
| 69675 | + /* The next line of code computes as follows, only faster: |
| 69676 | + ** if( oc==OP_SeekGt || oc==OP_SeekLe ){ |
| 69677 | + ** r.flags = UNPACKED_INCRKEY; |
| 69678 | + ** }else{ |
| 69679 | + ** r.flags = 0; |
| 69680 | + ** } |
| 69681 | + */ |
| 69682 | + r.flags = (u8)(UNPACKED_INCRKEY * (1 & (oc - OP_SeekLt))); |
| 69683 | + assert( oc!=OP_SeekGt || r.flags==UNPACKED_INCRKEY ); |
| 69684 | + assert( oc!=OP_SeekLe || r.flags==UNPACKED_INCRKEY ); |
| 69685 | + assert( oc!=OP_SeekGe || r.flags==0 ); |
| 69686 | + assert( oc!=OP_SeekLt || r.flags==0 ); |
| 69687 | + |
| 69688 | + r.aMem = &aMem[pOp->p3]; |
| 69689 | +#ifdef SQLITE_DEBUG |
| 69690 | + { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } |
| 69691 | +#endif |
| 69692 | + ExpandBlob(r.aMem); |
| 69693 | + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); |
| 69694 | + if( rc!=SQLITE_OK ){ |
| 69695 | + goto abort_due_to_error; |
| 69696 | + } |
| 69697 | + pC->rowidIsValid = 0; |
| 69698 | + } |
| 69699 | + pC->deferredMoveto = 0; |
| 69700 | + pC->cacheStatus = CACHE_STALE; |
| 69701 | +#ifdef SQLITE_TEST |
| 69702 | + sqlite3_search_count++; |
| 69703 | +#endif |
| 69704 | + if( oc>=OP_SeekGe ){ assert( oc==OP_SeekGe || oc==OP_SeekGt ); |
| 69705 | + if( res<0 || (res==0 && oc==OP_SeekGt) ){ |
| 69706 | + rc = sqlite3BtreeNext(pC->pCursor, &res); |
| 69707 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 69708 | + pC->rowidIsValid = 0; |
| 69709 | + }else{ |
| 69710 | + res = 0; |
| 69711 | + } |
| 69712 | + }else{ |
| 69713 | + assert( oc==OP_SeekLt || oc==OP_SeekLe ); |
| 69714 | + if( res>0 || (res==0 && oc==OP_SeekLt) ){ |
| 69715 | + rc = sqlite3BtreePrevious(pC->pCursor, &res); |
| 69716 | + if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 69717 | + pC->rowidIsValid = 0; |
| 69718 | + }else{ |
| 69719 | + /* res might be negative because the table is empty. Check to |
| 69720 | + ** see if this is the case. |
| 69721 | + */ |
| 69722 | + res = sqlite3BtreeEof(pC->pCursor); |
| 69723 | + } |
| 69724 | + } |
| 69725 | + assert( pOp->p2>0 ); |
| 69726 | + if( res ){ |
| 70145 | 69727 | pc = pOp->p2 - 1; |
| 70146 | 69728 | } |
| 70147 | 69729 | break; |
| 70148 | 69730 | } |
| 70149 | 69731 | |
| | @@ -70156,24 +69738,22 @@ |
| 70156 | 69738 | ** This is actually a deferred seek. Nothing actually happens until |
| 70157 | 69739 | ** the cursor is used to read a record. That way, if no reads |
| 70158 | 69740 | ** occur, no unnecessary I/O happens. |
| 70159 | 69741 | */ |
| 70160 | 69742 | case OP_Seek: { /* in2 */ |
| 70161 | | -#if 0 /* local variables moved into u.be */ |
| 70162 | 69743 | VdbeCursor *pC; |
| 70163 | | -#endif /* local variables moved into u.be */ |
| 70164 | 69744 | |
| 70165 | 69745 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70166 | | - u.be.pC = p->apCsr[pOp->p1]; |
| 70167 | | - assert( u.be.pC!=0 ); |
| 70168 | | - assert( u.be.pC->pCursor!=0 ); |
| 70169 | | - assert( u.be.pC->isTable ); |
| 70170 | | - u.be.pC->nullRow = 0; |
| 69746 | + pC = p->apCsr[pOp->p1]; |
| 69747 | + assert( pC!=0 ); |
| 69748 | + assert( pC->pCursor!=0 ); |
| 69749 | + assert( pC->isTable ); |
| 69750 | + pC->nullRow = 0; |
| 70171 | 69751 | pIn2 = &aMem[pOp->p2]; |
| 70172 | | - u.be.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 70173 | | - u.be.pC->rowidIsValid = 0; |
| 70174 | | - u.be.pC->deferredMoveto = 1; |
| 69752 | + pC->movetoTarget = sqlite3VdbeIntValue(pIn2); |
| 69753 | + pC->rowidIsValid = 0; |
| 69754 | + pC->deferredMoveto = 1; |
| 70175 | 69755 | break; |
| 70176 | 69756 | } |
| 70177 | 69757 | |
| 70178 | 69758 | |
| 70179 | 69759 | /* Opcode: Found P1 P2 P3 P4 * |
| | @@ -70224,85 +69804,83 @@ |
| 70224 | 69804 | ** See also: NotFound, Found, NotExists |
| 70225 | 69805 | */ |
| 70226 | 69806 | case OP_NoConflict: /* jump, in3 */ |
| 70227 | 69807 | case OP_NotFound: /* jump, in3 */ |
| 70228 | 69808 | case OP_Found: { /* jump, in3 */ |
| 70229 | | -#if 0 /* local variables moved into u.bf */ |
| 70230 | 69809 | int alreadyExists; |
| 70231 | 69810 | int ii; |
| 70232 | 69811 | VdbeCursor *pC; |
| 70233 | 69812 | int res; |
| 70234 | 69813 | char *pFree; |
| 70235 | 69814 | UnpackedRecord *pIdxKey; |
| 70236 | 69815 | UnpackedRecord r; |
| 70237 | 69816 | char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7]; |
| 70238 | | -#endif /* local variables moved into u.bf */ |
| 70239 | 69817 | |
| 70240 | 69818 | #ifdef SQLITE_TEST |
| 70241 | 69819 | if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; |
| 70242 | 69820 | #endif |
| 70243 | 69821 | |
| 70244 | | - u.bf.alreadyExists = 0; |
| 70245 | 69822 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70246 | 69823 | assert( pOp->p4type==P4_INT32 ); |
| 70247 | | - u.bf.pC = p->apCsr[pOp->p1]; |
| 70248 | | - assert( u.bf.pC!=0 ); |
| 69824 | + pC = p->apCsr[pOp->p1]; |
| 69825 | + assert( pC!=0 ); |
| 70249 | 69826 | pIn3 = &aMem[pOp->p3]; |
| 70250 | | - assert( u.bf.pC->pCursor!=0 ); |
| 70251 | | - assert( u.bf.pC->isTable==0 ); |
| 69827 | + assert( pC->pCursor!=0 ); |
| 69828 | + assert( pC->isTable==0 ); |
| 69829 | + pFree = 0; /* Not needed. Only used to suppress a compiler warning. */ |
| 70252 | 69830 | if( pOp->p4.i>0 ){ |
| 70253 | | - u.bf.r.pKeyInfo = u.bf.pC->pKeyInfo; |
| 70254 | | - u.bf.r.nField = (u16)pOp->p4.i; |
| 70255 | | - u.bf.r.aMem = pIn3; |
| 69831 | + r.pKeyInfo = pC->pKeyInfo; |
| 69832 | + r.nField = (u16)pOp->p4.i; |
| 69833 | + r.aMem = pIn3; |
| 70256 | 69834 | #ifdef SQLITE_DEBUG |
| 70257 | 69835 | { |
| 70258 | 69836 | int i; |
| 70259 | | - for(i=0; i<u.bf.r.nField; i++){ |
| 70260 | | - assert( memIsValid(&u.bf.r.aMem[i]) ); |
| 70261 | | - if( i ) REGISTER_TRACE(pOp->p3+i, &u.bf.r.aMem[i]); |
| 69837 | + for(i=0; i<r.nField; i++){ |
| 69838 | + assert( memIsValid(&r.aMem[i]) ); |
| 69839 | + if( i ) REGISTER_TRACE(pOp->p3+i, &r.aMem[i]); |
| 70262 | 69840 | } |
| 70263 | 69841 | } |
| 70264 | 69842 | #endif |
| 70265 | | - u.bf.r.flags = UNPACKED_PREFIX_MATCH; |
| 70266 | | - u.bf.pIdxKey = &u.bf.r; |
| 69843 | + r.flags = UNPACKED_PREFIX_MATCH; |
| 69844 | + pIdxKey = &r; |
| 70267 | 69845 | }else{ |
| 70268 | | - u.bf.pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 70269 | | - u.bf.pC->pKeyInfo, u.bf.aTempRec, sizeof(u.bf.aTempRec), &u.bf.pFree |
| 70270 | | - ); |
| 70271 | | - if( u.bf.pIdxKey==0 ) goto no_mem; |
| 69846 | + pIdxKey = sqlite3VdbeAllocUnpackedRecord( |
| 69847 | + pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree |
| 69848 | + ); |
| 69849 | + if( pIdxKey==0 ) goto no_mem; |
| 70272 | 69850 | assert( pIn3->flags & MEM_Blob ); |
| 70273 | 69851 | assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */ |
| 70274 | | - sqlite3VdbeRecordUnpack(u.bf.pC->pKeyInfo, pIn3->n, pIn3->z, u.bf.pIdxKey); |
| 70275 | | - u.bf.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; |
| 69852 | + sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); |
| 69853 | + pIdxKey->flags |= UNPACKED_PREFIX_MATCH; |
| 70276 | 69854 | } |
| 70277 | 69855 | if( pOp->opcode==OP_NoConflict ){ |
| 70278 | 69856 | /* For the OP_NoConflict opcode, take the jump if any of the |
| 70279 | 69857 | ** input fields are NULL, since any key with a NULL will not |
| 70280 | 69858 | ** conflict */ |
| 70281 | | - for(u.bf.ii=0; u.bf.ii<u.bf.r.nField; u.bf.ii++){ |
| 70282 | | - if( u.bf.r.aMem[u.bf.ii].flags & MEM_Null ){ |
| 69859 | + for(ii=0; ii<r.nField; ii++){ |
| 69860 | + if( r.aMem[ii].flags & MEM_Null ){ |
| 70283 | 69861 | pc = pOp->p2 - 1; |
| 70284 | 69862 | break; |
| 70285 | 69863 | } |
| 70286 | 69864 | } |
| 70287 | 69865 | } |
| 70288 | | - rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, u.bf.pIdxKey, 0, 0, &u.bf.res); |
| 69866 | + rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); |
| 70289 | 69867 | if( pOp->p4.i==0 ){ |
| 70290 | | - sqlite3DbFree(db, u.bf.pFree); |
| 69868 | + sqlite3DbFree(db, pFree); |
| 70291 | 69869 | } |
| 70292 | 69870 | if( rc!=SQLITE_OK ){ |
| 70293 | 69871 | break; |
| 70294 | 69872 | } |
| 70295 | | - u.bf.pC->seekResult = u.bf.res; |
| 70296 | | - u.bf.alreadyExists = (u.bf.res==0); |
| 70297 | | - u.bf.pC->nullRow = 1-u.bf.alreadyExists; |
| 70298 | | - u.bf.pC->deferredMoveto = 0; |
| 70299 | | - u.bf.pC->cacheStatus = CACHE_STALE; |
| 69873 | + pC->seekResult = res; |
| 69874 | + alreadyExists = (res==0); |
| 69875 | + pC->nullRow = 1-alreadyExists; |
| 69876 | + pC->deferredMoveto = 0; |
| 69877 | + pC->cacheStatus = CACHE_STALE; |
| 70300 | 69878 | if( pOp->opcode==OP_Found ){ |
| 70301 | | - if( u.bf.alreadyExists ) pc = pOp->p2 - 1; |
| 69879 | + if( alreadyExists ) pc = pOp->p2 - 1; |
| 70302 | 69880 | }else{ |
| 70303 | | - if( !u.bf.alreadyExists ) pc = pOp->p2 - 1; |
| 69881 | + if( !alreadyExists ) pc = pOp->p2 - 1; |
| 70304 | 69882 | } |
| 70305 | 69883 | break; |
| 70306 | 69884 | } |
| 70307 | 69885 | |
| 70308 | 69886 | /* Opcode: NotExists P1 P2 P3 * * |
| | @@ -70318,39 +69896,37 @@ |
| 70318 | 69896 | ** (with arbitrary multi-value keys). |
| 70319 | 69897 | ** |
| 70320 | 69898 | ** See also: Found, NotFound, NoConflict |
| 70321 | 69899 | */ |
| 70322 | 69900 | case OP_NotExists: { /* jump, in3 */ |
| 70323 | | -#if 0 /* local variables moved into u.bg */ |
| 70324 | 69901 | VdbeCursor *pC; |
| 70325 | 69902 | BtCursor *pCrsr; |
| 70326 | 69903 | int res; |
| 70327 | 69904 | u64 iKey; |
| 70328 | | -#endif /* local variables moved into u.bg */ |
| 70329 | 69905 | |
| 70330 | 69906 | pIn3 = &aMem[pOp->p3]; |
| 70331 | 69907 | assert( pIn3->flags & MEM_Int ); |
| 70332 | 69908 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70333 | | - u.bg.pC = p->apCsr[pOp->p1]; |
| 70334 | | - assert( u.bg.pC!=0 ); |
| 70335 | | - assert( u.bg.pC->isTable ); |
| 70336 | | - assert( u.bg.pC->pseudoTableReg==0 ); |
| 70337 | | - u.bg.pCrsr = u.bg.pC->pCursor; |
| 70338 | | - assert( u.bg.pCrsr!=0 ); |
| 70339 | | - u.bg.res = 0; |
| 70340 | | - u.bg.iKey = pIn3->u.i; |
| 70341 | | - rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res); |
| 70342 | | - u.bg.pC->lastRowid = pIn3->u.i; |
| 70343 | | - u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0; |
| 70344 | | - u.bg.pC->nullRow = 0; |
| 70345 | | - u.bg.pC->cacheStatus = CACHE_STALE; |
| 70346 | | - u.bg.pC->deferredMoveto = 0; |
| 70347 | | - if( u.bg.res!=0 ){ |
| 69909 | + pC = p->apCsr[pOp->p1]; |
| 69910 | + assert( pC!=0 ); |
| 69911 | + assert( pC->isTable ); |
| 69912 | + assert( pC->pseudoTableReg==0 ); |
| 69913 | + pCrsr = pC->pCursor; |
| 69914 | + assert( pCrsr!=0 ); |
| 69915 | + res = 0; |
| 69916 | + iKey = pIn3->u.i; |
| 69917 | + rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); |
| 69918 | + pC->lastRowid = pIn3->u.i; |
| 69919 | + pC->rowidIsValid = res==0 ?1:0; |
| 69920 | + pC->nullRow = 0; |
| 69921 | + pC->cacheStatus = CACHE_STALE; |
| 69922 | + pC->deferredMoveto = 0; |
| 69923 | + if( res!=0 ){ |
| 70348 | 69924 | pc = pOp->p2 - 1; |
| 70349 | | - assert( u.bg.pC->rowidIsValid==0 ); |
| 69925 | + assert( pC->rowidIsValid==0 ); |
| 70350 | 69926 | } |
| 70351 | | - u.bg.pC->seekResult = u.bg.res; |
| 69927 | + pC->seekResult = res; |
| 70352 | 69928 | break; |
| 70353 | 69929 | } |
| 70354 | 69930 | |
| 70355 | 69931 | /* Opcode: Sequence P1 P2 * * * |
| 70356 | 69932 | ** Synopsis: r[P2]=rowid |
| | @@ -70382,25 +69958,23 @@ |
| 70382 | 69958 | ** an SQLITE_FULL error is generated. The P3 register is updated with the ' |
| 70383 | 69959 | ** generated record number. This P3 mechanism is used to help implement the |
| 70384 | 69960 | ** AUTOINCREMENT feature. |
| 70385 | 69961 | */ |
| 70386 | 69962 | case OP_NewRowid: { /* out2-prerelease */ |
| 70387 | | -#if 0 /* local variables moved into u.bh */ |
| 70388 | 69963 | i64 v; /* The new rowid */ |
| 70389 | 69964 | VdbeCursor *pC; /* Cursor of table to get the new rowid */ |
| 70390 | 69965 | int res; /* Result of an sqlite3BtreeLast() */ |
| 70391 | 69966 | int cnt; /* Counter to limit the number of searches */ |
| 70392 | 69967 | Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
| 70393 | 69968 | VdbeFrame *pFrame; /* Root frame of VDBE */ |
| 70394 | | -#endif /* local variables moved into u.bh */ |
| 70395 | 69969 | |
| 70396 | | - u.bh.v = 0; |
| 70397 | | - u.bh.res = 0; |
| 69970 | + v = 0; |
| 69971 | + res = 0; |
| 70398 | 69972 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70399 | | - u.bh.pC = p->apCsr[pOp->p1]; |
| 70400 | | - assert( u.bh.pC!=0 ); |
| 70401 | | - if( NEVER(u.bh.pC->pCursor==0) ){ |
| 69973 | + pC = p->apCsr[pOp->p1]; |
| 69974 | + assert( pC!=0 ); |
| 69975 | + if( NEVER(pC->pCursor==0) ){ |
| 70402 | 69976 | /* The zero initialization above is all that is needed */ |
| 70403 | 69977 | }else{ |
| 70404 | 69978 | /* The next rowid or record number (different terms for the same |
| 70405 | 69979 | ** thing) is obtained in a two-step algorithm. |
| 70406 | 69980 | ** |
| | @@ -70412,11 +69986,11 @@ |
| 70412 | 69986 | ** The second algorithm is to select a rowid at random and see if |
| 70413 | 69987 | ** it already exists in the table. If it does not exist, we have |
| 70414 | 69988 | ** succeeded. If the random rowid does exist, we select a new one |
| 70415 | 69989 | ** and try again, up to 100 times. |
| 70416 | 69990 | */ |
| 70417 | | - assert( u.bh.pC->isTable ); |
| 69991 | + assert( pC->isTable ); |
| 70418 | 69992 | |
| 70419 | 69993 | #ifdef SQLITE_32BIT_ROWID |
| 70420 | 69994 | # define MAX_ROWID 0x7fffffff |
| 70421 | 69995 | #else |
| 70422 | 69996 | /* Some compilers complain about constants of the form 0x7fffffffffffffff. |
| | @@ -70424,101 +69998,101 @@ |
| 70424 | 69998 | ** to provide the constant while making all compilers happy. |
| 70425 | 69999 | */ |
| 70426 | 70000 | # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) |
| 70427 | 70001 | #endif |
| 70428 | 70002 | |
| 70429 | | - if( !u.bh.pC->useRandomRowid ){ |
| 70430 | | - u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor); |
| 70431 | | - if( u.bh.v==0 ){ |
| 70432 | | - rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res); |
| 70003 | + if( !pC->useRandomRowid ){ |
| 70004 | + v = sqlite3BtreeGetCachedRowid(pC->pCursor); |
| 70005 | + if( v==0 ){ |
| 70006 | + rc = sqlite3BtreeLast(pC->pCursor, &res); |
| 70433 | 70007 | if( rc!=SQLITE_OK ){ |
| 70434 | 70008 | goto abort_due_to_error; |
| 70435 | 70009 | } |
| 70436 | | - if( u.bh.res ){ |
| 70437 | | - u.bh.v = 1; /* IMP: R-61914-48074 */ |
| 70010 | + if( res ){ |
| 70011 | + v = 1; /* IMP: R-61914-48074 */ |
| 70438 | 70012 | }else{ |
| 70439 | | - assert( sqlite3BtreeCursorIsValid(u.bh.pC->pCursor) ); |
| 70440 | | - rc = sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v); |
| 70013 | + assert( sqlite3BtreeCursorIsValid(pC->pCursor) ); |
| 70014 | + rc = sqlite3BtreeKeySize(pC->pCursor, &v); |
| 70441 | 70015 | assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ |
| 70442 | | - if( u.bh.v>=MAX_ROWID ){ |
| 70443 | | - u.bh.pC->useRandomRowid = 1; |
| 70016 | + if( v>=MAX_ROWID ){ |
| 70017 | + pC->useRandomRowid = 1; |
| 70444 | 70018 | }else{ |
| 70445 | | - u.bh.v++; /* IMP: R-29538-34987 */ |
| 70019 | + v++; /* IMP: R-29538-34987 */ |
| 70446 | 70020 | } |
| 70447 | 70021 | } |
| 70448 | 70022 | } |
| 70449 | 70023 | |
| 70450 | 70024 | #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 70451 | 70025 | if( pOp->p3 ){ |
| 70452 | 70026 | /* Assert that P3 is a valid memory cell. */ |
| 70453 | 70027 | assert( pOp->p3>0 ); |
| 70454 | 70028 | if( p->pFrame ){ |
| 70455 | | - for(u.bh.pFrame=p->pFrame; u.bh.pFrame->pParent; u.bh.pFrame=u.bh.pFrame->pParent); |
| 70029 | + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); |
| 70456 | 70030 | /* Assert that P3 is a valid memory cell. */ |
| 70457 | | - assert( pOp->p3<=u.bh.pFrame->nMem ); |
| 70458 | | - u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3]; |
| 70031 | + assert( pOp->p3<=pFrame->nMem ); |
| 70032 | + pMem = &pFrame->aMem[pOp->p3]; |
| 70459 | 70033 | }else{ |
| 70460 | 70034 | /* Assert that P3 is a valid memory cell. */ |
| 70461 | 70035 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 70462 | | - u.bh.pMem = &aMem[pOp->p3]; |
| 70463 | | - memAboutToChange(p, u.bh.pMem); |
| 70464 | | - } |
| 70465 | | - assert( memIsValid(u.bh.pMem) ); |
| 70466 | | - |
| 70467 | | - REGISTER_TRACE(pOp->p3, u.bh.pMem); |
| 70468 | | - sqlite3VdbeMemIntegerify(u.bh.pMem); |
| 70469 | | - assert( (u.bh.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ |
| 70470 | | - if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){ |
| 70036 | + pMem = &aMem[pOp->p3]; |
| 70037 | + memAboutToChange(p, pMem); |
| 70038 | + } |
| 70039 | + assert( memIsValid(pMem) ); |
| 70040 | + |
| 70041 | + REGISTER_TRACE(pOp->p3, pMem); |
| 70042 | + sqlite3VdbeMemIntegerify(pMem); |
| 70043 | + assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ |
| 70044 | + if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ |
| 70471 | 70045 | rc = SQLITE_FULL; /* IMP: R-12275-61338 */ |
| 70472 | 70046 | goto abort_due_to_error; |
| 70473 | 70047 | } |
| 70474 | | - if( u.bh.v<u.bh.pMem->u.i+1 ){ |
| 70475 | | - u.bh.v = u.bh.pMem->u.i + 1; |
| 70048 | + if( v<pMem->u.i+1 ){ |
| 70049 | + v = pMem->u.i + 1; |
| 70476 | 70050 | } |
| 70477 | | - u.bh.pMem->u.i = u.bh.v; |
| 70051 | + pMem->u.i = v; |
| 70478 | 70052 | } |
| 70479 | 70053 | #endif |
| 70480 | 70054 | |
| 70481 | | - sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0); |
| 70055 | + sqlite3BtreeSetCachedRowid(pC->pCursor, v<MAX_ROWID ? v+1 : 0); |
| 70482 | 70056 | } |
| 70483 | | - if( u.bh.pC->useRandomRowid ){ |
| 70057 | + if( pC->useRandomRowid ){ |
| 70484 | 70058 | /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the |
| 70485 | 70059 | ** largest possible integer (9223372036854775807) then the database |
| 70486 | 70060 | ** engine starts picking positive candidate ROWIDs at random until |
| 70487 | 70061 | ** it finds one that is not previously used. */ |
| 70488 | 70062 | assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is |
| 70489 | 70063 | ** an AUTOINCREMENT table. */ |
| 70490 | 70064 | /* on the first attempt, simply do one more than previous */ |
| 70491 | | - u.bh.v = lastRowid; |
| 70492 | | - u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 70493 | | - u.bh.v++; /* ensure non-zero */ |
| 70494 | | - u.bh.cnt = 0; |
| 70495 | | - while( ((rc = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.v, |
| 70496 | | - 0, &u.bh.res))==SQLITE_OK) |
| 70497 | | - && (u.bh.res==0) |
| 70498 | | - && (++u.bh.cnt<100)){ |
| 70065 | + v = lastRowid; |
| 70066 | + v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 70067 | + v++; /* ensure non-zero */ |
| 70068 | + cnt = 0; |
| 70069 | + while( ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v, |
| 70070 | + 0, &res))==SQLITE_OK) |
| 70071 | + && (res==0) |
| 70072 | + && (++cnt<100)){ |
| 70499 | 70073 | /* collision - try another random rowid */ |
| 70500 | | - sqlite3_randomness(sizeof(u.bh.v), &u.bh.v); |
| 70501 | | - if( u.bh.cnt<5 ){ |
| 70074 | + sqlite3_randomness(sizeof(v), &v); |
| 70075 | + if( cnt<5 ){ |
| 70502 | 70076 | /* try "small" random rowids for the initial attempts */ |
| 70503 | | - u.bh.v &= 0xffffff; |
| 70077 | + v &= 0xffffff; |
| 70504 | 70078 | }else{ |
| 70505 | | - u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 70079 | + v &= (MAX_ROWID>>1); /* ensure doesn't go negative */ |
| 70506 | 70080 | } |
| 70507 | | - u.bh.v++; /* ensure non-zero */ |
| 70081 | + v++; /* ensure non-zero */ |
| 70508 | 70082 | } |
| 70509 | | - if( rc==SQLITE_OK && u.bh.res==0 ){ |
| 70083 | + if( rc==SQLITE_OK && res==0 ){ |
| 70510 | 70084 | rc = SQLITE_FULL; /* IMP: R-38219-53002 */ |
| 70511 | 70085 | goto abort_due_to_error; |
| 70512 | 70086 | } |
| 70513 | | - assert( u.bh.v>0 ); /* EV: R-40812-03570 */ |
| 70087 | + assert( v>0 ); /* EV: R-40812-03570 */ |
| 70514 | 70088 | } |
| 70515 | | - u.bh.pC->rowidIsValid = 0; |
| 70516 | | - u.bh.pC->deferredMoveto = 0; |
| 70517 | | - u.bh.pC->cacheStatus = CACHE_STALE; |
| 70089 | + pC->rowidIsValid = 0; |
| 70090 | + pC->deferredMoveto = 0; |
| 70091 | + pC->cacheStatus = CACHE_STALE; |
| 70518 | 70092 | } |
| 70519 | | - pOut->u.i = u.bh.v; |
| 70093 | + pOut->u.i = v; |
| 70520 | 70094 | break; |
| 70521 | 70095 | } |
| 70522 | 70096 | |
| 70523 | 70097 | /* Opcode: Insert P1 P2 P3 P4 P5 |
| 70524 | 70098 | ** Synopsis: intkey=r[P3] data=r[P2] |
| | @@ -70566,74 +70140,72 @@ |
| 70566 | 70140 | ** This works exactly like OP_Insert except that the key is the |
| 70567 | 70141 | ** integer value P3, not the value of the integer stored in register P3. |
| 70568 | 70142 | */ |
| 70569 | 70143 | case OP_Insert: |
| 70570 | 70144 | case OP_InsertInt: { |
| 70571 | | -#if 0 /* local variables moved into u.bi */ |
| 70572 | 70145 | Mem *pData; /* MEM cell holding data for the record to be inserted */ |
| 70573 | 70146 | Mem *pKey; /* MEM cell holding key for the record */ |
| 70574 | 70147 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
| 70575 | 70148 | VdbeCursor *pC; /* Cursor to table into which insert is written */ |
| 70576 | 70149 | int nZero; /* Number of zero-bytes to append */ |
| 70577 | 70150 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
| 70578 | 70151 | const char *zDb; /* database name - used by the update hook */ |
| 70579 | 70152 | const char *zTbl; /* Table name - used by the opdate hook */ |
| 70580 | 70153 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
| 70581 | | -#endif /* local variables moved into u.bi */ |
| 70582 | 70154 | |
| 70583 | | - u.bi.pData = &aMem[pOp->p2]; |
| 70155 | + pData = &aMem[pOp->p2]; |
| 70584 | 70156 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70585 | | - assert( memIsValid(u.bi.pData) ); |
| 70586 | | - u.bi.pC = p->apCsr[pOp->p1]; |
| 70587 | | - assert( u.bi.pC!=0 ); |
| 70588 | | - assert( u.bi.pC->pCursor!=0 ); |
| 70589 | | - assert( u.bi.pC->pseudoTableReg==0 ); |
| 70590 | | - assert( u.bi.pC->isTable ); |
| 70591 | | - REGISTER_TRACE(pOp->p2, u.bi.pData); |
| 70157 | + assert( memIsValid(pData) ); |
| 70158 | + pC = p->apCsr[pOp->p1]; |
| 70159 | + assert( pC!=0 ); |
| 70160 | + assert( pC->pCursor!=0 ); |
| 70161 | + assert( pC->pseudoTableReg==0 ); |
| 70162 | + assert( pC->isTable ); |
| 70163 | + REGISTER_TRACE(pOp->p2, pData); |
| 70592 | 70164 | |
| 70593 | 70165 | if( pOp->opcode==OP_Insert ){ |
| 70594 | | - u.bi.pKey = &aMem[pOp->p3]; |
| 70595 | | - assert( u.bi.pKey->flags & MEM_Int ); |
| 70596 | | - assert( memIsValid(u.bi.pKey) ); |
| 70597 | | - REGISTER_TRACE(pOp->p3, u.bi.pKey); |
| 70598 | | - u.bi.iKey = u.bi.pKey->u.i; |
| 70166 | + pKey = &aMem[pOp->p3]; |
| 70167 | + assert( pKey->flags & MEM_Int ); |
| 70168 | + assert( memIsValid(pKey) ); |
| 70169 | + REGISTER_TRACE(pOp->p3, pKey); |
| 70170 | + iKey = pKey->u.i; |
| 70599 | 70171 | }else{ |
| 70600 | 70172 | assert( pOp->opcode==OP_InsertInt ); |
| 70601 | | - u.bi.iKey = pOp->p3; |
| 70173 | + iKey = pOp->p3; |
| 70602 | 70174 | } |
| 70603 | 70175 | |
| 70604 | 70176 | if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; |
| 70605 | | - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bi.iKey; |
| 70606 | | - if( u.bi.pData->flags & MEM_Null ){ |
| 70607 | | - u.bi.pData->z = 0; |
| 70608 | | - u.bi.pData->n = 0; |
| 70609 | | - }else{ |
| 70610 | | - assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) ); |
| 70611 | | - } |
| 70612 | | - u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0); |
| 70613 | | - if( u.bi.pData->flags & MEM_Zero ){ |
| 70614 | | - u.bi.nZero = u.bi.pData->u.nZero; |
| 70615 | | - }else{ |
| 70616 | | - u.bi.nZero = 0; |
| 70617 | | - } |
| 70618 | | - sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0); |
| 70619 | | - rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey, |
| 70620 | | - u.bi.pData->z, u.bi.pData->n, u.bi.nZero, |
| 70621 | | - pOp->p5 & OPFLAG_APPEND, u.bi.seekResult |
| 70177 | + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey; |
| 70178 | + if( pData->flags & MEM_Null ){ |
| 70179 | + pData->z = 0; |
| 70180 | + pData->n = 0; |
| 70181 | + }else{ |
| 70182 | + assert( pData->flags & (MEM_Blob|MEM_Str) ); |
| 70183 | + } |
| 70184 | + seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); |
| 70185 | + if( pData->flags & MEM_Zero ){ |
| 70186 | + nZero = pData->u.nZero; |
| 70187 | + }else{ |
| 70188 | + nZero = 0; |
| 70189 | + } |
| 70190 | + sqlite3BtreeSetCachedRowid(pC->pCursor, 0); |
| 70191 | + rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, |
| 70192 | + pData->z, pData->n, nZero, |
| 70193 | + (pOp->p5 & OPFLAG_APPEND)!=0, seekResult |
| 70622 | 70194 | ); |
| 70623 | | - u.bi.pC->rowidIsValid = 0; |
| 70624 | | - u.bi.pC->deferredMoveto = 0; |
| 70625 | | - u.bi.pC->cacheStatus = CACHE_STALE; |
| 70195 | + pC->rowidIsValid = 0; |
| 70196 | + pC->deferredMoveto = 0; |
| 70197 | + pC->cacheStatus = CACHE_STALE; |
| 70626 | 70198 | |
| 70627 | 70199 | /* Invoke the update-hook if required. */ |
| 70628 | 70200 | if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 70629 | | - u.bi.zDb = db->aDb[u.bi.pC->iDb].zName; |
| 70630 | | - u.bi.zTbl = pOp->p4.z; |
| 70631 | | - u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); |
| 70632 | | - assert( u.bi.pC->isTable ); |
| 70633 | | - db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey); |
| 70634 | | - assert( u.bi.pC->iDb>=0 ); |
| 70201 | + zDb = db->aDb[pC->iDb].zName; |
| 70202 | + zTbl = pOp->p4.z; |
| 70203 | + op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); |
| 70204 | + assert( pC->isTable ); |
| 70205 | + db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey); |
| 70206 | + assert( pC->iDb>=0 ); |
| 70635 | 70207 | } |
| 70636 | 70208 | break; |
| 70637 | 70209 | } |
| 70638 | 70210 | |
| 70639 | 70211 | /* Opcode: Delete P1 P2 * P4 * |
| | @@ -70655,51 +70227,39 @@ |
| 70655 | 70227 | ** pointing to. The update hook will be invoked, if it exists. |
| 70656 | 70228 | ** If P4 is not NULL then the P1 cursor must have been positioned |
| 70657 | 70229 | ** using OP_NotFound prior to invoking this opcode. |
| 70658 | 70230 | */ |
| 70659 | 70231 | case OP_Delete: { |
| 70660 | | -#if 0 /* local variables moved into u.bj */ |
| 70661 | 70232 | i64 iKey; |
| 70662 | 70233 | VdbeCursor *pC; |
| 70663 | | -#endif /* local variables moved into u.bj */ |
| 70664 | 70234 | |
| 70665 | | - u.bj.iKey = 0; |
| 70666 | 70235 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70667 | | - u.bj.pC = p->apCsr[pOp->p1]; |
| 70668 | | - assert( u.bj.pC!=0 ); |
| 70669 | | - assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 70670 | | - |
| 70671 | | - /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the |
| 70672 | | - ** row being deleted. |
| 70673 | | - */ |
| 70674 | | - if( db->xUpdateCallback && pOp->p4.z ){ |
| 70675 | | - assert( u.bj.pC->isTable ); |
| 70676 | | - assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ |
| 70677 | | - u.bj.iKey = u.bj.pC->lastRowid; |
| 70678 | | - } |
| 70236 | + pC = p->apCsr[pOp->p1]; |
| 70237 | + assert( pC!=0 ); |
| 70238 | + assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 70239 | + iKey = pC->lastRowid; /* Only used for the update hook */ |
| 70679 | 70240 | |
| 70680 | 70241 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
| 70681 | 70242 | ** OP_Column on the same table without any intervening operations that |
| 70682 | | - ** might move or invalidate the cursor. Hence cursor u.bj.pC is always pointing |
| 70243 | + ** might move or invalidate the cursor. Hence cursor pC is always pointing |
| 70683 | 70244 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
| 70684 | 70245 | ** below is always a no-op and cannot fail. We will run it anyhow, though, |
| 70685 | 70246 | ** to guard against future changes to the code generator. |
| 70686 | 70247 | **/ |
| 70687 | | - assert( u.bj.pC->deferredMoveto==0 ); |
| 70688 | | - rc = sqlite3VdbeCursorMoveto(u.bj.pC); |
| 70248 | + assert( pC->deferredMoveto==0 ); |
| 70249 | + rc = sqlite3VdbeCursorMoveto(pC); |
| 70689 | 70250 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 70690 | 70251 | |
| 70691 | | - sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0); |
| 70692 | | - rc = sqlite3BtreeDelete(u.bj.pC->pCursor); |
| 70693 | | - u.bj.pC->cacheStatus = CACHE_STALE; |
| 70252 | + sqlite3BtreeSetCachedRowid(pC->pCursor, 0); |
| 70253 | + rc = sqlite3BtreeDelete(pC->pCursor); |
| 70254 | + pC->cacheStatus = CACHE_STALE; |
| 70694 | 70255 | |
| 70695 | 70256 | /* Invoke the update-hook if required. */ |
| 70696 | | - if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 70697 | | - const char *zDb = db->aDb[u.bj.pC->iDb].zName; |
| 70698 | | - const char *zTbl = pOp->p4.z; |
| 70699 | | - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey); |
| 70700 | | - assert( u.bj.pC->iDb>=0 ); |
| 70257 | + if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){ |
| 70258 | + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, |
| 70259 | + db->aDb[pC->iDb].zName, pOp->p4.z, iKey); |
| 70260 | + assert( pC->iDb>=0 ); |
| 70701 | 70261 | } |
| 70702 | 70262 | if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; |
| 70703 | 70263 | break; |
| 70704 | 70264 | } |
| 70705 | 70265 | /* Opcode: ResetCount * * * * * |
| | @@ -70729,23 +70289,21 @@ |
| 70729 | 70289 | ** |
| 70730 | 70290 | ** Fall through to next instruction if the two records compare equal to |
| 70731 | 70291 | ** each other. Jump to P2 if they are different. |
| 70732 | 70292 | */ |
| 70733 | 70293 | case OP_SorterCompare: { |
| 70734 | | -#if 0 /* local variables moved into u.bk */ |
| 70735 | 70294 | VdbeCursor *pC; |
| 70736 | 70295 | int res; |
| 70737 | 70296 | int nIgnore; |
| 70738 | | -#endif /* local variables moved into u.bk */ |
| 70739 | 70297 | |
| 70740 | | - u.bk.pC = p->apCsr[pOp->p1]; |
| 70741 | | - assert( isSorter(u.bk.pC) ); |
| 70298 | + pC = p->apCsr[pOp->p1]; |
| 70299 | + assert( isSorter(pC) ); |
| 70742 | 70300 | assert( pOp->p4type==P4_INT32 ); |
| 70743 | 70301 | pIn3 = &aMem[pOp->p3]; |
| 70744 | | - u.bk.nIgnore = pOp->p4.i; |
| 70745 | | - rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, u.bk.nIgnore, &u.bk.res); |
| 70746 | | - if( u.bk.res ){ |
| 70302 | + nIgnore = pOp->p4.i; |
| 70303 | + rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res); |
| 70304 | + if( res ){ |
| 70747 | 70305 | pc = pOp->p2-1; |
| 70748 | 70306 | } |
| 70749 | 70307 | break; |
| 70750 | 70308 | }; |
| 70751 | 70309 | |
| | @@ -70753,18 +70311,16 @@ |
| 70753 | 70311 | ** Synopsis: r[P2]=data |
| 70754 | 70312 | ** |
| 70755 | 70313 | ** Write into register P2 the current sorter data for sorter cursor P1. |
| 70756 | 70314 | */ |
| 70757 | 70315 | case OP_SorterData: { |
| 70758 | | -#if 0 /* local variables moved into u.bl */ |
| 70759 | 70316 | VdbeCursor *pC; |
| 70760 | | -#endif /* local variables moved into u.bl */ |
| 70761 | 70317 | |
| 70762 | 70318 | pOut = &aMem[pOp->p2]; |
| 70763 | | - u.bl.pC = p->apCsr[pOp->p1]; |
| 70764 | | - assert( u.bl.pC->isSorter ); |
| 70765 | | - rc = sqlite3VdbeSorterRowkey(u.bl.pC, pOut); |
| 70319 | + pC = p->apCsr[pOp->p1]; |
| 70320 | + assert( isSorter(pC) ); |
| 70321 | + rc = sqlite3VdbeSorterRowkey(pC, pOut); |
| 70766 | 70322 | break; |
| 70767 | 70323 | } |
| 70768 | 70324 | |
| 70769 | 70325 | /* Opcode: RowData P1 P2 * * * |
| 70770 | 70326 | ** Synopsis: r[P2]=data |
| | @@ -70788,66 +70344,64 @@ |
| 70788 | 70344 | ** If the P1 cursor must be pointing to a valid row (not a NULL row) |
| 70789 | 70345 | ** of a real table, not a pseudo-table. |
| 70790 | 70346 | */ |
| 70791 | 70347 | case OP_RowKey: |
| 70792 | 70348 | case OP_RowData: { |
| 70793 | | -#if 0 /* local variables moved into u.bm */ |
| 70794 | 70349 | VdbeCursor *pC; |
| 70795 | 70350 | BtCursor *pCrsr; |
| 70796 | 70351 | u32 n; |
| 70797 | 70352 | i64 n64; |
| 70798 | | -#endif /* local variables moved into u.bm */ |
| 70799 | 70353 | |
| 70800 | 70354 | pOut = &aMem[pOp->p2]; |
| 70801 | 70355 | memAboutToChange(p, pOut); |
| 70802 | 70356 | |
| 70803 | 70357 | /* Note that RowKey and RowData are really exactly the same instruction */ |
| 70804 | 70358 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70805 | | - u.bm.pC = p->apCsr[pOp->p1]; |
| 70806 | | - assert( u.bm.pC->isSorter==0 ); |
| 70807 | | - assert( u.bm.pC->isTable || pOp->opcode!=OP_RowData ); |
| 70808 | | - assert( u.bm.pC->isIndex || pOp->opcode==OP_RowData ); |
| 70809 | | - assert( u.bm.pC!=0 ); |
| 70810 | | - assert( u.bm.pC->nullRow==0 ); |
| 70811 | | - assert( u.bm.pC->pseudoTableReg==0 ); |
| 70812 | | - assert( u.bm.pC->pCursor!=0 ); |
| 70813 | | - u.bm.pCrsr = u.bm.pC->pCursor; |
| 70814 | | - assert( sqlite3BtreeCursorIsValid(u.bm.pCrsr) ); |
| 70359 | + pC = p->apCsr[pOp->p1]; |
| 70360 | + assert( isSorter(pC)==0 ); |
| 70361 | + assert( pC->isTable || pOp->opcode!=OP_RowData ); |
| 70362 | + assert( pC->isTable==0 || pOp->opcode==OP_RowData ); |
| 70363 | + assert( pC!=0 ); |
| 70364 | + assert( pC->nullRow==0 ); |
| 70365 | + assert( pC->pseudoTableReg==0 ); |
| 70366 | + assert( pC->pCursor!=0 ); |
| 70367 | + pCrsr = pC->pCursor; |
| 70368 | + assert( sqlite3BtreeCursorIsValid(pCrsr) ); |
| 70815 | 70369 | |
| 70816 | 70370 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
| 70817 | 70371 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
| 70818 | 70372 | ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
| 70819 | 70373 | ** a no-op and can never fail. But we leave it in place as a safety. |
| 70820 | 70374 | */ |
| 70821 | | - assert( u.bm.pC->deferredMoveto==0 ); |
| 70822 | | - rc = sqlite3VdbeCursorMoveto(u.bm.pC); |
| 70823 | | - if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 70824 | | - |
| 70825 | | - if( u.bm.pC->isIndex ){ |
| 70826 | | - assert( !u.bm.pC->isTable ); |
| 70827 | | - VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bm.pCrsr, &u.bm.n64); |
| 70828 | | - assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 70829 | | - if( u.bm.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 70830 | | - goto too_big; |
| 70831 | | - } |
| 70832 | | - u.bm.n = (u32)u.bm.n64; |
| 70833 | | - }else{ |
| 70834 | | - VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bm.pCrsr, &u.bm.n); |
| 70835 | | - assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 70836 | | - if( u.bm.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 70837 | | - goto too_big; |
| 70838 | | - } |
| 70839 | | - } |
| 70840 | | - if( sqlite3VdbeMemGrow(pOut, u.bm.n, 0) ){ |
| 70841 | | - goto no_mem; |
| 70842 | | - } |
| 70843 | | - pOut->n = u.bm.n; |
| 70844 | | - MemSetTypeFlag(pOut, MEM_Blob); |
| 70845 | | - if( u.bm.pC->isIndex ){ |
| 70846 | | - rc = sqlite3BtreeKey(u.bm.pCrsr, 0, u.bm.n, pOut->z); |
| 70847 | | - }else{ |
| 70848 | | - rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z); |
| 70375 | + assert( pC->deferredMoveto==0 ); |
| 70376 | + rc = sqlite3VdbeCursorMoveto(pC); |
| 70377 | + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; |
| 70378 | + |
| 70379 | + if( pC->isTable==0 ){ |
| 70380 | + assert( !pC->isTable ); |
| 70381 | + VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); |
| 70382 | + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ |
| 70383 | + if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 70384 | + goto too_big; |
| 70385 | + } |
| 70386 | + n = (u32)n64; |
| 70387 | + }else{ |
| 70388 | + VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n); |
| 70389 | + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ |
| 70390 | + if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ |
| 70391 | + goto too_big; |
| 70392 | + } |
| 70393 | + } |
| 70394 | + if( sqlite3VdbeMemGrow(pOut, n, 0) ){ |
| 70395 | + goto no_mem; |
| 70396 | + } |
| 70397 | + pOut->n = n; |
| 70398 | + MemSetTypeFlag(pOut, MEM_Blob); |
| 70399 | + if( pC->isTable==0 ){ |
| 70400 | + rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); |
| 70401 | + }else{ |
| 70402 | + rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z); |
| 70849 | 70403 | } |
| 70850 | 70404 | pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ |
| 70851 | 70405 | UPDATE_MAX_BLOBSIZE(pOut); |
| 70852 | 70406 | REGISTER_TRACE(pOp->p2, pOut); |
| 70853 | 70407 | break; |
| | @@ -70862,46 +70416,44 @@ |
| 70862 | 70416 | ** P1 can be either an ordinary table or a virtual table. There used to |
| 70863 | 70417 | ** be a separate OP_VRowid opcode for use with virtual tables, but this |
| 70864 | 70418 | ** one opcode now works for both table types. |
| 70865 | 70419 | */ |
| 70866 | 70420 | case OP_Rowid: { /* out2-prerelease */ |
| 70867 | | -#if 0 /* local variables moved into u.bn */ |
| 70868 | 70421 | VdbeCursor *pC; |
| 70869 | 70422 | i64 v; |
| 70870 | 70423 | sqlite3_vtab *pVtab; |
| 70871 | 70424 | const sqlite3_module *pModule; |
| 70872 | | -#endif /* local variables moved into u.bn */ |
| 70873 | 70425 | |
| 70874 | 70426 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70875 | | - u.bn.pC = p->apCsr[pOp->p1]; |
| 70876 | | - assert( u.bn.pC!=0 ); |
| 70877 | | - assert( u.bn.pC->pseudoTableReg==0 || u.bn.pC->nullRow ); |
| 70878 | | - if( u.bn.pC->nullRow ){ |
| 70427 | + pC = p->apCsr[pOp->p1]; |
| 70428 | + assert( pC!=0 ); |
| 70429 | + assert( pC->pseudoTableReg==0 || pC->nullRow ); |
| 70430 | + if( pC->nullRow ){ |
| 70879 | 70431 | pOut->flags = MEM_Null; |
| 70880 | 70432 | break; |
| 70881 | | - }else if( u.bn.pC->deferredMoveto ){ |
| 70882 | | - u.bn.v = u.bn.pC->movetoTarget; |
| 70433 | + }else if( pC->deferredMoveto ){ |
| 70434 | + v = pC->movetoTarget; |
| 70883 | 70435 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 70884 | | - }else if( u.bn.pC->pVtabCursor ){ |
| 70885 | | - u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab; |
| 70886 | | - u.bn.pModule = u.bn.pVtab->pModule; |
| 70887 | | - assert( u.bn.pModule->xRowid ); |
| 70888 | | - rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v); |
| 70889 | | - sqlite3VtabImportErrmsg(p, u.bn.pVtab); |
| 70436 | + }else if( pC->pVtabCursor ){ |
| 70437 | + pVtab = pC->pVtabCursor->pVtab; |
| 70438 | + pModule = pVtab->pModule; |
| 70439 | + assert( pModule->xRowid ); |
| 70440 | + rc = pModule->xRowid(pC->pVtabCursor, &v); |
| 70441 | + sqlite3VtabImportErrmsg(p, pVtab); |
| 70890 | 70442 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 70891 | 70443 | }else{ |
| 70892 | | - assert( u.bn.pC->pCursor!=0 ); |
| 70893 | | - rc = sqlite3VdbeCursorMoveto(u.bn.pC); |
| 70444 | + assert( pC->pCursor!=0 ); |
| 70445 | + rc = sqlite3VdbeCursorMoveto(pC); |
| 70894 | 70446 | if( rc ) goto abort_due_to_error; |
| 70895 | | - if( u.bn.pC->rowidIsValid ){ |
| 70896 | | - u.bn.v = u.bn.pC->lastRowid; |
| 70447 | + if( pC->rowidIsValid ){ |
| 70448 | + v = pC->lastRowid; |
| 70897 | 70449 | }else{ |
| 70898 | | - rc = sqlite3BtreeKeySize(u.bn.pC->pCursor, &u.bn.v); |
| 70450 | + rc = sqlite3BtreeKeySize(pC->pCursor, &v); |
| 70899 | 70451 | assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ |
| 70900 | 70452 | } |
| 70901 | 70453 | } |
| 70902 | | - pOut->u.i = u.bn.v; |
| 70454 | + pOut->u.i = v; |
| 70903 | 70455 | break; |
| 70904 | 70456 | } |
| 70905 | 70457 | |
| 70906 | 70458 | /* Opcode: NullRow P1 * * * * |
| 70907 | 70459 | ** |
| | @@ -70908,22 +70460,21 @@ |
| 70908 | 70460 | ** Move the cursor P1 to a null row. Any OP_Column operations |
| 70909 | 70461 | ** that occur while the cursor is on the null row will always |
| 70910 | 70462 | ** write a NULL. |
| 70911 | 70463 | */ |
| 70912 | 70464 | case OP_NullRow: { |
| 70913 | | -#if 0 /* local variables moved into u.bo */ |
| 70914 | 70465 | VdbeCursor *pC; |
| 70915 | | -#endif /* local variables moved into u.bo */ |
| 70916 | 70466 | |
| 70917 | 70467 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70918 | | - u.bo.pC = p->apCsr[pOp->p1]; |
| 70919 | | - assert( u.bo.pC!=0 ); |
| 70920 | | - u.bo.pC->nullRow = 1; |
| 70921 | | - u.bo.pC->rowidIsValid = 0; |
| 70922 | | - assert( u.bo.pC->pCursor || u.bo.pC->pVtabCursor ); |
| 70923 | | - if( u.bo.pC->pCursor ){ |
| 70924 | | - sqlite3BtreeClearCursor(u.bo.pC->pCursor); |
| 70468 | + pC = p->apCsr[pOp->p1]; |
| 70469 | + assert( pC!=0 ); |
| 70470 | + pC->nullRow = 1; |
| 70471 | + pC->rowidIsValid = 0; |
| 70472 | + pC->cacheStatus = CACHE_STALE; |
| 70473 | + assert( pC->pCursor || pC->pVtabCursor ); |
| 70474 | + if( pC->pCursor ){ |
| 70475 | + sqlite3BtreeClearCursor(pC->pCursor); |
| 70925 | 70476 | } |
| 70926 | 70477 | break; |
| 70927 | 70478 | } |
| 70928 | 70479 | |
| 70929 | 70480 | /* Opcode: Last P1 P2 * * * |
| | @@ -70933,28 +70484,26 @@ |
| 70933 | 70484 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 70934 | 70485 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 70935 | 70486 | ** to the following instruction. |
| 70936 | 70487 | */ |
| 70937 | 70488 | case OP_Last: { /* jump */ |
| 70938 | | -#if 0 /* local variables moved into u.bp */ |
| 70939 | 70489 | VdbeCursor *pC; |
| 70940 | 70490 | BtCursor *pCrsr; |
| 70941 | 70491 | int res; |
| 70942 | | -#endif /* local variables moved into u.bp */ |
| 70943 | 70492 | |
| 70944 | 70493 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70945 | | - u.bp.pC = p->apCsr[pOp->p1]; |
| 70946 | | - assert( u.bp.pC!=0 ); |
| 70947 | | - u.bp.pCrsr = u.bp.pC->pCursor; |
| 70948 | | - u.bp.res = 0; |
| 70949 | | - assert( u.bp.pCrsr!=0 ); |
| 70950 | | - rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res); |
| 70951 | | - u.bp.pC->nullRow = (u8)u.bp.res; |
| 70952 | | - u.bp.pC->deferredMoveto = 0; |
| 70953 | | - u.bp.pC->rowidIsValid = 0; |
| 70954 | | - u.bp.pC->cacheStatus = CACHE_STALE; |
| 70955 | | - if( pOp->p2>0 && u.bp.res ){ |
| 70494 | + pC = p->apCsr[pOp->p1]; |
| 70495 | + assert( pC!=0 ); |
| 70496 | + pCrsr = pC->pCursor; |
| 70497 | + res = 0; |
| 70498 | + assert( pCrsr!=0 ); |
| 70499 | + rc = sqlite3BtreeLast(pCrsr, &res); |
| 70500 | + pC->nullRow = (u8)res; |
| 70501 | + pC->deferredMoveto = 0; |
| 70502 | + pC->rowidIsValid = 0; |
| 70503 | + pC->cacheStatus = CACHE_STALE; |
| 70504 | + if( pOp->p2>0 && res ){ |
| 70956 | 70505 | pc = pOp->p2 - 1; |
| 70957 | 70506 | } |
| 70958 | 70507 | break; |
| 70959 | 70508 | } |
| 70960 | 70509 | |
| | @@ -70987,35 +70536,32 @@ |
| 70987 | 70536 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
| 70988 | 70537 | ** If P2 is 0 or if the table or index is not empty, fall through |
| 70989 | 70538 | ** to the following instruction. |
| 70990 | 70539 | */ |
| 70991 | 70540 | case OP_Rewind: { /* jump */ |
| 70992 | | -#if 0 /* local variables moved into u.bq */ |
| 70993 | 70541 | VdbeCursor *pC; |
| 70994 | 70542 | BtCursor *pCrsr; |
| 70995 | 70543 | int res; |
| 70996 | | -#endif /* local variables moved into u.bq */ |
| 70997 | 70544 | |
| 70998 | 70545 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70999 | | - u.bq.pC = p->apCsr[pOp->p1]; |
| 71000 | | - assert( u.bq.pC!=0 ); |
| 71001 | | - assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterSort) ); |
| 71002 | | - u.bq.res = 1; |
| 71003 | | - if( isSorter(u.bq.pC) ){ |
| 71004 | | - rc = sqlite3VdbeSorterRewind(db, u.bq.pC, &u.bq.res); |
| 70546 | + pC = p->apCsr[pOp->p1]; |
| 70547 | + assert( pC!=0 ); |
| 70548 | + assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); |
| 70549 | + res = 1; |
| 70550 | + if( isSorter(pC) ){ |
| 70551 | + rc = sqlite3VdbeSorterRewind(db, pC, &res); |
| 71005 | 70552 | }else{ |
| 71006 | | - u.bq.pCrsr = u.bq.pC->pCursor; |
| 71007 | | - assert( u.bq.pCrsr ); |
| 71008 | | - rc = sqlite3BtreeFirst(u.bq.pCrsr, &u.bq.res); |
| 71009 | | - u.bq.pC->atFirst = u.bq.res==0 ?1:0; |
| 71010 | | - u.bq.pC->deferredMoveto = 0; |
| 71011 | | - u.bq.pC->cacheStatus = CACHE_STALE; |
| 71012 | | - u.bq.pC->rowidIsValid = 0; |
| 71013 | | - } |
| 71014 | | - u.bq.pC->nullRow = (u8)u.bq.res; |
| 70553 | + pCrsr = pC->pCursor; |
| 70554 | + assert( pCrsr ); |
| 70555 | + rc = sqlite3BtreeFirst(pCrsr, &res); |
| 70556 | + pC->deferredMoveto = 0; |
| 70557 | + pC->cacheStatus = CACHE_STALE; |
| 70558 | + pC->rowidIsValid = 0; |
| 70559 | + } |
| 70560 | + pC->nullRow = (u8)res; |
| 71015 | 70561 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 71016 | | - if( u.bq.res ){ |
| 70562 | + if( res ){ |
| 71017 | 70563 | pc = pOp->p2 - 1; |
| 71018 | 70564 | } |
| 71019 | 70565 | break; |
| 71020 | 70566 | } |
| 71021 | 70567 | |
| | @@ -71024,71 +70570,85 @@ |
| 71024 | 70570 | ** Advance cursor P1 so that it points to the next key/data pair in its |
| 71025 | 70571 | ** table or index. If there are no more key/value pairs then fall through |
| 71026 | 70572 | ** to the following instruction. But if the cursor advance was successful, |
| 71027 | 70573 | ** jump immediately to P2. |
| 71028 | 70574 | ** |
| 71029 | | -** The P1 cursor must be for a real table, not a pseudo-table. |
| 70575 | +** The P1 cursor must be for a real table, not a pseudo-table. P1 must have |
| 70576 | +** been opened prior to this opcode or the program will segfault. |
| 71030 | 70577 | ** |
| 71031 | 70578 | ** P4 is always of type P4_ADVANCE. The function pointer points to |
| 71032 | 70579 | ** sqlite3BtreeNext(). |
| 71033 | 70580 | ** |
| 71034 | 70581 | ** If P5 is positive and the jump is taken, then event counter |
| 71035 | 70582 | ** number P5-1 in the prepared statement is incremented. |
| 71036 | 70583 | ** |
| 71037 | | -** See also: Prev |
| 70584 | +** See also: Prev, NextIfOpen |
| 70585 | +*/ |
| 70586 | +/* Opcode: NextIfOpen P1 P2 * * P5 |
| 70587 | +** |
| 70588 | +** This opcode works just like OP_Next except that if cursor P1 is not |
| 70589 | +** open it behaves a no-op. |
| 71038 | 70590 | */ |
| 71039 | 70591 | /* Opcode: Prev P1 P2 * * P5 |
| 71040 | 70592 | ** |
| 71041 | 70593 | ** Back up cursor P1 so that it points to the previous key/data pair in its |
| 71042 | 70594 | ** table or index. If there is no previous key/value pairs then fall through |
| 71043 | 70595 | ** to the following instruction. But if the cursor backup was successful, |
| 71044 | 70596 | ** jump immediately to P2. |
| 71045 | 70597 | ** |
| 71046 | | -** The P1 cursor must be for a real table, not a pseudo-table. |
| 70598 | +** The P1 cursor must be for a real table, not a pseudo-table. If P1 is |
| 70599 | +** not open then the behavior is undefined. |
| 71047 | 70600 | ** |
| 71048 | 70601 | ** P4 is always of type P4_ADVANCE. The function pointer points to |
| 71049 | 70602 | ** sqlite3BtreePrevious(). |
| 71050 | 70603 | ** |
| 71051 | 70604 | ** If P5 is positive and the jump is taken, then event counter |
| 71052 | 70605 | ** number P5-1 in the prepared statement is incremented. |
| 71053 | 70606 | */ |
| 71054 | | -case OP_SorterNext: /* jump */ |
| 70607 | +/* Opcode: PrevIfOpen P1 P2 * * P5 |
| 70608 | +** |
| 70609 | +** This opcode works just like OP_Prev except that if cursor P1 is not |
| 70610 | +** open it behaves a no-op. |
| 70611 | +*/ |
| 70612 | +case OP_SorterNext: { /* jump */ |
| 70613 | + VdbeCursor *pC; |
| 70614 | + int res; |
| 70615 | + |
| 70616 | + pC = p->apCsr[pOp->p1]; |
| 70617 | + assert( isSorter(pC) ); |
| 70618 | + rc = sqlite3VdbeSorterNext(db, pC, &res); |
| 70619 | + goto next_tail; |
| 70620 | +case OP_PrevIfOpen: /* jump */ |
| 70621 | +case OP_NextIfOpen: /* jump */ |
| 70622 | + if( p->apCsr[pOp->p1]==0 ) break; |
| 70623 | + /* Fall through */ |
| 71055 | 70624 | case OP_Prev: /* jump */ |
| 71056 | | -case OP_Next: { /* jump */ |
| 71057 | | -#if 0 /* local variables moved into u.br */ |
| 71058 | | - VdbeCursor *pC; |
| 71059 | | - int res; |
| 71060 | | -#endif /* local variables moved into u.br */ |
| 71061 | | - |
| 70625 | +case OP_Next: /* jump */ |
| 71062 | 70626 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71063 | 70627 | assert( pOp->p5<ArraySize(p->aCounter) ); |
| 71064 | | - u.br.pC = p->apCsr[pOp->p1]; |
| 71065 | | - if( u.br.pC==0 ){ |
| 71066 | | - break; /* See ticket #2273 */ |
| 71067 | | - } |
| 71068 | | - assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) ); |
| 71069 | | - if( isSorter(u.br.pC) ){ |
| 71070 | | - assert( pOp->opcode==OP_SorterNext ); |
| 71071 | | - rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res); |
| 71072 | | - }else{ |
| 71073 | | - /* u.br.res = 1; // Always initialized by the xAdvance() call */ |
| 71074 | | - assert( u.br.pC->deferredMoveto==0 ); |
| 71075 | | - assert( u.br.pC->pCursor ); |
| 71076 | | - assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 71077 | | - assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 71078 | | - rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res); |
| 71079 | | - } |
| 71080 | | - u.br.pC->nullRow = (u8)u.br.res; |
| 71081 | | - u.br.pC->cacheStatus = CACHE_STALE; |
| 71082 | | - if( u.br.res==0 ){ |
| 70628 | + pC = p->apCsr[pOp->p1]; |
| 70629 | + assert( pC!=0 ); |
| 70630 | + assert( pC->deferredMoveto==0 ); |
| 70631 | + assert( pC->pCursor ); |
| 70632 | + assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 70633 | + assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); |
| 70634 | + assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); |
| 70635 | + assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); |
| 70636 | + rc = pOp->p4.xAdvance(pC->pCursor, &res); |
| 70637 | +next_tail: |
| 70638 | + pC->cacheStatus = CACHE_STALE; |
| 70639 | + if( res==0 ){ |
| 70640 | + pC->nullRow = 0; |
| 71083 | 70641 | pc = pOp->p2 - 1; |
| 71084 | 70642 | p->aCounter[pOp->p5]++; |
| 71085 | 70643 | #ifdef SQLITE_TEST |
| 71086 | 70644 | sqlite3_search_count++; |
| 71087 | 70645 | #endif |
| 70646 | + }else{ |
| 70647 | + pC->nullRow = 1; |
| 71088 | 70648 | } |
| 71089 | | - u.br.pC->rowidIsValid = 0; |
| 70649 | + pC->rowidIsValid = 0; |
| 71090 | 70650 | goto check_for_interrupt; |
| 71091 | 70651 | } |
| 71092 | 70652 | |
| 71093 | 70653 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
| 71094 | 70654 | ** Synopsis: key=r[P2] |
| | @@ -71103,39 +70663,37 @@ |
| 71103 | 70663 | ** This instruction only works for indices. The equivalent instruction |
| 71104 | 70664 | ** for tables is OP_Insert. |
| 71105 | 70665 | */ |
| 71106 | 70666 | case OP_SorterInsert: /* in2 */ |
| 71107 | 70667 | case OP_IdxInsert: { /* in2 */ |
| 71108 | | -#if 0 /* local variables moved into u.bs */ |
| 71109 | 70668 | VdbeCursor *pC; |
| 71110 | 70669 | BtCursor *pCrsr; |
| 71111 | 70670 | int nKey; |
| 71112 | 70671 | const char *zKey; |
| 71113 | | -#endif /* local variables moved into u.bs */ |
| 71114 | 70672 | |
| 71115 | 70673 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71116 | | - u.bs.pC = p->apCsr[pOp->p1]; |
| 71117 | | - assert( u.bs.pC!=0 ); |
| 71118 | | - assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); |
| 70674 | + pC = p->apCsr[pOp->p1]; |
| 70675 | + assert( pC!=0 ); |
| 70676 | + assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); |
| 71119 | 70677 | pIn2 = &aMem[pOp->p2]; |
| 71120 | 70678 | assert( pIn2->flags & MEM_Blob ); |
| 71121 | | - u.bs.pCrsr = u.bs.pC->pCursor; |
| 70679 | + pCrsr = pC->pCursor; |
| 71122 | 70680 | if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; |
| 71123 | | - assert( u.bs.pCrsr!=0 ); |
| 71124 | | - assert( u.bs.pC->isTable==0 ); |
| 70681 | + assert( pCrsr!=0 ); |
| 70682 | + assert( pC->isTable==0 ); |
| 71125 | 70683 | rc = ExpandBlob(pIn2); |
| 71126 | 70684 | if( rc==SQLITE_OK ){ |
| 71127 | | - if( isSorter(u.bs.pC) ){ |
| 71128 | | - rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2); |
| 70685 | + if( isSorter(pC) ){ |
| 70686 | + rc = sqlite3VdbeSorterWrite(db, pC, pIn2); |
| 71129 | 70687 | }else{ |
| 71130 | | - u.bs.nKey = pIn2->n; |
| 71131 | | - u.bs.zKey = pIn2->z; |
| 71132 | | - rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3, |
| 71133 | | - ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0) |
| 70688 | + nKey = pIn2->n; |
| 70689 | + zKey = pIn2->z; |
| 70690 | + rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3, |
| 70691 | + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) |
| 71134 | 70692 | ); |
| 71135 | | - assert( u.bs.pC->deferredMoveto==0 ); |
| 71136 | | - u.bs.pC->cacheStatus = CACHE_STALE; |
| 70693 | + assert( pC->deferredMoveto==0 ); |
| 70694 | + pC->cacheStatus = CACHE_STALE; |
| 71137 | 70695 | } |
| 71138 | 70696 | } |
| 71139 | 70697 | break; |
| 71140 | 70698 | } |
| 71141 | 70699 | |
| | @@ -71145,38 +70703,36 @@ |
| 71145 | 70703 | ** The content of P3 registers starting at register P2 form |
| 71146 | 70704 | ** an unpacked index key. This opcode removes that entry from the |
| 71147 | 70705 | ** index opened by cursor P1. |
| 71148 | 70706 | */ |
| 71149 | 70707 | case OP_IdxDelete: { |
| 71150 | | -#if 0 /* local variables moved into u.bt */ |
| 71151 | 70708 | VdbeCursor *pC; |
| 71152 | 70709 | BtCursor *pCrsr; |
| 71153 | 70710 | int res; |
| 71154 | 70711 | UnpackedRecord r; |
| 71155 | | -#endif /* local variables moved into u.bt */ |
| 71156 | 70712 | |
| 71157 | 70713 | assert( pOp->p3>0 ); |
| 71158 | 70714 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); |
| 71159 | 70715 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71160 | | - u.bt.pC = p->apCsr[pOp->p1]; |
| 71161 | | - assert( u.bt.pC!=0 ); |
| 71162 | | - u.bt.pCrsr = u.bt.pC->pCursor; |
| 71163 | | - assert( u.bt.pCrsr!=0 ); |
| 70716 | + pC = p->apCsr[pOp->p1]; |
| 70717 | + assert( pC!=0 ); |
| 70718 | + pCrsr = pC->pCursor; |
| 70719 | + assert( pCrsr!=0 ); |
| 71164 | 70720 | assert( pOp->p5==0 ); |
| 71165 | | - u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; |
| 71166 | | - u.bt.r.nField = (u16)pOp->p3; |
| 71167 | | - u.bt.r.flags = UNPACKED_PREFIX_MATCH; |
| 71168 | | - u.bt.r.aMem = &aMem[pOp->p2]; |
| 70721 | + r.pKeyInfo = pC->pKeyInfo; |
| 70722 | + r.nField = (u16)pOp->p3; |
| 70723 | + r.flags = UNPACKED_PREFIX_MATCH; |
| 70724 | + r.aMem = &aMem[pOp->p2]; |
| 71169 | 70725 | #ifdef SQLITE_DEBUG |
| 71170 | | - { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); } |
| 70726 | + { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } |
| 71171 | 70727 | #endif |
| 71172 | | - rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res); |
| 71173 | | - if( rc==SQLITE_OK && u.bt.res==0 ){ |
| 71174 | | - rc = sqlite3BtreeDelete(u.bt.pCrsr); |
| 70728 | + rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); |
| 70729 | + if( rc==SQLITE_OK && res==0 ){ |
| 70730 | + rc = sqlite3BtreeDelete(pCrsr); |
| 71175 | 70731 | } |
| 71176 | | - assert( u.bt.pC->deferredMoveto==0 ); |
| 71177 | | - u.bt.pC->cacheStatus = CACHE_STALE; |
| 70732 | + assert( pC->deferredMoveto==0 ); |
| 70733 | + pC->cacheStatus = CACHE_STALE; |
| 71178 | 70734 | break; |
| 71179 | 70735 | } |
| 71180 | 70736 | |
| 71181 | 70737 | /* Opcode: IdxRowid P1 P2 * * * |
| 71182 | 70738 | ** Synopsis: r[P2]=rowid |
| | @@ -71186,32 +70742,31 @@ |
| 71186 | 70742 | ** the rowid of the table entry to which this index entry points. |
| 71187 | 70743 | ** |
| 71188 | 70744 | ** See also: Rowid, MakeRecord. |
| 71189 | 70745 | */ |
| 71190 | 70746 | case OP_IdxRowid: { /* out2-prerelease */ |
| 71191 | | -#if 0 /* local variables moved into u.bu */ |
| 71192 | 70747 | BtCursor *pCrsr; |
| 71193 | 70748 | VdbeCursor *pC; |
| 71194 | 70749 | i64 rowid; |
| 71195 | | -#endif /* local variables moved into u.bu */ |
| 71196 | 70750 | |
| 71197 | 70751 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71198 | | - u.bu.pC = p->apCsr[pOp->p1]; |
| 71199 | | - assert( u.bu.pC!=0 ); |
| 71200 | | - u.bu.pCrsr = u.bu.pC->pCursor; |
| 71201 | | - assert( u.bu.pCrsr!=0 ); |
| 70752 | + pC = p->apCsr[pOp->p1]; |
| 70753 | + assert( pC!=0 ); |
| 70754 | + pCrsr = pC->pCursor; |
| 70755 | + assert( pCrsr!=0 ); |
| 71202 | 70756 | pOut->flags = MEM_Null; |
| 71203 | | - rc = sqlite3VdbeCursorMoveto(u.bu.pC); |
| 70757 | + rc = sqlite3VdbeCursorMoveto(pC); |
| 71204 | 70758 | if( NEVER(rc) ) goto abort_due_to_error; |
| 71205 | | - assert( u.bu.pC->deferredMoveto==0 ); |
| 71206 | | - assert( u.bu.pC->isTable==0 ); |
| 71207 | | - if( !u.bu.pC->nullRow ){ |
| 71208 | | - rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid); |
| 70759 | + assert( pC->deferredMoveto==0 ); |
| 70760 | + assert( pC->isTable==0 ); |
| 70761 | + if( !pC->nullRow ){ |
| 70762 | + rowid = 0; /* Not needed. Only used to silence a warning. */ |
| 70763 | + rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); |
| 71209 | 70764 | if( rc!=SQLITE_OK ){ |
| 71210 | 70765 | goto abort_due_to_error; |
| 71211 | 70766 | } |
| 71212 | | - pOut->u.i = u.bu.rowid; |
| 70767 | + pOut->u.i = rowid; |
| 71213 | 70768 | pOut->flags = MEM_Int; |
| 71214 | 70769 | } |
| 71215 | 70770 | break; |
| 71216 | 70771 | } |
| 71217 | 70772 | |
| | @@ -71243,43 +70798,42 @@ |
| 71243 | 70798 | ** If P5 is non-zero then the key value is increased by an epsilon prior |
| 71244 | 70799 | ** to the comparison. This makes the opcode work like IdxLE. |
| 71245 | 70800 | */ |
| 71246 | 70801 | case OP_IdxLT: /* jump */ |
| 71247 | 70802 | case OP_IdxGE: { /* jump */ |
| 71248 | | -#if 0 /* local variables moved into u.bv */ |
| 71249 | 70803 | VdbeCursor *pC; |
| 71250 | 70804 | int res; |
| 71251 | 70805 | UnpackedRecord r; |
| 71252 | | -#endif /* local variables moved into u.bv */ |
| 71253 | 70806 | |
| 71254 | 70807 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 71255 | | - u.bv.pC = p->apCsr[pOp->p1]; |
| 71256 | | - assert( u.bv.pC!=0 ); |
| 71257 | | - assert( u.bv.pC->isOrdered ); |
| 71258 | | - assert( u.bv.pC->pCursor!=0); |
| 71259 | | - assert( u.bv.pC->deferredMoveto==0 ); |
| 70808 | + pC = p->apCsr[pOp->p1]; |
| 70809 | + assert( pC!=0 ); |
| 70810 | + assert( pC->isOrdered ); |
| 70811 | + assert( pC->pCursor!=0); |
| 70812 | + assert( pC->deferredMoveto==0 ); |
| 71260 | 70813 | assert( pOp->p5==0 || pOp->p5==1 ); |
| 71261 | 70814 | assert( pOp->p4type==P4_INT32 ); |
| 71262 | | - u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo; |
| 71263 | | - u.bv.r.nField = (u16)pOp->p4.i; |
| 70815 | + r.pKeyInfo = pC->pKeyInfo; |
| 70816 | + r.nField = (u16)pOp->p4.i; |
| 71264 | 70817 | if( pOp->p5 ){ |
| 71265 | | - u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; |
| 70818 | + r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; |
| 71266 | 70819 | }else{ |
| 71267 | | - u.bv.r.flags = UNPACKED_PREFIX_MATCH; |
| 70820 | + r.flags = UNPACKED_PREFIX_MATCH; |
| 71268 | 70821 | } |
| 71269 | | - u.bv.r.aMem = &aMem[pOp->p3]; |
| 70822 | + r.aMem = &aMem[pOp->p3]; |
| 71270 | 70823 | #ifdef SQLITE_DEBUG |
| 71271 | | - { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); } |
| 70824 | + { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } |
| 71272 | 70825 | #endif |
| 71273 | | - rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res); |
| 70826 | + res = 0; /* Not needed. Only used to silence a warning. */ |
| 70827 | + rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res); |
| 71274 | 70828 | if( pOp->opcode==OP_IdxLT ){ |
| 71275 | | - u.bv.res = -u.bv.res; |
| 70829 | + res = -res; |
| 71276 | 70830 | }else{ |
| 71277 | 70831 | assert( pOp->opcode==OP_IdxGE ); |
| 71278 | | - u.bv.res++; |
| 70832 | + res++; |
| 71279 | 70833 | } |
| 71280 | | - if( u.bv.res>0 ){ |
| 70834 | + if( res>0 ){ |
| 71281 | 70835 | pc = pOp->p2 - 1 ; |
| 71282 | 70836 | } |
| 71283 | 70837 | break; |
| 71284 | 70838 | } |
| 71285 | 70839 | |
| | @@ -71302,47 +70856,46 @@ |
| 71302 | 70856 | ** If AUTOVACUUM is disabled then a zero is stored in register P2. |
| 71303 | 70857 | ** |
| 71304 | 70858 | ** See also: Clear |
| 71305 | 70859 | */ |
| 71306 | 70860 | case OP_Destroy: { /* out2-prerelease */ |
| 71307 | | -#if 0 /* local variables moved into u.bw */ |
| 71308 | 70861 | int iMoved; |
| 71309 | 70862 | int iCnt; |
| 71310 | 70863 | Vdbe *pVdbe; |
| 71311 | 70864 | int iDb; |
| 71312 | | -#endif /* local variables moved into u.bw */ |
| 71313 | 70865 | |
| 71314 | 70866 | assert( p->readOnly==0 ); |
| 71315 | 70867 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 71316 | | - u.bw.iCnt = 0; |
| 71317 | | - for(u.bw.pVdbe=db->pVdbe; u.bw.pVdbe; u.bw.pVdbe = u.bw.pVdbe->pNext){ |
| 71318 | | - if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->bIsReader |
| 71319 | | - && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0 |
| 70868 | + iCnt = 0; |
| 70869 | + for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){ |
| 70870 | + if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->bIsReader |
| 70871 | + && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 |
| 71320 | 70872 | ){ |
| 71321 | | - u.bw.iCnt++; |
| 70873 | + iCnt++; |
| 71322 | 70874 | } |
| 71323 | 70875 | } |
| 71324 | 70876 | #else |
| 71325 | | - u.bw.iCnt = db->nVdbeRead; |
| 70877 | + iCnt = db->nVdbeRead; |
| 71326 | 70878 | #endif |
| 71327 | 70879 | pOut->flags = MEM_Null; |
| 71328 | | - if( u.bw.iCnt>1 ){ |
| 70880 | + if( iCnt>1 ){ |
| 71329 | 70881 | rc = SQLITE_LOCKED; |
| 71330 | 70882 | p->errorAction = OE_Abort; |
| 71331 | 70883 | }else{ |
| 71332 | | - u.bw.iDb = pOp->p3; |
| 71333 | | - assert( u.bw.iCnt==1 ); |
| 71334 | | - assert( (p->btreeMask & (((yDbMask)1)<<u.bw.iDb))!=0 ); |
| 71335 | | - rc = sqlite3BtreeDropTable(db->aDb[u.bw.iDb].pBt, pOp->p1, &u.bw.iMoved); |
| 70884 | + iDb = pOp->p3; |
| 70885 | + assert( iCnt==1 ); |
| 70886 | + assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); |
| 70887 | + iMoved = 0; /* Not needed. Only to silence a warning. */ |
| 70888 | + rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); |
| 71336 | 70889 | pOut->flags = MEM_Int; |
| 71337 | | - pOut->u.i = u.bw.iMoved; |
| 70890 | + pOut->u.i = iMoved; |
| 71338 | 70891 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 71339 | | - if( rc==SQLITE_OK && u.bw.iMoved!=0 ){ |
| 71340 | | - sqlite3RootPageMoved(db, u.bw.iDb, u.bw.iMoved, pOp->p1); |
| 70892 | + if( rc==SQLITE_OK && iMoved!=0 ){ |
| 70893 | + sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1); |
| 71341 | 70894 | /* All OP_Destroy operations occur on the same btree */ |
| 71342 | | - assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bw.iDb+1 ); |
| 71343 | | - resetSchemaOnFault = u.bw.iDb+1; |
| 70895 | + assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 ); |
| 70896 | + resetSchemaOnFault = iDb+1; |
| 71344 | 70897 | } |
| 71345 | 70898 | #endif |
| 71346 | 70899 | } |
| 71347 | 70900 | break; |
| 71348 | 70901 | } |
| | @@ -71364,27 +70917,25 @@ |
| 71364 | 70917 | ** also incremented by the number of rows in the table being cleared. |
| 71365 | 70918 | ** |
| 71366 | 70919 | ** See also: Destroy |
| 71367 | 70920 | */ |
| 71368 | 70921 | case OP_Clear: { |
| 71369 | | -#if 0 /* local variables moved into u.bx */ |
| 71370 | 70922 | int nChange; |
| 71371 | | -#endif /* local variables moved into u.bx */ |
| 71372 | | - |
| 71373 | | - u.bx.nChange = 0; |
| 70923 | + |
| 70924 | + nChange = 0; |
| 71374 | 70925 | assert( p->readOnly==0 ); |
| 71375 | 70926 | assert( pOp->p1!=1 ); |
| 71376 | 70927 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 71377 | 70928 | rc = sqlite3BtreeClearTable( |
| 71378 | | - db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0) |
| 70929 | + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) |
| 71379 | 70930 | ); |
| 71380 | 70931 | if( pOp->p3 ){ |
| 71381 | | - p->nChange += u.bx.nChange; |
| 70932 | + p->nChange += nChange; |
| 71382 | 70933 | if( pOp->p3>0 ){ |
| 71383 | 70934 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 71384 | 70935 | memAboutToChange(p, &aMem[pOp->p3]); |
| 71385 | | - aMem[pOp->p3].u.i += u.bx.nChange; |
| 70936 | + aMem[pOp->p3].u.i += nChange; |
| 71386 | 70937 | } |
| 71387 | 70938 | } |
| 71388 | 70939 | break; |
| 71389 | 70940 | } |
| 71390 | 70941 | |
| | @@ -71412,30 +70963,28 @@ |
| 71412 | 70963 | ** |
| 71413 | 70964 | ** See documentation on OP_CreateTable for additional information. |
| 71414 | 70965 | */ |
| 71415 | 70966 | case OP_CreateIndex: /* out2-prerelease */ |
| 71416 | 70967 | case OP_CreateTable: { /* out2-prerelease */ |
| 71417 | | -#if 0 /* local variables moved into u.by */ |
| 71418 | 70968 | int pgno; |
| 71419 | 70969 | int flags; |
| 71420 | 70970 | Db *pDb; |
| 71421 | | -#endif /* local variables moved into u.by */ |
| 71422 | 70971 | |
| 71423 | | - u.by.pgno = 0; |
| 70972 | + pgno = 0; |
| 71424 | 70973 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 71425 | 70974 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 71426 | 70975 | assert( p->readOnly==0 ); |
| 71427 | | - u.by.pDb = &db->aDb[pOp->p1]; |
| 71428 | | - assert( u.by.pDb->pBt!=0 ); |
| 70976 | + pDb = &db->aDb[pOp->p1]; |
| 70977 | + assert( pDb->pBt!=0 ); |
| 71429 | 70978 | if( pOp->opcode==OP_CreateTable ){ |
| 71430 | | - /* u.by.flags = BTREE_INTKEY; */ |
| 71431 | | - u.by.flags = BTREE_INTKEY; |
| 70979 | + /* flags = BTREE_INTKEY; */ |
| 70980 | + flags = BTREE_INTKEY; |
| 71432 | 70981 | }else{ |
| 71433 | | - u.by.flags = BTREE_BLOBKEY; |
| 70982 | + flags = BTREE_BLOBKEY; |
| 71434 | 70983 | } |
| 71435 | | - rc = sqlite3BtreeCreateTable(u.by.pDb->pBt, &u.by.pgno, u.by.flags); |
| 71436 | | - pOut->u.i = u.by.pgno; |
| 70984 | + rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); |
| 70985 | + pOut->u.i = pgno; |
| 71437 | 70986 | break; |
| 71438 | 70987 | } |
| 71439 | 70988 | |
| 71440 | 70989 | /* Opcode: ParseSchema P1 * * P4 * |
| 71441 | 70990 | ** |
| | @@ -71444,56 +70993,54 @@ |
| 71444 | 70993 | ** |
| 71445 | 70994 | ** This opcode invokes the parser to create a new virtual machine, |
| 71446 | 70995 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
| 71447 | 70996 | */ |
| 71448 | 70997 | case OP_ParseSchema: { |
| 71449 | | -#if 0 /* local variables moved into u.bz */ |
| 71450 | 70998 | int iDb; |
| 71451 | 70999 | const char *zMaster; |
| 71452 | 71000 | char *zSql; |
| 71453 | 71001 | InitData initData; |
| 71454 | | -#endif /* local variables moved into u.bz */ |
| 71455 | 71002 | |
| 71456 | 71003 | /* Any prepared statement that invokes this opcode will hold mutexes |
| 71457 | | - ** on every btree. This is a prerequisite for invoking |
| 71004 | + ** on every btree. This is a prerequisite for invoking |
| 71458 | 71005 | ** sqlite3InitCallback(). |
| 71459 | 71006 | */ |
| 71460 | 71007 | #ifdef SQLITE_DEBUG |
| 71461 | | - for(u.bz.iDb=0; u.bz.iDb<db->nDb; u.bz.iDb++){ |
| 71462 | | - assert( u.bz.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bz.iDb].pBt) ); |
| 71008 | + for(iDb=0; iDb<db->nDb; iDb++){ |
| 71009 | + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); |
| 71463 | 71010 | } |
| 71464 | 71011 | #endif |
| 71465 | 71012 | |
| 71466 | | - u.bz.iDb = pOp->p1; |
| 71467 | | - assert( u.bz.iDb>=0 && u.bz.iDb<db->nDb ); |
| 71468 | | - assert( DbHasProperty(db, u.bz.iDb, DB_SchemaLoaded) ); |
| 71013 | + iDb = pOp->p1; |
| 71014 | + assert( iDb>=0 && iDb<db->nDb ); |
| 71015 | + assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); |
| 71469 | 71016 | /* Used to be a conditional */ { |
| 71470 | | - u.bz.zMaster = SCHEMA_TABLE(u.bz.iDb); |
| 71471 | | - u.bz.initData.db = db; |
| 71472 | | - u.bz.initData.iDb = pOp->p1; |
| 71473 | | - u.bz.initData.pzErrMsg = &p->zErrMsg; |
| 71474 | | - u.bz.zSql = sqlite3MPrintf(db, |
| 71017 | + zMaster = SCHEMA_TABLE(iDb); |
| 71018 | + initData.db = db; |
| 71019 | + initData.iDb = pOp->p1; |
| 71020 | + initData.pzErrMsg = &p->zErrMsg; |
| 71021 | + zSql = sqlite3MPrintf(db, |
| 71475 | 71022 | "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", |
| 71476 | | - db->aDb[u.bz.iDb].zName, u.bz.zMaster, pOp->p4.z); |
| 71477 | | - if( u.bz.zSql==0 ){ |
| 71023 | + db->aDb[iDb].zName, zMaster, pOp->p4.z); |
| 71024 | + if( zSql==0 ){ |
| 71478 | 71025 | rc = SQLITE_NOMEM; |
| 71479 | 71026 | }else{ |
| 71480 | 71027 | assert( db->init.busy==0 ); |
| 71481 | 71028 | db->init.busy = 1; |
| 71482 | | - u.bz.initData.rc = SQLITE_OK; |
| 71029 | + initData.rc = SQLITE_OK; |
| 71483 | 71030 | assert( !db->mallocFailed ); |
| 71484 | | - rc = sqlite3_exec(db, u.bz.zSql, sqlite3InitCallback, &u.bz.initData, 0); |
| 71485 | | - if( rc==SQLITE_OK ) rc = u.bz.initData.rc; |
| 71486 | | - sqlite3DbFree(db, u.bz.zSql); |
| 71031 | + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); |
| 71032 | + if( rc==SQLITE_OK ) rc = initData.rc; |
| 71033 | + sqlite3DbFree(db, zSql); |
| 71487 | 71034 | db->init.busy = 0; |
| 71488 | 71035 | } |
| 71489 | 71036 | } |
| 71490 | 71037 | if( rc ) sqlite3ResetAllSchemasOfConnection(db); |
| 71491 | 71038 | if( rc==SQLITE_NOMEM ){ |
| 71492 | 71039 | goto no_mem; |
| 71493 | 71040 | } |
| 71494 | | - break; |
| 71041 | + break; |
| 71495 | 71042 | } |
| 71496 | 71043 | |
| 71497 | 71044 | #if !defined(SQLITE_OMIT_ANALYZE) |
| 71498 | 71045 | /* Opcode: LoadAnalysis P1 * * * * |
| 71499 | 71046 | ** |
| | @@ -71565,46 +71112,44 @@ |
| 71565 | 71112 | ** file, not the main database file. |
| 71566 | 71113 | ** |
| 71567 | 71114 | ** This opcode is used to implement the integrity_check pragma. |
| 71568 | 71115 | */ |
| 71569 | 71116 | case OP_IntegrityCk: { |
| 71570 | | -#if 0 /* local variables moved into u.ca */ |
| 71571 | 71117 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
| 71572 | 71118 | int *aRoot; /* Array of rootpage numbers for tables to be checked */ |
| 71573 | 71119 | int j; /* Loop counter */ |
| 71574 | 71120 | int nErr; /* Number of errors reported */ |
| 71575 | 71121 | char *z; /* Text of the error report */ |
| 71576 | 71122 | Mem *pnErr; /* Register keeping track of errors remaining */ |
| 71577 | | -#endif /* local variables moved into u.ca */ |
| 71578 | 71123 | |
| 71579 | 71124 | assert( p->bIsReader ); |
| 71580 | | - u.ca.nRoot = pOp->p2; |
| 71581 | | - assert( u.ca.nRoot>0 ); |
| 71582 | | - u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) ); |
| 71583 | | - if( u.ca.aRoot==0 ) goto no_mem; |
| 71125 | + nRoot = pOp->p2; |
| 71126 | + assert( nRoot>0 ); |
| 71127 | + aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) ); |
| 71128 | + if( aRoot==0 ) goto no_mem; |
| 71584 | 71129 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 71585 | | - u.ca.pnErr = &aMem[pOp->p3]; |
| 71586 | | - assert( (u.ca.pnErr->flags & MEM_Int)!=0 ); |
| 71587 | | - assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 71130 | + pnErr = &aMem[pOp->p3]; |
| 71131 | + assert( (pnErr->flags & MEM_Int)!=0 ); |
| 71132 | + assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 71588 | 71133 | pIn1 = &aMem[pOp->p1]; |
| 71589 | | - for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){ |
| 71590 | | - u.ca.aRoot[u.ca.j] = (int)sqlite3VdbeIntValue(&pIn1[u.ca.j]); |
| 71134 | + for(j=0; j<nRoot; j++){ |
| 71135 | + aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]); |
| 71591 | 71136 | } |
| 71592 | | - u.ca.aRoot[u.ca.j] = 0; |
| 71137 | + aRoot[j] = 0; |
| 71593 | 71138 | assert( pOp->p5<db->nDb ); |
| 71594 | 71139 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); |
| 71595 | | - u.ca.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.ca.aRoot, u.ca.nRoot, |
| 71596 | | - (int)u.ca.pnErr->u.i, &u.ca.nErr); |
| 71597 | | - sqlite3DbFree(db, u.ca.aRoot); |
| 71598 | | - u.ca.pnErr->u.i -= u.ca.nErr; |
| 71140 | + z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, |
| 71141 | + (int)pnErr->u.i, &nErr); |
| 71142 | + sqlite3DbFree(db, aRoot); |
| 71143 | + pnErr->u.i -= nErr; |
| 71599 | 71144 | sqlite3VdbeMemSetNull(pIn1); |
| 71600 | | - if( u.ca.nErr==0 ){ |
| 71601 | | - assert( u.ca.z==0 ); |
| 71602 | | - }else if( u.ca.z==0 ){ |
| 71145 | + if( nErr==0 ){ |
| 71146 | + assert( z==0 ); |
| 71147 | + }else if( z==0 ){ |
| 71603 | 71148 | goto no_mem; |
| 71604 | 71149 | }else{ |
| 71605 | | - sqlite3VdbeMemSetStr(pIn1, u.ca.z, -1, SQLITE_UTF8, sqlite3_free); |
| 71150 | + sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); |
| 71606 | 71151 | } |
| 71607 | 71152 | UPDATE_MAX_BLOBSIZE(pIn1); |
| 71608 | 71153 | sqlite3VdbeChangeEncoding(pIn1, encoding); |
| 71609 | 71154 | break; |
| 71610 | 71155 | } |
| | @@ -71636,24 +71181,22 @@ |
| 71636 | 71181 | ** Extract the smallest value from boolean index P1 and put that value into |
| 71637 | 71182 | ** register P3. Or, if boolean index P1 is initially empty, leave P3 |
| 71638 | 71183 | ** unchanged and jump to instruction P2. |
| 71639 | 71184 | */ |
| 71640 | 71185 | case OP_RowSetRead: { /* jump, in1, out3 */ |
| 71641 | | -#if 0 /* local variables moved into u.cb */ |
| 71642 | 71186 | i64 val; |
| 71643 | | -#endif /* local variables moved into u.cb */ |
| 71644 | 71187 | |
| 71645 | 71188 | pIn1 = &aMem[pOp->p1]; |
| 71646 | | - if( (pIn1->flags & MEM_RowSet)==0 |
| 71647 | | - || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0 |
| 71189 | + if( (pIn1->flags & MEM_RowSet)==0 |
| 71190 | + || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0 |
| 71648 | 71191 | ){ |
| 71649 | 71192 | /* The boolean index is empty */ |
| 71650 | 71193 | sqlite3VdbeMemSetNull(pIn1); |
| 71651 | 71194 | pc = pOp->p2 - 1; |
| 71652 | 71195 | }else{ |
| 71653 | 71196 | /* A value was pulled from the index */ |
| 71654 | | - sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val); |
| 71197 | + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); |
| 71655 | 71198 | } |
| 71656 | 71199 | goto check_for_interrupt; |
| 71657 | 71200 | } |
| 71658 | 71201 | |
| 71659 | 71202 | /* Opcode: RowSetTest P1 P2 P3 P4 |
| | @@ -71679,18 +71222,16 @@ |
| 71679 | 71222 | ** inserted, there is no need to search to see if the same value was |
| 71680 | 71223 | ** previously inserted as part of set X (only if it was previously |
| 71681 | 71224 | ** inserted as part of some other set). |
| 71682 | 71225 | */ |
| 71683 | 71226 | case OP_RowSetTest: { /* jump, in1, in3 */ |
| 71684 | | -#if 0 /* local variables moved into u.cc */ |
| 71685 | 71227 | int iSet; |
| 71686 | 71228 | int exists; |
| 71687 | | -#endif /* local variables moved into u.cc */ |
| 71688 | 71229 | |
| 71689 | 71230 | pIn1 = &aMem[pOp->p1]; |
| 71690 | 71231 | pIn3 = &aMem[pOp->p3]; |
| 71691 | | - u.cc.iSet = pOp->p4.i; |
| 71232 | + iSet = pOp->p4.i; |
| 71692 | 71233 | assert( pIn3->flags&MEM_Int ); |
| 71693 | 71234 | |
| 71694 | 71235 | /* If there is anything other than a rowset object in memory cell P1, |
| 71695 | 71236 | ** delete it now and initialize P1 with an empty rowset |
| 71696 | 71237 | */ |
| | @@ -71698,21 +71239,21 @@ |
| 71698 | 71239 | sqlite3VdbeMemSetRowSet(pIn1); |
| 71699 | 71240 | if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; |
| 71700 | 71241 | } |
| 71701 | 71242 | |
| 71702 | 71243 | assert( pOp->p4type==P4_INT32 ); |
| 71703 | | - assert( u.cc.iSet==-1 || u.cc.iSet>=0 ); |
| 71704 | | - if( u.cc.iSet ){ |
| 71705 | | - u.cc.exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 71706 | | - (u8)(u.cc.iSet>=0 ? u.cc.iSet & 0xf : 0xff), |
| 71244 | + assert( iSet==-1 || iSet>=0 ); |
| 71245 | + if( iSet ){ |
| 71246 | + exists = sqlite3RowSetTest(pIn1->u.pRowSet, |
| 71247 | + (u8)(iSet>=0 ? iSet & 0xf : 0xff), |
| 71707 | 71248 | pIn3->u.i); |
| 71708 | | - if( u.cc.exists ){ |
| 71249 | + if( exists ){ |
| 71709 | 71250 | pc = pOp->p2 - 1; |
| 71710 | 71251 | break; |
| 71711 | 71252 | } |
| 71712 | 71253 | } |
| 71713 | | - if( u.cc.iSet>=0 ){ |
| 71254 | + if( iSet>=0 ){ |
| 71714 | 71255 | sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); |
| 71715 | 71256 | } |
| 71716 | 71257 | break; |
| 71717 | 71258 | } |
| 71718 | 71259 | |
| | @@ -71731,111 +71272,109 @@ |
| 71731 | 71272 | ** memory required by the sub-vdbe at runtime. |
| 71732 | 71273 | ** |
| 71733 | 71274 | ** P4 is a pointer to the VM containing the trigger program. |
| 71734 | 71275 | */ |
| 71735 | 71276 | case OP_Program: { /* jump */ |
| 71736 | | -#if 0 /* local variables moved into u.cd */ |
| 71737 | 71277 | int nMem; /* Number of memory registers for sub-program */ |
| 71738 | 71278 | int nByte; /* Bytes of runtime space required for sub-program */ |
| 71739 | 71279 | Mem *pRt; /* Register to allocate runtime space */ |
| 71740 | 71280 | Mem *pMem; /* Used to iterate through memory cells */ |
| 71741 | 71281 | Mem *pEnd; /* Last memory cell in new array */ |
| 71742 | 71282 | VdbeFrame *pFrame; /* New vdbe frame to execute in */ |
| 71743 | 71283 | SubProgram *pProgram; /* Sub-program to execute */ |
| 71744 | 71284 | void *t; /* Token identifying trigger */ |
| 71745 | | -#endif /* local variables moved into u.cd */ |
| 71746 | 71285 | |
| 71747 | | - u.cd.pProgram = pOp->p4.pProgram; |
| 71748 | | - u.cd.pRt = &aMem[pOp->p3]; |
| 71749 | | - assert( u.cd.pProgram->nOp>0 ); |
| 71750 | | - |
| 71751 | | - /* If the p5 flag is clear, then recursive invocation of triggers is |
| 71286 | + pProgram = pOp->p4.pProgram; |
| 71287 | + pRt = &aMem[pOp->p3]; |
| 71288 | + assert( pProgram->nOp>0 ); |
| 71289 | + |
| 71290 | + /* If the p5 flag is clear, then recursive invocation of triggers is |
| 71752 | 71291 | ** disabled for backwards compatibility (p5 is set if this sub-program |
| 71753 | 71292 | ** is really a trigger, not a foreign key action, and the flag set |
| 71754 | 71293 | ** and cleared by the "PRAGMA recursive_triggers" command is clear). |
| 71755 | | - ** |
| 71756 | | - ** It is recursive invocation of triggers, at the SQL level, that is |
| 71757 | | - ** disabled. In some cases a single trigger may generate more than one |
| 71758 | | - ** SubProgram (if the trigger may be executed with more than one different |
| 71294 | + ** |
| 71295 | + ** It is recursive invocation of triggers, at the SQL level, that is |
| 71296 | + ** disabled. In some cases a single trigger may generate more than one |
| 71297 | + ** SubProgram (if the trigger may be executed with more than one different |
| 71759 | 71298 | ** ON CONFLICT algorithm). SubProgram structures associated with a |
| 71760 | | - ** single trigger all have the same value for the SubProgram.token |
| 71299 | + ** single trigger all have the same value for the SubProgram.token |
| 71761 | 71300 | ** variable. */ |
| 71762 | 71301 | if( pOp->p5 ){ |
| 71763 | | - u.cd.t = u.cd.pProgram->token; |
| 71764 | | - for(u.cd.pFrame=p->pFrame; u.cd.pFrame && u.cd.pFrame->token!=u.cd.t; u.cd.pFrame=u.cd.pFrame->pParent); |
| 71765 | | - if( u.cd.pFrame ) break; |
| 71302 | + t = pProgram->token; |
| 71303 | + for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent); |
| 71304 | + if( pFrame ) break; |
| 71766 | 71305 | } |
| 71767 | 71306 | |
| 71768 | 71307 | if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ |
| 71769 | 71308 | rc = SQLITE_ERROR; |
| 71770 | 71309 | sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); |
| 71771 | 71310 | break; |
| 71772 | 71311 | } |
| 71773 | 71312 | |
| 71774 | | - /* Register u.cd.pRt is used to store the memory required to save the state |
| 71313 | + /* Register pRt is used to store the memory required to save the state |
| 71775 | 71314 | ** of the current program, and the memory required at runtime to execute |
| 71776 | | - ** the trigger program. If this trigger has been fired before, then u.cd.pRt |
| 71315 | + ** the trigger program. If this trigger has been fired before, then pRt |
| 71777 | 71316 | ** is already allocated. Otherwise, it must be initialized. */ |
| 71778 | | - if( (u.cd.pRt->flags&MEM_Frame)==0 ){ |
| 71779 | | - /* SubProgram.nMem is set to the number of memory cells used by the |
| 71317 | + if( (pRt->flags&MEM_Frame)==0 ){ |
| 71318 | + /* SubProgram.nMem is set to the number of memory cells used by the |
| 71780 | 71319 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 71781 | 71320 | ** cell is required for each cursor used by the program. Set local |
| 71782 | | - ** variable u.cd.nMem (and later, VdbeFrame.nChildMem) to this value. |
| 71321 | + ** variable nMem (and later, VdbeFrame.nChildMem) to this value. |
| 71783 | 71322 | */ |
| 71784 | | - u.cd.nMem = u.cd.pProgram->nMem + u.cd.pProgram->nCsr; |
| 71785 | | - u.cd.nByte = ROUND8(sizeof(VdbeFrame)) |
| 71786 | | - + u.cd.nMem * sizeof(Mem) |
| 71787 | | - + u.cd.pProgram->nCsr * sizeof(VdbeCursor *) |
| 71788 | | - + u.cd.pProgram->nOnce * sizeof(u8); |
| 71789 | | - u.cd.pFrame = sqlite3DbMallocZero(db, u.cd.nByte); |
| 71790 | | - if( !u.cd.pFrame ){ |
| 71323 | + nMem = pProgram->nMem + pProgram->nCsr; |
| 71324 | + nByte = ROUND8(sizeof(VdbeFrame)) |
| 71325 | + + nMem * sizeof(Mem) |
| 71326 | + + pProgram->nCsr * sizeof(VdbeCursor *) |
| 71327 | + + pProgram->nOnce * sizeof(u8); |
| 71328 | + pFrame = sqlite3DbMallocZero(db, nByte); |
| 71329 | + if( !pFrame ){ |
| 71791 | 71330 | goto no_mem; |
| 71792 | 71331 | } |
| 71793 | | - sqlite3VdbeMemRelease(u.cd.pRt); |
| 71794 | | - u.cd.pRt->flags = MEM_Frame; |
| 71795 | | - u.cd.pRt->u.pFrame = u.cd.pFrame; |
| 71796 | | - |
| 71797 | | - u.cd.pFrame->v = p; |
| 71798 | | - u.cd.pFrame->nChildMem = u.cd.nMem; |
| 71799 | | - u.cd.pFrame->nChildCsr = u.cd.pProgram->nCsr; |
| 71800 | | - u.cd.pFrame->pc = pc; |
| 71801 | | - u.cd.pFrame->aMem = p->aMem; |
| 71802 | | - u.cd.pFrame->nMem = p->nMem; |
| 71803 | | - u.cd.pFrame->apCsr = p->apCsr; |
| 71804 | | - u.cd.pFrame->nCursor = p->nCursor; |
| 71805 | | - u.cd.pFrame->aOp = p->aOp; |
| 71806 | | - u.cd.pFrame->nOp = p->nOp; |
| 71807 | | - u.cd.pFrame->token = u.cd.pProgram->token; |
| 71808 | | - u.cd.pFrame->aOnceFlag = p->aOnceFlag; |
| 71809 | | - u.cd.pFrame->nOnceFlag = p->nOnceFlag; |
| 71810 | | - |
| 71811 | | - u.cd.pEnd = &VdbeFrameMem(u.cd.pFrame)[u.cd.pFrame->nChildMem]; |
| 71812 | | - for(u.cd.pMem=VdbeFrameMem(u.cd.pFrame); u.cd.pMem!=u.cd.pEnd; u.cd.pMem++){ |
| 71813 | | - u.cd.pMem->flags = MEM_Invalid; |
| 71814 | | - u.cd.pMem->db = db; |
| 71332 | + sqlite3VdbeMemRelease(pRt); |
| 71333 | + pRt->flags = MEM_Frame; |
| 71334 | + pRt->u.pFrame = pFrame; |
| 71335 | + |
| 71336 | + pFrame->v = p; |
| 71337 | + pFrame->nChildMem = nMem; |
| 71338 | + pFrame->nChildCsr = pProgram->nCsr; |
| 71339 | + pFrame->pc = pc; |
| 71340 | + pFrame->aMem = p->aMem; |
| 71341 | + pFrame->nMem = p->nMem; |
| 71342 | + pFrame->apCsr = p->apCsr; |
| 71343 | + pFrame->nCursor = p->nCursor; |
| 71344 | + pFrame->aOp = p->aOp; |
| 71345 | + pFrame->nOp = p->nOp; |
| 71346 | + pFrame->token = pProgram->token; |
| 71347 | + pFrame->aOnceFlag = p->aOnceFlag; |
| 71348 | + pFrame->nOnceFlag = p->nOnceFlag; |
| 71349 | + |
| 71350 | + pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; |
| 71351 | + for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ |
| 71352 | + pMem->flags = MEM_Invalid; |
| 71353 | + pMem->db = db; |
| 71815 | 71354 | } |
| 71816 | 71355 | }else{ |
| 71817 | | - u.cd.pFrame = u.cd.pRt->u.pFrame; |
| 71818 | | - assert( u.cd.pProgram->nMem+u.cd.pProgram->nCsr==u.cd.pFrame->nChildMem ); |
| 71819 | | - assert( u.cd.pProgram->nCsr==u.cd.pFrame->nChildCsr ); |
| 71820 | | - assert( pc==u.cd.pFrame->pc ); |
| 71356 | + pFrame = pRt->u.pFrame; |
| 71357 | + assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); |
| 71358 | + assert( pProgram->nCsr==pFrame->nChildCsr ); |
| 71359 | + assert( pc==pFrame->pc ); |
| 71821 | 71360 | } |
| 71822 | 71361 | |
| 71823 | 71362 | p->nFrame++; |
| 71824 | | - u.cd.pFrame->pParent = p->pFrame; |
| 71825 | | - u.cd.pFrame->lastRowid = lastRowid; |
| 71826 | | - u.cd.pFrame->nChange = p->nChange; |
| 71363 | + pFrame->pParent = p->pFrame; |
| 71364 | + pFrame->lastRowid = lastRowid; |
| 71365 | + pFrame->nChange = p->nChange; |
| 71827 | 71366 | p->nChange = 0; |
| 71828 | | - p->pFrame = u.cd.pFrame; |
| 71829 | | - p->aMem = aMem = &VdbeFrameMem(u.cd.pFrame)[-1]; |
| 71830 | | - p->nMem = u.cd.pFrame->nChildMem; |
| 71831 | | - p->nCursor = (u16)u.cd.pFrame->nChildCsr; |
| 71367 | + p->pFrame = pFrame; |
| 71368 | + p->aMem = aMem = &VdbeFrameMem(pFrame)[-1]; |
| 71369 | + p->nMem = pFrame->nChildMem; |
| 71370 | + p->nCursor = (u16)pFrame->nChildCsr; |
| 71832 | 71371 | p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; |
| 71833 | | - p->aOp = aOp = u.cd.pProgram->aOp; |
| 71834 | | - p->nOp = u.cd.pProgram->nOp; |
| 71372 | + p->aOp = aOp = pProgram->aOp; |
| 71373 | + p->nOp = pProgram->nOp; |
| 71835 | 71374 | p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; |
| 71836 | | - p->nOnceFlag = u.cd.pProgram->nOnce; |
| 71375 | + p->nOnceFlag = pProgram->nOnce; |
| 71837 | 71376 | pc = -1; |
| 71838 | 71377 | memset(p->aOnceFlag, 0, p->nOnceFlag); |
| 71839 | 71378 | |
| 71840 | 71379 | break; |
| 71841 | 71380 | } |
| | @@ -71851,17 +71390,15 @@ |
| 71851 | 71390 | ** The address of the cell in the parent frame is determined by adding |
| 71852 | 71391 | ** the value of the P1 argument to the value of the P1 argument to the |
| 71853 | 71392 | ** calling OP_Program instruction. |
| 71854 | 71393 | */ |
| 71855 | 71394 | case OP_Param: { /* out2-prerelease */ |
| 71856 | | -#if 0 /* local variables moved into u.ce */ |
| 71857 | 71395 | VdbeFrame *pFrame; |
| 71858 | 71396 | Mem *pIn; |
| 71859 | | -#endif /* local variables moved into u.ce */ |
| 71860 | | - u.ce.pFrame = p->pFrame; |
| 71861 | | - u.ce.pIn = &u.ce.pFrame->aMem[pOp->p1 + u.ce.pFrame->aOp[u.ce.pFrame->pc].p1]; |
| 71862 | | - sqlite3VdbeMemShallowCopy(pOut, u.ce.pIn, MEM_Ephem); |
| 71397 | + pFrame = p->pFrame; |
| 71398 | + pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; |
| 71399 | + sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); |
| 71863 | 71400 | break; |
| 71864 | 71401 | } |
| 71865 | 71402 | |
| 71866 | 71403 | #endif /* #ifndef SQLITE_OMIT_TRIGGER */ |
| 71867 | 71404 | |
| | @@ -71918,26 +71455,23 @@ |
| 71918 | 71455 | ** |
| 71919 | 71456 | ** This instruction throws an error if the memory cell is not initially |
| 71920 | 71457 | ** an integer. |
| 71921 | 71458 | */ |
| 71922 | 71459 | case OP_MemMax: { /* in2 */ |
| 71923 | | -#if 0 /* local variables moved into u.cf */ |
| 71924 | | - Mem *pIn1; |
| 71925 | 71460 | VdbeFrame *pFrame; |
| 71926 | | -#endif /* local variables moved into u.cf */ |
| 71927 | 71461 | if( p->pFrame ){ |
| 71928 | | - for(u.cf.pFrame=p->pFrame; u.cf.pFrame->pParent; u.cf.pFrame=u.cf.pFrame->pParent); |
| 71929 | | - u.cf.pIn1 = &u.cf.pFrame->aMem[pOp->p1]; |
| 71462 | + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); |
| 71463 | + pIn1 = &pFrame->aMem[pOp->p1]; |
| 71930 | 71464 | }else{ |
| 71931 | | - u.cf.pIn1 = &aMem[pOp->p1]; |
| 71465 | + pIn1 = &aMem[pOp->p1]; |
| 71932 | 71466 | } |
| 71933 | | - assert( memIsValid(u.cf.pIn1) ); |
| 71934 | | - sqlite3VdbeMemIntegerify(u.cf.pIn1); |
| 71467 | + assert( memIsValid(pIn1) ); |
| 71468 | + sqlite3VdbeMemIntegerify(pIn1); |
| 71935 | 71469 | pIn2 = &aMem[pOp->p2]; |
| 71936 | 71470 | sqlite3VdbeMemIntegerify(pIn2); |
| 71937 | | - if( u.cf.pIn1->u.i<pIn2->u.i){ |
| 71938 | | - u.cf.pIn1->u.i = pIn2->u.i; |
| 71471 | + if( pIn1->u.i<pIn2->u.i){ |
| 71472 | + pIn1->u.i = pIn2->u.i; |
| 71939 | 71473 | } |
| 71940 | 71474 | break; |
| 71941 | 71475 | } |
| 71942 | 71476 | #endif /* SQLITE_OMIT_AUTOINCREMENT */ |
| 71943 | 71477 | |
| | @@ -72004,60 +71538,58 @@ |
| 72004 | 71538 | ** |
| 72005 | 71539 | ** The P5 arguments are taken from register P2 and its |
| 72006 | 71540 | ** successors. |
| 72007 | 71541 | */ |
| 72008 | 71542 | case OP_AggStep: { |
| 72009 | | -#if 0 /* local variables moved into u.cg */ |
| 72010 | 71543 | int n; |
| 72011 | 71544 | int i; |
| 72012 | 71545 | Mem *pMem; |
| 72013 | 71546 | Mem *pRec; |
| 72014 | 71547 | sqlite3_context ctx; |
| 72015 | 71548 | sqlite3_value **apVal; |
| 72016 | | -#endif /* local variables moved into u.cg */ |
| 72017 | | - |
| 72018 | | - u.cg.n = pOp->p5; |
| 72019 | | - assert( u.cg.n>=0 ); |
| 72020 | | - u.cg.pRec = &aMem[pOp->p2]; |
| 72021 | | - u.cg.apVal = p->apArg; |
| 72022 | | - assert( u.cg.apVal || u.cg.n==0 ); |
| 72023 | | - for(u.cg.i=0; u.cg.i<u.cg.n; u.cg.i++, u.cg.pRec++){ |
| 72024 | | - assert( memIsValid(u.cg.pRec) ); |
| 72025 | | - u.cg.apVal[u.cg.i] = u.cg.pRec; |
| 72026 | | - memAboutToChange(p, u.cg.pRec); |
| 72027 | | - sqlite3VdbeMemStoreType(u.cg.pRec); |
| 72028 | | - } |
| 72029 | | - u.cg.ctx.pFunc = pOp->p4.pFunc; |
| 71549 | + |
| 71550 | + n = pOp->p5; |
| 71551 | + assert( n>=0 ); |
| 71552 | + pRec = &aMem[pOp->p2]; |
| 71553 | + apVal = p->apArg; |
| 71554 | + assert( apVal || n==0 ); |
| 71555 | + for(i=0; i<n; i++, pRec++){ |
| 71556 | + assert( memIsValid(pRec) ); |
| 71557 | + apVal[i] = pRec; |
| 71558 | + memAboutToChange(p, pRec); |
| 71559 | + sqlite3VdbeMemStoreType(pRec); |
| 71560 | + } |
| 71561 | + ctx.pFunc = pOp->p4.pFunc; |
| 72030 | 71562 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 72031 | | - u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3]; |
| 72032 | | - u.cg.pMem->n++; |
| 72033 | | - u.cg.ctx.s.flags = MEM_Null; |
| 72034 | | - u.cg.ctx.s.z = 0; |
| 72035 | | - u.cg.ctx.s.zMalloc = 0; |
| 72036 | | - u.cg.ctx.s.xDel = 0; |
| 72037 | | - u.cg.ctx.s.db = db; |
| 72038 | | - u.cg.ctx.isError = 0; |
| 72039 | | - u.cg.ctx.pColl = 0; |
| 72040 | | - u.cg.ctx.skipFlag = 0; |
| 72041 | | - if( u.cg.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 71563 | + ctx.pMem = pMem = &aMem[pOp->p3]; |
| 71564 | + pMem->n++; |
| 71565 | + ctx.s.flags = MEM_Null; |
| 71566 | + ctx.s.z = 0; |
| 71567 | + ctx.s.zMalloc = 0; |
| 71568 | + ctx.s.xDel = 0; |
| 71569 | + ctx.s.db = db; |
| 71570 | + ctx.isError = 0; |
| 71571 | + ctx.pColl = 0; |
| 71572 | + ctx.skipFlag = 0; |
| 71573 | + if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 72042 | 71574 | assert( pOp>p->aOp ); |
| 72043 | 71575 | assert( pOp[-1].p4type==P4_COLLSEQ ); |
| 72044 | 71576 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 72045 | | - u.cg.ctx.pColl = pOp[-1].p4.pColl; |
| 72046 | | - } |
| 72047 | | - (u.cg.ctx.pFunc->xStep)(&u.cg.ctx, u.cg.n, u.cg.apVal); /* IMP: R-24505-23230 */ |
| 72048 | | - if( u.cg.ctx.isError ){ |
| 72049 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cg.ctx.s)); |
| 72050 | | - rc = u.cg.ctx.isError; |
| 72051 | | - } |
| 72052 | | - if( u.cg.ctx.skipFlag ){ |
| 71577 | + ctx.pColl = pOp[-1].p4.pColl; |
| 71578 | + } |
| 71579 | + (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */ |
| 71580 | + if( ctx.isError ){ |
| 71581 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s)); |
| 71582 | + rc = ctx.isError; |
| 71583 | + } |
| 71584 | + if( ctx.skipFlag ){ |
| 72053 | 71585 | assert( pOp[-1].opcode==OP_CollSeq ); |
| 72054 | | - u.cg.i = pOp[-1].p1; |
| 72055 | | - if( u.cg.i ) sqlite3VdbeMemSetInt64(&aMem[u.cg.i], 1); |
| 71586 | + i = pOp[-1].p1; |
| 71587 | + if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); |
| 72056 | 71588 | } |
| 72057 | 71589 | |
| 72058 | | - sqlite3VdbeMemRelease(&u.cg.ctx.s); |
| 71590 | + sqlite3VdbeMemRelease(&ctx.s); |
| 72059 | 71591 | |
| 72060 | 71592 | break; |
| 72061 | 71593 | } |
| 72062 | 71594 | |
| 72063 | 71595 | /* Opcode: AggFinal P1 P2 * P4 * |
| | @@ -72072,23 +71604,21 @@ |
| 72072 | 71604 | ** functions that can take varying numbers of arguments. The |
| 72073 | 71605 | ** P4 argument is only needed for the degenerate case where |
| 72074 | 71606 | ** the step function was not previously called. |
| 72075 | 71607 | */ |
| 72076 | 71608 | case OP_AggFinal: { |
| 72077 | | -#if 0 /* local variables moved into u.ch */ |
| 72078 | 71609 | Mem *pMem; |
| 72079 | | -#endif /* local variables moved into u.ch */ |
| 72080 | 71610 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 72081 | | - u.ch.pMem = &aMem[pOp->p1]; |
| 72082 | | - assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 72083 | | - rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc); |
| 71611 | + pMem = &aMem[pOp->p1]; |
| 71612 | + assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 71613 | + rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); |
| 72084 | 71614 | if( rc ){ |
| 72085 | | - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem)); |
| 71615 | + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem)); |
| 72086 | 71616 | } |
| 72087 | | - sqlite3VdbeChangeEncoding(u.ch.pMem, encoding); |
| 72088 | | - UPDATE_MAX_BLOBSIZE(u.ch.pMem); |
| 72089 | | - if( sqlite3VdbeMemTooBig(u.ch.pMem) ){ |
| 71617 | + sqlite3VdbeChangeEncoding(pMem, encoding); |
| 71618 | + UPDATE_MAX_BLOBSIZE(pMem); |
| 71619 | + if( sqlite3VdbeMemTooBig(pMem) ){ |
| 72090 | 71620 | goto too_big; |
| 72091 | 71621 | } |
| 72092 | 71622 | break; |
| 72093 | 71623 | } |
| 72094 | 71624 | |
| | @@ -72103,31 +71633,29 @@ |
| 72103 | 71633 | ** in the WAL that have been checkpointed after the checkpoint |
| 72104 | 71634 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
| 72105 | 71635 | ** mem[P3+2] are initialized to -1. |
| 72106 | 71636 | */ |
| 72107 | 71637 | case OP_Checkpoint: { |
| 72108 | | -#if 0 /* local variables moved into u.ci */ |
| 72109 | 71638 | int i; /* Loop counter */ |
| 72110 | 71639 | int aRes[3]; /* Results */ |
| 72111 | 71640 | Mem *pMem; /* Write results here */ |
| 72112 | | -#endif /* local variables moved into u.ci */ |
| 72113 | 71641 | |
| 72114 | 71642 | assert( p->readOnly==0 ); |
| 72115 | | - u.ci.aRes[0] = 0; |
| 72116 | | - u.ci.aRes[1] = u.ci.aRes[2] = -1; |
| 71643 | + aRes[0] = 0; |
| 71644 | + aRes[1] = aRes[2] = -1; |
| 72117 | 71645 | assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE |
| 72118 | 71646 | || pOp->p2==SQLITE_CHECKPOINT_FULL |
| 72119 | 71647 | || pOp->p2==SQLITE_CHECKPOINT_RESTART |
| 72120 | 71648 | ); |
| 72121 | | - rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ci.aRes[1], &u.ci.aRes[2]); |
| 71649 | + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); |
| 72122 | 71650 | if( rc==SQLITE_BUSY ){ |
| 72123 | 71651 | rc = SQLITE_OK; |
| 72124 | | - u.ci.aRes[0] = 1; |
| 71652 | + aRes[0] = 1; |
| 72125 | 71653 | } |
| 72126 | | - for(u.ci.i=0, u.ci.pMem = &aMem[pOp->p3]; u.ci.i<3; u.ci.i++, u.ci.pMem++){ |
| 72127 | | - sqlite3VdbeMemSetInt64(u.ci.pMem, (i64)u.ci.aRes[u.ci.i]); |
| 72128 | | - } |
| 71654 | + for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){ |
| 71655 | + sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); |
| 71656 | + } |
| 72129 | 71657 | break; |
| 72130 | 71658 | }; |
| 72131 | 71659 | #endif |
| 72132 | 71660 | |
| 72133 | 71661 | #ifndef SQLITE_OMIT_PRAGMA |
| | @@ -72141,98 +71669,96 @@ |
| 72141 | 71669 | ** If changing into or out of WAL mode the procedure is more complicated. |
| 72142 | 71670 | ** |
| 72143 | 71671 | ** Write a string containing the final journal-mode to register P2. |
| 72144 | 71672 | */ |
| 72145 | 71673 | case OP_JournalMode: { /* out2-prerelease */ |
| 72146 | | -#if 0 /* local variables moved into u.cj */ |
| 72147 | 71674 | Btree *pBt; /* Btree to change journal mode of */ |
| 72148 | 71675 | Pager *pPager; /* Pager associated with pBt */ |
| 72149 | 71676 | int eNew; /* New journal mode */ |
| 72150 | 71677 | int eOld; /* The old journal mode */ |
| 72151 | 71678 | #ifndef SQLITE_OMIT_WAL |
| 72152 | 71679 | const char *zFilename; /* Name of database file for pPager */ |
| 72153 | 71680 | #endif |
| 72154 | | -#endif /* local variables moved into u.cj */ |
| 72155 | | - |
| 72156 | | - u.cj.eNew = pOp->p3; |
| 72157 | | - assert( u.cj.eNew==PAGER_JOURNALMODE_DELETE |
| 72158 | | - || u.cj.eNew==PAGER_JOURNALMODE_TRUNCATE |
| 72159 | | - || u.cj.eNew==PAGER_JOURNALMODE_PERSIST |
| 72160 | | - || u.cj.eNew==PAGER_JOURNALMODE_OFF |
| 72161 | | - || u.cj.eNew==PAGER_JOURNALMODE_MEMORY |
| 72162 | | - || u.cj.eNew==PAGER_JOURNALMODE_WAL |
| 72163 | | - || u.cj.eNew==PAGER_JOURNALMODE_QUERY |
| 71681 | + |
| 71682 | + eNew = pOp->p3; |
| 71683 | + assert( eNew==PAGER_JOURNALMODE_DELETE |
| 71684 | + || eNew==PAGER_JOURNALMODE_TRUNCATE |
| 71685 | + || eNew==PAGER_JOURNALMODE_PERSIST |
| 71686 | + || eNew==PAGER_JOURNALMODE_OFF |
| 71687 | + || eNew==PAGER_JOURNALMODE_MEMORY |
| 71688 | + || eNew==PAGER_JOURNALMODE_WAL |
| 71689 | + || eNew==PAGER_JOURNALMODE_QUERY |
| 72164 | 71690 | ); |
| 72165 | 71691 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 72166 | 71692 | assert( p->readOnly==0 ); |
| 72167 | 71693 | |
| 72168 | | - u.cj.pBt = db->aDb[pOp->p1].pBt; |
| 72169 | | - u.cj.pPager = sqlite3BtreePager(u.cj.pBt); |
| 72170 | | - u.cj.eOld = sqlite3PagerGetJournalMode(u.cj.pPager); |
| 72171 | | - if( u.cj.eNew==PAGER_JOURNALMODE_QUERY ) u.cj.eNew = u.cj.eOld; |
| 72172 | | - if( !sqlite3PagerOkToChangeJournalMode(u.cj.pPager) ) u.cj.eNew = u.cj.eOld; |
| 71694 | + pBt = db->aDb[pOp->p1].pBt; |
| 71695 | + pPager = sqlite3BtreePager(pBt); |
| 71696 | + eOld = sqlite3PagerGetJournalMode(pPager); |
| 71697 | + if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld; |
| 71698 | + if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; |
| 72173 | 71699 | |
| 72174 | 71700 | #ifndef SQLITE_OMIT_WAL |
| 72175 | | - u.cj.zFilename = sqlite3PagerFilename(u.cj.pPager, 1); |
| 71701 | + zFilename = sqlite3PagerFilename(pPager, 1); |
| 72176 | 71702 | |
| 72177 | 71703 | /* Do not allow a transition to journal_mode=WAL for a database |
| 72178 | | - ** in temporary storage or if the VFS does not support shared memory |
| 71704 | + ** in temporary storage or if the VFS does not support shared memory |
| 72179 | 71705 | */ |
| 72180 | | - if( u.cj.eNew==PAGER_JOURNALMODE_WAL |
| 72181 | | - && (sqlite3Strlen30(u.cj.zFilename)==0 /* Temp file */ |
| 72182 | | - || !sqlite3PagerWalSupported(u.cj.pPager)) /* No shared-memory support */ |
| 71706 | + if( eNew==PAGER_JOURNALMODE_WAL |
| 71707 | + && (sqlite3Strlen30(zFilename)==0 /* Temp file */ |
| 71708 | + || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */ |
| 72183 | 71709 | ){ |
| 72184 | | - u.cj.eNew = u.cj.eOld; |
| 71710 | + eNew = eOld; |
| 72185 | 71711 | } |
| 72186 | 71712 | |
| 72187 | | - if( (u.cj.eNew!=u.cj.eOld) |
| 72188 | | - && (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL) |
| 71713 | + if( (eNew!=eOld) |
| 71714 | + && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL) |
| 72189 | 71715 | ){ |
| 72190 | 71716 | if( !db->autoCommit || db->nVdbeRead>1 ){ |
| 72191 | 71717 | rc = SQLITE_ERROR; |
| 72192 | | - sqlite3SetString(&p->zErrMsg, db, |
| 71718 | + sqlite3SetString(&p->zErrMsg, db, |
| 72193 | 71719 | "cannot change %s wal mode from within a transaction", |
| 72194 | | - (u.cj.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 71720 | + (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
| 72195 | 71721 | ); |
| 72196 | 71722 | break; |
| 72197 | 71723 | }else{ |
| 72198 | | - |
| 72199 | | - if( u.cj.eOld==PAGER_JOURNALMODE_WAL ){ |
| 71724 | + |
| 71725 | + if( eOld==PAGER_JOURNALMODE_WAL ){ |
| 72200 | 71726 | /* If leaving WAL mode, close the log file. If successful, the call |
| 72201 | | - ** to PagerCloseWal() checkpoints and deletes the write-ahead-log |
| 72202 | | - ** file. An EXCLUSIVE lock may still be held on the database file |
| 72203 | | - ** after a successful return. |
| 71727 | + ** to PagerCloseWal() checkpoints and deletes the write-ahead-log |
| 71728 | + ** file. An EXCLUSIVE lock may still be held on the database file |
| 71729 | + ** after a successful return. |
| 72204 | 71730 | */ |
| 72205 | | - rc = sqlite3PagerCloseWal(u.cj.pPager); |
| 71731 | + rc = sqlite3PagerCloseWal(pPager); |
| 72206 | 71732 | if( rc==SQLITE_OK ){ |
| 72207 | | - sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew); |
| 71733 | + sqlite3PagerSetJournalMode(pPager, eNew); |
| 72208 | 71734 | } |
| 72209 | | - }else if( u.cj.eOld==PAGER_JOURNALMODE_MEMORY ){ |
| 71735 | + }else if( eOld==PAGER_JOURNALMODE_MEMORY ){ |
| 72210 | 71736 | /* Cannot transition directly from MEMORY to WAL. Use mode OFF |
| 72211 | 71737 | ** as an intermediate */ |
| 72212 | | - sqlite3PagerSetJournalMode(u.cj.pPager, PAGER_JOURNALMODE_OFF); |
| 71738 | + sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); |
| 72213 | 71739 | } |
| 72214 | | - |
| 71740 | + |
| 72215 | 71741 | /* Open a transaction on the database file. Regardless of the journal |
| 72216 | 71742 | ** mode, this transaction always uses a rollback journal. |
| 72217 | 71743 | */ |
| 72218 | | - assert( sqlite3BtreeIsInTrans(u.cj.pBt)==0 ); |
| 71744 | + assert( sqlite3BtreeIsInTrans(pBt)==0 ); |
| 72219 | 71745 | if( rc==SQLITE_OK ){ |
| 72220 | | - rc = sqlite3BtreeSetVersion(u.cj.pBt, (u.cj.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
| 71746 | + rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
| 72221 | 71747 | } |
| 72222 | 71748 | } |
| 72223 | 71749 | } |
| 72224 | 71750 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 72225 | 71751 | |
| 72226 | 71752 | if( rc ){ |
| 72227 | | - u.cj.eNew = u.cj.eOld; |
| 71753 | + eNew = eOld; |
| 72228 | 71754 | } |
| 72229 | | - u.cj.eNew = sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew); |
| 71755 | + eNew = sqlite3PagerSetJournalMode(pPager, eNew); |
| 72230 | 71756 | |
| 72231 | 71757 | pOut = &aMem[pOp->p2]; |
| 72232 | 71758 | pOut->flags = MEM_Str|MEM_Static|MEM_Term; |
| 72233 | | - pOut->z = (char *)sqlite3JournalModename(u.cj.eNew); |
| 71759 | + pOut->z = (char *)sqlite3JournalModename(eNew); |
| 72234 | 71760 | pOut->n = sqlite3Strlen30(pOut->z); |
| 72235 | 71761 | pOut->enc = SQLITE_UTF8; |
| 72236 | 71762 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 72237 | 71763 | break; |
| 72238 | 71764 | }; |
| | @@ -72258,19 +71784,17 @@ |
| 72258 | 71784 | ** Perform a single step of the incremental vacuum procedure on |
| 72259 | 71785 | ** the P1 database. If the vacuum has finished, jump to instruction |
| 72260 | 71786 | ** P2. Otherwise, fall through to the next instruction. |
| 72261 | 71787 | */ |
| 72262 | 71788 | case OP_IncrVacuum: { /* jump */ |
| 72263 | | -#if 0 /* local variables moved into u.ck */ |
| 72264 | 71789 | Btree *pBt; |
| 72265 | | -#endif /* local variables moved into u.ck */ |
| 72266 | 71790 | |
| 72267 | 71791 | assert( pOp->p1>=0 && pOp->p1<db->nDb ); |
| 72268 | 71792 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); |
| 72269 | 71793 | assert( p->readOnly==0 ); |
| 72270 | | - u.ck.pBt = db->aDb[pOp->p1].pBt; |
| 72271 | | - rc = sqlite3BtreeIncrVacuum(u.ck.pBt); |
| 71794 | + pBt = db->aDb[pOp->p1].pBt; |
| 71795 | + rc = sqlite3BtreeIncrVacuum(pBt); |
| 72272 | 71796 | if( rc==SQLITE_DONE ){ |
| 72273 | 71797 | pc = pOp->p2 - 1; |
| 72274 | 71798 | rc = SQLITE_OK; |
| 72275 | 71799 | } |
| 72276 | 71800 | break; |
| | @@ -72337,16 +71861,14 @@ |
| 72337 | 71861 | ** Also, whether or not P4 is set, check that this is not being called from |
| 72338 | 71862 | ** within a callback to a virtual table xSync() method. If it is, the error |
| 72339 | 71863 | ** code will be set to SQLITE_LOCKED. |
| 72340 | 71864 | */ |
| 72341 | 71865 | case OP_VBegin: { |
| 72342 | | -#if 0 /* local variables moved into u.cl */ |
| 72343 | 71866 | VTable *pVTab; |
| 72344 | | -#endif /* local variables moved into u.cl */ |
| 72345 | | - u.cl.pVTab = pOp->p4.pVtab; |
| 72346 | | - rc = sqlite3VtabBegin(db, u.cl.pVTab); |
| 72347 | | - if( u.cl.pVTab ) sqlite3VtabImportErrmsg(p, u.cl.pVTab->pVtab); |
| 71867 | + pVTab = pOp->p4.pVtab; |
| 71868 | + rc = sqlite3VtabBegin(db, pVTab); |
| 71869 | + if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab); |
| 72348 | 71870 | break; |
| 72349 | 71871 | } |
| 72350 | 71872 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 72351 | 71873 | |
| 72352 | 71874 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| | @@ -72381,37 +71903,34 @@ |
| 72381 | 71903 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 72382 | 71904 | ** P1 is a cursor number. This opcode opens a cursor to the virtual |
| 72383 | 71905 | ** table and stores that cursor in P1. |
| 72384 | 71906 | */ |
| 72385 | 71907 | case OP_VOpen: { |
| 72386 | | -#if 0 /* local variables moved into u.cm */ |
| 72387 | 71908 | VdbeCursor *pCur; |
| 72388 | 71909 | sqlite3_vtab_cursor *pVtabCursor; |
| 72389 | 71910 | sqlite3_vtab *pVtab; |
| 72390 | 71911 | sqlite3_module *pModule; |
| 72391 | | -#endif /* local variables moved into u.cm */ |
| 72392 | 71912 | |
| 72393 | 71913 | assert( p->bIsReader ); |
| 72394 | | - u.cm.pCur = 0; |
| 72395 | | - u.cm.pVtabCursor = 0; |
| 72396 | | - u.cm.pVtab = pOp->p4.pVtab->pVtab; |
| 72397 | | - u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule; |
| 72398 | | - assert(u.cm.pVtab && u.cm.pModule); |
| 72399 | | - rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor); |
| 72400 | | - sqlite3VtabImportErrmsg(p, u.cm.pVtab); |
| 71914 | + pCur = 0; |
| 71915 | + pVtabCursor = 0; |
| 71916 | + pVtab = pOp->p4.pVtab->pVtab; |
| 71917 | + pModule = (sqlite3_module *)pVtab->pModule; |
| 71918 | + assert(pVtab && pModule); |
| 71919 | + rc = pModule->xOpen(pVtab, &pVtabCursor); |
| 71920 | + sqlite3VtabImportErrmsg(p, pVtab); |
| 72401 | 71921 | if( SQLITE_OK==rc ){ |
| 72402 | 71922 | /* Initialize sqlite3_vtab_cursor base class */ |
| 72403 | | - u.cm.pVtabCursor->pVtab = u.cm.pVtab; |
| 71923 | + pVtabCursor->pVtab = pVtab; |
| 72404 | 71924 | |
| 72405 | 71925 | /* Initialize vdbe cursor object */ |
| 72406 | | - u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); |
| 72407 | | - if( u.cm.pCur ){ |
| 72408 | | - u.cm.pCur->pVtabCursor = u.cm.pVtabCursor; |
| 72409 | | - u.cm.pCur->pModule = u.cm.pVtabCursor->pVtab->pModule; |
| 71926 | + pCur = allocateCursor(p, pOp->p1, 0, -1, 0); |
| 71927 | + if( pCur ){ |
| 71928 | + pCur->pVtabCursor = pVtabCursor; |
| 72410 | 71929 | }else{ |
| 72411 | 71930 | db->mallocFailed = 1; |
| 72412 | | - u.cm.pModule->xClose(u.cm.pVtabCursor); |
| 71931 | + pModule->xClose(pVtabCursor); |
| 72413 | 71932 | } |
| 72414 | 71933 | } |
| 72415 | 71934 | break; |
| 72416 | 71935 | } |
| 72417 | 71936 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| | @@ -72435,11 +71954,10 @@ |
| 72435 | 71954 | ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. |
| 72436 | 71955 | ** |
| 72437 | 71956 | ** A jump is made to P2 if the result set after filtering would be empty. |
| 72438 | 71957 | */ |
| 72439 | 71958 | case OP_VFilter: { /* jump */ |
| 72440 | | -#if 0 /* local variables moved into u.cn */ |
| 72441 | 71959 | int nArg; |
| 72442 | 71960 | int iQuery; |
| 72443 | 71961 | const sqlite3_module *pModule; |
| 72444 | 71962 | Mem *pQuery; |
| 72445 | 71963 | Mem *pArgc; |
| | @@ -72447,49 +71965,48 @@ |
| 72447 | 71965 | sqlite3_vtab *pVtab; |
| 72448 | 71966 | VdbeCursor *pCur; |
| 72449 | 71967 | int res; |
| 72450 | 71968 | int i; |
| 72451 | 71969 | Mem **apArg; |
| 72452 | | -#endif /* local variables moved into u.cn */ |
| 72453 | | - |
| 72454 | | - u.cn.pQuery = &aMem[pOp->p3]; |
| 72455 | | - u.cn.pArgc = &u.cn.pQuery[1]; |
| 72456 | | - u.cn.pCur = p->apCsr[pOp->p1]; |
| 72457 | | - assert( memIsValid(u.cn.pQuery) ); |
| 72458 | | - REGISTER_TRACE(pOp->p3, u.cn.pQuery); |
| 72459 | | - assert( u.cn.pCur->pVtabCursor ); |
| 72460 | | - u.cn.pVtabCursor = u.cn.pCur->pVtabCursor; |
| 72461 | | - u.cn.pVtab = u.cn.pVtabCursor->pVtab; |
| 72462 | | - u.cn.pModule = u.cn.pVtab->pModule; |
| 71970 | + |
| 71971 | + pQuery = &aMem[pOp->p3]; |
| 71972 | + pArgc = &pQuery[1]; |
| 71973 | + pCur = p->apCsr[pOp->p1]; |
| 71974 | + assert( memIsValid(pQuery) ); |
| 71975 | + REGISTER_TRACE(pOp->p3, pQuery); |
| 71976 | + assert( pCur->pVtabCursor ); |
| 71977 | + pVtabCursor = pCur->pVtabCursor; |
| 71978 | + pVtab = pVtabCursor->pVtab; |
| 71979 | + pModule = pVtab->pModule; |
| 72463 | 71980 | |
| 72464 | 71981 | /* Grab the index number and argc parameters */ |
| 72465 | | - assert( (u.cn.pQuery->flags&MEM_Int)!=0 && u.cn.pArgc->flags==MEM_Int ); |
| 72466 | | - u.cn.nArg = (int)u.cn.pArgc->u.i; |
| 72467 | | - u.cn.iQuery = (int)u.cn.pQuery->u.i; |
| 71982 | + assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); |
| 71983 | + nArg = (int)pArgc->u.i; |
| 71984 | + iQuery = (int)pQuery->u.i; |
| 72468 | 71985 | |
| 72469 | 71986 | /* Invoke the xFilter method */ |
| 72470 | 71987 | { |
| 72471 | | - u.cn.res = 0; |
| 72472 | | - u.cn.apArg = p->apArg; |
| 72473 | | - for(u.cn.i = 0; u.cn.i<u.cn.nArg; u.cn.i++){ |
| 72474 | | - u.cn.apArg[u.cn.i] = &u.cn.pArgc[u.cn.i+1]; |
| 72475 | | - sqlite3VdbeMemStoreType(u.cn.apArg[u.cn.i]); |
| 71988 | + res = 0; |
| 71989 | + apArg = p->apArg; |
| 71990 | + for(i = 0; i<nArg; i++){ |
| 71991 | + apArg[i] = &pArgc[i+1]; |
| 71992 | + sqlite3VdbeMemStoreType(apArg[i]); |
| 72476 | 71993 | } |
| 72477 | 71994 | |
| 72478 | 71995 | p->inVtabMethod = 1; |
| 72479 | | - rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg); |
| 71996 | + rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg); |
| 72480 | 71997 | p->inVtabMethod = 0; |
| 72481 | | - sqlite3VtabImportErrmsg(p, u.cn.pVtab); |
| 71998 | + sqlite3VtabImportErrmsg(p, pVtab); |
| 72482 | 71999 | if( rc==SQLITE_OK ){ |
| 72483 | | - u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor); |
| 72000 | + res = pModule->xEof(pVtabCursor); |
| 72484 | 72001 | } |
| 72485 | 72002 | |
| 72486 | | - if( u.cn.res ){ |
| 72003 | + if( res ){ |
| 72487 | 72004 | pc = pOp->p2 - 1; |
| 72488 | 72005 | } |
| 72489 | 72006 | } |
| 72490 | | - u.cn.pCur->nullRow = 0; |
| 72007 | + pCur->nullRow = 0; |
| 72491 | 72008 | |
| 72492 | 72009 | break; |
| 72493 | 72010 | } |
| 72494 | 72011 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 72495 | 72012 | |
| | @@ -72500,55 +72017,53 @@ |
| 72500 | 72017 | ** Store the value of the P2-th column of |
| 72501 | 72018 | ** the row of the virtual-table that the |
| 72502 | 72019 | ** P1 cursor is pointing to into register P3. |
| 72503 | 72020 | */ |
| 72504 | 72021 | case OP_VColumn: { |
| 72505 | | -#if 0 /* local variables moved into u.co */ |
| 72506 | 72022 | sqlite3_vtab *pVtab; |
| 72507 | 72023 | const sqlite3_module *pModule; |
| 72508 | 72024 | Mem *pDest; |
| 72509 | 72025 | sqlite3_context sContext; |
| 72510 | | -#endif /* local variables moved into u.co */ |
| 72511 | 72026 | |
| 72512 | 72027 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 72513 | 72028 | assert( pCur->pVtabCursor ); |
| 72514 | 72029 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 72515 | | - u.co.pDest = &aMem[pOp->p3]; |
| 72516 | | - memAboutToChange(p, u.co.pDest); |
| 72030 | + pDest = &aMem[pOp->p3]; |
| 72031 | + memAboutToChange(p, pDest); |
| 72517 | 72032 | if( pCur->nullRow ){ |
| 72518 | | - sqlite3VdbeMemSetNull(u.co.pDest); |
| 72033 | + sqlite3VdbeMemSetNull(pDest); |
| 72519 | 72034 | break; |
| 72520 | 72035 | } |
| 72521 | | - u.co.pVtab = pCur->pVtabCursor->pVtab; |
| 72522 | | - u.co.pModule = u.co.pVtab->pModule; |
| 72523 | | - assert( u.co.pModule->xColumn ); |
| 72524 | | - memset(&u.co.sContext, 0, sizeof(u.co.sContext)); |
| 72036 | + pVtab = pCur->pVtabCursor->pVtab; |
| 72037 | + pModule = pVtab->pModule; |
| 72038 | + assert( pModule->xColumn ); |
| 72039 | + memset(&sContext, 0, sizeof(sContext)); |
| 72525 | 72040 | |
| 72526 | 72041 | /* The output cell may already have a buffer allocated. Move |
| 72527 | | - ** the current contents to u.co.sContext.s so in case the user-function |
| 72528 | | - ** can use the already allocated buffer instead of allocating a |
| 72042 | + ** the current contents to sContext.s so in case the user-function |
| 72043 | + ** can use the already allocated buffer instead of allocating a |
| 72529 | 72044 | ** new one. |
| 72530 | 72045 | */ |
| 72531 | | - sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest); |
| 72532 | | - MemSetTypeFlag(&u.co.sContext.s, MEM_Null); |
| 72046 | + sqlite3VdbeMemMove(&sContext.s, pDest); |
| 72047 | + MemSetTypeFlag(&sContext.s, MEM_Null); |
| 72533 | 72048 | |
| 72534 | | - rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2); |
| 72535 | | - sqlite3VtabImportErrmsg(p, u.co.pVtab); |
| 72536 | | - if( u.co.sContext.isError ){ |
| 72537 | | - rc = u.co.sContext.isError; |
| 72049 | + rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); |
| 72050 | + sqlite3VtabImportErrmsg(p, pVtab); |
| 72051 | + if( sContext.isError ){ |
| 72052 | + rc = sContext.isError; |
| 72538 | 72053 | } |
| 72539 | 72054 | |
| 72540 | 72055 | /* Copy the result of the function to the P3 register. We |
| 72541 | 72056 | ** do this regardless of whether or not an error occurred to ensure any |
| 72542 | | - ** dynamic allocation in u.co.sContext.s (a Mem struct) is released. |
| 72057 | + ** dynamic allocation in sContext.s (a Mem struct) is released. |
| 72543 | 72058 | */ |
| 72544 | | - sqlite3VdbeChangeEncoding(&u.co.sContext.s, encoding); |
| 72545 | | - sqlite3VdbeMemMove(u.co.pDest, &u.co.sContext.s); |
| 72546 | | - REGISTER_TRACE(pOp->p3, u.co.pDest); |
| 72547 | | - UPDATE_MAX_BLOBSIZE(u.co.pDest); |
| 72059 | + sqlite3VdbeChangeEncoding(&sContext.s, encoding); |
| 72060 | + sqlite3VdbeMemMove(pDest, &sContext.s); |
| 72061 | + REGISTER_TRACE(pOp->p3, pDest); |
| 72062 | + UPDATE_MAX_BLOBSIZE(pDest); |
| 72548 | 72063 | |
| 72549 | | - if( sqlite3VdbeMemTooBig(u.co.pDest) ){ |
| 72064 | + if( sqlite3VdbeMemTooBig(pDest) ){ |
| 72550 | 72065 | goto too_big; |
| 72551 | 72066 | } |
| 72552 | 72067 | break; |
| 72553 | 72068 | } |
| 72554 | 72069 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| | @@ -72559,42 +72074,40 @@ |
| 72559 | 72074 | ** Advance virtual table P1 to the next row in its result set and |
| 72560 | 72075 | ** jump to instruction P2. Or, if the virtual table has reached |
| 72561 | 72076 | ** the end of its result set, then fall through to the next instruction. |
| 72562 | 72077 | */ |
| 72563 | 72078 | case OP_VNext: { /* jump */ |
| 72564 | | -#if 0 /* local variables moved into u.cp */ |
| 72565 | 72079 | sqlite3_vtab *pVtab; |
| 72566 | 72080 | const sqlite3_module *pModule; |
| 72567 | 72081 | int res; |
| 72568 | 72082 | VdbeCursor *pCur; |
| 72569 | | -#endif /* local variables moved into u.cp */ |
| 72570 | 72083 | |
| 72571 | | - u.cp.res = 0; |
| 72572 | | - u.cp.pCur = p->apCsr[pOp->p1]; |
| 72573 | | - assert( u.cp.pCur->pVtabCursor ); |
| 72574 | | - if( u.cp.pCur->nullRow ){ |
| 72084 | + res = 0; |
| 72085 | + pCur = p->apCsr[pOp->p1]; |
| 72086 | + assert( pCur->pVtabCursor ); |
| 72087 | + if( pCur->nullRow ){ |
| 72575 | 72088 | break; |
| 72576 | 72089 | } |
| 72577 | | - u.cp.pVtab = u.cp.pCur->pVtabCursor->pVtab; |
| 72578 | | - u.cp.pModule = u.cp.pVtab->pModule; |
| 72579 | | - assert( u.cp.pModule->xNext ); |
| 72090 | + pVtab = pCur->pVtabCursor->pVtab; |
| 72091 | + pModule = pVtab->pModule; |
| 72092 | + assert( pModule->xNext ); |
| 72580 | 72093 | |
| 72581 | 72094 | /* Invoke the xNext() method of the module. There is no way for the |
| 72582 | 72095 | ** underlying implementation to return an error if one occurs during |
| 72583 | | - ** xNext(). Instead, if an error occurs, true is returned (indicating that |
| 72096 | + ** xNext(). Instead, if an error occurs, true is returned (indicating that |
| 72584 | 72097 | ** data is available) and the error code returned when xColumn or |
| 72585 | 72098 | ** some other method is next invoked on the save virtual table cursor. |
| 72586 | 72099 | */ |
| 72587 | 72100 | p->inVtabMethod = 1; |
| 72588 | | - rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor); |
| 72101 | + rc = pModule->xNext(pCur->pVtabCursor); |
| 72589 | 72102 | p->inVtabMethod = 0; |
| 72590 | | - sqlite3VtabImportErrmsg(p, u.cp.pVtab); |
| 72103 | + sqlite3VtabImportErrmsg(p, pVtab); |
| 72591 | 72104 | if( rc==SQLITE_OK ){ |
| 72592 | | - u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor); |
| 72105 | + res = pModule->xEof(pCur->pVtabCursor); |
| 72593 | 72106 | } |
| 72594 | 72107 | |
| 72595 | | - if( !u.cp.res ){ |
| 72108 | + if( !res ){ |
| 72596 | 72109 | /* If there is data, jump to P2 */ |
| 72597 | 72110 | pc = pOp->p2 - 1; |
| 72598 | 72111 | } |
| 72599 | 72112 | goto check_for_interrupt; |
| 72600 | 72113 | } |
| | @@ -72606,29 +72119,27 @@ |
| 72606 | 72119 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
| 72607 | 72120 | ** This opcode invokes the corresponding xRename method. The value |
| 72608 | 72121 | ** in register P1 is passed as the zName argument to the xRename method. |
| 72609 | 72122 | */ |
| 72610 | 72123 | case OP_VRename: { |
| 72611 | | -#if 0 /* local variables moved into u.cq */ |
| 72612 | 72124 | sqlite3_vtab *pVtab; |
| 72613 | 72125 | Mem *pName; |
| 72614 | | -#endif /* local variables moved into u.cq */ |
| 72615 | 72126 | |
| 72616 | | - u.cq.pVtab = pOp->p4.pVtab->pVtab; |
| 72617 | | - u.cq.pName = &aMem[pOp->p1]; |
| 72618 | | - assert( u.cq.pVtab->pModule->xRename ); |
| 72619 | | - assert( memIsValid(u.cq.pName) ); |
| 72127 | + pVtab = pOp->p4.pVtab->pVtab; |
| 72128 | + pName = &aMem[pOp->p1]; |
| 72129 | + assert( pVtab->pModule->xRename ); |
| 72130 | + assert( memIsValid(pName) ); |
| 72620 | 72131 | assert( p->readOnly==0 ); |
| 72621 | | - REGISTER_TRACE(pOp->p1, u.cq.pName); |
| 72622 | | - assert( u.cq.pName->flags & MEM_Str ); |
| 72623 | | - testcase( u.cq.pName->enc==SQLITE_UTF8 ); |
| 72624 | | - testcase( u.cq.pName->enc==SQLITE_UTF16BE ); |
| 72625 | | - testcase( u.cq.pName->enc==SQLITE_UTF16LE ); |
| 72626 | | - rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8); |
| 72132 | + REGISTER_TRACE(pOp->p1, pName); |
| 72133 | + assert( pName->flags & MEM_Str ); |
| 72134 | + testcase( pName->enc==SQLITE_UTF8 ); |
| 72135 | + testcase( pName->enc==SQLITE_UTF16BE ); |
| 72136 | + testcase( pName->enc==SQLITE_UTF16LE ); |
| 72137 | + rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); |
| 72627 | 72138 | if( rc==SQLITE_OK ){ |
| 72628 | | - rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z); |
| 72629 | | - sqlite3VtabImportErrmsg(p, u.cq.pVtab); |
| 72139 | + rc = pVtab->pModule->xRename(pVtab, pName->z); |
| 72140 | + sqlite3VtabImportErrmsg(p, pVtab); |
| 72630 | 72141 | p->expired = 0; |
| 72631 | 72142 | } |
| 72632 | 72143 | break; |
| 72633 | 72144 | } |
| 72634 | 72145 | #endif |
| | @@ -72657,46 +72168,44 @@ |
| 72657 | 72168 | ** P1 is a boolean flag. If it is set to true and the xUpdate call |
| 72658 | 72169 | ** is successful, then the value returned by sqlite3_last_insert_rowid() |
| 72659 | 72170 | ** is set to the value of the rowid for the row just inserted. |
| 72660 | 72171 | */ |
| 72661 | 72172 | case OP_VUpdate: { |
| 72662 | | -#if 0 /* local variables moved into u.cr */ |
| 72663 | 72173 | sqlite3_vtab *pVtab; |
| 72664 | 72174 | sqlite3_module *pModule; |
| 72665 | 72175 | int nArg; |
| 72666 | 72176 | int i; |
| 72667 | 72177 | sqlite_int64 rowid; |
| 72668 | 72178 | Mem **apArg; |
| 72669 | 72179 | Mem *pX; |
| 72670 | | -#endif /* local variables moved into u.cr */ |
| 72671 | 72180 | |
| 72672 | | - assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback |
| 72181 | + assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback |
| 72673 | 72182 | || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace |
| 72674 | 72183 | ); |
| 72675 | 72184 | assert( p->readOnly==0 ); |
| 72676 | | - u.cr.pVtab = pOp->p4.pVtab->pVtab; |
| 72677 | | - u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule; |
| 72678 | | - u.cr.nArg = pOp->p2; |
| 72185 | + pVtab = pOp->p4.pVtab->pVtab; |
| 72186 | + pModule = (sqlite3_module *)pVtab->pModule; |
| 72187 | + nArg = pOp->p2; |
| 72679 | 72188 | assert( pOp->p4type==P4_VTAB ); |
| 72680 | | - if( ALWAYS(u.cr.pModule->xUpdate) ){ |
| 72189 | + if( ALWAYS(pModule->xUpdate) ){ |
| 72681 | 72190 | u8 vtabOnConflict = db->vtabOnConflict; |
| 72682 | | - u.cr.apArg = p->apArg; |
| 72683 | | - u.cr.pX = &aMem[pOp->p3]; |
| 72684 | | - for(u.cr.i=0; u.cr.i<u.cr.nArg; u.cr.i++){ |
| 72685 | | - assert( memIsValid(u.cr.pX) ); |
| 72686 | | - memAboutToChange(p, u.cr.pX); |
| 72687 | | - sqlite3VdbeMemStoreType(u.cr.pX); |
| 72688 | | - u.cr.apArg[u.cr.i] = u.cr.pX; |
| 72689 | | - u.cr.pX++; |
| 72191 | + apArg = p->apArg; |
| 72192 | + pX = &aMem[pOp->p3]; |
| 72193 | + for(i=0; i<nArg; i++){ |
| 72194 | + assert( memIsValid(pX) ); |
| 72195 | + memAboutToChange(p, pX); |
| 72196 | + sqlite3VdbeMemStoreType(pX); |
| 72197 | + apArg[i] = pX; |
| 72198 | + pX++; |
| 72690 | 72199 | } |
| 72691 | 72200 | db->vtabOnConflict = pOp->p5; |
| 72692 | | - rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid); |
| 72201 | + rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); |
| 72693 | 72202 | db->vtabOnConflict = vtabOnConflict; |
| 72694 | | - sqlite3VtabImportErrmsg(p, u.cr.pVtab); |
| 72203 | + sqlite3VtabImportErrmsg(p, pVtab); |
| 72695 | 72204 | if( rc==SQLITE_OK && pOp->p1 ){ |
| 72696 | | - assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) ); |
| 72697 | | - db->lastRowid = lastRowid = u.cr.rowid; |
| 72205 | + assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); |
| 72206 | + db->lastRowid = lastRowid = rowid; |
| 72698 | 72207 | } |
| 72699 | 72208 | if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ |
| 72700 | 72209 | if( pOp->p5==OE_Ignore ){ |
| 72701 | 72210 | rc = SQLITE_OK; |
| 72702 | 72211 | }else{ |
| | @@ -72752,38 +72261,36 @@ |
| 72752 | 72261 | ** |
| 72753 | 72262 | ** If tracing is enabled (by the sqlite3_trace()) interface, then |
| 72754 | 72263 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 72755 | 72264 | */ |
| 72756 | 72265 | case OP_Trace: { |
| 72757 | | -#if 0 /* local variables moved into u.cs */ |
| 72758 | 72266 | char *zTrace; |
| 72759 | 72267 | char *z; |
| 72760 | | -#endif /* local variables moved into u.cs */ |
| 72761 | 72268 | |
| 72762 | 72269 | if( db->xTrace |
| 72763 | 72270 | && !p->doingRerun |
| 72764 | | - && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 72271 | + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 72765 | 72272 | ){ |
| 72766 | | - u.cs.z = sqlite3VdbeExpandSql(p, u.cs.zTrace); |
| 72767 | | - db->xTrace(db->pTraceArg, u.cs.z); |
| 72768 | | - sqlite3DbFree(db, u.cs.z); |
| 72273 | + z = sqlite3VdbeExpandSql(p, zTrace); |
| 72274 | + db->xTrace(db->pTraceArg, z); |
| 72275 | + sqlite3DbFree(db, z); |
| 72769 | 72276 | } |
| 72770 | 72277 | #ifdef SQLITE_USE_FCNTL_TRACE |
| 72771 | | - u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 72772 | | - if( u.cs.zTrace ){ |
| 72278 | + zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 72279 | + if( zTrace ){ |
| 72773 | 72280 | int i; |
| 72774 | 72281 | for(i=0; i<db->nDb; i++){ |
| 72775 | 72282 | if( ((1<<i) & p->btreeMask)==0 ) continue; |
| 72776 | | - sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, u.cs.zTrace); |
| 72283 | + sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); |
| 72777 | 72284 | } |
| 72778 | 72285 | } |
| 72779 | 72286 | #endif /* SQLITE_USE_FCNTL_TRACE */ |
| 72780 | 72287 | #ifdef SQLITE_DEBUG |
| 72781 | 72288 | if( (db->flags & SQLITE_SqlTrace)!=0 |
| 72782 | | - && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 72289 | + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 72783 | 72290 | ){ |
| 72784 | | - sqlite3DebugPrintf("SQL-trace: %s\n", u.cs.zTrace); |
| 72291 | + sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); |
| 72785 | 72292 | } |
| 72786 | 72293 | #endif /* SQLITE_DEBUG */ |
| 72787 | 72294 | break; |
| 72788 | 72295 | } |
| 72789 | 72296 | #endif |
| | @@ -72832,17 +72339,17 @@ |
| 72832 | 72339 | */ |
| 72833 | 72340 | #ifndef NDEBUG |
| 72834 | 72341 | assert( pc>=-1 && pc<p->nOp ); |
| 72835 | 72342 | |
| 72836 | 72343 | #ifdef SQLITE_DEBUG |
| 72837 | | - if( p->trace ){ |
| 72838 | | - if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc); |
| 72344 | + if( db->flags & SQLITE_VdbeTrace ){ |
| 72345 | + if( rc!=0 ) printf("rc=%d\n",rc); |
| 72839 | 72346 | if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){ |
| 72840 | | - registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]); |
| 72347 | + registerTrace(pOp->p2, &aMem[pOp->p2]); |
| 72841 | 72348 | } |
| 72842 | 72349 | if( pOp->opflags & OPFLG_OUT3 ){ |
| 72843 | | - registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]); |
| 72350 | + registerTrace(pOp->p3, &aMem[pOp->p3]); |
| 72844 | 72351 | } |
| 72845 | 72352 | } |
| 72846 | 72353 | #endif /* SQLITE_DEBUG */ |
| 72847 | 72354 | #endif /* NDEBUG */ |
| 72848 | 72355 | } /* The end of the for(;;) loop the loops through opcodes */ |
| | @@ -72908,10 +72415,11 @@ |
| 72908 | 72415 | rc = SQLITE_INTERRUPT; |
| 72909 | 72416 | p->rc = rc; |
| 72910 | 72417 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc)); |
| 72911 | 72418 | goto vdbe_error_halt; |
| 72912 | 72419 | } |
| 72420 | + |
| 72913 | 72421 | |
| 72914 | 72422 | /************** End of vdbe.c ************************************************/ |
| 72915 | 72423 | /************** Begin file vdbeblob.c ****************************************/ |
| 72916 | 72424 | /* |
| 72917 | 72425 | ** 2007 May 1 |
| | @@ -72975,22 +72483,23 @@ |
| 72975 | 72483 | assert( v->aVar[0].flags&MEM_Int ); |
| 72976 | 72484 | v->aVar[0].u.i = iRow; |
| 72977 | 72485 | |
| 72978 | 72486 | rc = sqlite3_step(p->pStmt); |
| 72979 | 72487 | if( rc==SQLITE_ROW ){ |
| 72980 | | - u32 type = v->apCsr[0]->aType[p->iCol]; |
| 72488 | + VdbeCursor *pC = v->apCsr[0]; |
| 72489 | + u32 type = pC->aType[p->iCol]; |
| 72981 | 72490 | if( type<12 ){ |
| 72982 | 72491 | zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", |
| 72983 | 72492 | type==0?"null": type==7?"real": "integer" |
| 72984 | 72493 | ); |
| 72985 | 72494 | rc = SQLITE_ERROR; |
| 72986 | 72495 | sqlite3_finalize(p->pStmt); |
| 72987 | 72496 | p->pStmt = 0; |
| 72988 | 72497 | }else{ |
| 72989 | | - p->iOffset = v->apCsr[0]->aOffset[p->iCol]; |
| 72498 | + p->iOffset = pC->aType[p->iCol + pC->nField]; |
| 72990 | 72499 | p->nByte = sqlite3VdbeSerialTypeLen(type); |
| 72991 | | - p->pCsr = v->apCsr[0]->pCursor; |
| 72500 | + p->pCsr = pC->pCursor; |
| 72992 | 72501 | sqlite3BtreeEnterCursor(p->pCsr); |
| 72993 | 72502 | sqlite3BtreeCacheOverflow(p->pCsr); |
| 72994 | 72503 | sqlite3BtreeLeaveCursor(p->pCsr); |
| 72995 | 72504 | } |
| 72996 | 72505 | } |
| | @@ -73239,10 +72748,11 @@ |
| 73239 | 72748 | if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); |
| 73240 | 72749 | sqlite3DbFree(db, pBlob); |
| 73241 | 72750 | } |
| 73242 | 72751 | sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); |
| 73243 | 72752 | sqlite3DbFree(db, zErr); |
| 72753 | + sqlite3ParserReset(pParse); |
| 73244 | 72754 | sqlite3StackFree(db, pParse); |
| 73245 | 72755 | rc = sqlite3ApiExit(db, rc); |
| 73246 | 72756 | sqlite3_mutex_leave(db->mutex); |
| 73247 | 72757 | return rc; |
| 73248 | 72758 | } |
| | @@ -75204,14 +74714,14 @@ |
| 75204 | 74714 | if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ |
| 75205 | 74715 | incrAggFunctionDepth(pDup, nSubquery); |
| 75206 | 74716 | pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); |
| 75207 | 74717 | if( pDup==0 ) return; |
| 75208 | 74718 | ExprSetProperty(pDup, EP_Skip); |
| 75209 | | - if( pEList->a[iCol].iAlias==0 ){ |
| 75210 | | - pEList->a[iCol].iAlias = (u16)(++pParse->nAlias); |
| 74719 | + if( pEList->a[iCol].u.x.iAlias==0 ){ |
| 74720 | + pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias); |
| 75211 | 74721 | } |
| 75212 | | - pDup->iTable = pEList->a[iCol].iAlias; |
| 74722 | + pDup->iTable = pEList->a[iCol].u.x.iAlias; |
| 75213 | 74723 | } |
| 75214 | 74724 | if( pExpr->op==TK_COLLATE ){ |
| 75215 | 74725 | pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); |
| 75216 | 74726 | } |
| 75217 | 74727 | |
| | @@ -75448,11 +74958,13 @@ |
| 75448 | 74958 | } |
| 75449 | 74959 | break; |
| 75450 | 74960 | } |
| 75451 | 74961 | } |
| 75452 | 74962 | if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){ |
| 75453 | | - iCol = -1; /* IMP: R-44911-55124 */ |
| 74963 | + /* IMP: R-24309-18625 */ |
| 74964 | + /* IMP: R-44911-55124 */ |
| 74965 | + iCol = -1; |
| 75454 | 74966 | } |
| 75455 | 74967 | if( iCol<pTab->nCol ){ |
| 75456 | 74968 | cnt++; |
| 75457 | 74969 | if( iCol<0 ){ |
| 75458 | 74970 | pExpr->affinity = SQLITE_AFF_INTEGER; |
| | @@ -75763,11 +75275,10 @@ |
| 75763 | 75275 | return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); |
| 75764 | 75276 | } |
| 75765 | 75277 | |
| 75766 | 75278 | /* Resolve function names |
| 75767 | 75279 | */ |
| 75768 | | - case TK_CONST_FUNC: |
| 75769 | 75280 | case TK_FUNCTION: { |
| 75770 | 75281 | ExprList *pList = pExpr->x.pList; /* The argument list */ |
| 75771 | 75282 | int n = pList ? pList->nExpr : 0; /* Number of arguments */ |
| 75772 | 75283 | int no_such_func = 0; /* True if no such function exists */ |
| 75773 | 75284 | int wrong_num_args = 0; /* True if wrong number of arguments */ |
| | @@ -75776,11 +75287,10 @@ |
| 75776 | 75287 | int nId; /* Number of characters in function name */ |
| 75777 | 75288 | const char *zId; /* The function name. */ |
| 75778 | 75289 | FuncDef *pDef; /* Information about the function */ |
| 75779 | 75290 | u8 enc = ENC(pParse->db); /* The database encoding */ |
| 75780 | 75291 | |
| 75781 | | - testcase( pExpr->op==TK_CONST_FUNC ); |
| 75782 | 75292 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 75783 | 75293 | notValidPartIdxWhere(pParse, pNC, "functions"); |
| 75784 | 75294 | zId = pExpr->u.zToken; |
| 75785 | 75295 | nId = sqlite3Strlen30(zId); |
| 75786 | 75296 | pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); |
| | @@ -75821,10 +75331,11 @@ |
| 75821 | 75331 | pNC->nErr++; |
| 75822 | 75332 | } |
| 75823 | 75333 | pExpr->op = TK_NULL; |
| 75824 | 75334 | return WRC_Prune; |
| 75825 | 75335 | } |
| 75336 | + if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant); |
| 75826 | 75337 | } |
| 75827 | 75338 | #endif |
| 75828 | 75339 | if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ |
| 75829 | 75340 | sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); |
| 75830 | 75341 | pNC->nErr++; |
| | @@ -76072,11 +75583,11 @@ |
| 76072 | 75583 | assert( pItem->pExpr->op==TK_COLLATE ); |
| 76073 | 75584 | assert( pItem->pExpr->pLeft==pE ); |
| 76074 | 75585 | pItem->pExpr->pLeft = pNew; |
| 76075 | 75586 | } |
| 76076 | 75587 | sqlite3ExprDelete(db, pE); |
| 76077 | | - pItem->iOrderByCol = (u16)iCol; |
| 75588 | + pItem->u.x.iOrderByCol = (u16)iCol; |
| 76078 | 75589 | pItem->done = 1; |
| 76079 | 75590 | }else{ |
| 76080 | 75591 | moreToDo = 1; |
| 76081 | 75592 | } |
| 76082 | 75593 | } |
| | @@ -76093,12 +75604,12 @@ |
| 76093 | 75604 | } |
| 76094 | 75605 | |
| 76095 | 75606 | /* |
| 76096 | 75607 | ** Check every term in the ORDER BY or GROUP BY clause pOrderBy of |
| 76097 | 75608 | ** the SELECT statement pSelect. If any term is reference to a |
| 76098 | | -** result set expression (as determined by the ExprList.a.iOrderByCol field) |
| 76099 | | -** then convert that term into a copy of the corresponding result set |
| 75609 | +** result set expression (as determined by the ExprList.a.u.x.iOrderByCol |
| 75610 | +** field) then convert that term into a copy of the corresponding result set |
| 76100 | 75611 | ** column. |
| 76101 | 75612 | ** |
| 76102 | 75613 | ** If any errors are detected, add an error message to pParse and |
| 76103 | 75614 | ** return non-zero. Return zero if no errors are seen. |
| 76104 | 75615 | */ |
| | @@ -76121,16 +75632,16 @@ |
| 76121 | 75632 | } |
| 76122 | 75633 | #endif |
| 76123 | 75634 | pEList = pSelect->pEList; |
| 76124 | 75635 | assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ |
| 76125 | 75636 | for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ |
| 76126 | | - if( pItem->iOrderByCol ){ |
| 76127 | | - if( pItem->iOrderByCol>pEList->nExpr ){ |
| 75637 | + if( pItem->u.x.iOrderByCol ){ |
| 75638 | + if( pItem->u.x.iOrderByCol>pEList->nExpr ){ |
| 76128 | 75639 | resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); |
| 76129 | 75640 | return 1; |
| 76130 | 75641 | } |
| 76131 | | - resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0); |
| 75642 | + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0); |
| 76132 | 75643 | } |
| 76133 | 75644 | } |
| 76134 | 75645 | return 0; |
| 76135 | 75646 | } |
| 76136 | 75647 | |
| | @@ -76175,11 +75686,11 @@ |
| 76175 | 75686 | if( iCol>0 ){ |
| 76176 | 75687 | /* If an AS-name match is found, mark this ORDER BY column as being |
| 76177 | 75688 | ** a copy of the iCol-th result-set column. The subsequent call to |
| 76178 | 75689 | ** sqlite3ResolveOrderGroupBy() will convert the expression to a |
| 76179 | 75690 | ** copy of the iCol-th result-set expression. */ |
| 76180 | | - pItem->iOrderByCol = (u16)iCol; |
| 75691 | + pItem->u.x.iOrderByCol = (u16)iCol; |
| 76181 | 75692 | continue; |
| 76182 | 75693 | } |
| 76183 | 75694 | } |
| 76184 | 75695 | if( sqlite3ExprIsInteger(pE2, &iCol) ){ |
| 76185 | 75696 | /* The ORDER BY term is an integer constant. Again, set the column |
| | @@ -76187,22 +75698,22 @@ |
| 76187 | 75698 | ** order-by term to a copy of the result-set expression */ |
| 76188 | 75699 | if( iCol<1 || iCol>0xffff ){ |
| 76189 | 75700 | resolveOutOfRangeError(pParse, zType, i+1, nResult); |
| 76190 | 75701 | return 1; |
| 76191 | 75702 | } |
| 76192 | | - pItem->iOrderByCol = (u16)iCol; |
| 75703 | + pItem->u.x.iOrderByCol = (u16)iCol; |
| 76193 | 75704 | continue; |
| 76194 | 75705 | } |
| 76195 | 75706 | |
| 76196 | 75707 | /* Otherwise, treat the ORDER BY term as an ordinary expression */ |
| 76197 | | - pItem->iOrderByCol = 0; |
| 75708 | + pItem->u.x.iOrderByCol = 0; |
| 76198 | 75709 | if( sqlite3ResolveExprNames(pNC, pE) ){ |
| 76199 | 75710 | return 1; |
| 76200 | 75711 | } |
| 76201 | 75712 | for(j=0; j<pSelect->pEList->nExpr; j++){ |
| 76202 | 75713 | if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ |
| 76203 | | - pItem->iOrderByCol = j+1; |
| 75714 | + pItem->u.x.iOrderByCol = j+1; |
| 76204 | 75715 | } |
| 76205 | 75716 | } |
| 76206 | 75717 | } |
| 76207 | 75718 | return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); |
| 76208 | 75719 | } |
| | @@ -77477,12 +76988,11 @@ |
| 77477 | 76988 | pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); |
| 77478 | 76989 | pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); |
| 77479 | 76990 | pItem->sortOrder = pOldItem->sortOrder; |
| 77480 | 76991 | pItem->done = 0; |
| 77481 | 76992 | pItem->bSpanIsTab = pOldItem->bSpanIsTab; |
| 77482 | | - pItem->iOrderByCol = pOldItem->iOrderByCol; |
| 77483 | | - pItem->iAlias = pOldItem->iAlias; |
| 76993 | + pItem->u = pOldItem->u; |
| 77484 | 76994 | } |
| 77485 | 76995 | return pNew; |
| 77486 | 76996 | } |
| 77487 | 76997 | |
| 77488 | 76998 | /* |
| | @@ -77739,13 +77249,16 @@ |
| 77739 | 77249 | return WRC_Abort; |
| 77740 | 77250 | } |
| 77741 | 77251 | |
| 77742 | 77252 | switch( pExpr->op ){ |
| 77743 | 77253 | /* Consider functions to be constant if all their arguments are constant |
| 77744 | | - ** and pWalker->u.i==2 */ |
| 77254 | + ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST |
| 77255 | + ** flag. */ |
| 77745 | 77256 | case TK_FUNCTION: |
| 77746 | | - if( pWalker->u.i==2 ) return 0; |
| 77257 | + if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){ |
| 77258 | + return WRC_Continue; |
| 77259 | + } |
| 77747 | 77260 | /* Fall through */ |
| 77748 | 77261 | case TK_ID: |
| 77749 | 77262 | case TK_COLUMN: |
| 77750 | 77263 | case TK_AGG_FUNCTION: |
| 77751 | 77264 | case TK_AGG_COLUMN: |
| | @@ -78903,10 +78416,11 @@ |
| 78903 | 78416 | int inReg = target; /* Results stored in register inReg */ |
| 78904 | 78417 | int regFree1 = 0; /* If non-zero free this temporary register */ |
| 78905 | 78418 | int regFree2 = 0; /* If non-zero free this temporary register */ |
| 78906 | 78419 | int r1, r2, r3, r4; /* Various register numbers */ |
| 78907 | 78420 | sqlite3 *db = pParse->db; /* The database connection */ |
| 78421 | + Expr tempX; /* Temporary expression node */ |
| 78908 | 78422 | |
| 78909 | 78423 | assert( target>0 && target<=pParse->nMem ); |
| 78910 | 78424 | if( v==0 ){ |
| 78911 | 78425 | assert( pParse->db->mallocFailed ); |
| 78912 | 78426 | return 0; |
| | @@ -79122,12 +78636,14 @@ |
| 79122 | 78636 | }else if( pLeft->op==TK_FLOAT ){ |
| 79123 | 78637 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 79124 | 78638 | codeReal(v, pLeft->u.zToken, 1, target); |
| 79125 | 78639 | #endif |
| 79126 | 78640 | }else{ |
| 79127 | | - regFree1 = r1 = sqlite3GetTempReg(pParse); |
| 79128 | | - sqlite3VdbeAddOp2(v, OP_Integer, 0, r1); |
| 78641 | + tempX.op = TK_INTEGER; |
| 78642 | + tempX.flags = EP_IntValue|EP_TokenOnly; |
| 78643 | + tempX.u.iValue = 0; |
| 78644 | + r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1); |
| 79129 | 78645 | r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); |
| 79130 | 78646 | sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); |
| 79131 | 78647 | testcase( regFree2==0 ); |
| 79132 | 78648 | } |
| 79133 | 78649 | inReg = target; |
| | @@ -79168,11 +78684,10 @@ |
| 79168 | 78684 | }else{ |
| 79169 | 78685 | inReg = pInfo->aFunc[pExpr->iAgg].iMem; |
| 79170 | 78686 | } |
| 79171 | 78687 | break; |
| 79172 | 78688 | } |
| 79173 | | - case TK_CONST_FUNC: |
| 79174 | 78689 | case TK_FUNCTION: { |
| 79175 | 78690 | ExprList *pFarg; /* List of function arguments */ |
| 79176 | 78691 | int nFarg; /* Number of function arguments */ |
| 79177 | 78692 | FuncDef *pDef; /* The function definition object */ |
| 79178 | 78693 | int nId; /* Length of the function name in bytes */ |
| | @@ -79181,12 +78696,10 @@ |
| 79181 | 78696 | int i; /* Loop counter */ |
| 79182 | 78697 | u8 enc = ENC(db); /* The text encoding used by this database */ |
| 79183 | 78698 | CollSeq *pColl = 0; /* A collating sequence */ |
| 79184 | 78699 | |
| 79185 | 78700 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 79186 | | - testcase( op==TK_CONST_FUNC ); |
| 79187 | | - testcase( op==TK_FUNCTION ); |
| 79188 | 78701 | if( ExprHasProperty(pExpr, EP_TokenOnly) ){ |
| 79189 | 78702 | pFarg = 0; |
| 79190 | 78703 | }else{ |
| 79191 | 78704 | pFarg = pExpr->x.pList; |
| 79192 | 78705 | } |
| | @@ -79226,12 +78739,25 @@ |
| 79226 | 78739 | assert( nFarg>=1 ); |
| 79227 | 78740 | sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); |
| 79228 | 78741 | break; |
| 79229 | 78742 | } |
| 79230 | 78743 | |
| 78744 | + for(i=0; i<nFarg; i++){ |
| 78745 | + if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ |
| 78746 | + constMask |= (1<<i); |
| 78747 | + } |
| 78748 | + if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ |
| 78749 | + pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); |
| 78750 | + } |
| 78751 | + } |
| 79231 | 78752 | if( pFarg ){ |
| 79232 | | - r1 = sqlite3GetTempRange(pParse, nFarg); |
| 78753 | + if( constMask ){ |
| 78754 | + r1 = pParse->nMem+1; |
| 78755 | + pParse->nMem += nFarg; |
| 78756 | + }else{ |
| 78757 | + r1 = sqlite3GetTempRange(pParse, nFarg); |
| 78758 | + } |
| 79233 | 78759 | |
| 79234 | 78760 | /* For length() and typeof() functions with a column argument, |
| 79235 | 78761 | ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG |
| 79236 | 78762 | ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data |
| 79237 | 78763 | ** loading. |
| | @@ -79242,18 +78768,19 @@ |
| 79242 | 78768 | assert( pFarg->a[0].pExpr!=0 ); |
| 79243 | 78769 | exprOp = pFarg->a[0].pExpr->op; |
| 79244 | 78770 | if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ |
| 79245 | 78771 | assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); |
| 79246 | 78772 | assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); |
| 79247 | | - testcase( (pDef->funcFlags&~SQLITE_FUNC_ENCMASK) |
| 79248 | | - ==SQLITE_FUNC_LENGTH ); |
| 79249 | | - pFarg->a[0].pExpr->op2 = pDef->funcFlags&~SQLITE_FUNC_ENCMASK; |
| 78773 | + testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); |
| 78774 | + pFarg->a[0].pExpr->op2 = |
| 78775 | + pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); |
| 79250 | 78776 | } |
| 79251 | 78777 | } |
| 79252 | 78778 | |
| 79253 | 78779 | sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ |
| 79254 | | - sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); |
| 78780 | + sqlite3ExprCodeExprList(pParse, pFarg, r1, |
| 78781 | + SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); |
| 79255 | 78782 | sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ |
| 79256 | 78783 | }else{ |
| 79257 | 78784 | r1 = 0; |
| 79258 | 78785 | } |
| 79259 | 78786 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| | @@ -79273,26 +78800,18 @@ |
| 79273 | 78800 | pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); |
| 79274 | 78801 | }else if( nFarg>0 ){ |
| 79275 | 78802 | pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); |
| 79276 | 78803 | } |
| 79277 | 78804 | #endif |
| 79278 | | - for(i=0; i<nFarg; i++){ |
| 79279 | | - if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ |
| 79280 | | - constMask |= (1<<i); |
| 79281 | | - } |
| 79282 | | - if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ |
| 79283 | | - pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); |
| 79284 | | - } |
| 79285 | | - } |
| 79286 | 78805 | if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ |
| 79287 | 78806 | if( !pColl ) pColl = db->pDfltColl; |
| 79288 | 78807 | sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); |
| 79289 | 78808 | } |
| 79290 | 78809 | sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target, |
| 79291 | 78810 | (char*)pDef, P4_FUNCDEF); |
| 79292 | 78811 | sqlite3VdbeChangeP5(v, (u8)nFarg); |
| 79293 | | - if( nFarg ){ |
| 78812 | + if( nFarg && constMask==0 ){ |
| 79294 | 78813 | sqlite3ReleaseTempRange(pParse, r1, nFarg); |
| 79295 | 78814 | } |
| 79296 | 78815 | break; |
| 79297 | 78816 | } |
| 79298 | 78817 | #ifndef SQLITE_OMIT_SUBQUERY |
| | @@ -79439,11 +78958,10 @@ |
| 79439 | 78958 | int nExpr; /* 2x number of WHEN terms */ |
| 79440 | 78959 | int i; /* Loop counter */ |
| 79441 | 78960 | ExprList *pEList; /* List of WHEN terms */ |
| 79442 | 78961 | struct ExprList_item *aListelem; /* Array of WHEN terms */ |
| 79443 | 78962 | Expr opCompare; /* The X==Ei expression */ |
| 79444 | | - Expr cacheX; /* Cached expression X */ |
| 79445 | 78963 | Expr *pX; /* The X expression */ |
| 79446 | 78964 | Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ |
| 79447 | 78965 | VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) |
| 79448 | 78966 | |
| 79449 | 78967 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); |
| | @@ -79451,17 +78969,16 @@ |
| 79451 | 78969 | pEList = pExpr->x.pList; |
| 79452 | 78970 | aListelem = pEList->a; |
| 79453 | 78971 | nExpr = pEList->nExpr; |
| 79454 | 78972 | endLabel = sqlite3VdbeMakeLabel(v); |
| 79455 | 78973 | if( (pX = pExpr->pLeft)!=0 ){ |
| 79456 | | - cacheX = *pX; |
| 78974 | + tempX = *pX; |
| 79457 | 78975 | testcase( pX->op==TK_COLUMN ); |
| 79458 | | - testcase( pX->op==TK_REGISTER ); |
| 79459 | | - exprToRegister(&cacheX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); |
| 78976 | + exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); |
| 79460 | 78977 | testcase( regFree1==0 ); |
| 79461 | 78978 | opCompare.op = TK_EQ; |
| 79462 | | - opCompare.pLeft = &cacheX; |
| 78979 | + opCompare.pLeft = &tempX; |
| 79463 | 78980 | pTest = &opCompare; |
| 79464 | 78981 | /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: |
| 79465 | 78982 | ** The value in regFree1 might get SCopy-ed into the file result. |
| 79466 | 78983 | ** So make sure that the regFree1 register is not reused for other |
| 79467 | 78984 | ** purposes and possibly overwritten. */ |
| | @@ -79477,11 +78994,10 @@ |
| 79477 | 78994 | } |
| 79478 | 78995 | nextCase = sqlite3VdbeMakeLabel(v); |
| 79479 | 78996 | testcase( pTest->op==TK_COLUMN ); |
| 79480 | 78997 | sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); |
| 79481 | 78998 | testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); |
| 79482 | | - testcase( aListelem[i+1].pExpr->op==TK_REGISTER ); |
| 79483 | 78999 | sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); |
| 79484 | 79000 | sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); |
| 79485 | 79001 | sqlite3ExprCachePop(pParse, 1); |
| 79486 | 79002 | sqlite3VdbeResolveLabel(v, nextCase); |
| 79487 | 79003 | } |
| | @@ -79527,28 +79043,75 @@ |
| 79527 | 79043 | } |
| 79528 | 79044 | sqlite3ReleaseTempReg(pParse, regFree1); |
| 79529 | 79045 | sqlite3ReleaseTempReg(pParse, regFree2); |
| 79530 | 79046 | return inReg; |
| 79531 | 79047 | } |
| 79048 | + |
| 79049 | +/* |
| 79050 | +** Factor out the code of the given expression to initialization time. |
| 79051 | +*/ |
| 79052 | +SQLITE_PRIVATE void sqlite3ExprCodeAtInit( |
| 79053 | + Parse *pParse, /* Parsing context */ |
| 79054 | + Expr *pExpr, /* The expression to code when the VDBE initializes */ |
| 79055 | + int regDest, /* Store the value in this register */ |
| 79056 | + u8 reusable /* True if this expression is reusable */ |
| 79057 | +){ |
| 79058 | + ExprList *p; |
| 79059 | + assert( ConstFactorOk(pParse) ); |
| 79060 | + p = pParse->pConstExpr; |
| 79061 | + pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); |
| 79062 | + p = sqlite3ExprListAppend(pParse, p, pExpr); |
| 79063 | + if( p ){ |
| 79064 | + struct ExprList_item *pItem = &p->a[p->nExpr-1]; |
| 79065 | + pItem->u.iConstExprReg = regDest; |
| 79066 | + pItem->reusable = reusable; |
| 79067 | + } |
| 79068 | + pParse->pConstExpr = p; |
| 79069 | +} |
| 79532 | 79070 | |
| 79533 | 79071 | /* |
| 79534 | 79072 | ** Generate code to evaluate an expression and store the results |
| 79535 | 79073 | ** into a register. Return the register number where the results |
| 79536 | 79074 | ** are stored. |
| 79537 | 79075 | ** |
| 79538 | 79076 | ** If the register is a temporary register that can be deallocated, |
| 79539 | 79077 | ** then write its number into *pReg. If the result register is not |
| 79540 | 79078 | ** a temporary, then set *pReg to zero. |
| 79079 | +** |
| 79080 | +** If pExpr is a constant, then this routine might generate this |
| 79081 | +** code to fill the register in the initialization section of the |
| 79082 | +** VDBE program, in order to factor it out of the evaluation loop. |
| 79541 | 79083 | */ |
| 79542 | 79084 | SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ |
| 79543 | | - int r1 = sqlite3GetTempReg(pParse); |
| 79544 | | - int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); |
| 79545 | | - if( r2==r1 ){ |
| 79546 | | - *pReg = r1; |
| 79085 | + int r2; |
| 79086 | + pExpr = sqlite3ExprSkipCollate(pExpr); |
| 79087 | + if( ConstFactorOk(pParse) |
| 79088 | + && pExpr->op!=TK_REGISTER |
| 79089 | + && sqlite3ExprIsConstantNotJoin(pExpr) |
| 79090 | + ){ |
| 79091 | + ExprList *p = pParse->pConstExpr; |
| 79092 | + int i; |
| 79093 | + *pReg = 0; |
| 79094 | + if( p ){ |
| 79095 | + struct ExprList_item *pItem; |
| 79096 | + for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ |
| 79097 | + if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){ |
| 79098 | + return pItem->u.iConstExprReg; |
| 79099 | + } |
| 79100 | + } |
| 79101 | + } |
| 79102 | + r2 = ++pParse->nMem; |
| 79103 | + sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1); |
| 79547 | 79104 | }else{ |
| 79548 | | - sqlite3ReleaseTempReg(pParse, r1); |
| 79549 | | - *pReg = 0; |
| 79105 | + int r1 = sqlite3GetTempReg(pParse); |
| 79106 | + r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); |
| 79107 | + if( r2==r1 ){ |
| 79108 | + *pReg = r1; |
| 79109 | + }else{ |
| 79110 | + sqlite3ReleaseTempReg(pParse, r1); |
| 79111 | + *pReg = 0; |
| 79112 | + } |
| 79550 | 79113 | } |
| 79551 | 79114 | return r2; |
| 79552 | 79115 | } |
| 79553 | 79116 | |
| 79554 | 79117 | /* |
| | @@ -79587,16 +79150,17 @@ |
| 79587 | 79150 | SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ |
| 79588 | 79151 | Vdbe *v = pParse->pVdbe; |
| 79589 | 79152 | int inReg; |
| 79590 | 79153 | inReg = sqlite3ExprCode(pParse, pExpr, target); |
| 79591 | 79154 | assert( target>0 ); |
| 79592 | | - /* This routine is called for terms to INSERT or UPDATE. And the only |
| 79593 | | - ** other place where expressions can be converted into TK_REGISTER is |
| 79594 | | - ** in WHERE clause processing. So as currently implemented, there is |
| 79595 | | - ** no way for a TK_REGISTER to exist here. But it seems prudent to |
| 79596 | | - ** keep the ALWAYS() in case the conditions above change with future |
| 79597 | | - ** modifications or enhancements. */ |
| 79155 | + /* The only place, other than this routine, where expressions can be |
| 79156 | + ** converted to TK_REGISTER is internal subexpressions in BETWEEN and |
| 79157 | + ** CASE operators. Neither ever calls this routine. And this routine |
| 79158 | + ** is never called twice on the same expression. Hence it is impossible |
| 79159 | + ** for the input to this routine to already be a register. Nevertheless, |
| 79160 | + ** it seems prudent to keep the ALWAYS() in case the conditions above |
| 79161 | + ** change with future modifications or enhancements. */ |
| 79598 | 79162 | if( ALWAYS(pExpr->op!=TK_REGISTER) ){ |
| 79599 | 79163 | int iMem; |
| 79600 | 79164 | iMem = ++pParse->nMem; |
| 79601 | 79165 | sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); |
| 79602 | 79166 | exprToRegister(pExpr, iMem); |
| | @@ -79724,11 +79288,10 @@ |
| 79724 | 79288 | sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken); |
| 79725 | 79289 | break; |
| 79726 | 79290 | } |
| 79727 | 79291 | |
| 79728 | 79292 | case TK_AGG_FUNCTION: |
| 79729 | | - case TK_CONST_FUNC: |
| 79730 | 79293 | case TK_FUNCTION: { |
| 79731 | 79294 | ExprList *pFarg; /* List of function arguments */ |
| 79732 | 79295 | if( ExprHasProperty(pExpr, EP_TokenOnly) ){ |
| 79733 | 79296 | pFarg = 0; |
| 79734 | 79297 | }else{ |
| | @@ -79874,169 +79437,46 @@ |
| 79874 | 79437 | } |
| 79875 | 79438 | sqlite3ExplainPop(pOut); |
| 79876 | 79439 | } |
| 79877 | 79440 | } |
| 79878 | 79441 | #endif /* SQLITE_DEBUG */ |
| 79879 | | - |
| 79880 | | -/* |
| 79881 | | -** Return TRUE if pExpr is an constant expression that is appropriate |
| 79882 | | -** for factoring out of a loop. Appropriate expressions are: |
| 79883 | | -** |
| 79884 | | -** * Any expression that evaluates to two or more opcodes. |
| 79885 | | -** |
| 79886 | | -** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null, |
| 79887 | | -** or OP_Variable that does not need to be placed in a |
| 79888 | | -** specific register. |
| 79889 | | -** |
| 79890 | | -** There is no point in factoring out single-instruction constant |
| 79891 | | -** expressions that need to be placed in a particular register. |
| 79892 | | -** We could factor them out, but then we would end up adding an |
| 79893 | | -** OP_SCopy instruction to move the value into the correct register |
| 79894 | | -** later. We might as well just use the original instruction and |
| 79895 | | -** avoid the OP_SCopy. |
| 79896 | | -*/ |
| 79897 | | -static int isAppropriateForFactoring(Expr *p){ |
| 79898 | | - if( !sqlite3ExprIsConstantNotJoin(p) ){ |
| 79899 | | - return 0; /* Only constant expressions are appropriate for factoring */ |
| 79900 | | - } |
| 79901 | | - if( (p->flags & EP_FixedDest)==0 ){ |
| 79902 | | - return 1; /* Any constant without a fixed destination is appropriate */ |
| 79903 | | - } |
| 79904 | | - while( p->op==TK_UPLUS ) p = p->pLeft; |
| 79905 | | - switch( p->op ){ |
| 79906 | | -#ifndef SQLITE_OMIT_BLOB_LITERAL |
| 79907 | | - case TK_BLOB: |
| 79908 | | -#endif |
| 79909 | | - case TK_VARIABLE: |
| 79910 | | - case TK_INTEGER: |
| 79911 | | - case TK_FLOAT: |
| 79912 | | - case TK_NULL: |
| 79913 | | - case TK_STRING: { |
| 79914 | | - testcase( p->op==TK_BLOB ); |
| 79915 | | - testcase( p->op==TK_VARIABLE ); |
| 79916 | | - testcase( p->op==TK_INTEGER ); |
| 79917 | | - testcase( p->op==TK_FLOAT ); |
| 79918 | | - testcase( p->op==TK_NULL ); |
| 79919 | | - testcase( p->op==TK_STRING ); |
| 79920 | | - /* Single-instruction constants with a fixed destination are |
| 79921 | | - ** better done in-line. If we factor them, they will just end |
| 79922 | | - ** up generating an OP_SCopy to move the value to the destination |
| 79923 | | - ** register. */ |
| 79924 | | - return 0; |
| 79925 | | - } |
| 79926 | | - case TK_UMINUS: { |
| 79927 | | - if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){ |
| 79928 | | - return 0; |
| 79929 | | - } |
| 79930 | | - break; |
| 79931 | | - } |
| 79932 | | - default: { |
| 79933 | | - break; |
| 79934 | | - } |
| 79935 | | - } |
| 79936 | | - return 1; |
| 79937 | | -} |
| 79938 | | - |
| 79939 | | -/* |
| 79940 | | -** If pExpr is a constant expression that is appropriate for |
| 79941 | | -** factoring out of a loop, then evaluate the expression |
| 79942 | | -** into a register and convert the expression into a TK_REGISTER |
| 79943 | | -** expression. |
| 79944 | | -*/ |
| 79945 | | -static int evalConstExpr(Walker *pWalker, Expr *pExpr){ |
| 79946 | | - Parse *pParse = pWalker->pParse; |
| 79947 | | - switch( pExpr->op ){ |
| 79948 | | - case TK_IN: |
| 79949 | | - case TK_REGISTER: { |
| 79950 | | - return WRC_Prune; |
| 79951 | | - } |
| 79952 | | - case TK_COLLATE: { |
| 79953 | | - return WRC_Continue; |
| 79954 | | - } |
| 79955 | | - case TK_FUNCTION: |
| 79956 | | - case TK_AGG_FUNCTION: |
| 79957 | | - case TK_CONST_FUNC: { |
| 79958 | | - /* The arguments to a function have a fixed destination. |
| 79959 | | - ** Mark them this way to avoid generated unneeded OP_SCopy |
| 79960 | | - ** instructions. |
| 79961 | | - */ |
| 79962 | | - ExprList *pList = pExpr->x.pList; |
| 79963 | | - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 79964 | | - if( pList ){ |
| 79965 | | - int i = pList->nExpr; |
| 79966 | | - struct ExprList_item *pItem = pList->a; |
| 79967 | | - for(; i>0; i--, pItem++){ |
| 79968 | | - if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest; |
| 79969 | | - } |
| 79970 | | - } |
| 79971 | | - break; |
| 79972 | | - } |
| 79973 | | - } |
| 79974 | | - if( isAppropriateForFactoring(pExpr) ){ |
| 79975 | | - int r1 = ++pParse->nMem; |
| 79976 | | - int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); |
| 79977 | | - /* If r2!=r1, it means that register r1 is never used. That is harmless |
| 79978 | | - ** but suboptimal, so we want to know about the situation to fix it. |
| 79979 | | - ** Hence the following assert: */ |
| 79980 | | - assert( r2==r1 ); |
| 79981 | | - exprToRegister(pExpr, r2); |
| 79982 | | - return WRC_Prune; |
| 79983 | | - } |
| 79984 | | - return WRC_Continue; |
| 79985 | | -} |
| 79986 | | - |
| 79987 | | -/* |
| 79988 | | -** Preevaluate constant subexpressions within pExpr and store the |
| 79989 | | -** results in registers. Modify pExpr so that the constant subexpresions |
| 79990 | | -** are TK_REGISTER opcodes that refer to the precomputed values. |
| 79991 | | -** |
| 79992 | | -** This routine is a no-op if the jump to the cookie-check code has |
| 79993 | | -** already occur. Since the cookie-check jump is generated prior to |
| 79994 | | -** any other serious processing, this check ensures that there is no |
| 79995 | | -** way to accidently bypass the constant initializations. |
| 79996 | | -** |
| 79997 | | -** This routine is also a no-op if the SQLITE_FactorOutConst optimization |
| 79998 | | -** is disabled via the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) |
| 79999 | | -** interface. This allows test logic to verify that the same answer is |
| 80000 | | -** obtained for queries regardless of whether or not constants are |
| 80001 | | -** precomputed into registers or if they are inserted in-line. |
| 80002 | | -*/ |
| 80003 | | -SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ |
| 80004 | | - Walker w; |
| 80005 | | - if( pParse->cookieGoto ) return; |
| 80006 | | - if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return; |
| 80007 | | - memset(&w, 0, sizeof(w)); |
| 80008 | | - w.xExprCallback = evalConstExpr; |
| 80009 | | - w.pParse = pParse; |
| 80010 | | - sqlite3WalkExpr(&w, pExpr); |
| 80011 | | -} |
| 80012 | | - |
| 80013 | 79442 | |
| 80014 | 79443 | /* |
| 80015 | 79444 | ** Generate code that pushes the value of every element of the given |
| 80016 | 79445 | ** expression list into a sequence of registers beginning at target. |
| 80017 | 79446 | ** |
| 80018 | 79447 | ** Return the number of elements evaluated. |
| 79448 | +** |
| 79449 | +** The SQLITE_ECEL_DUP flag prevents the arguments from being |
| 79450 | +** filled using OP_SCopy. OP_Copy must be used instead. |
| 79451 | +** |
| 79452 | +** The SQLITE_ECEL_FACTOR argument allows constant arguments to be |
| 79453 | +** factored out into initialization code. |
| 80019 | 79454 | */ |
| 80020 | 79455 | SQLITE_PRIVATE int sqlite3ExprCodeExprList( |
| 80021 | 79456 | Parse *pParse, /* Parsing context */ |
| 80022 | 79457 | ExprList *pList, /* The expression list to be coded */ |
| 80023 | 79458 | int target, /* Where to write results */ |
| 80024 | | - int doHardCopy /* Make a hard copy of every element */ |
| 79459 | + u8 flags /* SQLITE_ECEL_* flags */ |
| 80025 | 79460 | ){ |
| 80026 | 79461 | struct ExprList_item *pItem; |
| 80027 | 79462 | int i, n; |
| 79463 | + u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy; |
| 80028 | 79464 | assert( pList!=0 ); |
| 80029 | 79465 | assert( target>0 ); |
| 80030 | 79466 | assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ |
| 80031 | 79467 | n = pList->nExpr; |
| 79468 | + if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; |
| 80032 | 79469 | for(pItem=pList->a, i=0; i<n; i++, pItem++){ |
| 80033 | 79470 | Expr *pExpr = pItem->pExpr; |
| 80034 | | - int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); |
| 80035 | | - if( inReg!=target+i ){ |
| 80036 | | - sqlite3VdbeAddOp2(pParse->pVdbe, doHardCopy ? OP_Copy : OP_SCopy, |
| 80037 | | - inReg, target+i); |
| 79471 | + if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ |
| 79472 | + sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0); |
| 79473 | + }else{ |
| 79474 | + int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); |
| 79475 | + if( inReg!=target+i ){ |
| 79476 | + sqlite3VdbeAddOp2(pParse->pVdbe, copyOp, inReg, target+i); |
| 79477 | + } |
| 80038 | 79478 | } |
| 80039 | 79479 | } |
| 80040 | 79480 | return n; |
| 80041 | 79481 | } |
| 80042 | 79482 | |
| | @@ -80386,44 +79826,46 @@ |
| 80386 | 79826 | ** this routine is used, it does not hurt to get an extra 2 - that |
| 80387 | 79827 | ** just might result in some slightly slower code. But returning |
| 80388 | 79828 | ** an incorrect 0 or 1 could lead to a malfunction. |
| 80389 | 79829 | */ |
| 80390 | 79830 | SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ |
| 80391 | | - if( pA==0||pB==0 ){ |
| 79831 | + u32 combinedFlags; |
| 79832 | + if( pA==0 || pB==0 ){ |
| 80392 | 79833 | return pB==pA ? 0 : 2; |
| 80393 | 79834 | } |
| 80394 | | - assert( !ExprHasProperty(pA, EP_TokenOnly|EP_Reduced) ); |
| 80395 | | - assert( !ExprHasProperty(pB, EP_TokenOnly|EP_Reduced) ); |
| 80396 | | - if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){ |
| 79835 | + combinedFlags = pA->flags | pB->flags; |
| 79836 | + if( combinedFlags & EP_IntValue ){ |
| 79837 | + if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){ |
| 79838 | + return 0; |
| 79839 | + } |
| 80397 | 79840 | return 2; |
| 80398 | 79841 | } |
| 80399 | | - if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; |
| 80400 | | - if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){ |
| 79842 | + if( pA->op!=pB->op ){ |
| 80401 | 79843 | if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){ |
| 80402 | 79844 | return 1; |
| 80403 | 79845 | } |
| 80404 | 79846 | if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){ |
| 80405 | 79847 | return 1; |
| 80406 | 79848 | } |
| 80407 | 79849 | return 2; |
| 80408 | 79850 | } |
| 80409 | | - if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; |
| 80410 | | - if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; |
| 80411 | | - if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; |
| 80412 | | - if( pA->iColumn!=pB->iColumn ) return 2; |
| 80413 | | - if( pA->iTable!=pB->iTable |
| 80414 | | - && pA->op!=TK_REGISTER |
| 80415 | | - && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; |
| 80416 | | - if( ExprHasProperty(pA, EP_IntValue) ){ |
| 80417 | | - if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ |
| 80418 | | - return 2; |
| 80419 | | - } |
| 80420 | | - }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){ |
| 80421 | | - if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2; |
| 79851 | + if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){ |
| 80422 | 79852 | if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ |
| 80423 | 79853 | return pA->op==TK_COLLATE ? 1 : 2; |
| 80424 | 79854 | } |
| 79855 | + } |
| 79856 | + if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; |
| 79857 | + if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ |
| 79858 | + if( combinedFlags & EP_xIsSelect ) return 2; |
| 79859 | + if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; |
| 79860 | + if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; |
| 79861 | + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; |
| 79862 | + if( ALWAYS((combinedFlags & EP_Reduced)==0) ){ |
| 79863 | + if( pA->iColumn!=pB->iColumn ) return 2; |
| 79864 | + if( pA->iTable!=pB->iTable |
| 79865 | + && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; |
| 79866 | + } |
| 80425 | 79867 | } |
| 80426 | 79868 | return 0; |
| 80427 | 79869 | } |
| 80428 | 79870 | |
| 80429 | 79871 | /* |
| | @@ -83076,14 +82518,16 @@ |
| 83076 | 82518 | } |
| 83077 | 82519 | pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); |
| 83078 | 82520 | if( pTable==0 ){ |
| 83079 | 82521 | return 0; |
| 83080 | 82522 | } |
| 83081 | | - if( argv[1] ){ |
| 83082 | | - pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 83083 | | - }else{ |
| 82523 | + if( argv[1]==0 ){ |
| 83084 | 82524 | pIndex = 0; |
| 82525 | + }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ |
| 82526 | + pIndex = sqlite3PrimaryKeyIndex(pTable); |
| 82527 | + }else{ |
| 82528 | + pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 83085 | 82529 | } |
| 83086 | 82530 | z = argv[2]; |
| 83087 | 82531 | |
| 83088 | 82532 | if( pIndex ){ |
| 83089 | 82533 | decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex); |
| | @@ -84394,11 +83838,11 @@ |
| 84394 | 83838 | ** transaction on each used database and to verify the schema cookie |
| 84395 | 83839 | ** on each used database. |
| 84396 | 83840 | */ |
| 84397 | 83841 | if( pParse->cookieGoto>0 ){ |
| 84398 | 83842 | yDbMask mask; |
| 84399 | | - int iDb; |
| 83843 | + int iDb, i, addr; |
| 84400 | 83844 | sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); |
| 84401 | 83845 | for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ |
| 84402 | 83846 | if( (mask & pParse->cookieMask)==0 ) continue; |
| 84403 | 83847 | sqlite3VdbeUsesBtree(v, iDb); |
| 84404 | 83848 | sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); |
| | @@ -84408,18 +83852,15 @@ |
| 84408 | 83852 | iDb, pParse->cookieValue[iDb], |
| 84409 | 83853 | db->aDb[iDb].pSchema->iGeneration); |
| 84410 | 83854 | } |
| 84411 | 83855 | } |
| 84412 | 83856 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 84413 | | - { |
| 84414 | | - int i; |
| 84415 | | - for(i=0; i<pParse->nVtabLock; i++){ |
| 84416 | | - char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); |
| 84417 | | - sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); |
| 84418 | | - } |
| 84419 | | - pParse->nVtabLock = 0; |
| 84420 | | - } |
| 83857 | + for(i=0; i<pParse->nVtabLock; i++){ |
| 83858 | + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); |
| 83859 | + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); |
| 83860 | + } |
| 83861 | + pParse->nVtabLock = 0; |
| 84421 | 83862 | #endif |
| 84422 | 83863 | |
| 84423 | 83864 | /* Once all the cookies have been verified and transactions opened, |
| 84424 | 83865 | ** obtain the required table-locks. This is a no-op unless the |
| 84425 | 83866 | ** shared-cache feature is enabled. |
| | @@ -84427,24 +83868,30 @@ |
| 84427 | 83868 | codeTableLocks(pParse); |
| 84428 | 83869 | |
| 84429 | 83870 | /* Initialize any AUTOINCREMENT data structures required. |
| 84430 | 83871 | */ |
| 84431 | 83872 | sqlite3AutoincrementBegin(pParse); |
| 83873 | + |
| 83874 | + /* Code constant expressions that where factored out of inner loops */ |
| 83875 | + addr = pParse->cookieGoto; |
| 83876 | + if( pParse->pConstExpr ){ |
| 83877 | + ExprList *pEL = pParse->pConstExpr; |
| 83878 | + pParse->cookieGoto = 0; |
| 83879 | + for(i=0; i<pEL->nExpr; i++){ |
| 83880 | + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); |
| 83881 | + } |
| 83882 | + } |
| 84432 | 83883 | |
| 84433 | 83884 | /* Finally, jump back to the beginning of the executable code. */ |
| 84434 | | - sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto); |
| 83885 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); |
| 84435 | 83886 | } |
| 84436 | 83887 | } |
| 84437 | 83888 | |
| 84438 | 83889 | |
| 84439 | 83890 | /* Get the VDBE program ready for execution |
| 84440 | 83891 | */ |
| 84441 | 83892 | if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){ |
| 84442 | | -#ifdef SQLITE_DEBUG |
| 84443 | | - FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; |
| 84444 | | - sqlite3VdbeTrace(v, trace); |
| 84445 | | -#endif |
| 84446 | 83893 | assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ |
| 84447 | 83894 | /* A minimum of one cursor is required if autoincrement is used |
| 84448 | 83895 | * See ticket [a696379c1f08866] */ |
| 84449 | 83896 | if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; |
| 84450 | 83897 | sqlite3VdbeMakeReady(v, pParse); |
| | @@ -87031,11 +86478,11 @@ |
| 87031 | 86478 | Token *pName = 0; /* Unqualified name of the index to create */ |
| 87032 | 86479 | struct ExprList_item *pListItem; /* For looping over pList */ |
| 87033 | 86480 | const Column *pTabCol; /* A column in the table */ |
| 87034 | 86481 | int nExtra = 0; /* Space allocated for zExtra[] */ |
| 87035 | 86482 | int nExtraCol; /* Number of extra columns needed */ |
| 87036 | | - char *zExtra; /* Extra space after the Index object */ |
| 86483 | + char *zExtra = 0; /* Extra space after the Index object */ |
| 87037 | 86484 | Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ |
| 87038 | 86485 | |
| 87039 | 86486 | assert( pParse->nErr==0 ); /* Never called with prior errors */ |
| 87040 | 86487 | if( db->mallocFailed || IN_DECLARE_VTAB ){ |
| 87041 | 86488 | goto exit_create_index; |
| | @@ -88230,13 +87677,13 @@ |
| 88230 | 87677 | sqlite3StrAccumInit(&errMsg, 0, 0, 200); |
| 88231 | 87678 | errMsg.db = pParse->db; |
| 88232 | 87679 | for(j=0; j<pIdx->nKeyCol; j++){ |
| 88233 | 87680 | char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; |
| 88234 | 87681 | if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); |
| 88235 | | - sqlite3StrAccumAppend(&errMsg, pTab->zName, -1); |
| 87682 | + sqlite3StrAccumAppendAll(&errMsg, pTab->zName); |
| 88236 | 87683 | sqlite3StrAccumAppend(&errMsg, ".", 1); |
| 88237 | | - sqlite3StrAccumAppend(&errMsg, zCol, -1); |
| 87684 | + sqlite3StrAccumAppendAll(&errMsg, zCol); |
| 88238 | 87685 | } |
| 88239 | 87686 | zErr = sqlite3StrAccumFinish(&errMsg); |
| 88240 | 87687 | sqlite3HaltConstraint(pParse, |
| 88241 | 87688 | (pIdx->autoIndex==2)?SQLITE_CONSTRAINT_PRIMARYKEY:SQLITE_CONSTRAINT_UNIQUE, |
| 88242 | 87689 | onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); |
| | @@ -88424,12 +87871,13 @@ |
| 88424 | 87871 | } |
| 88425 | 87872 | if( pKey ){ |
| 88426 | 87873 | assert( sqlite3KeyInfoIsWriteable(pKey) ); |
| 88427 | 87874 | for(i=0; i<nCol; i++){ |
| 88428 | 87875 | char *zColl = pIdx->azColl[i]; |
| 88429 | | - if( NEVER(zColl==0) ) zColl = "BINARY"; |
| 88430 | | - pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl); |
| 87876 | + assert( zColl!=0 ); |
| 87877 | + pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 : |
| 87878 | + sqlite3LocateCollSeq(pParse, zColl); |
| 88431 | 87879 | pKey->aSortOrder[i] = pIdx->aSortOrder[i]; |
| 88432 | 87880 | } |
| 88433 | 87881 | if( pParse->nErr ){ |
| 88434 | 87882 | sqlite3KeyInfoUnref(pKey); |
| 88435 | 87883 | }else{ |
| | @@ -89148,24 +88596,38 @@ |
| 89148 | 88596 | Expr *pWhere /* The WHERE clause. May be null */ |
| 89149 | 88597 | ){ |
| 89150 | 88598 | Vdbe *v; /* The virtual database engine */ |
| 89151 | 88599 | Table *pTab; /* The table from which records will be deleted */ |
| 89152 | 88600 | const char *zDb; /* Name of database holding pTab */ |
| 89153 | | - int end, addr = 0; /* A couple addresses of generated code */ |
| 89154 | 88601 | int i; /* Loop counter */ |
| 89155 | 88602 | WhereInfo *pWInfo; /* Information about the WHERE clause */ |
| 89156 | 88603 | Index *pIdx; /* For looping over indices of the table */ |
| 89157 | 88604 | int iTabCur; /* Cursor number for the table */ |
| 89158 | 88605 | int iDataCur; /* VDBE cursor for the canonical data source */ |
| 89159 | 88606 | int iIdxCur; /* Cursor number of the first index */ |
| 88607 | + int nIdx; /* Number of indices */ |
| 89160 | 88608 | sqlite3 *db; /* Main database structure */ |
| 89161 | 88609 | AuthContext sContext; /* Authorization context */ |
| 89162 | 88610 | NameContext sNC; /* Name context to resolve expressions in */ |
| 89163 | 88611 | int iDb; /* Database number */ |
| 89164 | 88612 | int memCnt = -1; /* Memory cell used for change counting */ |
| 89165 | 88613 | int rcauth; /* Value returned by authorization callback */ |
| 89166 | | - |
| 88614 | + int okOnePass; /* True for one-pass algorithm without the FIFO */ |
| 88615 | + int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ |
| 88616 | + u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ |
| 88617 | + Index *pPk; /* The PRIMARY KEY index on the table */ |
| 88618 | + int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */ |
| 88619 | + i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ |
| 88620 | + int iKey; /* Memory cell holding key of row to be deleted */ |
| 88621 | + i16 nKey; /* Number of memory cells in the row key */ |
| 88622 | + int iEphCur = 0; /* Ephemeral table holding all primary key values */ |
| 88623 | + int iRowSet = 0; /* Register for rowset of rows to delete */ |
| 88624 | + int addrBypass = 0; /* Address of jump over the delete logic */ |
| 88625 | + int addrLoop = 0; /* Top of the delete loop */ |
| 88626 | + int addrDelete = 0; /* Jump directly to the delete logic */ |
| 88627 | + int addrEphOpen = 0; /* Instruction to open the Ephermeral table */ |
| 88628 | + |
| 89167 | 88629 | #ifndef SQLITE_OMIT_TRIGGER |
| 89168 | 88630 | int isView; /* True if attempting to delete from a view */ |
| 89169 | 88631 | Trigger *pTrigger; /* List of table triggers, if required */ |
| 89170 | 88632 | #endif |
| 89171 | 88633 | |
| | @@ -89216,15 +88678,15 @@ |
| 89216 | 88678 | if( rcauth==SQLITE_DENY ){ |
| 89217 | 88679 | goto delete_from_cleanup; |
| 89218 | 88680 | } |
| 89219 | 88681 | assert(!isView || pTrigger); |
| 89220 | 88682 | |
| 89221 | | - /* Assign cursor number to the table and all its indices. |
| 88683 | + /* Assign cursor numbers to the table and all its indices. |
| 89222 | 88684 | */ |
| 89223 | 88685 | assert( pTabList->nSrc==1 ); |
| 89224 | 88686 | iTabCur = pTabList->a[0].iCursor = pParse->nTab++; |
| 89225 | | - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 88687 | + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ |
| 89226 | 88688 | pParse->nTab++; |
| 89227 | 88689 | } |
| 89228 | 88690 | |
| 89229 | 88691 | /* Start the view context |
| 89230 | 88692 | */ |
| | @@ -89286,132 +88748,162 @@ |
| 89286 | 88748 | assert( pIdx->pSchema==pTab->pSchema ); |
| 89287 | 88749 | sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); |
| 89288 | 88750 | } |
| 89289 | 88751 | }else |
| 89290 | 88752 | #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ |
| 89291 | | - if( !HasRowid(pTab) ){ |
| 89292 | | - /* There is a WHERE clause on a WITHOUT ROWID table. |
| 89293 | | - */ |
| 89294 | | - Index *pPk; /* The PRIMARY KEY index on the table */ |
| 89295 | | - int iPk; /* First of nPk memory cells holding PRIMARY KEY value */ |
| 89296 | | - int iEph; /* Ephemeral table holding all primary key values */ |
| 89297 | | - int iKey; /* Key value inserting into iEph */ |
| 89298 | | - i16 nPk; /* Number of components of the PRIMARY KEY */ |
| 89299 | | - |
| 89300 | | - pPk = sqlite3PrimaryKeyIndex(pTab); |
| 89301 | | - assert( pPk!=0 ); |
| 89302 | | - nPk = pPk->nKeyCol; |
| 89303 | | - iPk = pParse->nMem+1; |
| 89304 | | - pParse->nMem += nPk; |
| 89305 | | - iKey = ++pParse->nMem; |
| 89306 | | - iEph = pParse->nTab++; |
| 89307 | | - |
| 89308 | | - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); |
| 89309 | | - sqlite3VdbeSetP4KeyInfo(pParse, pPk); |
| 89310 | | - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 0, 0); |
| 89311 | | - if( pWInfo==0 ) goto delete_from_cleanup; |
| 89312 | | - for(i=0; i<nPk; i++){ |
| 89313 | | - sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, pPk->aiColumn[i],iPk+i); |
| 89314 | | - } |
| 89315 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, |
| 89316 | | - sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT); |
| 89317 | | - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, iKey); |
| 89318 | | - if( db->flags & SQLITE_CountRows ){ |
| 89319 | | - sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); |
| 89320 | | - } |
| 89321 | | - sqlite3WhereEnd(pWInfo); |
| 89322 | | - |
| 89323 | | - /* Open cursors for all indices of the table. |
| 89324 | | - */ |
| 89325 | | - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, |
| 89326 | | - iTabCur, &iDataCur, &iIdxCur); |
| 89327 | | - |
| 89328 | | - /* Loop over the primary keys to be deleted. */ |
| 89329 | | - addr = sqlite3VdbeAddOp1(v, OP_Rewind, iEph); |
| 89330 | | - sqlite3VdbeAddOp2(v, OP_RowKey, iEph, iPk); |
| 89331 | | - |
| 89332 | | - /* Delete the row */ |
| 89333 | | - sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, |
| 89334 | | - iPk, 0, 1, OE_Default, 0); |
| 89335 | | - |
| 89336 | | - /* End of the delete loop */ |
| 89337 | | - sqlite3VdbeAddOp2(v, OP_Next, iEph, addr+1); |
| 89338 | | - sqlite3VdbeJumpHere(v, addr); |
| 89339 | | - |
| 89340 | | - /* Close the cursors open on the table and its indexes. */ |
| 89341 | | - assert( iDataCur>=iIdxCur ); |
| 89342 | | - for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ |
| 89343 | | - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur+i); |
| 89344 | | - } |
| 89345 | | - }else{ |
| 89346 | | - /* There is a WHERE clause on a rowid table. Run a loop that extracts |
| 89347 | | - ** all rowids to be deleted into a RowSet. |
| 89348 | | - */ |
| 89349 | | - int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */ |
| 89350 | | - int iRowid = ++pParse->nMem; /* Used for storing rowid values. */ |
| 89351 | | - int regRowid; /* Actual register containing rowids */ |
| 89352 | | - |
| 89353 | | - /* Collect rowids of every row to be deleted. |
| 89354 | | - */ |
| 89355 | | - sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); |
| 89356 | | - pWInfo = sqlite3WhereBegin( |
| 89357 | | - pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0 |
| 89358 | | - ); |
| 89359 | | - if( pWInfo==0 ) goto delete_from_cleanup; |
| 89360 | | - regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iRowid, 0); |
| 89361 | | - sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid); |
| 89362 | | - if( db->flags & SQLITE_CountRows ){ |
| 89363 | | - sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); |
| 89364 | | - } |
| 89365 | | - sqlite3WhereEnd(pWInfo); |
| 89366 | | - |
| 89367 | | - /* Delete every item whose key was written to the list during the |
| 89368 | | - ** database scan. We have to delete items after the scan is complete |
| 89369 | | - ** because deleting an item can change the scan order. */ |
| 89370 | | - end = sqlite3VdbeMakeLabel(v); |
| 89371 | | - |
| 89372 | | - /* Unless this is a view, open cursors for the table we are |
| 89373 | | - ** deleting from and all its indices. If this is a view, then the |
| 89374 | | - ** only effect this statement has is to fire the INSTEAD OF |
| 89375 | | - ** triggers. */ |
| 89376 | | - if( !isView ){ |
| 89377 | | - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, |
| 89378 | | - &iDataCur, &iIdxCur); |
| 89379 | | - assert( iDataCur==iTabCur ); |
| 89380 | | - assert( iIdxCur==iDataCur+1 ); |
| 89381 | | - } |
| 89382 | | - |
| 89383 | | - addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid); |
| 89384 | | - |
| 88753 | + { |
| 88754 | + if( HasRowid(pTab) ){ |
| 88755 | + /* For a rowid table, initialize the RowSet to an empty set */ |
| 88756 | + pPk = 0; |
| 88757 | + nPk = 1; |
| 88758 | + iRowSet = ++pParse->nMem; |
| 88759 | + sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); |
| 88760 | + }else{ |
| 88761 | + /* For a WITHOUT ROWID table, create an ephermeral table used to |
| 88762 | + ** hold all primary keys for rows to be deleted. */ |
| 88763 | + pPk = sqlite3PrimaryKeyIndex(pTab); |
| 88764 | + assert( pPk!=0 ); |
| 88765 | + nPk = pPk->nKeyCol; |
| 88766 | + iPk = pParse->nMem+1; |
| 88767 | + pParse->nMem += nPk; |
| 88768 | + iEphCur = pParse->nTab++; |
| 88769 | + addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); |
| 88770 | + sqlite3VdbeSetP4KeyInfo(pParse, pPk); |
| 88771 | + } |
| 88772 | + |
| 88773 | + /* Construct a query to find the rowid or primary key for every row |
| 88774 | + ** to be deleted, based on the WHERE clause. |
| 88775 | + */ |
| 88776 | + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, |
| 88777 | + WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK, |
| 88778 | + iTabCur+1); |
| 88779 | + if( pWInfo==0 ) goto delete_from_cleanup; |
| 88780 | + okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); |
| 88781 | + |
| 88782 | + /* Keep track of the number of rows to be deleted */ |
| 88783 | + if( db->flags & SQLITE_CountRows ){ |
| 88784 | + sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); |
| 88785 | + } |
| 88786 | + |
| 88787 | + /* Extract the rowid or primary key for the current row */ |
| 88788 | + if( pPk ){ |
| 88789 | + for(i=0; i<nPk; i++){ |
| 88790 | + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, |
| 88791 | + pPk->aiColumn[i], iPk+i); |
| 88792 | + } |
| 88793 | + iKey = iPk; |
| 88794 | + }else{ |
| 88795 | + iKey = pParse->nMem + 1; |
| 88796 | + iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0); |
| 88797 | + if( iKey>pParse->nMem ) pParse->nMem = iKey; |
| 88798 | + } |
| 88799 | + |
| 88800 | + if( okOnePass ){ |
| 88801 | + /* For ONEPASS, no need to store the rowid/primary-key. There is only |
| 88802 | + ** one, so just keep it in its register(s) and fall through to the |
| 88803 | + ** delete code. |
| 88804 | + */ |
| 88805 | + nKey = nPk; /* OP_Found will use an unpacked key */ |
| 88806 | + aToOpen = sqlite3DbMallocRaw(db, nIdx+2); |
| 88807 | + if( aToOpen==0 ){ |
| 88808 | + sqlite3WhereEnd(pWInfo); |
| 88809 | + goto delete_from_cleanup; |
| 88810 | + } |
| 88811 | + memset(aToOpen, 1, nIdx+1); |
| 88812 | + aToOpen[nIdx+1] = 0; |
| 88813 | + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; |
| 88814 | + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; |
| 88815 | + if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); |
| 88816 | + addrDelete = sqlite3VdbeAddOp0(v, OP_Goto); /* Jump to DELETE logic */ |
| 88817 | + }else if( pPk ){ |
| 88818 | + /* Construct a composite key for the row to be deleted and remember it */ |
| 88819 | + iKey = ++pParse->nMem; |
| 88820 | + nKey = 0; /* Zero tells OP_Found to use a composite key */ |
| 88821 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, |
| 88822 | + sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT); |
| 88823 | + sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey); |
| 88824 | + }else{ |
| 88825 | + /* Get the rowid of the row to be deleted and remember it in the RowSet */ |
| 88826 | + nKey = 1; /* OP_Seek always uses a single rowid */ |
| 88827 | + sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); |
| 88828 | + } |
| 88829 | + |
| 88830 | + /* End of the WHERE loop */ |
| 88831 | + sqlite3WhereEnd(pWInfo); |
| 88832 | + if( okOnePass ){ |
| 88833 | + /* Bypass the delete logic below if the WHERE loop found zero rows */ |
| 88834 | + addrBypass = sqlite3VdbeMakeLabel(v); |
| 88835 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass); |
| 88836 | + sqlite3VdbeJumpHere(v, addrDelete); |
| 88837 | + } |
| 88838 | + |
| 88839 | + /* Unless this is a view, open cursors for the table we are |
| 88840 | + ** deleting from and all its indices. If this is a view, then the |
| 88841 | + ** only effect this statement has is to fire the INSTEAD OF |
| 88842 | + ** triggers. |
| 88843 | + */ |
| 88844 | + if( !isView ){ |
| 88845 | + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, |
| 88846 | + &iDataCur, &iIdxCur); |
| 88847 | + assert( pPk || iDataCur==iTabCur ); |
| 88848 | + assert( pPk || iIdxCur==iDataCur+1 ); |
| 88849 | + } |
| 88850 | + |
| 88851 | + /* Set up a loop over the rowids/primary-keys that were found in the |
| 88852 | + ** where-clause loop above. |
| 88853 | + */ |
| 88854 | + if( okOnePass ){ |
| 88855 | + /* Just one row. Hence the top-of-loop is a no-op */ |
| 88856 | + assert( nKey==nPk ); /* OP_Found will use an unpacked key */ |
| 88857 | + if( aToOpen[iDataCur-iTabCur] ){ |
| 88858 | + assert( pPk!=0 ); |
| 88859 | + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); |
| 88860 | + } |
| 88861 | + }else if( pPk ){ |
| 88862 | + addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); |
| 88863 | + sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); |
| 88864 | + assert( nKey==0 ); /* OP_Found will use a composite key */ |
| 88865 | + }else{ |
| 88866 | + addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); |
| 88867 | + assert( nKey==1 ); |
| 88868 | + } |
| 88869 | + |
| 89385 | 88870 | /* Delete the row */ |
| 89386 | 88871 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 89387 | 88872 | if( IsVirtual(pTab) ){ |
| 89388 | 88873 | const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); |
| 89389 | 88874 | sqlite3VtabMakeWritable(pParse, pTab); |
| 89390 | | - sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); |
| 88875 | + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); |
| 89391 | 88876 | sqlite3VdbeChangeP5(v, OE_Abort); |
| 89392 | 88877 | sqlite3MayAbort(pParse); |
| 89393 | 88878 | }else |
| 89394 | 88879 | #endif |
| 89395 | 88880 | { |
| 89396 | 88881 | int count = (pParse->nested==0); /* True to count changes */ |
| 89397 | 88882 | sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, |
| 89398 | | - iRowid, 1, count, OE_Default, 0); |
| 88883 | + iKey, nKey, count, OE_Default, okOnePass); |
| 89399 | 88884 | } |
| 89400 | | - |
| 89401 | | - /* End of the delete loop */ |
| 89402 | | - sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); |
| 89403 | | - sqlite3VdbeResolveLabel(v, end); |
| 89404 | | - |
| 88885 | + |
| 88886 | + /* End of the loop over all rowids/primary-keys. */ |
| 88887 | + if( okOnePass ){ |
| 88888 | + sqlite3VdbeResolveLabel(v, addrBypass); |
| 88889 | + }else if( pPk ){ |
| 88890 | + sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); |
| 88891 | + sqlite3VdbeJumpHere(v, addrLoop); |
| 88892 | + }else{ |
| 88893 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop); |
| 88894 | + sqlite3VdbeJumpHere(v, addrLoop); |
| 88895 | + } |
| 88896 | + |
| 89405 | 88897 | /* Close the cursors open on the table and its indexes. */ |
| 89406 | 88898 | if( !isView && !IsVirtual(pTab) ){ |
| 89407 | | - sqlite3VdbeAddOp1(v, OP_Close, iDataCur); |
| 88899 | + if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur); |
| 89408 | 88900 | for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ |
| 89409 | 88901 | sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i); |
| 89410 | 88902 | } |
| 89411 | 88903 | } |
| 89412 | | - } |
| 88904 | + } /* End non-truncate path */ |
| 89413 | 88905 | |
| 89414 | 88906 | /* Update the sqlite_sequence table by storing the content of the |
| 89415 | 88907 | ** maximum rowid counter values recorded while inserting into |
| 89416 | 88908 | ** autoincrement tables. |
| 89417 | 88909 | */ |
| | @@ -89431,10 +88923,11 @@ |
| 89431 | 88923 | |
| 89432 | 88924 | delete_from_cleanup: |
| 89433 | 88925 | sqlite3AuthContextPop(&sContext); |
| 89434 | 88926 | sqlite3SrcListDelete(db, pTabList); |
| 89435 | 88927 | sqlite3ExprDelete(db, pWhere); |
| 88928 | + sqlite3DbFree(db, aToOpen); |
| 89436 | 88929 | return; |
| 89437 | 88930 | } |
| 89438 | 88931 | /* Make sure "isView" and other macros defined above are undefined. Otherwise |
| 89439 | 88932 | ** thely may interfere with compilation of other functions in this file |
| 89440 | 88933 | ** (or in another file, if this file becomes part of the amalgamation). */ |
| | @@ -89497,10 +88990,11 @@ |
| 89497 | 88990 | /* If there are any triggers to fire, allocate a range of registers to |
| 89498 | 88991 | ** use for the old.* references in the triggers. */ |
| 89499 | 88992 | if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ |
| 89500 | 88993 | u32 mask; /* Mask of OLD.* columns in use */ |
| 89501 | 88994 | int iCol; /* Iterator used while populating OLD.* */ |
| 88995 | + int addrStart; /* Start of BEFORE trigger programs */ |
| 89502 | 88996 | |
| 89503 | 88997 | /* TODO: Could use temporary registers here. Also could attempt to |
| 89504 | 88998 | ** avoid copying the contents of the rowid register. */ |
| 89505 | 88999 | mask = sqlite3TriggerColmask( |
| 89506 | 89000 | pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf |
| | @@ -89517,19 +89011,23 @@ |
| 89517 | 89011 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1); |
| 89518 | 89012 | } |
| 89519 | 89013 | } |
| 89520 | 89014 | |
| 89521 | 89015 | /* Invoke BEFORE DELETE trigger programs. */ |
| 89016 | + addrStart = sqlite3VdbeCurrentAddr(v); |
| 89522 | 89017 | sqlite3CodeRowTrigger(pParse, pTrigger, |
| 89523 | 89018 | TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel |
| 89524 | 89019 | ); |
| 89525 | 89020 | |
| 89526 | | - /* Seek the cursor to the row to be deleted again. It may be that |
| 89527 | | - ** the BEFORE triggers coded above have already removed the row |
| 89528 | | - ** being deleted. Do not attempt to delete the row a second time, and |
| 89529 | | - ** do not fire AFTER triggers. */ |
| 89530 | | - sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); |
| 89021 | + /* If any BEFORE triggers were coded, then seek the cursor to the |
| 89022 | + ** row to be deleted again. It may be that the BEFORE triggers moved |
| 89023 | + ** the cursor or of already deleted the row that the cursor was |
| 89024 | + ** pointing to. |
| 89025 | + */ |
| 89026 | + if( addrStart<sqlite3VdbeCurrentAddr(v) ){ |
| 89027 | + sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); |
| 89028 | + } |
| 89531 | 89029 | |
| 89532 | 89030 | /* Do FK processing. This call checks that any FK constraints that |
| 89533 | 89031 | ** refer to this table (i.e. constraints attached to other tables) |
| 89534 | 89032 | ** are not violated by deleting this row. */ |
| 89535 | 89033 | sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); |
| | @@ -91193,15 +90691,15 @@ |
| 91193 | 90691 | nSep = sqlite3_value_bytes(argv[1]); |
| 91194 | 90692 | }else{ |
| 91195 | 90693 | zSep = ","; |
| 91196 | 90694 | nSep = 1; |
| 91197 | 90695 | } |
| 91198 | | - sqlite3StrAccumAppend(pAccum, zSep, nSep); |
| 90696 | + if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep); |
| 91199 | 90697 | } |
| 91200 | 90698 | zVal = (char*)sqlite3_value_text(argv[0]); |
| 91201 | 90699 | nVal = sqlite3_value_bytes(argv[0]); |
| 91202 | | - sqlite3StrAccumAppend(pAccum, zVal, nVal); |
| 90700 | + if( nVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal); |
| 91203 | 90701 | } |
| 91204 | 90702 | } |
| 91205 | 90703 | static void groupConcatFinalize(sqlite3_context *context){ |
| 91206 | 90704 | StrAccum *pAccum; |
| 91207 | 90705 | pAccum = sqlite3_aggregate_context(context, 0); |
| | @@ -91346,24 +90844,24 @@ |
| 91346 | 90844 | FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), |
| 91347 | 90845 | FUNCTION(hex, 1, 0, 0, hexFunc ), |
| 91348 | 90846 | FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), |
| 91349 | 90847 | FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), |
| 91350 | 90848 | FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), |
| 91351 | | - FUNCTION(random, 0, 0, 0, randomFunc ), |
| 91352 | | - FUNCTION(randomblob, 1, 0, 0, randomBlob ), |
| 90849 | + VFUNCTION(random, 0, 0, 0, randomFunc ), |
| 90850 | + VFUNCTION(randomblob, 1, 0, 0, randomBlob ), |
| 91353 | 90851 | FUNCTION(nullif, 2, 0, 1, nullifFunc ), |
| 91354 | 90852 | FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), |
| 91355 | 90853 | FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), |
| 91356 | 90854 | FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), |
| 91357 | 90855 | #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS |
| 91358 | 90856 | FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), |
| 91359 | 90857 | FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), |
| 91360 | 90858 | #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ |
| 91361 | 90859 | FUNCTION(quote, 1, 0, 0, quoteFunc ), |
| 91362 | | - FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), |
| 91363 | | - FUNCTION(changes, 0, 0, 0, changes ), |
| 91364 | | - FUNCTION(total_changes, 0, 0, 0, total_changes ), |
| 90860 | + VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), |
| 90861 | + VFUNCTION(changes, 0, 0, 0, changes ), |
| 90862 | + VFUNCTION(total_changes, 0, 0, 0, total_changes ), |
| 91365 | 90863 | FUNCTION(replace, 3, 0, 0, replaceFunc ), |
| 91366 | 90864 | FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), |
| 91367 | 90865 | #ifdef SQLITE_SOUNDEX |
| 91368 | 90866 | FUNCTION(soundex, 1, 0, 0, soundexFunc ), |
| 91369 | 90867 | #endif |
| | @@ -91955,10 +91453,11 @@ |
| 91955 | 91453 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 91956 | 91454 | |
| 91957 | 91455 | assert( pIdx==0 || pIdx->pTable==pTab ); |
| 91958 | 91456 | assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol ); |
| 91959 | 91457 | assert( pIdx!=0 || pFKey->nCol==1 ); |
| 91458 | + assert( pIdx!=0 || HasRowid(pTab) ); |
| 91960 | 91459 | |
| 91961 | 91460 | if( nIncr<0 ){ |
| 91962 | 91461 | iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); |
| 91963 | 91462 | } |
| 91964 | 91463 | |
| | @@ -92007,10 +91506,11 @@ |
| 92007 | 91506 | pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); |
| 92008 | 91507 | pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); |
| 92009 | 91508 | }else{ |
| 92010 | 91509 | Expr *pEq, *pAll = 0; |
| 92011 | 91510 | Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
| 91511 | + assert( pIdx!=0 ); |
| 92012 | 91512 | for(i=0; i<pPk->nKeyCol; i++){ |
| 92013 | 91513 | i16 iCol = pIdx->aiColumn[i]; |
| 92014 | 91514 | pLeft = exprTableRegister(pParse, pTab, regData, iCol); |
| 92015 | 91515 | pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); |
| 92016 | 91516 | pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); |
| | @@ -93585,11 +93085,11 @@ |
| 93585 | 93085 | } |
| 93586 | 93086 | |
| 93587 | 93087 | /* If this is not a view, open the table and and all indices */ |
| 93588 | 93088 | if( !isView ){ |
| 93589 | 93089 | int nIdx; |
| 93590 | | - nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, |
| 93090 | + nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, 0, |
| 93591 | 93091 | &iDataCur, &iIdxCur); |
| 93592 | 93092 | aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1)); |
| 93593 | 93093 | if( aRegIdx==0 ){ |
| 93594 | 93094 | goto insert_cleanup; |
| 93595 | 93095 | } |
| | @@ -94445,42 +93945,50 @@ |
| 94445 | 93945 | SQLITE_PRIVATE int sqlite3OpenTableAndIndices( |
| 94446 | 93946 | Parse *pParse, /* Parsing context */ |
| 94447 | 93947 | Table *pTab, /* Table to be opened */ |
| 94448 | 93948 | int op, /* OP_OpenRead or OP_OpenWrite */ |
| 94449 | 93949 | int iBase, /* Use this for the table cursor, if there is one */ |
| 93950 | + u8 *aToOpen, /* If not NULL: boolean for each table and index */ |
| 94450 | 93951 | int *piDataCur, /* Write the database source cursor number here */ |
| 94451 | 93952 | int *piIdxCur /* Write the first index cursor number here */ |
| 94452 | 93953 | ){ |
| 94453 | 93954 | int i; |
| 94454 | 93955 | int iDb; |
| 93956 | + int iDataCur; |
| 94455 | 93957 | Index *pIdx; |
| 94456 | 93958 | Vdbe *v; |
| 94457 | 93959 | |
| 94458 | 93960 | assert( op==OP_OpenRead || op==OP_OpenWrite ); |
| 94459 | 93961 | if( IsVirtual(pTab) ){ |
| 93962 | + assert( aToOpen==0 ); |
| 94460 | 93963 | *piDataCur = 0; |
| 94461 | 93964 | *piIdxCur = 1; |
| 94462 | 93965 | return 0; |
| 94463 | 93966 | } |
| 94464 | 93967 | iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); |
| 94465 | 93968 | v = sqlite3GetVdbe(pParse); |
| 94466 | 93969 | assert( v!=0 ); |
| 94467 | 93970 | if( iBase<0 ) iBase = pParse->nTab; |
| 94468 | | - if( HasRowid(pTab) ){ |
| 94469 | | - *piDataCur = iBase++; |
| 94470 | | - sqlite3OpenTable(pParse, *piDataCur, iDb, pTab, op); |
| 93971 | + iDataCur = iBase++; |
| 93972 | + if( piDataCur ) *piDataCur = iDataCur; |
| 93973 | + if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ |
| 93974 | + sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); |
| 94471 | 93975 | }else{ |
| 94472 | 93976 | sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); |
| 94473 | 93977 | } |
| 94474 | | - *piIdxCur = iBase; |
| 93978 | + if( piIdxCur ) *piIdxCur = iBase; |
| 94475 | 93979 | for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ |
| 94476 | 93980 | int iIdxCur = iBase++; |
| 94477 | 93981 | assert( pIdx->pSchema==pTab->pSchema ); |
| 94478 | | - if( pIdx->autoIndex==2 && !HasRowid(pTab) ) *piDataCur = iIdxCur; |
| 94479 | | - sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); |
| 94480 | | - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 94481 | | - VdbeComment((v, "%s", pIdx->zName)); |
| 93982 | + if( pIdx->autoIndex==2 && !HasRowid(pTab) && piDataCur ){ |
| 93983 | + *piDataCur = iIdxCur; |
| 93984 | + } |
| 93985 | + if( aToOpen==0 || aToOpen[i+1] ){ |
| 93986 | + sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); |
| 93987 | + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 93988 | + VdbeComment((v, "%s", pIdx->zName)); |
| 93989 | + } |
| 94482 | 93990 | } |
| 94483 | 93991 | if( iBase>pParse->nTab ) pParse->nTab = iBase; |
| 94484 | 93992 | return i; |
| 94485 | 93993 | } |
| 94486 | 93994 | |
| | @@ -96650,10 +96158,14 @@ |
| 96650 | 96158 | /* iArg: */ SQLITE_VdbeAddopTrace }, |
| 96651 | 96159 | { /* zName: */ "vdbe_debug", |
| 96652 | 96160 | /* ePragTyp: */ PragTyp_FLAG, |
| 96653 | 96161 | /* ePragFlag: */ 0, |
| 96654 | 96162 | /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, |
| 96163 | + { /* zName: */ "vdbe_eqp", |
| 96164 | + /* ePragTyp: */ PragTyp_FLAG, |
| 96165 | + /* ePragFlag: */ 0, |
| 96166 | + /* iArg: */ SQLITE_VdbeEQP }, |
| 96655 | 96167 | { /* zName: */ "vdbe_listing", |
| 96656 | 96168 | /* ePragTyp: */ PragTyp_FLAG, |
| 96657 | 96169 | /* ePragFlag: */ 0, |
| 96658 | 96170 | /* iArg: */ SQLITE_VdbeListing }, |
| 96659 | 96171 | { /* zName: */ "vdbe_trace", |
| | @@ -96677,11 +96189,11 @@ |
| 96677 | 96189 | /* ePragTyp: */ PragTyp_FLAG, |
| 96678 | 96190 | /* ePragFlag: */ 0, |
| 96679 | 96191 | /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, |
| 96680 | 96192 | #endif |
| 96681 | 96193 | }; |
| 96682 | | -/* Number of pragmas: 56 on by default, 68 total. */ |
| 96194 | +/* Number of pragmas: 56 on by default, 69 total. */ |
| 96683 | 96195 | /* End of the automatically generated pragma table. |
| 96684 | 96196 | ***************************************************************************/ |
| 96685 | 96197 | |
| 96686 | 96198 | /* |
| 96687 | 96199 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| | @@ -98103,11 +97615,11 @@ |
| 98103 | 97615 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */ |
| 98104 | 97616 | sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); |
| 98105 | 97617 | sqlite3VdbeJumpHere(v, addr); |
| 98106 | 97618 | sqlite3ExprCacheClear(pParse); |
| 98107 | 97619 | sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, |
| 98108 | | - 1, &iDataCur, &iIdxCur); |
| 97620 | + 1, 0, &iDataCur, &iIdxCur); |
| 98109 | 97621 | sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); |
| 98110 | 97622 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ |
| 98111 | 97623 | sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ |
| 98112 | 97624 | } |
| 98113 | 97625 | pParse->nMem = MAX(pParse->nMem, 8+j); |
| | @@ -99038,10 +98550,17 @@ |
| 99038 | 98550 | } |
| 99039 | 98551 | assert( i>=0 && i<db->nDb ); |
| 99040 | 98552 | } |
| 99041 | 98553 | return i; |
| 99042 | 98554 | } |
| 98555 | + |
| 98556 | +/* |
| 98557 | +** Free all memory allocations in the pParse object |
| 98558 | +*/ |
| 98559 | +SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ |
| 98560 | + if( pParse ) sqlite3ExprListDelete(pParse->db, pParse->pConstExpr); |
| 98561 | +} |
| 99043 | 98562 | |
| 99044 | 98563 | /* |
| 99045 | 98564 | ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. |
| 99046 | 98565 | */ |
| 99047 | 98566 | static int sqlite3Prepare( |
| | @@ -99196,10 +98715,11 @@ |
| 99196 | 98715 | sqlite3DbFree(db, pT); |
| 99197 | 98716 | } |
| 99198 | 98717 | |
| 99199 | 98718 | end_prepare: |
| 99200 | 98719 | |
| 98720 | + sqlite3ParserReset(pParse); |
| 99201 | 98721 | sqlite3StackFree(db, pParse); |
| 99202 | 98722 | rc = sqlite3ApiExit(db, rc); |
| 99203 | 98723 | assert( (rc&db->errMask)==rc ); |
| 99204 | 98724 | return rc; |
| 99205 | 98725 | } |
| | @@ -99989,11 +99509,12 @@ |
| 99989 | 99509 | }else if( eDest!=SRT_Exists ){ |
| 99990 | 99510 | /* If the destination is an EXISTS(...) expression, the actual |
| 99991 | 99511 | ** values returned by the SELECT are not required. |
| 99992 | 99512 | */ |
| 99993 | 99513 | sqlite3ExprCacheClear(pParse); |
| 99994 | | - sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Output); |
| 99514 | + sqlite3ExprCodeExprList(pParse, pEList, regResult, |
| 99515 | + (eDest==SRT_Output)?SQLITE_ECEL_DUP:0); |
| 99995 | 99516 | } |
| 99996 | 99517 | nColumn = nResultCol; |
| 99997 | 99518 | |
| 99998 | 99519 | /* If the DISTINCT keyword was present on the SELECT statement |
| 99999 | 99520 | ** and this row has been seen before, then do not make this row |
| | @@ -101762,20 +101283,20 @@ |
| 101762 | 101283 | */ |
| 101763 | 101284 | if( op!=TK_ALL ){ |
| 101764 | 101285 | for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ |
| 101765 | 101286 | struct ExprList_item *pItem; |
| 101766 | 101287 | for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){ |
| 101767 | | - assert( pItem->iOrderByCol>0 ); |
| 101768 | | - if( pItem->iOrderByCol==i ) break; |
| 101288 | + assert( pItem->u.x.iOrderByCol>0 ); |
| 101289 | + if( pItem->u.x.iOrderByCol==i ) break; |
| 101769 | 101290 | } |
| 101770 | 101291 | if( j==nOrderBy ){ |
| 101771 | 101292 | Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); |
| 101772 | 101293 | if( pNew==0 ) return SQLITE_NOMEM; |
| 101773 | 101294 | pNew->flags |= EP_IntValue; |
| 101774 | 101295 | pNew->u.iValue = i; |
| 101775 | 101296 | pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); |
| 101776 | | - if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i; |
| 101297 | + if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; |
| 101777 | 101298 | } |
| 101778 | 101299 | } |
| 101779 | 101300 | } |
| 101780 | 101301 | |
| 101781 | 101302 | /* Compute the comparison permutation and keyinfo that is used with |
| | @@ -101787,12 +101308,13 @@ |
| 101787 | 101308 | */ |
| 101788 | 101309 | aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy); |
| 101789 | 101310 | if( aPermute ){ |
| 101790 | 101311 | struct ExprList_item *pItem; |
| 101791 | 101312 | for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){ |
| 101792 | | - assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr ); |
| 101793 | | - aPermute[i] = pItem->iOrderByCol - 1; |
| 101313 | + assert( pItem->u.x.iOrderByCol>0 |
| 101314 | + && pItem->u.x.iOrderByCol<=p->pEList->nExpr ); |
| 101315 | + aPermute[i] = pItem->u.x.iOrderByCol - 1; |
| 101794 | 101316 | } |
| 101795 | 101317 | pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1); |
| 101796 | 101318 | if( pKeyMerge ){ |
| 101797 | 101319 | for(i=0; i<nOrderBy; i++){ |
| 101798 | 101320 | CollSeq *pColl; |
| | @@ -102368,11 +101890,11 @@ |
| 102368 | 101890 | |
| 102369 | 101891 | /* Restriction 18. */ |
| 102370 | 101892 | if( p->pOrderBy ){ |
| 102371 | 101893 | int ii; |
| 102372 | 101894 | for(ii=0; ii<p->pOrderBy->nExpr; ii++){ |
| 102373 | | - if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0; |
| 101895 | + if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; |
| 102374 | 101896 | } |
| 102375 | 101897 | } |
| 102376 | 101898 | } |
| 102377 | 101899 | |
| 102378 | 101900 | /***** If we reach this point, flattening is permitted. *****/ |
| | @@ -103274,11 +102796,11 @@ |
| 103274 | 102796 | ExprList *pList = pF->pExpr->x.pList; |
| 103275 | 102797 | assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); |
| 103276 | 102798 | if( pList ){ |
| 103277 | 102799 | nArg = pList->nExpr; |
| 103278 | 102800 | regAgg = sqlite3GetTempRange(pParse, nArg); |
| 103279 | | - sqlite3ExprCodeExprList(pParse, pList, regAgg, 1); |
| 102801 | + sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP); |
| 103280 | 102802 | }else{ |
| 103281 | 102803 | nArg = 0; |
| 103282 | 102804 | regAgg = 0; |
| 103283 | 102805 | } |
| 103284 | 102806 | if( pF->iDistinct>=0 ){ |
| | @@ -103775,14 +103297,14 @@ |
| 103775 | 103297 | if( pGroupBy ){ |
| 103776 | 103298 | int k; /* Loop counter */ |
| 103777 | 103299 | struct ExprList_item *pItem; /* For looping over expression in a list */ |
| 103778 | 103300 | |
| 103779 | 103301 | for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){ |
| 103780 | | - pItem->iAlias = 0; |
| 103302 | + pItem->u.x.iAlias = 0; |
| 103781 | 103303 | } |
| 103782 | 103304 | for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ |
| 103783 | | - pItem->iAlias = 0; |
| 103305 | + pItem->u.x.iAlias = 0; |
| 103784 | 103306 | } |
| 103785 | 103307 | if( p->nSelectRow>100 ) p->nSelectRow = 100; |
| 103786 | 103308 | }else{ |
| 103787 | 103309 | p->nSelectRow = 1; |
| 103788 | 103310 | } |
| | @@ -104060,15 +103582,16 @@ |
| 104060 | 103582 | |
| 104061 | 103583 | /* Search for the index that has the lowest scan cost. |
| 104062 | 103584 | ** |
| 104063 | 103585 | ** (2011-04-15) Do not do a full scan of an unordered index. |
| 104064 | 103586 | ** |
| 104065 | | - ** (2013-10-03) Do not count the entires in a partial index. |
| 103587 | + ** (2013-10-03) Do not count the entries in a partial index. |
| 104066 | 103588 | ** |
| 104067 | 103589 | ** In practice the KeyInfo structure will not be used. It is only |
| 104068 | 103590 | ** passed to keep OP_OpenRead happy. |
| 104069 | 103591 | */ |
| 103592 | + if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab); |
| 104070 | 103593 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 104071 | 103594 | if( pIdx->bUnordered==0 |
| 104072 | 103595 | && pIdx->szIdxRow<pTab->szTabRow |
| 104073 | 103596 | && pIdx->pPartIdxWhere==0 |
| 104074 | 103597 | && (!pBest || pIdx->szIdxRow<pBest->szIdxRow) |
| | @@ -105428,10 +104951,11 @@ |
| 105428 | 104951 | sqlite3VdbeDelete(v); |
| 105429 | 104952 | } |
| 105430 | 104953 | |
| 105431 | 104954 | assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); |
| 105432 | 104955 | assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); |
| 104956 | + sqlite3ParserReset(pSubParse); |
| 105433 | 104957 | sqlite3StackFree(db, pSubParse); |
| 105434 | 104958 | |
| 105435 | 104959 | return pPrg; |
| 105436 | 104960 | } |
| 105437 | 104961 | |
| | @@ -105742,22 +105266,23 @@ |
| 105742 | 105266 | WhereInfo *pWInfo; /* Information about the WHERE clause */ |
| 105743 | 105267 | Vdbe *v; /* The virtual database engine */ |
| 105744 | 105268 | Index *pIdx; /* For looping over indices */ |
| 105745 | 105269 | Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */ |
| 105746 | 105270 | int nIdx; /* Number of indices that need updating */ |
| 105271 | + int iBaseCur; /* Base cursor number */ |
| 105747 | 105272 | int iDataCur; /* Cursor for the canonical data btree */ |
| 105748 | 105273 | int iIdxCur; /* Cursor for the first index */ |
| 105749 | 105274 | sqlite3 *db; /* The database structure */ |
| 105750 | 105275 | int *aRegIdx = 0; /* One register assigned to each index to be updated */ |
| 105751 | 105276 | int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the |
| 105752 | 105277 | ** an expression for the i-th column of the table. |
| 105753 | 105278 | ** aXRef[i]==-1 if the i-th column is not changed. */ |
| 105279 | + u8 *aToOpen; /* 1 for tables and indices to be opened */ |
| 105754 | 105280 | u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */ |
| 105755 | 105281 | u8 chngRowid; /* Rowid changed in a normal table */ |
| 105756 | 105282 | u8 chngKey; /* Either chngPk or chngRowid */ |
| 105757 | 105283 | Expr *pRowidExpr = 0; /* Expression defining the new record number */ |
| 105758 | | - int openAll = 0; /* True if all indices need to be opened */ |
| 105759 | 105284 | AuthContext sContext; /* The authorization context */ |
| 105760 | 105285 | NameContext sNC; /* The name-context to resolve expressions in */ |
| 105761 | 105286 | int iDb; /* Database containing the table being updated */ |
| 105762 | 105287 | int okOnePass; /* True for one-pass algorithm without the FIFO */ |
| 105763 | 105288 | int hasFK; /* True if foreign key processing is required */ |
| | @@ -105817,29 +105342,37 @@ |
| 105817 | 105342 | goto update_cleanup; |
| 105818 | 105343 | } |
| 105819 | 105344 | if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ |
| 105820 | 105345 | goto update_cleanup; |
| 105821 | 105346 | } |
| 105822 | | - aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol ); |
| 105823 | | - if( aXRef==0 ) goto update_cleanup; |
| 105824 | | - for(i=0; i<pTab->nCol; i++) aXRef[i] = -1; |
| 105825 | 105347 | |
| 105826 | 105348 | /* Allocate a cursors for the main database table and for all indices. |
| 105827 | 105349 | ** The index cursors might not be used, but if they are used they |
| 105828 | 105350 | ** need to occur right after the database cursor. So go ahead and |
| 105829 | 105351 | ** allocate enough space, just in case. |
| 105830 | 105352 | */ |
| 105831 | | - pTabList->a[0].iCursor = iDataCur = pParse->nTab++; |
| 105353 | + pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++; |
| 105832 | 105354 | iIdxCur = iDataCur+1; |
| 105833 | 105355 | pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); |
| 105834 | 105356 | for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ |
| 105835 | 105357 | if( pIdx->autoIndex==2 && pPk!=0 ){ |
| 105836 | 105358 | iDataCur = pParse->nTab; |
| 105837 | 105359 | pTabList->a[0].iCursor = iDataCur; |
| 105838 | 105360 | } |
| 105839 | 105361 | pParse->nTab++; |
| 105840 | 105362 | } |
| 105363 | + |
| 105364 | + /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. |
| 105365 | + ** Initialize aXRef[] and aToOpen[] to their default values. |
| 105366 | + */ |
| 105367 | + aXRef = sqlite3DbMallocRaw(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 ); |
| 105368 | + if( aXRef==0 ) goto update_cleanup; |
| 105369 | + aRegIdx = aXRef+pTab->nCol; |
| 105370 | + aToOpen = (u8*)(aRegIdx+nIdx); |
| 105371 | + memset(aToOpen, 1, nIdx+1); |
| 105372 | + aToOpen[nIdx+1] = 0; |
| 105373 | + for(i=0; i<pTab->nCol; i++) aXRef[i] = -1; |
| 105841 | 105374 | |
| 105842 | 105375 | /* Initialize the name-context */ |
| 105843 | 105376 | memset(&sNC, 0, sizeof(sNC)); |
| 105844 | 105377 | sNC.pParse = pParse; |
| 105845 | 105378 | sNC.pSrcList = pTabList; |
| | @@ -105894,22 +105427,22 @@ |
| 105894 | 105427 | } |
| 105895 | 105428 | assert( (chngRowid & chngPk)==0 ); |
| 105896 | 105429 | assert( chngRowid==0 || chngRowid==1 ); |
| 105897 | 105430 | assert( chngPk==0 || chngPk==1 ); |
| 105898 | 105431 | chngKey = chngRowid + chngPk; |
| 105432 | + |
| 105433 | + /* The SET expressions are not actually used inside the WHERE loop. |
| 105434 | + ** So reset the colUsed mask |
| 105435 | + */ |
| 105436 | + pTabList->a[0].colUsed = 0; |
| 105899 | 105437 | |
| 105900 | 105438 | hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); |
| 105901 | 105439 | |
| 105902 | | - /* Allocate memory for the array aRegIdx[]. There is one entry in the |
| 105903 | | - ** array for each index associated with table being updated. Fill in |
| 105904 | | - ** the value with a register number for indices that are to be used |
| 105905 | | - ** and with zero for unused indices. |
| 105440 | + /* There is one entry in the aRegIdx[] array for each index on the table |
| 105441 | + ** being updated. Fill in aRegIdx[] with a register number that will hold |
| 105442 | + ** the key for accessing each index. |
| 105906 | 105443 | */ |
| 105907 | | - if( nIdx>0 ){ |
| 105908 | | - aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx ); |
| 105909 | | - if( aRegIdx==0 ) goto update_cleanup; |
| 105910 | | - } |
| 105911 | 105444 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ |
| 105912 | 105445 | int reg; |
| 105913 | 105446 | if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){ |
| 105914 | 105447 | reg = ++pParse->nMem; |
| 105915 | 105448 | }else{ |
| | @@ -105919,10 +105452,11 @@ |
| 105919 | 105452 | reg = ++pParse->nMem; |
| 105920 | 105453 | break; |
| 105921 | 105454 | } |
| 105922 | 105455 | } |
| 105923 | 105456 | } |
| 105457 | + if( reg==0 ) aToOpen[j+1] = 0; |
| 105924 | 105458 | aRegIdx[j] = reg; |
| 105925 | 105459 | } |
| 105926 | 105460 | |
| 105927 | 105461 | /* Begin generating code. */ |
| 105928 | 105462 | v = sqlite3GetVdbe(pParse); |
| | @@ -106042,46 +105576,34 @@ |
| 106042 | 105576 | ** Open every index that needs updating. Note that if any |
| 106043 | 105577 | ** index could potentially invoke a REPLACE conflict resolution |
| 106044 | 105578 | ** action, then we need to open all indices because we might need |
| 106045 | 105579 | ** to be deleting some records. |
| 106046 | 105580 | */ |
| 106047 | | - if( !okOnePass && HasRowid(pTab) ){ |
| 106048 | | - sqlite3OpenTable(pParse, iDataCur, iDb, pTab, OP_OpenWrite); |
| 106049 | | - } |
| 106050 | | - sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); |
| 106051 | 105581 | if( onError==OE_Replace ){ |
| 106052 | | - openAll = 1; |
| 105582 | + memset(aToOpen, 1, nIdx+1); |
| 106053 | 105583 | }else{ |
| 106054 | | - openAll = 0; |
| 106055 | 105584 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 106056 | 105585 | if( pIdx->onError==OE_Replace ){ |
| 106057 | | - openAll = 1; |
| 105586 | + memset(aToOpen, 1, nIdx+1); |
| 106058 | 105587 | break; |
| 106059 | 105588 | } |
| 106060 | 105589 | } |
| 106061 | 105590 | } |
| 106062 | | - for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ |
| 106063 | | - int iThisCur = iIdxCur+i; |
| 106064 | | - assert( aRegIdx ); |
| 106065 | | - if( (openAll || aRegIdx[i]>0) |
| 106066 | | - && iThisCur!=aiCurOnePass[1] |
| 106067 | | - ){ |
| 106068 | | - assert( iThisCur!=aiCurOnePass[0] ); |
| 106069 | | - sqlite3VdbeAddOp3(v, OP_OpenWrite, iThisCur, pIdx->tnum, iDb); |
| 106070 | | - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 106071 | | - assert( pParse->nTab>iThisCur ); |
| 106072 | | - VdbeComment((v, "%s", pIdx->zName)); |
| 106073 | | - if( okOnePass && pPk && iThisCur==iDataCur ){ |
| 106074 | | - sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, |
| 106075 | | - regKey, nKey); |
| 106076 | | - } |
| 106077 | | - } |
| 106078 | | - } |
| 105591 | + if( okOnePass ){ |
| 105592 | + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; |
| 105593 | + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; |
| 105594 | + } |
| 105595 | + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen, |
| 105596 | + 0, 0); |
| 106079 | 105597 | } |
| 106080 | 105598 | |
| 106081 | 105599 | /* Top of the update loop */ |
| 106082 | 105600 | if( okOnePass ){ |
| 105601 | + if( aToOpen[iDataCur-iBaseCur] ){ |
| 105602 | + assert( pPk!=0 ); |
| 105603 | + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); |
| 105604 | + } |
| 106083 | 105605 | labelContinue = labelBreak; |
| 106084 | 105606 | sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); |
| 106085 | 105607 | }else if( pPk ){ |
| 106086 | 105608 | labelContinue = sqlite3VdbeMakeLabel(v); |
| 106087 | 105609 | sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); |
| | @@ -106222,15 +105744,11 @@ |
| 106222 | 105744 | /* If changing the record number, delete the old record. */ |
| 106223 | 105745 | if( hasFK || chngKey || pPk!=0 ){ |
| 106224 | 105746 | sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); |
| 106225 | 105747 | } |
| 106226 | 105748 | if( bReplace || chngKey ){ |
| 106227 | | - if( sqlite3VdbeCurrentAddr(v)==j1+1 ){ |
| 106228 | | - sqlite3VdbeChangeToNoop(v, j1); |
| 106229 | | - }else{ |
| 106230 | | - sqlite3VdbeJumpHere(v, j1); |
| 106231 | | - } |
| 105749 | + sqlite3VdbeJumpHere(v, j1); |
| 106232 | 105750 | } |
| 106233 | 105751 | |
| 106234 | 105752 | if( hasFK ){ |
| 106235 | 105753 | sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); |
| 106236 | 105754 | } |
| | @@ -106270,11 +105788,11 @@ |
| 106270 | 105788 | sqlite3VdbeResolveLabel(v, labelBreak); |
| 106271 | 105789 | |
| 106272 | 105790 | /* Close all tables */ |
| 106273 | 105791 | for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ |
| 106274 | 105792 | assert( aRegIdx ); |
| 106275 | | - if( openAll || aRegIdx[i]>0 ){ |
| 105793 | + if( aToOpen[i+1] ){ |
| 106276 | 105794 | sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0); |
| 106277 | 105795 | } |
| 106278 | 105796 | } |
| 106279 | 105797 | if( iDataCur<iIdxCur ) sqlite3VdbeAddOp2(v, OP_Close, iDataCur, 0); |
| 106280 | 105798 | |
| | @@ -106297,12 +105815,11 @@ |
| 106297 | 105815 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); |
| 106298 | 105816 | } |
| 106299 | 105817 | |
| 106300 | 105818 | update_cleanup: |
| 106301 | 105819 | sqlite3AuthContextPop(&sContext); |
| 106302 | | - sqlite3DbFree(db, aRegIdx); |
| 106303 | | - sqlite3DbFree(db, aXRef); |
| 105820 | + sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ |
| 106304 | 105821 | sqlite3SrcListDelete(db, pTabList); |
| 106305 | 105822 | sqlite3ExprListDelete(db, pChanges); |
| 106306 | 105823 | sqlite3ExprDelete(db, pWhere); |
| 106307 | 105824 | return; |
| 106308 | 105825 | } |
| | @@ -107521,10 +107038,11 @@ |
| 107521 | 107038 | |
| 107522 | 107039 | if( pParse->pVdbe ){ |
| 107523 | 107040 | sqlite3VdbeFinalize(pParse->pVdbe); |
| 107524 | 107041 | } |
| 107525 | 107042 | sqlite3DeleteTable(db, pParse->pNewTable); |
| 107043 | + sqlite3ParserReset(pParse); |
| 107526 | 107044 | sqlite3StackFree(db, pParse); |
| 107527 | 107045 | } |
| 107528 | 107046 | |
| 107529 | 107047 | assert( (rc&0xff)==rc ); |
| 107530 | 107048 | rc = sqlite3ApiExit(db, rc); |
| | @@ -107898,11 +107416,28 @@ |
| 107898 | 107416 | ** generating the code that loops through a table looking for applicable |
| 107899 | 107417 | ** rows. Indices are selected and used to speed the search when doing |
| 107900 | 107418 | ** so is applicable. Because this module is responsible for selecting |
| 107901 | 107419 | ** indices, you might also think of this module as the "query optimizer". |
| 107902 | 107420 | */ |
| 107903 | | - |
| 107421 | +/************** Include whereInt.h in the middle of where.c ******************/ |
| 107422 | +/************** Begin file whereInt.h ****************************************/ |
| 107423 | +/* |
| 107424 | +** 2013-11-12 |
| 107425 | +** |
| 107426 | +** The author disclaims copyright to this source code. In place of |
| 107427 | +** a legal notice, here is a blessing: |
| 107428 | +** |
| 107429 | +** May you do good and not evil. |
| 107430 | +** May you find forgiveness for yourself and forgive others. |
| 107431 | +** May you share freely, never taking more than you give. |
| 107432 | +** |
| 107433 | +************************************************************************* |
| 107434 | +** |
| 107435 | +** This file contains structure and macro definitions for the query |
| 107436 | +** planner logic in "where.c". These definitions are broken out into |
| 107437 | +** a separate source file for easier editing. |
| 107438 | +*/ |
| 107904 | 107439 | |
| 107905 | 107440 | /* |
| 107906 | 107441 | ** Trace output macros |
| 107907 | 107442 | */ |
| 107908 | 107443 | #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) |
| | @@ -107950,10 +107485,11 @@ |
| 107950 | 107485 | int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */ |
| 107951 | 107486 | int iTabCur; /* The VDBE cursor used to access the table */ |
| 107952 | 107487 | int iIdxCur; /* The VDBE cursor used to access pIdx */ |
| 107953 | 107488 | int addrBrk; /* Jump here to break out of the loop */ |
| 107954 | 107489 | int addrNxt; /* Jump here to start the next IN combination */ |
| 107490 | + int addrSkip; /* Jump here for next iteration of skip-scan */ |
| 107955 | 107491 | int addrCont; /* Jump here to continue with the next loop cycle */ |
| 107956 | 107492 | int addrFirst; /* First instruction of interior of the loop */ |
| 107957 | 107493 | int addrBody; /* Beginning of the body of this loop */ |
| 107958 | 107494 | u8 iFrom; /* Which entry in the FROM clause */ |
| 107959 | 107495 | u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */ |
| | @@ -107998,11 +107534,12 @@ |
| 107998 | 107534 | LogEst rSetup; /* One-time setup cost (ex: create transient index) */ |
| 107999 | 107535 | LogEst rRun; /* Cost of running each loop */ |
| 108000 | 107536 | LogEst nOut; /* Estimated number of output rows */ |
| 108001 | 107537 | union { |
| 108002 | 107538 | struct { /* Information for internal btree tables */ |
| 108003 | | - int nEq; /* Number of equality constraints */ |
| 107539 | + u16 nEq; /* Number of equality constraints */ |
| 107540 | + u16 nSkip; /* Number of initial index columns to skip */ |
| 108004 | 107541 | Index *pIndex; /* Index used, or NULL */ |
| 108005 | 107542 | } btree; |
| 108006 | 107543 | struct { /* Information for virtual tables */ |
| 108007 | 107544 | int idxNum; /* Index number */ |
| 108008 | 107545 | u8 needFree; /* True if sqlite3_free(idxStr) is needed */ |
| | @@ -108339,10 +107876,14 @@ |
| 108339 | 107876 | #define WHERE_VIRTUALTABLE 0x00000400 /* WhereLoop.u.vtab is valid */ |
| 108340 | 107877 | #define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */ |
| 108341 | 107878 | #define WHERE_ONEROW 0x00001000 /* Selects no more than one row */ |
| 108342 | 107879 | #define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */ |
| 108343 | 107880 | #define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */ |
| 107881 | +#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ |
| 107882 | + |
| 107883 | +/************** End of whereInt.h ********************************************/ |
| 107884 | +/************** Continuing where we left off in where.c **********************/ |
| 108344 | 107885 | |
| 108345 | 107886 | /* |
| 108346 | 107887 | ** Return the estimated number of output rows from a WHERE clause |
| 108347 | 107888 | */ |
| 108348 | 107889 | SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){ |
| | @@ -108990,13 +108531,10 @@ |
| 108990 | 108531 | } |
| 108991 | 108532 | assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */ |
| 108992 | 108533 | |
| 108993 | 108534 | pRight = pList->a[0].pExpr; |
| 108994 | 108535 | op = pRight->op; |
| 108995 | | - if( op==TK_REGISTER ){ |
| 108996 | | - op = pRight->op2; |
| 108997 | | - } |
| 108998 | 108536 | if( op==TK_VARIABLE ){ |
| 108999 | 108537 | Vdbe *pReprepare = pParse->pReprepare; |
| 109000 | 108538 | int iCol = pRight->iColumn; |
| 109001 | 108539 | pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE); |
| 109002 | 108540 | if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ |
| | @@ -109859,10 +109397,11 @@ |
| 109859 | 109397 | } |
| 109860 | 109398 | sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); |
| 109861 | 109399 | sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); |
| 109862 | 109400 | sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); |
| 109863 | 109401 | sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); |
| 109402 | + sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); |
| 109864 | 109403 | } |
| 109865 | 109404 | #else |
| 109866 | 109405 | #define TRACE_IDX_INPUTS(A) |
| 109867 | 109406 | #define TRACE_IDX_OUTPUTS(A) |
| 109868 | 109407 | #endif |
| | @@ -110228,12 +109767,11 @@ |
| 110228 | 109767 | int res; /* Result of comparison operation */ |
| 110229 | 109768 | |
| 110230 | 109769 | #ifndef SQLITE_DEBUG |
| 110231 | 109770 | UNUSED_PARAMETER( pParse ); |
| 110232 | 109771 | #endif |
| 110233 | | - assert( pRec!=0 || pParse->db->mallocFailed ); |
| 110234 | | - if( pRec==0 ) return; |
| 109772 | + assert( pRec!=0 ); |
| 110235 | 109773 | iCol = pRec->nField - 1; |
| 110236 | 109774 | assert( pIdx->nSample>0 ); |
| 110237 | 109775 | assert( pRec->nField>0 && iCol<pIdx->nSampleCol ); |
| 110238 | 109776 | do{ |
| 110239 | 109777 | iTest = (iMin+i)/2; |
| | @@ -110729,11 +110267,11 @@ |
| 110729 | 110267 | if( eType==IN_INDEX_ROWID ){ |
| 110730 | 110268 | pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg); |
| 110731 | 110269 | }else{ |
| 110732 | 110270 | pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg); |
| 110733 | 110271 | } |
| 110734 | | - pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; |
| 110272 | + pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; |
| 110735 | 110273 | sqlite3VdbeAddOp1(v, OP_IsNull, iReg); |
| 110736 | 110274 | }else{ |
| 110737 | 110275 | pLevel->u.in.nIn = 0; |
| 110738 | 110276 | } |
| 110739 | 110277 | #endif |
| | @@ -110742,11 +110280,11 @@ |
| 110742 | 110280 | return iReg; |
| 110743 | 110281 | } |
| 110744 | 110282 | |
| 110745 | 110283 | /* |
| 110746 | 110284 | ** Generate code that will evaluate all == and IN constraints for an |
| 110747 | | -** index. |
| 110285 | +** index scan. |
| 110748 | 110286 | ** |
| 110749 | 110287 | ** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). |
| 110750 | 110288 | ** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 |
| 110751 | 110289 | ** The index has as many as three equality constraints, but in this |
| 110752 | 110290 | ** example, the third "c" value is an inequality. So only two |
| | @@ -110757,13 +110295,19 @@ |
| 110757 | 110295 | ** In the example above nEq==2. But this subroutine works for any value |
| 110758 | 110296 | ** of nEq including 0. If nEq==0, this routine is nearly a no-op. |
| 110759 | 110297 | ** The only thing it does is allocate the pLevel->iMem memory cell and |
| 110760 | 110298 | ** compute the affinity string. |
| 110761 | 110299 | ** |
| 110762 | | -** This routine always allocates at least one memory cell and returns |
| 110763 | | -** the index of that memory cell. The code that |
| 110764 | | -** calls this routine will use that memory cell to store the termination |
| 110300 | +** The nExtraReg parameter is 0 or 1. It is 0 if all WHERE clause constraints |
| 110301 | +** are == or IN and are covered by the nEq. nExtraReg is 1 if there is |
| 110302 | +** an inequality constraint (such as the "c>=5 AND c<10" in the example) that |
| 110303 | +** occurs after the nEq quality constraints. |
| 110304 | +** |
| 110305 | +** This routine allocates a range of nEq+nExtraReg memory cells and returns |
| 110306 | +** the index of the first memory cell in that range. The code that |
| 110307 | +** calls this routine will use that memory range to store keys for |
| 110308 | +** start and termination conditions of the loop. |
| 110765 | 110309 | ** key value of the loop. If one or more IN operators appear, then |
| 110766 | 110310 | ** this routine allocates an additional nEq memory cells for internal |
| 110767 | 110311 | ** use. |
| 110768 | 110312 | ** |
| 110769 | 110313 | ** Before returning, *pzAff is set to point to a buffer containing a |
| | @@ -110786,11 +110330,12 @@ |
| 110786 | 110330 | WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ |
| 110787 | 110331 | int bRev, /* Reverse the order of IN operators */ |
| 110788 | 110332 | int nExtraReg, /* Number of extra registers to allocate */ |
| 110789 | 110333 | char **pzAff /* OUT: Set to point to affinity string */ |
| 110790 | 110334 | ){ |
| 110791 | | - int nEq; /* The number of == or IN constraints to code */ |
| 110335 | + u16 nEq; /* The number of == or IN constraints to code */ |
| 110336 | + u16 nSkip; /* Number of left-most columns to skip */ |
| 110792 | 110337 | Vdbe *v = pParse->pVdbe; /* The vm under construction */ |
| 110793 | 110338 | Index *pIdx; /* The index being used for this loop */ |
| 110794 | 110339 | WhereTerm *pTerm; /* A single constraint term */ |
| 110795 | 110340 | WhereLoop *pLoop; /* The WhereLoop object */ |
| 110796 | 110341 | int j; /* Loop counter */ |
| | @@ -110800,10 +110345,11 @@ |
| 110800 | 110345 | |
| 110801 | 110346 | /* This module is only called on query plans that use an index. */ |
| 110802 | 110347 | pLoop = pLevel->pWLoop; |
| 110803 | 110348 | assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); |
| 110804 | 110349 | nEq = pLoop->u.btree.nEq; |
| 110350 | + nSkip = pLoop->u.btree.nSkip; |
| 110805 | 110351 | pIdx = pLoop->u.btree.pIndex; |
| 110806 | 110352 | assert( pIdx!=0 ); |
| 110807 | 110353 | |
| 110808 | 110354 | /* Figure out how many memory cells we will need then allocate them. |
| 110809 | 110355 | */ |
| | @@ -110813,19 +110359,34 @@ |
| 110813 | 110359 | |
| 110814 | 110360 | zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx)); |
| 110815 | 110361 | if( !zAff ){ |
| 110816 | 110362 | pParse->db->mallocFailed = 1; |
| 110817 | 110363 | } |
| 110364 | + |
| 110365 | + if( nSkip ){ |
| 110366 | + int iIdxCur = pLevel->iIdxCur; |
| 110367 | + sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); |
| 110368 | + VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); |
| 110369 | + j = sqlite3VdbeAddOp0(v, OP_Goto); |
| 110370 | + pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLt:OP_SeekGt), |
| 110371 | + iIdxCur, 0, regBase, nSkip); |
| 110372 | + sqlite3VdbeJumpHere(v, j); |
| 110373 | + for(j=0; j<nSkip; j++){ |
| 110374 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j); |
| 110375 | + assert( pIdx->aiColumn[j]>=0 ); |
| 110376 | + VdbeComment((v, "%s", pIdx->pTable->aCol[pIdx->aiColumn[j]].zName)); |
| 110377 | + } |
| 110378 | + } |
| 110818 | 110379 | |
| 110819 | 110380 | /* Evaluate the equality constraints |
| 110820 | 110381 | */ |
| 110821 | 110382 | assert( zAff==0 || (int)strlen(zAff)>=nEq ); |
| 110822 | | - for(j=0; j<nEq; j++){ |
| 110383 | + for(j=nSkip; j<nEq; j++){ |
| 110823 | 110384 | int r1; |
| 110824 | 110385 | pTerm = pLoop->aLTerm[j]; |
| 110825 | 110386 | assert( pTerm!=0 ); |
| 110826 | | - /* The following true for indices with redundant columns. |
| 110387 | + /* The following testcase is true for indices with redundant columns. |
| 110827 | 110388 | ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ |
| 110828 | 110389 | testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); |
| 110829 | 110390 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); |
| 110830 | 110391 | r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); |
| 110831 | 110392 | if( r1!=regBase+j ){ |
| | @@ -110869,11 +110430,11 @@ |
| 110869 | 110430 | int iTerm, /* Index of this term. First is zero */ |
| 110870 | 110431 | const char *zColumn, /* Name of the column */ |
| 110871 | 110432 | const char *zOp /* Name of the operator */ |
| 110872 | 110433 | ){ |
| 110873 | 110434 | if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5); |
| 110874 | | - sqlite3StrAccumAppend(pStr, zColumn, -1); |
| 110435 | + sqlite3StrAccumAppendAll(pStr, zColumn); |
| 110875 | 110436 | sqlite3StrAccumAppend(pStr, zOp, 1); |
| 110876 | 110437 | sqlite3StrAccumAppend(pStr, "?", 1); |
| 110877 | 110438 | } |
| 110878 | 110439 | |
| 110879 | 110440 | /* |
| | @@ -110895,11 +110456,12 @@ |
| 110895 | 110456 | ** It is the responsibility of the caller to free the buffer when it is |
| 110896 | 110457 | ** no longer required. |
| 110897 | 110458 | */ |
| 110898 | 110459 | static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){ |
| 110899 | 110460 | Index *pIndex = pLoop->u.btree.pIndex; |
| 110900 | | - int nEq = pLoop->u.btree.nEq; |
| 110461 | + u16 nEq = pLoop->u.btree.nEq; |
| 110462 | + u16 nSkip = pLoop->u.btree.nSkip; |
| 110901 | 110463 | int i, j; |
| 110902 | 110464 | Column *aCol = pTab->aCol; |
| 110903 | 110465 | i16 *aiColumn = pIndex->aiColumn; |
| 110904 | 110466 | StrAccum txt; |
| 110905 | 110467 | |
| | @@ -110909,11 +110471,18 @@ |
| 110909 | 110471 | sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH); |
| 110910 | 110472 | txt.db = db; |
| 110911 | 110473 | sqlite3StrAccumAppend(&txt, " (", 2); |
| 110912 | 110474 | for(i=0; i<nEq; i++){ |
| 110913 | 110475 | char *z = (i==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[i]].zName; |
| 110914 | | - explainAppendTerm(&txt, i, z, "="); |
| 110476 | + if( i>=nSkip ){ |
| 110477 | + explainAppendTerm(&txt, i, z, "="); |
| 110478 | + }else{ |
| 110479 | + if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5); |
| 110480 | + sqlite3StrAccumAppend(&txt, "ANY(", 4); |
| 110481 | + sqlite3StrAccumAppendAll(&txt, z); |
| 110482 | + sqlite3StrAccumAppend(&txt, ")", 1); |
| 110483 | + } |
| 110915 | 110484 | } |
| 110916 | 110485 | |
| 110917 | 110486 | j = i; |
| 110918 | 110487 | if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ |
| 110919 | 110488 | char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName; |
| | @@ -110939,11 +110508,14 @@ |
| 110939 | 110508 | WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ |
| 110940 | 110509 | int iLevel, /* Value for "level" column of output */ |
| 110941 | 110510 | int iFrom, /* Value for "from" column of output */ |
| 110942 | 110511 | u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ |
| 110943 | 110512 | ){ |
| 110944 | | - if( pParse->explain==2 ){ |
| 110513 | +#ifndef SQLITE_DEBUG |
| 110514 | + if( pParse->explain==2 ) |
| 110515 | +#endif |
| 110516 | + { |
| 110945 | 110517 | struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; |
| 110946 | 110518 | Vdbe *v = pParse->pVdbe; /* VM being constructed */ |
| 110947 | 110519 | sqlite3 *db = pParse->db; /* Database handle */ |
| 110948 | 110520 | char *zMsg; /* Text to add to EQP output */ |
| 110949 | 110521 | int iId = pParse->iSelectId; /* Select id (left-most output column) */ |
| | @@ -111045,11 +110617,11 @@ |
| 111045 | 110617 | iCur = pTabItem->iCursor; |
| 111046 | 110618 | pLevel->notReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur); |
| 111047 | 110619 | bRev = (pWInfo->revMask>>iLevel)&1; |
| 111048 | 110620 | omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 |
| 111049 | 110621 | && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0; |
| 111050 | | - VdbeNoopComment((v, "Begin WHERE-Loop %d: %s", iLevel,pTabItem->pTab->zName)); |
| 110622 | + VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); |
| 111051 | 110623 | |
| 111052 | 110624 | /* Create labels for the "break" and "continue" instructions |
| 111053 | 110625 | ** for the current loop. Jump to addrBrk to break out of a loop. |
| 111054 | 110626 | ** Jump to cont to go immediately to the next iteration of the |
| 111055 | 110627 | ** loop. |
| | @@ -111272,12 +110844,12 @@ |
| 111272 | 110844 | static const u8 aEndOp[] = { |
| 111273 | 110845 | OP_Noop, /* 0: (!end_constraints) */ |
| 111274 | 110846 | OP_IdxGE, /* 1: (end_constraints && !bRev) */ |
| 111275 | 110847 | OP_IdxLT /* 2: (end_constraints && bRev) */ |
| 111276 | 110848 | }; |
| 111277 | | - int nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ |
| 111278 | | - int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ |
| 110849 | + u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ |
| 110850 | + int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ |
| 111279 | 110851 | int regBase; /* Base register holding constraint values */ |
| 111280 | 110852 | int r1; /* Temp register */ |
| 111281 | 110853 | WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ |
| 111282 | 110854 | WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ |
| 111283 | 110855 | int startEq; /* True if range start uses ==, >= or <= */ |
| | @@ -111287,14 +110859,15 @@ |
| 111287 | 110859 | Index *pIdx; /* The index we will be using */ |
| 111288 | 110860 | int iIdxCur; /* The VDBE cursor for the index */ |
| 111289 | 110861 | int nExtraReg = 0; /* Number of extra registers needed */ |
| 111290 | 110862 | int op; /* Instruction opcode */ |
| 111291 | 110863 | char *zStartAff; /* Affinity for start of range constraint */ |
| 111292 | | - char *zEndAff; /* Affinity for end of range constraint */ |
| 110864 | + char cEndAff = 0; /* Affinity for end of range constraint */ |
| 111293 | 110865 | |
| 111294 | 110866 | pIdx = pLoop->u.btree.pIndex; |
| 111295 | 110867 | iIdxCur = pLevel->iIdxCur; |
| 110868 | + assert( nEq>=pLoop->u.btree.nSkip ); |
| 111296 | 110869 | |
| 111297 | 110870 | /* If this loop satisfies a sort order (pOrderBy) request that |
| 111298 | 110871 | ** was passed to this function to implement a "SELECT min(x) ..." |
| 111299 | 110872 | ** query, then the caller will only allow the loop to run for |
| 111300 | 110873 | ** a single iteration. This means that the first row returned |
| | @@ -111304,12 +110877,11 @@ |
| 111304 | 110877 | */ |
| 111305 | 110878 | if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 |
| 111306 | 110879 | && (pWInfo->bOBSat!=0) |
| 111307 | 110880 | && (pIdx->nKeyCol>nEq) |
| 111308 | 110881 | ){ |
| 111309 | | - /* assert( pOrderBy->nExpr==1 ); */ |
| 111310 | | - /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */ |
| 110882 | + assert( pLoop->u.btree.nSkip==0 ); |
| 111311 | 110883 | isMinQuery = 1; |
| 111312 | 110884 | nExtraReg = 1; |
| 111313 | 110885 | } |
| 111314 | 110886 | |
| 111315 | 110887 | /* Find any inequality constraint terms for the start and end |
| | @@ -111328,11 +110900,12 @@ |
| 111328 | 110900 | /* Generate code to evaluate all constraint terms using == or IN |
| 111329 | 110901 | ** and store the values of those terms in an array of registers |
| 111330 | 110902 | ** starting at regBase. |
| 111331 | 110903 | */ |
| 111332 | 110904 | regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); |
| 111333 | | - zEndAff = sqlite3DbStrDup(db, zStartAff); |
| 110905 | + assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); |
| 110906 | + if( zStartAff ) cEndAff = zStartAff[nEq]; |
| 111334 | 110907 | addrNxt = pLevel->addrNxt; |
| 111335 | 110908 | |
| 111336 | 110909 | /* If we are doing a reverse order scan on an ascending index, or |
| 111337 | 110910 | ** a forward order scan on a descending index, interchange the |
| 111338 | 110911 | ** start and end terms (pRangeStart and pRangeEnd). |
| | @@ -111398,27 +110971,19 @@ |
| 111398 | 110971 | sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); |
| 111399 | 110972 | sqlite3ExprCode(pParse, pRight, regBase+nEq); |
| 111400 | 110973 | if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){ |
| 111401 | 110974 | sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); |
| 111402 | 110975 | } |
| 111403 | | - if( zEndAff ){ |
| 111404 | | - if( sqlite3CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){ |
| 111405 | | - /* Since the comparison is to be performed with no conversions |
| 111406 | | - ** applied to the operands, set the affinity to apply to pRight to |
| 111407 | | - ** SQLITE_AFF_NONE. */ |
| 111408 | | - zEndAff[nEq] = SQLITE_AFF_NONE; |
| 111409 | | - } |
| 111410 | | - if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){ |
| 111411 | | - zEndAff[nEq] = SQLITE_AFF_NONE; |
| 111412 | | - } |
| 111413 | | - } |
| 111414 | | - codeApplyAffinity(pParse, regBase, nEq+1, zEndAff); |
| 110976 | + if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_NONE |
| 110977 | + && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff) |
| 110978 | + ){ |
| 110979 | + codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff); |
| 110980 | + } |
| 111415 | 110981 | nConstraint++; |
| 111416 | 110982 | testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); |
| 111417 | 110983 | } |
| 111418 | 110984 | sqlite3DbFree(db, zStartAff); |
| 111419 | | - sqlite3DbFree(db, zEndAff); |
| 111420 | 110985 | |
| 111421 | 110986 | /* Top of the loop body */ |
| 111422 | 110987 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); |
| 111423 | 110988 | |
| 111424 | 110989 | /* Check if the index cursor is past the end of the range. */ |
| | @@ -111436,12 +111001,17 @@ |
| 111436 | 111001 | ** If it is, jump to the next iteration of the loop. |
| 111437 | 111002 | */ |
| 111438 | 111003 | r1 = sqlite3GetTempReg(pParse); |
| 111439 | 111004 | testcase( pLoop->wsFlags & WHERE_BTM_LIMIT ); |
| 111440 | 111005 | testcase( pLoop->wsFlags & WHERE_TOP_LIMIT ); |
| 111441 | | - if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){ |
| 111006 | + if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 |
| 111007 | + && (j = pIdx->aiColumn[nEq])>=0 |
| 111008 | + && pIdx->pTable->aCol[j].notNull==0 |
| 111009 | + && (nEq || (pLoop->wsFlags & WHERE_BTM_LIMIT)==0) |
| 111010 | + ){ |
| 111442 | 111011 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1); |
| 111012 | + VdbeComment((v, "%s", pIdx->pTable->aCol[j].zName)); |
| 111443 | 111013 | sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont); |
| 111444 | 111014 | } |
| 111445 | 111015 | sqlite3ReleaseTempReg(pParse, r1); |
| 111446 | 111016 | |
| 111447 | 111017 | /* Seek the table cursor, if required */ |
| | @@ -111752,11 +111322,11 @@ |
| 111752 | 111322 | pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0); |
| 111753 | 111323 | if( pAlt==0 ) continue; |
| 111754 | 111324 | if( pAlt->wtFlags & (TERM_CODED) ) continue; |
| 111755 | 111325 | testcase( pAlt->eOperator & WO_EQ ); |
| 111756 | 111326 | testcase( pAlt->eOperator & WO_IN ); |
| 111757 | | - VdbeNoopComment((v, "begin transitive constraint")); |
| 111327 | + VdbeModuleComment((v, "begin transitive constraint")); |
| 111758 | 111328 | pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt)); |
| 111759 | 111329 | if( pEAlt ){ |
| 111760 | 111330 | *pEAlt = *pAlt->pExpr; |
| 111761 | 111331 | pEAlt->pLeft = pE->pLeft; |
| 111762 | 111332 | sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL); |
| | @@ -111852,10 +111422,11 @@ |
| 111852 | 111422 | int i; |
| 111853 | 111423 | Vdbe *v = pWInfo->pParse->pVdbe; |
| 111854 | 111424 | sqlite3ExplainBegin(v); |
| 111855 | 111425 | for(i=0; i<p->nLTerm; i++){ |
| 111856 | 111426 | WhereTerm *pTerm = p->aLTerm[i]; |
| 111427 | + if( pTerm==0 ) continue; |
| 111857 | 111428 | sqlite3ExplainPrintf(v, " (%d) #%-2d ", i+1, (int)(pTerm-pWC->a)); |
| 111858 | 111429 | sqlite3ExplainPush(v); |
| 111859 | 111430 | whereExplainTerm(v, pTerm); |
| 111860 | 111431 | sqlite3ExplainPop(v); |
| 111861 | 111432 | sqlite3ExplainNL(v); |
| | @@ -112135,10 +111706,11 @@ |
| 112135 | 111706 | if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; |
| 112136 | 111707 | if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; |
| 112137 | 111708 | if( (pTerm->prereqAll & notAllowed)!=0 ) continue; |
| 112138 | 111709 | for(j=pLoop->nLTerm-1; j>=0; j--){ |
| 112139 | 111710 | pX = pLoop->aLTerm[j]; |
| 111711 | + if( pX==0 ) continue; |
| 112140 | 111712 | if( pX==pTerm ) break; |
| 112141 | 111713 | if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; |
| 112142 | 111714 | } |
| 112143 | 111715 | if( j<0 ) pLoop->nOut += pTerm->truthProb; |
| 112144 | 111716 | } |
| | @@ -112164,11 +111736,12 @@ |
| 112164 | 111736 | WhereTerm *pTerm; /* A WhereTerm under consideration */ |
| 112165 | 111737 | int opMask; /* Valid operators for constraints */ |
| 112166 | 111738 | WhereScan scan; /* Iterator for WHERE terms */ |
| 112167 | 111739 | Bitmask saved_prereq; /* Original value of pNew->prereq */ |
| 112168 | 111740 | u16 saved_nLTerm; /* Original value of pNew->nLTerm */ |
| 112169 | | - int saved_nEq; /* Original value of pNew->u.btree.nEq */ |
| 111741 | + u16 saved_nEq; /* Original value of pNew->u.btree.nEq */ |
| 111742 | + u16 saved_nSkip; /* Original value of pNew->u.btree.nSkip */ |
| 112170 | 111743 | u32 saved_wsFlags; /* Original value of pNew->wsFlags */ |
| 112171 | 111744 | LogEst saved_nOut; /* Original value of pNew->nOut */ |
| 112172 | 111745 | int iCol; /* Index of the column in the table */ |
| 112173 | 111746 | int rc = SQLITE_OK; /* Return code */ |
| 112174 | 111747 | LogEst nRowEst; /* Estimated index selectivity */ |
| | @@ -112199,16 +111772,37 @@ |
| 112199 | 111772 | nRowEst = 0; |
| 112200 | 111773 | } |
| 112201 | 111774 | pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol, |
| 112202 | 111775 | opMask, pProbe); |
| 112203 | 111776 | saved_nEq = pNew->u.btree.nEq; |
| 111777 | + saved_nSkip = pNew->u.btree.nSkip; |
| 112204 | 111778 | saved_nLTerm = pNew->nLTerm; |
| 112205 | 111779 | saved_wsFlags = pNew->wsFlags; |
| 112206 | 111780 | saved_prereq = pNew->prereq; |
| 112207 | 111781 | saved_nOut = pNew->nOut; |
| 112208 | 111782 | pNew->rSetup = 0; |
| 112209 | 111783 | rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0])); |
| 111784 | + |
| 111785 | + /* Consider using a skip-scan if there are no WHERE clause constraints |
| 111786 | + ** available for the left-most terms of the index, and if the average |
| 111787 | + ** number of repeats in the left-most terms is at least 18. The magic |
| 111788 | + ** number 18 was found by experimentation to be the payoff point where |
| 111789 | + ** skip-scan become faster than a full-scan. |
| 111790 | + */ |
| 111791 | + if( pTerm==0 |
| 111792 | + && saved_nEq==saved_nSkip |
| 111793 | + && saved_nEq+1<pProbe->nKeyCol |
| 111794 | + && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */ |
| 111795 | + ){ |
| 111796 | + LogEst nIter; |
| 111797 | + pNew->u.btree.nEq++; |
| 111798 | + pNew->u.btree.nSkip++; |
| 111799 | + pNew->aLTerm[pNew->nLTerm++] = 0; |
| 111800 | + pNew->wsFlags |= WHERE_SKIPSCAN; |
| 111801 | + nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]); |
| 111802 | + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter); |
| 111803 | + } |
| 112210 | 111804 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 112211 | 111805 | int nIn = 0; |
| 112212 | 111806 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 112213 | 111807 | int nRecValid = pBuilder->nRecValid; |
| 112214 | 111808 | #endif |
| | @@ -112240,12 +111834,14 @@ |
| 112240 | 111834 | } |
| 112241 | 111835 | pNew->rRun += nIn; |
| 112242 | 111836 | pNew->u.btree.nEq++; |
| 112243 | 111837 | pNew->nOut = nRowEst + nInMul + nIn; |
| 112244 | 111838 | }else if( pTerm->eOperator & (WO_EQ) ){ |
| 112245 | | - assert( (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 |
| 112246 | | - || nInMul==0 ); |
| 111839 | + assert( |
| 111840 | + (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN|WHERE_SKIPSCAN))!=0 |
| 111841 | + || nInMul==0 |
| 111842 | + ); |
| 112247 | 111843 | pNew->wsFlags |= WHERE_COLUMN_EQ; |
| 112248 | 111844 | if( iCol<0 |
| 112249 | 111845 | || (pProbe->onError!=OE_None && nInMul==0 |
| 112250 | 111846 | && pNew->u.btree.nEq==pProbe->nKeyCol-1) |
| 112251 | 111847 | ){ |
| | @@ -112322,10 +111918,11 @@ |
| 112322 | 111918 | pBuilder->nRecValid = nRecValid; |
| 112323 | 111919 | #endif |
| 112324 | 111920 | } |
| 112325 | 111921 | pNew->prereq = saved_prereq; |
| 112326 | 111922 | pNew->u.btree.nEq = saved_nEq; |
| 111923 | + pNew->u.btree.nSkip = saved_nSkip; |
| 112327 | 111924 | pNew->wsFlags = saved_wsFlags; |
| 112328 | 111925 | pNew->nOut = saved_nOut; |
| 112329 | 111926 | pNew->nLTerm = saved_nLTerm; |
| 112330 | 111927 | return rc; |
| 112331 | 111928 | } |
| | @@ -112468,10 +112065,11 @@ |
| 112468 | 112065 | WhereTerm *pWCEnd = pWC->a + pWC->nTerm; |
| 112469 | 112066 | for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){ |
| 112470 | 112067 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 112471 | 112068 | if( termCanDriveIndex(pTerm, pSrc, 0) ){ |
| 112472 | 112069 | pNew->u.btree.nEq = 1; |
| 112070 | + pNew->u.btree.nSkip = 0; |
| 112473 | 112071 | pNew->u.btree.pIndex = 0; |
| 112474 | 112072 | pNew->nLTerm = 1; |
| 112475 | 112073 | pNew->aLTerm[0] = pTerm; |
| 112476 | 112074 | /* TUNING: One-time cost for computing the automatic index is |
| 112477 | 112075 | ** approximately 7*N*log2(N) where N is the number of rows in |
| | @@ -112497,10 +112095,11 @@ |
| 112497 | 112095 | if( pProbe->pPartIdxWhere!=0 |
| 112498 | 112096 | && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){ |
| 112499 | 112097 | continue; /* Partial index inappropriate for this query */ |
| 112500 | 112098 | } |
| 112501 | 112099 | pNew->u.btree.nEq = 0; |
| 112100 | + pNew->u.btree.nSkip = 0; |
| 112502 | 112101 | pNew->nLTerm = 0; |
| 112503 | 112102 | pNew->iSortIdx = 0; |
| 112504 | 112103 | pNew->rSetup = 0; |
| 112505 | 112104 | pNew->prereq = mExtra; |
| 112506 | 112105 | pNew->nOut = rSize; |
| | @@ -112582,11 +112181,12 @@ |
| 112582 | 112181 | /* |
| 112583 | 112182 | ** Add all WhereLoop objects for a table of the join identified by |
| 112584 | 112183 | ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table. |
| 112585 | 112184 | */ |
| 112586 | 112185 | static int whereLoopAddVirtual( |
| 112587 | | - WhereLoopBuilder *pBuilder /* WHERE clause information */ |
| 112186 | + WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 112187 | + Bitmask mExtra |
| 112588 | 112188 | ){ |
| 112589 | 112189 | WhereInfo *pWInfo; /* WHERE analysis context */ |
| 112590 | 112190 | Parse *pParse; /* The parsing context */ |
| 112591 | 112191 | WhereClause *pWC; /* The WHERE clause */ |
| 112592 | 112192 | struct SrcList_item *pSrc; /* The FROM clause term to search */ |
| | @@ -112668,14 +112268,15 @@ |
| 112668 | 112268 | pIdxInfo->idxStr = 0; |
| 112669 | 112269 | pIdxInfo->idxNum = 0; |
| 112670 | 112270 | pIdxInfo->needToFreeIdxStr = 0; |
| 112671 | 112271 | pIdxInfo->orderByConsumed = 0; |
| 112672 | 112272 | pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; |
| 112273 | + pIdxInfo->estimatedRows = 25; |
| 112673 | 112274 | rc = vtabBestIndex(pParse, pTab, pIdxInfo); |
| 112674 | 112275 | if( rc ) goto whereLoopAddVtab_exit; |
| 112675 | 112276 | pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; |
| 112676 | | - pNew->prereq = 0; |
| 112277 | + pNew->prereq = mExtra; |
| 112677 | 112278 | mxTerm = -1; |
| 112678 | 112279 | assert( pNew->nLSlot>=nConstraint ); |
| 112679 | 112280 | for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0; |
| 112680 | 112281 | pNew->u.vtab.omitMask = 0; |
| 112681 | 112282 | for(i=0; i<nConstraint; i++, pIdxCons++){ |
| | @@ -112727,12 +112328,11 @@ |
| 112727 | 112328 | pNew->u.vtab.idxStr = pIdxInfo->idxStr; |
| 112728 | 112329 | pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0) |
| 112729 | 112330 | && pIdxInfo->orderByConsumed); |
| 112730 | 112331 | pNew->rSetup = 0; |
| 112731 | 112332 | pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); |
| 112732 | | - /* TUNING: Every virtual table query returns 25 rows */ |
| 112733 | | - pNew->nOut = 46; assert( 46==sqlite3LogEst(25) ); |
| 112333 | + pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); |
| 112734 | 112334 | whereLoopInsert(pBuilder, pNew); |
| 112735 | 112335 | if( pNew->u.vtab.needFree ){ |
| 112736 | 112336 | sqlite3_free(pNew->u.vtab.idxStr); |
| 112737 | 112337 | pNew->u.vtab.needFree = 0; |
| 112738 | 112338 | } |
| | @@ -112799,12 +112399,11 @@ |
| 112799 | 112399 | continue; |
| 112800 | 112400 | } |
| 112801 | 112401 | sCur.n = 0; |
| 112802 | 112402 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 112803 | 112403 | if( IsVirtual(pItem->pTab) ){ |
| 112804 | | - rc = whereLoopAddVirtual(&sSubBuild); |
| 112805 | | - for(i=0; i<sCur.n; i++) sCur.a[i].prereq |= mExtra; |
| 112404 | + rc = whereLoopAddVirtual(&sSubBuild, mExtra); |
| 112806 | 112405 | }else |
| 112807 | 112406 | #endif |
| 112808 | 112407 | { |
| 112809 | 112408 | rc = whereLoopAddBtree(&sSubBuild, mExtra); |
| 112810 | 112409 | } |
| | @@ -112870,11 +112469,11 @@ |
| 112870 | 112469 | if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){ |
| 112871 | 112470 | mExtra = mPrior; |
| 112872 | 112471 | } |
| 112873 | 112472 | priorJoinType = pItem->jointype; |
| 112874 | 112473 | if( IsVirtual(pItem->pTab) ){ |
| 112875 | | - rc = whereLoopAddVirtual(pBuilder); |
| 112474 | + rc = whereLoopAddVirtual(pBuilder, mExtra); |
| 112876 | 112475 | }else{ |
| 112877 | 112476 | rc = whereLoopAddBtree(pBuilder, mExtra); |
| 112878 | 112477 | } |
| 112879 | 112478 | if( rc==SQLITE_OK ){ |
| 112880 | 112479 | rc = whereLoopAddOr(pBuilder, mExtra); |
| | @@ -113031,10 +112630,11 @@ |
| 113031 | 112630 | for(j=0; j<nColumn; j++){ |
| 113032 | 112631 | u8 bOnce; /* True to run the ORDER BY search loop */ |
| 113033 | 112632 | |
| 113034 | 112633 | /* Skip over == and IS NULL terms */ |
| 113035 | 112634 | if( j<pLoop->u.btree.nEq |
| 112635 | + && pLoop->u.btree.nSkip==0 |
| 113036 | 112636 | && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0 |
| 113037 | 112637 | ){ |
| 113038 | 112638 | if( i & WO_ISNULL ){ |
| 113039 | 112639 | testcase( isOrderDistinct ); |
| 113040 | 112640 | isOrderDistinct = 0; |
| | @@ -113456,10 +113056,11 @@ |
| 113456 | 113056 | if( pItem->zIndex ) return 0; |
| 113457 | 113057 | iCur = pItem->iCursor; |
| 113458 | 113058 | pWC = &pWInfo->sWC; |
| 113459 | 113059 | pLoop = pBuilder->pNew; |
| 113460 | 113060 | pLoop->wsFlags = 0; |
| 113061 | + pLoop->u.btree.nSkip = 0; |
| 113461 | 113062 | pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0); |
| 113462 | 113063 | if( pTerm ){ |
| 113463 | 113064 | pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; |
| 113464 | 113065 | pLoop->aLTerm[0] = pTerm; |
| 113465 | 113066 | pLoop->nLTerm = 1; |
| | @@ -113684,11 +113285,10 @@ |
| 113684 | 113285 | /* Split the WHERE clause into separate subexpressions where each |
| 113685 | 113286 | ** subexpression is separated by an AND operator. |
| 113686 | 113287 | */ |
| 113687 | 113288 | initMaskSet(pMaskSet); |
| 113688 | 113289 | whereClauseInit(&pWInfo->sWC, pWInfo); |
| 113689 | | - sqlite3ExprCodeConstants(pParse, pWhere); |
| 113690 | 113290 | whereSplit(&pWInfo->sWC, pWhere, TK_AND); |
| 113691 | 113291 | sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ |
| 113692 | 113292 | |
| 113693 | 113293 | /* Special case: a WHERE clause that is constant. Evaluate the |
| 113694 | 113294 | ** expression and either jump over all of the code or fall thru. |
| | @@ -113999,10 +113599,11 @@ |
| 113999 | 113599 | notReady = codeOneLoopStart(pWInfo, ii, notReady); |
| 114000 | 113600 | pWInfo->iContinue = pLevel->addrCont; |
| 114001 | 113601 | } |
| 114002 | 113602 | |
| 114003 | 113603 | /* Done. */ |
| 113604 | + VdbeModuleComment((v, "Begin WHERE-core")); |
| 114004 | 113605 | return pWInfo; |
| 114005 | 113606 | |
| 114006 | 113607 | /* Jump here if malloc fails */ |
| 114007 | 113608 | whereBeginError: |
| 114008 | 113609 | if( pWInfo ){ |
| | @@ -114025,12 +113626,14 @@ |
| 114025 | 113626 | SrcList *pTabList = pWInfo->pTabList; |
| 114026 | 113627 | sqlite3 *db = pParse->db; |
| 114027 | 113628 | |
| 114028 | 113629 | /* Generate loop termination code. |
| 114029 | 113630 | */ |
| 113631 | + VdbeModuleComment((v, "End WHERE-core")); |
| 114030 | 113632 | sqlite3ExprCacheClear(pParse); |
| 114031 | 113633 | for(i=pWInfo->nLevel-1; i>=0; i--){ |
| 113634 | + int addr; |
| 114032 | 113635 | pLevel = &pWInfo->a[i]; |
| 114033 | 113636 | pLoop = pLevel->pWLoop; |
| 114034 | 113637 | sqlite3VdbeResolveLabel(v, pLevel->addrCont); |
| 114035 | 113638 | if( pLevel->op!=OP_Noop ){ |
| 114036 | 113639 | sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2); |
| | @@ -114046,12 +113649,17 @@ |
| 114046 | 113649 | sqlite3VdbeJumpHere(v, pIn->addrInTop-1); |
| 114047 | 113650 | } |
| 114048 | 113651 | sqlite3DbFree(db, pLevel->u.in.aInLoop); |
| 114049 | 113652 | } |
| 114050 | 113653 | sqlite3VdbeResolveLabel(v, pLevel->addrBrk); |
| 113654 | + if( pLevel->addrSkip ){ |
| 113655 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip); |
| 113656 | + VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); |
| 113657 | + sqlite3VdbeJumpHere(v, pLevel->addrSkip); |
| 113658 | + sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); |
| 113659 | + } |
| 114051 | 113660 | if( pLevel->iLeftJoin ){ |
| 114052 | | - int addr; |
| 114053 | 113661 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); |
| 114054 | 113662 | assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 |
| 114055 | 113663 | || (pLoop->wsFlags & WHERE_INDEXED)!=0 ); |
| 114056 | 113664 | if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){ |
| 114057 | 113665 | sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor); |
| | @@ -114064,11 +113672,11 @@ |
| 114064 | 113672 | }else{ |
| 114065 | 113673 | sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst); |
| 114066 | 113674 | } |
| 114067 | 113675 | sqlite3VdbeJumpHere(v, addr); |
| 114068 | 113676 | } |
| 114069 | | - VdbeNoopComment((v, "End WHERE-Loop %d: %s", i, |
| 113677 | + VdbeModuleComment((v, "End WHERE-loop%d: %s", i, |
| 114070 | 113678 | pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); |
| 114071 | 113679 | } |
| 114072 | 113680 | |
| 114073 | 113681 | /* The "break" point is here, just past the end of the outer loop. |
| 114074 | 113682 | ** Set it. |
| | @@ -116923,16 +116531,11 @@ |
| 116923 | 116531 | spanSet(&yygotominor.yy118,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); |
| 116924 | 116532 | } |
| 116925 | 116533 | break; |
| 116926 | 116534 | case 200: /* term ::= CTIME_KW */ |
| 116927 | 116535 | { |
| 116928 | | - /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are |
| 116929 | | - ** treated as functions that return constants */ |
| 116930 | | - yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); |
| 116931 | | - if( yygotominor.yy118.pExpr ){ |
| 116932 | | - yygotominor.yy118.pExpr->op = TK_CONST_FUNC; |
| 116933 | | - } |
| 116536 | + yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0); |
| 116934 | 116537 | spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); |
| 116935 | 116538 | } |
| 116936 | 116539 | break; |
| 116937 | 116540 | case 201: /* expr ::= expr AND expr */ |
| 116938 | 116541 | case 202: /* expr ::= expr OR expr */ yytestcase(yyruleno==202); |
| | @@ -119357,10 +118960,17 @@ |
| 119357 | 118960 | if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; |
| 119358 | 118961 | if( szMmap>mxMmap) szMmap = mxMmap; |
| 119359 | 118962 | sqlite3GlobalConfig.szMmap = szMmap; |
| 119360 | 118963 | break; |
| 119361 | 118964 | } |
| 118965 | + |
| 118966 | +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) |
| 118967 | + case SQLITE_CONFIG_WIN32_HEAPSIZE: { |
| 118968 | + sqlite3GlobalConfig.nHeap = va_arg(ap, int); |
| 118969 | + break; |
| 118970 | + } |
| 118971 | +#endif |
| 119362 | 118972 | |
| 119363 | 118973 | default: { |
| 119364 | 118974 | rc = SQLITE_ERROR; |
| 119365 | 118975 | break; |
| 119366 | 118976 | } |
| | @@ -119424,11 +119034,12 @@ |
| 119424 | 119034 | } |
| 119425 | 119035 | db->lookaside.pEnd = p; |
| 119426 | 119036 | db->lookaside.bEnabled = 1; |
| 119427 | 119037 | db->lookaside.bMalloced = pBuf==0 ?1:0; |
| 119428 | 119038 | }else{ |
| 119429 | | - db->lookaside.pEnd = 0; |
| 119039 | + db->lookaside.pStart = db; |
| 119040 | + db->lookaside.pEnd = db; |
| 119430 | 119041 | db->lookaside.bEnabled = 0; |
| 119431 | 119042 | db->lookaside.bMalloced = 0; |
| 119432 | 119043 | } |
| 119433 | 119044 | return SQLITE_OK; |
| 119434 | 119045 | } |
| | @@ -119922,10 +119533,11 @@ |
| 119922 | 119533 | case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; |
| 119923 | 119534 | case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; |
| 119924 | 119535 | case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; |
| 119925 | 119536 | case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; |
| 119926 | 119537 | case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; |
| 119538 | + case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; |
| 119927 | 119539 | case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; |
| 119928 | 119540 | case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; |
| 119929 | 119541 | case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; |
| 119930 | 119542 | case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break; |
| 119931 | 119543 | case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break; |
| | @@ -122132,10 +121744,23 @@ |
| 122132 | 121744 | *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt); |
| 122133 | 121745 | break; |
| 122134 | 121746 | } |
| 122135 | 121747 | #endif |
| 122136 | 121748 | |
| 121749 | + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); |
| 121750 | + ** |
| 121751 | + ** Set or clear a flag that indicates that the database file is always well- |
| 121752 | + ** formed and never corrupt. This flag is clear by default, indicating that |
| 121753 | + ** database files might have arbitrary corruption. Setting the flag during |
| 121754 | + ** testing causes certain assert() statements in the code to be activated |
| 121755 | + ** that demonstrat invariants on well-formed database files. |
| 121756 | + */ |
| 121757 | + case SQLITE_TESTCTRL_NEVER_CORRUPT: { |
| 121758 | + sqlite3Config.neverCorrupt = va_arg(ap, int); |
| 121759 | + break; |
| 121760 | + } |
| 121761 | + |
| 122137 | 121762 | } |
| 122138 | 121763 | va_end(ap); |
| 122139 | 121764 | #endif /* SQLITE_OMIT_BUILTIN_TEST */ |
| 122140 | 121765 | return rc; |
| 122141 | 121766 | } |
| | @@ -123649,10 +123274,14 @@ |
| 123649 | 123274 | char *aDoclist; /* Pointer to doclist buffer */ |
| 123650 | 123275 | int nDoclist; /* Size of aDoclist[] in bytes */ |
| 123651 | 123276 | }; |
| 123652 | 123277 | |
| 123653 | 123278 | SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); |
| 123279 | + |
| 123280 | +#define fts3GetVarint32(p, piVal) ( \ |
| 123281 | + (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ |
| 123282 | +) |
| 123654 | 123283 | |
| 123655 | 123284 | /* fts3.c */ |
| 123656 | 123285 | SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); |
| 123657 | 123286 | SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); |
| 123658 | 123287 | SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); |
| | @@ -123757,36 +123386,63 @@ |
| 123757 | 123386 | q[-1] &= 0x7f; /* turn off high bit in final byte */ |
| 123758 | 123387 | assert( q - (unsigned char *)p <= FTS3_VARINT_MAX ); |
| 123759 | 123388 | return (int) (q - (unsigned char *)p); |
| 123760 | 123389 | } |
| 123761 | 123390 | |
| 123391 | +#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \ |
| 123392 | + v = (v & mask1) | ( (*ptr++) << shift ); \ |
| 123393 | + if( (v & mask2)==0 ){ var = v; return ret; } |
| 123394 | +#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \ |
| 123395 | + v = (*ptr++); \ |
| 123396 | + if( (v & mask2)==0 ){ var = v; return ret; } |
| 123397 | + |
| 123762 | 123398 | /* |
| 123763 | 123399 | ** Read a 64-bit variable-length integer from memory starting at p[0]. |
| 123764 | 123400 | ** Return the number of bytes read, or 0 on error. |
| 123765 | 123401 | ** The value is stored in *v. |
| 123766 | 123402 | */ |
| 123767 | 123403 | SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){ |
| 123768 | | - const unsigned char *q = (const unsigned char *) p; |
| 123769 | | - sqlite_uint64 x = 0, y = 1; |
| 123770 | | - while( (*q&0x80)==0x80 && q-(unsigned char *)p<FTS3_VARINT_MAX ){ |
| 123771 | | - x += y * (*q++ & 0x7f); |
| 123772 | | - y <<= 7; |
| 123773 | | - } |
| 123774 | | - x += y * (*q++); |
| 123775 | | - *v = (sqlite_int64) x; |
| 123776 | | - return (int) (q - (unsigned char *)p); |
| 123404 | + const char *pStart = p; |
| 123405 | + u32 a; |
| 123406 | + u64 b; |
| 123407 | + int shift; |
| 123408 | + |
| 123409 | + GETVARINT_INIT(a, p, 0, 0x00, 0x80, *v, 1); |
| 123410 | + GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2); |
| 123411 | + GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3); |
| 123412 | + GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4); |
| 123413 | + b = (a & 0x0FFFFFFF ); |
| 123414 | + |
| 123415 | + for(shift=28; shift<=63; shift+=7){ |
| 123416 | + u64 c = *p++; |
| 123417 | + b += (c&0x7F) << shift; |
| 123418 | + if( (c & 0x80)==0 ) break; |
| 123419 | + } |
| 123420 | + *v = b; |
| 123421 | + return (int)(p - pStart); |
| 123777 | 123422 | } |
| 123778 | 123423 | |
| 123779 | 123424 | /* |
| 123780 | 123425 | ** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a |
| 123781 | 123426 | ** 32-bit integer before it is returned. |
| 123782 | 123427 | */ |
| 123783 | 123428 | SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){ |
| 123784 | | - sqlite_int64 i; |
| 123785 | | - int ret = sqlite3Fts3GetVarint(p, &i); |
| 123786 | | - *pi = (int) i; |
| 123787 | | - return ret; |
| 123429 | + u32 a; |
| 123430 | + |
| 123431 | +#ifndef fts3GetVarint32 |
| 123432 | + GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1); |
| 123433 | +#else |
| 123434 | + a = (*p++); |
| 123435 | + assert( a & 0x80 ); |
| 123436 | +#endif |
| 123437 | + |
| 123438 | + GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2); |
| 123439 | + GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3); |
| 123440 | + GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4); |
| 123441 | + a = (a & 0x0FFFFFFF ); |
| 123442 | + *pi = (int)(a | ((u32)(*p & 0x0F) << 28)); |
| 123443 | + return 5; |
| 123788 | 123444 | } |
| 123789 | 123445 | |
| 123790 | 123446 | /* |
| 123791 | 123447 | ** Return the number of bytes required to encode v as a varint |
| 123792 | 123448 | */ |
| | @@ -125142,14 +124798,14 @@ |
| 125142 | 124798 | int nBuffer; /* Total term size */ |
| 125143 | 124799 | |
| 125144 | 124800 | /* Load the next term on the node into zBuffer. Use realloc() to expand |
| 125145 | 124801 | ** the size of zBuffer if required. */ |
| 125146 | 124802 | if( !isFirstTerm ){ |
| 125147 | | - zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix); |
| 124803 | + zCsr += fts3GetVarint32(zCsr, &nPrefix); |
| 125148 | 124804 | } |
| 125149 | 124805 | isFirstTerm = 0; |
| 125150 | | - zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix); |
| 124806 | + zCsr += fts3GetVarint32(zCsr, &nSuffix); |
| 125151 | 124807 | |
| 125152 | 124808 | if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){ |
| 125153 | 124809 | rc = FTS_CORRUPT_VTAB; |
| 125154 | 124810 | goto finish_scan; |
| 125155 | 124811 | } |
| | @@ -125233,11 +124889,11 @@ |
| 125233 | 124889 | int rc; /* Return code */ |
| 125234 | 124890 | int iHeight; /* Height of this node in tree */ |
| 125235 | 124891 | |
| 125236 | 124892 | assert( piLeaf || piLeaf2 ); |
| 125237 | 124893 | |
| 125238 | | - sqlite3Fts3GetVarint32(zNode, &iHeight); |
| 124894 | + fts3GetVarint32(zNode, &iHeight); |
| 125239 | 124895 | rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); |
| 125240 | 124896 | assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); |
| 125241 | 124897 | |
| 125242 | 124898 | if( rc==SQLITE_OK && iHeight>1 ){ |
| 125243 | 124899 | char *zBlob = 0; /* Blob read from %_segments table */ |
| | @@ -125435,15 +125091,15 @@ |
| 125435 | 125091 | |
| 125436 | 125092 | while( *p1 || *p2 ){ |
| 125437 | 125093 | int iCol1; /* The current column index in pp1 */ |
| 125438 | 125094 | int iCol2; /* The current column index in pp2 */ |
| 125439 | 125095 | |
| 125440 | | - if( *p1==POS_COLUMN ) sqlite3Fts3GetVarint32(&p1[1], &iCol1); |
| 125096 | + if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1); |
| 125441 | 125097 | else if( *p1==POS_END ) iCol1 = POSITION_LIST_END; |
| 125442 | 125098 | else iCol1 = 0; |
| 125443 | 125099 | |
| 125444 | | - if( *p2==POS_COLUMN ) sqlite3Fts3GetVarint32(&p2[1], &iCol2); |
| 125100 | + if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2); |
| 125445 | 125101 | else if( *p2==POS_END ) iCol2 = POSITION_LIST_END; |
| 125446 | 125102 | else iCol2 = 0; |
| 125447 | 125103 | |
| 125448 | 125104 | if( iCol1==iCol2 ){ |
| 125449 | 125105 | sqlite3_int64 i1 = 0; /* Last position from pp1 */ |
| | @@ -125532,15 +125188,15 @@ |
| 125532 | 125188 | assert( isSaveLeft==0 || isExact==0 ); |
| 125533 | 125189 | |
| 125534 | 125190 | assert( p!=0 && *p1!=0 && *p2!=0 ); |
| 125535 | 125191 | if( *p1==POS_COLUMN ){ |
| 125536 | 125192 | p1++; |
| 125537 | | - p1 += sqlite3Fts3GetVarint32(p1, &iCol1); |
| 125193 | + p1 += fts3GetVarint32(p1, &iCol1); |
| 125538 | 125194 | } |
| 125539 | 125195 | if( *p2==POS_COLUMN ){ |
| 125540 | 125196 | p2++; |
| 125541 | | - p2 += sqlite3Fts3GetVarint32(p2, &iCol2); |
| 125197 | + p2 += fts3GetVarint32(p2, &iCol2); |
| 125542 | 125198 | } |
| 125543 | 125199 | |
| 125544 | 125200 | while( 1 ){ |
| 125545 | 125201 | if( iCol1==iCol2 ){ |
| 125546 | 125202 | char *pSave = p; |
| | @@ -125586,13 +125242,13 @@ |
| 125586 | 125242 | fts3ColumnlistCopy(0, &p2); |
| 125587 | 125243 | assert( (*p1&0xFE)==0 && (*p2&0xFE)==0 ); |
| 125588 | 125244 | if( 0==*p1 || 0==*p2 ) break; |
| 125589 | 125245 | |
| 125590 | 125246 | p1++; |
| 125591 | | - p1 += sqlite3Fts3GetVarint32(p1, &iCol1); |
| 125247 | + p1 += fts3GetVarint32(p1, &iCol1); |
| 125592 | 125248 | p2++; |
| 125593 | | - p2 += sqlite3Fts3GetVarint32(p2, &iCol2); |
| 125249 | + p2 += fts3GetVarint32(p2, &iCol2); |
| 125594 | 125250 | } |
| 125595 | 125251 | |
| 125596 | 125252 | /* Advance pointer p1 or p2 (whichever corresponds to the smaller of |
| 125597 | 125253 | ** iCol1 and iCol2) so that it points to either the 0x00 that marks the |
| 125598 | 125254 | ** end of the position list, or the 0x01 that precedes the next |
| | @@ -125600,16 +125256,16 @@ |
| 125600 | 125256 | */ |
| 125601 | 125257 | else if( iCol1<iCol2 ){ |
| 125602 | 125258 | fts3ColumnlistCopy(0, &p1); |
| 125603 | 125259 | if( 0==*p1 ) break; |
| 125604 | 125260 | p1++; |
| 125605 | | - p1 += sqlite3Fts3GetVarint32(p1, &iCol1); |
| 125261 | + p1 += fts3GetVarint32(p1, &iCol1); |
| 125606 | 125262 | }else{ |
| 125607 | 125263 | fts3ColumnlistCopy(0, &p2); |
| 125608 | 125264 | if( 0==*p2 ) break; |
| 125609 | 125265 | p2++; |
| 125610 | | - p2 += sqlite3Fts3GetVarint32(p2, &iCol2); |
| 125266 | + p2 += fts3GetVarint32(p2, &iCol2); |
| 125611 | 125267 | } |
| 125612 | 125268 | } |
| 125613 | 125269 | |
| 125614 | 125270 | fts3PoslistCopy(0, &p2); |
| 125615 | 125271 | fts3PoslistCopy(0, &p1); |
| | @@ -128772,11 +128428,11 @@ |
| 128772 | 128428 | */ |
| 128773 | 128429 | pExpr->aMI[iCol*3 + 1] += iCnt; |
| 128774 | 128430 | pExpr->aMI[iCol*3 + 2] += (iCnt>0); |
| 128775 | 128431 | if( *p==0x00 ) break; |
| 128776 | 128432 | p++; |
| 128777 | | - p += sqlite3Fts3GetVarint32(p, &iCol); |
| 128433 | + p += fts3GetVarint32(p, &iCol); |
| 128778 | 128434 | } |
| 128779 | 128435 | } |
| 128780 | 128436 | |
| 128781 | 128437 | fts3EvalUpdateCounts(pExpr->pLeft); |
| 128782 | 128438 | fts3EvalUpdateCounts(pExpr->pRight); |
| | @@ -129073,19 +128729,19 @@ |
| 129073 | 128729 | } |
| 129074 | 128730 | if( pIter==0 ) return SQLITE_OK; |
| 129075 | 128731 | |
| 129076 | 128732 | if( *pIter==0x01 ){ |
| 129077 | 128733 | pIter++; |
| 129078 | | - pIter += sqlite3Fts3GetVarint32(pIter, &iThis); |
| 128734 | + pIter += fts3GetVarint32(pIter, &iThis); |
| 129079 | 128735 | }else{ |
| 129080 | 128736 | iThis = 0; |
| 129081 | 128737 | } |
| 129082 | 128738 | while( iThis<iCol ){ |
| 129083 | 128739 | fts3ColumnlistCopy(0, &pIter); |
| 129084 | 128740 | if( *pIter==0x00 ) return 0; |
| 129085 | 128741 | pIter++; |
| 129086 | | - pIter += sqlite3Fts3GetVarint32(pIter, &iThis); |
| 128742 | + pIter += fts3GetVarint32(pIter, &iThis); |
| 129087 | 128743 | } |
| 129088 | 128744 | |
| 129089 | 128745 | *ppOut = ((iCol==iThis)?pIter:0); |
| 129090 | 128746 | return SQLITE_OK; |
| 129091 | 128747 | } |
| | @@ -134530,12 +134186,12 @@ |
| 134530 | 134186 | rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2); |
| 134531 | 134187 | if( rc!=SQLITE_OK ) return rc; |
| 134532 | 134188 | |
| 134533 | 134189 | /* Because of the FTS3_NODE_PADDING bytes of padding, the following is |
| 134534 | 134190 | ** safe (no risk of overread) even if the node data is corrupted. */ |
| 134535 | | - pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix); |
| 134536 | | - pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix); |
| 134191 | + pNext += fts3GetVarint32(pNext, &nPrefix); |
| 134192 | + pNext += fts3GetVarint32(pNext, &nSuffix); |
| 134537 | 134193 | if( nPrefix<0 || nSuffix<=0 |
| 134538 | 134194 | || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] |
| 134539 | 134195 | ){ |
| 134540 | 134196 | return FTS_CORRUPT_VTAB; |
| 134541 | 134197 | } |
| | @@ -134554,11 +134210,11 @@ |
| 134554 | 134210 | if( rc!=SQLITE_OK ) return rc; |
| 134555 | 134211 | |
| 134556 | 134212 | memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); |
| 134557 | 134213 | pReader->nTerm = nPrefix+nSuffix; |
| 134558 | 134214 | pNext += nSuffix; |
| 134559 | | - pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist); |
| 134215 | + pNext += fts3GetVarint32(pNext, &pReader->nDoclist); |
| 134560 | 134216 | pReader->aDoclist = pNext; |
| 134561 | 134217 | pReader->pOffsetList = 0; |
| 134562 | 134218 | |
| 134563 | 134219 | /* Check that the doclist does not appear to extend past the end of the |
| 134564 | 134220 | ** b-tree node. And that the final byte of the doclist is 0x00. If either |
| | @@ -135715,11 +135371,11 @@ |
| 135715 | 135371 | pList = p; |
| 135716 | 135372 | if( nList==0 ){ |
| 135717 | 135373 | break; |
| 135718 | 135374 | } |
| 135719 | 135375 | p = &pList[1]; |
| 135720 | | - p += sqlite3Fts3GetVarint32(p, &iCurrent); |
| 135376 | + p += fts3GetVarint32(p, &iCurrent); |
| 135721 | 135377 | } |
| 135722 | 135378 | |
| 135723 | 135379 | if( bZero && &pList[nList]!=pEnd ){ |
| 135724 | 135380 | memset(&pList[nList], 0, pEnd - &pList[nList]); |
| 135725 | 135381 | } |
| | @@ -136680,21 +136336,21 @@ |
| 136680 | 136336 | if( p->iOff>=p->nNode ){ |
| 136681 | 136337 | /* EOF */ |
| 136682 | 136338 | p->aNode = 0; |
| 136683 | 136339 | }else{ |
| 136684 | 136340 | if( bFirst==0 ){ |
| 136685 | | - p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); |
| 136341 | + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); |
| 136686 | 136342 | } |
| 136687 | | - p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); |
| 136343 | + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); |
| 136688 | 136344 | |
| 136689 | 136345 | blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); |
| 136690 | 136346 | if( rc==SQLITE_OK ){ |
| 136691 | 136347 | memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); |
| 136692 | 136348 | p->term.n = nPrefix+nSuffix; |
| 136693 | 136349 | p->iOff += nSuffix; |
| 136694 | 136350 | if( p->iChild==0 ){ |
| 136695 | | - p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); |
| 136351 | + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); |
| 136696 | 136352 | p->aDoclist = &p->aNode[p->iOff]; |
| 136697 | 136353 | p->iOff += p->nDoclist; |
| 136698 | 136354 | } |
| 136699 | 136355 | } |
| 136700 | 136356 | } |
| | @@ -137742,11 +137398,11 @@ |
| 137742 | 137398 | while( i>0 && (pHint->a[i-1] & 0x80) ) i--; |
| 137743 | 137399 | while( i>0 && (pHint->a[i-1] & 0x80) ) i--; |
| 137744 | 137400 | |
| 137745 | 137401 | pHint->n = i; |
| 137746 | 137402 | i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); |
| 137747 | | - i += sqlite3Fts3GetVarint32(&pHint->a[i], pnInput); |
| 137403 | + i += fts3GetVarint32(&pHint->a[i], pnInput); |
| 137748 | 137404 | if( i!=nHint ) return SQLITE_CORRUPT_VTAB; |
| 137749 | 137405 | |
| 137750 | 137406 | return SQLITE_OK; |
| 137751 | 137407 | } |
| 137752 | 137408 | |
| | @@ -138735,11 +138391,11 @@ |
| 138735 | 138391 | ** After it returns, *piPos contains the value of the next element of the |
| 138736 | 138392 | ** list and *pp is advanced to the following varint. |
| 138737 | 138393 | */ |
| 138738 | 138394 | static void fts3GetDeltaPosition(char **pp, int *piPos){ |
| 138739 | 138395 | int iVal; |
| 138740 | | - *pp += sqlite3Fts3GetVarint32(*pp, &iVal); |
| 138396 | + *pp += fts3GetVarint32(*pp, &iVal); |
| 138741 | 138397 | *piPos += (iVal-2); |
| 138742 | 138398 | } |
| 138743 | 138399 | |
| 138744 | 138400 | /* |
| 138745 | 138401 | ** Helper function for fts3ExprIterate() (see below). |
| | @@ -141028,10 +140684,20 @@ |
| 141028 | 140684 | ** ever contain very many entries, so a fixed number of buckets is |
| 141029 | 140685 | ** used. |
| 141030 | 140686 | */ |
| 141031 | 140687 | #define HASHSIZE 128 |
| 141032 | 140688 | |
| 140689 | +/* The xBestIndex method of this virtual table requires an estimate of |
| 140690 | +** the number of rows in the virtual table to calculate the costs of |
| 140691 | +** various strategies. If possible, this estimate is loaded from the |
| 140692 | +** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). |
| 140693 | +** Otherwise, if no sqlite_stat1 entry is available, use |
| 140694 | +** RTREE_DEFAULT_ROWEST. |
| 140695 | +*/ |
| 140696 | +#define RTREE_DEFAULT_ROWEST 1048576 |
| 140697 | +#define RTREE_MIN_ROWEST 100 |
| 140698 | + |
| 141033 | 140699 | /* |
| 141034 | 140700 | ** An rtree virtual-table object. |
| 141035 | 140701 | */ |
| 141036 | 140702 | struct Rtree { |
| 141037 | 140703 | sqlite3_vtab base; |
| | @@ -141042,10 +140708,11 @@ |
| 141042 | 140708 | int iDepth; /* Current depth of the r-tree structure */ |
| 141043 | 140709 | char *zDb; /* Name of database containing r-tree table */ |
| 141044 | 140710 | char *zName; /* Name of r-tree table */ |
| 141045 | 140711 | RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ |
| 141046 | 140712 | int nBusy; /* Current number of users of this structure */ |
| 140713 | + i64 nRowEst; /* Estimated number of rows in this table */ |
| 141047 | 140714 | |
| 141048 | 140715 | /* List of nodes removed during a CondenseTree operation. List is |
| 141049 | 140716 | ** linked together via the pointer normally used for hash chains - |
| 141050 | 140717 | ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree |
| 141051 | 140718 | ** headed by the node (leaf nodes have RtreeNode.iNode==0). |
| | @@ -142233,10 +141900,23 @@ |
| 142233 | 141900 | } |
| 142234 | 141901 | |
| 142235 | 141902 | rtreeRelease(pRtree); |
| 142236 | 141903 | return rc; |
| 142237 | 141904 | } |
| 141905 | + |
| 141906 | +/* |
| 141907 | +** Set the pIdxInfo->estimatedRows variable to nRow. Unless this |
| 141908 | +** extension is currently being used by a version of SQLite too old to |
| 141909 | +** support estimatedRows. In that case this function is a no-op. |
| 141910 | +*/ |
| 141911 | +static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ |
| 141912 | +#if SQLITE_VERSION_NUMBER>=3008002 |
| 141913 | + if( sqlite3_libversion_number()>=3008002 ){ |
| 141914 | + pIdxInfo->estimatedRows = nRow; |
| 141915 | + } |
| 141916 | +#endif |
| 141917 | +} |
| 142238 | 141918 | |
| 142239 | 141919 | /* |
| 142240 | 141920 | ** Rtree virtual table module xBestIndex method. There are three |
| 142241 | 141921 | ** table scan strategies to choose from (in order from most to |
| 142242 | 141922 | ** least desirable): |
| | @@ -142269,17 +141949,18 @@ |
| 142269 | 141949 | ** The second of each pair of bytes identifies the coordinate column |
| 142270 | 141950 | ** to which the constraint applies. The leftmost coordinate column |
| 142271 | 141951 | ** is 'a', the second from the left 'b' etc. |
| 142272 | 141952 | */ |
| 142273 | 141953 | static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |
| 141954 | + Rtree *pRtree = (Rtree*)tab; |
| 142274 | 141955 | int rc = SQLITE_OK; |
| 142275 | 141956 | int ii; |
| 141957 | + i64 nRow; /* Estimated rows returned by this scan */ |
| 142276 | 141958 | |
| 142277 | 141959 | int iIdx = 0; |
| 142278 | 141960 | char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; |
| 142279 | 141961 | memset(zIdxStr, 0, sizeof(zIdxStr)); |
| 142280 | | - UNUSED_PARAMETER(tab); |
| 142281 | 141962 | |
| 142282 | 141963 | assert( pIdxInfo->idxStr==0 ); |
| 142283 | 141964 | for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ |
| 142284 | 141965 | struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; |
| 142285 | 141966 | |
| | @@ -142295,13 +141976,15 @@ |
| 142295 | 141976 | pIdxInfo->aConstraintUsage[jj].omit = 1; |
| 142296 | 141977 | |
| 142297 | 141978 | /* This strategy involves a two rowid lookups on an B-Tree structures |
| 142298 | 141979 | ** and then a linear search of an R-Tree node. This should be |
| 142299 | 141980 | ** considered almost as quick as a direct rowid lookup (for which |
| 142300 | | - ** sqlite uses an internal cost of 0.0). |
| 141981 | + ** sqlite uses an internal cost of 0.0). It is expected to return |
| 141982 | + ** a single row. |
| 142301 | 141983 | */ |
| 142302 | | - pIdxInfo->estimatedCost = 10.0; |
| 141984 | + pIdxInfo->estimatedCost = 30.0; |
| 141985 | + setEstimatedRows(pIdxInfo, 1); |
| 142303 | 141986 | return SQLITE_OK; |
| 142304 | 141987 | } |
| 142305 | 141988 | |
| 142306 | 141989 | if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ |
| 142307 | 141990 | u8 op; |
| | @@ -142326,12 +142009,15 @@ |
| 142326 | 142009 | pIdxInfo->idxNum = 2; |
| 142327 | 142010 | pIdxInfo->needToFreeIdxStr = 1; |
| 142328 | 142011 | if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ |
| 142329 | 142012 | return SQLITE_NOMEM; |
| 142330 | 142013 | } |
| 142331 | | - assert( iIdx>=0 ); |
| 142332 | | - pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1)); |
| 142014 | + |
| 142015 | + nRow = pRtree->nRowEst / (iIdx + 1); |
| 142016 | + pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; |
| 142017 | + setEstimatedRows(pIdxInfo, nRow); |
| 142018 | + |
| 142333 | 142019 | return rc; |
| 142334 | 142020 | } |
| 142335 | 142021 | |
| 142336 | 142022 | /* |
| 142337 | 142023 | ** Return the N-dimensional volumn of the cell stored in *p. |
| | @@ -143801,10 +143487,41 @@ |
| 143801 | 143487 | rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); |
| 143802 | 143488 | sqlite3_free(zSql); |
| 143803 | 143489 | } |
| 143804 | 143490 | return rc; |
| 143805 | 143491 | } |
| 143492 | + |
| 143493 | +/* |
| 143494 | +** This function populates the pRtree->nRowEst variable with an estimate |
| 143495 | +** of the number of rows in the virtual table. If possible, this is based |
| 143496 | +** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. |
| 143497 | +*/ |
| 143498 | +static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ |
| 143499 | + const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'"; |
| 143500 | + sqlite3_stmt *p; |
| 143501 | + int rc; |
| 143502 | + i64 nRow = 0; |
| 143503 | + |
| 143504 | + rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); |
| 143505 | + if( rc==SQLITE_OK ){ |
| 143506 | + sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC); |
| 143507 | + if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); |
| 143508 | + rc = sqlite3_finalize(p); |
| 143509 | + }else if( rc!=SQLITE_NOMEM ){ |
| 143510 | + rc = SQLITE_OK; |
| 143511 | + } |
| 143512 | + |
| 143513 | + if( rc==SQLITE_OK ){ |
| 143514 | + if( nRow==0 ){ |
| 143515 | + pRtree->nRowEst = RTREE_DEFAULT_ROWEST; |
| 143516 | + }else{ |
| 143517 | + pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); |
| 143518 | + } |
| 143519 | + } |
| 143520 | + |
| 143521 | + return rc; |
| 143522 | +} |
| 143806 | 143523 | |
| 143807 | 143524 | static sqlite3_module rtreeModule = { |
| 143808 | 143525 | 0, /* iVersion */ |
| 143809 | 143526 | rtreeCreate, /* xCreate - create a table */ |
| 143810 | 143527 | rtreeConnect, /* xConnect - connect to an existing table */ |
| | @@ -143887,10 +143604,11 @@ |
| 143887 | 143604 | appStmt[5] = &pRtree->pDeleteRowid; |
| 143888 | 143605 | appStmt[6] = &pRtree->pReadParent; |
| 143889 | 143606 | appStmt[7] = &pRtree->pWriteParent; |
| 143890 | 143607 | appStmt[8] = &pRtree->pDeleteParent; |
| 143891 | 143608 | |
| 143609 | + rc = rtreeQueryStat1(db, pRtree); |
| 143892 | 143610 | for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){ |
| 143893 | 143611 | char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix); |
| 143894 | 143612 | if( zSql ){ |
| 143895 | 143613 | rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); |
| 143896 | 143614 | }else{ |
| 143897 | 143615 | |