diff options
| author | 2023-09-01 23:28:29 +0200 | |
|---|---|---|
| committer | 2023-09-01 23:28:29 +0200 | |
| commit | 5ae6e66876d7a7a0a206084e5672a4231945b7cc (patch) | |
| tree | 801c6d0f70e602765d93e250e2e635bd6f11f182 /c/sqlite3.c | |
| parent | update to Zig 0.11 (diff) | |
| parent | update sqlite to 3.43.0 (diff) | |
| download | zig-sqlite-5ae6e66876d7a7a0a206084e5672a4231945b7cc.tar.gz zig-sqlite-5ae6e66876d7a7a0a206084e5672a4231945b7cc.tar.xz zig-sqlite-5ae6e66876d7a7a0a206084e5672a4231945b7cc.zip | |
Merge branch 'update-sqlite'
Diffstat (limited to 'c/sqlite3.c')
| -rw-r--r-- | c/sqlite3.c | 21700 |
1 files changed, 15406 insertions, 6294 deletions
diff --git a/c/sqlite3.c b/c/sqlite3.c index 451ca8e..310583f 100644 --- a/c/sqlite3.c +++ b/c/sqlite3.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.39.3. By combining all the individual C code files into this | 3 | ** version 3.43.0. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements | 6 | ** possible if the files were compiled separately. Performance improvements |
| @@ -16,6 +16,9 @@ | |||
| 16 | ** if you want a wrapper to interface SQLite with your choice of programming | 16 | ** if you want a wrapper to interface SQLite with your choice of programming |
| 17 | ** language. The code for the "sqlite3" command-line shell is also in a | 17 | ** language. The code for the "sqlite3" command-line shell is also in a |
| 18 | ** separate file. This file contains only code for the core SQLite library. | 18 | ** separate file. This file contains only code for the core SQLite library. |
| 19 | ** | ||
| 20 | ** The content in this amalgamation comes from Fossil check-in | ||
| 21 | ** f80b798b3f4b81a7bb4233c58294edd0f11. | ||
| 19 | */ | 22 | */ |
| 20 | #define SQLITE_CORE 1 | 23 | #define SQLITE_CORE 1 |
| 21 | #define SQLITE_AMALGAMATION 1 | 24 | #define SQLITE_AMALGAMATION 1 |
| @@ -50,11 +53,11 @@ | |||
| 50 | ** used on lines of code that actually | 53 | ** used on lines of code that actually |
| 51 | ** implement parts of coverage testing. | 54 | ** implement parts of coverage testing. |
| 52 | ** | 55 | ** |
| 53 | ** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false | 56 | ** OPTIMIZATION-IF-TRUE - This branch is allowed to always be false |
| 54 | ** and the correct answer is still obtained, | 57 | ** and the correct answer is still obtained, |
| 55 | ** though perhaps more slowly. | 58 | ** though perhaps more slowly. |
| 56 | ** | 59 | ** |
| 57 | ** OPTIMIZATION-IF-FALSE - This branch is allowed to alway be true | 60 | ** OPTIMIZATION-IF-FALSE - This branch is allowed to always be true |
| 58 | ** and the correct answer is still obtained, | 61 | ** and the correct answer is still obtained, |
| 59 | ** though perhaps more slowly. | 62 | ** though perhaps more slowly. |
| 60 | ** | 63 | ** |
| @@ -123,6 +126,10 @@ | |||
| 123 | #define SQLITE_4_BYTE_ALIGNED_MALLOC | 126 | #define SQLITE_4_BYTE_ALIGNED_MALLOC |
| 124 | #endif /* defined(_MSC_VER) && !defined(_WIN64) */ | 127 | #endif /* defined(_MSC_VER) && !defined(_WIN64) */ |
| 125 | 128 | ||
| 129 | #if !defined(HAVE_LOG2) && defined(_MSC_VER) && _MSC_VER<1800 | ||
| 130 | #define HAVE_LOG2 0 | ||
| 131 | #endif /* !defined(HAVE_LOG2) && defined(_MSC_VER) && _MSC_VER<1800 */ | ||
| 132 | |||
| 126 | #endif /* SQLITE_MSVC_H */ | 133 | #endif /* SQLITE_MSVC_H */ |
| 127 | 134 | ||
| 128 | /************** End of msvc.h ************************************************/ | 135 | /************** End of msvc.h ************************************************/ |
| @@ -452,9 +459,9 @@ extern "C" { | |||
| 452 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], | 459 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 453 | ** [sqlite_version()] and [sqlite_source_id()]. | 460 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 454 | */ | 461 | */ |
| 455 | #define SQLITE_VERSION "3.39.3" | 462 | #define SQLITE_VERSION "3.43.0" |
| 456 | #define SQLITE_VERSION_NUMBER 3039003 | 463 | #define SQLITE_VERSION_NUMBER 3043000 |
| 457 | #define SQLITE_SOURCE_ID "2022-09-05 11:02:23 4635f4a69c8c2a8df242b384a992aea71224e39a2ccab42d8c0b0602f1e826e8" | 464 | #define SQLITE_SOURCE_ID "2023-08-24 12:36:59 0f80b798b3f4b81a7bb4233c58294edd0f1156f36b6ecf5ab8e83631d468778c" |
| 458 | 465 | ||
| 459 | /* | 466 | /* |
| 460 | ** CAPI3REF: Run-Time Library Version Numbers | 467 | ** CAPI3REF: Run-Time Library Version Numbers |
| @@ -834,6 +841,7 @@ SQLITE_API int sqlite3_exec( | |||
| 834 | #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) | 841 | #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) |
| 835 | #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) | 842 | #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) |
| 836 | #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) | 843 | #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) |
| 844 | #define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) | ||
| 837 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) | 845 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 838 | #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) | 846 | #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) |
| 839 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) | 847 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| @@ -869,6 +877,7 @@ SQLITE_API int sqlite3_exec( | |||
| 869 | #define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) | 877 | #define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) |
| 870 | #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) | 878 | #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) |
| 871 | #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) | 879 | #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) |
| 880 | #define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8)) | ||
| 872 | #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) | 881 | #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) |
| 873 | #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) | 882 | #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) |
| 874 | #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) | 883 | #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) |
| @@ -976,13 +985,17 @@ SQLITE_API int sqlite3_exec( | |||
| 976 | ** | 985 | ** |
| 977 | ** SQLite uses one of these integer values as the second | 986 | ** SQLite uses one of these integer values as the second |
| 978 | ** argument to calls it makes to the xLock() and xUnlock() methods | 987 | ** argument to calls it makes to the xLock() and xUnlock() methods |
| 979 | ** of an [sqlite3_io_methods] object. | 988 | ** of an [sqlite3_io_methods] object. These values are ordered from |
| 989 | ** lest restrictive to most restrictive. | ||
| 990 | ** | ||
| 991 | ** The argument to xLock() is always SHARED or higher. The argument to | ||
| 992 | ** xUnlock is either SHARED or NONE. | ||
| 980 | */ | 993 | */ |
| 981 | #define SQLITE_LOCK_NONE 0 | 994 | #define SQLITE_LOCK_NONE 0 /* xUnlock() only */ |
| 982 | #define SQLITE_LOCK_SHARED 1 | 995 | #define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ |
| 983 | #define SQLITE_LOCK_RESERVED 2 | 996 | #define SQLITE_LOCK_RESERVED 2 /* xLock() only */ |
| 984 | #define SQLITE_LOCK_PENDING 3 | 997 | #define SQLITE_LOCK_PENDING 3 /* xLock() only */ |
| 985 | #define SQLITE_LOCK_EXCLUSIVE 4 | 998 | #define SQLITE_LOCK_EXCLUSIVE 4 /* xLock() only */ |
| 986 | 999 | ||
| 987 | /* | 1000 | /* |
| 988 | ** CAPI3REF: Synchronization Type Flags | 1001 | ** CAPI3REF: Synchronization Type Flags |
| @@ -1060,7 +1073,14 @@ struct sqlite3_file { | |||
| 1060 | ** <li> [SQLITE_LOCK_PENDING], or | 1073 | ** <li> [SQLITE_LOCK_PENDING], or |
| 1061 | ** <li> [SQLITE_LOCK_EXCLUSIVE]. | 1074 | ** <li> [SQLITE_LOCK_EXCLUSIVE]. |
| 1062 | ** </ul> | 1075 | ** </ul> |
| 1063 | ** xLock() increases the lock. xUnlock() decreases the lock. | 1076 | ** xLock() upgrades the database file lock. In other words, xLock() moves the |
| 1077 | ** database file lock in the direction NONE toward EXCLUSIVE. The argument to | ||
| 1078 | ** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never | ||
| 1079 | ** SQLITE_LOCK_NONE. If the database file lock is already at or above the | ||
| 1080 | ** requested lock, then the call to xLock() is a no-op. | ||
| 1081 | ** xUnlock() downgrades the database file lock to either SHARED or NONE. | ||
| 1082 | * If the lock is already at or below the requested lock state, then the call | ||
| 1083 | ** to xUnlock() is a no-op. | ||
| 1064 | ** The xCheckReservedLock() method checks whether any database connection, | 1084 | ** The xCheckReservedLock() method checks whether any database connection, |
| 1065 | ** either in this process or in some other process, is holding a RESERVED, | 1085 | ** either in this process or in some other process, is holding a RESERVED, |
| 1066 | ** PENDING, or EXCLUSIVE lock on the file. It returns true | 1086 | ** PENDING, or EXCLUSIVE lock on the file. It returns true |
| @@ -1165,9 +1185,8 @@ struct sqlite3_io_methods { | |||
| 1165 | ** opcode causes the xFileControl method to write the current state of | 1185 | ** opcode causes the xFileControl method to write the current state of |
| 1166 | ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], | 1186 | ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], |
| 1167 | ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) | 1187 | ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) |
| 1168 | ** into an integer that the pArg argument points to. This capability | 1188 | ** into an integer that the pArg argument points to. |
| 1169 | ** is used during testing and is only available when the SQLITE_TEST | 1189 | ** This capability is only available if SQLite is compiled with [SQLITE_DEBUG]. |
| 1170 | ** compile-time option is used. | ||
| 1171 | ** | 1190 | ** |
| 1172 | ** <li>[[SQLITE_FCNTL_SIZE_HINT]] | 1191 | ** <li>[[SQLITE_FCNTL_SIZE_HINT]] |
| 1173 | ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS | 1192 | ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS |
| @@ -1471,7 +1490,6 @@ struct sqlite3_io_methods { | |||
| 1471 | ** in wal mode after the client has finished copying pages from the wal | 1490 | ** in wal mode after the client has finished copying pages from the wal |
| 1472 | ** file to the database file, but before the *-shm file is updated to | 1491 | ** file to the database file, but before the *-shm file is updated to |
| 1473 | ** record the fact that the pages have been checkpointed. | 1492 | ** record the fact that the pages have been checkpointed. |
| 1474 | ** </ul> | ||
| 1475 | ** | 1493 | ** |
| 1476 | ** <li>[[SQLITE_FCNTL_EXTERNAL_READER]] | 1494 | ** <li>[[SQLITE_FCNTL_EXTERNAL_READER]] |
| 1477 | ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect | 1495 | ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect |
| @@ -1484,10 +1502,16 @@ struct sqlite3_io_methods { | |||
| 1484 | ** the database is not a wal-mode db, or if there is no such connection in any | 1502 | ** the database is not a wal-mode db, or if there is no such connection in any |
| 1485 | ** other process. This opcode cannot be used to detect transactions opened | 1503 | ** other process. This opcode cannot be used to detect transactions opened |
| 1486 | ** by clients within the current process, only within other processes. | 1504 | ** by clients within the current process, only within other processes. |
| 1487 | ** </ul> | ||
| 1488 | ** | 1505 | ** |
| 1489 | ** <li>[[SQLITE_FCNTL_CKSM_FILE]] | 1506 | ** <li>[[SQLITE_FCNTL_CKSM_FILE]] |
| 1490 | ** Used by the cksmvfs VFS module only. | 1507 | ** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use internally by the |
| 1508 | ** [checksum VFS shim] only. | ||
| 1509 | ** | ||
| 1510 | ** <li>[[SQLITE_FCNTL_RESET_CACHE]] | ||
| 1511 | ** If there is currently no transaction open on the database, and the | ||
| 1512 | ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control | ||
| 1513 | ** purges the contents of the in-memory page cache. If there is an open | ||
| 1514 | ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. | ||
| 1491 | ** </ul> | 1515 | ** </ul> |
| 1492 | */ | 1516 | */ |
| 1493 | #define SQLITE_FCNTL_LOCKSTATE 1 | 1517 | #define SQLITE_FCNTL_LOCKSTATE 1 |
| @@ -1530,6 +1554,7 @@ struct sqlite3_io_methods { | |||
| 1530 | #define SQLITE_FCNTL_CKPT_START 39 | 1554 | #define SQLITE_FCNTL_CKPT_START 39 |
| 1531 | #define SQLITE_FCNTL_EXTERNAL_READER 40 | 1555 | #define SQLITE_FCNTL_EXTERNAL_READER 40 |
| 1532 | #define SQLITE_FCNTL_CKSM_FILE 41 | 1556 | #define SQLITE_FCNTL_CKSM_FILE 41 |
| 1557 | #define SQLITE_FCNTL_RESET_CACHE 42 | ||
| 1533 | 1558 | ||
| 1534 | /* deprecated names */ | 1559 | /* deprecated names */ |
| 1535 | #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE | 1560 | #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE |
| @@ -1560,6 +1585,26 @@ typedef struct sqlite3_mutex sqlite3_mutex; | |||
| 1560 | typedef struct sqlite3_api_routines sqlite3_api_routines; | 1585 | typedef struct sqlite3_api_routines sqlite3_api_routines; |
| 1561 | 1586 | ||
| 1562 | /* | 1587 | /* |
| 1588 | ** CAPI3REF: File Name | ||
| 1589 | ** | ||
| 1590 | ** Type [sqlite3_filename] is used by SQLite to pass filenames to the | ||
| 1591 | ** xOpen method of a [VFS]. It may be cast to (const char*) and treated | ||
| 1592 | ** as a normal, nul-terminated, UTF-8 buffer containing the filename, but | ||
| 1593 | ** may also be passed to special APIs such as: | ||
| 1594 | ** | ||
| 1595 | ** <ul> | ||
| 1596 | ** <li> sqlite3_filename_database() | ||
| 1597 | ** <li> sqlite3_filename_journal() | ||
| 1598 | ** <li> sqlite3_filename_wal() | ||
| 1599 | ** <li> sqlite3_uri_parameter() | ||
| 1600 | ** <li> sqlite3_uri_boolean() | ||
| 1601 | ** <li> sqlite3_uri_int64() | ||
| 1602 | ** <li> sqlite3_uri_key() | ||
| 1603 | ** </ul> | ||
| 1604 | */ | ||
| 1605 | typedef const char *sqlite3_filename; | ||
| 1606 | |||
| 1607 | /* | ||
| 1563 | ** CAPI3REF: OS Interface Object | 1608 | ** CAPI3REF: OS Interface Object |
| 1564 | ** | 1609 | ** |
| 1565 | ** An instance of the sqlite3_vfs object defines the interface between | 1610 | ** An instance of the sqlite3_vfs object defines the interface between |
| @@ -1737,7 +1782,7 @@ struct sqlite3_vfs { | |||
| 1737 | sqlite3_vfs *pNext; /* Next registered VFS */ | 1782 | sqlite3_vfs *pNext; /* Next registered VFS */ |
| 1738 | const char *zName; /* Name of this virtual file system */ | 1783 | const char *zName; /* Name of this virtual file system */ |
| 1739 | void *pAppData; /* Pointer to application-specific data */ | 1784 | void *pAppData; /* Pointer to application-specific data */ |
| 1740 | int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, | 1785 | int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, |
| 1741 | int flags, int *pOutFlags); | 1786 | int flags, int *pOutFlags); |
| 1742 | int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); | 1787 | int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); |
| 1743 | int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); | 1788 | int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); |
| @@ -1924,20 +1969,23 @@ SQLITE_API int sqlite3_os_end(void); | |||
| 1924 | ** must ensure that no other SQLite interfaces are invoked by other | 1969 | ** must ensure that no other SQLite interfaces are invoked by other |
| 1925 | ** threads while sqlite3_config() is running.</b> | 1970 | ** threads while sqlite3_config() is running.</b> |
| 1926 | ** | 1971 | ** |
| 1927 | ** The sqlite3_config() interface | ||
| 1928 | ** may only be invoked prior to library initialization using | ||
| 1929 | ** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. | ||
| 1930 | ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before | ||
| 1931 | ** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. | ||
| 1932 | ** Note, however, that ^sqlite3_config() can be called as part of the | ||
| 1933 | ** implementation of an application-defined [sqlite3_os_init()]. | ||
| 1934 | ** | ||
| 1935 | ** The first argument to sqlite3_config() is an integer | 1972 | ** The first argument to sqlite3_config() is an integer |
| 1936 | ** [configuration option] that determines | 1973 | ** [configuration option] that determines |
| 1937 | ** what property of SQLite is to be configured. Subsequent arguments | 1974 | ** what property of SQLite is to be configured. Subsequent arguments |
| 1938 | ** vary depending on the [configuration option] | 1975 | ** vary depending on the [configuration option] |
| 1939 | ** in the first argument. | 1976 | ** in the first argument. |
| 1940 | ** | 1977 | ** |
| 1978 | ** For most configuration options, the sqlite3_config() interface | ||
| 1979 | ** may only be invoked prior to library initialization using | ||
| 1980 | ** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. | ||
| 1981 | ** The exceptional configuration options that may be invoked at any time | ||
| 1982 | ** are called "anytime configuration options". | ||
| 1983 | ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before | ||
| 1984 | ** [sqlite3_shutdown()] with a first argument that is not an anytime | ||
| 1985 | ** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. | ||
| 1986 | ** Note, however, that ^sqlite3_config() can be called as part of the | ||
| 1987 | ** implementation of an application-defined [sqlite3_os_init()]. | ||
| 1988 | ** | ||
| 1941 | ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. | 1989 | ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. |
| 1942 | ** ^If the option is unknown or SQLite is unable to set the option | 1990 | ** ^If the option is unknown or SQLite is unable to set the option |
| 1943 | ** then this routine returns a non-zero [error code]. | 1991 | ** then this routine returns a non-zero [error code]. |
| @@ -2045,6 +2093,23 @@ struct sqlite3_mem_methods { | |||
| 2045 | ** These constants are the available integer configuration options that | 2093 | ** These constants are the available integer configuration options that |
| 2046 | ** can be passed as the first argument to the [sqlite3_config()] interface. | 2094 | ** can be passed as the first argument to the [sqlite3_config()] interface. |
| 2047 | ** | 2095 | ** |
| 2096 | ** Most of the configuration options for sqlite3_config() | ||
| 2097 | ** will only work if invoked prior to [sqlite3_initialize()] or after | ||
| 2098 | ** [sqlite3_shutdown()]. The few exceptions to this rule are called | ||
| 2099 | ** "anytime configuration options". | ||
| 2100 | ** ^Calling [sqlite3_config()] with a first argument that is not an | ||
| 2101 | ** anytime configuration option in between calls to [sqlite3_initialize()] and | ||
| 2102 | ** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE. | ||
| 2103 | ** | ||
| 2104 | ** The set of anytime configuration options can change (by insertions | ||
| 2105 | ** and/or deletions) from one release of SQLite to the next. | ||
| 2106 | ** As of SQLite version 3.42.0, the complete set of anytime configuration | ||
| 2107 | ** options is: | ||
| 2108 | ** <ul> | ||
| 2109 | ** <li> SQLITE_CONFIG_LOG | ||
| 2110 | ** <li> SQLITE_CONFIG_PCACHE_HDRSZ | ||
| 2111 | ** </ul> | ||
| 2112 | ** | ||
| 2048 | ** New configuration options may be added in future releases of SQLite. | 2113 | ** New configuration options may be added in future releases of SQLite. |
| 2049 | ** Existing configuration options might be discontinued. Applications | 2114 | ** Existing configuration options might be discontinued. Applications |
| 2050 | ** should check the return code from [sqlite3_config()] to make sure that | 2115 | ** should check the return code from [sqlite3_config()] to make sure that |
| @@ -2391,28 +2456,28 @@ struct sqlite3_mem_methods { | |||
| 2391 | ** compile-time option is not set, then the default maximum is 1073741824. | 2456 | ** compile-time option is not set, then the default maximum is 1073741824. |
| 2392 | ** </dl> | 2457 | ** </dl> |
| 2393 | */ | 2458 | */ |
| 2394 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ | 2459 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 2395 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ | 2460 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| 2396 | #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ | 2461 | #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ |
| 2397 | #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ | 2462 | #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ |
| 2398 | #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ | 2463 | #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ |
| 2399 | #define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ | 2464 | #define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ |
| 2400 | #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ | 2465 | #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ |
| 2401 | #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ | 2466 | #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ |
| 2402 | #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ | 2467 | #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ |
| 2403 | #define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ | 2468 | #define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ |
| 2404 | #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ | 2469 | #define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ |
| 2405 | /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ | 2470 | /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ |
| 2406 | #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ | 2471 | #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ |
| 2407 | #define SQLITE_CONFIG_PCACHE 14 /* no-op */ | 2472 | #define SQLITE_CONFIG_PCACHE 14 /* no-op */ |
| 2408 | #define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ | 2473 | #define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ |
| 2409 | #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ | 2474 | #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ |
| 2410 | #define SQLITE_CONFIG_URI 17 /* int */ | 2475 | #define SQLITE_CONFIG_URI 17 /* int */ |
| 2411 | #define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ | 2476 | #define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ |
| 2412 | #define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ | 2477 | #define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ |
| 2413 | #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ | 2478 | #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ |
| 2414 | #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ | 2479 | #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ |
| 2415 | #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ | 2480 | #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ |
| 2416 | #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ | 2481 | #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ |
| 2417 | #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ | 2482 | #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ |
| 2418 | #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ | 2483 | #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ |
| @@ -2453,7 +2518,7 @@ struct sqlite3_mem_methods { | |||
| 2453 | ** configuration for a database connection can only be changed when that | 2518 | ** configuration for a database connection can only be changed when that |
| 2454 | ** connection is not currently using lookaside memory, or in other words | 2519 | ** connection is not currently using lookaside memory, or in other words |
| 2455 | ** when the "current value" returned by | 2520 | ** when the "current value" returned by |
| 2456 | ** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. | 2521 | ** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. |
| 2457 | ** Any attempt to change the lookaside memory configuration when lookaside | 2522 | ** Any attempt to change the lookaside memory configuration when lookaside |
| 2458 | ** memory is in use leaves the configuration unchanged and returns | 2523 | ** memory is in use leaves the configuration unchanged and returns |
| 2459 | ** [SQLITE_BUSY].)^</dd> | 2524 | ** [SQLITE_BUSY].)^</dd> |
| @@ -2603,8 +2668,12 @@ struct sqlite3_mem_methods { | |||
| 2603 | ** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); | 2668 | ** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); |
| 2604 | ** </ol> | 2669 | ** </ol> |
| 2605 | ** Because resetting a database is destructive and irreversible, the | 2670 | ** Because resetting a database is destructive and irreversible, the |
| 2606 | ** process requires the use of this obscure API and multiple steps to help | 2671 | ** process requires the use of this obscure API and multiple steps to |
| 2607 | ** ensure that it does not happen by accident. | 2672 | ** help ensure that it does not happen by accident. Because this |
| 2673 | ** feature must be capable of resetting corrupt databases, and | ||
| 2674 | ** shutting down virtual tables may require access to that corrupt | ||
| 2675 | ** storage, the library must abandon any installed virtual tables | ||
| 2676 | ** without calling their xDestroy() methods. | ||
| 2608 | ** | 2677 | ** |
| 2609 | ** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt> | 2678 | ** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt> |
| 2610 | ** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the | 2679 | ** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the |
| @@ -2615,6 +2684,7 @@ struct sqlite3_mem_methods { | |||
| 2615 | ** <ul> | 2684 | ** <ul> |
| 2616 | ** <li> The [PRAGMA writable_schema=ON] statement. | 2685 | ** <li> The [PRAGMA writable_schema=ON] statement. |
| 2617 | ** <li> The [PRAGMA journal_mode=OFF] statement. | 2686 | ** <li> The [PRAGMA journal_mode=OFF] statement. |
| 2687 | ** <li> The [PRAGMA schema_version=N] statement. | ||
| 2618 | ** <li> Writes to the [sqlite_dbpage] virtual table. | 2688 | ** <li> Writes to the [sqlite_dbpage] virtual table. |
| 2619 | ** <li> Direct writes to [shadow tables]. | 2689 | ** <li> Direct writes to [shadow tables]. |
| 2620 | ** </ul> | 2690 | ** </ul> |
| @@ -2642,7 +2712,7 @@ struct sqlite3_mem_methods { | |||
| 2642 | ** </dd> | 2712 | ** </dd> |
| 2643 | ** | 2713 | ** |
| 2644 | ** [[SQLITE_DBCONFIG_DQS_DML]] | 2714 | ** [[SQLITE_DBCONFIG_DQS_DML]] |
| 2645 | ** <dt>SQLITE_DBCONFIG_DQS_DML</td> | 2715 | ** <dt>SQLITE_DBCONFIG_DQS_DML</dt> |
| 2646 | ** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates | 2716 | ** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates |
| 2647 | ** the legacy [double-quoted string literal] misfeature for DML statements | 2717 | ** the legacy [double-quoted string literal] misfeature for DML statements |
| 2648 | ** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The | 2718 | ** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The |
| @@ -2651,7 +2721,7 @@ struct sqlite3_mem_methods { | |||
| 2651 | ** </dd> | 2721 | ** </dd> |
| 2652 | ** | 2722 | ** |
| 2653 | ** [[SQLITE_DBCONFIG_DQS_DDL]] | 2723 | ** [[SQLITE_DBCONFIG_DQS_DDL]] |
| 2654 | ** <dt>SQLITE_DBCONFIG_DQS_DDL</td> | 2724 | ** <dt>SQLITE_DBCONFIG_DQS_DDL</dt> |
| 2655 | ** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates | 2725 | ** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates |
| 2656 | ** the legacy [double-quoted string literal] misfeature for DDL statements, | 2726 | ** the legacy [double-quoted string literal] misfeature for DDL statements, |
| 2657 | ** such as CREATE TABLE and CREATE INDEX. The | 2727 | ** such as CREATE TABLE and CREATE INDEX. The |
| @@ -2660,7 +2730,7 @@ struct sqlite3_mem_methods { | |||
| 2660 | ** </dd> | 2730 | ** </dd> |
| 2661 | ** | 2731 | ** |
| 2662 | ** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] | 2732 | ** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] |
| 2663 | ** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td> | 2733 | ** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</dt> |
| 2664 | ** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to | 2734 | ** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to |
| 2665 | ** assume that database schemas are untainted by malicious content. | 2735 | ** assume that database schemas are untainted by malicious content. |
| 2666 | ** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite | 2736 | ** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite |
| @@ -2680,7 +2750,7 @@ struct sqlite3_mem_methods { | |||
| 2680 | ** </dd> | 2750 | ** </dd> |
| 2681 | ** | 2751 | ** |
| 2682 | ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] | 2752 | ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] |
| 2683 | ** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</td> | 2753 | ** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt> |
| 2684 | ** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates | 2754 | ** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates |
| 2685 | ** the legacy file format flag. When activated, this flag causes all newly | 2755 | ** the legacy file format flag. When activated, this flag causes all newly |
| 2686 | ** created database file to have a schema format version number (the 4-byte | 2756 | ** created database file to have a schema format version number (the 4-byte |
| @@ -2689,7 +2759,7 @@ struct sqlite3_mem_methods { | |||
| 2689 | ** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, | 2759 | ** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, |
| 2690 | ** newly created databases are generally not understandable by SQLite versions | 2760 | ** newly created databases are generally not understandable by SQLite versions |
| 2691 | ** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there | 2761 | ** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there |
| 2692 | ** is now scarcely any need to generated database files that are compatible | 2762 | ** is now scarcely any need to generate database files that are compatible |
| 2693 | ** all the way back to version 3.0.0, and so this setting is of little | 2763 | ** all the way back to version 3.0.0, and so this setting is of little |
| 2694 | ** practical use, but is provided so that SQLite can continue to claim the | 2764 | ** practical use, but is provided so that SQLite can continue to claim the |
| 2695 | ** ability to generate new database files that are compatible with version | 2765 | ** ability to generate new database files that are compatible with version |
| @@ -2698,8 +2768,40 @@ struct sqlite3_mem_methods { | |||
| 2698 | ** the [VACUUM] command will fail with an obscure error when attempting to | 2768 | ** the [VACUUM] command will fail with an obscure error when attempting to |
| 2699 | ** process a table with generated columns and a descending index. This is | 2769 | ** process a table with generated columns and a descending index. This is |
| 2700 | ** not considered a bug since SQLite versions 3.3.0 and earlier do not support | 2770 | ** not considered a bug since SQLite versions 3.3.0 and earlier do not support |
| 2701 | ** either generated columns or decending indexes. | 2771 | ** either generated columns or descending indexes. |
| 2772 | ** </dd> | ||
| 2773 | ** | ||
| 2774 | ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] | ||
| 2775 | ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> | ||
| 2776 | ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in | ||
| 2777 | ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears | ||
| 2778 | ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() | ||
| 2779 | ** statistics. For statistics to be collected, the flag must be set on | ||
| 2780 | ** the database handle both when the SQL statement is prepared and when it | ||
| 2781 | ** is stepped. The flag is set (collection of statistics is enabled) | ||
| 2782 | ** by default. This option takes two arguments: an integer and a pointer to | ||
| 2783 | ** an integer.. The first argument is 1, 0, or -1 to enable, disable, or | ||
| 2784 | ** leave unchanged the statement scanstatus option. If the second argument | ||
| 2785 | ** is not NULL, then the value of the statement scanstatus setting after | ||
| 2786 | ** processing the first argument is written into the integer that the second | ||
| 2787 | ** argument points to. | ||
| 2788 | ** </dd> | ||
| 2789 | ** | ||
| 2790 | ** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] | ||
| 2791 | ** <dt>SQLITE_DBCONFIG_REVERSE_SCANORDER</dt> | ||
| 2792 | ** <dd>The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order | ||
| 2793 | ** in which tables and indexes are scanned so that the scans start at the end | ||
| 2794 | ** and work toward the beginning rather than starting at the beginning and | ||
| 2795 | ** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the | ||
| 2796 | ** same as setting [PRAGMA reverse_unordered_selects]. This option takes | ||
| 2797 | ** two arguments which are an integer and a pointer to an integer. The first | ||
| 2798 | ** argument is 1, 0, or -1 to enable, disable, or leave unchanged the | ||
| 2799 | ** reverse scan order flag, respectively. If the second argument is not NULL, | ||
| 2800 | ** then 0 or 1 is written into the integer that the second argument points to | ||
| 2801 | ** depending on if the reverse scan order flag is set after processing the | ||
| 2802 | ** first argument. | ||
| 2702 | ** </dd> | 2803 | ** </dd> |
| 2804 | ** | ||
| 2703 | ** </dl> | 2805 | ** </dl> |
| 2704 | */ | 2806 | */ |
| 2705 | #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ | 2807 | #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ |
| @@ -2720,7 +2822,9 @@ struct sqlite3_mem_methods { | |||
| 2720 | #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ | 2822 | #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ |
| 2721 | #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ | 2823 | #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ |
| 2722 | #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ | 2824 | #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ |
| 2723 | #define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ | 2825 | #define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ |
| 2826 | #define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ | ||
| 2827 | #define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */ | ||
| 2724 | 2828 | ||
| 2725 | /* | 2829 | /* |
| 2726 | ** CAPI3REF: Enable Or Disable Extended Result Codes | 2830 | ** CAPI3REF: Enable Or Disable Extended Result Codes |
| @@ -2942,8 +3046,13 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*); | |||
| 2942 | ** ^A call to sqlite3_interrupt(D) that occurs when there are no running | 3046 | ** ^A call to sqlite3_interrupt(D) that occurs when there are no running |
| 2943 | ** SQL statements is a no-op and has no effect on SQL statements | 3047 | ** SQL statements is a no-op and has no effect on SQL statements |
| 2944 | ** that are started after the sqlite3_interrupt() call returns. | 3048 | ** that are started after the sqlite3_interrupt() call returns. |
| 3049 | ** | ||
| 3050 | ** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether | ||
| 3051 | ** or not an interrupt is currently in effect for [database connection] D. | ||
| 3052 | ** It returns 1 if an interrupt is currently in effect, or 0 otherwise. | ||
| 2945 | */ | 3053 | */ |
| 2946 | SQLITE_API void sqlite3_interrupt(sqlite3*); | 3054 | SQLITE_API void sqlite3_interrupt(sqlite3*); |
| 3055 | SQLITE_API int sqlite3_is_interrupted(sqlite3*); | ||
| 2947 | 3056 | ||
| 2948 | /* | 3057 | /* |
| 2949 | ** CAPI3REF: Determine If An SQL Statement Is Complete | 3058 | ** CAPI3REF: Determine If An SQL Statement Is Complete |
| @@ -3561,8 +3670,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, | |||
| 3561 | ** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same | 3670 | ** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same |
| 3562 | ** information as is provided by the [sqlite3_profile()] callback. | 3671 | ** information as is provided by the [sqlite3_profile()] callback. |
| 3563 | ** ^The P argument is a pointer to the [prepared statement] and the | 3672 | ** ^The P argument is a pointer to the [prepared statement] and the |
| 3564 | ** X argument points to a 64-bit integer which is the estimated of | 3673 | ** X argument points to a 64-bit integer which is approximately |
| 3565 | ** the number of nanosecond that the prepared statement took to run. | 3674 | ** the number of nanoseconds that the prepared statement took to run. |
| 3566 | ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. | 3675 | ** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. |
| 3567 | ** | 3676 | ** |
| 3568 | ** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt> | 3677 | ** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt> |
| @@ -3594,8 +3703,10 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, | |||
| 3594 | ** M argument should be the bitwise OR-ed combination of | 3703 | ** M argument should be the bitwise OR-ed combination of |
| 3595 | ** zero or more [SQLITE_TRACE] constants. | 3704 | ** zero or more [SQLITE_TRACE] constants. |
| 3596 | ** | 3705 | ** |
| 3597 | ** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides | 3706 | ** ^Each call to either sqlite3_trace(D,X,P) or sqlite3_trace_v2(D,M,X,P) |
| 3598 | ** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). | 3707 | ** overrides (cancels) all prior calls to sqlite3_trace(D,X,P) or |
| 3708 | ** sqlite3_trace_v2(D,M,X,P) for the [database connection] D. Each | ||
| 3709 | ** database connection may have at most one trace callback. | ||
| 3599 | ** | 3710 | ** |
| 3600 | ** ^The X callback is invoked whenever any of the events identified by | 3711 | ** ^The X callback is invoked whenever any of the events identified by |
| 3601 | ** mask M occur. ^The integer return value from the callback is currently | 3712 | ** mask M occur. ^The integer return value from the callback is currently |
| @@ -3625,7 +3736,7 @@ SQLITE_API int sqlite3_trace_v2( | |||
| 3625 | ** | 3736 | ** |
| 3626 | ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback | 3737 | ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback |
| 3627 | ** function X to be invoked periodically during long running calls to | 3738 | ** function X to be invoked periodically during long running calls to |
| 3628 | ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for | 3739 | ** [sqlite3_step()] and [sqlite3_prepare()] and similar for |
| 3629 | ** database connection D. An example use for this | 3740 | ** database connection D. An example use for this |
| 3630 | ** interface is to keep a GUI updated during a large query. | 3741 | ** interface is to keep a GUI updated during a large query. |
| 3631 | ** | 3742 | ** |
| @@ -3650,6 +3761,13 @@ SQLITE_API int sqlite3_trace_v2( | |||
| 3650 | ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their | 3761 | ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their |
| 3651 | ** database connections for the meaning of "modify" in this paragraph. | 3762 | ** database connections for the meaning of "modify" in this paragraph. |
| 3652 | ** | 3763 | ** |
| 3764 | ** The progress handler callback would originally only be invoked from the | ||
| 3765 | ** bytecode engine. It still might be invoked during [sqlite3_prepare()] | ||
| 3766 | ** and similar because those routines might force a reparse of the schema | ||
| 3767 | ** which involves running the bytecode engine. However, beginning with | ||
| 3768 | ** SQLite version 3.41.0, the progress handler callback might also be | ||
| 3769 | ** invoked directly from [sqlite3_prepare()] while analyzing and generating | ||
| 3770 | ** code for complex queries. | ||
| 3653 | */ | 3771 | */ |
| 3654 | SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); | 3772 | SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); |
| 3655 | 3773 | ||
| @@ -3686,13 +3804,18 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); | |||
| 3686 | ** | 3804 | ** |
| 3687 | ** <dl> | 3805 | ** <dl> |
| 3688 | ** ^(<dt>[SQLITE_OPEN_READONLY]</dt> | 3806 | ** ^(<dt>[SQLITE_OPEN_READONLY]</dt> |
| 3689 | ** <dd>The database is opened in read-only mode. If the database does not | 3807 | ** <dd>The database is opened in read-only mode. If the database does |
| 3690 | ** already exist, an error is returned.</dd>)^ | 3808 | ** not already exist, an error is returned.</dd>)^ |
| 3691 | ** | 3809 | ** |
| 3692 | ** ^(<dt>[SQLITE_OPEN_READWRITE]</dt> | 3810 | ** ^(<dt>[SQLITE_OPEN_READWRITE]</dt> |
| 3693 | ** <dd>The database is opened for reading and writing if possible, or reading | 3811 | ** <dd>The database is opened for reading and writing if possible, or |
| 3694 | ** only if the file is write protected by the operating system. In either | 3812 | ** reading only if the file is write protected by the operating |
| 3695 | ** case the database must already exist, otherwise an error is returned.</dd>)^ | 3813 | ** system. In either case the database must already exist, otherwise |
| 3814 | ** an error is returned. For historical reasons, if opening in | ||
| 3815 | ** read-write mode fails due to OS-level permissions, an attempt is | ||
| 3816 | ** made to open it in read-only mode. [sqlite3_db_readonly()] can be | ||
| 3817 | ** used to determine whether the database is actually | ||
| 3818 | ** read-write.</dd>)^ | ||
| 3696 | ** | 3819 | ** |
| 3697 | ** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt> | 3820 | ** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt> |
| 3698 | ** <dd>The database is opened for reading and writing, and is created if | 3821 | ** <dd>The database is opened for reading and writing, and is created if |
| @@ -3730,6 +3853,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); | |||
| 3730 | ** <dd>The database is opened [shared cache] enabled, overriding | 3853 | ** <dd>The database is opened [shared cache] enabled, overriding |
| 3731 | ** the default shared cache setting provided by | 3854 | ** the default shared cache setting provided by |
| 3732 | ** [sqlite3_enable_shared_cache()].)^ | 3855 | ** [sqlite3_enable_shared_cache()].)^ |
| 3856 | ** The [use of shared cache mode is discouraged] and hence shared cache | ||
| 3857 | ** capabilities may be omitted from many builds of SQLite. In such cases, | ||
| 3858 | ** this option is a no-op. | ||
| 3733 | ** | 3859 | ** |
| 3734 | ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt> | 3860 | ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt> |
| 3735 | ** <dd>The database is opened [shared cache] disabled, overriding | 3861 | ** <dd>The database is opened [shared cache] disabled, overriding |
| @@ -3745,7 +3871,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); | |||
| 3745 | ** to return an extended result code.</dd> | 3871 | ** to return an extended result code.</dd> |
| 3746 | ** | 3872 | ** |
| 3747 | ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt> | 3873 | ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt> |
| 3748 | ** <dd>The database filename is not allowed to be a symbolic link</dd> | 3874 | ** <dd>The database filename is not allowed to contain a symbolic link</dd> |
| 3749 | ** </dl>)^ | 3875 | ** </dl>)^ |
| 3750 | ** | 3876 | ** |
| 3751 | ** If the 3rd parameter to sqlite3_open_v2() is not one of the | 3877 | ** If the 3rd parameter to sqlite3_open_v2() is not one of the |
| @@ -3949,7 +4075,7 @@ SQLITE_API int sqlite3_open_v2( | |||
| 3949 | ** as F) must be one of: | 4075 | ** as F) must be one of: |
| 3950 | ** <ul> | 4076 | ** <ul> |
| 3951 | ** <li> A database filename pointer created by the SQLite core and | 4077 | ** <li> A database filename pointer created by the SQLite core and |
| 3952 | ** passed into the xOpen() method of a VFS implemention, or | 4078 | ** passed into the xOpen() method of a VFS implementation, or |
| 3953 | ** <li> A filename obtained from [sqlite3_db_filename()], or | 4079 | ** <li> A filename obtained from [sqlite3_db_filename()], or |
| 3954 | ** <li> A new filename constructed using [sqlite3_create_filename()]. | 4080 | ** <li> A new filename constructed using [sqlite3_create_filename()]. |
| 3955 | ** </ul> | 4081 | ** </ul> |
| @@ -4004,10 +4130,10 @@ SQLITE_API int sqlite3_open_v2( | |||
| 4004 | ** | 4130 | ** |
| 4005 | ** See the [URI filename] documentation for additional information. | 4131 | ** See the [URI filename] documentation for additional information. |
| 4006 | */ | 4132 | */ |
| 4007 | SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); | 4133 | SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam); |
| 4008 | SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); | 4134 | SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault); |
| 4009 | SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); | 4135 | SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64); |
| 4010 | SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); | 4136 | SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N); |
| 4011 | 4137 | ||
| 4012 | /* | 4138 | /* |
| 4013 | ** CAPI3REF: Translate filenames | 4139 | ** CAPI3REF: Translate filenames |
| @@ -4036,9 +4162,9 @@ SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); | |||
| 4036 | ** return value from [sqlite3_db_filename()], then the result is | 4162 | ** return value from [sqlite3_db_filename()], then the result is |
| 4037 | ** undefined and is likely a memory access violation. | 4163 | ** undefined and is likely a memory access violation. |
| 4038 | */ | 4164 | */ |
| 4039 | SQLITE_API const char *sqlite3_filename_database(const char*); | 4165 | SQLITE_API const char *sqlite3_filename_database(sqlite3_filename); |
| 4040 | SQLITE_API const char *sqlite3_filename_journal(const char*); | 4166 | SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename); |
| 4041 | SQLITE_API const char *sqlite3_filename_wal(const char*); | 4167 | SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename); |
| 4042 | 4168 | ||
| 4043 | /* | 4169 | /* |
| 4044 | ** CAPI3REF: Database File Corresponding To A Journal | 4170 | ** CAPI3REF: Database File Corresponding To A Journal |
| @@ -4062,7 +4188,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); | |||
| 4062 | /* | 4188 | /* |
| 4063 | ** CAPI3REF: Create and Destroy VFS Filenames | 4189 | ** CAPI3REF: Create and Destroy VFS Filenames |
| 4064 | ** | 4190 | ** |
| 4065 | ** These interfces are provided for use by [VFS shim] implementations and | 4191 | ** These interfaces are provided for use by [VFS shim] implementations and |
| 4066 | ** are not useful outside of that context. | 4192 | ** are not useful outside of that context. |
| 4067 | ** | 4193 | ** |
| 4068 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of | 4194 | ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of |
| @@ -4104,14 +4230,14 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); | |||
| 4104 | ** then the corresponding [sqlite3_module.xClose() method should also be | 4230 | ** then the corresponding [sqlite3_module.xClose() method should also be |
| 4105 | ** invoked prior to calling sqlite3_free_filename(Y). | 4231 | ** invoked prior to calling sqlite3_free_filename(Y). |
| 4106 | */ | 4232 | */ |
| 4107 | SQLITE_API char *sqlite3_create_filename( | 4233 | SQLITE_API sqlite3_filename sqlite3_create_filename( |
| 4108 | const char *zDatabase, | 4234 | const char *zDatabase, |
| 4109 | const char *zJournal, | 4235 | const char *zJournal, |
| 4110 | const char *zWal, | 4236 | const char *zWal, |
| 4111 | int nParam, | 4237 | int nParam, |
| 4112 | const char **azParam | 4238 | const char **azParam |
| 4113 | ); | 4239 | ); |
| 4114 | SQLITE_API void sqlite3_free_filename(char*); | 4240 | SQLITE_API void sqlite3_free_filename(sqlite3_filename); |
| 4115 | 4241 | ||
| 4116 | /* | 4242 | /* |
| 4117 | ** CAPI3REF: Error Codes And Messages | 4243 | ** CAPI3REF: Error Codes And Messages |
| @@ -4610,6 +4736,41 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); | |||
| 4610 | SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); | 4736 | SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); |
| 4611 | 4737 | ||
| 4612 | /* | 4738 | /* |
| 4739 | ** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement | ||
| 4740 | ** METHOD: sqlite3_stmt | ||
| 4741 | ** | ||
| 4742 | ** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN | ||
| 4743 | ** setting for [prepared statement] S. If E is zero, then S becomes | ||
| 4744 | ** a normal prepared statement. If E is 1, then S behaves as if | ||
| 4745 | ** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if | ||
| 4746 | ** its SQL text began with "[EXPLAIN QUERY PLAN]". | ||
| 4747 | ** | ||
| 4748 | ** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared. | ||
| 4749 | ** SQLite tries to avoid a reprepare, but a reprepare might be necessary | ||
| 4750 | ** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode. | ||
| 4751 | ** | ||
| 4752 | ** Because of the potential need to reprepare, a call to | ||
| 4753 | ** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be | ||
| 4754 | ** reprepared because it was created using [sqlite3_prepare()] instead of | ||
| 4755 | ** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and | ||
| 4756 | ** hence has no saved SQL text with which to reprepare. | ||
| 4757 | ** | ||
| 4758 | ** Changing the explain setting for a prepared statement does not change | ||
| 4759 | ** the original SQL text for the statement. Hence, if the SQL text originally | ||
| 4760 | ** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0) | ||
| 4761 | ** is called to convert the statement into an ordinary statement, the EXPLAIN | ||
| 4762 | ** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S) | ||
| 4763 | ** output, even though the statement now acts like a normal SQL statement. | ||
| 4764 | ** | ||
| 4765 | ** This routine returns SQLITE_OK if the explain mode is successfully | ||
| 4766 | ** changed, or an error code if the explain mode could not be changed. | ||
| 4767 | ** The explain mode cannot be changed while a statement is active. | ||
| 4768 | ** Hence, it is good practice to call [sqlite3_reset(S)] | ||
| 4769 | ** immediately prior to calling sqlite3_stmt_explain(S,E). | ||
| 4770 | */ | ||
| 4771 | SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode); | ||
| 4772 | |||
| 4773 | /* | ||
| 4613 | ** CAPI3REF: Determine If A Prepared Statement Has Been Reset | 4774 | ** CAPI3REF: Determine If A Prepared Statement Has Been Reset |
| 4614 | ** METHOD: sqlite3_stmt | 4775 | ** METHOD: sqlite3_stmt |
| 4615 | ** | 4776 | ** |
| @@ -4772,7 +4933,7 @@ typedef struct sqlite3_context sqlite3_context; | |||
| 4772 | ** with it may be passed. ^It is called to dispose of the BLOB or string even | 4933 | ** with it may be passed. ^It is called to dispose of the BLOB or string even |
| 4773 | ** if the call to the bind API fails, except the destructor is not called if | 4934 | ** if the call to the bind API fails, except the destructor is not called if |
| 4774 | ** the third parameter is a NULL pointer or the fourth parameter is negative. | 4935 | ** the third parameter is a NULL pointer or the fourth parameter is negative. |
| 4775 | ** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that | 4936 | ** ^ (2) The special constant, [SQLITE_STATIC], may be passed to indicate that |
| 4776 | ** the application remains responsible for disposing of the object. ^In this | 4937 | ** the application remains responsible for disposing of the object. ^In this |
| 4777 | ** case, the object and the provided pointer to it must remain valid until | 4938 | ** case, the object and the provided pointer to it must remain valid until |
| 4778 | ** either the prepared statement is finalized or the same SQL parameter is | 4939 | ** either the prepared statement is finalized or the same SQL parameter is |
| @@ -5451,14 +5612,26 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); | |||
| 5451 | ** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S | 5612 | ** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S |
| 5452 | ** back to the beginning of its program. | 5613 | ** back to the beginning of its program. |
| 5453 | ** | 5614 | ** |
| 5454 | ** ^If the most recent call to [sqlite3_step(S)] for the | 5615 | ** ^The return code from [sqlite3_reset(S)] indicates whether or not |
| 5455 | ** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], | 5616 | ** the previous evaluation of prepared statement S completed successfully. |
| 5456 | ** or if [sqlite3_step(S)] has never before been called on S, | 5617 | ** ^If [sqlite3_step(S)] has never before been called on S or if |
| 5457 | ** then [sqlite3_reset(S)] returns [SQLITE_OK]. | 5618 | ** [sqlite3_step(S)] has not been called since the previous call |
| 5619 | ** to [sqlite3_reset(S)], then [sqlite3_reset(S)] will return | ||
| 5620 | ** [SQLITE_OK]. | ||
| 5458 | ** | 5621 | ** |
| 5459 | ** ^If the most recent call to [sqlite3_step(S)] for the | 5622 | ** ^If the most recent call to [sqlite3_step(S)] for the |
| 5460 | ** [prepared statement] S indicated an error, then | 5623 | ** [prepared statement] S indicated an error, then |
| 5461 | ** [sqlite3_reset(S)] returns an appropriate [error code]. | 5624 | ** [sqlite3_reset(S)] returns an appropriate [error code]. |
| 5625 | ** ^The [sqlite3_reset(S)] interface might also return an [error code] | ||
| 5626 | ** if there were no prior errors but the process of resetting | ||
| 5627 | ** the prepared statement caused a new error. ^For example, if an | ||
| 5628 | ** [INSERT] statement with a [RETURNING] clause is only stepped one time, | ||
| 5629 | ** that one call to [sqlite3_step(S)] might return SQLITE_ROW but | ||
| 5630 | ** the overall statement might still fail and the [sqlite3_reset(S)] call | ||
| 5631 | ** might return SQLITE_BUSY if locking constraints prevent the | ||
| 5632 | ** database change from committing. Therefore, it is important that | ||
| 5633 | ** applications check the return code from [sqlite3_reset(S)] even if | ||
| 5634 | ** no prior call to [sqlite3_step(S)] indicated a problem. | ||
| 5462 | ** | 5635 | ** |
| 5463 | ** ^The [sqlite3_reset(S)] interface does not change the values | 5636 | ** ^The [sqlite3_reset(S)] interface does not change the values |
| 5464 | ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. | 5637 | ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. |
| @@ -5670,10 +5843,21 @@ SQLITE_API int sqlite3_create_window_function( | |||
| 5670 | ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in | 5843 | ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in |
| 5671 | ** schema structures such as [CHECK constraints], [DEFAULT clauses], | 5844 | ** schema structures such as [CHECK constraints], [DEFAULT clauses], |
| 5672 | ** [expression indexes], [partial indexes], or [generated columns]. | 5845 | ** [expression indexes], [partial indexes], or [generated columns]. |
| 5673 | ** The SQLITE_DIRECTONLY flags is a security feature which is recommended | 5846 | ** <p> |
| 5674 | ** for all [application-defined SQL functions], and especially for functions | 5847 | ** The SQLITE_DIRECTONLY flag is recommended for any |
| 5675 | ** that have side-effects or that could potentially leak sensitive | 5848 | ** [application-defined SQL function] |
| 5676 | ** information. | 5849 | ** that has side-effects or that could potentially leak sensitive information. |
| 5850 | ** This will prevent attacks in which an application is tricked | ||
| 5851 | ** into using a database file that has had its schema surreptitiously | ||
| 5852 | ** modified to invoke the application-defined function in ways that are | ||
| 5853 | ** harmful. | ||
| 5854 | ** <p> | ||
| 5855 | ** Some people say it is good practice to set SQLITE_DIRECTONLY on all | ||
| 5856 | ** [application-defined SQL functions], regardless of whether or not they | ||
| 5857 | ** are security sensitive, as doing so prevents those functions from being used | ||
| 5858 | ** inside of the database schema, and thus ensures that the database | ||
| 5859 | ** can be inspected and modified using generic tools (such as the [CLI]) | ||
| 5860 | ** that do not have access to the application-defined functions. | ||
| 5677 | ** </dd> | 5861 | ** </dd> |
| 5678 | ** | 5862 | ** |
| 5679 | ** [[SQLITE_INNOCUOUS]] <dt>SQLITE_INNOCUOUS</dt><dd> | 5863 | ** [[SQLITE_INNOCUOUS]] <dt>SQLITE_INNOCUOUS</dt><dd> |
| @@ -5880,6 +6064,28 @@ SQLITE_API int sqlite3_value_nochange(sqlite3_value*); | |||
| 5880 | SQLITE_API int sqlite3_value_frombind(sqlite3_value*); | 6064 | SQLITE_API int sqlite3_value_frombind(sqlite3_value*); |
| 5881 | 6065 | ||
| 5882 | /* | 6066 | /* |
| 6067 | ** CAPI3REF: Report the internal text encoding state of an sqlite3_value object | ||
| 6068 | ** METHOD: sqlite3_value | ||
| 6069 | ** | ||
| 6070 | ** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8], | ||
| 6071 | ** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding | ||
| 6072 | ** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) | ||
| 6073 | ** returns something other than SQLITE_TEXT, then the return value from | ||
| 6074 | ** sqlite3_value_encoding(X) is meaningless. ^Calls to | ||
| 6075 | ** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], | ||
| 6076 | ** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or | ||
| 6077 | ** [sqlite3_value_bytes16(X)] might change the encoding of the value X and | ||
| 6078 | ** thus change the return from subsequent calls to sqlite3_value_encoding(X). | ||
| 6079 | ** | ||
| 6080 | ** This routine is intended for used by applications that test and validate | ||
| 6081 | ** the SQLite implementation. This routine is inquiring about the opaque | ||
| 6082 | ** internal state of an [sqlite3_value] object. Ordinary applications should | ||
| 6083 | ** not need to know what the internal state of an sqlite3_value object is and | ||
| 6084 | ** hence should not need to use this interface. | ||
| 6085 | */ | ||
| 6086 | SQLITE_API int sqlite3_value_encoding(sqlite3_value*); | ||
| 6087 | |||
| 6088 | /* | ||
| 5883 | ** CAPI3REF: Finding The Subtype Of SQL Values | 6089 | ** CAPI3REF: Finding The Subtype Of SQL Values |
| 5884 | ** METHOD: sqlite3_value | 6090 | ** METHOD: sqlite3_value |
| 5885 | ** | 6091 | ** |
| @@ -5931,7 +6137,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); | |||
| 5931 | ** | 6137 | ** |
| 5932 | ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer | 6138 | ** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer |
| 5933 | ** when first called if N is less than or equal to zero or if a memory | 6139 | ** when first called if N is less than or equal to zero or if a memory |
| 5934 | ** allocate error occurs. | 6140 | ** allocation error occurs. |
| 5935 | ** | 6141 | ** |
| 5936 | ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is | 6142 | ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is |
| 5937 | ** determined by the N parameter on first successful call. Changing the | 6143 | ** determined by the N parameter on first successful call. Changing the |
| @@ -6136,9 +6342,10 @@ typedef void (*sqlite3_destructor_type)(void*); | |||
| 6136 | ** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. | 6342 | ** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. |
| 6137 | ** ^SQLite takes the text result from the application from | 6343 | ** ^SQLite takes the text result from the application from |
| 6138 | ** the 2nd parameter of the sqlite3_result_text* interfaces. | 6344 | ** the 2nd parameter of the sqlite3_result_text* interfaces. |
| 6139 | ** ^If the 3rd parameter to the sqlite3_result_text* interfaces | 6345 | ** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces |
| 6140 | ** is negative, then SQLite takes result text from the 2nd parameter | 6346 | ** other than sqlite3_result_text64() is negative, then SQLite computes |
| 6141 | ** through the first zero character. | 6347 | ** the string length itself by searching the 2nd parameter for the first |
| 6348 | ** zero character. | ||
| 6142 | ** ^If the 3rd parameter to the sqlite3_result_text* interfaces | 6349 | ** ^If the 3rd parameter to the sqlite3_result_text* interfaces |
| 6143 | ** is non-negative, then as many bytes (not characters) of the text | 6350 | ** is non-negative, then as many bytes (not characters) of the text |
| 6144 | ** pointed to by the 2nd parameter are taken as the application-defined | 6351 | ** pointed to by the 2nd parameter are taken as the application-defined |
| @@ -6412,6 +6619,13 @@ SQLITE_API void sqlite3_activate_cerod( | |||
| 6412 | ** of the default VFS is not implemented correctly, or not implemented at | 6619 | ** of the default VFS is not implemented correctly, or not implemented at |
| 6413 | ** all, then the behavior of sqlite3_sleep() may deviate from the description | 6620 | ** all, then the behavior of sqlite3_sleep() may deviate from the description |
| 6414 | ** in the previous paragraphs. | 6621 | ** in the previous paragraphs. |
| 6622 | ** | ||
| 6623 | ** If a negative argument is passed to sqlite3_sleep() the results vary by | ||
| 6624 | ** VFS and operating system. Some system treat a negative argument as an | ||
| 6625 | ** instruction to sleep forever. Others understand it to mean do not sleep | ||
| 6626 | ** at all. ^In SQLite version 3.42.0 and later, a negative | ||
| 6627 | ** argument passed into sqlite3_sleep() is changed to zero before it is relayed | ||
| 6628 | ** down into the xSleep method of the VFS. | ||
| 6415 | */ | 6629 | */ |
| 6416 | SQLITE_API int sqlite3_sleep(int); | 6630 | SQLITE_API int sqlite3_sleep(int); |
| 6417 | 6631 | ||
| @@ -6634,7 +6848,7 @@ SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N); | |||
| 6634 | ** <li> [sqlite3_filename_wal()] | 6848 | ** <li> [sqlite3_filename_wal()] |
| 6635 | ** </ul> | 6849 | ** </ul> |
| 6636 | */ | 6850 | */ |
| 6637 | SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); | 6851 | SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName); |
| 6638 | 6852 | ||
| 6639 | /* | 6853 | /* |
| 6640 | ** CAPI3REF: Determine if a database is read-only | 6854 | ** CAPI3REF: Determine if a database is read-only |
| @@ -6771,7 +6985,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); | |||
| 6771 | ** function C that is invoked prior to each autovacuum of the database | 6985 | ** function C that is invoked prior to each autovacuum of the database |
| 6772 | ** file. ^The callback is passed a copy of the generic data pointer (P), | 6986 | ** file. ^The callback is passed a copy of the generic data pointer (P), |
| 6773 | ** the schema-name of the attached database that is being autovacuumed, | 6987 | ** the schema-name of the attached database that is being autovacuumed, |
| 6774 | ** the the size of the database file in pages, the number of free pages, | 6988 | ** the size of the database file in pages, the number of free pages, |
| 6775 | ** and the number of bytes per page, respectively. The callback should | 6989 | ** and the number of bytes per page, respectively. The callback should |
| 6776 | ** return the number of free pages that should be removed by the | 6990 | ** return the number of free pages that should be removed by the |
| 6777 | ** autovacuum. ^If the callback returns zero, then no autovacuum happens. | 6991 | ** autovacuum. ^If the callback returns zero, then no autovacuum happens. |
| @@ -6892,6 +7106,11 @@ SQLITE_API void *sqlite3_update_hook( | |||
| 6892 | ** to the same database. Sharing is enabled if the argument is true | 7106 | ** to the same database. Sharing is enabled if the argument is true |
| 6893 | ** and disabled if the argument is false.)^ | 7107 | ** and disabled if the argument is false.)^ |
| 6894 | ** | 7108 | ** |
| 7109 | ** This interface is omitted if SQLite is compiled with | ||
| 7110 | ** [-DSQLITE_OMIT_SHARED_CACHE]. The [-DSQLITE_OMIT_SHARED_CACHE] | ||
| 7111 | ** compile-time option is recommended because the | ||
| 7112 | ** [use of shared cache mode is discouraged]. | ||
| 7113 | ** | ||
| 6895 | ** ^Cache sharing is enabled and disabled for an entire process. | 7114 | ** ^Cache sharing is enabled and disabled for an entire process. |
| 6896 | ** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). | 7115 | ** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). |
| 6897 | ** In prior versions of SQLite, | 7116 | ** In prior versions of SQLite, |
| @@ -6990,7 +7209,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); | |||
| 6990 | ** ^The soft heap limit may not be greater than the hard heap limit. | 7209 | ** ^The soft heap limit may not be greater than the hard heap limit. |
| 6991 | ** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) | 7210 | ** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) |
| 6992 | ** is invoked with a value of N that is greater than the hard heap limit, | 7211 | ** is invoked with a value of N that is greater than the hard heap limit, |
| 6993 | ** the the soft heap limit is set to the value of the hard heap limit. | 7212 | ** the soft heap limit is set to the value of the hard heap limit. |
| 6994 | ** ^The soft heap limit is automatically enabled whenever the hard heap | 7213 | ** ^The soft heap limit is automatically enabled whenever the hard heap |
| 6995 | ** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and | 7214 | ** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and |
| 6996 | ** the soft heap limit is outside the range of 1..N, then the soft heap | 7215 | ** the soft heap limit is outside the range of 1..N, then the soft heap |
| @@ -7252,15 +7471,6 @@ SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); | |||
| 7252 | SQLITE_API void sqlite3_reset_auto_extension(void); | 7471 | SQLITE_API void sqlite3_reset_auto_extension(void); |
| 7253 | 7472 | ||
| 7254 | /* | 7473 | /* |
| 7255 | ** The interface to the virtual-table mechanism is currently considered | ||
| 7256 | ** to be experimental. The interface might change in incompatible ways. | ||
| 7257 | ** If this is a problem for you, do not use the interface at this time. | ||
| 7258 | ** | ||
| 7259 | ** When the virtual-table mechanism stabilizes, we will declare the | ||
| 7260 | ** interface fixed, support it indefinitely, and remove this comment. | ||
| 7261 | */ | ||
| 7262 | |||
| 7263 | /* | ||
| 7264 | ** Structures used by the virtual table interface | 7474 | ** Structures used by the virtual table interface |
| 7265 | */ | 7475 | */ |
| 7266 | typedef struct sqlite3_vtab sqlite3_vtab; | 7476 | typedef struct sqlite3_vtab sqlite3_vtab; |
| @@ -7378,10 +7588,10 @@ struct sqlite3_module { | |||
| 7378 | ** when the omit flag is true there is no guarantee that the constraint will | 7588 | ** when the omit flag is true there is no guarantee that the constraint will |
| 7379 | ** not be checked again using byte code.)^ | 7589 | ** not be checked again using byte code.)^ |
| 7380 | ** | 7590 | ** |
| 7381 | ** ^The idxNum and idxPtr values are recorded and passed into the | 7591 | ** ^The idxNum and idxStr values are recorded and passed into the |
| 7382 | ** [xFilter] method. | 7592 | ** [xFilter] method. |
| 7383 | ** ^[sqlite3_free()] is used to free idxPtr if and only if | 7593 | ** ^[sqlite3_free()] is used to free idxStr if and only if |
| 7384 | ** needToFreeIdxPtr is true. | 7594 | ** needToFreeIdxStr is true. |
| 7385 | ** | 7595 | ** |
| 7386 | ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in | 7596 | ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in |
| 7387 | ** the correct order to satisfy the ORDER BY clause so that no separate | 7597 | ** the correct order to satisfy the ORDER BY clause so that no separate |
| @@ -7501,7 +7711,7 @@ struct sqlite3_index_info { | |||
| 7501 | ** the [sqlite3_vtab_collation()] interface. For most real-world virtual | 7711 | ** the [sqlite3_vtab_collation()] interface. For most real-world virtual |
| 7502 | ** tables, the collating sequence of constraints does not matter (for example | 7712 | ** tables, the collating sequence of constraints does not matter (for example |
| 7503 | ** because the constraints are numeric) and so the sqlite3_vtab_collation() | 7713 | ** because the constraints are numeric) and so the sqlite3_vtab_collation() |
| 7504 | ** interface is no commonly needed. | 7714 | ** interface is not commonly needed. |
| 7505 | */ | 7715 | */ |
| 7506 | #define SQLITE_INDEX_CONSTRAINT_EQ 2 | 7716 | #define SQLITE_INDEX_CONSTRAINT_EQ 2 |
| 7507 | #define SQLITE_INDEX_CONSTRAINT_GT 4 | 7717 | #define SQLITE_INDEX_CONSTRAINT_GT 4 |
| @@ -7661,16 +7871,6 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); | |||
| 7661 | SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); | 7871 | SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); |
| 7662 | 7872 | ||
| 7663 | /* | 7873 | /* |
| 7664 | ** The interface to the virtual-table mechanism defined above (back up | ||
| 7665 | ** to a comment remarkably similar to this one) is currently considered | ||
| 7666 | ** to be experimental. The interface might change in incompatible ways. | ||
| 7667 | ** If this is a problem for you, do not use the interface at this time. | ||
| 7668 | ** | ||
| 7669 | ** When the virtual-table mechanism stabilizes, we will declare the | ||
| 7670 | ** interface fixed, support it indefinitely, and remove this comment. | ||
| 7671 | */ | ||
| 7672 | |||
| 7673 | /* | ||
| 7674 | ** CAPI3REF: A Handle To An Open BLOB | 7874 | ** CAPI3REF: A Handle To An Open BLOB |
| 7675 | ** KEYWORDS: {BLOB handle} {BLOB handles} | 7875 | ** KEYWORDS: {BLOB handle} {BLOB handles} |
| 7676 | ** | 7876 | ** |
| @@ -8053,9 +8253,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); | |||
| 8053 | ** is undefined if the mutex is not currently entered by the | 8253 | ** is undefined if the mutex is not currently entered by the |
| 8054 | ** calling thread or is not currently allocated. | 8254 | ** calling thread or is not currently allocated. |
| 8055 | ** | 8255 | ** |
| 8056 | ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or | 8256 | ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), |
| 8057 | ** sqlite3_mutex_leave() is a NULL pointer, then all three routines | 8257 | ** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer, |
| 8058 | ** behave as no-ops. | 8258 | ** then any of the four routines behaves as a no-op. |
| 8059 | ** | 8259 | ** |
| 8060 | ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. | 8260 | ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. |
| 8061 | */ | 8261 | */ |
| @@ -8325,7 +8525,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); | |||
| 8325 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 | 8525 | #define SQLITE_TESTCTRL_TRACEFLAGS 31 |
| 8326 | #define SQLITE_TESTCTRL_TUNE 32 | 8526 | #define SQLITE_TESTCTRL_TUNE 32 |
| 8327 | #define SQLITE_TESTCTRL_LOGEST 33 | 8527 | #define SQLITE_TESTCTRL_LOGEST 33 |
| 8328 | #define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ | 8528 | #define SQLITE_TESTCTRL_USELONGDOUBLE 34 |
| 8529 | #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ | ||
| 8329 | 8530 | ||
| 8330 | /* | 8531 | /* |
| 8331 | ** CAPI3REF: SQL Keyword Checking | 8532 | ** CAPI3REF: SQL Keyword Checking |
| @@ -9285,7 +9486,7 @@ typedef struct sqlite3_backup sqlite3_backup; | |||
| 9285 | ** if the application incorrectly accesses the destination [database connection] | 9486 | ** if the application incorrectly accesses the destination [database connection] |
| 9286 | ** and so no error code is reported, but the operations may malfunction | 9487 | ** and so no error code is reported, but the operations may malfunction |
| 9287 | ** nevertheless. Use of the destination database connection while a | 9488 | ** nevertheless. Use of the destination database connection while a |
| 9288 | ** backup is in progress might also also cause a mutex deadlock. | 9489 | ** backup is in progress might also cause a mutex deadlock. |
| 9289 | ** | 9490 | ** |
| 9290 | ** If running in [shared cache mode], the application must | 9491 | ** If running in [shared cache mode], the application must |
| 9291 | ** guarantee that the shared cache used by the destination database | 9492 | ** guarantee that the shared cache used by the destination database |
| @@ -9357,8 +9558,8 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); | |||
| 9357 | ** blocked connection already has a registered unlock-notify callback, | 9558 | ** blocked connection already has a registered unlock-notify callback, |
| 9358 | ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is | 9559 | ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is |
| 9359 | ** called with a NULL pointer as its second argument, then any existing | 9560 | ** called with a NULL pointer as its second argument, then any existing |
| 9360 | ** unlock-notify callback is canceled. ^The blocked connections | 9561 | ** unlock-notify callback is cancelled. ^The blocked connections |
| 9361 | ** unlock-notify callback may also be canceled by closing the blocked | 9562 | ** unlock-notify callback may also be cancelled by closing the blocked |
| 9362 | ** connection using [sqlite3_close()]. | 9563 | ** connection using [sqlite3_close()]. |
| 9363 | ** | 9564 | ** |
| 9364 | ** The unlock-notify callback is not reentrant. If an application invokes | 9565 | ** The unlock-notify callback is not reentrant. If an application invokes |
| @@ -9713,7 +9914,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( | |||
| 9713 | */ | 9914 | */ |
| 9714 | #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ | 9915 | #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ |
| 9715 | #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ | 9916 | #define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ |
| 9716 | #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */ | 9917 | #define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */ |
| 9717 | #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ | 9918 | #define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ |
| 9718 | 9919 | ||
| 9719 | /* | 9920 | /* |
| @@ -9781,7 +9982,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); | |||
| 9781 | ** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt> | 9982 | ** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt> |
| 9782 | ** <dd>Calls of the form | 9983 | ** <dd>Calls of the form |
| 9783 | ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the | 9984 | ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the |
| 9784 | ** the [xConnect] or [xCreate] methods of a [virtual table] implmentation | 9985 | ** the [xConnect] or [xCreate] methods of a [virtual table] implementation |
| 9785 | ** prohibits that virtual table from being used from within triggers and | 9986 | ** prohibits that virtual table from being used from within triggers and |
| 9786 | ** views. | 9987 | ** views. |
| 9787 | ** </dd> | 9988 | ** </dd> |
| @@ -9789,18 +9990,28 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); | |||
| 9789 | ** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt> | 9990 | ** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt> |
| 9790 | ** <dd>Calls of the form | 9991 | ** <dd>Calls of the form |
| 9791 | ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the | 9992 | ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the |
| 9792 | ** the [xConnect] or [xCreate] methods of a [virtual table] implmentation | 9993 | ** the [xConnect] or [xCreate] methods of a [virtual table] implementation |
| 9793 | ** identify that virtual table as being safe to use from within triggers | 9994 | ** identify that virtual table as being safe to use from within triggers |
| 9794 | ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the | 9995 | ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the |
| 9795 | ** virtual table can do no serious harm even if it is controlled by a | 9996 | ** virtual table can do no serious harm even if it is controlled by a |
| 9796 | ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS | 9997 | ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS |
| 9797 | ** flag unless absolutely necessary. | 9998 | ** flag unless absolutely necessary. |
| 9798 | ** </dd> | 9999 | ** </dd> |
| 10000 | ** | ||
| 10001 | ** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]<dt>SQLITE_VTAB_USES_ALL_SCHEMAS</dt> | ||
| 10002 | ** <dd>Calls of the form | ||
| 10003 | ** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the | ||
| 10004 | ** the [xConnect] or [xCreate] methods of a [virtual table] implementation | ||
| 10005 | ** instruct the query planner to begin at least a read transaction on | ||
| 10006 | ** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the | ||
| 10007 | ** virtual table is used. | ||
| 10008 | ** </dd> | ||
| 9799 | ** </dl> | 10009 | ** </dl> |
| 9800 | */ | 10010 | */ |
| 9801 | #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 | 10011 | #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 |
| 9802 | #define SQLITE_VTAB_INNOCUOUS 2 | 10012 | #define SQLITE_VTAB_INNOCUOUS 2 |
| 9803 | #define SQLITE_VTAB_DIRECTONLY 3 | 10013 | #define SQLITE_VTAB_DIRECTONLY 3 |
| 10014 | #define SQLITE_VTAB_USES_ALL_SCHEMAS 4 | ||
| 9804 | 10015 | ||
| 9805 | /* | 10016 | /* |
| 9806 | ** CAPI3REF: Determine The Virtual Table Conflict Policy | 10017 | ** CAPI3REF: Determine The Virtual Table Conflict Policy |
| @@ -9873,7 +10084,7 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); | |||
| 9873 | ** <li><p> Otherwise, "BINARY" is returned. | 10084 | ** <li><p> Otherwise, "BINARY" is returned. |
| 9874 | ** </ol> | 10085 | ** </ol> |
| 9875 | */ | 10086 | */ |
| 9876 | SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); | 10087 | SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); |
| 9877 | 10088 | ||
| 9878 | /* | 10089 | /* |
| 9879 | ** CAPI3REF: Determine if a virtual table query is DISTINCT | 10090 | ** CAPI3REF: Determine if a virtual table query is DISTINCT |
| @@ -9961,7 +10172,7 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); | |||
| 9961 | ** communicated to the xBestIndex method as a | 10172 | ** communicated to the xBestIndex method as a |
| 9962 | ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use | 10173 | ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use |
| 9963 | ** this constraint, it must set the corresponding | 10174 | ** this constraint, it must set the corresponding |
| 9964 | ** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under | 10175 | ** aConstraintUsage[].argvIndex to a positive integer. ^(Then, under |
| 9965 | ** the usual mode of handling IN operators, SQLite generates [bytecode] | 10176 | ** the usual mode of handling IN operators, SQLite generates [bytecode] |
| 9966 | ** that invokes the [xFilter|xFilter() method] once for each value | 10177 | ** that invokes the [xFilter|xFilter() method] once for each value |
| 9967 | ** on the right-hand side of the IN operator.)^ Thus the virtual table | 10178 | ** on the right-hand side of the IN operator.)^ Thus the virtual table |
| @@ -10030,21 +10241,20 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); | |||
| 10030 | ** is undefined and probably harmful. | 10241 | ** is undefined and probably harmful. |
| 10031 | ** | 10242 | ** |
| 10032 | ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or | 10243 | ** The X parameter in a call to sqlite3_vtab_in_first(X,P) or |
| 10033 | ** sqlite3_vtab_in_next(X,P) must be one of the parameters to the | 10244 | ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the |
| 10034 | ** xFilter method which invokes these routines, and specifically | 10245 | ** xFilter method which invokes these routines, and specifically |
| 10035 | ** a parameter that was previously selected for all-at-once IN constraint | 10246 | ** a parameter that was previously selected for all-at-once IN constraint |
| 10036 | ** processing use the [sqlite3_vtab_in()] interface in the | 10247 | ** processing use the [sqlite3_vtab_in()] interface in the |
| 10037 | ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not | 10248 | ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not |
| 10038 | ** an xFilter argument that was selected for all-at-once IN constraint | 10249 | ** an xFilter argument that was selected for all-at-once IN constraint |
| 10039 | ** processing, then these routines return [SQLITE_MISUSE])^ or perhaps | 10250 | ** processing, then these routines return [SQLITE_ERROR].)^ |
| 10040 | ** exhibit some other undefined or harmful behavior. | ||
| 10041 | ** | 10251 | ** |
| 10042 | ** ^(Use these routines to access all values on the right-hand side | 10252 | ** ^(Use these routines to access all values on the right-hand side |
| 10043 | ** of the IN constraint using code like the following: | 10253 | ** of the IN constraint using code like the following: |
| 10044 | ** | 10254 | ** |
| 10045 | ** <blockquote><pre> | 10255 | ** <blockquote><pre> |
| 10046 | ** for(rc=sqlite3_vtab_in_first(pList, &pVal); | 10256 | ** for(rc=sqlite3_vtab_in_first(pList, &pVal); |
| 10047 | ** rc==SQLITE_OK && pVal | 10257 | ** rc==SQLITE_OK && pVal; |
| 10048 | ** rc=sqlite3_vtab_in_next(pList, &pVal) | 10258 | ** rc=sqlite3_vtab_in_next(pList, &pVal) |
| 10049 | ** ){ | 10259 | ** ){ |
| 10050 | ** // do something with pVal | 10260 | ** // do something with pVal |
| @@ -10142,6 +10352,10 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** | |||
| 10142 | ** managed by the prepared statement S and will be automatically freed when | 10352 | ** managed by the prepared statement S and will be automatically freed when |
| 10143 | ** S is finalized. | 10353 | ** S is finalized. |
| 10144 | ** | 10354 | ** |
| 10355 | ** Not all values are available for all query elements. When a value is | ||
| 10356 | ** not available, the output variable is set to -1 if the value is numeric, | ||
| 10357 | ** or to NULL if it is a string (SQLITE_SCANSTAT_NAME). | ||
| 10358 | ** | ||
| 10145 | ** <dl> | 10359 | ** <dl> |
| 10146 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> | 10360 | ** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt> |
| 10147 | ** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be | 10361 | ** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be |
| @@ -10169,12 +10383,24 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** | |||
| 10169 | ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] | 10383 | ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] |
| 10170 | ** description for the X-th loop. | 10384 | ** description for the X-th loop. |
| 10171 | ** | 10385 | ** |
| 10172 | ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt> | 10386 | ** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECTID</dt> |
| 10173 | ** <dd>^The "int" variable pointed to by the V parameter will be set to the | 10387 | ** <dd>^The "int" variable pointed to by the V parameter will be set to the |
| 10174 | ** "select-id" for the X-th loop. The select-id identifies which query or | 10388 | ** id for the X-th query plan element. The id value is unique within the |
| 10175 | ** subquery the loop is part of. The main query has a select-id of zero. | 10389 | ** statement. The select-id is the same value as is output in the first |
| 10176 | ** The select-id is the same value as is output in the first column | 10390 | ** column of an [EXPLAIN QUERY PLAN] query. |
| 10177 | ** of an [EXPLAIN QUERY PLAN] query. | 10391 | ** |
| 10392 | ** [[SQLITE_SCANSTAT_PARENTID]] <dt>SQLITE_SCANSTAT_PARENTID</dt> | ||
| 10393 | ** <dd>The "int" variable pointed to by the V parameter will be set to the | ||
| 10394 | ** the id of the parent of the current query element, if applicable, or | ||
| 10395 | ** to zero if the query element has no parent. This is the same value as | ||
| 10396 | ** returned in the second column of an [EXPLAIN QUERY PLAN] query. | ||
| 10397 | ** | ||
| 10398 | ** [[SQLITE_SCANSTAT_NCYCLE]] <dt>SQLITE_SCANSTAT_NCYCLE</dt> | ||
| 10399 | ** <dd>The sqlite3_int64 output value is set to the number of cycles, | ||
| 10400 | ** according to the processor time-stamp counter, that elapsed while the | ||
| 10401 | ** query element was being processed. This value is not available for | ||
| 10402 | ** all query elements - if it is unavailable the output variable is | ||
| 10403 | ** set to -1. | ||
| 10178 | ** </dl> | 10404 | ** </dl> |
| 10179 | */ | 10405 | */ |
| 10180 | #define SQLITE_SCANSTAT_NLOOP 0 | 10406 | #define SQLITE_SCANSTAT_NLOOP 0 |
| @@ -10183,12 +10409,14 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** | |||
| 10183 | #define SQLITE_SCANSTAT_NAME 3 | 10409 | #define SQLITE_SCANSTAT_NAME 3 |
| 10184 | #define SQLITE_SCANSTAT_EXPLAIN 4 | 10410 | #define SQLITE_SCANSTAT_EXPLAIN 4 |
| 10185 | #define SQLITE_SCANSTAT_SELECTID 5 | 10411 | #define SQLITE_SCANSTAT_SELECTID 5 |
| 10412 | #define SQLITE_SCANSTAT_PARENTID 6 | ||
| 10413 | #define SQLITE_SCANSTAT_NCYCLE 7 | ||
| 10186 | 10414 | ||
| 10187 | /* | 10415 | /* |
| 10188 | ** CAPI3REF: Prepared Statement Scan Status | 10416 | ** CAPI3REF: Prepared Statement Scan Status |
| 10189 | ** METHOD: sqlite3_stmt | 10417 | ** METHOD: sqlite3_stmt |
| 10190 | ** | 10418 | ** |
| 10191 | ** This interface returns information about the predicted and measured | 10419 | ** These interfaces return information about the predicted and measured |
| 10192 | ** performance for pStmt. Advanced applications can use this | 10420 | ** performance for pStmt. Advanced applications can use this |
| 10193 | ** interface to compare the predicted and the measured performance and | 10421 | ** interface to compare the predicted and the measured performance and |
| 10194 | ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. | 10422 | ** issue warnings and/or rerun [ANALYZE] if discrepancies are found. |
| @@ -10199,19 +10427,25 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** | |||
| 10199 | ** | 10427 | ** |
| 10200 | ** The "iScanStatusOp" parameter determines which status information to return. | 10428 | ** The "iScanStatusOp" parameter determines which status information to return. |
| 10201 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior | 10429 | ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior |
| 10202 | ** of this interface is undefined. | 10430 | ** of this interface is undefined. ^The requested measurement is written into |
| 10203 | ** ^The requested measurement is written into a variable pointed to by | 10431 | ** a variable pointed to by the "pOut" parameter. |
| 10204 | ** the "pOut" parameter. | 10432 | ** |
| 10205 | ** Parameter "idx" identifies the specific loop to retrieve statistics for. | 10433 | ** The "flags" parameter must be passed a mask of flags. At present only |
| 10206 | ** Loops are numbered starting from zero. ^If idx is out of range - less than | 10434 | ** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX |
| 10207 | ** zero or greater than or equal to the total number of loops used to implement | 10435 | ** is specified, then status information is available for all elements |
| 10208 | ** the statement - a non-zero value is returned and the variable that pOut | 10436 | ** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If |
| 10209 | ** points to is unchanged. | 10437 | ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements |
| 10210 | ** | 10438 | ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of |
| 10211 | ** ^Statistics might not be available for all loops in all statements. ^In cases | 10439 | ** the EXPLAIN QUERY PLAN output) are available. Invoking API |
| 10212 | ** where there exist loops with no available statistics, this function behaves | 10440 | ** sqlite3_stmt_scanstatus() is equivalent to calling |
| 10213 | ** as if the loop did not exist - it returns non-zero and leave the variable | 10441 | ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. |
| 10214 | ** that pOut points to unchanged. | 10442 | ** |
| 10443 | ** Parameter "idx" identifies the specific query element to retrieve statistics | ||
| 10444 | ** for. Query elements are numbered starting from zero. A value of -1 may be | ||
| 10445 | ** to query for statistics regarding the entire query. ^If idx is out of range | ||
| 10446 | ** - less than -1 or greater than or equal to the total number of query | ||
| 10447 | ** elements used to implement the statement - a non-zero value is returned and | ||
| 10448 | ** the variable that pOut points to is unchanged. | ||
| 10215 | ** | 10449 | ** |
| 10216 | ** See also: [sqlite3_stmt_scanstatus_reset()] | 10450 | ** See also: [sqlite3_stmt_scanstatus_reset()] |
| 10217 | */ | 10451 | */ |
| @@ -10221,6 +10455,19 @@ SQLITE_API int sqlite3_stmt_scanstatus( | |||
| 10221 | int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ | 10455 | int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ |
| 10222 | void *pOut /* Result written here */ | 10456 | void *pOut /* Result written here */ |
| 10223 | ); | 10457 | ); |
| 10458 | SQLITE_API int sqlite3_stmt_scanstatus_v2( | ||
| 10459 | sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ | ||
| 10460 | int idx, /* Index of loop to report on */ | ||
| 10461 | int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ | ||
| 10462 | int flags, /* Mask of flags defined below */ | ||
| 10463 | void *pOut /* Result written here */ | ||
| 10464 | ); | ||
| 10465 | |||
| 10466 | /* | ||
| 10467 | ** CAPI3REF: Prepared Statement Scan Status | ||
| 10468 | ** KEYWORDS: {scan status flags} | ||
| 10469 | */ | ||
| 10470 | #define SQLITE_SCANSTAT_COMPLEX 0x0001 | ||
| 10224 | 10471 | ||
| 10225 | /* | 10472 | /* |
| 10226 | ** CAPI3REF: Zero Scan-Status Counters | 10473 | ** CAPI3REF: Zero Scan-Status Counters |
| @@ -10311,6 +10558,10 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); | |||
| 10311 | ** function is not defined for operations on WITHOUT ROWID tables, or for | 10558 | ** function is not defined for operations on WITHOUT ROWID tables, or for |
| 10312 | ** DELETE operations on rowid tables. | 10559 | ** DELETE operations on rowid tables. |
| 10313 | ** | 10560 | ** |
| 10561 | ** ^The sqlite3_preupdate_hook(D,C,P) function returns the P argument from | ||
| 10562 | ** the previous call on the same [database connection] D, or NULL for | ||
| 10563 | ** the first call on D. | ||
| 10564 | ** | ||
| 10314 | ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], | 10565 | ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], |
| 10315 | ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces | 10566 | ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces |
| 10316 | ** provide additional information about a preupdate event. These routines | 10567 | ** provide additional information about a preupdate event. These routines |
| @@ -10350,7 +10601,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); | |||
| 10350 | ** When the [sqlite3_blob_write()] API is used to update a blob column, | 10601 | ** When the [sqlite3_blob_write()] API is used to update a blob column, |
| 10351 | ** the pre-update hook is invoked with SQLITE_DELETE. This is because the | 10602 | ** the pre-update hook is invoked with SQLITE_DELETE. This is because the |
| 10352 | ** in this case the new values are not available. In this case, when a | 10603 | ** in this case the new values are not available. In this case, when a |
| 10353 | ** callback made with op==SQLITE_DELETE is actuall a write using the | 10604 | ** callback made with op==SQLITE_DELETE is actually a write using the |
| 10354 | ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns | 10605 | ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns |
| 10355 | ** the index of the column being written. In other cases, where the | 10606 | ** the index of the column being written. In other cases, where the |
| 10356 | ** pre-update hook is being invoked for some other reason, including a | 10607 | ** pre-update hook is being invoked for some other reason, including a |
| @@ -10716,6 +10967,19 @@ SQLITE_API int sqlite3_deserialize( | |||
| 10716 | # undef double | 10967 | # undef double |
| 10717 | #endif | 10968 | #endif |
| 10718 | 10969 | ||
| 10970 | #if defined(__wasi__) | ||
| 10971 | # undef SQLITE_WASI | ||
| 10972 | # define SQLITE_WASI 1 | ||
| 10973 | # undef SQLITE_OMIT_WAL | ||
| 10974 | # define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ | ||
| 10975 | # ifndef SQLITE_OMIT_LOAD_EXTENSION | ||
| 10976 | # define SQLITE_OMIT_LOAD_EXTENSION | ||
| 10977 | # endif | ||
| 10978 | # ifndef SQLITE_THREADSAFE | ||
| 10979 | # define SQLITE_THREADSAFE 0 | ||
| 10980 | # endif | ||
| 10981 | #endif | ||
| 10982 | |||
| 10719 | #if 0 | 10983 | #if 0 |
| 10720 | } /* End of the 'extern "C"' block */ | 10984 | } /* End of the 'extern "C"' block */ |
| 10721 | #endif | 10985 | #endif |
| @@ -10922,16 +11186,20 @@ SQLITE_API int sqlite3session_create( | |||
| 10922 | SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); | 11186 | SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); |
| 10923 | 11187 | ||
| 10924 | /* | 11188 | /* |
| 10925 | ** CAPIREF: Conigure a Session Object | 11189 | ** CAPI3REF: Configure a Session Object |
| 10926 | ** METHOD: sqlite3_session | 11190 | ** METHOD: sqlite3_session |
| 10927 | ** | 11191 | ** |
| 10928 | ** This method is used to configure a session object after it has been | 11192 | ** This method is used to configure a session object after it has been |
| 10929 | ** created. At present the only valid value for the second parameter is | 11193 | ** created. At present the only valid values for the second parameter are |
| 10930 | ** [SQLITE_SESSION_OBJCONFIG_SIZE]. | 11194 | ** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID]. |
| 10931 | ** | 11195 | ** |
| 10932 | ** Arguments for sqlite3session_object_config() | 11196 | */ |
| 11197 | SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); | ||
| 11198 | |||
| 11199 | /* | ||
| 11200 | ** CAPI3REF: Options for sqlite3session_object_config | ||
| 10933 | ** | 11201 | ** |
| 10934 | ** The following values may passed as the the 4th parameter to | 11202 | ** The following values may passed as the the 2nd parameter to |
| 10935 | ** sqlite3session_object_config(). | 11203 | ** sqlite3session_object_config(). |
| 10936 | ** | 11204 | ** |
| 10937 | ** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd> | 11205 | ** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd> |
| @@ -10947,12 +11215,21 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); | |||
| 10947 | ** | 11215 | ** |
| 10948 | ** It is an error (SQLITE_MISUSE) to attempt to modify this setting after | 11216 | ** It is an error (SQLITE_MISUSE) to attempt to modify this setting after |
| 10949 | ** the first table has been attached to the session object. | 11217 | ** the first table has been attached to the session object. |
| 11218 | ** | ||
| 11219 | ** <dt>SQLITE_SESSION_OBJCONFIG_ROWID <dd> | ||
| 11220 | ** This option is used to set, clear or query the flag that enables | ||
| 11221 | ** collection of data for tables with no explicit PRIMARY KEY. | ||
| 11222 | ** | ||
| 11223 | ** Normally, tables with no explicit PRIMARY KEY are simply ignored | ||
| 11224 | ** by the sessions module. However, if this flag is set, it behaves | ||
| 11225 | ** as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted | ||
| 11226 | ** as their leftmost columns. | ||
| 11227 | ** | ||
| 11228 | ** It is an error (SQLITE_MISUSE) to attempt to modify this setting after | ||
| 11229 | ** the first table has been attached to the session object. | ||
| 10950 | */ | 11230 | */ |
| 10951 | SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); | 11231 | #define SQLITE_SESSION_OBJCONFIG_SIZE 1 |
| 10952 | 11232 | #define SQLITE_SESSION_OBJCONFIG_ROWID 2 | |
| 10953 | /* | ||
| 10954 | */ | ||
| 10955 | #define SQLITE_SESSION_OBJCONFIG_SIZE 1 | ||
| 10956 | 11233 | ||
| 10957 | /* | 11234 | /* |
| 10958 | ** CAPI3REF: Enable Or Disable A Session Object | 11235 | ** CAPI3REF: Enable Or Disable A Session Object |
| @@ -12085,9 +12362,23 @@ SQLITE_API int sqlite3changeset_apply_v2( | |||
| 12085 | ** Invert the changeset before applying it. This is equivalent to inverting | 12362 | ** Invert the changeset before applying it. This is equivalent to inverting |
| 12086 | ** a changeset using sqlite3changeset_invert() before applying it. It is | 12363 | ** a changeset using sqlite3changeset_invert() before applying it. It is |
| 12087 | ** an error to specify this flag with a patchset. | 12364 | ** an error to specify this flag with a patchset. |
| 12365 | ** | ||
| 12366 | ** <dt>SQLITE_CHANGESETAPPLY_IGNORENOOP <dd> | ||
| 12367 | ** Do not invoke the conflict handler callback for any changes that | ||
| 12368 | ** would not actually modify the database even if they were applied. | ||
| 12369 | ** Specifically, this means that the conflict handler is not invoked | ||
| 12370 | ** for: | ||
| 12371 | ** <ul> | ||
| 12372 | ** <li>a delete change if the row being deleted cannot be found, | ||
| 12373 | ** <li>an update change if the modified fields are already set to | ||
| 12374 | ** their new values in the conflicting row, or | ||
| 12375 | ** <li>an insert change if all fields of the conflicting row match | ||
| 12376 | ** the row being inserted. | ||
| 12377 | ** </ul> | ||
| 12088 | */ | 12378 | */ |
| 12089 | #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 | 12379 | #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 |
| 12090 | #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 | 12380 | #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 |
| 12381 | #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 | ||
| 12091 | 12382 | ||
| 12092 | /* | 12383 | /* |
| 12093 | ** CAPI3REF: Constants Passed To The Conflict Handler | 12384 | ** CAPI3REF: Constants Passed To The Conflict Handler |
| @@ -12828,7 +13119,7 @@ struct Fts5PhraseIter { | |||
| 12828 | ** See xPhraseFirstColumn above. | 13119 | ** See xPhraseFirstColumn above. |
| 12829 | */ | 13120 | */ |
| 12830 | struct Fts5ExtensionApi { | 13121 | struct Fts5ExtensionApi { |
| 12831 | int iVersion; /* Currently always set to 3 */ | 13122 | int iVersion; /* Currently always set to 2 */ |
| 12832 | 13123 | ||
| 12833 | void *(*xUserData)(Fts5Context*); | 13124 | void *(*xUserData)(Fts5Context*); |
| 12834 | 13125 | ||
| @@ -13057,8 +13348,8 @@ struct Fts5ExtensionApi { | |||
| 13057 | ** as separate queries of the FTS index are required for each synonym. | 13348 | ** as separate queries of the FTS index are required for each synonym. |
| 13058 | ** | 13349 | ** |
| 13059 | ** When using methods (2) or (3), it is important that the tokenizer only | 13350 | ** When using methods (2) or (3), it is important that the tokenizer only |
| 13060 | ** provide synonyms when tokenizing document text (method (2)) or query | 13351 | ** provide synonyms when tokenizing document text (method (3)) or query |
| 13061 | ** text (method (3)), not both. Doing so will not cause any errors, but is | 13352 | ** text (method (2)), not both. Doing so will not cause any errors, but is |
| 13062 | ** inefficient. | 13353 | ** inefficient. |
| 13063 | */ | 13354 | */ |
| 13064 | typedef struct Fts5Tokenizer Fts5Tokenizer; | 13355 | typedef struct Fts5Tokenizer Fts5Tokenizer; |
| @@ -13106,7 +13397,7 @@ struct fts5_api { | |||
| 13106 | int (*xCreateTokenizer)( | 13397 | int (*xCreateTokenizer)( |
| 13107 | fts5_api *pApi, | 13398 | fts5_api *pApi, |
| 13108 | const char *zName, | 13399 | const char *zName, |
| 13109 | void *pContext, | 13400 | void *pUserData, |
| 13110 | fts5_tokenizer *pTokenizer, | 13401 | fts5_tokenizer *pTokenizer, |
| 13111 | void (*xDestroy)(void*) | 13402 | void (*xDestroy)(void*) |
| 13112 | ); | 13403 | ); |
| @@ -13115,7 +13406,7 @@ struct fts5_api { | |||
| 13115 | int (*xFindTokenizer)( | 13406 | int (*xFindTokenizer)( |
| 13116 | fts5_api *pApi, | 13407 | fts5_api *pApi, |
| 13117 | const char *zName, | 13408 | const char *zName, |
| 13118 | void **ppContext, | 13409 | void **ppUserData, |
| 13119 | fts5_tokenizer *pTokenizer | 13410 | fts5_tokenizer *pTokenizer |
| 13120 | ); | 13411 | ); |
| 13121 | 13412 | ||
| @@ -13123,7 +13414,7 @@ struct fts5_api { | |||
| 13123 | int (*xCreateFunction)( | 13414 | int (*xCreateFunction)( |
| 13124 | fts5_api *pApi, | 13415 | fts5_api *pApi, |
| 13125 | const char *zName, | 13416 | const char *zName, |
| 13126 | void *pContext, | 13417 | void *pUserData, |
| 13127 | fts5_extension_function xFunction, | 13418 | fts5_extension_function xFunction, |
| 13128 | void (*xDestroy)(void*) | 13419 | void (*xDestroy)(void*) |
| 13129 | ); | 13420 | ); |
| @@ -13154,7 +13445,7 @@ struct fts5_api { | |||
| 13154 | ** autoconf-based build | 13445 | ** autoconf-based build |
| 13155 | */ | 13446 | */ |
| 13156 | #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) | 13447 | #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) |
| 13157 | #include "config.h" | 13448 | #include "sqlite_cfg.h" |
| 13158 | #define SQLITECONFIG_H 1 | 13449 | #define SQLITECONFIG_H 1 |
| 13159 | #endif | 13450 | #endif |
| 13160 | 13451 | ||
| @@ -13234,7 +13525,7 @@ struct fts5_api { | |||
| 13234 | ** level of recursion for each term. A stack overflow can result | 13525 | ** level of recursion for each term. A stack overflow can result |
| 13235 | ** if the number of terms is too large. In practice, most SQL | 13526 | ** if the number of terms is too large. In practice, most SQL |
| 13236 | ** never has more than 3 or 4 terms. Use a value of 0 to disable | 13527 | ** never has more than 3 or 4 terms. Use a value of 0 to disable |
| 13237 | ** any limit on the number of terms in a compount SELECT. | 13528 | ** any limit on the number of terms in a compound SELECT. |
| 13238 | */ | 13529 | */ |
| 13239 | #ifndef SQLITE_MAX_COMPOUND_SELECT | 13530 | #ifndef SQLITE_MAX_COMPOUND_SELECT |
| 13240 | # define SQLITE_MAX_COMPOUND_SELECT 500 | 13531 | # define SQLITE_MAX_COMPOUND_SELECT 500 |
| @@ -13384,8 +13675,8 @@ struct fts5_api { | |||
| 13384 | #endif | 13675 | #endif |
| 13385 | 13676 | ||
| 13386 | /* | 13677 | /* |
| 13387 | ** WAL mode depends on atomic aligned 32-bit loads and stores in a few | 13678 | ** A few places in the code require atomic load/store of aligned |
| 13388 | ** places. The following macros try to make this explicit. | 13679 | ** integer values. |
| 13389 | */ | 13680 | */ |
| 13390 | #ifndef __has_extension | 13681 | #ifndef __has_extension |
| 13391 | # define __has_extension(x) 0 /* compatibility with non-clang compilers */ | 13682 | # define __has_extension(x) 0 /* compatibility with non-clang compilers */ |
| @@ -13441,15 +13732,22 @@ struct fts5_api { | |||
| 13441 | #endif | 13732 | #endif |
| 13442 | 13733 | ||
| 13443 | /* | 13734 | /* |
| 13444 | ** A macro to hint to the compiler that a function should not be | 13735 | ** Macros to hint to the compiler that a function should or should not be |
| 13445 | ** inlined. | 13736 | ** inlined. |
| 13446 | */ | 13737 | */ |
| 13447 | #if defined(__GNUC__) | 13738 | #if defined(__GNUC__) |
| 13448 | # define SQLITE_NOINLINE __attribute__((noinline)) | 13739 | # define SQLITE_NOINLINE __attribute__((noinline)) |
| 13740 | # define SQLITE_INLINE __attribute__((always_inline)) inline | ||
| 13449 | #elif defined(_MSC_VER) && _MSC_VER>=1310 | 13741 | #elif defined(_MSC_VER) && _MSC_VER>=1310 |
| 13450 | # define SQLITE_NOINLINE __declspec(noinline) | 13742 | # define SQLITE_NOINLINE __declspec(noinline) |
| 13743 | # define SQLITE_INLINE __forceinline | ||
| 13451 | #else | 13744 | #else |
| 13452 | # define SQLITE_NOINLINE | 13745 | # define SQLITE_NOINLINE |
| 13746 | # define SQLITE_INLINE | ||
| 13747 | #endif | ||
| 13748 | #if defined(SQLITE_COVERAGE_TEST) || defined(__STRICT_ANSI__) | ||
| 13749 | # undef SQLITE_INLINE | ||
| 13750 | # define SQLITE_INLINE | ||
| 13453 | #endif | 13751 | #endif |
| 13454 | 13752 | ||
| 13455 | /* | 13753 | /* |
| @@ -14267,15 +14565,9 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */ | |||
| 14267 | 14565 | ||
| 14268 | /* | 14566 | /* |
| 14269 | ** The datatype used to store estimates of the number of rows in a | 14567 | ** The datatype used to store estimates of the number of rows in a |
| 14270 | ** table or index. This is an unsigned integer type. For 99.9% of | 14568 | ** table or index. |
| 14271 | ** the world, a 32-bit integer is sufficient. But a 64-bit integer | ||
| 14272 | ** can be used at compile-time if desired. | ||
| 14273 | */ | 14569 | */ |
| 14274 | #ifdef SQLITE_64BIT_STATS | 14570 | typedef u64 tRowcnt; |
| 14275 | typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */ | ||
| 14276 | #else | ||
| 14277 | typedef u32 tRowcnt; /* 32-bit is the default */ | ||
| 14278 | #endif | ||
| 14279 | 14571 | ||
| 14280 | /* | 14572 | /* |
| 14281 | ** Estimated quantities used for query planning are stored as 16-bit | 14573 | ** Estimated quantities used for query planning are stored as 16-bit |
| @@ -14336,8 +14628,31 @@ typedef INT16_TYPE LogEst; | |||
| 14336 | ** the end of buffer S. This macro returns true if P points to something | 14628 | ** the end of buffer S. This macro returns true if P points to something |
| 14337 | ** contained within the buffer S. | 14629 | ** contained within the buffer S. |
| 14338 | */ | 14630 | */ |
| 14339 | #define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) | 14631 | #define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) |
| 14340 | 14632 | ||
| 14633 | /* | ||
| 14634 | ** P is one byte past the end of a large buffer. Return true if a span of bytes | ||
| 14635 | ** between S..E crosses the end of that buffer. In other words, return true | ||
| 14636 | ** if the sub-buffer S..E-1 overflows the buffer whose last byte is P-1. | ||
| 14637 | ** | ||
| 14638 | ** S is the start of the span. E is one byte past the end of end of span. | ||
| 14639 | ** | ||
| 14640 | ** P | ||
| 14641 | ** |-----------------| FALSE | ||
| 14642 | ** |-------| | ||
| 14643 | ** S E | ||
| 14644 | ** | ||
| 14645 | ** P | ||
| 14646 | ** |-----------------| | ||
| 14647 | ** |-------| TRUE | ||
| 14648 | ** S E | ||
| 14649 | ** | ||
| 14650 | ** P | ||
| 14651 | ** |-----------------| | ||
| 14652 | ** |-------| FALSE | ||
| 14653 | ** S E | ||
| 14654 | */ | ||
| 14655 | #define SQLITE_OVERFLOW(P,S,E) (((uptr)(S)<(uptr)(P))&&((uptr)(E)>(uptr)(P))) | ||
| 14341 | 14656 | ||
| 14342 | /* | 14657 | /* |
| 14343 | ** Macros to determine whether the machine is big or little endian, | 14658 | ** Macros to determine whether the machine is big or little endian, |
| @@ -14421,9 +14736,9 @@ typedef INT16_TYPE LogEst; | |||
| 14421 | ** pointers. In that case, only verify 4-byte alignment. | 14736 | ** pointers. In that case, only verify 4-byte alignment. |
| 14422 | */ | 14737 | */ |
| 14423 | #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC | 14738 | #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC |
| 14424 | # define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0) | 14739 | # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) |
| 14425 | #else | 14740 | #else |
| 14426 | # define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0) | 14741 | # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) |
| 14427 | #endif | 14742 | #endif |
| 14428 | 14743 | ||
| 14429 | /* | 14744 | /* |
| @@ -14477,15 +14792,38 @@ SQLITE_PRIVATE u32 sqlite3TreeTrace; | |||
| 14477 | && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \ | 14792 | && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \ |
| 14478 | || defined(SQLITE_ENABLE_TREETRACE)) | 14793 | || defined(SQLITE_ENABLE_TREETRACE)) |
| 14479 | # define TREETRACE_ENABLED 1 | 14794 | # define TREETRACE_ENABLED 1 |
| 14480 | # define SELECTTRACE(K,P,S,X) \ | 14795 | # define TREETRACE(K,P,S,X) \ |
| 14481 | if(sqlite3TreeTrace&(K)) \ | 14796 | if(sqlite3TreeTrace&(K)) \ |
| 14482 | sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ | 14797 | sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ |
| 14483 | sqlite3DebugPrintf X | 14798 | sqlite3DebugPrintf X |
| 14484 | #else | 14799 | #else |
| 14485 | # define SELECTTRACE(K,P,S,X) | 14800 | # define TREETRACE(K,P,S,X) |
| 14486 | # define TREETRACE_ENABLED 0 | 14801 | # define TREETRACE_ENABLED 0 |
| 14487 | #endif | 14802 | #endif |
| 14488 | 14803 | ||
| 14804 | /* TREETRACE flag meanings: | ||
| 14805 | ** | ||
| 14806 | ** 0x00000001 Beginning and end of SELECT processing | ||
| 14807 | ** 0x00000002 WHERE clause processing | ||
| 14808 | ** 0x00000004 Query flattener | ||
| 14809 | ** 0x00000008 Result-set wildcard expansion | ||
| 14810 | ** 0x00000010 Query name resolution | ||
| 14811 | ** 0x00000020 Aggregate analysis | ||
| 14812 | ** 0x00000040 Window functions | ||
| 14813 | ** 0x00000080 Generated column names | ||
| 14814 | ** 0x00000100 Move HAVING terms into WHERE | ||
| 14815 | ** 0x00000200 Count-of-view optimization | ||
| 14816 | ** 0x00000400 Compound SELECT processing | ||
| 14817 | ** 0x00000800 Drop superfluous ORDER BY | ||
| 14818 | ** 0x00001000 LEFT JOIN simplifies to JOIN | ||
| 14819 | ** 0x00002000 Constant propagation | ||
| 14820 | ** 0x00004000 Push-down optimization | ||
| 14821 | ** 0x00008000 After all FROM-clause analysis | ||
| 14822 | ** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing | ||
| 14823 | ** 0x00020000 Transform DISTINCT into GROUP BY | ||
| 14824 | ** 0x00040000 SELECT tree dump after all code has been generated | ||
| 14825 | */ | ||
| 14826 | |||
| 14489 | /* | 14827 | /* |
| 14490 | ** Macros for "wheretrace" | 14828 | ** Macros for "wheretrace" |
| 14491 | */ | 14829 | */ |
| @@ -14498,6 +14836,36 @@ SQLITE_PRIVATE u32 sqlite3WhereTrace; | |||
| 14498 | # define WHERETRACE(K,X) | 14836 | # define WHERETRACE(K,X) |
| 14499 | #endif | 14837 | #endif |
| 14500 | 14838 | ||
| 14839 | /* | ||
| 14840 | ** Bits for the sqlite3WhereTrace mask: | ||
| 14841 | ** | ||
| 14842 | ** (---any--) Top-level block structure | ||
| 14843 | ** 0x-------F High-level debug messages | ||
| 14844 | ** 0x----FFF- More detail | ||
| 14845 | ** 0xFFFF---- Low-level debug messages | ||
| 14846 | ** | ||
| 14847 | ** 0x00000001 Code generation | ||
| 14848 | ** 0x00000002 Solver | ||
| 14849 | ** 0x00000004 Solver costs | ||
| 14850 | ** 0x00000008 WhereLoop inserts | ||
| 14851 | ** | ||
| 14852 | ** 0x00000010 Display sqlite3_index_info xBestIndex calls | ||
| 14853 | ** 0x00000020 Range an equality scan metrics | ||
| 14854 | ** 0x00000040 IN operator decisions | ||
| 14855 | ** 0x00000080 WhereLoop cost adjustements | ||
| 14856 | ** 0x00000100 | ||
| 14857 | ** 0x00000200 Covering index decisions | ||
| 14858 | ** 0x00000400 OR optimization | ||
| 14859 | ** 0x00000800 Index scanner | ||
| 14860 | ** 0x00001000 More details associated with code generation | ||
| 14861 | ** 0x00002000 | ||
| 14862 | ** 0x00004000 Show all WHERE terms at key points | ||
| 14863 | ** 0x00008000 Show the full SELECT statement at key places | ||
| 14864 | ** | ||
| 14865 | ** 0x00010000 Show more detail when printing WHERE terms | ||
| 14866 | ** 0x00020000 Show WHERE terms returned from whereScanNext() | ||
| 14867 | */ | ||
| 14868 | |||
| 14501 | 14869 | ||
| 14502 | /* | 14870 | /* |
| 14503 | ** An instance of the following structure is used to store the busy-handler | 14871 | ** An instance of the following structure is used to store the busy-handler |
| @@ -14518,7 +14886,7 @@ struct BusyHandler { | |||
| 14518 | /* | 14886 | /* |
| 14519 | ** Name of table that holds the database schema. | 14887 | ** Name of table that holds the database schema. |
| 14520 | ** | 14888 | ** |
| 14521 | ** The PREFERRED names are used whereever possible. But LEGACY is also | 14889 | ** The PREFERRED names are used wherever possible. But LEGACY is also |
| 14522 | ** used for backwards compatibility. | 14890 | ** used for backwards compatibility. |
| 14523 | ** | 14891 | ** |
| 14524 | ** 1. Queries can use either the PREFERRED or the LEGACY names | 14892 | ** 1. Queries can use either the PREFERRED or the LEGACY names |
| @@ -14632,11 +15000,13 @@ typedef struct Schema Schema; | |||
| 14632 | typedef struct Expr Expr; | 15000 | typedef struct Expr Expr; |
| 14633 | typedef struct ExprList ExprList; | 15001 | typedef struct ExprList ExprList; |
| 14634 | typedef struct FKey FKey; | 15002 | typedef struct FKey FKey; |
| 15003 | typedef struct FpDecode FpDecode; | ||
| 14635 | typedef struct FuncDestructor FuncDestructor; | 15004 | typedef struct FuncDestructor FuncDestructor; |
| 14636 | typedef struct FuncDef FuncDef; | 15005 | typedef struct FuncDef FuncDef; |
| 14637 | typedef struct FuncDefHash FuncDefHash; | 15006 | typedef struct FuncDefHash FuncDefHash; |
| 14638 | typedef struct IdList IdList; | 15007 | typedef struct IdList IdList; |
| 14639 | typedef struct Index Index; | 15008 | typedef struct Index Index; |
| 15009 | typedef struct IndexedExpr IndexedExpr; | ||
| 14640 | typedef struct IndexSample IndexSample; | 15010 | typedef struct IndexSample IndexSample; |
| 14641 | typedef struct KeyClass KeyClass; | 15011 | typedef struct KeyClass KeyClass; |
| 14642 | typedef struct KeyInfo KeyInfo; | 15012 | typedef struct KeyInfo KeyInfo; |
| @@ -14649,6 +15019,7 @@ typedef struct Parse Parse; | |||
| 14649 | typedef struct ParseCleanup ParseCleanup; | 15019 | typedef struct ParseCleanup ParseCleanup; |
| 14650 | typedef struct PreUpdate PreUpdate; | 15020 | typedef struct PreUpdate PreUpdate; |
| 14651 | typedef struct PrintfArguments PrintfArguments; | 15021 | typedef struct PrintfArguments PrintfArguments; |
| 15022 | typedef struct RCStr RCStr; | ||
| 14652 | typedef struct RenameToken RenameToken; | 15023 | typedef struct RenameToken RenameToken; |
| 14653 | typedef struct Returning Returning; | 15024 | typedef struct Returning Returning; |
| 14654 | typedef struct RowSet RowSet; | 15025 | typedef struct RowSet RowSet; |
| @@ -14702,6 +15073,7 @@ typedef struct With With; | |||
| 14702 | #define MASKBIT32(n) (((unsigned int)1)<<(n)) | 15073 | #define MASKBIT32(n) (((unsigned int)1)<<(n)) |
| 14703 | #define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0) | 15074 | #define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0) |
| 14704 | #define ALLBITS ((Bitmask)-1) | 15075 | #define ALLBITS ((Bitmask)-1) |
| 15076 | #define TOPBIT (((Bitmask)1)<<(BMS-1)) | ||
| 14705 | 15077 | ||
| 14706 | /* A VList object records a mapping between parameters/variables/wildcards | 15078 | /* A VList object records a mapping between parameters/variables/wildcards |
| 14707 | ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer | 15079 | ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer |
| @@ -14716,6 +15088,331 @@ typedef int VList; | |||
| 14716 | ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque | 15088 | ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque |
| 14717 | ** pointer types (i.e. FuncDef) defined above. | 15089 | ** pointer types (i.e. FuncDef) defined above. |
| 14718 | */ | 15090 | */ |
| 15091 | /************** Include os.h in the middle of sqliteInt.h ********************/ | ||
| 15092 | /************** Begin file os.h **********************************************/ | ||
| 15093 | /* | ||
| 15094 | ** 2001 September 16 | ||
| 15095 | ** | ||
| 15096 | ** The author disclaims copyright to this source code. In place of | ||
| 15097 | ** a legal notice, here is a blessing: | ||
| 15098 | ** | ||
| 15099 | ** May you do good and not evil. | ||
| 15100 | ** May you find forgiveness for yourself and forgive others. | ||
| 15101 | ** May you share freely, never taking more than you give. | ||
| 15102 | ** | ||
| 15103 | ****************************************************************************** | ||
| 15104 | ** | ||
| 15105 | ** This header file (together with is companion C source-code file | ||
| 15106 | ** "os.c") attempt to abstract the underlying operating system so that | ||
| 15107 | ** the SQLite library will work on both POSIX and windows systems. | ||
| 15108 | ** | ||
| 15109 | ** This header file is #include-ed by sqliteInt.h and thus ends up | ||
| 15110 | ** being included by every source file. | ||
| 15111 | */ | ||
| 15112 | #ifndef _SQLITE_OS_H_ | ||
| 15113 | #define _SQLITE_OS_H_ | ||
| 15114 | |||
| 15115 | /* | ||
| 15116 | ** Attempt to automatically detect the operating system and setup the | ||
| 15117 | ** necessary pre-processor macros for it. | ||
| 15118 | */ | ||
| 15119 | /************** Include os_setup.h in the middle of os.h *********************/ | ||
| 15120 | /************** Begin file os_setup.h ****************************************/ | ||
| 15121 | /* | ||
| 15122 | ** 2013 November 25 | ||
| 15123 | ** | ||
| 15124 | ** The author disclaims copyright to this source code. In place of | ||
| 15125 | ** a legal notice, here is a blessing: | ||
| 15126 | ** | ||
| 15127 | ** May you do good and not evil. | ||
| 15128 | ** May you find forgiveness for yourself and forgive others. | ||
| 15129 | ** May you share freely, never taking more than you give. | ||
| 15130 | ** | ||
| 15131 | ****************************************************************************** | ||
| 15132 | ** | ||
| 15133 | ** This file contains pre-processor directives related to operating system | ||
| 15134 | ** detection and/or setup. | ||
| 15135 | */ | ||
| 15136 | #ifndef SQLITE_OS_SETUP_H | ||
| 15137 | #define SQLITE_OS_SETUP_H | ||
| 15138 | |||
| 15139 | /* | ||
| 15140 | ** Figure out if we are dealing with Unix, Windows, or some other operating | ||
| 15141 | ** system. | ||
| 15142 | ** | ||
| 15143 | ** After the following block of preprocess macros, all of | ||
| 15144 | ** | ||
| 15145 | ** SQLITE_OS_KV | ||
| 15146 | ** SQLITE_OS_OTHER | ||
| 15147 | ** SQLITE_OS_UNIX | ||
| 15148 | ** SQLITE_OS_WIN | ||
| 15149 | ** | ||
| 15150 | ** will defined to either 1 or 0. One of them will be 1. The others will be 0. | ||
| 15151 | ** If none of the macros are initially defined, then select either | ||
| 15152 | ** SQLITE_OS_UNIX or SQLITE_OS_WIN depending on the target platform. | ||
| 15153 | ** | ||
| 15154 | ** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application | ||
| 15155 | ** must provide its own VFS implementation together with sqlite3_os_init() | ||
| 15156 | ** and sqlite3_os_end() routines. | ||
| 15157 | */ | ||
| 15158 | #if !defined(SQLITE_OS_KV) && !defined(SQLITE_OS_OTHER) && \ | ||
| 15159 | !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_WIN) | ||
| 15160 | # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ | ||
| 15161 | defined(__MINGW32__) || defined(__BORLANDC__) | ||
| 15162 | # define SQLITE_OS_WIN 1 | ||
| 15163 | # define SQLITE_OS_UNIX 0 | ||
| 15164 | # else | ||
| 15165 | # define SQLITE_OS_WIN 0 | ||
| 15166 | # define SQLITE_OS_UNIX 1 | ||
| 15167 | # endif | ||
| 15168 | #endif | ||
| 15169 | #if SQLITE_OS_OTHER+1>1 | ||
| 15170 | # undef SQLITE_OS_KV | ||
| 15171 | # define SQLITE_OS_KV 0 | ||
| 15172 | # undef SQLITE_OS_UNIX | ||
| 15173 | # define SQLITE_OS_UNIX 0 | ||
| 15174 | # undef SQLITE_OS_WIN | ||
| 15175 | # define SQLITE_OS_WIN 0 | ||
| 15176 | #endif | ||
| 15177 | #if SQLITE_OS_KV+1>1 | ||
| 15178 | # undef SQLITE_OS_OTHER | ||
| 15179 | # define SQLITE_OS_OTHER 0 | ||
| 15180 | # undef SQLITE_OS_UNIX | ||
| 15181 | # define SQLITE_OS_UNIX 0 | ||
| 15182 | # undef SQLITE_OS_WIN | ||
| 15183 | # define SQLITE_OS_WIN 0 | ||
| 15184 | # define SQLITE_OMIT_LOAD_EXTENSION 1 | ||
| 15185 | # define SQLITE_OMIT_WAL 1 | ||
| 15186 | # define SQLITE_OMIT_DEPRECATED 1 | ||
| 15187 | # undef SQLITE_TEMP_STORE | ||
| 15188 | # define SQLITE_TEMP_STORE 3 /* Always use memory for temporary storage */ | ||
| 15189 | # define SQLITE_DQS 0 | ||
| 15190 | # define SQLITE_OMIT_SHARED_CACHE 1 | ||
| 15191 | # define SQLITE_OMIT_AUTOINIT 1 | ||
| 15192 | #endif | ||
| 15193 | #if SQLITE_OS_UNIX+1>1 | ||
| 15194 | # undef SQLITE_OS_KV | ||
| 15195 | # define SQLITE_OS_KV 0 | ||
| 15196 | # undef SQLITE_OS_OTHER | ||
| 15197 | # define SQLITE_OS_OTHER 0 | ||
| 15198 | # undef SQLITE_OS_WIN | ||
| 15199 | # define SQLITE_OS_WIN 0 | ||
| 15200 | #endif | ||
| 15201 | #if SQLITE_OS_WIN+1>1 | ||
| 15202 | # undef SQLITE_OS_KV | ||
| 15203 | # define SQLITE_OS_KV 0 | ||
| 15204 | # undef SQLITE_OS_OTHER | ||
| 15205 | # define SQLITE_OS_OTHER 0 | ||
| 15206 | # undef SQLITE_OS_UNIX | ||
| 15207 | # define SQLITE_OS_UNIX 0 | ||
| 15208 | #endif | ||
| 15209 | |||
| 15210 | |||
| 15211 | #endif /* SQLITE_OS_SETUP_H */ | ||
| 15212 | |||
| 15213 | /************** End of os_setup.h ********************************************/ | ||
| 15214 | /************** Continuing where we left off in os.h *************************/ | ||
| 15215 | |||
| 15216 | /* If the SET_FULLSYNC macro is not defined above, then make it | ||
| 15217 | ** a no-op | ||
| 15218 | */ | ||
| 15219 | #ifndef SET_FULLSYNC | ||
| 15220 | # define SET_FULLSYNC(x,y) | ||
| 15221 | #endif | ||
| 15222 | |||
| 15223 | /* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h | ||
| 15224 | */ | ||
| 15225 | #ifndef SQLITE_MAX_PATHLEN | ||
| 15226 | # define SQLITE_MAX_PATHLEN FILENAME_MAX | ||
| 15227 | #endif | ||
| 15228 | |||
| 15229 | /* Maximum number of symlinks that will be resolved while trying to | ||
| 15230 | ** expand a filename in xFullPathname() in the VFS. | ||
| 15231 | */ | ||
| 15232 | #ifndef SQLITE_MAX_SYMLINK | ||
| 15233 | # define SQLITE_MAX_SYMLINK 200 | ||
| 15234 | #endif | ||
| 15235 | |||
| 15236 | /* | ||
| 15237 | ** The default size of a disk sector | ||
| 15238 | */ | ||
| 15239 | #ifndef SQLITE_DEFAULT_SECTOR_SIZE | ||
| 15240 | # define SQLITE_DEFAULT_SECTOR_SIZE 4096 | ||
| 15241 | #endif | ||
| 15242 | |||
| 15243 | /* | ||
| 15244 | ** Temporary files are named starting with this prefix followed by 16 random | ||
| 15245 | ** alphanumeric characters, and no file extension. They are stored in the | ||
| 15246 | ** OS's standard temporary file directory, and are deleted prior to exit. | ||
| 15247 | ** If sqlite is being embedded in another program, you may wish to change the | ||
| 15248 | ** prefix to reflect your program's name, so that if your program exits | ||
| 15249 | ** prematurely, old temporary files can be easily identified. This can be done | ||
| 15250 | ** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. | ||
| 15251 | ** | ||
| 15252 | ** 2006-10-31: The default prefix used to be "sqlite_". But then | ||
| 15253 | ** Mcafee started using SQLite in their anti-virus product and it | ||
| 15254 | ** started putting files with the "sqlite" name in the c:/temp folder. | ||
| 15255 | ** This annoyed many windows users. Those users would then do a | ||
| 15256 | ** Google search for "sqlite", find the telephone numbers of the | ||
| 15257 | ** developers and call to wake them up at night and complain. | ||
| 15258 | ** For this reason, the default name prefix is changed to be "sqlite" | ||
| 15259 | ** spelled backwards. So the temp files are still identified, but | ||
| 15260 | ** anybody smart enough to figure out the code is also likely smart | ||
| 15261 | ** enough to know that calling the developer will not help get rid | ||
| 15262 | ** of the file. | ||
| 15263 | */ | ||
| 15264 | #ifndef SQLITE_TEMP_FILE_PREFIX | ||
| 15265 | # define SQLITE_TEMP_FILE_PREFIX "etilqs_" | ||
| 15266 | #endif | ||
| 15267 | |||
| 15268 | /* | ||
| 15269 | ** The following values may be passed as the second argument to | ||
| 15270 | ** sqlite3OsLock(). The various locks exhibit the following semantics: | ||
| 15271 | ** | ||
| 15272 | ** SHARED: Any number of processes may hold a SHARED lock simultaneously. | ||
| 15273 | ** RESERVED: A single process may hold a RESERVED lock on a file at | ||
| 15274 | ** any time. Other processes may hold and obtain new SHARED locks. | ||
| 15275 | ** PENDING: A single process may hold a PENDING lock on a file at | ||
| 15276 | ** any one time. Existing SHARED locks may persist, but no new | ||
| 15277 | ** SHARED locks may be obtained by other processes. | ||
| 15278 | ** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. | ||
| 15279 | ** | ||
| 15280 | ** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a | ||
| 15281 | ** process that requests an EXCLUSIVE lock may actually obtain a PENDING | ||
| 15282 | ** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to | ||
| 15283 | ** sqlite3OsLock(). | ||
| 15284 | */ | ||
| 15285 | #define NO_LOCK 0 | ||
| 15286 | #define SHARED_LOCK 1 | ||
| 15287 | #define RESERVED_LOCK 2 | ||
| 15288 | #define PENDING_LOCK 3 | ||
| 15289 | #define EXCLUSIVE_LOCK 4 | ||
| 15290 | |||
| 15291 | /* | ||
| 15292 | ** File Locking Notes: (Mostly about windows but also some info for Unix) | ||
| 15293 | ** | ||
| 15294 | ** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because | ||
| 15295 | ** those functions are not available. So we use only LockFile() and | ||
| 15296 | ** UnlockFile(). | ||
| 15297 | ** | ||
| 15298 | ** LockFile() prevents not just writing but also reading by other processes. | ||
| 15299 | ** A SHARED_LOCK is obtained by locking a single randomly-chosen | ||
| 15300 | ** byte out of a specific range of bytes. The lock byte is obtained at | ||
| 15301 | ** random so two separate readers can probably access the file at the | ||
| 15302 | ** same time, unless they are unlucky and choose the same lock byte. | ||
| 15303 | ** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. | ||
| 15304 | ** There can only be one writer. A RESERVED_LOCK is obtained by locking | ||
| 15305 | ** a single byte of the file that is designated as the reserved lock byte. | ||
| 15306 | ** A PENDING_LOCK is obtained by locking a designated byte different from | ||
| 15307 | ** the RESERVED_LOCK byte. | ||
| 15308 | ** | ||
| 15309 | ** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, | ||
| 15310 | ** which means we can use reader/writer locks. When reader/writer locks | ||
| 15311 | ** are used, the lock is placed on the same range of bytes that is used | ||
| 15312 | ** for probabilistic locking in Win95/98/ME. Hence, the locking scheme | ||
| 15313 | ** will support two or more Win95 readers or two or more WinNT readers. | ||
| 15314 | ** But a single Win95 reader will lock out all WinNT readers and a single | ||
| 15315 | ** WinNT reader will lock out all other Win95 readers. | ||
| 15316 | ** | ||
| 15317 | ** The following #defines specify the range of bytes used for locking. | ||
| 15318 | ** SHARED_SIZE is the number of bytes available in the pool from which | ||
| 15319 | ** a random byte is selected for a shared lock. The pool of bytes for | ||
| 15320 | ** shared locks begins at SHARED_FIRST. | ||
| 15321 | ** | ||
| 15322 | ** The same locking strategy and | ||
| 15323 | ** byte ranges are used for Unix. This leaves open the possibility of having | ||
| 15324 | ** clients on win95, winNT, and unix all talking to the same shared file | ||
| 15325 | ** and all locking correctly. To do so would require that samba (or whatever | ||
| 15326 | ** tool is being used for file sharing) implements locks correctly between | ||
| 15327 | ** windows and unix. I'm guessing that isn't likely to happen, but by | ||
| 15328 | ** using the same locking range we are at least open to the possibility. | ||
| 15329 | ** | ||
| 15330 | ** Locking in windows is manditory. For this reason, we cannot store | ||
| 15331 | ** actual data in the bytes used for locking. The pager never allocates | ||
| 15332 | ** the pages involved in locking therefore. SHARED_SIZE is selected so | ||
| 15333 | ** that all locks will fit on a single page even at the minimum page size. | ||
| 15334 | ** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE | ||
| 15335 | ** is set high so that we don't have to allocate an unused page except | ||
| 15336 | ** for very large databases. But one should test the page skipping logic | ||
| 15337 | ** by setting PENDING_BYTE low and running the entire regression suite. | ||
| 15338 | ** | ||
| 15339 | ** Changing the value of PENDING_BYTE results in a subtly incompatible | ||
| 15340 | ** file format. Depending on how it is changed, you might not notice | ||
| 15341 | ** the incompatibility right away, even running a full regression test. | ||
| 15342 | ** The default location of PENDING_BYTE is the first byte past the | ||
| 15343 | ** 1GB boundary. | ||
| 15344 | ** | ||
| 15345 | */ | ||
| 15346 | #ifdef SQLITE_OMIT_WSD | ||
| 15347 | # define PENDING_BYTE (0x40000000) | ||
| 15348 | #else | ||
| 15349 | # define PENDING_BYTE sqlite3PendingByte | ||
| 15350 | #endif | ||
| 15351 | #define RESERVED_BYTE (PENDING_BYTE+1) | ||
| 15352 | #define SHARED_FIRST (PENDING_BYTE+2) | ||
| 15353 | #define SHARED_SIZE 510 | ||
| 15354 | |||
| 15355 | /* | ||
| 15356 | ** Wrapper around OS specific sqlite3_os_init() function. | ||
| 15357 | */ | ||
| 15358 | SQLITE_PRIVATE int sqlite3OsInit(void); | ||
| 15359 | |||
| 15360 | /* | ||
| 15361 | ** Functions for accessing sqlite3_file methods | ||
| 15362 | */ | ||
| 15363 | SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); | ||
| 15364 | SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); | ||
| 15365 | SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); | ||
| 15366 | SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); | ||
| 15367 | SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); | ||
| 15368 | SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); | ||
| 15369 | SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); | ||
| 15370 | SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); | ||
| 15371 | SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); | ||
| 15372 | SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); | ||
| 15373 | SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); | ||
| 15374 | #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 | ||
| 15375 | SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); | ||
| 15376 | SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); | ||
| 15377 | #ifndef SQLITE_OMIT_WAL | ||
| 15378 | SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); | ||
| 15379 | SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); | ||
| 15380 | SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); | ||
| 15381 | SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); | ||
| 15382 | #endif /* SQLITE_OMIT_WAL */ | ||
| 15383 | SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); | ||
| 15384 | SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); | ||
| 15385 | |||
| 15386 | |||
| 15387 | /* | ||
| 15388 | ** Functions for accessing sqlite3_vfs methods | ||
| 15389 | */ | ||
| 15390 | SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); | ||
| 15391 | SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); | ||
| 15392 | SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); | ||
| 15393 | SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); | ||
| 15394 | #ifndef SQLITE_OMIT_LOAD_EXTENSION | ||
| 15395 | SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); | ||
| 15396 | SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); | ||
| 15397 | SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); | ||
| 15398 | SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); | ||
| 15399 | #endif /* SQLITE_OMIT_LOAD_EXTENSION */ | ||
| 15400 | SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); | ||
| 15401 | SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); | ||
| 15402 | SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); | ||
| 15403 | SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); | ||
| 15404 | |||
| 15405 | /* | ||
| 15406 | ** Convenience functions for opening and closing files using | ||
| 15407 | ** sqlite3_malloc() to obtain space for the file-handle structure. | ||
| 15408 | */ | ||
| 15409 | SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); | ||
| 15410 | SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); | ||
| 15411 | |||
| 15412 | #endif /* _SQLITE_OS_H_ */ | ||
| 15413 | |||
| 15414 | /************** End of os.h **************************************************/ | ||
| 15415 | /************** Continuing where we left off in sqliteInt.h ******************/ | ||
| 14719 | /************** Include pager.h in the middle of sqliteInt.h *****************/ | 15416 | /************** Include pager.h in the middle of sqliteInt.h *****************/ |
| 14720 | /************** Begin file pager.h *******************************************/ | 15417 | /************** Begin file pager.h *******************************************/ |
| 14721 | /* | 15418 | /* |
| @@ -14960,6 +15657,10 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); | |||
| 14960 | # define enable_simulated_io_errors() | 15657 | # define enable_simulated_io_errors() |
| 14961 | #endif | 15658 | #endif |
| 14962 | 15659 | ||
| 15660 | #if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) | ||
| 15661 | SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager*); | ||
| 15662 | #endif | ||
| 15663 | |||
| 14963 | #endif /* SQLITE_PAGER_H */ | 15664 | #endif /* SQLITE_PAGER_H */ |
| 14964 | 15665 | ||
| 14965 | /************** End of pager.h ***********************************************/ | 15666 | /************** End of pager.h ***********************************************/ |
| @@ -15151,7 +15852,7 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p); | |||
| 15151 | ** reduce network bandwidth. | 15852 | ** reduce network bandwidth. |
| 15152 | ** | 15853 | ** |
| 15153 | ** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by | 15854 | ** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by |
| 15154 | ** standard SQLite. The other hints are provided for extentions that use | 15855 | ** standard SQLite. The other hints are provided for extensions that use |
| 15155 | ** the SQLite parser and code generator but substitute their own storage | 15856 | ** the SQLite parser and code generator but substitute their own storage |
| 15156 | ** engine. | 15857 | ** engine. |
| 15157 | */ | 15858 | */ |
| @@ -15289,15 +15990,21 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags); | |||
| 15289 | SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*); | 15990 | SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*); |
| 15290 | SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*); | 15991 | SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*); |
| 15291 | SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*); | 15992 | SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*); |
| 15292 | #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC | ||
| 15293 | SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*); | 15993 | SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*); |
| 15294 | #endif | ||
| 15295 | SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); | 15994 | SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); |
| 15296 | SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); | 15995 | SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); |
| 15297 | SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); | 15996 | SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); |
| 15298 | SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); | 15997 | SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); |
| 15299 | 15998 | ||
| 15300 | SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*); | 15999 | SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( |
| 16000 | sqlite3 *db, /* Database connection that is running the check */ | ||
| 16001 | Btree *p, /* The btree to be checked */ | ||
| 16002 | Pgno *aRoot, /* An array of root pages numbers for individual trees */ | ||
| 16003 | int nRoot, /* Number of entries in aRoot[] */ | ||
| 16004 | int mxErr, /* Stop reporting errors after this many */ | ||
| 16005 | int *pnErr, /* OUT: Write number of errors seen to this variable */ | ||
| 16006 | char **pzOut /* OUT: Write the error message string here */ | ||
| 16007 | ); | ||
| 15301 | SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); | 16008 | SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); |
| 15302 | SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*); | 16009 | SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*); |
| 15303 | 16010 | ||
| @@ -15336,6 +16043,8 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); | |||
| 15336 | 16043 | ||
| 15337 | SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64); | 16044 | SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64); |
| 15338 | 16045 | ||
| 16046 | SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree*); | ||
| 16047 | |||
| 15339 | /* | 16048 | /* |
| 15340 | ** If we are not using shared cache, then there is no need to | 16049 | ** If we are not using shared cache, then there is no need to |
| 15341 | ** use mutexes to access the BtShared structures. So make the | 16050 | ** use mutexes to access the BtShared structures. So make the |
| @@ -15452,14 +16161,14 @@ struct VdbeOp { | |||
| 15452 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS | 16161 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS |
| 15453 | char *zComment; /* Comment to improve readability */ | 16162 | char *zComment; /* Comment to improve readability */ |
| 15454 | #endif | 16163 | #endif |
| 15455 | #ifdef VDBE_PROFILE | ||
| 15456 | u32 cnt; /* Number of times this instruction was executed */ | ||
| 15457 | u64 cycles; /* Total time spent executing this instruction */ | ||
| 15458 | #endif | ||
| 15459 | #ifdef SQLITE_VDBE_COVERAGE | 16164 | #ifdef SQLITE_VDBE_COVERAGE |
| 15460 | u32 iSrcLine; /* Source-code line that generated this opcode | 16165 | u32 iSrcLine; /* Source-code line that generated this opcode |
| 15461 | ** with flags in the upper 8 bits */ | 16166 | ** with flags in the upper 8 bits */ |
| 15462 | #endif | 16167 | #endif |
| 16168 | #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) | ||
| 16169 | u64 nExec; | ||
| 16170 | u64 nCycle; | ||
| 16171 | #endif | ||
| 15463 | }; | 16172 | }; |
| 15464 | typedef struct VdbeOp VdbeOp; | 16173 | typedef struct VdbeOp VdbeOp; |
| 15465 | 16174 | ||
| @@ -15560,48 +16269,48 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 15560 | #define OP_Vacuum 5 | 16269 | #define OP_Vacuum 5 |
| 15561 | #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ | 16270 | #define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ |
| 15562 | #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ | 16271 | #define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ |
| 15563 | #define OP_Goto 8 /* jump */ | 16272 | #define OP_Init 8 /* jump, synopsis: Start at P2 */ |
| 15564 | #define OP_Gosub 9 /* jump */ | 16273 | #define OP_Goto 9 /* jump */ |
| 15565 | #define OP_InitCoroutine 10 /* jump */ | 16274 | #define OP_Gosub 10 /* jump */ |
| 15566 | #define OP_Yield 11 /* jump */ | 16275 | #define OP_InitCoroutine 11 /* jump */ |
| 15567 | #define OP_MustBeInt 12 /* jump */ | 16276 | #define OP_Yield 12 /* jump */ |
| 15568 | #define OP_Jump 13 /* jump */ | 16277 | #define OP_MustBeInt 13 /* jump */ |
| 15569 | #define OP_Once 14 /* jump */ | 16278 | #define OP_Jump 14 /* jump */ |
| 15570 | #define OP_If 15 /* jump */ | 16279 | #define OP_Once 15 /* jump */ |
| 15571 | #define OP_IfNot 16 /* jump */ | 16280 | #define OP_If 16 /* jump */ |
| 15572 | #define OP_IsNullOrType 17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */ | 16281 | #define OP_IfNot 17 /* jump */ |
| 15573 | #define OP_IfNullRow 18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ | 16282 | #define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */ |
| 15574 | #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ | 16283 | #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ |
| 15575 | #define OP_SeekLT 20 /* jump, synopsis: key=r[P3@P4] */ | 16284 | #define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ |
| 15576 | #define OP_SeekLE 21 /* jump, synopsis: key=r[P3@P4] */ | 16285 | #define OP_SeekLT 21 /* jump, synopsis: key=r[P3@P4] */ |
| 15577 | #define OP_SeekGE 22 /* jump, synopsis: key=r[P3@P4] */ | 16286 | #define OP_SeekLE 22 /* jump, synopsis: key=r[P3@P4] */ |
| 15578 | #define OP_SeekGT 23 /* jump, synopsis: key=r[P3@P4] */ | 16287 | #define OP_SeekGE 23 /* jump, synopsis: key=r[P3@P4] */ |
| 15579 | #define OP_IfNotOpen 24 /* jump, synopsis: if( !csr[P1] ) goto P2 */ | 16288 | #define OP_SeekGT 24 /* jump, synopsis: key=r[P3@P4] */ |
| 15580 | #define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */ | 16289 | #define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ |
| 15581 | #define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */ | 16290 | #define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ |
| 15582 | #define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */ | 16291 | #define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ |
| 15583 | #define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */ | 16292 | #define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ |
| 15584 | #define OP_SeekRowid 29 /* jump, synopsis: intkey=r[P3] */ | 16293 | #define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ |
| 15585 | #define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */ | 16294 | #define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */ |
| 15586 | #define OP_Last 31 /* jump */ | 16295 | #define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ |
| 15587 | #define OP_IfSmaller 32 /* jump */ | 16296 | #define OP_Last 32 /* jump */ |
| 15588 | #define OP_SorterSort 33 /* jump */ | 16297 | #define OP_IfSmaller 33 /* jump */ |
| 15589 | #define OP_Sort 34 /* jump */ | 16298 | #define OP_SorterSort 34 /* jump */ |
| 15590 | #define OP_Rewind 35 /* jump */ | 16299 | #define OP_Sort 35 /* jump */ |
| 15591 | #define OP_SorterNext 36 /* jump */ | 16300 | #define OP_Rewind 36 /* jump */ |
| 15592 | #define OP_Prev 37 /* jump */ | 16301 | #define OP_SorterNext 37 /* jump */ |
| 15593 | #define OP_Next 38 /* jump */ | 16302 | #define OP_Prev 38 /* jump */ |
| 15594 | #define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */ | 16303 | #define OP_Next 39 /* jump */ |
| 15595 | #define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */ | 16304 | #define OP_IdxLE 40 /* jump, synopsis: key=r[P3@P4] */ |
| 15596 | #define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */ | 16305 | #define OP_IdxGT 41 /* jump, synopsis: key=r[P3@P4] */ |
| 15597 | #define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */ | 16306 | #define OP_IdxLT 42 /* jump, synopsis: key=r[P3@P4] */ |
| 15598 | #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ | 16307 | #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ |
| 15599 | #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ | 16308 | #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ |
| 15600 | #define OP_RowSetRead 45 /* jump, synopsis: r[P3]=rowset(P1) */ | 16309 | #define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ |
| 15601 | #define OP_RowSetTest 46 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ | 16310 | #define OP_RowSetRead 46 /* jump, synopsis: r[P3]=rowset(P1) */ |
| 15602 | #define OP_Program 47 /* jump */ | 16311 | #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ |
| 15603 | #define OP_FkIfZero 48 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ | 16312 | #define OP_Program 48 /* jump */ |
| 15604 | #define OP_IfPos 49 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ | 16313 | #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ |
| 15605 | #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ | 16314 | #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ |
| 15606 | #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ | 16315 | #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ |
| 15607 | #define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ | 16316 | #define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ |
| @@ -15611,12 +16320,12 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 15611 | #define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ | 16320 | #define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */ |
| 15612 | #define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ | 16321 | #define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */ |
| 15613 | #define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ | 16322 | #define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ |
| 15614 | #define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ | 16323 | #define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ |
| 15615 | #define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */ | 16324 | #define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ |
| 15616 | #define OP_IncrVacuum 61 /* jump */ | 16325 | #define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ |
| 15617 | #define OP_VNext 62 /* jump */ | 16326 | #define OP_IncrVacuum 62 /* jump */ |
| 15618 | #define OP_Filter 63 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ | 16327 | #define OP_VNext 63 /* jump */ |
| 15619 | #define OP_Init 64 /* jump, synopsis: Start at P2 */ | 16328 | #define OP_Filter 64 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ |
| 15620 | #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ | 16329 | #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ |
| 15621 | #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ | 16330 | #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ |
| 15622 | #define OP_Return 67 | 16331 | #define OP_Return 67 |
| @@ -15750,29 +16459,30 @@ typedef struct VdbeOpList VdbeOpList; | |||
| 15750 | #define OPFLG_IN3 0x08 /* in3: P3 is an input */ | 16459 | #define OPFLG_IN3 0x08 /* in3: P3 is an input */ |
| 15751 | #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ | 16460 | #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ |
| 15752 | #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ | 16461 | #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ |
| 16462 | #define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */ | ||
| 15753 | #define OPFLG_INITIALIZER {\ | 16463 | #define OPFLG_INITIALIZER {\ |
| 15754 | /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\ | 16464 | /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ |
| 15755 | /* 8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\ | 16465 | /* 8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\ |
| 15756 | /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\ | 16466 | /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x49, 0x49, 0x49,\ |
| 15757 | /* 24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\ | 16467 | /* 24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\ |
| 15758 | /* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ | 16468 | /* 32 */ 0x41, 0x01, 0x41, 0x41, 0x41, 0x01, 0x41, 0x41,\ |
| 15759 | /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\ | 16469 | /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ |
| 15760 | /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ | 16470 | /* 48 */ 0x01, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ |
| 15761 | /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\ | 16471 | /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ |
| 15762 | /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ | 16472 | /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ |
| 15763 | /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ | 16473 | /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ |
| 15764 | /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ | 16474 | /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ |
| 15765 | /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\ | 16475 | /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ |
| 15766 | /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\ | 16476 | /* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26, 0x26,\ |
| 15767 | /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ | 16477 | /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ |
| 15768 | /* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\ | 16478 | /* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\ |
| 15769 | /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\ | 16479 | /* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ |
| 15770 | /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ | 16480 | /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ |
| 15771 | /* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\ | 16481 | /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ |
| 15772 | /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ | 16482 | /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ |
| 15773 | /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ | 16483 | /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ |
| 15774 | /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ | 16484 | /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ |
| 15775 | /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\ | 16485 | /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x50, 0x40,\ |
| 15776 | /* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\ | 16486 | /* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\ |
| 15777 | /* 184 */ 0x00, 0x00, 0x00,} | 16487 | /* 184 */ 0x00, 0x00, 0x00,} |
| 15778 | 16488 | ||
| @@ -15827,14 +16537,20 @@ SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn(Vdbe*,int,int,int); | |||
| 15827 | #endif | 16537 | #endif |
| 15828 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); | 16538 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); |
| 15829 | #ifndef SQLITE_OMIT_EXPLAIN | 16539 | #ifndef SQLITE_OMIT_EXPLAIN |
| 15830 | SQLITE_PRIVATE void sqlite3VdbeExplain(Parse*,u8,const char*,...); | 16540 | SQLITE_PRIVATE int sqlite3VdbeExplain(Parse*,u8,const char*,...); |
| 15831 | SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse*); | 16541 | SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse*); |
| 15832 | SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*); | 16542 | SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*); |
| 15833 | # define ExplainQueryPlan(P) sqlite3VdbeExplain P | 16543 | # define ExplainQueryPlan(P) sqlite3VdbeExplain P |
| 16544 | # ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 16545 | # define ExplainQueryPlan2(V,P) (V = sqlite3VdbeExplain P) | ||
| 16546 | # else | ||
| 16547 | # define ExplainQueryPlan2(V,P) ExplainQueryPlan(P) | ||
| 16548 | # endif | ||
| 15834 | # define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P) | 16549 | # define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P) |
| 15835 | # define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P) | 16550 | # define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P) |
| 15836 | #else | 16551 | #else |
| 15837 | # define ExplainQueryPlan(P) | 16552 | # define ExplainQueryPlan(P) |
| 16553 | # define ExplainQueryPlan2(V,P) | ||
| 15838 | # define ExplainQueryPlanPop(P) | 16554 | # define ExplainQueryPlanPop(P) |
| 15839 | # define ExplainQueryPlanParent(P) 0 | 16555 | # define ExplainQueryPlanParent(P) 0 |
| 15840 | # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ | 16556 | # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ |
| @@ -15850,6 +16566,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); | |||
| 15850 | SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); | 16566 | SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); |
| 15851 | SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); | 16567 | SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); |
| 15852 | SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5); | 16568 | SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5); |
| 16569 | SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe*, int); | ||
| 15853 | SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); | 16570 | SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); |
| 15854 | SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr); | 16571 | SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr); |
| 15855 | SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr); | 16572 | SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr); |
| @@ -15864,6 +16581,7 @@ SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); | |||
| 15864 | SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); | 16581 | SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); |
| 15865 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); | 16582 | SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); |
| 15866 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); | 16583 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); |
| 16584 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe*); | ||
| 15867 | SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*); | 16585 | SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*); |
| 15868 | SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); | 16586 | SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); |
| 15869 | SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*); | 16587 | SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*); |
| @@ -15941,7 +16659,7 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); | |||
| 15941 | ** The VdbeCoverage macros are used to set a coverage testing point | 16659 | ** The VdbeCoverage macros are used to set a coverage testing point |
| 15942 | ** for VDBE branch instructions. The coverage testing points are line | 16660 | ** for VDBE branch instructions. The coverage testing points are line |
| 15943 | ** numbers in the sqlite3.c source file. VDBE branch coverage testing | 16661 | ** numbers in the sqlite3.c source file. VDBE branch coverage testing |
| 15944 | ** only works with an amalagmation build. That's ok since a VDBE branch | 16662 | ** only works with an amalgamation build. That's ok since a VDBE branch |
| 15945 | ** coverage build designed for testing the test suite only. No application | 16663 | ** coverage build designed for testing the test suite only. No application |
| 15946 | ** should ever ship with VDBE branch coverage measuring turned on. | 16664 | ** should ever ship with VDBE branch coverage measuring turned on. |
| 15947 | ** | 16665 | ** |
| @@ -15959,7 +16677,7 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); | |||
| 15959 | ** // NULL option is not possible | 16677 | ** // NULL option is not possible |
| 15960 | ** | 16678 | ** |
| 15961 | ** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested | 16679 | ** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested |
| 15962 | ** // in distingishing equal and not-equal. | 16680 | ** // in distinguishing equal and not-equal. |
| 15963 | ** | 16681 | ** |
| 15964 | ** Every VDBE branch operation must be tagged with one of the macros above. | 16682 | ** Every VDBE branch operation must be tagged with one of the macros above. |
| 15965 | ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and | 16683 | ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and |
| @@ -15969,7 +16687,7 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); | |||
| 15969 | ** During testing, the test application will invoke | 16687 | ** During testing, the test application will invoke |
| 15970 | ** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback | 16688 | ** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback |
| 15971 | ** routine that is invoked as each bytecode branch is taken. The callback | 16689 | ** routine that is invoked as each bytecode branch is taken. The callback |
| 15972 | ** contains the sqlite3.c source line number ov the VdbeCoverage macro and | 16690 | ** contains the sqlite3.c source line number of the VdbeCoverage macro and |
| 15973 | ** flags to indicate whether or not the branch was taken. The test application | 16691 | ** flags to indicate whether or not the branch was taken. The test application |
| 15974 | ** is responsible for keeping track of this and reporting byte-code branches | 16692 | ** is responsible for keeping track of this and reporting byte-code branches |
| 15975 | ** that are never taken. | 16693 | ** that are never taken. |
| @@ -16005,14 +16723,22 @@ SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int); | |||
| 16005 | 16723 | ||
| 16006 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | 16724 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| 16007 | SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); | 16725 | SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); |
| 16726 | SQLITE_PRIVATE void sqlite3VdbeScanStatusRange(Vdbe*, int, int, int); | ||
| 16727 | SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters(Vdbe*, int, int, int); | ||
| 16008 | #else | 16728 | #else |
| 16009 | # define sqlite3VdbeScanStatus(a,b,c,d,e) | 16729 | # define sqlite3VdbeScanStatus(a,b,c,d,e,f) |
| 16730 | # define sqlite3VdbeScanStatusRange(a,b,c,d) | ||
| 16731 | # define sqlite3VdbeScanStatusCounters(a,b,c,d) | ||
| 16010 | #endif | 16732 | #endif |
| 16011 | 16733 | ||
| 16012 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) | 16734 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 16013 | SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); | 16735 | SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); |
| 16014 | #endif | 16736 | #endif |
| 16015 | 16737 | ||
| 16738 | #if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) | ||
| 16739 | SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr); | ||
| 16740 | #endif | ||
| 16741 | |||
| 16016 | #endif /* SQLITE_VDBE_H */ | 16742 | #endif /* SQLITE_VDBE_H */ |
| 16017 | 16743 | ||
| 16018 | /************** End of vdbe.h ************************************************/ | 16744 | /************** End of vdbe.h ************************************************/ |
| @@ -16061,7 +16787,7 @@ struct PgHdr { | |||
| 16061 | ** private to pcache.c and should not be accessed by other modules. | 16787 | ** private to pcache.c and should not be accessed by other modules. |
| 16062 | ** pCache is grouped with the public elements for efficiency. | 16788 | ** pCache is grouped with the public elements for efficiency. |
| 16063 | */ | 16789 | */ |
| 16064 | i16 nRef; /* Number of users of this page */ | 16790 | i64 nRef; /* Number of users of this page */ |
| 16065 | PgHdr *pDirtyNext; /* Next element in list of dirty pages */ | 16791 | PgHdr *pDirtyNext; /* Next element in list of dirty pages */ |
| 16066 | PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ | 16792 | PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ |
| 16067 | /* NB: pDirtyNext and pDirtyPrev are undefined if the | 16793 | /* NB: pDirtyNext and pDirtyPrev are undefined if the |
| @@ -16142,12 +16868,12 @@ SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *); | |||
| 16142 | SQLITE_PRIVATE void sqlite3PcacheClear(PCache*); | 16868 | SQLITE_PRIVATE void sqlite3PcacheClear(PCache*); |
| 16143 | 16869 | ||
| 16144 | /* Return the total number of outstanding page references */ | 16870 | /* Return the total number of outstanding page references */ |
| 16145 | SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*); | 16871 | SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache*); |
| 16146 | 16872 | ||
| 16147 | /* Increment the reference count of an existing page */ | 16873 | /* Increment the reference count of an existing page */ |
| 16148 | SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*); | 16874 | SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*); |
| 16149 | 16875 | ||
| 16150 | SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*); | 16876 | SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr*); |
| 16151 | 16877 | ||
| 16152 | /* Return the total number of pages stored in the cache */ | 16878 | /* Return the total number of pages stored in the cache */ |
| 16153 | SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); | 16879 | SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); |
| @@ -16212,297 +16938,6 @@ SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache); | |||
| 16212 | 16938 | ||
| 16213 | /************** End of pcache.h **********************************************/ | 16939 | /************** End of pcache.h **********************************************/ |
| 16214 | /************** Continuing where we left off in sqliteInt.h ******************/ | 16940 | /************** Continuing where we left off in sqliteInt.h ******************/ |
| 16215 | /************** Include os.h in the middle of sqliteInt.h ********************/ | ||
| 16216 | /************** Begin file os.h **********************************************/ | ||
| 16217 | /* | ||
| 16218 | ** 2001 September 16 | ||
| 16219 | ** | ||
| 16220 | ** The author disclaims copyright to this source code. In place of | ||
| 16221 | ** a legal notice, here is a blessing: | ||
| 16222 | ** | ||
| 16223 | ** May you do good and not evil. | ||
| 16224 | ** May you find forgiveness for yourself and forgive others. | ||
| 16225 | ** May you share freely, never taking more than you give. | ||
| 16226 | ** | ||
| 16227 | ****************************************************************************** | ||
| 16228 | ** | ||
| 16229 | ** This header file (together with is companion C source-code file | ||
| 16230 | ** "os.c") attempt to abstract the underlying operating system so that | ||
| 16231 | ** the SQLite library will work on both POSIX and windows systems. | ||
| 16232 | ** | ||
| 16233 | ** This header file is #include-ed by sqliteInt.h and thus ends up | ||
| 16234 | ** being included by every source file. | ||
| 16235 | */ | ||
| 16236 | #ifndef _SQLITE_OS_H_ | ||
| 16237 | #define _SQLITE_OS_H_ | ||
| 16238 | |||
| 16239 | /* | ||
| 16240 | ** Attempt to automatically detect the operating system and setup the | ||
| 16241 | ** necessary pre-processor macros for it. | ||
| 16242 | */ | ||
| 16243 | /************** Include os_setup.h in the middle of os.h *********************/ | ||
| 16244 | /************** Begin file os_setup.h ****************************************/ | ||
| 16245 | /* | ||
| 16246 | ** 2013 November 25 | ||
| 16247 | ** | ||
| 16248 | ** The author disclaims copyright to this source code. In place of | ||
| 16249 | ** a legal notice, here is a blessing: | ||
| 16250 | ** | ||
| 16251 | ** May you do good and not evil. | ||
| 16252 | ** May you find forgiveness for yourself and forgive others. | ||
| 16253 | ** May you share freely, never taking more than you give. | ||
| 16254 | ** | ||
| 16255 | ****************************************************************************** | ||
| 16256 | ** | ||
| 16257 | ** This file contains pre-processor directives related to operating system | ||
| 16258 | ** detection and/or setup. | ||
| 16259 | */ | ||
| 16260 | #ifndef SQLITE_OS_SETUP_H | ||
| 16261 | #define SQLITE_OS_SETUP_H | ||
| 16262 | |||
| 16263 | /* | ||
| 16264 | ** Figure out if we are dealing with Unix, Windows, or some other operating | ||
| 16265 | ** system. | ||
| 16266 | ** | ||
| 16267 | ** After the following block of preprocess macros, all of SQLITE_OS_UNIX, | ||
| 16268 | ** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of | ||
| 16269 | ** the three will be 1. The other two will be 0. | ||
| 16270 | */ | ||
| 16271 | #if defined(SQLITE_OS_OTHER) | ||
| 16272 | # if SQLITE_OS_OTHER==1 | ||
| 16273 | # undef SQLITE_OS_UNIX | ||
| 16274 | # define SQLITE_OS_UNIX 0 | ||
| 16275 | # undef SQLITE_OS_WIN | ||
| 16276 | # define SQLITE_OS_WIN 0 | ||
| 16277 | # else | ||
| 16278 | # undef SQLITE_OS_OTHER | ||
| 16279 | # endif | ||
| 16280 | #endif | ||
| 16281 | #if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER) | ||
| 16282 | # define SQLITE_OS_OTHER 0 | ||
| 16283 | # ifndef SQLITE_OS_WIN | ||
| 16284 | # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ | ||
| 16285 | defined(__MINGW32__) || defined(__BORLANDC__) | ||
| 16286 | # define SQLITE_OS_WIN 1 | ||
| 16287 | # define SQLITE_OS_UNIX 0 | ||
| 16288 | # else | ||
| 16289 | # define SQLITE_OS_WIN 0 | ||
| 16290 | # define SQLITE_OS_UNIX 1 | ||
| 16291 | # endif | ||
| 16292 | # else | ||
| 16293 | # define SQLITE_OS_UNIX 0 | ||
| 16294 | # endif | ||
| 16295 | #else | ||
| 16296 | # ifndef SQLITE_OS_WIN | ||
| 16297 | # define SQLITE_OS_WIN 0 | ||
| 16298 | # endif | ||
| 16299 | #endif | ||
| 16300 | |||
| 16301 | #endif /* SQLITE_OS_SETUP_H */ | ||
| 16302 | |||
| 16303 | /************** End of os_setup.h ********************************************/ | ||
| 16304 | /************** Continuing where we left off in os.h *************************/ | ||
| 16305 | |||
| 16306 | /* If the SET_FULLSYNC macro is not defined above, then make it | ||
| 16307 | ** a no-op | ||
| 16308 | */ | ||
| 16309 | #ifndef SET_FULLSYNC | ||
| 16310 | # define SET_FULLSYNC(x,y) | ||
| 16311 | #endif | ||
| 16312 | |||
| 16313 | /* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h | ||
| 16314 | */ | ||
| 16315 | #ifndef SQLITE_MAX_PATHLEN | ||
| 16316 | # define SQLITE_MAX_PATHLEN FILENAME_MAX | ||
| 16317 | #endif | ||
| 16318 | |||
| 16319 | /* Maximum number of symlinks that will be resolved while trying to | ||
| 16320 | ** expand a filename in xFullPathname() in the VFS. | ||
| 16321 | */ | ||
| 16322 | #ifndef SQLITE_MAX_SYMLINK | ||
| 16323 | # define SQLITE_MAX_SYMLINK 200 | ||
| 16324 | #endif | ||
| 16325 | |||
| 16326 | /* | ||
| 16327 | ** The default size of a disk sector | ||
| 16328 | */ | ||
| 16329 | #ifndef SQLITE_DEFAULT_SECTOR_SIZE | ||
| 16330 | # define SQLITE_DEFAULT_SECTOR_SIZE 4096 | ||
| 16331 | #endif | ||
| 16332 | |||
| 16333 | /* | ||
| 16334 | ** Temporary files are named starting with this prefix followed by 16 random | ||
| 16335 | ** alphanumeric characters, and no file extension. They are stored in the | ||
| 16336 | ** OS's standard temporary file directory, and are deleted prior to exit. | ||
| 16337 | ** If sqlite is being embedded in another program, you may wish to change the | ||
| 16338 | ** prefix to reflect your program's name, so that if your program exits | ||
| 16339 | ** prematurely, old temporary files can be easily identified. This can be done | ||
| 16340 | ** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. | ||
| 16341 | ** | ||
| 16342 | ** 2006-10-31: The default prefix used to be "sqlite_". But then | ||
| 16343 | ** Mcafee started using SQLite in their anti-virus product and it | ||
| 16344 | ** started putting files with the "sqlite" name in the c:/temp folder. | ||
| 16345 | ** This annoyed many windows users. Those users would then do a | ||
| 16346 | ** Google search for "sqlite", find the telephone numbers of the | ||
| 16347 | ** developers and call to wake them up at night and complain. | ||
| 16348 | ** For this reason, the default name prefix is changed to be "sqlite" | ||
| 16349 | ** spelled backwards. So the temp files are still identified, but | ||
| 16350 | ** anybody smart enough to figure out the code is also likely smart | ||
| 16351 | ** enough to know that calling the developer will not help get rid | ||
| 16352 | ** of the file. | ||
| 16353 | */ | ||
| 16354 | #ifndef SQLITE_TEMP_FILE_PREFIX | ||
| 16355 | # define SQLITE_TEMP_FILE_PREFIX "etilqs_" | ||
| 16356 | #endif | ||
| 16357 | |||
| 16358 | /* | ||
| 16359 | ** The following values may be passed as the second argument to | ||
| 16360 | ** sqlite3OsLock(). The various locks exhibit the following semantics: | ||
| 16361 | ** | ||
| 16362 | ** SHARED: Any number of processes may hold a SHARED lock simultaneously. | ||
| 16363 | ** RESERVED: A single process may hold a RESERVED lock on a file at | ||
| 16364 | ** any time. Other processes may hold and obtain new SHARED locks. | ||
| 16365 | ** PENDING: A single process may hold a PENDING lock on a file at | ||
| 16366 | ** any one time. Existing SHARED locks may persist, but no new | ||
| 16367 | ** SHARED locks may be obtained by other processes. | ||
| 16368 | ** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. | ||
| 16369 | ** | ||
| 16370 | ** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a | ||
| 16371 | ** process that requests an EXCLUSIVE lock may actually obtain a PENDING | ||
| 16372 | ** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to | ||
| 16373 | ** sqlite3OsLock(). | ||
| 16374 | */ | ||
| 16375 | #define NO_LOCK 0 | ||
| 16376 | #define SHARED_LOCK 1 | ||
| 16377 | #define RESERVED_LOCK 2 | ||
| 16378 | #define PENDING_LOCK 3 | ||
| 16379 | #define EXCLUSIVE_LOCK 4 | ||
| 16380 | |||
| 16381 | /* | ||
| 16382 | ** File Locking Notes: (Mostly about windows but also some info for Unix) | ||
| 16383 | ** | ||
| 16384 | ** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because | ||
| 16385 | ** those functions are not available. So we use only LockFile() and | ||
| 16386 | ** UnlockFile(). | ||
| 16387 | ** | ||
| 16388 | ** LockFile() prevents not just writing but also reading by other processes. | ||
| 16389 | ** A SHARED_LOCK is obtained by locking a single randomly-chosen | ||
| 16390 | ** byte out of a specific range of bytes. The lock byte is obtained at | ||
| 16391 | ** random so two separate readers can probably access the file at the | ||
| 16392 | ** same time, unless they are unlucky and choose the same lock byte. | ||
| 16393 | ** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. | ||
| 16394 | ** There can only be one writer. A RESERVED_LOCK is obtained by locking | ||
| 16395 | ** a single byte of the file that is designated as the reserved lock byte. | ||
| 16396 | ** A PENDING_LOCK is obtained by locking a designated byte different from | ||
| 16397 | ** the RESERVED_LOCK byte. | ||
| 16398 | ** | ||
| 16399 | ** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, | ||
| 16400 | ** which means we can use reader/writer locks. When reader/writer locks | ||
| 16401 | ** are used, the lock is placed on the same range of bytes that is used | ||
| 16402 | ** for probabilistic locking in Win95/98/ME. Hence, the locking scheme | ||
| 16403 | ** will support two or more Win95 readers or two or more WinNT readers. | ||
| 16404 | ** But a single Win95 reader will lock out all WinNT readers and a single | ||
| 16405 | ** WinNT reader will lock out all other Win95 readers. | ||
| 16406 | ** | ||
| 16407 | ** The following #defines specify the range of bytes used for locking. | ||
| 16408 | ** SHARED_SIZE is the number of bytes available in the pool from which | ||
| 16409 | ** a random byte is selected for a shared lock. The pool of bytes for | ||
| 16410 | ** shared locks begins at SHARED_FIRST. | ||
| 16411 | ** | ||
| 16412 | ** The same locking strategy and | ||
| 16413 | ** byte ranges are used for Unix. This leaves open the possibility of having | ||
| 16414 | ** clients on win95, winNT, and unix all talking to the same shared file | ||
| 16415 | ** and all locking correctly. To do so would require that samba (or whatever | ||
| 16416 | ** tool is being used for file sharing) implements locks correctly between | ||
| 16417 | ** windows and unix. I'm guessing that isn't likely to happen, but by | ||
| 16418 | ** using the same locking range we are at least open to the possibility. | ||
| 16419 | ** | ||
| 16420 | ** Locking in windows is manditory. For this reason, we cannot store | ||
| 16421 | ** actual data in the bytes used for locking. The pager never allocates | ||
| 16422 | ** the pages involved in locking therefore. SHARED_SIZE is selected so | ||
| 16423 | ** that all locks will fit on a single page even at the minimum page size. | ||
| 16424 | ** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE | ||
| 16425 | ** is set high so that we don't have to allocate an unused page except | ||
| 16426 | ** for very large databases. But one should test the page skipping logic | ||
| 16427 | ** by setting PENDING_BYTE low and running the entire regression suite. | ||
| 16428 | ** | ||
| 16429 | ** Changing the value of PENDING_BYTE results in a subtly incompatible | ||
| 16430 | ** file format. Depending on how it is changed, you might not notice | ||
| 16431 | ** the incompatibility right away, even running a full regression test. | ||
| 16432 | ** The default location of PENDING_BYTE is the first byte past the | ||
| 16433 | ** 1GB boundary. | ||
| 16434 | ** | ||
| 16435 | */ | ||
| 16436 | #ifdef SQLITE_OMIT_WSD | ||
| 16437 | # define PENDING_BYTE (0x40000000) | ||
| 16438 | #else | ||
| 16439 | # define PENDING_BYTE sqlite3PendingByte | ||
| 16440 | #endif | ||
| 16441 | #define RESERVED_BYTE (PENDING_BYTE+1) | ||
| 16442 | #define SHARED_FIRST (PENDING_BYTE+2) | ||
| 16443 | #define SHARED_SIZE 510 | ||
| 16444 | |||
| 16445 | /* | ||
| 16446 | ** Wrapper around OS specific sqlite3_os_init() function. | ||
| 16447 | */ | ||
| 16448 | SQLITE_PRIVATE int sqlite3OsInit(void); | ||
| 16449 | |||
| 16450 | /* | ||
| 16451 | ** Functions for accessing sqlite3_file methods | ||
| 16452 | */ | ||
| 16453 | SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); | ||
| 16454 | SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); | ||
| 16455 | SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); | ||
| 16456 | SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); | ||
| 16457 | SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); | ||
| 16458 | SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); | ||
| 16459 | SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); | ||
| 16460 | SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); | ||
| 16461 | SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); | ||
| 16462 | SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); | ||
| 16463 | SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); | ||
| 16464 | #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 | ||
| 16465 | SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); | ||
| 16466 | SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); | ||
| 16467 | #ifndef SQLITE_OMIT_WAL | ||
| 16468 | SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); | ||
| 16469 | SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); | ||
| 16470 | SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); | ||
| 16471 | SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); | ||
| 16472 | #endif /* SQLITE_OMIT_WAL */ | ||
| 16473 | SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); | ||
| 16474 | SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); | ||
| 16475 | |||
| 16476 | |||
| 16477 | /* | ||
| 16478 | ** Functions for accessing sqlite3_vfs methods | ||
| 16479 | */ | ||
| 16480 | SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); | ||
| 16481 | SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); | ||
| 16482 | SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); | ||
| 16483 | SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); | ||
| 16484 | #ifndef SQLITE_OMIT_LOAD_EXTENSION | ||
| 16485 | SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); | ||
| 16486 | SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); | ||
| 16487 | SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); | ||
| 16488 | SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); | ||
| 16489 | #endif /* SQLITE_OMIT_LOAD_EXTENSION */ | ||
| 16490 | SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); | ||
| 16491 | SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); | ||
| 16492 | SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); | ||
| 16493 | SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); | ||
| 16494 | |||
| 16495 | /* | ||
| 16496 | ** Convenience functions for opening and closing files using | ||
| 16497 | ** sqlite3_malloc() to obtain space for the file-handle structure. | ||
| 16498 | */ | ||
| 16499 | SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); | ||
| 16500 | SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); | ||
| 16501 | |||
| 16502 | #endif /* _SQLITE_OS_H_ */ | ||
| 16503 | |||
| 16504 | /************** End of os.h **************************************************/ | ||
| 16505 | /************** Continuing where we left off in sqliteInt.h ******************/ | ||
| 16506 | /************** Include mutex.h in the middle of sqliteInt.h *****************/ | 16941 | /************** Include mutex.h in the middle of sqliteInt.h *****************/ |
| 16507 | /************** Begin file mutex.h *******************************************/ | 16942 | /************** Begin file mutex.h *******************************************/ |
| 16508 | /* | 16943 | /* |
| @@ -16591,7 +17026,7 @@ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); | |||
| 16591 | /* | 17026 | /* |
| 16592 | ** Default synchronous levels. | 17027 | ** Default synchronous levels. |
| 16593 | ** | 17028 | ** |
| 16594 | ** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ | 17029 | ** Note that (for historical reasons) the PAGER_SYNCHRONOUS_* macros differ |
| 16595 | ** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1. | 17030 | ** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1. |
| 16596 | ** | 17031 | ** |
| 16597 | ** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS | 17032 | ** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS |
| @@ -16630,7 +17065,7 @@ struct Db { | |||
| 16630 | ** An instance of the following structure stores a database schema. | 17065 | ** An instance of the following structure stores a database schema. |
| 16631 | ** | 17066 | ** |
| 16632 | ** Most Schema objects are associated with a Btree. The exception is | 17067 | ** Most Schema objects are associated with a Btree. The exception is |
| 16633 | ** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing. | 17068 | ** the Schema for the TEMP database (sqlite3.aDb[1]) which is free-standing. |
| 16634 | ** In shared cache mode, a single Schema object can be shared by multiple | 17069 | ** In shared cache mode, a single Schema object can be shared by multiple |
| 16635 | ** Btrees that refer to the same underlying BtShared object. | 17070 | ** Btrees that refer to the same underlying BtShared object. |
| 16636 | ** | 17071 | ** |
| @@ -16741,13 +17176,14 @@ struct Lookaside { | |||
| 16741 | LookasideSlot *pInit; /* List of buffers not previously used */ | 17176 | LookasideSlot *pInit; /* List of buffers not previously used */ |
| 16742 | LookasideSlot *pFree; /* List of available buffers */ | 17177 | LookasideSlot *pFree; /* List of available buffers */ |
| 16743 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE | 17178 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE |
| 16744 | LookasideSlot *pSmallInit; /* List of small buffers not prediously used */ | 17179 | LookasideSlot *pSmallInit; /* List of small buffers not previously used */ |
| 16745 | LookasideSlot *pSmallFree; /* List of available small buffers */ | 17180 | LookasideSlot *pSmallFree; /* List of available small buffers */ |
| 16746 | void *pMiddle; /* First byte past end of full-size buffers and | 17181 | void *pMiddle; /* First byte past end of full-size buffers and |
| 16747 | ** the first byte of LOOKASIDE_SMALL buffers */ | 17182 | ** the first byte of LOOKASIDE_SMALL buffers */ |
| 16748 | #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ | 17183 | #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ |
| 16749 | void *pStart; /* First byte of available memory space */ | 17184 | void *pStart; /* First byte of available memory space */ |
| 16750 | void *pEnd; /* First byte past end of available space */ | 17185 | void *pEnd; /* First byte past end of available space */ |
| 17186 | void *pTrueEnd; /* True value of pEnd, when db->pnBytesFreed!=0 */ | ||
| 16751 | }; | 17187 | }; |
| 16752 | struct LookasideSlot { | 17188 | struct LookasideSlot { |
| 16753 | LookasideSlot *pNext; /* Next buffer in the list of free buffers */ | 17189 | LookasideSlot *pNext; /* Next buffer in the list of free buffers */ |
| @@ -16757,7 +17193,7 @@ struct LookasideSlot { | |||
| 16757 | #define EnableLookaside db->lookaside.bDisable--;\ | 17193 | #define EnableLookaside db->lookaside.bDisable--;\ |
| 16758 | db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue | 17194 | db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue |
| 16759 | 17195 | ||
| 16760 | /* Size of the smaller allocations in two-size lookside */ | 17196 | /* Size of the smaller allocations in two-size lookaside */ |
| 16761 | #ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE | 17197 | #ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE |
| 16762 | # define LOOKASIDE_SMALL 0 | 17198 | # define LOOKASIDE_SMALL 0 |
| 16763 | #else | 17199 | #else |
| @@ -17012,7 +17448,7 @@ struct sqlite3 { | |||
| 17012 | #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ | 17448 | #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ |
| 17013 | /* result set is empty */ | 17449 | /* result set is empty */ |
| 17014 | #define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ | 17450 | #define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ |
| 17015 | #define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */ | 17451 | #define SQLITE_StmtScanStatus 0x00000400 /* Enable stmt_scanstats() counters */ |
| 17016 | #define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */ | 17452 | #define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */ |
| 17017 | #define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */ | 17453 | #define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */ |
| 17018 | #define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */ | 17454 | #define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */ |
| @@ -17038,6 +17474,7 @@ struct sqlite3 { | |||
| 17038 | /* DELETE, or UPDATE and return */ | 17474 | /* DELETE, or UPDATE and return */ |
| 17039 | /* the count using a callback. */ | 17475 | /* the count using a callback. */ |
| 17040 | #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ | 17476 | #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ |
| 17477 | #define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */ | ||
| 17041 | 17478 | ||
| 17042 | /* Flags used only if debugging */ | 17479 | /* Flags used only if debugging */ |
| 17043 | #ifdef SQLITE_DEBUG | 17480 | #ifdef SQLITE_DEBUG |
| @@ -17092,6 +17529,10 @@ struct sqlite3 { | |||
| 17092 | #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ | 17529 | #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ |
| 17093 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ | 17530 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ |
| 17094 | /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ | 17531 | /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ |
| 17532 | #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ | ||
| 17533 | #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ | ||
| 17534 | #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ | ||
| 17535 | #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ | ||
| 17095 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ | 17536 | #define SQLITE_AllOpts 0xffffffff /* All optimizations */ |
| 17096 | 17537 | ||
| 17097 | /* | 17538 | /* |
| @@ -17174,10 +17615,17 @@ struct FuncDestructor { | |||
| 17174 | ** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd | 17615 | ** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd |
| 17175 | ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG | 17616 | ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG |
| 17176 | ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG | 17617 | ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG |
| 17618 | ** SQLITE_FUNC_BYTELEN == OPFLAG_BYTELENARG | ||
| 17177 | ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API | 17619 | ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API |
| 17178 | ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API | 17620 | ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API |
| 17179 | ** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS | 17621 | ** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS -- opposite meanings!!! |
| 17180 | ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API | 17622 | ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API |
| 17623 | ** | ||
| 17624 | ** Note that even though SQLITE_FUNC_UNSAFE and SQLITE_INNOCUOUS have the | ||
| 17625 | ** same bit value, their meanings are inverted. SQLITE_FUNC_UNSAFE is | ||
| 17626 | ** used internally and if set means that the function has side effects. | ||
| 17627 | ** SQLITE_INNOCUOUS is used by application code and means "not unsafe". | ||
| 17628 | ** See multiple instances of tag-20230109-1. | ||
| 17181 | */ | 17629 | */ |
| 17182 | #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ | 17630 | #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ |
| 17183 | #define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ | 17631 | #define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ |
| @@ -17186,6 +17634,7 @@ struct FuncDestructor { | |||
| 17186 | #define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ | 17634 | #define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ |
| 17187 | #define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ | 17635 | #define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ |
| 17188 | #define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ | 17636 | #define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ |
| 17637 | #define SQLITE_FUNC_BYTELEN 0x00c0 /* Built-in octet_length() function */ | ||
| 17189 | #define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ | 17638 | #define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ |
| 17190 | /* 0x0200 -- available for reuse */ | 17639 | /* 0x0200 -- available for reuse */ |
| 17191 | #define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */ | 17640 | #define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */ |
| @@ -17294,7 +17743,7 @@ struct FuncDestructor { | |||
| 17294 | {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ | 17743 | {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ |
| 17295 | xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } | 17744 | xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } |
| 17296 | #define JFUNCTION(zName, nArg, iArg, xFunc) \ | 17745 | #define JFUNCTION(zName, nArg, iArg, xFunc) \ |
| 17297 | {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|\ | 17746 | {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|\ |
| 17298 | SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ | 17747 | SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ |
| 17299 | SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } | 17748 | SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } |
| 17300 | #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ | 17749 | #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ |
| @@ -17486,6 +17935,7 @@ struct CollSeq { | |||
| 17486 | #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ | 17935 | #define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ |
| 17487 | #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ | 17936 | #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ |
| 17488 | #define SQLITE_AFF_REAL 0x45 /* 'E' */ | 17937 | #define SQLITE_AFF_REAL 0x45 /* 'E' */ |
| 17938 | #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ | ||
| 17489 | 17939 | ||
| 17490 | #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) | 17940 | #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) |
| 17491 | 17941 | ||
| @@ -17556,6 +18006,7 @@ struct VTable { | |||
| 17556 | sqlite3_vtab *pVtab; /* Pointer to vtab instance */ | 18006 | sqlite3_vtab *pVtab; /* Pointer to vtab instance */ |
| 17557 | int nRef; /* Number of pointers to this structure */ | 18007 | int nRef; /* Number of pointers to this structure */ |
| 17558 | u8 bConstraint; /* True if constraints are supported */ | 18008 | u8 bConstraint; /* True if constraints are supported */ |
| 18009 | u8 bAllSchemas; /* True if might use any attached schema */ | ||
| 17559 | u8 eVtabRisk; /* Riskiness of allowing hacker access */ | 18010 | u8 eVtabRisk; /* Riskiness of allowing hacker access */ |
| 17560 | int iSavepoint; /* Depth of the SAVEPOINT stack */ | 18011 | int iSavepoint; /* Depth of the SAVEPOINT stack */ |
| 17561 | VTable *pNext; /* Next in linked list (see above) */ | 18012 | VTable *pNext; /* Next in linked list (see above) */ |
| @@ -17664,7 +18115,7 @@ struct Table { | |||
| 17664 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 18115 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 17665 | # define IsVirtual(X) ((X)->eTabType==TABTYP_VTAB) | 18116 | # define IsVirtual(X) ((X)->eTabType==TABTYP_VTAB) |
| 17666 | # define ExprIsVtab(X) \ | 18117 | # define ExprIsVtab(X) \ |
| 17667 | ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->eTabType==TABTYP_VTAB) | 18118 | ((X)->op==TK_COLUMN && (X)->y.pTab->eTabType==TABTYP_VTAB) |
| 17668 | #else | 18119 | #else |
| 17669 | # define IsVirtual(X) 0 | 18120 | # define IsVirtual(X) 0 |
| 17670 | # define ExprIsVtab(X) 0 | 18121 | # define ExprIsVtab(X) 0 |
| @@ -17763,7 +18214,7 @@ struct FKey { | |||
| 17763 | ** foreign key. | 18214 | ** foreign key. |
| 17764 | ** | 18215 | ** |
| 17765 | ** The OE_Default value is a place holder that means to use whatever | 18216 | ** The OE_Default value is a place holder that means to use whatever |
| 17766 | ** conflict resolution algorthm is required from context. | 18217 | ** conflict resolution algorithm is required from context. |
| 17767 | ** | 18218 | ** |
| 17768 | ** The following symbolic values are used to record which type | 18219 | ** The following symbolic values are used to record which type |
| 17769 | ** of conflict resolution action to take. | 18220 | ** of conflict resolution action to take. |
| @@ -17881,10 +18332,22 @@ struct UnpackedRecord { | |||
| 17881 | ** The Index.onError field determines whether or not the indexed columns | 18332 | ** The Index.onError field determines whether or not the indexed columns |
| 17882 | ** must be unique and what to do if they are not. When Index.onError=OE_None, | 18333 | ** must be unique and what to do if they are not. When Index.onError=OE_None, |
| 17883 | ** it means this is not a unique index. Otherwise it is a unique index | 18334 | ** it means this is not a unique index. Otherwise it is a unique index |
| 17884 | ** and the value of Index.onError indicate the which conflict resolution | 18335 | ** and the value of Index.onError indicates which conflict resolution |
| 17885 | ** algorithm to employ whenever an attempt is made to insert a non-unique | 18336 | ** algorithm to employ when an attempt is made to insert a non-unique |
| 17886 | ** element. | 18337 | ** element. |
| 17887 | ** | 18338 | ** |
| 18339 | ** The colNotIdxed bitmask is used in combination with SrcItem.colUsed | ||
| 18340 | ** for a fast test to see if an index can serve as a covering index. | ||
| 18341 | ** colNotIdxed has a 1 bit for every column of the original table that | ||
| 18342 | ** is *not* available in the index. Thus the expression | ||
| 18343 | ** "colUsed & colNotIdxed" will be non-zero if the index is not a | ||
| 18344 | ** covering index. The most significant bit of of colNotIdxed will always | ||
| 18345 | ** be true (note-20221022-a). If a column beyond the 63rd column of the | ||
| 18346 | ** table is used, the "colUsed & colNotIdxed" test will always be non-zero | ||
| 18347 | ** and we have to assume either that the index is not covering, or use | ||
| 18348 | ** an alternative (slower) algorithm to determine whether or not | ||
| 18349 | ** the index is covering. | ||
| 18350 | ** | ||
| 17888 | ** While parsing a CREATE TABLE or CREATE INDEX statement in order to | 18351 | ** While parsing a CREATE TABLE or CREATE INDEX statement in order to |
| 17889 | ** generate VDBE code (as opposed to parsing one read from an sqlite_schema | 18352 | ** generate VDBE code (as opposed to parsing one read from an sqlite_schema |
| 17890 | ** table as part of parsing an existing database schema), transient instances | 18353 | ** table as part of parsing an existing database schema), transient instances |
| @@ -17920,15 +18383,18 @@ struct Index { | |||
| 17920 | unsigned bNoQuery:1; /* Do not use this index to optimize queries */ | 18383 | unsigned bNoQuery:1; /* Do not use this index to optimize queries */ |
| 17921 | unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ | 18384 | unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ |
| 17922 | unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ | 18385 | unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ |
| 18386 | unsigned bHasExpr:1; /* Index contains an expression, either a literal | ||
| 18387 | ** expression, or a reference to a VIRTUAL column */ | ||
| 17923 | #ifdef SQLITE_ENABLE_STAT4 | 18388 | #ifdef SQLITE_ENABLE_STAT4 |
| 17924 | int nSample; /* Number of elements in aSample[] */ | 18389 | int nSample; /* Number of elements in aSample[] */ |
| 18390 | int mxSample; /* Number of slots allocated to aSample[] */ | ||
| 17925 | int nSampleCol; /* Size of IndexSample.anEq[] and so on */ | 18391 | int nSampleCol; /* Size of IndexSample.anEq[] and so on */ |
| 17926 | tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ | 18392 | tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ |
| 17927 | IndexSample *aSample; /* Samples of the left-most key */ | 18393 | IndexSample *aSample; /* Samples of the left-most key */ |
| 17928 | tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ | 18394 | tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ |
| 17929 | tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ | 18395 | tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ |
| 17930 | #endif | 18396 | #endif |
| 17931 | Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */ | 18397 | Bitmask colNotIdxed; /* Unindexed columns in pTab */ |
| 17932 | }; | 18398 | }; |
| 17933 | 18399 | ||
| 17934 | /* | 18400 | /* |
| @@ -18003,16 +18469,15 @@ struct AggInfo { | |||
| 18003 | ** from source tables rather than from accumulators */ | 18469 | ** from source tables rather than from accumulators */ |
| 18004 | u8 useSortingIdx; /* In direct mode, reference the sorting index rather | 18470 | u8 useSortingIdx; /* In direct mode, reference the sorting index rather |
| 18005 | ** than the source table */ | 18471 | ** than the source table */ |
| 18472 | u16 nSortingColumn; /* Number of columns in the sorting index */ | ||
| 18006 | int sortingIdx; /* Cursor number of the sorting index */ | 18473 | int sortingIdx; /* Cursor number of the sorting index */ |
| 18007 | int sortingIdxPTab; /* Cursor number of pseudo-table */ | 18474 | int sortingIdxPTab; /* Cursor number of pseudo-table */ |
| 18008 | int nSortingColumn; /* Number of columns in the sorting index */ | 18475 | int iFirstReg; /* First register in range for aCol[] and aFunc[] */ |
| 18009 | int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */ | ||
| 18010 | ExprList *pGroupBy; /* The group by clause */ | 18476 | ExprList *pGroupBy; /* The group by clause */ |
| 18011 | struct AggInfo_col { /* For each column used in source tables */ | 18477 | struct AggInfo_col { /* For each column used in source tables */ |
| 18012 | Table *pTab; /* Source table */ | 18478 | Table *pTab; /* Source table */ |
| 18013 | Expr *pCExpr; /* The original expression */ | 18479 | Expr *pCExpr; /* The original expression */ |
| 18014 | int iTable; /* Cursor number of the source table */ | 18480 | int iTable; /* Cursor number of the source table */ |
| 18015 | int iMem; /* Memory location that acts as accumulator */ | ||
| 18016 | i16 iColumn; /* Column number within the source table */ | 18481 | i16 iColumn; /* Column number within the source table */ |
| 18017 | i16 iSorterColumn; /* Column number in the sorting index */ | 18482 | i16 iSorterColumn; /* Column number in the sorting index */ |
| 18018 | } *aCol; | 18483 | } *aCol; |
| @@ -18023,15 +18488,28 @@ struct AggInfo { | |||
| 18023 | struct AggInfo_func { /* For each aggregate function */ | 18488 | struct AggInfo_func { /* For each aggregate function */ |
| 18024 | Expr *pFExpr; /* Expression encoding the function */ | 18489 | Expr *pFExpr; /* Expression encoding the function */ |
| 18025 | FuncDef *pFunc; /* The aggregate function implementation */ | 18490 | FuncDef *pFunc; /* The aggregate function implementation */ |
| 18026 | int iMem; /* Memory location that acts as accumulator */ | ||
| 18027 | int iDistinct; /* Ephemeral table used to enforce DISTINCT */ | 18491 | int iDistinct; /* Ephemeral table used to enforce DISTINCT */ |
| 18028 | int iDistAddr; /* Address of OP_OpenEphemeral */ | 18492 | int iDistAddr; /* Address of OP_OpenEphemeral */ |
| 18029 | } *aFunc; | 18493 | } *aFunc; |
| 18030 | int nFunc; /* Number of entries in aFunc[] */ | 18494 | int nFunc; /* Number of entries in aFunc[] */ |
| 18031 | u32 selId; /* Select to which this AggInfo belongs */ | 18495 | u32 selId; /* Select to which this AggInfo belongs */ |
| 18496 | #ifdef SQLITE_DEBUG | ||
| 18497 | Select *pSelect; /* SELECT statement that this AggInfo supports */ | ||
| 18498 | #endif | ||
| 18032 | }; | 18499 | }; |
| 18033 | 18500 | ||
| 18034 | /* | 18501 | /* |
| 18502 | ** Macros to compute aCol[] and aFunc[] register numbers. | ||
| 18503 | ** | ||
| 18504 | ** These macros should not be used prior to the call to | ||
| 18505 | ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. | ||
| 18506 | ** The assert()s that are part of this macro verify that constraint. | ||
| 18507 | */ | ||
| 18508 | #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) | ||
| 18509 | #define AggInfoFuncReg(A,I) \ | ||
| 18510 | (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) | ||
| 18511 | |||
| 18512 | /* | ||
| 18035 | ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. | 18513 | ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. |
| 18036 | ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater | 18514 | ** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater |
| 18037 | ** than 32767 we have to make it 32-bit. 16-bit is preferred because | 18515 | ** than 32767 we have to make it 32-bit. 16-bit is preferred because |
| @@ -18150,7 +18628,7 @@ struct Expr { | |||
| 18150 | ** TK_REGISTER: register number | 18628 | ** TK_REGISTER: register number |
| 18151 | ** TK_TRIGGER: 1 -> new, 0 -> old | 18629 | ** TK_TRIGGER: 1 -> new, 0 -> old |
| 18152 | ** EP_Unlikely: 134217728 times likelihood | 18630 | ** EP_Unlikely: 134217728 times likelihood |
| 18153 | ** TK_IN: ephemerial table holding RHS | 18631 | ** TK_IN: ephemeral table holding RHS |
| 18154 | ** TK_SELECT_COLUMN: Number of columns on the LHS | 18632 | ** TK_SELECT_COLUMN: Number of columns on the LHS |
| 18155 | ** TK_SELECT: 1st register of result vector */ | 18633 | ** TK_SELECT: 1st register of result vector */ |
| 18156 | ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. | 18634 | ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. |
| @@ -18196,7 +18674,7 @@ struct Expr { | |||
| 18196 | #define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ | 18674 | #define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ |
| 18197 | #define EP_Win 0x008000 /* Contains window functions */ | 18675 | #define EP_Win 0x008000 /* Contains window functions */ |
| 18198 | #define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ | 18676 | #define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ |
| 18199 | #define EP_MemToken 0x020000 /* Need to sqlite3DbFree() Expr.zToken */ | 18677 | /* 0x020000 // Available for reuse */ |
| 18200 | #define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */ | 18678 | #define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */ |
| 18201 | #define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */ | 18679 | #define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */ |
| 18202 | #define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ | 18680 | #define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ |
| @@ -18232,6 +18710,8 @@ struct Expr { | |||
| 18232 | */ | 18710 | */ |
| 18233 | #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) | 18711 | #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) |
| 18234 | #define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0) | 18712 | #define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0) |
| 18713 | #define ExprUseWOfst(E) (((E)->flags&(EP_InnerON|EP_OuterON))==0) | ||
| 18714 | #define ExprUseWJoin(E) (((E)->flags&(EP_InnerON|EP_OuterON))!=0) | ||
| 18235 | #define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0) | 18715 | #define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0) |
| 18236 | #define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0) | 18716 | #define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0) |
| 18237 | #define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0) | 18717 | #define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0) |
| @@ -18381,6 +18861,14 @@ struct IdList { | |||
| 18381 | ** The SrcItem object represents a single term in the FROM clause of a query. | 18861 | ** The SrcItem object represents a single term in the FROM clause of a query. |
| 18382 | ** The SrcList object is mostly an array of SrcItems. | 18862 | ** The SrcList object is mostly an array of SrcItems. |
| 18383 | ** | 18863 | ** |
| 18864 | ** The jointype starts out showing the join type between the current table | ||
| 18865 | ** and the next table on the list. The parser builds the list this way. | ||
| 18866 | ** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each | ||
| 18867 | ** jointype expresses the join between the table and the previous table. | ||
| 18868 | ** | ||
| 18869 | ** In the colUsed field, the high-order bit (bit 63) is set if the table | ||
| 18870 | ** contains more than 63 columns and the 64-th or later column is used. | ||
| 18871 | ** | ||
| 18384 | ** Union member validity: | 18872 | ** Union member validity: |
| 18385 | ** | 18873 | ** |
| 18386 | ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc | 18874 | ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc |
| @@ -18412,7 +18900,7 @@ struct SrcItem { | |||
| 18412 | unsigned notCte :1; /* This item may not match a CTE */ | 18900 | unsigned notCte :1; /* This item may not match a CTE */ |
| 18413 | unsigned isUsing :1; /* u3.pUsing is valid */ | 18901 | unsigned isUsing :1; /* u3.pUsing is valid */ |
| 18414 | unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ | 18902 | unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ |
| 18415 | unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */ | 18903 | unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ |
| 18416 | unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ | 18904 | unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ |
| 18417 | } fg; | 18905 | } fg; |
| 18418 | int iCursor; /* The VDBE cursor number used to access this table */ | 18906 | int iCursor; /* The VDBE cursor number used to access this table */ |
| @@ -18420,14 +18908,14 @@ struct SrcItem { | |||
| 18420 | Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ | 18908 | Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ |
| 18421 | IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ | 18909 | IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ |
| 18422 | } u3; | 18910 | } u3; |
| 18423 | Bitmask colUsed; /* Bit N (1<<N) set if column N of pTab is used */ | 18911 | Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ |
| 18424 | union { | 18912 | union { |
| 18425 | char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ | 18913 | char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */ |
| 18426 | ExprList *pFuncArg; /* Arguments to table-valued-function */ | 18914 | ExprList *pFuncArg; /* Arguments to table-valued-function */ |
| 18427 | } u1; | 18915 | } u1; |
| 18428 | union { | 18916 | union { |
| 18429 | Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ | 18917 | Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ |
| 18430 | CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */ | 18918 | CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ |
| 18431 | } u2; | 18919 | } u2; |
| 18432 | }; | 18920 | }; |
| 18433 | 18921 | ||
| @@ -18441,23 +18929,11 @@ struct OnOrUsing { | |||
| 18441 | }; | 18929 | }; |
| 18442 | 18930 | ||
| 18443 | /* | 18931 | /* |
| 18444 | ** The following structure describes the FROM clause of a SELECT statement. | 18932 | ** This object represents one or more tables that are the source of |
| 18445 | ** Each table or subquery in the FROM clause is a separate element of | 18933 | ** content for an SQL statement. For example, a single SrcList object |
| 18446 | ** the SrcList.a[] array. | 18934 | ** is used to hold the FROM clause of a SELECT statement. SrcList also |
| 18447 | ** | 18935 | ** represents the target tables for DELETE, INSERT, and UPDATE statements. |
| 18448 | ** With the addition of multiple database support, the following structure | ||
| 18449 | ** can also be used to describe a particular table such as the table that | ||
| 18450 | ** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL, | ||
| 18451 | ** such a table must be a simple name: ID. But in SQLite, the table can | ||
| 18452 | ** now be identified by a database name, a dot, then the table name: ID.ID. | ||
| 18453 | ** | 18936 | ** |
| 18454 | ** The jointype starts out showing the join type between the current table | ||
| 18455 | ** and the next table on the list. The parser builds the list this way. | ||
| 18456 | ** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each | ||
| 18457 | ** jointype expresses the join between the table and the previous table. | ||
| 18458 | ** | ||
| 18459 | ** In the colUsed field, the high-order bit (bit 63) is set if the table | ||
| 18460 | ** contains more than 63 columns and the 64-th or later column is used. | ||
| 18461 | */ | 18937 | */ |
| 18462 | struct SrcList { | 18938 | struct SrcList { |
| 18463 | int nSrc; /* Number of tables or subqueries in the FROM clause */ | 18939 | int nSrc; /* Number of tables or subqueries in the FROM clause */ |
| @@ -18565,7 +19041,7 @@ struct NameContext { | |||
| 18565 | #define NC_HasAgg 0x000010 /* One or more aggregate functions seen */ | 19041 | #define NC_HasAgg 0x000010 /* One or more aggregate functions seen */ |
| 18566 | #define NC_IdxExpr 0x000020 /* True if resolving columns of CREATE INDEX */ | 19042 | #define NC_IdxExpr 0x000020 /* True if resolving columns of CREATE INDEX */ |
| 18567 | #define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ | 19043 | #define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ |
| 18568 | #define NC_VarSelect 0x000040 /* A correlated subquery has been seen */ | 19044 | #define NC_Subquery 0x000040 /* A subquery has been seen */ |
| 18569 | #define NC_UEList 0x000080 /* True if uNC.pEList is used */ | 19045 | #define NC_UEList 0x000080 /* True if uNC.pEList is used */ |
| 18570 | #define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ | 19046 | #define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ |
| 18571 | #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ | 19047 | #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ |
| @@ -18694,6 +19170,7 @@ struct Select { | |||
| 18694 | #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ | 19170 | #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ |
| 18695 | #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ | 19171 | #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ |
| 18696 | #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ | 19172 | #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ |
| 19173 | #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ | ||
| 18697 | 19174 | ||
| 18698 | /* True if S exists and has SF_NestedFrom */ | 19175 | /* True if S exists and has SF_NestedFrom */ |
| 18699 | #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) | 19176 | #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) |
| @@ -18802,7 +19279,7 @@ struct SelectDest { | |||
| 18802 | int iSDParm2; /* A second parameter for the eDest disposal method */ | 19279 | int iSDParm2; /* A second parameter for the eDest disposal method */ |
| 18803 | int iSdst; /* Base register where results are written */ | 19280 | int iSdst; /* Base register where results are written */ |
| 18804 | int nSdst; /* Number of registers allocated */ | 19281 | int nSdst; /* Number of registers allocated */ |
| 18805 | char *zAffSdst; /* Affinity used when eDest==SRT_Set */ | 19282 | char *zAffSdst; /* Affinity used for SRT_Set */ |
| 18806 | ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */ | 19283 | ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */ |
| 18807 | }; | 19284 | }; |
| 18808 | 19285 | ||
| @@ -18861,11 +19338,34 @@ struct TriggerPrg { | |||
| 18861 | #else | 19338 | #else |
| 18862 | typedef unsigned int yDbMask; | 19339 | typedef unsigned int yDbMask; |
| 18863 | # define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) | 19340 | # define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) |
| 18864 | # define DbMaskZero(M) (M)=0 | 19341 | # define DbMaskZero(M) ((M)=0) |
| 18865 | # define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I)) | 19342 | # define DbMaskSet(M,I) ((M)|=(((yDbMask)1)<<(I))) |
| 18866 | # define DbMaskAllZero(M) (M)==0 | 19343 | # define DbMaskAllZero(M) ((M)==0) |
| 18867 | # define DbMaskNonZero(M) (M)!=0 | 19344 | # define DbMaskNonZero(M) ((M)!=0) |
| 19345 | #endif | ||
| 19346 | |||
| 19347 | /* | ||
| 19348 | ** For each index X that has as one of its arguments either an expression | ||
| 19349 | ** or the name of a virtual generated column, and if X is in scope such that | ||
| 19350 | ** the value of the expression can simply be read from the index, then | ||
| 19351 | ** there is an instance of this object on the Parse.pIdxExpr list. | ||
| 19352 | ** | ||
| 19353 | ** During code generation, while generating code to evaluate expressions, | ||
| 19354 | ** this list is consulted and if a matching expression is found, the value | ||
| 19355 | ** is read from the index rather than being recomputed. | ||
| 19356 | */ | ||
| 19357 | struct IndexedExpr { | ||
| 19358 | Expr *pExpr; /* The expression contained in the index */ | ||
| 19359 | int iDataCur; /* The data cursor associated with the index */ | ||
| 19360 | int iIdxCur; /* The index cursor */ | ||
| 19361 | int iIdxCol; /* The index column that contains value of pExpr */ | ||
| 19362 | u8 bMaybeNullRow; /* True if we need an OP_IfNullRow check */ | ||
| 19363 | u8 aff; /* Affinity of the pExpr expression */ | ||
| 19364 | IndexedExpr *pIENext; /* Next in a list of all indexed expressions */ | ||
| 19365 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS | ||
| 19366 | const char *zIdxName; /* Name of index, used only for bytecode comments */ | ||
| 18868 | #endif | 19367 | #endif |
| 19368 | }; | ||
| 18869 | 19369 | ||
| 18870 | /* | 19370 | /* |
| 18871 | ** An instance of the ParseCleanup object specifies an operation that | 19371 | ** An instance of the ParseCleanup object specifies an operation that |
| @@ -18908,11 +19408,14 @@ struct Parse { | |||
| 18908 | u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ | 19408 | u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ |
| 18909 | u8 okConstFactor; /* OK to factor out constants */ | 19409 | u8 okConstFactor; /* OK to factor out constants */ |
| 18910 | u8 disableLookaside; /* Number of times lookaside has been disabled */ | 19410 | u8 disableLookaside; /* Number of times lookaside has been disabled */ |
| 18911 | u8 disableVtab; /* Disable all virtual tables for this parse */ | 19411 | u8 prepFlags; /* SQLITE_PREPARE_* flags */ |
| 18912 | u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ | 19412 | u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ |
| 18913 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) | 19413 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) |
| 18914 | u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ | 19414 | u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ |
| 18915 | #endif | 19415 | #endif |
| 19416 | #ifdef SQLITE_DEBUG | ||
| 19417 | u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */ | ||
| 19418 | #endif | ||
| 18916 | int nRangeReg; /* Size of the temporary register block */ | 19419 | int nRangeReg; /* Size of the temporary register block */ |
| 18917 | int iRangeReg; /* First register in temporary register block */ | 19420 | int iRangeReg; /* First register in temporary register block */ |
| 18918 | int nErr; /* Number of errors seen */ | 19421 | int nErr; /* Number of errors seen */ |
| @@ -18925,6 +19428,7 @@ struct Parse { | |||
| 18925 | int nLabelAlloc; /* Number of slots in aLabel */ | 19428 | int nLabelAlloc; /* Number of slots in aLabel */ |
| 18926 | int *aLabel; /* Space to hold the labels */ | 19429 | int *aLabel; /* Space to hold the labels */ |
| 18927 | ExprList *pConstExpr;/* Constant expressions */ | 19430 | ExprList *pConstExpr;/* Constant expressions */ |
| 19431 | IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ | ||
| 18928 | Token constraintName;/* Name of the constraint currently being parsed */ | 19432 | Token constraintName;/* Name of the constraint currently being parsed */ |
| 18929 | yDbMask writeMask; /* Start a write transaction on these databases */ | 19433 | yDbMask writeMask; /* Start a write transaction on these databases */ |
| 18930 | yDbMask cookieMask; /* Bitmask of schema verified databases */ | 19434 | yDbMask cookieMask; /* Bitmask of schema verified databases */ |
| @@ -18932,6 +19436,9 @@ struct Parse { | |||
| 18932 | int regRoot; /* Register holding root page number for new objects */ | 19436 | int regRoot; /* Register holding root page number for new objects */ |
| 18933 | int nMaxArg; /* Max args passed to user function by sub-program */ | 19437 | int nMaxArg; /* Max args passed to user function by sub-program */ |
| 18934 | int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ | 19438 | int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ |
| 19439 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | ||
| 19440 | u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ | ||
| 19441 | #endif | ||
| 18935 | #ifndef SQLITE_OMIT_SHARED_CACHE | 19442 | #ifndef SQLITE_OMIT_SHARED_CACHE |
| 18936 | int nTableLock; /* Number of locks in aTableLock */ | 19443 | int nTableLock; /* Number of locks in aTableLock */ |
| 18937 | TableLock *aTableLock; /* Required table locks for shared-cache mode */ | 19444 | TableLock *aTableLock; /* Required table locks for shared-cache mode */ |
| @@ -18945,9 +19452,9 @@ struct Parse { | |||
| 18945 | int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ | 19452 | int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ |
| 18946 | Returning *pReturning; /* The RETURNING clause */ | 19453 | Returning *pReturning; /* The RETURNING clause */ |
| 18947 | } u1; | 19454 | } u1; |
| 18948 | u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ | ||
| 18949 | u32 oldmask; /* Mask of old.* columns referenced */ | 19455 | u32 oldmask; /* Mask of old.* columns referenced */ |
| 18950 | u32 newmask; /* Mask of new.* columns referenced */ | 19456 | u32 newmask; /* Mask of new.* columns referenced */ |
| 19457 | LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ | ||
| 18951 | u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ | 19458 | u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ |
| 18952 | u8 bReturning; /* Coding a RETURNING trigger */ | 19459 | u8 bReturning; /* Coding a RETURNING trigger */ |
| 18953 | u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ | 19460 | u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ |
| @@ -19071,6 +19578,7 @@ struct AuthContext { | |||
| 19071 | #define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ | 19578 | #define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ |
| 19072 | #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ | 19579 | #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ |
| 19073 | #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ | 19580 | #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ |
| 19581 | #define OPFLAG_BYTELENARG 0xc0 /* OP_Column only for octet_length() */ | ||
| 19074 | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ | 19582 | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ |
| 19075 | #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ | 19583 | #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ |
| 19076 | #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ | 19584 | #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ |
| @@ -19213,6 +19721,25 @@ struct sqlite3_str { | |||
| 19213 | 19721 | ||
| 19214 | #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) | 19722 | #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) |
| 19215 | 19723 | ||
| 19724 | /* | ||
| 19725 | ** The following object is the header for an "RCStr" or "reference-counted | ||
| 19726 | ** string". An RCStr is passed around and used like any other char* | ||
| 19727 | ** that has been dynamically allocated. The important interface | ||
| 19728 | ** differences: | ||
| 19729 | ** | ||
| 19730 | ** 1. RCStr strings are reference counted. They are deallocated | ||
| 19731 | ** when the reference count reaches zero. | ||
| 19732 | ** | ||
| 19733 | ** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than | ||
| 19734 | ** sqlite3_free() | ||
| 19735 | ** | ||
| 19736 | ** 3. Make a (read-only) copy of a read-only RCStr string using | ||
| 19737 | ** sqlite3RCStrRef(). | ||
| 19738 | */ | ||
| 19739 | struct RCStr { | ||
| 19740 | u64 nRCRef; /* Number of references */ | ||
| 19741 | /* Total structure size should be a multiple of 8 bytes for alignment */ | ||
| 19742 | }; | ||
| 19216 | 19743 | ||
| 19217 | /* | 19744 | /* |
| 19218 | ** A pointer to this structure is used to communicate information | 19745 | ** A pointer to this structure is used to communicate information |
| @@ -19239,7 +19766,7 @@ typedef struct { | |||
| 19239 | /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled | 19766 | /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled |
| 19240 | ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning | 19767 | ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning |
| 19241 | ** parameters are for temporary use during development, to help find | 19768 | ** parameters are for temporary use during development, to help find |
| 19242 | ** optimial values for parameters in the query planner. The should not | 19769 | ** optimal values for parameters in the query planner. The should not |
| 19243 | ** be used on trunk check-ins. They are a temporary mechanism available | 19770 | ** be used on trunk check-ins. They are a temporary mechanism available |
| 19244 | ** for transient development builds only. | 19771 | ** for transient development builds only. |
| 19245 | ** | 19772 | ** |
| @@ -19265,6 +19792,7 @@ struct Sqlite3Config { | |||
| 19265 | u8 bUseCis; /* Use covering indices for full-scans */ | 19792 | u8 bUseCis; /* Use covering indices for full-scans */ |
| 19266 | u8 bSmallMalloc; /* Avoid large memory allocations if true */ | 19793 | u8 bSmallMalloc; /* Avoid large memory allocations if true */ |
| 19267 | u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ | 19794 | u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ |
| 19795 | u8 bUseLongDouble; /* Make use of long double */ | ||
| 19268 | int mxStrlen; /* Maximum string length */ | 19796 | int mxStrlen; /* Maximum string length */ |
| 19269 | int neverCorrupt; /* Database is always well-formed */ | 19797 | int neverCorrupt; /* Database is always well-formed */ |
| 19270 | int szLookaside; /* Default lookaside buffer size */ | 19798 | int szLookaside; /* Default lookaside buffer size */ |
| @@ -19351,6 +19879,7 @@ struct Walker { | |||
| 19351 | void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ | 19879 | void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ |
| 19352 | int walkerDepth; /* Number of subqueries */ | 19880 | int walkerDepth; /* Number of subqueries */ |
| 19353 | u16 eCode; /* A small processing code */ | 19881 | u16 eCode; /* A small processing code */ |
| 19882 | u16 mWFlags; /* Use-dependent flags */ | ||
| 19354 | union { /* Extra data for callback */ | 19883 | union { /* Extra data for callback */ |
| 19355 | NameContext *pNC; /* Naming context */ | 19884 | NameContext *pNC; /* Naming context */ |
| 19356 | int n; /* A counter */ | 19885 | int n; /* A counter */ |
| @@ -19360,15 +19889,16 @@ struct Walker { | |||
| 19360 | struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ | 19889 | struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ |
| 19361 | int *aiCol; /* array of column indexes */ | 19890 | int *aiCol; /* array of column indexes */ |
| 19362 | struct IdxCover *pIdxCover; /* Check for index coverage */ | 19891 | struct IdxCover *pIdxCover; /* Check for index coverage */ |
| 19363 | struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */ | ||
| 19364 | ExprList *pGroupBy; /* GROUP BY clause */ | 19892 | ExprList *pGroupBy; /* GROUP BY clause */ |
| 19365 | Select *pSelect; /* HAVING to WHERE clause ctx */ | 19893 | Select *pSelect; /* HAVING to WHERE clause ctx */ |
| 19366 | struct WindowRewrite *pRewrite; /* Window rewrite context */ | 19894 | struct WindowRewrite *pRewrite; /* Window rewrite context */ |
| 19367 | struct WhereConst *pConst; /* WHERE clause constants */ | 19895 | struct WhereConst *pConst; /* WHERE clause constants */ |
| 19368 | struct RenameCtx *pRename; /* RENAME COLUMN context */ | 19896 | struct RenameCtx *pRename; /* RENAME COLUMN context */ |
| 19369 | struct Table *pTab; /* Table of generated column */ | 19897 | struct Table *pTab; /* Table of generated column */ |
| 19898 | struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ | ||
| 19370 | SrcItem *pSrcItem; /* A single FROM clause item */ | 19899 | SrcItem *pSrcItem; /* A single FROM clause item */ |
| 19371 | DbFixer *pFix; | 19900 | DbFixer *pFix; /* See sqlite3FixSelect() */ |
| 19901 | Mem *aMem; /* See sqlite3BtreeCursorHint() */ | ||
| 19372 | } u; | 19902 | } u; |
| 19373 | }; | 19903 | }; |
| 19374 | 19904 | ||
| @@ -19389,6 +19919,7 @@ struct DbFixer { | |||
| 19389 | 19919 | ||
| 19390 | /* Forward declarations */ | 19920 | /* Forward declarations */ |
| 19391 | SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); | 19921 | SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); |
| 19922 | SQLITE_PRIVATE int sqlite3WalkExprNN(Walker*, Expr*); | ||
| 19392 | SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); | 19923 | SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); |
| 19393 | SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); | 19924 | SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); |
| 19394 | SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*); | 19925 | SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*); |
| @@ -19638,6 +20169,8 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); | |||
| 19638 | # define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) | 20169 | # define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) |
| 19639 | # define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) | 20170 | # define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) |
| 19640 | # define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80) | 20171 | # define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80) |
| 20172 | # define sqlite3JsonId1(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x42) | ||
| 20173 | # define sqlite3JsonId2(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x46) | ||
| 19641 | #else | 20174 | #else |
| 19642 | # define sqlite3Toupper(x) toupper((unsigned char)(x)) | 20175 | # define sqlite3Toupper(x) toupper((unsigned char)(x)) |
| 19643 | # define sqlite3Isspace(x) isspace((unsigned char)(x)) | 20176 | # define sqlite3Isspace(x) isspace((unsigned char)(x)) |
| @@ -19647,6 +20180,8 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); | |||
| 19647 | # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) | 20180 | # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) |
| 19648 | # define sqlite3Tolower(x) tolower((unsigned char)(x)) | 20181 | # define sqlite3Tolower(x) tolower((unsigned char)(x)) |
| 19649 | # define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') | 20182 | # define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') |
| 20183 | # define sqlite3JsonId1(x) (sqlite3IsIdChar(x)&&(x)<'0') | ||
| 20184 | # define sqlite3JsonId2(x) sqlite3IsIdChar(x) | ||
| 19650 | #endif | 20185 | #endif |
| 19651 | SQLITE_PRIVATE int sqlite3IsIdChar(u8); | 20186 | SQLITE_PRIVATE int sqlite3IsIdChar(u8); |
| 19652 | 20187 | ||
| @@ -19674,6 +20209,7 @@ SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); | |||
| 19674 | SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); | 20209 | SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); |
| 19675 | SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); | 20210 | SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); |
| 19676 | SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); | 20211 | SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); |
| 20212 | SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3*, void*); | ||
| 19677 | SQLITE_PRIVATE int sqlite3MallocSize(const void*); | 20213 | SQLITE_PRIVATE int sqlite3MallocSize(const void*); |
| 19678 | SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, const void*); | 20214 | SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, const void*); |
| 19679 | SQLITE_PRIVATE void *sqlite3PageMalloc(int); | 20215 | SQLITE_PRIVATE void *sqlite3PageMalloc(int); |
| @@ -19694,12 +20230,14 @@ SQLITE_PRIVATE int sqlite3HeapNearlyFull(void); | |||
| 19694 | */ | 20230 | */ |
| 19695 | #ifdef SQLITE_USE_ALLOCA | 20231 | #ifdef SQLITE_USE_ALLOCA |
| 19696 | # define sqlite3StackAllocRaw(D,N) alloca(N) | 20232 | # define sqlite3StackAllocRaw(D,N) alloca(N) |
| 19697 | # define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N) | 20233 | # define sqlite3StackAllocRawNN(D,N) alloca(N) |
| 19698 | # define sqlite3StackFree(D,P) | 20234 | # define sqlite3StackFree(D,P) |
| 20235 | # define sqlite3StackFreeNN(D,P) | ||
| 19699 | #else | 20236 | #else |
| 19700 | # define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) | 20237 | # define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) |
| 19701 | # define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N) | 20238 | # define sqlite3StackAllocRawNN(D,N) sqlite3DbMallocRawNN(D,N) |
| 19702 | # define sqlite3StackFree(D,P) sqlite3DbFree(D,P) | 20239 | # define sqlite3StackFree(D,P) sqlite3DbFree(D,P) |
| 20240 | # define sqlite3StackFreeNN(D,P) sqlite3DbFreeNN(D,P) | ||
| 19703 | #endif | 20241 | #endif |
| 19704 | 20242 | ||
| 19705 | /* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they | 20243 | /* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they |
| @@ -19763,6 +20301,20 @@ struct PrintfArguments { | |||
| 19763 | sqlite3_value **apArg; /* The argument values */ | 20301 | sqlite3_value **apArg; /* The argument values */ |
| 19764 | }; | 20302 | }; |
| 19765 | 20303 | ||
| 20304 | /* | ||
| 20305 | ** An instance of this object receives the decoding of a floating point | ||
| 20306 | ** value into an approximate decimal representation. | ||
| 20307 | */ | ||
| 20308 | struct FpDecode { | ||
| 20309 | char sign; /* '+' or '-' */ | ||
| 20310 | char isSpecial; /* 1: Infinity 2: NaN */ | ||
| 20311 | int n; /* Significant digits in the decode */ | ||
| 20312 | int iDP; /* Location of the decimal point */ | ||
| 20313 | char *z; /* Start of significant digits */ | ||
| 20314 | char zBuf[24]; /* Storage for significant digits */ | ||
| 20315 | }; | ||
| 20316 | |||
| 20317 | SQLITE_PRIVATE void sqlite3FpDecode(FpDecode*,double,int,int); | ||
| 19766 | SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); | 20318 | SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); |
| 19767 | SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); | 20319 | SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); |
| 19768 | #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) | 20320 | #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) |
| @@ -19822,6 +20374,7 @@ SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); | |||
| 19822 | #endif | 20374 | #endif |
| 19823 | 20375 | ||
| 19824 | SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); | 20376 | SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); |
| 20377 | SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); | ||
| 19825 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); | 20378 | SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); |
| 19826 | SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); | 20379 | SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); |
| 19827 | SQLITE_PRIVATE void sqlite3Dequote(char*); | 20380 | SQLITE_PRIVATE void sqlite3Dequote(char*); |
| @@ -19836,6 +20389,10 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); | |||
| 19836 | SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); | 20389 | SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); |
| 19837 | SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); | 20390 | SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); |
| 19838 | SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*); | 20391 | SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*); |
| 20392 | SQLITE_PRIVATE void sqlite3TouchRegister(Parse*,int); | ||
| 20393 | #if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) | ||
| 20394 | SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse*,int); | ||
| 20395 | #endif | ||
| 19839 | #ifdef SQLITE_DEBUG | 20396 | #ifdef SQLITE_DEBUG |
| 19840 | SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); | 20397 | SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); |
| 19841 | #endif | 20398 | #endif |
| @@ -19879,7 +20436,7 @@ SQLITE_PRIVATE const char *sqlite3ColumnColl(Column*); | |||
| 19879 | SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); | 20436 | SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); |
| 19880 | SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); | 20437 | SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); |
| 19881 | SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); | 20438 | SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); |
| 19882 | SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); | 20439 | SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); |
| 19883 | SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); | 20440 | SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); |
| 19884 | SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); | 20441 | SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); |
| 19885 | SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); | 20442 | SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); |
| @@ -19986,7 +20543,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList | |||
| 19986 | Expr*,ExprList*,u32,Expr*); | 20543 | Expr*,ExprList*,u32,Expr*); |
| 19987 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); | 20544 | SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); |
| 19988 | SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); | 20545 | SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); |
| 19989 | SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); | 20546 | SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); |
| 19990 | SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); | 20547 | SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); |
| 19991 | #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) | 20548 | #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) |
| 19992 | SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); | 20549 | SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); |
| @@ -20048,7 +20605,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(const Parse*,const Expr*,const Expr*, int) | |||
| 20048 | SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*,Expr*,int); | 20605 | SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*,Expr*,int); |
| 20049 | SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList*,const ExprList*, int); | 20606 | SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList*,const ExprList*, int); |
| 20050 | SQLITE_PRIVATE int sqlite3ExprImpliesExpr(const Parse*,const Expr*,const Expr*, int); | 20607 | SQLITE_PRIVATE int sqlite3ExprImpliesExpr(const Parse*,const Expr*,const Expr*, int); |
| 20051 | SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int); | 20608 | SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int,int); |
| 20052 | SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*); | 20609 | SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*); |
| 20053 | SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); | 20610 | SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); |
| 20054 | SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); | 20611 | SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); |
| @@ -20075,7 +20632,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); | |||
| 20075 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); | 20632 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); |
| 20076 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); | 20633 | SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); |
| 20077 | SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); | 20634 | SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); |
| 20078 | SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*); | 20635 | SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int); |
| 20079 | #ifdef SQLITE_ENABLE_CURSOR_HINTS | 20636 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 20080 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); | 20637 | SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); |
| 20081 | #endif | 20638 | #endif |
| @@ -20197,8 +20754,10 @@ SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); | |||
| 20197 | SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); | 20754 | SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); |
| 20198 | SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); | 20755 | SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); |
| 20199 | SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); | 20756 | SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); |
| 20757 | |||
| 20200 | SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); | 20758 | SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); |
| 20201 | SQLITE_PRIVATE void sqlite3Int64ToText(i64,char*); | 20759 | SQLITE_PRIVATE i64 sqlite3RealToI64(double); |
| 20760 | SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*); | ||
| 20202 | SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); | 20761 | SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); |
| 20203 | SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); | 20762 | SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); |
| 20204 | SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); | 20763 | SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); |
| @@ -20243,11 +20802,13 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v); | |||
| 20243 | 20802 | ||
| 20244 | 20803 | ||
| 20245 | SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); | 20804 | SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); |
| 20805 | SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3*,const Table*); | ||
| 20246 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); | 20806 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); |
| 20247 | SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2); | 20807 | SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2); |
| 20248 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity); | 20808 | SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity); |
| 20249 | SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table*,int); | 20809 | SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table*,int); |
| 20250 | SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr); | 20810 | SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr); |
| 20811 | SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr); | ||
| 20251 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); | 20812 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 20252 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); | 20813 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); |
| 20253 | SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); | 20814 | SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); |
| @@ -20264,6 +20825,9 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int); | |||
| 20264 | 20825 | ||
| 20265 | #ifndef SQLITE_OMIT_DESERIALIZE | 20826 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 20266 | SQLITE_PRIVATE int sqlite3MemdbInit(void); | 20827 | SQLITE_PRIVATE int sqlite3MemdbInit(void); |
| 20828 | SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs*); | ||
| 20829 | #else | ||
| 20830 | # define sqlite3IsMemdb(X) 0 | ||
| 20267 | #endif | 20831 | #endif |
| 20268 | 20832 | ||
| 20269 | SQLITE_PRIVATE const char *sqlite3ErrStr(int); | 20833 | SQLITE_PRIVATE const char *sqlite3ErrStr(int); |
| @@ -20295,6 +20859,7 @@ SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); | |||
| 20295 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); | 20859 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); |
| 20296 | 20860 | ||
| 20297 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); | 20861 | SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); |
| 20862 | SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*)); | ||
| 20298 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); | 20863 | SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); |
| 20299 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, | 20864 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 20300 | void(*)(void*)); | 20865 | void(*)(void*)); |
| @@ -20314,7 +20879,6 @@ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; | |||
| 20314 | SQLITE_PRIVATE const char sqlite3StrBINARY[]; | 20879 | SQLITE_PRIVATE const char sqlite3StrBINARY[]; |
| 20315 | SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[]; | 20880 | SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[]; |
| 20316 | SQLITE_PRIVATE const char sqlite3StdTypeAffinity[]; | 20881 | SQLITE_PRIVATE const char sqlite3StdTypeAffinity[]; |
| 20317 | SQLITE_PRIVATE const char sqlite3StdTypeMap[]; | ||
| 20318 | SQLITE_PRIVATE const char *sqlite3StdType[]; | 20882 | SQLITE_PRIVATE const char *sqlite3StdType[]; |
| 20319 | SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; | 20883 | SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; |
| 20320 | SQLITE_PRIVATE const unsigned char *sqlite3aLTb; | 20884 | SQLITE_PRIVATE const unsigned char *sqlite3aLTb; |
| @@ -20403,8 +20967,13 @@ SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); | |||
| 20403 | SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); | 20967 | SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); |
| 20404 | SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); | 20968 | SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); |
| 20405 | 20969 | ||
| 20970 | SQLITE_PRIVATE char *sqlite3RCStrRef(char*); | ||
| 20971 | SQLITE_PRIVATE void sqlite3RCStrUnref(char*); | ||
| 20972 | SQLITE_PRIVATE char *sqlite3RCStrNew(u64); | ||
| 20973 | SQLITE_PRIVATE char *sqlite3RCStrResize(char*,u64); | ||
| 20974 | |||
| 20406 | SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); | 20975 | SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); |
| 20407 | SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, int); | 20976 | SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64); |
| 20408 | SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); | 20977 | SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); |
| 20409 | SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); | 20978 | SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); |
| 20410 | SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); | 20979 | SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); |
| @@ -20518,10 +21087,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); | |||
| 20518 | SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); | 21087 | SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); |
| 20519 | 21088 | ||
| 20520 | SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); | 21089 | SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); |
| 20521 | #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ | 21090 | SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse*); |
| 20522 | && !defined(SQLITE_OMIT_VIRTUALTABLE) | ||
| 20523 | SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info*); | ||
| 20524 | #endif | ||
| 20525 | SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); | 21091 | SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); |
| 20526 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); | 21092 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); |
| 20527 | SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); | 21093 | SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); |
| @@ -20657,6 +21223,7 @@ SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); | |||
| 20657 | #define sqlite3SelectExprHeight(x) 0 | 21223 | #define sqlite3SelectExprHeight(x) 0 |
| 20658 | #define sqlite3ExprCheckHeight(x,y) | 21224 | #define sqlite3ExprCheckHeight(x,y) |
| 20659 | #endif | 21225 | #endif |
| 21226 | SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr*,int); | ||
| 20660 | 21227 | ||
| 20661 | SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*); | 21228 | SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*); |
| 20662 | SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32); | 21229 | SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32); |
| @@ -20758,6 +21325,22 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse*, Expr*); | |||
| 20758 | SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt); | 21325 | SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt); |
| 20759 | #endif | 21326 | #endif |
| 20760 | 21327 | ||
| 21328 | #if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) | ||
| 21329 | SQLITE_PRIVATE int sqlite3KvvfsInit(void); | ||
| 21330 | #endif | ||
| 21331 | |||
| 21332 | #if defined(VDBE_PROFILE) \ | ||
| 21333 | || defined(SQLITE_PERFORMANCE_TRACE) \ | ||
| 21334 | || defined(SQLITE_ENABLE_STMT_SCANSTATUS) | ||
| 21335 | SQLITE_PRIVATE sqlite3_uint64 sqlite3Hwtime(void); | ||
| 21336 | #endif | ||
| 21337 | |||
| 21338 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 21339 | # define IS_STMT_SCANSTATUS(db) (db->flags & SQLITE_StmtScanStatus) | ||
| 21340 | #else | ||
| 21341 | # define IS_STMT_SCANSTATUS(db) 0 | ||
| 21342 | #endif | ||
| 21343 | |||
| 20761 | #endif /* SQLITEINT_H */ | 21344 | #endif /* SQLITEINT_H */ |
| 20762 | 21345 | ||
| 20763 | /************** End of sqliteInt.h *******************************************/ | 21346 | /************** End of sqliteInt.h *******************************************/ |
| @@ -20799,101 +21382,6 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt); | |||
| 20799 | */ | 21382 | */ |
| 20800 | #ifdef SQLITE_PERFORMANCE_TRACE | 21383 | #ifdef SQLITE_PERFORMANCE_TRACE |
| 20801 | 21384 | ||
| 20802 | /* | ||
| 20803 | ** hwtime.h contains inline assembler code for implementing | ||
| 20804 | ** high-performance timing routines. | ||
| 20805 | */ | ||
| 20806 | /************** Include hwtime.h in the middle of os_common.h ****************/ | ||
| 20807 | /************** Begin file hwtime.h ******************************************/ | ||
| 20808 | /* | ||
| 20809 | ** 2008 May 27 | ||
| 20810 | ** | ||
| 20811 | ** The author disclaims copyright to this source code. In place of | ||
| 20812 | ** a legal notice, here is a blessing: | ||
| 20813 | ** | ||
| 20814 | ** May you do good and not evil. | ||
| 20815 | ** May you find forgiveness for yourself and forgive others. | ||
| 20816 | ** May you share freely, never taking more than you give. | ||
| 20817 | ** | ||
| 20818 | ****************************************************************************** | ||
| 20819 | ** | ||
| 20820 | ** This file contains inline asm code for retrieving "high-performance" | ||
| 20821 | ** counters for x86 and x86_64 class CPUs. | ||
| 20822 | */ | ||
| 20823 | #ifndef SQLITE_HWTIME_H | ||
| 20824 | #define SQLITE_HWTIME_H | ||
| 20825 | |||
| 20826 | /* | ||
| 20827 | ** The following routine only works on pentium-class (or newer) processors. | ||
| 20828 | ** It uses the RDTSC opcode to read the cycle count value out of the | ||
| 20829 | ** processor and returns that value. This can be used for high-res | ||
| 20830 | ** profiling. | ||
| 20831 | */ | ||
| 20832 | #if !defined(__STRICT_ANSI__) && \ | ||
| 20833 | (defined(__GNUC__) || defined(_MSC_VER)) && \ | ||
| 20834 | (defined(i386) || defined(__i386__) || defined(_M_IX86)) | ||
| 20835 | |||
| 20836 | #if defined(__GNUC__) | ||
| 20837 | |||
| 20838 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 20839 | unsigned int lo, hi; | ||
| 20840 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
| 20841 | return (sqlite_uint64)hi << 32 | lo; | ||
| 20842 | } | ||
| 20843 | |||
| 20844 | #elif defined(_MSC_VER) | ||
| 20845 | |||
| 20846 | __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ | ||
| 20847 | __asm { | ||
| 20848 | rdtsc | ||
| 20849 | ret ; return value at EDX:EAX | ||
| 20850 | } | ||
| 20851 | } | ||
| 20852 | |||
| 20853 | #endif | ||
| 20854 | |||
| 20855 | #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) | ||
| 20856 | |||
| 20857 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 20858 | unsigned long val; | ||
| 20859 | __asm__ __volatile__ ("rdtsc" : "=A" (val)); | ||
| 20860 | return val; | ||
| 20861 | } | ||
| 20862 | |||
| 20863 | #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) | ||
| 20864 | |||
| 20865 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 20866 | unsigned long long retval; | ||
| 20867 | unsigned long junk; | ||
| 20868 | __asm__ __volatile__ ("\n\ | ||
| 20869 | 1: mftbu %1\n\ | ||
| 20870 | mftb %L0\n\ | ||
| 20871 | mftbu %0\n\ | ||
| 20872 | cmpw %0,%1\n\ | ||
| 20873 | bne 1b" | ||
| 20874 | : "=r" (retval), "=r" (junk)); | ||
| 20875 | return retval; | ||
| 20876 | } | ||
| 20877 | |||
| 20878 | #else | ||
| 20879 | |||
| 20880 | /* | ||
| 20881 | ** asm() is needed for hardware timing support. Without asm(), | ||
| 20882 | ** disable the sqlite3Hwtime() routine. | ||
| 20883 | ** | ||
| 20884 | ** sqlite3Hwtime() is only used for some obscure debugging | ||
| 20885 | ** and analysis configurations, not in any deliverable, so this | ||
| 20886 | ** should not be a great loss. | ||
| 20887 | */ | ||
| 20888 | SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } | ||
| 20889 | |||
| 20890 | #endif | ||
| 20891 | |||
| 20892 | #endif /* !defined(SQLITE_HWTIME_H) */ | ||
| 20893 | |||
| 20894 | /************** End of hwtime.h **********************************************/ | ||
| 20895 | /************** Continuing where we left off in os_common.h ******************/ | ||
| 20896 | |||
| 20897 | static sqlite_uint64 g_start; | 21385 | static sqlite_uint64 g_start; |
| 20898 | static sqlite_uint64 g_elapsed; | 21386 | static sqlite_uint64 g_elapsed; |
| 20899 | #define TIMER_START g_start=sqlite3Hwtime() | 21387 | #define TIMER_START g_start=sqlite3Hwtime() |
| @@ -20989,7 +21477,7 @@ SQLITE_API extern int sqlite3_open_file_count; | |||
| 20989 | ** autoconf-based build | 21477 | ** autoconf-based build |
| 20990 | */ | 21478 | */ |
| 20991 | #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) | 21479 | #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) |
| 20992 | /* #include "config.h" */ | 21480 | /* #include "sqlite_cfg.h" */ |
| 20993 | #define SQLITECONFIG_H 1 | 21481 | #define SQLITECONFIG_H 1 |
| 20994 | #endif | 21482 | #endif |
| 20995 | 21483 | ||
| @@ -21021,9 +21509,6 @@ static const char * const sqlite3azCompileOpt[] = { | |||
| 21021 | #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC | 21509 | #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC |
| 21022 | "4_BYTE_ALIGNED_MALLOC", | 21510 | "4_BYTE_ALIGNED_MALLOC", |
| 21023 | #endif | 21511 | #endif |
| 21024 | #ifdef SQLITE_64BIT_STATS | ||
| 21025 | "64BIT_STATS", | ||
| 21026 | #endif | ||
| 21027 | #ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN | 21512 | #ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN |
| 21028 | # if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1 | 21513 | # if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1 |
| 21029 | "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), | 21514 | "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), |
| @@ -21154,6 +21639,9 @@ static const char * const sqlite3azCompileOpt[] = { | |||
| 21154 | #ifdef SQLITE_DISABLE_SKIPAHEAD_DISTINCT | 21639 | #ifdef SQLITE_DISABLE_SKIPAHEAD_DISTINCT |
| 21155 | "DISABLE_SKIPAHEAD_DISTINCT", | 21640 | "DISABLE_SKIPAHEAD_DISTINCT", |
| 21156 | #endif | 21641 | #endif |
| 21642 | #ifdef SQLITE_DQS | ||
| 21643 | "DQS=" CTIMEOPT_VAL(SQLITE_DQS), | ||
| 21644 | #endif | ||
| 21157 | #ifdef SQLITE_ENABLE_8_3_NAMES | 21645 | #ifdef SQLITE_ENABLE_8_3_NAMES |
| 21158 | "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), | 21646 | "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), |
| 21159 | #endif | 21647 | #endif |
| @@ -21357,6 +21845,9 @@ static const char * const sqlite3azCompileOpt[] = { | |||
| 21357 | #ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX | 21845 | #ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX |
| 21358 | "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX), | 21846 | "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX), |
| 21359 | #endif | 21847 | #endif |
| 21848 | #ifdef SQLITE_LEGACY_JSON_VALID | ||
| 21849 | "LEGACY_JSON_VALID", | ||
| 21850 | #endif | ||
| 21360 | #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS | 21851 | #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS |
| 21361 | "LIKE_DOESNT_MATCH_BLOBS", | 21852 | "LIKE_DOESNT_MATCH_BLOBS", |
| 21362 | #endif | 21853 | #endif |
| @@ -21644,9 +22135,6 @@ static const char * const sqlite3azCompileOpt[] = { | |||
| 21644 | #ifdef SQLITE_OMIT_XFER_OPT | 22135 | #ifdef SQLITE_OMIT_XFER_OPT |
| 21645 | "OMIT_XFER_OPT", | 22136 | "OMIT_XFER_OPT", |
| 21646 | #endif | 22137 | #endif |
| 21647 | #ifdef SQLITE_PCACHE_SEPARATE_HEADER | ||
| 21648 | "PCACHE_SEPARATE_HEADER", | ||
| 21649 | #endif | ||
| 21650 | #ifdef SQLITE_PERFORMANCE_TRACE | 22138 | #ifdef SQLITE_PERFORMANCE_TRACE |
| 21651 | "PERFORMANCE_TRACE", | 22139 | "PERFORMANCE_TRACE", |
| 21652 | #endif | 22140 | #endif |
| @@ -21848,7 +22336,7 @@ SQLITE_PRIVATE const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP | |||
| 21848 | ** isalnum() 0x06 | 22336 | ** isalnum() 0x06 |
| 21849 | ** isxdigit() 0x08 | 22337 | ** isxdigit() 0x08 |
| 21850 | ** toupper() 0x20 | 22338 | ** toupper() 0x20 |
| 21851 | ** SQLite identifier character 0x40 | 22339 | ** SQLite identifier character 0x40 $, _, or non-ascii |
| 21852 | ** Quote character 0x80 | 22340 | ** Quote character 0x80 |
| 21853 | ** | 22341 | ** |
| 21854 | ** Bit 0x20 is set if the mapped character requires translation to upper | 22342 | ** Bit 0x20 is set if the mapped character requires translation to upper |
| @@ -21994,6 +22482,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { | |||
| 21994 | SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ | 22482 | SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ |
| 21995 | 0, /* bSmallMalloc */ | 22483 | 0, /* bSmallMalloc */ |
| 21996 | 1, /* bExtraSchemaChecks */ | 22484 | 1, /* bExtraSchemaChecks */ |
| 22485 | sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ | ||
| 21997 | 0x7ffffffe, /* mxStrlen */ | 22486 | 0x7ffffffe, /* mxStrlen */ |
| 21998 | 0, /* neverCorrupt */ | 22487 | 0, /* neverCorrupt */ |
| 21999 | SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ | 22488 | SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ |
| @@ -22042,7 +22531,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { | |||
| 22042 | SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ | 22531 | SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ |
| 22043 | 0, /* iPrngSeed */ | 22532 | 0, /* iPrngSeed */ |
| 22044 | #ifdef SQLITE_DEBUG | 22533 | #ifdef SQLITE_DEBUG |
| 22045 | {0,0,0,0,0,0} /* aTune */ | 22534 | {0,0,0,0,0,0}, /* aTune */ |
| 22046 | #endif | 22535 | #endif |
| 22047 | }; | 22536 | }; |
| 22048 | 22537 | ||
| @@ -22126,10 +22615,6 @@ SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY"; | |||
| 22126 | ** | 22615 | ** |
| 22127 | ** sqlite3StdTypeAffinity[] The affinity associated with each entry | 22616 | ** sqlite3StdTypeAffinity[] The affinity associated with each entry |
| 22128 | ** in sqlite3StdType[]. | 22617 | ** in sqlite3StdType[]. |
| 22129 | ** | ||
| 22130 | ** sqlite3StdTypeMap[] The type value (as returned from | ||
| 22131 | ** sqlite3_column_type() or sqlite3_value_type()) | ||
| 22132 | ** for each entry in sqlite3StdType[]. | ||
| 22133 | */ | 22618 | */ |
| 22134 | SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[] = { 3, 4, 3, 7, 4, 4 }; | 22619 | SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[] = { 3, 4, 3, 7, 4, 4 }; |
| 22135 | SQLITE_PRIVATE const char sqlite3StdTypeAffinity[] = { | 22620 | SQLITE_PRIVATE const char sqlite3StdTypeAffinity[] = { |
| @@ -22140,14 +22625,6 @@ SQLITE_PRIVATE const char sqlite3StdTypeAffinity[] = { | |||
| 22140 | SQLITE_AFF_REAL, | 22625 | SQLITE_AFF_REAL, |
| 22141 | SQLITE_AFF_TEXT | 22626 | SQLITE_AFF_TEXT |
| 22142 | }; | 22627 | }; |
| 22143 | SQLITE_PRIVATE const char sqlite3StdTypeMap[] = { | ||
| 22144 | 0, | ||
| 22145 | SQLITE_BLOB, | ||
| 22146 | SQLITE_INTEGER, | ||
| 22147 | SQLITE_INTEGER, | ||
| 22148 | SQLITE_FLOAT, | ||
| 22149 | SQLITE_TEXT | ||
| 22150 | }; | ||
| 22151 | SQLITE_PRIVATE const char *sqlite3StdType[] = { | 22628 | SQLITE_PRIVATE const char *sqlite3StdType[] = { |
| 22152 | "ANY", | 22629 | "ANY", |
| 22153 | "BLOB", | 22630 | "BLOB", |
| @@ -22235,6 +22712,9 @@ typedef struct VdbeSorter VdbeSorter; | |||
| 22235 | /* Elements of the linked list at Vdbe.pAuxData */ | 22712 | /* Elements of the linked list at Vdbe.pAuxData */ |
| 22236 | typedef struct AuxData AuxData; | 22713 | typedef struct AuxData AuxData; |
| 22237 | 22714 | ||
| 22715 | /* A cache of large TEXT or BLOB values in a VdbeCursor */ | ||
| 22716 | typedef struct VdbeTxtBlbCache VdbeTxtBlbCache; | ||
| 22717 | |||
| 22238 | /* Types of VDBE cursors */ | 22718 | /* Types of VDBE cursors */ |
| 22239 | #define CURTYPE_BTREE 0 | 22719 | #define CURTYPE_BTREE 0 |
| 22240 | #define CURTYPE_SORTER 1 | 22720 | #define CURTYPE_SORTER 1 |
| @@ -22266,6 +22746,7 @@ struct VdbeCursor { | |||
| 22266 | Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ | 22746 | Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ |
| 22267 | Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ | 22747 | Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ |
| 22268 | Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */ | 22748 | Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */ |
| 22749 | Bool colCache:1; /* pCache pointer is initialized and non-NULL */ | ||
| 22269 | u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ | 22750 | u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ |
| 22270 | union { /* pBtx for isEphermeral. pAltMap otherwise */ | 22751 | union { /* pBtx for isEphermeral. pAltMap otherwise */ |
| 22271 | Btree *pBtx; /* Separate file holding temporary table */ | 22752 | Btree *pBtx; /* Separate file holding temporary table */ |
| @@ -22306,6 +22787,7 @@ struct VdbeCursor { | |||
| 22306 | #ifdef SQLITE_ENABLE_COLUMN_USED_MASK | 22787 | #ifdef SQLITE_ENABLE_COLUMN_USED_MASK |
| 22307 | u64 maskUsed; /* Mask of columns used by this cursor */ | 22788 | u64 maskUsed; /* Mask of columns used by this cursor */ |
| 22308 | #endif | 22789 | #endif |
| 22790 | VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ | ||
| 22309 | 22791 | ||
| 22310 | /* 2*nField extra array elements allocated for aType[], beyond the one | 22792 | /* 2*nField extra array elements allocated for aType[], beyond the one |
| 22311 | ** static element declared in the structure. nField total array slots for | 22793 | ** static element declared in the structure. nField total array slots for |
| @@ -22318,13 +22800,26 @@ struct VdbeCursor { | |||
| 22318 | #define IsNullCursor(P) \ | 22800 | #define IsNullCursor(P) \ |
| 22319 | ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) | 22801 | ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) |
| 22320 | 22802 | ||
| 22321 | |||
| 22322 | /* | 22803 | /* |
| 22323 | ** A value for VdbeCursor.cacheStatus that means the cache is always invalid. | 22804 | ** A value for VdbeCursor.cacheStatus that means the cache is always invalid. |
| 22324 | */ | 22805 | */ |
| 22325 | #define CACHE_STALE 0 | 22806 | #define CACHE_STALE 0 |
| 22326 | 22807 | ||
| 22327 | /* | 22808 | /* |
| 22809 | ** Large TEXT or BLOB values can be slow to load, so we want to avoid | ||
| 22810 | ** loading them more than once. For that reason, large TEXT and BLOB values | ||
| 22811 | ** can be stored in a cache defined by this object, and attached to the | ||
| 22812 | ** VdbeCursor using the pCache field. | ||
| 22813 | */ | ||
| 22814 | struct VdbeTxtBlbCache { | ||
| 22815 | char *pCValue; /* A RCStr buffer to hold the value */ | ||
| 22816 | i64 iOffset; /* File offset of the row being cached */ | ||
| 22817 | int iCol; /* Column for which the cache is valid */ | ||
| 22818 | u32 cacheStatus; /* Vdbe.cacheCtr value */ | ||
| 22819 | u32 colCacheCtr; /* Column cache counter */ | ||
| 22820 | }; | ||
| 22821 | |||
| 22822 | /* | ||
| 22328 | ** When a sub-program is executed (OP_Program), a structure of this type | 22823 | ** When a sub-program is executed (OP_Program), a structure of this type |
| 22329 | ** is allocated to store the current value of the program counter, as | 22824 | ** is allocated to store the current value of the program counter, as |
| 22330 | ** well as the current memory cell array and various other frame specific | 22825 | ** well as the current memory cell array and various other frame specific |
| @@ -22350,7 +22845,6 @@ struct VdbeFrame { | |||
| 22350 | Vdbe *v; /* VM this frame belongs to */ | 22845 | Vdbe *v; /* VM this frame belongs to */ |
| 22351 | VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ | 22846 | VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ |
| 22352 | Op *aOp; /* Program instructions for parent frame */ | 22847 | Op *aOp; /* Program instructions for parent frame */ |
| 22353 | i64 *anExec; /* Event counters from parent frame */ | ||
| 22354 | Mem *aMem; /* Array of memory cells for parent frame */ | 22848 | Mem *aMem; /* Array of memory cells for parent frame */ |
| 22355 | VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ | 22849 | VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ |
| 22356 | u8 *aOnce; /* Bitmask used by OP_Once */ | 22850 | u8 *aOnce; /* Bitmask used by OP_Once */ |
| @@ -22566,10 +23060,19 @@ typedef unsigned bft; /* Bit Field Type */ | |||
| 22566 | 23060 | ||
| 22567 | /* The ScanStatus object holds a single value for the | 23061 | /* The ScanStatus object holds a single value for the |
| 22568 | ** sqlite3_stmt_scanstatus() interface. | 23062 | ** sqlite3_stmt_scanstatus() interface. |
| 23063 | ** | ||
| 23064 | ** aAddrRange[]: | ||
| 23065 | ** This array is used by ScanStatus elements associated with EQP | ||
| 23066 | ** notes that make an SQLITE_SCANSTAT_NCYCLE value available. It is | ||
| 23067 | ** an array of up to 3 ranges of VM addresses for which the Vdbe.anCycle[] | ||
| 23068 | ** values should be summed to calculate the NCYCLE value. Each pair of | ||
| 23069 | ** integer addresses is a start and end address (both inclusive) for a range | ||
| 23070 | ** instructions. A start value of 0 indicates an empty range. | ||
| 22569 | */ | 23071 | */ |
| 22570 | typedef struct ScanStatus ScanStatus; | 23072 | typedef struct ScanStatus ScanStatus; |
| 22571 | struct ScanStatus { | 23073 | struct ScanStatus { |
| 22572 | int addrExplain; /* OP_Explain for loop */ | 23074 | int addrExplain; /* OP_Explain for loop */ |
| 23075 | int aAddrRange[6]; | ||
| 22573 | int addrLoop; /* Address of "loops" counter */ | 23076 | int addrLoop; /* Address of "loops" counter */ |
| 22574 | int addrVisit; /* Address of "rows visited" counter */ | 23077 | int addrVisit; /* Address of "rows visited" counter */ |
| 22575 | int iSelectID; /* The "Select-ID" for this loop */ | 23078 | int iSelectID; /* The "Select-ID" for this loop */ |
| @@ -22599,7 +23102,7 @@ struct DblquoteStr { | |||
| 22599 | */ | 23102 | */ |
| 22600 | struct Vdbe { | 23103 | struct Vdbe { |
| 22601 | sqlite3 *db; /* The database connection that owns this statement */ | 23104 | sqlite3 *db; /* The database connection that owns this statement */ |
| 22602 | Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ | 23105 | Vdbe **ppVPrev,*pVNext; /* Linked list of VDBEs with the same Vdbe.db */ |
| 22603 | Parse *pParse; /* Parsing context used to create this Vdbe */ | 23106 | Parse *pParse; /* Parsing context used to create this Vdbe */ |
| 22604 | ynVar nVar; /* Number of entries in aVar[] */ | 23107 | ynVar nVar; /* Number of entries in aVar[] */ |
| 22605 | int nMem; /* Number of memory locations currently allocated */ | 23108 | int nMem; /* Number of memory locations currently allocated */ |
| @@ -22625,7 +23128,7 @@ struct Vdbe { | |||
| 22625 | int nOp; /* Number of instructions in the program */ | 23128 | int nOp; /* Number of instructions in the program */ |
| 22626 | int nOpAlloc; /* Slots allocated for aOp[] */ | 23129 | int nOpAlloc; /* Slots allocated for aOp[] */ |
| 22627 | Mem *aColName; /* Column names to return */ | 23130 | Mem *aColName; /* Column names to return */ |
| 22628 | Mem *pResultSet; /* Pointer to an array of results */ | 23131 | Mem *pResultRow; /* Current output row */ |
| 22629 | char *zErrMsg; /* Error message written here */ | 23132 | char *zErrMsg; /* Error message written here */ |
| 22630 | VList *pVList; /* Name of variables */ | 23133 | VList *pVList; /* Name of variables */ |
| 22631 | #ifndef SQLITE_OMIT_TRACE | 23134 | #ifndef SQLITE_OMIT_TRACE |
| @@ -22636,16 +23139,18 @@ struct Vdbe { | |||
| 22636 | u32 nWrite; /* Number of write operations that have occurred */ | 23139 | u32 nWrite; /* Number of write operations that have occurred */ |
| 22637 | #endif | 23140 | #endif |
| 22638 | u16 nResColumn; /* Number of columns in one row of the result set */ | 23141 | u16 nResColumn; /* Number of columns in one row of the result set */ |
| 23142 | u16 nResAlloc; /* Column slots allocated to aColName[] */ | ||
| 22639 | u8 errorAction; /* Recovery action to do in case of an error */ | 23143 | u8 errorAction; /* Recovery action to do in case of an error */ |
| 22640 | u8 minWriteFileFormat; /* Minimum file format for writable database files */ | 23144 | u8 minWriteFileFormat; /* Minimum file format for writable database files */ |
| 22641 | u8 prepFlags; /* SQLITE_PREPARE_* flags */ | 23145 | u8 prepFlags; /* SQLITE_PREPARE_* flags */ |
| 22642 | u8 eVdbeState; /* On of the VDBE_*_STATE values */ | 23146 | u8 eVdbeState; /* On of the VDBE_*_STATE values */ |
| 22643 | bft expired:2; /* 1: recompile VM immediately 2: when convenient */ | 23147 | bft expired:2; /* 1: recompile VM immediately 2: when convenient */ |
| 22644 | bft explain:2; /* True if EXPLAIN present on SQL command */ | 23148 | bft explain:2; /* 0: normal, 1: EXPLAIN, 2: EXPLAIN QUERY PLAN */ |
| 22645 | bft changeCntOn:1; /* True to update the change-counter */ | 23149 | bft changeCntOn:1; /* True to update the change-counter */ |
| 22646 | bft usesStmtJournal:1; /* True if uses a statement journal */ | 23150 | bft usesStmtJournal:1; /* True if uses a statement journal */ |
| 22647 | bft readOnly:1; /* True for statements that do not write */ | 23151 | bft readOnly:1; /* True for statements that do not write */ |
| 22648 | bft bIsReader:1; /* True for statements that read */ | 23152 | bft bIsReader:1; /* True for statements that read */ |
| 23153 | bft haveEqpOps:1; /* Bytecode supports EXPLAIN QUERY PLAN */ | ||
| 22649 | yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ | 23154 | yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ |
| 22650 | yDbMask lockMask; /* Subset of btreeMask that requires a lock */ | 23155 | yDbMask lockMask; /* Subset of btreeMask that requires a lock */ |
| 22651 | u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */ | 23156 | u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */ |
| @@ -22662,7 +23167,6 @@ struct Vdbe { | |||
| 22662 | SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ | 23167 | SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ |
| 22663 | AuxData *pAuxData; /* Linked list of auxdata allocations */ | 23168 | AuxData *pAuxData; /* Linked list of auxdata allocations */ |
| 22664 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | 23169 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| 22665 | i64 *anExec; /* Number of times each op has been executed */ | ||
| 22666 | int nScan; /* Entries in aScan[] */ | 23170 | int nScan; /* Entries in aScan[] */ |
| 22667 | ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ | 23171 | ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ |
| 22668 | #endif | 23172 | #endif |
| @@ -22693,7 +23197,7 @@ struct PreUpdate { | |||
| 22693 | i64 iKey1; /* First key value passed to hook */ | 23197 | i64 iKey1; /* First key value passed to hook */ |
| 22694 | i64 iKey2; /* Second key value passed to hook */ | 23198 | i64 iKey2; /* Second key value passed to hook */ |
| 22695 | Mem *aNew; /* Array of new.* values */ | 23199 | Mem *aNew; /* Array of new.* values */ |
| 22696 | Table *pTab; /* Schema object being upated */ | 23200 | Table *pTab; /* Schema object being updated */ |
| 22697 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ | 23201 | Index *pPk; /* PK index if pTab is WITHOUT ROWID */ |
| 22698 | }; | 23202 | }; |
| 22699 | 23203 | ||
| @@ -22783,6 +23287,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int); | |||
| 22783 | SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); | 23287 | SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); |
| 22784 | #endif | 23288 | #endif |
| 22785 | SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); | 23289 | SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); |
| 23290 | SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem*); | ||
| 22786 | SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); | 23291 | SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); |
| 22787 | SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); | 23292 | SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); |
| 22788 | SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); | 23293 | SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); |
| @@ -22829,6 +23334,8 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); | |||
| 22829 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); | 23334 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); |
| 22830 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); | 23335 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); |
| 22831 | 23336 | ||
| 23337 | SQLITE_PRIVATE void sqlite3VdbeValueListFree(void*); | ||
| 23338 | |||
| 22832 | #ifdef SQLITE_DEBUG | 23339 | #ifdef SQLITE_DEBUG |
| 22833 | SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); | 23340 | SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); |
| 22834 | SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*); | 23341 | SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*); |
| @@ -23157,6 +23664,8 @@ SQLITE_API int sqlite3_db_status( | |||
| 23157 | 23664 | ||
| 23158 | sqlite3BtreeEnterAll(db); | 23665 | sqlite3BtreeEnterAll(db); |
| 23159 | db->pnBytesFreed = &nByte; | 23666 | db->pnBytesFreed = &nByte; |
| 23667 | assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); | ||
| 23668 | db->lookaside.pEnd = db->lookaside.pStart; | ||
| 23160 | for(i=0; i<db->nDb; i++){ | 23669 | for(i=0; i<db->nDb; i++){ |
| 23161 | Schema *pSchema = db->aDb[i].pSchema; | 23670 | Schema *pSchema = db->aDb[i].pSchema; |
| 23162 | if( ALWAYS(pSchema!=0) ){ | 23671 | if( ALWAYS(pSchema!=0) ){ |
| @@ -23182,6 +23691,7 @@ SQLITE_API int sqlite3_db_status( | |||
| 23182 | } | 23691 | } |
| 23183 | } | 23692 | } |
| 23184 | db->pnBytesFreed = 0; | 23693 | db->pnBytesFreed = 0; |
| 23694 | db->lookaside.pEnd = db->lookaside.pTrueEnd; | ||
| 23185 | sqlite3BtreeLeaveAll(db); | 23695 | sqlite3BtreeLeaveAll(db); |
| 23186 | 23696 | ||
| 23187 | *pHighwater = 0; | 23697 | *pHighwater = 0; |
| @@ -23199,9 +23709,12 @@ SQLITE_API int sqlite3_db_status( | |||
| 23199 | int nByte = 0; /* Used to accumulate return value */ | 23709 | int nByte = 0; /* Used to accumulate return value */ |
| 23200 | 23710 | ||
| 23201 | db->pnBytesFreed = &nByte; | 23711 | db->pnBytesFreed = &nByte; |
| 23202 | for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ | 23712 | assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); |
| 23713 | db->lookaside.pEnd = db->lookaside.pStart; | ||
| 23714 | for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pVNext){ | ||
| 23203 | sqlite3VdbeDelete(pVdbe); | 23715 | sqlite3VdbeDelete(pVdbe); |
| 23204 | } | 23716 | } |
| 23717 | db->lookaside.pEnd = db->lookaside.pTrueEnd; | ||
| 23205 | db->pnBytesFreed = 0; | 23718 | db->pnBytesFreed = 0; |
| 23206 | 23719 | ||
| 23207 | *pHighwater = 0; /* IMP: R-64479-57858 */ | 23720 | *pHighwater = 0; /* IMP: R-64479-57858 */ |
| @@ -23338,6 +23851,7 @@ struct DateTime { | |||
| 23338 | char validTZ; /* True (1) if tz is valid */ | 23851 | char validTZ; /* True (1) if tz is valid */ |
| 23339 | char tzSet; /* Timezone was set explicitly */ | 23852 | char tzSet; /* Timezone was set explicitly */ |
| 23340 | char isError; /* An overflow has occurred */ | 23853 | char isError; /* An overflow has occurred */ |
| 23854 | char useSubsec; /* Display subsecond precision */ | ||
| 23341 | }; | 23855 | }; |
| 23342 | 23856 | ||
| 23343 | 23857 | ||
| @@ -23370,8 +23884,8 @@ struct DateTime { | |||
| 23370 | */ | 23884 | */ |
| 23371 | static int getDigits(const char *zDate, const char *zFormat, ...){ | 23885 | static int getDigits(const char *zDate, const char *zFormat, ...){ |
| 23372 | /* The aMx[] array translates the 3rd character of each format | 23886 | /* The aMx[] array translates the 3rd character of each format |
| 23373 | ** spec into a max size: a b c d e f */ | 23887 | ** spec into a max size: a b c d e f */ |
| 23374 | static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 }; | 23888 | static const u16 aMx[] = { 12, 14, 24, 31, 59, 14712 }; |
| 23375 | va_list ap; | 23889 | va_list ap; |
| 23376 | int cnt = 0; | 23890 | int cnt = 0; |
| 23377 | char nextC; | 23891 | char nextC; |
| @@ -23537,7 +24051,7 @@ static void computeJD(DateTime *p){ | |||
| 23537 | p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); | 24051 | p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); |
| 23538 | p->validJD = 1; | 24052 | p->validJD = 1; |
| 23539 | if( p->validHMS ){ | 24053 | if( p->validHMS ){ |
| 23540 | p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000); | 24054 | p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); |
| 23541 | if( p->validTZ ){ | 24055 | if( p->validTZ ){ |
| 23542 | p->iJD -= p->tz*60000; | 24056 | p->iJD -= p->tz*60000; |
| 23543 | p->validYMD = 0; | 24057 | p->validYMD = 0; |
| @@ -23652,6 +24166,11 @@ static int parseDateOrTime( | |||
| 23652 | }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ | 24166 | }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ |
| 23653 | setRawDateNumber(p, r); | 24167 | setRawDateNumber(p, r); |
| 23654 | return 0; | 24168 | return 0; |
| 24169 | }else if( (sqlite3StrICmp(zDate,"subsec")==0 | ||
| 24170 | || sqlite3StrICmp(zDate,"subsecond")==0) | ||
| 24171 | && sqlite3NotPureFunc(context) ){ | ||
| 24172 | p->useSubsec = 1; | ||
| 24173 | return setDateTimeToCurrent(context, p); | ||
| 23655 | } | 24174 | } |
| 23656 | return 1; | 24175 | return 1; |
| 23657 | } | 24176 | } |
| @@ -23707,17 +24226,14 @@ static void computeYMD(DateTime *p){ | |||
| 23707 | ** Compute the Hour, Minute, and Seconds from the julian day number. | 24226 | ** Compute the Hour, Minute, and Seconds from the julian day number. |
| 23708 | */ | 24227 | */ |
| 23709 | static void computeHMS(DateTime *p){ | 24228 | static void computeHMS(DateTime *p){ |
| 23710 | int s; | 24229 | int day_ms, day_min; /* milliseconds, minutes into the day */ |
| 23711 | if( p->validHMS ) return; | 24230 | if( p->validHMS ) return; |
| 23712 | computeJD(p); | 24231 | computeJD(p); |
| 23713 | s = (int)((p->iJD + 43200000) % 86400000); | 24232 | day_ms = (int)((p->iJD + 43200000) % 86400000); |
| 23714 | p->s = s/1000.0; | 24233 | p->s = (day_ms % 60000)/1000.0; |
| 23715 | s = (int)p->s; | 24234 | day_min = day_ms/60000; |
| 23716 | p->s -= s; | 24235 | p->m = day_min % 60; |
| 23717 | p->h = s/3600; | 24236 | p->h = day_min / 60; |
| 23718 | s -= p->h*3600; | ||
| 23719 | p->m = s/60; | ||
| 23720 | p->s += s - p->m*60; | ||
| 23721 | p->rawS = 0; | 24237 | p->rawS = 0; |
| 23722 | p->validHMS = 1; | 24238 | p->validHMS = 1; |
| 23723 | } | 24239 | } |
| @@ -23897,6 +24413,25 @@ static const struct { | |||
| 23897 | }; | 24413 | }; |
| 23898 | 24414 | ||
| 23899 | /* | 24415 | /* |
| 24416 | ** If the DateTime p is raw number, try to figure out if it is | ||
| 24417 | ** a julian day number of a unix timestamp. Set the p value | ||
| 24418 | ** appropriately. | ||
| 24419 | */ | ||
| 24420 | static void autoAdjustDate(DateTime *p){ | ||
| 24421 | if( !p->rawS || p->validJD ){ | ||
| 24422 | p->rawS = 0; | ||
| 24423 | }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ | ||
| 24424 | && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ | ||
| 24425 | ){ | ||
| 24426 | double r = p->s*1000.0 + 210866760000000.0; | ||
| 24427 | clearYMD_HMS_TZ(p); | ||
| 24428 | p->iJD = (sqlite3_int64)(r + 0.5); | ||
| 24429 | p->validJD = 1; | ||
| 24430 | p->rawS = 0; | ||
| 24431 | } | ||
| 24432 | } | ||
| 24433 | |||
| 24434 | /* | ||
| 23900 | ** Process a modifier to a date-time stamp. The modifiers are | 24435 | ** Process a modifier to a date-time stamp. The modifiers are |
| 23901 | ** as follows: | 24436 | ** as follows: |
| 23902 | ** | 24437 | ** |
| @@ -23939,19 +24474,8 @@ static int parseModifier( | |||
| 23939 | */ | 24474 | */ |
| 23940 | if( sqlite3_stricmp(z, "auto")==0 ){ | 24475 | if( sqlite3_stricmp(z, "auto")==0 ){ |
| 23941 | if( idx>1 ) return 1; /* IMP: R-33611-57934 */ | 24476 | if( idx>1 ) return 1; /* IMP: R-33611-57934 */ |
| 23942 | if( !p->rawS || p->validJD ){ | 24477 | autoAdjustDate(p); |
| 23943 | rc = 0; | 24478 | rc = 0; |
| 23944 | p->rawS = 0; | ||
| 23945 | }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ | ||
| 23946 | && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ | ||
| 23947 | ){ | ||
| 23948 | r = p->s*1000.0 + 210866760000000.0; | ||
| 23949 | clearYMD_HMS_TZ(p); | ||
| 23950 | p->iJD = (sqlite3_int64)(r + 0.5); | ||
| 23951 | p->validJD = 1; | ||
| 23952 | p->rawS = 0; | ||
| 23953 | rc = 0; | ||
| 23954 | } | ||
| 23955 | } | 24479 | } |
| 23956 | break; | 24480 | break; |
| 23957 | } | 24481 | } |
| @@ -24010,7 +24534,7 @@ static int parseModifier( | |||
| 24010 | i64 iOrigJD; /* Original localtime */ | 24534 | i64 iOrigJD; /* Original localtime */ |
| 24011 | i64 iGuess; /* Guess at the corresponding utc time */ | 24535 | i64 iGuess; /* Guess at the corresponding utc time */ |
| 24012 | int cnt = 0; /* Safety to prevent infinite loop */ | 24536 | int cnt = 0; /* Safety to prevent infinite loop */ |
| 24013 | int iErr; /* Guess is off by this much */ | 24537 | i64 iErr; /* Guess is off by this much */ |
| 24014 | 24538 | ||
| 24015 | computeJD(p); | 24539 | computeJD(p); |
| 24016 | iGuess = iOrigJD = p->iJD; | 24540 | iGuess = iOrigJD = p->iJD; |
| @@ -24046,7 +24570,7 @@ static int parseModifier( | |||
| 24046 | */ | 24570 | */ |
| 24047 | if( sqlite3_strnicmp(z, "weekday ", 8)==0 | 24571 | if( sqlite3_strnicmp(z, "weekday ", 8)==0 |
| 24048 | && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 | 24572 | && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 |
| 24049 | && (n=(int)r)==r && n>=0 && r<7 ){ | 24573 | && r>=0.0 && r<7.0 && (n=(int)r)==r ){ |
| 24050 | sqlite3_int64 Z; | 24574 | sqlite3_int64 Z; |
| 24051 | computeYMD_HMS(p); | 24575 | computeYMD_HMS(p); |
| 24052 | p->validTZ = 0; | 24576 | p->validTZ = 0; |
| @@ -24066,8 +24590,22 @@ static int parseModifier( | |||
| 24066 | ** | 24590 | ** |
| 24067 | ** Move the date backwards to the beginning of the current day, | 24591 | ** Move the date backwards to the beginning of the current day, |
| 24068 | ** or month or year. | 24592 | ** or month or year. |
| 24593 | ** | ||
| 24594 | ** subsecond | ||
| 24595 | ** subsec | ||
| 24596 | ** | ||
| 24597 | ** Show subsecond precision in the output of datetime() and | ||
| 24598 | ** unixepoch() and strftime('%s'). | ||
| 24069 | */ | 24599 | */ |
| 24070 | if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break; | 24600 | if( sqlite3_strnicmp(z, "start of ", 9)!=0 ){ |
| 24601 | if( sqlite3_stricmp(z, "subsec")==0 | ||
| 24602 | || sqlite3_stricmp(z, "subsecond")==0 | ||
| 24603 | ){ | ||
| 24604 | p->useSubsec = 1; | ||
| 24605 | rc = 0; | ||
| 24606 | } | ||
| 24607 | break; | ||
| 24608 | } | ||
| 24071 | if( !p->validJD && !p->validYMD && !p->validHMS ) break; | 24609 | if( !p->validJD && !p->validYMD && !p->validHMS ) break; |
| 24072 | z += 9; | 24610 | z += 9; |
| 24073 | computeYMD(p); | 24611 | computeYMD(p); |
| @@ -24103,18 +24641,73 @@ static int parseModifier( | |||
| 24103 | case '9': { | 24641 | case '9': { |
| 24104 | double rRounder; | 24642 | double rRounder; |
| 24105 | int i; | 24643 | int i; |
| 24106 | for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} | 24644 | int Y,M,D,h,m,x; |
| 24645 | const char *z2 = z; | ||
| 24646 | char z0 = z[0]; | ||
| 24647 | for(n=1; z[n]; n++){ | ||
| 24648 | if( z[n]==':' ) break; | ||
| 24649 | if( sqlite3Isspace(z[n]) ) break; | ||
| 24650 | if( z[n]=='-' ){ | ||
| 24651 | if( n==5 && getDigits(&z[1], "40f", &Y)==1 ) break; | ||
| 24652 | if( n==6 && getDigits(&z[1], "50f", &Y)==1 ) break; | ||
| 24653 | } | ||
| 24654 | } | ||
| 24107 | if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ | 24655 | if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ |
| 24108 | rc = 1; | 24656 | assert( rc==1 ); |
| 24109 | break; | 24657 | break; |
| 24110 | } | 24658 | } |
| 24111 | if( z[n]==':' ){ | 24659 | if( z[n]=='-' ){ |
| 24660 | /* A modifier of the form (+|-)YYYY-MM-DD adds or subtracts the | ||
| 24661 | ** specified number of years, months, and days. MM is limited to | ||
| 24662 | ** the range 0-11 and DD is limited to 0-30. | ||
| 24663 | */ | ||
| 24664 | if( z0!='+' && z0!='-' ) break; /* Must start with +/- */ | ||
| 24665 | if( n==5 ){ | ||
| 24666 | if( getDigits(&z[1], "40f-20a-20d", &Y, &M, &D)!=3 ) break; | ||
| 24667 | }else{ | ||
| 24668 | assert( n==6 ); | ||
| 24669 | if( getDigits(&z[1], "50f-20a-20d", &Y, &M, &D)!=3 ) break; | ||
| 24670 | z++; | ||
| 24671 | } | ||
| 24672 | if( M>=12 ) break; /* M range 0..11 */ | ||
| 24673 | if( D>=31 ) break; /* D range 0..30 */ | ||
| 24674 | computeYMD_HMS(p); | ||
| 24675 | p->validJD = 0; | ||
| 24676 | if( z0=='-' ){ | ||
| 24677 | p->Y -= Y; | ||
| 24678 | p->M -= M; | ||
| 24679 | D = -D; | ||
| 24680 | }else{ | ||
| 24681 | p->Y += Y; | ||
| 24682 | p->M += M; | ||
| 24683 | } | ||
| 24684 | x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; | ||
| 24685 | p->Y += x; | ||
| 24686 | p->M -= x*12; | ||
| 24687 | computeJD(p); | ||
| 24688 | p->validHMS = 0; | ||
| 24689 | p->validYMD = 0; | ||
| 24690 | p->iJD += (i64)D*86400000; | ||
| 24691 | if( z[11]==0 ){ | ||
| 24692 | rc = 0; | ||
| 24693 | break; | ||
| 24694 | } | ||
| 24695 | if( sqlite3Isspace(z[11]) | ||
| 24696 | && getDigits(&z[12], "20c:20e", &h, &m)==2 | ||
| 24697 | ){ | ||
| 24698 | z2 = &z[12]; | ||
| 24699 | n = 2; | ||
| 24700 | }else{ | ||
| 24701 | break; | ||
| 24702 | } | ||
| 24703 | } | ||
| 24704 | if( z2[n]==':' ){ | ||
| 24112 | /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the | 24705 | /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the |
| 24113 | ** specified number of hours, minutes, seconds, and fractional seconds | 24706 | ** specified number of hours, minutes, seconds, and fractional seconds |
| 24114 | ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be | 24707 | ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be |
| 24115 | ** omitted. | 24708 | ** omitted. |
| 24116 | */ | 24709 | */ |
| 24117 | const char *z2 = z; | 24710 | |
| 24118 | DateTime tx; | 24711 | DateTime tx; |
| 24119 | sqlite3_int64 day; | 24712 | sqlite3_int64 day; |
| 24120 | if( !sqlite3Isdigit(*z2) ) z2++; | 24713 | if( !sqlite3Isdigit(*z2) ) z2++; |
| @@ -24124,7 +24717,7 @@ static int parseModifier( | |||
| 24124 | tx.iJD -= 43200000; | 24717 | tx.iJD -= 43200000; |
| 24125 | day = tx.iJD/86400000; | 24718 | day = tx.iJD/86400000; |
| 24126 | tx.iJD -= day*86400000; | 24719 | tx.iJD -= day*86400000; |
| 24127 | if( z[0]=='-' ) tx.iJD = -tx.iJD; | 24720 | if( z0=='-' ) tx.iJD = -tx.iJD; |
| 24128 | computeJD(p); | 24721 | computeJD(p); |
| 24129 | clearYMD_HMS_TZ(p); | 24722 | clearYMD_HMS_TZ(p); |
| 24130 | p->iJD += tx.iJD; | 24723 | p->iJD += tx.iJD; |
| @@ -24140,7 +24733,7 @@ static int parseModifier( | |||
| 24140 | if( n>10 || n<3 ) break; | 24733 | if( n>10 || n<3 ) break; |
| 24141 | if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; | 24734 | if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; |
| 24142 | computeJD(p); | 24735 | computeJD(p); |
| 24143 | rc = 1; | 24736 | assert( rc==1 ); |
| 24144 | rRounder = r<0 ? -0.5 : +0.5; | 24737 | rRounder = r<0 ? -0.5 : +0.5; |
| 24145 | for(i=0; i<ArraySize(aXformType); i++){ | 24738 | for(i=0; i<ArraySize(aXformType); i++){ |
| 24146 | if( aXformType[i].nName==n | 24739 | if( aXformType[i].nName==n |
| @@ -24149,7 +24742,6 @@ static int parseModifier( | |||
| 24149 | ){ | 24742 | ){ |
| 24150 | switch( i ){ | 24743 | switch( i ){ |
| 24151 | case 4: { /* Special processing to add months */ | 24744 | case 4: { /* Special processing to add months */ |
| 24152 | int x; | ||
| 24153 | assert( strcmp(aXformType[i].zName,"month")==0 ); | 24745 | assert( strcmp(aXformType[i].zName,"month")==0 ); |
| 24154 | computeYMD_HMS(p); | 24746 | computeYMD_HMS(p); |
| 24155 | p->M += (int)r; | 24747 | p->M += (int)r; |
| @@ -24265,7 +24857,11 @@ static void unixepochFunc( | |||
| 24265 | DateTime x; | 24857 | DateTime x; |
| 24266 | if( isDate(context, argc, argv, &x)==0 ){ | 24858 | if( isDate(context, argc, argv, &x)==0 ){ |
| 24267 | computeJD(&x); | 24859 | computeJD(&x); |
| 24268 | sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); | 24860 | if( x.useSubsec ){ |
| 24861 | sqlite3_result_double(context, (x.iJD - 21086676*(i64)10000000)/1000.0); | ||
| 24862 | }else{ | ||
| 24863 | sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); | ||
| 24864 | } | ||
| 24269 | } | 24865 | } |
| 24270 | } | 24866 | } |
| 24271 | 24867 | ||
| @@ -24281,8 +24877,8 @@ static void datetimeFunc( | |||
| 24281 | ){ | 24877 | ){ |
| 24282 | DateTime x; | 24878 | DateTime x; |
| 24283 | if( isDate(context, argc, argv, &x)==0 ){ | 24879 | if( isDate(context, argc, argv, &x)==0 ){ |
| 24284 | int Y, s; | 24880 | int Y, s, n; |
| 24285 | char zBuf[24]; | 24881 | char zBuf[32]; |
| 24286 | computeYMD_HMS(&x); | 24882 | computeYMD_HMS(&x); |
| 24287 | Y = x.Y; | 24883 | Y = x.Y; |
| 24288 | if( Y<0 ) Y = -Y; | 24884 | if( Y<0 ) Y = -Y; |
| @@ -24303,15 +24899,28 @@ static void datetimeFunc( | |||
| 24303 | zBuf[15] = '0' + (x.m/10)%10; | 24899 | zBuf[15] = '0' + (x.m/10)%10; |
| 24304 | zBuf[16] = '0' + (x.m)%10; | 24900 | zBuf[16] = '0' + (x.m)%10; |
| 24305 | zBuf[17] = ':'; | 24901 | zBuf[17] = ':'; |
| 24306 | s = (int)x.s; | 24902 | if( x.useSubsec ){ |
| 24307 | zBuf[18] = '0' + (s/10)%10; | 24903 | s = (int)(1000.0*x.s + 0.5); |
| 24308 | zBuf[19] = '0' + (s)%10; | 24904 | zBuf[18] = '0' + (s/10000)%10; |
| 24309 | zBuf[20] = 0; | 24905 | zBuf[19] = '0' + (s/1000)%10; |
| 24906 | zBuf[20] = '.'; | ||
| 24907 | zBuf[21] = '0' + (s/100)%10; | ||
| 24908 | zBuf[22] = '0' + (s/10)%10; | ||
| 24909 | zBuf[23] = '0' + (s)%10; | ||
| 24910 | zBuf[24] = 0; | ||
| 24911 | n = 24; | ||
| 24912 | }else{ | ||
| 24913 | s = (int)x.s; | ||
| 24914 | zBuf[18] = '0' + (s/10)%10; | ||
| 24915 | zBuf[19] = '0' + (s)%10; | ||
| 24916 | zBuf[20] = 0; | ||
| 24917 | n = 20; | ||
| 24918 | } | ||
| 24310 | if( x.Y<0 ){ | 24919 | if( x.Y<0 ){ |
| 24311 | zBuf[0] = '-'; | 24920 | zBuf[0] = '-'; |
| 24312 | sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT); | 24921 | sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); |
| 24313 | }else{ | 24922 | }else{ |
| 24314 | sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT); | 24923 | sqlite3_result_text(context, &zBuf[1], n-1, SQLITE_TRANSIENT); |
| 24315 | } | 24924 | } |
| 24316 | } | 24925 | } |
| 24317 | } | 24926 | } |
| @@ -24328,7 +24937,7 @@ static void timeFunc( | |||
| 24328 | ){ | 24937 | ){ |
| 24329 | DateTime x; | 24938 | DateTime x; |
| 24330 | if( isDate(context, argc, argv, &x)==0 ){ | 24939 | if( isDate(context, argc, argv, &x)==0 ){ |
| 24331 | int s; | 24940 | int s, n; |
| 24332 | char zBuf[16]; | 24941 | char zBuf[16]; |
| 24333 | computeHMS(&x); | 24942 | computeHMS(&x); |
| 24334 | zBuf[0] = '0' + (x.h/10)%10; | 24943 | zBuf[0] = '0' + (x.h/10)%10; |
| @@ -24337,11 +24946,24 @@ static void timeFunc( | |||
| 24337 | zBuf[3] = '0' + (x.m/10)%10; | 24946 | zBuf[3] = '0' + (x.m/10)%10; |
| 24338 | zBuf[4] = '0' + (x.m)%10; | 24947 | zBuf[4] = '0' + (x.m)%10; |
| 24339 | zBuf[5] = ':'; | 24948 | zBuf[5] = ':'; |
| 24340 | s = (int)x.s; | 24949 | if( x.useSubsec ){ |
| 24341 | zBuf[6] = '0' + (s/10)%10; | 24950 | s = (int)(1000.0*x.s + 0.5); |
| 24342 | zBuf[7] = '0' + (s)%10; | 24951 | zBuf[6] = '0' + (s/10000)%10; |
| 24343 | zBuf[8] = 0; | 24952 | zBuf[7] = '0' + (s/1000)%10; |
| 24344 | sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT); | 24953 | zBuf[8] = '.'; |
| 24954 | zBuf[9] = '0' + (s/100)%10; | ||
| 24955 | zBuf[10] = '0' + (s/10)%10; | ||
| 24956 | zBuf[11] = '0' + (s)%10; | ||
| 24957 | zBuf[12] = 0; | ||
| 24958 | n = 12; | ||
| 24959 | }else{ | ||
| 24960 | s = (int)x.s; | ||
| 24961 | zBuf[6] = '0' + (s/10)%10; | ||
| 24962 | zBuf[7] = '0' + (s)%10; | ||
| 24963 | zBuf[8] = 0; | ||
| 24964 | n = 8; | ||
| 24965 | } | ||
| 24966 | sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); | ||
| 24345 | } | 24967 | } |
| 24346 | } | 24968 | } |
| 24347 | 24969 | ||
| @@ -24396,7 +25018,7 @@ static void dateFunc( | |||
| 24396 | ** %M minute 00-59 | 25018 | ** %M minute 00-59 |
| 24397 | ** %s seconds since 1970-01-01 | 25019 | ** %s seconds since 1970-01-01 |
| 24398 | ** %S seconds 00-59 | 25020 | ** %S seconds 00-59 |
| 24399 | ** %w day of week 0-6 sunday==0 | 25021 | ** %w day of week 0-6 Sunday==0 |
| 24400 | ** %W week of year 00-53 | 25022 | ** %W week of year 00-53 |
| 24401 | ** %Y year 0000-9999 | 25023 | ** %Y year 0000-9999 |
| 24402 | ** %% % | 25024 | ** %% % |
| @@ -24472,8 +25094,13 @@ static void strftimeFunc( | |||
| 24472 | break; | 25094 | break; |
| 24473 | } | 25095 | } |
| 24474 | case 's': { | 25096 | case 's': { |
| 24475 | i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); | 25097 | if( x.useSubsec ){ |
| 24476 | sqlite3_str_appendf(&sRes,"%lld",iS); | 25098 | sqlite3_str_appendf(&sRes,"%.3f", |
| 25099 | (x.iJD - 21086676*(i64)10000000)/1000.0); | ||
| 25100 | }else{ | ||
| 25101 | i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); | ||
| 25102 | sqlite3_str_appendf(&sRes,"%lld",iS); | ||
| 25103 | } | ||
| 24477 | break; | 25104 | break; |
| 24478 | } | 25105 | } |
| 24479 | case 'S': { | 25106 | case 'S': { |
| @@ -24532,6 +25159,117 @@ static void cdateFunc( | |||
| 24532 | } | 25159 | } |
| 24533 | 25160 | ||
| 24534 | /* | 25161 | /* |
| 25162 | ** timediff(DATE1, DATE2) | ||
| 25163 | ** | ||
| 25164 | ** Return the amount of time that must be added to DATE2 in order to | ||
| 25165 | ** convert it into DATE2. The time difference format is: | ||
| 25166 | ** | ||
| 25167 | ** +YYYY-MM-DD HH:MM:SS.SSS | ||
| 25168 | ** | ||
| 25169 | ** The initial "+" becomes "-" if DATE1 occurs before DATE2. For | ||
| 25170 | ** date/time values A and B, the following invariant should hold: | ||
| 25171 | ** | ||
| 25172 | ** datetime(A) == (datetime(B, timediff(A,B)) | ||
| 25173 | ** | ||
| 25174 | ** Both DATE arguments must be either a julian day number, or an | ||
| 25175 | ** ISO-8601 string. The unix timestamps are not supported by this | ||
| 25176 | ** routine. | ||
| 25177 | */ | ||
| 25178 | static void timediffFunc( | ||
| 25179 | sqlite3_context *context, | ||
| 25180 | int NotUsed1, | ||
| 25181 | sqlite3_value **argv | ||
| 25182 | ){ | ||
| 25183 | char sign; | ||
| 25184 | int Y, M; | ||
| 25185 | DateTime d1, d2; | ||
| 25186 | sqlite3_str sRes; | ||
| 25187 | UNUSED_PARAMETER(NotUsed1); | ||
| 25188 | if( isDate(context, 1, &argv[0], &d1) ) return; | ||
| 25189 | if( isDate(context, 1, &argv[1], &d2) ) return; | ||
| 25190 | computeYMD_HMS(&d1); | ||
| 25191 | computeYMD_HMS(&d2); | ||
| 25192 | if( d1.iJD>=d2.iJD ){ | ||
| 25193 | sign = '+'; | ||
| 25194 | Y = d1.Y - d2.Y; | ||
| 25195 | if( Y ){ | ||
| 25196 | d2.Y = d1.Y; | ||
| 25197 | d2.validJD = 0; | ||
| 25198 | computeJD(&d2); | ||
| 25199 | } | ||
| 25200 | M = d1.M - d2.M; | ||
| 25201 | if( M<0 ){ | ||
| 25202 | Y--; | ||
| 25203 | M += 12; | ||
| 25204 | } | ||
| 25205 | if( M!=0 ){ | ||
| 25206 | d2.M = d1.M; | ||
| 25207 | d2.validJD = 0; | ||
| 25208 | computeJD(&d2); | ||
| 25209 | } | ||
| 25210 | while( d1.iJD<d2.iJD ){ | ||
| 25211 | M--; | ||
| 25212 | if( M<0 ){ | ||
| 25213 | M = 11; | ||
| 25214 | Y--; | ||
| 25215 | } | ||
| 25216 | d2.M--; | ||
| 25217 | if( d2.M<1 ){ | ||
| 25218 | d2.M = 12; | ||
| 25219 | d2.Y--; | ||
| 25220 | } | ||
| 25221 | d2.validJD = 0; | ||
| 25222 | computeJD(&d2); | ||
| 25223 | } | ||
| 25224 | d1.iJD -= d2.iJD; | ||
| 25225 | d1.iJD += (u64)1486995408 * (u64)100000; | ||
| 25226 | }else /* d1<d2 */{ | ||
| 25227 | sign = '-'; | ||
| 25228 | Y = d2.Y - d1.Y; | ||
| 25229 | if( Y ){ | ||
| 25230 | d2.Y = d1.Y; | ||
| 25231 | d2.validJD = 0; | ||
| 25232 | computeJD(&d2); | ||
| 25233 | } | ||
| 25234 | M = d2.M - d1.M; | ||
| 25235 | if( M<0 ){ | ||
| 25236 | Y--; | ||
| 25237 | M += 12; | ||
| 25238 | } | ||
| 25239 | if( M!=0 ){ | ||
| 25240 | d2.M = d1.M; | ||
| 25241 | d2.validJD = 0; | ||
| 25242 | computeJD(&d2); | ||
| 25243 | } | ||
| 25244 | while( d1.iJD>d2.iJD ){ | ||
| 25245 | M--; | ||
| 25246 | if( M<0 ){ | ||
| 25247 | M = 11; | ||
| 25248 | Y--; | ||
| 25249 | } | ||
| 25250 | d2.M++; | ||
| 25251 | if( d2.M>12 ){ | ||
| 25252 | d2.M = 1; | ||
| 25253 | d2.Y++; | ||
| 25254 | } | ||
| 25255 | d2.validJD = 0; | ||
| 25256 | computeJD(&d2); | ||
| 25257 | } | ||
| 25258 | d1.iJD = d2.iJD - d1.iJD; | ||
| 25259 | d1.iJD += (u64)1486995408 * (u64)100000; | ||
| 25260 | } | ||
| 25261 | d1.validYMD = 0; | ||
| 25262 | d1.validHMS = 0; | ||
| 25263 | d1.validTZ = 0; | ||
| 25264 | computeYMD_HMS(&d1); | ||
| 25265 | sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); | ||
| 25266 | sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", | ||
| 25267 | sign, Y, M, d1.D-1, d1.h, d1.m, d1.s); | ||
| 25268 | sqlite3ResultStrAccum(context, &sRes); | ||
| 25269 | } | ||
| 25270 | |||
| 25271 | |||
| 25272 | /* | ||
| 24535 | ** current_timestamp() | 25273 | ** current_timestamp() |
| 24536 | ** | 25274 | ** |
| 24537 | ** This function returns the same value as datetime('now'). | 25275 | ** This function returns the same value as datetime('now'). |
| @@ -24605,6 +25343,7 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ | |||
| 24605 | PURE_DATE(time, -1, 0, 0, timeFunc ), | 25343 | PURE_DATE(time, -1, 0, 0, timeFunc ), |
| 24606 | PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), | 25344 | PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), |
| 24607 | PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), | 25345 | PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), |
| 25346 | PURE_DATE(timediff, 2, 0, 0, timediffFunc ), | ||
| 24608 | DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), | 25347 | DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), |
| 24609 | DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), | 25348 | DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), |
| 24610 | DFUNCTION(current_date, 0, 0, 0, cdateFunc ), | 25349 | DFUNCTION(current_date, 0, 0, 0, cdateFunc ), |
| @@ -24727,9 +25466,11 @@ SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ | |||
| 24727 | } | 25466 | } |
| 24728 | SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ | 25467 | SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ |
| 24729 | DO_OS_MALLOC_TEST(id); | 25468 | DO_OS_MALLOC_TEST(id); |
| 25469 | assert( lockType>=SQLITE_LOCK_SHARED && lockType<=SQLITE_LOCK_EXCLUSIVE ); | ||
| 24730 | return id->pMethods->xLock(id, lockType); | 25470 | return id->pMethods->xLock(id, lockType); |
| 24731 | } | 25471 | } |
| 24732 | SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ | 25472 | SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ |
| 25473 | assert( lockType==SQLITE_LOCK_NONE || lockType==SQLITE_LOCK_SHARED ); | ||
| 24733 | return id->pMethods->xUnlock(id, lockType); | 25474 | return id->pMethods->xUnlock(id, lockType); |
| 24734 | } | 25475 | } |
| 24735 | SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ | 25476 | SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ |
| @@ -24756,7 +25497,7 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ | |||
| 24756 | /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite | 25497 | /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite |
| 24757 | ** is using a regular VFS, it is called after the corresponding | 25498 | ** is using a regular VFS, it is called after the corresponding |
| 24758 | ** transaction has been committed. Injecting a fault at this point | 25499 | ** transaction has been committed. Injecting a fault at this point |
| 24759 | ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM | 25500 | ** confuses the test scripts - the COMMIT command returns SQLITE_NOMEM |
| 24760 | ** but the transaction is committed anyway. | 25501 | ** but the transaction is committed anyway. |
| 24761 | ** | 25502 | ** |
| 24762 | ** The core must call OsFileControl() though, not OsFileControlHint(), | 25503 | ** The core must call OsFileControl() though, not OsFileControlHint(), |
| @@ -24844,6 +25585,7 @@ SQLITE_PRIVATE int sqlite3OsOpen( | |||
| 24844 | ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, | 25585 | ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, |
| 24845 | ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before | 25586 | ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before |
| 24846 | ** reaching the VFS. */ | 25587 | ** reaching the VFS. */ |
| 25588 | assert( zPath || (flags & SQLITE_OPEN_EXCLUSIVE) ); | ||
| 24847 | rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut); | 25589 | rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut); |
| 24848 | assert( rc==SQLITE_OK || pFile->pMethods==0 ); | 25590 | assert( rc==SQLITE_OK || pFile->pMethods==0 ); |
| 24849 | return rc; | 25591 | return rc; |
| @@ -25376,7 +26118,7 @@ static void *sqlite3MemMalloc(int nByte){ | |||
| 25376 | ** or sqlite3MemRealloc(). | 26118 | ** or sqlite3MemRealloc(). |
| 25377 | ** | 26119 | ** |
| 25378 | ** For this low-level routine, we already know that pPrior!=0 since | 26120 | ** For this low-level routine, we already know that pPrior!=0 since |
| 25379 | ** cases where pPrior==0 will have been intecepted and dealt with | 26121 | ** cases where pPrior==0 will have been intercepted and dealt with |
| 25380 | ** by higher-level routines. | 26122 | ** by higher-level routines. |
| 25381 | */ | 26123 | */ |
| 25382 | static void sqlite3MemFree(void *pPrior){ | 26124 | static void sqlite3MemFree(void *pPrior){ |
| @@ -25464,7 +26206,7 @@ static int sqlite3MemInit(void *NotUsed){ | |||
| 25464 | return SQLITE_OK; | 26206 | return SQLITE_OK; |
| 25465 | } | 26207 | } |
| 25466 | len = sizeof(cpuCount); | 26208 | len = sizeof(cpuCount); |
| 25467 | /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ | 26209 | /* One usually wants to use hw.activecpu for MT decisions, but not here */ |
| 25468 | sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); | 26210 | sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); |
| 25469 | if( cpuCount>1 ){ | 26211 | if( cpuCount>1 ){ |
| 25470 | /* defer MT decisions to system malloc */ | 26212 | /* defer MT decisions to system malloc */ |
| @@ -27159,9 +27901,13 @@ static int memsys5Roundup(int n){ | |||
| 27159 | if( n<=mem5.szAtom ) return mem5.szAtom; | 27901 | if( n<=mem5.szAtom ) return mem5.szAtom; |
| 27160 | return mem5.szAtom*2; | 27902 | return mem5.szAtom*2; |
| 27161 | } | 27903 | } |
| 27162 | if( n>0x40000000 ) return 0; | 27904 | if( n>0x10000000 ){ |
| 27905 | if( n>0x40000000 ) return 0; | ||
| 27906 | if( n>0x20000000 ) return 0x40000000; | ||
| 27907 | return 0x20000000; | ||
| 27908 | } | ||
| 27163 | for(iFullSz=mem5.szAtom*8; iFullSz<n; iFullSz *= 4); | 27909 | for(iFullSz=mem5.szAtom*8; iFullSz<n; iFullSz *= 4); |
| 27164 | if( (iFullSz/2)>=n ) return iFullSz/2; | 27910 | if( (iFullSz/2)>=(i64)n ) return iFullSz/2; |
| 27165 | return iFullSz; | 27911 | return iFullSz; |
| 27166 | } | 27912 | } |
| 27167 | 27913 | ||
| @@ -27927,7 +28673,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ | |||
| 27927 | 28673 | ||
| 27928 | /* | 28674 | /* |
| 27929 | ** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields | 28675 | ** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields |
| 27930 | ** are necessary under two condidtions: (1) Debug builds and (2) using | 28676 | ** are necessary under two conditions: (1) Debug builds and (2) using |
| 27931 | ** home-grown mutexes. Encapsulate these conditions into a single #define. | 28677 | ** home-grown mutexes. Encapsulate these conditions into a single #define. |
| 27932 | */ | 28678 | */ |
| 27933 | #if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) | 28679 | #if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) |
| @@ -28428,7 +29174,7 @@ struct sqlite3_mutex { | |||
| 28428 | CRITICAL_SECTION mutex; /* Mutex controlling the lock */ | 29174 | CRITICAL_SECTION mutex; /* Mutex controlling the lock */ |
| 28429 | int id; /* Mutex type */ | 29175 | int id; /* Mutex type */ |
| 28430 | #ifdef SQLITE_DEBUG | 29176 | #ifdef SQLITE_DEBUG |
| 28431 | volatile int nRef; /* Number of enterances */ | 29177 | volatile int nRef; /* Number of entrances */ |
| 28432 | volatile DWORD owner; /* Thread holding this mutex */ | 29178 | volatile DWORD owner; /* Thread holding this mutex */ |
| 28433 | volatile LONG trace; /* True to trace changes */ | 29179 | volatile LONG trace; /* True to trace changes */ |
| 28434 | #endif | 29180 | #endif |
| @@ -29063,17 +29809,33 @@ static void mallocWithAlarm(int n, void **pp){ | |||
| 29063 | } | 29809 | } |
| 29064 | 29810 | ||
| 29065 | /* | 29811 | /* |
| 29812 | ** Maximum size of any single memory allocation. | ||
| 29813 | ** | ||
| 29814 | ** This is not a limit on the total amount of memory used. This is | ||
| 29815 | ** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). | ||
| 29816 | ** | ||
| 29817 | ** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 | ||
| 29818 | ** This provides a 256-byte safety margin for defense against 32-bit | ||
| 29819 | ** signed integer overflow bugs when computing memory allocation sizes. | ||
| 29820 | ** Paranoid applications might want to reduce the maximum allocation size | ||
| 29821 | ** further for an even larger safety margin. 0x3fffffff or 0x0fffffff | ||
| 29822 | ** or even smaller would be reasonable upper bounds on the size of a memory | ||
| 29823 | ** allocations for most applications. | ||
| 29824 | */ | ||
| 29825 | #ifndef SQLITE_MAX_ALLOCATION_SIZE | ||
| 29826 | # define SQLITE_MAX_ALLOCATION_SIZE 2147483391 | ||
| 29827 | #endif | ||
| 29828 | #if SQLITE_MAX_ALLOCATION_SIZE>2147483391 | ||
| 29829 | # error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 | ||
| 29830 | #endif | ||
| 29831 | |||
| 29832 | /* | ||
| 29066 | ** Allocate memory. This routine is like sqlite3_malloc() except that it | 29833 | ** Allocate memory. This routine is like sqlite3_malloc() except that it |
| 29067 | ** assumes the memory subsystem has already been initialized. | 29834 | ** assumes the memory subsystem has already been initialized. |
| 29068 | */ | 29835 | */ |
| 29069 | SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ | 29836 | SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ |
| 29070 | void *p; | 29837 | void *p; |
| 29071 | if( n==0 || n>=0x7fffff00 ){ | 29838 | if( n==0 || n>SQLITE_MAX_ALLOCATION_SIZE ){ |
| 29072 | /* A memory allocation of a number of bytes which is near the maximum | ||
| 29073 | ** signed integer value might cause an integer overflow inside of the | ||
| 29074 | ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving | ||
| 29075 | ** 255 bytes of overhead. SQLite itself will never use anything near | ||
| 29076 | ** this amount. The only way to reach the limit is with sqlite3_malloc() */ | ||
| 29077 | p = 0; | 29839 | p = 0; |
| 29078 | }else if( sqlite3GlobalConfig.bMemstat ){ | 29840 | }else if( sqlite3GlobalConfig.bMemstat ){ |
| 29079 | sqlite3_mutex_enter(mem0.mutex); | 29841 | sqlite3_mutex_enter(mem0.mutex); |
| @@ -29109,7 +29871,7 @@ SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){ | |||
| 29109 | */ | 29871 | */ |
| 29110 | #ifndef SQLITE_OMIT_LOOKASIDE | 29872 | #ifndef SQLITE_OMIT_LOOKASIDE |
| 29111 | static int isLookaside(sqlite3 *db, const void *p){ | 29873 | static int isLookaside(sqlite3 *db, const void *p){ |
| 29112 | return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd); | 29874 | return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pTrueEnd); |
| 29113 | } | 29875 | } |
| 29114 | #else | 29876 | #else |
| 29115 | #define isLookaside(A,B) 0 | 29877 | #define isLookaside(A,B) 0 |
| @@ -29133,18 +29895,16 @@ static int lookasideMallocSize(sqlite3 *db, const void *p){ | |||
| 29133 | SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){ | 29895 | SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){ |
| 29134 | assert( p!=0 ); | 29896 | assert( p!=0 ); |
| 29135 | #ifdef SQLITE_DEBUG | 29897 | #ifdef SQLITE_DEBUG |
| 29136 | if( db==0 || !isLookaside(db,p) ){ | 29898 | if( db==0 ){ |
| 29137 | if( db==0 ){ | 29899 | assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); |
| 29138 | assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); | 29900 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); |
| 29139 | assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); | 29901 | }else if( !isLookaside(db,p) ){ |
| 29140 | }else{ | 29902 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 29141 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | 29903 | assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 29142 | assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | ||
| 29143 | } | ||
| 29144 | } | 29904 | } |
| 29145 | #endif | 29905 | #endif |
| 29146 | if( db ){ | 29906 | if( db ){ |
| 29147 | if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ | 29907 | if( ((uptr)p)<(uptr)(db->lookaside.pTrueEnd) ){ |
| 29148 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE | 29908 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE |
| 29149 | if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ | 29909 | if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ |
| 29150 | assert( sqlite3_mutex_held(db->mutex) ); | 29910 | assert( sqlite3_mutex_held(db->mutex) ); |
| @@ -29200,14 +29960,11 @@ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ | |||
| 29200 | assert( db==0 || sqlite3_mutex_held(db->mutex) ); | 29960 | assert( db==0 || sqlite3_mutex_held(db->mutex) ); |
| 29201 | assert( p!=0 ); | 29961 | assert( p!=0 ); |
| 29202 | if( db ){ | 29962 | if( db ){ |
| 29203 | if( db->pnBytesFreed ){ | ||
| 29204 | measureAllocationSize(db, p); | ||
| 29205 | return; | ||
| 29206 | } | ||
| 29207 | if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ | 29963 | if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ |
| 29208 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE | 29964 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE |
| 29209 | if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ | 29965 | if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ |
| 29210 | LookasideSlot *pBuf = (LookasideSlot*)p; | 29966 | LookasideSlot *pBuf = (LookasideSlot*)p; |
| 29967 | assert( db->pnBytesFreed==0 ); | ||
| 29211 | #ifdef SQLITE_DEBUG | 29968 | #ifdef SQLITE_DEBUG |
| 29212 | memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ | 29969 | memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ |
| 29213 | #endif | 29970 | #endif |
| @@ -29218,6 +29975,7 @@ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ | |||
| 29218 | #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ | 29975 | #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ |
| 29219 | if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ | 29976 | if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ |
| 29220 | LookasideSlot *pBuf = (LookasideSlot*)p; | 29977 | LookasideSlot *pBuf = (LookasideSlot*)p; |
| 29978 | assert( db->pnBytesFreed==0 ); | ||
| 29221 | #ifdef SQLITE_DEBUG | 29979 | #ifdef SQLITE_DEBUG |
| 29222 | memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ | 29980 | memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ |
| 29223 | #endif | 29981 | #endif |
| @@ -29226,6 +29984,10 @@ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ | |||
| 29226 | return; | 29984 | return; |
| 29227 | } | 29985 | } |
| 29228 | } | 29986 | } |
| 29987 | if( db->pnBytesFreed ){ | ||
| 29988 | measureAllocationSize(db, p); | ||
| 29989 | return; | ||
| 29990 | } | ||
| 29229 | } | 29991 | } |
| 29230 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | 29992 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| 29231 | assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | 29993 | assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); |
| @@ -29233,6 +29995,43 @@ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ | |||
| 29233 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); | 29995 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| 29234 | sqlite3_free(p); | 29996 | sqlite3_free(p); |
| 29235 | } | 29997 | } |
| 29998 | SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3 *db, void *p){ | ||
| 29999 | assert( db!=0 ); | ||
| 30000 | assert( sqlite3_mutex_held(db->mutex) ); | ||
| 30001 | assert( p!=0 ); | ||
| 30002 | if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ | ||
| 30003 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE | ||
| 30004 | if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ | ||
| 30005 | LookasideSlot *pBuf = (LookasideSlot*)p; | ||
| 30006 | assert( db->pnBytesFreed==0 ); | ||
| 30007 | #ifdef SQLITE_DEBUG | ||
| 30008 | memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ | ||
| 30009 | #endif | ||
| 30010 | pBuf->pNext = db->lookaside.pSmallFree; | ||
| 30011 | db->lookaside.pSmallFree = pBuf; | ||
| 30012 | return; | ||
| 30013 | } | ||
| 30014 | #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ | ||
| 30015 | if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ | ||
| 30016 | LookasideSlot *pBuf = (LookasideSlot*)p; | ||
| 30017 | assert( db->pnBytesFreed==0 ); | ||
| 30018 | #ifdef SQLITE_DEBUG | ||
| 30019 | memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ | ||
| 30020 | #endif | ||
| 30021 | pBuf->pNext = db->lookaside.pFree; | ||
| 30022 | db->lookaside.pFree = pBuf; | ||
| 30023 | return; | ||
| 30024 | } | ||
| 30025 | } | ||
| 30026 | if( db->pnBytesFreed ){ | ||
| 30027 | measureAllocationSize(db, p); | ||
| 30028 | return; | ||
| 30029 | } | ||
| 30030 | assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | ||
| 30031 | assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); | ||
| 30032 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); | ||
| 30033 | sqlite3_free(p); | ||
| 30034 | } | ||
| 29236 | SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ | 30035 | SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ |
| 29237 | assert( db==0 || sqlite3_mutex_held(db->mutex) ); | 30036 | assert( db==0 || sqlite3_mutex_held(db->mutex) ); |
| 29238 | if( p ) sqlite3DbFreeNN(db, p); | 30037 | if( p ) sqlite3DbFreeNN(db, p); |
| @@ -29532,9 +30331,14 @@ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ | |||
| 29532 | */ | 30331 | */ |
| 29533 | SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ | 30332 | SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ |
| 29534 | int n; | 30333 | int n; |
| 30334 | #ifdef SQLITE_DEBUG | ||
| 30335 | /* Because of the way the parser works, the span is guaranteed to contain | ||
| 30336 | ** at least one non-space character */ | ||
| 30337 | for(n=0; sqlite3Isspace(zStart[n]); n++){ assert( &zStart[n]<zEnd ); } | ||
| 30338 | #endif | ||
| 29535 | while( sqlite3Isspace(zStart[0]) ) zStart++; | 30339 | while( sqlite3Isspace(zStart[0]) ) zStart++; |
| 29536 | n = (int)(zEnd - zStart); | 30340 | n = (int)(zEnd - zStart); |
| 29537 | while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--; | 30341 | while( sqlite3Isspace(zStart[n-1]) ) n--; |
| 29538 | return sqlite3DbStrNDup(db, zStart, n); | 30342 | return sqlite3DbStrNDup(db, zStart, n); |
| 29539 | } | 30343 | } |
| 29540 | 30344 | ||
| @@ -29742,43 +30546,6 @@ static const et_info fmtinfo[] = { | |||
| 29742 | ** %!S Like %S but prefer the zName over the zAlias | 30546 | ** %!S Like %S but prefer the zName over the zAlias |
| 29743 | */ | 30547 | */ |
| 29744 | 30548 | ||
| 29745 | /* Floating point constants used for rounding */ | ||
| 29746 | static const double arRound[] = { | ||
| 29747 | 5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05, | ||
| 29748 | 5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10, | ||
| 29749 | }; | ||
| 29750 | |||
| 29751 | /* | ||
| 29752 | ** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point | ||
| 29753 | ** conversions will work. | ||
| 29754 | */ | ||
| 29755 | #ifndef SQLITE_OMIT_FLOATING_POINT | ||
| 29756 | /* | ||
| 29757 | ** "*val" is a double such that 0.1 <= *val < 10.0 | ||
| 29758 | ** Return the ascii code for the leading digit of *val, then | ||
| 29759 | ** multiply "*val" by 10.0 to renormalize. | ||
| 29760 | ** | ||
| 29761 | ** Example: | ||
| 29762 | ** input: *val = 3.14159 | ||
| 29763 | ** output: *val = 1.4159 function return = '3' | ||
| 29764 | ** | ||
| 29765 | ** The counter *cnt is incremented each time. After counter exceeds | ||
| 29766 | ** 16 (the number of significant digits in a 64-bit float) '0' is | ||
| 29767 | ** always returned. | ||
| 29768 | */ | ||
| 29769 | static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ | ||
| 29770 | int digit; | ||
| 29771 | LONGDOUBLE_TYPE d; | ||
| 29772 | if( (*cnt)<=0 ) return '0'; | ||
| 29773 | (*cnt)--; | ||
| 29774 | digit = (int)*val; | ||
| 29775 | d = digit; | ||
| 29776 | digit += '0'; | ||
| 29777 | *val = (*val - d)*10.0; | ||
| 29778 | return (char)digit; | ||
| 29779 | } | ||
| 29780 | #endif /* SQLITE_OMIT_FLOATING_POINT */ | ||
| 29781 | |||
| 29782 | /* | 30549 | /* |
| 29783 | ** Set the StrAccum object to an error mode. | 30550 | ** Set the StrAccum object to an error mode. |
| 29784 | */ | 30551 | */ |
| @@ -29870,18 +30637,15 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 29870 | u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ | 30637 | u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ |
| 29871 | char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ | 30638 | char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ |
| 29872 | sqlite_uint64 longvalue; /* Value for integer types */ | 30639 | sqlite_uint64 longvalue; /* Value for integer types */ |
| 29873 | LONGDOUBLE_TYPE realvalue; /* Value for real types */ | 30640 | double realvalue; /* Value for real types */ |
| 29874 | const et_info *infop; /* Pointer to the appropriate info structure */ | 30641 | const et_info *infop; /* Pointer to the appropriate info structure */ |
| 29875 | char *zOut; /* Rendering buffer */ | 30642 | char *zOut; /* Rendering buffer */ |
| 29876 | int nOut; /* Size of the rendering buffer */ | 30643 | int nOut; /* Size of the rendering buffer */ |
| 29877 | char *zExtra = 0; /* Malloced memory used by some conversion */ | 30644 | char *zExtra = 0; /* Malloced memory used by some conversion */ |
| 29878 | #ifndef SQLITE_OMIT_FLOATING_POINT | 30645 | int exp, e2; /* exponent of real numbers */ |
| 29879 | int exp, e2; /* exponent of real numbers */ | ||
| 29880 | int nsd; /* Number of significant digits returned */ | ||
| 29881 | double rounder; /* Used for rounding floating point values */ | ||
| 29882 | etByte flag_dp; /* True if decimal point should be shown */ | 30646 | etByte flag_dp; /* True if decimal point should be shown */ |
| 29883 | etByte flag_rtz; /* True if trailing zeros should be removed */ | 30647 | etByte flag_rtz; /* True if trailing zeros should be removed */ |
| 29884 | #endif | 30648 | |
| 29885 | PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ | 30649 | PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ |
| 29886 | char buf[etBUFSIZE]; /* Conversion buffer */ | 30650 | char buf[etBUFSIZE]; /* Conversion buffer */ |
| 29887 | 30651 | ||
| @@ -30156,73 +30920,66 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 30156 | break; | 30920 | break; |
| 30157 | case etFLOAT: | 30921 | case etFLOAT: |
| 30158 | case etEXP: | 30922 | case etEXP: |
| 30159 | case etGENERIC: | 30923 | case etGENERIC: { |
| 30924 | FpDecode s; | ||
| 30925 | int iRound; | ||
| 30926 | int j; | ||
| 30927 | |||
| 30160 | if( bArgList ){ | 30928 | if( bArgList ){ |
| 30161 | realvalue = getDoubleArg(pArgList); | 30929 | realvalue = getDoubleArg(pArgList); |
| 30162 | }else{ | 30930 | }else{ |
| 30163 | realvalue = va_arg(ap,double); | 30931 | realvalue = va_arg(ap,double); |
| 30164 | } | 30932 | } |
| 30165 | #ifdef SQLITE_OMIT_FLOATING_POINT | ||
| 30166 | length = 0; | ||
| 30167 | #else | ||
| 30168 | if( precision<0 ) precision = 6; /* Set default precision */ | 30933 | if( precision<0 ) precision = 6; /* Set default precision */ |
| 30169 | #ifdef SQLITE_FP_PRECISION_LIMIT | 30934 | #ifdef SQLITE_FP_PRECISION_LIMIT |
| 30170 | if( precision>SQLITE_FP_PRECISION_LIMIT ){ | 30935 | if( precision>SQLITE_FP_PRECISION_LIMIT ){ |
| 30171 | precision = SQLITE_FP_PRECISION_LIMIT; | 30936 | precision = SQLITE_FP_PRECISION_LIMIT; |
| 30172 | } | 30937 | } |
| 30173 | #endif | 30938 | #endif |
| 30174 | if( realvalue<0.0 ){ | ||
| 30175 | realvalue = -realvalue; | ||
| 30176 | prefix = '-'; | ||
| 30177 | }else{ | ||
| 30178 | prefix = flag_prefix; | ||
| 30179 | } | ||
| 30180 | if( xtype==etGENERIC && precision>0 ) precision--; | ||
| 30181 | testcase( precision>0xfff ); | ||
| 30182 | idx = precision & 0xfff; | ||
| 30183 | rounder = arRound[idx%10]; | ||
| 30184 | while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; } | ||
| 30185 | if( xtype==etFLOAT ){ | 30939 | if( xtype==etFLOAT ){ |
| 30186 | double rx = (double)realvalue; | 30940 | iRound = -precision; |
| 30187 | sqlite3_uint64 u; | 30941 | }else if( xtype==etGENERIC ){ |
| 30188 | int ex; | 30942 | iRound = precision; |
| 30189 | memcpy(&u, &rx, sizeof(u)); | 30943 | }else{ |
| 30190 | ex = -1023 + (int)((u>>52)&0x7ff); | 30944 | iRound = precision+1; |
| 30191 | if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16; | ||
| 30192 | realvalue += rounder; | ||
| 30193 | } | ||
| 30194 | /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ | ||
| 30195 | exp = 0; | ||
| 30196 | if( sqlite3IsNaN((double)realvalue) ){ | ||
| 30197 | bufpt = "NaN"; | ||
| 30198 | length = 3; | ||
| 30199 | break; | ||
| 30200 | } | 30945 | } |
| 30201 | if( realvalue>0.0 ){ | 30946 | sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16); |
| 30202 | LONGDOUBLE_TYPE scale = 1.0; | 30947 | if( s.isSpecial ){ |
| 30203 | while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;} | 30948 | if( s.isSpecial==2 ){ |
| 30204 | while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; } | 30949 | bufpt = flag_zeropad ? "null" : "NaN"; |
| 30205 | while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } | 30950 | length = sqlite3Strlen30(bufpt); |
| 30206 | realvalue /= scale; | 30951 | break; |
| 30207 | while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } | 30952 | }else if( flag_zeropad ){ |
| 30208 | while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } | 30953 | s.z[0] = '9'; |
| 30209 | if( exp>350 ){ | 30954 | s.iDP = 1000; |
| 30955 | s.n = 1; | ||
| 30956 | }else{ | ||
| 30957 | memcpy(buf, "-Inf", 5); | ||
| 30210 | bufpt = buf; | 30958 | bufpt = buf; |
| 30211 | buf[0] = prefix; | 30959 | if( s.sign=='-' ){ |
| 30212 | memcpy(buf+(prefix!=0),"Inf",4); | 30960 | /* no-op */ |
| 30213 | length = 3+(prefix!=0); | 30961 | }else if( flag_prefix ){ |
| 30962 | buf[0] = flag_prefix; | ||
| 30963 | }else{ | ||
| 30964 | bufpt++; | ||
| 30965 | } | ||
| 30966 | length = sqlite3Strlen30(bufpt); | ||
| 30214 | break; | 30967 | break; |
| 30215 | } | 30968 | } |
| 30216 | } | 30969 | } |
| 30217 | bufpt = buf; | 30970 | if( s.sign=='-' ){ |
| 30971 | prefix = '-'; | ||
| 30972 | }else{ | ||
| 30973 | prefix = flag_prefix; | ||
| 30974 | } | ||
| 30975 | |||
| 30976 | exp = s.iDP-1; | ||
| 30977 | if( xtype==etGENERIC && precision>0 ) precision--; | ||
| 30978 | |||
| 30218 | /* | 30979 | /* |
| 30219 | ** If the field type is etGENERIC, then convert to either etEXP | 30980 | ** If the field type is etGENERIC, then convert to either etEXP |
| 30220 | ** or etFLOAT, as appropriate. | 30981 | ** or etFLOAT, as appropriate. |
| 30221 | */ | 30982 | */ |
| 30222 | if( xtype!=etFLOAT ){ | ||
| 30223 | realvalue += rounder; | ||
| 30224 | if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } | ||
| 30225 | } | ||
| 30226 | if( xtype==etGENERIC ){ | 30983 | if( xtype==etGENERIC ){ |
| 30227 | flag_rtz = !flag_alternateform; | 30984 | flag_rtz = !flag_alternateform; |
| 30228 | if( exp<-4 || exp>precision ){ | 30985 | if( exp<-4 || exp>precision ){ |
| @@ -30237,29 +30994,32 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 30237 | if( xtype==etEXP ){ | 30994 | if( xtype==etEXP ){ |
| 30238 | e2 = 0; | 30995 | e2 = 0; |
| 30239 | }else{ | 30996 | }else{ |
| 30240 | e2 = exp; | 30997 | e2 = s.iDP - 1; |
| 30241 | } | 30998 | } |
| 30999 | bufpt = buf; | ||
| 30242 | { | 31000 | { |
| 30243 | i64 szBufNeeded; /* Size of a temporary buffer needed */ | 31001 | i64 szBufNeeded; /* Size of a temporary buffer needed */ |
| 30244 | szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15; | 31002 | szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15; |
| 31003 | if( cThousand && e2>0 ) szBufNeeded += (e2+2)/3; | ||
| 30245 | if( szBufNeeded > etBUFSIZE ){ | 31004 | if( szBufNeeded > etBUFSIZE ){ |
| 30246 | bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded); | 31005 | bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded); |
| 30247 | if( bufpt==0 ) return; | 31006 | if( bufpt==0 ) return; |
| 30248 | } | 31007 | } |
| 30249 | } | 31008 | } |
| 30250 | zOut = bufpt; | 31009 | zOut = bufpt; |
| 30251 | nsd = 16 + flag_altform2*10; | ||
| 30252 | flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; | 31010 | flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; |
| 30253 | /* The sign in front of the number */ | 31011 | /* The sign in front of the number */ |
| 30254 | if( prefix ){ | 31012 | if( prefix ){ |
| 30255 | *(bufpt++) = prefix; | 31013 | *(bufpt++) = prefix; |
| 30256 | } | 31014 | } |
| 30257 | /* Digits prior to the decimal point */ | 31015 | /* Digits prior to the decimal point */ |
| 31016 | j = 0; | ||
| 30258 | if( e2<0 ){ | 31017 | if( e2<0 ){ |
| 30259 | *(bufpt++) = '0'; | 31018 | *(bufpt++) = '0'; |
| 30260 | }else{ | 31019 | }else{ |
| 30261 | for(; e2>=0; e2--){ | 31020 | for(; e2>=0; e2--){ |
| 30262 | *(bufpt++) = et_getdigit(&realvalue,&nsd); | 31021 | *(bufpt++) = j<s.n ? s.z[j++] : '0'; |
| 31022 | if( cThousand && (e2%3)==0 && e2>1 ) *(bufpt++) = ','; | ||
| 30263 | } | 31023 | } |
| 30264 | } | 31024 | } |
| 30265 | /* The decimal point */ | 31025 | /* The decimal point */ |
| @@ -30268,13 +31028,12 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 30268 | } | 31028 | } |
| 30269 | /* "0" digits after the decimal point but before the first | 31029 | /* "0" digits after the decimal point but before the first |
| 30270 | ** significant digit of the number */ | 31030 | ** significant digit of the number */ |
| 30271 | for(e2++; e2<0; precision--, e2++){ | 31031 | for(e2++; e2<0 && precision>0; precision--, e2++){ |
| 30272 | assert( precision>0 ); | ||
| 30273 | *(bufpt++) = '0'; | 31032 | *(bufpt++) = '0'; |
| 30274 | } | 31033 | } |
| 30275 | /* Significant digits after the decimal point */ | 31034 | /* Significant digits after the decimal point */ |
| 30276 | while( (precision--)>0 ){ | 31035 | while( (precision--)>0 ){ |
| 30277 | *(bufpt++) = et_getdigit(&realvalue,&nsd); | 31036 | *(bufpt++) = j<s.n ? s.z[j++] : '0'; |
| 30278 | } | 31037 | } |
| 30279 | /* Remove trailing zeros and the "." if no digits follow the "." */ | 31038 | /* Remove trailing zeros and the "." if no digits follow the "." */ |
| 30280 | if( flag_rtz && flag_dp ){ | 31039 | if( flag_rtz && flag_dp ){ |
| @@ -30290,6 +31049,7 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 30290 | } | 31049 | } |
| 30291 | /* Add the "eNNN" suffix */ | 31050 | /* Add the "eNNN" suffix */ |
| 30292 | if( xtype==etEXP ){ | 31051 | if( xtype==etEXP ){ |
| 31052 | exp = s.iDP - 1; | ||
| 30293 | *(bufpt++) = aDigits[infop->charset]; | 31053 | *(bufpt++) = aDigits[infop->charset]; |
| 30294 | if( exp<0 ){ | 31054 | if( exp<0 ){ |
| 30295 | *(bufpt++) = '-'; exp = -exp; | 31055 | *(bufpt++) = '-'; exp = -exp; |
| @@ -30323,8 +31083,8 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 30323 | while( nPad-- ) bufpt[i++] = '0'; | 31083 | while( nPad-- ) bufpt[i++] = '0'; |
| 30324 | length = width; | 31084 | length = width; |
| 30325 | } | 31085 | } |
| 30326 | #endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */ | ||
| 30327 | break; | 31086 | break; |
| 31087 | } | ||
| 30328 | case etSIZE: | 31088 | case etSIZE: |
| 30329 | if( !bArgList ){ | 31089 | if( !bArgList ){ |
| 30330 | *(va_arg(ap,int*)) = pAccum->nChar; | 31090 | *(va_arg(ap,int*)) = pAccum->nChar; |
| @@ -30373,13 +31133,26 @@ SQLITE_API void sqlite3_str_vappendf( | |||
| 30373 | } | 31133 | } |
| 30374 | } | 31134 | } |
| 30375 | if( precision>1 ){ | 31135 | if( precision>1 ){ |
| 31136 | i64 nPrior = 1; | ||
| 30376 | width -= precision-1; | 31137 | width -= precision-1; |
| 30377 | if( width>1 && !flag_leftjustify ){ | 31138 | if( width>1 && !flag_leftjustify ){ |
| 30378 | sqlite3_str_appendchar(pAccum, width-1, ' '); | 31139 | sqlite3_str_appendchar(pAccum, width-1, ' '); |
| 30379 | width = 0; | 31140 | width = 0; |
| 30380 | } | 31141 | } |
| 30381 | while( precision-- > 1 ){ | 31142 | sqlite3_str_append(pAccum, buf, length); |
| 30382 | sqlite3_str_append(pAccum, buf, length); | 31143 | precision--; |
| 31144 | while( precision > 1 ){ | ||
| 31145 | i64 nCopyBytes; | ||
| 31146 | if( nPrior > precision-1 ) nPrior = precision - 1; | ||
| 31147 | nCopyBytes = length*nPrior; | ||
| 31148 | if( nCopyBytes + pAccum->nChar >= pAccum->nAlloc ){ | ||
| 31149 | sqlite3StrAccumEnlarge(pAccum, nCopyBytes); | ||
| 31150 | } | ||
| 31151 | if( pAccum->accError ) break; | ||
| 31152 | sqlite3_str_append(pAccum, | ||
| 31153 | &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes); | ||
| 31154 | precision -= nPrior; | ||
| 31155 | nPrior *= 2; | ||
| 30383 | } | 31156 | } |
| 30384 | } | 31157 | } |
| 30385 | bufpt = buf; | 31158 | bufpt = buf; |
| @@ -30607,9 +31380,9 @@ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExp | |||
| 30607 | ** Return the number of bytes of text that StrAccum is able to accept | 31380 | ** Return the number of bytes of text that StrAccum is able to accept |
| 30608 | ** after the attempted enlargement. The value returned might be zero. | 31381 | ** after the attempted enlargement. The value returned might be zero. |
| 30609 | */ | 31382 | */ |
| 30610 | SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){ | 31383 | SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, i64 N){ |
| 30611 | char *zNew; | 31384 | char *zNew; |
| 30612 | assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ | 31385 | assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */ |
| 30613 | if( p->accError ){ | 31386 | if( p->accError ){ |
| 30614 | testcase(p->accError==SQLITE_TOOBIG); | 31387 | testcase(p->accError==SQLITE_TOOBIG); |
| 30615 | testcase(p->accError==SQLITE_NOMEM); | 31388 | testcase(p->accError==SQLITE_NOMEM); |
| @@ -30620,8 +31393,7 @@ SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){ | |||
| 30620 | return p->nAlloc - p->nChar - 1; | 31393 | return p->nAlloc - p->nChar - 1; |
| 30621 | }else{ | 31394 | }else{ |
| 30622 | char *zOld = isMalloced(p) ? p->zText : 0; | 31395 | char *zOld = isMalloced(p) ? p->zText : 0; |
| 30623 | i64 szNew = p->nChar; | 31396 | i64 szNew = p->nChar + N + 1; |
| 30624 | szNew += (sqlite3_int64)N + 1; | ||
| 30625 | if( szNew+p->nChar<=p->mxAlloc ){ | 31397 | if( szNew+p->nChar<=p->mxAlloc ){ |
| 30626 | /* Force exponential buffer size growth as long as it does not overflow, | 31398 | /* Force exponential buffer size growth as long as it does not overflow, |
| 30627 | ** to avoid having to call this routine too often */ | 31399 | ** to avoid having to call this routine too often */ |
| @@ -30651,7 +31423,8 @@ SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){ | |||
| 30651 | return 0; | 31423 | return 0; |
| 30652 | } | 31424 | } |
| 30653 | } | 31425 | } |
| 30654 | return N; | 31426 | assert( N>=0 && N<=0x7fffffff ); |
| 31427 | return (int)N; | ||
| 30655 | } | 31428 | } |
| 30656 | 31429 | ||
| 30657 | /* | 31430 | /* |
| @@ -30942,12 +31715,22 @@ SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_li | |||
| 30942 | return zBuf; | 31715 | return zBuf; |
| 30943 | } | 31716 | } |
| 30944 | SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ | 31717 | SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ |
| 30945 | char *z; | 31718 | StrAccum acc; |
| 30946 | va_list ap; | 31719 | va_list ap; |
| 31720 | if( n<=0 ) return zBuf; | ||
| 31721 | #ifdef SQLITE_ENABLE_API_ARMOR | ||
| 31722 | if( zBuf==0 || zFormat==0 ) { | ||
| 31723 | (void)SQLITE_MISUSE_BKPT; | ||
| 31724 | if( zBuf ) zBuf[0] = 0; | ||
| 31725 | return zBuf; | ||
| 31726 | } | ||
| 31727 | #endif | ||
| 31728 | sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); | ||
| 30947 | va_start(ap,zFormat); | 31729 | va_start(ap,zFormat); |
| 30948 | z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); | 31730 | sqlite3_str_vappendf(&acc, zFormat, ap); |
| 30949 | va_end(ap); | 31731 | va_end(ap); |
| 30950 | return z; | 31732 | zBuf[acc.nChar] = 0; |
| 31733 | return zBuf; | ||
| 30951 | } | 31734 | } |
| 30952 | 31735 | ||
| 30953 | /* | 31736 | /* |
| @@ -31025,6 +31808,75 @@ SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ | |||
| 31025 | va_end(ap); | 31808 | va_end(ap); |
| 31026 | } | 31809 | } |
| 31027 | 31810 | ||
| 31811 | |||
| 31812 | /***************************************************************************** | ||
| 31813 | ** Reference counted string storage | ||
| 31814 | *****************************************************************************/ | ||
| 31815 | |||
| 31816 | /* | ||
| 31817 | ** Increase the reference count of the string by one. | ||
| 31818 | ** | ||
| 31819 | ** The input parameter is returned. | ||
| 31820 | */ | ||
| 31821 | SQLITE_PRIVATE char *sqlite3RCStrRef(char *z){ | ||
| 31822 | RCStr *p = (RCStr*)z; | ||
| 31823 | assert( p!=0 ); | ||
| 31824 | p--; | ||
| 31825 | p->nRCRef++; | ||
| 31826 | return z; | ||
| 31827 | } | ||
| 31828 | |||
| 31829 | /* | ||
| 31830 | ** Decrease the reference count by one. Free the string when the | ||
| 31831 | ** reference count reaches zero. | ||
| 31832 | */ | ||
| 31833 | SQLITE_PRIVATE void sqlite3RCStrUnref(char *z){ | ||
| 31834 | RCStr *p = (RCStr*)z; | ||
| 31835 | assert( p!=0 ); | ||
| 31836 | p--; | ||
| 31837 | assert( p->nRCRef>0 ); | ||
| 31838 | if( p->nRCRef>=2 ){ | ||
| 31839 | p->nRCRef--; | ||
| 31840 | }else{ | ||
| 31841 | sqlite3_free(p); | ||
| 31842 | } | ||
| 31843 | } | ||
| 31844 | |||
| 31845 | /* | ||
| 31846 | ** Create a new string that is capable of holding N bytes of text, not counting | ||
| 31847 | ** the zero byte at the end. The string is uninitialized. | ||
| 31848 | ** | ||
| 31849 | ** The reference count is initially 1. Call sqlite3RCStrUnref() to free the | ||
| 31850 | ** newly allocated string. | ||
| 31851 | ** | ||
| 31852 | ** This routine returns 0 on an OOM. | ||
| 31853 | */ | ||
| 31854 | SQLITE_PRIVATE char *sqlite3RCStrNew(u64 N){ | ||
| 31855 | RCStr *p = sqlite3_malloc64( N + sizeof(*p) + 1 ); | ||
| 31856 | if( p==0 ) return 0; | ||
| 31857 | p->nRCRef = 1; | ||
| 31858 | return (char*)&p[1]; | ||
| 31859 | } | ||
| 31860 | |||
| 31861 | /* | ||
| 31862 | ** Change the size of the string so that it is able to hold N bytes. | ||
| 31863 | ** The string might be reallocated, so return the new allocation. | ||
| 31864 | */ | ||
| 31865 | SQLITE_PRIVATE char *sqlite3RCStrResize(char *z, u64 N){ | ||
| 31866 | RCStr *p = (RCStr*)z; | ||
| 31867 | RCStr *pNew; | ||
| 31868 | assert( p!=0 ); | ||
| 31869 | p--; | ||
| 31870 | assert( p->nRCRef==1 ); | ||
| 31871 | pNew = sqlite3_realloc64(p, N+sizeof(RCStr)+1); | ||
| 31872 | if( pNew==0 ){ | ||
| 31873 | sqlite3_free(p); | ||
| 31874 | return 0; | ||
| 31875 | }else{ | ||
| 31876 | return (char*)&pNew[1]; | ||
| 31877 | } | ||
| 31878 | } | ||
| 31879 | |||
| 31028 | /************** End of printf.c **********************************************/ | 31880 | /************** End of printf.c **********************************************/ |
| 31029 | /************** Begin file treeview.c ****************************************/ | 31881 | /************** Begin file treeview.c ****************************************/ |
| 31030 | /* | 31882 | /* |
| @@ -31247,6 +32099,13 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) | |||
| 31247 | if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ | 32099 | if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ |
| 31248 | sqlite3_str_appendf(&x, " ON"); | 32100 | sqlite3_str_appendf(&x, " ON"); |
| 31249 | } | 32101 | } |
| 32102 | if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); | ||
| 32103 | if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); | ||
| 32104 | if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized"); | ||
| 32105 | if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); | ||
| 32106 | if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); | ||
| 32107 | if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); | ||
| 32108 | |||
| 31250 | sqlite3StrAccumFinish(&x); | 32109 | sqlite3StrAccumFinish(&x); |
| 31251 | sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); | 32110 | sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1); |
| 31252 | n = 0; | 32111 | n = 0; |
| @@ -31516,7 +32375,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m | |||
| 31516 | sqlite3TreeViewPop(&pView); | 32375 | sqlite3TreeViewPop(&pView); |
| 31517 | return; | 32376 | return; |
| 31518 | } | 32377 | } |
| 31519 | if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){ | 32378 | if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags || pExpr->pAggInfo ){ |
| 31520 | StrAccum x; | 32379 | StrAccum x; |
| 31521 | sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); | 32380 | sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); |
| 31522 | sqlite3_str_appendf(&x, " fg.af=%x.%c", | 32381 | sqlite3_str_appendf(&x, " fg.af=%x.%c", |
| @@ -31533,6 +32392,9 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m | |||
| 31533 | if( ExprHasVVAProperty(pExpr, EP_Immutable) ){ | 32392 | if( ExprHasVVAProperty(pExpr, EP_Immutable) ){ |
| 31534 | sqlite3_str_appendf(&x, " IMMUTABLE"); | 32393 | sqlite3_str_appendf(&x, " IMMUTABLE"); |
| 31535 | } | 32394 | } |
| 32395 | if( pExpr->pAggInfo!=0 ){ | ||
| 32396 | sqlite3_str_appendf(&x, " agg-column[%d]", pExpr->iAgg); | ||
| 32397 | } | ||
| 31536 | sqlite3StrAccumFinish(&x); | 32398 | sqlite3StrAccumFinish(&x); |
| 31537 | }else{ | 32399 | }else{ |
| 31538 | zFlgs[0] = 0; | 32400 | zFlgs[0] = 0; |
| @@ -31662,7 +32524,8 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m | |||
| 31662 | }; | 32524 | }; |
| 31663 | assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); | 32525 | assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); |
| 31664 | assert( pExpr->pRight ); | 32526 | assert( pExpr->pRight ); |
| 31665 | assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE ); | 32527 | assert( sqlite3ExprSkipCollateAndLikely(pExpr->pRight)->op |
| 32528 | == TK_TRUEFALSE ); | ||
| 31666 | x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); | 32529 | x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); |
| 31667 | zUniOp = azOp[x]; | 32530 | zUniOp = azOp[x]; |
| 31668 | break; | 32531 | break; |
| @@ -32344,16 +33207,41 @@ SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc( | |||
| 32344 | ** This structure is the current state of the generator. | 33207 | ** This structure is the current state of the generator. |
| 32345 | */ | 33208 | */ |
| 32346 | static SQLITE_WSD struct sqlite3PrngType { | 33209 | static SQLITE_WSD struct sqlite3PrngType { |
| 32347 | unsigned char isInit; /* True if initialized */ | 33210 | u32 s[16]; /* 64 bytes of chacha20 state */ |
| 32348 | unsigned char i, j; /* State variables */ | 33211 | u8 out[64]; /* Output bytes */ |
| 32349 | unsigned char s[256]; /* State variables */ | 33212 | u8 n; /* Output bytes remaining */ |
| 32350 | } sqlite3Prng; | 33213 | } sqlite3Prng; |
| 32351 | 33214 | ||
| 33215 | |||
| 33216 | /* The RFC-7539 ChaCha20 block function | ||
| 33217 | */ | ||
| 33218 | #define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) | ||
| 33219 | #define QR(a, b, c, d) ( \ | ||
| 33220 | a += b, d ^= a, d = ROTL(d,16), \ | ||
| 33221 | c += d, b ^= c, b = ROTL(b,12), \ | ||
| 33222 | a += b, d ^= a, d = ROTL(d, 8), \ | ||
| 33223 | c += d, b ^= c, b = ROTL(b, 7)) | ||
| 33224 | static void chacha_block(u32 *out, const u32 *in){ | ||
| 33225 | int i; | ||
| 33226 | u32 x[16]; | ||
| 33227 | memcpy(x, in, 64); | ||
| 33228 | for(i=0; i<10; i++){ | ||
| 33229 | QR(x[0], x[4], x[ 8], x[12]); | ||
| 33230 | QR(x[1], x[5], x[ 9], x[13]); | ||
| 33231 | QR(x[2], x[6], x[10], x[14]); | ||
| 33232 | QR(x[3], x[7], x[11], x[15]); | ||
| 33233 | QR(x[0], x[5], x[10], x[15]); | ||
| 33234 | QR(x[1], x[6], x[11], x[12]); | ||
| 33235 | QR(x[2], x[7], x[ 8], x[13]); | ||
| 33236 | QR(x[3], x[4], x[ 9], x[14]); | ||
| 33237 | } | ||
| 33238 | for(i=0; i<16; i++) out[i] = x[i]+in[i]; | ||
| 33239 | } | ||
| 33240 | |||
| 32352 | /* | 33241 | /* |
| 32353 | ** Return N random bytes. | 33242 | ** Return N random bytes. |
| 32354 | */ | 33243 | */ |
| 32355 | SQLITE_API void sqlite3_randomness(int N, void *pBuf){ | 33244 | SQLITE_API void sqlite3_randomness(int N, void *pBuf){ |
| 32356 | unsigned char t; | ||
| 32357 | unsigned char *zBuf = pBuf; | 33245 | unsigned char *zBuf = pBuf; |
| 32358 | 33246 | ||
| 32359 | /* The "wsdPrng" macro will resolve to the pseudo-random number generator | 33247 | /* The "wsdPrng" macro will resolve to the pseudo-random number generator |
| @@ -32383,53 +33271,46 @@ SQLITE_API void sqlite3_randomness(int N, void *pBuf){ | |||
| 32383 | 33271 | ||
| 32384 | sqlite3_mutex_enter(mutex); | 33272 | sqlite3_mutex_enter(mutex); |
| 32385 | if( N<=0 || pBuf==0 ){ | 33273 | if( N<=0 || pBuf==0 ){ |
| 32386 | wsdPrng.isInit = 0; | 33274 | wsdPrng.s[0] = 0; |
| 32387 | sqlite3_mutex_leave(mutex); | 33275 | sqlite3_mutex_leave(mutex); |
| 32388 | return; | 33276 | return; |
| 32389 | } | 33277 | } |
| 32390 | 33278 | ||
| 32391 | /* Initialize the state of the random number generator once, | 33279 | /* Initialize the state of the random number generator once, |
| 32392 | ** the first time this routine is called. The seed value does | 33280 | ** the first time this routine is called. |
| 32393 | ** not need to contain a lot of randomness since we are not | ||
| 32394 | ** trying to do secure encryption or anything like that... | ||
| 32395 | ** | ||
| 32396 | ** Nothing in this file or anywhere else in SQLite does any kind of | ||
| 32397 | ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random | ||
| 32398 | ** number generator) not as an encryption device. | ||
| 32399 | */ | 33281 | */ |
| 32400 | if( !wsdPrng.isInit ){ | 33282 | if( wsdPrng.s[0]==0 ){ |
| 32401 | sqlite3_vfs *pVfs = sqlite3_vfs_find(0); | 33283 | sqlite3_vfs *pVfs = sqlite3_vfs_find(0); |
| 32402 | int i; | 33284 | static const u32 chacha20_init[] = { |
| 32403 | char k[256]; | 33285 | 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 |
| 32404 | wsdPrng.j = 0; | 33286 | }; |
| 32405 | wsdPrng.i = 0; | 33287 | memcpy(&wsdPrng.s[0], chacha20_init, 16); |
| 32406 | if( NEVER(pVfs==0) ){ | 33288 | if( NEVER(pVfs==0) ){ |
| 32407 | memset(k, 0, sizeof(k)); | 33289 | memset(&wsdPrng.s[4], 0, 44); |
| 32408 | }else{ | 33290 | }else{ |
| 32409 | sqlite3OsRandomness(pVfs, 256, k); | 33291 | sqlite3OsRandomness(pVfs, 44, (char*)&wsdPrng.s[4]); |
| 32410 | } | ||
| 32411 | for(i=0; i<256; i++){ | ||
| 32412 | wsdPrng.s[i] = (u8)i; | ||
| 32413 | } | ||
| 32414 | for(i=0; i<256; i++){ | ||
| 32415 | wsdPrng.j += wsdPrng.s[i] + k[i]; | ||
| 32416 | t = wsdPrng.s[wsdPrng.j]; | ||
| 32417 | wsdPrng.s[wsdPrng.j] = wsdPrng.s[i]; | ||
| 32418 | wsdPrng.s[i] = t; | ||
| 32419 | } | 33292 | } |
| 32420 | wsdPrng.isInit = 1; | 33293 | wsdPrng.s[15] = wsdPrng.s[12]; |
| 33294 | wsdPrng.s[12] = 0; | ||
| 33295 | wsdPrng.n = 0; | ||
| 32421 | } | 33296 | } |
| 32422 | 33297 | ||
| 32423 | assert( N>0 ); | 33298 | assert( N>0 ); |
| 32424 | do{ | 33299 | while( 1 /* exit by break */ ){ |
| 32425 | wsdPrng.i++; | 33300 | if( N<=wsdPrng.n ){ |
| 32426 | t = wsdPrng.s[wsdPrng.i]; | 33301 | memcpy(zBuf, &wsdPrng.out[wsdPrng.n-N], N); |
| 32427 | wsdPrng.j += t; | 33302 | wsdPrng.n -= N; |
| 32428 | wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j]; | 33303 | break; |
| 32429 | wsdPrng.s[wsdPrng.j] = t; | 33304 | } |
| 32430 | t += wsdPrng.s[wsdPrng.i]; | 33305 | if( wsdPrng.n>0 ){ |
| 32431 | *(zBuf++) = wsdPrng.s[t]; | 33306 | memcpy(zBuf, wsdPrng.out, wsdPrng.n); |
| 32432 | }while( --N ); | 33307 | N -= wsdPrng.n; |
| 33308 | zBuf += wsdPrng.n; | ||
| 33309 | } | ||
| 33310 | wsdPrng.s[12]++; | ||
| 33311 | chacha_block((u32*)wsdPrng.out, wsdPrng.s); | ||
| 33312 | wsdPrng.n = 64; | ||
| 33313 | } | ||
| 32433 | sqlite3_mutex_leave(mutex); | 33314 | sqlite3_mutex_leave(mutex); |
| 32434 | } | 33315 | } |
| 32435 | 33316 | ||
| @@ -33303,7 +34184,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ | |||
| 33303 | /* | 34184 | /* |
| 33304 | ** Calls to sqlite3FaultSim() are used to simulate a failure during testing, | 34185 | ** Calls to sqlite3FaultSim() are used to simulate a failure during testing, |
| 33305 | ** or to bypass normal error detection during testing in order to let | 34186 | ** or to bypass normal error detection during testing in order to let |
| 33306 | ** execute proceed futher downstream. | 34187 | ** execute proceed further downstream. |
| 33307 | ** | 34188 | ** |
| 33308 | ** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0). The | 34189 | ** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0). The |
| 33309 | ** sqlite3FaultSim() function only returns non-zero during testing. | 34190 | ** sqlite3FaultSim() function only returns non-zero during testing. |
| @@ -33420,6 +34301,23 @@ SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ | |||
| 33420 | */ | 34301 | */ |
| 33421 | SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ | 34302 | SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ |
| 33422 | if( rc==SQLITE_IOERR_NOMEM ) return; | 34303 | if( rc==SQLITE_IOERR_NOMEM ) return; |
| 34304 | #ifdef SQLITE_USE_SEH | ||
| 34305 | if( rc==SQLITE_IOERR_IN_PAGE ){ | ||
| 34306 | int ii; | ||
| 34307 | int iErr; | ||
| 34308 | sqlite3BtreeEnterAll(db); | ||
| 34309 | for(ii=0; ii<db->nDb; ii++){ | ||
| 34310 | if( db->aDb[ii].pBt ){ | ||
| 34311 | iErr = sqlite3PagerWalSystemErrno(sqlite3BtreePager(db->aDb[ii].pBt)); | ||
| 34312 | if( iErr ){ | ||
| 34313 | db->iSysErrno = iErr; | ||
| 34314 | } | ||
| 34315 | } | ||
| 34316 | } | ||
| 34317 | sqlite3BtreeLeaveAll(db); | ||
| 34318 | return; | ||
| 34319 | } | ||
| 34320 | #endif | ||
| 33423 | rc &= 0xff; | 34321 | rc &= 0xff; |
| 33424 | if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ | 34322 | if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ |
| 33425 | db->iSysErrno = sqlite3OsGetLastError(db->pVfs); | 34323 | db->iSysErrno = sqlite3OsGetLastError(db->pVfs); |
| @@ -33455,6 +34353,26 @@ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *z | |||
| 33455 | } | 34353 | } |
| 33456 | 34354 | ||
| 33457 | /* | 34355 | /* |
| 34356 | ** Check for interrupts and invoke progress callback. | ||
| 34357 | */ | ||
| 34358 | SQLITE_PRIVATE void sqlite3ProgressCheck(Parse *p){ | ||
| 34359 | sqlite3 *db = p->db; | ||
| 34360 | if( AtomicLoad(&db->u1.isInterrupted) ){ | ||
| 34361 | p->nErr++; | ||
| 34362 | p->rc = SQLITE_INTERRUPT; | ||
| 34363 | } | ||
| 34364 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | ||
| 34365 | if( db->xProgress && (++p->nProgressSteps)>=db->nProgressOps ){ | ||
| 34366 | if( db->xProgress(db->pProgressArg) ){ | ||
| 34367 | p->nErr++; | ||
| 34368 | p->rc = SQLITE_INTERRUPT; | ||
| 34369 | } | ||
| 34370 | p->nProgressSteps = 0; | ||
| 34371 | } | ||
| 34372 | #endif | ||
| 34373 | } | ||
| 34374 | |||
| 34375 | /* | ||
| 33458 | ** Add an error message to pParse->zErrMsg and increment pParse->nErr. | 34376 | ** Add an error message to pParse->zErrMsg and increment pParse->nErr. |
| 33459 | ** | 34377 | ** |
| 33460 | ** This function should be used to report any error that occurs while | 34378 | ** This function should be used to report any error that occurs while |
| @@ -33645,43 +34563,40 @@ SQLITE_PRIVATE u8 sqlite3StrIHash(const char *z){ | |||
| 33645 | return h; | 34563 | return h; |
| 33646 | } | 34564 | } |
| 33647 | 34565 | ||
| 33648 | /* | 34566 | /* Double-Double multiplication. (x[0],x[1]) *= (y,yy) |
| 33649 | ** Compute 10 to the E-th power. Examples: E==1 results in 10. | ||
| 33650 | ** E==2 results in 100. E==50 results in 1.0e50. | ||
| 33651 | ** | 34567 | ** |
| 33652 | ** This routine only works for values of E between 1 and 341. | 34568 | ** Reference: |
| 34569 | ** T. J. Dekker, "A Floating-Point Technique for Extending the | ||
| 34570 | ** Available Precision". 1971-07-26. | ||
| 33653 | */ | 34571 | */ |
| 33654 | static LONGDOUBLE_TYPE sqlite3Pow10(int E){ | 34572 | static void dekkerMul2(volatile double *x, double y, double yy){ |
| 33655 | #if defined(_MSC_VER) | 34573 | /* |
| 33656 | static const LONGDOUBLE_TYPE x[] = { | 34574 | ** The "volatile" keywords on parameter x[] and on local variables |
| 33657 | 1.0e+001L, | 34575 | ** below are needed force intermediate results to be truncated to |
| 33658 | 1.0e+002L, | 34576 | ** binary64 rather than be carried around in an extended-precision |
| 33659 | 1.0e+004L, | 34577 | ** format. The truncation is necessary for the Dekker algorithm to |
| 33660 | 1.0e+008L, | 34578 | ** work. Intel x86 floating point might omit the truncation without |
| 33661 | 1.0e+016L, | 34579 | ** the use of volatile. |
| 33662 | 1.0e+032L, | 34580 | */ |
| 33663 | 1.0e+064L, | 34581 | volatile double tx, ty, p, q, c, cc; |
| 33664 | 1.0e+128L, | 34582 | double hx, hy; |
| 33665 | 1.0e+256L | 34583 | u64 m; |
| 33666 | }; | 34584 | memcpy(&m, (void*)&x[0], 8); |
| 33667 | LONGDOUBLE_TYPE r = 1.0; | 34585 | m &= 0xfffffffffc000000LL; |
| 33668 | int i; | 34586 | memcpy(&hx, &m, 8); |
| 33669 | assert( E>=0 && E<=307 ); | 34587 | tx = x[0] - hx; |
| 33670 | for(i=0; E!=0; i++, E >>=1){ | 34588 | memcpy(&m, &y, 8); |
| 33671 | if( E & 1 ) r *= x[i]; | 34589 | m &= 0xfffffffffc000000LL; |
| 33672 | } | 34590 | memcpy(&hy, &m, 8); |
| 33673 | return r; | 34591 | ty = y - hy; |
| 33674 | #else | 34592 | p = hx*hy; |
| 33675 | LONGDOUBLE_TYPE x = 10.0; | 34593 | q = hx*ty + tx*hy; |
| 33676 | LONGDOUBLE_TYPE r = 1.0; | 34594 | c = p+q; |
| 33677 | while(1){ | 34595 | cc = p - c + q + tx*ty; |
| 33678 | if( E & 1 ) r *= x; | 34596 | cc = x[0]*yy + x[1]*y + cc; |
| 33679 | E >>= 1; | 34597 | x[0] = c + cc; |
| 33680 | if( E==0 ) break; | 34598 | x[1] = c - x[0]; |
| 33681 | x *= x; | 34599 | x[1] += cc; |
| 33682 | } | ||
| 33683 | return r; | ||
| 33684 | #endif | ||
| 33685 | } | 34600 | } |
| 33686 | 34601 | ||
| 33687 | /* | 34602 | /* |
| @@ -33722,12 +34637,11 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en | |||
| 33722 | const char *zEnd; | 34637 | const char *zEnd; |
| 33723 | /* sign * significand * (10 ^ (esign * exponent)) */ | 34638 | /* sign * significand * (10 ^ (esign * exponent)) */ |
| 33724 | int sign = 1; /* sign of significand */ | 34639 | int sign = 1; /* sign of significand */ |
| 33725 | i64 s = 0; /* significand */ | 34640 | u64 s = 0; /* significand */ |
| 33726 | int d = 0; /* adjust exponent for shifting decimal point */ | 34641 | int d = 0; /* adjust exponent for shifting decimal point */ |
| 33727 | int esign = 1; /* sign of exponent */ | 34642 | int esign = 1; /* sign of exponent */ |
| 33728 | int e = 0; /* exponent */ | 34643 | int e = 0; /* exponent */ |
| 33729 | int eValid = 1; /* True exponent is either not used or is well-formed */ | 34644 | int eValid = 1; /* True exponent is either not used or is well-formed */ |
| 33730 | double result; | ||
| 33731 | int nDigit = 0; /* Number of digits processed */ | 34645 | int nDigit = 0; /* Number of digits processed */ |
| 33732 | int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ | 34646 | int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ |
| 33733 | 34647 | ||
| @@ -33767,7 +34681,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en | |||
| 33767 | while( z<zEnd && sqlite3Isdigit(*z) ){ | 34681 | while( z<zEnd && sqlite3Isdigit(*z) ){ |
| 33768 | s = s*10 + (*z - '0'); | 34682 | s = s*10 + (*z - '0'); |
| 33769 | z+=incr; nDigit++; | 34683 | z+=incr; nDigit++; |
| 33770 | if( s>=((LARGEST_INT64-9)/10) ){ | 34684 | if( s>=((LARGEST_UINT64-9)/10) ){ |
| 33771 | /* skip non-significant significand digits | 34685 | /* skip non-significant significand digits |
| 33772 | ** (increase exponent by d to shift decimal left) */ | 34686 | ** (increase exponent by d to shift decimal left) */ |
| 33773 | while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; d++; } | 34687 | while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; d++; } |
| @@ -33782,7 +34696,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en | |||
| 33782 | /* copy digits from after decimal to significand | 34696 | /* copy digits from after decimal to significand |
| 33783 | ** (decrease exponent by d to shift decimal right) */ | 34697 | ** (decrease exponent by d to shift decimal right) */ |
| 33784 | while( z<zEnd && sqlite3Isdigit(*z) ){ | 34698 | while( z<zEnd && sqlite3Isdigit(*z) ){ |
| 33785 | if( s<((LARGEST_INT64-9)/10) ){ | 34699 | if( s<((LARGEST_UINT64-9)/10) ){ |
| 33786 | s = s*10 + (*z - '0'); | 34700 | s = s*10 + (*z - '0'); |
| 33787 | d--; | 34701 | d--; |
| 33788 | nDigit++; | 34702 | nDigit++; |
| @@ -33822,79 +34736,89 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en | |||
| 33822 | while( z<zEnd && sqlite3Isspace(*z) ) z+=incr; | 34736 | while( z<zEnd && sqlite3Isspace(*z) ) z+=incr; |
| 33823 | 34737 | ||
| 33824 | do_atof_calc: | 34738 | do_atof_calc: |
| 33825 | /* adjust exponent by d, and update sign */ | 34739 | /* Zero is a special case */ |
| 33826 | e = (e*esign) + d; | 34740 | if( s==0 ){ |
| 33827 | if( e<0 ) { | 34741 | *pResult = sign<0 ? -0.0 : +0.0; |
| 33828 | esign = -1; | 34742 | goto atof_return; |
| 33829 | e *= -1; | ||
| 33830 | } else { | ||
| 33831 | esign = 1; | ||
| 33832 | } | 34743 | } |
| 33833 | 34744 | ||
| 33834 | if( s==0 ) { | 34745 | /* adjust exponent by d, and update sign */ |
| 33835 | /* In the IEEE 754 standard, zero is signed. */ | 34746 | e = (e*esign) + d; |
| 33836 | result = sign<0 ? -(double)0 : (double)0; | ||
| 33837 | } else { | ||
| 33838 | /* Attempt to reduce exponent. | ||
| 33839 | ** | ||
| 33840 | ** Branches that are not required for the correct answer but which only | ||
| 33841 | ** help to obtain the correct answer faster are marked with special | ||
| 33842 | ** comments, as a hint to the mutation tester. | ||
| 33843 | */ | ||
| 33844 | while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/ | ||
| 33845 | if( esign>0 ){ | ||
| 33846 | if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/ | ||
| 33847 | s *= 10; | ||
| 33848 | }else{ | ||
| 33849 | if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/ | ||
| 33850 | s /= 10; | ||
| 33851 | } | ||
| 33852 | e--; | ||
| 33853 | } | ||
| 33854 | 34747 | ||
| 33855 | /* adjust the sign of significand */ | 34748 | /* Try to adjust the exponent to make it smaller */ |
| 33856 | s = sign<0 ? -s : s; | 34749 | while( e>0 && s<(LARGEST_UINT64/10) ){ |
| 34750 | s *= 10; | ||
| 34751 | e--; | ||
| 34752 | } | ||
| 34753 | while( e<0 && (s%10)==0 ){ | ||
| 34754 | s /= 10; | ||
| 34755 | e++; | ||
| 34756 | } | ||
| 33857 | 34757 | ||
| 33858 | if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ | 34758 | if( e==0 ){ |
| 33859 | result = (double)s; | 34759 | *pResult = s; |
| 34760 | }else if( sqlite3Config.bUseLongDouble ){ | ||
| 34761 | LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; | ||
| 34762 | if( e>0 ){ | ||
| 34763 | while( e>=100 ){ e-=100; r *= 1.0e+100L; } | ||
| 34764 | while( e>=10 ){ e-=10; r *= 1.0e+10L; } | ||
| 34765 | while( e>=1 ){ e-=1; r *= 1.0e+01L; } | ||
| 33860 | }else{ | 34766 | }else{ |
| 33861 | /* attempt to handle extremely small/large numbers better */ | 34767 | while( e<=-100 ){ e+=100; r *= 1.0e-100L; } |
| 33862 | if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/ | 34768 | while( e<=-10 ){ e+=10; r *= 1.0e-10L; } |
| 33863 | if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ | 34769 | while( e<=-1 ){ e+=1; r *= 1.0e-01L; } |
| 33864 | LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308); | 34770 | } |
| 33865 | if( esign<0 ){ | 34771 | assert( r>=0.0 ); |
| 33866 | result = s / scale; | 34772 | if( r>+1.7976931348623157081452742373e+308L ){ |
| 33867 | result /= 1.0e+308; | ||
| 33868 | }else{ | ||
| 33869 | result = s * scale; | ||
| 33870 | result *= 1.0e+308; | ||
| 33871 | } | ||
| 33872 | }else{ assert( e>=342 ); | ||
| 33873 | if( esign<0 ){ | ||
| 33874 | result = 0.0*s; | ||
| 33875 | }else{ | ||
| 33876 | #ifdef INFINITY | 34773 | #ifdef INFINITY |
| 33877 | result = INFINITY*s; | 34774 | *pResult = +INFINITY; |
| 33878 | #else | 34775 | #else |
| 33879 | result = 1e308*1e308*s; /* Infinity */ | 34776 | *pResult = 1.0e308*10.0; |
| 33880 | #endif | 34777 | #endif |
| 33881 | } | 34778 | }else{ |
| 33882 | } | 34779 | *pResult = (double)r; |
| 33883 | }else{ | 34780 | } |
| 33884 | LONGDOUBLE_TYPE scale = sqlite3Pow10(e); | 34781 | }else{ |
| 33885 | if( esign<0 ){ | 34782 | double rr[2]; |
| 33886 | result = s / scale; | 34783 | u64 s2; |
| 33887 | }else{ | 34784 | rr[0] = (double)s; |
| 33888 | result = s * scale; | 34785 | s2 = (u64)rr[0]; |
| 33889 | } | 34786 | rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); |
| 34787 | if( e>0 ){ | ||
| 34788 | while( e>=100 ){ | ||
| 34789 | e -= 100; | ||
| 34790 | dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); | ||
| 34791 | } | ||
| 34792 | while( e>=10 ){ | ||
| 34793 | e -= 10; | ||
| 34794 | dekkerMul2(rr, 1.0e+10, 0.0); | ||
| 34795 | } | ||
| 34796 | while( e>=1 ){ | ||
| 34797 | e -= 1; | ||
| 34798 | dekkerMul2(rr, 1.0e+01, 0.0); | ||
| 34799 | } | ||
| 34800 | }else{ | ||
| 34801 | while( e<=-100 ){ | ||
| 34802 | e += 100; | ||
| 34803 | dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); | ||
| 34804 | } | ||
| 34805 | while( e<=-10 ){ | ||
| 34806 | e += 10; | ||
| 34807 | dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); | ||
| 34808 | } | ||
| 34809 | while( e<=-1 ){ | ||
| 34810 | e += 1; | ||
| 34811 | dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); | ||
| 33890 | } | 34812 | } |
| 33891 | } | 34813 | } |
| 34814 | *pResult = rr[0]+rr[1]; | ||
| 34815 | if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; | ||
| 33892 | } | 34816 | } |
| 34817 | if( sign<0 ) *pResult = -*pResult; | ||
| 34818 | assert( !sqlite3IsNaN(*pResult) ); | ||
| 33893 | 34819 | ||
| 33894 | /* store the result */ | 34820 | atof_return: |
| 33895 | *pResult = result; | 34821 | /* return true if number and no extra non-whitespace characters after */ |
| 33896 | |||
| 33897 | /* return true if number and no extra non-whitespace chracters after */ | ||
| 33898 | if( z==zEnd && nDigit>0 && eValid && eType>0 ){ | 34822 | if( z==zEnd && nDigit>0 && eValid && eType>0 ){ |
| 33899 | return eType; | 34823 | return eType; |
| 33900 | }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){ | 34824 | }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){ |
| @@ -33911,11 +34835,14 @@ do_atof_calc: | |||
| 33911 | #endif | 34835 | #endif |
| 33912 | 34836 | ||
| 33913 | /* | 34837 | /* |
| 33914 | ** Render an signed 64-bit integer as text. Store the result in zOut[]. | 34838 | ** Render an signed 64-bit integer as text. Store the result in zOut[] and |
| 34839 | ** return the length of the string that was stored, in bytes. The value | ||
| 34840 | ** returned does not include the zero terminator at the end of the output | ||
| 34841 | ** string. | ||
| 33915 | ** | 34842 | ** |
| 33916 | ** The caller must ensure that zOut[] is at least 21 bytes in size. | 34843 | ** The caller must ensure that zOut[] is at least 21 bytes in size. |
| 33917 | */ | 34844 | */ |
| 33918 | SQLITE_PRIVATE void sqlite3Int64ToText(i64 v, char *zOut){ | 34845 | SQLITE_PRIVATE int sqlite3Int64ToText(i64 v, char *zOut){ |
| 33919 | int i; | 34846 | int i; |
| 33920 | u64 x; | 34847 | u64 x; |
| 33921 | char zTemp[22]; | 34848 | char zTemp[22]; |
| @@ -33926,12 +34853,15 @@ SQLITE_PRIVATE void sqlite3Int64ToText(i64 v, char *zOut){ | |||
| 33926 | } | 34853 | } |
| 33927 | i = sizeof(zTemp)-2; | 34854 | i = sizeof(zTemp)-2; |
| 33928 | zTemp[sizeof(zTemp)-1] = 0; | 34855 | zTemp[sizeof(zTemp)-1] = 0; |
| 33929 | do{ | 34856 | while( 1 /*exit-by-break*/ ){ |
| 33930 | zTemp[i--] = (x%10) + '0'; | 34857 | zTemp[i] = (x%10) + '0'; |
| 33931 | x = x/10; | 34858 | x = x/10; |
| 33932 | }while( x ); | 34859 | if( x==0 ) break; |
| 33933 | if( v<0 ) zTemp[i--] = '-'; | 34860 | i--; |
| 33934 | memcpy(zOut, &zTemp[i+1], sizeof(zTemp)-1-i); | 34861 | }; |
| 34862 | if( v<0 ) zTemp[--i] = '-'; | ||
| 34863 | memcpy(zOut, &zTemp[i], sizeof(zTemp)-i); | ||
| 34864 | return sizeof(zTemp)-1-i; | ||
| 33935 | } | 34865 | } |
| 33936 | 34866 | ||
| 33937 | /* | 34867 | /* |
| @@ -34024,7 +34954,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc | |||
| 34024 | /* This test and assignment is needed only to suppress UB warnings | 34954 | /* This test and assignment is needed only to suppress UB warnings |
| 34025 | ** from clang and -fsanitize=undefined. This test and assignment make | 34955 | ** from clang and -fsanitize=undefined. This test and assignment make |
| 34026 | ** the code a little larger and slower, and no harm comes from omitting | 34956 | ** the code a little larger and slower, and no harm comes from omitting |
| 34027 | ** them, but we must appaise the undefined-behavior pharisees. */ | 34957 | ** them, but we must appease the undefined-behavior pharisees. */ |
| 34028 | *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; | 34958 | *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; |
| 34029 | }else if( neg ){ | 34959 | }else if( neg ){ |
| 34030 | *pNum = -(i64)u; | 34960 | *pNum = -(i64)u; |
| @@ -34096,11 +35026,15 @@ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ | |||
| 34096 | u = u*16 + sqlite3HexToInt(z[k]); | 35026 | u = u*16 + sqlite3HexToInt(z[k]); |
| 34097 | } | 35027 | } |
| 34098 | memcpy(pOut, &u, 8); | 35028 | memcpy(pOut, &u, 8); |
| 34099 | return (z[k]==0 && k-i<=16) ? 0 : 2; | 35029 | if( k-i>16 ) return 2; |
| 35030 | if( z[k]!=0 ) return 1; | ||
| 35031 | return 0; | ||
| 34100 | }else | 35032 | }else |
| 34101 | #endif /* SQLITE_OMIT_HEX_INTEGER */ | 35033 | #endif /* SQLITE_OMIT_HEX_INTEGER */ |
| 34102 | { | 35034 | { |
| 34103 | return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); | 35035 | int n = (int)(0x3fffffff&strspn(z,"+- \n\t0123456789")); |
| 35036 | if( z[n] ) n++; | ||
| 35037 | return sqlite3Atoi64(z, pOut, n, SQLITE_UTF8); | ||
| 34104 | } | 35038 | } |
| 34105 | } | 35039 | } |
| 34106 | 35040 | ||
| @@ -34132,7 +35066,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){ | |||
| 34132 | u32 u = 0; | 35066 | u32 u = 0; |
| 34133 | zNum += 2; | 35067 | zNum += 2; |
| 34134 | while( zNum[0]=='0' ) zNum++; | 35068 | while( zNum[0]=='0' ) zNum++; |
| 34135 | for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ | 35069 | for(i=0; i<8 && sqlite3Isxdigit(zNum[i]); i++){ |
| 34136 | u = u*16 + sqlite3HexToInt(zNum[i]); | 35070 | u = u*16 + sqlite3HexToInt(zNum[i]); |
| 34137 | } | 35071 | } |
| 34138 | if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ | 35072 | if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ |
| @@ -34180,6 +35114,153 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ | |||
| 34180 | } | 35114 | } |
| 34181 | 35115 | ||
| 34182 | /* | 35116 | /* |
| 35117 | ** Decode a floating-point value into an approximate decimal | ||
| 35118 | ** representation. | ||
| 35119 | ** | ||
| 35120 | ** Round the decimal representation to n significant digits if | ||
| 35121 | ** n is positive. Or round to -n signficant digits after the | ||
| 35122 | ** decimal point if n is negative. No rounding is performed if | ||
| 35123 | ** n is zero. | ||
| 35124 | ** | ||
| 35125 | ** The significant digits of the decimal representation are | ||
| 35126 | ** stored in p->z[] which is a often (but not always) a pointer | ||
| 35127 | ** into the middle of p->zBuf[]. There are p->n significant digits. | ||
| 35128 | ** The p->z[] array is *not* zero-terminated. | ||
| 35129 | */ | ||
| 35130 | SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){ | ||
| 35131 | int i; | ||
| 35132 | u64 v; | ||
| 35133 | int e, exp = 0; | ||
| 35134 | p->isSpecial = 0; | ||
| 35135 | p->z = p->zBuf; | ||
| 35136 | |||
| 35137 | /* Convert negative numbers to positive. Deal with Infinity, 0.0, and | ||
| 35138 | ** NaN. */ | ||
| 35139 | if( r<0.0 ){ | ||
| 35140 | p->sign = '-'; | ||
| 35141 | r = -r; | ||
| 35142 | }else if( r==0.0 ){ | ||
| 35143 | p->sign = '+'; | ||
| 35144 | p->n = 1; | ||
| 35145 | p->iDP = 1; | ||
| 35146 | p->z = "0"; | ||
| 35147 | return; | ||
| 35148 | }else{ | ||
| 35149 | p->sign = '+'; | ||
| 35150 | } | ||
| 35151 | memcpy(&v,&r,8); | ||
| 35152 | e = v>>52; | ||
| 35153 | if( (e&0x7ff)==0x7ff ){ | ||
| 35154 | p->isSpecial = 1 + (v!=0x7ff0000000000000LL); | ||
| 35155 | p->n = 0; | ||
| 35156 | p->iDP = 0; | ||
| 35157 | return; | ||
| 35158 | } | ||
| 35159 | |||
| 35160 | /* Multiply r by powers of ten until it lands somewhere in between | ||
| 35161 | ** 1.0e+19 and 1.0e+17. | ||
| 35162 | */ | ||
| 35163 | if( sqlite3Config.bUseLongDouble ){ | ||
| 35164 | LONGDOUBLE_TYPE rr = r; | ||
| 35165 | if( rr>=1.0e+19 ){ | ||
| 35166 | while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } | ||
| 35167 | while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; } | ||
| 35168 | while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; } | ||
| 35169 | }else{ | ||
| 35170 | while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; } | ||
| 35171 | while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; } | ||
| 35172 | while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; } | ||
| 35173 | } | ||
| 35174 | v = (u64)rr; | ||
| 35175 | }else{ | ||
| 35176 | /* If high-precision floating point is not available using "long double", | ||
| 35177 | ** then use Dekker-style double-double computation to increase the | ||
| 35178 | ** precision. | ||
| 35179 | ** | ||
| 35180 | ** The error terms on constants like 1.0e+100 computed using the | ||
| 35181 | ** decimal extension, for example as follows: | ||
| 35182 | ** | ||
| 35183 | ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); | ||
| 35184 | */ | ||
| 35185 | double rr[2]; | ||
| 35186 | rr[0] = r; | ||
| 35187 | rr[1] = 0.0; | ||
| 35188 | if( rr[0]>1.84e+19 ){ | ||
| 35189 | while( rr[0]>1.84e+119 ){ | ||
| 35190 | exp += 100; | ||
| 35191 | dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); | ||
| 35192 | } | ||
| 35193 | while( rr[0]>1.84e+29 ){ | ||
| 35194 | exp += 10; | ||
| 35195 | dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); | ||
| 35196 | } | ||
| 35197 | while( rr[0]>1.84e+19 ){ | ||
| 35198 | exp += 1; | ||
| 35199 | dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); | ||
| 35200 | } | ||
| 35201 | }else{ | ||
| 35202 | while( rr[0]<1.84e-82 ){ | ||
| 35203 | exp -= 100; | ||
| 35204 | dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); | ||
| 35205 | } | ||
| 35206 | while( rr[0]<1.84e+08 ){ | ||
| 35207 | exp -= 10; | ||
| 35208 | dekkerMul2(rr, 1.0e+10, 0.0); | ||
| 35209 | } | ||
| 35210 | while( rr[0]<1.84e+18 ){ | ||
| 35211 | exp -= 1; | ||
| 35212 | dekkerMul2(rr, 1.0e+01, 0.0); | ||
| 35213 | } | ||
| 35214 | } | ||
| 35215 | v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; | ||
| 35216 | } | ||
| 35217 | |||
| 35218 | |||
| 35219 | /* Extract significant digits. */ | ||
| 35220 | i = sizeof(p->zBuf)-1; | ||
| 35221 | assert( v>0 ); | ||
| 35222 | while( v ){ p->zBuf[i--] = (v%10) + '0'; v /= 10; } | ||
| 35223 | assert( i>=0 && i<sizeof(p->zBuf)-1 ); | ||
| 35224 | p->n = sizeof(p->zBuf) - 1 - i; | ||
| 35225 | assert( p->n>0 ); | ||
| 35226 | assert( p->n<sizeof(p->zBuf) ); | ||
| 35227 | p->iDP = p->n + exp; | ||
| 35228 | if( iRound<0 ){ | ||
| 35229 | iRound = p->iDP - iRound; | ||
| 35230 | if( iRound==0 && p->zBuf[i+1]>='5' ){ | ||
| 35231 | iRound = 1; | ||
| 35232 | p->zBuf[i--] = '0'; | ||
| 35233 | p->n++; | ||
| 35234 | p->iDP++; | ||
| 35235 | } | ||
| 35236 | } | ||
| 35237 | if( iRound>0 && (iRound<p->n || p->n>mxRound) ){ | ||
| 35238 | char *z = &p->zBuf[i+1]; | ||
| 35239 | if( iRound>mxRound ) iRound = mxRound; | ||
| 35240 | p->n = iRound; | ||
| 35241 | if( z[iRound]>='5' ){ | ||
| 35242 | int j = iRound-1; | ||
| 35243 | while( 1 /*exit-by-break*/ ){ | ||
| 35244 | z[j]++; | ||
| 35245 | if( z[j]<='9' ) break; | ||
| 35246 | z[j] = '0'; | ||
| 35247 | if( j==0 ){ | ||
| 35248 | p->z[i--] = '1'; | ||
| 35249 | p->n++; | ||
| 35250 | p->iDP++; | ||
| 35251 | break; | ||
| 35252 | }else{ | ||
| 35253 | j--; | ||
| 35254 | } | ||
| 35255 | } | ||
| 35256 | } | ||
| 35257 | } | ||
| 35258 | p->z = &p->zBuf[i+1]; | ||
| 35259 | assert( i+p->n < sizeof(p->zBuf) ); | ||
| 35260 | while( ALWAYS(p->n>0) && p->z[p->n-1]=='0' ){ p->n--; } | ||
| 35261 | } | ||
| 35262 | |||
| 35263 | /* | ||
| 34183 | ** Try to convert z into an unsigned 32-bit integer. Return true on | 35264 | ** Try to convert z into an unsigned 32-bit integer. Return true on |
| 34184 | ** success and false if there is an error. | 35265 | ** success and false if there is an error. |
| 34185 | ** | 35266 | ** |
| @@ -34707,7 +35788,7 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ | |||
| 34707 | } | 35788 | } |
| 34708 | 35789 | ||
| 34709 | /* | 35790 | /* |
| 34710 | ** Attempt to add, substract, or multiply the 64-bit signed value iB against | 35791 | ** Attempt to add, subtract, or multiply the 64-bit signed value iB against |
| 34711 | ** the other 64-bit signed integer at *pA and store the result in *pA. | 35792 | ** the other 64-bit signed integer at *pA and store the result in *pA. |
| 34712 | ** Return 0 on success. Or if the operation would have resulted in an | 35793 | ** Return 0 on success. Or if the operation would have resulted in an |
| 34713 | ** overflow, leave *pA unchanged and return 1. | 35794 | ** overflow, leave *pA unchanged and return 1. |
| @@ -34993,6 +36074,104 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam | |||
| 34993 | return 0; | 36074 | return 0; |
| 34994 | } | 36075 | } |
| 34995 | 36076 | ||
| 36077 | /* | ||
| 36078 | ** High-resolution hardware timer used for debugging and testing only. | ||
| 36079 | */ | ||
| 36080 | #if defined(VDBE_PROFILE) \ | ||
| 36081 | || defined(SQLITE_PERFORMANCE_TRACE) \ | ||
| 36082 | || defined(SQLITE_ENABLE_STMT_SCANSTATUS) | ||
| 36083 | /************** Include hwtime.h in the middle of util.c *********************/ | ||
| 36084 | /************** Begin file hwtime.h ******************************************/ | ||
| 36085 | /* | ||
| 36086 | ** 2008 May 27 | ||
| 36087 | ** | ||
| 36088 | ** The author disclaims copyright to this source code. In place of | ||
| 36089 | ** a legal notice, here is a blessing: | ||
| 36090 | ** | ||
| 36091 | ** May you do good and not evil. | ||
| 36092 | ** May you find forgiveness for yourself and forgive others. | ||
| 36093 | ** May you share freely, never taking more than you give. | ||
| 36094 | ** | ||
| 36095 | ****************************************************************************** | ||
| 36096 | ** | ||
| 36097 | ** This file contains inline asm code for retrieving "high-performance" | ||
| 36098 | ** counters for x86 and x86_64 class CPUs. | ||
| 36099 | */ | ||
| 36100 | #ifndef SQLITE_HWTIME_H | ||
| 36101 | #define SQLITE_HWTIME_H | ||
| 36102 | |||
| 36103 | /* | ||
| 36104 | ** The following routine only works on Pentium-class (or newer) processors. | ||
| 36105 | ** It uses the RDTSC opcode to read the cycle count value out of the | ||
| 36106 | ** processor and returns that value. This can be used for high-res | ||
| 36107 | ** profiling. | ||
| 36108 | */ | ||
| 36109 | #if !defined(__STRICT_ANSI__) && \ | ||
| 36110 | (defined(__GNUC__) || defined(_MSC_VER)) && \ | ||
| 36111 | (defined(i386) || defined(__i386__) || defined(_M_IX86)) | ||
| 36112 | |||
| 36113 | #if defined(__GNUC__) | ||
| 36114 | |||
| 36115 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 36116 | unsigned int lo, hi; | ||
| 36117 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
| 36118 | return (sqlite_uint64)hi << 32 | lo; | ||
| 36119 | } | ||
| 36120 | |||
| 36121 | #elif defined(_MSC_VER) | ||
| 36122 | |||
| 36123 | __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ | ||
| 36124 | __asm { | ||
| 36125 | rdtsc | ||
| 36126 | ret ; return value at EDX:EAX | ||
| 36127 | } | ||
| 36128 | } | ||
| 36129 | |||
| 36130 | #endif | ||
| 36131 | |||
| 36132 | #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) | ||
| 36133 | |||
| 36134 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 36135 | unsigned int lo, hi; | ||
| 36136 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
| 36137 | return (sqlite_uint64)hi << 32 | lo; | ||
| 36138 | } | ||
| 36139 | |||
| 36140 | #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) | ||
| 36141 | |||
| 36142 | __inline__ sqlite_uint64 sqlite3Hwtime(void){ | ||
| 36143 | unsigned long long retval; | ||
| 36144 | unsigned long junk; | ||
| 36145 | __asm__ __volatile__ ("\n\ | ||
| 36146 | 1: mftbu %1\n\ | ||
| 36147 | mftb %L0\n\ | ||
| 36148 | mftbu %0\n\ | ||
| 36149 | cmpw %0,%1\n\ | ||
| 36150 | bne 1b" | ||
| 36151 | : "=r" (retval), "=r" (junk)); | ||
| 36152 | return retval; | ||
| 36153 | } | ||
| 36154 | |||
| 36155 | #else | ||
| 36156 | |||
| 36157 | /* | ||
| 36158 | ** asm() is needed for hardware timing support. Without asm(), | ||
| 36159 | ** disable the sqlite3Hwtime() routine. | ||
| 36160 | ** | ||
| 36161 | ** sqlite3Hwtime() is only used for some obscure debugging | ||
| 36162 | ** and analysis configurations, not in any deliverable, so this | ||
| 36163 | ** should not be a great loss. | ||
| 36164 | */ | ||
| 36165 | SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } | ||
| 36166 | |||
| 36167 | #endif | ||
| 36168 | |||
| 36169 | #endif /* !defined(SQLITE_HWTIME_H) */ | ||
| 36170 | |||
| 36171 | /************** End of hwtime.h **********************************************/ | ||
| 36172 | /************** Continuing where we left off in util.c ***********************/ | ||
| 36173 | #endif | ||
| 36174 | |||
| 34996 | /************** End of util.c ************************************************/ | 36175 | /************** End of util.c ************************************************/ |
| 34997 | /************** Begin file hash.c ********************************************/ | 36176 | /************** Begin file hash.c ********************************************/ |
| 34998 | /* | 36177 | /* |
| @@ -35094,7 +36273,7 @@ static void insertElement( | |||
| 35094 | } | 36273 | } |
| 35095 | 36274 | ||
| 35096 | 36275 | ||
| 35097 | /* Resize the hash table so that it cantains "new_size" buckets. | 36276 | /* Resize the hash table so that it contains "new_size" buckets. |
| 35098 | ** | 36277 | ** |
| 35099 | ** The hash table might fail to resize if sqlite3_malloc() fails or | 36278 | ** The hash table might fail to resize if sqlite3_malloc() fails or |
| 35100 | ** if the new size is the same as the prior size. | 36279 | ** if the new size is the same as the prior size. |
| @@ -35163,12 +36342,13 @@ static HashElem *findElementWithHash( | |||
| 35163 | count = pH->count; | 36342 | count = pH->count; |
| 35164 | } | 36343 | } |
| 35165 | if( pHash ) *pHash = h; | 36344 | if( pHash ) *pHash = h; |
| 35166 | while( count-- ){ | 36345 | while( count ){ |
| 35167 | assert( elem!=0 ); | 36346 | assert( elem!=0 ); |
| 35168 | if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ | 36347 | if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ |
| 35169 | return elem; | 36348 | return elem; |
| 35170 | } | 36349 | } |
| 35171 | elem = elem->next; | 36350 | elem = elem->next; |
| 36351 | count--; | ||
| 35172 | } | 36352 | } |
| 35173 | return &nullElement; | 36353 | return &nullElement; |
| 35174 | } | 36354 | } |
| @@ -35287,48 +36467,48 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 35287 | /* 5 */ "Vacuum" OpHelp(""), | 36467 | /* 5 */ "Vacuum" OpHelp(""), |
| 35288 | /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), | 36468 | /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), |
| 35289 | /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"), | 36469 | /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"), |
| 35290 | /* 8 */ "Goto" OpHelp(""), | 36470 | /* 8 */ "Init" OpHelp("Start at P2"), |
| 35291 | /* 9 */ "Gosub" OpHelp(""), | 36471 | /* 9 */ "Goto" OpHelp(""), |
| 35292 | /* 10 */ "InitCoroutine" OpHelp(""), | 36472 | /* 10 */ "Gosub" OpHelp(""), |
| 35293 | /* 11 */ "Yield" OpHelp(""), | 36473 | /* 11 */ "InitCoroutine" OpHelp(""), |
| 35294 | /* 12 */ "MustBeInt" OpHelp(""), | 36474 | /* 12 */ "Yield" OpHelp(""), |
| 35295 | /* 13 */ "Jump" OpHelp(""), | 36475 | /* 13 */ "MustBeInt" OpHelp(""), |
| 35296 | /* 14 */ "Once" OpHelp(""), | 36476 | /* 14 */ "Jump" OpHelp(""), |
| 35297 | /* 15 */ "If" OpHelp(""), | 36477 | /* 15 */ "Once" OpHelp(""), |
| 35298 | /* 16 */ "IfNot" OpHelp(""), | 36478 | /* 16 */ "If" OpHelp(""), |
| 35299 | /* 17 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"), | 36479 | /* 17 */ "IfNot" OpHelp(""), |
| 35300 | /* 18 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), | 36480 | /* 18 */ "IsType" OpHelp("if typeof(P1.P3) in P5 goto P2"), |
| 35301 | /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), | 36481 | /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), |
| 35302 | /* 20 */ "SeekLT" OpHelp("key=r[P3@P4]"), | 36482 | /* 20 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), |
| 35303 | /* 21 */ "SeekLE" OpHelp("key=r[P3@P4]"), | 36483 | /* 21 */ "SeekLT" OpHelp("key=r[P3@P4]"), |
| 35304 | /* 22 */ "SeekGE" OpHelp("key=r[P3@P4]"), | 36484 | /* 22 */ "SeekLE" OpHelp("key=r[P3@P4]"), |
| 35305 | /* 23 */ "SeekGT" OpHelp("key=r[P3@P4]"), | 36485 | /* 23 */ "SeekGE" OpHelp("key=r[P3@P4]"), |
| 35306 | /* 24 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), | 36486 | /* 24 */ "SeekGT" OpHelp("key=r[P3@P4]"), |
| 35307 | /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"), | 36487 | /* 25 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), |
| 35308 | /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"), | 36488 | /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), |
| 35309 | /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"), | 36489 | /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), |
| 35310 | /* 28 */ "Found" OpHelp("key=r[P3@P4]"), | 36490 | /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), |
| 35311 | /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"), | 36491 | /* 29 */ "Found" OpHelp("key=r[P3@P4]"), |
| 35312 | /* 30 */ "NotExists" OpHelp("intkey=r[P3]"), | 36492 | /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), |
| 35313 | /* 31 */ "Last" OpHelp(""), | 36493 | /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), |
| 35314 | /* 32 */ "IfSmaller" OpHelp(""), | 36494 | /* 32 */ "Last" OpHelp(""), |
| 35315 | /* 33 */ "SorterSort" OpHelp(""), | 36495 | /* 33 */ "IfSmaller" OpHelp(""), |
| 35316 | /* 34 */ "Sort" OpHelp(""), | 36496 | /* 34 */ "SorterSort" OpHelp(""), |
| 35317 | /* 35 */ "Rewind" OpHelp(""), | 36497 | /* 35 */ "Sort" OpHelp(""), |
| 35318 | /* 36 */ "SorterNext" OpHelp(""), | 36498 | /* 36 */ "Rewind" OpHelp(""), |
| 35319 | /* 37 */ "Prev" OpHelp(""), | 36499 | /* 37 */ "SorterNext" OpHelp(""), |
| 35320 | /* 38 */ "Next" OpHelp(""), | 36500 | /* 38 */ "Prev" OpHelp(""), |
| 35321 | /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"), | 36501 | /* 39 */ "Next" OpHelp(""), |
| 35322 | /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"), | 36502 | /* 40 */ "IdxLE" OpHelp("key=r[P3@P4]"), |
| 35323 | /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"), | 36503 | /* 41 */ "IdxGT" OpHelp("key=r[P3@P4]"), |
| 35324 | /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"), | 36504 | /* 42 */ "IdxLT" OpHelp("key=r[P3@P4]"), |
| 35325 | /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), | 36505 | /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), |
| 35326 | /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), | 36506 | /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), |
| 35327 | /* 45 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), | 36507 | /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), |
| 35328 | /* 46 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), | 36508 | /* 46 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), |
| 35329 | /* 47 */ "Program" OpHelp(""), | 36509 | /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), |
| 35330 | /* 48 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), | 36510 | /* 48 */ "Program" OpHelp(""), |
| 35331 | /* 49 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), | 36511 | /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), |
| 35332 | /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), | 36512 | /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), |
| 35333 | /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), | 36513 | /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), |
| 35334 | /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), | 36514 | /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), |
| @@ -35338,12 +36518,12 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 35338 | /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"), | 36518 | /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"), |
| 35339 | /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), | 36519 | /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"), |
| 35340 | /* 58 */ "ElseEq" OpHelp(""), | 36520 | /* 58 */ "ElseEq" OpHelp(""), |
| 35341 | /* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), | 36521 | /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), |
| 35342 | /* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), | 36522 | /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), |
| 35343 | /* 61 */ "IncrVacuum" OpHelp(""), | 36523 | /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), |
| 35344 | /* 62 */ "VNext" OpHelp(""), | 36524 | /* 62 */ "IncrVacuum" OpHelp(""), |
| 35345 | /* 63 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), | 36525 | /* 63 */ "VNext" OpHelp(""), |
| 35346 | /* 64 */ "Init" OpHelp("Start at P2"), | 36526 | /* 64 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), |
| 35347 | /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), | 36527 | /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), |
| 35348 | /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), | 36528 | /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), |
| 35349 | /* 67 */ "Return" OpHelp(""), | 36529 | /* 67 */ "Return" OpHelp(""), |
| @@ -35472,6 +36652,988 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 35472 | #endif | 36652 | #endif |
| 35473 | 36653 | ||
| 35474 | /************** End of opcodes.c *********************************************/ | 36654 | /************** End of opcodes.c *********************************************/ |
| 36655 | /************** Begin file os_kv.c *******************************************/ | ||
| 36656 | /* | ||
| 36657 | ** 2022-09-06 | ||
| 36658 | ** | ||
| 36659 | ** The author disclaims copyright to this source code. In place of | ||
| 36660 | ** a legal notice, here is a blessing: | ||
| 36661 | ** | ||
| 36662 | ** May you do good and not evil. | ||
| 36663 | ** May you find forgiveness for yourself and forgive others. | ||
| 36664 | ** May you share freely, never taking more than you give. | ||
| 36665 | ** | ||
| 36666 | ****************************************************************************** | ||
| 36667 | ** | ||
| 36668 | ** This file contains an experimental VFS layer that operates on a | ||
| 36669 | ** Key/Value storage engine where both keys and values must be pure | ||
| 36670 | ** text. | ||
| 36671 | */ | ||
| 36672 | /* #include <sqliteInt.h> */ | ||
| 36673 | #if SQLITE_OS_KV || (SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL)) | ||
| 36674 | |||
| 36675 | /***************************************************************************** | ||
| 36676 | ** Debugging logic | ||
| 36677 | */ | ||
| 36678 | |||
| 36679 | /* SQLITE_KV_TRACE() is used for tracing calls to kvstorage routines. */ | ||
| 36680 | #if 0 | ||
| 36681 | #define SQLITE_KV_TRACE(X) printf X | ||
| 36682 | #else | ||
| 36683 | #define SQLITE_KV_TRACE(X) | ||
| 36684 | #endif | ||
| 36685 | |||
| 36686 | /* SQLITE_KV_LOG() is used for tracing calls to the VFS interface */ | ||
| 36687 | #if 0 | ||
| 36688 | #define SQLITE_KV_LOG(X) printf X | ||
| 36689 | #else | ||
| 36690 | #define SQLITE_KV_LOG(X) | ||
| 36691 | #endif | ||
| 36692 | |||
| 36693 | |||
| 36694 | /* | ||
| 36695 | ** Forward declaration of objects used by this VFS implementation | ||
| 36696 | */ | ||
| 36697 | typedef struct KVVfsFile KVVfsFile; | ||
| 36698 | |||
| 36699 | /* A single open file. There are only two files represented by this | ||
| 36700 | ** VFS - the database and the rollback journal. | ||
| 36701 | */ | ||
| 36702 | struct KVVfsFile { | ||
| 36703 | sqlite3_file base; /* IO methods */ | ||
| 36704 | const char *zClass; /* Storage class */ | ||
| 36705 | int isJournal; /* True if this is a journal file */ | ||
| 36706 | unsigned int nJrnl; /* Space allocated for aJrnl[] */ | ||
| 36707 | char *aJrnl; /* Journal content */ | ||
| 36708 | int szPage; /* Last known page size */ | ||
| 36709 | sqlite3_int64 szDb; /* Database file size. -1 means unknown */ | ||
| 36710 | char *aData; /* Buffer to hold page data */ | ||
| 36711 | }; | ||
| 36712 | #define SQLITE_KVOS_SZ 133073 | ||
| 36713 | |||
| 36714 | /* | ||
| 36715 | ** Methods for KVVfsFile | ||
| 36716 | */ | ||
| 36717 | static int kvvfsClose(sqlite3_file*); | ||
| 36718 | static int kvvfsReadDb(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); | ||
| 36719 | static int kvvfsReadJrnl(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); | ||
| 36720 | static int kvvfsWriteDb(sqlite3_file*,const void*,int iAmt, sqlite3_int64); | ||
| 36721 | static int kvvfsWriteJrnl(sqlite3_file*,const void*,int iAmt, sqlite3_int64); | ||
| 36722 | static int kvvfsTruncateDb(sqlite3_file*, sqlite3_int64 size); | ||
| 36723 | static int kvvfsTruncateJrnl(sqlite3_file*, sqlite3_int64 size); | ||
| 36724 | static int kvvfsSyncDb(sqlite3_file*, int flags); | ||
| 36725 | static int kvvfsSyncJrnl(sqlite3_file*, int flags); | ||
| 36726 | static int kvvfsFileSizeDb(sqlite3_file*, sqlite3_int64 *pSize); | ||
| 36727 | static int kvvfsFileSizeJrnl(sqlite3_file*, sqlite3_int64 *pSize); | ||
| 36728 | static int kvvfsLock(sqlite3_file*, int); | ||
| 36729 | static int kvvfsUnlock(sqlite3_file*, int); | ||
| 36730 | static int kvvfsCheckReservedLock(sqlite3_file*, int *pResOut); | ||
| 36731 | static int kvvfsFileControlDb(sqlite3_file*, int op, void *pArg); | ||
| 36732 | static int kvvfsFileControlJrnl(sqlite3_file*, int op, void *pArg); | ||
| 36733 | static int kvvfsSectorSize(sqlite3_file*); | ||
| 36734 | static int kvvfsDeviceCharacteristics(sqlite3_file*); | ||
| 36735 | |||
| 36736 | /* | ||
| 36737 | ** Methods for sqlite3_vfs | ||
| 36738 | */ | ||
| 36739 | static int kvvfsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); | ||
| 36740 | static int kvvfsDelete(sqlite3_vfs*, const char *zName, int syncDir); | ||
| 36741 | static int kvvfsAccess(sqlite3_vfs*, const char *zName, int flags, int *); | ||
| 36742 | static int kvvfsFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); | ||
| 36743 | static void *kvvfsDlOpen(sqlite3_vfs*, const char *zFilename); | ||
| 36744 | static int kvvfsRandomness(sqlite3_vfs*, int nByte, char *zOut); | ||
| 36745 | static int kvvfsSleep(sqlite3_vfs*, int microseconds); | ||
| 36746 | static int kvvfsCurrentTime(sqlite3_vfs*, double*); | ||
| 36747 | static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); | ||
| 36748 | |||
| 36749 | static sqlite3_vfs sqlite3OsKvvfsObject = { | ||
| 36750 | 1, /* iVersion */ | ||
| 36751 | sizeof(KVVfsFile), /* szOsFile */ | ||
| 36752 | 1024, /* mxPathname */ | ||
| 36753 | 0, /* pNext */ | ||
| 36754 | "kvvfs", /* zName */ | ||
| 36755 | 0, /* pAppData */ | ||
| 36756 | kvvfsOpen, /* xOpen */ | ||
| 36757 | kvvfsDelete, /* xDelete */ | ||
| 36758 | kvvfsAccess, /* xAccess */ | ||
| 36759 | kvvfsFullPathname, /* xFullPathname */ | ||
| 36760 | kvvfsDlOpen, /* xDlOpen */ | ||
| 36761 | 0, /* xDlError */ | ||
| 36762 | 0, /* xDlSym */ | ||
| 36763 | 0, /* xDlClose */ | ||
| 36764 | kvvfsRandomness, /* xRandomness */ | ||
| 36765 | kvvfsSleep, /* xSleep */ | ||
| 36766 | kvvfsCurrentTime, /* xCurrentTime */ | ||
| 36767 | 0, /* xGetLastError */ | ||
| 36768 | kvvfsCurrentTimeInt64 /* xCurrentTimeInt64 */ | ||
| 36769 | }; | ||
| 36770 | |||
| 36771 | /* Methods for sqlite3_file objects referencing a database file | ||
| 36772 | */ | ||
| 36773 | static sqlite3_io_methods kvvfs_db_io_methods = { | ||
| 36774 | 1, /* iVersion */ | ||
| 36775 | kvvfsClose, /* xClose */ | ||
| 36776 | kvvfsReadDb, /* xRead */ | ||
| 36777 | kvvfsWriteDb, /* xWrite */ | ||
| 36778 | kvvfsTruncateDb, /* xTruncate */ | ||
| 36779 | kvvfsSyncDb, /* xSync */ | ||
| 36780 | kvvfsFileSizeDb, /* xFileSize */ | ||
| 36781 | kvvfsLock, /* xLock */ | ||
| 36782 | kvvfsUnlock, /* xUnlock */ | ||
| 36783 | kvvfsCheckReservedLock, /* xCheckReservedLock */ | ||
| 36784 | kvvfsFileControlDb, /* xFileControl */ | ||
| 36785 | kvvfsSectorSize, /* xSectorSize */ | ||
| 36786 | kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ | ||
| 36787 | 0, /* xShmMap */ | ||
| 36788 | 0, /* xShmLock */ | ||
| 36789 | 0, /* xShmBarrier */ | ||
| 36790 | 0, /* xShmUnmap */ | ||
| 36791 | 0, /* xFetch */ | ||
| 36792 | 0 /* xUnfetch */ | ||
| 36793 | }; | ||
| 36794 | |||
| 36795 | /* Methods for sqlite3_file objects referencing a rollback journal | ||
| 36796 | */ | ||
| 36797 | static sqlite3_io_methods kvvfs_jrnl_io_methods = { | ||
| 36798 | 1, /* iVersion */ | ||
| 36799 | kvvfsClose, /* xClose */ | ||
| 36800 | kvvfsReadJrnl, /* xRead */ | ||
| 36801 | kvvfsWriteJrnl, /* xWrite */ | ||
| 36802 | kvvfsTruncateJrnl, /* xTruncate */ | ||
| 36803 | kvvfsSyncJrnl, /* xSync */ | ||
| 36804 | kvvfsFileSizeJrnl, /* xFileSize */ | ||
| 36805 | kvvfsLock, /* xLock */ | ||
| 36806 | kvvfsUnlock, /* xUnlock */ | ||
| 36807 | kvvfsCheckReservedLock, /* xCheckReservedLock */ | ||
| 36808 | kvvfsFileControlJrnl, /* xFileControl */ | ||
| 36809 | kvvfsSectorSize, /* xSectorSize */ | ||
| 36810 | kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ | ||
| 36811 | 0, /* xShmMap */ | ||
| 36812 | 0, /* xShmLock */ | ||
| 36813 | 0, /* xShmBarrier */ | ||
| 36814 | 0, /* xShmUnmap */ | ||
| 36815 | 0, /* xFetch */ | ||
| 36816 | 0 /* xUnfetch */ | ||
| 36817 | }; | ||
| 36818 | |||
| 36819 | /****** Storage subsystem **************************************************/ | ||
| 36820 | #include <sys/types.h> | ||
| 36821 | #include <sys/stat.h> | ||
| 36822 | #include <unistd.h> | ||
| 36823 | |||
| 36824 | /* Forward declarations for the low-level storage engine | ||
| 36825 | */ | ||
| 36826 | static int kvstorageWrite(const char*, const char *zKey, const char *zData); | ||
| 36827 | static int kvstorageDelete(const char*, const char *zKey); | ||
| 36828 | static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf); | ||
| 36829 | #define KVSTORAGE_KEY_SZ 32 | ||
| 36830 | |||
| 36831 | /* Expand the key name with an appropriate prefix and put the result | ||
| 36832 | ** zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least | ||
| 36833 | ** KVSTORAGE_KEY_SZ bytes. | ||
| 36834 | */ | ||
| 36835 | static void kvstorageMakeKey( | ||
| 36836 | const char *zClass, | ||
| 36837 | const char *zKeyIn, | ||
| 36838 | char *zKeyOut | ||
| 36839 | ){ | ||
| 36840 | sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "kvvfs-%s-%s", zClass, zKeyIn); | ||
| 36841 | } | ||
| 36842 | |||
| 36843 | /* Write content into a key. zClass is the particular namespace of the | ||
| 36844 | ** underlying key/value store to use - either "local" or "session". | ||
| 36845 | ** | ||
| 36846 | ** Both zKey and zData are zero-terminated pure text strings. | ||
| 36847 | ** | ||
| 36848 | ** Return the number of errors. | ||
| 36849 | */ | ||
| 36850 | static int kvstorageWrite( | ||
| 36851 | const char *zClass, | ||
| 36852 | const char *zKey, | ||
| 36853 | const char *zData | ||
| 36854 | ){ | ||
| 36855 | FILE *fd; | ||
| 36856 | char zXKey[KVSTORAGE_KEY_SZ]; | ||
| 36857 | kvstorageMakeKey(zClass, zKey, zXKey); | ||
| 36858 | fd = fopen(zXKey, "wb"); | ||
| 36859 | if( fd ){ | ||
| 36860 | SQLITE_KV_TRACE(("KVVFS-WRITE %-15s (%d) %.50s%s\n", zXKey, | ||
| 36861 | (int)strlen(zData), zData, | ||
| 36862 | strlen(zData)>50 ? "..." : "")); | ||
| 36863 | fputs(zData, fd); | ||
| 36864 | fclose(fd); | ||
| 36865 | return 0; | ||
| 36866 | }else{ | ||
| 36867 | return 1; | ||
| 36868 | } | ||
| 36869 | } | ||
| 36870 | |||
| 36871 | /* Delete a key (with its corresponding data) from the key/value | ||
| 36872 | ** namespace given by zClass. If the key does not previously exist, | ||
| 36873 | ** this routine is a no-op. | ||
| 36874 | */ | ||
| 36875 | static int kvstorageDelete(const char *zClass, const char *zKey){ | ||
| 36876 | char zXKey[KVSTORAGE_KEY_SZ]; | ||
| 36877 | kvstorageMakeKey(zClass, zKey, zXKey); | ||
| 36878 | unlink(zXKey); | ||
| 36879 | SQLITE_KV_TRACE(("KVVFS-DELETE %-15s\n", zXKey)); | ||
| 36880 | return 0; | ||
| 36881 | } | ||
| 36882 | |||
| 36883 | /* Read the value associated with a zKey from the key/value namespace given | ||
| 36884 | ** by zClass and put the text data associated with that key in the first | ||
| 36885 | ** nBuf bytes of zBuf[]. The value might be truncated if zBuf is not large | ||
| 36886 | ** enough to hold it all. The value put into zBuf must always be zero | ||
| 36887 | ** terminated, even if it gets truncated because nBuf is not large enough. | ||
| 36888 | ** | ||
| 36889 | ** Return the total number of bytes in the data, without truncation, and | ||
| 36890 | ** not counting the final zero terminator. Return -1 if the key does | ||
| 36891 | ** not exist. | ||
| 36892 | ** | ||
| 36893 | ** If nBuf<=0 then this routine simply returns the size of the data without | ||
| 36894 | ** actually reading it. | ||
| 36895 | */ | ||
| 36896 | static int kvstorageRead( | ||
| 36897 | const char *zClass, | ||
| 36898 | const char *zKey, | ||
| 36899 | char *zBuf, | ||
| 36900 | int nBuf | ||
| 36901 | ){ | ||
| 36902 | FILE *fd; | ||
| 36903 | struct stat buf; | ||
| 36904 | char zXKey[KVSTORAGE_KEY_SZ]; | ||
| 36905 | kvstorageMakeKey(zClass, zKey, zXKey); | ||
| 36906 | if( access(zXKey, R_OK)!=0 | ||
| 36907 | || stat(zXKey, &buf)!=0 | ||
| 36908 | || !S_ISREG(buf.st_mode) | ||
| 36909 | ){ | ||
| 36910 | SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); | ||
| 36911 | return -1; | ||
| 36912 | } | ||
| 36913 | if( nBuf<=0 ){ | ||
| 36914 | return (int)buf.st_size; | ||
| 36915 | }else if( nBuf==1 ){ | ||
| 36916 | zBuf[0] = 0; | ||
| 36917 | SQLITE_KV_TRACE(("KVVFS-READ %-15s (%d)\n", zXKey, | ||
| 36918 | (int)buf.st_size)); | ||
| 36919 | return (int)buf.st_size; | ||
| 36920 | } | ||
| 36921 | if( nBuf > buf.st_size + 1 ){ | ||
| 36922 | nBuf = buf.st_size + 1; | ||
| 36923 | } | ||
| 36924 | fd = fopen(zXKey, "rb"); | ||
| 36925 | if( fd==0 ){ | ||
| 36926 | SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); | ||
| 36927 | return -1; | ||
| 36928 | }else{ | ||
| 36929 | sqlite3_int64 n = fread(zBuf, 1, nBuf-1, fd); | ||
| 36930 | fclose(fd); | ||
| 36931 | zBuf[n] = 0; | ||
| 36932 | SQLITE_KV_TRACE(("KVVFS-READ %-15s (%lld) %.50s%s\n", zXKey, | ||
| 36933 | n, zBuf, n>50 ? "..." : "")); | ||
| 36934 | return (int)n; | ||
| 36935 | } | ||
| 36936 | } | ||
| 36937 | |||
| 36938 | /* | ||
| 36939 | ** An internal level of indirection which enables us to replace the | ||
| 36940 | ** kvvfs i/o methods with JavaScript implementations in WASM builds. | ||
| 36941 | ** Maintenance reminder: if this struct changes in any way, the JSON | ||
| 36942 | ** rendering of its structure must be updated in | ||
| 36943 | ** sqlite3_wasm_enum_json(). There are no binary compatibility | ||
| 36944 | ** concerns, so it does not need an iVersion member. This file is | ||
| 36945 | ** necessarily always compiled together with sqlite3_wasm_enum_json(), | ||
| 36946 | ** and JS code dynamically creates the mapping of members based on | ||
| 36947 | ** that JSON description. | ||
| 36948 | */ | ||
| 36949 | typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods; | ||
| 36950 | struct sqlite3_kvvfs_methods { | ||
| 36951 | int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf); | ||
| 36952 | int (*xWrite)(const char *zClass, const char *zKey, const char *zData); | ||
| 36953 | int (*xDelete)(const char *zClass, const char *zKey); | ||
| 36954 | const int nKeySize; | ||
| 36955 | }; | ||
| 36956 | |||
| 36957 | /* | ||
| 36958 | ** This object holds the kvvfs I/O methods which may be swapped out | ||
| 36959 | ** for JavaScript-side implementations in WASM builds. In such builds | ||
| 36960 | ** it cannot be const, but in native builds it should be so that | ||
| 36961 | ** the compiler can hopefully optimize this level of indirection out. | ||
| 36962 | ** That said, kvvfs is intended primarily for use in WASM builds. | ||
| 36963 | ** | ||
| 36964 | ** Note that this is not explicitly flagged as static because the | ||
| 36965 | ** amalgamation build will tag it with SQLITE_PRIVATE. | ||
| 36966 | */ | ||
| 36967 | #ifndef SQLITE_WASM | ||
| 36968 | const | ||
| 36969 | #endif | ||
| 36970 | SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = { | ||
| 36971 | kvstorageRead, | ||
| 36972 | kvstorageWrite, | ||
| 36973 | kvstorageDelete, | ||
| 36974 | KVSTORAGE_KEY_SZ | ||
| 36975 | }; | ||
| 36976 | |||
| 36977 | /****** Utility subroutines ************************************************/ | ||
| 36978 | |||
| 36979 | /* | ||
| 36980 | ** Encode binary into the text encoded used to persist on disk. | ||
| 36981 | ** The output text is stored in aOut[], which must be at least | ||
| 36982 | ** nData+1 bytes in length. | ||
| 36983 | ** | ||
| 36984 | ** Return the actual length of the encoded text, not counting the | ||
| 36985 | ** zero terminator at the end. | ||
| 36986 | ** | ||
| 36987 | ** Encoding format | ||
| 36988 | ** --------------- | ||
| 36989 | ** | ||
| 36990 | ** * Non-zero bytes are encoded as upper-case hexadecimal | ||
| 36991 | ** | ||
| 36992 | ** * A sequence of one or more zero-bytes that are not at the | ||
| 36993 | ** beginning of the buffer are encoded as a little-endian | ||
| 36994 | ** base-26 number using a..z. "a" means 0. "b" means 1, | ||
| 36995 | ** "z" means 25. "ab" means 26. "ac" means 52. And so forth. | ||
| 36996 | ** | ||
| 36997 | ** * Because there is no overlap between the encoding characters | ||
| 36998 | ** of hexadecimal and base-26 numbers, it is always clear where | ||
| 36999 | ** one stops and the next begins. | ||
| 37000 | */ | ||
| 37001 | static int kvvfsEncode(const char *aData, int nData, char *aOut){ | ||
| 37002 | int i, j; | ||
| 37003 | const unsigned char *a = (const unsigned char*)aData; | ||
| 37004 | for(i=j=0; i<nData; i++){ | ||
| 37005 | unsigned char c = a[i]; | ||
| 37006 | if( c!=0 ){ | ||
| 37007 | aOut[j++] = "0123456789ABCDEF"[c>>4]; | ||
| 37008 | aOut[j++] = "0123456789ABCDEF"[c&0xf]; | ||
| 37009 | }else{ | ||
| 37010 | /* A sequence of 1 or more zeros is stored as a little-endian | ||
| 37011 | ** base-26 number using a..z as the digits. So one zero is "b". | ||
| 37012 | ** Two zeros is "c". 25 zeros is "z", 26 zeros is "ab", 27 is "bb", | ||
| 37013 | ** and so forth. | ||
| 37014 | */ | ||
| 37015 | int k; | ||
| 37016 | for(k=1; i+k<nData && a[i+k]==0; k++){} | ||
| 37017 | i += k-1; | ||
| 37018 | while( k>0 ){ | ||
| 37019 | aOut[j++] = 'a'+(k%26); | ||
| 37020 | k /= 26; | ||
| 37021 | } | ||
| 37022 | } | ||
| 37023 | } | ||
| 37024 | aOut[j] = 0; | ||
| 37025 | return j; | ||
| 37026 | } | ||
| 37027 | |||
| 37028 | static const signed char kvvfsHexValue[256] = { | ||
| 37029 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37030 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37031 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37032 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, | ||
| 37033 | -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37034 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37035 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37036 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37037 | |||
| 37038 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37039 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37040 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37041 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37042 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37043 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37044 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 37045 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 | ||
| 37046 | }; | ||
| 37047 | |||
| 37048 | /* | ||
| 37049 | ** Decode the text encoding back to binary. The binary content is | ||
| 37050 | ** written into pOut, which must be at least nOut bytes in length. | ||
| 37051 | ** | ||
| 37052 | ** The return value is the number of bytes actually written into aOut[]. | ||
| 37053 | */ | ||
| 37054 | static int kvvfsDecode(const char *a, char *aOut, int nOut){ | ||
| 37055 | int i, j; | ||
| 37056 | int c; | ||
| 37057 | const unsigned char *aIn = (const unsigned char*)a; | ||
| 37058 | i = 0; | ||
| 37059 | j = 0; | ||
| 37060 | while( 1 ){ | ||
| 37061 | c = kvvfsHexValue[aIn[i]]; | ||
| 37062 | if( c<0 ){ | ||
| 37063 | int n = 0; | ||
| 37064 | int mult = 1; | ||
| 37065 | c = aIn[i]; | ||
| 37066 | if( c==0 ) break; | ||
| 37067 | while( c>='a' && c<='z' ){ | ||
| 37068 | n += (c - 'a')*mult; | ||
| 37069 | mult *= 26; | ||
| 37070 | c = aIn[++i]; | ||
| 37071 | } | ||
| 37072 | if( j+n>nOut ) return -1; | ||
| 37073 | memset(&aOut[j], 0, n); | ||
| 37074 | j += n; | ||
| 37075 | if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */ | ||
| 37076 | }else{ | ||
| 37077 | aOut[j] = c<<4; | ||
| 37078 | c = kvvfsHexValue[aIn[++i]]; | ||
| 37079 | if( c<0 ) break; | ||
| 37080 | aOut[j++] += c; | ||
| 37081 | i++; | ||
| 37082 | } | ||
| 37083 | } | ||
| 37084 | return j; | ||
| 37085 | } | ||
| 37086 | |||
| 37087 | /* | ||
| 37088 | ** Decode a complete journal file. Allocate space in pFile->aJrnl | ||
| 37089 | ** and store the decoding there. Or leave pFile->aJrnl set to NULL | ||
| 37090 | ** if an error is encountered. | ||
| 37091 | ** | ||
| 37092 | ** The first few characters of the text encoding will be a little-endian | ||
| 37093 | ** base-26 number (digits a..z) that is the total number of bytes | ||
| 37094 | ** in the decoded journal file image. This base-26 number is followed | ||
| 37095 | ** by a single space, then the encoding of the journal. The space | ||
| 37096 | ** separator is required to act as a terminator for the base-26 number. | ||
| 37097 | */ | ||
| 37098 | static void kvvfsDecodeJournal( | ||
| 37099 | KVVfsFile *pFile, /* Store decoding in pFile->aJrnl */ | ||
| 37100 | const char *zTxt, /* Text encoding. Zero-terminated */ | ||
| 37101 | int nTxt /* Bytes in zTxt, excluding zero terminator */ | ||
| 37102 | ){ | ||
| 37103 | unsigned int n = 0; | ||
| 37104 | int c, i, mult; | ||
| 37105 | i = 0; | ||
| 37106 | mult = 1; | ||
| 37107 | while( (c = zTxt[i++])>='a' && c<='z' ){ | ||
| 37108 | n += (zTxt[i] - 'a')*mult; | ||
| 37109 | mult *= 26; | ||
| 37110 | } | ||
| 37111 | sqlite3_free(pFile->aJrnl); | ||
| 37112 | pFile->aJrnl = sqlite3_malloc64( n ); | ||
| 37113 | if( pFile->aJrnl==0 ){ | ||
| 37114 | pFile->nJrnl = 0; | ||
| 37115 | return; | ||
| 37116 | } | ||
| 37117 | pFile->nJrnl = n; | ||
| 37118 | n = kvvfsDecode(zTxt+i, pFile->aJrnl, pFile->nJrnl); | ||
| 37119 | if( n<pFile->nJrnl ){ | ||
| 37120 | sqlite3_free(pFile->aJrnl); | ||
| 37121 | pFile->aJrnl = 0; | ||
| 37122 | pFile->nJrnl = 0; | ||
| 37123 | } | ||
| 37124 | } | ||
| 37125 | |||
| 37126 | /* | ||
| 37127 | ** Read or write the "sz" element, containing the database file size. | ||
| 37128 | */ | ||
| 37129 | static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){ | ||
| 37130 | char zData[50]; | ||
| 37131 | zData[0] = 0; | ||
| 37132 | sqlite3KvvfsMethods.xRead(pFile->zClass, "sz", zData, sizeof(zData)-1); | ||
| 37133 | return strtoll(zData, 0, 0); | ||
| 37134 | } | ||
| 37135 | static int kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){ | ||
| 37136 | char zData[50]; | ||
| 37137 | sqlite3_snprintf(sizeof(zData), zData, "%lld", sz); | ||
| 37138 | return sqlite3KvvfsMethods.xWrite(pFile->zClass, "sz", zData); | ||
| 37139 | } | ||
| 37140 | |||
| 37141 | /****** sqlite3_io_methods methods ******************************************/ | ||
| 37142 | |||
| 37143 | /* | ||
| 37144 | ** Close an kvvfs-file. | ||
| 37145 | */ | ||
| 37146 | static int kvvfsClose(sqlite3_file *pProtoFile){ | ||
| 37147 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37148 | |||
| 37149 | SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass, | ||
| 37150 | pFile->isJournal ? "journal" : "db")); | ||
| 37151 | sqlite3_free(pFile->aJrnl); | ||
| 37152 | sqlite3_free(pFile->aData); | ||
| 37153 | return SQLITE_OK; | ||
| 37154 | } | ||
| 37155 | |||
| 37156 | /* | ||
| 37157 | ** Read from the -journal file. | ||
| 37158 | */ | ||
| 37159 | static int kvvfsReadJrnl( | ||
| 37160 | sqlite3_file *pProtoFile, | ||
| 37161 | void *zBuf, | ||
| 37162 | int iAmt, | ||
| 37163 | sqlite_int64 iOfst | ||
| 37164 | ){ | ||
| 37165 | KVVfsFile *pFile = (KVVfsFile*)pProtoFile; | ||
| 37166 | assert( pFile->isJournal ); | ||
| 37167 | SQLITE_KV_LOG(("xRead('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); | ||
| 37168 | if( pFile->aJrnl==0 ){ | ||
| 37169 | int szTxt = kvstorageRead(pFile->zClass, "jrnl", 0, 0); | ||
| 37170 | char *aTxt; | ||
| 37171 | if( szTxt<=4 ){ | ||
| 37172 | return SQLITE_IOERR; | ||
| 37173 | } | ||
| 37174 | aTxt = sqlite3_malloc64( szTxt+1 ); | ||
| 37175 | if( aTxt==0 ) return SQLITE_NOMEM; | ||
| 37176 | kvstorageRead(pFile->zClass, "jrnl", aTxt, szTxt+1); | ||
| 37177 | kvvfsDecodeJournal(pFile, aTxt, szTxt); | ||
| 37178 | sqlite3_free(aTxt); | ||
| 37179 | if( pFile->aJrnl==0 ) return SQLITE_IOERR; | ||
| 37180 | } | ||
| 37181 | if( iOfst+iAmt>pFile->nJrnl ){ | ||
| 37182 | return SQLITE_IOERR_SHORT_READ; | ||
| 37183 | } | ||
| 37184 | memcpy(zBuf, pFile->aJrnl+iOfst, iAmt); | ||
| 37185 | return SQLITE_OK; | ||
| 37186 | } | ||
| 37187 | |||
| 37188 | /* | ||
| 37189 | ** Read from the database file. | ||
| 37190 | */ | ||
| 37191 | static int kvvfsReadDb( | ||
| 37192 | sqlite3_file *pProtoFile, | ||
| 37193 | void *zBuf, | ||
| 37194 | int iAmt, | ||
| 37195 | sqlite_int64 iOfst | ||
| 37196 | ){ | ||
| 37197 | KVVfsFile *pFile = (KVVfsFile*)pProtoFile; | ||
| 37198 | unsigned int pgno; | ||
| 37199 | int got, n; | ||
| 37200 | char zKey[30]; | ||
| 37201 | char *aData = pFile->aData; | ||
| 37202 | assert( iOfst>=0 ); | ||
| 37203 | assert( iAmt>=0 ); | ||
| 37204 | SQLITE_KV_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); | ||
| 37205 | if( iOfst+iAmt>=512 ){ | ||
| 37206 | if( (iOfst % iAmt)!=0 ){ | ||
| 37207 | return SQLITE_IOERR_READ; | ||
| 37208 | } | ||
| 37209 | if( (iAmt & (iAmt-1))!=0 || iAmt<512 || iAmt>65536 ){ | ||
| 37210 | return SQLITE_IOERR_READ; | ||
| 37211 | } | ||
| 37212 | pFile->szPage = iAmt; | ||
| 37213 | pgno = 1 + iOfst/iAmt; | ||
| 37214 | }else{ | ||
| 37215 | pgno = 1; | ||
| 37216 | } | ||
| 37217 | sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); | ||
| 37218 | got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, | ||
| 37219 | aData, SQLITE_KVOS_SZ-1); | ||
| 37220 | if( got<0 ){ | ||
| 37221 | n = 0; | ||
| 37222 | }else{ | ||
| 37223 | aData[got] = 0; | ||
| 37224 | if( iOfst+iAmt<512 ){ | ||
| 37225 | int k = iOfst+iAmt; | ||
| 37226 | aData[k*2] = 0; | ||
| 37227 | n = kvvfsDecode(aData, &aData[2000], SQLITE_KVOS_SZ-2000); | ||
| 37228 | if( n>=iOfst+iAmt ){ | ||
| 37229 | memcpy(zBuf, &aData[2000+iOfst], iAmt); | ||
| 37230 | n = iAmt; | ||
| 37231 | }else{ | ||
| 37232 | n = 0; | ||
| 37233 | } | ||
| 37234 | }else{ | ||
| 37235 | n = kvvfsDecode(aData, zBuf, iAmt); | ||
| 37236 | } | ||
| 37237 | } | ||
| 37238 | if( n<iAmt ){ | ||
| 37239 | memset(zBuf+n, 0, iAmt-n); | ||
| 37240 | return SQLITE_IOERR_SHORT_READ; | ||
| 37241 | } | ||
| 37242 | return SQLITE_OK; | ||
| 37243 | } | ||
| 37244 | |||
| 37245 | |||
| 37246 | /* | ||
| 37247 | ** Write into the -journal file. | ||
| 37248 | */ | ||
| 37249 | static int kvvfsWriteJrnl( | ||
| 37250 | sqlite3_file *pProtoFile, | ||
| 37251 | const void *zBuf, | ||
| 37252 | int iAmt, | ||
| 37253 | sqlite_int64 iOfst | ||
| 37254 | ){ | ||
| 37255 | KVVfsFile *pFile = (KVVfsFile*)pProtoFile; | ||
| 37256 | sqlite3_int64 iEnd = iOfst+iAmt; | ||
| 37257 | SQLITE_KV_LOG(("xWrite('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); | ||
| 37258 | if( iEnd>=0x10000000 ) return SQLITE_FULL; | ||
| 37259 | if( pFile->aJrnl==0 || pFile->nJrnl<iEnd ){ | ||
| 37260 | char *aNew = sqlite3_realloc(pFile->aJrnl, iEnd); | ||
| 37261 | if( aNew==0 ){ | ||
| 37262 | return SQLITE_IOERR_NOMEM; | ||
| 37263 | } | ||
| 37264 | pFile->aJrnl = aNew; | ||
| 37265 | if( pFile->nJrnl<iOfst ){ | ||
| 37266 | memset(pFile->aJrnl+pFile->nJrnl, 0, iOfst-pFile->nJrnl); | ||
| 37267 | } | ||
| 37268 | pFile->nJrnl = iEnd; | ||
| 37269 | } | ||
| 37270 | memcpy(pFile->aJrnl+iOfst, zBuf, iAmt); | ||
| 37271 | return SQLITE_OK; | ||
| 37272 | } | ||
| 37273 | |||
| 37274 | /* | ||
| 37275 | ** Write into the database file. | ||
| 37276 | */ | ||
| 37277 | static int kvvfsWriteDb( | ||
| 37278 | sqlite3_file *pProtoFile, | ||
| 37279 | const void *zBuf, | ||
| 37280 | int iAmt, | ||
| 37281 | sqlite_int64 iOfst | ||
| 37282 | ){ | ||
| 37283 | KVVfsFile *pFile = (KVVfsFile*)pProtoFile; | ||
| 37284 | unsigned int pgno; | ||
| 37285 | char zKey[30]; | ||
| 37286 | char *aData = pFile->aData; | ||
| 37287 | SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); | ||
| 37288 | assert( iAmt>=512 && iAmt<=65536 ); | ||
| 37289 | assert( (iAmt & (iAmt-1))==0 ); | ||
| 37290 | assert( pFile->szPage<0 || pFile->szPage==iAmt ); | ||
| 37291 | pFile->szPage = iAmt; | ||
| 37292 | pgno = 1 + iOfst/iAmt; | ||
| 37293 | sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); | ||
| 37294 | kvvfsEncode(zBuf, iAmt, aData); | ||
| 37295 | if( sqlite3KvvfsMethods.xWrite(pFile->zClass, zKey, aData) ){ | ||
| 37296 | return SQLITE_IOERR; | ||
| 37297 | } | ||
| 37298 | if( iOfst+iAmt > pFile->szDb ){ | ||
| 37299 | pFile->szDb = iOfst + iAmt; | ||
| 37300 | } | ||
| 37301 | return SQLITE_OK; | ||
| 37302 | } | ||
| 37303 | |||
| 37304 | /* | ||
| 37305 | ** Truncate an kvvfs-file. | ||
| 37306 | */ | ||
| 37307 | static int kvvfsTruncateJrnl(sqlite3_file *pProtoFile, sqlite_int64 size){ | ||
| 37308 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37309 | SQLITE_KV_LOG(("xTruncate('%s-journal',%lld)\n", pFile->zClass, size)); | ||
| 37310 | assert( size==0 ); | ||
| 37311 | sqlite3KvvfsMethods.xDelete(pFile->zClass, "jrnl"); | ||
| 37312 | sqlite3_free(pFile->aJrnl); | ||
| 37313 | pFile->aJrnl = 0; | ||
| 37314 | pFile->nJrnl = 0; | ||
| 37315 | return SQLITE_OK; | ||
| 37316 | } | ||
| 37317 | static int kvvfsTruncateDb(sqlite3_file *pProtoFile, sqlite_int64 size){ | ||
| 37318 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37319 | if( pFile->szDb>size | ||
| 37320 | && pFile->szPage>0 | ||
| 37321 | && (size % pFile->szPage)==0 | ||
| 37322 | ){ | ||
| 37323 | char zKey[50]; | ||
| 37324 | unsigned int pgno, pgnoMax; | ||
| 37325 | SQLITE_KV_LOG(("xTruncate('%s-db',%lld)\n", pFile->zClass, size)); | ||
| 37326 | pgno = 1 + size/pFile->szPage; | ||
| 37327 | pgnoMax = 2 + pFile->szDb/pFile->szPage; | ||
| 37328 | while( pgno<=pgnoMax ){ | ||
| 37329 | sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); | ||
| 37330 | sqlite3KvvfsMethods.xDelete(pFile->zClass, zKey); | ||
| 37331 | pgno++; | ||
| 37332 | } | ||
| 37333 | pFile->szDb = size; | ||
| 37334 | return kvvfsWriteFileSize(pFile, size) ? SQLITE_IOERR : SQLITE_OK; | ||
| 37335 | } | ||
| 37336 | return SQLITE_IOERR; | ||
| 37337 | } | ||
| 37338 | |||
| 37339 | /* | ||
| 37340 | ** Sync an kvvfs-file. | ||
| 37341 | */ | ||
| 37342 | static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){ | ||
| 37343 | int i, n; | ||
| 37344 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37345 | char *zOut; | ||
| 37346 | SQLITE_KV_LOG(("xSync('%s-journal')\n", pFile->zClass)); | ||
| 37347 | if( pFile->nJrnl<=0 ){ | ||
| 37348 | return kvvfsTruncateJrnl(pProtoFile, 0); | ||
| 37349 | } | ||
| 37350 | zOut = sqlite3_malloc64( pFile->nJrnl*2 + 50 ); | ||
| 37351 | if( zOut==0 ){ | ||
| 37352 | return SQLITE_IOERR_NOMEM; | ||
| 37353 | } | ||
| 37354 | n = pFile->nJrnl; | ||
| 37355 | i = 0; | ||
| 37356 | do{ | ||
| 37357 | zOut[i++] = 'a' + (n%26); | ||
| 37358 | n /= 26; | ||
| 37359 | }while( n>0 ); | ||
| 37360 | zOut[i++] = ' '; | ||
| 37361 | kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]); | ||
| 37362 | i = sqlite3KvvfsMethods.xWrite(pFile->zClass, "jrnl", zOut); | ||
| 37363 | sqlite3_free(zOut); | ||
| 37364 | return i ? SQLITE_IOERR : SQLITE_OK; | ||
| 37365 | } | ||
| 37366 | static int kvvfsSyncDb(sqlite3_file *pProtoFile, int flags){ | ||
| 37367 | return SQLITE_OK; | ||
| 37368 | } | ||
| 37369 | |||
| 37370 | /* | ||
| 37371 | ** Return the current file-size of an kvvfs-file. | ||
| 37372 | */ | ||
| 37373 | static int kvvfsFileSizeJrnl(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ | ||
| 37374 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37375 | SQLITE_KV_LOG(("xFileSize('%s-journal')\n", pFile->zClass)); | ||
| 37376 | *pSize = pFile->nJrnl; | ||
| 37377 | return SQLITE_OK; | ||
| 37378 | } | ||
| 37379 | static int kvvfsFileSizeDb(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ | ||
| 37380 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37381 | SQLITE_KV_LOG(("xFileSize('%s-db')\n", pFile->zClass)); | ||
| 37382 | if( pFile->szDb>=0 ){ | ||
| 37383 | *pSize = pFile->szDb; | ||
| 37384 | }else{ | ||
| 37385 | *pSize = kvvfsReadFileSize(pFile); | ||
| 37386 | } | ||
| 37387 | return SQLITE_OK; | ||
| 37388 | } | ||
| 37389 | |||
| 37390 | /* | ||
| 37391 | ** Lock an kvvfs-file. | ||
| 37392 | */ | ||
| 37393 | static int kvvfsLock(sqlite3_file *pProtoFile, int eLock){ | ||
| 37394 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37395 | assert( !pFile->isJournal ); | ||
| 37396 | SQLITE_KV_LOG(("xLock(%s,%d)\n", pFile->zClass, eLock)); | ||
| 37397 | |||
| 37398 | if( eLock!=SQLITE_LOCK_NONE ){ | ||
| 37399 | pFile->szDb = kvvfsReadFileSize(pFile); | ||
| 37400 | } | ||
| 37401 | return SQLITE_OK; | ||
| 37402 | } | ||
| 37403 | |||
| 37404 | /* | ||
| 37405 | ** Unlock an kvvfs-file. | ||
| 37406 | */ | ||
| 37407 | static int kvvfsUnlock(sqlite3_file *pProtoFile, int eLock){ | ||
| 37408 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37409 | assert( !pFile->isJournal ); | ||
| 37410 | SQLITE_KV_LOG(("xUnlock(%s,%d)\n", pFile->zClass, eLock)); | ||
| 37411 | if( eLock==SQLITE_LOCK_NONE ){ | ||
| 37412 | pFile->szDb = -1; | ||
| 37413 | } | ||
| 37414 | return SQLITE_OK; | ||
| 37415 | } | ||
| 37416 | |||
| 37417 | /* | ||
| 37418 | ** Check if another file-handle holds a RESERVED lock on an kvvfs-file. | ||
| 37419 | */ | ||
| 37420 | static int kvvfsCheckReservedLock(sqlite3_file *pProtoFile, int *pResOut){ | ||
| 37421 | SQLITE_KV_LOG(("xCheckReservedLock\n")); | ||
| 37422 | *pResOut = 0; | ||
| 37423 | return SQLITE_OK; | ||
| 37424 | } | ||
| 37425 | |||
| 37426 | /* | ||
| 37427 | ** File control method. For custom operations on an kvvfs-file. | ||
| 37428 | */ | ||
| 37429 | static int kvvfsFileControlJrnl(sqlite3_file *pProtoFile, int op, void *pArg){ | ||
| 37430 | SQLITE_KV_LOG(("xFileControl(%d) on journal\n", op)); | ||
| 37431 | return SQLITE_NOTFOUND; | ||
| 37432 | } | ||
| 37433 | static int kvvfsFileControlDb(sqlite3_file *pProtoFile, int op, void *pArg){ | ||
| 37434 | SQLITE_KV_LOG(("xFileControl(%d) on database\n", op)); | ||
| 37435 | if( op==SQLITE_FCNTL_SYNC ){ | ||
| 37436 | KVVfsFile *pFile = (KVVfsFile *)pProtoFile; | ||
| 37437 | int rc = SQLITE_OK; | ||
| 37438 | SQLITE_KV_LOG(("xSync('%s-db')\n", pFile->zClass)); | ||
| 37439 | if( pFile->szDb>0 && 0!=kvvfsWriteFileSize(pFile, pFile->szDb) ){ | ||
| 37440 | rc = SQLITE_IOERR; | ||
| 37441 | } | ||
| 37442 | return rc; | ||
| 37443 | } | ||
| 37444 | return SQLITE_NOTFOUND; | ||
| 37445 | } | ||
| 37446 | |||
| 37447 | /* | ||
| 37448 | ** Return the sector-size in bytes for an kvvfs-file. | ||
| 37449 | */ | ||
| 37450 | static int kvvfsSectorSize(sqlite3_file *pFile){ | ||
| 37451 | return 512; | ||
| 37452 | } | ||
| 37453 | |||
| 37454 | /* | ||
| 37455 | ** Return the device characteristic flags supported by an kvvfs-file. | ||
| 37456 | */ | ||
| 37457 | static int kvvfsDeviceCharacteristics(sqlite3_file *pProtoFile){ | ||
| 37458 | return 0; | ||
| 37459 | } | ||
| 37460 | |||
| 37461 | /****** sqlite3_vfs methods *************************************************/ | ||
| 37462 | |||
| 37463 | /* | ||
| 37464 | ** Open an kvvfs file handle. | ||
| 37465 | */ | ||
| 37466 | static int kvvfsOpen( | ||
| 37467 | sqlite3_vfs *pProtoVfs, | ||
| 37468 | const char *zName, | ||
| 37469 | sqlite3_file *pProtoFile, | ||
| 37470 | int flags, | ||
| 37471 | int *pOutFlags | ||
| 37472 | ){ | ||
| 37473 | KVVfsFile *pFile = (KVVfsFile*)pProtoFile; | ||
| 37474 | if( zName==0 ) zName = ""; | ||
| 37475 | SQLITE_KV_LOG(("xOpen(\"%s\")\n", zName)); | ||
| 37476 | if( strcmp(zName, "local")==0 | ||
| 37477 | || strcmp(zName, "session")==0 | ||
| 37478 | ){ | ||
| 37479 | pFile->isJournal = 0; | ||
| 37480 | pFile->base.pMethods = &kvvfs_db_io_methods; | ||
| 37481 | }else | ||
| 37482 | if( strcmp(zName, "local-journal")==0 | ||
| 37483 | || strcmp(zName, "session-journal")==0 | ||
| 37484 | ){ | ||
| 37485 | pFile->isJournal = 1; | ||
| 37486 | pFile->base.pMethods = &kvvfs_jrnl_io_methods; | ||
| 37487 | }else{ | ||
| 37488 | return SQLITE_CANTOPEN; | ||
| 37489 | } | ||
| 37490 | if( zName[0]=='s' ){ | ||
| 37491 | pFile->zClass = "session"; | ||
| 37492 | }else{ | ||
| 37493 | pFile->zClass = "local"; | ||
| 37494 | } | ||
| 37495 | pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ); | ||
| 37496 | if( pFile->aData==0 ){ | ||
| 37497 | return SQLITE_NOMEM; | ||
| 37498 | } | ||
| 37499 | pFile->aJrnl = 0; | ||
| 37500 | pFile->nJrnl = 0; | ||
| 37501 | pFile->szPage = -1; | ||
| 37502 | pFile->szDb = -1; | ||
| 37503 | return SQLITE_OK; | ||
| 37504 | } | ||
| 37505 | |||
| 37506 | /* | ||
| 37507 | ** Delete the file located at zPath. If the dirSync argument is true, | ||
| 37508 | ** ensure the file-system modifications are synced to disk before | ||
| 37509 | ** returning. | ||
| 37510 | */ | ||
| 37511 | static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ | ||
| 37512 | if( strcmp(zPath, "local-journal")==0 ){ | ||
| 37513 | sqlite3KvvfsMethods.xDelete("local", "jrnl"); | ||
| 37514 | }else | ||
| 37515 | if( strcmp(zPath, "session-journal")==0 ){ | ||
| 37516 | sqlite3KvvfsMethods.xDelete("session", "jrnl"); | ||
| 37517 | } | ||
| 37518 | return SQLITE_OK; | ||
| 37519 | } | ||
| 37520 | |||
| 37521 | /* | ||
| 37522 | ** Test for access permissions. Return true if the requested permission | ||
| 37523 | ** is available, or false otherwise. | ||
| 37524 | */ | ||
| 37525 | static int kvvfsAccess( | ||
| 37526 | sqlite3_vfs *pProtoVfs, | ||
| 37527 | const char *zPath, | ||
| 37528 | int flags, | ||
| 37529 | int *pResOut | ||
| 37530 | ){ | ||
| 37531 | SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath)); | ||
| 37532 | if( strcmp(zPath, "local-journal")==0 ){ | ||
| 37533 | *pResOut = sqlite3KvvfsMethods.xRead("local", "jrnl", 0, 0)>0; | ||
| 37534 | }else | ||
| 37535 | if( strcmp(zPath, "session-journal")==0 ){ | ||
| 37536 | *pResOut = sqlite3KvvfsMethods.xRead("session", "jrnl", 0, 0)>0; | ||
| 37537 | }else | ||
| 37538 | if( strcmp(zPath, "local")==0 ){ | ||
| 37539 | *pResOut = sqlite3KvvfsMethods.xRead("local", "sz", 0, 0)>0; | ||
| 37540 | }else | ||
| 37541 | if( strcmp(zPath, "session")==0 ){ | ||
| 37542 | *pResOut = sqlite3KvvfsMethods.xRead("session", "sz", 0, 0)>0; | ||
| 37543 | }else | ||
| 37544 | { | ||
| 37545 | *pResOut = 0; | ||
| 37546 | } | ||
| 37547 | SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut)); | ||
| 37548 | return SQLITE_OK; | ||
| 37549 | } | ||
| 37550 | |||
| 37551 | /* | ||
| 37552 | ** Populate buffer zOut with the full canonical pathname corresponding | ||
| 37553 | ** to the pathname in zPath. zOut is guaranteed to point to a buffer | ||
| 37554 | ** of at least (INST_MAX_PATHNAME+1) bytes. | ||
| 37555 | */ | ||
| 37556 | static int kvvfsFullPathname( | ||
| 37557 | sqlite3_vfs *pVfs, | ||
| 37558 | const char *zPath, | ||
| 37559 | int nOut, | ||
| 37560 | char *zOut | ||
| 37561 | ){ | ||
| 37562 | size_t nPath; | ||
| 37563 | #ifdef SQLITE_OS_KV_ALWAYS_LOCAL | ||
| 37564 | zPath = "local"; | ||
| 37565 | #endif | ||
| 37566 | nPath = strlen(zPath); | ||
| 37567 | SQLITE_KV_LOG(("xFullPathname(\"%s\")\n", zPath)); | ||
| 37568 | if( nOut<nPath+1 ) nPath = nOut - 1; | ||
| 37569 | memcpy(zOut, zPath, nPath); | ||
| 37570 | zOut[nPath] = 0; | ||
| 37571 | return SQLITE_OK; | ||
| 37572 | } | ||
| 37573 | |||
| 37574 | /* | ||
| 37575 | ** Open the dynamic library located at zPath and return a handle. | ||
| 37576 | */ | ||
| 37577 | static void *kvvfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ | ||
| 37578 | return 0; | ||
| 37579 | } | ||
| 37580 | |||
| 37581 | /* | ||
| 37582 | ** Populate the buffer pointed to by zBufOut with nByte bytes of | ||
| 37583 | ** random data. | ||
| 37584 | */ | ||
| 37585 | static int kvvfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | ||
| 37586 | memset(zBufOut, 0, nByte); | ||
| 37587 | return nByte; | ||
| 37588 | } | ||
| 37589 | |||
| 37590 | /* | ||
| 37591 | ** Sleep for nMicro microseconds. Return the number of microseconds | ||
| 37592 | ** actually slept. | ||
| 37593 | */ | ||
| 37594 | static int kvvfsSleep(sqlite3_vfs *pVfs, int nMicro){ | ||
| 37595 | return SQLITE_OK; | ||
| 37596 | } | ||
| 37597 | |||
| 37598 | /* | ||
| 37599 | ** Return the current time as a Julian Day number in *pTimeOut. | ||
| 37600 | */ | ||
| 37601 | static int kvvfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ | ||
| 37602 | sqlite3_int64 i = 0; | ||
| 37603 | int rc; | ||
| 37604 | rc = kvvfsCurrentTimeInt64(0, &i); | ||
| 37605 | *pTimeOut = i/86400000.0; | ||
| 37606 | return rc; | ||
| 37607 | } | ||
| 37608 | #include <sys/time.h> | ||
| 37609 | static int kvvfsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ | ||
| 37610 | static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; | ||
| 37611 | struct timeval sNow; | ||
| 37612 | (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ | ||
| 37613 | *pTimeOut = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; | ||
| 37614 | return SQLITE_OK; | ||
| 37615 | } | ||
| 37616 | #endif /* SQLITE_OS_KV || SQLITE_OS_UNIX */ | ||
| 37617 | |||
| 37618 | #if SQLITE_OS_KV | ||
| 37619 | /* | ||
| 37620 | ** This routine is called initialize the KV-vfs as the default VFS. | ||
| 37621 | */ | ||
| 37622 | SQLITE_API int sqlite3_os_init(void){ | ||
| 37623 | return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 1); | ||
| 37624 | } | ||
| 37625 | SQLITE_API int sqlite3_os_end(void){ | ||
| 37626 | return SQLITE_OK; | ||
| 37627 | } | ||
| 37628 | #endif /* SQLITE_OS_KV */ | ||
| 37629 | |||
| 37630 | #if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) | ||
| 37631 | SQLITE_PRIVATE int sqlite3KvvfsInit(void){ | ||
| 37632 | return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 0); | ||
| 37633 | } | ||
| 37634 | #endif | ||
| 37635 | |||
| 37636 | /************** End of os_kv.c ***********************************************/ | ||
| 35475 | /************** Begin file os_unix.c *****************************************/ | 37637 | /************** Begin file os_unix.c *****************************************/ |
| 35476 | /* | 37638 | /* |
| 35477 | ** 2004 May 22 | 37639 | ** 2004 May 22 |
| @@ -35497,7 +37659,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 35497 | ** This source file is organized into divisions where the logic for various | 37659 | ** This source file is organized into divisions where the logic for various |
| 35498 | ** subfunctions is contained within the appropriate division. PLEASE | 37660 | ** subfunctions is contained within the appropriate division. PLEASE |
| 35499 | ** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed | 37661 | ** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed |
| 35500 | ** in the correct division and should be clearly labeled. | 37662 | ** in the correct division and should be clearly labelled. |
| 35501 | ** | 37663 | ** |
| 35502 | ** The layout of divisions is as follows: | 37664 | ** The layout of divisions is as follows: |
| 35503 | ** | 37665 | ** |
| @@ -35547,7 +37709,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 35547 | #endif | 37709 | #endif |
| 35548 | 37710 | ||
| 35549 | /* Use pread() and pwrite() if they are available */ | 37711 | /* Use pread() and pwrite() if they are available */ |
| 35550 | #if defined(__APPLE__) | 37712 | #if defined(__APPLE__) || defined(__linux__) |
| 35551 | # define HAVE_PREAD 1 | 37713 | # define HAVE_PREAD 1 |
| 35552 | # define HAVE_PWRITE 1 | 37714 | # define HAVE_PWRITE 1 |
| 35553 | #endif | 37715 | #endif |
| @@ -35562,15 +37724,16 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 35562 | /* | 37724 | /* |
| 35563 | ** standard include files. | 37725 | ** standard include files. |
| 35564 | */ | 37726 | */ |
| 35565 | #include <sys/types.h> | 37727 | #include <sys/types.h> /* amalgamator: keep */ |
| 35566 | #include <sys/stat.h> | 37728 | #include <sys/stat.h> /* amalgamator: keep */ |
| 35567 | #include <fcntl.h> | 37729 | #include <fcntl.h> |
| 35568 | #include <sys/ioctl.h> | 37730 | #include <sys/ioctl.h> |
| 35569 | #include <unistd.h> | 37731 | #include <unistd.h> /* amalgamator: keep */ |
| 35570 | /* #include <time.h> */ | 37732 | /* #include <time.h> */ |
| 35571 | #include <sys/time.h> | 37733 | #include <sys/time.h> /* amalgamator: keep */ |
| 35572 | #include <errno.h> | 37734 | #include <errno.h> |
| 35573 | #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 | 37735 | #if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ |
| 37736 | && !defined(SQLITE_WASI) | ||
| 35574 | # include <sys/mman.h> | 37737 | # include <sys/mman.h> |
| 35575 | #endif | 37738 | #endif |
| 35576 | 37739 | ||
| @@ -35658,9 +37821,46 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ | |||
| 35658 | */ | 37821 | */ |
| 35659 | #define SQLITE_MAX_SYMLINKS 100 | 37822 | #define SQLITE_MAX_SYMLINKS 100 |
| 35660 | 37823 | ||
| 37824 | /* | ||
| 37825 | ** Remove and stub certain info for WASI (WebAssembly System | ||
| 37826 | ** Interface) builds. | ||
| 37827 | */ | ||
| 37828 | #ifdef SQLITE_WASI | ||
| 37829 | # undef HAVE_FCHMOD | ||
| 37830 | # undef HAVE_FCHOWN | ||
| 37831 | # undef HAVE_MREMAP | ||
| 37832 | # define HAVE_MREMAP 0 | ||
| 37833 | # ifndef SQLITE_DEFAULT_UNIX_VFS | ||
| 37834 | # define SQLITE_DEFAULT_UNIX_VFS "unix-dotfile" | ||
| 37835 | /* ^^^ should SQLITE_DEFAULT_UNIX_VFS be "unix-none"? */ | ||
| 37836 | # endif | ||
| 37837 | # ifndef F_RDLCK | ||
| 37838 | # define F_RDLCK 0 | ||
| 37839 | # define F_WRLCK 1 | ||
| 37840 | # define F_UNLCK 2 | ||
| 37841 | # if __LONG_MAX == 0x7fffffffL | ||
| 37842 | # define F_GETLK 12 | ||
| 37843 | # define F_SETLK 13 | ||
| 37844 | # define F_SETLKW 14 | ||
| 37845 | # else | ||
| 37846 | # define F_GETLK 5 | ||
| 37847 | # define F_SETLK 6 | ||
| 37848 | # define F_SETLKW 7 | ||
| 37849 | # endif | ||
| 37850 | # endif | ||
| 37851 | #else /* !SQLITE_WASI */ | ||
| 37852 | # ifndef HAVE_FCHMOD | ||
| 37853 | # define HAVE_FCHMOD | ||
| 37854 | # endif | ||
| 37855 | #endif /* SQLITE_WASI */ | ||
| 37856 | |||
| 37857 | #ifdef SQLITE_WASI | ||
| 37858 | # define osGetpid(X) (pid_t)1 | ||
| 37859 | #else | ||
| 35661 | /* Always cast the getpid() return type for compatibility with | 37860 | /* Always cast the getpid() return type for compatibility with |
| 35662 | ** kernel modules in VxWorks. */ | 37861 | ** kernel modules in VxWorks. */ |
| 35663 | #define osGetpid(X) (pid_t)getpid() | 37862 | # define osGetpid(X) (pid_t)getpid() |
| 37863 | #endif | ||
| 35664 | 37864 | ||
| 35665 | /* | 37865 | /* |
| 35666 | ** Only set the lastErrno if the error code is a real error and not | 37866 | ** Only set the lastErrno if the error code is a real error and not |
| @@ -35932,7 +38132,11 @@ static struct unix_syscall { | |||
| 35932 | #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ | 38132 | #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ |
| 35933 | aSyscall[13].pCurrent) | 38133 | aSyscall[13].pCurrent) |
| 35934 | 38134 | ||
| 38135 | #if defined(HAVE_FCHMOD) | ||
| 35935 | { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, | 38136 | { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, |
| 38137 | #else | ||
| 38138 | { "fchmod", (sqlite3_syscall_ptr)0, 0 }, | ||
| 38139 | #endif | ||
| 35936 | #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) | 38140 | #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) |
| 35937 | 38141 | ||
| 35938 | #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE | 38142 | #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE |
| @@ -35968,14 +38172,16 @@ static struct unix_syscall { | |||
| 35968 | #endif | 38172 | #endif |
| 35969 | #define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) | 38173 | #define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) |
| 35970 | 38174 | ||
| 35971 | #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 | 38175 | #if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ |
| 38176 | && !defined(SQLITE_WASI) | ||
| 35972 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, | 38177 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, |
| 35973 | #else | 38178 | #else |
| 35974 | { "mmap", (sqlite3_syscall_ptr)0, 0 }, | 38179 | { "mmap", (sqlite3_syscall_ptr)0, 0 }, |
| 35975 | #endif | 38180 | #endif |
| 35976 | #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) | 38181 | #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) |
| 35977 | 38182 | ||
| 35978 | #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 | 38183 | #if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ |
| 38184 | && !defined(SQLITE_WASI) | ||
| 35979 | { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, | 38185 | { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, |
| 35980 | #else | 38186 | #else |
| 35981 | { "munmap", (sqlite3_syscall_ptr)0, 0 }, | 38187 | { "munmap", (sqlite3_syscall_ptr)0, 0 }, |
| @@ -36040,7 +38246,7 @@ static int robustFchown(int fd, uid_t uid, gid_t gid){ | |||
| 36040 | 38246 | ||
| 36041 | /* | 38247 | /* |
| 36042 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the | 38248 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| 36043 | ** "unix" VFSes. Return SQLITE_OK opon successfully updating the | 38249 | ** "unix" VFSes. Return SQLITE_OK upon successfully updating the |
| 36044 | ** system call pointer, or SQLITE_NOTFOUND if there is no configurable | 38250 | ** system call pointer, or SQLITE_NOTFOUND if there is no configurable |
| 36045 | ** system call named zName. | 38251 | ** system call named zName. |
| 36046 | */ | 38252 | */ |
| @@ -36161,6 +38367,9 @@ static int robust_open(const char *z, int f, mode_t m){ | |||
| 36161 | break; | 38367 | break; |
| 36162 | } | 38368 | } |
| 36163 | if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; | 38369 | if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; |
| 38370 | if( (f & (O_EXCL|O_CREAT))==(O_EXCL|O_CREAT) ){ | ||
| 38371 | (void)osUnlink(z); | ||
| 38372 | } | ||
| 36164 | osClose(fd); | 38373 | osClose(fd); |
| 36165 | sqlite3_log(SQLITE_WARNING, | 38374 | sqlite3_log(SQLITE_WARNING, |
| 36166 | "attempt to open \"%s\" as file descriptor %d", z, fd); | 38375 | "attempt to open \"%s\" as file descriptor %d", z, fd); |
| @@ -36559,7 +38768,7 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ | |||
| 36559 | ** If you close a file descriptor that points to a file that has locks, | 38768 | ** If you close a file descriptor that points to a file that has locks, |
| 36560 | ** all locks on that file that are owned by the current process are | 38769 | ** all locks on that file that are owned by the current process are |
| 36561 | ** released. To work around this problem, each unixInodeInfo object | 38770 | ** released. To work around this problem, each unixInodeInfo object |
| 36562 | ** maintains a count of the number of pending locks on tha inode. | 38771 | ** maintains a count of the number of pending locks on the inode. |
| 36563 | ** When an attempt is made to close an unixFile, if there are | 38772 | ** When an attempt is made to close an unixFile, if there are |
| 36564 | ** other unixFile open on the same inode that are holding locks, the call | 38773 | ** other unixFile open on the same inode that are holding locks, the call |
| 36565 | ** to close() the file descriptor is deferred until all of the locks clear. | 38774 | ** to close() the file descriptor is deferred until all of the locks clear. |
| @@ -36573,7 +38782,7 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ | |||
| 36573 | ** not posix compliant. Under LinuxThreads, a lock created by thread | 38782 | ** not posix compliant. Under LinuxThreads, a lock created by thread |
| 36574 | ** A cannot be modified or overridden by a different thread B. | 38783 | ** A cannot be modified or overridden by a different thread B. |
| 36575 | ** Only thread A can modify the lock. Locking behavior is correct | 38784 | ** Only thread A can modify the lock. Locking behavior is correct |
| 36576 | ** if the appliation uses the newer Native Posix Thread Library (NPTL) | 38785 | ** if the application uses the newer Native Posix Thread Library (NPTL) |
| 36577 | ** on linux - with NPTL a lock created by thread A can override locks | 38786 | ** on linux - with NPTL a lock created by thread A can override locks |
| 36578 | ** in thread B. But there is no way to know at compile-time which | 38787 | ** in thread B. But there is no way to know at compile-time which |
| 36579 | ** threading library is being used. So there is no way to know at | 38788 | ** threading library is being used. So there is no way to know at |
| @@ -36775,7 +38984,7 @@ static void storeLastErrno(unixFile *pFile, int error){ | |||
| 36775 | } | 38984 | } |
| 36776 | 38985 | ||
| 36777 | /* | 38986 | /* |
| 36778 | ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. | 38987 | ** Close all file descriptors accumulated in the unixInodeInfo->pUnused list. |
| 36779 | */ | 38988 | */ |
| 36780 | static void closePendingFds(unixFile *pFile){ | 38989 | static void closePendingFds(unixFile *pFile){ |
| 36781 | unixInodeInfo *pInode = pFile->pInode; | 38990 | unixInodeInfo *pInode = pFile->pInode; |
| @@ -37123,7 +39332,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ | |||
| 37123 | ** | 39332 | ** |
| 37124 | ** UNLOCKED -> SHARED | 39333 | ** UNLOCKED -> SHARED |
| 37125 | ** SHARED -> RESERVED | 39334 | ** SHARED -> RESERVED |
| 37126 | ** SHARED -> (PENDING) -> EXCLUSIVE | 39335 | ** SHARED -> EXCLUSIVE |
| 37127 | ** RESERVED -> (PENDING) -> EXCLUSIVE | 39336 | ** RESERVED -> (PENDING) -> EXCLUSIVE |
| 37128 | ** PENDING -> EXCLUSIVE | 39337 | ** PENDING -> EXCLUSIVE |
| 37129 | ** | 39338 | ** |
| @@ -37138,7 +39347,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ | |||
| 37138 | ** slightly in order to be compatible with Windows95 systems simultaneously | 39347 | ** slightly in order to be compatible with Windows95 systems simultaneously |
| 37139 | ** accessing the same database file, in case that is ever required. | 39348 | ** accessing the same database file, in case that is ever required. |
| 37140 | ** | 39349 | ** |
| 37141 | ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved | 39350 | ** Symbols defined in os.h identify the 'pending byte' and the 'reserved |
| 37142 | ** byte', each single bytes at well known offsets, and the 'shared byte | 39351 | ** byte', each single bytes at well known offsets, and the 'shared byte |
| 37143 | ** range', a range of 510 bytes at a well known offset. | 39352 | ** range', a range of 510 bytes at a well known offset. |
| 37144 | ** | 39353 | ** |
| @@ -37146,7 +39355,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ | |||
| 37146 | ** byte'. If this is successful, 'shared byte range' is read-locked | 39355 | ** byte'. If this is successful, 'shared byte range' is read-locked |
| 37147 | ** and the lock on the 'pending byte' released. (Legacy note: When | 39356 | ** and the lock on the 'pending byte' released. (Legacy note: When |
| 37148 | ** SQLite was first developed, Windows95 systems were still very common, | 39357 | ** SQLite was first developed, Windows95 systems were still very common, |
| 37149 | ** and Widnows95 lacks a shared-lock capability. So on Windows95, a | 39358 | ** and Windows95 lacks a shared-lock capability. So on Windows95, a |
| 37150 | ** single randomly selected by from the 'shared byte range' is locked. | 39359 | ** single randomly selected by from the 'shared byte range' is locked. |
| 37151 | ** Windows95 is now pretty much extinct, but this work-around for the | 39360 | ** Windows95 is now pretty much extinct, but this work-around for the |
| 37152 | ** lack of shared-locks on Windows95 lives on, for backwards | 39361 | ** lack of shared-locks on Windows95 lives on, for backwards |
| @@ -37156,19 +39365,20 @@ static int unixLock(sqlite3_file *id, int eFileLock){ | |||
| 37156 | ** A RESERVED lock is implemented by grabbing a write-lock on the | 39365 | ** A RESERVED lock is implemented by grabbing a write-lock on the |
| 37157 | ** 'reserved byte'. | 39366 | ** 'reserved byte'. |
| 37158 | ** | 39367 | ** |
| 37159 | ** A process may only obtain a PENDING lock after it has obtained a | 39368 | ** An EXCLUSIVE lock may only be requested after either a SHARED or |
| 37160 | ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock | 39369 | ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining |
| 37161 | ** on the 'pending byte'. This ensures that no new SHARED locks can be | 39370 | ** a write-lock on the entire 'shared byte range'. Since all other locks |
| 37162 | ** obtained, but existing SHARED locks are allowed to persist. A process | 39371 | ** require a read-lock on one of the bytes within this range, this ensures |
| 37163 | ** does not have to obtain a RESERVED lock on the way to a PENDING lock. | 39372 | ** that no other locks are held on the database. |
| 37164 | ** This property is used by the algorithm for rolling back a journal file | ||
| 37165 | ** after a crash. | ||
| 37166 | ** | 39373 | ** |
| 37167 | ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is | 39374 | ** If a process that holds a RESERVED lock requests an EXCLUSIVE, then |
| 37168 | ** implemented by obtaining a write-lock on the entire 'shared byte | 39375 | ** a PENDING lock is obtained first. A PENDING lock is implemented by |
| 37169 | ** range'. Since all other locks require a read-lock on one of the bytes | 39376 | ** obtaining a write-lock on the 'pending byte'. This ensures that no new |
| 37170 | ** within this range, this ensures that no other locks are held on the | 39377 | ** SHARED locks can be obtained, but existing SHARED locks are allowed to |
| 37171 | ** database. | 39378 | ** persist. If the call to this function fails to obtain the EXCLUSIVE |
| 39379 | ** lock in this case, it holds the PENDING lock instead. The client may | ||
| 39380 | ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED | ||
| 39381 | ** locks have cleared. | ||
| 37172 | */ | 39382 | */ |
| 37173 | int rc = SQLITE_OK; | 39383 | int rc = SQLITE_OK; |
| 37174 | unixFile *pFile = (unixFile*)id; | 39384 | unixFile *pFile = (unixFile*)id; |
| @@ -37194,7 +39404,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ | |||
| 37194 | 39404 | ||
| 37195 | /* Make sure the locking sequence is correct. | 39405 | /* Make sure the locking sequence is correct. |
| 37196 | ** (1) We never move from unlocked to anything higher than shared lock. | 39406 | ** (1) We never move from unlocked to anything higher than shared lock. |
| 37197 | ** (2) SQLite never explicitly requests a pendig lock. | 39407 | ** (2) SQLite never explicitly requests a pending lock. |
| 37198 | ** (3) A shared lock is always held when a reserve lock is requested. | 39408 | ** (3) A shared lock is always held when a reserve lock is requested. |
| 37199 | */ | 39409 | */ |
| 37200 | assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); | 39410 | assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); |
| @@ -37239,7 +39449,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ | |||
| 37239 | lock.l_len = 1L; | 39449 | lock.l_len = 1L; |
| 37240 | lock.l_whence = SEEK_SET; | 39450 | lock.l_whence = SEEK_SET; |
| 37241 | if( eFileLock==SHARED_LOCK | 39451 | if( eFileLock==SHARED_LOCK |
| 37242 | || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK) | 39452 | || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock==RESERVED_LOCK) |
| 37243 | ){ | 39453 | ){ |
| 37244 | lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); | 39454 | lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); |
| 37245 | lock.l_start = PENDING_BYTE; | 39455 | lock.l_start = PENDING_BYTE; |
| @@ -37250,6 +39460,9 @@ static int unixLock(sqlite3_file *id, int eFileLock){ | |||
| 37250 | storeLastErrno(pFile, tErrno); | 39460 | storeLastErrno(pFile, tErrno); |
| 37251 | } | 39461 | } |
| 37252 | goto end_lock; | 39462 | goto end_lock; |
| 39463 | }else if( eFileLock==EXCLUSIVE_LOCK ){ | ||
| 39464 | pFile->eFileLock = PENDING_LOCK; | ||
| 39465 | pInode->eFileLock = PENDING_LOCK; | ||
| 37253 | } | 39466 | } |
| 37254 | } | 39467 | } |
| 37255 | 39468 | ||
| @@ -37337,13 +39550,9 @@ static int unixLock(sqlite3_file *id, int eFileLock){ | |||
| 37337 | } | 39550 | } |
| 37338 | #endif | 39551 | #endif |
| 37339 | 39552 | ||
| 37340 | |||
| 37341 | if( rc==SQLITE_OK ){ | 39553 | if( rc==SQLITE_OK ){ |
| 37342 | pFile->eFileLock = eFileLock; | 39554 | pFile->eFileLock = eFileLock; |
| 37343 | pInode->eFileLock = eFileLock; | 39555 | pInode->eFileLock = eFileLock; |
| 37344 | }else if( eFileLock==EXCLUSIVE_LOCK ){ | ||
| 37345 | pFile->eFileLock = PENDING_LOCK; | ||
| 37346 | pInode->eFileLock = PENDING_LOCK; | ||
| 37347 | } | 39556 | } |
| 37348 | 39557 | ||
| 37349 | end_lock: | 39558 | end_lock: |
| @@ -38413,7 +40622,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ | |||
| 38413 | 40622 | ||
| 38414 | /* Make sure the locking sequence is correct | 40623 | /* Make sure the locking sequence is correct |
| 38415 | ** (1) We never move from unlocked to anything higher than shared lock. | 40624 | ** (1) We never move from unlocked to anything higher than shared lock. |
| 38416 | ** (2) SQLite never explicitly requests a pendig lock. | 40625 | ** (2) SQLite never explicitly requests a pending lock. |
| 38417 | ** (3) A shared lock is always held when a reserve lock is requested. | 40626 | ** (3) A shared lock is always held when a reserve lock is requested. |
| 38418 | */ | 40627 | */ |
| 38419 | assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); | 40628 | assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); |
| @@ -38529,7 +40738,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ | |||
| 38529 | if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + | 40738 | if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + |
| 38530 | pInode->sharedByte, 1, 0)) ){ | 40739 | pInode->sharedByte, 1, 0)) ){ |
| 38531 | int failed2 = SQLITE_OK; | 40740 | int failed2 = SQLITE_OK; |
| 38532 | /* now attemmpt to get the exclusive lock range */ | 40741 | /* now attempt to get the exclusive lock range */ |
| 38533 | failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, | 40742 | failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, |
| 38534 | SHARED_SIZE, 1); | 40743 | SHARED_SIZE, 1); |
| 38535 | if( failed && (failed2 = afpSetLock(context->dbPath, pFile, | 40744 | if( failed && (failed2 = afpSetLock(context->dbPath, pFile, |
| @@ -38750,12 +40959,6 @@ static int nfsUnlock(sqlite3_file *id, int eFileLock){ | |||
| 38750 | ** Seek to the offset passed as the second argument, then read cnt | 40959 | ** Seek to the offset passed as the second argument, then read cnt |
| 38751 | ** bytes into pBuf. Return the number of bytes actually read. | 40960 | ** bytes into pBuf. Return the number of bytes actually read. |
| 38752 | ** | 40961 | ** |
| 38753 | ** NB: If you define USE_PREAD or USE_PREAD64, then it might also | ||
| 38754 | ** be necessary to define _XOPEN_SOURCE to be 500. This varies from | ||
| 38755 | ** one system to another. Since SQLite does not define USE_PREAD | ||
| 38756 | ** in any form by default, we will not attempt to define _XOPEN_SOURCE. | ||
| 38757 | ** See tickets #2741 and #2681. | ||
| 38758 | ** | ||
| 38759 | ** To avoid stomping the errno value on a failed read the lastErrno value | 40962 | ** To avoid stomping the errno value on a failed read the lastErrno value |
| 38760 | ** is set before returning. | 40963 | ** is set before returning. |
| 38761 | */ | 40964 | */ |
| @@ -38830,7 +41033,7 @@ static int unixRead( | |||
| 38830 | #endif | 41033 | #endif |
| 38831 | 41034 | ||
| 38832 | #if SQLITE_MAX_MMAP_SIZE>0 | 41035 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 38833 | /* Deal with as much of this read request as possible by transfering | 41036 | /* Deal with as much of this read request as possible by transferring |
| 38834 | ** data from the memory mapping using memcpy(). */ | 41037 | ** data from the memory mapping using memcpy(). */ |
| 38835 | if( offset<pFile->mmapSize ){ | 41038 | if( offset<pFile->mmapSize ){ |
| 38836 | if( offset+amt <= pFile->mmapSize ){ | 41039 | if( offset+amt <= pFile->mmapSize ){ |
| @@ -38982,7 +41185,7 @@ static int unixWrite( | |||
| 38982 | #endif | 41185 | #endif |
| 38983 | 41186 | ||
| 38984 | #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 | 41187 | #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 |
| 38985 | /* Deal with as much of this write request as possible by transfering | 41188 | /* Deal with as much of this write request as possible by transferring |
| 38986 | ** data from the memory mapping using memcpy(). */ | 41189 | ** data from the memory mapping using memcpy(). */ |
| 38987 | if( offset<pFile->mmapSize ){ | 41190 | if( offset<pFile->mmapSize ){ |
| 38988 | if( offset+amt <= pFile->mmapSize ){ | 41191 | if( offset+amt <= pFile->mmapSize ){ |
| @@ -39104,7 +41307,7 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ | |||
| 39104 | /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a | 41307 | /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a |
| 39105 | ** no-op. But go ahead and call fstat() to validate the file | 41308 | ** no-op. But go ahead and call fstat() to validate the file |
| 39106 | ** descriptor as we need a method to provoke a failure during | 41309 | ** descriptor as we need a method to provoke a failure during |
| 39107 | ** coverate testing. | 41310 | ** coverage testing. |
| 39108 | */ | 41311 | */ |
| 39109 | #ifdef SQLITE_NO_SYNC | 41312 | #ifdef SQLITE_NO_SYNC |
| 39110 | { | 41313 | { |
| @@ -41934,12 +44137,10 @@ static void appendOnePathElement( | |||
| 41934 | if( zName[0]=='.' ){ | 44137 | if( zName[0]=='.' ){ |
| 41935 | if( nName==1 ) return; | 44138 | if( nName==1 ) return; |
| 41936 | if( zName[1]=='.' && nName==2 ){ | 44139 | if( zName[1]=='.' && nName==2 ){ |
| 41937 | if( pPath->nUsed<=1 ){ | 44140 | if( pPath->nUsed>1 ){ |
| 41938 | pPath->rc = SQLITE_ERROR; | 44141 | assert( pPath->zOut[0]=='/' ); |
| 41939 | return; | 44142 | while( pPath->zOut[--pPath->nUsed]!='/' ){} |
| 41940 | } | 44143 | } |
| 41941 | assert( pPath->zOut[0]=='/' ); | ||
| 41942 | while( pPath->zOut[--pPath->nUsed]!='/' ){} | ||
| 41943 | return; | 44144 | return; |
| 41944 | } | 44145 | } |
| 41945 | } | 44146 | } |
| @@ -42151,12 +44352,17 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ | |||
| 42151 | ** than the argument. | 44352 | ** than the argument. |
| 42152 | */ | 44353 | */ |
| 42153 | static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ | 44354 | static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ |
| 42154 | #if OS_VXWORKS | 44355 | #if !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP+0 |
| 42155 | struct timespec sp; | 44356 | struct timespec sp; |
| 42156 | |||
| 42157 | sp.tv_sec = microseconds / 1000000; | 44357 | sp.tv_sec = microseconds / 1000000; |
| 42158 | sp.tv_nsec = (microseconds % 1000000) * 1000; | 44358 | sp.tv_nsec = (microseconds % 1000000) * 1000; |
| 44359 | |||
| 44360 | /* Almost all modern unix systems support nanosleep(). But if you are | ||
| 44361 | ** compiling for one of the rare exceptions, you can use | ||
| 44362 | ** -DHAVE_NANOSLEEP=0 (perhaps in conjuction with -DHAVE_USLEEP if | ||
| 44363 | ** usleep() is available) in order to bypass the use of nanosleep() */ | ||
| 42159 | nanosleep(&sp, NULL); | 44364 | nanosleep(&sp, NULL); |
| 44365 | |||
| 42160 | UNUSED_PARAMETER(NotUsed); | 44366 | UNUSED_PARAMETER(NotUsed); |
| 42161 | return microseconds; | 44367 | return microseconds; |
| 42162 | #elif defined(HAVE_USLEEP) && HAVE_USLEEP | 44368 | #elif defined(HAVE_USLEEP) && HAVE_USLEEP |
| @@ -43533,8 +45739,16 @@ SQLITE_API int sqlite3_os_init(void){ | |||
| 43533 | 45739 | ||
| 43534 | /* Register all VFSes defined in the aVfs[] array */ | 45740 | /* Register all VFSes defined in the aVfs[] array */ |
| 43535 | for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ | 45741 | for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ |
| 45742 | #ifdef SQLITE_DEFAULT_UNIX_VFS | ||
| 45743 | sqlite3_vfs_register(&aVfs[i], | ||
| 45744 | 0==strcmp(aVfs[i].zName,SQLITE_DEFAULT_UNIX_VFS)); | ||
| 45745 | #else | ||
| 43536 | sqlite3_vfs_register(&aVfs[i], i==0); | 45746 | sqlite3_vfs_register(&aVfs[i], i==0); |
| 45747 | #endif | ||
| 43537 | } | 45748 | } |
| 45749 | #ifdef SQLITE_OS_KV_OPTIONAL | ||
| 45750 | sqlite3KvvfsInit(); | ||
| 45751 | #endif | ||
| 43538 | unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); | 45752 | unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); |
| 43539 | 45753 | ||
| 43540 | #ifndef SQLITE_OMIT_WAL | 45754 | #ifndef SQLITE_OMIT_WAL |
| @@ -44738,7 +46952,7 @@ static struct win_syscall { | |||
| 44738 | 46952 | ||
| 44739 | /* | 46953 | /* |
| 44740 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the | 46954 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| 44741 | ** "win32" VFSes. Return SQLITE_OK opon successfully updating the | 46955 | ** "win32" VFSes. Return SQLITE_OK upon successfully updating the |
| 44742 | ** system call pointer, or SQLITE_NOTFOUND if there is no configurable | 46956 | ** system call pointer, or SQLITE_NOTFOUND if there is no configurable |
| 44743 | ** system call named zName. | 46957 | ** system call named zName. |
| 44744 | */ | 46958 | */ |
| @@ -45497,8 +47711,9 @@ SQLITE_API int sqlite3_win32_set_directory8( | |||
| 45497 | const char *zValue /* New value for directory being set or reset */ | 47711 | const char *zValue /* New value for directory being set or reset */ |
| 45498 | ){ | 47712 | ){ |
| 45499 | char **ppDirectory = 0; | 47713 | char **ppDirectory = 0; |
| 47714 | int rc; | ||
| 45500 | #ifndef SQLITE_OMIT_AUTOINIT | 47715 | #ifndef SQLITE_OMIT_AUTOINIT |
| 45501 | int rc = sqlite3_initialize(); | 47716 | rc = sqlite3_initialize(); |
| 45502 | if( rc ) return rc; | 47717 | if( rc ) return rc; |
| 45503 | #endif | 47718 | #endif |
| 45504 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); | 47719 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); |
| @@ -46317,7 +48532,7 @@ static int winRead( | |||
| 46317 | pFile->h, pBuf, amt, offset, pFile->locktype)); | 48532 | pFile->h, pBuf, amt, offset, pFile->locktype)); |
| 46318 | 48533 | ||
| 46319 | #if SQLITE_MAX_MMAP_SIZE>0 | 48534 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 46320 | /* Deal with as much of this read request as possible by transfering | 48535 | /* Deal with as much of this read request as possible by transferring |
| 46321 | ** data from the memory mapping using memcpy(). */ | 48536 | ** data from the memory mapping using memcpy(). */ |
| 46322 | if( offset<pFile->mmapSize ){ | 48537 | if( offset<pFile->mmapSize ){ |
| 46323 | if( offset+amt <= pFile->mmapSize ){ | 48538 | if( offset+amt <= pFile->mmapSize ){ |
| @@ -46395,7 +48610,7 @@ static int winWrite( | |||
| 46395 | pFile->h, pBuf, amt, offset, pFile->locktype)); | 48610 | pFile->h, pBuf, amt, offset, pFile->locktype)); |
| 46396 | 48611 | ||
| 46397 | #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 | 48612 | #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 |
| 46398 | /* Deal with as much of this write request as possible by transfering | 48613 | /* Deal with as much of this write request as possible by transferring |
| 46399 | ** data from the memory mapping using memcpy(). */ | 48614 | ** data from the memory mapping using memcpy(). */ |
| 46400 | if( offset<pFile->mmapSize ){ | 48615 | if( offset<pFile->mmapSize ){ |
| 46401 | if( offset+amt <= pFile->mmapSize ){ | 48616 | if( offset+amt <= pFile->mmapSize ){ |
| @@ -46505,7 +48720,7 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ | |||
| 46505 | ** all references to memory-mapped content are closed. That is doable, | 48720 | ** all references to memory-mapped content are closed. That is doable, |
| 46506 | ** but involves adding a few branches in the common write code path which | 48721 | ** but involves adding a few branches in the common write code path which |
| 46507 | ** could slow down normal operations slightly. Hence, we have decided for | 48722 | ** could slow down normal operations slightly. Hence, we have decided for |
| 46508 | ** now to simply make trancations a no-op if there are pending reads. We | 48723 | ** now to simply make transactions a no-op if there are pending reads. We |
| 46509 | ** can maybe revisit this decision in the future. | 48724 | ** can maybe revisit this decision in the future. |
| 46510 | */ | 48725 | */ |
| 46511 | return SQLITE_OK; | 48726 | return SQLITE_OK; |
| @@ -46564,7 +48779,7 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ | |||
| 46564 | #ifdef SQLITE_TEST | 48779 | #ifdef SQLITE_TEST |
| 46565 | /* | 48780 | /* |
| 46566 | ** Count the number of fullsyncs and normal syncs. This is used to test | 48781 | ** Count the number of fullsyncs and normal syncs. This is used to test |
| 46567 | ** that syncs and fullsyncs are occuring at the right times. | 48782 | ** that syncs and fullsyncs are occurring at the right times. |
| 46568 | */ | 48783 | */ |
| 46569 | SQLITE_API int sqlite3_sync_count = 0; | 48784 | SQLITE_API int sqlite3_sync_count = 0; |
| 46570 | SQLITE_API int sqlite3_fullsync_count = 0; | 48785 | SQLITE_API int sqlite3_fullsync_count = 0; |
| @@ -46921,7 +49136,7 @@ static int winLock(sqlite3_file *id, int locktype){ | |||
| 46921 | */ | 49136 | */ |
| 46922 | if( locktype==EXCLUSIVE_LOCK && res ){ | 49137 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 46923 | assert( pFile->locktype>=SHARED_LOCK ); | 49138 | assert( pFile->locktype>=SHARED_LOCK ); |
| 46924 | res = winUnlockReadLock(pFile); | 49139 | (void)winUnlockReadLock(pFile); |
| 46925 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, | 49140 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 46926 | SHARED_SIZE, 0); | 49141 | SHARED_SIZE, 0); |
| 46927 | if( res ){ | 49142 | if( res ){ |
| @@ -48303,9 +50518,10 @@ static int winMakeEndInDirSep(int nBuf, char *zBuf){ | |||
| 48303 | } | 50518 | } |
| 48304 | 50519 | ||
| 48305 | /* | 50520 | /* |
| 48306 | ** If sqlite3_temp_directory is not, take the mutex and return true. | 50521 | ** If sqlite3_temp_directory is defined, take the mutex and return true. |
| 48307 | ** | 50522 | ** |
| 48308 | ** If sqlite3_temp_directory is NULL, omit the mutex and return false. | 50523 | ** If sqlite3_temp_directory is NULL (undefined), omit the mutex and |
| 50524 | ** return false. | ||
| 48309 | */ | 50525 | */ |
| 48310 | static int winTempDirDefined(void){ | 50526 | static int winTempDirDefined(void){ |
| 48311 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); | 50527 | sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); |
| @@ -48324,6 +50540,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ | |||
| 48324 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | 50540 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 48325 | "0123456789"; | 50541 | "0123456789"; |
| 48326 | size_t i, j; | 50542 | size_t i, j; |
| 50543 | DWORD pid; | ||
| 48327 | int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); | 50544 | int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); |
| 48328 | int nMax, nBuf, nDir, nLen; | 50545 | int nMax, nBuf, nDir, nLen; |
| 48329 | char *zBuf; | 50546 | char *zBuf; |
| @@ -48536,7 +50753,10 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ | |||
| 48536 | 50753 | ||
| 48537 | j = sqlite3Strlen30(zBuf); | 50754 | j = sqlite3Strlen30(zBuf); |
| 48538 | sqlite3_randomness(15, &zBuf[j]); | 50755 | sqlite3_randomness(15, &zBuf[j]); |
| 50756 | pid = osGetCurrentProcessId(); | ||
| 48539 | for(i=0; i<15; i++, j++){ | 50757 | for(i=0; i<15; i++, j++){ |
| 50758 | zBuf[j] += pid & 0xff; | ||
| 50759 | pid >>= 8; | ||
| 48540 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; | 50760 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 48541 | } | 50761 | } |
| 48542 | zBuf[j] = 0; | 50762 | zBuf[j] = 0; |
| @@ -48774,7 +50994,7 @@ static int winOpen( | |||
| 48774 | if( isReadWrite ){ | 50994 | if( isReadWrite ){ |
| 48775 | int rc2, isRO = 0; | 50995 | int rc2, isRO = 0; |
| 48776 | sqlite3BeginBenignMalloc(); | 50996 | sqlite3BeginBenignMalloc(); |
| 48777 | rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); | 50997 | rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); |
| 48778 | sqlite3EndBenignMalloc(); | 50998 | sqlite3EndBenignMalloc(); |
| 48779 | if( rc2==SQLITE_OK && isRO ) break; | 50999 | if( rc2==SQLITE_OK && isRO ) break; |
| 48780 | } | 51000 | } |
| @@ -48791,7 +51011,7 @@ static int winOpen( | |||
| 48791 | if( isReadWrite ){ | 51011 | if( isReadWrite ){ |
| 48792 | int rc2, isRO = 0; | 51012 | int rc2, isRO = 0; |
| 48793 | sqlite3BeginBenignMalloc(); | 51013 | sqlite3BeginBenignMalloc(); |
| 48794 | rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); | 51014 | rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); |
| 48795 | sqlite3EndBenignMalloc(); | 51015 | sqlite3EndBenignMalloc(); |
| 48796 | if( rc2==SQLITE_OK && isRO ) break; | 51016 | if( rc2==SQLITE_OK && isRO ) break; |
| 48797 | } | 51017 | } |
| @@ -48811,7 +51031,7 @@ static int winOpen( | |||
| 48811 | if( isReadWrite ){ | 51031 | if( isReadWrite ){ |
| 48812 | int rc2, isRO = 0; | 51032 | int rc2, isRO = 0; |
| 48813 | sqlite3BeginBenignMalloc(); | 51033 | sqlite3BeginBenignMalloc(); |
| 48814 | rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); | 51034 | rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); |
| 48815 | sqlite3EndBenignMalloc(); | 51035 | sqlite3EndBenignMalloc(); |
| 48816 | if( rc2==SQLITE_OK && isRO ) break; | 51036 | if( rc2==SQLITE_OK && isRO ) break; |
| 48817 | } | 51037 | } |
| @@ -49034,6 +51254,13 @@ static int winAccess( | |||
| 49034 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", | 51254 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 49035 | zFilename, flags, pResOut)); | 51255 | zFilename, flags, pResOut)); |
| 49036 | 51256 | ||
| 51257 | if( zFilename==0 ){ | ||
| 51258 | *pResOut = 0; | ||
| 51259 | OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", | ||
| 51260 | zFilename, pResOut, *pResOut)); | ||
| 51261 | return SQLITE_OK; | ||
| 51262 | } | ||
| 51263 | |||
| 49037 | zConverted = winConvertFromUtf8Filename(zFilename); | 51264 | zConverted = winConvertFromUtf8Filename(zFilename); |
| 49038 | if( zConverted==0 ){ | 51265 | if( zConverted==0 ){ |
| 49039 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); | 51266 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| @@ -49341,7 +51568,8 @@ static int winFullPathname( | |||
| 49341 | char *zFull /* Output buffer */ | 51568 | char *zFull /* Output buffer */ |
| 49342 | ){ | 51569 | ){ |
| 49343 | int rc; | 51570 | int rc; |
| 49344 | sqlite3_mutex *pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); | 51571 | MUTEX_LOGIC( sqlite3_mutex *pMutex; ) |
| 51572 | MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); ) | ||
| 49345 | sqlite3_mutex_enter(pMutex); | 51573 | sqlite3_mutex_enter(pMutex); |
| 49346 | rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull); | 51574 | rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull); |
| 49347 | sqlite3_mutex_leave(pMutex); | 51575 | sqlite3_mutex_leave(pMutex); |
| @@ -49883,6 +52111,7 @@ static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); | |||
| 49883 | static int memdbSync(sqlite3_file*, int flags); | 52111 | static int memdbSync(sqlite3_file*, int flags); |
| 49884 | static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); | 52112 | static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); |
| 49885 | static int memdbLock(sqlite3_file*, int); | 52113 | static int memdbLock(sqlite3_file*, int); |
| 52114 | static int memdbUnlock(sqlite3_file*, int); | ||
| 49886 | /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ | 52115 | /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ |
| 49887 | static int memdbFileControl(sqlite3_file*, int op, void *pArg); | 52116 | static int memdbFileControl(sqlite3_file*, int op, void *pArg); |
| 49888 | /* static int memdbSectorSize(sqlite3_file*); // not used */ | 52117 | /* static int memdbSectorSize(sqlite3_file*); // not used */ |
| @@ -49941,7 +52170,7 @@ static const sqlite3_io_methods memdb_io_methods = { | |||
| 49941 | memdbSync, /* xSync */ | 52170 | memdbSync, /* xSync */ |
| 49942 | memdbFileSize, /* xFileSize */ | 52171 | memdbFileSize, /* xFileSize */ |
| 49943 | memdbLock, /* xLock */ | 52172 | memdbLock, /* xLock */ |
| 49944 | memdbLock, /* xUnlock - same as xLock in this case */ | 52173 | memdbUnlock, /* xUnlock */ |
| 49945 | 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ | 52174 | 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ |
| 49946 | memdbFileControl, /* xFileControl */ | 52175 | memdbFileControl, /* xFileControl */ |
| 49947 | 0, /* memdbSectorSize,*/ /* xSectorSize */ | 52176 | 0, /* memdbSectorSize,*/ /* xSectorSize */ |
| @@ -50142,39 +52371,81 @@ static int memdbLock(sqlite3_file *pFile, int eLock){ | |||
| 50142 | MemFile *pThis = (MemFile*)pFile; | 52371 | MemFile *pThis = (MemFile*)pFile; |
| 50143 | MemStore *p = pThis->pStore; | 52372 | MemStore *p = pThis->pStore; |
| 50144 | int rc = SQLITE_OK; | 52373 | int rc = SQLITE_OK; |
| 50145 | if( eLock==pThis->eLock ) return SQLITE_OK; | 52374 | if( eLock<=pThis->eLock ) return SQLITE_OK; |
| 50146 | memdbEnter(p); | 52375 | memdbEnter(p); |
| 50147 | if( eLock>SQLITE_LOCK_SHARED ){ | 52376 | |
| 50148 | if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){ | 52377 | assert( p->nWrLock==0 || p->nWrLock==1 ); |
| 50149 | rc = SQLITE_READONLY; | 52378 | assert( pThis->eLock<=SQLITE_LOCK_SHARED || p->nWrLock==1 ); |
| 50150 | }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){ | 52379 | assert( pThis->eLock==SQLITE_LOCK_NONE || p->nRdLock>=1 ); |
| 50151 | if( p->nWrLock ){ | 52380 | |
| 50152 | rc = SQLITE_BUSY; | 52381 | if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ |
| 50153 | }else{ | 52382 | rc = SQLITE_READONLY; |
| 50154 | p->nWrLock = 1; | 52383 | }else{ |
| 52384 | switch( eLock ){ | ||
| 52385 | case SQLITE_LOCK_SHARED: { | ||
| 52386 | assert( pThis->eLock==SQLITE_LOCK_NONE ); | ||
| 52387 | if( p->nWrLock>0 ){ | ||
| 52388 | rc = SQLITE_BUSY; | ||
| 52389 | }else{ | ||
| 52390 | p->nRdLock++; | ||
| 52391 | } | ||
| 52392 | break; | ||
| 52393 | }; | ||
| 52394 | |||
| 52395 | case SQLITE_LOCK_RESERVED: | ||
| 52396 | case SQLITE_LOCK_PENDING: { | ||
| 52397 | assert( pThis->eLock>=SQLITE_LOCK_SHARED ); | ||
| 52398 | if( ALWAYS(pThis->eLock==SQLITE_LOCK_SHARED) ){ | ||
| 52399 | if( p->nWrLock>0 ){ | ||
| 52400 | rc = SQLITE_BUSY; | ||
| 52401 | }else{ | ||
| 52402 | p->nWrLock = 1; | ||
| 52403 | } | ||
| 52404 | } | ||
| 52405 | break; | ||
| 52406 | } | ||
| 52407 | |||
| 52408 | default: { | ||
| 52409 | assert( eLock==SQLITE_LOCK_EXCLUSIVE ); | ||
| 52410 | assert( pThis->eLock>=SQLITE_LOCK_SHARED ); | ||
| 52411 | if( p->nRdLock>1 ){ | ||
| 52412 | rc = SQLITE_BUSY; | ||
| 52413 | }else if( pThis->eLock==SQLITE_LOCK_SHARED ){ | ||
| 52414 | p->nWrLock = 1; | ||
| 52415 | } | ||
| 52416 | break; | ||
| 50155 | } | 52417 | } |
| 50156 | } | 52418 | } |
| 50157 | }else if( eLock==SQLITE_LOCK_SHARED ){ | 52419 | } |
| 50158 | if( pThis->eLock > SQLITE_LOCK_SHARED ){ | 52420 | if( rc==SQLITE_OK ) pThis->eLock = eLock; |
| 50159 | assert( p->nWrLock==1 ); | 52421 | memdbLeave(p); |
| 50160 | p->nWrLock = 0; | 52422 | return rc; |
| 50161 | }else if( p->nWrLock ){ | 52423 | } |
| 50162 | rc = SQLITE_BUSY; | 52424 | |
| 50163 | }else{ | 52425 | /* |
| 50164 | p->nRdLock++; | 52426 | ** Unlock an memdb-file. |
| 52427 | */ | ||
| 52428 | static int memdbUnlock(sqlite3_file *pFile, int eLock){ | ||
| 52429 | MemFile *pThis = (MemFile*)pFile; | ||
| 52430 | MemStore *p = pThis->pStore; | ||
| 52431 | if( eLock>=pThis->eLock ) return SQLITE_OK; | ||
| 52432 | memdbEnter(p); | ||
| 52433 | |||
| 52434 | assert( eLock==SQLITE_LOCK_SHARED || eLock==SQLITE_LOCK_NONE ); | ||
| 52435 | if( eLock==SQLITE_LOCK_SHARED ){ | ||
| 52436 | if( ALWAYS(pThis->eLock>SQLITE_LOCK_SHARED) ){ | ||
| 52437 | p->nWrLock--; | ||
| 50165 | } | 52438 | } |
| 50166 | }else{ | 52439 | }else{ |
| 50167 | assert( eLock==SQLITE_LOCK_NONE ); | ||
| 50168 | if( pThis->eLock>SQLITE_LOCK_SHARED ){ | 52440 | if( pThis->eLock>SQLITE_LOCK_SHARED ){ |
| 50169 | assert( p->nWrLock==1 ); | 52441 | p->nWrLock--; |
| 50170 | p->nWrLock = 0; | ||
| 50171 | } | 52442 | } |
| 50172 | assert( p->nRdLock>0 ); | ||
| 50173 | p->nRdLock--; | 52443 | p->nRdLock--; |
| 50174 | } | 52444 | } |
| 50175 | if( rc==SQLITE_OK ) pThis->eLock = eLock; | 52445 | |
| 52446 | pThis->eLock = eLock; | ||
| 50176 | memdbLeave(p); | 52447 | memdbLeave(p); |
| 50177 | return rc; | 52448 | return SQLITE_OK; |
| 50178 | } | 52449 | } |
| 50179 | 52450 | ||
| 50180 | #if 0 | 52451 | #if 0 |
| @@ -50284,7 +52555,7 @@ static int memdbOpen( | |||
| 50284 | 52555 | ||
| 50285 | memset(pFile, 0, sizeof(*pFile)); | 52556 | memset(pFile, 0, sizeof(*pFile)); |
| 50286 | szName = sqlite3Strlen30(zName); | 52557 | szName = sqlite3Strlen30(zName); |
| 50287 | if( szName>1 && zName[0]=='/' ){ | 52558 | if( szName>1 && (zName[0]=='/' || zName[0]=='\\') ){ |
| 50288 | int i; | 52559 | int i; |
| 50289 | #ifndef SQLITE_MUTEX_OMIT | 52560 | #ifndef SQLITE_MUTEX_OMIT |
| 50290 | sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); | 52561 | sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); |
| @@ -50632,6 +52903,13 @@ end_deserialize: | |||
| 50632 | } | 52903 | } |
| 50633 | 52904 | ||
| 50634 | /* | 52905 | /* |
| 52906 | ** Return true if the VFS is the memvfs. | ||
| 52907 | */ | ||
| 52908 | SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs *pVfs){ | ||
| 52909 | return pVfs==&memdb_vfs; | ||
| 52910 | } | ||
| 52911 | |||
| 52912 | /* | ||
| 50635 | ** This routine is called when the extension is loaded. | 52913 | ** This routine is called when the extension is loaded. |
| 50636 | ** Register the new VFS. | 52914 | ** Register the new VFS. |
| 50637 | */ | 52915 | */ |
| @@ -50843,7 +53121,7 @@ SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ | |||
| 50843 | h = BITVEC_HASH(i++); | 53121 | h = BITVEC_HASH(i++); |
| 50844 | /* if there wasn't a hash collision, and this doesn't */ | 53122 | /* if there wasn't a hash collision, and this doesn't */ |
| 50845 | /* completely fill the hash, then just add it without */ | 53123 | /* completely fill the hash, then just add it without */ |
| 50846 | /* worring about sub-dividing and re-hashing. */ | 53124 | /* worrying about sub-dividing and re-hashing. */ |
| 50847 | if( !p->u.aHash[h] ){ | 53125 | if( !p->u.aHash[h] ){ |
| 50848 | if (p->nSet<(BITVEC_NINT-1)) { | 53126 | if (p->nSet<(BITVEC_NINT-1)) { |
| 50849 | goto bitvec_set_end; | 53127 | goto bitvec_set_end; |
| @@ -51110,7 +53388,7 @@ bitvec_end: | |||
| 51110 | struct PCache { | 53388 | struct PCache { |
| 51111 | PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ | 53389 | PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ |
| 51112 | PgHdr *pSynced; /* Last synced page in dirty page list */ | 53390 | PgHdr *pSynced; /* Last synced page in dirty page list */ |
| 51113 | int nRefSum; /* Sum of ref counts over all pages */ | 53391 | i64 nRefSum; /* Sum of ref counts over all pages */ |
| 51114 | int szCache; /* Configured cache size */ | 53392 | int szCache; /* Configured cache size */ |
| 51115 | int szSpill; /* Size before spilling occurs */ | 53393 | int szSpill; /* Size before spilling occurs */ |
| 51116 | int szPage; /* Size of every page in this cache */ | 53394 | int szPage; /* Size of every page in this cache */ |
| @@ -51135,12 +53413,24 @@ struct PCache { | |||
| 51135 | int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ | 53413 | int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ |
| 51136 | int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ | 53414 | int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ |
| 51137 | # define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} | 53415 | # define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} |
| 51138 | void pcacheDump(PCache *pCache){ | 53416 | static void pcachePageTrace(int i, sqlite3_pcache_page *pLower){ |
| 51139 | int N; | ||
| 51140 | int i, j; | ||
| 51141 | sqlite3_pcache_page *pLower; | ||
| 51142 | PgHdr *pPg; | 53417 | PgHdr *pPg; |
| 51143 | unsigned char *a; | 53418 | unsigned char *a; |
| 53419 | int j; | ||
| 53420 | if( pLower==0 ){ | ||
| 53421 | printf("%3d: NULL\n", i); | ||
| 53422 | }else{ | ||
| 53423 | pPg = (PgHdr*)pLower->pExtra; | ||
| 53424 | printf("%3d: nRef %2lld flgs %02x data ", i, pPg->nRef, pPg->flags); | ||
| 53425 | a = (unsigned char *)pLower->pBuf; | ||
| 53426 | for(j=0; j<12; j++) printf("%02x", a[j]); | ||
| 53427 | printf(" ptr %p\n", pPg); | ||
| 53428 | } | ||
| 53429 | } | ||
| 53430 | static void pcacheDump(PCache *pCache){ | ||
| 53431 | int N; | ||
| 53432 | int i; | ||
| 53433 | sqlite3_pcache_page *pLower; | ||
| 51144 | 53434 | ||
| 51145 | if( sqlite3PcacheTrace<2 ) return; | 53435 | if( sqlite3PcacheTrace<2 ) return; |
| 51146 | if( pCache->pCache==0 ) return; | 53436 | if( pCache->pCache==0 ) return; |
| @@ -51148,23 +53438,43 @@ struct PCache { | |||
| 51148 | if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; | 53438 | if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; |
| 51149 | for(i=1; i<=N; i++){ | 53439 | for(i=1; i<=N; i++){ |
| 51150 | pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); | 53440 | pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); |
| 51151 | if( pLower==0 ) continue; | 53441 | pcachePageTrace(i, pLower); |
| 51152 | pPg = (PgHdr*)pLower->pExtra; | 53442 | if( pLower && ((PgHdr*)pLower)->pPage==0 ){ |
| 51153 | printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); | ||
| 51154 | a = (unsigned char *)pLower->pBuf; | ||
| 51155 | for(j=0; j<12; j++) printf("%02x", a[j]); | ||
| 51156 | printf("\n"); | ||
| 51157 | if( pPg->pPage==0 ){ | ||
| 51158 | sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); | 53443 | sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); |
| 51159 | } | 53444 | } |
| 51160 | } | 53445 | } |
| 51161 | } | 53446 | } |
| 51162 | #else | 53447 | #else |
| 51163 | # define pcacheTrace(X) | 53448 | # define pcacheTrace(X) |
| 53449 | # define pcachePageTrace(PGNO, X) | ||
| 51164 | # define pcacheDump(X) | 53450 | # define pcacheDump(X) |
| 51165 | #endif | 53451 | #endif |
| 51166 | 53452 | ||
| 51167 | /* | 53453 | /* |
| 53454 | ** Return 1 if pPg is on the dirty list for pCache. Return 0 if not. | ||
| 53455 | ** This routine runs inside of assert() statements only. | ||
| 53456 | */ | ||
| 53457 | #if defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) | ||
| 53458 | static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ | ||
| 53459 | PgHdr *p; | ||
| 53460 | for(p=pCache->pDirty; p; p=p->pDirtyNext){ | ||
| 53461 | if( p==pPg ) return 1; | ||
| 53462 | } | ||
| 53463 | return 0; | ||
| 53464 | } | ||
| 53465 | static int pageNotOnDirtyList(PCache *pCache, PgHdr *pPg){ | ||
| 53466 | PgHdr *p; | ||
| 53467 | for(p=pCache->pDirty; p; p=p->pDirtyNext){ | ||
| 53468 | if( p==pPg ) return 0; | ||
| 53469 | } | ||
| 53470 | return 1; | ||
| 53471 | } | ||
| 53472 | #else | ||
| 53473 | # define pageOnDirtyList(A,B) 1 | ||
| 53474 | # define pageNotOnDirtyList(A,B) 1 | ||
| 53475 | #endif | ||
| 53476 | |||
| 53477 | /* | ||
| 51168 | ** Check invariants on a PgHdr entry. Return true if everything is OK. | 53478 | ** Check invariants on a PgHdr entry. Return true if everything is OK. |
| 51169 | ** Return false if any invariant is violated. | 53479 | ** Return false if any invariant is violated. |
| 51170 | ** | 53480 | ** |
| @@ -51182,8 +53492,13 @@ SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){ | |||
| 51182 | assert( pCache!=0 ); /* Every page has an associated PCache */ | 53492 | assert( pCache!=0 ); /* Every page has an associated PCache */ |
| 51183 | if( pPg->flags & PGHDR_CLEAN ){ | 53493 | if( pPg->flags & PGHDR_CLEAN ){ |
| 51184 | assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ | 53494 | assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ |
| 51185 | assert( pCache->pDirty!=pPg ); /* CLEAN pages not on dirty list */ | 53495 | assert( pageNotOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirtylist */ |
| 51186 | assert( pCache->pDirtyTail!=pPg ); | 53496 | }else{ |
| 53497 | assert( (pPg->flags & PGHDR_DIRTY)!=0 );/* If not CLEAN must be DIRTY */ | ||
| 53498 | assert( pPg->pDirtyNext==0 || pPg->pDirtyNext->pDirtyPrev==pPg ); | ||
| 53499 | assert( pPg->pDirtyPrev==0 || pPg->pDirtyPrev->pDirtyNext==pPg ); | ||
| 53500 | assert( pPg->pDirtyPrev!=0 || pCache->pDirty==pPg ); | ||
| 53501 | assert( pageOnDirtyList(pCache, pPg) ); | ||
| 51187 | } | 53502 | } |
| 51188 | /* WRITEABLE pages must also be DIRTY */ | 53503 | /* WRITEABLE pages must also be DIRTY */ |
| 51189 | if( pPg->flags & PGHDR_WRITEABLE ){ | 53504 | if( pPg->flags & PGHDR_WRITEABLE ){ |
| @@ -51313,7 +53628,7 @@ static int numberOfCachePages(PCache *p){ | |||
| 51313 | return p->szCache; | 53628 | return p->szCache; |
| 51314 | }else{ | 53629 | }else{ |
| 51315 | i64 n; | 53630 | i64 n; |
| 51316 | /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the | 53631 | /* IMPLEMENTATION-OF: R-59858-46238 If the argument N is negative, then the |
| 51317 | ** number of cache pages is adjusted to be a number of pages that would | 53632 | ** number of cache pages is adjusted to be a number of pages that would |
| 51318 | ** use approximately abs(N*1024) bytes of memory based on the current | 53633 | ** use approximately abs(N*1024) bytes of memory based on the current |
| 51319 | ** page size. */ | 53634 | ** page size. */ |
| @@ -51457,8 +53772,9 @@ SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch( | |||
| 51457 | assert( createFlag==0 || pCache->eCreate==eCreate ); | 53772 | assert( createFlag==0 || pCache->eCreate==eCreate ); |
| 51458 | assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); | 53773 | assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); |
| 51459 | pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); | 53774 | pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); |
| 51460 | pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno, | 53775 | pcacheTrace(("%p.FETCH %d%s (result: %p) ",pCache,pgno, |
| 51461 | createFlag?" create":"",pRes)); | 53776 | createFlag?" create":"",pRes)); |
| 53777 | pcachePageTrace(pgno, pRes); | ||
| 51462 | return pRes; | 53778 | return pRes; |
| 51463 | } | 53779 | } |
| 51464 | 53780 | ||
| @@ -51586,6 +53902,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ | |||
| 51586 | pcacheUnpin(p); | 53902 | pcacheUnpin(p); |
| 51587 | }else{ | 53903 | }else{ |
| 51588 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); | 53904 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); |
| 53905 | assert( sqlite3PcachePageSanity(p) ); | ||
| 51589 | } | 53906 | } |
| 51590 | } | 53907 | } |
| 51591 | } | 53908 | } |
| @@ -51629,6 +53946,7 @@ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ | |||
| 51629 | pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); | 53946 | pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); |
| 51630 | assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); | 53947 | assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); |
| 51631 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); | 53948 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); |
| 53949 | assert( sqlite3PcachePageSanity(p) ); | ||
| 51632 | } | 53950 | } |
| 51633 | assert( sqlite3PcachePageSanity(p) ); | 53951 | assert( sqlite3PcachePageSanity(p) ); |
| 51634 | } | 53952 | } |
| @@ -51691,14 +54009,24 @@ SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){ | |||
| 51691 | */ | 54009 | */ |
| 51692 | SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ | 54010 | SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ |
| 51693 | PCache *pCache = p->pCache; | 54011 | PCache *pCache = p->pCache; |
| 54012 | sqlite3_pcache_page *pOther; | ||
| 51694 | assert( p->nRef>0 ); | 54013 | assert( p->nRef>0 ); |
| 51695 | assert( newPgno>0 ); | 54014 | assert( newPgno>0 ); |
| 51696 | assert( sqlite3PcachePageSanity(p) ); | 54015 | assert( sqlite3PcachePageSanity(p) ); |
| 51697 | pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); | 54016 | pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); |
| 54017 | pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0); | ||
| 54018 | if( pOther ){ | ||
| 54019 | PgHdr *pXPage = (PgHdr*)pOther->pExtra; | ||
| 54020 | assert( pXPage->nRef==0 ); | ||
| 54021 | pXPage->nRef++; | ||
| 54022 | pCache->nRefSum++; | ||
| 54023 | sqlite3PcacheDrop(pXPage); | ||
| 54024 | } | ||
| 51698 | sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); | 54025 | sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); |
| 51699 | p->pgno = newPgno; | 54026 | p->pgno = newPgno; |
| 51700 | if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ | 54027 | if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ |
| 51701 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); | 54028 | pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); |
| 54029 | assert( sqlite3PcachePageSanity(p) ); | ||
| 51702 | } | 54030 | } |
| 51703 | } | 54031 | } |
| 51704 | 54032 | ||
| @@ -51788,7 +54116,7 @@ static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ | |||
| 51788 | } | 54116 | } |
| 51789 | 54117 | ||
| 51790 | /* | 54118 | /* |
| 51791 | ** Sort the list of pages in accending order by pgno. Pages are | 54119 | ** Sort the list of pages in ascending order by pgno. Pages are |
| 51792 | ** connected by pDirty pointers. The pDirtyPrev pointers are | 54120 | ** connected by pDirty pointers. The pDirtyPrev pointers are |
| 51793 | ** corrupted by this sort. | 54121 | ** corrupted by this sort. |
| 51794 | ** | 54122 | ** |
| @@ -51847,14 +54175,14 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){ | |||
| 51847 | ** This is not the total number of pages referenced, but the sum of the | 54175 | ** This is not the total number of pages referenced, but the sum of the |
| 51848 | ** reference count for all pages. | 54176 | ** reference count for all pages. |
| 51849 | */ | 54177 | */ |
| 51850 | SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){ | 54178 | SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache *pCache){ |
| 51851 | return pCache->nRefSum; | 54179 | return pCache->nRefSum; |
| 51852 | } | 54180 | } |
| 51853 | 54181 | ||
| 51854 | /* | 54182 | /* |
| 51855 | ** Return the number of references to the page supplied as an argument. | 54183 | ** Return the number of references to the page supplied as an argument. |
| 51856 | */ | 54184 | */ |
| 51857 | SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){ | 54185 | SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr *p){ |
| 51858 | return p->nRef; | 54186 | return p->nRef; |
| 51859 | } | 54187 | } |
| 51860 | 54188 | ||
| @@ -51996,12 +54324,13 @@ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHd | |||
| 51996 | ** size can vary according to architecture, compile-time options, and | 54324 | ** size can vary according to architecture, compile-time options, and |
| 51997 | ** SQLite library version number. | 54325 | ** SQLite library version number. |
| 51998 | ** | 54326 | ** |
| 51999 | ** If SQLITE_PCACHE_SEPARATE_HEADER is defined, then the extension is obtained | 54327 | ** Historical note: It used to be that if the SQLITE_PCACHE_SEPARATE_HEADER |
| 52000 | ** using a separate memory allocation from the database page content. This | 54328 | ** was defined, then the page content would be held in a separate memory |
| 52001 | ** seeks to overcome the "clownshoe" problem (also called "internal | 54329 | ** allocation from the PgHdr1. This was intended to avoid clownshoe memory |
| 52002 | ** fragmentation" in academic literature) of allocating a few bytes more | 54330 | ** allocations. However, the btree layer needs a small (16-byte) overrun |
| 52003 | ** than a power of two with the memory allocator rounding up to the next | 54331 | ** area after the page content buffer. The header serves as that overrun |
| 52004 | ** power of two, and leaving the rounded-up space unused. | 54332 | ** area. Therefore SQLITE_PCACHE_SEPARATE_HEADER was discontinued to avoid |
| 54333 | ** any possibility of a memory error. | ||
| 52005 | ** | 54334 | ** |
| 52006 | ** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates | 54335 | ** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates |
| 52007 | ** with this module. Information is passed back and forth as PgHdr1 pointers. | 54336 | ** with this module. Information is passed back and forth as PgHdr1 pointers. |
| @@ -52027,7 +54356,7 @@ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHd | |||
| 52027 | ** If N is positive, then N pages worth of memory are allocated using a single | 54356 | ** If N is positive, then N pages worth of memory are allocated using a single |
| 52028 | ** sqlite3Malloc() call and that memory is used for the first N pages allocated. | 54357 | ** sqlite3Malloc() call and that memory is used for the first N pages allocated. |
| 52029 | ** Or if N is negative, then -1024*N bytes of memory are allocated and used | 54358 | ** Or if N is negative, then -1024*N bytes of memory are allocated and used |
| 52030 | ** for as many pages as can be accomodated. | 54359 | ** for as many pages as can be accommodated. |
| 52031 | ** | 54360 | ** |
| 52032 | ** Only one of (2) or (3) can be used. Once the memory available to (2) or | 54361 | ** Only one of (2) or (3) can be used. Once the memory available to (2) or |
| 52033 | ** (3) is exhausted, subsequent allocations fail over to the general-purpose | 54362 | ** (3) is exhausted, subsequent allocations fail over to the general-purpose |
| @@ -52046,30 +54375,40 @@ typedef struct PGroup PGroup; | |||
| 52046 | 54375 | ||
| 52047 | /* | 54376 | /* |
| 52048 | ** Each cache entry is represented by an instance of the following | 54377 | ** Each cache entry is represented by an instance of the following |
| 52049 | ** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of | 54378 | ** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated |
| 52050 | ** PgHdr1.pCache->szPage bytes is allocated directly before this structure | 54379 | ** directly before this structure and is used to cache the page content. |
| 52051 | ** in memory. | 54380 | ** |
| 54381 | ** When reading a corrupt database file, it is possible that SQLite might | ||
| 54382 | ** read a few bytes (no more than 16 bytes) past the end of the page buffer. | ||
| 54383 | ** It will only read past the end of the page buffer, never write. This | ||
| 54384 | ** object is positioned immediately after the page buffer to serve as an | ||
| 54385 | ** overrun area, so that overreads are harmless. | ||
| 52052 | ** | 54386 | ** |
| 52053 | ** Note: Variables isBulkLocal and isAnchor were once type "u8". That works, | 54387 | ** Variables isBulkLocal and isAnchor were once type "u8". That works, |
| 52054 | ** but causes a 2-byte gap in the structure for most architectures (since | 54388 | ** but causes a 2-byte gap in the structure for most architectures (since |
| 52055 | ** pointers must be either 4 or 8-byte aligned). As this structure is located | 54389 | ** pointers must be either 4 or 8-byte aligned). As this structure is located |
| 52056 | ** in memory directly after the associated page data, if the database is | 54390 | ** in memory directly after the associated page data, if the database is |
| 52057 | ** corrupt, code at the b-tree layer may overread the page buffer and | 54391 | ** corrupt, code at the b-tree layer may overread the page buffer and |
| 52058 | ** read part of this structure before the corruption is detected. This | 54392 | ** read part of this structure before the corruption is detected. This |
| 52059 | ** can cause a valgrind error if the unitialized gap is accessed. Using u16 | 54393 | ** can cause a valgrind error if the uninitialized gap is accessed. Using u16 |
| 52060 | ** ensures there is no such gap, and therefore no bytes of unitialized memory | 54394 | ** ensures there is no such gap, and therefore no bytes of uninitialized |
| 52061 | ** in the structure. | 54395 | ** memory in the structure. |
| 54396 | ** | ||
| 54397 | ** The pLruNext and pLruPrev pointers form a double-linked circular list | ||
| 54398 | ** of all pages that are unpinned. The PGroup.lru element (which should be | ||
| 54399 | ** the only element on the list with PgHdr1.isAnchor set to 1) forms the | ||
| 54400 | ** beginning and the end of the list. | ||
| 52062 | */ | 54401 | */ |
| 52063 | struct PgHdr1 { | 54402 | struct PgHdr1 { |
| 52064 | sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ | 54403 | sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ |
| 52065 | unsigned int iKey; /* Key value (page number) */ | 54404 | unsigned int iKey; /* Key value (page number) */ |
| 52066 | u16 isBulkLocal; /* This page from bulk local storage */ | 54405 | u16 isBulkLocal; /* This page from bulk local storage */ |
| 52067 | u16 isAnchor; /* This is the PGroup.lru element */ | 54406 | u16 isAnchor; /* This is the PGroup.lru element */ |
| 52068 | PgHdr1 *pNext; /* Next in hash table chain */ | 54407 | PgHdr1 *pNext; /* Next in hash table chain */ |
| 52069 | PCache1 *pCache; /* Cache that currently owns this page */ | 54408 | PCache1 *pCache; /* Cache that currently owns this page */ |
| 52070 | PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ | 54409 | PgHdr1 *pLruNext; /* Next in circular LRU list of unpinned pages */ |
| 52071 | PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ | 54410 | PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ |
| 52072 | /* NB: pLruPrev is only valid if pLruNext!=0 */ | 54411 | /* NB: pLruPrev is only valid if pLruNext!=0 */ |
| 52073 | }; | 54412 | }; |
| 52074 | 54413 | ||
| 52075 | /* | 54414 | /* |
| @@ -52395,25 +54734,13 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ | |||
| 52395 | pcache1LeaveMutex(pCache->pGroup); | 54734 | pcache1LeaveMutex(pCache->pGroup); |
| 52396 | #endif | 54735 | #endif |
| 52397 | if( benignMalloc ){ sqlite3BeginBenignMalloc(); } | 54736 | if( benignMalloc ){ sqlite3BeginBenignMalloc(); } |
| 52398 | #ifdef SQLITE_PCACHE_SEPARATE_HEADER | ||
| 52399 | pPg = pcache1Alloc(pCache->szPage); | ||
| 52400 | p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); | ||
| 52401 | if( !pPg || !p ){ | ||
| 52402 | pcache1Free(pPg); | ||
| 52403 | sqlite3_free(p); | ||
| 52404 | pPg = 0; | ||
| 52405 | } | ||
| 52406 | #else | ||
| 52407 | pPg = pcache1Alloc(pCache->szAlloc); | 54737 | pPg = pcache1Alloc(pCache->szAlloc); |
| 52408 | #endif | ||
| 52409 | if( benignMalloc ){ sqlite3EndBenignMalloc(); } | 54738 | if( benignMalloc ){ sqlite3EndBenignMalloc(); } |
| 52410 | #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT | 54739 | #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT |
| 52411 | pcache1EnterMutex(pCache->pGroup); | 54740 | pcache1EnterMutex(pCache->pGroup); |
| 52412 | #endif | 54741 | #endif |
| 52413 | if( pPg==0 ) return 0; | 54742 | if( pPg==0 ) return 0; |
| 52414 | #ifndef SQLITE_PCACHE_SEPARATE_HEADER | ||
| 52415 | p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; | 54743 | p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; |
| 52416 | #endif | ||
| 52417 | p->page.pBuf = pPg; | 54744 | p->page.pBuf = pPg; |
| 52418 | p->page.pExtra = &p[1]; | 54745 | p->page.pExtra = &p[1]; |
| 52419 | p->isBulkLocal = 0; | 54746 | p->isBulkLocal = 0; |
| @@ -52437,9 +54764,6 @@ static void pcache1FreePage(PgHdr1 *p){ | |||
| 52437 | pCache->pFree = p; | 54764 | pCache->pFree = p; |
| 52438 | }else{ | 54765 | }else{ |
| 52439 | pcache1Free(p->page.pBuf); | 54766 | pcache1Free(p->page.pBuf); |
| 52440 | #ifdef SQLITE_PCACHE_SEPARATE_HEADER | ||
| 52441 | sqlite3_free(p); | ||
| 52442 | #endif | ||
| 52443 | } | 54767 | } |
| 52444 | (*pCache->pnPurgeable)--; | 54768 | (*pCache->pnPurgeable)--; |
| 52445 | } | 54769 | } |
| @@ -53080,23 +55404,26 @@ static void pcache1Rekey( | |||
| 53080 | PCache1 *pCache = (PCache1 *)p; | 55404 | PCache1 *pCache = (PCache1 *)p; |
| 53081 | PgHdr1 *pPage = (PgHdr1 *)pPg; | 55405 | PgHdr1 *pPage = (PgHdr1 *)pPg; |
| 53082 | PgHdr1 **pp; | 55406 | PgHdr1 **pp; |
| 53083 | unsigned int h; | 55407 | unsigned int hOld, hNew; |
| 53084 | assert( pPage->iKey==iOld ); | 55408 | assert( pPage->iKey==iOld ); |
| 53085 | assert( pPage->pCache==pCache ); | 55409 | assert( pPage->pCache==pCache ); |
| 55410 | assert( iOld!=iNew ); /* The page number really is changing */ | ||
| 53086 | 55411 | ||
| 53087 | pcache1EnterMutex(pCache->pGroup); | 55412 | pcache1EnterMutex(pCache->pGroup); |
| 53088 | 55413 | ||
| 53089 | h = iOld%pCache->nHash; | 55414 | assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */ |
| 53090 | pp = &pCache->apHash[h]; | 55415 | hOld = iOld%pCache->nHash; |
| 55416 | pp = &pCache->apHash[hOld]; | ||
| 53091 | while( (*pp)!=pPage ){ | 55417 | while( (*pp)!=pPage ){ |
| 53092 | pp = &(*pp)->pNext; | 55418 | pp = &(*pp)->pNext; |
| 53093 | } | 55419 | } |
| 53094 | *pp = pPage->pNext; | 55420 | *pp = pPage->pNext; |
| 53095 | 55421 | ||
| 53096 | h = iNew%pCache->nHash; | 55422 | assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */ |
| 55423 | hNew = iNew%pCache->nHash; | ||
| 53097 | pPage->iKey = iNew; | 55424 | pPage->iKey = iNew; |
| 53098 | pPage->pNext = pCache->apHash[h]; | 55425 | pPage->pNext = pCache->apHash[hNew]; |
| 53099 | pCache->apHash[h] = pPage; | 55426 | pCache->apHash[hNew] = pPage; |
| 53100 | if( iNew>pCache->iMaxKey ){ | 55427 | if( iNew>pCache->iMaxKey ){ |
| 53101 | pCache->iMaxKey = iNew; | 55428 | pCache->iMaxKey = iNew; |
| 53102 | } | 55429 | } |
| @@ -53203,9 +55530,6 @@ SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){ | |||
| 53203 | && p->isAnchor==0 | 55530 | && p->isAnchor==0 |
| 53204 | ){ | 55531 | ){ |
| 53205 | nFree += pcache1MemSize(p->page.pBuf); | 55532 | nFree += pcache1MemSize(p->page.pBuf); |
| 53206 | #ifdef SQLITE_PCACHE_SEPARATE_HEADER | ||
| 53207 | nFree += sqlite3MemSize(p); | ||
| 53208 | #endif | ||
| 53209 | assert( PAGE_IS_UNPINNED(p) ); | 55533 | assert( PAGE_IS_UNPINNED(p) ); |
| 53210 | pcache1PinPage(p); | 55534 | pcache1PinPage(p); |
| 53211 | pcache1RemoveFromHash(p, 1); | 55535 | pcache1RemoveFromHash(p, 1); |
| @@ -53286,7 +55610,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats( | |||
| 53286 | ** The TEST primitive includes a "batch" number. The TEST primitive | 55610 | ** The TEST primitive includes a "batch" number. The TEST primitive |
| 53287 | ** will only see elements that were inserted before the last change | 55611 | ** will only see elements that were inserted before the last change |
| 53288 | ** in the batch number. In other words, if an INSERT occurs between | 55612 | ** in the batch number. In other words, if an INSERT occurs between |
| 53289 | ** two TESTs where the TESTs have the same batch nubmer, then the | 55613 | ** two TESTs where the TESTs have the same batch number, then the |
| 53290 | ** value added by the INSERT will not be visible to the second TEST. | 55614 | ** value added by the INSERT will not be visible to the second TEST. |
| 53291 | ** The initial batch number is zero, so if the very first TEST contains | 55615 | ** The initial batch number is zero, so if the very first TEST contains |
| 53292 | ** a non-zero batch number, it will see all prior INSERTs. | 55616 | ** a non-zero batch number, it will see all prior INSERTs. |
| @@ -53818,6 +56142,7 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 | |||
| 53818 | # define sqlite3WalFramesize(z) 0 | 56142 | # define sqlite3WalFramesize(z) 0 |
| 53819 | # define sqlite3WalFindFrame(x,y,z) 0 | 56143 | # define sqlite3WalFindFrame(x,y,z) 0 |
| 53820 | # define sqlite3WalFile(x) 0 | 56144 | # define sqlite3WalFile(x) 0 |
| 56145 | # undef SQLITE_USE_SEH | ||
| 53821 | #else | 56146 | #else |
| 53822 | 56147 | ||
| 53823 | #define WAL_SAVEPOINT_NDATA 4 | 56148 | #define WAL_SAVEPOINT_NDATA 4 |
| @@ -53924,6 +56249,10 @@ SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock); | |||
| 53924 | SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db); | 56249 | SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db); |
| 53925 | #endif | 56250 | #endif |
| 53926 | 56251 | ||
| 56252 | #ifdef SQLITE_USE_SEH | ||
| 56253 | SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal*); | ||
| 56254 | #endif | ||
| 56255 | |||
| 53927 | #endif /* ifndef SQLITE_OMIT_WAL */ | 56256 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 53928 | #endif /* SQLITE_WAL_H */ | 56257 | #endif /* SQLITE_WAL_H */ |
| 53929 | 56258 | ||
| @@ -54209,7 +56538,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ | |||
| 54209 | ** outstanding transactions have been abandoned, the pager is able to | 56538 | ** outstanding transactions have been abandoned, the pager is able to |
| 54210 | ** transition back to OPEN state, discarding the contents of the | 56539 | ** transition back to OPEN state, discarding the contents of the |
| 54211 | ** page-cache and any other in-memory state at the same time. Everything | 56540 | ** page-cache and any other in-memory state at the same time. Everything |
| 54212 | ** is reloaded from disk (and, if necessary, hot-journal rollback peformed) | 56541 | ** is reloaded from disk (and, if necessary, hot-journal rollback performed) |
| 54213 | ** when a read-transaction is next opened on the pager (transitioning | 56542 | ** when a read-transaction is next opened on the pager (transitioning |
| 54214 | ** the pager into READER state). At that point the system has recovered | 56543 | ** the pager into READER state). At that point the system has recovered |
| 54215 | ** from the error. | 56544 | ** from the error. |
| @@ -55582,7 +57911,7 @@ static int readJournalHdr( | |||
| 55582 | ** + 4 bytes: super-journal name checksum. | 57911 | ** + 4 bytes: super-journal name checksum. |
| 55583 | ** + 8 bytes: aJournalMagic[]. | 57912 | ** + 8 bytes: aJournalMagic[]. |
| 55584 | ** | 57913 | ** |
| 55585 | ** The super-journal page checksum is the sum of the bytes in thesuper-journal | 57914 | ** The super-journal page checksum is the sum of the bytes in the super-journal |
| 55586 | ** name, where each byte is interpreted as a signed 8-bit integer. | 57915 | ** name, where each byte is interpreted as a signed 8-bit integer. |
| 55587 | ** | 57916 | ** |
| 55588 | ** If zSuper is a NULL pointer (occurs for a single database transaction), | 57917 | ** If zSuper is a NULL pointer (occurs for a single database transaction), |
| @@ -55635,7 +57964,7 @@ static int writeSuperJournal(Pager *pPager, const char *zSuper){ | |||
| 55635 | } | 57964 | } |
| 55636 | pPager->journalOff += (nSuper+20); | 57965 | pPager->journalOff += (nSuper+20); |
| 55637 | 57966 | ||
| 55638 | /* If the pager is in peristent-journal mode, then the physical | 57967 | /* If the pager is in persistent-journal mode, then the physical |
| 55639 | ** journal-file may extend past the end of the super-journal name | 57968 | ** journal-file may extend past the end of the super-journal name |
| 55640 | ** and 8 bytes of magic data just written to the file. This is | 57969 | ** and 8 bytes of magic data just written to the file. This is |
| 55641 | ** dangerous because the code to rollback a hot-journal file | 57970 | ** dangerous because the code to rollback a hot-journal file |
| @@ -55805,7 +58134,7 @@ static void pager_unlock(Pager *pPager){ | |||
| 55805 | 58134 | ||
| 55806 | /* | 58135 | /* |
| 55807 | ** This function is called whenever an IOERR or FULL error that requires | 58136 | ** This function is called whenever an IOERR or FULL error that requires |
| 55808 | ** the pager to transition into the ERROR state may ahve occurred. | 58137 | ** the pager to transition into the ERROR state may have occurred. |
| 55809 | ** The first argument is a pointer to the pager structure, the second | 58138 | ** The first argument is a pointer to the pager structure, the second |
| 55810 | ** the error-code about to be returned by a pager API function. The | 58139 | ** the error-code about to be returned by a pager API function. The |
| 55811 | ** value returned is a copy of the second argument to this function. | 58140 | ** value returned is a copy of the second argument to this function. |
| @@ -56080,7 +58409,7 @@ static void pagerUnlockAndRollback(Pager *pPager){ | |||
| 56080 | 58409 | ||
| 56081 | /* | 58410 | /* |
| 56082 | ** Parameter aData must point to a buffer of pPager->pageSize bytes | 58411 | ** Parameter aData must point to a buffer of pPager->pageSize bytes |
| 56083 | ** of data. Compute and return a checksum based ont the contents of the | 58412 | ** of data. Compute and return a checksum based on the contents of the |
| 56084 | ** page of data and the current value of pPager->cksumInit. | 58413 | ** page of data and the current value of pPager->cksumInit. |
| 56085 | ** | 58414 | ** |
| 56086 | ** This is not a real checksum. It is really just the sum of the | 58415 | ** This is not a real checksum. It is really just the sum of the |
| @@ -56513,6 +58842,8 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ | |||
| 56513 | int rc = SQLITE_OK; | 58842 | int rc = SQLITE_OK; |
| 56514 | assert( pPager->eState!=PAGER_ERROR ); | 58843 | assert( pPager->eState!=PAGER_ERROR ); |
| 56515 | assert( pPager->eState!=PAGER_READER ); | 58844 | assert( pPager->eState!=PAGER_READER ); |
| 58845 | PAGERTRACE(("Truncate %d npage %u\n", PAGERID(pPager), nPage)); | ||
| 58846 | |||
| 56516 | 58847 | ||
| 56517 | if( isOpen(pPager->fd) | 58848 | if( isOpen(pPager->fd) |
| 56518 | && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) | 58849 | && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) |
| @@ -56843,7 +59174,7 @@ end_playback: | |||
| 56843 | ** see if it is possible to delete the super-journal. | 59174 | ** see if it is possible to delete the super-journal. |
| 56844 | */ | 59175 | */ |
| 56845 | assert( zSuper==&pPager->pTmpSpace[4] ); | 59176 | assert( zSuper==&pPager->pTmpSpace[4] ); |
| 56846 | memset(&zSuper[-4], 0, 4); | 59177 | memset(pPager->pTmpSpace, 0, 4); |
| 56847 | rc = pager_delsuper(pPager, zSuper); | 59178 | rc = pager_delsuper(pPager, zSuper); |
| 56848 | testcase( rc!=SQLITE_OK ); | 59179 | testcase( rc!=SQLITE_OK ); |
| 56849 | } | 59180 | } |
| @@ -57044,7 +59375,7 @@ static int pagerWalFrames( | |||
| 57044 | assert( pPager->pWal ); | 59375 | assert( pPager->pWal ); |
| 57045 | assert( pList ); | 59376 | assert( pList ); |
| 57046 | #ifdef SQLITE_DEBUG | 59377 | #ifdef SQLITE_DEBUG |
| 57047 | /* Verify that the page list is in accending order */ | 59378 | /* Verify that the page list is in ascending order */ |
| 57048 | for(p=pList; p && p->pDirty; p=p->pDirty){ | 59379 | for(p=pList; p && p->pDirty; p=p->pDirty){ |
| 57049 | assert( p->pgno < p->pDirty->pgno ); | 59380 | assert( p->pgno < p->pDirty->pgno ); |
| 57050 | } | 59381 | } |
| @@ -57175,7 +59506,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){ | |||
| 57175 | #ifndef SQLITE_OMIT_WAL | 59506 | #ifndef SQLITE_OMIT_WAL |
| 57176 | /* | 59507 | /* |
| 57177 | ** Check if the *-wal file that corresponds to the database opened by pPager | 59508 | ** Check if the *-wal file that corresponds to the database opened by pPager |
| 57178 | ** exists if the database is not empy, or verify that the *-wal file does | 59509 | ** exists if the database is not empty, or verify that the *-wal file does |
| 57179 | ** not exist (by deleting it) if the database file is empty. | 59510 | ** not exist (by deleting it) if the database file is empty. |
| 57180 | ** | 59511 | ** |
| 57181 | ** If the database is not empty and the *-wal file exists, open the pager | 59512 | ** If the database is not empty and the *-wal file exists, open the pager |
| @@ -57464,7 +59795,6 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){ | |||
| 57464 | ** Numeric values associated with these states are OFF==1, NORMAL=2, | 59795 | ** Numeric values associated with these states are OFF==1, NORMAL=2, |
| 57465 | ** and FULL=3. | 59796 | ** and FULL=3. |
| 57466 | */ | 59797 | */ |
| 57467 | #ifndef SQLITE_OMIT_PAGER_PRAGMAS | ||
| 57468 | SQLITE_PRIVATE void sqlite3PagerSetFlags( | 59798 | SQLITE_PRIVATE void sqlite3PagerSetFlags( |
| 57469 | Pager *pPager, /* The pager to set safety level for */ | 59799 | Pager *pPager, /* The pager to set safety level for */ |
| 57470 | unsigned pgFlags /* Various flags */ | 59800 | unsigned pgFlags /* Various flags */ |
| @@ -57499,7 +59829,6 @@ SQLITE_PRIVATE void sqlite3PagerSetFlags( | |||
| 57499 | pPager->doNotSpill |= SPILLFLAG_OFF; | 59829 | pPager->doNotSpill |= SPILLFLAG_OFF; |
| 57500 | } | 59830 | } |
| 57501 | } | 59831 | } |
| 57502 | #endif | ||
| 57503 | 59832 | ||
| 57504 | /* | 59833 | /* |
| 57505 | ** The following global variable is incremented whenever the library | 59834 | ** The following global variable is incremented whenever the library |
| @@ -58587,11 +60916,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( | |||
| 58587 | int rc = SQLITE_OK; /* Return code */ | 60916 | int rc = SQLITE_OK; /* Return code */ |
| 58588 | int tempFile = 0; /* True for temp files (incl. in-memory files) */ | 60917 | int tempFile = 0; /* True for temp files (incl. in-memory files) */ |
| 58589 | int memDb = 0; /* True if this is an in-memory file */ | 60918 | int memDb = 0; /* True if this is an in-memory file */ |
| 58590 | #ifndef SQLITE_OMIT_DESERIALIZE | ||
| 58591 | int memJM = 0; /* Memory journal mode */ | 60919 | int memJM = 0; /* Memory journal mode */ |
| 58592 | #else | ||
| 58593 | # define memJM 0 | ||
| 58594 | #endif | ||
| 58595 | int readOnly = 0; /* True if this is a read-only file */ | 60920 | int readOnly = 0; /* True if this is a read-only file */ |
| 58596 | int journalFileSize; /* Bytes to allocate for each journal fd */ | 60921 | int journalFileSize; /* Bytes to allocate for each journal fd */ |
| 58597 | char *zPathname = 0; /* Full path to database file */ | 60922 | char *zPathname = 0; /* Full path to database file */ |
| @@ -58601,7 +60926,6 @@ SQLITE_PRIVATE int sqlite3PagerOpen( | |||
| 58601 | u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ | 60926 | u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ |
| 58602 | const char *zUri = 0; /* URI args to copy */ | 60927 | const char *zUri = 0; /* URI args to copy */ |
| 58603 | int nUriByte = 1; /* Number of bytes of URI args at *zUri */ | 60928 | int nUriByte = 1; /* Number of bytes of URI args at *zUri */ |
| 58604 | int nUri = 0; /* Number of URI parameters */ | ||
| 58605 | 60929 | ||
| 58606 | /* Figure out how much space is required for each journal file-handle | 60930 | /* Figure out how much space is required for each journal file-handle |
| 58607 | ** (there are two of them, the main journal and the sub-journal). */ | 60931 | ** (there are two of them, the main journal and the sub-journal). */ |
| @@ -58649,7 +60973,6 @@ SQLITE_PRIVATE int sqlite3PagerOpen( | |||
| 58649 | while( *z ){ | 60973 | while( *z ){ |
| 58650 | z += strlen(z)+1; | 60974 | z += strlen(z)+1; |
| 58651 | z += strlen(z)+1; | 60975 | z += strlen(z)+1; |
| 58652 | nUri++; | ||
| 58653 | } | 60976 | } |
| 58654 | nUriByte = (int)(&z[1] - zUri); | 60977 | nUriByte = (int)(&z[1] - zUri); |
| 58655 | assert( nUriByte>=1 ); | 60978 | assert( nUriByte>=1 ); |
| @@ -58712,12 +61035,13 @@ SQLITE_PRIVATE int sqlite3PagerOpen( | |||
| 58712 | ** specific formatting and order of the various filenames, so if the format | 61035 | ** specific formatting and order of the various filenames, so if the format |
| 58713 | ** changes here, be sure to change it there as well. | 61036 | ** changes here, be sure to change it there as well. |
| 58714 | */ | 61037 | */ |
| 61038 | assert( SQLITE_PTRSIZE==sizeof(Pager*) ); | ||
| 58715 | pPtr = (u8 *)sqlite3MallocZero( | 61039 | pPtr = (u8 *)sqlite3MallocZero( |
| 58716 | ROUND8(sizeof(*pPager)) + /* Pager structure */ | 61040 | ROUND8(sizeof(*pPager)) + /* Pager structure */ |
| 58717 | ROUND8(pcacheSize) + /* PCache object */ | 61041 | ROUND8(pcacheSize) + /* PCache object */ |
| 58718 | ROUND8(pVfs->szOsFile) + /* The main db file */ | 61042 | ROUND8(pVfs->szOsFile) + /* The main db file */ |
| 58719 | journalFileSize * 2 + /* The two journal files */ | 61043 | journalFileSize * 2 + /* The two journal files */ |
| 58720 | sizeof(pPager) + /* Space to hold a pointer */ | 61044 | SQLITE_PTRSIZE + /* Space to hold a pointer */ |
| 58721 | 4 + /* Database prefix */ | 61045 | 4 + /* Database prefix */ |
| 58722 | nPathname + 1 + /* database filename */ | 61046 | nPathname + 1 + /* database filename */ |
| 58723 | nUriByte + /* query parameters */ | 61047 | nUriByte + /* query parameters */ |
| @@ -58738,7 +61062,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( | |||
| 58738 | pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; | 61062 | pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; |
| 58739 | pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; | 61063 | pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; |
| 58740 | assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); | 61064 | assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); |
| 58741 | memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); | 61065 | memcpy(pPtr, &pPager, SQLITE_PTRSIZE); pPtr += SQLITE_PTRSIZE; |
| 58742 | 61066 | ||
| 58743 | /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ | 61067 | /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ |
| 58744 | pPtr += 4; /* Skip zero prefix */ | 61068 | pPtr += 4; /* Skip zero prefix */ |
| @@ -58792,9 +61116,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( | |||
| 58792 | int fout = 0; /* VFS flags returned by xOpen() */ | 61116 | int fout = 0; /* VFS flags returned by xOpen() */ |
| 58793 | rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); | 61117 | rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); |
| 58794 | assert( !memDb ); | 61118 | assert( !memDb ); |
| 58795 | #ifndef SQLITE_OMIT_DESERIALIZE | ||
| 58796 | pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; | 61119 | pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; |
| 58797 | #endif | ||
| 58798 | readOnly = (fout&SQLITE_OPEN_READONLY)!=0; | 61120 | readOnly = (fout&SQLITE_OPEN_READONLY)!=0; |
| 58799 | 61121 | ||
| 58800 | /* If the file was successfully opened for read/write access, | 61122 | /* If the file was successfully opened for read/write access, |
| @@ -58905,18 +61227,7 @@ act_like_temp_file: | |||
| 58905 | pPager->memDb = (u8)memDb; | 61227 | pPager->memDb = (u8)memDb; |
| 58906 | pPager->readOnly = (u8)readOnly; | 61228 | pPager->readOnly = (u8)readOnly; |
| 58907 | assert( useJournal || pPager->tempFile ); | 61229 | assert( useJournal || pPager->tempFile ); |
| 58908 | pPager->noSync = pPager->tempFile; | 61230 | sqlite3PagerSetFlags(pPager, (SQLITE_DEFAULT_SYNCHRONOUS+1)|PAGER_CACHESPILL); |
| 58909 | if( pPager->noSync ){ | ||
| 58910 | assert( pPager->fullSync==0 ); | ||
| 58911 | assert( pPager->extraSync==0 ); | ||
| 58912 | assert( pPager->syncFlags==0 ); | ||
| 58913 | assert( pPager->walSyncFlags==0 ); | ||
| 58914 | }else{ | ||
| 58915 | pPager->fullSync = 1; | ||
| 58916 | pPager->extraSync = 0; | ||
| 58917 | pPager->syncFlags = SQLITE_SYNC_NORMAL; | ||
| 58918 | pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2); | ||
| 58919 | } | ||
| 58920 | /* pPager->pFirst = 0; */ | 61231 | /* pPager->pFirst = 0; */ |
| 58921 | /* pPager->pFirstSynced = 0; */ | 61232 | /* pPager->pFirstSynced = 0; */ |
| 58922 | /* pPager->pLast = 0; */ | 61233 | /* pPager->pLast = 0; */ |
| @@ -58942,7 +61253,7 @@ act_like_temp_file: | |||
| 58942 | 61253 | ||
| 58943 | /* | 61254 | /* |
| 58944 | ** Return the sqlite3_file for the main database given the name | 61255 | ** Return the sqlite3_file for the main database given the name |
| 58945 | ** of the corresonding WAL or Journal name as passed into | 61256 | ** of the corresponding WAL or Journal name as passed into |
| 58946 | ** xOpen. | 61257 | ** xOpen. |
| 58947 | */ | 61258 | */ |
| 58948 | SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ | 61259 | SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ |
| @@ -59445,6 +61756,10 @@ static int getPageNormal( | |||
| 59445 | if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){ | 61756 | if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){ |
| 59446 | if( pgno>pPager->mxPgno ){ | 61757 | if( pgno>pPager->mxPgno ){ |
| 59447 | rc = SQLITE_FULL; | 61758 | rc = SQLITE_FULL; |
| 61759 | if( pgno<=pPager->dbSize ){ | ||
| 61760 | sqlite3PcacheRelease(pPg); | ||
| 61761 | pPg = 0; | ||
| 61762 | } | ||
| 59448 | goto pager_acquire_err; | 61763 | goto pager_acquire_err; |
| 59449 | } | 61764 | } |
| 59450 | if( noContent ){ | 61765 | if( noContent ){ |
| @@ -59609,10 +61924,12 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ | |||
| 59609 | /* | 61924 | /* |
| 59610 | ** Release a page reference. | 61925 | ** Release a page reference. |
| 59611 | ** | 61926 | ** |
| 59612 | ** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be | 61927 | ** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be used |
| 59613 | ** used if we know that the page being released is not the last page. | 61928 | ** if we know that the page being released is not the last reference to page1. |
| 59614 | ** The btree layer always holds page1 open until the end, so these first | 61929 | ** The btree layer always holds page1 open until the end, so these first |
| 59615 | ** to routines can be used to release any page other than BtShared.pPage1. | 61930 | ** two routines can be used to release any page other than BtShared.pPage1. |
| 61931 | ** The assert() at tag-20230419-2 proves that this constraint is always | ||
| 61932 | ** honored. | ||
| 59616 | ** | 61933 | ** |
| 59617 | ** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine | 61934 | ** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine |
| 59618 | ** checks the total number of outstanding pages and if the number of | 61935 | ** checks the total number of outstanding pages and if the number of |
| @@ -59628,7 +61945,7 @@ SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ | |||
| 59628 | sqlite3PcacheRelease(pPg); | 61945 | sqlite3PcacheRelease(pPg); |
| 59629 | } | 61946 | } |
| 59630 | /* Do not use this routine to release the last reference to page1 */ | 61947 | /* Do not use this routine to release the last reference to page1 */ |
| 59631 | assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); | 61948 | assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); /* tag-20230419-2 */ |
| 59632 | } | 61949 | } |
| 59633 | SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ | 61950 | SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ |
| 59634 | if( pPg ) sqlite3PagerUnrefNotNull(pPg); | 61951 | if( pPg ) sqlite3PagerUnrefNotNull(pPg); |
| @@ -59694,6 +62011,7 @@ static int pager_open_journal(Pager *pPager){ | |||
| 59694 | 62011 | ||
| 59695 | if( pPager->tempFile ){ | 62012 | if( pPager->tempFile ){ |
| 59696 | flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); | 62013 | flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); |
| 62014 | flags |= SQLITE_OPEN_EXCLUSIVE; | ||
| 59697 | nSpill = sqlite3Config.nStmtSpill; | 62015 | nSpill = sqlite3Config.nStmtSpill; |
| 59698 | }else{ | 62016 | }else{ |
| 59699 | flags |= SQLITE_OPEN_MAIN_JOURNAL; | 62017 | flags |= SQLITE_OPEN_MAIN_JOURNAL; |
| @@ -60176,7 +62494,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ | |||
| 60176 | # define DIRECT_MODE isDirectMode | 62494 | # define DIRECT_MODE isDirectMode |
| 60177 | #endif | 62495 | #endif |
| 60178 | 62496 | ||
| 60179 | if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ | 62497 | if( !pPager->changeCountDone && pPager->dbSize>0 ){ |
| 60180 | PgHdr *pPgHdr; /* Reference to page 1 */ | 62498 | PgHdr *pPgHdr; /* Reference to page 1 */ |
| 60181 | 62499 | ||
| 60182 | assert( !pPager->tempFile && isOpen(pPager->fd) ); | 62500 | assert( !pPager->tempFile && isOpen(pPager->fd) ); |
| @@ -60916,7 +63234,11 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ | |||
| 60916 | */ | 63234 | */ |
| 60917 | SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ | 63235 | SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ |
| 60918 | static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | 63236 | static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 60919 | return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename; | 63237 | if( nullIfMemDb && (pPager->memDb || sqlite3IsMemdb(pPager->pVfs)) ){ |
| 63238 | return &zFake[4]; | ||
| 63239 | }else{ | ||
| 63240 | return pPager->zFilename; | ||
| 63241 | } | ||
| 60920 | } | 63242 | } |
| 60921 | 63243 | ||
| 60922 | /* | 63244 | /* |
| @@ -61216,7 +63538,7 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ | |||
| 61216 | assert( pPager->eState!=PAGER_ERROR ); | 63538 | assert( pPager->eState!=PAGER_ERROR ); |
| 61217 | pPager->journalMode = (u8)eMode; | 63539 | pPager->journalMode = (u8)eMode; |
| 61218 | 63540 | ||
| 61219 | /* When transistioning from TRUNCATE or PERSIST to any other journal | 63541 | /* When transitioning from TRUNCATE or PERSIST to any other journal |
| 61220 | ** mode except WAL, unless the pager is in locking_mode=exclusive mode, | 63542 | ** mode except WAL, unless the pager is in locking_mode=exclusive mode, |
| 61221 | ** delete the journal file. | 63543 | ** delete the journal file. |
| 61222 | */ | 63544 | */ |
| @@ -61285,7 +63607,7 @@ SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){ | |||
| 61285 | SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ | 63607 | SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ |
| 61286 | assert( assert_pager_state(pPager) ); | 63608 | assert( assert_pager_state(pPager) ); |
| 61287 | if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; | 63609 | if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; |
| 61288 | if( isOpen(pPager->jfd) && pPager->journalOff>0 ) return 0; | 63610 | if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; |
| 61289 | return 1; | 63611 | return 1; |
| 61290 | } | 63612 | } |
| 61291 | 63613 | ||
| @@ -61383,13 +63705,15 @@ SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ | |||
| 61383 | */ | 63705 | */ |
| 61384 | static int pagerExclusiveLock(Pager *pPager){ | 63706 | static int pagerExclusiveLock(Pager *pPager){ |
| 61385 | int rc; /* Return code */ | 63707 | int rc; /* Return code */ |
| 63708 | u8 eOrigLock; /* Original lock */ | ||
| 61386 | 63709 | ||
| 61387 | assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); | 63710 | assert( pPager->eLock>=SHARED_LOCK ); |
| 63711 | eOrigLock = pPager->eLock; | ||
| 61388 | rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); | 63712 | rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); |
| 61389 | if( rc!=SQLITE_OK ){ | 63713 | if( rc!=SQLITE_OK ){ |
| 61390 | /* If the attempt to grab the exclusive lock failed, release the | 63714 | /* If the attempt to grab the exclusive lock failed, release the |
| 61391 | ** pending lock that may have been obtained instead. */ | 63715 | ** pending lock that may have been obtained instead. */ |
| 61392 | pagerUnlockDb(pPager, SHARED_LOCK); | 63716 | pagerUnlockDb(pPager, eOrigLock); |
| 61393 | } | 63717 | } |
| 61394 | 63718 | ||
| 61395 | return rc; | 63719 | return rc; |
| @@ -61642,6 +63966,12 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ | |||
| 61642 | } | 63966 | } |
| 61643 | #endif | 63967 | #endif |
| 61644 | 63968 | ||
| 63969 | #ifdef SQLITE_USE_SEH | ||
| 63970 | SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ | ||
| 63971 | return sqlite3WalSystemErrno(pPager->pWal); | ||
| 63972 | } | ||
| 63973 | #endif | ||
| 63974 | |||
| 61645 | #endif /* SQLITE_OMIT_DISKIO */ | 63975 | #endif /* SQLITE_OMIT_DISKIO */ |
| 61646 | 63976 | ||
| 61647 | /************** End of pager.c ***********************************************/ | 63977 | /************** End of pager.c ***********************************************/ |
| @@ -61932,7 +64262,7 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0; | |||
| 61932 | ** | 64262 | ** |
| 61933 | ** Technically, the various VFSes are free to implement these locks however | 64263 | ** Technically, the various VFSes are free to implement these locks however |
| 61934 | ** they see fit. However, compatibility is encouraged so that VFSes can | 64264 | ** they see fit. However, compatibility is encouraged so that VFSes can |
| 61935 | ** interoperate. The standard implemention used on both unix and windows | 64265 | ** interoperate. The standard implementation used on both unix and windows |
| 61936 | ** is for the index number to indicate a byte offset into the | 64266 | ** is for the index number to indicate a byte offset into the |
| 61937 | ** WalCkptInfo.aLock[] array in the wal-index header. In other words, all | 64267 | ** WalCkptInfo.aLock[] array in the wal-index header. In other words, all |
| 61938 | ** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which | 64268 | ** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which |
| @@ -62008,7 +64338,7 @@ struct WalIndexHdr { | |||
| 62008 | ** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) | 64338 | ** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) |
| 62009 | ** for any aReadMark[] means that entry is unused. aReadMark[0] is | 64339 | ** for any aReadMark[] means that entry is unused. aReadMark[0] is |
| 62010 | ** a special case; its value is never used and it exists as a place-holder | 64340 | ** a special case; its value is never used and it exists as a place-holder |
| 62011 | ** to avoid having to offset aReadMark[] indexs by one. Readers holding | 64341 | ** to avoid having to offset aReadMark[] indexes by one. Readers holding |
| 62012 | ** WAL_READ_LOCK(0) always ignore the entire WAL and read all content | 64342 | ** WAL_READ_LOCK(0) always ignore the entire WAL and read all content |
| 62013 | ** directly from the database. | 64343 | ** directly from the database. |
| 62014 | ** | 64344 | ** |
| @@ -62176,7 +64506,15 @@ struct Wal { | |||
| 62176 | u32 iReCksum; /* On commit, recalculate checksums from here */ | 64506 | u32 iReCksum; /* On commit, recalculate checksums from here */ |
| 62177 | const char *zWalName; /* Name of WAL file */ | 64507 | const char *zWalName; /* Name of WAL file */ |
| 62178 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ | 64508 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ |
| 64509 | #ifdef SQLITE_USE_SEH | ||
| 64510 | u32 lockMask; /* Mask of locks held */ | ||
| 64511 | void *pFree; /* Pointer to sqlite3_free() if exception thrown */ | ||
| 64512 | u32 *pWiValue; /* Value to write into apWiData[iWiPg] */ | ||
| 64513 | int iWiPg; /* Write pWiValue into apWiData[iWiPg] */ | ||
| 64514 | int iSysErrno; /* System error code following exception */ | ||
| 64515 | #endif | ||
| 62179 | #ifdef SQLITE_DEBUG | 64516 | #ifdef SQLITE_DEBUG |
| 64517 | int nSehTry; /* Number of nested SEH_TRY{} blocks */ | ||
| 62180 | u8 lockError; /* True if a locking error has occurred */ | 64518 | u8 lockError; /* True if a locking error has occurred */ |
| 62181 | #endif | 64519 | #endif |
| 62182 | #ifdef SQLITE_ENABLE_SNAPSHOT | 64520 | #ifdef SQLITE_ENABLE_SNAPSHOT |
| @@ -62259,6 +64597,113 @@ struct WalIterator { | |||
| 62259 | ) | 64597 | ) |
| 62260 | 64598 | ||
| 62261 | /* | 64599 | /* |
| 64600 | ** Structured Exception Handling (SEH) is a Windows-specific technique | ||
| 64601 | ** for catching exceptions raised while accessing memory-mapped files. | ||
| 64602 | ** | ||
| 64603 | ** The -DSQLITE_USE_SEH compile-time option means to use SEH to catch and | ||
| 64604 | ** deal with system-level errors that arise during WAL -shm file processing. | ||
| 64605 | ** Without this compile-time option, any system-level faults that appear | ||
| 64606 | ** while accessing the memory-mapped -shm file will cause a process-wide | ||
| 64607 | ** signal to be deliver, which will more than likely cause the entire | ||
| 64608 | ** process to exit. | ||
| 64609 | */ | ||
| 64610 | #ifdef SQLITE_USE_SEH | ||
| 64611 | #include <Windows.h> | ||
| 64612 | |||
| 64613 | /* Beginning of a block of code in which an exception might occur */ | ||
| 64614 | # define SEH_TRY __try { \ | ||
| 64615 | assert( walAssertLockmask(pWal) && pWal->nSehTry==0 ); \ | ||
| 64616 | VVA_ONLY(pWal->nSehTry++); | ||
| 64617 | |||
| 64618 | /* The end of a block of code in which an exception might occur */ | ||
| 64619 | # define SEH_EXCEPT(X) \ | ||
| 64620 | VVA_ONLY(pWal->nSehTry--); \ | ||
| 64621 | assert( pWal->nSehTry==0 ); \ | ||
| 64622 | } __except( sehExceptionFilter(pWal, GetExceptionCode(), GetExceptionInformation() ) ){ X } | ||
| 64623 | |||
| 64624 | /* Simulate a memory-mapping fault in the -shm file for testing purposes */ | ||
| 64625 | # define SEH_INJECT_FAULT sehInjectFault(pWal) | ||
| 64626 | |||
| 64627 | /* | ||
| 64628 | ** The second argument is the return value of GetExceptionCode() for the | ||
| 64629 | ** current exception. Return EXCEPTION_EXECUTE_HANDLER if the exception code | ||
| 64630 | ** indicates that the exception may have been caused by accessing the *-shm | ||
| 64631 | ** file mapping. Or EXCEPTION_CONTINUE_SEARCH otherwise. | ||
| 64632 | */ | ||
| 64633 | static int sehExceptionFilter(Wal *pWal, int eCode, EXCEPTION_POINTERS *p){ | ||
| 64634 | VVA_ONLY(pWal->nSehTry--); | ||
| 64635 | if( eCode==EXCEPTION_IN_PAGE_ERROR ){ | ||
| 64636 | if( p && p->ExceptionRecord && p->ExceptionRecord->NumberParameters>=3 ){ | ||
| 64637 | /* From MSDN: For this type of exception, the first element of the | ||
| 64638 | ** ExceptionInformation[] array is a read-write flag - 0 if the exception | ||
| 64639 | ** was thrown while reading, 1 if while writing. The second element is | ||
| 64640 | ** the virtual address being accessed. The "third array element specifies | ||
| 64641 | ** the underlying NTSTATUS code that resulted in the exception". */ | ||
| 64642 | pWal->iSysErrno = (int)p->ExceptionRecord->ExceptionInformation[2]; | ||
| 64643 | } | ||
| 64644 | return EXCEPTION_EXECUTE_HANDLER; | ||
| 64645 | } | ||
| 64646 | return EXCEPTION_CONTINUE_SEARCH; | ||
| 64647 | } | ||
| 64648 | |||
| 64649 | /* | ||
| 64650 | ** If one is configured, invoke the xTestCallback callback with 650 as | ||
| 64651 | ** the argument. If it returns true, throw the same exception that is | ||
| 64652 | ** thrown by the system if the *-shm file mapping is accessed after it | ||
| 64653 | ** has been invalidated. | ||
| 64654 | */ | ||
| 64655 | static void sehInjectFault(Wal *pWal){ | ||
| 64656 | int res; | ||
| 64657 | assert( pWal->nSehTry>0 ); | ||
| 64658 | |||
| 64659 | res = sqlite3FaultSim(650); | ||
| 64660 | if( res!=0 ){ | ||
| 64661 | ULONG_PTR aArg[3]; | ||
| 64662 | aArg[0] = 0; | ||
| 64663 | aArg[1] = 0; | ||
| 64664 | aArg[2] = (ULONG_PTR)res; | ||
| 64665 | RaiseException(EXCEPTION_IN_PAGE_ERROR, 0, 3, (const ULONG_PTR*)aArg); | ||
| 64666 | } | ||
| 64667 | } | ||
| 64668 | |||
| 64669 | /* | ||
| 64670 | ** There are two ways to use this macro. To set a pointer to be freed | ||
| 64671 | ** if an exception is thrown: | ||
| 64672 | ** | ||
| 64673 | ** SEH_FREE_ON_ERROR(0, pPtr); | ||
| 64674 | ** | ||
| 64675 | ** and to cancel the same: | ||
| 64676 | ** | ||
| 64677 | ** SEH_FREE_ON_ERROR(pPtr, 0); | ||
| 64678 | ** | ||
| 64679 | ** In the first case, there must not already be a pointer registered to | ||
| 64680 | ** be freed. In the second case, pPtr must be the registered pointer. | ||
| 64681 | */ | ||
| 64682 | #define SEH_FREE_ON_ERROR(X,Y) \ | ||
| 64683 | assert( (X==0 || Y==0) && pWal->pFree==X ); pWal->pFree = Y | ||
| 64684 | |||
| 64685 | /* | ||
| 64686 | ** There are two ways to use this macro. To arrange for pWal->apWiData[iPg] | ||
| 64687 | ** to be set to pValue if an exception is thrown: | ||
| 64688 | ** | ||
| 64689 | ** SEH_SET_ON_ERROR(iPg, pValue); | ||
| 64690 | ** | ||
| 64691 | ** and to cancel the same: | ||
| 64692 | ** | ||
| 64693 | ** SEH_SET_ON_ERROR(0, 0); | ||
| 64694 | */ | ||
| 64695 | #define SEH_SET_ON_ERROR(X,Y) pWal->iWiPg = X; pWal->pWiValue = Y | ||
| 64696 | |||
| 64697 | #else | ||
| 64698 | # define SEH_TRY VVA_ONLY(pWal->nSehTry++); | ||
| 64699 | # define SEH_EXCEPT(X) VVA_ONLY(pWal->nSehTry--); assert( pWal->nSehTry==0 ); | ||
| 64700 | # define SEH_INJECT_FAULT assert( pWal->nSehTry>0 ); | ||
| 64701 | # define SEH_FREE_ON_ERROR(X,Y) | ||
| 64702 | # define SEH_SET_ON_ERROR(X,Y) | ||
| 64703 | #endif /* ifdef SQLITE_USE_SEH */ | ||
| 64704 | |||
| 64705 | |||
| 64706 | /* | ||
| 62262 | ** Obtain a pointer to the iPage'th page of the wal-index. The wal-index | 64707 | ** Obtain a pointer to the iPage'th page of the wal-index. The wal-index |
| 62263 | ** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are | 64708 | ** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are |
| 62264 | ** numbered from zero. | 64709 | ** numbered from zero. |
| @@ -62330,6 +64775,7 @@ static int walIndexPage( | |||
| 62330 | int iPage, /* The page we seek */ | 64775 | int iPage, /* The page we seek */ |
| 62331 | volatile u32 **ppPage /* Write the page pointer here */ | 64776 | volatile u32 **ppPage /* Write the page pointer here */ |
| 62332 | ){ | 64777 | ){ |
| 64778 | SEH_INJECT_FAULT; | ||
| 62333 | if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ | 64779 | if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ |
| 62334 | return walIndexPageRealloc(pWal, iPage, ppPage); | 64780 | return walIndexPageRealloc(pWal, iPage, ppPage); |
| 62335 | } | 64781 | } |
| @@ -62341,6 +64787,7 @@ static int walIndexPage( | |||
| 62341 | */ | 64787 | */ |
| 62342 | static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ | 64788 | static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ |
| 62343 | assert( pWal->nWiData>0 && pWal->apWiData[0] ); | 64789 | assert( pWal->nWiData>0 && pWal->apWiData[0] ); |
| 64790 | SEH_INJECT_FAULT; | ||
| 62344 | return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); | 64791 | return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); |
| 62345 | } | 64792 | } |
| 62346 | 64793 | ||
| @@ -62349,6 +64796,7 @@ static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ | |||
| 62349 | */ | 64796 | */ |
| 62350 | static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ | 64797 | static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ |
| 62351 | assert( pWal->nWiData>0 && pWal->apWiData[0] ); | 64798 | assert( pWal->nWiData>0 && pWal->apWiData[0] ); |
| 64799 | SEH_INJECT_FAULT; | ||
| 62352 | return (volatile WalIndexHdr*)pWal->apWiData[0]; | 64800 | return (volatile WalIndexHdr*)pWal->apWiData[0]; |
| 62353 | } | 64801 | } |
| 62354 | 64802 | ||
| @@ -62394,19 +64842,40 @@ static void walChecksumBytes( | |||
| 62394 | assert( nByte>=8 ); | 64842 | assert( nByte>=8 ); |
| 62395 | assert( (nByte&0x00000007)==0 ); | 64843 | assert( (nByte&0x00000007)==0 ); |
| 62396 | assert( nByte<=65536 ); | 64844 | assert( nByte<=65536 ); |
| 64845 | assert( nByte%4==0 ); | ||
| 62397 | 64846 | ||
| 62398 | if( nativeCksum ){ | 64847 | if( !nativeCksum ){ |
| 62399 | do { | 64848 | do { |
| 64849 | s1 += BYTESWAP32(aData[0]) + s2; | ||
| 64850 | s2 += BYTESWAP32(aData[1]) + s1; | ||
| 64851 | aData += 2; | ||
| 64852 | }while( aData<aEnd ); | ||
| 64853 | }else if( nByte%64==0 ){ | ||
| 64854 | do { | ||
| 64855 | s1 += *aData++ + s2; | ||
| 64856 | s2 += *aData++ + s1; | ||
| 64857 | s1 += *aData++ + s2; | ||
| 64858 | s2 += *aData++ + s1; | ||
| 64859 | s1 += *aData++ + s2; | ||
| 64860 | s2 += *aData++ + s1; | ||
| 64861 | s1 += *aData++ + s2; | ||
| 64862 | s2 += *aData++ + s1; | ||
| 64863 | s1 += *aData++ + s2; | ||
| 64864 | s2 += *aData++ + s1; | ||
| 64865 | s1 += *aData++ + s2; | ||
| 64866 | s2 += *aData++ + s1; | ||
| 64867 | s1 += *aData++ + s2; | ||
| 64868 | s2 += *aData++ + s1; | ||
| 62400 | s1 += *aData++ + s2; | 64869 | s1 += *aData++ + s2; |
| 62401 | s2 += *aData++ + s1; | 64870 | s2 += *aData++ + s1; |
| 62402 | }while( aData<aEnd ); | 64871 | }while( aData<aEnd ); |
| 62403 | }else{ | 64872 | }else{ |
| 62404 | do { | 64873 | do { |
| 62405 | s1 += BYTESWAP32(aData[0]) + s2; | 64874 | s1 += *aData++ + s2; |
| 62406 | s2 += BYTESWAP32(aData[1]) + s1; | 64875 | s2 += *aData++ + s1; |
| 62407 | aData += 2; | ||
| 62408 | }while( aData<aEnd ); | 64876 | }while( aData<aEnd ); |
| 62409 | } | 64877 | } |
| 64878 | assert( aData==aEnd ); | ||
| 62410 | 64879 | ||
| 62411 | aOut[0] = s1; | 64880 | aOut[0] = s1; |
| 62412 | aOut[1] = s2; | 64881 | aOut[1] = s2; |
| @@ -62517,7 +64986,7 @@ static int walDecodeFrame( | |||
| 62517 | return 0; | 64986 | return 0; |
| 62518 | } | 64987 | } |
| 62519 | 64988 | ||
| 62520 | /* A frame is only valid if the page number is creater than zero. | 64989 | /* A frame is only valid if the page number is greater than zero. |
| 62521 | */ | 64990 | */ |
| 62522 | pgno = sqlite3Get4byte(&aFrame[0]); | 64991 | pgno = sqlite3Get4byte(&aFrame[0]); |
| 62523 | if( pgno==0 ){ | 64992 | if( pgno==0 ){ |
| @@ -62525,7 +64994,7 @@ static int walDecodeFrame( | |||
| 62525 | } | 64994 | } |
| 62526 | 64995 | ||
| 62527 | /* A frame is only valid if a checksum of the WAL header, | 64996 | /* A frame is only valid if a checksum of the WAL header, |
| 62528 | ** all prior frams, the first 16 bytes of this frame-header, | 64997 | ** all prior frames, the first 16 bytes of this frame-header, |
| 62529 | ** and the frame-data matches the checksum in the last 8 | 64998 | ** and the frame-data matches the checksum in the last 8 |
| 62530 | ** bytes of this frame-header. | 64999 | ** bytes of this frame-header. |
| 62531 | */ | 65000 | */ |
| @@ -62585,12 +65054,18 @@ static int walLockShared(Wal *pWal, int lockIdx){ | |||
| 62585 | WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, | 65054 | WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, |
| 62586 | walLockName(lockIdx), rc ? "failed" : "ok")); | 65055 | walLockName(lockIdx), rc ? "failed" : "ok")); |
| 62587 | VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) | 65056 | VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) |
| 65057 | #ifdef SQLITE_USE_SEH | ||
| 65058 | if( rc==SQLITE_OK ) pWal->lockMask |= (1 << lockIdx); | ||
| 65059 | #endif | ||
| 62588 | return rc; | 65060 | return rc; |
| 62589 | } | 65061 | } |
| 62590 | static void walUnlockShared(Wal *pWal, int lockIdx){ | 65062 | static void walUnlockShared(Wal *pWal, int lockIdx){ |
| 62591 | if( pWal->exclusiveMode ) return; | 65063 | if( pWal->exclusiveMode ) return; |
| 62592 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, | 65064 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, |
| 62593 | SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); | 65065 | SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); |
| 65066 | #ifdef SQLITE_USE_SEH | ||
| 65067 | pWal->lockMask &= ~(1 << lockIdx); | ||
| 65068 | #endif | ||
| 62594 | WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); | 65069 | WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); |
| 62595 | } | 65070 | } |
| 62596 | static int walLockExclusive(Wal *pWal, int lockIdx, int n){ | 65071 | static int walLockExclusive(Wal *pWal, int lockIdx, int n){ |
| @@ -62601,12 +65076,20 @@ static int walLockExclusive(Wal *pWal, int lockIdx, int n){ | |||
| 62601 | WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, | 65076 | WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, |
| 62602 | walLockName(lockIdx), n, rc ? "failed" : "ok")); | 65077 | walLockName(lockIdx), n, rc ? "failed" : "ok")); |
| 62603 | VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) | 65078 | VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) |
| 65079 | #ifdef SQLITE_USE_SEH | ||
| 65080 | if( rc==SQLITE_OK ){ | ||
| 65081 | pWal->lockMask |= (((1<<n)-1) << (SQLITE_SHM_NLOCK+lockIdx)); | ||
| 65082 | } | ||
| 65083 | #endif | ||
| 62604 | return rc; | 65084 | return rc; |
| 62605 | } | 65085 | } |
| 62606 | static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ | 65086 | static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ |
| 62607 | if( pWal->exclusiveMode ) return; | 65087 | if( pWal->exclusiveMode ) return; |
| 62608 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, | 65088 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, |
| 62609 | SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); | 65089 | SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); |
| 65090 | #ifdef SQLITE_USE_SEH | ||
| 65091 | pWal->lockMask &= ~(((1<<n)-1) << (SQLITE_SHM_NLOCK+lockIdx)); | ||
| 65092 | #endif | ||
| 62610 | WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, | 65093 | WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, |
| 62611 | walLockName(lockIdx), n)); | 65094 | walLockName(lockIdx), n)); |
| 62612 | } | 65095 | } |
| @@ -62698,6 +65181,7 @@ static int walFramePage(u32 iFrame){ | |||
| 62698 | */ | 65181 | */ |
| 62699 | static u32 walFramePgno(Wal *pWal, u32 iFrame){ | 65182 | static u32 walFramePgno(Wal *pWal, u32 iFrame){ |
| 62700 | int iHash = walFramePage(iFrame); | 65183 | int iHash = walFramePage(iFrame); |
| 65184 | SEH_INJECT_FAULT; | ||
| 62701 | if( iHash==0 ){ | 65185 | if( iHash==0 ){ |
| 62702 | return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; | 65186 | return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; |
| 62703 | } | 65187 | } |
| @@ -62957,6 +65441,7 @@ static int walIndexRecover(Wal *pWal){ | |||
| 62957 | /* Malloc a buffer to read frames into. */ | 65441 | /* Malloc a buffer to read frames into. */ |
| 62958 | szFrame = szPage + WAL_FRAME_HDRSIZE; | 65442 | szFrame = szPage + WAL_FRAME_HDRSIZE; |
| 62959 | aFrame = (u8 *)sqlite3_malloc64(szFrame + WALINDEX_PGSZ); | 65443 | aFrame = (u8 *)sqlite3_malloc64(szFrame + WALINDEX_PGSZ); |
| 65444 | SEH_FREE_ON_ERROR(0, aFrame); | ||
| 62960 | if( !aFrame ){ | 65445 | if( !aFrame ){ |
| 62961 | rc = SQLITE_NOMEM_BKPT; | 65446 | rc = SQLITE_NOMEM_BKPT; |
| 62962 | goto recovery_error; | 65447 | goto recovery_error; |
| @@ -62975,6 +65460,7 @@ static int walIndexRecover(Wal *pWal){ | |||
| 62975 | rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); | 65460 | rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); |
| 62976 | assert( aShare!=0 || rc!=SQLITE_OK ); | 65461 | assert( aShare!=0 || rc!=SQLITE_OK ); |
| 62977 | if( aShare==0 ) break; | 65462 | if( aShare==0 ) break; |
| 65463 | SEH_SET_ON_ERROR(iPg, aShare); | ||
| 62978 | pWal->apWiData[iPg] = aPrivate; | 65464 | pWal->apWiData[iPg] = aPrivate; |
| 62979 | 65465 | ||
| 62980 | for(iFrame=iFirst; iFrame<=iLast; iFrame++){ | 65466 | for(iFrame=iFirst; iFrame<=iLast; iFrame++){ |
| @@ -63002,6 +65488,7 @@ static int walIndexRecover(Wal *pWal){ | |||
| 63002 | } | 65488 | } |
| 63003 | } | 65489 | } |
| 63004 | pWal->apWiData[iPg] = aShare; | 65490 | pWal->apWiData[iPg] = aShare; |
| 65491 | SEH_SET_ON_ERROR(0,0); | ||
| 63005 | nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0); | 65492 | nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0); |
| 63006 | nHdr32 = nHdr / sizeof(u32); | 65493 | nHdr32 = nHdr / sizeof(u32); |
| 63007 | #ifndef SQLITE_SAFER_WALINDEX_RECOVERY | 65494 | #ifndef SQLITE_SAFER_WALINDEX_RECOVERY |
| @@ -63032,9 +65519,11 @@ static int walIndexRecover(Wal *pWal){ | |||
| 63032 | } | 65519 | } |
| 63033 | } | 65520 | } |
| 63034 | #endif | 65521 | #endif |
| 65522 | SEH_INJECT_FAULT; | ||
| 63035 | if( iFrame<=iLast ) break; | 65523 | if( iFrame<=iLast ) break; |
| 63036 | } | 65524 | } |
| 63037 | 65525 | ||
| 65526 | SEH_FREE_ON_ERROR(aFrame, 0); | ||
| 63038 | sqlite3_free(aFrame); | 65527 | sqlite3_free(aFrame); |
| 63039 | } | 65528 | } |
| 63040 | 65529 | ||
| @@ -63062,6 +65551,7 @@ finished: | |||
| 63062 | }else{ | 65551 | }else{ |
| 63063 | pInfo->aReadMark[i] = READMARK_NOT_USED; | 65552 | pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 63064 | } | 65553 | } |
| 65554 | SEH_INJECT_FAULT; | ||
| 63065 | walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); | 65555 | walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 63066 | }else if( rc!=SQLITE_BUSY ){ | 65556 | }else if( rc!=SQLITE_BUSY ){ |
| 63067 | goto recovery_error; | 65557 | goto recovery_error; |
| @@ -63219,7 +65709,7 @@ SQLITE_PRIVATE int sqlite3WalOpen( | |||
| 63219 | } | 65709 | } |
| 63220 | 65710 | ||
| 63221 | /* | 65711 | /* |
| 63222 | ** Change the size to which the WAL file is trucated on each reset. | 65712 | ** Change the size to which the WAL file is truncated on each reset. |
| 63223 | */ | 65713 | */ |
| 63224 | SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ | 65714 | SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ |
| 63225 | if( pWal ) pWal->mxWalSize = iLimit; | 65715 | if( pWal ) pWal->mxWalSize = iLimit; |
| @@ -63445,23 +65935,16 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ | |||
| 63445 | nByte = sizeof(WalIterator) | 65935 | nByte = sizeof(WalIterator) |
| 63446 | + (nSegment-1)*sizeof(struct WalSegment) | 65936 | + (nSegment-1)*sizeof(struct WalSegment) |
| 63447 | + iLast*sizeof(ht_slot); | 65937 | + iLast*sizeof(ht_slot); |
| 63448 | p = (WalIterator *)sqlite3_malloc64(nByte); | 65938 | p = (WalIterator *)sqlite3_malloc64(nByte |
| 65939 | + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) | ||
| 65940 | ); | ||
| 63449 | if( !p ){ | 65941 | if( !p ){ |
| 63450 | return SQLITE_NOMEM_BKPT; | 65942 | return SQLITE_NOMEM_BKPT; |
| 63451 | } | 65943 | } |
| 63452 | memset(p, 0, nByte); | 65944 | memset(p, 0, nByte); |
| 63453 | p->nSegment = nSegment; | 65945 | p->nSegment = nSegment; |
| 63454 | 65946 | aTmp = (ht_slot*)&(((u8*)p)[nByte]); | |
| 63455 | /* Allocate temporary space used by the merge-sort routine. This block | 65947 | SEH_FREE_ON_ERROR(0, p); |
| 63456 | ** of memory will be freed before this function returns. | ||
| 63457 | */ | ||
| 63458 | aTmp = (ht_slot *)sqlite3_malloc64( | ||
| 63459 | sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) | ||
| 63460 | ); | ||
| 63461 | if( !aTmp ){ | ||
| 63462 | rc = SQLITE_NOMEM_BKPT; | ||
| 63463 | } | ||
| 63464 | |||
| 63465 | for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){ | 65948 | for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){ |
| 63466 | WalHashLoc sLoc; | 65949 | WalHashLoc sLoc; |
| 63467 | 65950 | ||
| @@ -63489,9 +65972,8 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ | |||
| 63489 | p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; | 65972 | p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; |
| 63490 | } | 65973 | } |
| 63491 | } | 65974 | } |
| 63492 | sqlite3_free(aTmp); | ||
| 63493 | |||
| 63494 | if( rc!=SQLITE_OK ){ | 65975 | if( rc!=SQLITE_OK ){ |
| 65976 | SEH_FREE_ON_ERROR(p, 0); | ||
| 63495 | walIteratorFree(p); | 65977 | walIteratorFree(p); |
| 63496 | p = 0; | 65978 | p = 0; |
| 63497 | } | 65979 | } |
| @@ -63717,13 +66199,13 @@ static int walCheckpoint( | |||
| 63717 | mxSafeFrame = pWal->hdr.mxFrame; | 66199 | mxSafeFrame = pWal->hdr.mxFrame; |
| 63718 | mxPage = pWal->hdr.nPage; | 66200 | mxPage = pWal->hdr.nPage; |
| 63719 | for(i=1; i<WAL_NREADER; i++){ | 66201 | for(i=1; i<WAL_NREADER; i++){ |
| 63720 | u32 y = AtomicLoad(pInfo->aReadMark+i); | 66202 | u32 y = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; |
| 63721 | if( mxSafeFrame>y ){ | 66203 | if( mxSafeFrame>y ){ |
| 63722 | assert( y<=pWal->hdr.mxFrame ); | 66204 | assert( y<=pWal->hdr.mxFrame ); |
| 63723 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); | 66205 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); |
| 63724 | if( rc==SQLITE_OK ){ | 66206 | if( rc==SQLITE_OK ){ |
| 63725 | u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED); | 66207 | u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED); |
| 63726 | AtomicStore(pInfo->aReadMark+i, iMark); | 66208 | AtomicStore(pInfo->aReadMark+i, iMark); SEH_INJECT_FAULT; |
| 63727 | walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); | 66209 | walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 63728 | }else if( rc==SQLITE_BUSY ){ | 66210 | }else if( rc==SQLITE_BUSY ){ |
| 63729 | mxSafeFrame = y; | 66211 | mxSafeFrame = y; |
| @@ -63744,8 +66226,7 @@ static int walCheckpoint( | |||
| 63744 | && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK | 66226 | && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK |
| 63745 | ){ | 66227 | ){ |
| 63746 | u32 nBackfill = pInfo->nBackfill; | 66228 | u32 nBackfill = pInfo->nBackfill; |
| 63747 | 66229 | pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; | |
| 63748 | pInfo->nBackfillAttempted = mxSafeFrame; | ||
| 63749 | 66230 | ||
| 63750 | /* Sync the WAL to disk */ | 66231 | /* Sync the WAL to disk */ |
| 63751 | rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); | 66232 | rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); |
| @@ -63776,6 +66257,7 @@ static int walCheckpoint( | |||
| 63776 | while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ | 66257 | while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ |
| 63777 | i64 iOffset; | 66258 | i64 iOffset; |
| 63778 | assert( walFramePgno(pWal, iFrame)==iDbpage ); | 66259 | assert( walFramePgno(pWal, iFrame)==iDbpage ); |
| 66260 | SEH_INJECT_FAULT; | ||
| 63779 | if( AtomicLoad(&db->u1.isInterrupted) ){ | 66261 | if( AtomicLoad(&db->u1.isInterrupted) ){ |
| 63780 | rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; | 66262 | rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; |
| 63781 | break; | 66263 | break; |
| @@ -63805,7 +66287,7 @@ static int walCheckpoint( | |||
| 63805 | } | 66287 | } |
| 63806 | } | 66288 | } |
| 63807 | if( rc==SQLITE_OK ){ | 66289 | if( rc==SQLITE_OK ){ |
| 63808 | AtomicStore(&pInfo->nBackfill, mxSafeFrame); | 66290 | AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; |
| 63809 | } | 66291 | } |
| 63810 | } | 66292 | } |
| 63811 | 66293 | ||
| @@ -63827,6 +66309,7 @@ static int walCheckpoint( | |||
| 63827 | */ | 66309 | */ |
| 63828 | if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ | 66310 | if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ |
| 63829 | assert( pWal->writeLock ); | 66311 | assert( pWal->writeLock ); |
| 66312 | SEH_INJECT_FAULT; | ||
| 63830 | if( pInfo->nBackfill<pWal->hdr.mxFrame ){ | 66313 | if( pInfo->nBackfill<pWal->hdr.mxFrame ){ |
| 63831 | rc = SQLITE_BUSY; | 66314 | rc = SQLITE_BUSY; |
| 63832 | }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ | 66315 | }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ |
| @@ -63858,6 +66341,7 @@ static int walCheckpoint( | |||
| 63858 | } | 66341 | } |
| 63859 | 66342 | ||
| 63860 | walcheckpoint_out: | 66343 | walcheckpoint_out: |
| 66344 | SEH_FREE_ON_ERROR(pIter, 0); | ||
| 63861 | walIteratorFree(pIter); | 66345 | walIteratorFree(pIter); |
| 63862 | return rc; | 66346 | return rc; |
| 63863 | } | 66347 | } |
| @@ -63880,6 +66364,93 @@ static void walLimitSize(Wal *pWal, i64 nMax){ | |||
| 63880 | } | 66364 | } |
| 63881 | } | 66365 | } |
| 63882 | 66366 | ||
| 66367 | #ifdef SQLITE_USE_SEH | ||
| 66368 | /* | ||
| 66369 | ** This is the "standard" exception handler used in a few places to handle | ||
| 66370 | ** an exception thrown by reading from the *-shm mapping after it has become | ||
| 66371 | ** invalid in SQLITE_USE_SEH builds. It is used as follows: | ||
| 66372 | ** | ||
| 66373 | ** SEH_TRY { ... } | ||
| 66374 | ** SEH_EXCEPT( rc = walHandleException(pWal); ) | ||
| 66375 | ** | ||
| 66376 | ** This function does three things: | ||
| 66377 | ** | ||
| 66378 | ** 1) Determines the locks that should be held, based on the contents of | ||
| 66379 | ** the Wal.readLock, Wal.writeLock and Wal.ckptLock variables. All other | ||
| 66380 | ** held locks are assumed to be transient locks that would have been | ||
| 66381 | ** released had the exception not been thrown and are dropped. | ||
| 66382 | ** | ||
| 66383 | ** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free(). | ||
| 66384 | ** | ||
| 66385 | ** 3) Set pWal->apWiData[pWal->iWiPg] to pWal->pWiValue if not NULL | ||
| 66386 | ** | ||
| 66387 | ** 4) Returns SQLITE_IOERR. | ||
| 66388 | */ | ||
| 66389 | static int walHandleException(Wal *pWal){ | ||
| 66390 | if( pWal->exclusiveMode==0 ){ | ||
| 66391 | static const int S = 1; | ||
| 66392 | static const int E = (1<<SQLITE_SHM_NLOCK); | ||
| 66393 | int ii; | ||
| 66394 | u32 mUnlock = pWal->lockMask & ~( | ||
| 66395 | (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) | ||
| 66396 | | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) | ||
| 66397 | | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) | ||
| 66398 | ); | ||
| 66399 | for(ii=0; ii<SQLITE_SHM_NLOCK; ii++){ | ||
| 66400 | if( (S<<ii) & mUnlock ) walUnlockShared(pWal, ii); | ||
| 66401 | if( (E<<ii) & mUnlock ) walUnlockExclusive(pWal, ii, 1); | ||
| 66402 | } | ||
| 66403 | } | ||
| 66404 | sqlite3_free(pWal->pFree); | ||
| 66405 | pWal->pFree = 0; | ||
| 66406 | if( pWal->pWiValue ){ | ||
| 66407 | pWal->apWiData[pWal->iWiPg] = pWal->pWiValue; | ||
| 66408 | pWal->pWiValue = 0; | ||
| 66409 | } | ||
| 66410 | return SQLITE_IOERR_IN_PAGE; | ||
| 66411 | } | ||
| 66412 | |||
| 66413 | /* | ||
| 66414 | ** Assert that the Wal.lockMask mask, which indicates the locks held | ||
| 66415 | ** by the connenction, is consistent with the Wal.readLock, Wal.writeLock | ||
| 66416 | ** and Wal.ckptLock variables. To be used as: | ||
| 66417 | ** | ||
| 66418 | ** assert( walAssertLockmask(pWal) ); | ||
| 66419 | */ | ||
| 66420 | static int walAssertLockmask(Wal *pWal){ | ||
| 66421 | if( pWal->exclusiveMode==0 ){ | ||
| 66422 | static const int S = 1; | ||
| 66423 | static const int E = (1<<SQLITE_SHM_NLOCK); | ||
| 66424 | u32 mExpect = ( | ||
| 66425 | (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) | ||
| 66426 | | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) | ||
| 66427 | | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) | ||
| 66428 | #ifdef SQLITE_ENABLE_SNAPSHOT | ||
| 66429 | | (pWal->pSnapshot ? (pWal->lockMask & (1 << WAL_CKPT_LOCK)) : 0) | ||
| 66430 | #endif | ||
| 66431 | ); | ||
| 66432 | assert( mExpect==pWal->lockMask ); | ||
| 66433 | } | ||
| 66434 | return 1; | ||
| 66435 | } | ||
| 66436 | |||
| 66437 | /* | ||
| 66438 | ** Return and zero the "system error" field set when an | ||
| 66439 | ** EXCEPTION_IN_PAGE_ERROR exception is caught. | ||
| 66440 | */ | ||
| 66441 | SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal *pWal){ | ||
| 66442 | int iRet = 0; | ||
| 66443 | if( pWal ){ | ||
| 66444 | iRet = pWal->iSysErrno; | ||
| 66445 | pWal->iSysErrno = 0; | ||
| 66446 | } | ||
| 66447 | return iRet; | ||
| 66448 | } | ||
| 66449 | |||
| 66450 | #else | ||
| 66451 | # define walAssertLockmask(x) 1 | ||
| 66452 | #endif /* ifdef SQLITE_USE_SEH */ | ||
| 66453 | |||
| 63883 | /* | 66454 | /* |
| 63884 | ** Close a connection to a log file. | 66455 | ** Close a connection to a log file. |
| 63885 | */ | 66456 | */ |
| @@ -63894,6 +66465,8 @@ SQLITE_PRIVATE int sqlite3WalClose( | |||
| 63894 | if( pWal ){ | 66465 | if( pWal ){ |
| 63895 | int isDelete = 0; /* True to unlink wal and wal-index files */ | 66466 | int isDelete = 0; /* True to unlink wal and wal-index files */ |
| 63896 | 66467 | ||
| 66468 | assert( walAssertLockmask(pWal) ); | ||
| 66469 | |||
| 63897 | /* If an EXCLUSIVE lock can be obtained on the database file (using the | 66470 | /* If an EXCLUSIVE lock can be obtained on the database file (using the |
| 63898 | ** ordinary, rollback-mode locking methods, this guarantees that the | 66471 | ** ordinary, rollback-mode locking methods, this guarantees that the |
| 63899 | ** connection associated with this log file is the only connection to | 66472 | ** connection associated with this log file is the only connection to |
| @@ -63918,7 +66491,7 @@ SQLITE_PRIVATE int sqlite3WalClose( | |||
| 63918 | ); | 66491 | ); |
| 63919 | if( bPersist!=1 ){ | 66492 | if( bPersist!=1 ){ |
| 63920 | /* Try to delete the WAL file if the checkpoint completed and | 66493 | /* Try to delete the WAL file if the checkpoint completed and |
| 63921 | ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal | 66494 | ** fsynced (rc==SQLITE_OK) and if we are not in persistent-wal |
| 63922 | ** mode (!bPersist) */ | 66495 | ** mode (!bPersist) */ |
| 63923 | isDelete = 1; | 66496 | isDelete = 1; |
| 63924 | }else if( pWal->mxWalSize>=0 ){ | 66497 | }else if( pWal->mxWalSize>=0 ){ |
| @@ -63985,7 +66558,7 @@ static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){ | |||
| 63985 | ** give false-positive warnings about these accesses because the tools do not | 66558 | ** give false-positive warnings about these accesses because the tools do not |
| 63986 | ** account for the double-read and the memory barrier. The use of mutexes | 66559 | ** account for the double-read and the memory barrier. The use of mutexes |
| 63987 | ** here would be problematic as the memory being accessed is potentially | 66560 | ** here would be problematic as the memory being accessed is potentially |
| 63988 | ** shared among multiple processes and not all mutex implementions work | 66561 | ** shared among multiple processes and not all mutex implementations work |
| 63989 | ** reliably in that environment. | 66562 | ** reliably in that environment. |
| 63990 | */ | 66563 | */ |
| 63991 | aHdr = walIndexHdr(pWal); | 66564 | aHdr = walIndexHdr(pWal); |
| @@ -64436,6 +67009,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ | |||
| 64436 | assert( pWal->nWiData>0 ); | 67009 | assert( pWal->nWiData>0 ); |
| 64437 | assert( pWal->apWiData[0]!=0 ); | 67010 | assert( pWal->apWiData[0]!=0 ); |
| 64438 | pInfo = walCkptInfo(pWal); | 67011 | pInfo = walCkptInfo(pWal); |
| 67012 | SEH_INJECT_FAULT; | ||
| 64439 | if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame | 67013 | if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame |
| 64440 | #ifdef SQLITE_ENABLE_SNAPSHOT | 67014 | #ifdef SQLITE_ENABLE_SNAPSHOT |
| 64441 | && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) | 67015 | && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) |
| @@ -64485,7 +67059,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ | |||
| 64485 | } | 67059 | } |
| 64486 | #endif | 67060 | #endif |
| 64487 | for(i=1; i<WAL_NREADER; i++){ | 67061 | for(i=1; i<WAL_NREADER; i++){ |
| 64488 | u32 thisMark = AtomicLoad(pInfo->aReadMark+i); | 67062 | u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; |
| 64489 | if( mxReadMark<=thisMark && thisMark<=mxFrame ){ | 67063 | if( mxReadMark<=thisMark && thisMark<=mxFrame ){ |
| 64490 | assert( thisMark!=READMARK_NOT_USED ); | 67064 | assert( thisMark!=READMARK_NOT_USED ); |
| 64491 | mxReadMark = thisMark; | 67065 | mxReadMark = thisMark; |
| @@ -64551,7 +67125,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ | |||
| 64551 | ** we can guarantee that the checkpointer that set nBackfill could not | 67125 | ** we can guarantee that the checkpointer that set nBackfill could not |
| 64552 | ** see any pages past pWal->hdr.mxFrame, this problem does not come up. | 67126 | ** see any pages past pWal->hdr.mxFrame, this problem does not come up. |
| 64553 | */ | 67127 | */ |
| 64554 | pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; | 67128 | pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; |
| 64555 | walShmBarrier(pWal); | 67129 | walShmBarrier(pWal); |
| 64556 | if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark | 67130 | if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark |
| 64557 | || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) | 67131 | || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) |
| @@ -64567,6 +67141,54 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ | |||
| 64567 | 67141 | ||
| 64568 | #ifdef SQLITE_ENABLE_SNAPSHOT | 67142 | #ifdef SQLITE_ENABLE_SNAPSHOT |
| 64569 | /* | 67143 | /* |
| 67144 | ** This function does the work of sqlite3WalSnapshotRecover(). | ||
| 67145 | */ | ||
| 67146 | static int walSnapshotRecover( | ||
| 67147 | Wal *pWal, /* WAL handle */ | ||
| 67148 | void *pBuf1, /* Temp buffer pWal->szPage bytes in size */ | ||
| 67149 | void *pBuf2 /* Temp buffer pWal->szPage bytes in size */ | ||
| 67150 | ){ | ||
| 67151 | int szPage = (int)pWal->szPage; | ||
| 67152 | int rc; | ||
| 67153 | i64 szDb; /* Size of db file in bytes */ | ||
| 67154 | |||
| 67155 | rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); | ||
| 67156 | if( rc==SQLITE_OK ){ | ||
| 67157 | volatile WalCkptInfo *pInfo = walCkptInfo(pWal); | ||
| 67158 | u32 i = pInfo->nBackfillAttempted; | ||
| 67159 | for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){ | ||
| 67160 | WalHashLoc sLoc; /* Hash table location */ | ||
| 67161 | u32 pgno; /* Page number in db file */ | ||
| 67162 | i64 iDbOff; /* Offset of db file entry */ | ||
| 67163 | i64 iWalOff; /* Offset of wal file entry */ | ||
| 67164 | |||
| 67165 | rc = walHashGet(pWal, walFramePage(i), &sLoc); | ||
| 67166 | if( rc!=SQLITE_OK ) break; | ||
| 67167 | assert( i - sLoc.iZero - 1 >=0 ); | ||
| 67168 | pgno = sLoc.aPgno[i-sLoc.iZero-1]; | ||
| 67169 | iDbOff = (i64)(pgno-1) * szPage; | ||
| 67170 | |||
| 67171 | if( iDbOff+szPage<=szDb ){ | ||
| 67172 | iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; | ||
| 67173 | rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); | ||
| 67174 | |||
| 67175 | if( rc==SQLITE_OK ){ | ||
| 67176 | rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); | ||
| 67177 | } | ||
| 67178 | |||
| 67179 | if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ | ||
| 67180 | break; | ||
| 67181 | } | ||
| 67182 | } | ||
| 67183 | |||
| 67184 | pInfo->nBackfillAttempted = i-1; | ||
| 67185 | } | ||
| 67186 | } | ||
| 67187 | |||
| 67188 | return rc; | ||
| 67189 | } | ||
| 67190 | |||
| 67191 | /* | ||
| 64570 | ** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted | 67192 | ** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted |
| 64571 | ** variable so that older snapshots can be accessed. To do this, loop | 67193 | ** variable so that older snapshots can be accessed. To do this, loop |
| 64572 | ** through all wal frames from nBackfillAttempted to (nBackfill+1), | 67194 | ** through all wal frames from nBackfillAttempted to (nBackfill+1), |
| @@ -64591,50 +67213,21 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ | |||
| 64591 | assert( pWal->readLock>=0 ); | 67213 | assert( pWal->readLock>=0 ); |
| 64592 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); | 67214 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 64593 | if( rc==SQLITE_OK ){ | 67215 | if( rc==SQLITE_OK ){ |
| 64594 | volatile WalCkptInfo *pInfo = walCkptInfo(pWal); | 67216 | void *pBuf1 = sqlite3_malloc(pWal->szPage); |
| 64595 | int szPage = (int)pWal->szPage; | 67217 | void *pBuf2 = sqlite3_malloc(pWal->szPage); |
| 64596 | i64 szDb; /* Size of db file in bytes */ | 67218 | if( pBuf1==0 || pBuf2==0 ){ |
| 64597 | 67219 | rc = SQLITE_NOMEM; | |
| 64598 | rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); | 67220 | }else{ |
| 64599 | if( rc==SQLITE_OK ){ | 67221 | pWal->ckptLock = 1; |
| 64600 | void *pBuf1 = sqlite3_malloc(szPage); | 67222 | SEH_TRY { |
| 64601 | void *pBuf2 = sqlite3_malloc(szPage); | 67223 | rc = walSnapshotRecover(pWal, pBuf1, pBuf2); |
| 64602 | if( pBuf1==0 || pBuf2==0 ){ | ||
| 64603 | rc = SQLITE_NOMEM; | ||
| 64604 | }else{ | ||
| 64605 | u32 i = pInfo->nBackfillAttempted; | ||
| 64606 | for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){ | ||
| 64607 | WalHashLoc sLoc; /* Hash table location */ | ||
| 64608 | u32 pgno; /* Page number in db file */ | ||
| 64609 | i64 iDbOff; /* Offset of db file entry */ | ||
| 64610 | i64 iWalOff; /* Offset of wal file entry */ | ||
| 64611 | |||
| 64612 | rc = walHashGet(pWal, walFramePage(i), &sLoc); | ||
| 64613 | if( rc!=SQLITE_OK ) break; | ||
| 64614 | assert( i - sLoc.iZero - 1 >=0 ); | ||
| 64615 | pgno = sLoc.aPgno[i-sLoc.iZero-1]; | ||
| 64616 | iDbOff = (i64)(pgno-1) * szPage; | ||
| 64617 | |||
| 64618 | if( iDbOff+szPage<=szDb ){ | ||
| 64619 | iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; | ||
| 64620 | rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); | ||
| 64621 | |||
| 64622 | if( rc==SQLITE_OK ){ | ||
| 64623 | rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); | ||
| 64624 | } | ||
| 64625 | |||
| 64626 | if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ | ||
| 64627 | break; | ||
| 64628 | } | ||
| 64629 | } | ||
| 64630 | |||
| 64631 | pInfo->nBackfillAttempted = i-1; | ||
| 64632 | } | ||
| 64633 | } | 67224 | } |
| 64634 | 67225 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) | |
| 64635 | sqlite3_free(pBuf1); | 67226 | pWal->ckptLock = 0; |
| 64636 | sqlite3_free(pBuf2); | ||
| 64637 | } | 67227 | } |
| 67228 | |||
| 67229 | sqlite3_free(pBuf1); | ||
| 67230 | sqlite3_free(pBuf2); | ||
| 64638 | walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); | 67231 | walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 64639 | } | 67232 | } |
| 64640 | 67233 | ||
| @@ -64643,28 +67236,20 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ | |||
| 64643 | #endif /* SQLITE_ENABLE_SNAPSHOT */ | 67236 | #endif /* SQLITE_ENABLE_SNAPSHOT */ |
| 64644 | 67237 | ||
| 64645 | /* | 67238 | /* |
| 64646 | ** Begin a read transaction on the database. | 67239 | ** This function does the work of sqlite3WalBeginReadTransaction() (see |
| 64647 | ** | 67240 | ** below). That function simply calls this one inside an SEH_TRY{...} block. |
| 64648 | ** This routine used to be called sqlite3OpenSnapshot() and with good reason: | ||
| 64649 | ** it takes a snapshot of the state of the WAL and wal-index for the current | ||
| 64650 | ** instant in time. The current thread will continue to use this snapshot. | ||
| 64651 | ** Other threads might append new content to the WAL and wal-index but | ||
| 64652 | ** that extra content is ignored by the current thread. | ||
| 64653 | ** | ||
| 64654 | ** If the database contents have changes since the previous read | ||
| 64655 | ** transaction, then *pChanged is set to 1 before returning. The | ||
| 64656 | ** Pager layer will use this to know that its cache is stale and | ||
| 64657 | ** needs to be flushed. | ||
| 64658 | */ | 67241 | */ |
| 64659 | SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ | 67242 | static int walBeginReadTransaction(Wal *pWal, int *pChanged){ |
| 64660 | int rc; /* Return code */ | 67243 | int rc; /* Return code */ |
| 64661 | int cnt = 0; /* Number of TryBeginRead attempts */ | 67244 | int cnt = 0; /* Number of TryBeginRead attempts */ |
| 64662 | #ifdef SQLITE_ENABLE_SNAPSHOT | 67245 | #ifdef SQLITE_ENABLE_SNAPSHOT |
| 67246 | int ckptLock = 0; | ||
| 64663 | int bChanged = 0; | 67247 | int bChanged = 0; |
| 64664 | WalIndexHdr *pSnapshot = pWal->pSnapshot; | 67248 | WalIndexHdr *pSnapshot = pWal->pSnapshot; |
| 64665 | #endif | 67249 | #endif |
| 64666 | 67250 | ||
| 64667 | assert( pWal->ckptLock==0 ); | 67251 | assert( pWal->ckptLock==0 ); |
| 67252 | assert( pWal->nSehTry>0 ); | ||
| 64668 | 67253 | ||
| 64669 | #ifdef SQLITE_ENABLE_SNAPSHOT | 67254 | #ifdef SQLITE_ENABLE_SNAPSHOT |
| 64670 | if( pSnapshot ){ | 67255 | if( pSnapshot ){ |
| @@ -64687,7 +67272,7 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ | |||
| 64687 | if( rc!=SQLITE_OK ){ | 67272 | if( rc!=SQLITE_OK ){ |
| 64688 | return rc; | 67273 | return rc; |
| 64689 | } | 67274 | } |
| 64690 | pWal->ckptLock = 1; | 67275 | ckptLock = 1; |
| 64691 | } | 67276 | } |
| 64692 | #endif | 67277 | #endif |
| 64693 | 67278 | ||
| @@ -64751,16 +67336,38 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ | |||
| 64751 | } | 67336 | } |
| 64752 | 67337 | ||
| 64753 | /* Release the shared CKPT lock obtained above. */ | 67338 | /* Release the shared CKPT lock obtained above. */ |
| 64754 | if( pWal->ckptLock ){ | 67339 | if( ckptLock ){ |
| 64755 | assert( pSnapshot ); | 67340 | assert( pSnapshot ); |
| 64756 | walUnlockShared(pWal, WAL_CKPT_LOCK); | 67341 | walUnlockShared(pWal, WAL_CKPT_LOCK); |
| 64757 | pWal->ckptLock = 0; | ||
| 64758 | } | 67342 | } |
| 64759 | #endif | 67343 | #endif |
| 64760 | return rc; | 67344 | return rc; |
| 64761 | } | 67345 | } |
| 64762 | 67346 | ||
| 64763 | /* | 67347 | /* |
| 67348 | ** Begin a read transaction on the database. | ||
| 67349 | ** | ||
| 67350 | ** This routine used to be called sqlite3OpenSnapshot() and with good reason: | ||
| 67351 | ** it takes a snapshot of the state of the WAL and wal-index for the current | ||
| 67352 | ** instant in time. The current thread will continue to use this snapshot. | ||
| 67353 | ** Other threads might append new content to the WAL and wal-index but | ||
| 67354 | ** that extra content is ignored by the current thread. | ||
| 67355 | ** | ||
| 67356 | ** If the database contents have changes since the previous read | ||
| 67357 | ** transaction, then *pChanged is set to 1 before returning. The | ||
| 67358 | ** Pager layer will use this to know that its cache is stale and | ||
| 67359 | ** needs to be flushed. | ||
| 67360 | */ | ||
| 67361 | SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ | ||
| 67362 | int rc; | ||
| 67363 | SEH_TRY { | ||
| 67364 | rc = walBeginReadTransaction(pWal, pChanged); | ||
| 67365 | } | ||
| 67366 | SEH_EXCEPT( rc = walHandleException(pWal); ) | ||
| 67367 | return rc; | ||
| 67368 | } | ||
| 67369 | |||
| 67370 | /* | ||
| 64764 | ** Finish with a read transaction. All this does is release the | 67371 | ** Finish with a read transaction. All this does is release the |
| 64765 | ** read-lock. | 67372 | ** read-lock. |
| 64766 | */ | 67373 | */ |
| @@ -64780,7 +67387,7 @@ SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ | |||
| 64780 | ** Return SQLITE_OK if successful, or an error code if an error occurs. If an | 67387 | ** Return SQLITE_OK if successful, or an error code if an error occurs. If an |
| 64781 | ** error does occur, the final value of *piRead is undefined. | 67388 | ** error does occur, the final value of *piRead is undefined. |
| 64782 | */ | 67389 | */ |
| 64783 | SQLITE_PRIVATE int sqlite3WalFindFrame( | 67390 | static int walFindFrame( |
| 64784 | Wal *pWal, /* WAL handle */ | 67391 | Wal *pWal, /* WAL handle */ |
| 64785 | Pgno pgno, /* Database page number to read data for */ | 67392 | Pgno pgno, /* Database page number to read data for */ |
| 64786 | u32 *piRead /* OUT: Frame number (or zero) */ | 67393 | u32 *piRead /* OUT: Frame number (or zero) */ |
| @@ -64843,6 +67450,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame( | |||
| 64843 | } | 67450 | } |
| 64844 | nCollide = HASHTABLE_NSLOT; | 67451 | nCollide = HASHTABLE_NSLOT; |
| 64845 | iKey = walHash(pgno); | 67452 | iKey = walHash(pgno); |
| 67453 | SEH_INJECT_FAULT; | ||
| 64846 | while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){ | 67454 | while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){ |
| 64847 | u32 iFrame = iH + sLoc.iZero; | 67455 | u32 iFrame = iH + sLoc.iZero; |
| 64848 | if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){ | 67456 | if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){ |
| @@ -64880,6 +67488,30 @@ SQLITE_PRIVATE int sqlite3WalFindFrame( | |||
| 64880 | } | 67488 | } |
| 64881 | 67489 | ||
| 64882 | /* | 67490 | /* |
| 67491 | ** Search the wal file for page pgno. If found, set *piRead to the frame that | ||
| 67492 | ** contains the page. Otherwise, if pgno is not in the wal file, set *piRead | ||
| 67493 | ** to zero. | ||
| 67494 | ** | ||
| 67495 | ** Return SQLITE_OK if successful, or an error code if an error occurs. If an | ||
| 67496 | ** error does occur, the final value of *piRead is undefined. | ||
| 67497 | ** | ||
| 67498 | ** The difference between this function and walFindFrame() is that this | ||
| 67499 | ** function wraps walFindFrame() in an SEH_TRY{...} block. | ||
| 67500 | */ | ||
| 67501 | SQLITE_PRIVATE int sqlite3WalFindFrame( | ||
| 67502 | Wal *pWal, /* WAL handle */ | ||
| 67503 | Pgno pgno, /* Database page number to read data for */ | ||
| 67504 | u32 *piRead /* OUT: Frame number (or zero) */ | ||
| 67505 | ){ | ||
| 67506 | int rc; | ||
| 67507 | SEH_TRY { | ||
| 67508 | rc = walFindFrame(pWal, pgno, piRead); | ||
| 67509 | } | ||
| 67510 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) | ||
| 67511 | return rc; | ||
| 67512 | } | ||
| 67513 | |||
| 67514 | /* | ||
| 64883 | ** Read the contents of frame iRead from the wal file into buffer pOut | 67515 | ** Read the contents of frame iRead from the wal file into buffer pOut |
| 64884 | ** (which is nOut bytes in size). Return SQLITE_OK if successful, or an | 67516 | ** (which is nOut bytes in size). Return SQLITE_OK if successful, or an |
| 64885 | ** error code otherwise. | 67517 | ** error code otherwise. |
| @@ -64960,12 +67592,17 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ | |||
| 64960 | ** time the read transaction on this connection was started, then | 67592 | ** time the read transaction on this connection was started, then |
| 64961 | ** the write is disallowed. | 67593 | ** the write is disallowed. |
| 64962 | */ | 67594 | */ |
| 64963 | if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ | 67595 | SEH_TRY { |
| 67596 | if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ | ||
| 67597 | rc = SQLITE_BUSY_SNAPSHOT; | ||
| 67598 | } | ||
| 67599 | } | ||
| 67600 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) | ||
| 67601 | |||
| 67602 | if( rc!=SQLITE_OK ){ | ||
| 64964 | walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); | 67603 | walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); |
| 64965 | pWal->writeLock = 0; | 67604 | pWal->writeLock = 0; |
| 64966 | rc = SQLITE_BUSY_SNAPSHOT; | ||
| 64967 | } | 67605 | } |
| 64968 | |||
| 64969 | return rc; | 67606 | return rc; |
| 64970 | } | 67607 | } |
| 64971 | 67608 | ||
| @@ -65001,30 +67638,33 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p | |||
| 65001 | Pgno iMax = pWal->hdr.mxFrame; | 67638 | Pgno iMax = pWal->hdr.mxFrame; |
| 65002 | Pgno iFrame; | 67639 | Pgno iFrame; |
| 65003 | 67640 | ||
| 65004 | /* Restore the clients cache of the wal-index header to the state it | 67641 | SEH_TRY { |
| 65005 | ** was in before the client began writing to the database. | 67642 | /* Restore the clients cache of the wal-index header to the state it |
| 65006 | */ | 67643 | ** was in before the client began writing to the database. |
| 65007 | memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); | ||
| 65008 | |||
| 65009 | for(iFrame=pWal->hdr.mxFrame+1; | ||
| 65010 | ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; | ||
| 65011 | iFrame++ | ||
| 65012 | ){ | ||
| 65013 | /* This call cannot fail. Unless the page for which the page number | ||
| 65014 | ** is passed as the second argument is (a) in the cache and | ||
| 65015 | ** (b) has an outstanding reference, then xUndo is either a no-op | ||
| 65016 | ** (if (a) is false) or simply expels the page from the cache (if (b) | ||
| 65017 | ** is false). | ||
| 65018 | ** | ||
| 65019 | ** If the upper layer is doing a rollback, it is guaranteed that there | ||
| 65020 | ** are no outstanding references to any page other than page 1. And | ||
| 65021 | ** page 1 is never written to the log until the transaction is | ||
| 65022 | ** committed. As a result, the call to xUndo may not fail. | ||
| 65023 | */ | 67644 | */ |
| 65024 | assert( walFramePgno(pWal, iFrame)!=1 ); | 67645 | memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); |
| 65025 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); | 67646 | |
| 67647 | for(iFrame=pWal->hdr.mxFrame+1; | ||
| 67648 | ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; | ||
| 67649 | iFrame++ | ||
| 67650 | ){ | ||
| 67651 | /* This call cannot fail. Unless the page for which the page number | ||
| 67652 | ** is passed as the second argument is (a) in the cache and | ||
| 67653 | ** (b) has an outstanding reference, then xUndo is either a no-op | ||
| 67654 | ** (if (a) is false) or simply expels the page from the cache (if (b) | ||
| 67655 | ** is false). | ||
| 67656 | ** | ||
| 67657 | ** If the upper layer is doing a rollback, it is guaranteed that there | ||
| 67658 | ** are no outstanding references to any page other than page 1. And | ||
| 67659 | ** page 1 is never written to the log until the transaction is | ||
| 67660 | ** committed. As a result, the call to xUndo may not fail. | ||
| 67661 | */ | ||
| 67662 | assert( walFramePgno(pWal, iFrame)!=1 ); | ||
| 67663 | rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); | ||
| 67664 | } | ||
| 67665 | if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); | ||
| 65026 | } | 67666 | } |
| 65027 | if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); | 67667 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) |
| 65028 | } | 67668 | } |
| 65029 | return rc; | 67669 | return rc; |
| 65030 | } | 67670 | } |
| @@ -65068,7 +67708,10 @@ SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ | |||
| 65068 | pWal->hdr.mxFrame = aWalData[0]; | 67708 | pWal->hdr.mxFrame = aWalData[0]; |
| 65069 | pWal->hdr.aFrameCksum[0] = aWalData[1]; | 67709 | pWal->hdr.aFrameCksum[0] = aWalData[1]; |
| 65070 | pWal->hdr.aFrameCksum[1] = aWalData[2]; | 67710 | pWal->hdr.aFrameCksum[1] = aWalData[2]; |
| 65071 | walCleanupHash(pWal); | 67711 | SEH_TRY { |
| 67712 | walCleanupHash(pWal); | ||
| 67713 | } | ||
| 67714 | SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) | ||
| 65072 | } | 67715 | } |
| 65073 | 67716 | ||
| 65074 | return rc; | 67717 | return rc; |
| @@ -65249,7 +67892,7 @@ static int walRewriteChecksums(Wal *pWal, u32 iLast){ | |||
| 65249 | ** Write a set of frames to the log. The caller must hold the write-lock | 67892 | ** Write a set of frames to the log. The caller must hold the write-lock |
| 65250 | ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). | 67893 | ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). |
| 65251 | */ | 67894 | */ |
| 65252 | SQLITE_PRIVATE int sqlite3WalFrames( | 67895 | static int walFrames( |
| 65253 | Wal *pWal, /* Wal handle to write to */ | 67896 | Wal *pWal, /* Wal handle to write to */ |
| 65254 | int szPage, /* Database page-size in bytes */ | 67897 | int szPage, /* Database page-size in bytes */ |
| 65255 | PgHdr *pList, /* List of dirty pages to write */ | 67898 | PgHdr *pList, /* List of dirty pages to write */ |
| @@ -65337,7 +67980,9 @@ SQLITE_PRIVATE int sqlite3WalFrames( | |||
| 65337 | if( rc ) return rc; | 67980 | if( rc ) return rc; |
| 65338 | } | 67981 | } |
| 65339 | } | 67982 | } |
| 65340 | assert( (int)pWal->szPage==szPage ); | 67983 | if( (int)pWal->szPage!=szPage ){ |
| 67984 | return SQLITE_CORRUPT_BKPT; /* TH3 test case: cov1/corrupt155.test */ | ||
| 67985 | } | ||
| 65341 | 67986 | ||
| 65342 | /* Setup information needed to write frames into the WAL */ | 67987 | /* Setup information needed to write frames into the WAL */ |
| 65343 | w.pWal = pWal; | 67988 | w.pWal = pWal; |
| @@ -65358,7 +68003,7 @@ SQLITE_PRIVATE int sqlite3WalFrames( | |||
| 65358 | ** checksums must be recomputed when the transaction is committed. */ | 68003 | ** checksums must be recomputed when the transaction is committed. */ |
| 65359 | if( iFirst && (p->pDirty || isCommit==0) ){ | 68004 | if( iFirst && (p->pDirty || isCommit==0) ){ |
| 65360 | u32 iWrite = 0; | 68005 | u32 iWrite = 0; |
| 65361 | VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite); | 68006 | VVA_ONLY(rc =) walFindFrame(pWal, p->pgno, &iWrite); |
| 65362 | assert( rc==SQLITE_OK || iWrite==0 ); | 68007 | assert( rc==SQLITE_OK || iWrite==0 ); |
| 65363 | if( iWrite>=iFirst ){ | 68008 | if( iWrite>=iFirst ){ |
| 65364 | i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; | 68009 | i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; |
| @@ -65478,6 +68123,29 @@ SQLITE_PRIVATE int sqlite3WalFrames( | |||
| 65478 | } | 68123 | } |
| 65479 | 68124 | ||
| 65480 | /* | 68125 | /* |
| 68126 | ** Write a set of frames to the log. The caller must hold the write-lock | ||
| 68127 | ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). | ||
| 68128 | ** | ||
| 68129 | ** The difference between this function and walFrames() is that this | ||
| 68130 | ** function wraps walFrames() in an SEH_TRY{...} block. | ||
| 68131 | */ | ||
| 68132 | SQLITE_PRIVATE int sqlite3WalFrames( | ||
| 68133 | Wal *pWal, /* Wal handle to write to */ | ||
| 68134 | int szPage, /* Database page-size in bytes */ | ||
| 68135 | PgHdr *pList, /* List of dirty pages to write */ | ||
| 68136 | Pgno nTruncate, /* Database size after this commit */ | ||
| 68137 | int isCommit, /* True if this is a commit */ | ||
| 68138 | int sync_flags /* Flags to pass to OsSync() (or 0) */ | ||
| 68139 | ){ | ||
| 68140 | int rc; | ||
| 68141 | SEH_TRY { | ||
| 68142 | rc = walFrames(pWal, szPage, pList, nTruncate, isCommit, sync_flags); | ||
| 68143 | } | ||
| 68144 | SEH_EXCEPT( rc = walHandleException(pWal); ) | ||
| 68145 | return rc; | ||
| 68146 | } | ||
| 68147 | |||
| 68148 | /* | ||
| 65481 | ** This routine is called to implement sqlite3_wal_checkpoint() and | 68149 | ** This routine is called to implement sqlite3_wal_checkpoint() and |
| 65482 | ** related interfaces. | 68150 | ** related interfaces. |
| 65483 | ** | 68151 | ** |
| @@ -65556,30 +68224,33 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( | |||
| 65556 | 68224 | ||
| 65557 | 68225 | ||
| 65558 | /* Read the wal-index header. */ | 68226 | /* Read the wal-index header. */ |
| 65559 | if( rc==SQLITE_OK ){ | 68227 | SEH_TRY { |
| 65560 | walDisableBlocking(pWal); | 68228 | if( rc==SQLITE_OK ){ |
| 65561 | rc = walIndexReadHdr(pWal, &isChanged); | 68229 | walDisableBlocking(pWal); |
| 65562 | (void)walEnableBlocking(pWal); | 68230 | rc = walIndexReadHdr(pWal, &isChanged); |
| 65563 | if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ | 68231 | (void)walEnableBlocking(pWal); |
| 65564 | sqlite3OsUnfetch(pWal->pDbFd, 0, 0); | 68232 | if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ |
| 68233 | sqlite3OsUnfetch(pWal->pDbFd, 0, 0); | ||
| 68234 | } | ||
| 65565 | } | 68235 | } |
| 65566 | } | ||
| 65567 | 68236 | ||
| 65568 | /* Copy data from the log to the database file. */ | 68237 | /* Copy data from the log to the database file. */ |
| 65569 | if( rc==SQLITE_OK ){ | 68238 | if( rc==SQLITE_OK ){ |
| 65570 | 68239 | if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ | |
| 65571 | if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ | 68240 | rc = SQLITE_CORRUPT_BKPT; |
| 65572 | rc = SQLITE_CORRUPT_BKPT; | 68241 | }else{ |
| 65573 | }else{ | 68242 | rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf); |
| 65574 | rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); | 68243 | } |
| 65575 | } | ||
| 65576 | 68244 | ||
| 65577 | /* If no error occurred, set the output variables. */ | 68245 | /* If no error occurred, set the output variables. */ |
| 65578 | if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ | 68246 | if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ |
| 65579 | if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; | 68247 | if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; |
| 65580 | if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); | 68248 | SEH_INJECT_FAULT; |
| 68249 | if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); | ||
| 68250 | } | ||
| 65581 | } | 68251 | } |
| 65582 | } | 68252 | } |
| 68253 | SEH_EXCEPT( rc = walHandleException(pWal); ) | ||
| 65583 | 68254 | ||
| 65584 | if( isChanged ){ | 68255 | if( isChanged ){ |
| 65585 | /* If a new wal-index header was loaded before the checkpoint was | 68256 | /* If a new wal-index header was loaded before the checkpoint was |
| @@ -65656,7 +68327,9 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ | |||
| 65656 | ** locks are taken in this case). Nor should the pager attempt to | 68327 | ** locks are taken in this case). Nor should the pager attempt to |
| 65657 | ** upgrade to exclusive-mode following such an error. | 68328 | ** upgrade to exclusive-mode following such an error. |
| 65658 | */ | 68329 | */ |
| 68330 | #ifndef SQLITE_USE_SEH | ||
| 65659 | assert( pWal->readLock>=0 || pWal->lockError ); | 68331 | assert( pWal->readLock>=0 || pWal->lockError ); |
| 68332 | #endif | ||
| 65660 | assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); | 68333 | assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); |
| 65661 | 68334 | ||
| 65662 | if( op==0 ){ | 68335 | if( op==0 ){ |
| @@ -65757,16 +68430,19 @@ SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ | |||
| 65757 | */ | 68430 | */ |
| 65758 | SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ | 68431 | SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ |
| 65759 | int rc; | 68432 | int rc; |
| 65760 | rc = walLockShared(pWal, WAL_CKPT_LOCK); | 68433 | SEH_TRY { |
| 65761 | if( rc==SQLITE_OK ){ | 68434 | rc = walLockShared(pWal, WAL_CKPT_LOCK); |
| 65762 | WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; | 68435 | if( rc==SQLITE_OK ){ |
| 65763 | if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) | 68436 | WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; |
| 65764 | || pNew->mxFrame<walCkptInfo(pWal)->nBackfillAttempted | 68437 | if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) |
| 65765 | ){ | 68438 | || pNew->mxFrame<walCkptInfo(pWal)->nBackfillAttempted |
| 65766 | rc = SQLITE_ERROR_SNAPSHOT; | 68439 | ){ |
| 65767 | walUnlockShared(pWal, WAL_CKPT_LOCK); | 68440 | rc = SQLITE_ERROR_SNAPSHOT; |
| 68441 | walUnlockShared(pWal, WAL_CKPT_LOCK); | ||
| 68442 | } | ||
| 65768 | } | 68443 | } |
| 65769 | } | 68444 | } |
| 68445 | SEH_EXCEPT( rc = walHandleException(pWal); ) | ||
| 65770 | return rc; | 68446 | return rc; |
| 65771 | } | 68447 | } |
| 65772 | 68448 | ||
| @@ -65997,7 +68673,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ | |||
| 65997 | ** byte are used. The integer consists of all bytes that have bit 8 set and | 68673 | ** byte are used. The integer consists of all bytes that have bit 8 set and |
| 65998 | ** the first byte with bit 8 clear. The most significant byte of the integer | 68674 | ** the first byte with bit 8 clear. The most significant byte of the integer |
| 65999 | ** appears first. A variable-length integer may not be more than 9 bytes long. | 68675 | ** appears first. A variable-length integer may not be more than 9 bytes long. |
| 66000 | ** As a special case, all 8 bytes of the 9th byte are used as data. This | 68676 | ** As a special case, all 8 bits of the 9th byte are used as data. This |
| 66001 | ** allows a 64-bit integer to be encoded in 9 bytes. | 68677 | ** allows a 64-bit integer to be encoded in 9 bytes. |
| 66002 | ** | 68678 | ** |
| 66003 | ** 0x00 becomes 0x00000000 | 68679 | ** 0x00 becomes 0x00000000 |
| @@ -66005,7 +68681,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ | |||
| 66005 | ** 0x81 0x00 becomes 0x00000080 | 68681 | ** 0x81 0x00 becomes 0x00000080 |
| 66006 | ** 0x82 0x00 becomes 0x00000100 | 68682 | ** 0x82 0x00 becomes 0x00000100 |
| 66007 | ** 0x80 0x7f becomes 0x0000007f | 68683 | ** 0x80 0x7f becomes 0x0000007f |
| 66008 | ** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678 | 68684 | ** 0x81 0x91 0xd1 0xac 0x78 becomes 0x12345678 |
| 66009 | ** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 | 68685 | ** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 |
| 66010 | ** | 68686 | ** |
| 66011 | ** Variable length integers are used for rowids and to hold the number of | 68687 | ** Variable length integers are used for rowids and to hold the number of |
| @@ -66088,7 +68764,7 @@ typedef struct CellInfo CellInfo; | |||
| 66088 | ** page that has been loaded into memory. The information in this object | 68764 | ** page that has been loaded into memory. The information in this object |
| 66089 | ** is derived from the raw on-disk page content. | 68765 | ** is derived from the raw on-disk page content. |
| 66090 | ** | 68766 | ** |
| 66091 | ** As each database page is loaded into memory, the pager allocats an | 68767 | ** As each database page is loaded into memory, the pager allocates an |
| 66092 | ** instance of this object and zeros the first 8 bytes. (This is the | 68768 | ** instance of this object and zeros the first 8 bytes. (This is the |
| 66093 | ** "extra" information associated with each page of the pager.) | 68769 | ** "extra" information associated with each page of the pager.) |
| 66094 | ** | 68770 | ** |
| @@ -66381,7 +69057,7 @@ struct BtCursor { | |||
| 66381 | #define BTCF_WriteFlag 0x01 /* True if a write cursor */ | 69057 | #define BTCF_WriteFlag 0x01 /* True if a write cursor */ |
| 66382 | #define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ | 69058 | #define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ |
| 66383 | #define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ | 69059 | #define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ |
| 66384 | #define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ | 69060 | #define BTCF_AtLast 0x08 /* Cursor is pointing to the last entry */ |
| 66385 | #define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ | 69061 | #define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ |
| 66386 | #define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ | 69062 | #define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ |
| 66387 | #define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */ | 69063 | #define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */ |
| @@ -66499,15 +69175,15 @@ struct BtCursor { | |||
| 66499 | ** So, this macro is defined instead. | 69175 | ** So, this macro is defined instead. |
| 66500 | */ | 69176 | */ |
| 66501 | #ifndef SQLITE_OMIT_AUTOVACUUM | 69177 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 66502 | #define ISAUTOVACUUM (pBt->autoVacuum) | 69178 | #define ISAUTOVACUUM(pBt) (pBt->autoVacuum) |
| 66503 | #else | 69179 | #else |
| 66504 | #define ISAUTOVACUUM 0 | 69180 | #define ISAUTOVACUUM(pBt) 0 |
| 66505 | #endif | 69181 | #endif |
| 66506 | 69182 | ||
| 66507 | 69183 | ||
| 66508 | /* | 69184 | /* |
| 66509 | ** This structure is passed around through all the sanity checking routines | 69185 | ** This structure is passed around through all the PRAGMA integrity_check |
| 66510 | ** in order to keep track of some global state information. | 69186 | ** checking routines in order to keep track of some global state information. |
| 66511 | ** | 69187 | ** |
| 66512 | ** The aRef[] array is allocated so that there is 1 bit for each page in | 69188 | ** The aRef[] array is allocated so that there is 1 bit for each page in |
| 66513 | ** the database. As the integrity-check proceeds, for each page used in | 69189 | ** the database. As the integrity-check proceeds, for each page used in |
| @@ -66523,10 +69199,12 @@ struct IntegrityCk { | |||
| 66523 | Pgno nPage; /* Number of pages in the database */ | 69199 | Pgno nPage; /* Number of pages in the database */ |
| 66524 | int mxErr; /* Stop accumulating errors when this reaches zero */ | 69200 | int mxErr; /* Stop accumulating errors when this reaches zero */ |
| 66525 | int nErr; /* Number of messages written to zErrMsg so far */ | 69201 | int nErr; /* Number of messages written to zErrMsg so far */ |
| 66526 | int bOomFault; /* A memory allocation error has occurred */ | 69202 | int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ |
| 69203 | u32 nStep; /* Number of steps into the integrity_check process */ | ||
| 66527 | const char *zPfx; /* Error message prefix */ | 69204 | const char *zPfx; /* Error message prefix */ |
| 66528 | Pgno v1; /* Value for first %u substitution in zPfx */ | 69205 | Pgno v0; /* Value for first %u substitution in zPfx (root page) */ |
| 66529 | int v2; /* Value for second %d substitution in zPfx */ | 69206 | Pgno v1; /* Value for second %u substitution in zPfx (current pg) */ |
| 69207 | int v2; /* Value for third %d substitution in zPfx */ | ||
| 66530 | StrAccum errMsg; /* Accumulate the error message text here */ | 69208 | StrAccum errMsg; /* Accumulate the error message text here */ |
| 66531 | u32 *heap; /* Min-heap used for analyzing cell coverage */ | 69209 | u32 *heap; /* Min-heap used for analyzing cell coverage */ |
| 66532 | sqlite3 *db; /* Database connection running the check */ | 69210 | sqlite3 *db; /* Database connection running the check */ |
| @@ -66542,7 +69220,7 @@ struct IntegrityCk { | |||
| 66542 | 69220 | ||
| 66543 | /* | 69221 | /* |
| 66544 | ** get2byteAligned(), unlike get2byte(), requires that its argument point to a | 69222 | ** get2byteAligned(), unlike get2byte(), requires that its argument point to a |
| 66545 | ** two-byte aligned address. get2bytea() is only used for accessing the | 69223 | ** two-byte aligned address. get2byteAligned() is only used for accessing the |
| 66546 | ** cell addresses in a btree header. | 69224 | ** cell addresses in a btree header. |
| 66547 | */ | 69225 | */ |
| 66548 | #if SQLITE_BYTEORDER==4321 | 69226 | #if SQLITE_BYTEORDER==4321 |
| @@ -66719,7 +69397,7 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ | |||
| 66719 | ** | 69397 | ** |
| 66720 | ** There is a corresponding leave-all procedures. | 69398 | ** There is a corresponding leave-all procedures. |
| 66721 | ** | 69399 | ** |
| 66722 | ** Enter the mutexes in accending order by BtShared pointer address | 69400 | ** Enter the mutexes in ascending order by BtShared pointer address |
| 66723 | ** to avoid the possibility of deadlock when two threads with | 69401 | ** to avoid the possibility of deadlock when two threads with |
| 66724 | ** two or more btrees in common both try to lock all their btrees | 69402 | ** two or more btrees in common both try to lock all their btrees |
| 66725 | ** at the same instant. | 69403 | ** at the same instant. |
| @@ -66793,6 +69471,7 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ | |||
| 66793 | SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ | 69471 | SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ |
| 66794 | Btree *p; | 69472 | Btree *p; |
| 66795 | assert( db!=0 ); | 69473 | assert( db!=0 ); |
| 69474 | if( db->pVfs==0 && db->nDb==0 ) return 1; | ||
| 66796 | if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); | 69475 | if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); |
| 66797 | assert( iDb>=0 && iDb<db->nDb ); | 69476 | assert( iDb>=0 && iDb<db->nDb ); |
| 66798 | if( !sqlite3_mutex_held(db->mutex) ) return 0; | 69477 | if( !sqlite3_mutex_held(db->mutex) ) return 0; |
| @@ -66850,6 +69529,7 @@ SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ | |||
| 66850 | 69529 | ||
| 66851 | /************** End of btmutex.c *********************************************/ | 69530 | /************** End of btmutex.c *********************************************/ |
| 66852 | /************** Begin file btree.c *******************************************/ | 69531 | /************** Begin file btree.c *******************************************/ |
| 69532 | |||
| 66853 | /* | 69533 | /* |
| 66854 | ** 2004 April 6 | 69534 | ** 2004 April 6 |
| 66855 | ** | 69535 | ** |
| @@ -66988,8 +69668,8 @@ SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){ | |||
| 66988 | int corruptPageError(int lineno, MemPage *p){ | 69668 | int corruptPageError(int lineno, MemPage *p){ |
| 66989 | char *zMsg; | 69669 | char *zMsg; |
| 66990 | sqlite3BeginBenignMalloc(); | 69670 | sqlite3BeginBenignMalloc(); |
| 66991 | zMsg = sqlite3_mprintf("database corruption page %d of %s", | 69671 | zMsg = sqlite3_mprintf("database corruption page %u of %s", |
| 66992 | (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) | 69672 | p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) |
| 66993 | ); | 69673 | ); |
| 66994 | sqlite3EndBenignMalloc(); | 69674 | sqlite3EndBenignMalloc(); |
| 66995 | if( zMsg ){ | 69675 | if( zMsg ){ |
| @@ -67798,8 +70478,25 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow) | |||
| 67798 | */ | 70478 | */ |
| 67799 | SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ | 70479 | SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ |
| 67800 | /* Used only by system that substitute their own storage engine */ | 70480 | /* Used only by system that substitute their own storage engine */ |
| 70481 | #ifdef SQLITE_DEBUG | ||
| 70482 | if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){ | ||
| 70483 | va_list ap; | ||
| 70484 | Expr *pExpr; | ||
| 70485 | Walker w; | ||
| 70486 | memset(&w, 0, sizeof(w)); | ||
| 70487 | w.xExprCallback = sqlite3CursorRangeHintExprCheck; | ||
| 70488 | va_start(ap, eHintType); | ||
| 70489 | pExpr = va_arg(ap, Expr*); | ||
| 70490 | w.u.aMem = va_arg(ap, Mem*); | ||
| 70491 | va_end(ap); | ||
| 70492 | assert( pExpr!=0 ); | ||
| 70493 | assert( w.u.aMem!=0 ); | ||
| 70494 | sqlite3WalkExpr(&w, pExpr); | ||
| 70495 | } | ||
| 70496 | #endif /* SQLITE_DEBUG */ | ||
| 67801 | } | 70497 | } |
| 67802 | #endif | 70498 | #endif /* SQLITE_ENABLE_CURSOR_HINTS */ |
| 70499 | |||
| 67803 | 70500 | ||
| 67804 | /* | 70501 | /* |
| 67805 | ** Provide flag hints to the cursor. | 70502 | ** Provide flag hints to the cursor. |
| @@ -67884,7 +70581,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ | |||
| 67884 | pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); | 70581 | pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); |
| 67885 | 70582 | ||
| 67886 | if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ | 70583 | if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ |
| 67887 | TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); | 70584 | TRACE(("PTRMAP_UPDATE: %u->(%u,%u)\n", key, eType, parent)); |
| 67888 | *pRC= rc = sqlite3PagerWrite(pDbPage); | 70585 | *pRC= rc = sqlite3PagerWrite(pDbPage); |
| 67889 | if( rc==SQLITE_OK ){ | 70586 | if( rc==SQLITE_OK ){ |
| 67890 | pPtrmap[offset] = eType; | 70587 | pPtrmap[offset] = eType; |
| @@ -68083,27 +70780,31 @@ static void btreeParseCellPtr( | |||
| 68083 | iKey = *pIter; | 70780 | iKey = *pIter; |
| 68084 | if( iKey>=0x80 ){ | 70781 | if( iKey>=0x80 ){ |
| 68085 | u8 x; | 70782 | u8 x; |
| 68086 | iKey = ((iKey&0x7f)<<7) | ((x = *++pIter) & 0x7f); | 70783 | iKey = (iKey<<7) ^ (x = *++pIter); |
| 68087 | if( x>=0x80 ){ | 70784 | if( x>=0x80 ){ |
| 68088 | iKey = (iKey<<7) | ((x =*++pIter) & 0x7f); | 70785 | iKey = (iKey<<7) ^ (x = *++pIter); |
| 68089 | if( x>=0x80 ){ | 70786 | if( x>=0x80 ){ |
| 68090 | iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); | 70787 | iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++pIter); |
| 68091 | if( x>=0x80 ){ | 70788 | if( x>=0x80 ){ |
| 68092 | iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); | 70789 | iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); |
| 68093 | if( x>=0x80 ){ | 70790 | if( x>=0x80 ){ |
| 68094 | iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); | 70791 | iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); |
| 68095 | if( x>=0x80 ){ | 70792 | if( x>=0x80 ){ |
| 68096 | iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); | 70793 | iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); |
| 68097 | if( x>=0x80 ){ | 70794 | if( x>=0x80 ){ |
| 68098 | iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); | 70795 | iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); |
| 68099 | if( x>=0x80 ){ | 70796 | if( x>=0x80 ){ |
| 68100 | iKey = (iKey<<8) | (*++pIter); | 70797 | iKey = (iKey<<8) ^ 0x8000 ^ (*++pIter); |
| 68101 | } | 70798 | } |
| 68102 | } | 70799 | } |
| 68103 | } | 70800 | } |
| 68104 | } | 70801 | } |
| 68105 | } | 70802 | } |
| 70803 | }else{ | ||
| 70804 | iKey ^= 0x204000; | ||
| 68106 | } | 70805 | } |
| 70806 | }else{ | ||
| 70807 | iKey ^= 0x4000; | ||
| 68107 | } | 70808 | } |
| 68108 | } | 70809 | } |
| 68109 | pIter++; | 70810 | pIter++; |
| @@ -68180,10 +70881,11 @@ static void btreeParseCell( | |||
| 68180 | ** | 70881 | ** |
| 68181 | ** cellSizePtrNoPayload() => table internal nodes | 70882 | ** cellSizePtrNoPayload() => table internal nodes |
| 68182 | ** cellSizePtrTableLeaf() => table leaf nodes | 70883 | ** cellSizePtrTableLeaf() => table leaf nodes |
| 68183 | ** cellSizePtr() => all index nodes & table leaf nodes | 70884 | ** cellSizePtr() => index internal nodes |
| 70885 | ** cellSizeIdxLeaf() => index leaf nodes | ||
| 68184 | */ | 70886 | */ |
| 68185 | static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ | 70887 | static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ |
| 68186 | u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ | 70888 | u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ |
| 68187 | u8 *pEnd; /* End mark for a varint */ | 70889 | u8 *pEnd; /* End mark for a varint */ |
| 68188 | u32 nSize; /* Size value to return */ | 70890 | u32 nSize; /* Size value to return */ |
| 68189 | 70891 | ||
| @@ -68196,6 +70898,49 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ | |||
| 68196 | pPage->xParseCell(pPage, pCell, &debuginfo); | 70898 | pPage->xParseCell(pPage, pCell, &debuginfo); |
| 68197 | #endif | 70899 | #endif |
| 68198 | 70900 | ||
| 70901 | assert( pPage->childPtrSize==4 ); | ||
| 70902 | nSize = *pIter; | ||
| 70903 | if( nSize>=0x80 ){ | ||
| 70904 | pEnd = &pIter[8]; | ||
| 70905 | nSize &= 0x7f; | ||
| 70906 | do{ | ||
| 70907 | nSize = (nSize<<7) | (*++pIter & 0x7f); | ||
| 70908 | }while( *(pIter)>=0x80 && pIter<pEnd ); | ||
| 70909 | } | ||
| 70910 | pIter++; | ||
| 70911 | testcase( nSize==pPage->maxLocal ); | ||
| 70912 | testcase( nSize==(u32)pPage->maxLocal+1 ); | ||
| 70913 | if( nSize<=pPage->maxLocal ){ | ||
| 70914 | nSize += (u32)(pIter - pCell); | ||
| 70915 | assert( nSize>4 ); | ||
| 70916 | }else{ | ||
| 70917 | int minLocal = pPage->minLocal; | ||
| 70918 | nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); | ||
| 70919 | testcase( nSize==pPage->maxLocal ); | ||
| 70920 | testcase( nSize==(u32)pPage->maxLocal+1 ); | ||
| 70921 | if( nSize>pPage->maxLocal ){ | ||
| 70922 | nSize = minLocal; | ||
| 70923 | } | ||
| 70924 | nSize += 4 + (u16)(pIter - pCell); | ||
| 70925 | } | ||
| 70926 | assert( nSize==debuginfo.nSize || CORRUPT_DB ); | ||
| 70927 | return (u16)nSize; | ||
| 70928 | } | ||
| 70929 | static u16 cellSizePtrIdxLeaf(MemPage *pPage, u8 *pCell){ | ||
| 70930 | u8 *pIter = pCell; /* For looping over bytes of pCell */ | ||
| 70931 | u8 *pEnd; /* End mark for a varint */ | ||
| 70932 | u32 nSize; /* Size value to return */ | ||
| 70933 | |||
| 70934 | #ifdef SQLITE_DEBUG | ||
| 70935 | /* The value returned by this function should always be the same as | ||
| 70936 | ** the (CellInfo.nSize) value found by doing a full parse of the | ||
| 70937 | ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of | ||
| 70938 | ** this function verifies that this invariant is not violated. */ | ||
| 70939 | CellInfo debuginfo; | ||
| 70940 | pPage->xParseCell(pPage, pCell, &debuginfo); | ||
| 70941 | #endif | ||
| 70942 | |||
| 70943 | assert( pPage->childPtrSize==0 ); | ||
| 68199 | nSize = *pIter; | 70944 | nSize = *pIter; |
| 68200 | if( nSize>=0x80 ){ | 70945 | if( nSize>=0x80 ){ |
| 68201 | pEnd = &pIter[8]; | 70946 | pEnd = &pIter[8]; |
| @@ -68320,7 +71065,7 @@ static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){ | |||
| 68320 | pPage->xParseCell(pPage, pCell, &info); | 71065 | pPage->xParseCell(pPage, pCell, &info); |
| 68321 | if( info.nLocal<info.nPayload ){ | 71066 | if( info.nLocal<info.nPayload ){ |
| 68322 | Pgno ovfl; | 71067 | Pgno ovfl; |
| 68323 | if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){ | 71068 | if( SQLITE_OVERFLOW(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){ |
| 68324 | testcase( pSrc!=pPage ); | 71069 | testcase( pSrc!=pPage ); |
| 68325 | *pRC = SQLITE_CORRUPT_BKPT; | 71070 | *pRC = SQLITE_CORRUPT_BKPT; |
| 68326 | return; | 71071 | return; |
| @@ -68365,8 +71110,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ | |||
| 68365 | assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); | 71110 | assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); |
| 68366 | assert( pPage->nOverflow==0 ); | 71111 | assert( pPage->nOverflow==0 ); |
| 68367 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); | 71112 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 68368 | temp = 0; | 71113 | data = pPage->aData; |
| 68369 | src = data = pPage->aData; | ||
| 68370 | hdr = pPage->hdrOffset; | 71114 | hdr = pPage->hdrOffset; |
| 68371 | cellOffset = pPage->cellOffset; | 71115 | cellOffset = pPage->cellOffset; |
| 68372 | nCell = pPage->nCell; | 71116 | nCell = pPage->nCell; |
| @@ -68400,7 +71144,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ | |||
| 68400 | if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); | 71144 | if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); |
| 68401 | memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); | 71145 | memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); |
| 68402 | sz += sz2; | 71146 | sz += sz2; |
| 68403 | }else if( NEVER(iFree+sz>usableSize) ){ | 71147 | }else if( iFree+sz>usableSize ){ |
| 68404 | return SQLITE_CORRUPT_PAGE(pPage); | 71148 | return SQLITE_CORRUPT_PAGE(pPage); |
| 68405 | } | 71149 | } |
| 68406 | 71150 | ||
| @@ -68420,39 +71164,38 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ | |||
| 68420 | cbrk = usableSize; | 71164 | cbrk = usableSize; |
| 68421 | iCellLast = usableSize - 4; | 71165 | iCellLast = usableSize - 4; |
| 68422 | iCellStart = get2byte(&data[hdr+5]); | 71166 | iCellStart = get2byte(&data[hdr+5]); |
| 68423 | for(i=0; i<nCell; i++){ | 71167 | if( nCell>0 ){ |
| 68424 | u8 *pAddr; /* The i-th cell pointer */ | 71168 | temp = sqlite3PagerTempSpace(pPage->pBt->pPager); |
| 68425 | pAddr = &data[cellOffset + i*2]; | 71169 | memcpy(temp, data, usableSize); |
| 68426 | pc = get2byte(pAddr); | 71170 | src = temp; |
| 68427 | testcase( pc==iCellFirst ); | 71171 | for(i=0; i<nCell; i++){ |
| 68428 | testcase( pc==iCellLast ); | 71172 | u8 *pAddr; /* The i-th cell pointer */ |
| 68429 | /* These conditions have already been verified in btreeInitPage() | 71173 | pAddr = &data[cellOffset + i*2]; |
| 68430 | ** if PRAGMA cell_size_check=ON. | 71174 | pc = get2byte(pAddr); |
| 68431 | */ | 71175 | testcase( pc==iCellFirst ); |
| 68432 | if( pc<iCellStart || pc>iCellLast ){ | 71176 | testcase( pc==iCellLast ); |
| 68433 | return SQLITE_CORRUPT_PAGE(pPage); | 71177 | /* These conditions have already been verified in btreeInitPage() |
| 68434 | } | 71178 | ** if PRAGMA cell_size_check=ON. |
| 68435 | assert( pc>=iCellStart && pc<=iCellLast ); | 71179 | */ |
| 68436 | size = pPage->xCellSize(pPage, &src[pc]); | 71180 | if( pc>iCellLast ){ |
| 68437 | cbrk -= size; | 71181 | return SQLITE_CORRUPT_PAGE(pPage); |
| 68438 | if( cbrk<iCellStart || pc+size>usableSize ){ | 71182 | } |
| 68439 | return SQLITE_CORRUPT_PAGE(pPage); | 71183 | assert( pc>=0 && pc<=iCellLast ); |
| 68440 | } | 71184 | size = pPage->xCellSize(pPage, &src[pc]); |
| 68441 | assert( cbrk+size<=usableSize && cbrk>=iCellStart ); | 71185 | cbrk -= size; |
| 68442 | testcase( cbrk+size==usableSize ); | 71186 | if( cbrk<iCellStart || pc+size>usableSize ){ |
| 68443 | testcase( pc+size==usableSize ); | 71187 | return SQLITE_CORRUPT_PAGE(pPage); |
| 68444 | put2byte(pAddr, cbrk); | 71188 | } |
| 68445 | if( temp==0 ){ | 71189 | assert( cbrk+size<=usableSize && cbrk>=iCellStart ); |
| 68446 | if( cbrk==pc ) continue; | 71190 | testcase( cbrk+size==usableSize ); |
| 68447 | temp = sqlite3PagerTempSpace(pPage->pBt->pPager); | 71191 | testcase( pc+size==usableSize ); |
| 68448 | memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); | 71192 | put2byte(pAddr, cbrk); |
| 68449 | src = temp; | 71193 | memcpy(&data[cbrk], &src[pc], size); |
| 68450 | } | 71194 | } |
| 68451 | memcpy(&data[cbrk], &src[pc], size); | ||
| 68452 | } | 71195 | } |
| 68453 | data[hdr+7] = 0; | 71196 | data[hdr+7] = 0; |
| 68454 | 71197 | ||
| 68455 | defragment_out: | 71198 | defragment_out: |
| 68456 | assert( pPage->nFree>=0 ); | 71199 | assert( pPage->nFree>=0 ); |
| 68457 | if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ | 71200 | if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ |
| 68458 | return SQLITE_CORRUPT_PAGE(pPage); | 71201 | return SQLITE_CORRUPT_PAGE(pPage); |
| @@ -68509,7 +71252,6 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ | |||
| 68509 | ** fragmented bytes within the page. */ | 71252 | ** fragmented bytes within the page. */ |
| 68510 | memcpy(&aData[iAddr], &aData[pc], 2); | 71253 | memcpy(&aData[iAddr], &aData[pc], 2); |
| 68511 | aData[hdr+7] += (u8)x; | 71254 | aData[hdr+7] += (u8)x; |
| 68512 | testcase( pc+x>maxPC ); | ||
| 68513 | return &aData[pc]; | 71255 | return &aData[pc]; |
| 68514 | }else if( x+pc > maxPC ){ | 71256 | }else if( x+pc > maxPC ){ |
| 68515 | /* This slot extends off the end of the usable part of the page */ | 71257 | /* This slot extends off the end of the usable part of the page */ |
| @@ -68525,9 +71267,9 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ | |||
| 68525 | iAddr = pc; | 71267 | iAddr = pc; |
| 68526 | pTmp = &aData[pc]; | 71268 | pTmp = &aData[pc]; |
| 68527 | pc = get2byte(pTmp); | 71269 | pc = get2byte(pTmp); |
| 68528 | if( pc<=iAddr+size ){ | 71270 | if( pc<=iAddr ){ |
| 68529 | if( pc ){ | 71271 | if( pc ){ |
| 68530 | /* The next slot in the chain is not past the end of the current slot */ | 71272 | /* The next slot in the chain comes before the current slot */ |
| 68531 | *pRc = SQLITE_CORRUPT_PAGE(pPg); | 71273 | *pRc = SQLITE_CORRUPT_PAGE(pPg); |
| 68532 | } | 71274 | } |
| 68533 | return 0; | 71275 | return 0; |
| @@ -68553,7 +71295,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ | |||
| 68553 | ** allocation is being made in order to insert a new cell, so we will | 71295 | ** allocation is being made in order to insert a new cell, so we will |
| 68554 | ** also end up needing a new cell pointer. | 71296 | ** also end up needing a new cell pointer. |
| 68555 | */ | 71297 | */ |
| 68556 | static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ | 71298 | static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ |
| 68557 | const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ | 71299 | const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ |
| 68558 | u8 * const data = pPage->aData; /* Local cache of pPage->aData */ | 71300 | u8 * const data = pPage->aData; /* Local cache of pPage->aData */ |
| 68559 | int top; /* First byte of cell content area */ | 71301 | int top; /* First byte of cell content area */ |
| @@ -68579,13 +71321,14 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ | |||
| 68579 | ** integer, so a value of 0 is used in its place. */ | 71321 | ** integer, so a value of 0 is used in its place. */ |
| 68580 | pTmp = &data[hdr+5]; | 71322 | pTmp = &data[hdr+5]; |
| 68581 | top = get2byte(pTmp); | 71323 | top = get2byte(pTmp); |
| 68582 | assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */ | ||
| 68583 | if( gap>top ){ | 71324 | if( gap>top ){ |
| 68584 | if( top==0 && pPage->pBt->usableSize==65536 ){ | 71325 | if( top==0 && pPage->pBt->usableSize==65536 ){ |
| 68585 | top = 65536; | 71326 | top = 65536; |
| 68586 | }else{ | 71327 | }else{ |
| 68587 | return SQLITE_CORRUPT_PAGE(pPage); | 71328 | return SQLITE_CORRUPT_PAGE(pPage); |
| 68588 | } | 71329 | } |
| 71330 | }else if( top>(int)pPage->pBt->usableSize ){ | ||
| 71331 | return SQLITE_CORRUPT_PAGE(pPage); | ||
| 68589 | } | 71332 | } |
| 68590 | 71333 | ||
| 68591 | /* If there is enough space between gap and top for one more cell pointer, | 71334 | /* If there is enough space between gap and top for one more cell pointer, |
| @@ -68647,7 +71390,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ | |||
| 68647 | ** | 71390 | ** |
| 68648 | ** Even though the freeblock list was checked by btreeComputeFreeSpace(), | 71391 | ** Even though the freeblock list was checked by btreeComputeFreeSpace(), |
| 68649 | ** that routine will not detect overlap between cells or freeblocks. Nor | 71392 | ** that routine will not detect overlap between cells or freeblocks. Nor |
| 68650 | ** does it detect cells or freeblocks that encrouch into the reserved bytes | 71393 | ** does it detect cells or freeblocks that encroach into the reserved bytes |
| 68651 | ** at the end of the page. So do additional corruption checks inside this | 71394 | ** at the end of the page. So do additional corruption checks inside this |
| 68652 | ** routine and return SQLITE_CORRUPT if any problems are found. | 71395 | ** routine and return SQLITE_CORRUPT if any problems are found. |
| 68653 | */ | 71396 | */ |
| @@ -68668,7 +71411,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ | |||
| 68668 | assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); | 71411 | assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); |
| 68669 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); | 71412 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 68670 | assert( iSize>=4 ); /* Minimum cell size is 4 */ | 71413 | assert( iSize>=4 ); /* Minimum cell size is 4 */ |
| 68671 | assert( iStart<=pPage->pBt->usableSize-4 ); | 71414 | assert( CORRUPT_DB || iStart<=pPage->pBt->usableSize-4 ); |
| 68672 | 71415 | ||
| 68673 | /* The list of freeblocks must be in ascending order. Find the | 71416 | /* The list of freeblocks must be in ascending order. Find the |
| 68674 | ** spot on the list where iStart should be inserted. | 71417 | ** spot on the list where iStart should be inserted. |
| @@ -68679,7 +71422,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ | |||
| 68679 | iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ | 71422 | iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ |
| 68680 | }else{ | 71423 | }else{ |
| 68681 | while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){ | 71424 | while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){ |
| 68682 | if( iFreeBlk<iPtr+4 ){ | 71425 | if( iFreeBlk<=iPtr ){ |
| 68683 | if( iFreeBlk==0 ) break; /* TH3: corrupt082.100 */ | 71426 | if( iFreeBlk==0 ) break; /* TH3: corrupt082.100 */ |
| 68684 | return SQLITE_CORRUPT_PAGE(pPage); | 71427 | return SQLITE_CORRUPT_PAGE(pPage); |
| 68685 | } | 71428 | } |
| @@ -68725,6 +71468,11 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ | |||
| 68725 | } | 71468 | } |
| 68726 | pTmp = &data[hdr+5]; | 71469 | pTmp = &data[hdr+5]; |
| 68727 | x = get2byte(pTmp); | 71470 | x = get2byte(pTmp); |
| 71471 | if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ | ||
| 71472 | /* Overwrite deleted information with zeros when the secure_delete | ||
| 71473 | ** option is enabled */ | ||
| 71474 | memset(&data[iStart], 0, iSize); | ||
| 71475 | } | ||
| 68728 | if( iStart<=x ){ | 71476 | if( iStart<=x ){ |
| 68729 | /* The new freeblock is at the beginning of the cell content area, | 71477 | /* The new freeblock is at the beginning of the cell content area, |
| 68730 | ** so just extend the cell content area rather than create another | 71478 | ** so just extend the cell content area rather than create another |
| @@ -68736,14 +71484,9 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ | |||
| 68736 | }else{ | 71484 | }else{ |
| 68737 | /* Insert the new freeblock into the freelist */ | 71485 | /* Insert the new freeblock into the freelist */ |
| 68738 | put2byte(&data[iPtr], iStart); | 71486 | put2byte(&data[iPtr], iStart); |
| 71487 | put2byte(&data[iStart], iFreeBlk); | ||
| 71488 | put2byte(&data[iStart+2], iSize); | ||
| 68739 | } | 71489 | } |
| 68740 | if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ | ||
| 68741 | /* Overwrite deleted information with zeros when the secure_delete | ||
| 68742 | ** option is enabled */ | ||
| 68743 | memset(&data[iStart], 0, iSize); | ||
| 68744 | } | ||
| 68745 | put2byte(&data[iStart], iFreeBlk); | ||
| 68746 | put2byte(&data[iStart+2], iSize); | ||
| 68747 | pPage->nFree += iOrigSize; | 71490 | pPage->nFree += iOrigSize; |
| 68748 | return SQLITE_OK; | 71491 | return SQLITE_OK; |
| 68749 | } | 71492 | } |
| @@ -68755,62 +71498,67 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ | |||
| 68755 | ** Only the following combinations are supported. Anything different | 71498 | ** Only the following combinations are supported. Anything different |
| 68756 | ** indicates a corrupt database files: | 71499 | ** indicates a corrupt database files: |
| 68757 | ** | 71500 | ** |
| 68758 | ** PTF_ZERODATA | 71501 | ** PTF_ZERODATA (0x02, 2) |
| 68759 | ** PTF_ZERODATA | PTF_LEAF | 71502 | ** PTF_LEAFDATA | PTF_INTKEY (0x05, 5) |
| 68760 | ** PTF_LEAFDATA | PTF_INTKEY | 71503 | ** PTF_ZERODATA | PTF_LEAF (0x0a, 10) |
| 68761 | ** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF | 71504 | ** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF (0x0d, 13) |
| 68762 | */ | 71505 | */ |
| 68763 | static int decodeFlags(MemPage *pPage, int flagByte){ | 71506 | static int decodeFlags(MemPage *pPage, int flagByte){ |
| 68764 | BtShared *pBt; /* A copy of pPage->pBt */ | 71507 | BtShared *pBt; /* A copy of pPage->pBt */ |
| 68765 | 71508 | ||
| 68766 | assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); | 71509 | assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); |
| 68767 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); | 71510 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 68768 | pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); | ||
| 68769 | flagByte &= ~PTF_LEAF; | ||
| 68770 | pPage->childPtrSize = 4-4*pPage->leaf; | ||
| 68771 | pBt = pPage->pBt; | 71511 | pBt = pPage->pBt; |
| 68772 | if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ | 71512 | pPage->max1bytePayload = pBt->max1bytePayload; |
| 68773 | /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an | 71513 | if( flagByte>=(PTF_ZERODATA | PTF_LEAF) ){ |
| 68774 | ** interior table b-tree page. */ | 71514 | pPage->childPtrSize = 0; |
| 68775 | assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); | 71515 | pPage->leaf = 1; |
| 68776 | /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a | 71516 | if( flagByte==(PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF) ){ |
| 68777 | ** leaf table b-tree page. */ | ||
| 68778 | assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); | ||
| 68779 | pPage->intKey = 1; | ||
| 68780 | if( pPage->leaf ){ | ||
| 68781 | pPage->intKeyLeaf = 1; | 71517 | pPage->intKeyLeaf = 1; |
| 68782 | pPage->xCellSize = cellSizePtrTableLeaf; | 71518 | pPage->xCellSize = cellSizePtrTableLeaf; |
| 68783 | pPage->xParseCell = btreeParseCellPtr; | 71519 | pPage->xParseCell = btreeParseCellPtr; |
| 71520 | pPage->intKey = 1; | ||
| 71521 | pPage->maxLocal = pBt->maxLeaf; | ||
| 71522 | pPage->minLocal = pBt->minLeaf; | ||
| 71523 | }else if( flagByte==(PTF_ZERODATA | PTF_LEAF) ){ | ||
| 71524 | pPage->intKey = 0; | ||
| 71525 | pPage->intKeyLeaf = 0; | ||
| 71526 | pPage->xCellSize = cellSizePtrIdxLeaf; | ||
| 71527 | pPage->xParseCell = btreeParseCellPtrIndex; | ||
| 71528 | pPage->maxLocal = pBt->maxLocal; | ||
| 71529 | pPage->minLocal = pBt->minLocal; | ||
| 68784 | }else{ | 71530 | }else{ |
| 71531 | pPage->intKey = 0; | ||
| 71532 | pPage->intKeyLeaf = 0; | ||
| 71533 | pPage->xCellSize = cellSizePtrIdxLeaf; | ||
| 71534 | pPage->xParseCell = btreeParseCellPtrIndex; | ||
| 71535 | return SQLITE_CORRUPT_PAGE(pPage); | ||
| 71536 | } | ||
| 71537 | }else{ | ||
| 71538 | pPage->childPtrSize = 4; | ||
| 71539 | pPage->leaf = 0; | ||
| 71540 | if( flagByte==(PTF_ZERODATA) ){ | ||
| 71541 | pPage->intKey = 0; | ||
| 71542 | pPage->intKeyLeaf = 0; | ||
| 71543 | pPage->xCellSize = cellSizePtr; | ||
| 71544 | pPage->xParseCell = btreeParseCellPtrIndex; | ||
| 71545 | pPage->maxLocal = pBt->maxLocal; | ||
| 71546 | pPage->minLocal = pBt->minLocal; | ||
| 71547 | }else if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ | ||
| 68785 | pPage->intKeyLeaf = 0; | 71548 | pPage->intKeyLeaf = 0; |
| 68786 | pPage->xCellSize = cellSizePtrNoPayload; | 71549 | pPage->xCellSize = cellSizePtrNoPayload; |
| 68787 | pPage->xParseCell = btreeParseCellPtrNoPayload; | 71550 | pPage->xParseCell = btreeParseCellPtrNoPayload; |
| 71551 | pPage->intKey = 1; | ||
| 71552 | pPage->maxLocal = pBt->maxLeaf; | ||
| 71553 | pPage->minLocal = pBt->minLeaf; | ||
| 71554 | }else{ | ||
| 71555 | pPage->intKey = 0; | ||
| 71556 | pPage->intKeyLeaf = 0; | ||
| 71557 | pPage->xCellSize = cellSizePtr; | ||
| 71558 | pPage->xParseCell = btreeParseCellPtrIndex; | ||
| 71559 | return SQLITE_CORRUPT_PAGE(pPage); | ||
| 68788 | } | 71560 | } |
| 68789 | pPage->maxLocal = pBt->maxLeaf; | ||
| 68790 | pPage->minLocal = pBt->minLeaf; | ||
| 68791 | }else if( flagByte==PTF_ZERODATA ){ | ||
| 68792 | /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an | ||
| 68793 | ** interior index b-tree page. */ | ||
| 68794 | assert( (PTF_ZERODATA)==2 ); | ||
| 68795 | /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a | ||
| 68796 | ** leaf index b-tree page. */ | ||
| 68797 | assert( (PTF_ZERODATA|PTF_LEAF)==10 ); | ||
| 68798 | pPage->intKey = 0; | ||
| 68799 | pPage->intKeyLeaf = 0; | ||
| 68800 | pPage->xCellSize = cellSizePtr; | ||
| 68801 | pPage->xParseCell = btreeParseCellPtrIndex; | ||
| 68802 | pPage->maxLocal = pBt->maxLocal; | ||
| 68803 | pPage->minLocal = pBt->minLocal; | ||
| 68804 | }else{ | ||
| 68805 | /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is | ||
| 68806 | ** an error. */ | ||
| 68807 | pPage->intKey = 0; | ||
| 68808 | pPage->intKeyLeaf = 0; | ||
| 68809 | pPage->xCellSize = cellSizePtr; | ||
| 68810 | pPage->xParseCell = btreeParseCellPtrIndex; | ||
| 68811 | return SQLITE_CORRUPT_PAGE(pPage); | ||
| 68812 | } | 71561 | } |
| 68813 | pPage->max1bytePayload = pBt->max1bytePayload; | ||
| 68814 | return SQLITE_OK; | 71562 | return SQLITE_OK; |
| 68815 | } | 71563 | } |
| 68816 | 71564 | ||
| @@ -69101,70 +71849,41 @@ SQLITE_PRIVATE Pgno sqlite3BtreeLastPage(Btree *p){ | |||
| 69101 | 71849 | ||
| 69102 | /* | 71850 | /* |
| 69103 | ** Get a page from the pager and initialize it. | 71851 | ** Get a page from the pager and initialize it. |
| 69104 | ** | ||
| 69105 | ** If pCur!=0 then the page is being fetched as part of a moveToChild() | ||
| 69106 | ** call. Do additional sanity checking on the page in this case. | ||
| 69107 | ** And if the fetch fails, this routine must decrement pCur->iPage. | ||
| 69108 | ** | ||
| 69109 | ** The page is fetched as read-write unless pCur is not NULL and is | ||
| 69110 | ** a read-only cursor. | ||
| 69111 | ** | ||
| 69112 | ** If an error occurs, then *ppPage is undefined. It | ||
| 69113 | ** may remain unchanged, or it may be set to an invalid value. | ||
| 69114 | */ | 71852 | */ |
| 69115 | static int getAndInitPage( | 71853 | static int getAndInitPage( |
| 69116 | BtShared *pBt, /* The database file */ | 71854 | BtShared *pBt, /* The database file */ |
| 69117 | Pgno pgno, /* Number of the page to get */ | 71855 | Pgno pgno, /* Number of the page to get */ |
| 69118 | MemPage **ppPage, /* Write the page pointer here */ | 71856 | MemPage **ppPage, /* Write the page pointer here */ |
| 69119 | BtCursor *pCur, /* Cursor to receive the page, or NULL */ | ||
| 69120 | int bReadOnly /* True for a read-only page */ | 71857 | int bReadOnly /* True for a read-only page */ |
| 69121 | ){ | 71858 | ){ |
| 69122 | int rc; | 71859 | int rc; |
| 69123 | DbPage *pDbPage; | 71860 | DbPage *pDbPage; |
| 71861 | MemPage *pPage; | ||
| 69124 | assert( sqlite3_mutex_held(pBt->mutex) ); | 71862 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 69125 | assert( pCur==0 || ppPage==&pCur->pPage ); | ||
| 69126 | assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); | ||
| 69127 | assert( pCur==0 || pCur->iPage>0 ); | ||
| 69128 | 71863 | ||
| 69129 | if( pgno>btreePagecount(pBt) ){ | 71864 | if( pgno>btreePagecount(pBt) ){ |
| 69130 | rc = SQLITE_CORRUPT_BKPT; | 71865 | *ppPage = 0; |
| 69131 | goto getAndInitPage_error1; | 71866 | return SQLITE_CORRUPT_BKPT; |
| 69132 | } | 71867 | } |
| 69133 | rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); | 71868 | rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); |
| 69134 | if( rc ){ | 71869 | if( rc ){ |
| 69135 | goto getAndInitPage_error1; | 71870 | *ppPage = 0; |
| 71871 | return rc; | ||
| 69136 | } | 71872 | } |
| 69137 | *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); | 71873 | pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); |
| 69138 | if( (*ppPage)->isInit==0 ){ | 71874 | if( pPage->isInit==0 ){ |
| 69139 | btreePageFromDbPage(pDbPage, pgno, pBt); | 71875 | btreePageFromDbPage(pDbPage, pgno, pBt); |
| 69140 | rc = btreeInitPage(*ppPage); | 71876 | rc = btreeInitPage(pPage); |
| 69141 | if( rc!=SQLITE_OK ){ | 71877 | if( rc!=SQLITE_OK ){ |
| 69142 | goto getAndInitPage_error2; | 71878 | releasePage(pPage); |
| 71879 | *ppPage = 0; | ||
| 71880 | return rc; | ||
| 69143 | } | 71881 | } |
| 69144 | } | 71882 | } |
| 69145 | assert( (*ppPage)->pgno==pgno || CORRUPT_DB ); | 71883 | assert( pPage->pgno==pgno || CORRUPT_DB ); |
| 69146 | assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); | 71884 | assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); |
| 69147 | 71885 | *ppPage = pPage; | |
| 69148 | /* If obtaining a child page for a cursor, we must verify that the page is | ||
| 69149 | ** compatible with the root page. */ | ||
| 69150 | if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){ | ||
| 69151 | rc = SQLITE_CORRUPT_PGNO(pgno); | ||
| 69152 | goto getAndInitPage_error2; | ||
| 69153 | } | ||
| 69154 | return SQLITE_OK; | 71886 | return SQLITE_OK; |
| 69155 | |||
| 69156 | getAndInitPage_error2: | ||
| 69157 | releasePage(*ppPage); | ||
| 69158 | getAndInitPage_error1: | ||
| 69159 | if( pCur ){ | ||
| 69160 | pCur->iPage--; | ||
| 69161 | pCur->pPage = pCur->apPage[pCur->iPage]; | ||
| 69162 | } | ||
| 69163 | testcase( pgno==0 ); | ||
| 69164 | assert( pgno!=0 || rc==SQLITE_CORRUPT | ||
| 69165 | || rc==SQLITE_IOERR_NOMEM | ||
| 69166 | || rc==SQLITE_NOMEM ); | ||
| 69167 | return rc; | ||
| 69168 | } | 71887 | } |
| 69169 | 71888 | ||
| 69170 | /* | 71889 | /* |
| @@ -69247,7 +71966,7 @@ static void pageReinit(DbPage *pData){ | |||
| 69247 | ** call to btreeInitPage() will likely return SQLITE_CORRUPT. | 71966 | ** call to btreeInitPage() will likely return SQLITE_CORRUPT. |
| 69248 | ** But no harm is done by this. And it is very important that | 71967 | ** But no harm is done by this. And it is very important that |
| 69249 | ** btreeInitPage() be called on every btree page so we make | 71968 | ** btreeInitPage() be called on every btree page so we make |
| 69250 | ** the call for every page that comes in for re-initing. */ | 71969 | ** the call for every page that comes in for re-initializing. */ |
| 69251 | btreeInitPage(pPage); | 71970 | btreeInitPage(pPage); |
| 69252 | } | 71971 | } |
| 69253 | } | 71972 | } |
| @@ -69426,6 +72145,9 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( | |||
| 69426 | assert( sizeof(u16)==2 ); | 72145 | assert( sizeof(u16)==2 ); |
| 69427 | assert( sizeof(Pgno)==4 ); | 72146 | assert( sizeof(Pgno)==4 ); |
| 69428 | 72147 | ||
| 72148 | /* Suppress false-positive compiler warning from PVS-Studio */ | ||
| 72149 | memset(&zDbHeader[16], 0, 8); | ||
| 72150 | |||
| 69429 | pBt = sqlite3MallocZero( sizeof(*pBt) ); | 72151 | pBt = sqlite3MallocZero( sizeof(*pBt) ); |
| 69430 | if( pBt==0 ){ | 72152 | if( pBt==0 ){ |
| 69431 | rc = SQLITE_NOMEM_BKPT; | 72153 | rc = SQLITE_NOMEM_BKPT; |
| @@ -69642,7 +72364,7 @@ static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){ | |||
| 69642 | ** can mean that fillInCell() only initializes the first 2 or 3 | 72364 | ** can mean that fillInCell() only initializes the first 2 or 3 |
| 69643 | ** bytes of pTmpSpace, but that the first 4 bytes are copied from | 72365 | ** bytes of pTmpSpace, but that the first 4 bytes are copied from |
| 69644 | ** it into a database page. This is not actually a problem, but it | 72366 | ** it into a database page. This is not actually a problem, but it |
| 69645 | ** does cause a valgrind error when the 1 or 2 bytes of unitialized | 72367 | ** does cause a valgrind error when the 1 or 2 bytes of uninitialized |
| 69646 | ** data is passed to system call write(). So to avoid this error, | 72368 | ** data is passed to system call write(). So to avoid this error, |
| 69647 | ** zero the first 4 bytes of temp space here. | 72369 | ** zero the first 4 bytes of temp space here. |
| 69648 | ** | 72370 | ** |
| @@ -69877,7 +72599,7 @@ SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){ | |||
| 69877 | 72599 | ||
| 69878 | /* | 72600 | /* |
| 69879 | ** Return the number of bytes of space at the end of every page that | 72601 | ** Return the number of bytes of space at the end of every page that |
| 69880 | ** are intentually left unused. This is the "reserved" space that is | 72602 | ** are intentionally left unused. This is the "reserved" space that is |
| 69881 | ** sometimes used by extensions. | 72603 | ** sometimes used by extensions. |
| 69882 | ** | 72604 | ** |
| 69883 | ** The value returned is the larger of the current reserve size and | 72605 | ** The value returned is the larger of the current reserve size and |
| @@ -70124,7 +72846,6 @@ static int lockBtree(BtShared *pBt){ | |||
| 70124 | ){ | 72846 | ){ |
| 70125 | goto page1_init_failed; | 72847 | goto page1_init_failed; |
| 70126 | } | 72848 | } |
| 70127 | pBt->btsFlags |= BTS_PAGESIZE_FIXED; | ||
| 70128 | assert( (pageSize & 7)==0 ); | 72849 | assert( (pageSize & 7)==0 ); |
| 70129 | /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte | 72850 | /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte |
| 70130 | ** integer at offset 20 is the number of bytes of space at the end of | 72851 | ** integer at offset 20 is the number of bytes of space at the end of |
| @@ -70144,6 +72865,7 @@ static int lockBtree(BtShared *pBt){ | |||
| 70144 | releasePageOne(pPage1); | 72865 | releasePageOne(pPage1); |
| 70145 | pBt->usableSize = usableSize; | 72866 | pBt->usableSize = usableSize; |
| 70146 | pBt->pageSize = pageSize; | 72867 | pBt->pageSize = pageSize; |
| 72868 | pBt->btsFlags |= BTS_PAGESIZE_FIXED; | ||
| 70147 | freeTempSpace(pBt); | 72869 | freeTempSpace(pBt); |
| 70148 | rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, | 72870 | rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, |
| 70149 | pageSize-usableSize); | 72871 | pageSize-usableSize); |
| @@ -70163,6 +72885,7 @@ static int lockBtree(BtShared *pBt){ | |||
| 70163 | if( usableSize<480 ){ | 72885 | if( usableSize<480 ){ |
| 70164 | goto page1_init_failed; | 72886 | goto page1_init_failed; |
| 70165 | } | 72887 | } |
| 72888 | pBt->btsFlags |= BTS_PAGESIZE_FIXED; | ||
| 70166 | pBt->pageSize = pageSize; | 72889 | pBt->pageSize = pageSize; |
| 70167 | pBt->usableSize = usableSize; | 72890 | pBt->usableSize = usableSize; |
| 70168 | #ifndef SQLITE_OMIT_AUTOVACUUM | 72891 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -70341,7 +73064,11 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ | |||
| 70341 | ** when A already has a read lock, we encourage A to give up and let B | 73064 | ** when A already has a read lock, we encourage A to give up and let B |
| 70342 | ** proceed. | 73065 | ** proceed. |
| 70343 | */ | 73066 | */ |
| 70344 | SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ | 73067 | static SQLITE_NOINLINE int btreeBeginTrans( |
| 73068 | Btree *p, /* The btree in which to start the transaction */ | ||
| 73069 | int wrflag, /* True to start a write transaction */ | ||
| 73070 | int *pSchemaVersion /* Put schema version number here, if not NULL */ | ||
| 73071 | ){ | ||
| 70345 | BtShared *pBt = p->pBt; | 73072 | BtShared *pBt = p->pBt; |
| 70346 | Pager *pPager = pBt->pPager; | 73073 | Pager *pPager = pBt->pPager; |
| 70347 | int rc = SQLITE_OK; | 73074 | int rc = SQLITE_OK; |
| @@ -70513,6 +73240,28 @@ trans_begun: | |||
| 70513 | sqlite3BtreeLeave(p); | 73240 | sqlite3BtreeLeave(p); |
| 70514 | return rc; | 73241 | return rc; |
| 70515 | } | 73242 | } |
| 73243 | SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ | ||
| 73244 | BtShared *pBt; | ||
| 73245 | if( p->sharable | ||
| 73246 | || p->inTrans==TRANS_NONE | ||
| 73247 | || (p->inTrans==TRANS_READ && wrflag!=0) | ||
| 73248 | ){ | ||
| 73249 | return btreeBeginTrans(p,wrflag,pSchemaVersion); | ||
| 73250 | } | ||
| 73251 | pBt = p->pBt; | ||
| 73252 | if( pSchemaVersion ){ | ||
| 73253 | *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); | ||
| 73254 | } | ||
| 73255 | if( wrflag ){ | ||
| 73256 | /* This call makes sure that the pager has the correct number of | ||
| 73257 | ** open savepoints. If the second parameter is greater than 0 and | ||
| 73258 | ** the sub-journal is not already open, then it will be opened here. | ||
| 73259 | */ | ||
| 73260 | return sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); | ||
| 73261 | }else{ | ||
| 73262 | return SQLITE_OK; | ||
| 73263 | } | ||
| 73264 | } | ||
| 70516 | 73265 | ||
| 70517 | #ifndef SQLITE_OMIT_AUTOVACUUM | 73266 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 70518 | 73267 | ||
| @@ -70599,6 +73348,9 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ | |||
| 70599 | } | 73348 | } |
| 70600 | } | 73349 | } |
| 70601 | }else{ | 73350 | }else{ |
| 73351 | if( pCell+4 > pPage->aData+pPage->pBt->usableSize ){ | ||
| 73352 | return SQLITE_CORRUPT_PAGE(pPage); | ||
| 73353 | } | ||
| 70602 | if( get4byte(pCell)==iFrom ){ | 73354 | if( get4byte(pCell)==iFrom ){ |
| 70603 | put4byte(pCell, iTo); | 73355 | put4byte(pCell, iTo); |
| 70604 | break; | 73356 | break; |
| @@ -70647,7 +73399,7 @@ static int relocatePage( | |||
| 70647 | if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; | 73399 | if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; |
| 70648 | 73400 | ||
| 70649 | /* Move page iDbPage from its current location to page number iFreePage */ | 73401 | /* Move page iDbPage from its current location to page number iFreePage */ |
| 70650 | TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", | 73402 | TRACE(("AUTOVACUUM: Moving %u to free page %u (ptr page %u type %u)\n", |
| 70651 | iDbPage, iFreePage, iPtrPage, eType)); | 73403 | iDbPage, iFreePage, iPtrPage, eType)); |
| 70652 | rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); | 73404 | rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); |
| 70653 | if( rc!=SQLITE_OK ){ | 73405 | if( rc!=SQLITE_OK ){ |
| @@ -71605,7 +74357,6 @@ SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){ | |||
| 71605 | pCur->curFlags &= ~BTCF_Pinned; | 74357 | pCur->curFlags &= ~BTCF_Pinned; |
| 71606 | } | 74358 | } |
| 71607 | 74359 | ||
| 71608 | #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC | ||
| 71609 | /* | 74360 | /* |
| 71610 | ** Return the offset into the database file for the start of the | 74361 | ** Return the offset into the database file for the start of the |
| 71611 | ** payload to which the cursor is pointing. | 74362 | ** payload to which the cursor is pointing. |
| @@ -71617,7 +74368,6 @@ SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){ | |||
| 71617 | return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) + | 74368 | return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) + |
| 71618 | (i64)(pCur->info.pPayload - pCur->pPage->aData); | 74369 | (i64)(pCur->info.pPayload - pCur->pPage->aData); |
| 71619 | } | 74370 | } |
| 71620 | #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ | ||
| 71621 | 74371 | ||
| 71622 | /* | 74372 | /* |
| 71623 | ** Return the number of bytes of payload for the entry that pCur is | 74373 | ** Return the number of bytes of payload for the entry that pCur is |
| @@ -71643,7 +74393,7 @@ SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){ | |||
| 71643 | ** routine always returns 2147483647 (which is the largest record | 74393 | ** routine always returns 2147483647 (which is the largest record |
| 71644 | ** that SQLite can handle) or more. But returning a smaller value might | 74394 | ** that SQLite can handle) or more. But returning a smaller value might |
| 71645 | ** prevent large memory allocations when trying to interpret a | 74395 | ** prevent large memory allocations when trying to interpret a |
| 71646 | ** corrupt datrabase. | 74396 | ** corrupt database. |
| 71647 | ** | 74397 | ** |
| 71648 | ** The current implementation merely returns the size of the underlying | 74398 | ** The current implementation merely returns the size of the underlying |
| 71649 | ** database file. | 74399 | ** database file. |
| @@ -72105,8 +74855,7 @@ SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ | |||
| 72105 | ** vice-versa). | 74855 | ** vice-versa). |
| 72106 | */ | 74856 | */ |
| 72107 | static int moveToChild(BtCursor *pCur, u32 newPgno){ | 74857 | static int moveToChild(BtCursor *pCur, u32 newPgno){ |
| 72108 | BtShared *pBt = pCur->pBt; | 74858 | int rc; |
| 72109 | |||
| 72110 | assert( cursorOwnsBtShared(pCur) ); | 74859 | assert( cursorOwnsBtShared(pCur) ); |
| 72111 | assert( pCur->eState==CURSOR_VALID ); | 74860 | assert( pCur->eState==CURSOR_VALID ); |
| 72112 | assert( pCur->iPage<BTCURSOR_MAX_DEPTH ); | 74861 | assert( pCur->iPage<BTCURSOR_MAX_DEPTH ); |
| @@ -72120,7 +74869,18 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ | |||
| 72120 | pCur->apPage[pCur->iPage] = pCur->pPage; | 74869 | pCur->apPage[pCur->iPage] = pCur->pPage; |
| 72121 | pCur->ix = 0; | 74870 | pCur->ix = 0; |
| 72122 | pCur->iPage++; | 74871 | pCur->iPage++; |
| 72123 | return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags); | 74872 | rc = getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur->curPagerFlags); |
| 74873 | assert( pCur->pPage!=0 || rc!=SQLITE_OK ); | ||
| 74874 | if( rc==SQLITE_OK | ||
| 74875 | && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) | ||
| 74876 | ){ | ||
| 74877 | releasePage(pCur->pPage); | ||
| 74878 | rc = SQLITE_CORRUPT_PGNO(newPgno); | ||
| 74879 | } | ||
| 74880 | if( rc ){ | ||
| 74881 | pCur->pPage = pCur->apPage[--pCur->iPage]; | ||
| 74882 | } | ||
| 74883 | return rc; | ||
| 72124 | } | 74884 | } |
| 72125 | 74885 | ||
| 72126 | #ifdef SQLITE_DEBUG | 74886 | #ifdef SQLITE_DEBUG |
| @@ -72226,8 +74986,8 @@ static int moveToRoot(BtCursor *pCur){ | |||
| 72226 | } | 74986 | } |
| 72227 | sqlite3BtreeClearCursor(pCur); | 74987 | sqlite3BtreeClearCursor(pCur); |
| 72228 | } | 74988 | } |
| 72229 | rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, | 74989 | rc = getAndInitPage(pCur->pBt, pCur->pgnoRoot, &pCur->pPage, |
| 72230 | 0, pCur->curPagerFlags); | 74990 | pCur->curPagerFlags); |
| 72231 | if( rc!=SQLITE_OK ){ | 74991 | if( rc!=SQLITE_OK ){ |
| 72232 | pCur->eState = CURSOR_INVALID; | 74992 | pCur->eState = CURSOR_INVALID; |
| 72233 | return rc; | 74993 | return rc; |
| @@ -72339,7 +75099,7 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ | |||
| 72339 | *pRes = 0; | 75099 | *pRes = 0; |
| 72340 | rc = moveToLeftmost(pCur); | 75100 | rc = moveToLeftmost(pCur); |
| 72341 | }else if( rc==SQLITE_EMPTY ){ | 75101 | }else if( rc==SQLITE_EMPTY ){ |
| 72342 | assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); | 75102 | assert( pCur->pgnoRoot==0 || (pCur->pPage!=0 && pCur->pPage->nCell==0) ); |
| 72343 | *pRes = 1; | 75103 | *pRes = 1; |
| 72344 | rc = SQLITE_OK; | 75104 | rc = SQLITE_OK; |
| 72345 | } | 75105 | } |
| @@ -72350,9 +75110,25 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ | |||
| 72350 | ** on success. Set *pRes to 0 if the cursor actually points to something | 75110 | ** on success. Set *pRes to 0 if the cursor actually points to something |
| 72351 | ** or set *pRes to 1 if the table is empty. | 75111 | ** or set *pRes to 1 if the table is empty. |
| 72352 | */ | 75112 | */ |
| 75113 | static SQLITE_NOINLINE int btreeLast(BtCursor *pCur, int *pRes){ | ||
| 75114 | int rc = moveToRoot(pCur); | ||
| 75115 | if( rc==SQLITE_OK ){ | ||
| 75116 | assert( pCur->eState==CURSOR_VALID ); | ||
| 75117 | *pRes = 0; | ||
| 75118 | rc = moveToRightmost(pCur); | ||
| 75119 | if( rc==SQLITE_OK ){ | ||
| 75120 | pCur->curFlags |= BTCF_AtLast; | ||
| 75121 | }else{ | ||
| 75122 | pCur->curFlags &= ~BTCF_AtLast; | ||
| 75123 | } | ||
| 75124 | }else if( rc==SQLITE_EMPTY ){ | ||
| 75125 | assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); | ||
| 75126 | *pRes = 1; | ||
| 75127 | rc = SQLITE_OK; | ||
| 75128 | } | ||
| 75129 | return rc; | ||
| 75130 | } | ||
| 72353 | SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ | 75131 | SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ |
| 72354 | int rc; | ||
| 72355 | |||
| 72356 | assert( cursorOwnsBtShared(pCur) ); | 75132 | assert( cursorOwnsBtShared(pCur) ); |
| 72357 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); | 75133 | assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); |
| 72358 | 75134 | ||
| @@ -72373,23 +75149,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ | |||
| 72373 | *pRes = 0; | 75149 | *pRes = 0; |
| 72374 | return SQLITE_OK; | 75150 | return SQLITE_OK; |
| 72375 | } | 75151 | } |
| 72376 | 75152 | return btreeLast(pCur, pRes); | |
| 72377 | rc = moveToRoot(pCur); | ||
| 72378 | if( rc==SQLITE_OK ){ | ||
| 72379 | assert( pCur->eState==CURSOR_VALID ); | ||
| 72380 | *pRes = 0; | ||
| 72381 | rc = moveToRightmost(pCur); | ||
| 72382 | if( rc==SQLITE_OK ){ | ||
| 72383 | pCur->curFlags |= BTCF_AtLast; | ||
| 72384 | }else{ | ||
| 72385 | pCur->curFlags &= ~BTCF_AtLast; | ||
| 72386 | } | ||
| 72387 | }else if( rc==SQLITE_EMPTY ){ | ||
| 72388 | assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); | ||
| 72389 | *pRes = 1; | ||
| 72390 | rc = SQLITE_OK; | ||
| 72391 | } | ||
| 72392 | return rc; | ||
| 72393 | } | 75153 | } |
| 72394 | 75154 | ||
| 72395 | /* Move the cursor so that it points to an entry in a table (a.k.a INTKEY) | 75155 | /* Move the cursor so that it points to an entry in a table (a.k.a INTKEY) |
| @@ -72444,7 +75204,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto( | |||
| 72444 | /* If the requested key is one more than the previous key, then | 75204 | /* If the requested key is one more than the previous key, then |
| 72445 | ** try to get there using sqlite3BtreeNext() rather than a full | 75205 | ** try to get there using sqlite3BtreeNext() rather than a full |
| 72446 | ** binary search. This is an optimization only. The correct answer | 75206 | ** binary search. This is an optimization only. The correct answer |
| 72447 | ** is still obtained without this case, only a little more slowely */ | 75207 | ** is still obtained without this case, only a little more slowly. */ |
| 72448 | if( pCur->info.nKey+1==intKey ){ | 75208 | if( pCur->info.nKey+1==intKey ){ |
| 72449 | *pRes = 0; | 75209 | *pRes = 0; |
| 72450 | rc = sqlite3BtreeNext(pCur, 0); | 75210 | rc = sqlite3BtreeNext(pCur, 0); |
| @@ -72840,10 +75600,36 @@ bypass_moveto_root: | |||
| 72840 | }else{ | 75600 | }else{ |
| 72841 | chldPg = get4byte(findCell(pPage, lwr)); | 75601 | chldPg = get4byte(findCell(pPage, lwr)); |
| 72842 | } | 75602 | } |
| 72843 | pCur->ix = (u16)lwr; | 75603 | |
| 72844 | rc = moveToChild(pCur, chldPg); | 75604 | /* This block is similar to an in-lined version of: |
| 72845 | if( rc ) break; | 75605 | ** |
| 72846 | } | 75606 | ** pCur->ix = (u16)lwr; |
| 75607 | ** rc = moveToChild(pCur, chldPg); | ||
| 75608 | ** if( rc ) break; | ||
| 75609 | */ | ||
| 75610 | pCur->info.nSize = 0; | ||
| 75611 | pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); | ||
| 75612 | if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ | ||
| 75613 | return SQLITE_CORRUPT_BKPT; | ||
| 75614 | } | ||
| 75615 | pCur->aiIdx[pCur->iPage] = (u16)lwr; | ||
| 75616 | pCur->apPage[pCur->iPage] = pCur->pPage; | ||
| 75617 | pCur->ix = 0; | ||
| 75618 | pCur->iPage++; | ||
| 75619 | rc = getAndInitPage(pCur->pBt, chldPg, &pCur->pPage, pCur->curPagerFlags); | ||
| 75620 | if( rc==SQLITE_OK | ||
| 75621 | && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) | ||
| 75622 | ){ | ||
| 75623 | releasePage(pCur->pPage); | ||
| 75624 | rc = SQLITE_CORRUPT_PGNO(chldPg); | ||
| 75625 | } | ||
| 75626 | if( rc ){ | ||
| 75627 | pCur->pPage = pCur->apPage[--pCur->iPage]; | ||
| 75628 | break; | ||
| 75629 | } | ||
| 75630 | /* | ||
| 75631 | ***** End of in-lined moveToChild() call */ | ||
| 75632 | } | ||
| 72847 | moveto_index_finish: | 75633 | moveto_index_finish: |
| 72848 | pCur->info.nSize = 0; | 75634 | pCur->info.nSize = 0; |
| 72849 | assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); | 75635 | assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); |
| @@ -72934,14 +75720,8 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ | |||
| 72934 | 75720 | ||
| 72935 | pPage = pCur->pPage; | 75721 | pPage = pCur->pPage; |
| 72936 | idx = ++pCur->ix; | 75722 | idx = ++pCur->ix; |
| 72937 | if( !pPage->isInit || sqlite3FaultSim(412) ){ | 75723 | if( sqlite3FaultSim(412) ) pPage->isInit = 0; |
| 72938 | /* The only known way for this to happen is for there to be a | 75724 | if( !pPage->isInit ){ |
| 72939 | ** recursive SQL function that does a DELETE operation as part of a | ||
| 72940 | ** SELECT which deletes content out from under an active cursor | ||
| 72941 | ** in a corrupt database file where the table being DELETE-ed from | ||
| 72942 | ** has pages in common with the table being queried. See TH3 | ||
| 72943 | ** module cov1/btree78.test testcase 220 (2018-06-08) for an | ||
| 72944 | ** example. */ | ||
| 72945 | return SQLITE_CORRUPT_BKPT; | 75725 | return SQLITE_CORRUPT_BKPT; |
| 72946 | } | 75726 | } |
| 72947 | 75727 | ||
| @@ -73117,8 +75897,8 @@ static int allocateBtreePage( | |||
| 73117 | assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); | 75897 | assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); |
| 73118 | pPage1 = pBt->pPage1; | 75898 | pPage1 = pBt->pPage1; |
| 73119 | mxPage = btreePagecount(pBt); | 75899 | mxPage = btreePagecount(pBt); |
| 73120 | /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36 | 75900 | /* EVIDENCE-OF: R-21003-45125 The 4-byte big-endian integer at offset 36 |
| 73121 | ** stores stores the total number of pages on the freelist. */ | 75901 | ** stores the total number of pages on the freelist. */ |
| 73122 | n = get4byte(&pPage1->aData[36]); | 75902 | n = get4byte(&pPage1->aData[36]); |
| 73123 | testcase( n==mxPage-1 ); | 75903 | testcase( n==mxPage-1 ); |
| 73124 | if( n>=mxPage ){ | 75904 | if( n>=mxPage ){ |
| @@ -73204,7 +75984,7 @@ static int allocateBtreePage( | |||
| 73204 | memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); | 75984 | memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); |
| 73205 | *ppPage = pTrunk; | 75985 | *ppPage = pTrunk; |
| 73206 | pTrunk = 0; | 75986 | pTrunk = 0; |
| 73207 | TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); | 75987 | TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); |
| 73208 | }else if( k>(u32)(pBt->usableSize/4 - 2) ){ | 75988 | }else if( k>(u32)(pBt->usableSize/4 - 2) ){ |
| 73209 | /* Value of k is out of range. Database corruption */ | 75989 | /* Value of k is out of range. Database corruption */ |
| 73210 | rc = SQLITE_CORRUPT_PGNO(iTrunk); | 75990 | rc = SQLITE_CORRUPT_PGNO(iTrunk); |
| @@ -73270,7 +76050,7 @@ static int allocateBtreePage( | |||
| 73270 | } | 76050 | } |
| 73271 | } | 76051 | } |
| 73272 | pTrunk = 0; | 76052 | pTrunk = 0; |
| 73273 | TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); | 76053 | TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); |
| 73274 | #endif | 76054 | #endif |
| 73275 | }else if( k>0 ){ | 76055 | }else if( k>0 ){ |
| 73276 | /* Extract a leaf from the trunk */ | 76056 | /* Extract a leaf from the trunk */ |
| @@ -73315,8 +76095,8 @@ static int allocateBtreePage( | |||
| 73315 | ){ | 76095 | ){ |
| 73316 | int noContent; | 76096 | int noContent; |
| 73317 | *pPgno = iPage; | 76097 | *pPgno = iPage; |
| 73318 | TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" | 76098 | TRACE(("ALLOCATE: %u was leaf %u of %u on trunk %u" |
| 73319 | ": %d more free pages\n", | 76099 | ": %u more free pages\n", |
| 73320 | *pPgno, closest+1, k, pTrunk->pgno, n-1)); | 76100 | *pPgno, closest+1, k, pTrunk->pgno, n-1)); |
| 73321 | rc = sqlite3PagerWrite(pTrunk->pDbPage); | 76101 | rc = sqlite3PagerWrite(pTrunk->pDbPage); |
| 73322 | if( rc ) goto end_allocate_page; | 76102 | if( rc ) goto end_allocate_page; |
| @@ -73372,7 +76152,7 @@ static int allocateBtreePage( | |||
| 73372 | ** becomes a new pointer-map page, the second is used by the caller. | 76152 | ** becomes a new pointer-map page, the second is used by the caller. |
| 73373 | */ | 76153 | */ |
| 73374 | MemPage *pPg = 0; | 76154 | MemPage *pPg = 0; |
| 73375 | TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); | 76155 | TRACE(("ALLOCATE: %u from end of file (pointer-map page)\n", pBt->nPage)); |
| 73376 | assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); | 76156 | assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); |
| 73377 | rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); | 76157 | rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); |
| 73378 | if( rc==SQLITE_OK ){ | 76158 | if( rc==SQLITE_OK ){ |
| @@ -73395,7 +76175,7 @@ static int allocateBtreePage( | |||
| 73395 | releasePage(*ppPage); | 76175 | releasePage(*ppPage); |
| 73396 | *ppPage = 0; | 76176 | *ppPage = 0; |
| 73397 | } | 76177 | } |
| 73398 | TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); | 76178 | TRACE(("ALLOCATE: %u from end of file\n", *pPgno)); |
| 73399 | } | 76179 | } |
| 73400 | 76180 | ||
| 73401 | assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) ); | 76181 | assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) ); |
| @@ -73463,7 +76243,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ | |||
| 73463 | /* If the database supports auto-vacuum, write an entry in the pointer-map | 76243 | /* If the database supports auto-vacuum, write an entry in the pointer-map |
| 73464 | ** to indicate that the page is free. | 76244 | ** to indicate that the page is free. |
| 73465 | */ | 76245 | */ |
| 73466 | if( ISAUTOVACUUM ){ | 76246 | if( ISAUTOVACUUM(pBt) ){ |
| 73467 | ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); | 76247 | ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); |
| 73468 | if( rc ) goto freepage_out; | 76248 | if( rc ) goto freepage_out; |
| 73469 | } | 76249 | } |
| @@ -73523,7 +76303,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ | |||
| 73523 | } | 76303 | } |
| 73524 | rc = btreeSetHasContent(pBt, iPage); | 76304 | rc = btreeSetHasContent(pBt, iPage); |
| 73525 | } | 76305 | } |
| 73526 | TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); | 76306 | TRACE(("FREE-PAGE: %u leaf on trunk page %u\n",pPage->pgno,pTrunk->pgno)); |
| 73527 | goto freepage_out; | 76307 | goto freepage_out; |
| 73528 | } | 76308 | } |
| 73529 | } | 76309 | } |
| @@ -73544,7 +76324,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ | |||
| 73544 | put4byte(pPage->aData, iTrunk); | 76324 | put4byte(pPage->aData, iTrunk); |
| 73545 | put4byte(&pPage->aData[4], 0); | 76325 | put4byte(&pPage->aData[4], 0); |
| 73546 | put4byte(&pPage1->aData[32], iPage); | 76326 | put4byte(&pPage1->aData[32], iPage); |
| 73547 | TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk)); | 76327 | TRACE(("FREE-PAGE: %u new trunk page replacing %u\n", pPage->pgno, iTrunk)); |
| 73548 | 76328 | ||
| 73549 | freepage_out: | 76329 | freepage_out: |
| 73550 | if( pPage ){ | 76330 | if( pPage ){ |
| @@ -73633,7 +76413,7 @@ static SQLITE_NOINLINE int clearCellOverflow( | |||
| 73633 | 76413 | ||
| 73634 | /* Call xParseCell to compute the size of a cell. If the cell contains | 76414 | /* Call xParseCell to compute the size of a cell. If the cell contains |
| 73635 | ** overflow, then invoke cellClearOverflow to clear out that overflow. | 76415 | ** overflow, then invoke cellClearOverflow to clear out that overflow. |
| 73636 | ** STore the result code (SQLITE_OK or some error code) in rc. | 76416 | ** Store the result code (SQLITE_OK or some error code) in rc. |
| 73637 | ** | 76417 | ** |
| 73638 | ** Implemented as macro to force inlining for performance. | 76418 | ** Implemented as macro to force inlining for performance. |
| 73639 | */ | 76419 | */ |
| @@ -73867,12 +76647,6 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ | |||
| 73867 | assert( pPage->pBt->usableSize > (u32)(ptr-data) ); | 76647 | assert( pPage->pBt->usableSize > (u32)(ptr-data) ); |
| 73868 | pc = get2byte(ptr); | 76648 | pc = get2byte(ptr); |
| 73869 | hdr = pPage->hdrOffset; | 76649 | hdr = pPage->hdrOffset; |
| 73870 | #if 0 /* Not required. Omit for efficiency */ | ||
| 73871 | if( pc<hdr+pPage->nCell*2 ){ | ||
| 73872 | *pRC = SQLITE_CORRUPT_BKPT; | ||
| 73873 | return; | ||
| 73874 | } | ||
| 73875 | #endif | ||
| 73876 | testcase( pc==(u32)get2byte(&data[hdr+5]) ); | 76650 | testcase( pc==(u32)get2byte(&data[hdr+5]) ); |
| 73877 | testcase( pc+sz==pPage->pBt->usableSize ); | 76651 | testcase( pc+sz==pPage->pBt->usableSize ); |
| 73878 | if( pc+sz > pPage->pBt->usableSize ){ | 76652 | if( pc+sz > pPage->pBt->usableSize ){ |
| @@ -73910,23 +76684,27 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ | |||
| 73910 | ** Allocating a new entry in pPage->aCell[] implies that | 76684 | ** Allocating a new entry in pPage->aCell[] implies that |
| 73911 | ** pPage->nOverflow is incremented. | 76685 | ** pPage->nOverflow is incremented. |
| 73912 | ** | 76686 | ** |
| 73913 | ** *pRC must be SQLITE_OK when this routine is called. | 76687 | ** The insertCellFast() routine below works exactly the same as |
| 76688 | ** insertCell() except that it lacks the pTemp and iChild parameters | ||
| 76689 | ** which are assumed zero. Other than that, the two routines are the | ||
| 76690 | ** same. | ||
| 76691 | ** | ||
| 76692 | ** Fixes or enhancements to this routine should be reflected in | ||
| 76693 | ** insertCellFast()! | ||
| 73914 | */ | 76694 | */ |
| 73915 | static void insertCell( | 76695 | static int insertCell( |
| 73916 | MemPage *pPage, /* Page into which we are copying */ | 76696 | MemPage *pPage, /* Page into which we are copying */ |
| 73917 | int i, /* New cell becomes the i-th cell of the page */ | 76697 | int i, /* New cell becomes the i-th cell of the page */ |
| 73918 | u8 *pCell, /* Content of the new cell */ | 76698 | u8 *pCell, /* Content of the new cell */ |
| 73919 | int sz, /* Bytes of content in pCell */ | 76699 | int sz, /* Bytes of content in pCell */ |
| 73920 | u8 *pTemp, /* Temp storage space for pCell, if needed */ | 76700 | u8 *pTemp, /* Temp storage space for pCell, if needed */ |
| 73921 | Pgno iChild, /* If non-zero, replace first 4 bytes with this value */ | 76701 | Pgno iChild /* If non-zero, replace first 4 bytes with this value */ |
| 73922 | int *pRC /* Read and write return code from here */ | ||
| 73923 | ){ | 76702 | ){ |
| 73924 | int idx = 0; /* Where to write new cell content in data[] */ | 76703 | int idx = 0; /* Where to write new cell content in data[] */ |
| 73925 | int j; /* Loop counter */ | 76704 | int j; /* Loop counter */ |
| 73926 | u8 *data; /* The content of the whole page */ | 76705 | u8 *data; /* The content of the whole page */ |
| 73927 | u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ | 76706 | u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ |
| 73928 | 76707 | ||
| 73929 | assert( *pRC==SQLITE_OK ); | ||
| 73930 | assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); | 76708 | assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); |
| 73931 | assert( MX_CELL(pPage->pBt)<=10921 ); | 76709 | assert( MX_CELL(pPage->pBt)<=10921 ); |
| 73932 | assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); | 76710 | assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); |
| @@ -73935,14 +76713,103 @@ static void insertCell( | |||
| 73935 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); | 76713 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 73936 | assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); | 76714 | assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); |
| 73937 | assert( pPage->nFree>=0 ); | 76715 | assert( pPage->nFree>=0 ); |
| 76716 | assert( iChild>0 ); | ||
| 73938 | if( pPage->nOverflow || sz+2>pPage->nFree ){ | 76717 | if( pPage->nOverflow || sz+2>pPage->nFree ){ |
| 73939 | if( pTemp ){ | 76718 | if( pTemp ){ |
| 73940 | memcpy(pTemp, pCell, sz); | 76719 | memcpy(pTemp, pCell, sz); |
| 73941 | pCell = pTemp; | 76720 | pCell = pTemp; |
| 73942 | } | 76721 | } |
| 73943 | if( iChild ){ | 76722 | put4byte(pCell, iChild); |
| 73944 | put4byte(pCell, iChild); | 76723 | j = pPage->nOverflow++; |
| 76724 | /* Comparison against ArraySize-1 since we hold back one extra slot | ||
| 76725 | ** as a contingency. In other words, never need more than 3 overflow | ||
| 76726 | ** slots but 4 are allocated, just to be safe. */ | ||
| 76727 | assert( j < ArraySize(pPage->apOvfl)-1 ); | ||
| 76728 | pPage->apOvfl[j] = pCell; | ||
| 76729 | pPage->aiOvfl[j] = (u16)i; | ||
| 76730 | |||
| 76731 | /* When multiple overflows occur, they are always sequential and in | ||
| 76732 | ** sorted order. This invariants arise because multiple overflows can | ||
| 76733 | ** only occur when inserting divider cells into the parent page during | ||
| 76734 | ** balancing, and the dividers are adjacent and sorted. | ||
| 76735 | */ | ||
| 76736 | assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ | ||
| 76737 | assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ | ||
| 76738 | }else{ | ||
| 76739 | int rc = sqlite3PagerWrite(pPage->pDbPage); | ||
| 76740 | if( NEVER(rc!=SQLITE_OK) ){ | ||
| 76741 | return rc; | ||
| 76742 | } | ||
| 76743 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); | ||
| 76744 | data = pPage->aData; | ||
| 76745 | assert( &data[pPage->cellOffset]==pPage->aCellIdx ); | ||
| 76746 | rc = allocateSpace(pPage, sz, &idx); | ||
| 76747 | if( rc ){ return rc; } | ||
| 76748 | /* The allocateSpace() routine guarantees the following properties | ||
| 76749 | ** if it returns successfully */ | ||
| 76750 | assert( idx >= 0 ); | ||
| 76751 | assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); | ||
| 76752 | assert( idx+sz <= (int)pPage->pBt->usableSize ); | ||
| 76753 | pPage->nFree -= (u16)(2 + sz); | ||
| 76754 | /* In a corrupt database where an entry in the cell index section of | ||
| 76755 | ** a btree page has a value of 3 or less, the pCell value might point | ||
| 76756 | ** as many as 4 bytes in front of the start of the aData buffer for | ||
| 76757 | ** the source page. Make sure this does not cause problems by not | ||
| 76758 | ** reading the first 4 bytes */ | ||
| 76759 | memcpy(&data[idx+4], pCell+4, sz-4); | ||
| 76760 | put4byte(&data[idx], iChild); | ||
| 76761 | pIns = pPage->aCellIdx + i*2; | ||
| 76762 | memmove(pIns+2, pIns, 2*(pPage->nCell - i)); | ||
| 76763 | put2byte(pIns, idx); | ||
| 76764 | pPage->nCell++; | ||
| 76765 | /* increment the cell count */ | ||
| 76766 | if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; | ||
| 76767 | assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); | ||
| 76768 | #ifndef SQLITE_OMIT_AUTOVACUUM | ||
| 76769 | if( pPage->pBt->autoVacuum ){ | ||
| 76770 | int rc2 = SQLITE_OK; | ||
| 76771 | /* The cell may contain a pointer to an overflow page. If so, write | ||
| 76772 | ** the entry for the overflow page into the pointer map. | ||
| 76773 | */ | ||
| 76774 | ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); | ||
| 76775 | if( rc2 ) return rc2; | ||
| 73945 | } | 76776 | } |
| 76777 | #endif | ||
| 76778 | } | ||
| 76779 | return SQLITE_OK; | ||
| 76780 | } | ||
| 76781 | |||
| 76782 | /* | ||
| 76783 | ** This variant of insertCell() assumes that the pTemp and iChild | ||
| 76784 | ** parameters are both zero. Use this variant in sqlite3BtreeInsert() | ||
| 76785 | ** for performance improvement, and also so that this variant is only | ||
| 76786 | ** called from that one place, and is thus inlined, and thus runs must | ||
| 76787 | ** faster. | ||
| 76788 | ** | ||
| 76789 | ** Fixes or enhancements to this routine should be reflected into | ||
| 76790 | ** the insertCell() routine. | ||
| 76791 | */ | ||
| 76792 | static int insertCellFast( | ||
| 76793 | MemPage *pPage, /* Page into which we are copying */ | ||
| 76794 | int i, /* New cell becomes the i-th cell of the page */ | ||
| 76795 | u8 *pCell, /* Content of the new cell */ | ||
| 76796 | int sz /* Bytes of content in pCell */ | ||
| 76797 | ){ | ||
| 76798 | int idx = 0; /* Where to write new cell content in data[] */ | ||
| 76799 | int j; /* Loop counter */ | ||
| 76800 | u8 *data; /* The content of the whole page */ | ||
| 76801 | u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ | ||
| 76802 | |||
| 76803 | assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); | ||
| 76804 | assert( MX_CELL(pPage->pBt)<=10921 ); | ||
| 76805 | assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); | ||
| 76806 | assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); | ||
| 76807 | assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); | ||
| 76808 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); | ||
| 76809 | assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); | ||
| 76810 | assert( pPage->nFree>=0 ); | ||
| 76811 | assert( pPage->nOverflow==0 ); | ||
| 76812 | if( sz+2>pPage->nFree ){ | ||
| 73946 | j = pPage->nOverflow++; | 76813 | j = pPage->nOverflow++; |
| 73947 | /* Comparison against ArraySize-1 since we hold back one extra slot | 76814 | /* Comparison against ArraySize-1 since we hold back one extra slot |
| 73948 | ** as a contingency. In other words, never need more than 3 overflow | 76815 | ** as a contingency. In other words, never need more than 3 overflow |
| @@ -73961,31 +76828,20 @@ static void insertCell( | |||
| 73961 | }else{ | 76828 | }else{ |
| 73962 | int rc = sqlite3PagerWrite(pPage->pDbPage); | 76829 | int rc = sqlite3PagerWrite(pPage->pDbPage); |
| 73963 | if( rc!=SQLITE_OK ){ | 76830 | if( rc!=SQLITE_OK ){ |
| 73964 | *pRC = rc; | 76831 | return rc; |
| 73965 | return; | ||
| 73966 | } | 76832 | } |
| 73967 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); | 76833 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); |
| 73968 | data = pPage->aData; | 76834 | data = pPage->aData; |
| 73969 | assert( &data[pPage->cellOffset]==pPage->aCellIdx ); | 76835 | assert( &data[pPage->cellOffset]==pPage->aCellIdx ); |
| 73970 | rc = allocateSpace(pPage, sz, &idx); | 76836 | rc = allocateSpace(pPage, sz, &idx); |
| 73971 | if( rc ){ *pRC = rc; return; } | 76837 | if( rc ){ return rc; } |
| 73972 | /* The allocateSpace() routine guarantees the following properties | 76838 | /* The allocateSpace() routine guarantees the following properties |
| 73973 | ** if it returns successfully */ | 76839 | ** if it returns successfully */ |
| 73974 | assert( idx >= 0 ); | 76840 | assert( idx >= 0 ); |
| 73975 | assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); | 76841 | assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); |
| 73976 | assert( idx+sz <= (int)pPage->pBt->usableSize ); | 76842 | assert( idx+sz <= (int)pPage->pBt->usableSize ); |
| 73977 | pPage->nFree -= (u16)(2 + sz); | 76843 | pPage->nFree -= (u16)(2 + sz); |
| 73978 | if( iChild ){ | 76844 | memcpy(&data[idx], pCell, sz); |
| 73979 | /* In a corrupt database where an entry in the cell index section of | ||
| 73980 | ** a btree page has a value of 3 or less, the pCell value might point | ||
| 73981 | ** as many as 4 bytes in front of the start of the aData buffer for | ||
| 73982 | ** the source page. Make sure this does not cause problems by not | ||
| 73983 | ** reading the first 4 bytes */ | ||
| 73984 | memcpy(&data[idx+4], pCell+4, sz-4); | ||
| 73985 | put4byte(&data[idx], iChild); | ||
| 73986 | }else{ | ||
| 73987 | memcpy(&data[idx], pCell, sz); | ||
| 73988 | } | ||
| 73989 | pIns = pPage->aCellIdx + i*2; | 76845 | pIns = pPage->aCellIdx + i*2; |
| 73990 | memmove(pIns+2, pIns, 2*(pPage->nCell - i)); | 76846 | memmove(pIns+2, pIns, 2*(pPage->nCell - i)); |
| 73991 | put2byte(pIns, idx); | 76847 | put2byte(pIns, idx); |
| @@ -73995,13 +76851,16 @@ static void insertCell( | |||
| 73995 | assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); | 76851 | assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); |
| 73996 | #ifndef SQLITE_OMIT_AUTOVACUUM | 76852 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 73997 | if( pPage->pBt->autoVacuum ){ | 76853 | if( pPage->pBt->autoVacuum ){ |
| 76854 | int rc2 = SQLITE_OK; | ||
| 73998 | /* The cell may contain a pointer to an overflow page. If so, write | 76855 | /* The cell may contain a pointer to an overflow page. If so, write |
| 73999 | ** the entry for the overflow page into the pointer map. | 76856 | ** the entry for the overflow page into the pointer map. |
| 74000 | */ | 76857 | */ |
| 74001 | ptrmapPutOvflPtr(pPage, pPage, pCell, pRC); | 76858 | ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); |
| 76859 | if( rc2 ) return rc2; | ||
| 74002 | } | 76860 | } |
| 74003 | #endif | 76861 | #endif |
| 74004 | } | 76862 | } |
| 76863 | return SQLITE_OK; | ||
| 74005 | } | 76864 | } |
| 74006 | 76865 | ||
| 74007 | /* | 76866 | /* |
| @@ -74102,14 +76961,16 @@ struct CellArray { | |||
| 74102 | ** computed. | 76961 | ** computed. |
| 74103 | */ | 76962 | */ |
| 74104 | static void populateCellCache(CellArray *p, int idx, int N){ | 76963 | static void populateCellCache(CellArray *p, int idx, int N){ |
| 76964 | MemPage *pRef = p->pRef; | ||
| 76965 | u16 *szCell = p->szCell; | ||
| 74105 | assert( idx>=0 && idx+N<=p->nCell ); | 76966 | assert( idx>=0 && idx+N<=p->nCell ); |
| 74106 | while( N>0 ){ | 76967 | while( N>0 ){ |
| 74107 | assert( p->apCell[idx]!=0 ); | 76968 | assert( p->apCell[idx]!=0 ); |
| 74108 | if( p->szCell[idx]==0 ){ | 76969 | if( szCell[idx]==0 ){ |
| 74109 | p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]); | 76970 | szCell[idx] = pRef->xCellSize(pRef, p->apCell[idx]); |
| 74110 | }else{ | 76971 | }else{ |
| 74111 | assert( CORRUPT_DB || | 76972 | assert( CORRUPT_DB || |
| 74112 | p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) ); | 76973 | szCell[idx]==pRef->xCellSize(pRef, p->apCell[idx]) ); |
| 74113 | } | 76974 | } |
| 74114 | idx++; | 76975 | idx++; |
| 74115 | N--; | 76976 | N--; |
| @@ -74165,10 +77026,10 @@ static int rebuildPage( | |||
| 74165 | 77026 | ||
| 74166 | assert( i<iEnd ); | 77027 | assert( i<iEnd ); |
| 74167 | j = get2byte(&aData[hdr+5]); | 77028 | j = get2byte(&aData[hdr+5]); |
| 74168 | if( j>(u32)usableSize ){ j = 0; } | 77029 | if( NEVER(j>(u32)usableSize) ){ j = 0; } |
| 74169 | memcpy(&pTmp[j], &aData[j], usableSize - j); | 77030 | memcpy(&pTmp[j], &aData[j], usableSize - j); |
| 74170 | 77031 | ||
| 74171 | for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){} | 77032 | for(k=0; ALWAYS(k<NB*2) && pCArray->ixNx[k]<=i; k++){} |
| 74172 | pSrcEnd = pCArray->apEnd[k]; | 77033 | pSrcEnd = pCArray->apEnd[k]; |
| 74173 | 77034 | ||
| 74174 | pData = pEnd; | 77035 | pData = pEnd; |
| @@ -74231,7 +77092,7 @@ static int rebuildPage( | |||
| 74231 | ** Finally, argument pBegin points to the byte immediately following the | 77092 | ** Finally, argument pBegin points to the byte immediately following the |
| 74232 | ** end of the space required by this page for the cell-pointer area (for | 77093 | ** end of the space required by this page for the cell-pointer area (for |
| 74233 | ** all cells - not just those inserted by the current call). If the content | 77094 | ** all cells - not just those inserted by the current call). If the content |
| 74234 | ** area must be extended to before this point in order to accomodate all | 77095 | ** area must be extended to before this point in order to accommodate all |
| 74235 | ** cells in apCell[], then the cells do not fit and non-zero is returned. | 77096 | ** cells in apCell[], then the cells do not fit and non-zero is returned. |
| 74236 | */ | 77097 | */ |
| 74237 | static int pageInsertArray( | 77098 | static int pageInsertArray( |
| @@ -74251,7 +77112,7 @@ static int pageInsertArray( | |||
| 74251 | u8 *pEnd; /* Maximum extent of cell data */ | 77112 | u8 *pEnd; /* Maximum extent of cell data */ |
| 74252 | assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ | 77113 | assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ |
| 74253 | if( iEnd<=iFirst ) return 0; | 77114 | if( iEnd<=iFirst ) return 0; |
| 74254 | for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){} | 77115 | for(k=0; ALWAYS(k<NB*2) && pCArray->ixNx[k]<=i ; k++){} |
| 74255 | pEnd = pCArray->apEnd[k]; | 77116 | pEnd = pCArray->apEnd[k]; |
| 74256 | while( 1 /*Exit by break*/ ){ | 77117 | while( 1 /*Exit by break*/ ){ |
| 74257 | int sz, rc; | 77118 | int sz, rc; |
| @@ -74309,39 +77170,50 @@ static int pageFreeArray( | |||
| 74309 | u8 * const pEnd = &aData[pPg->pBt->usableSize]; | 77170 | u8 * const pEnd = &aData[pPg->pBt->usableSize]; |
| 74310 | u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; | 77171 | u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; |
| 74311 | int nRet = 0; | 77172 | int nRet = 0; |
| 74312 | int i; | 77173 | int i, j; |
| 74313 | int iEnd = iFirst + nCell; | 77174 | int iEnd = iFirst + nCell; |
| 74314 | u8 *pFree = 0; | 77175 | int nFree = 0; |
| 74315 | int szFree = 0; | 77176 | int aOfst[10]; |
| 77177 | int aAfter[10]; | ||
| 74316 | 77178 | ||
| 74317 | for(i=iFirst; i<iEnd; i++){ | 77179 | for(i=iFirst; i<iEnd; i++){ |
| 74318 | u8 *pCell = pCArray->apCell[i]; | 77180 | u8 *pCell = pCArray->apCell[i]; |
| 74319 | if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ | 77181 | if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ |
| 74320 | int sz; | 77182 | int sz; |
| 77183 | int iAfter; | ||
| 77184 | int iOfst; | ||
| 74321 | /* No need to use cachedCellSize() here. The sizes of all cells that | 77185 | /* No need to use cachedCellSize() here. The sizes of all cells that |
| 74322 | ** are to be freed have already been computing while deciding which | 77186 | ** are to be freed have already been computing while deciding which |
| 74323 | ** cells need freeing */ | 77187 | ** cells need freeing */ |
| 74324 | sz = pCArray->szCell[i]; assert( sz>0 ); | 77188 | sz = pCArray->szCell[i]; assert( sz>0 ); |
| 74325 | if( pFree!=(pCell + sz) ){ | 77189 | iOfst = (u16)(pCell - aData); |
| 74326 | if( pFree ){ | 77190 | iAfter = iOfst+sz; |
| 74327 | assert( pFree>aData && (pFree - aData)<65536 ); | 77191 | for(j=0; j<nFree; j++){ |
| 74328 | freeSpace(pPg, (u16)(pFree - aData), szFree); | 77192 | if( aOfst[j]==iAfter ){ |
| 74329 | } | 77193 | aOfst[j] = iOfst; |
| 74330 | pFree = pCell; | 77194 | break; |
| 74331 | szFree = sz; | 77195 | }else if( aAfter[j]==iOfst ){ |
| 74332 | if( pFree+sz>pEnd ){ | 77196 | aAfter[j] = iAfter; |
| 74333 | return 0; | 77197 | break; |
| 74334 | } | 77198 | } |
| 74335 | }else{ | 77199 | } |
| 74336 | pFree = pCell; | 77200 | if( j>=nFree ){ |
| 74337 | szFree += sz; | 77201 | if( nFree>=(int)(sizeof(aOfst)/sizeof(aOfst[0])) ){ |
| 77202 | for(j=0; j<nFree; j++){ | ||
| 77203 | freeSpace(pPg, aOfst[j], aAfter[j]-aOfst[j]); | ||
| 77204 | } | ||
| 77205 | nFree = 0; | ||
| 77206 | } | ||
| 77207 | aOfst[nFree] = iOfst; | ||
| 77208 | aAfter[nFree] = iAfter; | ||
| 77209 | if( &aData[iAfter]>pEnd ) return 0; | ||
| 77210 | nFree++; | ||
| 74338 | } | 77211 | } |
| 74339 | nRet++; | 77212 | nRet++; |
| 74340 | } | 77213 | } |
| 74341 | } | 77214 | } |
| 74342 | if( pFree ){ | 77215 | for(j=0; j<nFree; j++){ |
| 74343 | assert( pFree>aData && (pFree - aData)<65536 ); | 77216 | freeSpace(pPg, aOfst[j], aAfter[j]-aOfst[j]); |
| 74344 | freeSpace(pPg, (u16)(pFree - aData), szFree); | ||
| 74345 | } | 77217 | } |
| 74346 | return nRet; | 77218 | return nRet; |
| 74347 | } | 77219 | } |
| @@ -74394,9 +77266,9 @@ static int editPage( | |||
| 74394 | nCell -= nTail; | 77266 | nCell -= nTail; |
| 74395 | } | 77267 | } |
| 74396 | 77268 | ||
| 74397 | pData = &aData[get2byteNotZero(&aData[hdr+5])]; | 77269 | pData = &aData[get2byte(&aData[hdr+5])]; |
| 74398 | if( pData<pBegin ) goto editpage_fail; | 77270 | if( pData<pBegin ) goto editpage_fail; |
| 74399 | if( pData>pPg->aDataEnd ) goto editpage_fail; | 77271 | if( NEVER(pData>pPg->aDataEnd) ) goto editpage_fail; |
| 74400 | 77272 | ||
| 74401 | /* Add cells to the start of the page */ | 77273 | /* Add cells to the start of the page */ |
| 74402 | if( iNew<iOld ){ | 77274 | if( iNew<iOld ){ |
| @@ -74535,12 +77407,12 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ | |||
| 74535 | ** with entries for the new page, and any pointer from the | 77407 | ** with entries for the new page, and any pointer from the |
| 74536 | ** cell on the page to an overflow page. If either of these | 77408 | ** cell on the page to an overflow page. If either of these |
| 74537 | ** operations fails, the return code is set, but the contents | 77409 | ** operations fails, the return code is set, but the contents |
| 74538 | ** of the parent page are still manipulated by thh code below. | 77410 | ** of the parent page are still manipulated by the code below. |
| 74539 | ** That is Ok, at this point the parent page is guaranteed to | 77411 | ** That is Ok, at this point the parent page is guaranteed to |
| 74540 | ** be marked as dirty. Returning an error code will cause a | 77412 | ** be marked as dirty. Returning an error code will cause a |
| 74541 | ** rollback, undoing any changes made to the parent page. | 77413 | ** rollback, undoing any changes made to the parent page. |
| 74542 | */ | 77414 | */ |
| 74543 | if( ISAUTOVACUUM ){ | 77415 | if( ISAUTOVACUUM(pBt) ){ |
| 74544 | ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); | 77416 | ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); |
| 74545 | if( szCell>pNew->minLocal ){ | 77417 | if( szCell>pNew->minLocal ){ |
| 74546 | ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); | 77418 | ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); |
| @@ -74568,8 +77440,8 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ | |||
| 74568 | 77440 | ||
| 74569 | /* Insert the new divider cell into pParent. */ | 77441 | /* Insert the new divider cell into pParent. */ |
| 74570 | if( rc==SQLITE_OK ){ | 77442 | if( rc==SQLITE_OK ){ |
| 74571 | insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace), | 77443 | rc = insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace), |
| 74572 | 0, pPage->pgno, &rc); | 77444 | 0, pPage->pgno); |
| 74573 | } | 77445 | } |
| 74574 | 77446 | ||
| 74575 | /* Set the right-child pointer of pParent to point to the new page. */ | 77447 | /* Set the right-child pointer of pParent to point to the new page. */ |
| @@ -74678,7 +77550,7 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ | |||
| 74678 | /* If this is an auto-vacuum database, update the pointer-map entries | 77550 | /* If this is an auto-vacuum database, update the pointer-map entries |
| 74679 | ** for any b-tree or overflow pages that pTo now contains the pointers to. | 77551 | ** for any b-tree or overflow pages that pTo now contains the pointers to. |
| 74680 | */ | 77552 | */ |
| 74681 | if( ISAUTOVACUUM ){ | 77553 | if( ISAUTOVACUUM(pBt) ){ |
| 74682 | *pRC = setChildPtrmaps(pTo); | 77554 | *pRC = setChildPtrmaps(pTo); |
| 74683 | } | 77555 | } |
| 74684 | } | 77556 | } |
| @@ -74756,8 +77628,6 @@ static int balance_nonroot( | |||
| 74756 | Pgno pgno; /* Temp var to store a page number in */ | 77628 | Pgno pgno; /* Temp var to store a page number in */ |
| 74757 | u8 abDone[NB+2]; /* True after i'th new page is populated */ | 77629 | u8 abDone[NB+2]; /* True after i'th new page is populated */ |
| 74758 | Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ | 77630 | Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ |
| 74759 | Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */ | ||
| 74760 | u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */ | ||
| 74761 | CellArray b; /* Parsed information on cells being balanced */ | 77631 | CellArray b; /* Parsed information on cells being balanced */ |
| 74762 | 77632 | ||
| 74763 | memset(abDone, 0, sizeof(abDone)); | 77633 | memset(abDone, 0, sizeof(abDone)); |
| @@ -74813,7 +77683,7 @@ static int balance_nonroot( | |||
| 74813 | pgno = get4byte(pRight); | 77683 | pgno = get4byte(pRight); |
| 74814 | while( 1 ){ | 77684 | while( 1 ){ |
| 74815 | if( rc==SQLITE_OK ){ | 77685 | if( rc==SQLITE_OK ){ |
| 74816 | rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); | 77686 | rc = getAndInitPage(pBt, pgno, &apOld[i], 0); |
| 74817 | } | 77687 | } |
| 74818 | if( rc ){ | 77688 | if( rc ){ |
| 74819 | memset(apOld, 0, (i+1)*sizeof(MemPage*)); | 77689 | memset(apOld, 0, (i+1)*sizeof(MemPage*)); |
| @@ -75104,15 +77974,17 @@ static int balance_nonroot( | |||
| 75104 | d = r + 1 - leafData; | 77974 | d = r + 1 - leafData; |
| 75105 | (void)cachedCellSize(&b, d); | 77975 | (void)cachedCellSize(&b, d); |
| 75106 | do{ | 77976 | do{ |
| 77977 | int szR, szD; | ||
| 75107 | assert( d<nMaxCells ); | 77978 | assert( d<nMaxCells ); |
| 75108 | assert( r<nMaxCells ); | 77979 | assert( r<nMaxCells ); |
| 75109 | (void)cachedCellSize(&b, r); | 77980 | szR = cachedCellSize(&b, r); |
| 77981 | szD = b.szCell[d]; | ||
| 75110 | if( szRight!=0 | 77982 | if( szRight!=0 |
| 75111 | && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){ | 77983 | && (bBulk || szRight+szD+2 > szLeft-(szR+(i==k-1?0:2)))){ |
| 75112 | break; | 77984 | break; |
| 75113 | } | 77985 | } |
| 75114 | szRight += b.szCell[d] + 2; | 77986 | szRight += szD + 2; |
| 75115 | szLeft -= b.szCell[r] + 2; | 77987 | szLeft -= szR + 2; |
| 75116 | cntNew[i-1] = r; | 77988 | cntNew[i-1] = r; |
| 75117 | r--; | 77989 | r--; |
| 75118 | d--; | 77990 | d--; |
| @@ -75125,7 +77997,7 @@ static int balance_nonroot( | |||
| 75125 | } | 77997 | } |
| 75126 | } | 77998 | } |
| 75127 | 77999 | ||
| 75128 | /* Sanity check: For a non-corrupt database file one of the follwing | 78000 | /* Sanity check: For a non-corrupt database file one of the following |
| 75129 | ** must be true: | 78001 | ** must be true: |
| 75130 | ** (1) We found one or more cells (cntNew[0])>0), or | 78002 | ** (1) We found one or more cells (cntNew[0])>0), or |
| 75131 | ** (2) pPage is a virtual root page. A virtual root page is when | 78003 | ** (2) pPage is a virtual root page. A virtual root page is when |
| @@ -75133,7 +78005,7 @@ static int balance_nonroot( | |||
| 75133 | ** that page. | 78005 | ** that page. |
| 75134 | */ | 78006 | */ |
| 75135 | assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB); | 78007 | assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB); |
| 75136 | TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n", | 78008 | TRACE(("BALANCE: old: %u(nc=%u) %u(nc=%u) %u(nc=%u)\n", |
| 75137 | apOld[0]->pgno, apOld[0]->nCell, | 78009 | apOld[0]->pgno, apOld[0]->nCell, |
| 75138 | nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0, | 78010 | nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0, |
| 75139 | nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0 | 78011 | nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0 |
| @@ -75166,7 +78038,7 @@ static int balance_nonroot( | |||
| 75166 | cntOld[i] = b.nCell; | 78038 | cntOld[i] = b.nCell; |
| 75167 | 78039 | ||
| 75168 | /* Set the pointer-map entry for the new sibling page. */ | 78040 | /* Set the pointer-map entry for the new sibling page. */ |
| 75169 | if( ISAUTOVACUUM ){ | 78041 | if( ISAUTOVACUUM(pBt) ){ |
| 75170 | ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); | 78042 | ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); |
| 75171 | if( rc!=SQLITE_OK ){ | 78043 | if( rc!=SQLITE_OK ){ |
| 75172 | goto balance_cleanup; | 78044 | goto balance_cleanup; |
| @@ -75181,47 +78053,44 @@ static int balance_nonroot( | |||
| 75181 | ** of the table is closer to a linear scan through the file. That in turn | 78053 | ** of the table is closer to a linear scan through the file. That in turn |
| 75182 | ** helps the operating system to deliver pages from the disk more rapidly. | 78054 | ** helps the operating system to deliver pages from the disk more rapidly. |
| 75183 | ** | 78055 | ** |
| 75184 | ** An O(n^2) insertion sort algorithm is used, but since n is never more | 78056 | ** An O(N*N) sort algorithm is used, but since N is never more than NB+2 |
| 75185 | ** than (NB+2) (a small constant), that should not be a problem. | 78057 | ** (5), that is not a performance concern. |
| 75186 | ** | 78058 | ** |
| 75187 | ** When NB==3, this one optimization makes the database about 25% faster | 78059 | ** When NB==3, this one optimization makes the database about 25% faster |
| 75188 | ** for large insertions and deletions. | 78060 | ** for large insertions and deletions. |
| 75189 | */ | 78061 | */ |
| 75190 | for(i=0; i<nNew; i++){ | 78062 | for(i=0; i<nNew; i++){ |
| 75191 | aPgOrder[i] = aPgno[i] = apNew[i]->pgno; | 78063 | aPgno[i] = apNew[i]->pgno; |
| 75192 | aPgFlags[i] = apNew[i]->pDbPage->flags; | 78064 | assert( apNew[i]->pDbPage->flags & PGHDR_WRITEABLE ); |
| 75193 | for(j=0; j<i; j++){ | 78065 | assert( apNew[i]->pDbPage->flags & PGHDR_DIRTY ); |
| 75194 | if( NEVER(aPgno[j]==aPgno[i]) ){ | ||
| 75195 | /* This branch is taken if the set of sibling pages somehow contains | ||
| 75196 | ** duplicate entries. This can happen if the database is corrupt. | ||
| 75197 | ** It would be simpler to detect this as part of the loop below, but | ||
| 75198 | ** we do the detection here in order to avoid populating the pager | ||
| 75199 | ** cache with two separate objects associated with the same | ||
| 75200 | ** page number. */ | ||
| 75201 | assert( CORRUPT_DB ); | ||
| 75202 | rc = SQLITE_CORRUPT_BKPT; | ||
| 75203 | goto balance_cleanup; | ||
| 75204 | } | ||
| 75205 | } | ||
| 75206 | } | 78066 | } |
| 75207 | for(i=0; i<nNew; i++){ | 78067 | for(i=0; i<nNew-1; i++){ |
| 75208 | int iBest = 0; /* aPgno[] index of page number to use */ | 78068 | int iB = i; |
| 75209 | for(j=1; j<nNew; j++){ | 78069 | for(j=i+1; j<nNew; j++){ |
| 75210 | if( aPgOrder[j]<aPgOrder[iBest] ) iBest = j; | 78070 | if( apNew[j]->pgno < apNew[iB]->pgno ) iB = j; |
| 75211 | } | ||
| 75212 | pgno = aPgOrder[iBest]; | ||
| 75213 | aPgOrder[iBest] = 0xffffffff; | ||
| 75214 | if( iBest!=i ){ | ||
| 75215 | if( iBest>i ){ | ||
| 75216 | sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0); | ||
| 75217 | } | ||
| 75218 | sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]); | ||
| 75219 | apNew[i]->pgno = pgno; | ||
| 75220 | } | 78071 | } |
| 75221 | } | ||
| 75222 | 78072 | ||
| 75223 | TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) " | 78073 | /* If apNew[i] has a page number that is bigger than any of the |
| 75224 | "%d(%d nc=%d) %d(%d nc=%d)\n", | 78074 | ** subsequence apNew[i] entries, then swap apNew[i] with the subsequent |
| 78075 | ** entry that has the smallest page number (which we know to be | ||
| 78076 | ** entry apNew[iB]). | ||
| 78077 | */ | ||
| 78078 | if( iB!=i ){ | ||
| 78079 | Pgno pgnoA = apNew[i]->pgno; | ||
| 78080 | Pgno pgnoB = apNew[iB]->pgno; | ||
| 78081 | Pgno pgnoTemp = (PENDING_BYTE/pBt->pageSize)+1; | ||
| 78082 | u16 fgA = apNew[i]->pDbPage->flags; | ||
| 78083 | u16 fgB = apNew[iB]->pDbPage->flags; | ||
| 78084 | sqlite3PagerRekey(apNew[i]->pDbPage, pgnoTemp, fgB); | ||
| 78085 | sqlite3PagerRekey(apNew[iB]->pDbPage, pgnoA, fgA); | ||
| 78086 | sqlite3PagerRekey(apNew[i]->pDbPage, pgnoB, fgB); | ||
| 78087 | apNew[i]->pgno = pgnoB; | ||
| 78088 | apNew[iB]->pgno = pgnoA; | ||
| 78089 | } | ||
| 78090 | } | ||
| 78091 | |||
| 78092 | TRACE(("BALANCE: new: %u(%u nc=%u) %u(%u nc=%u) %u(%u nc=%u) " | ||
| 78093 | "%u(%u nc=%u) %u(%u nc=%u)\n", | ||
| 75225 | apNew[0]->pgno, szNew[0], cntNew[0], | 78094 | apNew[0]->pgno, szNew[0], cntNew[0], |
| 75226 | nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, | 78095 | nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, |
| 75227 | nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0, | 78096 | nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0, |
| @@ -75262,7 +78131,7 @@ static int balance_nonroot( | |||
| 75262 | ** updated. This happens below, after the sibling pages have been | 78131 | ** updated. This happens below, after the sibling pages have been |
| 75263 | ** populated, not here. | 78132 | ** populated, not here. |
| 75264 | */ | 78133 | */ |
| 75265 | if( ISAUTOVACUUM ){ | 78134 | if( ISAUTOVACUUM(pBt) ){ |
| 75266 | MemPage *pOld; | 78135 | MemPage *pOld; |
| 75267 | MemPage *pNew = pOld = apNew[0]; | 78136 | MemPage *pNew = pOld = apNew[0]; |
| 75268 | int cntOldNext = pNew->nCell + pNew->nOverflow; | 78137 | int cntOldNext = pNew->nCell + pNew->nOverflow; |
| @@ -75353,13 +78222,13 @@ static int balance_nonroot( | |||
| 75353 | iOvflSpace += sz; | 78222 | iOvflSpace += sz; |
| 75354 | assert( sz<=pBt->maxLocal+23 ); | 78223 | assert( sz<=pBt->maxLocal+23 ); |
| 75355 | assert( iOvflSpace <= (int)pBt->pageSize ); | 78224 | assert( iOvflSpace <= (int)pBt->pageSize ); |
| 75356 | for(k=0; b.ixNx[k]<=j && ALWAYS(k<NB*2); k++){} | 78225 | for(k=0; ALWAYS(k<NB*2) && b.ixNx[k]<=j; k++){} |
| 75357 | pSrcEnd = b.apEnd[k]; | 78226 | pSrcEnd = b.apEnd[k]; |
| 75358 | if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){ | 78227 | if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){ |
| 75359 | rc = SQLITE_CORRUPT_BKPT; | 78228 | rc = SQLITE_CORRUPT_BKPT; |
| 75360 | goto balance_cleanup; | 78229 | goto balance_cleanup; |
| 75361 | } | 78230 | } |
| 75362 | insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); | 78231 | rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno); |
| 75363 | if( rc!=SQLITE_OK ) goto balance_cleanup; | 78232 | if( rc!=SQLITE_OK ) goto balance_cleanup; |
| 75364 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); | 78233 | assert( sqlite3PagerIswriteable(pParent->pDbPage) ); |
| 75365 | } | 78234 | } |
| @@ -75389,6 +78258,8 @@ static int balance_nonroot( | |||
| 75389 | for(i=1-nNew; i<nNew; i++){ | 78258 | for(i=1-nNew; i<nNew; i++){ |
| 75390 | int iPg = i<0 ? -i : i; | 78259 | int iPg = i<0 ? -i : i; |
| 75391 | assert( iPg>=0 && iPg<nNew ); | 78260 | assert( iPg>=0 && iPg<nNew ); |
| 78261 | assert( iPg>=1 || i>=0 ); | ||
| 78262 | assert( iPg<ArraySize(cntOld) ); | ||
| 75392 | if( abDone[iPg] ) continue; /* Skip pages already processed */ | 78263 | if( abDone[iPg] ) continue; /* Skip pages already processed */ |
| 75393 | if( i>=0 /* On the upwards pass, or... */ | 78264 | if( i>=0 /* On the upwards pass, or... */ |
| 75394 | || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ | 78265 | || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ |
| @@ -75455,7 +78326,7 @@ static int balance_nonroot( | |||
| 75455 | ); | 78326 | ); |
| 75456 | copyNodeContent(apNew[0], pParent, &rc); | 78327 | copyNodeContent(apNew[0], pParent, &rc); |
| 75457 | freePage(apNew[0], &rc); | 78328 | freePage(apNew[0], &rc); |
| 75458 | }else if( ISAUTOVACUUM && !leafCorrection ){ | 78329 | }else if( ISAUTOVACUUM(pBt) && !leafCorrection ){ |
| 75459 | /* Fix the pointer map entries associated with the right-child of each | 78330 | /* Fix the pointer map entries associated with the right-child of each |
| 75460 | ** sibling page. All other pointer map entries have already been taken | 78331 | ** sibling page. All other pointer map entries have already been taken |
| 75461 | ** care of. */ | 78332 | ** care of. */ |
| @@ -75466,7 +78337,7 @@ static int balance_nonroot( | |||
| 75466 | } | 78337 | } |
| 75467 | 78338 | ||
| 75468 | assert( pParent->isInit ); | 78339 | assert( pParent->isInit ); |
| 75469 | TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", | 78340 | TRACE(("BALANCE: finished: old=%u new=%u cells=%u\n", |
| 75470 | nOld, nNew, b.nCell)); | 78341 | nOld, nNew, b.nCell)); |
| 75471 | 78342 | ||
| 75472 | /* Free any old pages that were not reused as new pages. | 78343 | /* Free any old pages that were not reused as new pages. |
| @@ -75476,7 +78347,7 @@ static int balance_nonroot( | |||
| 75476 | } | 78347 | } |
| 75477 | 78348 | ||
| 75478 | #if 0 | 78349 | #if 0 |
| 75479 | if( ISAUTOVACUUM && rc==SQLITE_OK && apNew[0]->isInit ){ | 78350 | if( ISAUTOVACUUM(pBt) && rc==SQLITE_OK && apNew[0]->isInit ){ |
| 75480 | /* The ptrmapCheckPages() contains assert() statements that verify that | 78351 | /* The ptrmapCheckPages() contains assert() statements that verify that |
| 75481 | ** all pointer map pages are set correctly. This is helpful while | 78352 | ** all pointer map pages are set correctly. This is helpful while |
| 75482 | ** debugging. This is usually disabled because a corrupt database may | 78353 | ** debugging. This is usually disabled because a corrupt database may |
| @@ -75538,7 +78409,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ | |||
| 75538 | if( rc==SQLITE_OK ){ | 78409 | if( rc==SQLITE_OK ){ |
| 75539 | rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); | 78410 | rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); |
| 75540 | copyNodeContent(pRoot, pChild, &rc); | 78411 | copyNodeContent(pRoot, pChild, &rc); |
| 75541 | if( ISAUTOVACUUM ){ | 78412 | if( ISAUTOVACUUM(pBt) ){ |
| 75542 | ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); | 78413 | ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); |
| 75543 | } | 78414 | } |
| 75544 | } | 78415 | } |
| @@ -75551,7 +78422,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ | |||
| 75551 | assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); | 78422 | assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); |
| 75552 | assert( pChild->nCell==pRoot->nCell || CORRUPT_DB ); | 78423 | assert( pChild->nCell==pRoot->nCell || CORRUPT_DB ); |
| 75553 | 78424 | ||
| 75554 | TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); | 78425 | TRACE(("BALANCE: copy root %u into %u\n", pRoot->pgno, pChild->pgno)); |
| 75555 | 78426 | ||
| 75556 | /* Copy the overflow cells from pRoot to pChild */ | 78427 | /* Copy the overflow cells from pRoot to pChild */ |
| 75557 | memcpy(pChild->aiOvfl, pRoot->aiOvfl, | 78428 | memcpy(pChild->aiOvfl, pRoot->aiOvfl, |
| @@ -75642,6 +78513,11 @@ static int balance(BtCursor *pCur){ | |||
| 75642 | }else{ | 78513 | }else{ |
| 75643 | break; | 78514 | break; |
| 75644 | } | 78515 | } |
| 78516 | }else if( sqlite3PagerPageRefcount(pPage->pDbPage)>1 ){ | ||
| 78517 | /* The page being written is not a root page, and there is currently | ||
| 78518 | ** more than one reference to it. This only happens if the page is one | ||
| 78519 | ** of its own ancestor pages. Corruption. */ | ||
| 78520 | rc = SQLITE_CORRUPT_BKPT; | ||
| 75645 | }else{ | 78521 | }else{ |
| 75646 | MemPage * const pParent = pCur->apPage[iPage-1]; | 78522 | MemPage * const pParent = pCur->apPage[iPage-1]; |
| 75647 | int const iIdx = pCur->aiIdx[iPage-1]; | 78523 | int const iIdx = pCur->aiIdx[iPage-1]; |
| @@ -75740,7 +78616,7 @@ static int btreeOverwriteContent( | |||
| 75740 | ){ | 78616 | ){ |
| 75741 | int nData = pX->nData - iOffset; | 78617 | int nData = pX->nData - iOffset; |
| 75742 | if( nData<=0 ){ | 78618 | if( nData<=0 ){ |
| 75743 | /* Overwritting with zeros */ | 78619 | /* Overwriting with zeros */ |
| 75744 | int i; | 78620 | int i; |
| 75745 | for(i=0; i<iAmt && pDest[i]==0; i++){} | 78621 | for(i=0; i<iAmt && pDest[i]==0; i++){} |
| 75746 | if( i<iAmt ){ | 78622 | if( i<iAmt ){ |
| @@ -75772,9 +78648,13 @@ static int btreeOverwriteContent( | |||
| 75772 | 78648 | ||
| 75773 | /* | 78649 | /* |
| 75774 | ** Overwrite the cell that cursor pCur is pointing to with fresh content | 78650 | ** Overwrite the cell that cursor pCur is pointing to with fresh content |
| 75775 | ** contained in pX. | 78651 | ** contained in pX. In this variant, pCur is pointing to an overflow |
| 78652 | ** cell. | ||
| 75776 | */ | 78653 | */ |
| 75777 | static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ | 78654 | static SQLITE_NOINLINE int btreeOverwriteOverflowCell( |
| 78655 | BtCursor *pCur, /* Cursor pointing to cell to overwrite */ | ||
| 78656 | const BtreePayload *pX /* Content to write into the cell */ | ||
| 78657 | ){ | ||
| 75778 | int iOffset; /* Next byte of pX->pData to write */ | 78658 | int iOffset; /* Next byte of pX->pData to write */ |
| 75779 | int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ | 78659 | int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ |
| 75780 | int rc; /* Return code */ | 78660 | int rc; /* Return code */ |
| @@ -75783,16 +78663,12 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ | |||
| 75783 | Pgno ovflPgno; /* Next overflow page to write */ | 78663 | Pgno ovflPgno; /* Next overflow page to write */ |
| 75784 | u32 ovflPageSize; /* Size to write on overflow page */ | 78664 | u32 ovflPageSize; /* Size to write on overflow page */ |
| 75785 | 78665 | ||
| 75786 | if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd | 78666 | assert( pCur->info.nLocal<nTotal ); /* pCur is an overflow cell */ |
| 75787 | || pCur->info.pPayload < pPage->aData + pPage->cellOffset | 78667 | |
| 75788 | ){ | ||
| 75789 | return SQLITE_CORRUPT_BKPT; | ||
| 75790 | } | ||
| 75791 | /* Overwrite the local portion first */ | 78668 | /* Overwrite the local portion first */ |
| 75792 | rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, | 78669 | rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, |
| 75793 | 0, pCur->info.nLocal); | 78670 | 0, pCur->info.nLocal); |
| 75794 | if( rc ) return rc; | 78671 | if( rc ) return rc; |
| 75795 | if( pCur->info.nLocal==nTotal ) return SQLITE_OK; | ||
| 75796 | 78672 | ||
| 75797 | /* Now overwrite the overflow pages */ | 78673 | /* Now overwrite the overflow pages */ |
| 75798 | iOffset = pCur->info.nLocal; | 78674 | iOffset = pCur->info.nLocal; |
| @@ -75822,6 +78698,29 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ | |||
| 75822 | return SQLITE_OK; | 78698 | return SQLITE_OK; |
| 75823 | } | 78699 | } |
| 75824 | 78700 | ||
| 78701 | /* | ||
| 78702 | ** Overwrite the cell that cursor pCur is pointing to with fresh content | ||
| 78703 | ** contained in pX. | ||
| 78704 | */ | ||
| 78705 | static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ | ||
| 78706 | int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ | ||
| 78707 | MemPage *pPage = pCur->pPage; /* Page being written */ | ||
| 78708 | |||
| 78709 | if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd | ||
| 78710 | || pCur->info.pPayload < pPage->aData + pPage->cellOffset | ||
| 78711 | ){ | ||
| 78712 | return SQLITE_CORRUPT_BKPT; | ||
| 78713 | } | ||
| 78714 | if( pCur->info.nLocal==nTotal ){ | ||
| 78715 | /* The entire cell is local */ | ||
| 78716 | return btreeOverwriteContent(pPage, pCur->info.pPayload, pX, | ||
| 78717 | 0, pCur->info.nLocal); | ||
| 78718 | }else{ | ||
| 78719 | /* The cell contains overflow content */ | ||
| 78720 | return btreeOverwriteOverflowCell(pCur, pX); | ||
| 78721 | } | ||
| 78722 | } | ||
| 78723 | |||
| 75825 | 78724 | ||
| 75826 | /* | 78725 | /* |
| 75827 | ** Insert a new record into the BTree. The content of the new record | 78726 | ** Insert a new record into the BTree. The content of the new record |
| @@ -75865,7 +78764,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 75865 | int idx; | 78764 | int idx; |
| 75866 | MemPage *pPage; | 78765 | MemPage *pPage; |
| 75867 | Btree *p = pCur->pBtree; | 78766 | Btree *p = pCur->pBtree; |
| 75868 | BtShared *pBt = p->pBt; | ||
| 75869 | unsigned char *oldCell; | 78767 | unsigned char *oldCell; |
| 75870 | unsigned char *newCell = 0; | 78768 | unsigned char *newCell = 0; |
| 75871 | 78769 | ||
| @@ -75884,7 +78782,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 75884 | ** not to clear the cursor here. | 78782 | ** not to clear the cursor here. |
| 75885 | */ | 78783 | */ |
| 75886 | if( pCur->curFlags & BTCF_Multiple ){ | 78784 | if( pCur->curFlags & BTCF_Multiple ){ |
| 75887 | rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); | 78785 | rc = saveAllCursors(p->pBt, pCur->pgnoRoot, pCur); |
| 75888 | if( rc ) return rc; | 78786 | if( rc ) return rc; |
| 75889 | if( loc && pCur->iPage<0 ){ | 78787 | if( loc && pCur->iPage<0 ){ |
| 75890 | /* This can only happen if the schema is corrupt such that there is more | 78788 | /* This can only happen if the schema is corrupt such that there is more |
| @@ -75908,8 +78806,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 75908 | 78806 | ||
| 75909 | assert( cursorOwnsBtShared(pCur) ); | 78807 | assert( cursorOwnsBtShared(pCur) ); |
| 75910 | assert( (pCur->curFlags & BTCF_WriteFlag)!=0 | 78808 | assert( (pCur->curFlags & BTCF_WriteFlag)!=0 |
| 75911 | && pBt->inTransaction==TRANS_WRITE | 78809 | && p->pBt->inTransaction==TRANS_WRITE |
| 75912 | && (pBt->btsFlags & BTS_READ_ONLY)==0 ); | 78810 | && (p->pBt->btsFlags & BTS_READ_ONLY)==0 ); |
| 75913 | assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); | 78811 | assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); |
| 75914 | 78812 | ||
| 75915 | /* Assert that the caller has been consistent. If this cursor was opened | 78813 | /* Assert that the caller has been consistent. If this cursor was opened |
| @@ -76007,7 +78905,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 76007 | } | 78905 | } |
| 76008 | } | 78906 | } |
| 76009 | assert( pCur->eState==CURSOR_VALID | 78907 | assert( pCur->eState==CURSOR_VALID |
| 76010 | || (pCur->eState==CURSOR_INVALID && loc) ); | 78908 | || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); |
| 76011 | 78909 | ||
| 76012 | pPage = pCur->pPage; | 78910 | pPage = pCur->pPage; |
| 76013 | assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); | 78911 | assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); |
| @@ -76022,31 +78920,34 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 76022 | if( rc ) return rc; | 78920 | if( rc ) return rc; |
| 76023 | } | 78921 | } |
| 76024 | 78922 | ||
| 76025 | TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", | 78923 | TRACE(("INSERT: table=%u nkey=%lld ndata=%u page=%u %s\n", |
| 76026 | pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, | 78924 | pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, |
| 76027 | loc==0 ? "overwrite" : "new entry")); | 78925 | loc==0 ? "overwrite" : "new entry")); |
| 76028 | assert( pPage->isInit || CORRUPT_DB ); | 78926 | assert( pPage->isInit || CORRUPT_DB ); |
| 76029 | newCell = pBt->pTmpSpace; | 78927 | newCell = p->pBt->pTmpSpace; |
| 76030 | assert( newCell!=0 ); | 78928 | assert( newCell!=0 ); |
| 78929 | assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); | ||
| 76031 | if( flags & BTREE_PREFORMAT ){ | 78930 | if( flags & BTREE_PREFORMAT ){ |
| 76032 | rc = SQLITE_OK; | 78931 | rc = SQLITE_OK; |
| 76033 | szNew = pBt->nPreformatSize; | 78932 | szNew = p->pBt->nPreformatSize; |
| 76034 | if( szNew<4 ) szNew = 4; | 78933 | if( szNew<4 ) szNew = 4; |
| 76035 | if( ISAUTOVACUUM && szNew>pPage->maxLocal ){ | 78934 | if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ |
| 76036 | CellInfo info; | 78935 | CellInfo info; |
| 76037 | pPage->xParseCell(pPage, newCell, &info); | 78936 | pPage->xParseCell(pPage, newCell, &info); |
| 76038 | if( info.nPayload!=info.nLocal ){ | 78937 | if( info.nPayload!=info.nLocal ){ |
| 76039 | Pgno ovfl = get4byte(&newCell[szNew-4]); | 78938 | Pgno ovfl = get4byte(&newCell[szNew-4]); |
| 76040 | ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); | 78939 | ptrmapPut(p->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); |
| 78940 | if( NEVER(rc) ) goto end_insert; | ||
| 76041 | } | 78941 | } |
| 76042 | } | 78942 | } |
| 76043 | }else{ | 78943 | }else{ |
| 76044 | rc = fillInCell(pPage, newCell, pX, &szNew); | 78944 | rc = fillInCell(pPage, newCell, pX, &szNew); |
| 78945 | if( rc ) goto end_insert; | ||
| 76045 | } | 78946 | } |
| 76046 | if( rc ) goto end_insert; | ||
| 76047 | assert( szNew==pPage->xCellSize(pPage, newCell) ); | 78947 | assert( szNew==pPage->xCellSize(pPage, newCell) ); |
| 76048 | assert( szNew <= MX_CELL_SIZE(pBt) ); | 78948 | assert( szNew <= MX_CELL_SIZE(p->pBt) ); |
| 76049 | idx = pCur->ix; | 78949 | idx = pCur->ix; |
| 78950 | pCur->info.nSize = 0; | ||
| 76050 | if( loc==0 ){ | 78951 | if( loc==0 ){ |
| 76051 | CellInfo info; | 78952 | CellInfo info; |
| 76052 | assert( idx>=0 ); | 78953 | assert( idx>=0 ); |
| @@ -76065,7 +78966,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 76065 | testcase( pCur->curFlags & BTCF_ValidOvfl ); | 78966 | testcase( pCur->curFlags & BTCF_ValidOvfl ); |
| 76066 | invalidateOverflowCache(pCur); | 78967 | invalidateOverflowCache(pCur); |
| 76067 | if( info.nSize==szNew && info.nLocal==info.nPayload | 78968 | if( info.nSize==szNew && info.nLocal==info.nPayload |
| 76068 | && (!ISAUTOVACUUM || szNew<pPage->minLocal) | 78969 | && (!ISAUTOVACUUM(p->pBt) || szNew<pPage->minLocal) |
| 76069 | ){ | 78970 | ){ |
| 76070 | /* Overwrite the old cell with the new if they are the same size. | 78971 | /* Overwrite the old cell with the new if they are the same size. |
| 76071 | ** We could also try to do this if the old cell is smaller, then add | 78972 | ** We could also try to do this if the old cell is smaller, then add |
| @@ -76095,7 +78996,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 76095 | }else{ | 78996 | }else{ |
| 76096 | assert( pPage->leaf ); | 78997 | assert( pPage->leaf ); |
| 76097 | } | 78998 | } |
| 76098 | insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); | 78999 | rc = insertCellFast(pPage, idx, newCell, szNew); |
| 76099 | assert( pPage->nOverflow==0 || rc==SQLITE_OK ); | 79000 | assert( pPage->nOverflow==0 || rc==SQLITE_OK ); |
| 76100 | assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); | 79001 | assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); |
| 76101 | 79002 | ||
| @@ -76119,7 +79020,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( | |||
| 76119 | ** larger than the largest existing key, it is possible to insert the | 79020 | ** larger than the largest existing key, it is possible to insert the |
| 76120 | ** row without seeking the cursor. This can be a big performance boost. | 79021 | ** row without seeking the cursor. This can be a big performance boost. |
| 76121 | */ | 79022 | */ |
| 76122 | pCur->info.nSize = 0; | ||
| 76123 | if( pPage->nOverflow ){ | 79023 | if( pPage->nOverflow ){ |
| 76124 | assert( rc==SQLITE_OK ); | 79024 | assert( rc==SQLITE_OK ); |
| 76125 | pCur->curFlags &= ~(BTCF_ValidNKey); | 79025 | pCur->curFlags &= ~(BTCF_ValidNKey); |
| @@ -76168,7 +79068,6 @@ end_insert: | |||
| 76168 | ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. | 79068 | ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. |
| 76169 | */ | 79069 | */ |
| 76170 | SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ | 79070 | SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ |
| 76171 | int rc = SQLITE_OK; | ||
| 76172 | BtShared *pBt = pDest->pBt; | 79071 | BtShared *pBt = pDest->pBt; |
| 76173 | u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ | 79072 | u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ |
| 76174 | const u8 *aIn; /* Pointer to next input buffer */ | 79073 | const u8 *aIn; /* Pointer to next input buffer */ |
| @@ -76191,7 +79090,9 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 | |||
| 76191 | if( nIn==nRem && nIn<pDest->pPage->maxLocal ){ | 79090 | if( nIn==nRem && nIn<pDest->pPage->maxLocal ){ |
| 76192 | memcpy(aOut, aIn, nIn); | 79091 | memcpy(aOut, aIn, nIn); |
| 76193 | pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); | 79092 | pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); |
| 79093 | return SQLITE_OK; | ||
| 76194 | }else{ | 79094 | }else{ |
| 79095 | int rc = SQLITE_OK; | ||
| 76195 | Pager *pSrcPager = pSrc->pBt->pPager; | 79096 | Pager *pSrcPager = pSrc->pBt->pPager; |
| 76196 | u8 *pPgnoOut = 0; | 79097 | u8 *pPgnoOut = 0; |
| 76197 | Pgno ovflIn = 0; | 79098 | Pgno ovflIn = 0; |
| @@ -76243,7 +79144,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 | |||
| 76243 | MemPage *pNew = 0; | 79144 | MemPage *pNew = 0; |
| 76244 | rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); | 79145 | rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); |
| 76245 | put4byte(pPgnoOut, pgnoNew); | 79146 | put4byte(pPgnoOut, pgnoNew); |
| 76246 | if( ISAUTOVACUUM && pPageOut ){ | 79147 | if( ISAUTOVACUUM(pBt) && pPageOut ){ |
| 76247 | ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); | 79148 | ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); |
| 76248 | } | 79149 | } |
| 76249 | releasePage(pPageOut); | 79150 | releasePage(pPageOut); |
| @@ -76259,9 +79160,8 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 | |||
| 76259 | 79160 | ||
| 76260 | releasePage(pPageOut); | 79161 | releasePage(pPageOut); |
| 76261 | sqlite3PagerUnref(pPageIn); | 79162 | sqlite3PagerUnref(pPageIn); |
| 79163 | return rc; | ||
| 76262 | } | 79164 | } |
| 76263 | |||
| 76264 | return rc; | ||
| 76265 | } | 79165 | } |
| 76266 | 79166 | ||
| 76267 | /* | 79167 | /* |
| @@ -76320,6 +79220,9 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ | |||
| 76320 | if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ | 79220 | if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ |
| 76321 | return SQLITE_CORRUPT_BKPT; | 79221 | return SQLITE_CORRUPT_BKPT; |
| 76322 | } | 79222 | } |
| 79223 | if( pCell<&pPage->aCellIdx[pPage->nCell] ){ | ||
| 79224 | return SQLITE_CORRUPT_BKPT; | ||
| 79225 | } | ||
| 76323 | 79226 | ||
| 76324 | /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must | 79227 | /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must |
| 76325 | ** be preserved following this delete operation. If the current delete | 79228 | ** be preserved following this delete operation. If the current delete |
| @@ -76416,7 +79319,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ | |||
| 76416 | assert( pTmp!=0 ); | 79319 | assert( pTmp!=0 ); |
| 76417 | rc = sqlite3PagerWrite(pLeaf->pDbPage); | 79320 | rc = sqlite3PagerWrite(pLeaf->pDbPage); |
| 76418 | if( rc==SQLITE_OK ){ | 79321 | if( rc==SQLITE_OK ){ |
| 76419 | insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); | 79322 | rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n); |
| 76420 | } | 79323 | } |
| 76421 | dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); | 79324 | dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); |
| 76422 | if( rc ) return rc; | 79325 | if( rc ) return rc; |
| @@ -76496,7 +79399,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ | |||
| 76496 | MemPage *pRoot; | 79399 | MemPage *pRoot; |
| 76497 | Pgno pgnoRoot; | 79400 | Pgno pgnoRoot; |
| 76498 | int rc; | 79401 | int rc; |
| 76499 | int ptfFlags; /* Page-type flage for the root page of new table */ | 79402 | int ptfFlags; /* Page-type flags for the root page of new table */ |
| 76500 | 79403 | ||
| 76501 | assert( sqlite3BtreeHoldsMutex(p) ); | 79404 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 76502 | assert( pBt->inTransaction==TRANS_WRITE ); | 79405 | assert( pBt->inTransaction==TRANS_WRITE ); |
| @@ -76665,7 +79568,7 @@ static int clearDatabasePage( | |||
| 76665 | if( pgno>btreePagecount(pBt) ){ | 79568 | if( pgno>btreePagecount(pBt) ){ |
| 76666 | return SQLITE_CORRUPT_BKPT; | 79569 | return SQLITE_CORRUPT_BKPT; |
| 76667 | } | 79570 | } |
| 76668 | rc = getAndInitPage(pBt, pgno, &pPage, 0, 0); | 79571 | rc = getAndInitPage(pBt, pgno, &pPage, 0); |
| 76669 | if( rc ) return rc; | 79572 | if( rc ) return rc; |
| 76670 | if( (pBt->openFlags & BTREE_SINGLE)==0 | 79573 | if( (pBt->openFlags & BTREE_SINGLE)==0 |
| 76671 | && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) | 79574 | && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) |
| @@ -77016,6 +79919,41 @@ SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){ | |||
| 77016 | 79919 | ||
| 77017 | #ifndef SQLITE_OMIT_INTEGRITY_CHECK | 79920 | #ifndef SQLITE_OMIT_INTEGRITY_CHECK |
| 77018 | /* | 79921 | /* |
| 79922 | ** Record an OOM error during integrity_check | ||
| 79923 | */ | ||
| 79924 | static void checkOom(IntegrityCk *pCheck){ | ||
| 79925 | pCheck->rc = SQLITE_NOMEM; | ||
| 79926 | pCheck->mxErr = 0; /* Causes integrity_check processing to stop */ | ||
| 79927 | if( pCheck->nErr==0 ) pCheck->nErr++; | ||
| 79928 | } | ||
| 79929 | |||
| 79930 | /* | ||
| 79931 | ** Invoke the progress handler, if appropriate. Also check for an | ||
| 79932 | ** interrupt. | ||
| 79933 | */ | ||
| 79934 | static void checkProgress(IntegrityCk *pCheck){ | ||
| 79935 | sqlite3 *db = pCheck->db; | ||
| 79936 | if( AtomicLoad(&db->u1.isInterrupted) ){ | ||
| 79937 | pCheck->rc = SQLITE_INTERRUPT; | ||
| 79938 | pCheck->nErr++; | ||
| 79939 | pCheck->mxErr = 0; | ||
| 79940 | } | ||
| 79941 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | ||
| 79942 | if( db->xProgress ){ | ||
| 79943 | assert( db->nProgressOps>0 ); | ||
| 79944 | pCheck->nStep++; | ||
| 79945 | if( (pCheck->nStep % db->nProgressOps)==0 | ||
| 79946 | && db->xProgress(db->pProgressArg) | ||
| 79947 | ){ | ||
| 79948 | pCheck->rc = SQLITE_INTERRUPT; | ||
| 79949 | pCheck->nErr++; | ||
| 79950 | pCheck->mxErr = 0; | ||
| 79951 | } | ||
| 79952 | } | ||
| 79953 | #endif | ||
| 79954 | } | ||
| 79955 | |||
| 79956 | /* | ||
| 77019 | ** Append a message to the error message string. | 79957 | ** Append a message to the error message string. |
| 77020 | */ | 79958 | */ |
| 77021 | static void checkAppendMsg( | 79959 | static void checkAppendMsg( |
| @@ -77024,6 +79962,7 @@ static void checkAppendMsg( | |||
| 77024 | ... | 79962 | ... |
| 77025 | ){ | 79963 | ){ |
| 77026 | va_list ap; | 79964 | va_list ap; |
| 79965 | checkProgress(pCheck); | ||
| 77027 | if( !pCheck->mxErr ) return; | 79966 | if( !pCheck->mxErr ) return; |
| 77028 | pCheck->mxErr--; | 79967 | pCheck->mxErr--; |
| 77029 | pCheck->nErr++; | 79968 | pCheck->nErr++; |
| @@ -77032,12 +79971,13 @@ static void checkAppendMsg( | |||
| 77032 | sqlite3_str_append(&pCheck->errMsg, "\n", 1); | 79971 | sqlite3_str_append(&pCheck->errMsg, "\n", 1); |
| 77033 | } | 79972 | } |
| 77034 | if( pCheck->zPfx ){ | 79973 | if( pCheck->zPfx ){ |
| 77035 | sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); | 79974 | sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, |
| 79975 | pCheck->v0, pCheck->v1, pCheck->v2); | ||
| 77036 | } | 79976 | } |
| 77037 | sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); | 79977 | sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); |
| 77038 | va_end(ap); | 79978 | va_end(ap); |
| 77039 | if( pCheck->errMsg.accError==SQLITE_NOMEM ){ | 79979 | if( pCheck->errMsg.accError==SQLITE_NOMEM ){ |
| 77040 | pCheck->bOomFault = 1; | 79980 | checkOom(pCheck); |
| 77041 | } | 79981 | } |
| 77042 | } | 79982 | } |
| 77043 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ | 79983 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| @@ -77072,14 +80012,13 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ | |||
| 77072 | */ | 80012 | */ |
| 77073 | static int checkRef(IntegrityCk *pCheck, Pgno iPage){ | 80013 | static int checkRef(IntegrityCk *pCheck, Pgno iPage){ |
| 77074 | if( iPage>pCheck->nPage || iPage==0 ){ | 80014 | if( iPage>pCheck->nPage || iPage==0 ){ |
| 77075 | checkAppendMsg(pCheck, "invalid page number %d", iPage); | 80015 | checkAppendMsg(pCheck, "invalid page number %u", iPage); |
| 77076 | return 1; | 80016 | return 1; |
| 77077 | } | 80017 | } |
| 77078 | if( getPageReferenced(pCheck, iPage) ){ | 80018 | if( getPageReferenced(pCheck, iPage) ){ |
| 77079 | checkAppendMsg(pCheck, "2nd reference to page %d", iPage); | 80019 | checkAppendMsg(pCheck, "2nd reference to page %u", iPage); |
| 77080 | return 1; | 80020 | return 1; |
| 77081 | } | 80021 | } |
| 77082 | if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1; | ||
| 77083 | setPageReferenced(pCheck, iPage); | 80022 | setPageReferenced(pCheck, iPage); |
| 77084 | return 0; | 80023 | return 0; |
| 77085 | } | 80024 | } |
| @@ -77102,14 +80041,14 @@ static void checkPtrmap( | |||
| 77102 | 80041 | ||
| 77103 | rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); | 80042 | rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); |
| 77104 | if( rc!=SQLITE_OK ){ | 80043 | if( rc!=SQLITE_OK ){ |
| 77105 | if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->bOomFault = 1; | 80044 | if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) checkOom(pCheck); |
| 77106 | checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild); | 80045 | checkAppendMsg(pCheck, "Failed to read ptrmap key=%u", iChild); |
| 77107 | return; | 80046 | return; |
| 77108 | } | 80047 | } |
| 77109 | 80048 | ||
| 77110 | if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ | 80049 | if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ |
| 77111 | checkAppendMsg(pCheck, | 80050 | checkAppendMsg(pCheck, |
| 77112 | "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", | 80051 | "Bad ptr map entry key=%u expected=(%u,%u) got=(%u,%u)", |
| 77113 | iChild, eType, iParent, ePtrmapType, iPtrmapParent); | 80052 | iChild, eType, iParent, ePtrmapType, iPtrmapParent); |
| 77114 | } | 80053 | } |
| 77115 | } | 80054 | } |
| @@ -77134,7 +80073,7 @@ static void checkList( | |||
| 77134 | if( checkRef(pCheck, iPage) ) break; | 80073 | if( checkRef(pCheck, iPage) ) break; |
| 77135 | N--; | 80074 | N--; |
| 77136 | if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ | 80075 | if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ |
| 77137 | checkAppendMsg(pCheck, "failed to get page %d", iPage); | 80076 | checkAppendMsg(pCheck, "failed to get page %u", iPage); |
| 77138 | break; | 80077 | break; |
| 77139 | } | 80078 | } |
| 77140 | pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); | 80079 | pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); |
| @@ -77147,7 +80086,7 @@ static void checkList( | |||
| 77147 | #endif | 80086 | #endif |
| 77148 | if( n>pCheck->pBt->usableSize/4-2 ){ | 80087 | if( n>pCheck->pBt->usableSize/4-2 ){ |
| 77149 | checkAppendMsg(pCheck, | 80088 | checkAppendMsg(pCheck, |
| 77150 | "freelist leaf count too big on page %d", iPage); | 80089 | "freelist leaf count too big on page %u", iPage); |
| 77151 | N--; | 80090 | N--; |
| 77152 | }else{ | 80091 | }else{ |
| 77153 | for(i=0; i<(int)n; i++){ | 80092 | for(i=0; i<(int)n; i++){ |
| @@ -77179,7 +80118,7 @@ static void checkList( | |||
| 77179 | } | 80118 | } |
| 77180 | if( N && nErrAtStart==pCheck->nErr ){ | 80119 | if( N && nErrAtStart==pCheck->nErr ){ |
| 77181 | checkAppendMsg(pCheck, | 80120 | checkAppendMsg(pCheck, |
| 77182 | "%s is %d but should be %d", | 80121 | "%s is %u but should be %u", |
| 77183 | isFreeList ? "size" : "overflow list length", | 80122 | isFreeList ? "size" : "overflow list length", |
| 77184 | expected-N, expected); | 80123 | expected-N, expected); |
| 77185 | } | 80124 | } |
| @@ -77209,7 +80148,9 @@ static void checkList( | |||
| 77209 | ** lower 16 bits are the index of the last byte of that range. | 80148 | ** lower 16 bits are the index of the last byte of that range. |
| 77210 | */ | 80149 | */ |
| 77211 | static void btreeHeapInsert(u32 *aHeap, u32 x){ | 80150 | static void btreeHeapInsert(u32 *aHeap, u32 x){ |
| 77212 | u32 j, i = ++aHeap[0]; | 80151 | u32 j, i; |
| 80152 | assert( aHeap!=0 ); | ||
| 80153 | i = ++aHeap[0]; | ||
| 77213 | aHeap[i] = x; | 80154 | aHeap[i] = x; |
| 77214 | while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ | 80155 | while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ |
| 77215 | x = aHeap[j]; | 80156 | x = aHeap[j]; |
| @@ -77286,11 +80227,13 @@ static int checkTreePage( | |||
| 77286 | 80227 | ||
| 77287 | /* Check that the page exists | 80228 | /* Check that the page exists |
| 77288 | */ | 80229 | */ |
| 80230 | checkProgress(pCheck); | ||
| 80231 | if( pCheck->mxErr==0 ) goto end_of_check; | ||
| 77289 | pBt = pCheck->pBt; | 80232 | pBt = pCheck->pBt; |
| 77290 | usableSize = pBt->usableSize; | 80233 | usableSize = pBt->usableSize; |
| 77291 | if( iPage==0 ) return 0; | 80234 | if( iPage==0 ) return 0; |
| 77292 | if( checkRef(pCheck, iPage) ) return 0; | 80235 | if( checkRef(pCheck, iPage) ) return 0; |
| 77293 | pCheck->zPfx = "Page %u: "; | 80236 | pCheck->zPfx = "Tree %u page %u: "; |
| 77294 | pCheck->v1 = iPage; | 80237 | pCheck->v1 = iPage; |
| 77295 | if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ | 80238 | if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ |
| 77296 | checkAppendMsg(pCheck, | 80239 | checkAppendMsg(pCheck, |
| @@ -77317,7 +80260,7 @@ static int checkTreePage( | |||
| 77317 | hdr = pPage->hdrOffset; | 80260 | hdr = pPage->hdrOffset; |
| 77318 | 80261 | ||
| 77319 | /* Set up for cell analysis */ | 80262 | /* Set up for cell analysis */ |
| 77320 | pCheck->zPfx = "On tree page %u cell %d: "; | 80263 | pCheck->zPfx = "Tree %u page %u cell %u: "; |
| 77321 | contentOffset = get2byteNotZero(&data[hdr+5]); | 80264 | contentOffset = get2byteNotZero(&data[hdr+5]); |
| 77322 | assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ | 80265 | assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ |
| 77323 | 80266 | ||
| @@ -77337,7 +80280,7 @@ static int checkTreePage( | |||
| 77337 | pgno = get4byte(&data[hdr+8]); | 80280 | pgno = get4byte(&data[hdr+8]); |
| 77338 | #ifndef SQLITE_OMIT_AUTOVACUUM | 80281 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 77339 | if( pBt->autoVacuum ){ | 80282 | if( pBt->autoVacuum ){ |
| 77340 | pCheck->zPfx = "On page %u at right child: "; | 80283 | pCheck->zPfx = "Tree %u page %u right child: "; |
| 77341 | checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); | 80284 | checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); |
| 77342 | } | 80285 | } |
| 77343 | #endif | 80286 | #endif |
| @@ -77361,7 +80304,7 @@ static int checkTreePage( | |||
| 77361 | pc = get2byteAligned(pCellIdx); | 80304 | pc = get2byteAligned(pCellIdx); |
| 77362 | pCellIdx -= 2; | 80305 | pCellIdx -= 2; |
| 77363 | if( pc<contentOffset || pc>usableSize-4 ){ | 80306 | if( pc<contentOffset || pc>usableSize-4 ){ |
| 77364 | checkAppendMsg(pCheck, "Offset %d out of range %d..%d", | 80307 | checkAppendMsg(pCheck, "Offset %u out of range %u..%u", |
| 77365 | pc, contentOffset, usableSize-4); | 80308 | pc, contentOffset, usableSize-4); |
| 77366 | doCoverageCheck = 0; | 80309 | doCoverageCheck = 0; |
| 77367 | continue; | 80310 | continue; |
| @@ -77493,7 +80436,7 @@ static int checkTreePage( | |||
| 77493 | */ | 80436 | */ |
| 77494 | if( heap[0]==0 && nFrag!=data[hdr+7] ){ | 80437 | if( heap[0]==0 && nFrag!=data[hdr+7] ){ |
| 77495 | checkAppendMsg(pCheck, | 80438 | checkAppendMsg(pCheck, |
| 77496 | "Fragmentation of %d bytes reported as %d on page %u", | 80439 | "Fragmentation of %u bytes reported as %u on page %u", |
| 77497 | nFrag, data[hdr+7], iPage); | 80440 | nFrag, data[hdr+7], iPage); |
| 77498 | } | 80441 | } |
| 77499 | } | 80442 | } |
| @@ -77531,13 +80474,14 @@ end_of_check: | |||
| 77531 | ** the unverified btrees. Except, if aRoot[1] is 1, then the freelist | 80474 | ** the unverified btrees. Except, if aRoot[1] is 1, then the freelist |
| 77532 | ** checks are still performed. | 80475 | ** checks are still performed. |
| 77533 | */ | 80476 | */ |
| 77534 | SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | 80477 | SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( |
| 77535 | sqlite3 *db, /* Database connection that is running the check */ | 80478 | sqlite3 *db, /* Database connection that is running the check */ |
| 77536 | Btree *p, /* The btree to be checked */ | 80479 | Btree *p, /* The btree to be checked */ |
| 77537 | Pgno *aRoot, /* An array of root pages numbers for individual trees */ | 80480 | Pgno *aRoot, /* An array of root pages numbers for individual trees */ |
| 77538 | int nRoot, /* Number of entries in aRoot[] */ | 80481 | int nRoot, /* Number of entries in aRoot[] */ |
| 77539 | int mxErr, /* Stop reporting errors after this many */ | 80482 | int mxErr, /* Stop reporting errors after this many */ |
| 77540 | int *pnErr /* Write number of errors seen to this variable */ | 80483 | int *pnErr, /* OUT: Write number of errors seen to this variable */ |
| 80484 | char **pzOut /* OUT: Write the error message string here */ | ||
| 77541 | ){ | 80485 | ){ |
| 77542 | Pgno i; | 80486 | Pgno i; |
| 77543 | IntegrityCk sCheck; | 80487 | IntegrityCk sCheck; |
| @@ -77560,18 +80504,12 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | |||
| 77560 | assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); | 80504 | assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); |
| 77561 | VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); | 80505 | VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); |
| 77562 | assert( nRef>=0 ); | 80506 | assert( nRef>=0 ); |
| 80507 | memset(&sCheck, 0, sizeof(sCheck)); | ||
| 77563 | sCheck.db = db; | 80508 | sCheck.db = db; |
| 77564 | sCheck.pBt = pBt; | 80509 | sCheck.pBt = pBt; |
| 77565 | sCheck.pPager = pBt->pPager; | 80510 | sCheck.pPager = pBt->pPager; |
| 77566 | sCheck.nPage = btreePagecount(sCheck.pBt); | 80511 | sCheck.nPage = btreePagecount(sCheck.pBt); |
| 77567 | sCheck.mxErr = mxErr; | 80512 | sCheck.mxErr = mxErr; |
| 77568 | sCheck.nErr = 0; | ||
| 77569 | sCheck.bOomFault = 0; | ||
| 77570 | sCheck.zPfx = 0; | ||
| 77571 | sCheck.v1 = 0; | ||
| 77572 | sCheck.v2 = 0; | ||
| 77573 | sCheck.aPgRef = 0; | ||
| 77574 | sCheck.heap = 0; | ||
| 77575 | sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); | 80513 | sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); |
| 77576 | sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; | 80514 | sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; |
| 77577 | if( sCheck.nPage==0 ){ | 80515 | if( sCheck.nPage==0 ){ |
| @@ -77580,12 +80518,12 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | |||
| 77580 | 80518 | ||
| 77581 | sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); | 80519 | sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); |
| 77582 | if( !sCheck.aPgRef ){ | 80520 | if( !sCheck.aPgRef ){ |
| 77583 | sCheck.bOomFault = 1; | 80521 | checkOom(&sCheck); |
| 77584 | goto integrity_ck_cleanup; | 80522 | goto integrity_ck_cleanup; |
| 77585 | } | 80523 | } |
| 77586 | sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); | 80524 | sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); |
| 77587 | if( sCheck.heap==0 ){ | 80525 | if( sCheck.heap==0 ){ |
| 77588 | sCheck.bOomFault = 1; | 80526 | checkOom(&sCheck); |
| 77589 | goto integrity_ck_cleanup; | 80527 | goto integrity_ck_cleanup; |
| 77590 | } | 80528 | } |
| 77591 | 80529 | ||
| @@ -77595,7 +80533,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | |||
| 77595 | /* Check the integrity of the freelist | 80533 | /* Check the integrity of the freelist |
| 77596 | */ | 80534 | */ |
| 77597 | if( bCkFreelist ){ | 80535 | if( bCkFreelist ){ |
| 77598 | sCheck.zPfx = "Main freelist: "; | 80536 | sCheck.zPfx = "Freelist: "; |
| 77599 | checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), | 80537 | checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), |
| 77600 | get4byte(&pBt->pPage1->aData[36])); | 80538 | get4byte(&pBt->pPage1->aData[36])); |
| 77601 | sCheck.zPfx = 0; | 80539 | sCheck.zPfx = 0; |
| @@ -77612,7 +80550,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | |||
| 77612 | mxInHdr = get4byte(&pBt->pPage1->aData[52]); | 80550 | mxInHdr = get4byte(&pBt->pPage1->aData[52]); |
| 77613 | if( mx!=mxInHdr ){ | 80551 | if( mx!=mxInHdr ){ |
| 77614 | checkAppendMsg(&sCheck, | 80552 | checkAppendMsg(&sCheck, |
| 77615 | "max rootpage (%d) disagrees with header (%d)", | 80553 | "max rootpage (%u) disagrees with header (%u)", |
| 77616 | mx, mxInHdr | 80554 | mx, mxInHdr |
| 77617 | ); | 80555 | ); |
| 77618 | } | 80556 | } |
| @@ -77633,6 +80571,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | |||
| 77633 | checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); | 80571 | checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); |
| 77634 | } | 80572 | } |
| 77635 | #endif | 80573 | #endif |
| 80574 | sCheck.v0 = aRoot[i]; | ||
| 77636 | checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); | 80575 | checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); |
| 77637 | } | 80576 | } |
| 77638 | pBt->db->flags = savedDbFlags; | 80577 | pBt->db->flags = savedDbFlags; |
| @@ -77643,7 +80582,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | |||
| 77643 | for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ | 80582 | for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ |
| 77644 | #ifdef SQLITE_OMIT_AUTOVACUUM | 80583 | #ifdef SQLITE_OMIT_AUTOVACUUM |
| 77645 | if( getPageReferenced(&sCheck, i)==0 ){ | 80584 | if( getPageReferenced(&sCheck, i)==0 ){ |
| 77646 | checkAppendMsg(&sCheck, "Page %d is never used", i); | 80585 | checkAppendMsg(&sCheck, "Page %u: never used", i); |
| 77647 | } | 80586 | } |
| 77648 | #else | 80587 | #else |
| 77649 | /* If the database supports auto-vacuum, make sure no tables contain | 80588 | /* If the database supports auto-vacuum, make sure no tables contain |
| @@ -77651,11 +80590,11 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | |||
| 77651 | */ | 80590 | */ |
| 77652 | if( getPageReferenced(&sCheck, i)==0 && | 80591 | if( getPageReferenced(&sCheck, i)==0 && |
| 77653 | (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ | 80592 | (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ |
| 77654 | checkAppendMsg(&sCheck, "Page %d is never used", i); | 80593 | checkAppendMsg(&sCheck, "Page %u: never used", i); |
| 77655 | } | 80594 | } |
| 77656 | if( getPageReferenced(&sCheck, i)!=0 && | 80595 | if( getPageReferenced(&sCheck, i)!=0 && |
| 77657 | (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ | 80596 | (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ |
| 77658 | checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i); | 80597 | checkAppendMsg(&sCheck, "Page %u: pointer map referenced", i); |
| 77659 | } | 80598 | } |
| 77660 | #endif | 80599 | #endif |
| 77661 | } | 80600 | } |
| @@ -77666,16 +80605,17 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( | |||
| 77666 | integrity_ck_cleanup: | 80605 | integrity_ck_cleanup: |
| 77667 | sqlite3PageFree(sCheck.heap); | 80606 | sqlite3PageFree(sCheck.heap); |
| 77668 | sqlite3_free(sCheck.aPgRef); | 80607 | sqlite3_free(sCheck.aPgRef); |
| 77669 | if( sCheck.bOomFault ){ | 80608 | *pnErr = sCheck.nErr; |
| 80609 | if( sCheck.nErr==0 ){ | ||
| 77670 | sqlite3_str_reset(&sCheck.errMsg); | 80610 | sqlite3_str_reset(&sCheck.errMsg); |
| 77671 | sCheck.nErr++; | 80611 | *pzOut = 0; |
| 80612 | }else{ | ||
| 80613 | *pzOut = sqlite3StrAccumFinish(&sCheck.errMsg); | ||
| 77672 | } | 80614 | } |
| 77673 | *pnErr = sCheck.nErr; | ||
| 77674 | if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg); | ||
| 77675 | /* Make sure this analysis did not leave any unref() pages. */ | 80615 | /* Make sure this analysis did not leave any unref() pages. */ |
| 77676 | assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); | 80616 | assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); |
| 77677 | sqlite3BtreeLeave(p); | 80617 | sqlite3BtreeLeave(p); |
| 77678 | return sqlite3StrAccumFinish(&sCheck.errMsg); | 80618 | return sCheck.rc; |
| 77679 | } | 80619 | } |
| 77680 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ | 80620 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ |
| 77681 | 80621 | ||
| @@ -77940,6 +80880,17 @@ SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){ | |||
| 77940 | */ | 80880 | */ |
| 77941 | SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } | 80881 | SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } |
| 77942 | 80882 | ||
| 80883 | /* | ||
| 80884 | ** If no transaction is active and the database is not a temp-db, clear | ||
| 80885 | ** the in-memory pager cache. | ||
| 80886 | */ | ||
| 80887 | SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree *p){ | ||
| 80888 | BtShared *pBt = p->pBt; | ||
| 80889 | if( pBt->inTransaction==TRANS_NONE ){ | ||
| 80890 | sqlite3PagerClearCache(pBt->pPager); | ||
| 80891 | } | ||
| 80892 | } | ||
| 80893 | |||
| 77943 | #if !defined(SQLITE_OMIT_SHARED_CACHE) | 80894 | #if !defined(SQLITE_OMIT_SHARED_CACHE) |
| 77944 | /* | 80895 | /* |
| 77945 | ** Return true if the Btree passed as the only argument is sharable. | 80896 | ** Return true if the Btree passed as the only argument is sharable. |
| @@ -78205,13 +81156,7 @@ static int backupOnePage( | |||
| 78205 | assert( !isFatalError(p->rc) ); | 81156 | assert( !isFatalError(p->rc) ); |
| 78206 | assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); | 81157 | assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); |
| 78207 | assert( zSrcData ); | 81158 | assert( zSrcData ); |
| 78208 | 81159 | assert( nSrcPgsz==nDestPgsz || sqlite3PagerIsMemdb(pDestPager)==0 ); | |
| 78209 | /* Catch the case where the destination is an in-memory database and the | ||
| 78210 | ** page sizes of the source and destination differ. | ||
| 78211 | */ | ||
| 78212 | if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ | ||
| 78213 | rc = SQLITE_READONLY; | ||
| 78214 | } | ||
| 78215 | 81160 | ||
| 78216 | /* This loop runs once for each destination page spanned by the source | 81161 | /* This loop runs once for each destination page spanned by the source |
| 78217 | ** page. For each iteration, variable iOff is set to the byte offset | 81162 | ** page. For each iteration, variable iOff is set to the byte offset |
| @@ -78344,7 +81289,10 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ | |||
| 78344 | pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); | 81289 | pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); |
| 78345 | pgszDest = sqlite3BtreeGetPageSize(p->pDest); | 81290 | pgszDest = sqlite3BtreeGetPageSize(p->pDest); |
| 78346 | destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); | 81291 | destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); |
| 78347 | if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){ | 81292 | if( SQLITE_OK==rc |
| 81293 | && (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager)) | ||
| 81294 | && pgszSrc!=pgszDest | ||
| 81295 | ){ | ||
| 78348 | rc = SQLITE_READONLY; | 81296 | rc = SQLITE_READONLY; |
| 78349 | } | 81297 | } |
| 78350 | 81298 | ||
| @@ -78850,9 +81798,9 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ | |||
| 78850 | i64 x; | 81798 | i64 x; |
| 78851 | assert( (p->flags&MEM_Int)*2==sizeof(x) ); | 81799 | assert( (p->flags&MEM_Int)*2==sizeof(x) ); |
| 78852 | memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2); | 81800 | memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2); |
| 78853 | sqlite3Int64ToText(x, zBuf); | 81801 | p->n = sqlite3Int64ToText(x, zBuf); |
| 78854 | #else | 81802 | #else |
| 78855 | sqlite3Int64ToText(p->u.i, zBuf); | 81803 | p->n = sqlite3Int64ToText(p->u.i, zBuf); |
| 78856 | #endif | 81804 | #endif |
| 78857 | }else{ | 81805 | }else{ |
| 78858 | sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); | 81806 | sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); |
| @@ -78860,6 +81808,7 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ | |||
| 78860 | (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r); | 81808 | (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r); |
| 78861 | assert( acc.zText==zBuf && acc.mxAlloc<=0 ); | 81809 | assert( acc.zText==zBuf && acc.mxAlloc<=0 ); |
| 78862 | zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ | 81810 | zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ |
| 81811 | p->n = acc.nChar; | ||
| 78863 | } | 81812 | } |
| 78864 | } | 81813 | } |
| 78865 | 81814 | ||
| @@ -78887,10 +81836,12 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ | |||
| 78887 | ** This routine is for use inside of assert() statements only. | 81836 | ** This routine is for use inside of assert() statements only. |
| 78888 | */ | 81837 | */ |
| 78889 | SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ | 81838 | SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ |
| 81839 | Mem tmp; | ||
| 78890 | char zBuf[100]; | 81840 | char zBuf[100]; |
| 78891 | char *z; | 81841 | char *z; |
| 78892 | int i, j, incr; | 81842 | int i, j, incr; |
| 78893 | if( (p->flags & MEM_Str)==0 ) return 1; | 81843 | if( (p->flags & MEM_Str)==0 ) return 1; |
| 81844 | if( p->db && p->db->mallocFailed ) return 1; | ||
| 78894 | if( p->flags & MEM_Term ){ | 81845 | if( p->flags & MEM_Term ){ |
| 78895 | /* Insure that the string is properly zero-terminated. Pay particular | 81846 | /* Insure that the string is properly zero-terminated. Pay particular |
| 78896 | ** attention to the case where p->n is odd */ | 81847 | ** attention to the case where p->n is odd */ |
| @@ -78903,7 +81854,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ | |||
| 78903 | assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 ); | 81854 | assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 ); |
| 78904 | } | 81855 | } |
| 78905 | if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; | 81856 | if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; |
| 78906 | vdbeMemRenderNum(sizeof(zBuf), zBuf, p); | 81857 | memcpy(&tmp, p, sizeof(tmp)); |
| 81858 | vdbeMemRenderNum(sizeof(zBuf), zBuf, &tmp); | ||
| 78907 | z = p->z; | 81859 | z = p->z; |
| 78908 | i = j = 0; | 81860 | i = j = 0; |
| 78909 | incr = 1; | 81861 | incr = 1; |
| @@ -79047,6 +81999,40 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ | |||
| 79047 | } | 81999 | } |
| 79048 | 82000 | ||
| 79049 | /* | 82001 | /* |
| 82002 | ** If pMem is already a string, detect if it is a zero-terminated | ||
| 82003 | ** string, or make it into one if possible, and mark it as such. | ||
| 82004 | ** | ||
| 82005 | ** This is an optimization. Correct operation continues even if | ||
| 82006 | ** this routine is a no-op. | ||
| 82007 | */ | ||
| 82008 | SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ | ||
| 82009 | if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){ | ||
| 82010 | /* pMem must be a string, and it cannot be an ephemeral or static string */ | ||
| 82011 | return; | ||
| 82012 | } | ||
| 82013 | if( pMem->enc!=SQLITE_UTF8 ) return; | ||
| 82014 | if( NEVER(pMem->z==0) ) return; | ||
| 82015 | if( pMem->flags & MEM_Dyn ){ | ||
| 82016 | if( pMem->xDel==sqlite3_free | ||
| 82017 | && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1) | ||
| 82018 | ){ | ||
| 82019 | pMem->z[pMem->n] = 0; | ||
| 82020 | pMem->flags |= MEM_Term; | ||
| 82021 | return; | ||
| 82022 | } | ||
| 82023 | if( pMem->xDel==(void(*)(void*))sqlite3RCStrUnref ){ | ||
| 82024 | /* Blindly assume that all RCStr objects are zero-terminated */ | ||
| 82025 | pMem->flags |= MEM_Term; | ||
| 82026 | return; | ||
| 82027 | } | ||
| 82028 | }else if( pMem->szMalloc >= pMem->n+1 ){ | ||
| 82029 | pMem->z[pMem->n] = 0; | ||
| 82030 | pMem->flags |= MEM_Term; | ||
| 82031 | return; | ||
| 82032 | } | ||
| 82033 | } | ||
| 82034 | |||
| 82035 | /* | ||
| 79050 | ** It is already known that pMem contains an unterminated string. | 82036 | ** It is already known that pMem contains an unterminated string. |
| 79051 | ** Add the zero terminator. | 82037 | ** Add the zero terminator. |
| 79052 | ** | 82038 | ** |
| @@ -79172,7 +82158,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ | |||
| 79172 | 82158 | ||
| 79173 | vdbeMemRenderNum(nByte, pMem->z, pMem); | 82159 | vdbeMemRenderNum(nByte, pMem->z, pMem); |
| 79174 | assert( pMem->z!=0 ); | 82160 | assert( pMem->z!=0 ); |
| 79175 | pMem->n = sqlite3Strlen30NN(pMem->z); | 82161 | assert( pMem->n==(int)sqlite3Strlen30NN(pMem->z) ); |
| 79176 | pMem->enc = SQLITE_UTF8; | 82162 | pMem->enc = SQLITE_UTF8; |
| 79177 | pMem->flags |= MEM_Str|MEM_Term; | 82163 | pMem->flags |= MEM_Str|MEM_Term; |
| 79178 | if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); | 82164 | if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); |
| @@ -79308,36 +82294,6 @@ SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){ | |||
| 79308 | } | 82294 | } |
| 79309 | 82295 | ||
| 79310 | /* | 82296 | /* |
| 79311 | ** Convert a 64-bit IEEE double into a 64-bit signed integer. | ||
| 79312 | ** If the double is out of range of a 64-bit signed integer then | ||
| 79313 | ** return the closest available 64-bit signed integer. | ||
| 79314 | */ | ||
| 79315 | static SQLITE_NOINLINE i64 doubleToInt64(double r){ | ||
| 79316 | #ifdef SQLITE_OMIT_FLOATING_POINT | ||
| 79317 | /* When floating-point is omitted, double and int64 are the same thing */ | ||
| 79318 | return r; | ||
| 79319 | #else | ||
| 79320 | /* | ||
| 79321 | ** Many compilers we encounter do not define constants for the | ||
| 79322 | ** minimum and maximum 64-bit integers, or they define them | ||
| 79323 | ** inconsistently. And many do not understand the "LL" notation. | ||
| 79324 | ** So we define our own static constants here using nothing | ||
| 79325 | ** larger than a 32-bit integer constant. | ||
| 79326 | */ | ||
| 79327 | static const i64 maxInt = LARGEST_INT64; | ||
| 79328 | static const i64 minInt = SMALLEST_INT64; | ||
| 79329 | |||
| 79330 | if( r<=(double)minInt ){ | ||
| 79331 | return minInt; | ||
| 79332 | }else if( r>=(double)maxInt ){ | ||
| 79333 | return maxInt; | ||
| 79334 | }else{ | ||
| 79335 | return (i64)r; | ||
| 79336 | } | ||
| 79337 | #endif | ||
| 79338 | } | ||
| 79339 | |||
| 79340 | /* | ||
| 79341 | ** Return some kind of integer value which is the best we can do | 82297 | ** Return some kind of integer value which is the best we can do |
| 79342 | ** at representing the value that *pMem describes as an integer. | 82298 | ** at representing the value that *pMem describes as an integer. |
| 79343 | ** If pMem is an integer, then the value is exact. If pMem is | 82299 | ** If pMem is an integer, then the value is exact. If pMem is |
| @@ -79363,7 +82319,7 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){ | |||
| 79363 | testcase( flags & MEM_IntReal ); | 82319 | testcase( flags & MEM_IntReal ); |
| 79364 | return pMem->u.i; | 82320 | return pMem->u.i; |
| 79365 | }else if( flags & MEM_Real ){ | 82321 | }else if( flags & MEM_Real ){ |
| 79366 | return doubleToInt64(pMem->u.r); | 82322 | return sqlite3RealToI64(pMem->u.r); |
| 79367 | }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ | 82323 | }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ |
| 79368 | return memIntValue(pMem); | 82324 | return memIntValue(pMem); |
| 79369 | }else{ | 82325 | }else{ |
| @@ -79412,32 +82368,35 @@ SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ | |||
| 79412 | } | 82368 | } |
| 79413 | 82369 | ||
| 79414 | /* | 82370 | /* |
| 79415 | ** The MEM structure is already a MEM_Real. Try to also make it a | 82371 | ** The MEM structure is already a MEM_Real or MEM_IntReal. Try to |
| 79416 | ** MEM_Int if we can. | 82372 | ** make it a MEM_Int if we can. |
| 79417 | */ | 82373 | */ |
| 79418 | SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ | 82374 | SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ |
| 79419 | i64 ix; | ||
| 79420 | assert( pMem!=0 ); | 82375 | assert( pMem!=0 ); |
| 79421 | assert( pMem->flags & MEM_Real ); | 82376 | assert( pMem->flags & (MEM_Real|MEM_IntReal) ); |
| 79422 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); | 82377 | assert( !sqlite3VdbeMemIsRowSet(pMem) ); |
| 79423 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); | 82378 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 79424 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); | 82379 | assert( EIGHT_BYTE_ALIGNMENT(pMem) ); |
| 79425 | 82380 | ||
| 79426 | ix = doubleToInt64(pMem->u.r); | 82381 | if( pMem->flags & MEM_IntReal ){ |
| 79427 | |||
| 79428 | /* Only mark the value as an integer if | ||
| 79429 | ** | ||
| 79430 | ** (1) the round-trip conversion real->int->real is a no-op, and | ||
| 79431 | ** (2) The integer is neither the largest nor the smallest | ||
| 79432 | ** possible integer (ticket #3922) | ||
| 79433 | ** | ||
| 79434 | ** The second and third terms in the following conditional enforces | ||
| 79435 | ** the second condition under the assumption that addition overflow causes | ||
| 79436 | ** values to wrap around. | ||
| 79437 | */ | ||
| 79438 | if( pMem->u.r==ix && ix>SMALLEST_INT64 && ix<LARGEST_INT64 ){ | ||
| 79439 | pMem->u.i = ix; | ||
| 79440 | MemSetTypeFlag(pMem, MEM_Int); | 82382 | MemSetTypeFlag(pMem, MEM_Int); |
| 82383 | }else{ | ||
| 82384 | i64 ix = sqlite3RealToI64(pMem->u.r); | ||
| 82385 | |||
| 82386 | /* Only mark the value as an integer if | ||
| 82387 | ** | ||
| 82388 | ** (1) the round-trip conversion real->int->real is a no-op, and | ||
| 82389 | ** (2) The integer is neither the largest nor the smallest | ||
| 82390 | ** possible integer (ticket #3922) | ||
| 82391 | ** | ||
| 82392 | ** The second and third terms in the following conditional enforces | ||
| 82393 | ** the second condition under the assumption that addition overflow causes | ||
| 82394 | ** values to wrap around. | ||
| 82395 | */ | ||
| 82396 | if( pMem->u.r==ix && ix>SMALLEST_INT64 && ix<LARGEST_INT64 ){ | ||
| 82397 | pMem->u.i = ix; | ||
| 82398 | MemSetTypeFlag(pMem, MEM_Int); | ||
| 82399 | } | ||
| 79441 | } | 82400 | } |
| 79442 | } | 82401 | } |
| 79443 | 82402 | ||
| @@ -79485,6 +82444,16 @@ SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ | |||
| 79485 | && i >= -2251799813685248LL && i < 2251799813685248LL); | 82444 | && i >= -2251799813685248LL && i < 2251799813685248LL); |
| 79486 | } | 82445 | } |
| 79487 | 82446 | ||
| 82447 | /* Convert a floating point value to its closest integer. Do so in | ||
| 82448 | ** a way that avoids 'outside the range of representable values' warnings | ||
| 82449 | ** from UBSAN. | ||
| 82450 | */ | ||
| 82451 | SQLITE_PRIVATE i64 sqlite3RealToI64(double r){ | ||
| 82452 | if( r<-9223372036854774784.0 ) return SMALLEST_INT64; | ||
| 82453 | if( r>+9223372036854774784.0 ) return LARGEST_INT64; | ||
| 82454 | return (i64)r; | ||
| 82455 | } | ||
| 82456 | |||
| 79488 | /* | 82457 | /* |
| 79489 | ** Convert pMem so that it has type MEM_Real or MEM_Int. | 82458 | ** Convert pMem so that it has type MEM_Real or MEM_Int. |
| 79490 | ** Invalidate any prior representations. | 82459 | ** Invalidate any prior representations. |
| @@ -79506,7 +82475,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ | |||
| 79506 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); | 82475 | assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); |
| 79507 | rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); | 82476 | rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); |
| 79508 | if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1) | 82477 | if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1) |
| 79509 | || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r)) | 82478 | || sqlite3RealSameAsInt(pMem->u.r, (ix = sqlite3RealToI64(pMem->u.r))) |
| 79510 | ){ | 82479 | ){ |
| 79511 | pMem->u.i = ix; | 82480 | pMem->u.i = ix; |
| 79512 | MemSetTypeFlag(pMem, MEM_Int); | 82481 | MemSetTypeFlag(pMem, MEM_Int); |
| @@ -79552,13 +82521,17 @@ SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ | |||
| 79552 | break; | 82521 | break; |
| 79553 | } | 82522 | } |
| 79554 | default: { | 82523 | default: { |
| 82524 | int rc; | ||
| 79555 | assert( aff==SQLITE_AFF_TEXT ); | 82525 | assert( aff==SQLITE_AFF_TEXT ); |
| 79556 | assert( MEM_Str==(MEM_Blob>>3) ); | 82526 | assert( MEM_Str==(MEM_Blob>>3) ); |
| 79557 | pMem->flags |= (pMem->flags&MEM_Blob)>>3; | 82527 | pMem->flags |= (pMem->flags&MEM_Blob)>>3; |
| 79558 | sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); | 82528 | sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); |
| 79559 | assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); | 82529 | assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); |
| 79560 | pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); | 82530 | pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); |
| 79561 | return sqlite3VdbeChangeEncoding(pMem, encoding); | 82531 | if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1; |
| 82532 | rc = sqlite3VdbeChangeEncoding(pMem, encoding); | ||
| 82533 | if( rc ) return rc; | ||
| 82534 | sqlite3VdbeMemZeroTerminateIfAble(pMem); | ||
| 79562 | } | 82535 | } |
| 79563 | } | 82536 | } |
| 79564 | return SQLITE_OK; | 82537 | return SQLITE_OK; |
| @@ -80082,6 +83055,24 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ | |||
| 80082 | return valueToText(pVal, enc); | 83055 | return valueToText(pVal, enc); |
| 80083 | } | 83056 | } |
| 80084 | 83057 | ||
| 83058 | /* Return true if sqlit3_value object pVal is a string or blob value | ||
| 83059 | ** that uses the destructor specified in the second argument. | ||
| 83060 | ** | ||
| 83061 | ** TODO: Maybe someday promote this interface into a published API so | ||
| 83062 | ** that third-party extensions can get access to it? | ||
| 83063 | */ | ||
| 83064 | SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value *pVal, void(*xFree)(void*)){ | ||
| 83065 | if( ALWAYS(pVal!=0) | ||
| 83066 | && ALWAYS((pVal->flags & (MEM_Str|MEM_Blob))!=0) | ||
| 83067 | && (pVal->flags & MEM_Dyn)!=0 | ||
| 83068 | && pVal->xDel==xFree | ||
| 83069 | ){ | ||
| 83070 | return 1; | ||
| 83071 | }else{ | ||
| 83072 | return 0; | ||
| 83073 | } | ||
| 83074 | } | ||
| 83075 | |||
| 80085 | /* | 83076 | /* |
| 80086 | ** Create a new sqlite3_value object. | 83077 | ** Create a new sqlite3_value object. |
| 80087 | */ | 83078 | */ |
| @@ -80149,6 +83140,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ | |||
| 80149 | } | 83140 | } |
| 80150 | 83141 | ||
| 80151 | pRec->nField = p->iVal+1; | 83142 | pRec->nField = p->iVal+1; |
| 83143 | sqlite3VdbeMemSetNull(&pRec->aMem[p->iVal]); | ||
| 80152 | return &pRec->aMem[p->iVal]; | 83144 | return &pRec->aMem[p->iVal]; |
| 80153 | } | 83145 | } |
| 80154 | #else | 83146 | #else |
| @@ -80202,6 +83194,9 @@ static int valueFromFunction( | |||
| 80202 | if( pList ) nVal = pList->nExpr; | 83194 | if( pList ) nVal = pList->nExpr; |
| 80203 | assert( !ExprHasProperty(p, EP_IntValue) ); | 83195 | assert( !ExprHasProperty(p, EP_IntValue) ); |
| 80204 | pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); | 83196 | pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); |
| 83197 | #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION | ||
| 83198 | if( pFunc==0 ) return SQLITE_OK; | ||
| 83199 | #endif | ||
| 80205 | assert( pFunc ); | 83200 | assert( pFunc ); |
| 80206 | if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 | 83201 | if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 |
| 80207 | || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) | 83202 | || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) |
| @@ -80227,8 +83222,6 @@ static int valueFromFunction( | |||
| 80227 | goto value_from_function_out; | 83222 | goto value_from_function_out; |
| 80228 | } | 83223 | } |
| 80229 | 83224 | ||
| 80230 | testcase( pCtx->pParse->rc==SQLITE_ERROR ); | ||
| 80231 | testcase( pCtx->pParse->rc==SQLITE_OK ); | ||
| 80232 | memset(&ctx, 0, sizeof(ctx)); | 83225 | memset(&ctx, 0, sizeof(ctx)); |
| 80233 | ctx.pOut = pVal; | 83226 | ctx.pOut = pVal; |
| 80234 | ctx.pFunc = pFunc; | 83227 | ctx.pFunc = pFunc; |
| @@ -80241,16 +83234,16 @@ static int valueFromFunction( | |||
| 80241 | sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); | 83234 | sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); |
| 80242 | assert( rc==SQLITE_OK ); | 83235 | assert( rc==SQLITE_OK ); |
| 80243 | rc = sqlite3VdbeChangeEncoding(pVal, enc); | 83236 | rc = sqlite3VdbeChangeEncoding(pVal, enc); |
| 80244 | if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ | 83237 | if( NEVER(rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal)) ){ |
| 80245 | rc = SQLITE_TOOBIG; | 83238 | rc = SQLITE_TOOBIG; |
| 80246 | pCtx->pParse->nErr++; | 83239 | pCtx->pParse->nErr++; |
| 80247 | } | 83240 | } |
| 80248 | } | 83241 | } |
| 80249 | pCtx->pParse->rc = rc; | ||
| 80250 | 83242 | ||
| 80251 | value_from_function_out: | 83243 | value_from_function_out: |
| 80252 | if( rc!=SQLITE_OK ){ | 83244 | if( rc!=SQLITE_OK ){ |
| 80253 | pVal = 0; | 83245 | pVal = 0; |
| 83246 | pCtx->pParse->rc = rc; | ||
| 80254 | } | 83247 | } |
| 80255 | if( apVal ){ | 83248 | if( apVal ){ |
| 80256 | for(i=0; i<nVal; i++){ | 83249 | for(i=0; i<nVal; i++){ |
| @@ -80308,6 +83301,13 @@ static int valueFromExpr( | |||
| 80308 | rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); | 83301 | rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); |
| 80309 | testcase( rc!=SQLITE_OK ); | 83302 | testcase( rc!=SQLITE_OK ); |
| 80310 | if( *ppVal ){ | 83303 | if( *ppVal ){ |
| 83304 | #ifdef SQLITE_ENABLE_STAT4 | ||
| 83305 | rc = ExpandBlob(*ppVal); | ||
| 83306 | #else | ||
| 83307 | /* zero-blobs only come from functions, not literal values. And | ||
| 83308 | ** functions are only processed under STAT4 */ | ||
| 83309 | assert( (ppVal[0][0].flags & MEM_Zero)==0 ); | ||
| 83310 | #endif | ||
| 80311 | sqlite3VdbeMemCast(*ppVal, aff, enc); | 83311 | sqlite3VdbeMemCast(*ppVal, aff, enc); |
| 80312 | sqlite3ValueApplyAffinity(*ppVal, affinity, enc); | 83312 | sqlite3ValueApplyAffinity(*ppVal, affinity, enc); |
| 80313 | } | 83313 | } |
| @@ -80693,6 +83693,9 @@ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ | |||
| 80693 | if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){ | 83693 | if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){ |
| 80694 | return p->n; | 83694 | return p->n; |
| 80695 | } | 83695 | } |
| 83696 | if( (p->flags & MEM_Str)!=0 && enc!=SQLITE_UTF8 && pVal->enc!=SQLITE_UTF8 ){ | ||
| 83697 | return p->n; | ||
| 83698 | } | ||
| 80696 | if( (p->flags & MEM_Blob)!=0 ){ | 83699 | if( (p->flags & MEM_Blob)!=0 ){ |
| 80697 | if( p->flags & MEM_Zero ){ | 83700 | if( p->flags & MEM_Zero ){ |
| 80698 | return p->n + p->u.nZero; | 83701 | return p->n + p->u.nZero; |
| @@ -80738,10 +83741,10 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ | |||
| 80738 | memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); | 83741 | memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); |
| 80739 | p->db = db; | 83742 | p->db = db; |
| 80740 | if( db->pVdbe ){ | 83743 | if( db->pVdbe ){ |
| 80741 | db->pVdbe->pPrev = p; | 83744 | db->pVdbe->ppVPrev = &p->pVNext; |
| 80742 | } | 83745 | } |
| 80743 | p->pNext = db->pVdbe; | 83746 | p->pVNext = db->pVdbe; |
| 80744 | p->pPrev = 0; | 83747 | p->ppVPrev = &db->pVdbe; |
| 80745 | db->pVdbe = p; | 83748 | db->pVdbe = p; |
| 80746 | assert( p->eVdbeState==VDBE_INIT_STATE ); | 83749 | assert( p->eVdbeState==VDBE_INIT_STATE ); |
| 80747 | p->pParse = pParse; | 83750 | p->pParse = pParse; |
| @@ -80823,21 +83826,28 @@ SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString( | |||
| 80823 | #endif | 83826 | #endif |
| 80824 | 83827 | ||
| 80825 | /* | 83828 | /* |
| 80826 | ** Swap all content between two VDBE structures. | 83829 | ** Swap byte-code between two VDBE structures. |
| 83830 | ** | ||
| 83831 | ** This happens after pB was previously run and returned | ||
| 83832 | ** SQLITE_SCHEMA. The statement was then reprepared in pA. | ||
| 83833 | ** This routine transfers the new bytecode in pA over to pB | ||
| 83834 | ** so that pB can be run again. The old pB byte code is | ||
| 83835 | ** moved back to pA so that it will be cleaned up when pA is | ||
| 83836 | ** finalized. | ||
| 80827 | */ | 83837 | */ |
| 80828 | SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ | 83838 | SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ |
| 80829 | Vdbe tmp, *pTmp; | 83839 | Vdbe tmp, *pTmp, **ppTmp; |
| 80830 | char *zTmp; | 83840 | char *zTmp; |
| 80831 | assert( pA->db==pB->db ); | 83841 | assert( pA->db==pB->db ); |
| 80832 | tmp = *pA; | 83842 | tmp = *pA; |
| 80833 | *pA = *pB; | 83843 | *pA = *pB; |
| 80834 | *pB = tmp; | 83844 | *pB = tmp; |
| 80835 | pTmp = pA->pNext; | 83845 | pTmp = pA->pVNext; |
| 80836 | pA->pNext = pB->pNext; | 83846 | pA->pVNext = pB->pVNext; |
| 80837 | pB->pNext = pTmp; | 83847 | pB->pVNext = pTmp; |
| 80838 | pTmp = pA->pPrev; | 83848 | ppTmp = pA->ppVPrev; |
| 80839 | pA->pPrev = pB->pPrev; | 83849 | pA->ppVPrev = pB->ppVPrev; |
| 80840 | pB->pPrev = pTmp; | 83850 | pB->ppVPrev = ppTmp; |
| 80841 | zTmp = pA->zSql; | 83851 | zTmp = pA->zSql; |
| 80842 | pA->zSql = pB->zSql; | 83852 | pA->zSql = pB->zSql; |
| 80843 | pB->zSql = zTmp; | 83853 | pB->zSql = zTmp; |
| @@ -80913,11 +83923,42 @@ static int growOpArray(Vdbe *v, int nOp){ | |||
| 80913 | */ | 83923 | */ |
| 80914 | static void test_addop_breakpoint(int pc, Op *pOp){ | 83924 | static void test_addop_breakpoint(int pc, Op *pOp){ |
| 80915 | static int n = 0; | 83925 | static int n = 0; |
| 83926 | (void)pc; | ||
| 83927 | (void)pOp; | ||
| 80916 | n++; | 83928 | n++; |
| 80917 | } | 83929 | } |
| 80918 | #endif | 83930 | #endif |
| 80919 | 83931 | ||
| 80920 | /* | 83932 | /* |
| 83933 | ** Slow paths for sqlite3VdbeAddOp3() and sqlite3VdbeAddOp4Int() for the | ||
| 83934 | ** unusual case when we need to increase the size of the Vdbe.aOp[] array | ||
| 83935 | ** before adding the new opcode. | ||
| 83936 | */ | ||
| 83937 | static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ | ||
| 83938 | assert( p->nOpAlloc<=p->nOp ); | ||
| 83939 | if( growOpArray(p, 1) ) return 1; | ||
| 83940 | assert( p->nOpAlloc>p->nOp ); | ||
| 83941 | return sqlite3VdbeAddOp3(p, op, p1, p2, p3); | ||
| 83942 | } | ||
| 83943 | static SQLITE_NOINLINE int addOp4IntSlow( | ||
| 83944 | Vdbe *p, /* Add the opcode to this VM */ | ||
| 83945 | int op, /* The new opcode */ | ||
| 83946 | int p1, /* The P1 operand */ | ||
| 83947 | int p2, /* The P2 operand */ | ||
| 83948 | int p3, /* The P3 operand */ | ||
| 83949 | int p4 /* The P4 operand as an integer */ | ||
| 83950 | ){ | ||
| 83951 | int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); | ||
| 83952 | if( p->db->mallocFailed==0 ){ | ||
| 83953 | VdbeOp *pOp = &p->aOp[addr]; | ||
| 83954 | pOp->p4type = P4_INT32; | ||
| 83955 | pOp->p4.i = p4; | ||
| 83956 | } | ||
| 83957 | return addr; | ||
| 83958 | } | ||
| 83959 | |||
| 83960 | |||
| 83961 | /* | ||
| 80921 | ** Add a new instruction to the list of instructions current in the | 83962 | ** Add a new instruction to the list of instructions current in the |
| 80922 | ** VDBE. Return the address of the new instruction. | 83963 | ** VDBE. Return the address of the new instruction. |
| 80923 | ** | 83964 | ** |
| @@ -80927,17 +83968,16 @@ static void test_addop_breakpoint(int pc, Op *pOp){ | |||
| 80927 | ** | 83968 | ** |
| 80928 | ** op The opcode for this instruction | 83969 | ** op The opcode for this instruction |
| 80929 | ** | 83970 | ** |
| 80930 | ** p1, p2, p3 Operands | 83971 | ** p1, p2, p3, p4 Operands |
| 80931 | ** | ||
| 80932 | ** Use the sqlite3VdbeResolveLabel() function to fix an address and | ||
| 80933 | ** the sqlite3VdbeChangeP4() function to change the value of the P4 | ||
| 80934 | ** operand. | ||
| 80935 | */ | 83972 | */ |
| 80936 | static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ | 83973 | SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ |
| 80937 | assert( p->nOpAlloc<=p->nOp ); | 83974 | return sqlite3VdbeAddOp3(p, op, 0, 0, 0); |
| 80938 | if( growOpArray(p, 1) ) return 1; | 83975 | } |
| 80939 | assert( p->nOpAlloc>p->nOp ); | 83976 | SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ |
| 80940 | return sqlite3VdbeAddOp3(p, op, p1, p2, p3); | 83977 | return sqlite3VdbeAddOp3(p, op, p1, 0, 0); |
| 83978 | } | ||
| 83979 | SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ | ||
| 83980 | return sqlite3VdbeAddOp3(p, op, p1, p2, 0); | ||
| 80941 | } | 83981 | } |
| 80942 | SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ | 83982 | SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ |
| 80943 | int i; | 83983 | int i; |
| @@ -80960,32 +84000,78 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ | |||
| 80960 | pOp->p3 = p3; | 84000 | pOp->p3 = p3; |
| 80961 | pOp->p4.p = 0; | 84001 | pOp->p4.p = 0; |
| 80962 | pOp->p4type = P4_NOTUSED; | 84002 | pOp->p4type = P4_NOTUSED; |
| 84003 | |||
| 84004 | /* Replicate this logic in sqlite3VdbeAddOp4Int() | ||
| 84005 | ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ | ||
| 80963 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS | 84006 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS |
| 80964 | pOp->zComment = 0; | 84007 | pOp->zComment = 0; |
| 80965 | #endif | 84008 | #endif |
| 84009 | #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) | ||
| 84010 | pOp->nExec = 0; | ||
| 84011 | pOp->nCycle = 0; | ||
| 84012 | #endif | ||
| 80966 | #ifdef SQLITE_DEBUG | 84013 | #ifdef SQLITE_DEBUG |
| 80967 | if( p->db->flags & SQLITE_VdbeAddopTrace ){ | 84014 | if( p->db->flags & SQLITE_VdbeAddopTrace ){ |
| 80968 | sqlite3VdbePrintOp(0, i, &p->aOp[i]); | 84015 | sqlite3VdbePrintOp(0, i, &p->aOp[i]); |
| 80969 | test_addop_breakpoint(i, &p->aOp[i]); | 84016 | test_addop_breakpoint(i, &p->aOp[i]); |
| 80970 | } | 84017 | } |
| 80971 | #endif | 84018 | #endif |
| 80972 | #ifdef VDBE_PROFILE | ||
| 80973 | pOp->cycles = 0; | ||
| 80974 | pOp->cnt = 0; | ||
| 80975 | #endif | ||
| 80976 | #ifdef SQLITE_VDBE_COVERAGE | 84019 | #ifdef SQLITE_VDBE_COVERAGE |
| 80977 | pOp->iSrcLine = 0; | 84020 | pOp->iSrcLine = 0; |
| 80978 | #endif | 84021 | #endif |
| 84022 | /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 84023 | ** Replicate in sqlite3VdbeAddOp4Int() */ | ||
| 84024 | |||
| 80979 | return i; | 84025 | return i; |
| 80980 | } | 84026 | } |
| 80981 | SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ | 84027 | SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( |
| 80982 | return sqlite3VdbeAddOp3(p, op, 0, 0, 0); | 84028 | Vdbe *p, /* Add the opcode to this VM */ |
| 80983 | } | 84029 | int op, /* The new opcode */ |
| 80984 | SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ | 84030 | int p1, /* The P1 operand */ |
| 80985 | return sqlite3VdbeAddOp3(p, op, p1, 0, 0); | 84031 | int p2, /* The P2 operand */ |
| 80986 | } | 84032 | int p3, /* The P3 operand */ |
| 80987 | SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ | 84033 | int p4 /* The P4 operand as an integer */ |
| 80988 | return sqlite3VdbeAddOp3(p, op, p1, p2, 0); | 84034 | ){ |
| 84035 | int i; | ||
| 84036 | VdbeOp *pOp; | ||
| 84037 | |||
| 84038 | i = p->nOp; | ||
| 84039 | if( p->nOpAlloc<=i ){ | ||
| 84040 | return addOp4IntSlow(p, op, p1, p2, p3, p4); | ||
| 84041 | } | ||
| 84042 | p->nOp++; | ||
| 84043 | pOp = &p->aOp[i]; | ||
| 84044 | assert( pOp!=0 ); | ||
| 84045 | pOp->opcode = (u8)op; | ||
| 84046 | pOp->p5 = 0; | ||
| 84047 | pOp->p1 = p1; | ||
| 84048 | pOp->p2 = p2; | ||
| 84049 | pOp->p3 = p3; | ||
| 84050 | pOp->p4.i = p4; | ||
| 84051 | pOp->p4type = P4_INT32; | ||
| 84052 | |||
| 84053 | /* Replicate this logic in sqlite3VdbeAddOp3() | ||
| 84054 | ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ | ||
| 84055 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS | ||
| 84056 | pOp->zComment = 0; | ||
| 84057 | #endif | ||
| 84058 | #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) | ||
| 84059 | pOp->nExec = 0; | ||
| 84060 | pOp->nCycle = 0; | ||
| 84061 | #endif | ||
| 84062 | #ifdef SQLITE_DEBUG | ||
| 84063 | if( p->db->flags & SQLITE_VdbeAddopTrace ){ | ||
| 84064 | sqlite3VdbePrintOp(0, i, &p->aOp[i]); | ||
| 84065 | test_addop_breakpoint(i, &p->aOp[i]); | ||
| 84066 | } | ||
| 84067 | #endif | ||
| 84068 | #ifdef SQLITE_VDBE_COVERAGE | ||
| 84069 | pOp->iSrcLine = 0; | ||
| 84070 | #endif | ||
| 84071 | /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 84072 | ** Replicate in sqlite3VdbeAddOp3() */ | ||
| 84073 | |||
| 84074 | return i; | ||
| 80989 | } | 84075 | } |
| 80990 | 84076 | ||
| 80991 | /* Generate code for an unconditional jump to instruction iDest | 84077 | /* Generate code for an unconditional jump to instruction iDest |
| @@ -81140,11 +84226,12 @@ SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){ | |||
| 81140 | ** If the bPush flag is true, then make this opcode the parent for | 84226 | ** If the bPush flag is true, then make this opcode the parent for |
| 81141 | ** subsequent Explains until sqlite3VdbeExplainPop() is called. | 84227 | ** subsequent Explains until sqlite3VdbeExplainPop() is called. |
| 81142 | */ | 84228 | */ |
| 81143 | SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ | 84229 | SQLITE_PRIVATE int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ |
| 81144 | #ifndef SQLITE_DEBUG | 84230 | int addr = 0; |
| 84231 | #if !defined(SQLITE_DEBUG) | ||
| 81145 | /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. | 84232 | /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. |
| 81146 | ** But omit them (for performance) during production builds */ | 84233 | ** But omit them (for performance) during production builds */ |
| 81147 | if( pParse->explain==2 ) | 84234 | if( pParse->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) |
| 81148 | #endif | 84235 | #endif |
| 81149 | { | 84236 | { |
| 81150 | char *zMsg; | 84237 | char *zMsg; |
| @@ -81156,13 +84243,15 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt | |||
| 81156 | va_end(ap); | 84243 | va_end(ap); |
| 81157 | v = pParse->pVdbe; | 84244 | v = pParse->pVdbe; |
| 81158 | iThis = v->nOp; | 84245 | iThis = v->nOp; |
| 81159 | sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, | 84246 | addr = sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, |
| 81160 | zMsg, P4_DYNAMIC); | 84247 | zMsg, P4_DYNAMIC); |
| 81161 | sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z); | 84248 | sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetLastOp(v)->p4.z); |
| 81162 | if( bPush){ | 84249 | if( bPush){ |
| 81163 | pParse->addrExplain = iThis; | 84250 | pParse->addrExplain = iThis; |
| 81164 | } | 84251 | } |
| 84252 | sqlite3VdbeScanStatus(v, iThis, -1, -1, 0, 0); | ||
| 81165 | } | 84253 | } |
| 84254 | return addr; | ||
| 81166 | } | 84255 | } |
| 81167 | 84256 | ||
| 81168 | /* | 84257 | /* |
| @@ -81190,26 +84279,6 @@ SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, | |||
| 81190 | sqlite3MayAbort(p->pParse); | 84279 | sqlite3MayAbort(p->pParse); |
| 81191 | } | 84280 | } |
| 81192 | 84281 | ||
| 81193 | /* | ||
| 81194 | ** Add an opcode that includes the p4 value as an integer. | ||
| 81195 | */ | ||
| 81196 | SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( | ||
| 81197 | Vdbe *p, /* Add the opcode to this VM */ | ||
| 81198 | int op, /* The new opcode */ | ||
| 81199 | int p1, /* The P1 operand */ | ||
| 81200 | int p2, /* The P2 operand */ | ||
| 81201 | int p3, /* The P3 operand */ | ||
| 81202 | int p4 /* The P4 operand as an integer */ | ||
| 81203 | ){ | ||
| 81204 | int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); | ||
| 81205 | if( p->db->mallocFailed==0 ){ | ||
| 81206 | VdbeOp *pOp = &p->aOp[addr]; | ||
| 81207 | pOp->p4type = P4_INT32; | ||
| 81208 | pOp->p4.i = p4; | ||
| 81209 | } | ||
| 81210 | return addr; | ||
| 81211 | } | ||
| 81212 | |||
| 81213 | /* Insert the end of a co-routine | 84282 | /* Insert the end of a co-routine |
| 81214 | */ | 84283 | */ |
| 81215 | SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ | 84284 | SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ |
| @@ -81270,6 +84339,9 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ | |||
| 81270 | int i; | 84339 | int i; |
| 81271 | for(i=p->nLabelAlloc; i<nNewSize; i++) p->aLabel[i] = -1; | 84340 | for(i=p->nLabelAlloc; i<nNewSize; i++) p->aLabel[i] = -1; |
| 81272 | #endif | 84341 | #endif |
| 84342 | if( nNewSize>=100 && (nNewSize/100)>(p->nLabelAlloc/100) ){ | ||
| 84343 | sqlite3ProgressCheck(p); | ||
| 84344 | } | ||
| 81273 | p->nLabelAlloc = nNewSize; | 84345 | p->nLabelAlloc = nNewSize; |
| 81274 | p->aLabel[j] = v->nOp; | 84346 | p->aLabel[j] = v->nOp; |
| 81275 | } | 84347 | } |
| @@ -81513,11 +84585,13 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ | |||
| 81513 | Op *pOp; | 84585 | Op *pOp; |
| 81514 | Parse *pParse = p->pParse; | 84586 | Parse *pParse = p->pParse; |
| 81515 | int *aLabel = pParse->aLabel; | 84587 | int *aLabel = pParse->aLabel; |
| 84588 | |||
| 84589 | assert( pParse->db->mallocFailed==0 ); /* tag-20230419-1 */ | ||
| 81516 | p->readOnly = 1; | 84590 | p->readOnly = 1; |
| 81517 | p->bIsReader = 0; | 84591 | p->bIsReader = 0; |
| 81518 | pOp = &p->aOp[p->nOp-1]; | 84592 | pOp = &p->aOp[p->nOp-1]; |
| 81519 | while(1){ | 84593 | assert( p->aOp[0].opcode==OP_Init ); |
| 81520 | 84594 | while( 1 /* Loop terminates when it reaches the OP_Init opcode */ ){ | |
| 81521 | /* Only JUMP opcodes and the short list of special opcodes in the switch | 84595 | /* Only JUMP opcodes and the short list of special opcodes in the switch |
| 81522 | ** below need to be considered. The mkopcodeh.tcl generator script groups | 84596 | ** below need to be considered. The mkopcodeh.tcl generator script groups |
| 81523 | ** all these opcodes together near the front of the opcode list. Skip | 84597 | ** all these opcodes together near the front of the opcode list. Skip |
| @@ -81546,6 +84620,10 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ | |||
| 81546 | p->bIsReader = 1; | 84620 | p->bIsReader = 1; |
| 81547 | break; | 84621 | break; |
| 81548 | } | 84622 | } |
| 84623 | case OP_Init: { | ||
| 84624 | assert( pOp->p2>=0 ); | ||
| 84625 | goto resolve_p2_values_loop_exit; | ||
| 84626 | } | ||
| 81549 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 84627 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 81550 | case OP_VUpdate: { | 84628 | case OP_VUpdate: { |
| 81551 | if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; | 84629 | if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; |
| @@ -81568,6 +84646,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ | |||
| 81568 | ** have non-negative values for P2. */ | 84646 | ** have non-negative values for P2. */ |
| 81569 | assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); | 84647 | assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); |
| 81570 | assert( ADDR(pOp->p2)<-pParse->nLabel ); | 84648 | assert( ADDR(pOp->p2)<-pParse->nLabel ); |
| 84649 | assert( aLabel!=0 ); /* True because of tag-20230419-1 */ | ||
| 81571 | pOp->p2 = aLabel[ADDR(pOp->p2)]; | 84650 | pOp->p2 = aLabel[ADDR(pOp->p2)]; |
| 81572 | } | 84651 | } |
| 81573 | break; | 84652 | break; |
| @@ -81578,11 +84657,12 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ | |||
| 81578 | ** have non-negative values for P2. */ | 84657 | ** have non-negative values for P2. */ |
| 81579 | assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); | 84658 | assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); |
| 81580 | } | 84659 | } |
| 81581 | if( pOp==p->aOp ) break; | 84660 | assert( pOp>p->aOp ); |
| 81582 | pOp--; | 84661 | pOp--; |
| 81583 | } | 84662 | } |
| 84663 | resolve_p2_values_loop_exit: | ||
| 81584 | if( aLabel ){ | 84664 | if( aLabel ){ |
| 81585 | sqlite3DbFreeNN(p->db, pParse->aLabel); | 84665 | sqlite3DbNNFreeNN(p->db, pParse->aLabel); |
| 81586 | pParse->aLabel = 0; | 84666 | pParse->aLabel = 0; |
| 81587 | } | 84667 | } |
| 81588 | pParse->nLabel = 0; | 84668 | pParse->nLabel = 0; |
| @@ -81810,20 +84890,83 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus( | |||
| 81810 | LogEst nEst, /* Estimated number of output rows */ | 84890 | LogEst nEst, /* Estimated number of output rows */ |
| 81811 | const char *zName /* Name of table or index being scanned */ | 84891 | const char *zName /* Name of table or index being scanned */ |
| 81812 | ){ | 84892 | ){ |
| 81813 | sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); | 84893 | if( IS_STMT_SCANSTATUS(p->db) ){ |
| 81814 | ScanStatus *aNew; | 84894 | sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); |
| 81815 | aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); | 84895 | ScanStatus *aNew; |
| 81816 | if( aNew ){ | 84896 | aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); |
| 81817 | ScanStatus *pNew = &aNew[p->nScan++]; | 84897 | if( aNew ){ |
| 81818 | pNew->addrExplain = addrExplain; | 84898 | ScanStatus *pNew = &aNew[p->nScan++]; |
| 81819 | pNew->addrLoop = addrLoop; | 84899 | memset(pNew, 0, sizeof(ScanStatus)); |
| 81820 | pNew->addrVisit = addrVisit; | 84900 | pNew->addrExplain = addrExplain; |
| 81821 | pNew->nEst = nEst; | 84901 | pNew->addrLoop = addrLoop; |
| 81822 | pNew->zName = sqlite3DbStrDup(p->db, zName); | 84902 | pNew->addrVisit = addrVisit; |
| 81823 | p->aScan = aNew; | 84903 | pNew->nEst = nEst; |
| 84904 | pNew->zName = sqlite3DbStrDup(p->db, zName); | ||
| 84905 | p->aScan = aNew; | ||
| 84906 | } | ||
| 81824 | } | 84907 | } |
| 81825 | } | 84908 | } |
| 81826 | #endif | 84909 | |
| 84910 | /* | ||
| 84911 | ** Add the range of instructions from addrStart to addrEnd (inclusive) to | ||
| 84912 | ** the set of those corresponding to the sqlite3_stmt_scanstatus() counters | ||
| 84913 | ** associated with the OP_Explain instruction at addrExplain. The | ||
| 84914 | ** sum of the sqlite3Hwtime() values for each of these instructions | ||
| 84915 | ** will be returned for SQLITE_SCANSTAT_NCYCLE requests. | ||
| 84916 | */ | ||
| 84917 | SQLITE_PRIVATE void sqlite3VdbeScanStatusRange( | ||
| 84918 | Vdbe *p, | ||
| 84919 | int addrExplain, | ||
| 84920 | int addrStart, | ||
| 84921 | int addrEnd | ||
| 84922 | ){ | ||
| 84923 | if( IS_STMT_SCANSTATUS(p->db) ){ | ||
| 84924 | ScanStatus *pScan = 0; | ||
| 84925 | int ii; | ||
| 84926 | for(ii=p->nScan-1; ii>=0; ii--){ | ||
| 84927 | pScan = &p->aScan[ii]; | ||
| 84928 | if( pScan->addrExplain==addrExplain ) break; | ||
| 84929 | pScan = 0; | ||
| 84930 | } | ||
| 84931 | if( pScan ){ | ||
| 84932 | if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1; | ||
| 84933 | for(ii=0; ii<ArraySize(pScan->aAddrRange); ii+=2){ | ||
| 84934 | if( pScan->aAddrRange[ii]==0 ){ | ||
| 84935 | pScan->aAddrRange[ii] = addrStart; | ||
| 84936 | pScan->aAddrRange[ii+1] = addrEnd; | ||
| 84937 | break; | ||
| 84938 | } | ||
| 84939 | } | ||
| 84940 | } | ||
| 84941 | } | ||
| 84942 | } | ||
| 84943 | |||
| 84944 | /* | ||
| 84945 | ** Set the addresses for the SQLITE_SCANSTAT_NLOOP and SQLITE_SCANSTAT_NROW | ||
| 84946 | ** counters for the query element associated with the OP_Explain at | ||
| 84947 | ** addrExplain. | ||
| 84948 | */ | ||
| 84949 | SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters( | ||
| 84950 | Vdbe *p, | ||
| 84951 | int addrExplain, | ||
| 84952 | int addrLoop, | ||
| 84953 | int addrVisit | ||
| 84954 | ){ | ||
| 84955 | if( IS_STMT_SCANSTATUS(p->db) ){ | ||
| 84956 | ScanStatus *pScan = 0; | ||
| 84957 | int ii; | ||
| 84958 | for(ii=p->nScan-1; ii>=0; ii--){ | ||
| 84959 | pScan = &p->aScan[ii]; | ||
| 84960 | if( pScan->addrExplain==addrExplain ) break; | ||
| 84961 | pScan = 0; | ||
| 84962 | } | ||
| 84963 | if( pScan ){ | ||
| 84964 | if( addrLoop>0 ) pScan->addrLoop = addrLoop; | ||
| 84965 | if( addrVisit>0 ) pScan->addrVisit = addrVisit; | ||
| 84966 | } | ||
| 84967 | } | ||
| 84968 | } | ||
| 84969 | #endif /* defined(SQLITE_ENABLE_STMT_SCANSTATUS) */ | ||
| 81827 | 84970 | ||
| 81828 | 84971 | ||
| 81829 | /* | 84972 | /* |
| @@ -81831,15 +84974,19 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus( | |||
| 81831 | ** for a specific instruction. | 84974 | ** for a specific instruction. |
| 81832 | */ | 84975 | */ |
| 81833 | SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ | 84976 | SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ |
| 84977 | assert( addr>=0 ); | ||
| 81834 | sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; | 84978 | sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; |
| 81835 | } | 84979 | } |
| 81836 | SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ | 84980 | SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ |
| 84981 | assert( addr>=0 ); | ||
| 81837 | sqlite3VdbeGetOp(p,addr)->p1 = val; | 84982 | sqlite3VdbeGetOp(p,addr)->p1 = val; |
| 81838 | } | 84983 | } |
| 81839 | SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ | 84984 | SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ |
| 84985 | assert( addr>=0 || p->db->mallocFailed ); | ||
| 81840 | sqlite3VdbeGetOp(p,addr)->p2 = val; | 84986 | sqlite3VdbeGetOp(p,addr)->p2 = val; |
| 81841 | } | 84987 | } |
| 81842 | SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ | 84988 | SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ |
| 84989 | assert( addr>=0 ); | ||
| 81843 | sqlite3VdbeGetOp(p,addr)->p3 = val; | 84990 | sqlite3VdbeGetOp(p,addr)->p3 = val; |
| 81844 | } | 84991 | } |
| 81845 | SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ | 84992 | SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ |
| @@ -81848,6 +84995,18 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ | |||
| 81848 | } | 84995 | } |
| 81849 | 84996 | ||
| 81850 | /* | 84997 | /* |
| 84998 | ** If the previous opcode is an OP_Column that delivers results | ||
| 84999 | ** into register iDest, then add the OPFLAG_TYPEOFARG flag to that | ||
| 85000 | ** opcode. | ||
| 85001 | */ | ||
| 85002 | SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ | ||
| 85003 | VdbeOp *pOp = sqlite3VdbeGetLastOp(p); | ||
| 85004 | if( pOp->p3==iDest && pOp->opcode==OP_Column ){ | ||
| 85005 | pOp->p5 |= OPFLAG_TYPEOFARG; | ||
| 85006 | } | ||
| 85007 | } | ||
| 85008 | |||
| 85009 | /* | ||
| 81851 | ** Change the P2 operand of instruction addr so that it points to | 85010 | ** Change the P2 operand of instruction addr so that it points to |
| 81852 | ** the address of the next instruction to be coded. | 85011 | ** the address of the next instruction to be coded. |
| 81853 | */ | 85012 | */ |
| @@ -81875,7 +85034,7 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){ | |||
| 81875 | || p->aOp[addr].opcode==OP_FkIfZero ); | 85034 | || p->aOp[addr].opcode==OP_FkIfZero ); |
| 81876 | assert( p->aOp[addr].p4type==0 ); | 85035 | assert( p->aOp[addr].p4type==0 ); |
| 81877 | #ifdef SQLITE_VDBE_COVERAGE | 85036 | #ifdef SQLITE_VDBE_COVERAGE |
| 81878 | sqlite3VdbeGetOp(p,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ | 85037 | sqlite3VdbeGetLastOp(p)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ |
| 81879 | #endif | 85038 | #endif |
| 81880 | p->nOp--; | 85039 | p->nOp--; |
| 81881 | }else{ | 85040 | }else{ |
| @@ -81886,11 +85045,12 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){ | |||
| 81886 | 85045 | ||
| 81887 | /* | 85046 | /* |
| 81888 | ** If the input FuncDef structure is ephemeral, then free it. If | 85047 | ** If the input FuncDef structure is ephemeral, then free it. If |
| 81889 | ** the FuncDef is not ephermal, then do nothing. | 85048 | ** the FuncDef is not ephemeral, then do nothing. |
| 81890 | */ | 85049 | */ |
| 81891 | static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ | 85050 | static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ |
| 85051 | assert( db!=0 ); | ||
| 81892 | if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ | 85052 | if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ |
| 81893 | sqlite3DbFreeNN(db, pDef); | 85053 | sqlite3DbNNFreeNN(db, pDef); |
| 81894 | } | 85054 | } |
| 81895 | } | 85055 | } |
| 81896 | 85056 | ||
| @@ -81899,11 +85059,12 @@ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ | |||
| 81899 | */ | 85059 | */ |
| 81900 | static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ | 85060 | static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ |
| 81901 | if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); | 85061 | if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); |
| 81902 | sqlite3DbFreeNN(db, p); | 85062 | sqlite3DbNNFreeNN(db, p); |
| 81903 | } | 85063 | } |
| 81904 | static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ | 85064 | static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ |
| 85065 | assert( db!=0 ); | ||
| 81905 | freeEphemeralFunction(db, p->pFunc); | 85066 | freeEphemeralFunction(db, p->pFunc); |
| 81906 | sqlite3DbFreeNN(db, p); | 85067 | sqlite3DbNNFreeNN(db, p); |
| 81907 | } | 85068 | } |
| 81908 | static void freeP4(sqlite3 *db, int p4type, void *p4){ | 85069 | static void freeP4(sqlite3 *db, int p4type, void *p4){ |
| 81909 | assert( db ); | 85070 | assert( db ); |
| @@ -81916,7 +85077,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ | |||
| 81916 | case P4_INT64: | 85077 | case P4_INT64: |
| 81917 | case P4_DYNAMIC: | 85078 | case P4_DYNAMIC: |
| 81918 | case P4_INTARRAY: { | 85079 | case P4_INTARRAY: { |
| 81919 | sqlite3DbFree(db, p4); | 85080 | if( p4 ) sqlite3DbNNFreeNN(db, p4); |
| 81920 | break; | 85081 | break; |
| 81921 | } | 85082 | } |
| 81922 | case P4_KEYINFO: { | 85083 | case P4_KEYINFO: { |
| @@ -81955,6 +85116,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ | |||
| 81955 | */ | 85116 | */ |
| 81956 | static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ | 85117 | static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ |
| 81957 | assert( nOp>=0 ); | 85118 | assert( nOp>=0 ); |
| 85119 | assert( db!=0 ); | ||
| 81958 | if( aOp ){ | 85120 | if( aOp ){ |
| 81959 | Op *pOp = &aOp[nOp-1]; | 85121 | Op *pOp = &aOp[nOp-1]; |
| 81960 | while(1){ /* Exit via break */ | 85122 | while(1){ /* Exit via break */ |
| @@ -81965,7 +85127,7 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ | |||
| 81965 | if( pOp==aOp ) break; | 85127 | if( pOp==aOp ) break; |
| 81966 | pOp--; | 85128 | pOp--; |
| 81967 | } | 85129 | } |
| 81968 | sqlite3DbFreeNN(db, aOp); | 85130 | sqlite3DbNNFreeNN(db, aOp); |
| 81969 | } | 85131 | } |
| 81970 | } | 85132 | } |
| 81971 | 85133 | ||
| @@ -82047,7 +85209,6 @@ SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters( | |||
| 82047 | } | 85209 | } |
| 82048 | #endif /* SQLITE_DEBUG */ | 85210 | #endif /* SQLITE_DEBUG */ |
| 82049 | 85211 | ||
| 82050 | |||
| 82051 | /* | 85212 | /* |
| 82052 | ** Change the value of the P4 operand for a specific instruction. | 85213 | ** Change the value of the P4 operand for a specific instruction. |
| 82053 | ** This routine is useful when a large program is loaded from a | 85214 | ** This routine is useful when a large program is loaded from a |
| @@ -82134,7 +85295,7 @@ SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){ | |||
| 82134 | if( p->db->mallocFailed ){ | 85295 | if( p->db->mallocFailed ){ |
| 82135 | freeP4(p->db, n, pP4); | 85296 | freeP4(p->db, n, pP4); |
| 82136 | }else{ | 85297 | }else{ |
| 82137 | assert( pP4!=0 ); | 85298 | assert( pP4!=0 || n==P4_DYNAMIC ); |
| 82138 | assert( p->nOp>0 ); | 85299 | assert( p->nOp>0 ); |
| 82139 | pOp = &p->aOp[p->nOp-1]; | 85300 | pOp = &p->aOp[p->nOp-1]; |
| 82140 | assert( pOp->p4type==P4_NOTUSED ); | 85301 | assert( pOp->p4type==P4_NOTUSED ); |
| @@ -82196,13 +85357,13 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ | |||
| 82196 | ** Set the value if the iSrcLine field for the previously coded instruction. | 85357 | ** Set the value if the iSrcLine field for the previously coded instruction. |
| 82197 | */ | 85358 | */ |
| 82198 | SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ | 85359 | SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ |
| 82199 | sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine; | 85360 | sqlite3VdbeGetLastOp(v)->iSrcLine = iLine; |
| 82200 | } | 85361 | } |
| 82201 | #endif /* SQLITE_VDBE_COVERAGE */ | 85362 | #endif /* SQLITE_VDBE_COVERAGE */ |
| 82202 | 85363 | ||
| 82203 | /* | 85364 | /* |
| 82204 | ** Return the opcode for a given address. If the address is -1, then | 85365 | ** Return the opcode for a given address. The address must be non-negative. |
| 82205 | ** return the most recently inserted opcode. | 85366 | ** See sqlite3VdbeGetLastOp() to get the most recently added opcode. |
| 82206 | ** | 85367 | ** |
| 82207 | ** If a memory allocation error has occurred prior to the calling of this | 85368 | ** If a memory allocation error has occurred prior to the calling of this |
| 82208 | ** routine, then a pointer to a dummy VdbeOp will be returned. That opcode | 85369 | ** routine, then a pointer to a dummy VdbeOp will be returned. That opcode |
| @@ -82218,9 +85379,6 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ | |||
| 82218 | ** zeros, which is correct. MSVC generates a warning, nevertheless. */ | 85379 | ** zeros, which is correct. MSVC generates a warning, nevertheless. */ |
| 82219 | static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ | 85380 | static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ |
| 82220 | assert( p->eVdbeState==VDBE_INIT_STATE ); | 85381 | assert( p->eVdbeState==VDBE_INIT_STATE ); |
| 82221 | if( addr<0 ){ | ||
| 82222 | addr = p->nOp - 1; | ||
| 82223 | } | ||
| 82224 | assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed ); | 85382 | assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed ); |
| 82225 | if( p->db->mallocFailed ){ | 85383 | if( p->db->mallocFailed ){ |
| 82226 | return (VdbeOp*)&dummy; | 85384 | return (VdbeOp*)&dummy; |
| @@ -82229,6 +85387,12 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ | |||
| 82229 | } | 85387 | } |
| 82230 | } | 85388 | } |
| 82231 | 85389 | ||
| 85390 | /* Return the most recently added opcode | ||
| 85391 | */ | ||
| 85392 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe *p){ | ||
| 85393 | return sqlite3VdbeGetOp(p, p->nOp - 1); | ||
| 85394 | } | ||
| 85395 | |||
| 82232 | #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) | 85396 | #if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) |
| 82233 | /* | 85397 | /* |
| 82234 | ** Return an integer value for one of the parameters to the opcode pOp | 85398 | ** Return an integer value for one of the parameters to the opcode pOp |
| @@ -82716,7 +85880,7 @@ static void releaseMemArray(Mem *p, int N){ | |||
| 82716 | sqlite3VdbeMemRelease(p); | 85880 | sqlite3VdbeMemRelease(p); |
| 82717 | p->flags = MEM_Undefined; | 85881 | p->flags = MEM_Undefined; |
| 82718 | }else if( p->szMalloc ){ | 85882 | }else if( p->szMalloc ){ |
| 82719 | sqlite3DbFreeNN(db, p->zMalloc); | 85883 | sqlite3DbNNFreeNN(db, p->zMalloc); |
| 82720 | p->szMalloc = 0; | 85884 | p->szMalloc = 0; |
| 82721 | p->flags = MEM_Undefined; | 85885 | p->flags = MEM_Undefined; |
| 82722 | } | 85886 | } |
| @@ -82930,7 +86094,6 @@ SQLITE_PRIVATE int sqlite3VdbeList( | |||
| 82930 | ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. | 86094 | ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. |
| 82931 | */ | 86095 | */ |
| 82932 | releaseMemArray(pMem, 8); | 86096 | releaseMemArray(pMem, 8); |
| 82933 | p->pResultSet = 0; | ||
| 82934 | 86097 | ||
| 82935 | if( p->rc==SQLITE_NOMEM ){ | 86098 | if( p->rc==SQLITE_NOMEM ){ |
| 82936 | /* This happens if a malloc() inside a call to sqlite3_column_text() or | 86099 | /* This happens if a malloc() inside a call to sqlite3_column_text() or |
| @@ -82966,7 +86129,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( | |||
| 82966 | sqlite3VdbeMemSetInt64(pMem+1, pOp->p2); | 86129 | sqlite3VdbeMemSetInt64(pMem+1, pOp->p2); |
| 82967 | sqlite3VdbeMemSetInt64(pMem+2, pOp->p3); | 86130 | sqlite3VdbeMemSetInt64(pMem+2, pOp->p3); |
| 82968 | sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free); | 86131 | sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free); |
| 82969 | p->nResColumn = 4; | 86132 | assert( p->nResColumn==4 ); |
| 82970 | }else{ | 86133 | }else{ |
| 82971 | sqlite3VdbeMemSetInt64(pMem+0, i); | 86134 | sqlite3VdbeMemSetInt64(pMem+0, i); |
| 82972 | sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode), | 86135 | sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode), |
| @@ -82985,9 +86148,9 @@ SQLITE_PRIVATE int sqlite3VdbeList( | |||
| 82985 | sqlite3VdbeMemSetNull(pMem+7); | 86148 | sqlite3VdbeMemSetNull(pMem+7); |
| 82986 | #endif | 86149 | #endif |
| 82987 | sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); | 86150 | sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); |
| 82988 | p->nResColumn = 8; | 86151 | assert( p->nResColumn==8 ); |
| 82989 | } | 86152 | } |
| 82990 | p->pResultSet = pMem; | 86153 | p->pResultRow = pMem; |
| 82991 | if( db->mallocFailed ){ | 86154 | if( db->mallocFailed ){ |
| 82992 | p->rc = SQLITE_NOMEM; | 86155 | p->rc = SQLITE_NOMEM; |
| 82993 | rc = SQLITE_ERROR; | 86156 | rc = SQLITE_ERROR; |
| @@ -83098,7 +86261,7 @@ static void *allocSpace( | |||
| 83098 | ** running it. | 86261 | ** running it. |
| 83099 | */ | 86262 | */ |
| 83100 | SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ | 86263 | SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ |
| 83101 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) | 86264 | #if defined(SQLITE_DEBUG) |
| 83102 | int i; | 86265 | int i; |
| 83103 | #endif | 86266 | #endif |
| 83104 | assert( p!=0 ); | 86267 | assert( p!=0 ); |
| @@ -83127,8 +86290,8 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ | |||
| 83127 | p->nFkConstraint = 0; | 86290 | p->nFkConstraint = 0; |
| 83128 | #ifdef VDBE_PROFILE | 86291 | #ifdef VDBE_PROFILE |
| 83129 | for(i=0; i<p->nOp; i++){ | 86292 | for(i=0; i<p->nOp; i++){ |
| 83130 | p->aOp[i].cnt = 0; | 86293 | p->aOp[i].nExec = 0; |
| 83131 | p->aOp[i].cycles = 0; | 86294 | p->aOp[i].nCycle = 0; |
| 83132 | } | 86295 | } |
| 83133 | #endif | 86296 | #endif |
| 83134 | } | 86297 | } |
| @@ -83199,26 +86362,9 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( | |||
| 83199 | resolveP2Values(p, &nArg); | 86362 | resolveP2Values(p, &nArg); |
| 83200 | p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); | 86363 | p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); |
| 83201 | if( pParse->explain ){ | 86364 | if( pParse->explain ){ |
| 83202 | static const char * const azColName[] = { | ||
| 83203 | "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", | ||
| 83204 | "id", "parent", "notused", "detail" | ||
| 83205 | }; | ||
| 83206 | int iFirst, mx, i; | ||
| 83207 | if( nMem<10 ) nMem = 10; | 86365 | if( nMem<10 ) nMem = 10; |
| 83208 | p->explain = pParse->explain; | 86366 | p->explain = pParse->explain; |
| 83209 | if( pParse->explain==2 ){ | 86367 | p->nResColumn = 12 - 4*p->explain; |
| 83210 | sqlite3VdbeSetNumCols(p, 4); | ||
| 83211 | iFirst = 8; | ||
| 83212 | mx = 12; | ||
| 83213 | }else{ | ||
| 83214 | sqlite3VdbeSetNumCols(p, 8); | ||
| 83215 | iFirst = 0; | ||
| 83216 | mx = 8; | ||
| 83217 | } | ||
| 83218 | for(i=iFirst; i<mx; i++){ | ||
| 83219 | sqlite3VdbeSetColName(p, i-iFirst, COLNAME_NAME, | ||
| 83220 | azColName[i], SQLITE_STATIC); | ||
| 83221 | } | ||
| 83222 | } | 86368 | } |
| 83223 | p->expired = 0; | 86369 | p->expired = 0; |
| 83224 | 86370 | ||
| @@ -83237,9 +86383,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( | |||
| 83237 | p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); | 86383 | p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); |
| 83238 | p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); | 86384 | p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); |
| 83239 | p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); | 86385 | p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); |
| 83240 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 83241 | p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64)); | ||
| 83242 | #endif | ||
| 83243 | if( x.nNeeded ){ | 86386 | if( x.nNeeded ){ |
| 83244 | x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); | 86387 | x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); |
| 83245 | x.nFree = x.nNeeded; | 86388 | x.nFree = x.nNeeded; |
| @@ -83248,9 +86391,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( | |||
| 83248 | p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); | 86391 | p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); |
| 83249 | p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); | 86392 | p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); |
| 83250 | p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); | 86393 | p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); |
| 83251 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 83252 | p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); | ||
| 83253 | #endif | ||
| 83254 | } | 86394 | } |
| 83255 | } | 86395 | } |
| 83256 | 86396 | ||
| @@ -83265,9 +86405,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( | |||
| 83265 | p->nMem = nMem; | 86405 | p->nMem = nMem; |
| 83266 | initMemArray(p->aMem, nMem, db, MEM_Undefined); | 86406 | initMemArray(p->aMem, nMem, db, MEM_Undefined); |
| 83267 | memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); | 86407 | memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); |
| 83268 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 83269 | memset(p->anExec, 0, p->nOp*sizeof(i64)); | ||
| 83270 | #endif | ||
| 83271 | } | 86408 | } |
| 83272 | sqlite3VdbeRewind(p); | 86409 | sqlite3VdbeRewind(p); |
| 83273 | } | 86410 | } |
| @@ -83279,7 +86416,23 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( | |||
| 83279 | SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ | 86416 | SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ |
| 83280 | if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx); | 86417 | if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx); |
| 83281 | } | 86418 | } |
| 86419 | static SQLITE_NOINLINE void freeCursorWithCache(Vdbe *p, VdbeCursor *pCx){ | ||
| 86420 | VdbeTxtBlbCache *pCache = pCx->pCache; | ||
| 86421 | assert( pCx->colCache ); | ||
| 86422 | pCx->colCache = 0; | ||
| 86423 | pCx->pCache = 0; | ||
| 86424 | if( pCache->pCValue ){ | ||
| 86425 | sqlite3RCStrUnref(pCache->pCValue); | ||
| 86426 | pCache->pCValue = 0; | ||
| 86427 | } | ||
| 86428 | sqlite3DbFree(p->db, pCache); | ||
| 86429 | sqlite3VdbeFreeCursorNN(p, pCx); | ||
| 86430 | } | ||
| 83282 | SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){ | 86431 | SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){ |
| 86432 | if( pCx->colCache ){ | ||
| 86433 | freeCursorWithCache(p, pCx); | ||
| 86434 | return; | ||
| 86435 | } | ||
| 83283 | switch( pCx->eCurType ){ | 86436 | switch( pCx->eCurType ){ |
| 83284 | case CURTYPE_SORTER: { | 86437 | case CURTYPE_SORTER: { |
| 83285 | sqlite3VdbeSorterClose(p->db, pCx); | 86438 | sqlite3VdbeSorterClose(p->db, pCx); |
| @@ -83325,9 +86478,6 @@ static void closeCursorsInFrame(Vdbe *p){ | |||
| 83325 | SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ | 86478 | SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ |
| 83326 | Vdbe *v = pFrame->v; | 86479 | Vdbe *v = pFrame->v; |
| 83327 | closeCursorsInFrame(v); | 86480 | closeCursorsInFrame(v); |
| 83328 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 83329 | v->anExec = pFrame->anExec; | ||
| 83330 | #endif | ||
| 83331 | v->aOp = pFrame->aOp; | 86481 | v->aOp = pFrame->aOp; |
| 83332 | v->nOp = pFrame->nOp; | 86482 | v->nOp = pFrame->nOp; |
| 83333 | v->aMem = pFrame->aMem; | 86483 | v->aMem = pFrame->aMem; |
| @@ -83383,12 +86533,12 @@ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ | |||
| 83383 | int n; | 86533 | int n; |
| 83384 | sqlite3 *db = p->db; | 86534 | sqlite3 *db = p->db; |
| 83385 | 86535 | ||
| 83386 | if( p->nResColumn ){ | 86536 | if( p->nResAlloc ){ |
| 83387 | releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); | 86537 | releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); |
| 83388 | sqlite3DbFree(db, p->aColName); | 86538 | sqlite3DbFree(db, p->aColName); |
| 83389 | } | 86539 | } |
| 83390 | n = nResColumn*COLNAME_N; | 86540 | n = nResColumn*COLNAME_N; |
| 83391 | p->nResColumn = (u16)nResColumn; | 86541 | p->nResColumn = p->nResAlloc = (u16)nResColumn; |
| 83392 | p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); | 86542 | p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); |
| 83393 | if( p->aColName==0 ) return; | 86543 | if( p->aColName==0 ) return; |
| 83394 | initMemArray(p->aColName, n, db, MEM_Null); | 86544 | initMemArray(p->aColName, n, db, MEM_Null); |
| @@ -83413,14 +86563,14 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName( | |||
| 83413 | ){ | 86563 | ){ |
| 83414 | int rc; | 86564 | int rc; |
| 83415 | Mem *pColName; | 86565 | Mem *pColName; |
| 83416 | assert( idx<p->nResColumn ); | 86566 | assert( idx<p->nResAlloc ); |
| 83417 | assert( var<COLNAME_N ); | 86567 | assert( var<COLNAME_N ); |
| 83418 | if( p->db->mallocFailed ){ | 86568 | if( p->db->mallocFailed ){ |
| 83419 | assert( !zName || xDel!=SQLITE_DYNAMIC ); | 86569 | assert( !zName || xDel!=SQLITE_DYNAMIC ); |
| 83420 | return SQLITE_NOMEM_BKPT; | 86570 | return SQLITE_NOMEM_BKPT; |
| 83421 | } | 86571 | } |
| 83422 | assert( p->aColName!=0 ); | 86572 | assert( p->aColName!=0 ); |
| 83423 | pColName = &(p->aColName[idx+var*p->nResColumn]); | 86573 | pColName = &(p->aColName[idx+var*p->nResAlloc]); |
| 83424 | rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); | 86574 | rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); |
| 83425 | assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); | 86575 | assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); |
| 83426 | return rc; | 86576 | return rc; |
| @@ -83708,7 +86858,7 @@ static void checkActiveVdbeCnt(sqlite3 *db){ | |||
| 83708 | if( p->readOnly==0 ) nWrite++; | 86858 | if( p->readOnly==0 ) nWrite++; |
| 83709 | if( p->bIsReader ) nRead++; | 86859 | if( p->bIsReader ) nRead++; |
| 83710 | } | 86860 | } |
| 83711 | p = p->pNext; | 86861 | p = p->pVNext; |
| 83712 | } | 86862 | } |
| 83713 | assert( cnt==db->nVdbeActive ); | 86863 | assert( cnt==db->nVdbeActive ); |
| 83714 | assert( nWrite==db->nVdbeWrite ); | 86864 | assert( nWrite==db->nVdbeWrite ); |
| @@ -83933,6 +87083,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ | |||
| 83933 | sqlite3VdbeLeave(p); | 87083 | sqlite3VdbeLeave(p); |
| 83934 | return SQLITE_BUSY; | 87084 | return SQLITE_BUSY; |
| 83935 | }else if( rc!=SQLITE_OK ){ | 87085 | }else if( rc!=SQLITE_OK ){ |
| 87086 | sqlite3SystemError(db, rc); | ||
| 83936 | p->rc = rc; | 87087 | p->rc = rc; |
| 83937 | sqlite3RollbackAll(db, SQLITE_OK); | 87088 | sqlite3RollbackAll(db, SQLITE_OK); |
| 83938 | p->nChange = 0; | 87089 | p->nChange = 0; |
| @@ -83942,6 +87093,8 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ | |||
| 83942 | db->flags &= ~(u64)SQLITE_DeferFKs; | 87093 | db->flags &= ~(u64)SQLITE_DeferFKs; |
| 83943 | sqlite3CommitInternalChanges(db); | 87094 | sqlite3CommitInternalChanges(db); |
| 83944 | } | 87095 | } |
| 87096 | }else if( p->rc==SQLITE_SCHEMA && db->nVdbeActive>1 ){ | ||
| 87097 | p->nChange = 0; | ||
| 83945 | }else{ | 87098 | }else{ |
| 83946 | sqlite3RollbackAll(db, SQLITE_OK); | 87099 | sqlite3RollbackAll(db, SQLITE_OK); |
| 83947 | p->nChange = 0; | 87100 | p->nChange = 0; |
| @@ -84131,7 +87284,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ | |||
| 84131 | sqlite3DbFree(db, p->zErrMsg); | 87284 | sqlite3DbFree(db, p->zErrMsg); |
| 84132 | p->zErrMsg = 0; | 87285 | p->zErrMsg = 0; |
| 84133 | } | 87286 | } |
| 84134 | p->pResultSet = 0; | 87287 | p->pResultRow = 0; |
| 84135 | #ifdef SQLITE_DEBUG | 87288 | #ifdef SQLITE_DEBUG |
| 84136 | p->nWrite = 0; | 87289 | p->nWrite = 0; |
| 84137 | #endif | 87290 | #endif |
| @@ -84159,10 +87312,12 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ | |||
| 84159 | } | 87312 | } |
| 84160 | for(i=0; i<p->nOp; i++){ | 87313 | for(i=0; i<p->nOp; i++){ |
| 84161 | char zHdr[100]; | 87314 | char zHdr[100]; |
| 87315 | i64 cnt = p->aOp[i].nExec; | ||
| 87316 | i64 cycles = p->aOp[i].nCycle; | ||
| 84162 | sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", | 87317 | sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", |
| 84163 | p->aOp[i].cnt, | 87318 | cnt, |
| 84164 | p->aOp[i].cycles, | 87319 | cycles, |
| 84165 | p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0 | 87320 | cnt>0 ? cycles/cnt : 0 |
| 84166 | ); | 87321 | ); |
| 84167 | fprintf(out, "%s", zHdr); | 87322 | fprintf(out, "%s", zHdr); |
| 84168 | sqlite3VdbePrintOp(out, i, &p->aOp[i]); | 87323 | sqlite3VdbePrintOp(out, i, &p->aOp[i]); |
| @@ -84237,10 +87392,11 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, | |||
| 84237 | */ | 87392 | */ |
| 84238 | static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ | 87393 | static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ |
| 84239 | SubProgram *pSub, *pNext; | 87394 | SubProgram *pSub, *pNext; |
| 87395 | assert( db!=0 ); | ||
| 84240 | assert( p->db==0 || p->db==db ); | 87396 | assert( p->db==0 || p->db==db ); |
| 84241 | if( p->aColName ){ | 87397 | if( p->aColName ){ |
| 84242 | releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); | 87398 | releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); |
| 84243 | sqlite3DbFreeNN(db, p->aColName); | 87399 | sqlite3DbNNFreeNN(db, p->aColName); |
| 84244 | } | 87400 | } |
| 84245 | for(pSub=p->pProgram; pSub; pSub=pNext){ | 87401 | for(pSub=p->pProgram; pSub; pSub=pNext){ |
| 84246 | pNext = pSub->pNext; | 87402 | pNext = pSub->pNext; |
| @@ -84249,17 +87405,17 @@ static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ | |||
| 84249 | } | 87405 | } |
| 84250 | if( p->eVdbeState!=VDBE_INIT_STATE ){ | 87406 | if( p->eVdbeState!=VDBE_INIT_STATE ){ |
| 84251 | releaseMemArray(p->aVar, p->nVar); | 87407 | releaseMemArray(p->aVar, p->nVar); |
| 84252 | if( p->pVList ) sqlite3DbFreeNN(db, p->pVList); | 87408 | if( p->pVList ) sqlite3DbNNFreeNN(db, p->pVList); |
| 84253 | if( p->pFree ) sqlite3DbFreeNN(db, p->pFree); | 87409 | if( p->pFree ) sqlite3DbNNFreeNN(db, p->pFree); |
| 84254 | } | 87410 | } |
| 84255 | vdbeFreeOpArray(db, p->aOp, p->nOp); | 87411 | vdbeFreeOpArray(db, p->aOp, p->nOp); |
| 84256 | sqlite3DbFree(db, p->zSql); | 87412 | if( p->zSql ) sqlite3DbNNFreeNN(db, p->zSql); |
| 84257 | #ifdef SQLITE_ENABLE_NORMALIZE | 87413 | #ifdef SQLITE_ENABLE_NORMALIZE |
| 84258 | sqlite3DbFree(db, p->zNormSql); | 87414 | sqlite3DbFree(db, p->zNormSql); |
| 84259 | { | 87415 | { |
| 84260 | DblquoteStr *pThis, *pNext; | 87416 | DblquoteStr *pThis, *pNxt; |
| 84261 | for(pThis=p->pDblStr; pThis; pThis=pNext){ | 87417 | for(pThis=p->pDblStr; pThis; pThis=pNxt){ |
| 84262 | pNext = pThis->pNextStr; | 87418 | pNxt = pThis->pNextStr; |
| 84263 | sqlite3DbFree(db, pThis); | 87419 | sqlite3DbFree(db, pThis); |
| 84264 | } | 87420 | } |
| 84265 | } | 87421 | } |
| @@ -84283,20 +87439,17 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ | |||
| 84283 | 87439 | ||
| 84284 | assert( p!=0 ); | 87440 | assert( p!=0 ); |
| 84285 | db = p->db; | 87441 | db = p->db; |
| 87442 | assert( db!=0 ); | ||
| 84286 | assert( sqlite3_mutex_held(db->mutex) ); | 87443 | assert( sqlite3_mutex_held(db->mutex) ); |
| 84287 | sqlite3VdbeClearObject(db, p); | 87444 | sqlite3VdbeClearObject(db, p); |
| 84288 | if( db->pnBytesFreed==0 ){ | 87445 | if( db->pnBytesFreed==0 ){ |
| 84289 | if( p->pPrev ){ | 87446 | assert( p->ppVPrev!=0 ); |
| 84290 | p->pPrev->pNext = p->pNext; | 87447 | *p->ppVPrev = p->pVNext; |
| 84291 | }else{ | 87448 | if( p->pVNext ){ |
| 84292 | assert( db->pVdbe==p ); | 87449 | p->pVNext->ppVPrev = p->ppVPrev; |
| 84293 | db->pVdbe = p->pNext; | ||
| 84294 | } | ||
| 84295 | if( p->pNext ){ | ||
| 84296 | p->pNext->pPrev = p->pPrev; | ||
| 84297 | } | 87450 | } |
| 84298 | } | 87451 | } |
| 84299 | sqlite3DbFreeNN(db, p); | 87452 | sqlite3DbNNFreeNN(db, p); |
| 84300 | } | 87453 | } |
| 84301 | 87454 | ||
| 84302 | /* | 87455 | /* |
| @@ -84842,6 +87995,15 @@ static int vdbeRecordCompareDebug( | |||
| 84842 | if( d1+(u64)serial_type1+2>(u64)nKey1 | 87995 | if( d1+(u64)serial_type1+2>(u64)nKey1 |
| 84843 | && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 | 87996 | && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 |
| 84844 | ){ | 87997 | ){ |
| 87998 | if( serial_type1>=1 | ||
| 87999 | && serial_type1<=7 | ||
| 88000 | && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)<=(u64)nKey1+8 | ||
| 88001 | && CORRUPT_DB | ||
| 88002 | ){ | ||
| 88003 | return 1; /* corrupt record not detected by | ||
| 88004 | ** sqlite3VdbeRecordCompareWithSkip(). Return true | ||
| 88005 | ** to avoid firing the assert() */ | ||
| 88006 | } | ||
| 84845 | break; | 88007 | break; |
| 84846 | } | 88008 | } |
| 84847 | 88009 | ||
| @@ -85251,7 +88413,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( | |||
| 85251 | assert( pPKey2->pKeyInfo->aSortFlags!=0 ); | 88413 | assert( pPKey2->pKeyInfo->aSortFlags!=0 ); |
| 85252 | assert( pPKey2->pKeyInfo->nKeyField>0 ); | 88414 | assert( pPKey2->pKeyInfo->nKeyField>0 ); |
| 85253 | assert( idx1<=szHdr1 || CORRUPT_DB ); | 88415 | assert( idx1<=szHdr1 || CORRUPT_DB ); |
| 85254 | do{ | 88416 | while( 1 /*exit-by-break*/ ){ |
| 85255 | u32 serial_type; | 88417 | u32 serial_type; |
| 85256 | 88418 | ||
| 85257 | /* RHS is an integer */ | 88419 | /* RHS is an integer */ |
| @@ -85261,7 +88423,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( | |||
| 85261 | serial_type = aKey1[idx1]; | 88423 | serial_type = aKey1[idx1]; |
| 85262 | testcase( serial_type==12 ); | 88424 | testcase( serial_type==12 ); |
| 85263 | if( serial_type>=10 ){ | 88425 | if( serial_type>=10 ){ |
| 85264 | rc = +1; | 88426 | rc = serial_type==10 ? -1 : +1; |
| 85265 | }else if( serial_type==0 ){ | 88427 | }else if( serial_type==0 ){ |
| 85266 | rc = -1; | 88428 | rc = -1; |
| 85267 | }else if( serial_type==7 ){ | 88429 | }else if( serial_type==7 ){ |
| @@ -85285,8 +88447,8 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( | |||
| 85285 | /* Serial types 12 or greater are strings and blobs (greater than | 88447 | /* Serial types 12 or greater are strings and blobs (greater than |
| 85286 | ** numbers). Types 10 and 11 are currently "reserved for future | 88448 | ** numbers). Types 10 and 11 are currently "reserved for future |
| 85287 | ** use", so it doesn't really matter what the results of comparing | 88449 | ** use", so it doesn't really matter what the results of comparing |
| 85288 | ** them to numberic values are. */ | 88450 | ** them to numeric values are. */ |
| 85289 | rc = +1; | 88451 | rc = serial_type==10 ? -1 : +1; |
| 85290 | }else if( serial_type==0 ){ | 88452 | }else if( serial_type==0 ){ |
| 85291 | rc = -1; | 88453 | rc = -1; |
| 85292 | }else{ | 88454 | }else{ |
| @@ -85367,7 +88529,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( | |||
| 85367 | /* RHS is null */ | 88529 | /* RHS is null */ |
| 85368 | else{ | 88530 | else{ |
| 85369 | serial_type = aKey1[idx1]; | 88531 | serial_type = aKey1[idx1]; |
| 85370 | rc = (serial_type!=0); | 88532 | rc = (serial_type!=0 && serial_type!=10); |
| 85371 | } | 88533 | } |
| 85372 | 88534 | ||
| 85373 | if( rc!=0 ){ | 88535 | if( rc!=0 ){ |
| @@ -85389,8 +88551,13 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( | |||
| 85389 | if( i==pPKey2->nField ) break; | 88551 | if( i==pPKey2->nField ) break; |
| 85390 | pRhs++; | 88552 | pRhs++; |
| 85391 | d1 += sqlite3VdbeSerialTypeLen(serial_type); | 88553 | d1 += sqlite3VdbeSerialTypeLen(serial_type); |
| 88554 | if( d1>(unsigned)nKey1 ) break; | ||
| 85392 | idx1 += sqlite3VarintLen(serial_type); | 88555 | idx1 += sqlite3VarintLen(serial_type); |
| 85393 | }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 ); | 88556 | if( idx1>=(unsigned)szHdr1 ){ |
| 88557 | pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; | ||
| 88558 | return 0; /* Corrupt index */ | ||
| 88559 | } | ||
| 88560 | } | ||
| 85394 | 88561 | ||
| 85395 | /* No memory allocation is ever used on mem1. Prove this using | 88562 | /* No memory allocation is ever used on mem1. Prove this using |
| 85396 | ** the following assert(). If the assert() fails, it indicates a | 88563 | ** the following assert(). If the assert() fails, it indicates a |
| @@ -85791,7 +88958,7 @@ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){ | |||
| 85791 | */ | 88958 | */ |
| 85792 | SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ | 88959 | SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ |
| 85793 | Vdbe *p; | 88960 | Vdbe *p; |
| 85794 | for(p = db->pVdbe; p; p=p->pNext){ | 88961 | for(p = db->pVdbe; p; p=p->pVNext){ |
| 85795 | p->expired = iCode+1; | 88962 | p->expired = iCode+1; |
| 85796 | } | 88963 | } |
| 85797 | } | 88964 | } |
| @@ -85884,6 +89051,20 @@ SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){ | |||
| 85884 | return 1; | 89051 | return 1; |
| 85885 | } | 89052 | } |
| 85886 | 89053 | ||
| 89054 | #if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) | ||
| 89055 | /* | ||
| 89056 | ** This Walker callback is used to help verify that calls to | ||
| 89057 | ** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have | ||
| 89058 | ** byte-code register values correctly initialized. | ||
| 89059 | */ | ||
| 89060 | SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ | ||
| 89061 | if( pExpr->op==TK_REGISTER ){ | ||
| 89062 | assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 ); | ||
| 89063 | } | ||
| 89064 | return WRC_Continue; | ||
| 89065 | } | ||
| 89066 | #endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */ | ||
| 89067 | |||
| 85887 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 89068 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 85888 | /* | 89069 | /* |
| 85889 | ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored | 89070 | ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored |
| @@ -85912,13 +89093,14 @@ SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ | |||
| 85912 | ** the vdbeUnpackRecord() function found in vdbeapi.c. | 89093 | ** the vdbeUnpackRecord() function found in vdbeapi.c. |
| 85913 | */ | 89094 | */ |
| 85914 | static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ | 89095 | static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ |
| 89096 | assert( db!=0 ); | ||
| 85915 | if( p ){ | 89097 | if( p ){ |
| 85916 | int i; | 89098 | int i; |
| 85917 | for(i=0; i<nField; i++){ | 89099 | for(i=0; i<nField; i++){ |
| 85918 | Mem *pMem = &p->aMem[i]; | 89100 | Mem *pMem = &p->aMem[i]; |
| 85919 | if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem); | 89101 | if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem); |
| 85920 | } | 89102 | } |
| 85921 | sqlite3DbFreeNN(db, p); | 89103 | sqlite3DbNNFreeNN(db, p); |
| 85922 | } | 89104 | } |
| 85923 | } | 89105 | } |
| 85924 | #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ | 89106 | #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ |
| @@ -85945,6 +89127,16 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( | |||
| 85945 | PreUpdate preupdate; | 89127 | PreUpdate preupdate; |
| 85946 | const char *zTbl = pTab->zName; | 89128 | const char *zTbl = pTab->zName; |
| 85947 | static const u8 fakeSortOrder = 0; | 89129 | static const u8 fakeSortOrder = 0; |
| 89130 | #ifdef SQLITE_DEBUG | ||
| 89131 | int nRealCol; | ||
| 89132 | if( pTab->tabFlags & TF_WithoutRowid ){ | ||
| 89133 | nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; | ||
| 89134 | }else if( pTab->tabFlags & TF_HasVirtual ){ | ||
| 89135 | nRealCol = pTab->nNVCol; | ||
| 89136 | }else{ | ||
| 89137 | nRealCol = pTab->nCol; | ||
| 89138 | } | ||
| 89139 | #endif | ||
| 85948 | 89140 | ||
| 85949 | assert( db->pPreUpdate==0 ); | 89141 | assert( db->pPreUpdate==0 ); |
| 85950 | memset(&preupdate, 0, sizeof(PreUpdate)); | 89142 | memset(&preupdate, 0, sizeof(PreUpdate)); |
| @@ -85961,8 +89153,8 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( | |||
| 85961 | 89153 | ||
| 85962 | assert( pCsr!=0 ); | 89154 | assert( pCsr!=0 ); |
| 85963 | assert( pCsr->eCurType==CURTYPE_BTREE ); | 89155 | assert( pCsr->eCurType==CURTYPE_BTREE ); |
| 85964 | assert( pCsr->nField==pTab->nCol | 89156 | assert( pCsr->nField==nRealCol |
| 85965 | || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1) | 89157 | || (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1) |
| 85966 | ); | 89158 | ); |
| 85967 | 89159 | ||
| 85968 | preupdate.v = v; | 89160 | preupdate.v = v; |
| @@ -85989,7 +89181,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( | |||
| 85989 | for(i=0; i<pCsr->nField; i++){ | 89181 | for(i=0; i<pCsr->nField; i++){ |
| 85990 | sqlite3VdbeMemRelease(&preupdate.aNew[i]); | 89182 | sqlite3VdbeMemRelease(&preupdate.aNew[i]); |
| 85991 | } | 89183 | } |
| 85992 | sqlite3DbFreeNN(db, preupdate.aNew); | 89184 | sqlite3DbNNFreeNN(db, preupdate.aNew); |
| 85993 | } | 89185 | } |
| 85994 | } | 89186 | } |
| 85995 | #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ | 89187 | #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ |
| @@ -86013,6 +89205,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( | |||
| 86013 | */ | 89205 | */ |
| 86014 | /* #include "sqliteInt.h" */ | 89206 | /* #include "sqliteInt.h" */ |
| 86015 | /* #include "vdbeInt.h" */ | 89207 | /* #include "vdbeInt.h" */ |
| 89208 | /* #include "opcodes.h" */ | ||
| 86016 | 89209 | ||
| 86017 | #ifndef SQLITE_OMIT_DEPRECATED | 89210 | #ifndef SQLITE_OMIT_DEPRECATED |
| 86018 | /* | 89211 | /* |
| @@ -86106,7 +89299,9 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ | |||
| 86106 | if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; | 89299 | if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; |
| 86107 | sqlite3_mutex_enter(db->mutex); | 89300 | sqlite3_mutex_enter(db->mutex); |
| 86108 | checkProfileCallback(db, v); | 89301 | checkProfileCallback(db, v); |
| 86109 | rc = sqlite3VdbeFinalize(v); | 89302 | assert( v->eVdbeState>=VDBE_READY_STATE ); |
| 89303 | rc = sqlite3VdbeReset(v); | ||
| 89304 | sqlite3VdbeDelete(v); | ||
| 86110 | rc = sqlite3ApiExit(db, rc); | 89305 | rc = sqlite3ApiExit(db, rc); |
| 86111 | sqlite3LeaveMutexAndCloseZombie(db); | 89306 | sqlite3LeaveMutexAndCloseZombie(db); |
| 86112 | } | 89307 | } |
| @@ -86266,7 +89461,7 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ | |||
| 86266 | SQLITE_NULL, /* 0x1f (not possible) */ | 89461 | SQLITE_NULL, /* 0x1f (not possible) */ |
| 86267 | SQLITE_FLOAT, /* 0x20 INTREAL */ | 89462 | SQLITE_FLOAT, /* 0x20 INTREAL */ |
| 86268 | SQLITE_NULL, /* 0x21 (not possible) */ | 89463 | SQLITE_NULL, /* 0x21 (not possible) */ |
| 86269 | SQLITE_TEXT, /* 0x22 INTREAL + TEXT */ | 89464 | SQLITE_FLOAT, /* 0x22 INTREAL + TEXT */ |
| 86270 | SQLITE_NULL, /* 0x23 (not possible) */ | 89465 | SQLITE_NULL, /* 0x23 (not possible) */ |
| 86271 | SQLITE_FLOAT, /* 0x24 (not possible) */ | 89466 | SQLITE_FLOAT, /* 0x24 (not possible) */ |
| 86272 | SQLITE_NULL, /* 0x25 (not possible) */ | 89467 | SQLITE_NULL, /* 0x25 (not possible) */ |
| @@ -86314,6 +89509,9 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ | |||
| 86314 | #endif | 89509 | #endif |
| 86315 | return aType[pVal->flags&MEM_AffMask]; | 89510 | return aType[pVal->flags&MEM_AffMask]; |
| 86316 | } | 89511 | } |
| 89512 | SQLITE_API int sqlite3_value_encoding(sqlite3_value *pVal){ | ||
| 89513 | return pVal->enc; | ||
| 89514 | } | ||
| 86317 | 89515 | ||
| 86318 | /* Return true if a parameter to xUpdate represents an unchanged column */ | 89516 | /* Return true if a parameter to xUpdate represents an unchanged column */ |
| 86319 | SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){ | 89517 | SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){ |
| @@ -86498,11 +89696,15 @@ SQLITE_API void sqlite3_result_text64( | |||
| 86498 | ){ | 89696 | ){ |
| 86499 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); | 89697 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 86500 | assert( xDel!=SQLITE_DYNAMIC ); | 89698 | assert( xDel!=SQLITE_DYNAMIC ); |
| 86501 | if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; | 89699 | if( enc!=SQLITE_UTF8 ){ |
| 89700 | if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; | ||
| 89701 | n &= ~(u64)1; | ||
| 89702 | } | ||
| 86502 | if( n>0x7fffffff ){ | 89703 | if( n>0x7fffffff ){ |
| 86503 | (void)invokeValueDestructor(z, xDel, pCtx); | 89704 | (void)invokeValueDestructor(z, xDel, pCtx); |
| 86504 | }else{ | 89705 | }else{ |
| 86505 | setResultStrOrError(pCtx, z, (int)n, enc, xDel); | 89706 | setResultStrOrError(pCtx, z, (int)n, enc, xDel); |
| 89707 | sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut); | ||
| 86506 | } | 89708 | } |
| 86507 | } | 89709 | } |
| 86508 | #ifndef SQLITE_OMIT_UTF16 | 89710 | #ifndef SQLITE_OMIT_UTF16 |
| @@ -86513,7 +89715,7 @@ SQLITE_API void sqlite3_result_text16( | |||
| 86513 | void (*xDel)(void *) | 89715 | void (*xDel)(void *) |
| 86514 | ){ | 89716 | ){ |
| 86515 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); | 89717 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 86516 | setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); | 89718 | setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16NATIVE, xDel); |
| 86517 | } | 89719 | } |
| 86518 | SQLITE_API void sqlite3_result_text16be( | 89720 | SQLITE_API void sqlite3_result_text16be( |
| 86519 | sqlite3_context *pCtx, | 89721 | sqlite3_context *pCtx, |
| @@ -86522,7 +89724,7 @@ SQLITE_API void sqlite3_result_text16be( | |||
| 86522 | void (*xDel)(void *) | 89724 | void (*xDel)(void *) |
| 86523 | ){ | 89725 | ){ |
| 86524 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); | 89726 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 86525 | setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); | 89727 | setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16BE, xDel); |
| 86526 | } | 89728 | } |
| 86527 | SQLITE_API void sqlite3_result_text16le( | 89729 | SQLITE_API void sqlite3_result_text16le( |
| 86528 | sqlite3_context *pCtx, | 89730 | sqlite3_context *pCtx, |
| @@ -86531,7 +89733,7 @@ SQLITE_API void sqlite3_result_text16le( | |||
| 86531 | void (*xDel)(void *) | 89733 | void (*xDel)(void *) |
| 86532 | ){ | 89734 | ){ |
| 86533 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); | 89735 | assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); |
| 86534 | setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); | 89736 | setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16LE, xDel); |
| 86535 | } | 89737 | } |
| 86536 | #endif /* SQLITE_OMIT_UTF16 */ | 89738 | #endif /* SQLITE_OMIT_UTF16 */ |
| 86537 | SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ | 89739 | SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ |
| @@ -86742,7 +89944,7 @@ static int sqlite3Step(Vdbe *p){ | |||
| 86742 | /* If the statement completed successfully, invoke the profile callback */ | 89944 | /* If the statement completed successfully, invoke the profile callback */ |
| 86743 | checkProfileCallback(db, p); | 89945 | checkProfileCallback(db, p); |
| 86744 | #endif | 89946 | #endif |
| 86745 | 89947 | p->pResultRow = 0; | |
| 86746 | if( rc==SQLITE_DONE && db->autoCommit ){ | 89948 | if( rc==SQLITE_DONE && db->autoCommit ){ |
| 86747 | assert( p->rc==SQLITE_OK ); | 89949 | assert( p->rc==SQLITE_OK ); |
| 86748 | p->rc = doWalCallbacks(db); | 89950 | p->rc = doWalCallbacks(db); |
| @@ -86872,6 +90074,17 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ | |||
| 86872 | } | 90074 | } |
| 86873 | 90075 | ||
| 86874 | /* | 90076 | /* |
| 90077 | ** The destructor function for a ValueList object. This needs to be | ||
| 90078 | ** a separate function, unknowable to the application, to ensure that | ||
| 90079 | ** calls to sqlite3_vtab_in_first()/sqlite3_vtab_in_next() that are not | ||
| 90080 | ** preceded by activation of IN processing via sqlite3_vtab_int() do not | ||
| 90081 | ** try to access a fake ValueList object inserted by a hostile extension. | ||
| 90082 | */ | ||
| 90083 | SQLITE_PRIVATE void sqlite3VdbeValueListFree(void *pToDelete){ | ||
| 90084 | sqlite3_free(pToDelete); | ||
| 90085 | } | ||
| 90086 | |||
| 90087 | /* | ||
| 86875 | ** Implementation of sqlite3_vtab_in_first() (if bNext==0) and | 90088 | ** Implementation of sqlite3_vtab_in_first() (if bNext==0) and |
| 86876 | ** sqlite3_vtab_in_next() (if bNext!=0). | 90089 | ** sqlite3_vtab_in_next() (if bNext!=0). |
| 86877 | */ | 90090 | */ |
| @@ -86885,8 +90098,15 @@ static int valueFromValueList( | |||
| 86885 | 90098 | ||
| 86886 | *ppOut = 0; | 90099 | *ppOut = 0; |
| 86887 | if( pVal==0 ) return SQLITE_MISUSE; | 90100 | if( pVal==0 ) return SQLITE_MISUSE; |
| 86888 | pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList"); | 90101 | if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){ |
| 86889 | if( pRhs==0 ) return SQLITE_MISUSE; | 90102 | return SQLITE_ERROR; |
| 90103 | }else{ | ||
| 90104 | assert( (pVal->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == | ||
| 90105 | (MEM_Null|MEM_Term|MEM_Subtype) ); | ||
| 90106 | assert( pVal->eSubtype=='p' ); | ||
| 90107 | assert( pVal->u.zPType!=0 && strcmp(pVal->u.zPType,"ValueList")==0 ); | ||
| 90108 | pRhs = (ValueList*)pVal->z; | ||
| 90109 | } | ||
| 86890 | if( bNext ){ | 90110 | if( bNext ){ |
| 86891 | rc = sqlite3BtreeNext(pRhs->pCsr, 0); | 90111 | rc = sqlite3BtreeNext(pRhs->pCsr, 0); |
| 86892 | }else{ | 90112 | }else{ |
| @@ -87097,7 +90317,8 @@ SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){ | |||
| 87097 | */ | 90317 | */ |
| 87098 | SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ | 90318 | SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ |
| 87099 | Vdbe *pVm = (Vdbe *)pStmt; | 90319 | Vdbe *pVm = (Vdbe *)pStmt; |
| 87100 | return pVm ? pVm->nResColumn : 0; | 90320 | if( pVm==0 ) return 0; |
| 90321 | return pVm->nResColumn; | ||
| 87101 | } | 90322 | } |
| 87102 | 90323 | ||
| 87103 | /* | 90324 | /* |
| @@ -87106,7 +90327,7 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ | |||
| 87106 | */ | 90327 | */ |
| 87107 | SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ | 90328 | SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ |
| 87108 | Vdbe *pVm = (Vdbe *)pStmt; | 90329 | Vdbe *pVm = (Vdbe *)pStmt; |
| 87109 | if( pVm==0 || pVm->pResultSet==0 ) return 0; | 90330 | if( pVm==0 || pVm->pResultRow==0 ) return 0; |
| 87110 | return pVm->nResColumn; | 90331 | return pVm->nResColumn; |
| 87111 | } | 90332 | } |
| 87112 | 90333 | ||
| @@ -87161,8 +90382,8 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ | |||
| 87161 | if( pVm==0 ) return (Mem*)columnNullValue(); | 90382 | if( pVm==0 ) return (Mem*)columnNullValue(); |
| 87162 | assert( pVm->db ); | 90383 | assert( pVm->db ); |
| 87163 | sqlite3_mutex_enter(pVm->db->mutex); | 90384 | sqlite3_mutex_enter(pVm->db->mutex); |
| 87164 | if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){ | 90385 | if( pVm->pResultRow!=0 && i<pVm->nResColumn && i>=0 ){ |
| 87165 | pOut = &pVm->pResultSet[i]; | 90386 | pOut = &pVm->pResultRow[i]; |
| 87166 | }else{ | 90387 | }else{ |
| 87167 | sqlite3Error(pVm->db, SQLITE_RANGE); | 90388 | sqlite3Error(pVm->db, SQLITE_RANGE); |
| 87168 | pOut = (Mem*)columnNullValue(); | 90389 | pOut = (Mem*)columnNullValue(); |
| @@ -87186,7 +90407,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ | |||
| 87186 | ** sqlite3_column_real() | 90407 | ** sqlite3_column_real() |
| 87187 | ** sqlite3_column_bytes() | 90408 | ** sqlite3_column_bytes() |
| 87188 | ** sqlite3_column_bytes16() | 90409 | ** sqlite3_column_bytes16() |
| 87189 | ** sqiite3_column_blob() | 90410 | ** sqlite3_column_blob() |
| 87190 | */ | 90411 | */ |
| 87191 | static void columnMallocFailure(sqlite3_stmt *pStmt) | 90412 | static void columnMallocFailure(sqlite3_stmt *pStmt) |
| 87192 | { | 90413 | { |
| @@ -87271,6 +90492,32 @@ SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ | |||
| 87271 | } | 90492 | } |
| 87272 | 90493 | ||
| 87273 | /* | 90494 | /* |
| 90495 | ** Column names appropriate for EXPLAIN or EXPLAIN QUERY PLAN. | ||
| 90496 | */ | ||
| 90497 | static const char * const azExplainColNames8[] = { | ||
| 90498 | "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", /* EXPLAIN */ | ||
| 90499 | "id", "parent", "notused", "detail" /* EQP */ | ||
| 90500 | }; | ||
| 90501 | static const u16 azExplainColNames16data[] = { | ||
| 90502 | /* 0 */ 'a', 'd', 'd', 'r', 0, | ||
| 90503 | /* 5 */ 'o', 'p', 'c', 'o', 'd', 'e', 0, | ||
| 90504 | /* 12 */ 'p', '1', 0, | ||
| 90505 | /* 15 */ 'p', '2', 0, | ||
| 90506 | /* 18 */ 'p', '3', 0, | ||
| 90507 | /* 21 */ 'p', '4', 0, | ||
| 90508 | /* 24 */ 'p', '5', 0, | ||
| 90509 | /* 27 */ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0, | ||
| 90510 | /* 35 */ 'i', 'd', 0, | ||
| 90511 | /* 38 */ 'p', 'a', 'r', 'e', 'n', 't', 0, | ||
| 90512 | /* 45 */ 'n', 'o', 't', 'u', 's', 'e', 'd', 0, | ||
| 90513 | /* 53 */ 'd', 'e', 't', 'a', 'i', 'l', 0 | ||
| 90514 | }; | ||
| 90515 | static const u8 iExplainColNames16[] = { | ||
| 90516 | 0, 5, 12, 15, 18, 21, 24, 27, | ||
| 90517 | 35, 38, 45, 53 | ||
| 90518 | }; | ||
| 90519 | |||
| 90520 | /* | ||
| 87274 | ** Convert the N-th element of pStmt->pColName[] into a string using | 90521 | ** Convert the N-th element of pStmt->pColName[] into a string using |
| 87275 | ** xFunc() then return that string. If N is out of range, return 0. | 90522 | ** xFunc() then return that string. If N is out of range, return 0. |
| 87276 | ** | 90523 | ** |
| @@ -87302,15 +90549,29 @@ static const void *columnName( | |||
| 87302 | return 0; | 90549 | return 0; |
| 87303 | } | 90550 | } |
| 87304 | #endif | 90551 | #endif |
| 90552 | if( N<0 ) return 0; | ||
| 87305 | ret = 0; | 90553 | ret = 0; |
| 87306 | p = (Vdbe *)pStmt; | 90554 | p = (Vdbe *)pStmt; |
| 87307 | db = p->db; | 90555 | db = p->db; |
| 87308 | assert( db!=0 ); | 90556 | assert( db!=0 ); |
| 87309 | n = sqlite3_column_count(pStmt); | 90557 | sqlite3_mutex_enter(db->mutex); |
| 87310 | if( N<n && N>=0 ){ | 90558 | |
| 90559 | if( p->explain ){ | ||
| 90560 | if( useType>0 ) goto columnName_end; | ||
| 90561 | n = p->explain==1 ? 8 : 4; | ||
| 90562 | if( N>=n ) goto columnName_end; | ||
| 90563 | if( useUtf16 ){ | ||
| 90564 | int i = iExplainColNames16[N + 8*p->explain - 8]; | ||
| 90565 | ret = (void*)&azExplainColNames16data[i]; | ||
| 90566 | }else{ | ||
| 90567 | ret = (void*)azExplainColNames8[N + 8*p->explain - 8]; | ||
| 90568 | } | ||
| 90569 | goto columnName_end; | ||
| 90570 | } | ||
| 90571 | n = p->nResColumn; | ||
| 90572 | if( N<n ){ | ||
| 90573 | u8 prior_mallocFailed = db->mallocFailed; | ||
| 87311 | N += useType*n; | 90574 | N += useType*n; |
| 87312 | sqlite3_mutex_enter(db->mutex); | ||
| 87313 | assert( db->mallocFailed==0 ); | ||
| 87314 | #ifndef SQLITE_OMIT_UTF16 | 90575 | #ifndef SQLITE_OMIT_UTF16 |
| 87315 | if( useUtf16 ){ | 90576 | if( useUtf16 ){ |
| 87316 | ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]); | 90577 | ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]); |
| @@ -87322,12 +90583,14 @@ static const void *columnName( | |||
| 87322 | /* A malloc may have failed inside of the _text() call. If this | 90583 | /* A malloc may have failed inside of the _text() call. If this |
| 87323 | ** is the case, clear the mallocFailed flag and return NULL. | 90584 | ** is the case, clear the mallocFailed flag and return NULL. |
| 87324 | */ | 90585 | */ |
| 87325 | if( db->mallocFailed ){ | 90586 | assert( db->mallocFailed==0 || db->mallocFailed==1 ); |
| 90587 | if( db->mallocFailed > prior_mallocFailed ){ | ||
| 87326 | sqlite3OomClear(db); | 90588 | sqlite3OomClear(db); |
| 87327 | ret = 0; | 90589 | ret = 0; |
| 87328 | } | 90590 | } |
| 87329 | sqlite3_mutex_leave(db->mutex); | ||
| 87330 | } | 90591 | } |
| 90592 | columnName_end: | ||
| 90593 | sqlite3_mutex_leave(db->mutex); | ||
| 87331 | return ret; | 90594 | return ret; |
| 87332 | } | 90595 | } |
| 87333 | 90596 | ||
| @@ -87420,7 +90683,7 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ | |||
| 87420 | /* | 90683 | /* |
| 87421 | ** Unbind the value bound to variable i in virtual machine p. This is the | 90684 | ** Unbind the value bound to variable i in virtual machine p. This is the |
| 87422 | ** the same as binding a NULL value to the column. If the "i" parameter is | 90685 | ** the same as binding a NULL value to the column. If the "i" parameter is |
| 87423 | ** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. | 90686 | ** out of range, then SQLITE_RANGE is returned. Otherwise SQLITE_OK. |
| 87424 | ** | 90687 | ** |
| 87425 | ** A successful evaluation of this routine acquires the mutex on p. | 90688 | ** A successful evaluation of this routine acquires the mutex on p. |
| 87426 | ** the mutex is released if any kind of error occurs. | 90689 | ** the mutex is released if any kind of error occurs. |
| @@ -87428,7 +90691,7 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ | |||
| 87428 | ** The error code stored in database p->db is overwritten with the return | 90691 | ** The error code stored in database p->db is overwritten with the return |
| 87429 | ** value in any case. | 90692 | ** value in any case. |
| 87430 | */ | 90693 | */ |
| 87431 | static int vdbeUnbind(Vdbe *p, int i){ | 90694 | static int vdbeUnbind(Vdbe *p, unsigned int i){ |
| 87432 | Mem *pVar; | 90695 | Mem *pVar; |
| 87433 | if( vdbeSafetyNotNull(p) ){ | 90696 | if( vdbeSafetyNotNull(p) ){ |
| 87434 | return SQLITE_MISUSE_BKPT; | 90697 | return SQLITE_MISUSE_BKPT; |
| @@ -87441,12 +90704,11 @@ static int vdbeUnbind(Vdbe *p, int i){ | |||
| 87441 | "bind on a busy prepared statement: [%s]", p->zSql); | 90704 | "bind on a busy prepared statement: [%s]", p->zSql); |
| 87442 | return SQLITE_MISUSE_BKPT; | 90705 | return SQLITE_MISUSE_BKPT; |
| 87443 | } | 90706 | } |
| 87444 | if( i<1 || i>p->nVar ){ | 90707 | if( i>=(unsigned int)p->nVar ){ |
| 87445 | sqlite3Error(p->db, SQLITE_RANGE); | 90708 | sqlite3Error(p->db, SQLITE_RANGE); |
| 87446 | sqlite3_mutex_leave(p->db->mutex); | 90709 | sqlite3_mutex_leave(p->db->mutex); |
| 87447 | return SQLITE_RANGE; | 90710 | return SQLITE_RANGE; |
| 87448 | } | 90711 | } |
| 87449 | i--; | ||
| 87450 | pVar = &p->aVar[i]; | 90712 | pVar = &p->aVar[i]; |
| 87451 | sqlite3VdbeMemRelease(pVar); | 90713 | sqlite3VdbeMemRelease(pVar); |
| 87452 | pVar->flags = MEM_Null; | 90714 | pVar->flags = MEM_Null; |
| @@ -87483,7 +90745,7 @@ static int bindText( | |||
| 87483 | Mem *pVar; | 90745 | Mem *pVar; |
| 87484 | int rc; | 90746 | int rc; |
| 87485 | 90747 | ||
| 87486 | rc = vdbeUnbind(p, i); | 90748 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 87487 | if( rc==SQLITE_OK ){ | 90749 | if( rc==SQLITE_OK ){ |
| 87488 | if( zData!=0 ){ | 90750 | if( zData!=0 ){ |
| 87489 | pVar = &p->aVar[i-1]; | 90751 | pVar = &p->aVar[i-1]; |
| @@ -87532,7 +90794,7 @@ SQLITE_API int sqlite3_bind_blob64( | |||
| 87532 | SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ | 90794 | SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ |
| 87533 | int rc; | 90795 | int rc; |
| 87534 | Vdbe *p = (Vdbe *)pStmt; | 90796 | Vdbe *p = (Vdbe *)pStmt; |
| 87535 | rc = vdbeUnbind(p, i); | 90797 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 87536 | if( rc==SQLITE_OK ){ | 90798 | if( rc==SQLITE_OK ){ |
| 87537 | sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); | 90799 | sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); |
| 87538 | sqlite3_mutex_leave(p->db->mutex); | 90800 | sqlite3_mutex_leave(p->db->mutex); |
| @@ -87545,7 +90807,7 @@ SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ | |||
| 87545 | SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ | 90807 | SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ |
| 87546 | int rc; | 90808 | int rc; |
| 87547 | Vdbe *p = (Vdbe *)pStmt; | 90809 | Vdbe *p = (Vdbe *)pStmt; |
| 87548 | rc = vdbeUnbind(p, i); | 90810 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 87549 | if( rc==SQLITE_OK ){ | 90811 | if( rc==SQLITE_OK ){ |
| 87550 | sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); | 90812 | sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); |
| 87551 | sqlite3_mutex_leave(p->db->mutex); | 90813 | sqlite3_mutex_leave(p->db->mutex); |
| @@ -87555,7 +90817,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu | |||
| 87555 | SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ | 90817 | SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ |
| 87556 | int rc; | 90818 | int rc; |
| 87557 | Vdbe *p = (Vdbe*)pStmt; | 90819 | Vdbe *p = (Vdbe*)pStmt; |
| 87558 | rc = vdbeUnbind(p, i); | 90820 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 87559 | if( rc==SQLITE_OK ){ | 90821 | if( rc==SQLITE_OK ){ |
| 87560 | sqlite3_mutex_leave(p->db->mutex); | 90822 | sqlite3_mutex_leave(p->db->mutex); |
| 87561 | } | 90823 | } |
| @@ -87570,7 +90832,7 @@ SQLITE_API int sqlite3_bind_pointer( | |||
| 87570 | ){ | 90832 | ){ |
| 87571 | int rc; | 90833 | int rc; |
| 87572 | Vdbe *p = (Vdbe*)pStmt; | 90834 | Vdbe *p = (Vdbe*)pStmt; |
| 87573 | rc = vdbeUnbind(p, i); | 90835 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 87574 | if( rc==SQLITE_OK ){ | 90836 | if( rc==SQLITE_OK ){ |
| 87575 | sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); | 90837 | sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); |
| 87576 | sqlite3_mutex_leave(p->db->mutex); | 90838 | sqlite3_mutex_leave(p->db->mutex); |
| @@ -87597,7 +90859,10 @@ SQLITE_API int sqlite3_bind_text64( | |||
| 87597 | unsigned char enc | 90859 | unsigned char enc |
| 87598 | ){ | 90860 | ){ |
| 87599 | assert( xDel!=SQLITE_DYNAMIC ); | 90861 | assert( xDel!=SQLITE_DYNAMIC ); |
| 87600 | if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; | 90862 | if( enc!=SQLITE_UTF8 ){ |
| 90863 | if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; | ||
| 90864 | nData &= ~(u16)1; | ||
| 90865 | } | ||
| 87601 | return bindText(pStmt, i, zData, nData, xDel, enc); | 90866 | return bindText(pStmt, i, zData, nData, xDel, enc); |
| 87602 | } | 90867 | } |
| 87603 | #ifndef SQLITE_OMIT_UTF16 | 90868 | #ifndef SQLITE_OMIT_UTF16 |
| @@ -87605,10 +90870,10 @@ SQLITE_API int sqlite3_bind_text16( | |||
| 87605 | sqlite3_stmt *pStmt, | 90870 | sqlite3_stmt *pStmt, |
| 87606 | int i, | 90871 | int i, |
| 87607 | const void *zData, | 90872 | const void *zData, |
| 87608 | int nData, | 90873 | int n, |
| 87609 | void (*xDel)(void*) | 90874 | void (*xDel)(void*) |
| 87610 | ){ | 90875 | ){ |
| 87611 | return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); | 90876 | return bindText(pStmt, i, zData, n & ~(u64)1, xDel, SQLITE_UTF16NATIVE); |
| 87612 | } | 90877 | } |
| 87613 | #endif /* SQLITE_OMIT_UTF16 */ | 90878 | #endif /* SQLITE_OMIT_UTF16 */ |
| 87614 | SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ | 90879 | SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ |
| @@ -87648,7 +90913,7 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu | |||
| 87648 | SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ | 90913 | SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ |
| 87649 | int rc; | 90914 | int rc; |
| 87650 | Vdbe *p = (Vdbe *)pStmt; | 90915 | Vdbe *p = (Vdbe *)pStmt; |
| 87651 | rc = vdbeUnbind(p, i); | 90916 | rc = vdbeUnbind(p, (u32)(i-1)); |
| 87652 | if( rc==SQLITE_OK ){ | 90917 | if( rc==SQLITE_OK ){ |
| 87653 | #ifndef SQLITE_OMIT_INCRBLOB | 90918 | #ifndef SQLITE_OMIT_INCRBLOB |
| 87654 | sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); | 90919 | sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); |
| @@ -87783,6 +91048,39 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ | |||
| 87783 | } | 91048 | } |
| 87784 | 91049 | ||
| 87785 | /* | 91050 | /* |
| 91051 | ** Set the explain mode for a statement. | ||
| 91052 | */ | ||
| 91053 | SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ | ||
| 91054 | Vdbe *v = (Vdbe*)pStmt; | ||
| 91055 | int rc; | ||
| 91056 | sqlite3_mutex_enter(v->db->mutex); | ||
| 91057 | if( ((int)v->explain)==eMode ){ | ||
| 91058 | rc = SQLITE_OK; | ||
| 91059 | }else if( eMode<0 || eMode>2 ){ | ||
| 91060 | rc = SQLITE_ERROR; | ||
| 91061 | }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ | ||
| 91062 | rc = SQLITE_ERROR; | ||
| 91063 | }else if( v->eVdbeState!=VDBE_READY_STATE ){ | ||
| 91064 | rc = SQLITE_BUSY; | ||
| 91065 | }else if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){ | ||
| 91066 | /* No reprepare necessary */ | ||
| 91067 | v->explain = eMode; | ||
| 91068 | rc = SQLITE_OK; | ||
| 91069 | }else{ | ||
| 91070 | v->explain = eMode; | ||
| 91071 | rc = sqlite3Reprepare(v); | ||
| 91072 | v->haveEqpOps = eMode==2; | ||
| 91073 | } | ||
| 91074 | if( v->explain ){ | ||
| 91075 | v->nResColumn = 12 - 4*v->explain; | ||
| 91076 | }else{ | ||
| 91077 | v->nResColumn = v->nResAlloc; | ||
| 91078 | } | ||
| 91079 | sqlite3_mutex_leave(v->db->mutex); | ||
| 91080 | return rc; | ||
| 91081 | } | ||
| 91082 | |||
| 91083 | /* | ||
| 87786 | ** Return true if the prepared statement is in need of being reset. | 91084 | ** Return true if the prepared statement is in need of being reset. |
| 87787 | */ | 91085 | */ |
| 87788 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ | 91086 | SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ |
| @@ -87808,7 +91106,7 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ | |||
| 87808 | if( pStmt==0 ){ | 91106 | if( pStmt==0 ){ |
| 87809 | pNext = (sqlite3_stmt*)pDb->pVdbe; | 91107 | pNext = (sqlite3_stmt*)pDb->pVdbe; |
| 87810 | }else{ | 91108 | }else{ |
| 87811 | pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext; | 91109 | pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pVNext; |
| 87812 | } | 91110 | } |
| 87813 | sqlite3_mutex_leave(pDb->mutex); | 91111 | sqlite3_mutex_leave(pDb->mutex); |
| 87814 | return pNext; | 91112 | return pNext; |
| @@ -87833,8 +91131,11 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ | |||
| 87833 | sqlite3_mutex_enter(db->mutex); | 91131 | sqlite3_mutex_enter(db->mutex); |
| 87834 | v = 0; | 91132 | v = 0; |
| 87835 | db->pnBytesFreed = (int*)&v; | 91133 | db->pnBytesFreed = (int*)&v; |
| 91134 | assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); | ||
| 91135 | db->lookaside.pEnd = db->lookaside.pStart; | ||
| 87836 | sqlite3VdbeDelete(pVdbe); | 91136 | sqlite3VdbeDelete(pVdbe); |
| 87837 | db->pnBytesFreed = 0; | 91137 | db->pnBytesFreed = 0; |
| 91138 | db->lookaside.pEnd = db->lookaside.pTrueEnd; | ||
| 87838 | sqlite3_mutex_leave(db->mutex); | 91139 | sqlite3_mutex_leave(db->mutex); |
| 87839 | }else{ | 91140 | }else{ |
| 87840 | v = pVdbe->aCounter[op]; | 91141 | v = pVdbe->aCounter[op]; |
| @@ -88096,23 +91397,69 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppVa | |||
| 88096 | /* | 91397 | /* |
| 88097 | ** Return status data for a single loop within query pStmt. | 91398 | ** Return status data for a single loop within query pStmt. |
| 88098 | */ | 91399 | */ |
| 88099 | SQLITE_API int sqlite3_stmt_scanstatus( | 91400 | SQLITE_API int sqlite3_stmt_scanstatus_v2( |
| 88100 | sqlite3_stmt *pStmt, /* Prepared statement being queried */ | 91401 | sqlite3_stmt *pStmt, /* Prepared statement being queried */ |
| 88101 | int idx, /* Index of loop to report on */ | 91402 | int iScan, /* Index of loop to report on */ |
| 88102 | int iScanStatusOp, /* Which metric to return */ | 91403 | int iScanStatusOp, /* Which metric to return */ |
| 91404 | int flags, | ||
| 88103 | void *pOut /* OUT: Write the answer here */ | 91405 | void *pOut /* OUT: Write the answer here */ |
| 88104 | ){ | 91406 | ){ |
| 88105 | Vdbe *p = (Vdbe*)pStmt; | 91407 | Vdbe *p = (Vdbe*)pStmt; |
| 88106 | ScanStatus *pScan; | 91408 | VdbeOp *aOp = p->aOp; |
| 88107 | if( idx<0 || idx>=p->nScan ) return 1; | 91409 | int nOp = p->nOp; |
| 88108 | pScan = &p->aScan[idx]; | 91410 | ScanStatus *pScan = 0; |
| 91411 | int idx; | ||
| 91412 | |||
| 91413 | if( p->pFrame ){ | ||
| 91414 | VdbeFrame *pFrame; | ||
| 91415 | for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); | ||
| 91416 | aOp = pFrame->aOp; | ||
| 91417 | nOp = pFrame->nOp; | ||
| 91418 | } | ||
| 91419 | |||
| 91420 | if( iScan<0 ){ | ||
| 91421 | int ii; | ||
| 91422 | if( iScanStatusOp==SQLITE_SCANSTAT_NCYCLE ){ | ||
| 91423 | i64 res = 0; | ||
| 91424 | for(ii=0; ii<nOp; ii++){ | ||
| 91425 | res += aOp[ii].nCycle; | ||
| 91426 | } | ||
| 91427 | *(i64*)pOut = res; | ||
| 91428 | return 0; | ||
| 91429 | } | ||
| 91430 | return 1; | ||
| 91431 | } | ||
| 91432 | if( flags & SQLITE_SCANSTAT_COMPLEX ){ | ||
| 91433 | idx = iScan; | ||
| 91434 | pScan = &p->aScan[idx]; | ||
| 91435 | }else{ | ||
| 91436 | /* If the COMPLEX flag is clear, then this function must ignore any | ||
| 91437 | ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ | ||
| 91438 | for(idx=0; idx<p->nScan; idx++){ | ||
| 91439 | pScan = &p->aScan[idx]; | ||
| 91440 | if( pScan->zName ){ | ||
| 91441 | iScan--; | ||
| 91442 | if( iScan<0 ) break; | ||
| 91443 | } | ||
| 91444 | } | ||
| 91445 | } | ||
| 91446 | if( idx>=p->nScan ) return 1; | ||
| 91447 | |||
| 88109 | switch( iScanStatusOp ){ | 91448 | switch( iScanStatusOp ){ |
| 88110 | case SQLITE_SCANSTAT_NLOOP: { | 91449 | case SQLITE_SCANSTAT_NLOOP: { |
| 88111 | *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop]; | 91450 | if( pScan->addrLoop>0 ){ |
| 91451 | *(sqlite3_int64*)pOut = aOp[pScan->addrLoop].nExec; | ||
| 91452 | }else{ | ||
| 91453 | *(sqlite3_int64*)pOut = -1; | ||
| 91454 | } | ||
| 88112 | break; | 91455 | break; |
| 88113 | } | 91456 | } |
| 88114 | case SQLITE_SCANSTAT_NVISIT: { | 91457 | case SQLITE_SCANSTAT_NVISIT: { |
| 88115 | *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit]; | 91458 | if( pScan->addrVisit>0 ){ |
| 91459 | *(sqlite3_int64*)pOut = aOp[pScan->addrVisit].nExec; | ||
| 91460 | }else{ | ||
| 91461 | *(sqlite3_int64*)pOut = -1; | ||
| 91462 | } | ||
| 88116 | break; | 91463 | break; |
| 88117 | } | 91464 | } |
| 88118 | case SQLITE_SCANSTAT_EST: { | 91465 | case SQLITE_SCANSTAT_EST: { |
| @@ -88131,7 +91478,7 @@ SQLITE_API int sqlite3_stmt_scanstatus( | |||
| 88131 | } | 91478 | } |
| 88132 | case SQLITE_SCANSTAT_EXPLAIN: { | 91479 | case SQLITE_SCANSTAT_EXPLAIN: { |
| 88133 | if( pScan->addrExplain ){ | 91480 | if( pScan->addrExplain ){ |
| 88134 | *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z; | 91481 | *(const char**)pOut = aOp[ pScan->addrExplain ].p4.z; |
| 88135 | }else{ | 91482 | }else{ |
| 88136 | *(const char**)pOut = 0; | 91483 | *(const char**)pOut = 0; |
| 88137 | } | 91484 | } |
| @@ -88139,12 +91486,51 @@ SQLITE_API int sqlite3_stmt_scanstatus( | |||
| 88139 | } | 91486 | } |
| 88140 | case SQLITE_SCANSTAT_SELECTID: { | 91487 | case SQLITE_SCANSTAT_SELECTID: { |
| 88141 | if( pScan->addrExplain ){ | 91488 | if( pScan->addrExplain ){ |
| 88142 | *(int*)pOut = p->aOp[ pScan->addrExplain ].p1; | 91489 | *(int*)pOut = aOp[ pScan->addrExplain ].p1; |
| 88143 | }else{ | 91490 | }else{ |
| 88144 | *(int*)pOut = -1; | 91491 | *(int*)pOut = -1; |
| 88145 | } | 91492 | } |
| 88146 | break; | 91493 | break; |
| 88147 | } | 91494 | } |
| 91495 | case SQLITE_SCANSTAT_PARENTID: { | ||
| 91496 | if( pScan->addrExplain ){ | ||
| 91497 | *(int*)pOut = aOp[ pScan->addrExplain ].p2; | ||
| 91498 | }else{ | ||
| 91499 | *(int*)pOut = -1; | ||
| 91500 | } | ||
| 91501 | break; | ||
| 91502 | } | ||
| 91503 | case SQLITE_SCANSTAT_NCYCLE: { | ||
| 91504 | i64 res = 0; | ||
| 91505 | if( pScan->aAddrRange[0]==0 ){ | ||
| 91506 | res = -1; | ||
| 91507 | }else{ | ||
| 91508 | int ii; | ||
| 91509 | for(ii=0; ii<ArraySize(pScan->aAddrRange); ii+=2){ | ||
| 91510 | int iIns = pScan->aAddrRange[ii]; | ||
| 91511 | int iEnd = pScan->aAddrRange[ii+1]; | ||
| 91512 | if( iIns==0 ) break; | ||
| 91513 | if( iIns>0 ){ | ||
| 91514 | while( iIns<=iEnd ){ | ||
| 91515 | res += aOp[iIns].nCycle; | ||
| 91516 | iIns++; | ||
| 91517 | } | ||
| 91518 | }else{ | ||
| 91519 | int iOp; | ||
| 91520 | for(iOp=0; iOp<nOp; iOp++){ | ||
| 91521 | Op *pOp = &aOp[iOp]; | ||
| 91522 | if( pOp->p1!=iEnd ) continue; | ||
| 91523 | if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_NCYCLE)==0 ){ | ||
| 91524 | continue; | ||
| 91525 | } | ||
| 91526 | res += aOp[iOp].nCycle; | ||
| 91527 | } | ||
| 91528 | } | ||
| 91529 | } | ||
| 91530 | } | ||
| 91531 | *(i64*)pOut = res; | ||
| 91532 | break; | ||
| 91533 | } | ||
| 88148 | default: { | 91534 | default: { |
| 88149 | return 1; | 91535 | return 1; |
| 88150 | } | 91536 | } |
| @@ -88153,11 +91539,28 @@ SQLITE_API int sqlite3_stmt_scanstatus( | |||
| 88153 | } | 91539 | } |
| 88154 | 91540 | ||
| 88155 | /* | 91541 | /* |
| 91542 | ** Return status data for a single loop within query pStmt. | ||
| 91543 | */ | ||
| 91544 | SQLITE_API int sqlite3_stmt_scanstatus( | ||
| 91545 | sqlite3_stmt *pStmt, /* Prepared statement being queried */ | ||
| 91546 | int iScan, /* Index of loop to report on */ | ||
| 91547 | int iScanStatusOp, /* Which metric to return */ | ||
| 91548 | void *pOut /* OUT: Write the answer here */ | ||
| 91549 | ){ | ||
| 91550 | return sqlite3_stmt_scanstatus_v2(pStmt, iScan, iScanStatusOp, 0, pOut); | ||
| 91551 | } | ||
| 91552 | |||
| 91553 | /* | ||
| 88156 | ** Zero all counters associated with the sqlite3_stmt_scanstatus() data. | 91554 | ** Zero all counters associated with the sqlite3_stmt_scanstatus() data. |
| 88157 | */ | 91555 | */ |
| 88158 | SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ | 91556 | SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ |
| 88159 | Vdbe *p = (Vdbe*)pStmt; | 91557 | Vdbe *p = (Vdbe*)pStmt; |
| 88160 | memset(p->anExec, 0, p->nOp * sizeof(i64)); | 91558 | int ii; |
| 91559 | for(ii=0; ii<p->nOp; ii++){ | ||
| 91560 | Op *pOp = &p->aOp[ii]; | ||
| 91561 | pOp->nExec = 0; | ||
| 91562 | pOp->nCycle = 0; | ||
| 91563 | } | ||
| 88161 | } | 91564 | } |
| 88162 | #endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ | 91565 | #endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ |
| 88163 | 91566 | ||
| @@ -88493,6 +91896,9 @@ SQLITE_API int sqlite3_found_count = 0; | |||
| 88493 | */ | 91896 | */ |
| 88494 | static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ | 91897 | static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ |
| 88495 | static int n = 0; | 91898 | static int n = 0; |
| 91899 | (void)pc; | ||
| 91900 | (void)pOp; | ||
| 91901 | (void)v; | ||
| 88496 | n++; | 91902 | n++; |
| 88497 | } | 91903 | } |
| 88498 | #endif | 91904 | #endif |
| @@ -88674,7 +92080,8 @@ static VdbeCursor *allocateCursor( | |||
| 88674 | ** return false. | 92080 | ** return false. |
| 88675 | */ | 92081 | */ |
| 88676 | static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ | 92082 | static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ |
| 88677 | i64 iValue = (double)rValue; | 92083 | i64 iValue; |
| 92084 | iValue = sqlite3RealToI64(rValue); | ||
| 88678 | if( sqlite3RealSameAsInt(rValue,iValue) ){ | 92085 | if( sqlite3RealSameAsInt(rValue,iValue) ){ |
| 88679 | *piValue = iValue; | 92086 | *piValue = iValue; |
| 88680 | return 1; | 92087 | return 1; |
| @@ -88730,6 +92137,10 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ | |||
| 88730 | ** always preferred, even if the affinity is REAL, because | 92137 | ** always preferred, even if the affinity is REAL, because |
| 88731 | ** an integer representation is more space efficient on disk. | 92138 | ** an integer representation is more space efficient on disk. |
| 88732 | ** | 92139 | ** |
| 92140 | ** SQLITE_AFF_FLEXNUM: | ||
| 92141 | ** If the value is text, then try to convert it into a number of | ||
| 92142 | ** some kind (integer or real) but do not make any other changes. | ||
| 92143 | ** | ||
| 88733 | ** SQLITE_AFF_TEXT: | 92144 | ** SQLITE_AFF_TEXT: |
| 88734 | ** Convert pRec to a text representation. | 92145 | ** Convert pRec to a text representation. |
| 88735 | ** | 92146 | ** |
| @@ -88744,11 +92155,11 @@ static void applyAffinity( | |||
| 88744 | ){ | 92155 | ){ |
| 88745 | if( affinity>=SQLITE_AFF_NUMERIC ){ | 92156 | if( affinity>=SQLITE_AFF_NUMERIC ){ |
| 88746 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL | 92157 | assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL |
| 88747 | || affinity==SQLITE_AFF_NUMERIC ); | 92158 | || affinity==SQLITE_AFF_NUMERIC || affinity==SQLITE_AFF_FLEXNUM ); |
| 88748 | if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ | 92159 | if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ |
| 88749 | if( (pRec->flags & MEM_Real)==0 ){ | 92160 | if( (pRec->flags & (MEM_Real|MEM_IntReal))==0 ){ |
| 88750 | if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); | 92161 | if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); |
| 88751 | }else{ | 92162 | }else if( affinity<=SQLITE_AFF_REAL ){ |
| 88752 | sqlite3VdbeIntegerAffinity(pRec); | 92163 | sqlite3VdbeIntegerAffinity(pRec); |
| 88753 | } | 92164 | } |
| 88754 | } | 92165 | } |
| @@ -88836,17 +92247,18 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ | |||
| 88836 | ** But it does set pMem->u.r and pMem->u.i appropriately. | 92247 | ** But it does set pMem->u.r and pMem->u.i appropriately. |
| 88837 | */ | 92248 | */ |
| 88838 | static u16 numericType(Mem *pMem){ | 92249 | static u16 numericType(Mem *pMem){ |
| 88839 | if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){ | 92250 | assert( (pMem->flags & MEM_Null)==0 |
| 92251 | || pMem->db==0 || pMem->db->mallocFailed ); | ||
| 92252 | if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null) ){ | ||
| 88840 | testcase( pMem->flags & MEM_Int ); | 92253 | testcase( pMem->flags & MEM_Int ); |
| 88841 | testcase( pMem->flags & MEM_Real ); | 92254 | testcase( pMem->flags & MEM_Real ); |
| 88842 | testcase( pMem->flags & MEM_IntReal ); | 92255 | testcase( pMem->flags & MEM_IntReal ); |
| 88843 | return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal); | 92256 | return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null); |
| 88844 | } | ||
| 88845 | if( pMem->flags & (MEM_Str|MEM_Blob) ){ | ||
| 88846 | testcase( pMem->flags & MEM_Str ); | ||
| 88847 | testcase( pMem->flags & MEM_Blob ); | ||
| 88848 | return computeNumericType(pMem); | ||
| 88849 | } | 92257 | } |
| 92258 | assert( pMem->flags & (MEM_Str|MEM_Blob) ); | ||
| 92259 | testcase( pMem->flags & MEM_Str ); | ||
| 92260 | testcase( pMem->flags & MEM_Blob ); | ||
| 92261 | return computeNumericType(pMem); | ||
| 88850 | return 0; | 92262 | return 0; |
| 88851 | } | 92263 | } |
| 88852 | 92264 | ||
| @@ -88907,6 +92319,9 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ | |||
| 88907 | sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); | 92319 | sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); |
| 88908 | } | 92320 | } |
| 88909 | sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); | 92321 | sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); |
| 92322 | if( f & MEM_Term ){ | ||
| 92323 | sqlite3_str_appendf(pStr, "(0-term)"); | ||
| 92324 | } | ||
| 88910 | } | 92325 | } |
| 88911 | } | 92326 | } |
| 88912 | #endif | 92327 | #endif |
| @@ -88975,17 +92390,6 @@ SQLITE_PRIVATE void sqlite3VdbeRegisterDump(Vdbe *v){ | |||
| 88975 | # define REGISTER_TRACE(R,M) | 92390 | # define REGISTER_TRACE(R,M) |
| 88976 | #endif | 92391 | #endif |
| 88977 | 92392 | ||
| 88978 | |||
| 88979 | #ifdef VDBE_PROFILE | ||
| 88980 | |||
| 88981 | /* | ||
| 88982 | ** hwtime.h contains inline assembler code for implementing | ||
| 88983 | ** high-performance timing routines. | ||
| 88984 | */ | ||
| 88985 | /* #include "hwtime.h" */ | ||
| 88986 | |||
| 88987 | #endif | ||
| 88988 | |||
| 88989 | #ifndef NDEBUG | 92393 | #ifndef NDEBUG |
| 88990 | /* | 92394 | /* |
| 88991 | ** This function is only called from within an assert() expression. It | 92395 | ** This function is only called from within an assert() expression. It |
| @@ -89045,13 +92449,102 @@ static u64 filterHash(const Mem *aMem, const Op *pOp){ | |||
| 89045 | }else if( p->flags & MEM_Real ){ | 92449 | }else if( p->flags & MEM_Real ){ |
| 89046 | h += sqlite3VdbeIntValue(p); | 92450 | h += sqlite3VdbeIntValue(p); |
| 89047 | }else if( p->flags & (MEM_Str|MEM_Blob) ){ | 92451 | }else if( p->flags & (MEM_Str|MEM_Blob) ){ |
| 89048 | h += p->n; | 92452 | /* All strings have the same hash and all blobs have the same hash, |
| 89049 | if( p->flags & MEM_Zero ) h += p->u.nZero; | 92453 | ** though, at least, those hashes are different from each other and |
| 92454 | ** from NULL. */ | ||
| 92455 | h += 4093 + (p->flags & (MEM_Str|MEM_Blob)); | ||
| 89050 | } | 92456 | } |
| 89051 | } | 92457 | } |
| 89052 | return h; | 92458 | return h; |
| 89053 | } | 92459 | } |
| 89054 | 92460 | ||
| 92461 | |||
| 92462 | /* | ||
| 92463 | ** For OP_Column, factor out the case where content is loaded from | ||
| 92464 | ** overflow pages, so that the code to implement this case is separate | ||
| 92465 | ** the common case where all content fits on the page. Factoring out | ||
| 92466 | ** the code reduces register pressure and helps the common case | ||
| 92467 | ** to run faster. | ||
| 92468 | */ | ||
| 92469 | static SQLITE_NOINLINE int vdbeColumnFromOverflow( | ||
| 92470 | VdbeCursor *pC, /* The BTree cursor from which we are reading */ | ||
| 92471 | int iCol, /* The column to read */ | ||
| 92472 | int t, /* The serial-type code for the column value */ | ||
| 92473 | i64 iOffset, /* Offset to the start of the content value */ | ||
| 92474 | u32 cacheStatus, /* Current Vdbe.cacheCtr value */ | ||
| 92475 | u32 colCacheCtr, /* Current value of the column cache counter */ | ||
| 92476 | Mem *pDest /* Store the value into this register. */ | ||
| 92477 | ){ | ||
| 92478 | int rc; | ||
| 92479 | sqlite3 *db = pDest->db; | ||
| 92480 | int encoding = pDest->enc; | ||
| 92481 | int len = sqlite3VdbeSerialTypeLen(t); | ||
| 92482 | assert( pC->eCurType==CURTYPE_BTREE ); | ||
| 92483 | if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) return SQLITE_TOOBIG; | ||
| 92484 | if( len > 4000 && pC->pKeyInfo==0 ){ | ||
| 92485 | /* Cache large column values that are on overflow pages using | ||
| 92486 | ** an RCStr (reference counted string) so that if they are reloaded, | ||
| 92487 | ** that do not have to be copied a second time. The overhead of | ||
| 92488 | ** creating and managing the cache is such that this is only | ||
| 92489 | ** profitable for larger TEXT and BLOB values. | ||
| 92490 | ** | ||
| 92491 | ** Only do this on table-btrees so that writes to index-btrees do not | ||
| 92492 | ** need to clear the cache. This buys performance in the common case | ||
| 92493 | ** in exchange for generality. | ||
| 92494 | */ | ||
| 92495 | VdbeTxtBlbCache *pCache; | ||
| 92496 | char *pBuf; | ||
| 92497 | if( pC->colCache==0 ){ | ||
| 92498 | pC->pCache = sqlite3DbMallocZero(db, sizeof(VdbeTxtBlbCache) ); | ||
| 92499 | if( pC->pCache==0 ) return SQLITE_NOMEM; | ||
| 92500 | pC->colCache = 1; | ||
| 92501 | } | ||
| 92502 | pCache = pC->pCache; | ||
| 92503 | if( pCache->pCValue==0 | ||
| 92504 | || pCache->iCol!=iCol | ||
| 92505 | || pCache->cacheStatus!=cacheStatus | ||
| 92506 | || pCache->colCacheCtr!=colCacheCtr | ||
| 92507 | || pCache->iOffset!=sqlite3BtreeOffset(pC->uc.pCursor) | ||
| 92508 | ){ | ||
| 92509 | if( pCache->pCValue ) sqlite3RCStrUnref(pCache->pCValue); | ||
| 92510 | pBuf = pCache->pCValue = sqlite3RCStrNew( len+3 ); | ||
| 92511 | if( pBuf==0 ) return SQLITE_NOMEM; | ||
| 92512 | rc = sqlite3BtreePayload(pC->uc.pCursor, iOffset, len, pBuf); | ||
| 92513 | if( rc ) return rc; | ||
| 92514 | pBuf[len] = 0; | ||
| 92515 | pBuf[len+1] = 0; | ||
| 92516 | pBuf[len+2] = 0; | ||
| 92517 | pCache->iCol = iCol; | ||
| 92518 | pCache->cacheStatus = cacheStatus; | ||
| 92519 | pCache->colCacheCtr = colCacheCtr; | ||
| 92520 | pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor); | ||
| 92521 | }else{ | ||
| 92522 | pBuf = pCache->pCValue; | ||
| 92523 | } | ||
| 92524 | assert( t>=12 ); | ||
| 92525 | sqlite3RCStrRef(pBuf); | ||
| 92526 | if( t&1 ){ | ||
| 92527 | rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding, | ||
| 92528 | (void(*)(void*))sqlite3RCStrUnref); | ||
| 92529 | pDest->flags |= MEM_Term; | ||
| 92530 | }else{ | ||
| 92531 | rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, | ||
| 92532 | (void(*)(void*))sqlite3RCStrUnref); | ||
| 92533 | } | ||
| 92534 | }else{ | ||
| 92535 | rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest); | ||
| 92536 | if( rc ) return rc; | ||
| 92537 | sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); | ||
| 92538 | if( (t&1)!=0 && encoding==SQLITE_UTF8 ){ | ||
| 92539 | pDest->z[len] = 0; | ||
| 92540 | pDest->flags |= MEM_Term; | ||
| 92541 | } | ||
| 92542 | } | ||
| 92543 | pDest->flags &= ~MEM_Ephem; | ||
| 92544 | return rc; | ||
| 92545 | } | ||
| 92546 | |||
| 92547 | |||
| 89055 | /* | 92548 | /* |
| 89056 | ** Return the symbolic name for the data type of a pMem | 92549 | ** Return the symbolic name for the data type of a pMem |
| 89057 | */ | 92550 | */ |
| @@ -89075,11 +92568,10 @@ SQLITE_PRIVATE int sqlite3VdbeExec( | |||
| 89075 | ){ | 92568 | ){ |
| 89076 | Op *aOp = p->aOp; /* Copy of p->aOp */ | 92569 | Op *aOp = p->aOp; /* Copy of p->aOp */ |
| 89077 | Op *pOp = aOp; /* Current operation */ | 92570 | Op *pOp = aOp; /* Current operation */ |
| 89078 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) | ||
| 89079 | Op *pOrigOp; /* Value of pOp at the top of the loop */ | ||
| 89080 | #endif | ||
| 89081 | #ifdef SQLITE_DEBUG | 92571 | #ifdef SQLITE_DEBUG |
| 92572 | Op *pOrigOp; /* Value of pOp at the top of the loop */ | ||
| 89082 | int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ | 92573 | int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ |
| 92574 | u8 iCompareIsInit = 0; /* iCompare is initialized */ | ||
| 89083 | #endif | 92575 | #endif |
| 89084 | int rc = SQLITE_OK; /* Value to return */ | 92576 | int rc = SQLITE_OK; /* Value to return */ |
| 89085 | sqlite3 *db = p->db; /* The database */ | 92577 | sqlite3 *db = p->db; /* The database */ |
| @@ -89095,13 +92587,17 @@ SQLITE_PRIVATE int sqlite3VdbeExec( | |||
| 89095 | Mem *pIn2 = 0; /* 2nd input operand */ | 92587 | Mem *pIn2 = 0; /* 2nd input operand */ |
| 89096 | Mem *pIn3 = 0; /* 3rd input operand */ | 92588 | Mem *pIn3 = 0; /* 3rd input operand */ |
| 89097 | Mem *pOut = 0; /* Output operand */ | 92589 | Mem *pOut = 0; /* Output operand */ |
| 89098 | #ifdef VDBE_PROFILE | 92590 | u32 colCacheCtr = 0; /* Column cache counter */ |
| 89099 | u64 start; /* CPU clock count at start of opcode */ | 92591 | #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) |
| 92592 | u64 *pnCycle = 0; | ||
| 92593 | int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0; | ||
| 89100 | #endif | 92594 | #endif |
| 89101 | /*** INSERT STACK UNION HERE ***/ | 92595 | /*** INSERT STACK UNION HERE ***/ |
| 89102 | 92596 | ||
| 89103 | assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ | 92597 | assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ |
| 89104 | sqlite3VdbeEnter(p); | 92598 | if( DbMaskNonZero(p->lockMask) ){ |
| 92599 | sqlite3VdbeEnter(p); | ||
| 92600 | } | ||
| 89105 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | 92601 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 89106 | if( db->xProgress ){ | 92602 | if( db->xProgress ){ |
| 89107 | u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; | 92603 | u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; |
| @@ -89122,7 +92618,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec( | |||
| 89122 | assert( p->bIsReader || p->readOnly!=0 ); | 92618 | assert( p->bIsReader || p->readOnly!=0 ); |
| 89123 | p->iCurrentTime = 0; | 92619 | p->iCurrentTime = 0; |
| 89124 | assert( p->explain==0 ); | 92620 | assert( p->explain==0 ); |
| 89125 | p->pResultSet = 0; | ||
| 89126 | db->busyHandler.nBusy = 0; | 92621 | db->busyHandler.nBusy = 0; |
| 89127 | if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; | 92622 | if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; |
| 89128 | sqlite3VdbeIOTraceSql(p); | 92623 | sqlite3VdbeIOTraceSql(p); |
| @@ -89159,12 +92654,18 @@ SQLITE_PRIVATE int sqlite3VdbeExec( | |||
| 89159 | assert( rc==SQLITE_OK ); | 92654 | assert( rc==SQLITE_OK ); |
| 89160 | 92655 | ||
| 89161 | assert( pOp>=aOp && pOp<&aOp[p->nOp]); | 92656 | assert( pOp>=aOp && pOp<&aOp[p->nOp]); |
| 89162 | #ifdef VDBE_PROFILE | ||
| 89163 | start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); | ||
| 89164 | #endif | ||
| 89165 | nVmStep++; | 92657 | nVmStep++; |
| 89166 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | 92658 | |
| 89167 | if( p->anExec ) p->anExec[(int)(pOp-aOp)]++; | 92659 | #if defined(VDBE_PROFILE) |
| 92660 | pOp->nExec++; | ||
| 92661 | pnCycle = &pOp->nCycle; | ||
| 92662 | if( sqlite3NProfileCnt==0 ) *pnCycle -= sqlite3Hwtime(); | ||
| 92663 | #elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) | ||
| 92664 | if( bStmtScanStatus ){ | ||
| 92665 | pOp->nExec++; | ||
| 92666 | pnCycle = &pOp->nCycle; | ||
| 92667 | *pnCycle -= sqlite3Hwtime(); | ||
| 92668 | } | ||
| 89168 | #endif | 92669 | #endif |
| 89169 | 92670 | ||
| 89170 | /* Only allow tracing if SQLITE_DEBUG is defined. | 92671 | /* Only allow tracing if SQLITE_DEBUG is defined. |
| @@ -89226,7 +92727,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( | |||
| 89226 | } | 92727 | } |
| 89227 | } | 92728 | } |
| 89228 | #endif | 92729 | #endif |
| 89229 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) | 92730 | #ifdef SQLITE_DEBUG |
| 89230 | pOrigOp = pOp; | 92731 | pOrigOp = pOp; |
| 89231 | #endif | 92732 | #endif |
| 89232 | 92733 | ||
| @@ -89282,8 +92783,8 @@ SQLITE_PRIVATE int sqlite3VdbeExec( | |||
| 89282 | case OP_Goto: { /* jump */ | 92783 | case OP_Goto: { /* jump */ |
| 89283 | 92784 | ||
| 89284 | #ifdef SQLITE_DEBUG | 92785 | #ifdef SQLITE_DEBUG |
| 89285 | /* In debuggging mode, when the p5 flags is set on an OP_Goto, that | 92786 | /* In debugging mode, when the p5 flags is set on an OP_Goto, that |
| 89286 | ** means we should really jump back to the preceeding OP_ReleaseReg | 92787 | ** means we should really jump back to the preceding OP_ReleaseReg |
| 89287 | ** instruction. */ | 92788 | ** instruction. */ |
| 89288 | if( pOp->p5 ){ | 92789 | if( pOp->p5 ){ |
| 89289 | assert( pOp->p2 < (int)(pOp - aOp) ); | 92790 | assert( pOp->p2 < (int)(pOp - aOp) ); |
| @@ -89491,7 +92992,7 @@ case OP_HaltIfNull: { /* in3 */ | |||
| 89491 | ** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. | 92992 | ** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. |
| 89492 | ** | 92993 | ** |
| 89493 | ** 0: (no change) | 92994 | ** 0: (no change) |
| 89494 | ** 1: NOT NULL contraint failed: P4 | 92995 | ** 1: NOT NULL constraint failed: P4 |
| 89495 | ** 2: UNIQUE constraint failed: P4 | 92996 | ** 2: UNIQUE constraint failed: P4 |
| 89496 | ** 3: CHECK constraint failed: P4 | 92997 | ** 3: CHECK constraint failed: P4 |
| 89497 | ** 4: FOREIGN KEY constraint failed: P4 | 92998 | ** 4: FOREIGN KEY constraint failed: P4 |
| @@ -89510,6 +93011,12 @@ case OP_Halt: { | |||
| 89510 | #ifdef SQLITE_DEBUG | 93011 | #ifdef SQLITE_DEBUG |
| 89511 | if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } | 93012 | if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } |
| 89512 | #endif | 93013 | #endif |
| 93014 | |||
| 93015 | /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates | ||
| 93016 | ** something is wrong with the code generator. Raise an assertion in order | ||
| 93017 | ** to bring this to the attention of fuzzers and other testing tools. */ | ||
| 93018 | assert( pOp->p1!=SQLITE_INTERNAL ); | ||
| 93019 | |||
| 89513 | if( p->pFrame && pOp->p1==SQLITE_OK ){ | 93020 | if( p->pFrame && pOp->p1==SQLITE_OK ){ |
| 89514 | /* Halt the sub-program. Return control to the parent frame. */ | 93021 | /* Halt the sub-program. Return control to the parent frame. */ |
| 89515 | pFrame = p->pFrame; | 93022 | pFrame = p->pFrame; |
| @@ -89951,10 +93458,10 @@ case OP_ResultRow: { | |||
| 89951 | assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); | 93458 | assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); |
| 89952 | 93459 | ||
| 89953 | p->cacheCtr = (p->cacheCtr + 2)|1; | 93460 | p->cacheCtr = (p->cacheCtr + 2)|1; |
| 89954 | p->pResultSet = &aMem[pOp->p1]; | 93461 | p->pResultRow = &aMem[pOp->p1]; |
| 89955 | #ifdef SQLITE_DEBUG | 93462 | #ifdef SQLITE_DEBUG |
| 89956 | { | 93463 | { |
| 89957 | Mem *pMem = p->pResultSet; | 93464 | Mem *pMem = p->pResultRow; |
| 89958 | int i; | 93465 | int i; |
| 89959 | for(i=0; i<pOp->p2; i++){ | 93466 | for(i=0; i<pOp->p2; i++){ |
| 89960 | assert( memIsValid(&pMem[i]) ); | 93467 | assert( memIsValid(&pMem[i]) ); |
| @@ -90091,7 +93598,6 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ | |||
| 90091 | case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ | 93598 | case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ |
| 90092 | case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ | 93599 | case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ |
| 90093 | case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ | 93600 | case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ |
| 90094 | u16 flags; /* Combined MEM_* flags from both inputs */ | ||
| 90095 | u16 type1; /* Numeric type of left operand */ | 93601 | u16 type1; /* Numeric type of left operand */ |
| 90096 | u16 type2; /* Numeric type of right operand */ | 93602 | u16 type2; /* Numeric type of right operand */ |
| 90097 | i64 iA; /* Integer value of left operand */ | 93603 | i64 iA; /* Integer value of left operand */ |
| @@ -90100,12 +93606,12 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ | |||
| 90100 | double rB; /* Real value of right operand */ | 93606 | double rB; /* Real value of right operand */ |
| 90101 | 93607 | ||
| 90102 | pIn1 = &aMem[pOp->p1]; | 93608 | pIn1 = &aMem[pOp->p1]; |
| 90103 | type1 = numericType(pIn1); | 93609 | type1 = pIn1->flags; |
| 90104 | pIn2 = &aMem[pOp->p2]; | 93610 | pIn2 = &aMem[pOp->p2]; |
| 90105 | type2 = numericType(pIn2); | 93611 | type2 = pIn2->flags; |
| 90106 | pOut = &aMem[pOp->p3]; | 93612 | pOut = &aMem[pOp->p3]; |
| 90107 | flags = pIn1->flags | pIn2->flags; | ||
| 90108 | if( (type1 & type2 & MEM_Int)!=0 ){ | 93613 | if( (type1 & type2 & MEM_Int)!=0 ){ |
| 93614 | int_math: | ||
| 90109 | iA = pIn1->u.i; | 93615 | iA = pIn1->u.i; |
| 90110 | iB = pIn2->u.i; | 93616 | iB = pIn2->u.i; |
| 90111 | switch( pOp->opcode ){ | 93617 | switch( pOp->opcode ){ |
| @@ -90127,9 +93633,12 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ | |||
| 90127 | } | 93633 | } |
| 90128 | pOut->u.i = iB; | 93634 | pOut->u.i = iB; |
| 90129 | MemSetTypeFlag(pOut, MEM_Int); | 93635 | MemSetTypeFlag(pOut, MEM_Int); |
| 90130 | }else if( (flags & MEM_Null)!=0 ){ | 93636 | }else if( ((type1 | type2) & MEM_Null)!=0 ){ |
| 90131 | goto arithmetic_result_is_null; | 93637 | goto arithmetic_result_is_null; |
| 90132 | }else{ | 93638 | }else{ |
| 93639 | type1 = numericType(pIn1); | ||
| 93640 | type2 = numericType(pIn2); | ||
| 93641 | if( (type1 & type2 & MEM_Int)!=0 ) goto int_math; | ||
| 90133 | fp_math: | 93642 | fp_math: |
| 90134 | rA = sqlite3VdbeRealValue(pIn1); | 93643 | rA = sqlite3VdbeRealValue(pIn1); |
| 90135 | rB = sqlite3VdbeRealValue(pIn2); | 93644 | rB = sqlite3VdbeRealValue(pIn2); |
| @@ -90482,7 +93991,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 90482 | flags1 = pIn1->flags; | 93991 | flags1 = pIn1->flags; |
| 90483 | flags3 = pIn3->flags; | 93992 | flags3 = pIn3->flags; |
| 90484 | if( (flags1 & flags3 & MEM_Int)!=0 ){ | 93993 | if( (flags1 & flags3 & MEM_Int)!=0 ){ |
| 90485 | assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB ); | ||
| 90486 | /* Common case of comparison of two integers */ | 93994 | /* Common case of comparison of two integers */ |
| 90487 | if( pIn3->u.i > pIn1->u.i ){ | 93995 | if( pIn3->u.i > pIn1->u.i ){ |
| 90488 | if( sqlite3aGTb[pOp->opcode] ){ | 93996 | if( sqlite3aGTb[pOp->opcode] ){ |
| @@ -90490,18 +93998,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 90490 | goto jump_to_p2; | 93998 | goto jump_to_p2; |
| 90491 | } | 93999 | } |
| 90492 | iCompare = +1; | 94000 | iCompare = +1; |
| 94001 | VVA_ONLY( iCompareIsInit = 1; ) | ||
| 90493 | }else if( pIn3->u.i < pIn1->u.i ){ | 94002 | }else if( pIn3->u.i < pIn1->u.i ){ |
| 90494 | if( sqlite3aLTb[pOp->opcode] ){ | 94003 | if( sqlite3aLTb[pOp->opcode] ){ |
| 90495 | VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); | 94004 | VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); |
| 90496 | goto jump_to_p2; | 94005 | goto jump_to_p2; |
| 90497 | } | 94006 | } |
| 90498 | iCompare = -1; | 94007 | iCompare = -1; |
| 94008 | VVA_ONLY( iCompareIsInit = 1; ) | ||
| 90499 | }else{ | 94009 | }else{ |
| 90500 | if( sqlite3aEQb[pOp->opcode] ){ | 94010 | if( sqlite3aEQb[pOp->opcode] ){ |
| 90501 | VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); | 94011 | VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); |
| 90502 | goto jump_to_p2; | 94012 | goto jump_to_p2; |
| 90503 | } | 94013 | } |
| 90504 | iCompare = 0; | 94014 | iCompare = 0; |
| 94015 | VVA_ONLY( iCompareIsInit = 1; ) | ||
| 90505 | } | 94016 | } |
| 90506 | VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); | 94017 | VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); |
| 90507 | break; | 94018 | break; |
| @@ -90533,6 +94044,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 90533 | goto jump_to_p2; | 94044 | goto jump_to_p2; |
| 90534 | } | 94045 | } |
| 90535 | iCompare = 1; /* Operands are not equal */ | 94046 | iCompare = 1; /* Operands are not equal */ |
| 94047 | VVA_ONLY( iCompareIsInit = 1; ) | ||
| 90536 | break; | 94048 | break; |
| 90537 | } | 94049 | } |
| 90538 | }else{ | 94050 | }else{ |
| @@ -90543,14 +94055,14 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 90543 | if( (flags1 | flags3)&MEM_Str ){ | 94055 | if( (flags1 | flags3)&MEM_Str ){ |
| 90544 | if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ | 94056 | if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ |
| 90545 | applyNumericAffinity(pIn1,0); | 94057 | applyNumericAffinity(pIn1,0); |
| 90546 | testcase( flags3==pIn3->flags ); | 94058 | assert( flags3==pIn3->flags || CORRUPT_DB ); |
| 90547 | flags3 = pIn3->flags; | 94059 | flags3 = pIn3->flags; |
| 90548 | } | 94060 | } |
| 90549 | if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ | 94061 | if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ |
| 90550 | applyNumericAffinity(pIn3,0); | 94062 | applyNumericAffinity(pIn3,0); |
| 90551 | } | 94063 | } |
| 90552 | } | 94064 | } |
| 90553 | }else if( affinity==SQLITE_AFF_TEXT ){ | 94065 | }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ |
| 90554 | if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ | 94066 | if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ |
| 90555 | testcase( pIn1->flags & MEM_Int ); | 94067 | testcase( pIn1->flags & MEM_Int ); |
| 90556 | testcase( pIn1->flags & MEM_Real ); | 94068 | testcase( pIn1->flags & MEM_Real ); |
| @@ -90558,7 +94070,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 90558 | sqlite3VdbeMemStringify(pIn1, encoding, 1); | 94070 | sqlite3VdbeMemStringify(pIn1, encoding, 1); |
| 90559 | testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); | 94071 | testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); |
| 90560 | flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); | 94072 | flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); |
| 90561 | if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str; | 94073 | if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; |
| 90562 | } | 94074 | } |
| 90563 | if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ | 94075 | if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ |
| 90564 | testcase( pIn3->flags & MEM_Int ); | 94076 | testcase( pIn3->flags & MEM_Int ); |
| @@ -90589,6 +94101,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 90589 | res2 = sqlite3aGTb[pOp->opcode]; | 94101 | res2 = sqlite3aGTb[pOp->opcode]; |
| 90590 | } | 94102 | } |
| 90591 | iCompare = res; | 94103 | iCompare = res; |
| 94104 | VVA_ONLY( iCompareIsInit = 1; ) | ||
| 90592 | 94105 | ||
| 90593 | /* Undo any changes made by applyAffinity() to the input registers. */ | 94106 | /* Undo any changes made by applyAffinity() to the input registers. */ |
| 90594 | assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); | 94107 | assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); |
| @@ -90610,10 +94123,10 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ | |||
| 90610 | ** opcodes are allowed to occur between this instruction and the previous | 94123 | ** opcodes are allowed to occur between this instruction and the previous |
| 90611 | ** OP_Lt or OP_Gt. | 94124 | ** OP_Lt or OP_Gt. |
| 90612 | ** | 94125 | ** |
| 90613 | ** If result of an OP_Eq comparison on the same two operands as the | 94126 | ** If the result of an OP_Eq comparison on the same two operands as |
| 90614 | ** prior OP_Lt or OP_Gt would have been true, then jump to P2. | 94127 | ** the prior OP_Lt or OP_Gt would have been true, then jump to P2. If |
| 90615 | ** If the result of an OP_Eq comparison on the two previous | 94128 | ** the result of an OP_Eq comparison on the two previous operands |
| 90616 | ** operands would have been false or NULL, then fall through. | 94129 | ** would have been false or NULL, then fall through. |
| 90617 | */ | 94130 | */ |
| 90618 | case OP_ElseEq: { /* same as TK_ESCAPE, jump */ | 94131 | case OP_ElseEq: { /* same as TK_ESCAPE, jump */ |
| 90619 | 94132 | ||
| @@ -90627,6 +94140,7 @@ case OP_ElseEq: { /* same as TK_ESCAPE, jump */ | |||
| 90627 | break; | 94140 | break; |
| 90628 | } | 94141 | } |
| 90629 | #endif /* SQLITE_DEBUG */ | 94142 | #endif /* SQLITE_DEBUG */ |
| 94143 | assert( iCompareIsInit ); | ||
| 90630 | VdbeBranchTaken(iCompare==0, 2); | 94144 | VdbeBranchTaken(iCompare==0, 2); |
| 90631 | if( iCompare==0 ) goto jump_to_p2; | 94145 | if( iCompare==0 ) goto jump_to_p2; |
| 90632 | break; | 94146 | break; |
| @@ -90721,6 +94235,7 @@ case OP_Compare: { | |||
| 90721 | pColl = pKeyInfo->aColl[i]; | 94235 | pColl = pKeyInfo->aColl[i]; |
| 90722 | bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); | 94236 | bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); |
| 90723 | iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); | 94237 | iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); |
| 94238 | VVA_ONLY( iCompareIsInit = 1; ) | ||
| 90724 | if( iCompare ){ | 94239 | if( iCompare ){ |
| 90725 | if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) | 94240 | if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) |
| 90726 | && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) | 94241 | && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) |
| @@ -90738,13 +94253,14 @@ case OP_Compare: { | |||
| 90738 | /* Opcode: Jump P1 P2 P3 * * | 94253 | /* Opcode: Jump P1 P2 P3 * * |
| 90739 | ** | 94254 | ** |
| 90740 | ** Jump to the instruction at address P1, P2, or P3 depending on whether | 94255 | ** Jump to the instruction at address P1, P2, or P3 depending on whether |
| 90741 | ** in the most recent OP_Compare instruction the P1 vector was less than | 94256 | ** in the most recent OP_Compare instruction the P1 vector was less than, |
| 90742 | ** equal to, or greater than the P2 vector, respectively. | 94257 | ** equal to, or greater than the P2 vector, respectively. |
| 90743 | ** | 94258 | ** |
| 90744 | ** This opcode must immediately follow an OP_Compare opcode. | 94259 | ** This opcode must immediately follow an OP_Compare opcode. |
| 90745 | */ | 94260 | */ |
| 90746 | case OP_Jump: { /* jump */ | 94261 | case OP_Jump: { /* jump */ |
| 90747 | assert( pOp>aOp && pOp[-1].opcode==OP_Compare ); | 94262 | assert( pOp>aOp && pOp[-1].opcode==OP_Compare ); |
| 94263 | assert( iCompareIsInit ); | ||
| 90748 | if( iCompare<0 ){ | 94264 | if( iCompare<0 ){ |
| 90749 | VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; | 94265 | VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; |
| 90750 | }else if( iCompare==0 ){ | 94266 | }else if( iCompare==0 ){ |
| @@ -90944,26 +94460,103 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ | |||
| 90944 | break; | 94460 | break; |
| 90945 | } | 94461 | } |
| 90946 | 94462 | ||
| 90947 | /* Opcode: IsNullOrType P1 P2 P3 * * | 94463 | /* Opcode: IsType P1 P2 P3 P4 P5 |
| 90948 | ** Synopsis: if typeof(r[P1]) IN (P3,5) goto P2 | 94464 | ** Synopsis: if typeof(P1.P3) in P5 goto P2 |
| 94465 | ** | ||
| 94466 | ** Jump to P2 if the type of a column in a btree is one of the types specified | ||
| 94467 | ** by the P5 bitmask. | ||
| 94468 | ** | ||
| 94469 | ** P1 is normally a cursor on a btree for which the row decode cache is | ||
| 94470 | ** valid through at least column P3. In other words, there should have been | ||
| 94471 | ** a prior OP_Column for column P3 or greater. If the cursor is not valid, | ||
| 94472 | ** then this opcode might give spurious results. | ||
| 94473 | ** The the btree row has fewer than P3 columns, then use P4 as the | ||
| 94474 | ** datatype. | ||
| 94475 | ** | ||
| 94476 | ** If P1 is -1, then P3 is a register number and the datatype is taken | ||
| 94477 | ** from the value in that register. | ||
| 94478 | ** | ||
| 94479 | ** P5 is a bitmask of data types. SQLITE_INTEGER is the least significant | ||
| 94480 | ** (0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04. | ||
| 94481 | ** SQLITE_BLOB is 0x08. SQLITE_NULL is 0x10. | ||
| 94482 | ** | ||
| 94483 | ** WARNING: This opcode does not reliably distinguish between NULL and REAL | ||
| 94484 | ** when P1>=0. If the database contains a NaN value, this opcode will think | ||
| 94485 | ** that the datatype is REAL when it should be NULL. When P1<0 and the value | ||
| 94486 | ** is already stored in register P3, then this opcode does reliably | ||
| 94487 | ** distinguish between NULL and REAL. The problem only arises then P1>=0. | ||
| 94488 | ** | ||
| 94489 | ** Take the jump to address P2 if and only if the datatype of the | ||
| 94490 | ** value determined by P1 and P3 corresponds to one of the bits in the | ||
| 94491 | ** P5 bitmask. | ||
| 90949 | ** | 94492 | ** |
| 90950 | ** Jump to P2 if the value in register P1 is NULL or has a datatype P3. | ||
| 90951 | ** P3 is an integer which should be one of SQLITE_INTEGER, SQLITE_FLOAT, | ||
| 90952 | ** SQLITE_BLOB, SQLITE_NULL, or SQLITE_TEXT. | ||
| 90953 | */ | 94493 | */ |
| 90954 | case OP_IsNullOrType: { /* jump, in1 */ | 94494 | case OP_IsType: { /* jump */ |
| 90955 | int doTheJump; | 94495 | VdbeCursor *pC; |
| 90956 | pIn1 = &aMem[pOp->p1]; | 94496 | u16 typeMask; |
| 90957 | doTheJump = (pIn1->flags & MEM_Null)!=0 || sqlite3_value_type(pIn1)==pOp->p3; | 94497 | u32 serialType; |
| 90958 | VdbeBranchTaken( doTheJump, 2); | 94498 | |
| 90959 | if( doTheJump ) goto jump_to_p2; | 94499 | assert( pOp->p1>=(-1) && pOp->p1<p->nCursor ); |
| 94500 | assert( pOp->p1>=0 || (pOp->p3>=0 && pOp->p3<=(p->nMem+1 - p->nCursor)) ); | ||
| 94501 | if( pOp->p1>=0 ){ | ||
| 94502 | pC = p->apCsr[pOp->p1]; | ||
| 94503 | assert( pC!=0 ); | ||
| 94504 | assert( pOp->p3>=0 ); | ||
| 94505 | if( pOp->p3<pC->nHdrParsed ){ | ||
| 94506 | serialType = pC->aType[pOp->p3]; | ||
| 94507 | if( serialType>=12 ){ | ||
| 94508 | if( serialType&1 ){ | ||
| 94509 | typeMask = 0x04; /* SQLITE_TEXT */ | ||
| 94510 | }else{ | ||
| 94511 | typeMask = 0x08; /* SQLITE_BLOB */ | ||
| 94512 | } | ||
| 94513 | }else{ | ||
| 94514 | static const unsigned char aMask[] = { | ||
| 94515 | 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2, | ||
| 94516 | 0x01, 0x01, 0x10, 0x10 | ||
| 94517 | }; | ||
| 94518 | testcase( serialType==0 ); | ||
| 94519 | testcase( serialType==1 ); | ||
| 94520 | testcase( serialType==2 ); | ||
| 94521 | testcase( serialType==3 ); | ||
| 94522 | testcase( serialType==4 ); | ||
| 94523 | testcase( serialType==5 ); | ||
| 94524 | testcase( serialType==6 ); | ||
| 94525 | testcase( serialType==7 ); | ||
| 94526 | testcase( serialType==8 ); | ||
| 94527 | testcase( serialType==9 ); | ||
| 94528 | testcase( serialType==10 ); | ||
| 94529 | testcase( serialType==11 ); | ||
| 94530 | typeMask = aMask[serialType]; | ||
| 94531 | } | ||
| 94532 | }else{ | ||
| 94533 | typeMask = 1 << (pOp->p4.i - 1); | ||
| 94534 | testcase( typeMask==0x01 ); | ||
| 94535 | testcase( typeMask==0x02 ); | ||
| 94536 | testcase( typeMask==0x04 ); | ||
| 94537 | testcase( typeMask==0x08 ); | ||
| 94538 | testcase( typeMask==0x10 ); | ||
| 94539 | } | ||
| 94540 | }else{ | ||
| 94541 | assert( memIsValid(&aMem[pOp->p3]) ); | ||
| 94542 | typeMask = 1 << (sqlite3_value_type((sqlite3_value*)&aMem[pOp->p3])-1); | ||
| 94543 | testcase( typeMask==0x01 ); | ||
| 94544 | testcase( typeMask==0x02 ); | ||
| 94545 | testcase( typeMask==0x04 ); | ||
| 94546 | testcase( typeMask==0x08 ); | ||
| 94547 | testcase( typeMask==0x10 ); | ||
| 94548 | } | ||
| 94549 | VdbeBranchTaken( (typeMask & pOp->p5)!=0, 2); | ||
| 94550 | if( typeMask & pOp->p5 ){ | ||
| 94551 | goto jump_to_p2; | ||
| 94552 | } | ||
| 90960 | break; | 94553 | break; |
| 90961 | } | 94554 | } |
| 90962 | 94555 | ||
| 90963 | /* Opcode: ZeroOrNull P1 P2 P3 * * | 94556 | /* Opcode: ZeroOrNull P1 P2 P3 * * |
| 90964 | ** Synopsis: r[P2] = 0 OR NULL | 94557 | ** Synopsis: r[P2] = 0 OR NULL |
| 90965 | ** | 94558 | ** |
| 90966 | ** If all both registers P1 and P3 are NOT NULL, then store a zero in | 94559 | ** If both registers P1 and P3 are NOT NULL, then store a zero in |
| 90967 | ** register P2. If either registers P1 or P3 are NULL then put | 94560 | ** register P2. If either registers P1 or P3 are NULL then put |
| 90968 | ** a NULL in register P2. | 94561 | ** a NULL in register P2. |
| 90969 | */ | 94562 | */ |
| @@ -90999,11 +94592,14 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ | |||
| 90999 | ** If it is, then set register P3 to NULL and jump immediately to P2. | 94592 | ** If it is, then set register P3 to NULL and jump immediately to P2. |
| 91000 | ** If P1 is not on a NULL row, then fall through without making any | 94593 | ** If P1 is not on a NULL row, then fall through without making any |
| 91001 | ** changes. | 94594 | ** changes. |
| 94595 | ** | ||
| 94596 | ** If P1 is not an open cursor, then this opcode is a no-op. | ||
| 91002 | */ | 94597 | */ |
| 91003 | case OP_IfNullRow: { /* jump */ | 94598 | case OP_IfNullRow: { /* jump */ |
| 94599 | VdbeCursor *pC; | ||
| 91004 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 94600 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 91005 | assert( p->apCsr[pOp->p1]!=0 ); | 94601 | pC = p->apCsr[pOp->p1]; |
| 91006 | if( p->apCsr[pOp->p1]->nullRow ){ | 94602 | if( pC && pC->nullRow ){ |
| 91007 | sqlite3VdbeMemSetNull(aMem + pOp->p3); | 94603 | sqlite3VdbeMemSetNull(aMem + pOp->p3); |
| 91008 | goto jump_to_p2; | 94604 | goto jump_to_p2; |
| 91009 | } | 94605 | } |
| @@ -91054,7 +94650,7 @@ case OP_Offset: { /* out3 */ | |||
| 91054 | ** Interpret the data that cursor P1 points to as a structure built using | 94650 | ** Interpret the data that cursor P1 points to as a structure built using |
| 91055 | ** the MakeRecord instruction. (See the MakeRecord opcode for additional | 94651 | ** the MakeRecord instruction. (See the MakeRecord opcode for additional |
| 91056 | ** information about the format of the data.) Extract the P2-th column | 94652 | ** information about the format of the data.) Extract the P2-th column |
| 91057 | ** from this record. If there are less that (P2+1) | 94653 | ** from this record. If there are less than (P2+1) |
| 91058 | ** values in the record, extract a NULL. | 94654 | ** values in the record, extract a NULL. |
| 91059 | ** | 94655 | ** |
| 91060 | ** The value extracted is stored in register P3. | 94656 | ** The value extracted is stored in register P3. |
| @@ -91063,12 +94659,14 @@ case OP_Offset: { /* out3 */ | |||
| 91063 | ** if the P4 argument is a P4_MEM use the value of the P4 argument as | 94659 | ** if the P4 argument is a P4_MEM use the value of the P4 argument as |
| 91064 | ** the result. | 94660 | ** the result. |
| 91065 | ** | 94661 | ** |
| 91066 | ** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then | 94662 | ** If the OPFLAG_LENGTHARG bit is set in P5 then the result is guaranteed |
| 91067 | ** the result is guaranteed to only be used as the argument of a length() | 94663 | ** to only be used by the length() function or the equivalent. The content |
| 91068 | ** or typeof() function, respectively. The loading of large blobs can be | 94664 | ** of large blobs is not loaded, thus saving CPU cycles. If the |
| 91069 | ** skipped for length() and all content loading can be skipped for typeof(). | 94665 | ** OPFLAG_TYPEOFARG bit is set then the result will only be used by the |
| 94666 | ** typeof() function or the IS NULL or IS NOT NULL operators or the | ||
| 94667 | ** equivalent. In this case, all content loading can be omitted. | ||
| 91070 | */ | 94668 | */ |
| 91071 | case OP_Column: { | 94669 | case OP_Column: { /* ncycle */ |
| 91072 | u32 p2; /* column number to retrieve */ | 94670 | u32 p2; /* column number to retrieve */ |
| 91073 | VdbeCursor *pC; /* The VDBE cursor */ | 94671 | VdbeCursor *pC; /* The VDBE cursor */ |
| 91074 | BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */ | 94672 | BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */ |
| @@ -91312,11 +94910,16 @@ op_column_restart: | |||
| 91312 | pDest->flags = aFlag[t&1]; | 94910 | pDest->flags = aFlag[t&1]; |
| 91313 | } | 94911 | } |
| 91314 | }else{ | 94912 | }else{ |
| 94913 | u8 p5; | ||
| 91315 | pDest->enc = encoding; | 94914 | pDest->enc = encoding; |
| 94915 | assert( pDest->db==db ); | ||
| 91316 | /* This branch happens only when content is on overflow pages */ | 94916 | /* This branch happens only when content is on overflow pages */ |
| 91317 | if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 | 94917 | if( ((p5 = (pOp->p5 & OPFLAG_BYTELENARG))!=0 |
| 91318 | && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) | 94918 | && (p5==OPFLAG_TYPEOFARG |
| 91319 | || (len = sqlite3VdbeSerialTypeLen(t))==0 | 94919 | || (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG)) |
| 94920 | ) | ||
| 94921 | ) | ||
| 94922 | || sqlite3VdbeSerialTypeLen(t)==0 | ||
| 91320 | ){ | 94923 | ){ |
| 91321 | /* Content is irrelevant for | 94924 | /* Content is irrelevant for |
| 91322 | ** 1. the typeof() function, | 94925 | ** 1. the typeof() function, |
| @@ -91333,11 +94936,13 @@ op_column_restart: | |||
| 91333 | */ | 94936 | */ |
| 91334 | sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); | 94937 | sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); |
| 91335 | }else{ | 94938 | }else{ |
| 91336 | if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; | 94939 | rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2], |
| 91337 | rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); | 94940 | p->cacheCtr, colCacheCtr, pDest); |
| 91338 | if( rc!=SQLITE_OK ) goto abort_due_to_error; | 94941 | if( rc ){ |
| 91339 | sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); | 94942 | if( rc==SQLITE_NOMEM ) goto no_mem; |
| 91340 | pDest->flags &= ~MEM_Ephem; | 94943 | if( rc==SQLITE_TOOBIG ) goto too_big; |
| 94944 | goto abort_due_to_error; | ||
| 94945 | } | ||
| 91341 | } | 94946 | } |
| 91342 | } | 94947 | } |
| 91343 | 94948 | ||
| @@ -91417,7 +95022,7 @@ case OP_TypeCheck: { | |||
| 91417 | } | 95022 | } |
| 91418 | case COLTYPE_REAL: { | 95023 | case COLTYPE_REAL: { |
| 91419 | testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real ); | 95024 | testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real ); |
| 91420 | testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_IntReal ); | 95025 | assert( (pIn1->flags & MEM_IntReal)==0 ); |
| 91421 | if( pIn1->flags & MEM_Int ){ | 95026 | if( pIn1->flags & MEM_Int ){ |
| 91422 | /* When applying REAL affinity, if the result is still an MEM_Int | 95027 | /* When applying REAL affinity, if the result is still an MEM_Int |
| 91423 | ** that will fit in 6 bytes, then change the type to MEM_IntReal | 95028 | ** that will fit in 6 bytes, then change the type to MEM_IntReal |
| @@ -91496,7 +95101,7 @@ case OP_Affinity: { | |||
| 91496 | }else{ | 95101 | }else{ |
| 91497 | pIn1->u.r = (double)pIn1->u.i; | 95102 | pIn1->u.r = (double)pIn1->u.i; |
| 91498 | pIn1->flags |= MEM_Real; | 95103 | pIn1->flags |= MEM_Real; |
| 91499 | pIn1->flags &= ~MEM_Int; | 95104 | pIn1->flags &= ~(MEM_Int|MEM_Str); |
| 91500 | } | 95105 | } |
| 91501 | } | 95106 | } |
| 91502 | REGISTER_TRACE((int)(pIn1-aMem), pIn1); | 95107 | REGISTER_TRACE((int)(pIn1-aMem), pIn1); |
| @@ -92420,7 +96025,7 @@ case OP_SetCookie: { | |||
| 92420 | ** | 96025 | ** |
| 92421 | ** See also: OP_OpenRead, OP_ReopenIdx | 96026 | ** See also: OP_OpenRead, OP_ReopenIdx |
| 92422 | */ | 96027 | */ |
| 92423 | case OP_ReopenIdx: { | 96028 | case OP_ReopenIdx: { /* ncycle */ |
| 92424 | int nField; | 96029 | int nField; |
| 92425 | KeyInfo *pKeyInfo; | 96030 | KeyInfo *pKeyInfo; |
| 92426 | u32 p2; | 96031 | u32 p2; |
| @@ -92441,7 +96046,7 @@ case OP_ReopenIdx: { | |||
| 92441 | } | 96046 | } |
| 92442 | /* If the cursor is not currently open or is open on a different | 96047 | /* If the cursor is not currently open or is open on a different |
| 92443 | ** index, then fall through into OP_OpenRead to force a reopen */ | 96048 | ** index, then fall through into OP_OpenRead to force a reopen */ |
| 92444 | case OP_OpenRead: | 96049 | case OP_OpenRead: /* ncycle */ |
| 92445 | case OP_OpenWrite: | 96050 | case OP_OpenWrite: |
| 92446 | 96051 | ||
| 92447 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); | 96052 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); |
| @@ -92535,7 +96140,7 @@ open_cursor_set_hints: | |||
| 92535 | ** | 96140 | ** |
| 92536 | ** Duplicate ephemeral cursors are used for self-joins of materialized views. | 96141 | ** Duplicate ephemeral cursors are used for self-joins of materialized views. |
| 92537 | */ | 96142 | */ |
| 92538 | case OP_OpenDup: { | 96143 | case OP_OpenDup: { /* ncycle */ |
| 92539 | VdbeCursor *pOrig; /* The original cursor to be duplicated */ | 96144 | VdbeCursor *pOrig; /* The original cursor to be duplicated */ |
| 92540 | VdbeCursor *pCx; /* The new cursor */ | 96145 | VdbeCursor *pCx; /* The new cursor */ |
| 92541 | 96146 | ||
| @@ -92597,8 +96202,8 @@ case OP_OpenDup: { | |||
| 92597 | ** by this opcode will be used for automatically created transient | 96202 | ** by this opcode will be used for automatically created transient |
| 92598 | ** indices in joins. | 96203 | ** indices in joins. |
| 92599 | */ | 96204 | */ |
| 92600 | case OP_OpenAutoindex: | 96205 | case OP_OpenAutoindex: /* ncycle */ |
| 92601 | case OP_OpenEphemeral: { | 96206 | case OP_OpenEphemeral: { /* ncycle */ |
| 92602 | VdbeCursor *pCx; | 96207 | VdbeCursor *pCx; |
| 92603 | KeyInfo *pKeyInfo; | 96208 | KeyInfo *pKeyInfo; |
| 92604 | 96209 | ||
| @@ -92621,7 +96226,7 @@ case OP_OpenEphemeral: { | |||
| 92621 | } | 96226 | } |
| 92622 | pCx = p->apCsr[pOp->p1]; | 96227 | pCx = p->apCsr[pOp->p1]; |
| 92623 | if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){ | 96228 | if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){ |
| 92624 | /* If the ephermeral table is already open and has no duplicates from | 96229 | /* If the ephemeral table is already open and has no duplicates from |
| 92625 | ** OP_OpenDup, then erase all existing content so that the table is | 96230 | ** OP_OpenDup, then erase all existing content so that the table is |
| 92626 | ** empty again, rather than creating a new table. */ | 96231 | ** empty again, rather than creating a new table. */ |
| 92627 | assert( pCx->isEphemeral ); | 96232 | assert( pCx->isEphemeral ); |
| @@ -92756,7 +96361,7 @@ case OP_OpenPseudo: { | |||
| 92756 | ** Close a cursor previously opened as P1. If P1 is not | 96361 | ** Close a cursor previously opened as P1. If P1 is not |
| 92757 | ** currently open, this instruction is a no-op. | 96362 | ** currently open, this instruction is a no-op. |
| 92758 | */ | 96363 | */ |
| 92759 | case OP_Close: { | 96364 | case OP_Close: { /* ncycle */ |
| 92760 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 96365 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 92761 | sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); | 96366 | sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); |
| 92762 | p->apCsr[pOp->p1] = 0; | 96367 | p->apCsr[pOp->p1] = 0; |
| @@ -92873,10 +96478,10 @@ case OP_ColumnsUsed: { | |||
| 92873 | ** | 96478 | ** |
| 92874 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt | 96479 | ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt |
| 92875 | */ | 96480 | */ |
| 92876 | case OP_SeekLT: /* jump, in3, group */ | 96481 | case OP_SeekLT: /* jump, in3, group, ncycle */ |
| 92877 | case OP_SeekLE: /* jump, in3, group */ | 96482 | case OP_SeekLE: /* jump, in3, group, ncycle */ |
| 92878 | case OP_SeekGE: /* jump, in3, group */ | 96483 | case OP_SeekGE: /* jump, in3, group, ncycle */ |
| 92879 | case OP_SeekGT: { /* jump, in3, group */ | 96484 | case OP_SeekGT: { /* jump, in3, group, ncycle */ |
| 92880 | int res; /* Comparison result */ | 96485 | int res; /* Comparison result */ |
| 92881 | int oc; /* Opcode */ | 96486 | int oc; /* Opcode */ |
| 92882 | VdbeCursor *pC; /* The cursor to seek */ | 96487 | VdbeCursor *pC; /* The cursor to seek */ |
| @@ -93005,7 +96610,13 @@ case OP_SeekGT: { /* jump, in3, group */ | |||
| 93005 | 96610 | ||
| 93006 | r.aMem = &aMem[pOp->p3]; | 96611 | r.aMem = &aMem[pOp->p3]; |
| 93007 | #ifdef SQLITE_DEBUG | 96612 | #ifdef SQLITE_DEBUG |
| 93008 | { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); } | 96613 | { |
| 96614 | int i; | ||
| 96615 | for(i=0; i<r.nField; i++){ | ||
| 96616 | assert( memIsValid(&r.aMem[i]) ); | ||
| 96617 | if( i>0 ) REGISTER_TRACE(pOp->p3+i, &r.aMem[i]); | ||
| 96618 | } | ||
| 96619 | } | ||
| 93009 | #endif | 96620 | #endif |
| 93010 | r.eqSeen = 0; | 96621 | r.eqSeen = 0; |
| 93011 | rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res); | 96622 | rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res); |
| @@ -93068,7 +96679,7 @@ seek_not_found: | |||
| 93068 | } | 96679 | } |
| 93069 | 96680 | ||
| 93070 | 96681 | ||
| 93071 | /* Opcode: SeekScan P1 P2 * * * | 96682 | /* Opcode: SeekScan P1 P2 * * P5 |
| 93072 | ** Synopsis: Scan-ahead up to P1 rows | 96683 | ** Synopsis: Scan-ahead up to P1 rows |
| 93073 | ** | 96684 | ** |
| 93074 | ** This opcode is a prefix opcode to OP_SeekGE. In other words, this | 96685 | ** This opcode is a prefix opcode to OP_SeekGE. In other words, this |
| @@ -93078,8 +96689,8 @@ seek_not_found: | |||
| 93078 | ** This opcode uses the P1 through P4 operands of the subsequent | 96689 | ** This opcode uses the P1 through P4 operands of the subsequent |
| 93079 | ** OP_SeekGE. In the text that follows, the operands of the subsequent | 96690 | ** OP_SeekGE. In the text that follows, the operands of the subsequent |
| 93080 | ** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only | 96691 | ** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only |
| 93081 | ** the P1 and P2 operands of this opcode are also used, and are called | 96692 | ** the P1, P2 and P5 operands of this opcode are also used, and are called |
| 93082 | ** This.P1 and This.P2. | 96693 | ** This.P1, This.P2 and This.P5. |
| 93083 | ** | 96694 | ** |
| 93084 | ** This opcode helps to optimize IN operators on a multi-column index | 96695 | ** This opcode helps to optimize IN operators on a multi-column index |
| 93085 | ** where the IN operator is on the later terms of the index by avoiding | 96696 | ** where the IN operator is on the later terms of the index by avoiding |
| @@ -93089,32 +96700,54 @@ seek_not_found: | |||
| 93089 | ** | 96700 | ** |
| 93090 | ** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which | 96701 | ** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which |
| 93091 | ** is the desired entry that we want the cursor SeekGE.P1 to be pointing | 96702 | ** is the desired entry that we want the cursor SeekGE.P1 to be pointing |
| 93092 | ** to. Call this SeekGE.P4/P5 row the "target". | 96703 | ** to. Call this SeekGE.P3/P4 row the "target". |
| 93093 | ** | 96704 | ** |
| 93094 | ** If the SeekGE.P1 cursor is not currently pointing to a valid row, | 96705 | ** If the SeekGE.P1 cursor is not currently pointing to a valid row, |
| 93095 | ** then this opcode is a no-op and control passes through into the OP_SeekGE. | 96706 | ** then this opcode is a no-op and control passes through into the OP_SeekGE. |
| 93096 | ** | 96707 | ** |
| 93097 | ** If the SeekGE.P1 cursor is pointing to a valid row, then that row | 96708 | ** If the SeekGE.P1 cursor is pointing to a valid row, then that row |
| 93098 | ** might be the target row, or it might be near and slightly before the | 96709 | ** might be the target row, or it might be near and slightly before the |
| 93099 | ** target row. This opcode attempts to position the cursor on the target | 96710 | ** target row, or it might be after the target row. If the cursor is |
| 93100 | ** row by, perhaps by invoking sqlite3BtreeStep() on the cursor | 96711 | ** currently before the target row, then this opcode attempts to position |
| 93101 | ** between 0 and This.P1 times. | 96712 | ** the cursor on or after the target row by invoking sqlite3BtreeStep() |
| 93102 | ** | 96713 | ** on the cursor between 1 and This.P1 times. |
| 93103 | ** There are three possible outcomes from this opcode:<ol> | 96714 | ** |
| 93104 | ** | 96715 | ** The This.P5 parameter is a flag that indicates what to do if the |
| 93105 | ** <li> If after This.P1 steps, the cursor is still pointing to a place that | 96716 | ** cursor ends up pointing at a valid row that is past the target |
| 93106 | ** is earlier in the btree than the target row, then fall through | 96717 | ** row. If This.P5 is false (0) then a jump is made to SeekGE.P2. If |
| 93107 | ** into the subsquence OP_SeekGE opcode. | 96718 | ** This.P5 is true (non-zero) then a jump is made to This.P2. The P5==0 |
| 93108 | ** | 96719 | ** case occurs when there are no inequality constraints to the right of |
| 93109 | ** <li> If the cursor is successfully moved to the target row by 0 or more | 96720 | ** the IN constraint. The jump to SeekGE.P2 ends the loop. The P5!=0 case |
| 93110 | ** sqlite3BtreeNext() calls, then jump to This.P2, which will land just | 96721 | ** occurs when there are inequality constraints to the right of the IN |
| 93111 | ** past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE. | 96722 | ** operator. In that case, the This.P2 will point either directly to or |
| 93112 | ** | 96723 | ** to setup code prior to the OP_IdxGT or OP_IdxGE opcode that checks for |
| 93113 | ** <li> If the cursor ends up past the target row (indicating the the target | 96724 | ** loop terminate. |
| 93114 | ** row does not exist in the btree) then jump to SeekOP.P2. | 96725 | ** |
| 96726 | ** Possible outcomes from this opcode:<ol> | ||
| 96727 | ** | ||
| 96728 | ** <li> If the cursor is initially not pointed to any valid row, then | ||
| 96729 | ** fall through into the subsequent OP_SeekGE opcode. | ||
| 96730 | ** | ||
| 96731 | ** <li> If the cursor is left pointing to a row that is before the target | ||
| 96732 | ** row, even after making as many as This.P1 calls to | ||
| 96733 | ** sqlite3BtreeNext(), then also fall through into OP_SeekGE. | ||
| 96734 | ** | ||
| 96735 | ** <li> If the cursor is left pointing at the target row, either because it | ||
| 96736 | ** was at the target row to begin with or because one or more | ||
| 96737 | ** sqlite3BtreeNext() calls moved the cursor to the target row, | ||
| 96738 | ** then jump to This.P2.., | ||
| 96739 | ** | ||
| 96740 | ** <li> If the cursor started out before the target row and a call to | ||
| 96741 | ** to sqlite3BtreeNext() moved the cursor off the end of the index | ||
| 96742 | ** (indicating that the target row definitely does not exist in the | ||
| 96743 | ** btree) then jump to SeekGE.P2, ending the loop. | ||
| 96744 | ** | ||
| 96745 | ** <li> If the cursor ends up on a valid row that is past the target row | ||
| 96746 | ** (indicating that the target row does not exist in the btree) then | ||
| 96747 | ** jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0. | ||
| 93115 | ** </ol> | 96748 | ** </ol> |
| 93116 | */ | 96749 | */ |
| 93117 | case OP_SeekScan: { | 96750 | case OP_SeekScan: { /* ncycle */ |
| 93118 | VdbeCursor *pC; | 96751 | VdbeCursor *pC; |
| 93119 | int res; | 96752 | int res; |
| 93120 | int nStep; | 96753 | int nStep; |
| @@ -93122,14 +96755,25 @@ case OP_SeekScan: { | |||
| 93122 | 96755 | ||
| 93123 | assert( pOp[1].opcode==OP_SeekGE ); | 96756 | assert( pOp[1].opcode==OP_SeekGE ); |
| 93124 | 96757 | ||
| 93125 | /* pOp->p2 points to the first instruction past the OP_IdxGT that | 96758 | /* If pOp->p5 is clear, then pOp->p2 points to the first instruction past the |
| 93126 | ** follows the OP_SeekGE. */ | 96759 | ** OP_IdxGT that follows the OP_SeekGE. Otherwise, it points to the first |
| 96760 | ** opcode past the OP_SeekGE itself. */ | ||
| 93127 | assert( pOp->p2>=(int)(pOp-aOp)+2 ); | 96761 | assert( pOp->p2>=(int)(pOp-aOp)+2 ); |
| 93128 | assert( aOp[pOp->p2-1].opcode==OP_IdxGT || aOp[pOp->p2-1].opcode==OP_IdxGE ); | 96762 | #ifdef SQLITE_DEBUG |
| 93129 | testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); | 96763 | if( pOp->p5==0 ){ |
| 93130 | assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); | 96764 | /* There are no inequality constraints following the IN constraint. */ |
| 93131 | assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); | 96765 | assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); |
| 93132 | assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); | 96766 | assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); |
| 96767 | assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); | ||
| 96768 | assert( aOp[pOp->p2-1].opcode==OP_IdxGT | ||
| 96769 | || aOp[pOp->p2-1].opcode==OP_IdxGE ); | ||
| 96770 | testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); | ||
| 96771 | }else{ | ||
| 96772 | /* There are inequality constraints. */ | ||
| 96773 | assert( pOp->p2==(int)(pOp-aOp)+2 ); | ||
| 96774 | assert( aOp[pOp->p2-1].opcode==OP_SeekGE ); | ||
| 96775 | } | ||
| 96776 | #endif | ||
| 93133 | 96777 | ||
| 93134 | assert( pOp->p1>0 ); | 96778 | assert( pOp->p1>0 ); |
| 93135 | pC = p->apCsr[pOp[1].p1]; | 96779 | pC = p->apCsr[pOp[1].p1]; |
| @@ -93163,8 +96807,9 @@ case OP_SeekScan: { | |||
| 93163 | while(1){ | 96807 | while(1){ |
| 93164 | rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); | 96808 | rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); |
| 93165 | if( rc ) goto abort_due_to_error; | 96809 | if( rc ) goto abort_due_to_error; |
| 93166 | if( res>0 ){ | 96810 | if( res>0 && pOp->p5==0 ){ |
| 93167 | seekscan_search_fail: | 96811 | seekscan_search_fail: |
| 96812 | /* Jump to SeekGE.P2, ending the loop */ | ||
| 93168 | #ifdef SQLITE_DEBUG | 96813 | #ifdef SQLITE_DEBUG |
| 93169 | if( db->flags&SQLITE_VdbeTrace ){ | 96814 | if( db->flags&SQLITE_VdbeTrace ){ |
| 93170 | printf("... %d steps and then skip\n", pOp->p1 - nStep); | 96815 | printf("... %d steps and then skip\n", pOp->p1 - nStep); |
| @@ -93174,7 +96819,8 @@ case OP_SeekScan: { | |||
| 93174 | pOp++; | 96819 | pOp++; |
| 93175 | goto jump_to_p2; | 96820 | goto jump_to_p2; |
| 93176 | } | 96821 | } |
| 93177 | if( res==0 ){ | 96822 | if( res>=0 ){ |
| 96823 | /* Jump to This.P2, bypassing the OP_SeekGE opcode */ | ||
| 93178 | #ifdef SQLITE_DEBUG | 96824 | #ifdef SQLITE_DEBUG |
| 93179 | if( db->flags&SQLITE_VdbeTrace ){ | 96825 | if( db->flags&SQLITE_VdbeTrace ){ |
| 93180 | printf("... %d steps and then success\n", pOp->p1 - nStep); | 96826 | printf("... %d steps and then success\n", pOp->p1 - nStep); |
| @@ -93194,6 +96840,7 @@ case OP_SeekScan: { | |||
| 93194 | break; | 96840 | break; |
| 93195 | } | 96841 | } |
| 93196 | nStep--; | 96842 | nStep--; |
| 96843 | pC->cacheStatus = CACHE_STALE; | ||
| 93197 | rc = sqlite3BtreeNext(pC->uc.pCursor, 0); | 96844 | rc = sqlite3BtreeNext(pC->uc.pCursor, 0); |
| 93198 | if( rc ){ | 96845 | if( rc ){ |
| 93199 | if( rc==SQLITE_DONE ){ | 96846 | if( rc==SQLITE_DONE ){ |
| @@ -93223,7 +96870,7 @@ case OP_SeekScan: { | |||
| 93223 | ** | 96870 | ** |
| 93224 | ** P1 must be a valid b-tree cursor. | 96871 | ** P1 must be a valid b-tree cursor. |
| 93225 | */ | 96872 | */ |
| 93226 | case OP_SeekHit: { | 96873 | case OP_SeekHit: { /* ncycle */ |
| 93227 | VdbeCursor *pC; | 96874 | VdbeCursor *pC; |
| 93228 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 96875 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 93229 | pC = p->apCsr[pOp->p1]; | 96876 | pC = p->apCsr[pOp->p1]; |
| @@ -93250,12 +96897,16 @@ case OP_SeekHit: { | |||
| 93250 | /* Opcode: IfNotOpen P1 P2 * * * | 96897 | /* Opcode: IfNotOpen P1 P2 * * * |
| 93251 | ** Synopsis: if( !csr[P1] ) goto P2 | 96898 | ** Synopsis: if( !csr[P1] ) goto P2 |
| 93252 | ** | 96899 | ** |
| 93253 | ** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through. | 96900 | ** If cursor P1 is not open or if P1 is set to a NULL row using the |
| 96901 | ** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through. | ||
| 93254 | */ | 96902 | */ |
| 93255 | case OP_IfNotOpen: { /* jump */ | 96903 | case OP_IfNotOpen: { /* jump */ |
| 96904 | VdbeCursor *pCur; | ||
| 96905 | |||
| 93256 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 96906 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 93257 | VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2); | 96907 | pCur = p->apCsr[pOp->p1]; |
| 93258 | if( !p->apCsr[pOp->p1] ){ | 96908 | VdbeBranchTaken(pCur==0 || pCur->nullRow, 2); |
| 96909 | if( pCur==0 || pCur->nullRow ){ | ||
| 93259 | goto jump_to_p2_and_check_for_interrupt; | 96910 | goto jump_to_p2_and_check_for_interrupt; |
| 93260 | } | 96911 | } |
| 93261 | break; | 96912 | break; |
| @@ -93306,13 +96957,13 @@ case OP_IfNotOpen: { /* jump */ | |||
| 93306 | ** operands to OP_NotFound and OP_IdxGT. | 96957 | ** operands to OP_NotFound and OP_IdxGT. |
| 93307 | ** | 96958 | ** |
| 93308 | ** This opcode is an optimization attempt only. If this opcode always | 96959 | ** This opcode is an optimization attempt only. If this opcode always |
| 93309 | ** falls through, the correct answer is still obtained, but extra works | 96960 | ** falls through, the correct answer is still obtained, but extra work |
| 93310 | ** is performed. | 96961 | ** is performed. |
| 93311 | ** | 96962 | ** |
| 93312 | ** A value of N in the seekHit flag of cursor P1 means that there exists | 96963 | ** A value of N in the seekHit flag of cursor P1 means that there exists |
| 93313 | ** a key P3:N that will match some record in the index. We want to know | 96964 | ** a key P3:N that will match some record in the index. We want to know |
| 93314 | ** if it is possible for a record P3:P4 to match some record in the | 96965 | ** if it is possible for a record P3:P4 to match some record in the |
| 93315 | ** index. If it is not possible, we can skips some work. So if seekHit | 96966 | ** index. If it is not possible, we can skip some work. So if seekHit |
| 93316 | ** is less than P4, attempt to find out if a match is possible by running | 96967 | ** is less than P4, attempt to find out if a match is possible by running |
| 93317 | ** OP_NotFound. | 96968 | ** OP_NotFound. |
| 93318 | ** | 96969 | ** |
| @@ -93351,7 +97002,7 @@ case OP_IfNotOpen: { /* jump */ | |||
| 93351 | ** | 97002 | ** |
| 93352 | ** See also: NotFound, Found, NotExists | 97003 | ** See also: NotFound, Found, NotExists |
| 93353 | */ | 97004 | */ |
| 93354 | case OP_IfNoHope: { /* jump, in3 */ | 97005 | case OP_IfNoHope: { /* jump, in3, ncycle */ |
| 93355 | VdbeCursor *pC; | 97006 | VdbeCursor *pC; |
| 93356 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 97007 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 93357 | pC = p->apCsr[pOp->p1]; | 97008 | pC = p->apCsr[pOp->p1]; |
| @@ -93365,9 +97016,9 @@ case OP_IfNoHope: { /* jump, in3 */ | |||
| 93365 | /* Fall through into OP_NotFound */ | 97016 | /* Fall through into OP_NotFound */ |
| 93366 | /* no break */ deliberate_fall_through | 97017 | /* no break */ deliberate_fall_through |
| 93367 | } | 97018 | } |
| 93368 | case OP_NoConflict: /* jump, in3 */ | 97019 | case OP_NoConflict: /* jump, in3, ncycle */ |
| 93369 | case OP_NotFound: /* jump, in3 */ | 97020 | case OP_NotFound: /* jump, in3, ncycle */ |
| 93370 | case OP_Found: { /* jump, in3 */ | 97021 | case OP_Found: { /* jump, in3, ncycle */ |
| 93371 | int alreadyExists; | 97022 | int alreadyExists; |
| 93372 | int ii; | 97023 | int ii; |
| 93373 | VdbeCursor *pC; | 97024 | VdbeCursor *pC; |
| @@ -93497,7 +97148,7 @@ case OP_Found: { /* jump, in3 */ | |||
| 93497 | ** | 97148 | ** |
| 93498 | ** See also: Found, NotFound, NoConflict, SeekRowid | 97149 | ** See also: Found, NotFound, NoConflict, SeekRowid |
| 93499 | */ | 97150 | */ |
| 93500 | case OP_SeekRowid: { /* jump, in3 */ | 97151 | case OP_SeekRowid: { /* jump, in3, ncycle */ |
| 93501 | VdbeCursor *pC; | 97152 | VdbeCursor *pC; |
| 93502 | BtCursor *pCrsr; | 97153 | BtCursor *pCrsr; |
| 93503 | int res; | 97154 | int res; |
| @@ -93522,7 +97173,7 @@ case OP_SeekRowid: { /* jump, in3 */ | |||
| 93522 | } | 97173 | } |
| 93523 | /* Fall through into OP_NotExists */ | 97174 | /* Fall through into OP_NotExists */ |
| 93524 | /* no break */ deliberate_fall_through | 97175 | /* no break */ deliberate_fall_through |
| 93525 | case OP_NotExists: /* jump, in3 */ | 97176 | case OP_NotExists: /* jump, in3, ncycle */ |
| 93526 | pIn3 = &aMem[pOp->p3]; | 97177 | pIn3 = &aMem[pOp->p3]; |
| 93527 | assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); | 97178 | assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); |
| 93528 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 97179 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| @@ -93802,8 +97453,11 @@ case OP_Insert: { | |||
| 93802 | if( pOp->p5 & OPFLAG_ISNOOP ) break; | 97453 | if( pOp->p5 & OPFLAG_ISNOOP ) break; |
| 93803 | #endif | 97454 | #endif |
| 93804 | 97455 | ||
| 93805 | if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; | 97456 | assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 ); |
| 93806 | if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; | 97457 | if( pOp->p5 & OPFLAG_NCHANGE ){ |
| 97458 | p->nChange++; | ||
| 97459 | if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; | ||
| 97460 | } | ||
| 93807 | assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); | 97461 | assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); |
| 93808 | x.pData = pData->z; | 97462 | x.pData = pData->z; |
| 93809 | x.nData = pData->n; | 97463 | x.nData = pData->n; |
| @@ -93814,12 +97468,14 @@ case OP_Insert: { | |||
| 93814 | x.nZero = 0; | 97468 | x.nZero = 0; |
| 93815 | } | 97469 | } |
| 93816 | x.pKey = 0; | 97470 | x.pKey = 0; |
| 97471 | assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); | ||
| 93817 | rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, | 97472 | rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, |
| 93818 | (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), | 97473 | (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), |
| 93819 | seekResult | 97474 | seekResult |
| 93820 | ); | 97475 | ); |
| 93821 | pC->deferredMoveto = 0; | 97476 | pC->deferredMoveto = 0; |
| 93822 | pC->cacheStatus = CACHE_STALE; | 97477 | pC->cacheStatus = CACHE_STALE; |
| 97478 | colCacheCtr++; | ||
| 93823 | 97479 | ||
| 93824 | /* Invoke the update-hook if required. */ | 97480 | /* Invoke the update-hook if required. */ |
| 93825 | if( rc ) goto abort_due_to_error; | 97481 | if( rc ) goto abort_due_to_error; |
| @@ -93873,10 +97529,10 @@ case OP_RowCell: { | |||
| 93873 | ** left in an undefined state. | 97529 | ** left in an undefined state. |
| 93874 | ** | 97530 | ** |
| 93875 | ** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this | 97531 | ** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this |
| 93876 | ** delete one of several associated with deleting a table row and all its | 97532 | ** delete is one of several associated with deleting a table row and |
| 93877 | ** associated index entries. Exactly one of those deletes is the "primary" | 97533 | ** all its associated index entries. Exactly one of those deletes is |
| 93878 | ** delete. The others are all on OPFLAG_FORDELETE cursors or else are | 97534 | ** the "primary" delete. The others are all on OPFLAG_FORDELETE |
| 93879 | ** marked with the AUXDELETE flag. | 97535 | ** cursors or else are marked with the AUXDELETE flag. |
| 93880 | ** | 97536 | ** |
| 93881 | ** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row | 97537 | ** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row |
| 93882 | ** change count is incremented (otherwise not). | 97538 | ** change count is incremented (otherwise not). |
| @@ -93980,6 +97636,7 @@ case OP_Delete: { | |||
| 93980 | 97636 | ||
| 93981 | rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); | 97637 | rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); |
| 93982 | pC->cacheStatus = CACHE_STALE; | 97638 | pC->cacheStatus = CACHE_STALE; |
| 97639 | colCacheCtr++; | ||
| 93983 | pC->seekResult = 0; | 97640 | pC->seekResult = 0; |
| 93984 | if( rc ) goto abort_due_to_error; | 97641 | if( rc ) goto abort_due_to_error; |
| 93985 | 97642 | ||
| @@ -94047,13 +97704,13 @@ case OP_SorterCompare: { | |||
| 94047 | ** Write into register P2 the current sorter data for sorter cursor P1. | 97704 | ** Write into register P2 the current sorter data for sorter cursor P1. |
| 94048 | ** Then clear the column header cache on cursor P3. | 97705 | ** Then clear the column header cache on cursor P3. |
| 94049 | ** | 97706 | ** |
| 94050 | ** This opcode is normally use to move a record out of the sorter and into | 97707 | ** This opcode is normally used to move a record out of the sorter and into |
| 94051 | ** a register that is the source for a pseudo-table cursor created using | 97708 | ** a register that is the source for a pseudo-table cursor created using |
| 94052 | ** OpenPseudo. That pseudo-table cursor is the one that is identified by | 97709 | ** OpenPseudo. That pseudo-table cursor is the one that is identified by |
| 94053 | ** parameter P3. Clearing the P3 column cache as part of this opcode saves | 97710 | ** parameter P3. Clearing the P3 column cache as part of this opcode saves |
| 94054 | ** us from having to issue a separate NullRow instruction to clear that cache. | 97711 | ** us from having to issue a separate NullRow instruction to clear that cache. |
| 94055 | */ | 97712 | */ |
| 94056 | case OP_SorterData: { | 97713 | case OP_SorterData: { /* ncycle */ |
| 94057 | VdbeCursor *pC; | 97714 | VdbeCursor *pC; |
| 94058 | 97715 | ||
| 94059 | pOut = &aMem[pOp->p2]; | 97716 | pOut = &aMem[pOp->p2]; |
| @@ -94145,7 +97802,7 @@ case OP_RowData: { | |||
| 94145 | ** be a separate OP_VRowid opcode for use with virtual tables, but this | 97802 | ** be a separate OP_VRowid opcode for use with virtual tables, but this |
| 94146 | ** one opcode now works for both table types. | 97803 | ** one opcode now works for both table types. |
| 94147 | */ | 97804 | */ |
| 94148 | case OP_Rowid: { /* out2 */ | 97805 | case OP_Rowid: { /* out2, ncycle */ |
| 94149 | VdbeCursor *pC; | 97806 | VdbeCursor *pC; |
| 94150 | i64 v; | 97807 | i64 v; |
| 94151 | sqlite3_vtab *pVtab; | 97808 | sqlite3_vtab *pVtab; |
| @@ -94244,8 +97901,8 @@ case OP_NullRow: { | |||
| 94244 | ** from the end toward the beginning. In other words, the cursor is | 97901 | ** from the end toward the beginning. In other words, the cursor is |
| 94245 | ** configured to use Prev, not Next. | 97902 | ** configured to use Prev, not Next. |
| 94246 | */ | 97903 | */ |
| 94247 | case OP_SeekEnd: | 97904 | case OP_SeekEnd: /* ncycle */ |
| 94248 | case OP_Last: { /* jump */ | 97905 | case OP_Last: { /* jump, ncycle */ |
| 94249 | VdbeCursor *pC; | 97906 | VdbeCursor *pC; |
| 94250 | BtCursor *pCrsr; | 97907 | BtCursor *pCrsr; |
| 94251 | int res; | 97908 | int res; |
| @@ -94328,8 +97985,8 @@ case OP_IfSmaller: { /* jump */ | |||
| 94328 | ** regression tests can determine whether or not the optimizer is | 97985 | ** regression tests can determine whether or not the optimizer is |
| 94329 | ** correctly optimizing out sorts. | 97986 | ** correctly optimizing out sorts. |
| 94330 | */ | 97987 | */ |
| 94331 | case OP_SorterSort: /* jump */ | 97988 | case OP_SorterSort: /* jump ncycle */ |
| 94332 | case OP_Sort: { /* jump */ | 97989 | case OP_Sort: { /* jump ncycle */ |
| 94333 | #ifdef SQLITE_TEST | 97990 | #ifdef SQLITE_TEST |
| 94334 | sqlite3_sort_count++; | 97991 | sqlite3_sort_count++; |
| 94335 | sqlite3_search_count--; | 97992 | sqlite3_search_count--; |
| @@ -94346,17 +98003,22 @@ case OP_Sort: { /* jump */ | |||
| 94346 | ** If the table or index is not empty, fall through to the following | 98003 | ** If the table or index is not empty, fall through to the following |
| 94347 | ** instruction. | 98004 | ** instruction. |
| 94348 | ** | 98005 | ** |
| 98006 | ** If P2 is zero, that is an assertion that the P1 table is never | ||
| 98007 | ** empty and hence the jump will never be taken. | ||
| 98008 | ** | ||
| 94349 | ** This opcode leaves the cursor configured to move in forward order, | 98009 | ** This opcode leaves the cursor configured to move in forward order, |
| 94350 | ** from the beginning toward the end. In other words, the cursor is | 98010 | ** from the beginning toward the end. In other words, the cursor is |
| 94351 | ** configured to use Next, not Prev. | 98011 | ** configured to use Next, not Prev. |
| 94352 | */ | 98012 | */ |
| 94353 | case OP_Rewind: { /* jump */ | 98013 | case OP_Rewind: { /* jump, ncycle */ |
| 94354 | VdbeCursor *pC; | 98014 | VdbeCursor *pC; |
| 94355 | BtCursor *pCrsr; | 98015 | BtCursor *pCrsr; |
| 94356 | int res; | 98016 | int res; |
| 94357 | 98017 | ||
| 94358 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 98018 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 94359 | assert( pOp->p5==0 ); | 98019 | assert( pOp->p5==0 ); |
| 98020 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); | ||
| 98021 | |||
| 94360 | pC = p->apCsr[pOp->p1]; | 98022 | pC = p->apCsr[pOp->p1]; |
| 94361 | assert( pC!=0 ); | 98023 | assert( pC!=0 ); |
| 94362 | assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); | 98024 | assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); |
| @@ -94376,9 +98038,10 @@ case OP_Rewind: { /* jump */ | |||
| 94376 | } | 98038 | } |
| 94377 | if( rc ) goto abort_due_to_error; | 98039 | if( rc ) goto abort_due_to_error; |
| 94378 | pC->nullRow = (u8)res; | 98040 | pC->nullRow = (u8)res; |
| 94379 | assert( pOp->p2>0 && pOp->p2<p->nOp ); | 98041 | if( pOp->p2>0 ){ |
| 94380 | VdbeBranchTaken(res!=0,2); | 98042 | VdbeBranchTaken(res!=0,2); |
| 94381 | if( res ) goto jump_to_p2; | 98043 | if( res ) goto jump_to_p2; |
| 98044 | } | ||
| 94382 | break; | 98045 | break; |
| 94383 | } | 98046 | } |
| 94384 | 98047 | ||
| @@ -94444,9 +98107,11 @@ case OP_SorterNext: { /* jump */ | |||
| 94444 | rc = sqlite3VdbeSorterNext(db, pC); | 98107 | rc = sqlite3VdbeSorterNext(db, pC); |
| 94445 | goto next_tail; | 98108 | goto next_tail; |
| 94446 | 98109 | ||
| 94447 | case OP_Prev: /* jump */ | 98110 | case OP_Prev: /* jump, ncycle */ |
| 94448 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 98111 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 94449 | assert( pOp->p5<ArraySize(p->aCounter) ); | 98112 | assert( pOp->p5==0 |
| 98113 | || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP | ||
| 98114 | || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); | ||
| 94450 | pC = p->apCsr[pOp->p1]; | 98115 | pC = p->apCsr[pOp->p1]; |
| 94451 | assert( pC!=0 ); | 98116 | assert( pC!=0 ); |
| 94452 | assert( pC->deferredMoveto==0 ); | 98117 | assert( pC->deferredMoveto==0 ); |
| @@ -94457,9 +98122,11 @@ case OP_Prev: /* jump */ | |||
| 94457 | rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3); | 98122 | rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3); |
| 94458 | goto next_tail; | 98123 | goto next_tail; |
| 94459 | 98124 | ||
| 94460 | case OP_Next: /* jump */ | 98125 | case OP_Next: /* jump, ncycle */ |
| 94461 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 98126 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 94462 | assert( pOp->p5<ArraySize(p->aCounter) ); | 98127 | assert( pOp->p5==0 |
| 98128 | || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP | ||
| 98129 | || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); | ||
| 94463 | pC = p->apCsr[pOp->p1]; | 98130 | pC = p->apCsr[pOp->p1]; |
| 94464 | assert( pC!=0 ); | 98131 | assert( pC!=0 ); |
| 94465 | assert( pC->deferredMoveto==0 ); | 98132 | assert( pC->deferredMoveto==0 ); |
| @@ -94647,8 +98314,8 @@ case OP_IdxDelete: { | |||
| 94647 | ** | 98314 | ** |
| 94648 | ** See also: Rowid, MakeRecord. | 98315 | ** See also: Rowid, MakeRecord. |
| 94649 | */ | 98316 | */ |
| 94650 | case OP_DeferredSeek: | 98317 | case OP_DeferredSeek: /* ncycle */ |
| 94651 | case OP_IdxRowid: { /* out2 */ | 98318 | case OP_IdxRowid: { /* out2, ncycle */ |
| 94652 | VdbeCursor *pC; /* The P1 index cursor */ | 98319 | VdbeCursor *pC; /* The P1 index cursor */ |
| 94653 | VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */ | 98320 | VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */ |
| 94654 | i64 rowid; /* Rowid that P1 current points to */ | 98321 | i64 rowid; /* Rowid that P1 current points to */ |
| @@ -94666,10 +98333,10 @@ case OP_IdxRowid: { /* out2 */ | |||
| 94666 | ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ | 98333 | ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ |
| 94667 | rc = sqlite3VdbeCursorRestore(pC); | 98334 | rc = sqlite3VdbeCursorRestore(pC); |
| 94668 | 98335 | ||
| 94669 | /* sqlite3VbeCursorRestore() can only fail if the record has been deleted | 98336 | /* sqlite3VdbeCursorRestore() may fail if the cursor has been disturbed |
| 94670 | ** out from under the cursor. That will never happens for an IdxRowid | 98337 | ** since it was last positioned and an error (e.g. OOM or an IO error) |
| 94671 | ** or Seek opcode */ | 98338 | ** occurs while trying to reposition it. */ |
| 94672 | if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; | 98339 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 94673 | 98340 | ||
| 94674 | if( !pC->nullRow ){ | 98341 | if( !pC->nullRow ){ |
| 94675 | rowid = 0; /* Not needed. Only used to silence a warning. */ | 98342 | rowid = 0; /* Not needed. Only used to silence a warning. */ |
| @@ -94710,8 +98377,8 @@ case OP_IdxRowid: { /* out2 */ | |||
| 94710 | ** seek operation now, without further delay. If the cursor seek has | 98377 | ** seek operation now, without further delay. If the cursor seek has |
| 94711 | ** already occurred, this instruction is a no-op. | 98378 | ** already occurred, this instruction is a no-op. |
| 94712 | */ | 98379 | */ |
| 94713 | case OP_FinishSeek: { | 98380 | case OP_FinishSeek: { /* ncycle */ |
| 94714 | VdbeCursor *pC; /* The P1 index cursor */ | 98381 | VdbeCursor *pC; /* The P1 index cursor */ |
| 94715 | 98382 | ||
| 94716 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); | 98383 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 94717 | pC = p->apCsr[pOp->p1]; | 98384 | pC = p->apCsr[pOp->p1]; |
| @@ -94766,10 +98433,10 @@ case OP_FinishSeek: { | |||
| 94766 | ** If the P1 index entry is less than or equal to the key value then jump | 98433 | ** If the P1 index entry is less than or equal to the key value then jump |
| 94767 | ** to P2. Otherwise fall through to the next instruction. | 98434 | ** to P2. Otherwise fall through to the next instruction. |
| 94768 | */ | 98435 | */ |
| 94769 | case OP_IdxLE: /* jump */ | 98436 | case OP_IdxLE: /* jump, ncycle */ |
| 94770 | case OP_IdxGT: /* jump */ | 98437 | case OP_IdxGT: /* jump, ncycle */ |
| 94771 | case OP_IdxLT: /* jump */ | 98438 | case OP_IdxLT: /* jump, ncycle */ |
| 94772 | case OP_IdxGE: { /* jump */ | 98439 | case OP_IdxGE: { /* jump, ncycle */ |
| 94773 | VdbeCursor *pC; | 98440 | VdbeCursor *pC; |
| 94774 | int res; | 98441 | int res; |
| 94775 | UnpackedRecord r; | 98442 | UnpackedRecord r; |
| @@ -94846,7 +98513,7 @@ case OP_IdxGE: { /* jump */ | |||
| 94846 | ** file is given by P1. | 98513 | ** file is given by P1. |
| 94847 | ** | 98514 | ** |
| 94848 | ** The table being destroyed is in the main database file if P3==0. If | 98515 | ** The table being destroyed is in the main database file if P3==0. If |
| 94849 | ** P3==1 then the table to be clear is in the auxiliary database file | 98516 | ** P3==1 then the table to be destroyed is in the auxiliary database file |
| 94850 | ** that is used to store tables create using CREATE TEMPORARY TABLE. | 98517 | ** that is used to store tables create using CREATE TEMPORARY TABLE. |
| 94851 | ** | 98518 | ** |
| 94852 | ** If AUTOVACUUM is enabled then it is possible that another root page | 98519 | ** If AUTOVACUUM is enabled then it is possible that another root page |
| @@ -94906,8 +98573,8 @@ case OP_Destroy: { /* out2 */ | |||
| 94906 | ** in the database file is given by P1. But, unlike Destroy, do not | 98573 | ** in the database file is given by P1. But, unlike Destroy, do not |
| 94907 | ** remove the table or index from the database file. | 98574 | ** remove the table or index from the database file. |
| 94908 | ** | 98575 | ** |
| 94909 | ** The table being clear is in the main database file if P2==0. If | 98576 | ** The table being cleared is in the main database file if P2==0. If |
| 94910 | ** P2==1 then the table to be clear is in the auxiliary database file | 98577 | ** P2==1 then the table to be cleared is in the auxiliary database file |
| 94911 | ** that is used to store tables create using CREATE TEMPORARY TABLE. | 98578 | ** that is used to store tables create using CREATE TEMPORARY TABLE. |
| 94912 | ** | 98579 | ** |
| 94913 | ** If the P3 value is non-zero, then the row change count is incremented | 98580 | ** If the P3 value is non-zero, then the row change count is incremented |
| @@ -95180,13 +98847,14 @@ case OP_IntegrityCk: { | |||
| 95180 | pIn1 = &aMem[pOp->p1]; | 98847 | pIn1 = &aMem[pOp->p1]; |
| 95181 | assert( pOp->p5<db->nDb ); | 98848 | assert( pOp->p5<db->nDb ); |
| 95182 | assert( DbMaskTest(p->btreeMask, pOp->p5) ); | 98849 | assert( DbMaskTest(p->btreeMask, pOp->p5) ); |
| 95183 | z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, | 98850 | rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, |
| 95184 | (int)pnErr->u.i+1, &nErr); | 98851 | (int)pnErr->u.i+1, &nErr, &z); |
| 95185 | sqlite3VdbeMemSetNull(pIn1); | 98852 | sqlite3VdbeMemSetNull(pIn1); |
| 95186 | if( nErr==0 ){ | 98853 | if( nErr==0 ){ |
| 95187 | assert( z==0 ); | 98854 | assert( z==0 ); |
| 95188 | }else if( z==0 ){ | 98855 | }else if( rc ){ |
| 95189 | goto no_mem; | 98856 | sqlite3_free(z); |
| 98857 | goto abort_due_to_error; | ||
| 95190 | }else{ | 98858 | }else{ |
| 95191 | pnErr->u.i -= nErr-1; | 98859 | pnErr->u.i -= nErr-1; |
| 95192 | sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); | 98860 | sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); |
| @@ -95390,9 +99058,6 @@ case OP_Program: { /* jump */ | |||
| 95390 | pFrame->aOp = p->aOp; | 99058 | pFrame->aOp = p->aOp; |
| 95391 | pFrame->nOp = p->nOp; | 99059 | pFrame->nOp = p->nOp; |
| 95392 | pFrame->token = pProgram->token; | 99060 | pFrame->token = pProgram->token; |
| 95393 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 95394 | pFrame->anExec = p->anExec; | ||
| 95395 | #endif | ||
| 95396 | #ifdef SQLITE_DEBUG | 99061 | #ifdef SQLITE_DEBUG |
| 95397 | pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; | 99062 | pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; |
| 95398 | #endif | 99063 | #endif |
| @@ -95429,9 +99094,6 @@ case OP_Program: { /* jump */ | |||
| 95429 | memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8); | 99094 | memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8); |
| 95430 | p->aOp = aOp = pProgram->aOp; | 99095 | p->aOp = aOp = pProgram->aOp; |
| 95431 | p->nOp = pProgram->nOp; | 99096 | p->nOp = pProgram->nOp; |
| 95432 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 95433 | p->anExec = 0; | ||
| 95434 | #endif | ||
| 95435 | #ifdef SQLITE_DEBUG | 99097 | #ifdef SQLITE_DEBUG |
| 95436 | /* Verify that second and subsequent executions of the same trigger do not | 99098 | /* Verify that second and subsequent executions of the same trigger do not |
| 95437 | ** try to reuse register values from the first use. */ | 99099 | ** try to reuse register values from the first use. */ |
| @@ -95571,7 +99233,7 @@ case OP_IfPos: { /* jump, in1 */ | |||
| 95571 | ** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) | 99233 | ** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) |
| 95572 | ** | 99234 | ** |
| 95573 | ** This opcode performs a commonly used computation associated with | 99235 | ** This opcode performs a commonly used computation associated with |
| 95574 | ** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3] | 99236 | ** LIMIT and OFFSET processing. r[P1] holds the limit counter. r[P3] |
| 95575 | ** holds the offset counter. The opcode computes the combined value | 99237 | ** holds the offset counter. The opcode computes the combined value |
| 95576 | ** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] | 99238 | ** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] |
| 95577 | ** value computed is the total number of rows that will need to be | 99239 | ** value computed is the total number of rows that will need to be |
| @@ -95738,7 +99400,7 @@ case OP_AggStep1: { | |||
| 95738 | /* If this function is inside of a trigger, the register array in aMem[] | 99400 | /* If this function is inside of a trigger, the register array in aMem[] |
| 95739 | ** might change from one evaluation to the next. The next block of code | 99401 | ** might change from one evaluation to the next. The next block of code |
| 95740 | ** checks to see if the register array has changed, and if so it | 99402 | ** checks to see if the register array has changed, and if so it |
| 95741 | ** reinitializes the relavant parts of the sqlite3_context object */ | 99403 | ** reinitializes the relevant parts of the sqlite3_context object */ |
| 95742 | if( pCtx->pMem != pMem ){ | 99404 | if( pCtx->pMem != pMem ){ |
| 95743 | pCtx->pMem = pMem; | 99405 | pCtx->pMem = pMem; |
| 95744 | for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; | 99406 | for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; |
| @@ -95833,6 +99495,7 @@ case OP_AggFinal: { | |||
| 95833 | } | 99495 | } |
| 95834 | sqlite3VdbeChangeEncoding(pMem, encoding); | 99496 | sqlite3VdbeChangeEncoding(pMem, encoding); |
| 95835 | UPDATE_MAX_BLOBSIZE(pMem); | 99497 | UPDATE_MAX_BLOBSIZE(pMem); |
| 99498 | REGISTER_TRACE((int)(pMem-aMem), pMem); | ||
| 95836 | break; | 99499 | break; |
| 95837 | } | 99500 | } |
| 95838 | 99501 | ||
| @@ -96188,7 +99851,7 @@ case OP_VDestroy: { | |||
| 96188 | ** P1 is a cursor number. This opcode opens a cursor to the virtual | 99851 | ** P1 is a cursor number. This opcode opens a cursor to the virtual |
| 96189 | ** table and stores that cursor in P1. | 99852 | ** table and stores that cursor in P1. |
| 96190 | */ | 99853 | */ |
| 96191 | case OP_VOpen: { | 99854 | case OP_VOpen: { /* ncycle */ |
| 96192 | VdbeCursor *pCur; | 99855 | VdbeCursor *pCur; |
| 96193 | sqlite3_vtab_cursor *pVCur; | 99856 | sqlite3_vtab_cursor *pVCur; |
| 96194 | sqlite3_vtab *pVtab; | 99857 | sqlite3_vtab *pVtab; |
| @@ -96235,7 +99898,7 @@ case OP_VOpen: { | |||
| 96235 | ** cursor. Register P3 is used to hold the values returned by | 99898 | ** cursor. Register P3 is used to hold the values returned by |
| 96236 | ** sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). | 99899 | ** sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). |
| 96237 | */ | 99900 | */ |
| 96238 | case OP_VInitIn: { /* out2 */ | 99901 | case OP_VInitIn: { /* out2, ncycle */ |
| 96239 | VdbeCursor *pC; /* The cursor containing the RHS values */ | 99902 | VdbeCursor *pC; /* The cursor containing the RHS values */ |
| 96240 | ValueList *pRhs; /* New ValueList object to put in reg[P2] */ | 99903 | ValueList *pRhs; /* New ValueList object to put in reg[P2] */ |
| 96241 | 99904 | ||
| @@ -96246,7 +99909,7 @@ case OP_VInitIn: { /* out2 */ | |||
| 96246 | pRhs->pOut = &aMem[pOp->p3]; | 99909 | pRhs->pOut = &aMem[pOp->p3]; |
| 96247 | pOut = out2Prerelease(p, pOp); | 99910 | pOut = out2Prerelease(p, pOp); |
| 96248 | pOut->flags = MEM_Null; | 99911 | pOut->flags = MEM_Null; |
| 96249 | sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free); | 99912 | sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3VdbeValueListFree); |
| 96250 | break; | 99913 | break; |
| 96251 | } | 99914 | } |
| 96252 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ | 99915 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| @@ -96272,7 +99935,7 @@ case OP_VInitIn: { /* out2 */ | |||
| 96272 | ** | 99935 | ** |
| 96273 | ** A jump is made to P2 if the result set after filtering would be empty. | 99936 | ** A jump is made to P2 if the result set after filtering would be empty. |
| 96274 | */ | 99937 | */ |
| 96275 | case OP_VFilter: { /* jump */ | 99938 | case OP_VFilter: { /* jump, ncycle */ |
| 96276 | int nArg; | 99939 | int nArg; |
| 96277 | int iQuery; | 99940 | int iQuery; |
| 96278 | const sqlite3_module *pModule; | 99941 | const sqlite3_module *pModule; |
| @@ -96332,7 +99995,7 @@ case OP_VFilter: { /* jump */ | |||
| 96332 | ** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are | 99995 | ** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are |
| 96333 | ** unused by OP_VColumn. | 99996 | ** unused by OP_VColumn. |
| 96334 | */ | 99997 | */ |
| 96335 | case OP_VColumn: { | 99998 | case OP_VColumn: { /* ncycle */ |
| 96336 | sqlite3_vtab *pVtab; | 99999 | sqlite3_vtab *pVtab; |
| 96337 | const sqlite3_module *pModule; | 100000 | const sqlite3_module *pModule; |
| 96338 | Mem *pDest; | 100001 | Mem *pDest; |
| @@ -96384,7 +100047,7 @@ case OP_VColumn: { | |||
| 96384 | ** jump to instruction P2. Or, if the virtual table has reached | 100047 | ** jump to instruction P2. Or, if the virtual table has reached |
| 96385 | ** the end of its result set, then fall through to the next instruction. | 100048 | ** the end of its result set, then fall through to the next instruction. |
| 96386 | */ | 100049 | */ |
| 96387 | case OP_VNext: { /* jump */ | 100050 | case OP_VNext: { /* jump, ncycle */ |
| 96388 | sqlite3_vtab *pVtab; | 100051 | sqlite3_vtab *pVtab; |
| 96389 | const sqlite3_module *pModule; | 100052 | const sqlite3_module *pModule; |
| 96390 | int res; | 100053 | int res; |
| @@ -96615,7 +100278,7 @@ case OP_MaxPgcnt: { /* out2 */ | |||
| 96615 | ** This opcode works exactly like OP_Function. The only difference is in | 100278 | ** This opcode works exactly like OP_Function. The only difference is in |
| 96616 | ** its name. This opcode is used in places where the function must be | 100279 | ** its name. This opcode is used in places where the function must be |
| 96617 | ** purely non-deterministic. Some built-in date/time functions can be | 100280 | ** purely non-deterministic. Some built-in date/time functions can be |
| 96618 | ** either determinitic of non-deterministic, depending on their arguments. | 100281 | ** either deterministic of non-deterministic, depending on their arguments. |
| 96619 | ** When those function are used in a non-deterministic way, they will check | 100282 | ** When those function are used in a non-deterministic way, they will check |
| 96620 | ** to see if they were called using OP_PureFunc instead of OP_Function, and | 100283 | ** to see if they were called using OP_PureFunc instead of OP_Function, and |
| 96621 | ** if they were, they throw an error. | 100284 | ** if they were, they throw an error. |
| @@ -96633,7 +100296,7 @@ case OP_Function: { /* group */ | |||
| 96633 | /* If this function is inside of a trigger, the register array in aMem[] | 100296 | /* If this function is inside of a trigger, the register array in aMem[] |
| 96634 | ** might change from one evaluation to the next. The next block of code | 100297 | ** might change from one evaluation to the next. The next block of code |
| 96635 | ** checks to see if the register array has changed, and if so it | 100298 | ** checks to see if the register array has changed, and if so it |
| 96636 | ** reinitializes the relavant parts of the sqlite3_context object */ | 100299 | ** reinitializes the relevant parts of the sqlite3_context object */ |
| 96637 | pOut = &aMem[pOp->p3]; | 100300 | pOut = &aMem[pOp->p3]; |
| 96638 | if( pCtx->pOut != pOut ){ | 100301 | if( pCtx->pOut != pOut ){ |
| 96639 | pCtx->pVdbe = p; | 100302 | pCtx->pVdbe = p; |
| @@ -96709,7 +100372,7 @@ case OP_FilterAdd: { | |||
| 96709 | printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); | 100372 | printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); |
| 96710 | } | 100373 | } |
| 96711 | #endif | 100374 | #endif |
| 96712 | h %= pIn1->n; | 100375 | h %= (pIn1->n*8); |
| 96713 | pIn1->z[h/8] |= 1<<(h&7); | 100376 | pIn1->z[h/8] |= 1<<(h&7); |
| 96714 | break; | 100377 | break; |
| 96715 | } | 100378 | } |
| @@ -96745,7 +100408,7 @@ case OP_Filter: { /* jump */ | |||
| 96745 | printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); | 100408 | printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); |
| 96746 | } | 100409 | } |
| 96747 | #endif | 100410 | #endif |
| 96748 | h %= pIn1->n; | 100411 | h %= (pIn1->n*8); |
| 96749 | if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ | 100412 | if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ |
| 96750 | VdbeBranchTaken(1, 2); | 100413 | VdbeBranchTaken(1, 2); |
| 96751 | p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; | 100414 | p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; |
| @@ -96967,11 +100630,13 @@ default: { /* This is really OP_Noop, OP_Explain */ | |||
| 96967 | *****************************************************************************/ | 100630 | *****************************************************************************/ |
| 96968 | } | 100631 | } |
| 96969 | 100632 | ||
| 96970 | #ifdef VDBE_PROFILE | 100633 | #if defined(VDBE_PROFILE) |
| 96971 | { | 100634 | *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); |
| 96972 | u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); | 100635 | pnCycle = 0; |
| 96973 | if( endTime>start ) pOrigOp->cycles += endTime - start; | 100636 | #elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) |
| 96974 | pOrigOp->cnt++; | 100637 | if( pnCycle ){ |
| 100638 | *pnCycle += sqlite3Hwtime(); | ||
| 100639 | pnCycle = 0; | ||
| 96975 | } | 100640 | } |
| 96976 | #endif | 100641 | #endif |
| 96977 | 100642 | ||
| @@ -96995,7 +100660,7 @@ default: { /* This is really OP_Noop, OP_Explain */ | |||
| 96995 | } | 100660 | } |
| 96996 | if( opProperty==0xff ){ | 100661 | if( opProperty==0xff ){ |
| 96997 | /* Never happens. This code exists to avoid a harmless linkage | 100662 | /* Never happens. This code exists to avoid a harmless linkage |
| 96998 | ** warning aboud sqlite3VdbeRegisterDump() being defined but not | 100663 | ** warning about sqlite3VdbeRegisterDump() being defined but not |
| 96999 | ** used. */ | 100664 | ** used. */ |
| 97000 | sqlite3VdbeRegisterDump(p); | 100665 | sqlite3VdbeRegisterDump(p); |
| 97001 | } | 100666 | } |
| @@ -97048,6 +100713,18 @@ abort_due_to_error: | |||
| 97048 | ** release the mutexes on btrees that were acquired at the | 100713 | ** release the mutexes on btrees that were acquired at the |
| 97049 | ** top. */ | 100714 | ** top. */ |
| 97050 | vdbe_return: | 100715 | vdbe_return: |
| 100716 | #if defined(VDBE_PROFILE) | ||
| 100717 | if( pnCycle ){ | ||
| 100718 | *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); | ||
| 100719 | pnCycle = 0; | ||
| 100720 | } | ||
| 100721 | #elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) | ||
| 100722 | if( pnCycle ){ | ||
| 100723 | *pnCycle += sqlite3Hwtime(); | ||
| 100724 | pnCycle = 0; | ||
| 100725 | } | ||
| 100726 | #endif | ||
| 100727 | |||
| 97051 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | 100728 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 97052 | while( nVmStep>=nProgressLimit && db->xProgress!=0 ){ | 100729 | while( nVmStep>=nProgressLimit && db->xProgress!=0 ){ |
| 97053 | nProgressLimit += db->nProgressOps; | 100730 | nProgressLimit += db->nProgressOps; |
| @@ -97059,7 +100736,9 @@ vdbe_return: | |||
| 97059 | } | 100736 | } |
| 97060 | #endif | 100737 | #endif |
| 97061 | p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; | 100738 | p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; |
| 97062 | sqlite3VdbeLeave(p); | 100739 | if( DbMaskNonZero(p->lockMask) ){ |
| 100740 | sqlite3VdbeLeave(p); | ||
| 100741 | } | ||
| 97063 | assert( rc!=SQLITE_OK || nExtraDelete==0 | 100742 | assert( rc!=SQLITE_OK || nExtraDelete==0 |
| 97064 | || sqlite3_strlike("DELETE%",p->zSql,0)!=0 | 100743 | || sqlite3_strlike("DELETE%",p->zSql,0)!=0 |
| 97065 | ); | 100744 | ); |
| @@ -97437,7 +101116,7 @@ blob_open_out: | |||
| 97437 | if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); | 101116 | if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); |
| 97438 | sqlite3DbFree(db, pBlob); | 101117 | sqlite3DbFree(db, pBlob); |
| 97439 | } | 101118 | } |
| 97440 | sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); | 101119 | sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); |
| 97441 | sqlite3DbFree(db, zErr); | 101120 | sqlite3DbFree(db, zErr); |
| 97442 | sqlite3ParseObjectReset(&sParse); | 101121 | sqlite3ParseObjectReset(&sParse); |
| 97443 | rc = sqlite3ApiExit(db, rc); | 101122 | rc = sqlite3ApiExit(db, rc); |
| @@ -97596,7 +101275,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ | |||
| 97596 | ((Vdbe*)p->pStmt)->rc = SQLITE_OK; | 101275 | ((Vdbe*)p->pStmt)->rc = SQLITE_OK; |
| 97597 | rc = blobSeekToRow(p, iRow, &zErr); | 101276 | rc = blobSeekToRow(p, iRow, &zErr); |
| 97598 | if( rc!=SQLITE_OK ){ | 101277 | if( rc!=SQLITE_OK ){ |
| 97599 | sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); | 101278 | sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); |
| 97600 | sqlite3DbFree(db, zErr); | 101279 | sqlite3DbFree(db, zErr); |
| 97601 | } | 101280 | } |
| 97602 | assert( rc!=SQLITE_SCHEMA ); | 101281 | assert( rc!=SQLITE_SCHEMA ); |
| @@ -97699,7 +101378,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ | |||
| 97699 | ** The threshold for the amount of main memory to use before flushing | 101378 | ** The threshold for the amount of main memory to use before flushing |
| 97700 | ** records to a PMA is roughly the same as the limit configured for the | 101379 | ** records to a PMA is roughly the same as the limit configured for the |
| 97701 | ** page-cache of the main database. Specifically, the threshold is set to | 101380 | ** page-cache of the main database. Specifically, the threshold is set to |
| 97702 | ** the value returned by "PRAGMA main.page_size" multipled by | 101381 | ** the value returned by "PRAGMA main.page_size" multiplied by |
| 97703 | ** that returned by "PRAGMA main.cache_size", in bytes. | 101382 | ** that returned by "PRAGMA main.cache_size", in bytes. |
| 97704 | ** | 101383 | ** |
| 97705 | ** If the sorter is running in single-threaded mode, then all PMAs generated | 101384 | ** If the sorter is running in single-threaded mode, then all PMAs generated |
| @@ -97722,7 +101401,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ | |||
| 97722 | ** | 101401 | ** |
| 97723 | ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the | 101402 | ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the |
| 97724 | ** sorter is running in single-threaded mode, then these PMAs are merged | 101403 | ** sorter is running in single-threaded mode, then these PMAs are merged |
| 97725 | ** incrementally as keys are retreived from the sorter by the VDBE. The | 101404 | ** incrementally as keys are retrieved from the sorter by the VDBE. The |
| 97726 | ** MergeEngine object, described in further detail below, performs this | 101405 | ** MergeEngine object, described in further detail below, performs this |
| 97727 | ** merge. | 101406 | ** merge. |
| 97728 | ** | 101407 | ** |
| @@ -97885,7 +101564,7 @@ struct MergeEngine { | |||
| 97885 | ** | 101564 | ** |
| 97886 | ** Essentially, this structure contains all those fields of the VdbeSorter | 101565 | ** Essentially, this structure contains all those fields of the VdbeSorter |
| 97887 | ** structure for which each thread requires a separate instance. For example, | 101566 | ** structure for which each thread requires a separate instance. For example, |
| 97888 | ** each thread requries its own UnpackedRecord object to unpack records in | 101567 | ** each thread requeries its own UnpackedRecord object to unpack records in |
| 97889 | ** as part of comparison operations. | 101568 | ** as part of comparison operations. |
| 97890 | ** | 101569 | ** |
| 97891 | ** Before a background thread is launched, variable bDone is set to 0. Then, | 101570 | ** Before a background thread is launched, variable bDone is set to 0. Then, |
| @@ -97957,7 +101636,7 @@ struct VdbeSorter { | |||
| 97957 | ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. | 101636 | ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. |
| 97958 | ** aKey might point into aMap or into aBuffer. If neither of those locations | 101637 | ** aKey might point into aMap or into aBuffer. If neither of those locations |
| 97959 | ** contain a contiguous representation of the key, then aAlloc is allocated | 101638 | ** contain a contiguous representation of the key, then aAlloc is allocated |
| 97960 | ** and the key is copied into aAlloc and aKey is made to poitn to aAlloc. | 101639 | ** and the key is copied into aAlloc and aKey is made to point to aAlloc. |
| 97961 | ** | 101640 | ** |
| 97962 | ** pFd==0 at EOF. | 101641 | ** pFd==0 at EOF. |
| 97963 | */ | 101642 | */ |
| @@ -99328,7 +103007,7 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ | |||
| 99328 | ** the background thread from a sub-tasks previous turn is still running, | 103007 | ** the background thread from a sub-tasks previous turn is still running, |
| 99329 | ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, | 103008 | ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, |
| 99330 | ** fall back to using the final sub-task. The first (pSorter->nTask-1) | 103009 | ** fall back to using the final sub-task. The first (pSorter->nTask-1) |
| 99331 | ** sub-tasks are prefered as they use background threads - the final | 103010 | ** sub-tasks are preferred as they use background threads - the final |
| 99332 | ** sub-task uses the main thread. */ | 103011 | ** sub-task uses the main thread. */ |
| 99333 | for(i=0; i<nWorker; i++){ | 103012 | for(i=0; i<nWorker; i++){ |
| 99334 | int iTest = (pSorter->iPrev + i + 1) % nWorker; | 103013 | int iTest = (pSorter->iPrev + i + 1) % nWorker; |
| @@ -99812,7 +103491,7 @@ static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ | |||
| 99812 | 103491 | ||
| 99813 | rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); | 103492 | rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); |
| 99814 | 103493 | ||
| 99815 | /* Set up the required files for pIncr. A multi-theaded IncrMerge object | 103494 | /* Set up the required files for pIncr. A multi-threaded IncrMerge object |
| 99816 | ** requires two temp files to itself, whereas a single-threaded object | 103495 | ** requires two temp files to itself, whereas a single-threaded object |
| 99817 | ** only requires a region of pTask->file2. */ | 103496 | ** only requires a region of pTask->file2. */ |
| 99818 | if( rc==SQLITE_OK ){ | 103497 | if( rc==SQLITE_OK ){ |
| @@ -100452,6 +104131,8 @@ static int bytecodevtabConnect( | |||
| 100452 | "p5 INT," | 104131 | "p5 INT," |
| 100453 | "comment TEXT," | 104132 | "comment TEXT," |
| 100454 | "subprog TEXT," | 104133 | "subprog TEXT," |
| 104134 | "nexec INT," | ||
| 104135 | "ncycle INT," | ||
| 100455 | "stmt HIDDEN" | 104136 | "stmt HIDDEN" |
| 100456 | ");", | 104137 | ");", |
| 100457 | 104138 | ||
| @@ -100466,6 +104147,9 @@ static int bytecodevtabConnect( | |||
| 100466 | ");" | 104147 | ");" |
| 100467 | }; | 104148 | }; |
| 100468 | 104149 | ||
| 104150 | (void)argc; | ||
| 104151 | (void)argv; | ||
| 104152 | (void)pzErr; | ||
| 100469 | rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]); | 104153 | rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]); |
| 100470 | if( rc==SQLITE_OK ){ | 104154 | if( rc==SQLITE_OK ){ |
| 100471 | pNew = sqlite3_malloc( sizeof(*pNew) ); | 104155 | pNew = sqlite3_malloc( sizeof(*pNew) ); |
| @@ -100611,7 +104295,7 @@ static int bytecodevtabColumn( | |||
| 100611 | } | 104295 | } |
| 100612 | } | 104296 | } |
| 100613 | } | 104297 | } |
| 100614 | i += 10; | 104298 | i += 20; |
| 100615 | } | 104299 | } |
| 100616 | } | 104300 | } |
| 100617 | switch( i ){ | 104301 | switch( i ){ |
| @@ -100661,16 +104345,31 @@ static int bytecodevtabColumn( | |||
| 100661 | } | 104345 | } |
| 100662 | break; | 104346 | break; |
| 100663 | } | 104347 | } |
| 100664 | case 10: /* tables_used.type */ | 104348 | |
| 104349 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 104350 | case 9: /* nexec */ | ||
| 104351 | sqlite3_result_int(ctx, pOp->nExec); | ||
| 104352 | break; | ||
| 104353 | case 10: /* ncycle */ | ||
| 104354 | sqlite3_result_int(ctx, pOp->nCycle); | ||
| 104355 | break; | ||
| 104356 | #else | ||
| 104357 | case 9: /* nexec */ | ||
| 104358 | case 10: /* ncycle */ | ||
| 104359 | sqlite3_result_int(ctx, 0); | ||
| 104360 | break; | ||
| 104361 | #endif | ||
| 104362 | |||
| 104363 | case 20: /* tables_used.type */ | ||
| 100665 | sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC); | 104364 | sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC); |
| 100666 | break; | 104365 | break; |
| 100667 | case 11: /* tables_used.schema */ | 104366 | case 21: /* tables_used.schema */ |
| 100668 | sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC); | 104367 | sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC); |
| 100669 | break; | 104368 | break; |
| 100670 | case 12: /* tables_used.name */ | 104369 | case 22: /* tables_used.name */ |
| 100671 | sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC); | 104370 | sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC); |
| 100672 | break; | 104371 | break; |
| 100673 | case 13: /* tables_used.wr */ | 104372 | case 23: /* tables_used.wr */ |
| 100674 | sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite); | 104373 | sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite); |
| 100675 | break; | 104374 | break; |
| 100676 | } | 104375 | } |
| @@ -100701,6 +104400,7 @@ static int bytecodevtabFilter( | |||
| 100701 | bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor; | 104400 | bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor; |
| 100702 | bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab; | 104401 | bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab; |
| 100703 | int rc = SQLITE_OK; | 104402 | int rc = SQLITE_OK; |
| 104403 | (void)idxStr; | ||
| 100704 | 104404 | ||
| 100705 | bytecodevtabCursorClear(pCur); | 104405 | bytecodevtabCursorClear(pCur); |
| 100706 | pCur->iRowid = 0; | 104406 | pCur->iRowid = 0; |
| @@ -100743,7 +104443,7 @@ static int bytecodevtabBestIndex( | |||
| 100743 | int rc = SQLITE_CONSTRAINT; | 104443 | int rc = SQLITE_CONSTRAINT; |
| 100744 | struct sqlite3_index_constraint *p; | 104444 | struct sqlite3_index_constraint *p; |
| 100745 | bytecodevtab *pVTab = (bytecodevtab*)tab; | 104445 | bytecodevtab *pVTab = (bytecodevtab*)tab; |
| 100746 | int iBaseCol = pVTab->bTablesUsed ? 4 : 8; | 104446 | int iBaseCol = pVTab->bTablesUsed ? 4 : 10; |
| 100747 | pIdxInfo->estimatedCost = (double)100; | 104447 | pIdxInfo->estimatedCost = (double)100; |
| 100748 | pIdxInfo->estimatedRows = 100; | 104448 | pIdxInfo->estimatedRows = 100; |
| 100749 | pIdxInfo->idxNum = 0; | 104449 | pIdxInfo->idxNum = 0; |
| @@ -101169,6 +104869,8 @@ SQLITE_PRIVATE int sqlite3JournalOpen( | |||
| 101169 | ){ | 104869 | ){ |
| 101170 | MemJournal *p = (MemJournal*)pJfd; | 104870 | MemJournal *p = (MemJournal*)pJfd; |
| 101171 | 104871 | ||
| 104872 | assert( zName || nSpill<0 || (flags & SQLITE_OPEN_EXCLUSIVE) ); | ||
| 104873 | |||
| 101172 | /* Zero the file-handle object. If nSpill was passed zero, initialize | 104874 | /* Zero the file-handle object. If nSpill was passed zero, initialize |
| 101173 | ** it using the sqlite3OsOpen() function of the underlying VFS. In this | 104875 | ** it using the sqlite3OsOpen() function of the underlying VFS. In this |
| 101174 | ** case none of the code in this module is executed as a result of calls | 104876 | ** case none of the code in this module is executed as a result of calls |
| @@ -101312,7 +105014,7 @@ static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){ | |||
| 101312 | ** The return value from this routine is WRC_Abort to abandon the tree walk | 105014 | ** The return value from this routine is WRC_Abort to abandon the tree walk |
| 101313 | ** and WRC_Continue to continue. | 105015 | ** and WRC_Continue to continue. |
| 101314 | */ | 105016 | */ |
| 101315 | static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ | 105017 | SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3WalkExprNN(Walker *pWalker, Expr *pExpr){ |
| 101316 | int rc; | 105018 | int rc; |
| 101317 | testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); | 105019 | testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); |
| 101318 | testcase( ExprHasProperty(pExpr, EP_Reduced) ); | 105020 | testcase( ExprHasProperty(pExpr, EP_Reduced) ); |
| @@ -101321,7 +105023,9 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ | |||
| 101321 | if( rc ) return rc & WRC_Abort; | 105023 | if( rc ) return rc & WRC_Abort; |
| 101322 | if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ | 105024 | if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ |
| 101323 | assert( pExpr->x.pList==0 || pExpr->pRight==0 ); | 105025 | assert( pExpr->x.pList==0 || pExpr->pRight==0 ); |
| 101324 | if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; | 105026 | if( pExpr->pLeft && sqlite3WalkExprNN(pWalker, pExpr->pLeft) ){ |
| 105027 | return WRC_Abort; | ||
| 105028 | } | ||
| 101325 | if( pExpr->pRight ){ | 105029 | if( pExpr->pRight ){ |
| 101326 | assert( !ExprHasProperty(pExpr, EP_WinFunc) ); | 105030 | assert( !ExprHasProperty(pExpr, EP_WinFunc) ); |
| 101327 | pExpr = pExpr->pRight; | 105031 | pExpr = pExpr->pRight; |
| @@ -101345,7 +105049,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ | |||
| 101345 | return WRC_Continue; | 105049 | return WRC_Continue; |
| 101346 | } | 105050 | } |
| 101347 | SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ | 105051 | SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ |
| 101348 | return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue; | 105052 | return pExpr ? sqlite3WalkExprNN(pWalker,pExpr) : WRC_Continue; |
| 101349 | } | 105053 | } |
| 101350 | 105054 | ||
| 101351 | /* | 105055 | /* |
| @@ -101471,7 +105175,7 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ | |||
| 101471 | } | 105175 | } |
| 101472 | 105176 | ||
| 101473 | /* Increase the walkerDepth when entering a subquery, and | 105177 | /* Increase the walkerDepth when entering a subquery, and |
| 101474 | ** descrease when leaving the subquery. | 105178 | ** decrease when leaving the subquery. |
| 101475 | */ | 105179 | */ |
| 101476 | SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){ | 105180 | SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){ |
| 101477 | UNUSED_PARAMETER(pSelect); | 105181 | UNUSED_PARAMETER(pSelect); |
| @@ -101610,9 +105314,7 @@ static void resolveAlias( | |||
| 101610 | pExpr->y.pWin->pOwner = pExpr; | 105314 | pExpr->y.pWin->pOwner = pExpr; |
| 101611 | } | 105315 | } |
| 101612 | } | 105316 | } |
| 101613 | sqlite3ParserAddCleanup(pParse, | 105317 | sqlite3ExprDeferredDelete(pParse, pDup); |
| 101614 | (void(*)(sqlite3*,void*))sqlite3ExprDelete, | ||
| 101615 | pDup); | ||
| 101616 | } | 105318 | } |
| 101617 | } | 105319 | } |
| 101618 | 105320 | ||
| @@ -101716,6 +105418,32 @@ static void extendFJMatch( | |||
| 101716 | } | 105418 | } |
| 101717 | 105419 | ||
| 101718 | /* | 105420 | /* |
| 105421 | ** Return TRUE (non-zero) if zTab is a valid name for the schema table pTab. | ||
| 105422 | */ | ||
| 105423 | static SQLITE_NOINLINE int isValidSchemaTableName( | ||
| 105424 | const char *zTab, /* Name as it appears in the SQL */ | ||
| 105425 | Table *pTab, /* The schema table we are trying to match */ | ||
| 105426 | Schema *pSchema /* non-NULL if a database qualifier is present */ | ||
| 105427 | ){ | ||
| 105428 | const char *zLegacy; | ||
| 105429 | assert( pTab!=0 ); | ||
| 105430 | assert( pTab->tnum==1 ); | ||
| 105431 | if( sqlite3StrNICmp(zTab, "sqlite_", 7)!=0 ) return 0; | ||
| 105432 | zLegacy = pTab->zName; | ||
| 105433 | if( strcmp(zLegacy+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ | ||
| 105434 | if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ | ||
| 105435 | return 1; | ||
| 105436 | } | ||
| 105437 | if( pSchema==0 ) return 0; | ||
| 105438 | if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; | ||
| 105439 | if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; | ||
| 105440 | }else{ | ||
| 105441 | if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; | ||
| 105442 | } | ||
| 105443 | return 0; | ||
| 105444 | } | ||
| 105445 | |||
| 105446 | /* | ||
| 101719 | ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up | 105447 | ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up |
| 101720 | ** that name in the set of source tables in pSrcList and make the pExpr | 105448 | ** that name in the set of source tables in pSrcList and make the pExpr |
| 101721 | ** expression node refer back to that source column. The following changes | 105449 | ** expression node refer back to that source column. The following changes |
| @@ -101868,15 +105596,17 @@ static int lookupName( | |||
| 101868 | } | 105596 | } |
| 101869 | assert( zDb==0 || zTab!=0 ); | 105597 | assert( zDb==0 || zTab!=0 ); |
| 101870 | if( zTab ){ | 105598 | if( zTab ){ |
| 101871 | const char *zTabName; | ||
| 101872 | if( zDb ){ | 105599 | if( zDb ){ |
| 101873 | if( pTab->pSchema!=pSchema ) continue; | 105600 | if( pTab->pSchema!=pSchema ) continue; |
| 101874 | if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; | 105601 | if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; |
| 101875 | } | 105602 | } |
| 101876 | zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; | 105603 | if( pItem->zAlias!=0 ){ |
| 101877 | assert( zTabName!=0 ); | 105604 | if( sqlite3StrICmp(zTab, pItem->zAlias)!=0 ){ |
| 101878 | if( sqlite3StrICmp(zTabName, zTab)!=0 ){ | 105605 | continue; |
| 101879 | continue; | 105606 | } |
| 105607 | }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ | ||
| 105608 | if( pTab->tnum!=1 ) continue; | ||
| 105609 | if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue; | ||
| 101880 | } | 105610 | } |
| 101881 | assert( ExprUseYTab(pExpr) ); | 105611 | assert( ExprUseYTab(pExpr) ); |
| 101882 | if( IN_RENAME_OBJECT && pItem->zAlias ){ | 105612 | if( IN_RENAME_OBJECT && pItem->zAlias ){ |
| @@ -101952,7 +105682,8 @@ static int lookupName( | |||
| 101952 | assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); | 105682 | assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); |
| 101953 | if( pParse->bReturning ){ | 105683 | if( pParse->bReturning ){ |
| 101954 | if( (pNC->ncFlags & NC_UBaseReg)!=0 | 105684 | if( (pNC->ncFlags & NC_UBaseReg)!=0 |
| 101955 | && (zTab==0 || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) | 105685 | && ALWAYS(zTab==0 |
| 105686 | || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) | ||
| 101956 | ){ | 105687 | ){ |
| 101957 | pExpr->iTable = op!=TK_DELETE; | 105688 | pExpr->iTable = op!=TK_DELETE; |
| 101958 | pTab = pParse->pTriggerTab; | 105689 | pTab = pParse->pTriggerTab; |
| @@ -102019,6 +105750,7 @@ static int lookupName( | |||
| 102019 | if( pParse->bReturning ){ | 105750 | if( pParse->bReturning ){ |
| 102020 | eNewExprOp = TK_REGISTER; | 105751 | eNewExprOp = TK_REGISTER; |
| 102021 | pExpr->op2 = TK_COLUMN; | 105752 | pExpr->op2 = TK_COLUMN; |
| 105753 | pExpr->iColumn = iCol; | ||
| 102022 | pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + | 105754 | pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + |
| 102023 | sqlite3TableColumnToStorage(pTab, iCol) + 1; | 105755 | sqlite3TableColumnToStorage(pTab, iCol) + 1; |
| 102024 | }else{ | 105756 | }else{ |
| @@ -102431,14 +106163,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 102431 | if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ | 106163 | if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ |
| 102432 | testcase( ExprHasProperty(pExpr, EP_OuterON) ); | 106164 | testcase( ExprHasProperty(pExpr, EP_OuterON) ); |
| 102433 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 106165 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 102434 | if( pExpr->op==TK_NOTNULL ){ | 106166 | pExpr->u.iValue = (pExpr->op==TK_NOTNULL); |
| 102435 | pExpr->u.zToken = "true"; | 106167 | pExpr->flags |= EP_IntValue; |
| 102436 | ExprSetProperty(pExpr, EP_IsTrue); | 106168 | pExpr->op = TK_INTEGER; |
| 102437 | }else{ | 106169 | |
| 102438 | pExpr->u.zToken = "false"; | ||
| 102439 | ExprSetProperty(pExpr, EP_IsFalse); | ||
| 102440 | } | ||
| 102441 | pExpr->op = TK_TRUEFALSE; | ||
| 102442 | for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){ | 106170 | for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){ |
| 102443 | p->nRef = anRef[i]; | 106171 | p->nRef = anRef[i]; |
| 102444 | } | 106172 | } |
| @@ -102740,8 +106468,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ | |||
| 102740 | assert( pNC->nRef>=nRef ); | 106468 | assert( pNC->nRef>=nRef ); |
| 102741 | if( nRef!=pNC->nRef ){ | 106469 | if( nRef!=pNC->nRef ){ |
| 102742 | ExprSetProperty(pExpr, EP_VarSelect); | 106470 | ExprSetProperty(pExpr, EP_VarSelect); |
| 102743 | pNC->ncFlags |= NC_VarSelect; | ||
| 102744 | } | 106471 | } |
| 106472 | pNC->ncFlags |= NC_Subquery; | ||
| 102745 | } | 106473 | } |
| 102746 | break; | 106474 | break; |
| 102747 | } | 106475 | } |
| @@ -103181,7 +106909,7 @@ static int resolveOrderGroupBy( | |||
| 103181 | } | 106909 | } |
| 103182 | for(j=0; j<pSelect->pEList->nExpr; j++){ | 106910 | for(j=0; j<pSelect->pEList->nExpr; j++){ |
| 103183 | if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ | 106911 | if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ |
| 103184 | /* Since this expresion is being changed into a reference | 106912 | /* Since this expression is being changed into a reference |
| 103185 | ** to an identical expression in the result set, remove all Window | 106913 | ** to an identical expression in the result set, remove all Window |
| 103186 | ** objects belonging to the expression from the Select.pWin list. */ | 106914 | ** objects belonging to the expression from the Select.pWin list. */ |
| 103187 | windowRemoveExprFromSelect(pSelect, pE); | 106915 | windowRemoveExprFromSelect(pSelect, pE); |
| @@ -103504,7 +107232,8 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames( | |||
| 103504 | return SQLITE_ERROR; | 107232 | return SQLITE_ERROR; |
| 103505 | } | 107233 | } |
| 103506 | #endif | 107234 | #endif |
| 103507 | sqlite3WalkExpr(&w, pExpr); | 107235 | assert( pExpr!=0 ); |
| 107236 | sqlite3WalkExprNN(&w, pExpr); | ||
| 103508 | #if SQLITE_MAX_EXPR_DEPTH>0 | 107237 | #if SQLITE_MAX_EXPR_DEPTH>0 |
| 103509 | w.pParse->nHeight -= pExpr->nHeight; | 107238 | w.pParse->nHeight -= pExpr->nHeight; |
| 103510 | #endif | 107239 | #endif |
| @@ -103546,7 +107275,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( | |||
| 103546 | return WRC_Abort; | 107275 | return WRC_Abort; |
| 103547 | } | 107276 | } |
| 103548 | #endif | 107277 | #endif |
| 103549 | sqlite3WalkExpr(&w, pExpr); | 107278 | sqlite3WalkExprNN(&w, pExpr); |
| 103550 | #if SQLITE_MAX_EXPR_DEPTH>0 | 107279 | #if SQLITE_MAX_EXPR_DEPTH>0 |
| 103551 | w.pParse->nHeight -= pExpr->nHeight; | 107280 | w.pParse->nHeight -= pExpr->nHeight; |
| 103552 | #endif | 107281 | #endif |
| @@ -103568,7 +107297,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( | |||
| 103568 | 107297 | ||
| 103569 | /* | 107298 | /* |
| 103570 | ** Resolve all names in all expressions of a SELECT and in all | 107299 | ** Resolve all names in all expressions of a SELECT and in all |
| 103571 | ** decendents of the SELECT, including compounds off of p->pPrior, | 107300 | ** descendants of the SELECT, including compounds off of p->pPrior, |
| 103572 | ** subqueries in expressions, and subqueries used as FROM clause | 107301 | ** subqueries in expressions, and subqueries used as FROM clause |
| 103573 | ** terms. | 107302 | ** terms. |
| 103574 | ** | 107303 | ** |
| @@ -103695,50 +107424,123 @@ SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){ | |||
| 103695 | */ | 107424 | */ |
| 103696 | SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ | 107425 | SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ |
| 103697 | int op; | 107426 | int op; |
| 103698 | while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ | ||
| 103699 | assert( pExpr->op==TK_COLLATE | ||
| 103700 | || pExpr->op==TK_IF_NULL_ROW | ||
| 103701 | || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); | ||
| 103702 | pExpr = pExpr->pLeft; | ||
| 103703 | assert( pExpr!=0 ); | ||
| 103704 | } | ||
| 103705 | op = pExpr->op; | 107427 | op = pExpr->op; |
| 103706 | if( op==TK_REGISTER ) op = pExpr->op2; | 107428 | while( 1 /* exit-by-break */ ){ |
| 103707 | if( op==TK_COLUMN || op==TK_AGG_COLUMN ){ | 107429 | if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){ |
| 103708 | assert( ExprUseYTab(pExpr) ); | 107430 | assert( ExprUseYTab(pExpr) ); |
| 103709 | if( pExpr->y.pTab ){ | 107431 | assert( pExpr->y.pTab!=0 ); |
| 103710 | return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); | 107432 | return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); |
| 103711 | } | 107433 | } |
| 103712 | } | 107434 | if( op==TK_SELECT ){ |
| 103713 | if( op==TK_SELECT ){ | 107435 | assert( ExprUseXSelect(pExpr) ); |
| 103714 | assert( ExprUseXSelect(pExpr) ); | 107436 | assert( pExpr->x.pSelect!=0 ); |
| 103715 | assert( pExpr->x.pSelect!=0 ); | 107437 | assert( pExpr->x.pSelect->pEList!=0 ); |
| 103716 | assert( pExpr->x.pSelect->pEList!=0 ); | 107438 | assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); |
| 103717 | assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); | 107439 | return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); |
| 103718 | return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); | 107440 | } |
| 103719 | } | ||
| 103720 | #ifndef SQLITE_OMIT_CAST | 107441 | #ifndef SQLITE_OMIT_CAST |
| 103721 | if( op==TK_CAST ){ | 107442 | if( op==TK_CAST ){ |
| 103722 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 107443 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 103723 | return sqlite3AffinityType(pExpr->u.zToken, 0); | 107444 | return sqlite3AffinityType(pExpr->u.zToken, 0); |
| 103724 | } | 107445 | } |
| 103725 | #endif | 107446 | #endif |
| 103726 | if( op==TK_SELECT_COLUMN ){ | 107447 | if( op==TK_SELECT_COLUMN ){ |
| 103727 | assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); | 107448 | assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); |
| 103728 | assert( pExpr->iColumn < pExpr->iTable ); | 107449 | assert( pExpr->iColumn < pExpr->iTable ); |
| 103729 | assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); | 107450 | assert( pExpr->iColumn >= 0 ); |
| 103730 | return sqlite3ExprAffinity( | 107451 | assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); |
| 103731 | pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr | 107452 | return sqlite3ExprAffinity( |
| 103732 | ); | 107453 | pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr |
| 103733 | } | 107454 | ); |
| 103734 | if( op==TK_VECTOR ){ | 107455 | } |
| 103735 | assert( ExprUseXList(pExpr) ); | 107456 | if( op==TK_VECTOR ){ |
| 103736 | return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); | 107457 | assert( ExprUseXList(pExpr) ); |
| 107458 | return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); | ||
| 107459 | } | ||
| 107460 | if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ | ||
| 107461 | assert( pExpr->op==TK_COLLATE | ||
| 107462 | || pExpr->op==TK_IF_NULL_ROW | ||
| 107463 | || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); | ||
| 107464 | pExpr = pExpr->pLeft; | ||
| 107465 | op = pExpr->op; | ||
| 107466 | continue; | ||
| 107467 | } | ||
| 107468 | if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; | ||
| 103737 | } | 107469 | } |
| 103738 | return pExpr->affExpr; | 107470 | return pExpr->affExpr; |
| 103739 | } | 107471 | } |
| 103740 | 107472 | ||
| 103741 | /* | 107473 | /* |
| 107474 | ** Make a guess at all the possible datatypes of the result that could | ||
| 107475 | ** be returned by an expression. Return a bitmask indicating the answer: | ||
| 107476 | ** | ||
| 107477 | ** 0x01 Numeric | ||
| 107478 | ** 0x02 Text | ||
| 107479 | ** 0x04 Blob | ||
| 107480 | ** | ||
| 107481 | ** If the expression must return NULL, then 0x00 is returned. | ||
| 107482 | */ | ||
| 107483 | SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr){ | ||
| 107484 | while( pExpr ){ | ||
| 107485 | switch( pExpr->op ){ | ||
| 107486 | case TK_COLLATE: | ||
| 107487 | case TK_IF_NULL_ROW: | ||
| 107488 | case TK_UPLUS: { | ||
| 107489 | pExpr = pExpr->pLeft; | ||
| 107490 | break; | ||
| 107491 | } | ||
| 107492 | case TK_NULL: { | ||
| 107493 | pExpr = 0; | ||
| 107494 | break; | ||
| 107495 | } | ||
| 107496 | case TK_STRING: { | ||
| 107497 | return 0x02; | ||
| 107498 | } | ||
| 107499 | case TK_BLOB: { | ||
| 107500 | return 0x04; | ||
| 107501 | } | ||
| 107502 | case TK_CONCAT: { | ||
| 107503 | return 0x06; | ||
| 107504 | } | ||
| 107505 | case TK_VARIABLE: | ||
| 107506 | case TK_AGG_FUNCTION: | ||
| 107507 | case TK_FUNCTION: { | ||
| 107508 | return 0x07; | ||
| 107509 | } | ||
| 107510 | case TK_COLUMN: | ||
| 107511 | case TK_AGG_COLUMN: | ||
| 107512 | case TK_SELECT: | ||
| 107513 | case TK_CAST: | ||
| 107514 | case TK_SELECT_COLUMN: | ||
| 107515 | case TK_VECTOR: { | ||
| 107516 | int aff = sqlite3ExprAffinity(pExpr); | ||
| 107517 | if( aff>=SQLITE_AFF_NUMERIC ) return 0x05; | ||
| 107518 | if( aff==SQLITE_AFF_TEXT ) return 0x06; | ||
| 107519 | return 0x07; | ||
| 107520 | } | ||
| 107521 | case TK_CASE: { | ||
| 107522 | int res = 0; | ||
| 107523 | int ii; | ||
| 107524 | ExprList *pList = pExpr->x.pList; | ||
| 107525 | assert( ExprUseXList(pExpr) && pList!=0 ); | ||
| 107526 | assert( pList->nExpr > 0); | ||
| 107527 | for(ii=1; ii<pList->nExpr; ii+=2){ | ||
| 107528 | res |= sqlite3ExprDataType(pList->a[ii].pExpr); | ||
| 107529 | } | ||
| 107530 | if( pList->nExpr % 2 ){ | ||
| 107531 | res |= sqlite3ExprDataType(pList->a[pList->nExpr-1].pExpr); | ||
| 107532 | } | ||
| 107533 | return res; | ||
| 107534 | } | ||
| 107535 | default: { | ||
| 107536 | return 0x01; | ||
| 107537 | } | ||
| 107538 | } /* End of switch(op) */ | ||
| 107539 | } /* End of while(pExpr) */ | ||
| 107540 | return 0x00; | ||
| 107541 | } | ||
| 107542 | |||
| 107543 | /* | ||
| 103742 | ** Set the collating sequence for expression pExpr to be the collating | 107544 | ** Set the collating sequence for expression pExpr to be the collating |
| 103743 | ** sequence named by pToken. Return a pointer to a new Expr node that | 107545 | ** sequence named by pToken. Return a pointer to a new Expr node that |
| 103744 | ** implements the COLLATE operator. | 107546 | ** implements the COLLATE operator. |
| @@ -103825,18 +107627,17 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ | |||
| 103825 | while( p ){ | 107627 | while( p ){ |
| 103826 | int op = p->op; | 107628 | int op = p->op; |
| 103827 | if( op==TK_REGISTER ) op = p->op2; | 107629 | if( op==TK_REGISTER ) op = p->op2; |
| 103828 | if( op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER ){ | 107630 | if( (op==TK_AGG_COLUMN && p->y.pTab!=0) |
| 107631 | || op==TK_COLUMN || op==TK_TRIGGER | ||
| 107632 | ){ | ||
| 107633 | int j; | ||
| 103829 | assert( ExprUseYTab(p) ); | 107634 | assert( ExprUseYTab(p) ); |
| 103830 | if( p->y.pTab!=0 ){ | 107635 | assert( p->y.pTab!=0 ); |
| 103831 | /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally | 107636 | if( (j = p->iColumn)>=0 ){ |
| 103832 | ** a TK_COLUMN but was previously evaluated and cached in a register */ | 107637 | const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); |
| 103833 | int j = p->iColumn; | 107638 | pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); |
| 103834 | if( j>=0 ){ | ||
| 103835 | const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); | ||
| 103836 | pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); | ||
| 103837 | } | ||
| 103838 | break; | ||
| 103839 | } | 107639 | } |
| 107640 | break; | ||
| 103840 | } | 107641 | } |
| 103841 | if( op==TK_CAST || op==TK_UPLUS ){ | 107642 | if( op==TK_CAST || op==TK_UPLUS ){ |
| 103842 | p = p->pLeft; | 107643 | p = p->pLeft; |
| @@ -103858,11 +107659,10 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ | |||
| 103858 | }else{ | 107659 | }else{ |
| 103859 | Expr *pNext = p->pRight; | 107660 | Expr *pNext = p->pRight; |
| 103860 | /* The Expr.x union is never used at the same time as Expr.pRight */ | 107661 | /* The Expr.x union is never used at the same time as Expr.pRight */ |
| 103861 | assert( ExprUseXList(p) ); | 107662 | assert( !ExprUseXList(p) || p->x.pList==0 || p->pRight==0 ); |
| 103862 | assert( p->x.pList==0 || p->pRight==0 ); | 107663 | if( ExprUseXList(p) && p->x.pList!=0 && !db->mallocFailed ){ |
| 103863 | if( p->x.pList!=0 && !db->mallocFailed ){ | ||
| 103864 | int i; | 107664 | int i; |
| 103865 | for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){ | 107665 | for(i=0; i<p->x.pList->nExpr; i++){ |
| 103866 | if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ | 107666 | if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ |
| 103867 | pNext = p->x.pList->a[i].pExpr; | 107667 | pNext = p->x.pList->a[i].pExpr; |
| 103868 | break; | 107668 | break; |
| @@ -103884,7 +107684,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ | |||
| 103884 | /* | 107684 | /* |
| 103885 | ** Return the collation sequence for the expression pExpr. If | 107685 | ** Return the collation sequence for the expression pExpr. If |
| 103886 | ** there is no defined collating sequence, return a pointer to the | 107686 | ** there is no defined collating sequence, return a pointer to the |
| 103887 | ** defautl collation sequence. | 107687 | ** default collation sequence. |
| 103888 | ** | 107688 | ** |
| 103889 | ** See also: sqlite3ExprCollSeq() | 107689 | ** See also: sqlite3ExprCollSeq() |
| 103890 | ** | 107690 | ** |
| @@ -104014,7 +107814,7 @@ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq( | |||
| 104014 | return pColl; | 107814 | return pColl; |
| 104015 | } | 107815 | } |
| 104016 | 107816 | ||
| 104017 | /* Expresssion p is a comparison operator. Return a collation sequence | 107817 | /* Expression p is a comparison operator. Return a collation sequence |
| 104018 | ** appropriate for the comparison operator. | 107818 | ** appropriate for the comparison operator. |
| 104019 | ** | 107819 | ** |
| 104020 | ** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). | 107820 | ** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). |
| @@ -104421,7 +108221,9 @@ static void heightOfSelect(const Select *pSelect, int *pnHeight){ | |||
| 104421 | */ | 108221 | */ |
| 104422 | static void exprSetHeight(Expr *p){ | 108222 | static void exprSetHeight(Expr *p){ |
| 104423 | int nHeight = p->pLeft ? p->pLeft->nHeight : 0; | 108223 | int nHeight = p->pLeft ? p->pLeft->nHeight : 0; |
| 104424 | if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight; | 108224 | if( NEVER(p->pRight) && p->pRight->nHeight>nHeight ){ |
| 108225 | nHeight = p->pRight->nHeight; | ||
| 108226 | } | ||
| 104425 | if( ExprUseXSelect(p) ){ | 108227 | if( ExprUseXSelect(p) ){ |
| 104426 | heightOfSelect(p->x.pSelect, &nHeight); | 108228 | heightOfSelect(p->x.pSelect, &nHeight); |
| 104427 | }else if( p->x.pList ){ | 108229 | }else if( p->x.pList ){ |
| @@ -104469,6 +108271,15 @@ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ | |||
| 104469 | #endif /* SQLITE_MAX_EXPR_DEPTH>0 */ | 108271 | #endif /* SQLITE_MAX_EXPR_DEPTH>0 */ |
| 104470 | 108272 | ||
| 104471 | /* | 108273 | /* |
| 108274 | ** Set the error offset for an Expr node, if possible. | ||
| 108275 | */ | ||
| 108276 | SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ | ||
| 108277 | if( pExpr==0 ) return; | ||
| 108278 | if( NEVER(ExprUseWJoin(pExpr)) ) return; | ||
| 108279 | pExpr->w.iOfst = iOfst; | ||
| 108280 | } | ||
| 108281 | |||
| 108282 | /* | ||
| 104472 | ** This routine is the core allocator for Expr nodes. | 108283 | ** This routine is the core allocator for Expr nodes. |
| 104473 | ** | 108284 | ** |
| 104474 | ** Construct a new expression node and return a pointer to it. Memory | 108285 | ** Construct a new expression node and return a pointer to it. Memory |
| @@ -104564,15 +108375,26 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees( | |||
| 104564 | sqlite3ExprDelete(db, pLeft); | 108375 | sqlite3ExprDelete(db, pLeft); |
| 104565 | sqlite3ExprDelete(db, pRight); | 108376 | sqlite3ExprDelete(db, pRight); |
| 104566 | }else{ | 108377 | }else{ |
| 108378 | assert( ExprUseXList(pRoot) ); | ||
| 108379 | assert( pRoot->x.pSelect==0 ); | ||
| 104567 | if( pRight ){ | 108380 | if( pRight ){ |
| 104568 | pRoot->pRight = pRight; | 108381 | pRoot->pRight = pRight; |
| 104569 | pRoot->flags |= EP_Propagate & pRight->flags; | 108382 | pRoot->flags |= EP_Propagate & pRight->flags; |
| 108383 | #if SQLITE_MAX_EXPR_DEPTH>0 | ||
| 108384 | pRoot->nHeight = pRight->nHeight+1; | ||
| 108385 | }else{ | ||
| 108386 | pRoot->nHeight = 1; | ||
| 108387 | #endif | ||
| 104570 | } | 108388 | } |
| 104571 | if( pLeft ){ | 108389 | if( pLeft ){ |
| 104572 | pRoot->pLeft = pLeft; | 108390 | pRoot->pLeft = pLeft; |
| 104573 | pRoot->flags |= EP_Propagate & pLeft->flags; | 108391 | pRoot->flags |= EP_Propagate & pLeft->flags; |
| 108392 | #if SQLITE_MAX_EXPR_DEPTH>0 | ||
| 108393 | if( pLeft->nHeight>=pRoot->nHeight ){ | ||
| 108394 | pRoot->nHeight = pLeft->nHeight+1; | ||
| 108395 | } | ||
| 108396 | #endif | ||
| 104574 | } | 108397 | } |
| 104575 | exprSetHeight(pRoot); | ||
| 104576 | } | 108398 | } |
| 104577 | } | 108399 | } |
| 104578 | 108400 | ||
| @@ -104681,9 +108503,9 @@ SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprLis | |||
| 104681 | ** Join two expressions using an AND operator. If either expression is | 108503 | ** Join two expressions using an AND operator. If either expression is |
| 104682 | ** NULL, then just return the other expression. | 108504 | ** NULL, then just return the other expression. |
| 104683 | ** | 108505 | ** |
| 104684 | ** If one side or the other of the AND is known to be false, then instead | 108506 | ** If one side or the other of the AND is known to be false, and neither side |
| 104685 | ** of returning an AND expression, just return a constant expression with | 108507 | ** is part of an ON clause, then instead of returning an AND expression, |
| 104686 | ** a value of false. | 108508 | ** just return a constant expression with a value of false. |
| 104687 | */ | 108509 | */ |
| 104688 | SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ | 108510 | SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ |
| 104689 | sqlite3 *db = pParse->db; | 108511 | sqlite3 *db = pParse->db; |
| @@ -104691,14 +108513,17 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ | |||
| 104691 | return pRight; | 108513 | return pRight; |
| 104692 | }else if( pRight==0 ){ | 108514 | }else if( pRight==0 ){ |
| 104693 | return pLeft; | 108515 | return pLeft; |
| 104694 | }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight)) | ||
| 104695 | && !IN_RENAME_OBJECT | ||
| 104696 | ){ | ||
| 104697 | sqlite3ExprDeferredDelete(pParse, pLeft); | ||
| 104698 | sqlite3ExprDeferredDelete(pParse, pRight); | ||
| 104699 | return sqlite3Expr(db, TK_INTEGER, "0"); | ||
| 104700 | }else{ | 108516 | }else{ |
| 104701 | return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); | 108517 | u32 f = pLeft->flags | pRight->flags; |
| 108518 | if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse | ||
| 108519 | && !IN_RENAME_OBJECT | ||
| 108520 | ){ | ||
| 108521 | sqlite3ExprDeferredDelete(pParse, pLeft); | ||
| 108522 | sqlite3ExprDeferredDelete(pParse, pRight); | ||
| 108523 | return sqlite3Expr(db, TK_INTEGER, "0"); | ||
| 108524 | }else{ | ||
| 108525 | return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); | ||
| 108526 | } | ||
| 104702 | } | 108527 | } |
| 104703 | } | 108528 | } |
| 104704 | 108529 | ||
| @@ -104858,6 +108683,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n | |||
| 104858 | */ | 108683 | */ |
| 104859 | static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ | 108684 | static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ |
| 104860 | assert( p!=0 ); | 108685 | assert( p!=0 ); |
| 108686 | assert( db!=0 ); | ||
| 104861 | assert( !ExprUseUValue(p) || p->u.iValue>=0 ); | 108687 | assert( !ExprUseUValue(p) || p->u.iValue>=0 ); |
| 104862 | assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); | 108688 | assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); |
| 104863 | assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); | 108689 | assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); |
| @@ -104889,12 +108715,8 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ | |||
| 104889 | #endif | 108715 | #endif |
| 104890 | } | 108716 | } |
| 104891 | } | 108717 | } |
| 104892 | if( ExprHasProperty(p, EP_MemToken) ){ | ||
| 104893 | assert( !ExprHasProperty(p, EP_IntValue) ); | ||
| 104894 | sqlite3DbFree(db, p->u.zToken); | ||
| 104895 | } | ||
| 104896 | if( !ExprHasProperty(p, EP_Static) ){ | 108718 | if( !ExprHasProperty(p, EP_Static) ){ |
| 104897 | sqlite3DbFreeNN(db, p); | 108719 | sqlite3DbNNFreeNN(db, p); |
| 104898 | } | 108720 | } |
| 104899 | } | 108721 | } |
| 104900 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ | 108722 | SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ |
| @@ -104917,7 +108739,7 @@ SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ | |||
| 104917 | /* | 108739 | /* |
| 104918 | ** Arrange to cause pExpr to be deleted when the pParse is deleted. | 108740 | ** Arrange to cause pExpr to be deleted when the pParse is deleted. |
| 104919 | ** This is similar to sqlite3ExprDelete() except that the delete is | 108741 | ** This is similar to sqlite3ExprDelete() except that the delete is |
| 104920 | ** deferred untilthe pParse is deleted. | 108742 | ** deferred until the pParse is deleted. |
| 104921 | ** | 108743 | ** |
| 104922 | ** The pExpr might be deleted immediately on an OOM error. | 108744 | ** The pExpr might be deleted immediately on an OOM error. |
| 104923 | ** | 108745 | ** |
| @@ -104925,8 +108747,9 @@ SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ | |||
| 104925 | ** pExpr to the pParse->pConstExpr list with a register number of 0. | 108747 | ** pExpr to the pParse->pConstExpr list with a register number of 0. |
| 104926 | */ | 108748 | */ |
| 104927 | SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ | 108749 | SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ |
| 104928 | pParse->pConstExpr = | 108750 | sqlite3ParserAddCleanup(pParse, |
| 104929 | sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); | 108751 | (void(*)(sqlite3*,void*))sqlite3ExprDelete, |
| 108752 | pExpr); | ||
| 104930 | } | 108753 | } |
| 104931 | 108754 | ||
| 104932 | /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the | 108755 | /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the |
| @@ -105000,7 +108823,6 @@ static int dupedExprStructSize(const Expr *p, int flags){ | |||
| 105000 | }else{ | 108823 | }else{ |
| 105001 | assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); | 108824 | assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); |
| 105002 | assert( !ExprHasProperty(p, EP_OuterON) ); | 108825 | assert( !ExprHasProperty(p, EP_OuterON) ); |
| 105003 | assert( !ExprHasProperty(p, EP_MemToken) ); | ||
| 105004 | assert( !ExprHasVVAProperty(p, EP_NoReduce) ); | 108826 | assert( !ExprHasVVAProperty(p, EP_NoReduce) ); |
| 105005 | if( p->pLeft || p->x.pList ){ | 108827 | if( p->pLeft || p->x.pList ){ |
| 105006 | nSize = EXPR_REDUCEDSIZE | EP_Reduced; | 108828 | nSize = EXPR_REDUCEDSIZE | EP_Reduced; |
| @@ -105104,7 +108926,7 @@ static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ | |||
| 105104 | } | 108926 | } |
| 105105 | 108927 | ||
| 105106 | /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ | 108928 | /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */ |
| 105107 | pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken); | 108929 | pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static); |
| 105108 | pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); | 108930 | pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); |
| 105109 | pNew->flags |= staticFlag; | 108931 | pNew->flags |= staticFlag; |
| 105110 | ExprClearVVAProperties(pNew); | 108932 | ExprClearVVAProperties(pNew); |
| @@ -105680,12 +109502,13 @@ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ | |||
| 105680 | int i = pList->nExpr; | 109502 | int i = pList->nExpr; |
| 105681 | struct ExprList_item *pItem = pList->a; | 109503 | struct ExprList_item *pItem = pList->a; |
| 105682 | assert( pList->nExpr>0 ); | 109504 | assert( pList->nExpr>0 ); |
| 109505 | assert( db!=0 ); | ||
| 105683 | do{ | 109506 | do{ |
| 105684 | sqlite3ExprDelete(db, pItem->pExpr); | 109507 | sqlite3ExprDelete(db, pItem->pExpr); |
| 105685 | sqlite3DbFree(db, pItem->zEName); | 109508 | if( pItem->zEName ) sqlite3DbNNFreeNN(db, pItem->zEName); |
| 105686 | pItem++; | 109509 | pItem++; |
| 105687 | }while( --i>0 ); | 109510 | }while( --i>0 ); |
| 105688 | sqlite3DbFreeNN(db, pList); | 109511 | sqlite3DbNNFreeNN(db, pList); |
| 105689 | } | 109512 | } |
| 105690 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ | 109513 | SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ |
| 105691 | if( pList ) exprListDeleteNN(db, pList); | 109514 | if( pList ) exprListDeleteNN(db, pList); |
| @@ -105758,7 +109581,7 @@ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ | |||
| 105758 | ** and 0 if it is FALSE. | 109581 | ** and 0 if it is FALSE. |
| 105759 | */ | 109582 | */ |
| 105760 | SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){ | 109583 | SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){ |
| 105761 | pExpr = sqlite3ExprSkipCollate((Expr*)pExpr); | 109584 | pExpr = sqlite3ExprSkipCollateAndLikely((Expr*)pExpr); |
| 105762 | assert( pExpr->op==TK_TRUEFALSE ); | 109585 | assert( pExpr->op==TK_TRUEFALSE ); |
| 105763 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 109586 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 105764 | assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 | 109587 | assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 |
| @@ -105945,12 +109768,17 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ | |||
| 105945 | } | 109768 | } |
| 105946 | 109769 | ||
| 105947 | /* | 109770 | /* |
| 105948 | ** Check pExpr to see if it is an invariant constraint on data source pSrc. | 109771 | ** Check pExpr to see if it is an constraint on the single data source |
| 109772 | ** pSrc = &pSrcList->a[iSrc]. In other words, check to see if pExpr | ||
| 109773 | ** constrains pSrc but does not depend on any other tables or data | ||
| 109774 | ** sources anywhere else in the query. Return true (non-zero) if pExpr | ||
| 109775 | ** is a constraint on pSrc only. | ||
| 109776 | ** | ||
| 105949 | ** This is an optimization. False negatives will perhaps cause slower | 109777 | ** This is an optimization. False negatives will perhaps cause slower |
| 105950 | ** queries, but false positives will yield incorrect answers. So when in | 109778 | ** queries, but false positives will yield incorrect answers. So when in |
| 105951 | ** doubt, return 0. | 109779 | ** doubt, return 0. |
| 105952 | ** | 109780 | ** |
| 105953 | ** To be an invariant constraint, the following must be true: | 109781 | ** To be an single-source constraint, the following must be true: |
| 105954 | ** | 109782 | ** |
| 105955 | ** (1) pExpr cannot refer to any table other than pSrc->iCursor. | 109783 | ** (1) pExpr cannot refer to any table other than pSrc->iCursor. |
| 105956 | ** | 109784 | ** |
| @@ -105961,13 +109789,31 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ | |||
| 105961 | ** | 109789 | ** |
| 105962 | ** (4) If pSrc is the right operand of a LEFT JOIN, then... | 109790 | ** (4) If pSrc is the right operand of a LEFT JOIN, then... |
| 105963 | ** (4a) pExpr must come from an ON clause.. | 109791 | ** (4a) pExpr must come from an ON clause.. |
| 105964 | (4b) and specifically the ON clause associated with the LEFT JOIN. | 109792 | ** (4b) and specifically the ON clause associated with the LEFT JOIN. |
| 105965 | ** | 109793 | ** |
| 105966 | ** (5) If pSrc is not the right operand of a LEFT JOIN or the left | 109794 | ** (5) If pSrc is not the right operand of a LEFT JOIN or the left |
| 105967 | ** operand of a RIGHT JOIN, then pExpr must be from the WHERE | 109795 | ** operand of a RIGHT JOIN, then pExpr must be from the WHERE |
| 105968 | ** clause, not an ON clause. | 109796 | ** clause, not an ON clause. |
| 109797 | ** | ||
| 109798 | ** (6) Either: | ||
| 109799 | ** | ||
| 109800 | ** (6a) pExpr does not originate in an ON or USING clause, or | ||
| 109801 | ** | ||
| 109802 | ** (6b) The ON or USING clause from which pExpr is derived is | ||
| 109803 | ** not to the left of a RIGHT JOIN (or FULL JOIN). | ||
| 109804 | ** | ||
| 109805 | ** Without this restriction, accepting pExpr as a single-table | ||
| 109806 | ** constraint might move the the ON/USING filter expression | ||
| 109807 | ** from the left side of a RIGHT JOIN over to the right side, | ||
| 109808 | ** which leads to incorrect answers. See also restriction (9) | ||
| 109809 | ** on push-down. | ||
| 105969 | */ | 109810 | */ |
| 105970 | SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ | 109811 | SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( |
| 109812 | Expr *pExpr, /* The constraint */ | ||
| 109813 | const SrcList *pSrcList, /* Complete FROM clause */ | ||
| 109814 | int iSrc /* Which element of pSrcList to use */ | ||
| 109815 | ){ | ||
| 109816 | const SrcItem *pSrc = &pSrcList->a[iSrc]; | ||
| 105971 | if( pSrc->fg.jointype & JT_LTORJ ){ | 109817 | if( pSrc->fg.jointype & JT_LTORJ ){ |
| 105972 | return 0; /* rule (3) */ | 109818 | return 0; /* rule (3) */ |
| 105973 | } | 109819 | } |
| @@ -105977,6 +109823,19 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc | |||
| 105977 | }else{ | 109823 | }else{ |
| 105978 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */ | 109824 | if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */ |
| 105979 | } | 109825 | } |
| 109826 | if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) /* (6a) */ | ||
| 109827 | && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (6b) */ | ||
| 109828 | ){ | ||
| 109829 | int jj; | ||
| 109830 | for(jj=0; jj<iSrc; jj++){ | ||
| 109831 | if( pExpr->w.iJoin==pSrcList->a[jj].iCursor ){ | ||
| 109832 | if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){ | ||
| 109833 | return 0; /* restriction (6) */ | ||
| 109834 | } | ||
| 109835 | break; | ||
| 109836 | } | ||
| 109837 | } | ||
| 109838 | } | ||
| 105980 | return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ | 109839 | return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ |
| 105981 | } | 109840 | } |
| 105982 | 109841 | ||
| @@ -106219,7 +110078,7 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ | |||
| 106219 | ** pX is the RHS of an IN operator. If pX is a SELECT statement | 110078 | ** pX is the RHS of an IN operator. If pX is a SELECT statement |
| 106220 | ** that can be simplified to a direct table access, then return | 110079 | ** that can be simplified to a direct table access, then return |
| 106221 | ** a pointer to the SELECT statement. If pX is not a SELECT statement, | 110080 | ** a pointer to the SELECT statement. If pX is not a SELECT statement, |
| 106222 | ** or if the SELECT statement needs to be manifested into a transient | 110081 | ** or if the SELECT statement needs to be materialized into a transient |
| 106223 | ** table, then return NULL. | 110082 | ** table, then return NULL. |
| 106224 | */ | 110083 | */ |
| 106225 | #ifndef SQLITE_OMIT_SUBQUERY | 110084 | #ifndef SQLITE_OMIT_SUBQUERY |
| @@ -106315,7 +110174,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ | |||
| 106315 | ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. | 110174 | ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. |
| 106316 | ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. | 110175 | ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. |
| 106317 | ** IN_INDEX_EPH - The cursor was opened on a specially created and | 110176 | ** IN_INDEX_EPH - The cursor was opened on a specially created and |
| 106318 | ** populated epheremal table. | 110177 | ** populated ephemeral table. |
| 106319 | ** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be | 110178 | ** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be |
| 106320 | ** implemented as a sequence of comparisons. | 110179 | ** implemented as a sequence of comparisons. |
| 106321 | ** | 110180 | ** |
| @@ -106328,7 +110187,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ | |||
| 106328 | ** an ephemeral table might need to be generated from the RHS and then | 110187 | ** an ephemeral table might need to be generated from the RHS and then |
| 106329 | ** pX->iTable made to point to the ephemeral table instead of an | 110188 | ** pX->iTable made to point to the ephemeral table instead of an |
| 106330 | ** existing table. In this case, the creation and initialization of the | 110189 | ** existing table. In this case, the creation and initialization of the |
| 106331 | ** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag | 110190 | ** ephemeral table might be put inside of a subroutine, the EP_Subrtn flag |
| 106332 | ** will be set on pX and the pX->y.sub fields will be set to show where | 110191 | ** will be set on pX and the pX->y.sub fields will be set to show where |
| 106333 | ** the subroutine is coded. | 110192 | ** the subroutine is coded. |
| 106334 | ** | 110193 | ** |
| @@ -106340,12 +110199,12 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ | |||
| 106340 | ** | 110199 | ** |
| 106341 | ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate | 110200 | ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate |
| 106342 | ** through the set members) then the b-tree must not contain duplicates. | 110201 | ** through the set members) then the b-tree must not contain duplicates. |
| 106343 | ** An epheremal table will be created unless the selected columns are guaranteed | 110202 | ** An ephemeral table will be created unless the selected columns are guaranteed |
| 106344 | ** to be unique - either because it is an INTEGER PRIMARY KEY or due to | 110203 | ** to be unique - either because it is an INTEGER PRIMARY KEY or due to |
| 106345 | ** a UNIQUE constraint or index. | 110204 | ** a UNIQUE constraint or index. |
| 106346 | ** | 110205 | ** |
| 106347 | ** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used | 110206 | ** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used |
| 106348 | ** for fast set membership tests) then an epheremal table must | 110207 | ** for fast set membership tests) then an ephemeral table must |
| 106349 | ** be used unless <columns> is a single INTEGER PRIMARY KEY column or an | 110208 | ** be used unless <columns> is a single INTEGER PRIMARY KEY column or an |
| 106350 | ** index can be found with the specified <columns> as its left-most. | 110209 | ** index can be found with the specified <columns> as its left-most. |
| 106351 | ** | 110210 | ** |
| @@ -106505,7 +110364,6 @@ SQLITE_PRIVATE int sqlite3FindInIndex( | |||
| 106505 | CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); | 110364 | CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); |
| 106506 | int j; | 110365 | int j; |
| 106507 | 110366 | ||
| 106508 | assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr ); | ||
| 106509 | for(j=0; j<nExpr; j++){ | 110367 | for(j=0; j<nExpr; j++){ |
| 106510 | if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue; | 110368 | if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue; |
| 106511 | assert( pIdx->azColl[j] ); | 110369 | assert( pIdx->azColl[j] ); |
| @@ -106679,7 +110537,7 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ | |||
| 106679 | ** x IN (SELECT a FROM b) -- IN operator with subquery on the right | 110537 | ** x IN (SELECT a FROM b) -- IN operator with subquery on the right |
| 106680 | ** | 110538 | ** |
| 106681 | ** The pExpr parameter is the IN operator. The cursor number for the | 110539 | ** The pExpr parameter is the IN operator. The cursor number for the |
| 106682 | ** constructed ephermeral table is returned. The first time the ephemeral | 110540 | ** constructed ephemeral table is returned. The first time the ephemeral |
| 106683 | ** table is computed, the cursor number is also stored in pExpr->iTable, | 110541 | ** table is computed, the cursor number is also stored in pExpr->iTable, |
| 106684 | ** however the cursor number returned might not be the same, as it might | 110542 | ** however the cursor number returned might not be the same, as it might |
| 106685 | ** have been duplicated using OP_OpenDup. | 110543 | ** have been duplicated using OP_OpenDup. |
| @@ -106863,6 +110721,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( | |||
| 106863 | sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); | 110721 | sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); |
| 106864 | } | 110722 | } |
| 106865 | if( addrOnce ){ | 110723 | if( addrOnce ){ |
| 110724 | sqlite3VdbeAddOp1(v, OP_NullRow, iTab); | ||
| 106866 | sqlite3VdbeJumpHere(v, addrOnce); | 110725 | sqlite3VdbeJumpHere(v, addrOnce); |
| 106867 | /* Subroutine return */ | 110726 | /* Subroutine return */ |
| 106868 | assert( ExprUseYSub(pExpr) ); | 110727 | assert( ExprUseYSub(pExpr) ); |
| @@ -106898,6 +110757,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ | |||
| 106898 | SelectDest dest; /* How to deal with SELECT result */ | 110757 | SelectDest dest; /* How to deal with SELECT result */ |
| 106899 | int nReg; /* Registers to allocate */ | 110758 | int nReg; /* Registers to allocate */ |
| 106900 | Expr *pLimit; /* New limit expression */ | 110759 | Expr *pLimit; /* New limit expression */ |
| 110760 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 110761 | int addrExplain; /* Address of OP_Explain instruction */ | ||
| 110762 | #endif | ||
| 106901 | 110763 | ||
| 106902 | Vdbe *v = pParse->pVdbe; | 110764 | Vdbe *v = pParse->pVdbe; |
| 106903 | assert( v!=0 ); | 110765 | assert( v!=0 ); |
| @@ -106950,8 +110812,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ | |||
| 106950 | ** In both cases, the query is augmented with "LIMIT 1". Any | 110812 | ** In both cases, the query is augmented with "LIMIT 1". Any |
| 106951 | ** preexisting limit is discarded in place of the new LIMIT 1. | 110813 | ** preexisting limit is discarded in place of the new LIMIT 1. |
| 106952 | */ | 110814 | */ |
| 106953 | ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d", | 110815 | ExplainQueryPlan2(addrExplain, (pParse, 1, "%sSCALAR SUBQUERY %d", |
| 106954 | addrOnce?"":"CORRELATED ", pSel->selId)); | 110816 | addrOnce?"":"CORRELATED ", pSel->selId)); |
| 110817 | sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, -1); | ||
| 106955 | nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; | 110818 | nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; |
| 106956 | sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); | 110819 | sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); |
| 106957 | pParse->nMem += nReg; | 110820 | pParse->nMem += nReg; |
| @@ -106976,7 +110839,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ | |||
| 106976 | pLimit = sqlite3PExpr(pParse, TK_NE, | 110839 | pLimit = sqlite3PExpr(pParse, TK_NE, |
| 106977 | sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); | 110840 | sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); |
| 106978 | } | 110841 | } |
| 106979 | sqlite3ExprDelete(db, pSel->pLimit->pLeft); | 110842 | sqlite3ExprDeferredDelete(pParse, pSel->pLimit->pLeft); |
| 106980 | pSel->pLimit->pLeft = pLimit; | 110843 | pSel->pLimit->pLeft = pLimit; |
| 106981 | }else{ | 110844 | }else{ |
| 106982 | /* If there is no pre-existing limit add a limit of 1 */ | 110845 | /* If there is no pre-existing limit add a limit of 1 */ |
| @@ -106994,6 +110857,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ | |||
| 106994 | if( addrOnce ){ | 110857 | if( addrOnce ){ |
| 106995 | sqlite3VdbeJumpHere(v, addrOnce); | 110858 | sqlite3VdbeJumpHere(v, addrOnce); |
| 106996 | } | 110859 | } |
| 110860 | sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); | ||
| 106997 | 110861 | ||
| 106998 | /* Subroutine return */ | 110862 | /* Subroutine return */ |
| 106999 | assert( ExprUseYSub(pExpr) ); | 110863 | assert( ExprUseYSub(pExpr) ); |
| @@ -107402,6 +111266,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn( | |||
| 107402 | ){ | 111266 | ){ |
| 107403 | int iAddr; | 111267 | int iAddr; |
| 107404 | Vdbe *v = pParse->pVdbe; | 111268 | Vdbe *v = pParse->pVdbe; |
| 111269 | int nErr = pParse->nErr; | ||
| 107405 | assert( v!=0 ); | 111270 | assert( v!=0 ); |
| 107406 | assert( pParse->iSelfTab!=0 ); | 111271 | assert( pParse->iSelfTab!=0 ); |
| 107407 | if( pParse->iSelfTab>0 ){ | 111272 | if( pParse->iSelfTab>0 ){ |
| @@ -107414,6 +111279,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn( | |||
| 107414 | sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); | 111279 | sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); |
| 107415 | } | 111280 | } |
| 107416 | if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); | 111281 | if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); |
| 111282 | if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; | ||
| 107417 | } | 111283 | } |
| 107418 | #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ | 111284 | #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ |
| 107419 | 111285 | ||
| @@ -107429,10 +111295,8 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( | |||
| 107429 | ){ | 111295 | ){ |
| 107430 | Column *pCol; | 111296 | Column *pCol; |
| 107431 | assert( v!=0 ); | 111297 | assert( v!=0 ); |
| 107432 | if( pTab==0 ){ | 111298 | assert( pTab!=0 ); |
| 107433 | sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); | 111299 | assert( iCol!=XN_EXPR ); |
| 107434 | return; | ||
| 107435 | } | ||
| 107436 | if( iCol<0 || iCol==pTab->iPKey ){ | 111300 | if( iCol<0 || iCol==pTab->iPKey ){ |
| 107437 | sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); | 111301 | sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); |
| 107438 | VdbeComment((v, "%s.rowid", pTab->zName)); | 111302 | VdbeComment((v, "%s.rowid", pTab->zName)); |
| @@ -107488,10 +111352,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( | |||
| 107488 | u8 p5 /* P5 value for OP_Column + FLAGS */ | 111352 | u8 p5 /* P5 value for OP_Column + FLAGS */ |
| 107489 | ){ | 111353 | ){ |
| 107490 | assert( pParse->pVdbe!=0 ); | 111354 | assert( pParse->pVdbe!=0 ); |
| 111355 | assert( (p5 & (OPFLAG_NOCHNG|OPFLAG_TYPEOFARG|OPFLAG_LENGTHARG))==p5 ); | ||
| 111356 | assert( IsVirtual(pTab) || (p5 & OPFLAG_NOCHNG)==0 ); | ||
| 107491 | sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); | 111357 | sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); |
| 107492 | if( p5 ){ | 111358 | if( p5 ){ |
| 107493 | VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); | 111359 | VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); |
| 107494 | if( pOp->opcode==OP_Column ) pOp->p5 = p5; | 111360 | if( pOp->opcode==OP_Column ) pOp->p5 = p5; |
| 111361 | if( pOp->opcode==OP_VColumn ) pOp->p5 = (p5 & OPFLAG_NOCHNG); | ||
| 107495 | } | 111362 | } |
| 107496 | return iReg; | 111363 | return iReg; |
| 107497 | } | 111364 | } |
| @@ -107520,7 +111387,7 @@ static void exprToRegister(Expr *pExpr, int iReg){ | |||
| 107520 | 111387 | ||
| 107521 | /* | 111388 | /* |
| 107522 | ** Evaluate an expression (either a vector or a scalar expression) and store | 111389 | ** Evaluate an expression (either a vector or a scalar expression) and store |
| 107523 | ** the result in continguous temporary registers. Return the index of | 111390 | ** the result in contiguous temporary registers. Return the index of |
| 107524 | ** the first register used to store the result. | 111391 | ** the first register used to store the result. |
| 107525 | ** | 111392 | ** |
| 107526 | ** If the returned result register is a temporary scalar, then also write | 111393 | ** If the returned result register is a temporary scalar, then also write |
| @@ -107559,8 +111426,8 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ | |||
| 107559 | ** so that a subsequent copy will not be merged into this one. | 111426 | ** so that a subsequent copy will not be merged into this one. |
| 107560 | */ | 111427 | */ |
| 107561 | static void setDoNotMergeFlagOnCopy(Vdbe *v){ | 111428 | static void setDoNotMergeFlagOnCopy(Vdbe *v){ |
| 107562 | if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){ | 111429 | if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){ |
| 107563 | sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */ | 111430 | sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergeable */ |
| 107564 | } | 111431 | } |
| 107565 | } | 111432 | } |
| 107566 | 111433 | ||
| @@ -107650,13 +111517,13 @@ static int exprCodeInlineFunction( | |||
| 107650 | } | 111517 | } |
| 107651 | 111518 | ||
| 107652 | case INLINEFUNC_implies_nonnull_row: { | 111519 | case INLINEFUNC_implies_nonnull_row: { |
| 107653 | /* REsult of sqlite3ExprImpliesNonNullRow() */ | 111520 | /* Result of sqlite3ExprImpliesNonNullRow() */ |
| 107654 | Expr *pA1; | 111521 | Expr *pA1; |
| 107655 | assert( nFarg==2 ); | 111522 | assert( nFarg==2 ); |
| 107656 | pA1 = pFarg->a[1].pExpr; | 111523 | pA1 = pFarg->a[1].pExpr; |
| 107657 | if( pA1->op==TK_COLUMN ){ | 111524 | if( pA1->op==TK_COLUMN ){ |
| 107658 | sqlite3VdbeAddOp2(v, OP_Integer, | 111525 | sqlite3VdbeAddOp2(v, OP_Integer, |
| 107659 | sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable), | 111526 | sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable,1), |
| 107660 | target); | 111527 | target); |
| 107661 | }else{ | 111528 | }else{ |
| 107662 | sqlite3VdbeAddOp2(v, OP_Null, 0, target); | 111529 | sqlite3VdbeAddOp2(v, OP_Null, 0, target); |
| @@ -107669,10 +111536,13 @@ static int exprCodeInlineFunction( | |||
| 107669 | ** the type affinity of the argument. This is used for testing of | 111536 | ** the type affinity of the argument. This is used for testing of |
| 107670 | ** the SQLite type logic. | 111537 | ** the SQLite type logic. |
| 107671 | */ | 111538 | */ |
| 107672 | const char *azAff[] = { "blob", "text", "numeric", "integer", "real" }; | 111539 | const char *azAff[] = { "blob", "text", "numeric", "integer", |
| 111540 | "real", "flexnum" }; | ||
| 107673 | char aff; | 111541 | char aff; |
| 107674 | assert( nFarg==1 ); | 111542 | assert( nFarg==1 ); |
| 107675 | aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); | 111543 | aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); |
| 111544 | assert( aff<=SQLITE_AFF_NONE | ||
| 111545 | || (aff>=SQLITE_AFF_BLOB && aff<=SQLITE_AFF_FLEXNUM) ); | ||
| 107676 | sqlite3VdbeLoadString(v, target, | 111546 | sqlite3VdbeLoadString(v, target, |
| 107677 | (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); | 111547 | (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); |
| 107678 | break; | 111548 | break; |
| @@ -107682,6 +111552,64 @@ static int exprCodeInlineFunction( | |||
| 107682 | return target; | 111552 | return target; |
| 107683 | } | 111553 | } |
| 107684 | 111554 | ||
| 111555 | /* | ||
| 111556 | ** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. | ||
| 111557 | ** If it is, then resolve the expression by reading from the index and | ||
| 111558 | ** return the register into which the value has been read. If pExpr is | ||
| 111559 | ** not an indexed expression, then return negative. | ||
| 111560 | */ | ||
| 111561 | static SQLITE_NOINLINE int sqlite3IndexedExprLookup( | ||
| 111562 | Parse *pParse, /* The parsing context */ | ||
| 111563 | Expr *pExpr, /* The expression to potentially bypass */ | ||
| 111564 | int target /* Where to store the result of the expression */ | ||
| 111565 | ){ | ||
| 111566 | IndexedExpr *p; | ||
| 111567 | Vdbe *v; | ||
| 111568 | for(p=pParse->pIdxEpr; p; p=p->pIENext){ | ||
| 111569 | u8 exprAff; | ||
| 111570 | int iDataCur = p->iDataCur; | ||
| 111571 | if( iDataCur<0 ) continue; | ||
| 111572 | if( pParse->iSelfTab ){ | ||
| 111573 | if( p->iDataCur!=pParse->iSelfTab-1 ) continue; | ||
| 111574 | iDataCur = -1; | ||
| 111575 | } | ||
| 111576 | if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue; | ||
| 111577 | assert( p->aff>=SQLITE_AFF_BLOB && p->aff<=SQLITE_AFF_NUMERIC ); | ||
| 111578 | exprAff = sqlite3ExprAffinity(pExpr); | ||
| 111579 | if( (exprAff<=SQLITE_AFF_BLOB && p->aff!=SQLITE_AFF_BLOB) | ||
| 111580 | || (exprAff==SQLITE_AFF_TEXT && p->aff!=SQLITE_AFF_TEXT) | ||
| 111581 | || (exprAff>=SQLITE_AFF_NUMERIC && p->aff!=SQLITE_AFF_NUMERIC) | ||
| 111582 | ){ | ||
| 111583 | /* Affinity mismatch on a generated column */ | ||
| 111584 | continue; | ||
| 111585 | } | ||
| 111586 | |||
| 111587 | v = pParse->pVdbe; | ||
| 111588 | assert( v!=0 ); | ||
| 111589 | if( p->bMaybeNullRow ){ | ||
| 111590 | /* If the index is on a NULL row due to an outer join, then we | ||
| 111591 | ** cannot extract the value from the index. The value must be | ||
| 111592 | ** computed using the original expression. */ | ||
| 111593 | int addr = sqlite3VdbeCurrentAddr(v); | ||
| 111594 | sqlite3VdbeAddOp3(v, OP_IfNullRow, p->iIdxCur, addr+3, target); | ||
| 111595 | VdbeCoverage(v); | ||
| 111596 | sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); | ||
| 111597 | VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); | ||
| 111598 | sqlite3VdbeGoto(v, 0); | ||
| 111599 | p = pParse->pIdxEpr; | ||
| 111600 | pParse->pIdxEpr = 0; | ||
| 111601 | sqlite3ExprCode(pParse, pExpr, target); | ||
| 111602 | pParse->pIdxEpr = p; | ||
| 111603 | sqlite3VdbeJumpHere(v, addr+2); | ||
| 111604 | }else{ | ||
| 111605 | sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); | ||
| 111606 | VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); | ||
| 111607 | } | ||
| 111608 | return target; | ||
| 111609 | } | ||
| 111610 | return -1; /* Not found */ | ||
| 111611 | } | ||
| 111612 | |||
| 107685 | 111613 | ||
| 107686 | /* | 111614 | /* |
| 107687 | ** Generate code into the current Vdbe to evaluate the given | 111615 | ** Generate code into the current Vdbe to evaluate the given |
| @@ -107710,6 +111638,11 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) | |||
| 107710 | expr_code_doover: | 111638 | expr_code_doover: |
| 107711 | if( pExpr==0 ){ | 111639 | if( pExpr==0 ){ |
| 107712 | op = TK_NULL; | 111640 | op = TK_NULL; |
| 111641 | }else if( pParse->pIdxEpr!=0 | ||
| 111642 | && !ExprHasProperty(pExpr, EP_Leaf) | ||
| 111643 | && (r1 = sqlite3IndexedExprLookup(pParse, pExpr, target))>=0 | ||
| 111644 | ){ | ||
| 111645 | return r1; | ||
| 107713 | }else{ | 111646 | }else{ |
| 107714 | assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); | 111647 | assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); |
| 107715 | op = pExpr->op; | 111648 | op = pExpr->op; |
| @@ -107719,16 +111652,29 @@ expr_code_doover: | |||
| 107719 | AggInfo *pAggInfo = pExpr->pAggInfo; | 111652 | AggInfo *pAggInfo = pExpr->pAggInfo; |
| 107720 | struct AggInfo_col *pCol; | 111653 | struct AggInfo_col *pCol; |
| 107721 | assert( pAggInfo!=0 ); | 111654 | assert( pAggInfo!=0 ); |
| 107722 | assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn ); | 111655 | assert( pExpr->iAgg>=0 ); |
| 111656 | if( pExpr->iAgg>=pAggInfo->nColumn ){ | ||
| 111657 | /* Happens when the left table of a RIGHT JOIN is null and | ||
| 111658 | ** is using an expression index */ | ||
| 111659 | sqlite3VdbeAddOp2(v, OP_Null, 0, target); | ||
| 111660 | #ifdef SQLITE_VDBE_COVERAGE | ||
| 111661 | /* Verify that the OP_Null above is exercised by tests | ||
| 111662 | ** tag-20230325-2 */ | ||
| 111663 | sqlite3VdbeAddOp2(v, OP_NotNull, target, 1); | ||
| 111664 | VdbeCoverageNeverTaken(v); | ||
| 111665 | #endif | ||
| 111666 | break; | ||
| 111667 | } | ||
| 107723 | pCol = &pAggInfo->aCol[pExpr->iAgg]; | 111668 | pCol = &pAggInfo->aCol[pExpr->iAgg]; |
| 107724 | if( !pAggInfo->directMode ){ | 111669 | if( !pAggInfo->directMode ){ |
| 107725 | assert( pCol->iMem>0 ); | 111670 | return AggInfoColumnReg(pAggInfo, pExpr->iAgg); |
| 107726 | return pCol->iMem; | ||
| 107727 | }else if( pAggInfo->useSortingIdx ){ | 111671 | }else if( pAggInfo->useSortingIdx ){ |
| 107728 | Table *pTab = pCol->pTab; | 111672 | Table *pTab = pCol->pTab; |
| 107729 | sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, | 111673 | sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, |
| 107730 | pCol->iSorterColumn, target); | 111674 | pCol->iSorterColumn, target); |
| 107731 | if( pCol->iColumn<0 ){ | 111675 | if( pTab==0 ){ |
| 111676 | /* No comment added */ | ||
| 111677 | }else if( pCol->iColumn<0 ){ | ||
| 107732 | VdbeComment((v,"%s.rowid",pTab->zName)); | 111678 | VdbeComment((v,"%s.rowid",pTab->zName)); |
| 107733 | }else{ | 111679 | }else{ |
| 107734 | VdbeComment((v,"%s.%s", | 111680 | VdbeComment((v,"%s.%s", |
| @@ -107738,6 +111684,11 @@ expr_code_doover: | |||
| 107738 | } | 111684 | } |
| 107739 | } | 111685 | } |
| 107740 | return target; | 111686 | return target; |
| 111687 | }else if( pExpr->y.pTab==0 ){ | ||
| 111688 | /* This case happens when the argument to an aggregate function | ||
| 111689 | ** is rewritten by aggregateConvertIndexedExprRefToColumn() */ | ||
| 111690 | sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, pExpr->iColumn, target); | ||
| 111691 | return target; | ||
| 107741 | } | 111692 | } |
| 107742 | /* Otherwise, fall thru into the TK_COLUMN case */ | 111693 | /* Otherwise, fall thru into the TK_COLUMN case */ |
| 107743 | /* no break */ deliberate_fall_through | 111694 | /* no break */ deliberate_fall_through |
| @@ -107748,20 +111699,17 @@ expr_code_doover: | |||
| 107748 | if( ExprHasProperty(pExpr, EP_FixedCol) ){ | 111699 | if( ExprHasProperty(pExpr, EP_FixedCol) ){ |
| 107749 | /* This COLUMN expression is really a constant due to WHERE clause | 111700 | /* This COLUMN expression is really a constant due to WHERE clause |
| 107750 | ** constraints, and that constant is coded by the pExpr->pLeft | 111701 | ** constraints, and that constant is coded by the pExpr->pLeft |
| 107751 | ** expresssion. However, make sure the constant has the correct | 111702 | ** expression. However, make sure the constant has the correct |
| 107752 | ** datatype by applying the Affinity of the table column to the | 111703 | ** datatype by applying the Affinity of the table column to the |
| 107753 | ** constant. | 111704 | ** constant. |
| 107754 | */ | 111705 | */ |
| 107755 | int aff; | 111706 | int aff; |
| 107756 | iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); | 111707 | iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); |
| 107757 | assert( ExprUseYTab(pExpr) ); | 111708 | assert( ExprUseYTab(pExpr) ); |
| 107758 | if( pExpr->y.pTab ){ | 111709 | assert( pExpr->y.pTab!=0 ); |
| 107759 | aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); | 111710 | aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); |
| 107760 | }else{ | ||
| 107761 | aff = pExpr->affExpr; | ||
| 107762 | } | ||
| 107763 | if( aff>SQLITE_AFF_BLOB ){ | 111711 | if( aff>SQLITE_AFF_BLOB ){ |
| 107764 | static const char zAff[] = "B\000C\000D\000E"; | 111712 | static const char zAff[] = "B\000C\000D\000E\000F"; |
| 107765 | assert( SQLITE_AFF_BLOB=='A' ); | 111713 | assert( SQLITE_AFF_BLOB=='A' ); |
| 107766 | assert( SQLITE_AFF_TEXT=='B' ); | 111714 | assert( SQLITE_AFF_TEXT=='B' ); |
| 107767 | sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, | 111715 | sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, |
| @@ -107821,12 +111769,10 @@ expr_code_doover: | |||
| 107821 | } | 111769 | } |
| 107822 | } | 111770 | } |
| 107823 | assert( ExprUseYTab(pExpr) ); | 111771 | assert( ExprUseYTab(pExpr) ); |
| 111772 | assert( pExpr->y.pTab!=0 ); | ||
| 107824 | iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, | 111773 | iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, |
| 107825 | pExpr->iColumn, iTab, target, | 111774 | pExpr->iColumn, iTab, target, |
| 107826 | pExpr->op2); | 111775 | pExpr->op2); |
| 107827 | if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){ | ||
| 107828 | sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); | ||
| 107829 | } | ||
| 107830 | return iReg; | 111776 | return iReg; |
| 107831 | } | 111777 | } |
| 107832 | case TK_INTEGER: { | 111778 | case TK_INTEGER: { |
| @@ -107893,11 +111839,8 @@ expr_code_doover: | |||
| 107893 | #ifndef SQLITE_OMIT_CAST | 111839 | #ifndef SQLITE_OMIT_CAST |
| 107894 | case TK_CAST: { | 111840 | case TK_CAST: { |
| 107895 | /* Expressions of the form: CAST(pLeft AS token) */ | 111841 | /* Expressions of the form: CAST(pLeft AS token) */ |
| 107896 | inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); | 111842 | sqlite3ExprCode(pParse, pExpr->pLeft, target); |
| 107897 | if( inReg!=target ){ | 111843 | assert( inReg==target ); |
| 107898 | sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); | ||
| 107899 | inReg = target; | ||
| 107900 | } | ||
| 107901 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 111844 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 107902 | sqlite3VdbeAddOp2(v, OP_Cast, target, | 111845 | sqlite3VdbeAddOp2(v, OP_Cast, target, |
| 107903 | sqlite3AffinityType(pExpr->u.zToken, 0)); | 111846 | sqlite3AffinityType(pExpr->u.zToken, 0)); |
| @@ -108040,7 +111983,7 @@ expr_code_doover: | |||
| 108040 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 111983 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 108041 | sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr); | 111984 | sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr); |
| 108042 | }else{ | 111985 | }else{ |
| 108043 | return pInfo->aFunc[pExpr->iAgg].iMem; | 111986 | return AggInfoFuncReg(pInfo, pExpr->iAgg); |
| 108044 | } | 111987 | } |
| 108045 | break; | 111988 | break; |
| 108046 | } | 111989 | } |
| @@ -108082,7 +112025,7 @@ expr_code_doover: | |||
| 108082 | sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); | 112025 | sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); |
| 108083 | break; | 112026 | break; |
| 108084 | } | 112027 | } |
| 108085 | if( pDef->funcFlags & SQLITE_FUNC_INLINE ){ | 112028 | if( (pDef->funcFlags & SQLITE_FUNC_INLINE)!=0 && ALWAYS(pFarg!=0) ){ |
| 108086 | assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); | 112029 | assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); |
| 108087 | assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); | 112030 | assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); |
| 108088 | return exprCodeInlineFunction(pParse, pFarg, | 112031 | return exprCodeInlineFunction(pParse, pFarg, |
| @@ -108108,10 +112051,10 @@ expr_code_doover: | |||
| 108108 | r1 = sqlite3GetTempRange(pParse, nFarg); | 112051 | r1 = sqlite3GetTempRange(pParse, nFarg); |
| 108109 | } | 112052 | } |
| 108110 | 112053 | ||
| 108111 | /* For length() and typeof() functions with a column argument, | 112054 | /* For length() and typeof() and octet_length() functions, |
| 108112 | ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG | 112055 | ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG |
| 108113 | ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data | 112056 | ** or OPFLAG_TYPEOFARG or OPFLAG_BYTELENARG respectively, to avoid |
| 108114 | ** loading. | 112057 | ** unnecessary data loading. |
| 108115 | */ | 112058 | */ |
| 108116 | if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ | 112059 | if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ |
| 108117 | u8 exprOp; | 112060 | u8 exprOp; |
| @@ -108121,14 +112064,16 @@ expr_code_doover: | |||
| 108121 | if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ | 112064 | if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ |
| 108122 | assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); | 112065 | assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); |
| 108123 | assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); | 112066 | assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); |
| 108124 | testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); | 112067 | assert( SQLITE_FUNC_BYTELEN==OPFLAG_BYTELENARG ); |
| 108125 | pFarg->a[0].pExpr->op2 = | 112068 | assert( (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG)==OPFLAG_BYTELENARG ); |
| 108126 | pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); | 112069 | testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_LENGTHARG ); |
| 112070 | testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_TYPEOFARG ); | ||
| 112071 | testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_BYTELENARG); | ||
| 112072 | pFarg->a[0].pExpr->op2 = pDef->funcFlags & OPFLAG_BYTELENARG; | ||
| 108127 | } | 112073 | } |
| 108128 | } | 112074 | } |
| 108129 | 112075 | ||
| 108130 | sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, | 112076 | sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR); |
| 108131 | SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); | ||
| 108132 | }else{ | 112077 | }else{ |
| 108133 | r1 = 0; | 112078 | r1 = 0; |
| 108134 | } | 112079 | } |
| @@ -108229,17 +112174,16 @@ expr_code_doover: | |||
| 108229 | return target; | 112174 | return target; |
| 108230 | } | 112175 | } |
| 108231 | case TK_COLLATE: { | 112176 | case TK_COLLATE: { |
| 108232 | if( !ExprHasProperty(pExpr, EP_Collate) | 112177 | if( !ExprHasProperty(pExpr, EP_Collate) ){ |
| 108233 | && ALWAYS(pExpr->pLeft) | 112178 | /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called |
| 108234 | && pExpr->pLeft->op==TK_FUNCTION | 112179 | ** "SOFT-COLLATE" that is added to constraints that are pushed down |
| 108235 | ){ | 112180 | ** from outer queries into sub-queries by the push-down optimization. |
| 108236 | inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); | 112181 | ** Clear subtypes as subtypes may not cross a subquery boundary. |
| 108237 | if( inReg!=target ){ | 112182 | */ |
| 108238 | sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); | 112183 | assert( pExpr->pLeft ); |
| 108239 | inReg = target; | 112184 | sqlite3ExprCode(pParse, pExpr->pLeft, target); |
| 108240 | } | 112185 | sqlite3VdbeAddOp1(v, OP_ClrSubtype, target); |
| 108241 | sqlite3VdbeAddOp1(v, OP_ClrSubtype, inReg); | 112186 | return target; |
| 108242 | return inReg; | ||
| 108243 | }else{ | 112187 | }else{ |
| 108244 | pExpr = pExpr->pLeft; | 112188 | pExpr = pExpr->pLeft; |
| 108245 | goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */ | 112189 | goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */ |
| @@ -108325,16 +112269,34 @@ expr_code_doover: | |||
| 108325 | case TK_IF_NULL_ROW: { | 112269 | case TK_IF_NULL_ROW: { |
| 108326 | int addrINR; | 112270 | int addrINR; |
| 108327 | u8 okConstFactor = pParse->okConstFactor; | 112271 | u8 okConstFactor = pParse->okConstFactor; |
| 108328 | addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); | 112272 | AggInfo *pAggInfo = pExpr->pAggInfo; |
| 108329 | /* Temporarily disable factoring of constant expressions, since | 112273 | if( pAggInfo ){ |
| 108330 | ** even though expressions may appear to be constant, they are not | 112274 | assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn ); |
| 108331 | ** really constant because they originate from the right-hand side | 112275 | if( !pAggInfo->directMode ){ |
| 108332 | ** of a LEFT JOIN. */ | 112276 | inReg = AggInfoColumnReg(pAggInfo, pExpr->iAgg); |
| 108333 | pParse->okConstFactor = 0; | 112277 | break; |
| 108334 | inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); | 112278 | } |
| 112279 | if( pExpr->pAggInfo->useSortingIdx ){ | ||
| 112280 | sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, | ||
| 112281 | pAggInfo->aCol[pExpr->iAgg].iSorterColumn, | ||
| 112282 | target); | ||
| 112283 | inReg = target; | ||
| 112284 | break; | ||
| 112285 | } | ||
| 112286 | } | ||
| 112287 | addrINR = sqlite3VdbeAddOp3(v, OP_IfNullRow, pExpr->iTable, 0, target); | ||
| 112288 | /* The OP_IfNullRow opcode above can overwrite the result register with | ||
| 112289 | ** NULL. So we have to ensure that the result register is not a value | ||
| 112290 | ** that is suppose to be a constant. Two defenses are needed: | ||
| 112291 | ** (1) Temporarily disable factoring of constant expressions | ||
| 112292 | ** (2) Make sure the computed value really is stored in register | ||
| 112293 | ** "target" and not someplace else. | ||
| 112294 | */ | ||
| 112295 | pParse->okConstFactor = 0; /* note (1) above */ | ||
| 112296 | sqlite3ExprCode(pParse, pExpr->pLeft, target); | ||
| 112297 | assert( target==inReg ); | ||
| 108335 | pParse->okConstFactor = okConstFactor; | 112298 | pParse->okConstFactor = okConstFactor; |
| 108336 | sqlite3VdbeJumpHere(v, addrINR); | 112299 | sqlite3VdbeJumpHere(v, addrINR); |
| 108337 | sqlite3VdbeChangeP3(v, addrINR, inReg); | ||
| 108338 | break; | 112300 | break; |
| 108339 | } | 112301 | } |
| 108340 | 112302 | ||
| @@ -108468,7 +112430,7 @@ expr_code_doover: | |||
| 108468 | ** | 112430 | ** |
| 108469 | ** If regDest>=0 then the result is always stored in that register and the | 112431 | ** If regDest>=0 then the result is always stored in that register and the |
| 108470 | ** result is not reusable. If regDest<0 then this routine is free to | 112432 | ** result is not reusable. If regDest<0 then this routine is free to |
| 108471 | ** store the value whereever it wants. The register where the expression | 112433 | ** store the value wherever it wants. The register where the expression |
| 108472 | ** is stored is returned. When regDest<0, two identical expressions might | 112434 | ** is stored is returned. When regDest<0, two identical expressions might |
| 108473 | ** code to the same register, if they do not contain function calls and hence | 112435 | ** code to the same register, if they do not contain function calls and hence |
| 108474 | ** are factored out into the initialization section at the end of the | 112436 | ** are factored out into the initialization section at the end of the |
| @@ -108571,7 +112533,9 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ | |||
| 108571 | inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); | 112533 | inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); |
| 108572 | if( inReg!=target ){ | 112534 | if( inReg!=target ){ |
| 108573 | u8 op; | 112535 | u8 op; |
| 108574 | if( ALWAYS(pExpr) && ExprHasProperty(pExpr,EP_Subquery) ){ | 112536 | if( ALWAYS(pExpr) |
| 112537 | && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER) | ||
| 112538 | ){ | ||
| 108575 | op = OP_Copy; | 112539 | op = OP_Copy; |
| 108576 | }else{ | 112540 | }else{ |
| 108577 | op = OP_SCopy; | 112541 | op = OP_SCopy; |
| @@ -108666,7 +112630,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList( | |||
| 108666 | if( inReg!=target+i ){ | 112630 | if( inReg!=target+i ){ |
| 108667 | VdbeOp *pOp; | 112631 | VdbeOp *pOp; |
| 108668 | if( copyOp==OP_Copy | 112632 | if( copyOp==OP_Copy |
| 108669 | && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy | 112633 | && (pOp=sqlite3VdbeGetLastOp(v))->opcode==OP_Copy |
| 108670 | && pOp->p1+pOp->p3+1==inReg | 112634 | && pOp->p1+pOp->p3+1==inReg |
| 108671 | && pOp->p2+pOp->p3+1==target+i | 112635 | && pOp->p2+pOp->p3+1==target+i |
| 108672 | && pOp->p5==0 /* The do-not-merge flag must be clear */ | 112636 | && pOp->p5==0 /* The do-not-merge flag must be clear */ |
| @@ -108865,6 +112829,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int | |||
| 108865 | assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); | 112829 | assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); |
| 108866 | assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); | 112830 | assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); |
| 108867 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); | 112831 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); |
| 112832 | sqlite3VdbeTypeofColumn(v, r1); | ||
| 108868 | sqlite3VdbeAddOp2(v, op, r1, dest); | 112833 | sqlite3VdbeAddOp2(v, op, r1, dest); |
| 108869 | VdbeCoverageIf(v, op==TK_ISNULL); | 112834 | VdbeCoverageIf(v, op==TK_ISNULL); |
| 108870 | VdbeCoverageIf(v, op==TK_NOTNULL); | 112835 | VdbeCoverageIf(v, op==TK_NOTNULL); |
| @@ -109039,6 +113004,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int | |||
| 109039 | case TK_ISNULL: | 113004 | case TK_ISNULL: |
| 109040 | case TK_NOTNULL: { | 113005 | case TK_NOTNULL: { |
| 109041 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); | 113006 | r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); |
| 113007 | sqlite3VdbeTypeofColumn(v, r1); | ||
| 109042 | sqlite3VdbeAddOp2(v, op, r1, dest); | 113008 | sqlite3VdbeAddOp2(v, op, r1, dest); |
| 109043 | testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); | 113009 | testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); |
| 109044 | testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); | 113010 | testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); |
| @@ -109192,7 +113158,13 @@ SQLITE_PRIVATE int sqlite3ExprCompare( | |||
| 109192 | if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ | 113158 | if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ |
| 109193 | return 1; | 113159 | return 1; |
| 109194 | } | 113160 | } |
| 109195 | return 2; | 113161 | if( pA->op==TK_AGG_COLUMN && pB->op==TK_COLUMN |
| 113162 | && pB->iTable<0 && pA->iTable==iTab | ||
| 113163 | ){ | ||
| 113164 | /* fall through */ | ||
| 113165 | }else{ | ||
| 113166 | return 2; | ||
| 113167 | } | ||
| 109196 | } | 113168 | } |
| 109197 | assert( !ExprHasProperty(pA, EP_IntValue) ); | 113169 | assert( !ExprHasProperty(pA, EP_IntValue) ); |
| 109198 | assert( !ExprHasProperty(pB, EP_IntValue) ); | 113170 | assert( !ExprHasProperty(pB, EP_IntValue) ); |
| @@ -109376,7 +113348,7 @@ static int exprImpliesNotNull( | |||
| 109376 | ** pE1: x!=123 pE2: x IS NOT NULL Result: true | 113348 | ** pE1: x!=123 pE2: x IS NOT NULL Result: true |
| 109377 | ** pE1: x!=?1 pE2: x IS NOT NULL Result: true | 113349 | ** pE1: x!=?1 pE2: x IS NOT NULL Result: true |
| 109378 | ** pE1: x IS NULL pE2: x IS NOT NULL Result: false | 113350 | ** pE1: x IS NULL pE2: x IS NOT NULL Result: false |
| 109379 | ** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false | 113351 | ** pE1: x IS ?2 pE2: x IS NOT NULL Result: false |
| 109380 | ** | 113352 | ** |
| 109381 | ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has | 113353 | ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has |
| 109382 | ** Expr.iTable<0 then assume a table number given by iTab. | 113354 | ** Expr.iTable<0 then assume a table number given by iTab. |
| @@ -109413,11 +113385,29 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr( | |||
| 109413 | return 0; | 113385 | return 0; |
| 109414 | } | 113386 | } |
| 109415 | 113387 | ||
| 113388 | /* This is a helper function to impliesNotNullRow(). In this routine, | ||
| 113389 | ** set pWalker->eCode to one only if *both* of the input expressions | ||
| 113390 | ** separately have the implies-not-null-row property. | ||
| 113391 | */ | ||
| 113392 | static void bothImplyNotNullRow(Walker *pWalker, Expr *pE1, Expr *pE2){ | ||
| 113393 | if( pWalker->eCode==0 ){ | ||
| 113394 | sqlite3WalkExpr(pWalker, pE1); | ||
| 113395 | if( pWalker->eCode ){ | ||
| 113396 | pWalker->eCode = 0; | ||
| 113397 | sqlite3WalkExpr(pWalker, pE2); | ||
| 113398 | } | ||
| 113399 | } | ||
| 113400 | } | ||
| 113401 | |||
| 109416 | /* | 113402 | /* |
| 109417 | ** This is the Expr node callback for sqlite3ExprImpliesNonNullRow(). | 113403 | ** This is the Expr node callback for sqlite3ExprImpliesNonNullRow(). |
| 109418 | ** If the expression node requires that the table at pWalker->iCur | 113404 | ** If the expression node requires that the table at pWalker->iCur |
| 109419 | ** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. | 113405 | ** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. |
| 109420 | ** | 113406 | ** |
| 113407 | ** pWalker->mWFlags is non-zero if this inquiry is being undertaking on | ||
| 113408 | ** behalf of a RIGHT JOIN (or FULL JOIN). That makes a difference when | ||
| 113409 | ** evaluating terms in the ON clause of an inner join. | ||
| 113410 | ** | ||
| 109421 | ** This routine controls an optimization. False positives (setting | 113411 | ** This routine controls an optimization. False positives (setting |
| 109422 | ** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives | 113412 | ** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives |
| 109423 | ** (never setting pWalker->eCode) is a harmless missed optimization. | 113413 | ** (never setting pWalker->eCode) is a harmless missed optimization. |
| @@ -109426,28 +113416,33 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ | |||
| 109426 | testcase( pExpr->op==TK_AGG_COLUMN ); | 113416 | testcase( pExpr->op==TK_AGG_COLUMN ); |
| 109427 | testcase( pExpr->op==TK_AGG_FUNCTION ); | 113417 | testcase( pExpr->op==TK_AGG_FUNCTION ); |
| 109428 | if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune; | 113418 | if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune; |
| 113419 | if( ExprHasProperty(pExpr, EP_InnerON) && pWalker->mWFlags ){ | ||
| 113420 | /* If iCur is used in an inner-join ON clause to the left of a | ||
| 113421 | ** RIGHT JOIN, that does *not* mean that the table must be non-null. | ||
| 113422 | ** But it is difficult to check for that condition precisely. | ||
| 113423 | ** To keep things simple, any use of iCur from any inner-join is | ||
| 113424 | ** ignored while attempting to simplify a RIGHT JOIN. */ | ||
| 113425 | return WRC_Prune; | ||
| 113426 | } | ||
| 109429 | switch( pExpr->op ){ | 113427 | switch( pExpr->op ){ |
| 109430 | case TK_ISNOT: | 113428 | case TK_ISNOT: |
| 109431 | case TK_ISNULL: | 113429 | case TK_ISNULL: |
| 109432 | case TK_NOTNULL: | 113430 | case TK_NOTNULL: |
| 109433 | case TK_IS: | 113431 | case TK_IS: |
| 109434 | case TK_OR: | ||
| 109435 | case TK_VECTOR: | 113432 | case TK_VECTOR: |
| 109436 | case TK_CASE: | ||
| 109437 | case TK_IN: | ||
| 109438 | case TK_FUNCTION: | 113433 | case TK_FUNCTION: |
| 109439 | case TK_TRUTH: | 113434 | case TK_TRUTH: |
| 113435 | case TK_CASE: | ||
| 109440 | testcase( pExpr->op==TK_ISNOT ); | 113436 | testcase( pExpr->op==TK_ISNOT ); |
| 109441 | testcase( pExpr->op==TK_ISNULL ); | 113437 | testcase( pExpr->op==TK_ISNULL ); |
| 109442 | testcase( pExpr->op==TK_NOTNULL ); | 113438 | testcase( pExpr->op==TK_NOTNULL ); |
| 109443 | testcase( pExpr->op==TK_IS ); | 113439 | testcase( pExpr->op==TK_IS ); |
| 109444 | testcase( pExpr->op==TK_OR ); | ||
| 109445 | testcase( pExpr->op==TK_VECTOR ); | 113440 | testcase( pExpr->op==TK_VECTOR ); |
| 109446 | testcase( pExpr->op==TK_CASE ); | ||
| 109447 | testcase( pExpr->op==TK_IN ); | ||
| 109448 | testcase( pExpr->op==TK_FUNCTION ); | 113441 | testcase( pExpr->op==TK_FUNCTION ); |
| 109449 | testcase( pExpr->op==TK_TRUTH ); | 113442 | testcase( pExpr->op==TK_TRUTH ); |
| 113443 | testcase( pExpr->op==TK_CASE ); | ||
| 109450 | return WRC_Prune; | 113444 | return WRC_Prune; |
| 113445 | |||
| 109451 | case TK_COLUMN: | 113446 | case TK_COLUMN: |
| 109452 | if( pWalker->u.iCur==pExpr->iTable ){ | 113447 | if( pWalker->u.iCur==pExpr->iTable ){ |
| 109453 | pWalker->eCode = 1; | 113448 | pWalker->eCode = 1; |
| @@ -109455,21 +113450,38 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ | |||
| 109455 | } | 113450 | } |
| 109456 | return WRC_Prune; | 113451 | return WRC_Prune; |
| 109457 | 113452 | ||
| 113453 | case TK_OR: | ||
| 109458 | case TK_AND: | 113454 | case TK_AND: |
| 109459 | if( pWalker->eCode==0 ){ | 113455 | /* Both sides of an AND or OR must separately imply non-null-row. |
| 113456 | ** Consider these cases: | ||
| 113457 | ** 1. NOT (x AND y) | ||
| 113458 | ** 2. x OR y | ||
| 113459 | ** If only one of x or y is non-null-row, then the overall expression | ||
| 113460 | ** can be true if the other arm is false (case 1) or true (case 2). | ||
| 113461 | */ | ||
| 113462 | testcase( pExpr->op==TK_OR ); | ||
| 113463 | testcase( pExpr->op==TK_AND ); | ||
| 113464 | bothImplyNotNullRow(pWalker, pExpr->pLeft, pExpr->pRight); | ||
| 113465 | return WRC_Prune; | ||
| 113466 | |||
| 113467 | case TK_IN: | ||
| 113468 | /* Beware of "x NOT IN ()" and "x NOT IN (SELECT 1 WHERE false)", | ||
| 113469 | ** both of which can be true. But apart from these cases, if | ||
| 113470 | ** the left-hand side of the IN is NULL then the IN itself will be | ||
| 113471 | ** NULL. */ | ||
| 113472 | if( ExprUseXList(pExpr) && ALWAYS(pExpr->x.pList->nExpr>0) ){ | ||
| 109460 | sqlite3WalkExpr(pWalker, pExpr->pLeft); | 113473 | sqlite3WalkExpr(pWalker, pExpr->pLeft); |
| 109461 | if( pWalker->eCode ){ | ||
| 109462 | pWalker->eCode = 0; | ||
| 109463 | sqlite3WalkExpr(pWalker, pExpr->pRight); | ||
| 109464 | } | ||
| 109465 | } | 113474 | } |
| 109466 | return WRC_Prune; | 113475 | return WRC_Prune; |
| 109467 | 113476 | ||
| 109468 | case TK_BETWEEN: | 113477 | case TK_BETWEEN: |
| 109469 | if( sqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){ | 113478 | /* In "x NOT BETWEEN y AND z" either x must be non-null-row or else |
| 109470 | assert( pWalker->eCode ); | 113479 | ** both y and z must be non-null row */ |
| 109471 | return WRC_Abort; | 113480 | assert( ExprUseXList(pExpr) ); |
| 109472 | } | 113481 | assert( pExpr->x.pList->nExpr==2 ); |
| 113482 | sqlite3WalkExpr(pWalker, pExpr->pLeft); | ||
| 113483 | bothImplyNotNullRow(pWalker, pExpr->x.pList->a[0].pExpr, | ||
| 113484 | pExpr->x.pList->a[1].pExpr); | ||
| 109473 | return WRC_Prune; | 113485 | return WRC_Prune; |
| 109474 | 113486 | ||
| 109475 | /* Virtual tables are allowed to use constraints like x=NULL. So | 113487 | /* Virtual tables are allowed to use constraints like x=NULL. So |
| @@ -109494,10 +113506,10 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ | |||
| 109494 | assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); | 113506 | assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); |
| 109495 | assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); | 113507 | assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); |
| 109496 | if( (pLeft->op==TK_COLUMN | 113508 | if( (pLeft->op==TK_COLUMN |
| 109497 | && pLeft->y.pTab!=0 | 113509 | && ALWAYS(pLeft->y.pTab!=0) |
| 109498 | && IsVirtual(pLeft->y.pTab)) | 113510 | && IsVirtual(pLeft->y.pTab)) |
| 109499 | || (pRight->op==TK_COLUMN | 113511 | || (pRight->op==TK_COLUMN |
| 109500 | && pRight->y.pTab!=0 | 113512 | && ALWAYS(pRight->y.pTab!=0) |
| 109501 | && IsVirtual(pRight->y.pTab)) | 113513 | && IsVirtual(pRight->y.pTab)) |
| 109502 | ){ | 113514 | ){ |
| 109503 | return WRC_Prune; | 113515 | return WRC_Prune; |
| @@ -109531,7 +113543,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ | |||
| 109531 | ** be non-NULL, then the LEFT JOIN can be safely converted into an | 113543 | ** be non-NULL, then the LEFT JOIN can be safely converted into an |
| 109532 | ** ordinary join. | 113544 | ** ordinary join. |
| 109533 | */ | 113545 | */ |
| 109534 | SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ | 113546 | SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){ |
| 109535 | Walker w; | 113547 | Walker w; |
| 109536 | p = sqlite3ExprSkipCollateAndLikely(p); | 113548 | p = sqlite3ExprSkipCollateAndLikely(p); |
| 109537 | if( p==0 ) return 0; | 113549 | if( p==0 ) return 0; |
| @@ -109539,7 +113551,7 @@ SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ | |||
| 109539 | p = p->pLeft; | 113551 | p = p->pLeft; |
| 109540 | }else{ | 113552 | }else{ |
| 109541 | while( p->op==TK_AND ){ | 113553 | while( p->op==TK_AND ){ |
| 109542 | if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1; | 113554 | if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab, isRJ) ) return 1; |
| 109543 | p = p->pRight; | 113555 | p = p->pRight; |
| 109544 | } | 113556 | } |
| 109545 | } | 113557 | } |
| @@ -109547,6 +113559,7 @@ SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ | |||
| 109547 | w.xSelectCallback = 0; | 113559 | w.xSelectCallback = 0; |
| 109548 | w.xSelectCallback2 = 0; | 113560 | w.xSelectCallback2 = 0; |
| 109549 | w.eCode = 0; | 113561 | w.eCode = 0; |
| 113562 | w.mWFlags = isRJ!=0; | ||
| 109550 | w.u.iCur = iTab; | 113563 | w.u.iCur = iTab; |
| 109551 | sqlite3WalkExpr(&w, p); | 113564 | sqlite3WalkExpr(&w, p); |
| 109552 | return w.eCode; | 113565 | return w.eCode; |
| @@ -109607,7 +113620,7 @@ SQLITE_PRIVATE int sqlite3ExprCoveredByIndex( | |||
| 109607 | } | 113620 | } |
| 109608 | 113621 | ||
| 109609 | 113622 | ||
| 109610 | /* Structure used to pass information throught the Walker in order to | 113623 | /* Structure used to pass information throughout the Walker in order to |
| 109611 | ** implement sqlite3ReferencesSrcList(). | 113624 | ** implement sqlite3ReferencesSrcList(). |
| 109612 | */ | 113625 | */ |
| 109613 | struct RefSrcList { | 113626 | struct RefSrcList { |
| @@ -109702,6 +113715,7 @@ static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){ | |||
| 109702 | SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){ | 113715 | SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){ |
| 109703 | Walker w; | 113716 | Walker w; |
| 109704 | struct RefSrcList x; | 113717 | struct RefSrcList x; |
| 113718 | assert( pParse->db!=0 ); | ||
| 109705 | memset(&w, 0, sizeof(w)); | 113719 | memset(&w, 0, sizeof(w)); |
| 109706 | memset(&x, 0, sizeof(x)); | 113720 | memset(&x, 0, sizeof(x)); |
| 109707 | w.xExprCallback = exprRefToSrcList; | 113721 | w.xExprCallback = exprRefToSrcList; |
| @@ -109718,7 +113732,7 @@ SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList | |||
| 109718 | sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); | 113732 | sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); |
| 109719 | } | 113733 | } |
| 109720 | #endif | 113734 | #endif |
| 109721 | sqlite3DbFree(pParse->db, x.aiExclude); | 113735 | if( x.aiExclude ) sqlite3DbNNFreeNN(pParse->db, x.aiExclude); |
| 109722 | if( w.eCode & 0x01 ){ | 113736 | if( w.eCode & 0x01 ){ |
| 109723 | return 1; | 113737 | return 1; |
| 109724 | }else if( w.eCode ){ | 113738 | }else if( w.eCode ){ |
| @@ -109736,10 +113750,8 @@ SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList | |||
| 109736 | ** it does, make a copy. This is done because the pExpr argument is | 113750 | ** it does, make a copy. This is done because the pExpr argument is |
| 109737 | ** subject to change. | 113751 | ** subject to change. |
| 109738 | ** | 113752 | ** |
| 109739 | ** The copy is stored on pParse->pConstExpr with a register number of 0. | 113753 | ** The copy is scheduled for deletion using the sqlite3ExprDeferredDelete() |
| 109740 | ** This will cause the expression to be deleted automatically when the | 113754 | ** which builds on the sqlite3ParserAddCleanup() mechanism. |
| 109741 | ** Parse object is destroyed, but the zero register number means that it | ||
| 109742 | ** will not generate any code in the preamble. | ||
| 109743 | */ | 113755 | */ |
| 109744 | static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ | 113756 | static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ |
| 109745 | if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced)) | 113757 | if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced)) |
| @@ -109749,10 +113761,11 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ | |||
| 109749 | int iAgg = pExpr->iAgg; | 113761 | int iAgg = pExpr->iAgg; |
| 109750 | Parse *pParse = pWalker->pParse; | 113762 | Parse *pParse = pWalker->pParse; |
| 109751 | sqlite3 *db = pParse->db; | 113763 | sqlite3 *db = pParse->db; |
| 109752 | assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_AGG_FUNCTION ); | 113764 | assert( iAgg>=0 ); |
| 109753 | if( pExpr->op==TK_AGG_COLUMN ){ | 113765 | if( pExpr->op!=TK_AGG_FUNCTION ){ |
| 109754 | assert( iAgg>=0 && iAgg<pAggInfo->nColumn ); | 113766 | if( iAgg<pAggInfo->nColumn |
| 109755 | if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){ | 113767 | && pAggInfo->aCol[iAgg].pCExpr==pExpr |
| 113768 | ){ | ||
| 109756 | pExpr = sqlite3ExprDup(db, pExpr, 0); | 113769 | pExpr = sqlite3ExprDup(db, pExpr, 0); |
| 109757 | if( pExpr ){ | 113770 | if( pExpr ){ |
| 109758 | pAggInfo->aCol[iAgg].pCExpr = pExpr; | 113771 | pAggInfo->aCol[iAgg].pCExpr = pExpr; |
| @@ -109760,8 +113773,10 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ | |||
| 109760 | } | 113773 | } |
| 109761 | } | 113774 | } |
| 109762 | }else{ | 113775 | }else{ |
| 109763 | assert( iAgg>=0 && iAgg<pAggInfo->nFunc ); | 113776 | assert( pExpr->op==TK_AGG_FUNCTION ); |
| 109764 | if( pAggInfo->aFunc[iAgg].pFExpr==pExpr ){ | 113777 | if( ALWAYS(iAgg<pAggInfo->nFunc) |
| 113778 | && pAggInfo->aFunc[iAgg].pFExpr==pExpr | ||
| 113779 | ){ | ||
| 109765 | pExpr = sqlite3ExprDup(db, pExpr, 0); | 113780 | pExpr = sqlite3ExprDup(db, pExpr, 0); |
| 109766 | if( pExpr ){ | 113781 | if( pExpr ){ |
| 109767 | pAggInfo->aFunc[iAgg].pFExpr = pExpr; | 113782 | pAggInfo->aFunc[iAgg].pFExpr = pExpr; |
| @@ -109817,6 +113832,74 @@ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ | |||
| 109817 | } | 113832 | } |
| 109818 | 113833 | ||
| 109819 | /* | 113834 | /* |
| 113835 | ** Search the AggInfo object for an aCol[] entry that has iTable and iColumn. | ||
| 113836 | ** Return the index in aCol[] of the entry that describes that column. | ||
| 113837 | ** | ||
| 113838 | ** If no prior entry is found, create a new one and return -1. The | ||
| 113839 | ** new column will have an index of pAggInfo->nColumn-1. | ||
| 113840 | */ | ||
| 113841 | static void findOrCreateAggInfoColumn( | ||
| 113842 | Parse *pParse, /* Parsing context */ | ||
| 113843 | AggInfo *pAggInfo, /* The AggInfo object to search and/or modify */ | ||
| 113844 | Expr *pExpr /* Expr describing the column to find or insert */ | ||
| 113845 | ){ | ||
| 113846 | struct AggInfo_col *pCol; | ||
| 113847 | int k; | ||
| 113848 | |||
| 113849 | assert( pAggInfo->iFirstReg==0 ); | ||
| 113850 | pCol = pAggInfo->aCol; | ||
| 113851 | for(k=0; k<pAggInfo->nColumn; k++, pCol++){ | ||
| 113852 | if( pCol->pCExpr==pExpr ) return; | ||
| 113853 | if( pCol->iTable==pExpr->iTable | ||
| 113854 | && pCol->iColumn==pExpr->iColumn | ||
| 113855 | && pExpr->op!=TK_IF_NULL_ROW | ||
| 113856 | ){ | ||
| 113857 | goto fix_up_expr; | ||
| 113858 | } | ||
| 113859 | } | ||
| 113860 | k = addAggInfoColumn(pParse->db, pAggInfo); | ||
| 113861 | if( k<0 ){ | ||
| 113862 | /* OOM on resize */ | ||
| 113863 | assert( pParse->db->mallocFailed ); | ||
| 113864 | return; | ||
| 113865 | } | ||
| 113866 | pCol = &pAggInfo->aCol[k]; | ||
| 113867 | assert( ExprUseYTab(pExpr) ); | ||
| 113868 | pCol->pTab = pExpr->y.pTab; | ||
| 113869 | pCol->iTable = pExpr->iTable; | ||
| 113870 | pCol->iColumn = pExpr->iColumn; | ||
| 113871 | pCol->iSorterColumn = -1; | ||
| 113872 | pCol->pCExpr = pExpr; | ||
| 113873 | if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){ | ||
| 113874 | int j, n; | ||
| 113875 | ExprList *pGB = pAggInfo->pGroupBy; | ||
| 113876 | struct ExprList_item *pTerm = pGB->a; | ||
| 113877 | n = pGB->nExpr; | ||
| 113878 | for(j=0; j<n; j++, pTerm++){ | ||
| 113879 | Expr *pE = pTerm->pExpr; | ||
| 113880 | if( pE->op==TK_COLUMN | ||
| 113881 | && pE->iTable==pExpr->iTable | ||
| 113882 | && pE->iColumn==pExpr->iColumn | ||
| 113883 | ){ | ||
| 113884 | pCol->iSorterColumn = j; | ||
| 113885 | break; | ||
| 113886 | } | ||
| 113887 | } | ||
| 113888 | } | ||
| 113889 | if( pCol->iSorterColumn<0 ){ | ||
| 113890 | pCol->iSorterColumn = pAggInfo->nSortingColumn++; | ||
| 113891 | } | ||
| 113892 | fix_up_expr: | ||
| 113893 | ExprSetVVAProperty(pExpr, EP_NoReduce); | ||
| 113894 | assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo ); | ||
| 113895 | pExpr->pAggInfo = pAggInfo; | ||
| 113896 | if( pExpr->op==TK_COLUMN ){ | ||
| 113897 | pExpr->op = TK_AGG_COLUMN; | ||
| 113898 | } | ||
| 113899 | pExpr->iAgg = (i16)k; | ||
| 113900 | } | ||
| 113901 | |||
| 113902 | /* | ||
| 109820 | ** This is the xExprCallback for a tree walker. It is used to | 113903 | ** This is the xExprCallback for a tree walker. It is used to |
| 109821 | ** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates | 113904 | ** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates |
| 109822 | ** for additional information. | 113905 | ** for additional information. |
| @@ -109829,76 +113912,64 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ | |||
| 109829 | AggInfo *pAggInfo = pNC->uNC.pAggInfo; | 113912 | AggInfo *pAggInfo = pNC->uNC.pAggInfo; |
| 109830 | 113913 | ||
| 109831 | assert( pNC->ncFlags & NC_UAggInfo ); | 113914 | assert( pNC->ncFlags & NC_UAggInfo ); |
| 113915 | assert( pAggInfo->iFirstReg==0 ); | ||
| 109832 | switch( pExpr->op ){ | 113916 | switch( pExpr->op ){ |
| 113917 | default: { | ||
| 113918 | IndexedExpr *pIEpr; | ||
| 113919 | Expr tmp; | ||
| 113920 | assert( pParse->iSelfTab==0 ); | ||
| 113921 | if( (pNC->ncFlags & NC_InAggFunc)==0 ) break; | ||
| 113922 | if( pParse->pIdxEpr==0 ) break; | ||
| 113923 | for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ | ||
| 113924 | int iDataCur = pIEpr->iDataCur; | ||
| 113925 | if( iDataCur<0 ) continue; | ||
| 113926 | if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break; | ||
| 113927 | } | ||
| 113928 | if( pIEpr==0 ) break; | ||
| 113929 | if( NEVER(!ExprUseYTab(pExpr)) ) break; | ||
| 113930 | for(i=0; i<pSrcList->nSrc; i++){ | ||
| 113931 | if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break; | ||
| 113932 | } | ||
| 113933 | if( i>=pSrcList->nSrc ) break; | ||
| 113934 | if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ | ||
| 113935 | if( pParse->nErr ){ return WRC_Abort; } | ||
| 113936 | |||
| 113937 | /* If we reach this point, it means that expression pExpr can be | ||
| 113938 | ** translated into a reference to an index column as described by | ||
| 113939 | ** pIEpr. | ||
| 113940 | */ | ||
| 113941 | memset(&tmp, 0, sizeof(tmp)); | ||
| 113942 | tmp.op = TK_AGG_COLUMN; | ||
| 113943 | tmp.iTable = pIEpr->iIdxCur; | ||
| 113944 | tmp.iColumn = pIEpr->iIdxCol; | ||
| 113945 | findOrCreateAggInfoColumn(pParse, pAggInfo, &tmp); | ||
| 113946 | if( pParse->nErr ){ return WRC_Abort; } | ||
| 113947 | assert( pAggInfo->aCol!=0 ); | ||
| 113948 | assert( tmp.iAgg<pAggInfo->nColumn ); | ||
| 113949 | pAggInfo->aCol[tmp.iAgg].pCExpr = pExpr; | ||
| 113950 | pExpr->pAggInfo = pAggInfo; | ||
| 113951 | pExpr->iAgg = tmp.iAgg; | ||
| 113952 | return WRC_Prune; | ||
| 113953 | } | ||
| 113954 | case TK_IF_NULL_ROW: | ||
| 109833 | case TK_AGG_COLUMN: | 113955 | case TK_AGG_COLUMN: |
| 109834 | case TK_COLUMN: { | 113956 | case TK_COLUMN: { |
| 109835 | testcase( pExpr->op==TK_AGG_COLUMN ); | 113957 | testcase( pExpr->op==TK_AGG_COLUMN ); |
| 109836 | testcase( pExpr->op==TK_COLUMN ); | 113958 | testcase( pExpr->op==TK_COLUMN ); |
| 113959 | testcase( pExpr->op==TK_IF_NULL_ROW ); | ||
| 109837 | /* Check to see if the column is in one of the tables in the FROM | 113960 | /* Check to see if the column is in one of the tables in the FROM |
| 109838 | ** clause of the aggregate query */ | 113961 | ** clause of the aggregate query */ |
| 109839 | if( ALWAYS(pSrcList!=0) ){ | 113962 | if( ALWAYS(pSrcList!=0) ){ |
| 109840 | SrcItem *pItem = pSrcList->a; | 113963 | SrcItem *pItem = pSrcList->a; |
| 109841 | for(i=0; i<pSrcList->nSrc; i++, pItem++){ | 113964 | for(i=0; i<pSrcList->nSrc; i++, pItem++){ |
| 109842 | struct AggInfo_col *pCol; | ||
| 109843 | assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); | 113965 | assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| 109844 | if( pExpr->iTable==pItem->iCursor ){ | 113966 | if( pExpr->iTable==pItem->iCursor ){ |
| 109845 | /* If we reach this point, it means that pExpr refers to a table | 113967 | findOrCreateAggInfoColumn(pParse, pAggInfo, pExpr); |
| 109846 | ** that is in the FROM clause of the aggregate query. | ||
| 109847 | ** | ||
| 109848 | ** Make an entry for the column in pAggInfo->aCol[] if there | ||
| 109849 | ** is not an entry there already. | ||
| 109850 | */ | ||
| 109851 | int k; | ||
| 109852 | pCol = pAggInfo->aCol; | ||
| 109853 | for(k=0; k<pAggInfo->nColumn; k++, pCol++){ | ||
| 109854 | if( pCol->iTable==pExpr->iTable && | ||
| 109855 | pCol->iColumn==pExpr->iColumn ){ | ||
| 109856 | break; | ||
| 109857 | } | ||
| 109858 | } | ||
| 109859 | if( (k>=pAggInfo->nColumn) | ||
| 109860 | && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 | ||
| 109861 | ){ | ||
| 109862 | pCol = &pAggInfo->aCol[k]; | ||
| 109863 | assert( ExprUseYTab(pExpr) ); | ||
| 109864 | pCol->pTab = pExpr->y.pTab; | ||
| 109865 | pCol->iTable = pExpr->iTable; | ||
| 109866 | pCol->iColumn = pExpr->iColumn; | ||
| 109867 | pCol->iMem = ++pParse->nMem; | ||
| 109868 | pCol->iSorterColumn = -1; | ||
| 109869 | pCol->pCExpr = pExpr; | ||
| 109870 | if( pAggInfo->pGroupBy ){ | ||
| 109871 | int j, n; | ||
| 109872 | ExprList *pGB = pAggInfo->pGroupBy; | ||
| 109873 | struct ExprList_item *pTerm = pGB->a; | ||
| 109874 | n = pGB->nExpr; | ||
| 109875 | for(j=0; j<n; j++, pTerm++){ | ||
| 109876 | Expr *pE = pTerm->pExpr; | ||
| 109877 | if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable && | ||
| 109878 | pE->iColumn==pExpr->iColumn ){ | ||
| 109879 | pCol->iSorterColumn = j; | ||
| 109880 | break; | ||
| 109881 | } | ||
| 109882 | } | ||
| 109883 | } | ||
| 109884 | if( pCol->iSorterColumn<0 ){ | ||
| 109885 | pCol->iSorterColumn = pAggInfo->nSortingColumn++; | ||
| 109886 | } | ||
| 109887 | } | ||
| 109888 | /* There is now an entry for pExpr in pAggInfo->aCol[] (either | ||
| 109889 | ** because it was there before or because we just created it). | ||
| 109890 | ** Convert the pExpr to be a TK_AGG_COLUMN referring to that | ||
| 109891 | ** pAggInfo->aCol[] entry. | ||
| 109892 | */ | ||
| 109893 | ExprSetVVAProperty(pExpr, EP_NoReduce); | ||
| 109894 | pExpr->pAggInfo = pAggInfo; | ||
| 109895 | pExpr->op = TK_AGG_COLUMN; | ||
| 109896 | pExpr->iAgg = (i16)k; | ||
| 109897 | break; | 113968 | break; |
| 109898 | } /* endif pExpr->iTable==pItem->iCursor */ | 113969 | } /* endif pExpr->iTable==pItem->iCursor */ |
| 109899 | } /* end loop over pSrcList */ | 113970 | } /* end loop over pSrcList */ |
| 109900 | } | 113971 | } |
| 109901 | return WRC_Prune; | 113972 | return WRC_Continue; |
| 109902 | } | 113973 | } |
| 109903 | case TK_AGG_FUNCTION: { | 113974 | case TK_AGG_FUNCTION: { |
| 109904 | if( (pNC->ncFlags & NC_InAggFunc)==0 | 113975 | if( (pNC->ncFlags & NC_InAggFunc)==0 |
| @@ -109923,7 +113994,6 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ | |||
| 109923 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); | 113994 | assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 109924 | pItem = &pAggInfo->aFunc[i]; | 113995 | pItem = &pAggInfo->aFunc[i]; |
| 109925 | pItem->pFExpr = pExpr; | 113996 | pItem->pFExpr = pExpr; |
| 109926 | pItem->iMem = ++pParse->nMem; | ||
| 109927 | assert( ExprUseUToken(pExpr) ); | 113997 | assert( ExprUseUToken(pExpr) ); |
| 109928 | pItem->pFunc = sqlite3FindFunction(pParse->db, | 113998 | pItem->pFunc = sqlite3FindFunction(pParse->db, |
| 109929 | pExpr->u.zToken, | 113999 | pExpr->u.zToken, |
| @@ -110053,6 +114123,37 @@ SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ | |||
| 110053 | } | 114123 | } |
| 110054 | 114124 | ||
| 110055 | /* | 114125 | /* |
| 114126 | ** Make sure sufficient registers have been allocated so that | ||
| 114127 | ** iReg is a valid register number. | ||
| 114128 | */ | ||
| 114129 | SQLITE_PRIVATE void sqlite3TouchRegister(Parse *pParse, int iReg){ | ||
| 114130 | if( pParse->nMem<iReg ) pParse->nMem = iReg; | ||
| 114131 | } | ||
| 114132 | |||
| 114133 | #if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) | ||
| 114134 | /* | ||
| 114135 | ** Return the latest reusable register in the set of all registers. | ||
| 114136 | ** The value returned is no less than iMin. If any register iMin or | ||
| 114137 | ** greater is in permanent use, then return one more than that last | ||
| 114138 | ** permanent register. | ||
| 114139 | */ | ||
| 114140 | SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse *pParse, int iMin){ | ||
| 114141 | const ExprList *pList = pParse->pConstExpr; | ||
| 114142 | if( pList ){ | ||
| 114143 | int i; | ||
| 114144 | for(i=0; i<pList->nExpr; i++){ | ||
| 114145 | if( pList->a[i].u.iConstExprReg>=iMin ){ | ||
| 114146 | iMin = pList->a[i].u.iConstExprReg + 1; | ||
| 114147 | } | ||
| 114148 | } | ||
| 114149 | } | ||
| 114150 | pParse->nTempReg = 0; | ||
| 114151 | pParse->nRangeReg = 0; | ||
| 114152 | return iMin; | ||
| 114153 | } | ||
| 114154 | #endif /* SQLITE_ENABLE_STAT4 || SQLITE_DEBUG */ | ||
| 114155 | |||
| 114156 | /* | ||
| 110056 | ** Validate that no temporary register falls within the range of | 114157 | ** Validate that no temporary register falls within the range of |
| 110057 | ** iFirst..iLast, inclusive. This routine is only call from within assert() | 114158 | ** iFirst..iLast, inclusive. This routine is only call from within assert() |
| 110058 | ** statements. | 114159 | ** statements. |
| @@ -110071,6 +114172,14 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ | |||
| 110071 | return 0; | 114172 | return 0; |
| 110072 | } | 114173 | } |
| 110073 | } | 114174 | } |
| 114175 | if( pParse->pConstExpr ){ | ||
| 114176 | ExprList *pList = pParse->pConstExpr; | ||
| 114177 | for(i=0; i<pList->nExpr; i++){ | ||
| 114178 | int iReg = pList->a[i].u.iConstExprReg; | ||
| 114179 | if( iReg==0 ) continue; | ||
| 114180 | if( iReg>=iFirst && iReg<=iLast ) return 0; | ||
| 114181 | } | ||
| 114182 | } | ||
| 110074 | return 1; | 114183 | return 1; |
| 110075 | } | 114184 | } |
| 110076 | #endif /* SQLITE_DEBUG */ | 114185 | #endif /* SQLITE_DEBUG */ |
| @@ -110621,7 +114730,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ | |||
| 110621 | pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); | 114730 | pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); |
| 110622 | pNew->pSchema = db->aDb[iDb].pSchema; | 114731 | pNew->pSchema = db->aDb[iDb].pSchema; |
| 110623 | pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; | 114732 | pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; |
| 110624 | pNew->nTabRef = 1; | 114733 | assert( pNew->nTabRef==1 ); |
| 110625 | 114734 | ||
| 110626 | exit_begin_add_column: | 114735 | exit_begin_add_column: |
| 110627 | sqlite3SrcListDelete(db, pSrc); | 114736 | sqlite3SrcListDelete(db, pSrc); |
| @@ -110820,13 +114929,14 @@ static void renameTokenCheckAll(Parse *pParse, const void *pPtr){ | |||
| 110820 | assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); | 114929 | assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); |
| 110821 | if( pParse->nErr==0 ){ | 114930 | if( pParse->nErr==0 ){ |
| 110822 | const RenameToken *p; | 114931 | const RenameToken *p; |
| 110823 | u8 i = 0; | 114932 | u32 i = 1; |
| 110824 | for(p=pParse->pRename; p; p=p->pNext){ | 114933 | for(p=pParse->pRename; p; p=p->pNext){ |
| 110825 | if( p->p ){ | 114934 | if( p->p ){ |
| 110826 | assert( p->p!=pPtr ); | 114935 | assert( p->p!=pPtr ); |
| 110827 | i += *(u8*)(p->p); | 114936 | i += *(u8*)(p->p) | 1; |
| 110828 | } | 114937 | } |
| 110829 | } | 114938 | } |
| 114939 | assert( i>0 ); | ||
| 110830 | } | 114940 | } |
| 110831 | } | 114941 | } |
| 110832 | #else | 114942 | #else |
| @@ -111125,7 +115235,7 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ | |||
| 111125 | } | 115235 | } |
| 111126 | 115236 | ||
| 111127 | /* | 115237 | /* |
| 111128 | ** An error occured while parsing or otherwise processing a database | 115238 | ** An error occurred while parsing or otherwise processing a database |
| 111129 | ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an | 115239 | ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an |
| 111130 | ** ALTER TABLE RENAME COLUMN program. The error message emitted by the | 115240 | ** ALTER TABLE RENAME COLUMN program. The error message emitted by the |
| 111131 | ** sub-routine is currently stored in pParse->zErrMsg. This function | 115241 | ** sub-routine is currently stored in pParse->zErrMsg. This function |
| @@ -111358,6 +115468,19 @@ static int renameEditSql( | |||
| 111358 | } | 115468 | } |
| 111359 | 115469 | ||
| 111360 | /* | 115470 | /* |
| 115471 | ** Set all pEList->a[].fg.eEName fields in the expression-list to val. | ||
| 115472 | */ | ||
| 115473 | static void renameSetENames(ExprList *pEList, int val){ | ||
| 115474 | if( pEList ){ | ||
| 115475 | int i; | ||
| 115476 | for(i=0; i<pEList->nExpr; i++){ | ||
| 115477 | assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); | ||
| 115478 | pEList->a[i].fg.eEName = val; | ||
| 115479 | } | ||
| 115480 | } | ||
| 115481 | } | ||
| 115482 | |||
| 115483 | /* | ||
| 111361 | ** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming | 115484 | ** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming |
| 111362 | ** it was read from the schema of database zDb. Return SQLITE_OK if | 115485 | ** it was read from the schema of database zDb. Return SQLITE_OK if |
| 111363 | ** successful. Otherwise, return an SQLite error code and leave an error | 115486 | ** successful. Otherwise, return an SQLite error code and leave an error |
| @@ -111404,7 +115527,17 @@ static int renameResolveTrigger(Parse *pParse){ | |||
| 111404 | pSrc = 0; | 115527 | pSrc = 0; |
| 111405 | rc = SQLITE_NOMEM; | 115528 | rc = SQLITE_NOMEM; |
| 111406 | }else{ | 115529 | }else{ |
| 115530 | /* pStep->pExprList contains an expression-list used for an UPDATE | ||
| 115531 | ** statement. So the a[].zEName values are the RHS of the | ||
| 115532 | ** "<col> = <expr>" clauses of the UPDATE statement. So, before | ||
| 115533 | ** running SelectPrep(), change all the eEName values in | ||
| 115534 | ** pStep->pExprList to ENAME_SPAN (from their current value of | ||
| 115535 | ** ENAME_NAME). This is to prevent any ids in ON() clauses that are | ||
| 115536 | ** part of pSrc from being incorrectly resolved against the | ||
| 115537 | ** a[].zEName values as if they were column aliases. */ | ||
| 115538 | renameSetENames(pStep->pExprList, ENAME_SPAN); | ||
| 111407 | sqlite3SelectPrep(pParse, pSel, 0); | 115539 | sqlite3SelectPrep(pParse, pSel, 0); |
| 115540 | renameSetENames(pStep->pExprList, ENAME_NAME); | ||
| 111408 | rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK; | 115541 | rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK; |
| 111409 | assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList ); | 115542 | assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList ); |
| 111410 | assert( pSrc==pSel->pSrc ); | 115543 | assert( pSrc==pSel->pSrc ); |
| @@ -113312,6 +117445,7 @@ static void analyzeVdbeCommentIndexWithColumnName( | |||
| 113312 | if( NEVER(i==XN_ROWID) ){ | 117445 | if( NEVER(i==XN_ROWID) ){ |
| 113313 | VdbeComment((v,"%s.rowid",pIdx->zName)); | 117446 | VdbeComment((v,"%s.rowid",pIdx->zName)); |
| 113314 | }else if( i==XN_EXPR ){ | 117447 | }else if( i==XN_EXPR ){ |
| 117448 | assert( pIdx->bHasExpr ); | ||
| 113315 | VdbeComment((v,"%s.expr(%d)",pIdx->zName, k)); | 117449 | VdbeComment((v,"%s.expr(%d)",pIdx->zName, k)); |
| 113316 | }else{ | 117450 | }else{ |
| 113317 | VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName)); | 117451 | VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName)); |
| @@ -113352,11 +117486,15 @@ static void analyzeOneTable( | |||
| 113352 | int regIdxname = iMem++; /* Register containing index name */ | 117486 | int regIdxname = iMem++; /* Register containing index name */ |
| 113353 | int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ | 117487 | int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ |
| 113354 | int regPrev = iMem; /* MUST BE LAST (see below) */ | 117488 | int regPrev = iMem; /* MUST BE LAST (see below) */ |
| 117489 | #ifdef SQLITE_ENABLE_STAT4 | ||
| 117490 | int doOnce = 1; /* Flag for a one-time computation */ | ||
| 117491 | #endif | ||
| 113355 | #ifdef SQLITE_ENABLE_PREUPDATE_HOOK | 117492 | #ifdef SQLITE_ENABLE_PREUPDATE_HOOK |
| 113356 | Table *pStat1 = 0; | 117493 | Table *pStat1 = 0; |
| 113357 | #endif | 117494 | #endif |
| 113358 | 117495 | ||
| 113359 | pParse->nMem = MAX(pParse->nMem, iMem); | 117496 | sqlite3TouchRegister(pParse, iMem); |
| 117497 | assert( sqlite3NoTempsInRange(pParse, regNewRowid, iMem) ); | ||
| 113360 | v = sqlite3GetVdbe(pParse); | 117498 | v = sqlite3GetVdbe(pParse); |
| 113361 | if( v==0 || NEVER(pTab==0) ){ | 117499 | if( v==0 || NEVER(pTab==0) ){ |
| 113362 | return; | 117500 | return; |
| @@ -113462,7 +117600,7 @@ static void analyzeOneTable( | |||
| 113462 | ** the regPrev array and a trailing rowid (the rowid slot is required | 117600 | ** the regPrev array and a trailing rowid (the rowid slot is required |
| 113463 | ** when building a record to insert into the sample column of | 117601 | ** when building a record to insert into the sample column of |
| 113464 | ** the sqlite_stat4 table. */ | 117602 | ** the sqlite_stat4 table. */ |
| 113465 | pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); | 117603 | sqlite3TouchRegister(pParse, regPrev+nColTest); |
| 113466 | 117604 | ||
| 113467 | /* Open a read-only cursor on the index being analyzed. */ | 117605 | /* Open a read-only cursor on the index being analyzed. */ |
| 113468 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); | 117606 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| @@ -113634,7 +117772,35 @@ static void analyzeOneTable( | |||
| 113634 | int addrIsNull; | 117772 | int addrIsNull; |
| 113635 | u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; | 117773 | u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; |
| 113636 | 117774 | ||
| 113637 | pParse->nMem = MAX(pParse->nMem, regCol+nCol); | 117775 | if( doOnce ){ |
| 117776 | int mxCol = nCol; | ||
| 117777 | Index *pX; | ||
| 117778 | |||
| 117779 | /* Compute the maximum number of columns in any index */ | ||
| 117780 | for(pX=pTab->pIndex; pX; pX=pX->pNext){ | ||
| 117781 | int nColX; /* Number of columns in pX */ | ||
| 117782 | if( !HasRowid(pTab) && IsPrimaryKeyIndex(pX) ){ | ||
| 117783 | nColX = pX->nKeyCol; | ||
| 117784 | }else{ | ||
| 117785 | nColX = pX->nColumn; | ||
| 117786 | } | ||
| 117787 | if( nColX>mxCol ) mxCol = nColX; | ||
| 117788 | } | ||
| 117789 | |||
| 117790 | /* Allocate space to compute results for the largest index */ | ||
| 117791 | sqlite3TouchRegister(pParse, regCol+mxCol); | ||
| 117792 | doOnce = 0; | ||
| 117793 | #ifdef SQLITE_DEBUG | ||
| 117794 | /* Verify that the call to sqlite3ClearTempRegCache() below | ||
| 117795 | ** really is needed. | ||
| 117796 | ** https://sqlite.org/forum/forumpost/83cb4a95a0 (2023-03-25) | ||
| 117797 | */ | ||
| 117798 | testcase( !sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); | ||
| 117799 | #endif | ||
| 117800 | sqlite3ClearTempRegCache(pParse); /* tag-20230325-1 */ | ||
| 117801 | assert( sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); | ||
| 117802 | } | ||
| 117803 | assert( sqlite3NoTempsInRange(pParse, regEq, regCol+nCol) ); | ||
| 113638 | 117804 | ||
| 113639 | addrNext = sqlite3VdbeCurrentAddr(v); | 117805 | addrNext = sqlite3VdbeCurrentAddr(v); |
| 113640 | callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid); | 117806 | callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid); |
| @@ -113715,6 +117881,11 @@ static void analyzeDatabase(Parse *pParse, int iDb){ | |||
| 113715 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ | 117881 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ |
| 113716 | Table *pTab = (Table*)sqliteHashData(k); | 117882 | Table *pTab = (Table*)sqliteHashData(k); |
| 113717 | analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); | 117883 | analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); |
| 117884 | #ifdef SQLITE_ENABLE_STAT4 | ||
| 117885 | iMem = sqlite3FirstAvailableRegister(pParse, iMem); | ||
| 117886 | #else | ||
| 117887 | assert( iMem==sqlite3FirstAvailableRegister(pParse,iMem) ); | ||
| 117888 | #endif | ||
| 113718 | } | 117889 | } |
| 113719 | loadAnalysis(pParse, iDb); | 117890 | loadAnalysis(pParse, iDb); |
| 113720 | } | 117891 | } |
| @@ -113955,6 +118126,8 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ | |||
| 113955 | ** and its contents. | 118126 | ** and its contents. |
| 113956 | */ | 118127 | */ |
| 113957 | SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ | 118128 | SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ |
| 118129 | assert( db!=0 ); | ||
| 118130 | assert( pIdx!=0 ); | ||
| 113958 | #ifdef SQLITE_ENABLE_STAT4 | 118131 | #ifdef SQLITE_ENABLE_STAT4 |
| 113959 | if( pIdx->aSample ){ | 118132 | if( pIdx->aSample ){ |
| 113960 | int j; | 118133 | int j; |
| @@ -113964,7 +118137,7 @@ SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ | |||
| 113964 | } | 118137 | } |
| 113965 | sqlite3DbFree(db, pIdx->aSample); | 118138 | sqlite3DbFree(db, pIdx->aSample); |
| 113966 | } | 118139 | } |
| 113967 | if( db && db->pnBytesFreed==0 ){ | 118140 | if( db->pnBytesFreed==0 ){ |
| 113968 | pIdx->nSample = 0; | 118141 | pIdx->nSample = 0; |
| 113969 | pIdx->aSample = 0; | 118142 | pIdx->aSample = 0; |
| 113970 | } | 118143 | } |
| @@ -114100,6 +118273,10 @@ static int loadStatTbl( | |||
| 114100 | pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); | 118273 | pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); |
| 114101 | assert( pIdx==0 || pIdx->nSample==0 ); | 118274 | assert( pIdx==0 || pIdx->nSample==0 ); |
| 114102 | if( pIdx==0 ) continue; | 118275 | if( pIdx==0 ) continue; |
| 118276 | if( pIdx->aSample!=0 ){ | ||
| 118277 | /* The same index appears in sqlite_stat4 under multiple names */ | ||
| 118278 | continue; | ||
| 118279 | } | ||
| 114103 | assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); | 118280 | assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); |
| 114104 | if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ | 118281 | if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ |
| 114105 | nIdxCol = pIdx->nKeyCol; | 118282 | nIdxCol = pIdx->nKeyCol; |
| @@ -114107,6 +118284,7 @@ static int loadStatTbl( | |||
| 114107 | nIdxCol = pIdx->nColumn; | 118284 | nIdxCol = pIdx->nColumn; |
| 114108 | } | 118285 | } |
| 114109 | pIdx->nSampleCol = nIdxCol; | 118286 | pIdx->nSampleCol = nIdxCol; |
| 118287 | pIdx->mxSample = nSample; | ||
| 114110 | nByte = sizeof(IndexSample) * nSample; | 118288 | nByte = sizeof(IndexSample) * nSample; |
| 114111 | nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; | 118289 | nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; |
| 114112 | nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ | 118290 | nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ |
| @@ -114146,6 +118324,11 @@ static int loadStatTbl( | |||
| 114146 | if( zIndex==0 ) continue; | 118324 | if( zIndex==0 ) continue; |
| 114147 | pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); | 118325 | pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); |
| 114148 | if( pIdx==0 ) continue; | 118326 | if( pIdx==0 ) continue; |
| 118327 | if( pIdx->nSample>=pIdx->mxSample ){ | ||
| 118328 | /* Too many slots used because the same index appears in | ||
| 118329 | ** sqlite_stat4 using multiple names */ | ||
| 118330 | continue; | ||
| 118331 | } | ||
| 114149 | /* This next condition is true if data has already been loaded from | 118332 | /* This next condition is true if data has already been loaded from |
| 114150 | ** the sqlite_stat4 table. */ | 118333 | ** the sqlite_stat4 table. */ |
| 114151 | nCol = pIdx->nSampleCol; | 118334 | nCol = pIdx->nSampleCol; |
| @@ -114158,14 +118341,15 @@ static int loadStatTbl( | |||
| 114158 | decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); | 118341 | decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); |
| 114159 | decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); | 118342 | decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); |
| 114160 | 118343 | ||
| 114161 | /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. | 118344 | /* Take a copy of the sample. Add 8 extra 0x00 bytes the end of the buffer. |
| 114162 | ** This is in case the sample record is corrupted. In that case, the | 118345 | ** This is in case the sample record is corrupted. In that case, the |
| 114163 | ** sqlite3VdbeRecordCompare() may read up to two varints past the | 118346 | ** sqlite3VdbeRecordCompare() may read up to two varints past the |
| 114164 | ** end of the allocated buffer before it realizes it is dealing with | 118347 | ** end of the allocated buffer before it realizes it is dealing with |
| 114165 | ** a corrupt record. Adding the two 0x00 bytes prevents this from causing | 118348 | ** a corrupt record. Or it might try to read a large integer from the |
| 118349 | ** buffer. In any case, eight 0x00 bytes prevents this from causing | ||
| 114166 | ** a buffer overread. */ | 118350 | ** a buffer overread. */ |
| 114167 | pSample->n = sqlite3_column_bytes(pStmt, 4); | 118351 | pSample->n = sqlite3_column_bytes(pStmt, 4); |
| 114168 | pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); | 118352 | pSample->p = sqlite3DbMallocZero(db, pSample->n + 8); |
| 114169 | if( pSample->p==0 ){ | 118353 | if( pSample->p==0 ){ |
| 114170 | sqlite3_finalize(pStmt); | 118354 | sqlite3_finalize(pStmt); |
| 114171 | return SQLITE_NOMEM_BKPT; | 118355 | return SQLITE_NOMEM_BKPT; |
| @@ -114189,11 +118373,12 @@ static int loadStat4(sqlite3 *db, const char *zDb){ | |||
| 114189 | const Table *pStat4; | 118373 | const Table *pStat4; |
| 114190 | 118374 | ||
| 114191 | assert( db->lookaside.bDisable ); | 118375 | assert( db->lookaside.bDisable ); |
| 114192 | if( (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0 | 118376 | if( OptimizationEnabled(db, SQLITE_Stat4) |
| 118377 | && (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0 | ||
| 114193 | && IsOrdinaryTable(pStat4) | 118378 | && IsOrdinaryTable(pStat4) |
| 114194 | ){ | 118379 | ){ |
| 114195 | rc = loadStatTbl(db, | 118380 | rc = loadStatTbl(db, |
| 114196 | "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", | 118381 | "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx COLLATE nocase", |
| 114197 | "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", | 118382 | "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", |
| 114198 | zDb | 118383 | zDb |
| 114199 | ); | 118384 | ); |
| @@ -114383,7 +118568,7 @@ static void attachFunc( | |||
| 114383 | char *zErr = 0; | 118568 | char *zErr = 0; |
| 114384 | unsigned int flags; | 118569 | unsigned int flags; |
| 114385 | Db *aNew; /* New array of Db pointers */ | 118570 | Db *aNew; /* New array of Db pointers */ |
| 114386 | Db *pNew; /* Db object for the newly attached database */ | 118571 | Db *pNew = 0; /* Db object for the newly attached database */ |
| 114387 | char *zErrDyn = 0; | 118572 | char *zErrDyn = 0; |
| 114388 | sqlite3_vfs *pVfs; | 118573 | sqlite3_vfs *pVfs; |
| 114389 | 118574 | ||
| @@ -114403,13 +118588,26 @@ static void attachFunc( | |||
| 114403 | /* This is not a real ATTACH. Instead, this routine is being called | 118588 | /* This is not a real ATTACH. Instead, this routine is being called |
| 114404 | ** from sqlite3_deserialize() to close database db->init.iDb and | 118589 | ** from sqlite3_deserialize() to close database db->init.iDb and |
| 114405 | ** reopen it as a MemDB */ | 118590 | ** reopen it as a MemDB */ |
| 118591 | Btree *pNewBt = 0; | ||
| 114406 | pVfs = sqlite3_vfs_find("memdb"); | 118592 | pVfs = sqlite3_vfs_find("memdb"); |
| 114407 | if( pVfs==0 ) return; | 118593 | if( pVfs==0 ) return; |
| 114408 | pNew = &db->aDb[db->init.iDb]; | 118594 | rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); |
| 114409 | if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); | 118595 | if( rc==SQLITE_OK ){ |
| 114410 | pNew->pBt = 0; | 118596 | Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt); |
| 114411 | pNew->pSchema = 0; | 118597 | if( pNewSchema ){ |
| 114412 | rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); | 118598 | /* Both the Btree and the new Schema were allocated successfully. |
| 118599 | ** Close the old db and update the aDb[] slot with the new memdb | ||
| 118600 | ** values. */ | ||
| 118601 | pNew = &db->aDb[db->init.iDb]; | ||
| 118602 | if( ALWAYS(pNew->pBt) ) sqlite3BtreeClose(pNew->pBt); | ||
| 118603 | pNew->pBt = pNewBt; | ||
| 118604 | pNew->pSchema = pNewSchema; | ||
| 118605 | }else{ | ||
| 118606 | sqlite3BtreeClose(pNewBt); | ||
| 118607 | rc = SQLITE_NOMEM; | ||
| 118608 | } | ||
| 118609 | } | ||
| 118610 | if( rc ) goto attach_error; | ||
| 114413 | }else{ | 118611 | }else{ |
| 114414 | /* This is a real ATTACH | 118612 | /* This is a real ATTACH |
| 114415 | ** | 118613 | ** |
| @@ -114522,7 +118720,7 @@ static void attachFunc( | |||
| 114522 | } | 118720 | } |
| 114523 | #endif | 118721 | #endif |
| 114524 | if( rc ){ | 118722 | if( rc ){ |
| 114525 | if( !REOPEN_AS_MEMDB(db) ){ | 118723 | if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ |
| 114526 | int iDb = db->nDb - 1; | 118724 | int iDb = db->nDb - 1; |
| 114527 | assert( iDb>=2 ); | 118725 | assert( iDb>=2 ); |
| 114528 | if( db->aDb[iDb].pBt ){ | 118726 | if( db->aDb[iDb].pBt ){ |
| @@ -114639,6 +118837,8 @@ static void codeAttach( | |||
| 114639 | sqlite3* db = pParse->db; | 118837 | sqlite3* db = pParse->db; |
| 114640 | int regArgs; | 118838 | int regArgs; |
| 114641 | 118839 | ||
| 118840 | if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto attach_end; | ||
| 118841 | |||
| 114642 | if( pParse->nErr ) goto attach_end; | 118842 | if( pParse->nErr ) goto attach_end; |
| 114643 | memset(&sName, 0, sizeof(NameContext)); | 118843 | memset(&sName, 0, sizeof(NameContext)); |
| 114644 | sName.pParse = pParse; | 118844 | sName.pParse = pParse; |
| @@ -115107,7 +119307,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( | |||
| 115107 | sqlite3 *db = pParse->db; | 119307 | sqlite3 *db = pParse->db; |
| 115108 | int rc; | 119308 | int rc; |
| 115109 | 119309 | ||
| 115110 | /* Don't do any authorization checks if the database is initialising | 119310 | /* Don't do any authorization checks if the database is initializing |
| 115111 | ** or if the parser is being invoked from within sqlite3_declare_vtab. | 119311 | ** or if the parser is being invoked from within sqlite3_declare_vtab. |
| 115112 | */ | 119312 | */ |
| 115113 | assert( !IN_RENAME_OBJECT || db->xAuth==0 ); | 119313 | assert( !IN_RENAME_OBJECT || db->xAuth==0 ); |
| @@ -115314,6 +119514,7 @@ SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ | |||
| 115314 | SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ | 119514 | SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ |
| 115315 | sqlite3 *db; | 119515 | sqlite3 *db; |
| 115316 | Vdbe *v; | 119516 | Vdbe *v; |
| 119517 | int iDb, i; | ||
| 115317 | 119518 | ||
| 115318 | assert( pParse->pToplevel==0 ); | 119519 | assert( pParse->pToplevel==0 ); |
| 115319 | db = pParse->db; | 119520 | db = pParse->db; |
| @@ -115343,7 +119544,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ | |||
| 115343 | if( pParse->bReturning ){ | 119544 | if( pParse->bReturning ){ |
| 115344 | Returning *pReturning = pParse->u1.pReturning; | 119545 | Returning *pReturning = pParse->u1.pReturning; |
| 115345 | int addrRewind; | 119546 | int addrRewind; |
| 115346 | int i; | ||
| 115347 | int reg; | 119547 | int reg; |
| 115348 | 119548 | ||
| 115349 | if( pReturning->nRetCol ){ | 119549 | if( pReturning->nRetCol ){ |
| @@ -115380,76 +119580,71 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ | |||
| 115380 | ** transaction on each used database and to verify the schema cookie | 119580 | ** transaction on each used database and to verify the schema cookie |
| 115381 | ** on each used database. | 119581 | ** on each used database. |
| 115382 | */ | 119582 | */ |
| 115383 | if( db->mallocFailed==0 | 119583 | assert( pParse->nErr>0 || sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); |
| 115384 | && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) | 119584 | sqlite3VdbeJumpHere(v, 0); |
| 115385 | ){ | 119585 | assert( db->nDb>0 ); |
| 115386 | int iDb, i; | 119586 | iDb = 0; |
| 115387 | assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); | 119587 | do{ |
| 115388 | sqlite3VdbeJumpHere(v, 0); | 119588 | Schema *pSchema; |
| 115389 | assert( db->nDb>0 ); | 119589 | if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; |
| 115390 | iDb = 0; | 119590 | sqlite3VdbeUsesBtree(v, iDb); |
| 115391 | do{ | 119591 | pSchema = db->aDb[iDb].pSchema; |
| 115392 | Schema *pSchema; | 119592 | sqlite3VdbeAddOp4Int(v, |
| 115393 | if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; | 119593 | OP_Transaction, /* Opcode */ |
| 115394 | sqlite3VdbeUsesBtree(v, iDb); | 119594 | iDb, /* P1 */ |
| 115395 | pSchema = db->aDb[iDb].pSchema; | 119595 | DbMaskTest(pParse->writeMask,iDb), /* P2 */ |
| 115396 | sqlite3VdbeAddOp4Int(v, | 119596 | pSchema->schema_cookie, /* P3 */ |
| 115397 | OP_Transaction, /* Opcode */ | 119597 | pSchema->iGeneration /* P4 */ |
| 115398 | iDb, /* P1 */ | 119598 | ); |
| 115399 | DbMaskTest(pParse->writeMask,iDb), /* P2 */ | 119599 | if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); |
| 115400 | pSchema->schema_cookie, /* P3 */ | 119600 | VdbeComment((v, |
| 115401 | pSchema->iGeneration /* P4 */ | 119601 | "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); |
| 115402 | ); | 119602 | }while( ++iDb<db->nDb ); |
| 115403 | if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); | ||
| 115404 | VdbeComment((v, | ||
| 115405 | "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); | ||
| 115406 | }while( ++iDb<db->nDb ); | ||
| 115407 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 119603 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 115408 | for(i=0; i<pParse->nVtabLock; i++){ | 119604 | for(i=0; i<pParse->nVtabLock; i++){ |
| 115409 | char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); | 119605 | char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); |
| 115410 | sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); | 119606 | sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); |
| 115411 | } | 119607 | } |
| 115412 | pParse->nVtabLock = 0; | 119608 | pParse->nVtabLock = 0; |
| 115413 | #endif | 119609 | #endif |
| 115414 | 119610 | ||
| 115415 | /* Once all the cookies have been verified and transactions opened, | 119611 | #ifndef SQLITE_OMIT_SHARED_CACHE |
| 115416 | ** obtain the required table-locks. This is a no-op unless the | 119612 | /* Once all the cookies have been verified and transactions opened, |
| 115417 | ** shared-cache feature is enabled. | 119613 | ** obtain the required table-locks. This is a no-op unless the |
| 115418 | */ | 119614 | ** shared-cache feature is enabled. |
| 115419 | codeTableLocks(pParse); | 119615 | */ |
| 119616 | if( pParse->nTableLock ) codeTableLocks(pParse); | ||
| 119617 | #endif | ||
| 115420 | 119618 | ||
| 115421 | /* Initialize any AUTOINCREMENT data structures required. | 119619 | /* Initialize any AUTOINCREMENT data structures required. |
| 115422 | */ | 119620 | */ |
| 115423 | sqlite3AutoincrementBegin(pParse); | 119621 | if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse); |
| 115424 | 119622 | ||
| 115425 | /* Code constant expressions that where factored out of inner loops. | 119623 | /* Code constant expressions that where factored out of inner loops. |
| 115426 | ** | 119624 | ** |
| 115427 | ** The pConstExpr list might also contain expressions that we simply | 119625 | ** The pConstExpr list might also contain expressions that we simply |
| 115428 | ** want to keep around until the Parse object is deleted. Such | 119626 | ** want to keep around until the Parse object is deleted. Such |
| 115429 | ** expressions have iConstExprReg==0. Do not generate code for | 119627 | ** expressions have iConstExprReg==0. Do not generate code for |
| 115430 | ** those expressions, of course. | 119628 | ** those expressions, of course. |
| 115431 | */ | 119629 | */ |
| 115432 | if( pParse->pConstExpr ){ | 119630 | if( pParse->pConstExpr ){ |
| 115433 | ExprList *pEL = pParse->pConstExpr; | 119631 | ExprList *pEL = pParse->pConstExpr; |
| 115434 | pParse->okConstFactor = 0; | 119632 | pParse->okConstFactor = 0; |
| 115435 | for(i=0; i<pEL->nExpr; i++){ | 119633 | for(i=0; i<pEL->nExpr; i++){ |
| 115436 | int iReg = pEL->a[i].u.iConstExprReg; | 119634 | int iReg = pEL->a[i].u.iConstExprReg; |
| 115437 | if( iReg>0 ){ | 119635 | sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); |
| 115438 | sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); | ||
| 115439 | } | ||
| 115440 | } | ||
| 115441 | } | 119636 | } |
| 119637 | } | ||
| 115442 | 119638 | ||
| 115443 | if( pParse->bReturning ){ | 119639 | if( pParse->bReturning ){ |
| 115444 | Returning *pRet = pParse->u1.pReturning; | 119640 | Returning *pRet = pParse->u1.pReturning; |
| 115445 | if( pRet->nRetCol ){ | 119641 | if( pRet->nRetCol ){ |
| 115446 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); | 119642 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); |
| 115447 | } | ||
| 115448 | } | 119643 | } |
| 115449 | |||
| 115450 | /* Finally, jump back to the beginning of the executable code. */ | ||
| 115451 | sqlite3VdbeGoto(v, 1); | ||
| 115452 | } | 119644 | } |
| 119645 | |||
| 119646 | /* Finally, jump back to the beginning of the executable code. */ | ||
| 119647 | sqlite3VdbeGoto(v, 1); | ||
| 115453 | } | 119648 | } |
| 115454 | 119649 | ||
| 115455 | /* Get the VDBE program ready for execution | 119650 | /* Get the VDBE program ready for execution |
| @@ -115488,6 +119683,7 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ | |||
| 115488 | char saveBuf[PARSE_TAIL_SZ]; | 119683 | char saveBuf[PARSE_TAIL_SZ]; |
| 115489 | 119684 | ||
| 115490 | if( pParse->nErr ) return; | 119685 | if( pParse->nErr ) return; |
| 119686 | if( pParse->eParseMode ) return; | ||
| 115491 | assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ | 119687 | assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ |
| 115492 | va_start(ap, zFormat); | 119688 | va_start(ap, zFormat); |
| 115493 | zSql = sqlite3VMPrintf(db, zFormat, ap); | 119689 | zSql = sqlite3VMPrintf(db, zFormat, ap); |
| @@ -115634,7 +119830,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( | |||
| 115634 | /* If zName is the not the name of a table in the schema created using | 119830 | /* If zName is the not the name of a table in the schema created using |
| 115635 | ** CREATE, then check to see if it is the name of an virtual table that | 119831 | ** CREATE, then check to see if it is the name of an virtual table that |
| 115636 | ** can be an eponymous virtual table. */ | 119832 | ** can be an eponymous virtual table. */ |
| 115637 | if( pParse->disableVtab==0 && db->init.busy==0 ){ | 119833 | if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){ |
| 115638 | Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); | 119834 | Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); |
| 115639 | if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ | 119835 | if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ |
| 115640 | pMod = sqlite3PragmaVtabRegister(db, zName); | 119836 | pMod = sqlite3PragmaVtabRegister(db, zName); |
| @@ -115647,7 +119843,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( | |||
| 115647 | #endif | 119843 | #endif |
| 115648 | if( flags & LOCATE_NOERR ) return 0; | 119844 | if( flags & LOCATE_NOERR ) return 0; |
| 115649 | pParse->checkSchema = 1; | 119845 | pParse->checkSchema = 1; |
| 115650 | }else if( IsVirtual(p) && pParse->disableVtab ){ | 119846 | }else if( IsVirtual(p) && (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)!=0 ){ |
| 115651 | p = 0; | 119847 | p = 0; |
| 115652 | } | 119848 | } |
| 115653 | 119849 | ||
| @@ -115935,7 +120131,7 @@ SQLITE_PRIVATE void sqlite3ColumnSetColl( | |||
| 115935 | } | 120131 | } |
| 115936 | 120132 | ||
| 115937 | /* | 120133 | /* |
| 115938 | ** Return the collating squence name for a column | 120134 | ** Return the collating sequence name for a column |
| 115939 | */ | 120135 | */ |
| 115940 | SQLITE_PRIVATE const char *sqlite3ColumnColl(Column *pCol){ | 120136 | SQLITE_PRIVATE const char *sqlite3ColumnColl(Column *pCol){ |
| 115941 | const char *z; | 120137 | const char *z; |
| @@ -115956,16 +120152,17 @@ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ | |||
| 115956 | int i; | 120152 | int i; |
| 115957 | Column *pCol; | 120153 | Column *pCol; |
| 115958 | assert( pTable!=0 ); | 120154 | assert( pTable!=0 ); |
| 120155 | assert( db!=0 ); | ||
| 115959 | if( (pCol = pTable->aCol)!=0 ){ | 120156 | if( (pCol = pTable->aCol)!=0 ){ |
| 115960 | for(i=0; i<pTable->nCol; i++, pCol++){ | 120157 | for(i=0; i<pTable->nCol; i++, pCol++){ |
| 115961 | assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); | 120158 | assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); |
| 115962 | sqlite3DbFree(db, pCol->zCnName); | 120159 | sqlite3DbFree(db, pCol->zCnName); |
| 115963 | } | 120160 | } |
| 115964 | sqlite3DbFree(db, pTable->aCol); | 120161 | sqlite3DbNNFreeNN(db, pTable->aCol); |
| 115965 | if( IsOrdinaryTable(pTable) ){ | 120162 | if( IsOrdinaryTable(pTable) ){ |
| 115966 | sqlite3ExprListDelete(db, pTable->u.tab.pDfltList); | 120163 | sqlite3ExprListDelete(db, pTable->u.tab.pDfltList); |
| 115967 | } | 120164 | } |
| 115968 | if( db==0 || db->pnBytesFreed==0 ){ | 120165 | if( db->pnBytesFreed==0 ){ |
| 115969 | pTable->aCol = 0; | 120166 | pTable->aCol = 0; |
| 115970 | pTable->nCol = 0; | 120167 | pTable->nCol = 0; |
| 115971 | if( IsOrdinaryTable(pTable) ){ | 120168 | if( IsOrdinaryTable(pTable) ){ |
| @@ -116002,7 +120199,8 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ | |||
| 116002 | ** a Table object that was going to be marked ephemeral. So do not check | 120199 | ** a Table object that was going to be marked ephemeral. So do not check |
| 116003 | ** that no lookaside memory is used in this case either. */ | 120200 | ** that no lookaside memory is used in this case either. */ |
| 116004 | int nLookaside = 0; | 120201 | int nLookaside = 0; |
| 116005 | if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ | 120202 | assert( db!=0 ); |
| 120203 | if( !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ | ||
| 116006 | nLookaside = sqlite3LookasideUsed(db, 0); | 120204 | nLookaside = sqlite3LookasideUsed(db, 0); |
| 116007 | } | 120205 | } |
| 116008 | #endif | 120206 | #endif |
| @@ -116012,7 +120210,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ | |||
| 116012 | pNext = pIndex->pNext; | 120210 | pNext = pIndex->pNext; |
| 116013 | assert( pIndex->pSchema==pTable->pSchema | 120211 | assert( pIndex->pSchema==pTable->pSchema |
| 116014 | || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); | 120212 | || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); |
| 116015 | if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){ | 120213 | if( db->pnBytesFreed==0 && !IsVirtual(pTable) ){ |
| 116016 | char *zName = pIndex->zName; | 120214 | char *zName = pIndex->zName; |
| 116017 | TESTONLY ( Index *pOld = ) sqlite3HashInsert( | 120215 | TESTONLY ( Index *pOld = ) sqlite3HashInsert( |
| 116018 | &pIndex->pSchema->idxHash, zName, 0 | 120216 | &pIndex->pSchema->idxHash, zName, 0 |
| @@ -116026,7 +120224,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ | |||
| 116026 | if( IsOrdinaryTable(pTable) ){ | 120224 | if( IsOrdinaryTable(pTable) ){ |
| 116027 | sqlite3FkDelete(db, pTable); | 120225 | sqlite3FkDelete(db, pTable); |
| 116028 | } | 120226 | } |
| 116029 | #ifndef SQLITE_OMIT_VIRTUAL_TABLE | 120227 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 116030 | else if( IsVirtual(pTable) ){ | 120228 | else if( IsVirtual(pTable) ){ |
| 116031 | sqlite3VtabClear(db, pTable); | 120229 | sqlite3VtabClear(db, pTable); |
| 116032 | } | 120230 | } |
| @@ -116049,8 +120247,9 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ | |||
| 116049 | } | 120247 | } |
| 116050 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ | 120248 | SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ |
| 116051 | /* Do not delete the table until the reference count reaches zero. */ | 120249 | /* Do not delete the table until the reference count reaches zero. */ |
| 120250 | assert( db!=0 ); | ||
| 116052 | if( !pTable ) return; | 120251 | if( !pTable ) return; |
| 116053 | if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return; | 120252 | if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; |
| 116054 | deleteTable(db, pTable); | 120253 | deleteTable(db, pTable); |
| 116055 | } | 120254 | } |
| 116056 | 120255 | ||
| @@ -116628,7 +120827,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ | |||
| 116628 | if( pParse->pNewTrigger ){ | 120827 | if( pParse->pNewTrigger ){ |
| 116629 | sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger"); | 120828 | sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger"); |
| 116630 | }else{ | 120829 | }else{ |
| 116631 | assert( pParse->bReturning==0 ); | 120830 | assert( pParse->bReturning==0 || pParse->ifNotExists ); |
| 116632 | } | 120831 | } |
| 116633 | pParse->bReturning = 1; | 120832 | pParse->bReturning = 1; |
| 116634 | pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); | 120833 | pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); |
| @@ -116654,7 +120853,8 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ | |||
| 116654 | pRet->retTStep.pTrig = &pRet->retTrig; | 120853 | pRet->retTStep.pTrig = &pRet->retTrig; |
| 116655 | pRet->retTStep.pExprList = pList; | 120854 | pRet->retTStep.pExprList = pList; |
| 116656 | pHash = &(db->aDb[1].pSchema->trigHash); | 120855 | pHash = &(db->aDb[1].pSchema->trigHash); |
| 116657 | assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr ); | 120856 | assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 |
| 120857 | || pParse->nErr || pParse->ifNotExists ); | ||
| 116658 | if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) | 120858 | if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) |
| 116659 | ==&pRet->retTrig ){ | 120859 | ==&pRet->retTrig ){ |
| 116660 | sqlite3OomFault(db); | 120860 | sqlite3OomFault(db); |
| @@ -116689,7 +120889,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ | |||
| 116689 | } | 120889 | } |
| 116690 | if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); | 120890 | if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); |
| 116691 | 120891 | ||
| 116692 | /* Because keywords GENERATE ALWAYS can be converted into indentifiers | 120892 | /* Because keywords GENERATE ALWAYS can be converted into identifiers |
| 116693 | ** by the parser, we can sometimes end up with a typename that ends | 120893 | ** by the parser, we can sometimes end up with a typename that ends |
| 116694 | ** with "generated always". Check for this case and omit the surplus | 120894 | ** with "generated always". Check for this case and omit the surplus |
| 116695 | ** text. */ | 120895 | ** text. */ |
| @@ -116910,7 +121110,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue( | |||
| 116910 | Parse *pParse, /* Parsing context */ | 121110 | Parse *pParse, /* Parsing context */ |
| 116911 | Expr *pExpr, /* The parsed expression of the default value */ | 121111 | Expr *pExpr, /* The parsed expression of the default value */ |
| 116912 | const char *zStart, /* Start of the default value text */ | 121112 | const char *zStart, /* Start of the default value text */ |
| 116913 | const char *zEnd /* First character past end of defaut value text */ | 121113 | const char *zEnd /* First character past end of default value text */ |
| 116914 | ){ | 121114 | ){ |
| 116915 | Table *p; | 121115 | Table *p; |
| 116916 | Column *pCol; | 121116 | Column *pCol; |
| @@ -117182,6 +121382,14 @@ SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType | |||
| 117182 | if( pCol->colFlags & COLFLAG_PRIMKEY ){ | 121382 | if( pCol->colFlags & COLFLAG_PRIMKEY ){ |
| 117183 | makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ | 121383 | makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ |
| 117184 | } | 121384 | } |
| 121385 | if( ALWAYS(pExpr) && pExpr->op==TK_ID ){ | ||
| 121386 | /* The value of a generated column needs to be a real expression, not | ||
| 121387 | ** just a reference to another column, in order for covering index | ||
| 121388 | ** optimizations to work correctly. So if the value is not an expression, | ||
| 121389 | ** turn it into one by adding a unary "+" operator. */ | ||
| 121390 | pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0); | ||
| 121391 | } | ||
| 121392 | if( pExpr && pExpr->op!=TK_RAISE ) pExpr->affExpr = pCol->affinity; | ||
| 117185 | sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr); | 121393 | sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr); |
| 117186 | pExpr = 0; | 121394 | pExpr = 0; |
| 117187 | goto generated_done; | 121395 | goto generated_done; |
| @@ -117250,7 +121458,7 @@ static int identLength(const char *z){ | |||
| 117250 | ** to the specified offset in the buffer and updates *pIdx to refer | 121458 | ** to the specified offset in the buffer and updates *pIdx to refer |
| 117251 | ** to the first byte after the last byte written before returning. | 121459 | ** to the first byte after the last byte written before returning. |
| 117252 | ** | 121460 | ** |
| 117253 | ** If the string zSignedIdent consists entirely of alpha-numeric | 121461 | ** If the string zSignedIdent consists entirely of alphanumeric |
| 117254 | ** characters, does not begin with a digit and is not an SQL keyword, | 121462 | ** characters, does not begin with a digit and is not an SQL keyword, |
| 117255 | ** then it is copied to the output buffer exactly as it is. Otherwise, | 121463 | ** then it is copied to the output buffer exactly as it is. Otherwise, |
| 117256 | ** it is quoted using double-quotes. | 121464 | ** it is quoted using double-quotes. |
| @@ -117318,7 +121526,8 @@ static char *createTableStmt(sqlite3 *db, Table *p){ | |||
| 117318 | /* SQLITE_AFF_TEXT */ " TEXT", | 121526 | /* SQLITE_AFF_TEXT */ " TEXT", |
| 117319 | /* SQLITE_AFF_NUMERIC */ " NUM", | 121527 | /* SQLITE_AFF_NUMERIC */ " NUM", |
| 117320 | /* SQLITE_AFF_INTEGER */ " INT", | 121528 | /* SQLITE_AFF_INTEGER */ " INT", |
| 117321 | /* SQLITE_AFF_REAL */ " REAL" | 121529 | /* SQLITE_AFF_REAL */ " REAL", |
| 121530 | /* SQLITE_AFF_FLEXNUM */ " NUM", | ||
| 117322 | }; | 121531 | }; |
| 117323 | int len; | 121532 | int len; |
| 117324 | const char *zType; | 121533 | const char *zType; |
| @@ -117334,10 +121543,12 @@ static char *createTableStmt(sqlite3 *db, Table *p){ | |||
| 117334 | testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); | 121543 | testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); |
| 117335 | testcase( pCol->affinity==SQLITE_AFF_INTEGER ); | 121544 | testcase( pCol->affinity==SQLITE_AFF_INTEGER ); |
| 117336 | testcase( pCol->affinity==SQLITE_AFF_REAL ); | 121545 | testcase( pCol->affinity==SQLITE_AFF_REAL ); |
| 121546 | testcase( pCol->affinity==SQLITE_AFF_FLEXNUM ); | ||
| 117337 | 121547 | ||
| 117338 | zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; | 121548 | zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; |
| 117339 | len = sqlite3Strlen30(zType); | 121549 | len = sqlite3Strlen30(zType); |
| 117340 | assert( pCol->affinity==SQLITE_AFF_BLOB | 121550 | assert( pCol->affinity==SQLITE_AFF_BLOB |
| 121551 | || pCol->affinity==SQLITE_AFF_FLEXNUM | ||
| 117341 | || pCol->affinity==sqlite3AffinityType(zType, 0) ); | 121552 | || pCol->affinity==sqlite3AffinityType(zType, 0) ); |
| 117342 | memcpy(&zStmt[k], zType, len); | 121553 | memcpy(&zStmt[k], zType, len); |
| 117343 | k += len; | 121554 | k += len; |
| @@ -117399,7 +121610,7 @@ static void estimateIndexWidth(Index *pIdx){ | |||
| 117399 | for(i=0; i<pIdx->nColumn; i++){ | 121610 | for(i=0; i<pIdx->nColumn; i++){ |
| 117400 | i16 x = pIdx->aiColumn[i]; | 121611 | i16 x = pIdx->aiColumn[i]; |
| 117401 | assert( x<pIdx->pTable->nCol ); | 121612 | assert( x<pIdx->pTable->nCol ); |
| 117402 | wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst; | 121613 | wIndex += x<0 ? 1 : aCol[x].szEst; |
| 117403 | } | 121614 | } |
| 117404 | pIdx->szIdxRow = sqlite3LogEst(wIndex*4); | 121615 | pIdx->szIdxRow = sqlite3LogEst(wIndex*4); |
| 117405 | } | 121616 | } |
| @@ -117454,7 +121665,8 @@ static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){ | |||
| 117454 | /* Recompute the colNotIdxed field of the Index. | 121665 | /* Recompute the colNotIdxed field of the Index. |
| 117455 | ** | 121666 | ** |
| 117456 | ** colNotIdxed is a bitmask that has a 0 bit representing each indexed | 121667 | ** colNotIdxed is a bitmask that has a 0 bit representing each indexed |
| 117457 | ** columns that are within the first 63 columns of the table. The | 121668 | ** columns that are within the first 63 columns of the table and a 1 for |
| 121669 | ** all other bits (all columns that are not in the index). The | ||
| 117458 | ** high-order bit of colNotIdxed is always 1. All unindexed columns | 121670 | ** high-order bit of colNotIdxed is always 1. All unindexed columns |
| 117459 | ** of the table have a 1. | 121671 | ** of the table have a 1. |
| 117460 | ** | 121672 | ** |
| @@ -117482,7 +121694,7 @@ static void recomputeColumnsNotIndexed(Index *pIdx){ | |||
| 117482 | } | 121694 | } |
| 117483 | } | 121695 | } |
| 117484 | pIdx->colNotIdxed = ~m; | 121696 | pIdx->colNotIdxed = ~m; |
| 117485 | assert( (pIdx->colNotIdxed>>63)==1 ); | 121697 | assert( (pIdx->colNotIdxed>>63)==1 ); /* See note-20221022-a */ |
| 117486 | } | 121698 | } |
| 117487 | 121699 | ||
| 117488 | /* | 121700 | /* |
| @@ -117751,6 +121963,7 @@ SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ | |||
| 117751 | ** not pass them into code generator routines by mistake. | 121963 | ** not pass them into code generator routines by mistake. |
| 117752 | */ | 121964 | */ |
| 117753 | static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){ | 121965 | static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){ |
| 121966 | (void)pWalker; | ||
| 117754 | ExprSetVVAProperty(pExpr, EP_Immutable); | 121967 | ExprSetVVAProperty(pExpr, EP_Immutable); |
| 117755 | return WRC_Continue; | 121968 | return WRC_Continue; |
| 117756 | } | 121969 | } |
| @@ -118223,7 +122436,7 @@ create_view_fail: | |||
| 118223 | ** the columns of the view in the pTable structure. Return the number | 122436 | ** the columns of the view in the pTable structure. Return the number |
| 118224 | ** of errors. If an error is seen leave an error message in pParse->zErrMsg. | 122437 | ** of errors. If an error is seen leave an error message in pParse->zErrMsg. |
| 118225 | */ | 122438 | */ |
| 118226 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ | 122439 | static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ |
| 118227 | Table *pSelTab; /* A fake table from which we get the result set */ | 122440 | Table *pSelTab; /* A fake table from which we get the result set */ |
| 118228 | Select *pSel; /* Copy of the SELECT that implements the view */ | 122441 | Select *pSel; /* Copy of the SELECT that implements the view */ |
| 118229 | int nErr = 0; /* Number of errors encountered */ | 122442 | int nErr = 0; /* Number of errors encountered */ |
| @@ -118248,9 +122461,10 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ | |||
| 118248 | 122461 | ||
| 118249 | #ifndef SQLITE_OMIT_VIEW | 122462 | #ifndef SQLITE_OMIT_VIEW |
| 118250 | /* A positive nCol means the columns names for this view are | 122463 | /* A positive nCol means the columns names for this view are |
| 118251 | ** already known. | 122464 | ** already known. This routine is not called unless either the |
| 122465 | ** table is virtual or nCol is zero. | ||
| 118252 | */ | 122466 | */ |
| 118253 | if( pTable->nCol>0 ) return 0; | 122467 | assert( pTable->nCol<=0 ); |
| 118254 | 122468 | ||
| 118255 | /* A negative nCol is a special marker meaning that we are currently | 122469 | /* A negative nCol is a special marker meaning that we are currently |
| 118256 | ** trying to compute the column names. If we enter this routine with | 122470 | ** trying to compute the column names. If we enter this routine with |
| @@ -118316,8 +122530,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ | |||
| 118316 | && pTable->nCol==pSel->pEList->nExpr | 122530 | && pTable->nCol==pSel->pEList->nExpr |
| 118317 | ){ | 122531 | ){ |
| 118318 | assert( db->mallocFailed==0 ); | 122532 | assert( db->mallocFailed==0 ); |
| 118319 | sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, | 122533 | sqlite3SubqueryColumnTypes(pParse, pTable, pSel, SQLITE_AFF_NONE); |
| 118320 | SQLITE_AFF_NONE); | ||
| 118321 | } | 122534 | } |
| 118322 | }else{ | 122535 | }else{ |
| 118323 | /* CREATE VIEW name AS... without an argument list. Construct | 122536 | /* CREATE VIEW name AS... without an argument list. Construct |
| @@ -118346,6 +122559,11 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ | |||
| 118346 | #endif /* SQLITE_OMIT_VIEW */ | 122559 | #endif /* SQLITE_OMIT_VIEW */ |
| 118347 | return nErr; | 122560 | return nErr; |
| 118348 | } | 122561 | } |
| 122562 | SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ | ||
| 122563 | assert( pTable!=0 ); | ||
| 122564 | if( !IsVirtual(pTable) && pTable->nCol>0 ) return 0; | ||
| 122565 | return viewGetColumnNames(pParse, pTable); | ||
| 122566 | } | ||
| 118349 | #endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ | 122567 | #endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ |
| 118350 | 122568 | ||
| 118351 | #ifndef SQLITE_OMIT_VIEW | 122569 | #ifndef SQLITE_OMIT_VIEW |
| @@ -119130,7 +123348,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( | |||
| 119130 | #ifndef SQLITE_OMIT_TEMPDB | 123348 | #ifndef SQLITE_OMIT_TEMPDB |
| 119131 | /* If the index name was unqualified, check if the table | 123349 | /* If the index name was unqualified, check if the table |
| 119132 | ** is a temp table. If so, set the database to 1. Do not do this | 123350 | ** is a temp table. If so, set the database to 1. Do not do this |
| 119133 | ** if initialising a database schema. | 123351 | ** if initializing a database schema. |
| 119134 | */ | 123352 | */ |
| 119135 | if( !db->init.busy ){ | 123353 | if( !db->init.busy ){ |
| 119136 | pTab = sqlite3SrcListLookup(pParse, pTblName); | 123354 | pTab = sqlite3SrcListLookup(pParse, pTblName); |
| @@ -119211,7 +123429,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( | |||
| 119211 | } | 123429 | } |
| 119212 | if( !IN_RENAME_OBJECT ){ | 123430 | if( !IN_RENAME_OBJECT ){ |
| 119213 | if( !db->init.busy ){ | 123431 | if( !db->init.busy ){ |
| 119214 | if( sqlite3FindTable(db, zName, 0)!=0 ){ | 123432 | if( sqlite3FindTable(db, zName, pDb->zDbSName)!=0 ){ |
| 119215 | sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); | 123433 | sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); |
| 119216 | goto exit_create_index; | 123434 | goto exit_create_index; |
| 119217 | } | 123435 | } |
| @@ -119364,6 +123582,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( | |||
| 119364 | j = XN_EXPR; | 123582 | j = XN_EXPR; |
| 119365 | pIndex->aiColumn[i] = XN_EXPR; | 123583 | pIndex->aiColumn[i] = XN_EXPR; |
| 119366 | pIndex->uniqNotNull = 0; | 123584 | pIndex->uniqNotNull = 0; |
| 123585 | pIndex->bHasExpr = 1; | ||
| 119367 | }else{ | 123586 | }else{ |
| 119368 | j = pCExpr->iColumn; | 123587 | j = pCExpr->iColumn; |
| 119369 | assert( j<=0x7fff ); | 123588 | assert( j<=0x7fff ); |
| @@ -119375,6 +123594,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( | |||
| 119375 | } | 123594 | } |
| 119376 | if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ | 123595 | if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ |
| 119377 | pIndex->bHasVCol = 1; | 123596 | pIndex->bHasVCol = 1; |
| 123597 | pIndex->bHasExpr = 1; | ||
| 119378 | } | 123598 | } |
| 119379 | } | 123599 | } |
| 119380 | pIndex->aiColumn[i] = (i16)j; | 123600 | pIndex->aiColumn[i] = (i16)j; |
| @@ -119864,12 +124084,13 @@ SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token * | |||
| 119864 | */ | 124084 | */ |
| 119865 | SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ | 124085 | SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ |
| 119866 | int i; | 124086 | int i; |
| 124087 | assert( db!=0 ); | ||
| 119867 | if( pList==0 ) return; | 124088 | if( pList==0 ) return; |
| 119868 | assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */ | 124089 | assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */ |
| 119869 | for(i=0; i<pList->nId; i++){ | 124090 | for(i=0; i<pList->nId; i++){ |
| 119870 | sqlite3DbFree(db, pList->a[i].zName); | 124091 | sqlite3DbFree(db, pList->a[i].zName); |
| 119871 | } | 124092 | } |
| 119872 | sqlite3DbFreeNN(db, pList); | 124093 | sqlite3DbNNFreeNN(db, pList); |
| 119873 | } | 124094 | } |
| 119874 | 124095 | ||
| 119875 | /* | 124096 | /* |
| @@ -120072,11 +124293,12 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ | |||
| 120072 | SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ | 124293 | SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ |
| 120073 | int i; | 124294 | int i; |
| 120074 | SrcItem *pItem; | 124295 | SrcItem *pItem; |
| 124296 | assert( db!=0 ); | ||
| 120075 | if( pList==0 ) return; | 124297 | if( pList==0 ) return; |
| 120076 | for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ | 124298 | for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ |
| 120077 | if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); | 124299 | if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase); |
| 120078 | sqlite3DbFree(db, pItem->zName); | 124300 | if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); |
| 120079 | if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias); | 124301 | if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); |
| 120080 | if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); | 124302 | if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); |
| 120081 | if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); | 124303 | if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); |
| 120082 | sqlite3DeleteTable(db, pItem->pTab); | 124304 | sqlite3DeleteTable(db, pItem->pTab); |
| @@ -120087,7 +124309,7 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ | |||
| 120087 | sqlite3ExprDelete(db, pItem->u3.pOn); | 124309 | sqlite3ExprDelete(db, pItem->u3.pOn); |
| 120088 | } | 124310 | } |
| 120089 | } | 124311 | } |
| 120090 | sqlite3DbFreeNN(db, pList); | 124312 | sqlite3DbNNFreeNN(db, pList); |
| 120091 | } | 124313 | } |
| 120092 | 124314 | ||
| 120093 | /* | 124315 | /* |
| @@ -120783,7 +125005,7 @@ SQLITE_PRIVATE void sqlite3CteDelete(sqlite3 *db, Cte *pCte){ | |||
| 120783 | 125005 | ||
| 120784 | /* | 125006 | /* |
| 120785 | ** This routine is invoked once per CTE by the parser while parsing a | 125007 | ** This routine is invoked once per CTE by the parser while parsing a |
| 120786 | ** WITH clause. The CTE described by teh third argument is added to | 125008 | ** WITH clause. The CTE described by the third argument is added to |
| 120787 | ** the WITH clause of the second argument. If the second argument is | 125009 | ** the WITH clause of the second argument. If the second argument is |
| 120788 | ** NULL, then a new WITH argument is created. | 125010 | ** NULL, then a new WITH argument is created. |
| 120789 | */ | 125011 | */ |
| @@ -121034,6 +125256,7 @@ SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){ | |||
| 121034 | ** strings is BINARY. | 125256 | ** strings is BINARY. |
| 121035 | */ | 125257 | */ |
| 121036 | db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0); | 125258 | db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0); |
| 125259 | sqlite3ExpirePreparedStatements(db, 1); | ||
| 121037 | } | 125260 | } |
| 121038 | 125261 | ||
| 121039 | /* | 125262 | /* |
| @@ -121339,19 +125562,21 @@ SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ | |||
| 121339 | Hash temp2; | 125562 | Hash temp2; |
| 121340 | HashElem *pElem; | 125563 | HashElem *pElem; |
| 121341 | Schema *pSchema = (Schema *)p; | 125564 | Schema *pSchema = (Schema *)p; |
| 125565 | sqlite3 xdb; | ||
| 121342 | 125566 | ||
| 125567 | memset(&xdb, 0, sizeof(xdb)); | ||
| 121343 | temp1 = pSchema->tblHash; | 125568 | temp1 = pSchema->tblHash; |
| 121344 | temp2 = pSchema->trigHash; | 125569 | temp2 = pSchema->trigHash; |
| 121345 | sqlite3HashInit(&pSchema->trigHash); | 125570 | sqlite3HashInit(&pSchema->trigHash); |
| 121346 | sqlite3HashClear(&pSchema->idxHash); | 125571 | sqlite3HashClear(&pSchema->idxHash); |
| 121347 | for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ | 125572 | for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ |
| 121348 | sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); | 125573 | sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem)); |
| 121349 | } | 125574 | } |
| 121350 | sqlite3HashClear(&temp2); | 125575 | sqlite3HashClear(&temp2); |
| 121351 | sqlite3HashInit(&pSchema->tblHash); | 125576 | sqlite3HashInit(&pSchema->tblHash); |
| 121352 | for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ | 125577 | for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ |
| 121353 | Table *pTab = sqliteHashData(pElem); | 125578 | Table *pTab = sqliteHashData(pElem); |
| 121354 | sqlite3DeleteTable(0, pTab); | 125579 | sqlite3DeleteTable(&xdb, pTab); |
| 121355 | } | 125580 | } |
| 121356 | sqlite3HashClear(&temp1); | 125581 | sqlite3HashClear(&temp1); |
| 121357 | sqlite3HashClear(&pSchema->fkeyHash); | 125582 | sqlite3HashClear(&pSchema->fkeyHash); |
| @@ -121422,8 +125647,9 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ | |||
| 121422 | Table *pTab; | 125647 | Table *pTab; |
| 121423 | assert( pItem && pSrc->nSrc>=1 ); | 125648 | assert( pItem && pSrc->nSrc>=1 ); |
| 121424 | pTab = sqlite3LocateTableItem(pParse, 0, pItem); | 125649 | pTab = sqlite3LocateTableItem(pParse, 0, pItem); |
| 121425 | sqlite3DeleteTable(pParse->db, pItem->pTab); | 125650 | if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab); |
| 121426 | pItem->pTab = pTab; | 125651 | pItem->pTab = pTab; |
| 125652 | pItem->fg.notCte = 1; | ||
| 121427 | if( pTab ){ | 125653 | if( pTab ){ |
| 121428 | pTab->nTabRef++; | 125654 | pTab->nTabRef++; |
| 121429 | if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ | 125655 | if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ |
| @@ -121450,18 +125676,42 @@ SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char * | |||
| 121450 | ** 1) It is a virtual table and no implementation of the xUpdate method | 125676 | ** 1) It is a virtual table and no implementation of the xUpdate method |
| 121451 | ** has been provided | 125677 | ** has been provided |
| 121452 | ** | 125678 | ** |
| 121453 | ** 2) It is a system table (i.e. sqlite_schema), this call is not | 125679 | ** 2) A trigger is currently being coded and the table is a virtual table |
| 125680 | ** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and | ||
| 125681 | ** the table is not SQLITE_VTAB_INNOCUOUS. | ||
| 125682 | ** | ||
| 125683 | ** 3) It is a system table (i.e. sqlite_schema), this call is not | ||
| 121454 | ** part of a nested parse and writable_schema pragma has not | 125684 | ** part of a nested parse and writable_schema pragma has not |
| 121455 | ** been specified | 125685 | ** been specified |
| 121456 | ** | 125686 | ** |
| 121457 | ** 3) The table is a shadow table, the database connection is in | 125687 | ** 4) The table is a shadow table, the database connection is in |
| 121458 | ** defensive mode, and the current sqlite3_prepare() | 125688 | ** defensive mode, and the current sqlite3_prepare() |
| 121459 | ** is for a top-level SQL statement. | 125689 | ** is for a top-level SQL statement. |
| 121460 | */ | 125690 | */ |
| 125691 | static int vtabIsReadOnly(Parse *pParse, Table *pTab){ | ||
| 125692 | if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ | ||
| 125693 | return 1; | ||
| 125694 | } | ||
| 125695 | |||
| 125696 | /* Within triggers: | ||
| 125697 | ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY | ||
| 125698 | ** virtual tables | ||
| 125699 | ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS | ||
| 125700 | ** virtual tables if PRAGMA trusted_schema=ON. | ||
| 125701 | */ | ||
| 125702 | if( pParse->pToplevel!=0 | ||
| 125703 | && pTab->u.vtab.p->eVtabRisk > | ||
| 125704 | ((pParse->db->flags & SQLITE_TrustedSchema)!=0) | ||
| 125705 | ){ | ||
| 125706 | sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", | ||
| 125707 | pTab->zName); | ||
| 125708 | } | ||
| 125709 | return 0; | ||
| 125710 | } | ||
| 121461 | static int tabIsReadOnly(Parse *pParse, Table *pTab){ | 125711 | static int tabIsReadOnly(Parse *pParse, Table *pTab){ |
| 121462 | sqlite3 *db; | 125712 | sqlite3 *db; |
| 121463 | if( IsVirtual(pTab) ){ | 125713 | if( IsVirtual(pTab) ){ |
| 121464 | return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0; | 125714 | return vtabIsReadOnly(pParse, pTab); |
| 121465 | } | 125715 | } |
| 121466 | if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; | 125716 | if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; |
| 121467 | db = pParse->db; | 125717 | db = pParse->db; |
| @@ -121473,17 +125723,21 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){ | |||
| 121473 | } | 125723 | } |
| 121474 | 125724 | ||
| 121475 | /* | 125725 | /* |
| 121476 | ** Check to make sure the given table is writable. If it is not | 125726 | ** Check to make sure the given table is writable. |
| 121477 | ** writable, generate an error message and return 1. If it is | 125727 | ** |
| 121478 | ** writable return 0; | 125728 | ** If pTab is not writable -> generate an error message and return 1. |
| 125729 | ** If pTab is writable but other errors have occurred -> return 1. | ||
| 125730 | ** If pTab is writable and no prior errors -> return 0; | ||
| 121479 | */ | 125731 | */ |
| 121480 | SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ | 125732 | SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, Trigger *pTrigger){ |
| 121481 | if( tabIsReadOnly(pParse, pTab) ){ | 125733 | if( tabIsReadOnly(pParse, pTab) ){ |
| 121482 | sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); | 125734 | sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); |
| 121483 | return 1; | 125735 | return 1; |
| 121484 | } | 125736 | } |
| 121485 | #ifndef SQLITE_OMIT_VIEW | 125737 | #ifndef SQLITE_OMIT_VIEW |
| 121486 | if( !viewOk && IsView(pTab) ){ | 125738 | if( IsView(pTab) |
| 125739 | && (pTrigger==0 || (pTrigger->bReturning && pTrigger->pNext==0)) | ||
| 125740 | ){ | ||
| 121487 | sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); | 125741 | sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); |
| 121488 | return 1; | 125742 | return 1; |
| 121489 | } | 125743 | } |
| @@ -121548,7 +125802,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( | |||
| 121548 | sqlite3 *db = pParse->db; | 125802 | sqlite3 *db = pParse->db; |
| 121549 | Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ | 125803 | Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ |
| 121550 | Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ | 125804 | Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ |
| 121551 | ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ | 125805 | ExprList *pEList = NULL; /* Expression list containing only pSelectRowid*/ |
| 121552 | SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ | 125806 | SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ |
| 121553 | Select *pSelect = NULL; /* Complete SELECT tree */ | 125807 | Select *pSelect = NULL; /* Complete SELECT tree */ |
| 121554 | Table *pTab; | 125808 | Table *pTab; |
| @@ -121586,14 +125840,20 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( | |||
| 121586 | ); | 125840 | ); |
| 121587 | }else{ | 125841 | }else{ |
| 121588 | Index *pPk = sqlite3PrimaryKeyIndex(pTab); | 125842 | Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
| 125843 | assert( pPk!=0 ); | ||
| 125844 | assert( pPk->nKeyCol>=1 ); | ||
| 121589 | if( pPk->nKeyCol==1 ){ | 125845 | if( pPk->nKeyCol==1 ){ |
| 121590 | const char *zName = pTab->aCol[pPk->aiColumn[0]].zCnName; | 125846 | const char *zName; |
| 125847 | assert( pPk->aiColumn[0]>=0 && pPk->aiColumn[0]<pTab->nCol ); | ||
| 125848 | zName = pTab->aCol[pPk->aiColumn[0]].zCnName; | ||
| 121591 | pLhs = sqlite3Expr(db, TK_ID, zName); | 125849 | pLhs = sqlite3Expr(db, TK_ID, zName); |
| 121592 | pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); | 125850 | pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); |
| 121593 | }else{ | 125851 | }else{ |
| 121594 | int i; | 125852 | int i; |
| 121595 | for(i=0; i<pPk->nKeyCol; i++){ | 125853 | for(i=0; i<pPk->nKeyCol; i++){ |
| 121596 | Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); | 125854 | Expr *p; |
| 125855 | assert( pPk->aiColumn[i]>=0 && pPk->aiColumn[i]<pTab->nCol ); | ||
| 125856 | p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); | ||
| 121597 | pEList = sqlite3ExprListAppend(pParse, pEList, p); | 125857 | pEList = sqlite3ExprListAppend(pParse, pEList, p); |
| 121598 | } | 125858 | } |
| 121599 | pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); | 125859 | pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); |
| @@ -121622,7 +125882,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( | |||
| 121622 | pOrderBy,0,pLimit | 125882 | pOrderBy,0,pLimit |
| 121623 | ); | 125883 | ); |
| 121624 | 125884 | ||
| 121625 | /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ | 125885 | /* now generate the new WHERE rowid IN clause for the DELETE/UPDATE */ |
| 121626 | pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); | 125886 | pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); |
| 121627 | sqlite3PExprAddSelect(pParse, pInClause, pSelect); | 125887 | sqlite3PExprAddSelect(pParse, pInClause, pSelect); |
| 121628 | return pInClause; | 125888 | return pInClause; |
| @@ -121737,7 +125997,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( | |||
| 121737 | goto delete_from_cleanup; | 125997 | goto delete_from_cleanup; |
| 121738 | } | 125998 | } |
| 121739 | 125999 | ||
| 121740 | if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ | 126000 | if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ |
| 121741 | goto delete_from_cleanup; | 126001 | goto delete_from_cleanup; |
| 121742 | } | 126002 | } |
| 121743 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | 126003 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| @@ -121836,21 +126096,22 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( | |||
| 121836 | } | 126096 | } |
| 121837 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 126097 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 121838 | assert( pIdx->pSchema==pTab->pSchema ); | 126098 | assert( pIdx->pSchema==pTab->pSchema ); |
| 121839 | sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); | ||
| 121840 | if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ | 126099 | if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ |
| 121841 | sqlite3VdbeChangeP3(v, -1, memCnt ? memCnt : -1); | 126100 | sqlite3VdbeAddOp3(v, OP_Clear, pIdx->tnum, iDb, memCnt ? memCnt : -1); |
| 126101 | }else{ | ||
| 126102 | sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); | ||
| 121842 | } | 126103 | } |
| 121843 | } | 126104 | } |
| 121844 | }else | 126105 | }else |
| 121845 | #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ | 126106 | #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ |
| 121846 | { | 126107 | { |
| 121847 | u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; | 126108 | u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; |
| 121848 | if( sNC.ncFlags & NC_VarSelect ) bComplex = 1; | 126109 | if( sNC.ncFlags & NC_Subquery ) bComplex = 1; |
| 121849 | wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); | 126110 | wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); |
| 121850 | if( HasRowid(pTab) ){ | 126111 | if( HasRowid(pTab) ){ |
| 121851 | /* For a rowid table, initialize the RowSet to an empty set */ | 126112 | /* For a rowid table, initialize the RowSet to an empty set */ |
| 121852 | pPk = 0; | 126113 | pPk = 0; |
| 121853 | nPk = 1; | 126114 | assert( nPk==1 ); |
| 121854 | iRowSet = ++pParse->nMem; | 126115 | iRowSet = ++pParse->nMem; |
| 121855 | sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); | 126116 | sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); |
| 121856 | }else{ | 126117 | }else{ |
| @@ -121878,7 +126139,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( | |||
| 121878 | if( pWInfo==0 ) goto delete_from_cleanup; | 126139 | if( pWInfo==0 ) goto delete_from_cleanup; |
| 121879 | eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); | 126140 | eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); |
| 121880 | assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); | 126141 | assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); |
| 121881 | assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); | 126142 | assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF |
| 126143 | || OptimizationDisabled(db, SQLITE_OnePass) ); | ||
| 121882 | if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); | 126144 | if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); |
| 121883 | if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ | 126145 | if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ |
| 121884 | sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); | 126146 | sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); |
| @@ -122038,7 +126300,7 @@ delete_from_cleanup: | |||
| 122038 | sqlite3ExprListDelete(db, pOrderBy); | 126300 | sqlite3ExprListDelete(db, pOrderBy); |
| 122039 | sqlite3ExprDelete(db, pLimit); | 126301 | sqlite3ExprDelete(db, pLimit); |
| 122040 | #endif | 126302 | #endif |
| 122041 | sqlite3DbFree(db, aToOpen); | 126303 | if( aToOpen ) sqlite3DbNNFreeNN(db, aToOpen); |
| 122042 | return; | 126304 | return; |
| 122043 | } | 126305 | } |
| 122044 | /* Make sure "isView" and other macros defined above are undefined. Otherwise | 126306 | /* Make sure "isView" and other macros defined above are undefined. Otherwise |
| @@ -122215,9 +126477,11 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete( | |||
| 122215 | sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); | 126477 | sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); |
| 122216 | 126478 | ||
| 122217 | /* Invoke AFTER DELETE trigger programs. */ | 126479 | /* Invoke AFTER DELETE trigger programs. */ |
| 122218 | sqlite3CodeRowTrigger(pParse, pTrigger, | 126480 | if( pTrigger ){ |
| 122219 | TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel | 126481 | sqlite3CodeRowTrigger(pParse, pTrigger, |
| 122220 | ); | 126482 | TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel |
| 126483 | ); | ||
| 126484 | } | ||
| 122221 | 126485 | ||
| 122222 | /* Jump here if the row had already been deleted before any BEFORE | 126486 | /* Jump here if the row had already been deleted before any BEFORE |
| 122223 | ** trigger programs were invoked. Or if a trigger program throws a | 126487 | ** trigger programs were invoked. Or if a trigger program throws a |
| @@ -122531,6 +126795,42 @@ static void lengthFunc( | |||
| 122531 | } | 126795 | } |
| 122532 | 126796 | ||
| 122533 | /* | 126797 | /* |
| 126798 | ** Implementation of the octet_length() function | ||
| 126799 | */ | ||
| 126800 | static void bytelengthFunc( | ||
| 126801 | sqlite3_context *context, | ||
| 126802 | int argc, | ||
| 126803 | sqlite3_value **argv | ||
| 126804 | ){ | ||
| 126805 | assert( argc==1 ); | ||
| 126806 | UNUSED_PARAMETER(argc); | ||
| 126807 | switch( sqlite3_value_type(argv[0]) ){ | ||
| 126808 | case SQLITE_BLOB: { | ||
| 126809 | sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); | ||
| 126810 | break; | ||
| 126811 | } | ||
| 126812 | case SQLITE_INTEGER: | ||
| 126813 | case SQLITE_FLOAT: { | ||
| 126814 | i64 m = sqlite3_context_db_handle(context)->enc<=SQLITE_UTF8 ? 1 : 2; | ||
| 126815 | sqlite3_result_int64(context, sqlite3_value_bytes(argv[0])*m); | ||
| 126816 | break; | ||
| 126817 | } | ||
| 126818 | case SQLITE_TEXT: { | ||
| 126819 | if( sqlite3_value_encoding(argv[0])<=SQLITE_UTF8 ){ | ||
| 126820 | sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); | ||
| 126821 | }else{ | ||
| 126822 | sqlite3_result_int(context, sqlite3_value_bytes16(argv[0])); | ||
| 126823 | } | ||
| 126824 | break; | ||
| 126825 | } | ||
| 126826 | default: { | ||
| 126827 | sqlite3_result_null(context); | ||
| 126828 | break; | ||
| 126829 | } | ||
| 126830 | } | ||
| 126831 | } | ||
| 126832 | |||
| 126833 | /* | ||
| 122534 | ** Implementation of the abs() function. | 126834 | ** Implementation of the abs() function. |
| 122535 | ** | 126835 | ** |
| 122536 | ** IMP: R-23979-26855 The abs(X) function returns the absolute value of | 126836 | ** IMP: R-23979-26855 The abs(X) function returns the absolute value of |
| @@ -122806,7 +127106,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ | |||
| 122806 | }else if( n==0 ){ | 127106 | }else if( n==0 ){ |
| 122807 | r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); | 127107 | r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); |
| 122808 | }else{ | 127108 | }else{ |
| 122809 | zBuf = sqlite3_mprintf("%.*f",n,r); | 127109 | zBuf = sqlite3_mprintf("%!.*f",n,r); |
| 122810 | if( zBuf==0 ){ | 127110 | if( zBuf==0 ){ |
| 122811 | sqlite3_result_error_nomem(context); | 127111 | sqlite3_result_error_nomem(context); |
| 122812 | return; | 127112 | return; |
| @@ -123006,7 +127306,7 @@ struct compareInfo { | |||
| 123006 | 127306 | ||
| 123007 | /* | 127307 | /* |
| 123008 | ** For LIKE and GLOB matching on EBCDIC machines, assume that every | 127308 | ** For LIKE and GLOB matching on EBCDIC machines, assume that every |
| 123009 | ** character is exactly one byte in size. Also, provde the Utf8Read() | 127309 | ** character is exactly one byte in size. Also, provide the Utf8Read() |
| 123010 | ** macro for fast reading of the next character in the common case where | 127310 | ** macro for fast reading of the next character in the common case where |
| 123011 | ** the next character is ASCII. | 127311 | ** the next character is ASCII. |
| 123012 | */ | 127312 | */ |
| @@ -123121,7 +127421,7 @@ static int patternCompare( | |||
| 123121 | ** c but in the other case and search the input string for either | 127421 | ** c but in the other case and search the input string for either |
| 123122 | ** c or cx. | 127422 | ** c or cx. |
| 123123 | */ | 127423 | */ |
| 123124 | if( c<=0x80 ){ | 127424 | if( c<0x80 ){ |
| 123125 | char zStop[3]; | 127425 | char zStop[3]; |
| 123126 | int bMatch; | 127426 | int bMatch; |
| 123127 | if( noCase ){ | 127427 | if( noCase ){ |
| @@ -123204,7 +127504,13 @@ static int patternCompare( | |||
| 123204 | ** non-zero if there is no match. | 127504 | ** non-zero if there is no match. |
| 123205 | */ | 127505 | */ |
| 123206 | SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ | 127506 | SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ |
| 123207 | return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); | 127507 | if( zString==0 ){ |
| 127508 | return zGlobPattern!=0; | ||
| 127509 | }else if( zGlobPattern==0 ){ | ||
| 127510 | return 1; | ||
| 127511 | }else { | ||
| 127512 | return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); | ||
| 127513 | } | ||
| 123208 | } | 127514 | } |
| 123209 | 127515 | ||
| 123210 | /* | 127516 | /* |
| @@ -123212,7 +127518,13 @@ SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ | |||
| 123212 | ** a miss - like strcmp(). | 127518 | ** a miss - like strcmp(). |
| 123213 | */ | 127519 | */ |
| 123214 | SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ | 127520 | SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ |
| 123215 | return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); | 127521 | if( zStr==0 ){ |
| 127522 | return zPattern!=0; | ||
| 127523 | }else if( zPattern==0 ){ | ||
| 127524 | return 1; | ||
| 127525 | }else{ | ||
| 127526 | return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); | ||
| 127527 | } | ||
| 123216 | } | 127528 | } |
| 123217 | 127529 | ||
| 123218 | /* | 127530 | /* |
| @@ -123227,7 +127539,7 @@ SQLITE_API int sqlite3_like_count = 0; | |||
| 123227 | 127539 | ||
| 123228 | /* | 127540 | /* |
| 123229 | ** Implementation of the like() SQL function. This function implements | 127541 | ** Implementation of the like() SQL function. This function implements |
| 123230 | ** the build-in LIKE operator. The first argument to the function is the | 127542 | ** the built-in LIKE operator. The first argument to the function is the |
| 123231 | ** pattern and the second argument is the string. So, the SQL statements: | 127543 | ** pattern and the second argument is the string. So, the SQL statements: |
| 123232 | ** | 127544 | ** |
| 123233 | ** A LIKE B | 127545 | ** A LIKE B |
| @@ -123451,7 +127763,7 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ | |||
| 123451 | } | 127763 | } |
| 123452 | case SQLITE_BLOB: { | 127764 | case SQLITE_BLOB: { |
| 123453 | char const *zBlob = sqlite3_value_blob(pValue); | 127765 | char const *zBlob = sqlite3_value_blob(pValue); |
| 123454 | int nBlob = sqlite3_value_bytes(pValue); | 127766 | i64 nBlob = sqlite3_value_bytes(pValue); |
| 123455 | assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */ | 127767 | assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */ |
| 123456 | sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4); | 127768 | sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4); |
| 123457 | if( pStr->accError==0 ){ | 127769 | if( pStr->accError==0 ){ |
| @@ -123560,6 +127872,7 @@ static void charFunc( | |||
| 123560 | *zOut++ = 0x80 + (u8)(c & 0x3F); | 127872 | *zOut++ = 0x80 + (u8)(c & 0x3F); |
| 123561 | } \ | 127873 | } \ |
| 123562 | } | 127874 | } |
| 127875 | *zOut = 0; | ||
| 123563 | sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); | 127876 | sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); |
| 123564 | } | 127877 | } |
| 123565 | 127878 | ||
| @@ -123593,6 +127906,96 @@ static void hexFunc( | |||
| 123593 | } | 127906 | } |
| 123594 | 127907 | ||
| 123595 | /* | 127908 | /* |
| 127909 | ** Buffer zStr contains nStr bytes of utf-8 encoded text. Return 1 if zStr | ||
| 127910 | ** contains character ch, or 0 if it does not. | ||
| 127911 | */ | ||
| 127912 | static int strContainsChar(const u8 *zStr, int nStr, u32 ch){ | ||
| 127913 | const u8 *zEnd = &zStr[nStr]; | ||
| 127914 | const u8 *z = zStr; | ||
| 127915 | while( z<zEnd ){ | ||
| 127916 | u32 tst = Utf8Read(z); | ||
| 127917 | if( tst==ch ) return 1; | ||
| 127918 | } | ||
| 127919 | return 0; | ||
| 127920 | } | ||
| 127921 | |||
| 127922 | /* | ||
| 127923 | ** The unhex() function. This function may be invoked with either one or | ||
| 127924 | ** two arguments. In both cases the first argument is interpreted as text | ||
| 127925 | ** a text value containing a set of pairs of hexadecimal digits which are | ||
| 127926 | ** decoded and returned as a blob. | ||
| 127927 | ** | ||
| 127928 | ** If there is only a single argument, then it must consist only of an | ||
| 127929 | ** even number of hexadecimal digits. Otherwise, return NULL. | ||
| 127930 | ** | ||
| 127931 | ** Or, if there is a second argument, then any character that appears in | ||
| 127932 | ** the second argument is also allowed to appear between pairs of hexadecimal | ||
| 127933 | ** digits in the first argument. If any other character appears in the | ||
| 127934 | ** first argument, or if one of the allowed characters appears between | ||
| 127935 | ** two hexadecimal digits that make up a single byte, NULL is returned. | ||
| 127936 | ** | ||
| 127937 | ** The following expressions are all true: | ||
| 127938 | ** | ||
| 127939 | ** unhex('ABCD') IS x'ABCD' | ||
| 127940 | ** unhex('AB CD') IS NULL | ||
| 127941 | ** unhex('AB CD', ' ') IS x'ABCD' | ||
| 127942 | ** unhex('A BCD', ' ') IS NULL | ||
| 127943 | */ | ||
| 127944 | static void unhexFunc( | ||
| 127945 | sqlite3_context *pCtx, | ||
| 127946 | int argc, | ||
| 127947 | sqlite3_value **argv | ||
| 127948 | ){ | ||
| 127949 | const u8 *zPass = (const u8*)""; | ||
| 127950 | int nPass = 0; | ||
| 127951 | const u8 *zHex = sqlite3_value_text(argv[0]); | ||
| 127952 | int nHex = sqlite3_value_bytes(argv[0]); | ||
| 127953 | #ifdef SQLITE_DEBUG | ||
| 127954 | const u8 *zEnd = zHex ? &zHex[nHex] : 0; | ||
| 127955 | #endif | ||
| 127956 | u8 *pBlob = 0; | ||
| 127957 | u8 *p = 0; | ||
| 127958 | |||
| 127959 | assert( argc==1 || argc==2 ); | ||
| 127960 | if( argc==2 ){ | ||
| 127961 | zPass = sqlite3_value_text(argv[1]); | ||
| 127962 | nPass = sqlite3_value_bytes(argv[1]); | ||
| 127963 | } | ||
| 127964 | if( !zHex || !zPass ) return; | ||
| 127965 | |||
| 127966 | p = pBlob = contextMalloc(pCtx, (nHex/2)+1); | ||
| 127967 | if( pBlob ){ | ||
| 127968 | u8 c; /* Most significant digit of next byte */ | ||
| 127969 | u8 d; /* Least significant digit of next byte */ | ||
| 127970 | |||
| 127971 | while( (c = *zHex)!=0x00 ){ | ||
| 127972 | while( !sqlite3Isxdigit(c) ){ | ||
| 127973 | u32 ch = Utf8Read(zHex); | ||
| 127974 | assert( zHex<=zEnd ); | ||
| 127975 | if( !strContainsChar(zPass, nPass, ch) ) goto unhex_null; | ||
| 127976 | c = *zHex; | ||
| 127977 | if( c==0x00 ) goto unhex_done; | ||
| 127978 | } | ||
| 127979 | zHex++; | ||
| 127980 | assert( *zEnd==0x00 ); | ||
| 127981 | assert( zHex<=zEnd ); | ||
| 127982 | d = *(zHex++); | ||
| 127983 | if( !sqlite3Isxdigit(d) ) goto unhex_null; | ||
| 127984 | *(p++) = (sqlite3HexToInt(c)<<4) | sqlite3HexToInt(d); | ||
| 127985 | } | ||
| 127986 | } | ||
| 127987 | |||
| 127988 | unhex_done: | ||
| 127989 | sqlite3_result_blob(pCtx, pBlob, (p - pBlob), sqlite3_free); | ||
| 127990 | return; | ||
| 127991 | |||
| 127992 | unhex_null: | ||
| 127993 | sqlite3_free(pBlob); | ||
| 127994 | return; | ||
| 127995 | } | ||
| 127996 | |||
| 127997 | |||
| 127998 | /* | ||
| 123596 | ** The zeroblob(N) function returns a zero-filled blob of size N bytes. | 127999 | ** The zeroblob(N) function returns a zero-filled blob of size N bytes. |
| 123597 | */ | 128000 | */ |
| 123598 | static void zeroblobFunc( | 128001 | static void zeroblobFunc( |
| @@ -123797,7 +128200,7 @@ static void trimFunc( | |||
| 123797 | /* | 128200 | /* |
| 123798 | ** The "unknown" function is automatically substituted in place of | 128201 | ** The "unknown" function is automatically substituted in place of |
| 123799 | ** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN | 128202 | ** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN |
| 123800 | ** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used. | 128203 | ** when the SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION compile-time option is used. |
| 123801 | ** When the "sqlite3" command-line shell is built using this functionality, | 128204 | ** When the "sqlite3" command-line shell is built using this functionality, |
| 123802 | ** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries | 128205 | ** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries |
| 123803 | ** involving application-defined functions to be examined in a generic | 128206 | ** involving application-defined functions to be examined in a generic |
| @@ -123809,6 +128212,9 @@ static void unknownFunc( | |||
| 123809 | sqlite3_value **argv | 128212 | sqlite3_value **argv |
| 123810 | ){ | 128213 | ){ |
| 123811 | /* no-op */ | 128214 | /* no-op */ |
| 128215 | (void)context; | ||
| 128216 | (void)argc; | ||
| 128217 | (void)argv; | ||
| 123812 | } | 128218 | } |
| 123813 | #endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/ | 128219 | #endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/ |
| 123814 | 128220 | ||
| @@ -123910,14 +128316,69 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ | |||
| 123910 | */ | 128316 | */ |
| 123911 | typedef struct SumCtx SumCtx; | 128317 | typedef struct SumCtx SumCtx; |
| 123912 | struct SumCtx { | 128318 | struct SumCtx { |
| 123913 | double rSum; /* Floating point sum */ | 128319 | double rSum; /* Running sum as as a double */ |
| 123914 | i64 iSum; /* Integer sum */ | 128320 | double rErr; /* Error term for Kahan-Babushka-Neumaier summation */ |
| 128321 | i64 iSum; /* Running sum as a signed integer */ | ||
| 123915 | i64 cnt; /* Number of elements summed */ | 128322 | i64 cnt; /* Number of elements summed */ |
| 123916 | u8 overflow; /* True if integer overflow seen */ | 128323 | u8 approx; /* True if any non-integer value was input to the sum */ |
| 123917 | u8 approx; /* True if non-integer value was input to the sum */ | 128324 | u8 ovrfl; /* Integer overflow seen */ |
| 123918 | }; | 128325 | }; |
| 123919 | 128326 | ||
| 123920 | /* | 128327 | /* |
| 128328 | ** Do one step of the Kahan-Babushka-Neumaier summation. | ||
| 128329 | ** | ||
| 128330 | ** https://en.wikipedia.org/wiki/Kahan_summation_algorithm | ||
| 128331 | ** | ||
| 128332 | ** Variables are marked "volatile" to defeat c89 x86 floating point | ||
| 128333 | ** optimizations can mess up this algorithm. | ||
| 128334 | */ | ||
| 128335 | static void kahanBabuskaNeumaierStep( | ||
| 128336 | volatile SumCtx *pSum, | ||
| 128337 | volatile double r | ||
| 128338 | ){ | ||
| 128339 | volatile double s = pSum->rSum; | ||
| 128340 | volatile double t = s + r; | ||
| 128341 | if( fabs(s) > fabs(r) ){ | ||
| 128342 | pSum->rErr += (s - t) + r; | ||
| 128343 | }else{ | ||
| 128344 | pSum->rErr += (r - t) + s; | ||
| 128345 | } | ||
| 128346 | pSum->rSum = t; | ||
| 128347 | } | ||
| 128348 | |||
| 128349 | /* | ||
| 128350 | ** Add a (possibly large) integer to the running sum. | ||
| 128351 | */ | ||
| 128352 | static void kahanBabuskaNeumaierStepInt64(volatile SumCtx *pSum, i64 iVal){ | ||
| 128353 | if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ | ||
| 128354 | i64 iBig, iSm; | ||
| 128355 | iSm = iVal % 16384; | ||
| 128356 | iBig = iVal - iSm; | ||
| 128357 | kahanBabuskaNeumaierStep(pSum, iBig); | ||
| 128358 | kahanBabuskaNeumaierStep(pSum, iSm); | ||
| 128359 | }else{ | ||
| 128360 | kahanBabuskaNeumaierStep(pSum, (double)iVal); | ||
| 128361 | } | ||
| 128362 | } | ||
| 128363 | |||
| 128364 | /* | ||
| 128365 | ** Initialize the Kahan-Babaska-Neumaier sum from a 64-bit integer | ||
| 128366 | */ | ||
| 128367 | static void kahanBabuskaNeumaierInit( | ||
| 128368 | volatile SumCtx *p, | ||
| 128369 | i64 iVal | ||
| 128370 | ){ | ||
| 128371 | if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ | ||
| 128372 | i64 iSm = iVal % 16384; | ||
| 128373 | p->rSum = (double)(iVal - iSm); | ||
| 128374 | p->rErr = (double)iSm; | ||
| 128375 | }else{ | ||
| 128376 | p->rSum = (double)iVal; | ||
| 128377 | p->rErr = 0.0; | ||
| 128378 | } | ||
| 128379 | } | ||
| 128380 | |||
| 128381 | /* | ||
| 123921 | ** Routines used to compute the sum, average, and total. | 128382 | ** Routines used to compute the sum, average, and total. |
| 123922 | ** | 128383 | ** |
| 123923 | ** The SUM() function follows the (broken) SQL standard which means | 128384 | ** The SUM() function follows the (broken) SQL standard which means |
| @@ -123936,15 +128397,29 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ | |||
| 123936 | type = sqlite3_value_numeric_type(argv[0]); | 128397 | type = sqlite3_value_numeric_type(argv[0]); |
| 123937 | if( p && type!=SQLITE_NULL ){ | 128398 | if( p && type!=SQLITE_NULL ){ |
| 123938 | p->cnt++; | 128399 | p->cnt++; |
| 123939 | if( type==SQLITE_INTEGER ){ | 128400 | if( p->approx==0 ){ |
| 123940 | i64 v = sqlite3_value_int64(argv[0]); | 128401 | if( type!=SQLITE_INTEGER ){ |
| 123941 | p->rSum += v; | 128402 | kahanBabuskaNeumaierInit(p, p->iSum); |
| 123942 | if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ | 128403 | p->approx = 1; |
| 123943 | p->approx = p->overflow = 1; | 128404 | kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); |
| 128405 | }else{ | ||
| 128406 | i64 x = p->iSum; | ||
| 128407 | if( sqlite3AddInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ | ||
| 128408 | p->iSum = x; | ||
| 128409 | }else{ | ||
| 128410 | p->ovrfl = 1; | ||
| 128411 | kahanBabuskaNeumaierInit(p, p->iSum); | ||
| 128412 | p->approx = 1; | ||
| 128413 | kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); | ||
| 128414 | } | ||
| 123944 | } | 128415 | } |
| 123945 | }else{ | 128416 | }else{ |
| 123946 | p->rSum += sqlite3_value_double(argv[0]); | 128417 | if( type==SQLITE_INTEGER ){ |
| 123947 | p->approx = 1; | 128418 | kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); |
| 128419 | }else{ | ||
| 128420 | p->ovrfl = 0; | ||
| 128421 | kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); | ||
| 128422 | } | ||
| 123948 | } | 128423 | } |
| 123949 | } | 128424 | } |
| 123950 | } | 128425 | } |
| @@ -123961,13 +128436,18 @@ static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ | |||
| 123961 | if( ALWAYS(p) && type!=SQLITE_NULL ){ | 128436 | if( ALWAYS(p) && type!=SQLITE_NULL ){ |
| 123962 | assert( p->cnt>0 ); | 128437 | assert( p->cnt>0 ); |
| 123963 | p->cnt--; | 128438 | p->cnt--; |
| 123964 | assert( type==SQLITE_INTEGER || p->approx ); | 128439 | if( !p->approx ){ |
| 123965 | if( type==SQLITE_INTEGER && p->approx==0 ){ | 128440 | p->iSum -= sqlite3_value_int64(argv[0]); |
| 123966 | i64 v = sqlite3_value_int64(argv[0]); | 128441 | }else if( type==SQLITE_INTEGER ){ |
| 123967 | p->rSum -= v; | 128442 | i64 iVal = sqlite3_value_int64(argv[0]); |
| 123968 | p->iSum -= v; | 128443 | if( iVal!=SMALLEST_INT64 ){ |
| 128444 | kahanBabuskaNeumaierStepInt64(p, -iVal); | ||
| 128445 | }else{ | ||
| 128446 | kahanBabuskaNeumaierStepInt64(p, LARGEST_INT64); | ||
| 128447 | kahanBabuskaNeumaierStepInt64(p, 1); | ||
| 128448 | } | ||
| 123969 | }else{ | 128449 | }else{ |
| 123970 | p->rSum -= sqlite3_value_double(argv[0]); | 128450 | kahanBabuskaNeumaierStep(p, -sqlite3_value_double(argv[0])); |
| 123971 | } | 128451 | } |
| 123972 | } | 128452 | } |
| 123973 | } | 128453 | } |
| @@ -123978,10 +128458,12 @@ static void sumFinalize(sqlite3_context *context){ | |||
| 123978 | SumCtx *p; | 128458 | SumCtx *p; |
| 123979 | p = sqlite3_aggregate_context(context, 0); | 128459 | p = sqlite3_aggregate_context(context, 0); |
| 123980 | if( p && p->cnt>0 ){ | 128460 | if( p && p->cnt>0 ){ |
| 123981 | if( p->overflow ){ | 128461 | if( p->approx ){ |
| 123982 | sqlite3_result_error(context,"integer overflow",-1); | 128462 | if( p->ovrfl ){ |
| 123983 | }else if( p->approx ){ | 128463 | sqlite3_result_error(context,"integer overflow",-1); |
| 123984 | sqlite3_result_double(context, p->rSum); | 128464 | }else{ |
| 128465 | sqlite3_result_double(context, p->rSum+p->rErr); | ||
| 128466 | } | ||
| 123985 | }else{ | 128467 | }else{ |
| 123986 | sqlite3_result_int64(context, p->iSum); | 128468 | sqlite3_result_int64(context, p->iSum); |
| 123987 | } | 128469 | } |
| @@ -123991,14 +128473,27 @@ static void avgFinalize(sqlite3_context *context){ | |||
| 123991 | SumCtx *p; | 128473 | SumCtx *p; |
| 123992 | p = sqlite3_aggregate_context(context, 0); | 128474 | p = sqlite3_aggregate_context(context, 0); |
| 123993 | if( p && p->cnt>0 ){ | 128475 | if( p && p->cnt>0 ){ |
| 123994 | sqlite3_result_double(context, p->rSum/(double)p->cnt); | 128476 | double r; |
| 128477 | if( p->approx ){ | ||
| 128478 | r = p->rSum+p->rErr; | ||
| 128479 | }else{ | ||
| 128480 | r = (double)(p->iSum); | ||
| 128481 | } | ||
| 128482 | sqlite3_result_double(context, r/(double)p->cnt); | ||
| 123995 | } | 128483 | } |
| 123996 | } | 128484 | } |
| 123997 | static void totalFinalize(sqlite3_context *context){ | 128485 | static void totalFinalize(sqlite3_context *context){ |
| 123998 | SumCtx *p; | 128486 | SumCtx *p; |
| 128487 | double r = 0.0; | ||
| 123999 | p = sqlite3_aggregate_context(context, 0); | 128488 | p = sqlite3_aggregate_context(context, 0); |
| 124000 | /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ | 128489 | if( p ){ |
| 124001 | sqlite3_result_double(context, p ? p->rSum : (double)0); | 128490 | if( p->approx ){ |
| 128491 | r = p->rSum+p->rErr; | ||
| 128492 | }else{ | ||
| 128493 | r = (double)(p->iSum); | ||
| 128494 | } | ||
| 128495 | } | ||
| 128496 | sqlite3_result_double(context, r); | ||
| 124002 | } | 128497 | } |
| 124003 | 128498 | ||
| 124004 | /* | 128499 | /* |
| @@ -124220,7 +128715,7 @@ static void groupConcatInverse( | |||
| 124220 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; | 128715 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; |
| 124221 | pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); | 128716 | pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); |
| 124222 | /* pGCC is always non-NULL since groupConcatStep() will have always | 128717 | /* pGCC is always non-NULL since groupConcatStep() will have always |
| 124223 | ** run frist to initialize it */ | 128718 | ** run first to initialize it */ |
| 124224 | if( ALWAYS(pGCC) ){ | 128719 | if( ALWAYS(pGCC) ){ |
| 124225 | int nVS; | 128720 | int nVS; |
| 124226 | /* Must call sqlite3_value_text() to convert the argument into text prior | 128721 | /* Must call sqlite3_value_text() to convert the argument into text prior |
| @@ -124304,8 +128799,10 @@ SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){ | |||
| 124304 | ** sensitive. | 128799 | ** sensitive. |
| 124305 | */ | 128800 | */ |
| 124306 | SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ | 128801 | SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ |
| 128802 | FuncDef *pDef; | ||
| 124307 | struct compareInfo *pInfo; | 128803 | struct compareInfo *pInfo; |
| 124308 | int flags; | 128804 | int flags; |
| 128805 | int nArg; | ||
| 124309 | if( caseSensitive ){ | 128806 | if( caseSensitive ){ |
| 124310 | pInfo = (struct compareInfo*)&likeInfoAlt; | 128807 | pInfo = (struct compareInfo*)&likeInfoAlt; |
| 124311 | flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE; | 128808 | flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE; |
| @@ -124313,10 +128810,13 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) | |||
| 124313 | pInfo = (struct compareInfo*)&likeInfoNorm; | 128810 | pInfo = (struct compareInfo*)&likeInfoNorm; |
| 124314 | flags = SQLITE_FUNC_LIKE; | 128811 | flags = SQLITE_FUNC_LIKE; |
| 124315 | } | 128812 | } |
| 124316 | sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); | 128813 | for(nArg=2; nArg<=3; nArg++){ |
| 124317 | sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); | 128814 | sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc, |
| 124318 | sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags; | 128815 | 0, 0, 0, 0, 0); |
| 124319 | sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags; | 128816 | pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0); |
| 128817 | pDef->funcFlags |= flags; | ||
| 128818 | pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE; | ||
| 128819 | } | ||
| 124320 | } | 128820 | } |
| 124321 | 128821 | ||
| 124322 | /* | 128822 | /* |
| @@ -124438,6 +128938,18 @@ static double xCeil(double x){ return ceil(x); } | |||
| 124438 | static double xFloor(double x){ return floor(x); } | 128938 | static double xFloor(double x){ return floor(x); } |
| 124439 | 128939 | ||
| 124440 | /* | 128940 | /* |
| 128941 | ** Some systems do not have log2() and log10() in their standard math | ||
| 128942 | ** libraries. | ||
| 128943 | */ | ||
| 128944 | #if defined(HAVE_LOG10) && HAVE_LOG10==0 | ||
| 128945 | # define log10(X) (0.4342944819032517867*log(X)) | ||
| 128946 | #endif | ||
| 128947 | #if defined(HAVE_LOG2) && HAVE_LOG2==0 | ||
| 128948 | # define log2(X) (1.442695040888963456*log(X)) | ||
| 128949 | #endif | ||
| 128950 | |||
| 128951 | |||
| 128952 | /* | ||
| 124441 | ** Implementation of SQL functions: | 128953 | ** Implementation of SQL functions: |
| 124442 | ** | 128954 | ** |
| 124443 | ** ln(X) - natural logarithm | 128955 | ** ln(X) - natural logarithm |
| @@ -124475,17 +128987,15 @@ static void logFunc( | |||
| 124475 | } | 128987 | } |
| 124476 | ans = log(x)/b; | 128988 | ans = log(x)/b; |
| 124477 | }else{ | 128989 | }else{ |
| 124478 | ans = log(x); | ||
| 124479 | switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){ | 128990 | switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){ |
| 124480 | case 1: | 128991 | case 1: |
| 124481 | /* Convert from natural logarithm to log base 10 */ | 128992 | ans = log10(x); |
| 124482 | ans /= M_LN10; | ||
| 124483 | break; | 128993 | break; |
| 124484 | case 2: | 128994 | case 2: |
| 124485 | /* Convert from natural logarithm to log base 2 */ | 128995 | ans = log2(x); |
| 124486 | ans /= M_LN2; | ||
| 124487 | break; | 128996 | break; |
| 124488 | default: | 128997 | default: |
| 128998 | ans = log(x); | ||
| 124489 | break; | 128999 | break; |
| 124490 | } | 129000 | } |
| 124491 | } | 129001 | } |
| @@ -124554,6 +129064,7 @@ static void piFunc( | |||
| 124554 | sqlite3_value **argv | 129064 | sqlite3_value **argv |
| 124555 | ){ | 129065 | ){ |
| 124556 | assert( argc==0 ); | 129066 | assert( argc==0 ); |
| 129067 | (void)argv; | ||
| 124557 | sqlite3_result_double(context, M_PI); | 129068 | sqlite3_result_double(context, M_PI); |
| 124558 | } | 129069 | } |
| 124559 | 129070 | ||
| @@ -124577,6 +129088,37 @@ static void signFunc( | |||
| 124577 | sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); | 129088 | sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); |
| 124578 | } | 129089 | } |
| 124579 | 129090 | ||
| 129091 | #ifdef SQLITE_DEBUG | ||
| 129092 | /* | ||
| 129093 | ** Implementation of fpdecode(x,y,z) function. | ||
| 129094 | ** | ||
| 129095 | ** x is a real number that is to be decoded. y is the precision. | ||
| 129096 | ** z is the maximum real precision. | ||
| 129097 | */ | ||
| 129098 | static void fpdecodeFunc( | ||
| 129099 | sqlite3_context *context, | ||
| 129100 | int argc, | ||
| 129101 | sqlite3_value **argv | ||
| 129102 | ){ | ||
| 129103 | FpDecode s; | ||
| 129104 | double x; | ||
| 129105 | int y, z; | ||
| 129106 | char zBuf[100]; | ||
| 129107 | UNUSED_PARAMETER(argc); | ||
| 129108 | assert( argc==3 ); | ||
| 129109 | x = sqlite3_value_double(argv[0]); | ||
| 129110 | y = sqlite3_value_int(argv[1]); | ||
| 129111 | z = sqlite3_value_int(argv[2]); | ||
| 129112 | sqlite3FpDecode(&s, x, y, z); | ||
| 129113 | if( s.isSpecial==2 ){ | ||
| 129114 | sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); | ||
| 129115 | }else{ | ||
| 129116 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP); | ||
| 129117 | } | ||
| 129118 | sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); | ||
| 129119 | } | ||
| 129120 | #endif /* SQLITE_DEBUG */ | ||
| 129121 | |||
| 124580 | /* | 129122 | /* |
| 124581 | ** All of the FuncDef structures in the aBuiltinFunc[] array above | 129123 | ** All of the FuncDef structures in the aBuiltinFunc[] array above |
| 124582 | ** to the global function hash table. This occurs at start-time (as | 129124 | ** to the global function hash table. This occurs at start-time (as |
| @@ -124641,12 +129183,16 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ | |||
| 124641 | FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), | 129183 | FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), |
| 124642 | FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), | 129184 | FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), |
| 124643 | FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), | 129185 | FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), |
| 129186 | FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN), | ||
| 124644 | FUNCTION(instr, 2, 0, 0, instrFunc ), | 129187 | FUNCTION(instr, 2, 0, 0, instrFunc ), |
| 124645 | FUNCTION(printf, -1, 0, 0, printfFunc ), | 129188 | FUNCTION(printf, -1, 0, 0, printfFunc ), |
| 124646 | FUNCTION(format, -1, 0, 0, printfFunc ), | 129189 | FUNCTION(format, -1, 0, 0, printfFunc ), |
| 124647 | FUNCTION(unicode, 1, 0, 0, unicodeFunc ), | 129190 | FUNCTION(unicode, 1, 0, 0, unicodeFunc ), |
| 124648 | FUNCTION(char, -1, 0, 0, charFunc ), | 129191 | FUNCTION(char, -1, 0, 0, charFunc ), |
| 124649 | FUNCTION(abs, 1, 0, 0, absFunc ), | 129192 | FUNCTION(abs, 1, 0, 0, absFunc ), |
| 129193 | #ifdef SQLITE_DEBUG | ||
| 129194 | FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), | ||
| 129195 | #endif | ||
| 124650 | #ifndef SQLITE_OMIT_FLOATING_POINT | 129196 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 124651 | FUNCTION(round, 1, 0, 0, roundFunc ), | 129197 | FUNCTION(round, 1, 0, 0, roundFunc ), |
| 124652 | FUNCTION(round, 2, 0, 0, roundFunc ), | 129198 | FUNCTION(round, 2, 0, 0, roundFunc ), |
| @@ -124654,6 +129200,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ | |||
| 124654 | FUNCTION(upper, 1, 0, 0, upperFunc ), | 129200 | FUNCTION(upper, 1, 0, 0, upperFunc ), |
| 124655 | FUNCTION(lower, 1, 0, 0, lowerFunc ), | 129201 | FUNCTION(lower, 1, 0, 0, lowerFunc ), |
| 124656 | FUNCTION(hex, 1, 0, 0, hexFunc ), | 129202 | FUNCTION(hex, 1, 0, 0, hexFunc ), |
| 129203 | FUNCTION(unhex, 1, 0, 0, unhexFunc ), | ||
| 129204 | FUNCTION(unhex, 2, 0, 0, unhexFunc ), | ||
| 124657 | INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ), | 129205 | INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ), |
| 124658 | VFUNCTION(random, 0, 0, 0, randomFunc ), | 129206 | VFUNCTION(random, 0, 0, 0, randomFunc ), |
| 124659 | VFUNCTION(randomblob, 1, 0, 0, randomBlob ), | 129207 | VFUNCTION(randomblob, 1, 0, 0, randomBlob ), |
| @@ -126084,22 +130632,22 @@ static Trigger *fkActionTrigger( | |||
| 126084 | 130632 | ||
| 126085 | if( action==OE_Restrict ){ | 130633 | if( action==OE_Restrict ){ |
| 126086 | int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | 130634 | int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| 126087 | Token tFrom; | 130635 | SrcList *pSrc; |
| 126088 | Token tDb; | ||
| 126089 | Expr *pRaise; | 130636 | Expr *pRaise; |
| 126090 | 130637 | ||
| 126091 | tFrom.z = zFrom; | ||
| 126092 | tFrom.n = nFrom; | ||
| 126093 | tDb.z = db->aDb[iDb].zDbSName; | ||
| 126094 | tDb.n = sqlite3Strlen30(tDb.z); | ||
| 126095 | |||
| 126096 | pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); | 130638 | pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); |
| 126097 | if( pRaise ){ | 130639 | if( pRaise ){ |
| 126098 | pRaise->affExpr = OE_Abort; | 130640 | pRaise->affExpr = OE_Abort; |
| 126099 | } | 130641 | } |
| 130642 | pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); | ||
| 130643 | if( pSrc ){ | ||
| 130644 | assert( pSrc->nSrc==1 ); | ||
| 130645 | pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); | ||
| 130646 | pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); | ||
| 130647 | } | ||
| 126100 | pSelect = sqlite3SelectNew(pParse, | 130648 | pSelect = sqlite3SelectNew(pParse, |
| 126101 | sqlite3ExprListAppend(pParse, 0, pRaise), | 130649 | sqlite3ExprListAppend(pParse, 0, pRaise), |
| 126102 | sqlite3SrcListAppend(pParse, 0, &tDb, &tFrom), | 130650 | pSrc, |
| 126103 | pWhere, | 130651 | pWhere, |
| 126104 | 0, 0, 0, 0, 0 | 130652 | 0, 0, 0, 0, 0 |
| 126105 | ); | 130653 | ); |
| @@ -126206,17 +130754,17 @@ SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ | |||
| 126206 | FKey *pNext; /* Copy of pFKey->pNextFrom */ | 130754 | FKey *pNext; /* Copy of pFKey->pNextFrom */ |
| 126207 | 130755 | ||
| 126208 | assert( IsOrdinaryTable(pTab) ); | 130756 | assert( IsOrdinaryTable(pTab) ); |
| 130757 | assert( db!=0 ); | ||
| 126209 | for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){ | 130758 | for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){ |
| 126210 | assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); | 130759 | assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); |
| 126211 | 130760 | ||
| 126212 | /* Remove the FK from the fkeyHash hash table. */ | 130761 | /* Remove the FK from the fkeyHash hash table. */ |
| 126213 | if( !db || db->pnBytesFreed==0 ){ | 130762 | if( db->pnBytesFreed==0 ){ |
| 126214 | if( pFKey->pPrevTo ){ | 130763 | if( pFKey->pPrevTo ){ |
| 126215 | pFKey->pPrevTo->pNextTo = pFKey->pNextTo; | 130764 | pFKey->pPrevTo->pNextTo = pFKey->pNextTo; |
| 126216 | }else{ | 130765 | }else{ |
| 126217 | void *p = (void *)pFKey->pNextTo; | 130766 | const char *z = (pFKey->pNextTo ? pFKey->pNextTo->zTo : pFKey->zTo); |
| 126218 | const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); | 130767 | sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, pFKey->pNextTo); |
| 126219 | sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); | ||
| 126220 | } | 130768 | } |
| 126221 | if( pFKey->pNextTo ){ | 130769 | if( pFKey->pNextTo ){ |
| 126222 | pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; | 130770 | pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; |
| @@ -126279,8 +130827,10 @@ SQLITE_PRIVATE void sqlite3OpenTable( | |||
| 126279 | assert( pParse->pVdbe!=0 ); | 130827 | assert( pParse->pVdbe!=0 ); |
| 126280 | v = pParse->pVdbe; | 130828 | v = pParse->pVdbe; |
| 126281 | assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); | 130829 | assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); |
| 126282 | sqlite3TableLock(pParse, iDb, pTab->tnum, | 130830 | if( !pParse->db->noSharedCache ){ |
| 126283 | (opcode==OP_OpenWrite)?1:0, pTab->zName); | 130831 | sqlite3TableLock(pParse, iDb, pTab->tnum, |
| 130832 | (opcode==OP_OpenWrite)?1:0, pTab->zName); | ||
| 130833 | } | ||
| 126284 | if( HasRowid(pTab) ){ | 130834 | if( HasRowid(pTab) ){ |
| 126285 | sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); | 130835 | sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); |
| 126286 | VdbeComment((v, "%s", pTab->zName)); | 130836 | VdbeComment((v, "%s", pTab->zName)); |
| @@ -126314,43 +130864,68 @@ SQLITE_PRIVATE void sqlite3OpenTable( | |||
| 126314 | ** is managed along with the rest of the Index structure. It will be | 130864 | ** is managed along with the rest of the Index structure. It will be |
| 126315 | ** released when sqlite3DeleteIndex() is called. | 130865 | ** released when sqlite3DeleteIndex() is called. |
| 126316 | */ | 130866 | */ |
| 126317 | SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ | 130867 | static SQLITE_NOINLINE const char *computeIndexAffStr(sqlite3 *db, Index *pIdx){ |
| 130868 | /* The first time a column affinity string for a particular index is | ||
| 130869 | ** required, it is allocated and populated here. It is then stored as | ||
| 130870 | ** a member of the Index structure for subsequent use. | ||
| 130871 | ** | ||
| 130872 | ** The column affinity string will eventually be deleted by | ||
| 130873 | ** sqliteDeleteIndex() when the Index structure itself is cleaned | ||
| 130874 | ** up. | ||
| 130875 | */ | ||
| 130876 | int n; | ||
| 130877 | Table *pTab = pIdx->pTable; | ||
| 130878 | pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); | ||
| 126318 | if( !pIdx->zColAff ){ | 130879 | if( !pIdx->zColAff ){ |
| 126319 | /* The first time a column affinity string for a particular index is | 130880 | sqlite3OomFault(db); |
| 126320 | ** required, it is allocated and populated here. It is then stored as | 130881 | return 0; |
| 126321 | ** a member of the Index structure for subsequent use. | 130882 | } |
| 126322 | ** | 130883 | for(n=0; n<pIdx->nColumn; n++){ |
| 126323 | ** The column affinity string will eventually be deleted by | 130884 | i16 x = pIdx->aiColumn[n]; |
| 126324 | ** sqliteDeleteIndex() when the Index structure itself is cleaned | 130885 | char aff; |
| 126325 | ** up. | 130886 | if( x>=0 ){ |
| 126326 | */ | 130887 | aff = pTab->aCol[x].affinity; |
| 126327 | int n; | 130888 | }else if( x==XN_ROWID ){ |
| 126328 | Table *pTab = pIdx->pTable; | 130889 | aff = SQLITE_AFF_INTEGER; |
| 126329 | pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); | 130890 | }else{ |
| 126330 | if( !pIdx->zColAff ){ | 130891 | assert( x==XN_EXPR ); |
| 126331 | sqlite3OomFault(db); | 130892 | assert( pIdx->bHasExpr ); |
| 126332 | return 0; | 130893 | assert( pIdx->aColExpr!=0 ); |
| 130894 | aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); | ||
| 126333 | } | 130895 | } |
| 126334 | for(n=0; n<pIdx->nColumn; n++){ | 130896 | if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB; |
| 126335 | i16 x = pIdx->aiColumn[n]; | 130897 | if( aff>SQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; |
| 126336 | char aff; | 130898 | pIdx->zColAff[n] = aff; |
| 126337 | if( x>=0 ){ | 130899 | } |
| 126338 | aff = pTab->aCol[x].affinity; | 130900 | pIdx->zColAff[n] = 0; |
| 126339 | }else if( x==XN_ROWID ){ | 130901 | return pIdx->zColAff; |
| 126340 | aff = SQLITE_AFF_INTEGER; | 130902 | } |
| 126341 | }else{ | 130903 | SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ |
| 126342 | assert( x==XN_EXPR ); | 130904 | if( !pIdx->zColAff ) return computeIndexAffStr(db, pIdx); |
| 126343 | assert( pIdx->aColExpr!=0 ); | 130905 | return pIdx->zColAff; |
| 126344 | aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); | 130906 | } |
| 130907 | |||
| 130908 | |||
| 130909 | /* | ||
| 130910 | ** Compute an affinity string for a table. Space is obtained | ||
| 130911 | ** from sqlite3DbMalloc(). The caller is responsible for freeing | ||
| 130912 | ** the space when done. | ||
| 130913 | */ | ||
| 130914 | SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3 *db, const Table *pTab){ | ||
| 130915 | char *zColAff; | ||
| 130916 | zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1); | ||
| 130917 | if( zColAff ){ | ||
| 130918 | int i, j; | ||
| 130919 | for(i=j=0; i<pTab->nCol; i++){ | ||
| 130920 | if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ | ||
| 130921 | zColAff[j++] = pTab->aCol[i].affinity; | ||
| 126345 | } | 130922 | } |
| 126346 | if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB; | ||
| 126347 | if( aff>SQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; | ||
| 126348 | pIdx->zColAff[n] = aff; | ||
| 126349 | } | 130923 | } |
| 126350 | pIdx->zColAff[n] = 0; | 130924 | do{ |
| 130925 | zColAff[j--] = 0; | ||
| 130926 | }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); | ||
| 126351 | } | 130927 | } |
| 126352 | 130928 | return zColAff; | |
| 126353 | return pIdx->zColAff; | ||
| 126354 | } | 130929 | } |
| 126355 | 130930 | ||
| 126356 | /* | 130931 | /* |
| @@ -126384,7 +130959,7 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ | |||
| 126384 | ** For STRICT tables: | 130959 | ** For STRICT tables: |
| 126385 | ** ------------------ | 130960 | ** ------------------ |
| 126386 | ** | 130961 | ** |
| 126387 | ** Generate an appropropriate OP_TypeCheck opcode that will verify the | 130962 | ** Generate an appropriate OP_TypeCheck opcode that will verify the |
| 126388 | ** datatypes against the column definitions in pTab. If iReg==0, that | 130963 | ** datatypes against the column definitions in pTab. If iReg==0, that |
| 126389 | ** means an OP_MakeRecord opcode has already been generated and should be | 130964 | ** means an OP_MakeRecord opcode has already been generated and should be |
| 126390 | ** the last opcode generated. The new OP_TypeCheck needs to be inserted | 130965 | ** the last opcode generated. The new OP_TypeCheck needs to be inserted |
| @@ -126394,7 +130969,7 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ | |||
| 126394 | ** Apply the type checking to that array of registers. | 130969 | ** Apply the type checking to that array of registers. |
| 126395 | */ | 130970 | */ |
| 126396 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ | 130971 | SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ |
| 126397 | int i, j; | 130972 | int i; |
| 126398 | char *zColAff; | 130973 | char *zColAff; |
| 126399 | if( pTab->tabFlags & TF_Strict ){ | 130974 | if( pTab->tabFlags & TF_Strict ){ |
| 126400 | if( iReg==0 ){ | 130975 | if( iReg==0 ){ |
| @@ -126403,7 +130978,7 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ | |||
| 126403 | ** OP_MakeRecord is found */ | 130978 | ** OP_MakeRecord is found */ |
| 126404 | VdbeOp *pPrev; | 130979 | VdbeOp *pPrev; |
| 126405 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); | 130980 | sqlite3VdbeAppendP4(v, pTab, P4_TABLE); |
| 126406 | pPrev = sqlite3VdbeGetOp(v, -1); | 130981 | pPrev = sqlite3VdbeGetLastOp(v); |
| 126407 | assert( pPrev!=0 ); | 130982 | assert( pPrev!=0 ); |
| 126408 | assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); | 130983 | assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); |
| 126409 | pPrev->opcode = OP_TypeCheck; | 130984 | pPrev->opcode = OP_TypeCheck; |
| @@ -126417,22 +130992,11 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ | |||
| 126417 | } | 130992 | } |
| 126418 | zColAff = pTab->zColAff; | 130993 | zColAff = pTab->zColAff; |
| 126419 | if( zColAff==0 ){ | 130994 | if( zColAff==0 ){ |
| 126420 | sqlite3 *db = sqlite3VdbeDb(v); | 130995 | zColAff = sqlite3TableAffinityStr(0, pTab); |
| 126421 | zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); | ||
| 126422 | if( !zColAff ){ | 130996 | if( !zColAff ){ |
| 126423 | sqlite3OomFault(db); | 130997 | sqlite3OomFault(sqlite3VdbeDb(v)); |
| 126424 | return; | 130998 | return; |
| 126425 | } | 130999 | } |
| 126426 | |||
| 126427 | for(i=j=0; i<pTab->nCol; i++){ | ||
| 126428 | assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 ); | ||
| 126429 | if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ | ||
| 126430 | zColAff[j++] = pTab->aCol[i].affinity; | ||
| 126431 | } | ||
| 126432 | } | ||
| 126433 | do{ | ||
| 126434 | zColAff[j--] = 0; | ||
| 126435 | }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); | ||
| 126436 | pTab->zColAff = zColAff; | 131000 | pTab->zColAff = zColAff; |
| 126437 | } | 131001 | } |
| 126438 | assert( zColAff!=0 ); | 131002 | assert( zColAff!=0 ); |
| @@ -126441,7 +131005,7 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ | |||
| 126441 | if( iReg ){ | 131005 | if( iReg ){ |
| 126442 | sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); | 131006 | sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); |
| 126443 | }else{ | 131007 | }else{ |
| 126444 | assert( sqlite3VdbeGetOp(v, -1)->opcode==OP_MakeRecord | 131008 | assert( sqlite3VdbeGetLastOp(v)->opcode==OP_MakeRecord |
| 126445 | || sqlite3VdbeDb(v)->mallocFailed ); | 131009 | || sqlite3VdbeDb(v)->mallocFailed ); |
| 126446 | sqlite3VdbeChangeP4(v, -1, zColAff, i); | 131010 | sqlite3VdbeChangeP4(v, -1, zColAff, i); |
| 126447 | } | 131011 | } |
| @@ -126527,7 +131091,7 @@ SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns( | |||
| 126527 | */ | 131091 | */ |
| 126528 | sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); | 131092 | sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); |
| 126529 | if( (pTab->tabFlags & TF_HasStored)!=0 ){ | 131093 | if( (pTab->tabFlags & TF_HasStored)!=0 ){ |
| 126530 | pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); | 131094 | pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); |
| 126531 | if( pOp->opcode==OP_Affinity ){ | 131095 | if( pOp->opcode==OP_Affinity ){ |
| 126532 | /* Change the OP_Affinity argument to '@' (NONE) for all stored | 131096 | /* Change the OP_Affinity argument to '@' (NONE) for all stored |
| 126533 | ** columns. '@' is the no-op affinity and those columns have not | 131097 | ** columns. '@' is the no-op affinity and those columns have not |
| @@ -127026,7 +131590,7 @@ SQLITE_PRIVATE void sqlite3Insert( | |||
| 127026 | 131590 | ||
| 127027 | /* Cannot insert into a read-only table. | 131591 | /* Cannot insert into a read-only table. |
| 127028 | */ | 131592 | */ |
| 127029 | if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ | 131593 | if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ |
| 127030 | goto insert_cleanup; | 131594 | goto insert_cleanup; |
| 127031 | } | 131595 | } |
| 127032 | 131596 | ||
| @@ -127433,7 +131997,12 @@ SQLITE_PRIVATE void sqlite3Insert( | |||
| 127433 | sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); | 131997 | sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); |
| 127434 | } | 131998 | } |
| 127435 | }else{ | 131999 | }else{ |
| 127436 | sqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore); | 132000 | Expr *pX = pList->a[k].pExpr; |
| 132001 | int y = sqlite3ExprCodeTarget(pParse, pX, iRegStore); | ||
| 132002 | if( y!=iRegStore ){ | ||
| 132003 | sqlite3VdbeAddOp2(v, | ||
| 132004 | ExprHasProperty(pX, EP_Subquery) ? OP_Copy : OP_SCopy, y, iRegStore); | ||
| 132005 | } | ||
| 127437 | } | 132006 | } |
| 127438 | } | 132007 | } |
| 127439 | 132008 | ||
| @@ -127468,7 +132037,7 @@ SQLITE_PRIVATE void sqlite3Insert( | |||
| 127468 | } | 132037 | } |
| 127469 | 132038 | ||
| 127470 | /* Copy the new data already generated. */ | 132039 | /* Copy the new data already generated. */ |
| 127471 | assert( pTab->nNVCol>0 ); | 132040 | assert( pTab->nNVCol>0 || pParse->nErr>0 ); |
| 127472 | sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); | 132041 | sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); |
| 127473 | 132042 | ||
| 127474 | #ifndef SQLITE_OMIT_GENERATED_COLUMNS | 132043 | #ifndef SQLITE_OMIT_GENERATED_COLUMNS |
| @@ -127570,7 +132139,9 @@ SQLITE_PRIVATE void sqlite3Insert( | |||
| 127570 | sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, | 132139 | sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, |
| 127571 | regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert | 132140 | regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert |
| 127572 | ); | 132141 | ); |
| 127573 | sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); | 132142 | if( db->flags & SQLITE_ForeignKeys ){ |
| 132143 | sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); | ||
| 132144 | } | ||
| 127574 | 132145 | ||
| 127575 | /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE | 132146 | /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE |
| 127576 | ** constraints or (b) there are no triggers and this table is not a | 132147 | ** constraints or (b) there are no triggers and this table is not a |
| @@ -127654,7 +132225,7 @@ insert_cleanup: | |||
| 127654 | sqlite3UpsertDelete(db, pUpsert); | 132225 | sqlite3UpsertDelete(db, pUpsert); |
| 127655 | sqlite3SelectDelete(db, pSelect); | 132226 | sqlite3SelectDelete(db, pSelect); |
| 127656 | sqlite3IdListDelete(db, pColumn); | 132227 | sqlite3IdListDelete(db, pColumn); |
| 127657 | sqlite3DbFree(db, aRegIdx); | 132228 | if( aRegIdx ) sqlite3DbNNFreeNN(db, aRegIdx); |
| 127658 | } | 132229 | } |
| 127659 | 132230 | ||
| 127660 | /* Make sure "isView" and other macros defined above are undefined. Otherwise | 132231 | /* Make sure "isView" and other macros defined above are undefined. Otherwise |
| @@ -127680,7 +132251,7 @@ insert_cleanup: | |||
| 127680 | /* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). | 132251 | /* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). |
| 127681 | * Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this | 132252 | * Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this |
| 127682 | ** expression node references any of the | 132253 | ** expression node references any of the |
| 127683 | ** columns that are being modifed by an UPDATE statement. | 132254 | ** columns that are being modified by an UPDATE statement. |
| 127684 | */ | 132255 | */ |
| 127685 | static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ | 132256 | static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ |
| 127686 | if( pExpr->op==TK_COLUMN ){ | 132257 | if( pExpr->op==TK_COLUMN ){ |
| @@ -127903,7 +132474,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( | |||
| 127903 | int *aiChng, /* column i is unchanged if aiChng[i]<0 */ | 132474 | int *aiChng, /* column i is unchanged if aiChng[i]<0 */ |
| 127904 | Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ | 132475 | Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ |
| 127905 | ){ | 132476 | ){ |
| 127906 | Vdbe *v; /* VDBE under constrution */ | 132477 | Vdbe *v; /* VDBE under construction */ |
| 127907 | Index *pIdx; /* Pointer to one of the indices */ | 132478 | Index *pIdx; /* Pointer to one of the indices */ |
| 127908 | Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ | 132479 | Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ |
| 127909 | sqlite3 *db; /* Database connection */ | 132480 | sqlite3 *db; /* Database connection */ |
| @@ -128018,6 +132589,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( | |||
| 128018 | case OE_Fail: { | 132589 | case OE_Fail: { |
| 128019 | char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, | 132590 | char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, |
| 128020 | pCol->zCnName); | 132591 | pCol->zCnName); |
| 132592 | testcase( zMsg==0 && db->mallocFailed==0 ); | ||
| 128021 | sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, | 132593 | sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, |
| 128022 | onError, iReg); | 132594 | onError, iReg); |
| 128023 | sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); | 132595 | sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); |
| @@ -128385,7 +132957,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( | |||
| 128385 | pIdx; | 132957 | pIdx; |
| 128386 | pIdx = indexIteratorNext(&sIdxIter, &ix) | 132958 | pIdx = indexIteratorNext(&sIdxIter, &ix) |
| 128387 | ){ | 132959 | ){ |
| 128388 | int regIdx; /* Range of registers hold conent for pIdx */ | 132960 | int regIdx; /* Range of registers holding content for pIdx */ |
| 128389 | int regR; /* Range of registers holding conflicting PK */ | 132961 | int regR; /* Range of registers holding conflicting PK */ |
| 128390 | int iThisCur; /* Cursor for this UNIQUE index */ | 132962 | int iThisCur; /* Cursor for this UNIQUE index */ |
| 128391 | int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ | 132963 | int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ |
| @@ -128880,6 +133452,8 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices( | |||
| 128880 | 133452 | ||
| 128881 | assert( op==OP_OpenRead || op==OP_OpenWrite ); | 133453 | assert( op==OP_OpenRead || op==OP_OpenWrite ); |
| 128882 | assert( op==OP_OpenWrite || p5==0 ); | 133454 | assert( op==OP_OpenWrite || p5==0 ); |
| 133455 | assert( piDataCur!=0 ); | ||
| 133456 | assert( piIdxCur!=0 ); | ||
| 128883 | if( IsVirtual(pTab) ){ | 133457 | if( IsVirtual(pTab) ){ |
| 128884 | /* This routine is a no-op for virtual tables. Leave the output | 133458 | /* This routine is a no-op for virtual tables. Leave the output |
| 128885 | ** variables *piDataCur and *piIdxCur set to illegal cursor numbers | 133459 | ** variables *piDataCur and *piIdxCur set to illegal cursor numbers |
| @@ -128892,18 +133466,18 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices( | |||
| 128892 | assert( v!=0 ); | 133466 | assert( v!=0 ); |
| 128893 | if( iBase<0 ) iBase = pParse->nTab; | 133467 | if( iBase<0 ) iBase = pParse->nTab; |
| 128894 | iDataCur = iBase++; | 133468 | iDataCur = iBase++; |
| 128895 | if( piDataCur ) *piDataCur = iDataCur; | 133469 | *piDataCur = iDataCur; |
| 128896 | if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ | 133470 | if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ |
| 128897 | sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); | 133471 | sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); |
| 128898 | }else{ | 133472 | }else if( pParse->db->noSharedCache==0 ){ |
| 128899 | sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); | 133473 | sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); |
| 128900 | } | 133474 | } |
| 128901 | if( piIdxCur ) *piIdxCur = iBase; | 133475 | *piIdxCur = iBase; |
| 128902 | for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ | 133476 | for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ |
| 128903 | int iIdxCur = iBase++; | 133477 | int iIdxCur = iBase++; |
| 128904 | assert( pIdx->pSchema==pTab->pSchema ); | 133478 | assert( pIdx->pSchema==pTab->pSchema ); |
| 128905 | if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ | 133479 | if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ |
| 128906 | if( piDataCur ) *piDataCur = iIdxCur; | 133480 | *piDataCur = iIdxCur; |
| 128907 | p5 = 0; | 133481 | p5 = 0; |
| 128908 | } | 133482 | } |
| 128909 | if( aToOpen==0 || aToOpen[i+1] ){ | 133483 | if( aToOpen==0 || aToOpen[i+1] ){ |
| @@ -129201,7 +133775,7 @@ static int xferOptimization( | |||
| 129201 | } | 133775 | } |
| 129202 | #endif | 133776 | #endif |
| 129203 | #ifndef SQLITE_OMIT_FOREIGN_KEY | 133777 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 129204 | /* Disallow the transfer optimization if the destination table constains | 133778 | /* Disallow the transfer optimization if the destination table contains |
| 129205 | ** any foreign key constraints. This is more restrictive than necessary. | 133779 | ** any foreign key constraints. This is more restrictive than necessary. |
| 129206 | ** But the main beneficiary of the transfer optimization is the VACUUM | 133780 | ** But the main beneficiary of the transfer optimization is the VACUUM |
| 129207 | ** command, and the VACUUM command disables foreign key constraints. So | 133781 | ** command, and the VACUUM command disables foreign key constraints. So |
| @@ -129881,9 +134455,9 @@ struct sqlite3_api_routines { | |||
| 129881 | const char *(*filename_journal)(const char*); | 134455 | const char *(*filename_journal)(const char*); |
| 129882 | const char *(*filename_wal)(const char*); | 134456 | const char *(*filename_wal)(const char*); |
| 129883 | /* Version 3.32.0 and later */ | 134457 | /* Version 3.32.0 and later */ |
| 129884 | char *(*create_filename)(const char*,const char*,const char*, | 134458 | const char *(*create_filename)(const char*,const char*,const char*, |
| 129885 | int,const char**); | 134459 | int,const char**); |
| 129886 | void (*free_filename)(char*); | 134460 | void (*free_filename)(const char*); |
| 129887 | sqlite3_file *(*database_file_object)(const char*); | 134461 | sqlite3_file *(*database_file_object)(const char*); |
| 129888 | /* Version 3.34.0 and later */ | 134462 | /* Version 3.34.0 and later */ |
| 129889 | int (*txn_state)(sqlite3*,const char*); | 134463 | int (*txn_state)(sqlite3*,const char*); |
| @@ -129907,6 +134481,12 @@ struct sqlite3_api_routines { | |||
| 129907 | unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, | 134481 | unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, |
| 129908 | unsigned int); | 134482 | unsigned int); |
| 129909 | const char *(*db_name)(sqlite3*,int); | 134483 | const char *(*db_name)(sqlite3*,int); |
| 134484 | /* Version 3.40.0 and later */ | ||
| 134485 | int (*value_encoding)(sqlite3_value*); | ||
| 134486 | /* Version 3.41.0 and later */ | ||
| 134487 | int (*is_interrupted)(sqlite3*); | ||
| 134488 | /* Version 3.43.0 and later */ | ||
| 134489 | int (*stmt_explain)(sqlite3_stmt*,int); | ||
| 129910 | }; | 134490 | }; |
| 129911 | 134491 | ||
| 129912 | /* | 134492 | /* |
| @@ -130231,6 +134811,12 @@ typedef int (*sqlite3_loadext_entry)( | |||
| 130231 | #define sqlite3_serialize sqlite3_api->serialize | 134811 | #define sqlite3_serialize sqlite3_api->serialize |
| 130232 | #endif | 134812 | #endif |
| 130233 | #define sqlite3_db_name sqlite3_api->db_name | 134813 | #define sqlite3_db_name sqlite3_api->db_name |
| 134814 | /* Version 3.40.0 and later */ | ||
| 134815 | #define sqlite3_value_encoding sqlite3_api->value_encoding | ||
| 134816 | /* Version 3.41.0 and later */ | ||
| 134817 | #define sqlite3_is_interrupted sqlite3_api->is_interrupted | ||
| 134818 | /* Version 3.43.0 and later */ | ||
| 134819 | #define sqlite3_stmt_explain sqlite3_api->stmt_explain | ||
| 130234 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ | 134820 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 130235 | 134821 | ||
| 130236 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) | 134822 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| @@ -130743,7 +135329,13 @@ static const sqlite3_api_routines sqlite3Apis = { | |||
| 130743 | 0, | 135329 | 0, |
| 130744 | 0, | 135330 | 0, |
| 130745 | #endif | 135331 | #endif |
| 130746 | sqlite3_db_name | 135332 | sqlite3_db_name, |
| 135333 | /* Version 3.40.0 and later */ | ||
| 135334 | sqlite3_value_encoding, | ||
| 135335 | /* Version 3.41.0 and later */ | ||
| 135336 | sqlite3_is_interrupted, | ||
| 135337 | /* Version 3.43.0 and later */ | ||
| 135338 | sqlite3_stmt_explain | ||
| 130747 | }; | 135339 | }; |
| 130748 | 135340 | ||
| 130749 | /* True if x is the directory separator character | 135341 | /* True if x is the directory separator character |
| @@ -130816,15 +135408,25 @@ static int sqlite3LoadExtension( | |||
| 130816 | /* tag-20210611-1. Some dlopen() implementations will segfault if given | 135408 | /* tag-20210611-1. Some dlopen() implementations will segfault if given |
| 130817 | ** an oversize filename. Most filesystems have a pathname limit of 4K, | 135409 | ** an oversize filename. Most filesystems have a pathname limit of 4K, |
| 130818 | ** so limit the extension filename length to about twice that. | 135410 | ** so limit the extension filename length to about twice that. |
| 130819 | ** https://sqlite.org/forum/forumpost/08a0d6d9bf */ | 135411 | ** https://sqlite.org/forum/forumpost/08a0d6d9bf |
| 135412 | ** | ||
| 135413 | ** Later (2023-03-25): Save an extra 6 bytes for the filename suffix. | ||
| 135414 | ** See https://sqlite.org/forum/forumpost/24083b579d. | ||
| 135415 | */ | ||
| 130820 | if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found; | 135416 | if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found; |
| 130821 | 135417 | ||
| 135418 | /* Do not allow sqlite3_load_extension() to link to a copy of the | ||
| 135419 | ** running application, by passing in an empty filename. */ | ||
| 135420 | if( nMsg==0 ) goto extension_not_found; | ||
| 135421 | |||
| 130822 | handle = sqlite3OsDlOpen(pVfs, zFile); | 135422 | handle = sqlite3OsDlOpen(pVfs, zFile); |
| 130823 | #if SQLITE_OS_UNIX || SQLITE_OS_WIN | 135423 | #if SQLITE_OS_UNIX || SQLITE_OS_WIN |
| 130824 | for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){ | 135424 | for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){ |
| 130825 | char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]); | 135425 | char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]); |
| 130826 | if( zAltFile==0 ) return SQLITE_NOMEM_BKPT; | 135426 | if( zAltFile==0 ) return SQLITE_NOMEM_BKPT; |
| 130827 | handle = sqlite3OsDlOpen(pVfs, zAltFile); | 135427 | if( nMsg+strlen(azEndings[ii])+1<=SQLITE_MAX_PATHLEN ){ |
| 135428 | handle = sqlite3OsDlOpen(pVfs, zAltFile); | ||
| 135429 | } | ||
| 130828 | sqlite3_free(zAltFile); | 135430 | sqlite3_free(zAltFile); |
| 130829 | } | 135431 | } |
| 130830 | #endif | 135432 | #endif |
| @@ -132649,7 +137251,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 132649 | ** | 137251 | ** |
| 132650 | ** The first form reports the current local setting for the | 137252 | ** The first form reports the current local setting for the |
| 132651 | ** page cache spill size. The second form turns cache spill on | 137253 | ** page cache spill size. The second form turns cache spill on |
| 132652 | ** or off. When turnning cache spill on, the size is set to the | 137254 | ** or off. When turning cache spill on, the size is set to the |
| 132653 | ** current cache_size. The third form sets a spill size that | 137255 | ** current cache_size. The third form sets a spill size that |
| 132654 | ** may be different form the cache size. | 137256 | ** may be different form the cache size. |
| 132655 | ** If N is positive then that is the | 137257 | ** If N is positive then that is the |
| @@ -133319,7 +137921,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133319 | zDb = db->aDb[iDb].zDbSName; | 137921 | zDb = db->aDb[iDb].zDbSName; |
| 133320 | sqlite3CodeVerifySchema(pParse, iDb); | 137922 | sqlite3CodeVerifySchema(pParse, iDb); |
| 133321 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); | 137923 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 133322 | if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; | 137924 | sqlite3TouchRegister(pParse, pTab->nCol+regRow); |
| 133323 | sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); | 137925 | sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); |
| 133324 | sqlite3VdbeLoadString(v, regResult, pTab->zName); | 137926 | sqlite3VdbeLoadString(v, regResult, pTab->zName); |
| 133325 | assert( IsOrdinaryTable(pTab) ); | 137927 | assert( IsOrdinaryTable(pTab) ); |
| @@ -133360,7 +137962,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133360 | ** regRow..regRow+n. If any of the child key values are NULL, this | 137962 | ** regRow..regRow+n. If any of the child key values are NULL, this |
| 133361 | ** row cannot cause an FK violation. Jump directly to addrOk in | 137963 | ** row cannot cause an FK violation. Jump directly to addrOk in |
| 133362 | ** this case. */ | 137964 | ** this case. */ |
| 133363 | if( regRow+pFK->nCol>pParse->nMem ) pParse->nMem = regRow+pFK->nCol; | 137965 | sqlite3TouchRegister(pParse, regRow + pFK->nCol); |
| 133364 | for(j=0; j<pFK->nCol; j++){ | 137966 | for(j=0; j<pFK->nCol; j++){ |
| 133365 | int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; | 137967 | int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; |
| 133366 | sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); | 137968 | sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); |
| @@ -133427,9 +138029,9 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133427 | ** The "quick_check" is reduced version of | 138029 | ** The "quick_check" is reduced version of |
| 133428 | ** integrity_check designed to detect most database corruption | 138030 | ** integrity_check designed to detect most database corruption |
| 133429 | ** without the overhead of cross-checking indexes. Quick_check | 138031 | ** without the overhead of cross-checking indexes. Quick_check |
| 133430 | ** is linear time wherease integrity_check is O(NlogN). | 138032 | ** is linear time whereas integrity_check is O(NlogN). |
| 133431 | ** | 138033 | ** |
| 133432 | ** The maximum nubmer of errors is 100 by default. A different default | 138034 | ** The maximum number of errors is 100 by default. A different default |
| 133433 | ** can be specified using a numeric parameter N. | 138035 | ** can be specified using a numeric parameter N. |
| 133434 | ** | 138036 | ** |
| 133435 | ** Or, the parameter N can be the name of a table. In that case, only | 138037 | ** Or, the parameter N can be the name of a table. In that case, only |
| @@ -133489,6 +138091,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133489 | if( iDb>=0 && i!=iDb ) continue; | 138091 | if( iDb>=0 && i!=iDb ) continue; |
| 133490 | 138092 | ||
| 133491 | sqlite3CodeVerifySchema(pParse, i); | 138093 | sqlite3CodeVerifySchema(pParse, i); |
| 138094 | pParse->okConstFactor = 0; /* tag-20230327-1 */ | ||
| 133492 | 138095 | ||
| 133493 | /* Do an integrity check of the B-Tree | 138096 | /* Do an integrity check of the B-Tree |
| 133494 | ** | 138097 | ** |
| @@ -133524,7 +138127,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133524 | aRoot[0] = cnt; | 138127 | aRoot[0] = cnt; |
| 133525 | 138128 | ||
| 133526 | /* Make sure sufficient number of registers have been allocated */ | 138129 | /* Make sure sufficient number of registers have been allocated */ |
| 133527 | pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); | 138130 | sqlite3TouchRegister(pParse, 8+mxIdx); |
| 133528 | sqlite3ClearTempRegCache(pParse); | 138131 | sqlite3ClearTempRegCache(pParse); |
| 133529 | 138132 | ||
| 133530 | /* Do the b-tree integrity checks */ | 138133 | /* Do the b-tree integrity checks */ |
| @@ -133543,15 +138146,24 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133543 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ | 138146 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ |
| 133544 | Table *pTab = sqliteHashData(x); | 138147 | Table *pTab = sqliteHashData(x); |
| 133545 | Index *pIdx, *pPk; | 138148 | Index *pIdx, *pPk; |
| 133546 | Index *pPrior = 0; | 138149 | Index *pPrior = 0; /* Previous index */ |
| 133547 | int loopTop; | 138150 | int loopTop; |
| 133548 | int iDataCur, iIdxCur; | 138151 | int iDataCur, iIdxCur; |
| 133549 | int r1 = -1; | 138152 | int r1 = -1; |
| 133550 | int bStrict; | 138153 | int bStrict; /* True for a STRICT table */ |
| 138154 | int r2; /* Previous key for WITHOUT ROWID tables */ | ||
| 138155 | int mxCol; /* Maximum non-virtual column number */ | ||
| 133551 | 138156 | ||
| 133552 | if( !IsOrdinaryTable(pTab) ) continue; | 138157 | if( !IsOrdinaryTable(pTab) ) continue; |
| 133553 | if( pObjTab && pObjTab!=pTab ) continue; | 138158 | if( pObjTab && pObjTab!=pTab ) continue; |
| 133554 | pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); | 138159 | if( isQuick || HasRowid(pTab) ){ |
| 138160 | pPk = 0; | ||
| 138161 | r2 = 0; | ||
| 138162 | }else{ | ||
| 138163 | pPk = sqlite3PrimaryKeyIndex(pTab); | ||
| 138164 | r2 = sqlite3GetTempRange(pParse, pPk->nKeyCol); | ||
| 138165 | sqlite3VdbeAddOp3(v, OP_Null, 1, r2, r2+pPk->nKeyCol-1); | ||
| 138166 | } | ||
| 133555 | sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, | 138167 | sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, |
| 133556 | 1, 0, &iDataCur, &iIdxCur); | 138168 | 1, 0, &iDataCur, &iIdxCur); |
| 133557 | /* reg[7] counts the number of entries in the table. | 138169 | /* reg[7] counts the number of entries in the table. |
| @@ -133565,52 +138177,180 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133565 | assert( sqlite3NoTempsInRange(pParse,1,7+j) ); | 138177 | assert( sqlite3NoTempsInRange(pParse,1,7+j) ); |
| 133566 | sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); | 138178 | sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); |
| 133567 | loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); | 138179 | loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); |
| 138180 | |||
| 138181 | /* Fetch the right-most column from the table. This will cause | ||
| 138182 | ** the entire record header to be parsed and sanity checked. It | ||
| 138183 | ** will also prepopulate the cursor column cache that is used | ||
| 138184 | ** by the OP_IsType code, so it is a required step. | ||
| 138185 | */ | ||
| 138186 | assert( !IsVirtual(pTab) ); | ||
| 138187 | if( HasRowid(pTab) ){ | ||
| 138188 | mxCol = -1; | ||
| 138189 | for(j=0; j<pTab->nCol; j++){ | ||
| 138190 | if( (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)==0 ) mxCol++; | ||
| 138191 | } | ||
| 138192 | if( mxCol==pTab->iPKey ) mxCol--; | ||
| 138193 | }else{ | ||
| 138194 | /* COLFLAG_VIRTUAL columns are not included in the WITHOUT ROWID | ||
| 138195 | ** PK index column-count, so there is no need to account for them | ||
| 138196 | ** in this case. */ | ||
| 138197 | mxCol = sqlite3PrimaryKeyIndex(pTab)->nColumn-1; | ||
| 138198 | } | ||
| 138199 | if( mxCol>=0 ){ | ||
| 138200 | sqlite3VdbeAddOp3(v, OP_Column, iDataCur, mxCol, 3); | ||
| 138201 | sqlite3VdbeTypeofColumn(v, 3); | ||
| 138202 | } | ||
| 138203 | |||
| 133568 | if( !isQuick ){ | 138204 | if( !isQuick ){ |
| 133569 | /* Sanity check on record header decoding */ | 138205 | if( pPk ){ |
| 133570 | sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3); | 138206 | /* Verify WITHOUT ROWID keys are in ascending order */ |
| 133571 | sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); | 138207 | int a1; |
| 133572 | VdbeComment((v, "(right-most column)")); | 138208 | char *zErr; |
| 138209 | a1 = sqlite3VdbeAddOp4Int(v, OP_IdxGT, iDataCur, 0,r2,pPk->nKeyCol); | ||
| 138210 | VdbeCoverage(v); | ||
| 138211 | sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); | ||
| 138212 | zErr = sqlite3MPrintf(db, | ||
| 138213 | "row not in PRIMARY KEY order for %s", | ||
| 138214 | pTab->zName); | ||
| 138215 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); | ||
| 138216 | integrityCheckResultRow(v); | ||
| 138217 | sqlite3VdbeJumpHere(v, a1); | ||
| 138218 | sqlite3VdbeJumpHere(v, a1+1); | ||
| 138219 | for(j=0; j<pPk->nKeyCol; j++){ | ||
| 138220 | sqlite3ExprCodeLoadIndexColumn(pParse, pPk, iDataCur, j, r2+j); | ||
| 138221 | } | ||
| 138222 | } | ||
| 133573 | } | 138223 | } |
| 133574 | /* Verify that all NOT NULL columns really are NOT NULL. At the | 138224 | /* Verify datatypes for all columns: |
| 133575 | ** same time verify the type of the content of STRICT tables */ | 138225 | ** |
| 138226 | ** (1) NOT NULL columns may not contain a NULL | ||
| 138227 | ** (2) Datatype must be exact for non-ANY columns in STRICT tables | ||
| 138228 | ** (3) Datatype for TEXT columns in non-STRICT tables must be | ||
| 138229 | ** NULL, TEXT, or BLOB. | ||
| 138230 | ** (4) Datatype for numeric columns in non-STRICT tables must not | ||
| 138231 | ** be a TEXT value that can be losslessly converted to numeric. | ||
| 138232 | */ | ||
| 133576 | bStrict = (pTab->tabFlags & TF_Strict)!=0; | 138233 | bStrict = (pTab->tabFlags & TF_Strict)!=0; |
| 133577 | for(j=0; j<pTab->nCol; j++){ | 138234 | for(j=0; j<pTab->nCol; j++){ |
| 133578 | char *zErr; | 138235 | char *zErr; |
| 133579 | Column *pCol = pTab->aCol + j; | 138236 | Column *pCol = pTab->aCol + j; /* The column to be checked */ |
| 133580 | int doError, jmp2; | 138237 | int labelError; /* Jump here to report an error */ |
| 138238 | int labelOk; /* Jump here if all looks ok */ | ||
| 138239 | int p1, p3, p4; /* Operands to the OP_IsType opcode */ | ||
| 138240 | int doTypeCheck; /* Check datatypes (besides NOT NULL) */ | ||
| 138241 | |||
| 133581 | if( j==pTab->iPKey ) continue; | 138242 | if( j==pTab->iPKey ) continue; |
| 133582 | if( pCol->notNull==0 && !bStrict ) continue; | 138243 | if( bStrict ){ |
| 133583 | doError = bStrict ? sqlite3VdbeMakeLabel(pParse) : 0; | 138244 | doTypeCheck = pCol->eCType>COLTYPE_ANY; |
| 133584 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); | 138245 | }else{ |
| 133585 | if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){ | 138246 | doTypeCheck = pCol->affinity>SQLITE_AFF_BLOB; |
| 133586 | sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); | 138247 | } |
| 138248 | if( pCol->notNull==0 && !doTypeCheck ) continue; | ||
| 138249 | |||
| 138250 | /* Compute the operands that will be needed for OP_IsType */ | ||
| 138251 | p4 = SQLITE_NULL; | ||
| 138252 | if( pCol->colFlags & COLFLAG_VIRTUAL ){ | ||
| 138253 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); | ||
| 138254 | p1 = -1; | ||
| 138255 | p3 = 3; | ||
| 138256 | }else{ | ||
| 138257 | if( pCol->iDflt ){ | ||
| 138258 | sqlite3_value *pDfltValue = 0; | ||
| 138259 | sqlite3ValueFromExpr(db, sqlite3ColumnExpr(pTab,pCol), ENC(db), | ||
| 138260 | pCol->affinity, &pDfltValue); | ||
| 138261 | if( pDfltValue ){ | ||
| 138262 | p4 = sqlite3_value_type(pDfltValue); | ||
| 138263 | sqlite3ValueFree(pDfltValue); | ||
| 138264 | } | ||
| 138265 | } | ||
| 138266 | p1 = iDataCur; | ||
| 138267 | if( !HasRowid(pTab) ){ | ||
| 138268 | testcase( j!=sqlite3TableColumnToStorage(pTab, j) ); | ||
| 138269 | p3 = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), j); | ||
| 138270 | }else{ | ||
| 138271 | p3 = sqlite3TableColumnToStorage(pTab,j); | ||
| 138272 | testcase( p3!=j); | ||
| 138273 | } | ||
| 133587 | } | 138274 | } |
| 138275 | |||
| 138276 | labelError = sqlite3VdbeMakeLabel(pParse); | ||
| 138277 | labelOk = sqlite3VdbeMakeLabel(pParse); | ||
| 133588 | if( pCol->notNull ){ | 138278 | if( pCol->notNull ){ |
| 133589 | jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); | 138279 | /* (1) NOT NULL columns may not contain a NULL */ |
| 138280 | int jmp3; | ||
| 138281 | int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); | ||
| 138282 | VdbeCoverage(v); | ||
| 138283 | if( p1<0 ){ | ||
| 138284 | sqlite3VdbeChangeP5(v, 0x0f); /* INT, REAL, TEXT, or BLOB */ | ||
| 138285 | jmp3 = jmp2; | ||
| 138286 | }else{ | ||
| 138287 | sqlite3VdbeChangeP5(v, 0x0d); /* INT, TEXT, or BLOB */ | ||
| 138288 | /* OP_IsType does not detect NaN values in the database file | ||
| 138289 | ** which should be treated as a NULL. So if the header type | ||
| 138290 | ** is REAL, we have to load the actual data using OP_Column | ||
| 138291 | ** to reliably determine if the value is a NULL. */ | ||
| 138292 | sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); | ||
| 138293 | jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); | ||
| 138294 | VdbeCoverage(v); | ||
| 138295 | } | ||
| 133590 | zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, | 138296 | zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, |
| 133591 | pCol->zCnName); | 138297 | pCol->zCnName); |
| 133592 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); | 138298 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); |
| 133593 | if( bStrict && pCol->eCType!=COLTYPE_ANY ){ | 138299 | if( doTypeCheck ){ |
| 133594 | sqlite3VdbeGoto(v, doError); | 138300 | sqlite3VdbeGoto(v, labelError); |
| 138301 | sqlite3VdbeJumpHere(v, jmp2); | ||
| 138302 | sqlite3VdbeJumpHere(v, jmp3); | ||
| 133595 | }else{ | 138303 | }else{ |
| 133596 | integrityCheckResultRow(v); | 138304 | /* VDBE byte code will fall thru */ |
| 133597 | } | 138305 | } |
| 133598 | sqlite3VdbeJumpHere(v, jmp2); | ||
| 133599 | } | 138306 | } |
| 133600 | if( (pTab->tabFlags & TF_Strict)!=0 | 138307 | if( bStrict && doTypeCheck ){ |
| 133601 | && pCol->eCType!=COLTYPE_ANY | 138308 | /* (2) Datatype must be exact for non-ANY columns in STRICT tables*/ |
| 133602 | ){ | 138309 | static unsigned char aStdTypeMask[] = { |
| 133603 | jmp2 = sqlite3VdbeAddOp3(v, OP_IsNullOrType, 3, 0, | 138310 | 0x1f, /* ANY */ |
| 133604 | sqlite3StdTypeMap[pCol->eCType-1]); | 138311 | 0x18, /* BLOB */ |
| 138312 | 0x11, /* INT */ | ||
| 138313 | 0x11, /* INTEGER */ | ||
| 138314 | 0x13, /* REAL */ | ||
| 138315 | 0x14 /* TEXT */ | ||
| 138316 | }; | ||
| 138317 | sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); | ||
| 138318 | assert( pCol->eCType>=1 && pCol->eCType<=sizeof(aStdTypeMask) ); | ||
| 138319 | sqlite3VdbeChangeP5(v, aStdTypeMask[pCol->eCType-1]); | ||
| 133605 | VdbeCoverage(v); | 138320 | VdbeCoverage(v); |
| 133606 | zErr = sqlite3MPrintf(db, "non-%s value in %s.%s", | 138321 | zErr = sqlite3MPrintf(db, "non-%s value in %s.%s", |
| 133607 | sqlite3StdType[pCol->eCType-1], | 138322 | sqlite3StdType[pCol->eCType-1], |
| 133608 | pTab->zName, pTab->aCol[j].zCnName); | 138323 | pTab->zName, pTab->aCol[j].zCnName); |
| 133609 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); | 138324 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); |
| 133610 | sqlite3VdbeResolveLabel(v, doError); | 138325 | }else if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){ |
| 133611 | integrityCheckResultRow(v); | 138326 | /* (3) Datatype for TEXT columns in non-STRICT tables must be |
| 133612 | sqlite3VdbeJumpHere(v, jmp2); | 138327 | ** NULL, TEXT, or BLOB. */ |
| 138328 | sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); | ||
| 138329 | sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ | ||
| 138330 | VdbeCoverage(v); | ||
| 138331 | zErr = sqlite3MPrintf(db, "NUMERIC value in %s.%s", | ||
| 138332 | pTab->zName, pTab->aCol[j].zCnName); | ||
| 138333 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); | ||
| 138334 | }else if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){ | ||
| 138335 | /* (4) Datatype for numeric columns in non-STRICT tables must not | ||
| 138336 | ** be a TEXT value that can be converted to numeric. */ | ||
| 138337 | sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); | ||
| 138338 | sqlite3VdbeChangeP5(v, 0x1b); /* NULL, INT, FLOAT, or BLOB */ | ||
| 138339 | VdbeCoverage(v); | ||
| 138340 | if( p1>=0 ){ | ||
| 138341 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); | ||
| 138342 | } | ||
| 138343 | sqlite3VdbeAddOp4(v, OP_Affinity, 3, 1, 0, "C", P4_STATIC); | ||
| 138344 | sqlite3VdbeAddOp4Int(v, OP_IsType, -1, labelOk, 3, p4); | ||
| 138345 | sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ | ||
| 138346 | VdbeCoverage(v); | ||
| 138347 | zErr = sqlite3MPrintf(db, "TEXT value in %s.%s", | ||
| 138348 | pTab->zName, pTab->aCol[j].zCnName); | ||
| 138349 | sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); | ||
| 133613 | } | 138350 | } |
| 138351 | sqlite3VdbeResolveLabel(v, labelError); | ||
| 138352 | integrityCheckResultRow(v); | ||
| 138353 | sqlite3VdbeResolveLabel(v, labelOk); | ||
| 133614 | } | 138354 | } |
| 133615 | /* Verify CHECK constraints */ | 138355 | /* Verify CHECK constraints */ |
| 133616 | if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ | 138356 | if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ |
| @@ -133639,7 +138379,8 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133639 | if( !isQuick ){ /* Omit the remaining tests for quick_check */ | 138379 | if( !isQuick ){ /* Omit the remaining tests for quick_check */ |
| 133640 | /* Validate index entries for the current row */ | 138380 | /* Validate index entries for the current row */ |
| 133641 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ | 138381 | for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ |
| 133642 | int jmp2, jmp3, jmp4, jmp5; | 138382 | int jmp2, jmp3, jmp4, jmp5, label6; |
| 138383 | int kk; | ||
| 133643 | int ckUniq = sqlite3VdbeMakeLabel(pParse); | 138384 | int ckUniq = sqlite3VdbeMakeLabel(pParse); |
| 133644 | if( pPk==pIdx ) continue; | 138385 | if( pPk==pIdx ) continue; |
| 133645 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, | 138386 | r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, |
| @@ -133657,13 +138398,49 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133657 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); | 138398 | sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); |
| 133658 | jmp4 = integrityCheckResultRow(v); | 138399 | jmp4 = integrityCheckResultRow(v); |
| 133659 | sqlite3VdbeJumpHere(v, jmp2); | 138400 | sqlite3VdbeJumpHere(v, jmp2); |
| 138401 | |||
| 138402 | /* The OP_IdxRowid opcode is an optimized version of OP_Column | ||
| 138403 | ** that extracts the rowid off the end of the index record. | ||
| 138404 | ** But it only works correctly if index record does not have | ||
| 138405 | ** any extra bytes at the end. Verify that this is the case. */ | ||
| 138406 | if( HasRowid(pTab) ){ | ||
| 138407 | int jmp7; | ||
| 138408 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur+j, 3); | ||
| 138409 | jmp7 = sqlite3VdbeAddOp3(v, OP_Eq, 3, 0, r1+pIdx->nColumn-1); | ||
| 138410 | VdbeCoverageNeverNull(v); | ||
| 138411 | sqlite3VdbeLoadString(v, 3, | ||
| 138412 | "rowid not at end-of-record for row "); | ||
| 138413 | sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); | ||
| 138414 | sqlite3VdbeLoadString(v, 4, " of index "); | ||
| 138415 | sqlite3VdbeGoto(v, jmp5-1); | ||
| 138416 | sqlite3VdbeJumpHere(v, jmp7); | ||
| 138417 | } | ||
| 138418 | |||
| 138419 | /* Any indexed columns with non-BINARY collations must still hold | ||
| 138420 | ** the exact same text value as the table. */ | ||
| 138421 | label6 = 0; | ||
| 138422 | for(kk=0; kk<pIdx->nKeyCol; kk++){ | ||
| 138423 | if( pIdx->azColl[kk]==sqlite3StrBINARY ) continue; | ||
| 138424 | if( label6==0 ) label6 = sqlite3VdbeMakeLabel(pParse); | ||
| 138425 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur+j, kk, 3); | ||
| 138426 | sqlite3VdbeAddOp3(v, OP_Ne, 3, label6, r1+kk); VdbeCoverage(v); | ||
| 138427 | } | ||
| 138428 | if( label6 ){ | ||
| 138429 | int jmp6 = sqlite3VdbeAddOp0(v, OP_Goto); | ||
| 138430 | sqlite3VdbeResolveLabel(v, label6); | ||
| 138431 | sqlite3VdbeLoadString(v, 3, "row "); | ||
| 138432 | sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); | ||
| 138433 | sqlite3VdbeLoadString(v, 4, " values differ from index "); | ||
| 138434 | sqlite3VdbeGoto(v, jmp5-1); | ||
| 138435 | sqlite3VdbeJumpHere(v, jmp6); | ||
| 138436 | } | ||
| 138437 | |||
| 133660 | /* For UNIQUE indexes, verify that only one entry exists with the | 138438 | /* For UNIQUE indexes, verify that only one entry exists with the |
| 133661 | ** current key. The entry is unique if (1) any column is NULL | 138439 | ** current key. The entry is unique if (1) any column is NULL |
| 133662 | ** or (2) the next entry has a different key */ | 138440 | ** or (2) the next entry has a different key */ |
| 133663 | if( IsUniqueIndex(pIdx) ){ | 138441 | if( IsUniqueIndex(pIdx) ){ |
| 133664 | int uniqOk = sqlite3VdbeMakeLabel(pParse); | 138442 | int uniqOk = sqlite3VdbeMakeLabel(pParse); |
| 133665 | int jmp6; | 138443 | int jmp6; |
| 133666 | int kk; | ||
| 133667 | for(kk=0; kk<pIdx->nKeyCol; kk++){ | 138444 | for(kk=0; kk<pIdx->nKeyCol; kk++){ |
| 133668 | int iCol = pIdx->aiColumn[kk]; | 138445 | int iCol = pIdx->aiColumn[kk]; |
| 133669 | assert( iCol!=XN_ROWID && iCol<pTab->nCol ); | 138446 | assert( iCol!=XN_ROWID && iCol<pTab->nCol ); |
| @@ -133698,6 +138475,9 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133698 | integrityCheckResultRow(v); | 138475 | integrityCheckResultRow(v); |
| 133699 | sqlite3VdbeJumpHere(v, addr); | 138476 | sqlite3VdbeJumpHere(v, addr); |
| 133700 | } | 138477 | } |
| 138478 | if( pPk ){ | ||
| 138479 | sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); | ||
| 138480 | } | ||
| 133701 | } | 138481 | } |
| 133702 | } | 138482 | } |
| 133703 | } | 138483 | } |
| @@ -133848,6 +138628,11 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 133848 | aOp[1].p2 = iCookie; | 138628 | aOp[1].p2 = iCookie; |
| 133849 | aOp[1].p3 = sqlite3Atoi(zRight); | 138629 | aOp[1].p3 = sqlite3Atoi(zRight); |
| 133850 | aOp[1].p5 = 1; | 138630 | aOp[1].p5 = 1; |
| 138631 | if( iCookie==BTREE_SCHEMA_VERSION && (db->flags & SQLITE_Defensive)!=0 ){ | ||
| 138632 | /* Do not allow the use of PRAGMA schema_version=VALUE in defensive | ||
| 138633 | ** mode. Change the OP_SetCookie opcode into a no-op. */ | ||
| 138634 | aOp[1].opcode = OP_Noop; | ||
| 138635 | } | ||
| 133851 | }else{ | 138636 | }else{ |
| 133852 | /* Read the specified cookie value */ | 138637 | /* Read the specified cookie value */ |
| 133853 | static const VdbeOpList readCookie[] = { | 138638 | static const VdbeOpList readCookie[] = { |
| @@ -134004,7 +138789,7 @@ SQLITE_PRIVATE void sqlite3Pragma( | |||
| 134004 | Schema *pSchema; /* The current schema */ | 138789 | Schema *pSchema; /* The current schema */ |
| 134005 | Table *pTab; /* A table in the schema */ | 138790 | Table *pTab; /* A table in the schema */ |
| 134006 | Index *pIdx; /* An index of the table */ | 138791 | Index *pIdx; /* An index of the table */ |
| 134007 | LogEst szThreshold; /* Size threshold above which reanalysis is needd */ | 138792 | LogEst szThreshold; /* Size threshold above which reanalysis needed */ |
| 134008 | char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ | 138793 | char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ |
| 134009 | u32 opMask; /* Mask of operations to perform */ | 138794 | u32 opMask; /* Mask of operations to perform */ |
| 134010 | 138795 | ||
| @@ -134828,7 +139613,14 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl | |||
| 134828 | #else | 139613 | #else |
| 134829 | encoding = SQLITE_UTF8; | 139614 | encoding = SQLITE_UTF8; |
| 134830 | #endif | 139615 | #endif |
| 134831 | sqlite3SetTextEncoding(db, encoding); | 139616 | if( db->nVdbeActive>0 && encoding!=ENC(db) |
| 139617 | && (db->mDbFlags & DBFLAG_Vacuum)==0 | ||
| 139618 | ){ | ||
| 139619 | rc = SQLITE_LOCKED; | ||
| 139620 | goto initone_error_out; | ||
| 139621 | }else{ | ||
| 139622 | sqlite3SetTextEncoding(db, encoding); | ||
| 139623 | } | ||
| 134832 | }else{ | 139624 | }else{ |
| 134833 | /* If opening an attached database, the encoding much match ENC(db) */ | 139625 | /* If opening an attached database, the encoding much match ENC(db) */ |
| 134834 | if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ | 139626 | if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ |
| @@ -135042,8 +139834,8 @@ static void schemaIsValid(Parse *pParse){ | |||
| 135042 | sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); | 139834 | sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); |
| 135043 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); | 139835 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 135044 | if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ | 139836 | if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ |
| 139837 | if( DbHasProperty(db, iDb, DB_SchemaLoaded) ) pParse->rc = SQLITE_SCHEMA; | ||
| 135045 | sqlite3ResetOneSchema(db, iDb); | 139838 | sqlite3ResetOneSchema(db, iDb); |
| 135046 | pParse->rc = SQLITE_SCHEMA; | ||
| 135047 | } | 139839 | } |
| 135048 | 139840 | ||
| 135049 | /* Close the transaction, if one was opened. */ | 139841 | /* Close the transaction, if one was opened. */ |
| @@ -135096,15 +139888,15 @@ SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ | |||
| 135096 | assert( db->pParse==pParse ); | 139888 | assert( db->pParse==pParse ); |
| 135097 | assert( pParse->nested==0 ); | 139889 | assert( pParse->nested==0 ); |
| 135098 | #ifndef SQLITE_OMIT_SHARED_CACHE | 139890 | #ifndef SQLITE_OMIT_SHARED_CACHE |
| 135099 | sqlite3DbFree(db, pParse->aTableLock); | 139891 | if( pParse->aTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); |
| 135100 | #endif | 139892 | #endif |
| 135101 | while( pParse->pCleanup ){ | 139893 | while( pParse->pCleanup ){ |
| 135102 | ParseCleanup *pCleanup = pParse->pCleanup; | 139894 | ParseCleanup *pCleanup = pParse->pCleanup; |
| 135103 | pParse->pCleanup = pCleanup->pNext; | 139895 | pParse->pCleanup = pCleanup->pNext; |
| 135104 | pCleanup->xCleanup(db, pCleanup->pPtr); | 139896 | pCleanup->xCleanup(db, pCleanup->pPtr); |
| 135105 | sqlite3DbFreeNN(db, pCleanup); | 139897 | sqlite3DbNNFreeNN(db, pCleanup); |
| 135106 | } | 139898 | } |
| 135107 | sqlite3DbFree(db, pParse->aLabel); | 139899 | if( pParse->aLabel ) sqlite3DbNNFreeNN(db, pParse->aLabel); |
| 135108 | if( pParse->pConstExpr ){ | 139900 | if( pParse->pConstExpr ){ |
| 135109 | sqlite3ExprListDelete(db, pParse->pConstExpr); | 139901 | sqlite3ExprListDelete(db, pParse->pConstExpr); |
| 135110 | } | 139902 | } |
| @@ -135123,7 +139915,7 @@ SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ | |||
| 135123 | ** immediately. | 139915 | ** immediately. |
| 135124 | ** | 139916 | ** |
| 135125 | ** Use this mechanism for uncommon cleanups. There is a higher setup | 139917 | ** Use this mechanism for uncommon cleanups. There is a higher setup |
| 135126 | ** cost for this mechansim (an extra malloc), so it should not be used | 139918 | ** cost for this mechanism (an extra malloc), so it should not be used |
| 135127 | ** for common cleanups that happen on most calls. But for less | 139919 | ** for common cleanups that happen on most calls. But for less |
| 135128 | ** common cleanups, we save a single NULL-pointer comparison in | 139920 | ** common cleanups, we save a single NULL-pointer comparison in |
| 135129 | ** sqlite3ParseObjectReset(), which reduces the total CPU cycle count. | 139921 | ** sqlite3ParseObjectReset(), which reduces the total CPU cycle count. |
| @@ -135215,9 +140007,18 @@ static int sqlite3Prepare( | |||
| 135215 | sParse.pOuterParse = db->pParse; | 140007 | sParse.pOuterParse = db->pParse; |
| 135216 | db->pParse = &sParse; | 140008 | db->pParse = &sParse; |
| 135217 | sParse.db = db; | 140009 | sParse.db = db; |
| 135218 | sParse.pReprepare = pReprepare; | 140010 | if( pReprepare ){ |
| 140011 | sParse.pReprepare = pReprepare; | ||
| 140012 | sParse.explain = sqlite3_stmt_isexplain((sqlite3_stmt*)pReprepare); | ||
| 140013 | }else{ | ||
| 140014 | assert( sParse.pReprepare==0 ); | ||
| 140015 | } | ||
| 135219 | assert( ppStmt && *ppStmt==0 ); | 140016 | assert( ppStmt && *ppStmt==0 ); |
| 135220 | if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory"); | 140017 | if( db->mallocFailed ){ |
| 140018 | sqlite3ErrorMsg(&sParse, "out of memory"); | ||
| 140019 | db->errCode = rc = SQLITE_NOMEM; | ||
| 140020 | goto end_prepare; | ||
| 140021 | } | ||
| 135221 | assert( sqlite3_mutex_held(db->mutex) ); | 140022 | assert( sqlite3_mutex_held(db->mutex) ); |
| 135222 | 140023 | ||
| 135223 | /* For a long-term use prepared statement avoid the use of | 140024 | /* For a long-term use prepared statement avoid the use of |
| @@ -135227,7 +140028,7 @@ static int sqlite3Prepare( | |||
| 135227 | sParse.disableLookaside++; | 140028 | sParse.disableLookaside++; |
| 135228 | DisableLookaside; | 140029 | DisableLookaside; |
| 135229 | } | 140030 | } |
| 135230 | sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0; | 140031 | sParse.prepFlags = prepFlags & 0xff; |
| 135231 | 140032 | ||
| 135232 | /* Check to verify that it is possible to get a read lock on all | 140033 | /* Check to verify that it is possible to get a read lock on all |
| 135233 | ** database schemas. The inability to get a read lock indicates that | 140034 | ** database schemas. The inability to get a read lock indicates that |
| @@ -135268,7 +140069,9 @@ static int sqlite3Prepare( | |||
| 135268 | } | 140069 | } |
| 135269 | } | 140070 | } |
| 135270 | 140071 | ||
| 135271 | sqlite3VtabUnlockList(db); | 140072 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 140073 | if( db->pDisconnect ) sqlite3VtabUnlockList(db); | ||
| 140074 | #endif | ||
| 135272 | 140075 | ||
| 135273 | if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ | 140076 | if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ |
| 135274 | char *zSqlCopy; | 140077 | char *zSqlCopy; |
| @@ -135652,6 +140455,10 @@ struct SortCtx { | |||
| 135652 | } aDefer[4]; | 140455 | } aDefer[4]; |
| 135653 | #endif | 140456 | #endif |
| 135654 | struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ | 140457 | struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ |
| 140458 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 140459 | int addrPush; /* First instruction to push data into sorter */ | ||
| 140460 | int addrPushEnd; /* Last instruction that pushes data into sorter */ | ||
| 140461 | #endif | ||
| 135655 | }; | 140462 | }; |
| 135656 | #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ | 140463 | #define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ |
| 135657 | 140464 | ||
| @@ -135663,6 +140470,7 @@ struct SortCtx { | |||
| 135663 | ** If bFree==0, Leave the first Select object unfreed | 140470 | ** If bFree==0, Leave the first Select object unfreed |
| 135664 | */ | 140471 | */ |
| 135665 | static void clearSelect(sqlite3 *db, Select *p, int bFree){ | 140472 | static void clearSelect(sqlite3 *db, Select *p, int bFree){ |
| 140473 | assert( db!=0 ); | ||
| 135666 | while( p ){ | 140474 | while( p ){ |
| 135667 | Select *pPrior = p->pPrior; | 140475 | Select *pPrior = p->pPrior; |
| 135668 | sqlite3ExprListDelete(db, p->pEList); | 140476 | sqlite3ExprListDelete(db, p->pEList); |
| @@ -135682,7 +140490,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ | |||
| 135682 | sqlite3WindowUnlinkFromSelect(p->pWin); | 140490 | sqlite3WindowUnlinkFromSelect(p->pWin); |
| 135683 | } | 140491 | } |
| 135684 | #endif | 140492 | #endif |
| 135685 | if( bFree ) sqlite3DbFreeNN(db, p); | 140493 | if( bFree ) sqlite3DbNNFreeNN(db, p); |
| 135686 | p = pPrior; | 140494 | p = pPrior; |
| 135687 | bFree = 1; | 140495 | bFree = 1; |
| 135688 | } | 140496 | } |
| @@ -135814,7 +140622,7 @@ static Select *findRightmost(Select *p){ | |||
| 135814 | ** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT | 140622 | ** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT |
| 135815 | ** | 140623 | ** |
| 135816 | ** To preserve historical compatibly, SQLite also accepts a variety | 140624 | ** To preserve historical compatibly, SQLite also accepts a variety |
| 135817 | ** of other non-standard and in many cases non-sensical join types. | 140625 | ** of other non-standard and in many cases nonsensical join types. |
| 135818 | ** This routine makes as much sense at it can from the nonsense join | 140626 | ** This routine makes as much sense at it can from the nonsense join |
| 135819 | ** type and returns a result. Examples of accepted nonsense join types | 140627 | ** type and returns a result. Examples of accepted nonsense join types |
| 135820 | ** include but are not limited to: | 140628 | ** include but are not limited to: |
| @@ -136085,7 +140893,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ | |||
| 136085 | if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; | 140893 | if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; |
| 136086 | joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; | 140894 | joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; |
| 136087 | 140895 | ||
| 136088 | /* If this is a NATURAL join, synthesize an approprate USING clause | 140896 | /* If this is a NATURAL join, synthesize an appropriate USING clause |
| 136089 | ** to specify which columns should be joined. | 140897 | ** to specify which columns should be joined. |
| 136090 | */ | 140898 | */ |
| 136091 | if( pRight->fg.jointype & JT_NATURAL ){ | 140899 | if( pRight->fg.jointype & JT_NATURAL ){ |
| @@ -136299,14 +141107,18 @@ static void pushOntoSorter( | |||
| 136299 | ** (2) All output columns are included in the sort record. In that | 141107 | ** (2) All output columns are included in the sort record. In that |
| 136300 | ** case regData==regOrigData. | 141108 | ** case regData==regOrigData. |
| 136301 | ** (3) Some output columns are omitted from the sort record due to | 141109 | ** (3) Some output columns are omitted from the sort record due to |
| 136302 | ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the | 141110 | ** the SQLITE_ENABLE_SORTER_REFERENCES optimization, or due to the |
| 136303 | ** SQLITE_ECEL_OMITREF optimization, or due to the | 141111 | ** SQLITE_ECEL_OMITREF optimization, or due to the |
| 136304 | ** SortCtx.pDeferredRowLoad optimiation. In any of these cases | 141112 | ** SortCtx.pDeferredRowLoad optimization. In any of these cases |
| 136305 | ** regOrigData is 0 to prevent this routine from trying to copy | 141113 | ** regOrigData is 0 to prevent this routine from trying to copy |
| 136306 | ** values that might not yet exist. | 141114 | ** values that might not yet exist. |
| 136307 | */ | 141115 | */ |
| 136308 | assert( nData==1 || regData==regOrigData || regOrigData==0 ); | 141116 | assert( nData==1 || regData==regOrigData || regOrigData==0 ); |
| 136309 | 141117 | ||
| 141118 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 141119 | pSort->addrPush = sqlite3VdbeCurrentAddr(v); | ||
| 141120 | #endif | ||
| 141121 | |||
| 136310 | if( nPrefixReg ){ | 141122 | if( nPrefixReg ){ |
| 136311 | assert( nPrefixReg==nExpr+bSeq ); | 141123 | assert( nPrefixReg==nExpr+bSeq ); |
| 136312 | regBase = regData - nPrefixReg; | 141124 | regBase = regData - nPrefixReg; |
| @@ -136353,7 +141165,7 @@ static void pushOntoSorter( | |||
| 136353 | testcase( pKI->nAllField > pKI->nKeyField+2 ); | 141165 | testcase( pKI->nAllField > pKI->nKeyField+2 ); |
| 136354 | pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, | 141166 | pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, |
| 136355 | pKI->nAllField-pKI->nKeyField-1); | 141167 | pKI->nAllField-pKI->nKeyField-1); |
| 136356 | pOp = 0; /* Ensure pOp not used after sqltie3VdbeAddOp3() */ | 141168 | pOp = 0; /* Ensure pOp not used after sqlite3VdbeAddOp3() */ |
| 136357 | addrJmp = sqlite3VdbeCurrentAddr(v); | 141169 | addrJmp = sqlite3VdbeCurrentAddr(v); |
| 136358 | sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); | 141170 | sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); |
| 136359 | pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); | 141171 | pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); |
| @@ -136407,6 +141219,9 @@ static void pushOntoSorter( | |||
| 136407 | sqlite3VdbeChangeP2(v, iSkip, | 141219 | sqlite3VdbeChangeP2(v, iSkip, |
| 136408 | pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); | 141220 | pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); |
| 136409 | } | 141221 | } |
| 141222 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 141223 | pSort->addrPushEnd = sqlite3VdbeCurrentAddr(v)-1; | ||
| 141224 | #endif | ||
| 136410 | } | 141225 | } |
| 136411 | 141226 | ||
| 136412 | /* | 141227 | /* |
| @@ -136444,7 +141259,7 @@ static void codeOffset( | |||
| 136444 | ** The returned value in this case is a copy of parameter iTab. | 141259 | ** The returned value in this case is a copy of parameter iTab. |
| 136445 | ** | 141260 | ** |
| 136446 | ** WHERE_DISTINCT_ORDERED: | 141261 | ** WHERE_DISTINCT_ORDERED: |
| 136447 | ** In this case rows are being delivered sorted order. The ephermal | 141262 | ** In this case rows are being delivered sorted order. The ephemeral |
| 136448 | ** table is not required. Instead, the current set of values | 141263 | ** table is not required. Instead, the current set of values |
| 136449 | ** is compared against previous row. If they match, the new row | 141264 | ** is compared against previous row. If they match, the new row |
| 136450 | ** is not distinct and control jumps to VM address addrRepeat. Otherwise, | 141265 | ** is not distinct and control jumps to VM address addrRepeat. Otherwise, |
| @@ -136873,6 +141688,16 @@ static void selectInnerLoop( | |||
| 136873 | testcase( eDest==SRT_Fifo ); | 141688 | testcase( eDest==SRT_Fifo ); |
| 136874 | testcase( eDest==SRT_DistFifo ); | 141689 | testcase( eDest==SRT_DistFifo ); |
| 136875 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); | 141690 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); |
| 141691 | #if !defined(SQLITE_ENABLE_NULL_TRIM) && defined(SQLITE_DEBUG) | ||
| 141692 | /* A destination of SRT_Table and a non-zero iSDParm2 parameter means | ||
| 141693 | ** that this is an "UPDATE ... FROM" on a virtual table or view. In this | ||
| 141694 | ** case set the p5 parameter of the OP_MakeRecord to OPFLAG_NOCHNG_MAGIC. | ||
| 141695 | ** This does not affect operation in any way - it just allows MakeRecord | ||
| 141696 | ** to process OPFLAG_NOCHANGE values without an assert() failing. */ | ||
| 141697 | if( eDest==SRT_Table && pDest->iSDParm2 ){ | ||
| 141698 | sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); | ||
| 141699 | } | ||
| 141700 | #endif | ||
| 136876 | #ifndef SQLITE_OMIT_CTE | 141701 | #ifndef SQLITE_OMIT_CTE |
| 136877 | if( eDest==SRT_DistFifo ){ | 141702 | if( eDest==SRT_DistFifo ){ |
| 136878 | /* If the destination is DistFifo, then cursor (iParm+1) is open | 141703 | /* If the destination is DistFifo, then cursor (iParm+1) is open |
| @@ -137088,9 +141913,10 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ | |||
| 137088 | */ | 141913 | */ |
| 137089 | SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ | 141914 | SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ |
| 137090 | if( p ){ | 141915 | if( p ){ |
| 141916 | assert( p->db!=0 ); | ||
| 137091 | assert( p->nRef>0 ); | 141917 | assert( p->nRef>0 ); |
| 137092 | p->nRef--; | 141918 | p->nRef--; |
| 137093 | if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p); | 141919 | if( p->nRef==0 ) sqlite3DbNNFreeNN(p->db, p); |
| 137094 | } | 141920 | } |
| 137095 | } | 141921 | } |
| 137096 | 141922 | ||
| @@ -137229,6 +142055,16 @@ static void generateSortTail( | |||
| 137229 | int bSeq; /* True if sorter record includes seq. no. */ | 142055 | int bSeq; /* True if sorter record includes seq. no. */ |
| 137230 | int nRefKey = 0; | 142056 | int nRefKey = 0; |
| 137231 | struct ExprList_item *aOutEx = p->pEList->a; | 142057 | struct ExprList_item *aOutEx = p->pEList->a; |
| 142058 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 142059 | int addrExplain; /* Address of OP_Explain instruction */ | ||
| 142060 | #endif | ||
| 142061 | |||
| 142062 | ExplainQueryPlan2(addrExplain, (pParse, 0, | ||
| 142063 | "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"") | ||
| 142064 | ); | ||
| 142065 | sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); | ||
| 142066 | sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); | ||
| 142067 | |||
| 137232 | 142068 | ||
| 137233 | assert( addrBreak<0 ); | 142069 | assert( addrBreak<0 ); |
| 137234 | if( pSort->labelBkOut ){ | 142070 | if( pSort->labelBkOut ){ |
| @@ -137341,6 +142177,7 @@ static void generateSortTail( | |||
| 137341 | VdbeComment((v, "%s", aOutEx[i].zEName)); | 142177 | VdbeComment((v, "%s", aOutEx[i].zEName)); |
| 137342 | } | 142178 | } |
| 137343 | } | 142179 | } |
| 142180 | sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); | ||
| 137344 | switch( eDest ){ | 142181 | switch( eDest ){ |
| 137345 | case SRT_Table: | 142182 | case SRT_Table: |
| 137346 | case SRT_EphemTab: { | 142183 | case SRT_EphemTab: { |
| @@ -137402,6 +142239,7 @@ static void generateSortTail( | |||
| 137402 | }else{ | 142239 | }else{ |
| 137403 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); | 142240 | sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); |
| 137404 | } | 142241 | } |
| 142242 | sqlite3VdbeScanStatusRange(v, addrExplain, sqlite3VdbeCurrentAddr(v)-1, -1); | ||
| 137405 | if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); | 142243 | if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); |
| 137406 | sqlite3VdbeResolveLabel(v, addrBreak); | 142244 | sqlite3VdbeResolveLabel(v, addrBreak); |
| 137407 | } | 142245 | } |
| @@ -137410,9 +142248,6 @@ static void generateSortTail( | |||
| 137410 | ** Return a pointer to a string containing the 'declaration type' of the | 142248 | ** Return a pointer to a string containing the 'declaration type' of the |
| 137411 | ** expression pExpr. The string may be treated as static by the caller. | 142249 | ** expression pExpr. The string may be treated as static by the caller. |
| 137412 | ** | 142250 | ** |
| 137413 | ** Also try to estimate the size of the returned value and return that | ||
| 137414 | ** result in *pEstWidth. | ||
| 137415 | ** | ||
| 137416 | ** The declaration type is the exact datatype definition extracted from the | 142251 | ** The declaration type is the exact datatype definition extracted from the |
| 137417 | ** original CREATE TABLE statement if the expression is a column. The | 142252 | ** original CREATE TABLE statement if the expression is a column. The |
| 137418 | ** declaration type for a ROWID field is INTEGER. Exactly when an expression | 142253 | ** declaration type for a ROWID field is INTEGER. Exactly when an expression |
| @@ -137666,17 +142501,10 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames( | |||
| 137666 | int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */ | 142501 | int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */ |
| 137667 | int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */ | 142502 | int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */ |
| 137668 | 142503 | ||
| 137669 | #ifndef SQLITE_OMIT_EXPLAIN | ||
| 137670 | /* If this is an EXPLAIN, skip this step */ | ||
| 137671 | if( pParse->explain ){ | ||
| 137672 | return; | ||
| 137673 | } | ||
| 137674 | #endif | ||
| 137675 | |||
| 137676 | if( pParse->colNamesSet ) return; | 142504 | if( pParse->colNamesSet ) return; |
| 137677 | /* Column names are determined by the left-most term of a compound select */ | 142505 | /* Column names are determined by the left-most term of a compound select */ |
| 137678 | while( pSelect->pPrior ) pSelect = pSelect->pPrior; | 142506 | while( pSelect->pPrior ) pSelect = pSelect->pPrior; |
| 137679 | SELECTTRACE(1,pParse,pSelect,("generating column names\n")); | 142507 | TREETRACE(0x80,pParse,pSelect,("generating column names\n")); |
| 137680 | pTabList = pSelect->pSrc; | 142508 | pTabList = pSelect->pSrc; |
| 137681 | pEList = pSelect->pEList; | 142509 | pEList = pSelect->pEList; |
| 137682 | assert( v!=0 ); | 142510 | assert( v!=0 ); |
| @@ -137776,7 +142604,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( | |||
| 137776 | *pnCol = nCol; | 142604 | *pnCol = nCol; |
| 137777 | *paCol = aCol; | 142605 | *paCol = aCol; |
| 137778 | 142606 | ||
| 137779 | for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){ | 142607 | for(i=0, pCol=aCol; i<nCol && !pParse->nErr; i++, pCol++){ |
| 137780 | struct ExprList_item *pX = &pEList->a[i]; | 142608 | struct ExprList_item *pX = &pEList->a[i]; |
| 137781 | struct ExprList_item *pCollide; | 142609 | struct ExprList_item *pCollide; |
| 137782 | /* Get an appropriate name for the column | 142610 | /* Get an appropriate name for the column |
| @@ -137826,7 +142654,10 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( | |||
| 137826 | if( zName[j]==':' ) nName = j; | 142654 | if( zName[j]==':' ) nName = j; |
| 137827 | } | 142655 | } |
| 137828 | zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); | 142656 | zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); |
| 137829 | if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); | 142657 | sqlite3ProgressCheck(pParse); |
| 142658 | if( cnt>3 ){ | ||
| 142659 | sqlite3_randomness(sizeof(cnt), &cnt); | ||
| 142660 | } | ||
| 137830 | } | 142661 | } |
| 137831 | pCol->zCnName = zName; | 142662 | pCol->zCnName = zName; |
| 137832 | pCol->hName = sqlite3StrIHash(zName); | 142663 | pCol->hName = sqlite3StrIHash(zName); |
| @@ -137839,71 +142670,104 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( | |||
| 137839 | } | 142670 | } |
| 137840 | } | 142671 | } |
| 137841 | sqlite3HashClear(&ht); | 142672 | sqlite3HashClear(&ht); |
| 137842 | if( db->mallocFailed ){ | 142673 | if( pParse->nErr ){ |
| 137843 | for(j=0; j<i; j++){ | 142674 | for(j=0; j<i; j++){ |
| 137844 | sqlite3DbFree(db, aCol[j].zCnName); | 142675 | sqlite3DbFree(db, aCol[j].zCnName); |
| 137845 | } | 142676 | } |
| 137846 | sqlite3DbFree(db, aCol); | 142677 | sqlite3DbFree(db, aCol); |
| 137847 | *paCol = 0; | 142678 | *paCol = 0; |
| 137848 | *pnCol = 0; | 142679 | *pnCol = 0; |
| 137849 | return SQLITE_NOMEM_BKPT; | 142680 | return pParse->rc; |
| 137850 | } | 142681 | } |
| 137851 | return SQLITE_OK; | 142682 | return SQLITE_OK; |
| 137852 | } | 142683 | } |
| 137853 | 142684 | ||
| 137854 | /* | 142685 | /* |
| 137855 | ** Add type and collation information to a column list based on | 142686 | ** pTab is a transient Table object that represents a subquery of some |
| 137856 | ** a SELECT statement. | 142687 | ** kind (maybe a parenthesized subquery in the FROM clause of a larger |
| 137857 | ** | 142688 | ** query, or a VIEW, or a CTE). This routine computes type information |
| 137858 | ** The column list presumably came from selectColumnNamesFromExprList(). | 142689 | ** for that Table object based on the Select object that implements the |
| 137859 | ** The column list has only names, not types or collations. This | 142690 | ** subquery. For the purposes of this routine, "type information" means: |
| 137860 | ** routine goes through and adds the types and collations. | ||
| 137861 | ** | 142691 | ** |
| 137862 | ** This routine requires that all identifiers in the SELECT | 142692 | ** * The datatype name, as it might appear in a CREATE TABLE statement |
| 137863 | ** statement be resolved. | 142693 | ** * Which collating sequence to use for the column |
| 142694 | ** * The affinity of the column | ||
| 137864 | */ | 142695 | */ |
| 137865 | SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation( | 142696 | SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( |
| 137866 | Parse *pParse, /* Parsing contexts */ | 142697 | Parse *pParse, /* Parsing contexts */ |
| 137867 | Table *pTab, /* Add column type information to this table */ | 142698 | Table *pTab, /* Add column type information to this table */ |
| 137868 | Select *pSelect, /* SELECT used to determine types and collations */ | 142699 | Select *pSelect, /* SELECT used to determine types and collations */ |
| 137869 | char aff /* Default affinity for columns */ | 142700 | char aff /* Default affinity. */ |
| 137870 | ){ | 142701 | ){ |
| 137871 | sqlite3 *db = pParse->db; | 142702 | sqlite3 *db = pParse->db; |
| 137872 | NameContext sNC; | ||
| 137873 | Column *pCol; | 142703 | Column *pCol; |
| 137874 | CollSeq *pColl; | 142704 | CollSeq *pColl; |
| 137875 | int i; | 142705 | int i,j; |
| 137876 | Expr *p; | 142706 | Expr *p; |
| 137877 | struct ExprList_item *a; | 142707 | struct ExprList_item *a; |
| 142708 | NameContext sNC; | ||
| 137878 | 142709 | ||
| 137879 | assert( pSelect!=0 ); | 142710 | assert( pSelect!=0 ); |
| 137880 | assert( (pSelect->selFlags & SF_Resolved)!=0 ); | 142711 | assert( (pSelect->selFlags & SF_Resolved)!=0 ); |
| 137881 | assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed ); | 142712 | assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); |
| 137882 | if( db->mallocFailed ) return; | 142713 | assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); |
| 142714 | if( db->mallocFailed || IN_RENAME_OBJECT ) return; | ||
| 142715 | while( pSelect->pPrior ) pSelect = pSelect->pPrior; | ||
| 142716 | a = pSelect->pEList->a; | ||
| 137883 | memset(&sNC, 0, sizeof(sNC)); | 142717 | memset(&sNC, 0, sizeof(sNC)); |
| 137884 | sNC.pSrcList = pSelect->pSrc; | 142718 | sNC.pSrcList = pSelect->pSrc; |
| 137885 | a = pSelect->pEList->a; | ||
| 137886 | for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ | 142719 | for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ |
| 137887 | const char *zType; | 142720 | const char *zType; |
| 137888 | i64 n, m; | 142721 | i64 n; |
| 137889 | pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); | 142722 | pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); |
| 137890 | p = a[i].pExpr; | 142723 | p = a[i].pExpr; |
| 137891 | zType = columnType(&sNC, p, 0, 0, 0); | ||
| 137892 | /* pCol->szEst = ... // Column size est for SELECT tables never used */ | 142724 | /* pCol->szEst = ... // Column size est for SELECT tables never used */ |
| 137893 | pCol->affinity = sqlite3ExprAffinity(p); | 142725 | pCol->affinity = sqlite3ExprAffinity(p); |
| 142726 | if( pCol->affinity<=SQLITE_AFF_NONE ){ | ||
| 142727 | pCol->affinity = aff; | ||
| 142728 | } | ||
| 142729 | if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){ | ||
| 142730 | int m = 0; | ||
| 142731 | Select *pS2; | ||
| 142732 | for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){ | ||
| 142733 | m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); | ||
| 142734 | } | ||
| 142735 | if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ | ||
| 142736 | pCol->affinity = SQLITE_AFF_BLOB; | ||
| 142737 | }else | ||
| 142738 | if( pCol->affinity>=SQLITE_AFF_NUMERIC && (m&0x02)!=0 ){ | ||
| 142739 | pCol->affinity = SQLITE_AFF_BLOB; | ||
| 142740 | } | ||
| 142741 | if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){ | ||
| 142742 | pCol->affinity = SQLITE_AFF_FLEXNUM; | ||
| 142743 | } | ||
| 142744 | } | ||
| 142745 | zType = columnType(&sNC, p, 0, 0, 0); | ||
| 142746 | if( zType==0 || pCol->affinity!=sqlite3AffinityType(zType, 0) ){ | ||
| 142747 | if( pCol->affinity==SQLITE_AFF_NUMERIC | ||
| 142748 | || pCol->affinity==SQLITE_AFF_FLEXNUM | ||
| 142749 | ){ | ||
| 142750 | zType = "NUM"; | ||
| 142751 | }else{ | ||
| 142752 | zType = 0; | ||
| 142753 | for(j=1; j<SQLITE_N_STDTYPE; j++){ | ||
| 142754 | if( sqlite3StdTypeAffinity[j]==pCol->affinity ){ | ||
| 142755 | zType = sqlite3StdType[j]; | ||
| 142756 | break; | ||
| 142757 | } | ||
| 142758 | } | ||
| 142759 | } | ||
| 142760 | } | ||
| 137894 | if( zType ){ | 142761 | if( zType ){ |
| 137895 | m = sqlite3Strlen30(zType); | 142762 | i64 m = sqlite3Strlen30(zType); |
| 137896 | n = sqlite3Strlen30(pCol->zCnName); | 142763 | n = sqlite3Strlen30(pCol->zCnName); |
| 137897 | pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); | 142764 | pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); |
| 142765 | pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); | ||
| 137898 | if( pCol->zCnName ){ | 142766 | if( pCol->zCnName ){ |
| 137899 | memcpy(&pCol->zCnName[n+1], zType, m+1); | 142767 | memcpy(&pCol->zCnName[n+1], zType, m+1); |
| 137900 | pCol->colFlags |= COLFLAG_HASTYPE; | 142768 | pCol->colFlags |= COLFLAG_HASTYPE; |
| 137901 | }else{ | ||
| 137902 | testcase( pCol->colFlags & COLFLAG_HASTYPE ); | ||
| 137903 | pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); | ||
| 137904 | } | 142769 | } |
| 137905 | } | 142770 | } |
| 137906 | if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff; | ||
| 137907 | pColl = sqlite3ExprCollSeq(pParse, p); | 142771 | pColl = sqlite3ExprCollSeq(pParse, p); |
| 137908 | if( pColl ){ | 142772 | if( pColl ){ |
| 137909 | assert( pTab->pIndex==0 ); | 142773 | assert( pTab->pIndex==0 ); |
| @@ -137937,7 +142801,7 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, c | |||
| 137937 | pTab->zName = 0; | 142801 | pTab->zName = 0; |
| 137938 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); | 142802 | pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); |
| 137939 | sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); | 142803 | sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); |
| 137940 | sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff); | 142804 | sqlite3SubqueryColumnTypes(pParse, pTab, pSelect, aff); |
| 137941 | pTab->iPKey = -1; | 142805 | pTab->iPKey = -1; |
| 137942 | if( db->mallocFailed ){ | 142806 | if( db->mallocFailed ){ |
| 137943 | sqlite3DeleteTable(db, pTab); | 142807 | sqlite3DeleteTable(db, pTab); |
| @@ -138152,7 +143016,7 @@ static void generateWithRecursiveQuery( | |||
| 138152 | int iQueue; /* The Queue table */ | 143016 | int iQueue; /* The Queue table */ |
| 138153 | int iDistinct = 0; /* To ensure unique results if UNION */ | 143017 | int iDistinct = 0; /* To ensure unique results if UNION */ |
| 138154 | int eDest = SRT_Fifo; /* How to write to Queue */ | 143018 | int eDest = SRT_Fifo; /* How to write to Queue */ |
| 138155 | SelectDest destQueue; /* SelectDest targetting the Queue table */ | 143019 | SelectDest destQueue; /* SelectDest targeting the Queue table */ |
| 138156 | int i; /* Loop counter */ | 143020 | int i; /* Loop counter */ |
| 138157 | int rc; /* Result code */ | 143021 | int rc; /* Result code */ |
| 138158 | ExprList *pOrderBy; /* The ORDER BY clause */ | 143022 | ExprList *pOrderBy; /* The ORDER BY clause */ |
| @@ -138462,7 +143326,7 @@ static int multiSelect( | |||
| 138462 | pPrior->iLimit = p->iLimit; | 143326 | pPrior->iLimit = p->iLimit; |
| 138463 | pPrior->iOffset = p->iOffset; | 143327 | pPrior->iOffset = p->iOffset; |
| 138464 | pPrior->pLimit = p->pLimit; | 143328 | pPrior->pLimit = p->pLimit; |
| 138465 | SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL left...\n")); | 143329 | TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n")); |
| 138466 | rc = sqlite3Select(pParse, pPrior, &dest); | 143330 | rc = sqlite3Select(pParse, pPrior, &dest); |
| 138467 | pPrior->pLimit = 0; | 143331 | pPrior->pLimit = 0; |
| 138468 | if( rc ){ | 143332 | if( rc ){ |
| @@ -138480,7 +143344,7 @@ static int multiSelect( | |||
| 138480 | } | 143344 | } |
| 138481 | } | 143345 | } |
| 138482 | ExplainQueryPlan((pParse, 1, "UNION ALL")); | 143346 | ExplainQueryPlan((pParse, 1, "UNION ALL")); |
| 138483 | SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL right...\n")); | 143347 | TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); |
| 138484 | rc = sqlite3Select(pParse, p, &dest); | 143348 | rc = sqlite3Select(pParse, p, &dest); |
| 138485 | testcase( rc!=SQLITE_OK ); | 143349 | testcase( rc!=SQLITE_OK ); |
| 138486 | pDelete = p->pPrior; | 143350 | pDelete = p->pPrior; |
| @@ -138533,7 +143397,7 @@ static int multiSelect( | |||
| 138533 | */ | 143397 | */ |
| 138534 | assert( !pPrior->pOrderBy ); | 143398 | assert( !pPrior->pOrderBy ); |
| 138535 | sqlite3SelectDestInit(&uniondest, priorOp, unionTab); | 143399 | sqlite3SelectDestInit(&uniondest, priorOp, unionTab); |
| 138536 | SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); | 143400 | TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); |
| 138537 | rc = sqlite3Select(pParse, pPrior, &uniondest); | 143401 | rc = sqlite3Select(pParse, pPrior, &uniondest); |
| 138538 | if( rc ){ | 143402 | if( rc ){ |
| 138539 | goto multi_select_end; | 143403 | goto multi_select_end; |
| @@ -138553,7 +143417,7 @@ static int multiSelect( | |||
| 138553 | uniondest.eDest = op; | 143417 | uniondest.eDest = op; |
| 138554 | ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", | 143418 | ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", |
| 138555 | sqlite3SelectOpName(p->op))); | 143419 | sqlite3SelectOpName(p->op))); |
| 138556 | SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); | 143420 | TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); |
| 138557 | rc = sqlite3Select(pParse, p, &uniondest); | 143421 | rc = sqlite3Select(pParse, p, &uniondest); |
| 138558 | testcase( rc!=SQLITE_OK ); | 143422 | testcase( rc!=SQLITE_OK ); |
| 138559 | assert( p->pOrderBy==0 ); | 143423 | assert( p->pOrderBy==0 ); |
| @@ -138614,7 +143478,7 @@ static int multiSelect( | |||
| 138614 | /* Code the SELECTs to our left into temporary table "tab1". | 143478 | /* Code the SELECTs to our left into temporary table "tab1". |
| 138615 | */ | 143479 | */ |
| 138616 | sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); | 143480 | sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); |
| 138617 | SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT left...\n")); | 143481 | TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n")); |
| 138618 | rc = sqlite3Select(pParse, pPrior, &intersectdest); | 143482 | rc = sqlite3Select(pParse, pPrior, &intersectdest); |
| 138619 | if( rc ){ | 143483 | if( rc ){ |
| 138620 | goto multi_select_end; | 143484 | goto multi_select_end; |
| @@ -138631,7 +143495,7 @@ static int multiSelect( | |||
| 138631 | intersectdest.iSDParm = tab2; | 143495 | intersectdest.iSDParm = tab2; |
| 138632 | ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", | 143496 | ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", |
| 138633 | sqlite3SelectOpName(p->op))); | 143497 | sqlite3SelectOpName(p->op))); |
| 138634 | SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT right...\n")); | 143498 | TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT right...\n")); |
| 138635 | rc = sqlite3Select(pParse, p, &intersectdest); | 143499 | rc = sqlite3Select(pParse, p, &intersectdest); |
| 138636 | testcase( rc!=SQLITE_OK ); | 143500 | testcase( rc!=SQLITE_OK ); |
| 138637 | pDelete = p->pPrior; | 143501 | pDelete = p->pPrior; |
| @@ -138752,7 +143616,7 @@ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ | |||
| 138752 | 143616 | ||
| 138753 | /* | 143617 | /* |
| 138754 | ** Code an output subroutine for a coroutine implementation of a | 143618 | ** Code an output subroutine for a coroutine implementation of a |
| 138755 | ** SELECT statment. | 143619 | ** SELECT statement. |
| 138756 | ** | 143620 | ** |
| 138757 | ** The data to be output is contained in pIn->iSdst. There are | 143621 | ** The data to be output is contained in pIn->iSdst. There are |
| 138758 | ** pIn->nSdst columns to be output. pDest is where the output should | 143622 | ** pIn->nSdst columns to be output. pDest is where the output should |
| @@ -138974,7 +143838,7 @@ static int generateOutputSubroutine( | |||
| 138974 | ** | 143838 | ** |
| 138975 | ** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not | 143839 | ** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not |
| 138976 | ** actually called using Gosub and they do not Return. EofA and EofB loop | 143840 | ** actually called using Gosub and they do not Return. EofA and EofB loop |
| 138977 | ** until all data is exhausted then jump to the "end" labe. AltB, AeqB, | 143841 | ** until all data is exhausted then jump to the "end" label. AltB, AeqB, |
| 138978 | ** and AgtB jump to either L2 or to one of EofA or EofB. | 143842 | ** and AgtB jump to either L2 or to one of EofA or EofB. |
| 138979 | */ | 143843 | */ |
| 138980 | #ifndef SQLITE_OMIT_COMPOUND_SELECT | 143844 | #ifndef SQLITE_OMIT_COMPOUND_SELECT |
| @@ -139011,7 +143875,7 @@ static int multiSelectOrderBy( | |||
| 139011 | int savedOffset; /* Saved value of p->iOffset */ | 143875 | int savedOffset; /* Saved value of p->iOffset */ |
| 139012 | int labelCmpr; /* Label for the start of the merge algorithm */ | 143876 | int labelCmpr; /* Label for the start of the merge algorithm */ |
| 139013 | int labelEnd; /* Label for the end of the overall SELECT stmt */ | 143877 | int labelEnd; /* Label for the end of the overall SELECT stmt */ |
| 139014 | int addr1; /* Jump instructions that get retargetted */ | 143878 | int addr1; /* Jump instructions that get retargeted */ |
| 139015 | int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ | 143879 | int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ |
| 139016 | KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ | 143880 | KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ |
| 139017 | KeyInfo *pKeyMerge; /* Comparison information for merging rows */ | 143881 | KeyInfo *pKeyMerge; /* Comparison information for merging rows */ |
| @@ -139278,8 +144142,8 @@ static int multiSelectOrderBy( | |||
| 139278 | */ | 144142 | */ |
| 139279 | sqlite3VdbeResolveLabel(v, labelEnd); | 144143 | sqlite3VdbeResolveLabel(v, labelEnd); |
| 139280 | 144144 | ||
| 139281 | /* Reassemble the compound query so that it will be freed correctly | 144145 | /* Make arrangements to free the 2nd and subsequent arms of the compound |
| 139282 | ** by the calling function */ | 144146 | ** after the parse has finished */ |
| 139283 | if( pSplit->pPrior ){ | 144147 | if( pSplit->pPrior ){ |
| 139284 | sqlite3ParserAddCleanup(pParse, | 144148 | sqlite3ParserAddCleanup(pParse, |
| 139285 | (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); | 144149 | (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); |
| @@ -139312,7 +144176,7 @@ static int multiSelectOrderBy( | |||
| 139312 | ** the left operands of a RIGHT JOIN. In either case, we need to potentially | 144176 | ** the left operands of a RIGHT JOIN. In either case, we need to potentially |
| 139313 | ** bypass the substituted expression with OP_IfNullRow. | 144177 | ** bypass the substituted expression with OP_IfNullRow. |
| 139314 | ** | 144178 | ** |
| 139315 | ** Suppose the original expression integer constant. Even though the table | 144179 | ** Suppose the original expression is an integer constant. Even though the table |
| 139316 | ** has the nullRow flag set, because the expression is an integer constant, | 144180 | ** has the nullRow flag set, because the expression is an integer constant, |
| 139317 | ** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode | 144181 | ** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode |
| 139318 | ** that checks to see if the nullRow flag is set on the table. If the nullRow | 144182 | ** that checks to see if the nullRow flag is set on the table. If the nullRow |
| @@ -139338,6 +144202,7 @@ typedef struct SubstContext { | |||
| 139338 | int iNewTable; /* New table number */ | 144202 | int iNewTable; /* New table number */ |
| 139339 | int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ | 144203 | int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ |
| 139340 | ExprList *pEList; /* Replacement expressions */ | 144204 | ExprList *pEList; /* Replacement expressions */ |
| 144205 | ExprList *pCList; /* Collation sequences for replacement expr */ | ||
| 139341 | } SubstContext; | 144206 | } SubstContext; |
| 139342 | 144207 | ||
| 139343 | /* Forward Declarations */ | 144208 | /* Forward Declarations */ |
| @@ -139379,19 +144244,26 @@ static Expr *substExpr( | |||
| 139379 | #endif | 144244 | #endif |
| 139380 | { | 144245 | { |
| 139381 | Expr *pNew; | 144246 | Expr *pNew; |
| 139382 | Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr; | 144247 | int iColumn; |
| 144248 | Expr *pCopy; | ||
| 139383 | Expr ifNullRow; | 144249 | Expr ifNullRow; |
| 139384 | assert( pSubst->pEList!=0 && pExpr->iColumn<pSubst->pEList->nExpr ); | 144250 | iColumn = pExpr->iColumn; |
| 144251 | assert( iColumn>=0 ); | ||
| 144252 | assert( pSubst->pEList!=0 && iColumn<pSubst->pEList->nExpr ); | ||
| 139385 | assert( pExpr->pRight==0 ); | 144253 | assert( pExpr->pRight==0 ); |
| 144254 | pCopy = pSubst->pEList->a[iColumn].pExpr; | ||
| 139386 | if( sqlite3ExprIsVector(pCopy) ){ | 144255 | if( sqlite3ExprIsVector(pCopy) ){ |
| 139387 | sqlite3VectorErrorMsg(pSubst->pParse, pCopy); | 144256 | sqlite3VectorErrorMsg(pSubst->pParse, pCopy); |
| 139388 | }else{ | 144257 | }else{ |
| 139389 | sqlite3 *db = pSubst->pParse->db; | 144258 | sqlite3 *db = pSubst->pParse->db; |
| 139390 | if( pSubst->isOuterJoin && pCopy->op!=TK_COLUMN ){ | 144259 | if( pSubst->isOuterJoin |
| 144260 | && (pCopy->op!=TK_COLUMN || pCopy->iTable!=pSubst->iNewTable) | ||
| 144261 | ){ | ||
| 139391 | memset(&ifNullRow, 0, sizeof(ifNullRow)); | 144262 | memset(&ifNullRow, 0, sizeof(ifNullRow)); |
| 139392 | ifNullRow.op = TK_IF_NULL_ROW; | 144263 | ifNullRow.op = TK_IF_NULL_ROW; |
| 139393 | ifNullRow.pLeft = pCopy; | 144264 | ifNullRow.pLeft = pCopy; |
| 139394 | ifNullRow.iTable = pSubst->iNewTable; | 144265 | ifNullRow.iTable = pSubst->iNewTable; |
| 144266 | ifNullRow.iColumn = -99; | ||
| 139395 | ifNullRow.flags = EP_IfNullRow; | 144267 | ifNullRow.flags = EP_IfNullRow; |
| 139396 | pCopy = &ifNullRow; | 144268 | pCopy = &ifNullRow; |
| 139397 | } | 144269 | } |
| @@ -139418,11 +144290,16 @@ static Expr *substExpr( | |||
| 139418 | 144290 | ||
| 139419 | /* Ensure that the expression now has an implicit collation sequence, | 144291 | /* Ensure that the expression now has an implicit collation sequence, |
| 139420 | ** just as it did when it was a column of a view or sub-query. */ | 144292 | ** just as it did when it was a column of a view or sub-query. */ |
| 139421 | if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ | 144293 | { |
| 139422 | CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); | 144294 | CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pExpr); |
| 139423 | pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, | 144295 | CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, |
| 139424 | (pColl ? pColl->zName : "BINARY") | 144296 | pSubst->pCList->a[iColumn].pExpr |
| 139425 | ); | 144297 | ); |
| 144298 | if( pNat!=pColl || (pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE) ){ | ||
| 144299 | pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, | ||
| 144300 | (pColl ? pColl->zName : "BINARY") | ||
| 144301 | ); | ||
| 144302 | } | ||
| 139426 | } | 144303 | } |
| 139427 | ExprClearProperty(pExpr, EP_Collate); | 144304 | ExprClearProperty(pExpr, EP_Collate); |
| 139428 | } | 144305 | } |
| @@ -139615,6 +144492,46 @@ static void renumberCursors( | |||
| 139615 | } | 144492 | } |
| 139616 | #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ | 144493 | #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ |
| 139617 | 144494 | ||
| 144495 | /* | ||
| 144496 | ** If pSel is not part of a compound SELECT, return a pointer to its | ||
| 144497 | ** expression list. Otherwise, return a pointer to the expression list | ||
| 144498 | ** of the leftmost SELECT in the compound. | ||
| 144499 | */ | ||
| 144500 | static ExprList *findLeftmostExprlist(Select *pSel){ | ||
| 144501 | while( pSel->pPrior ){ | ||
| 144502 | pSel = pSel->pPrior; | ||
| 144503 | } | ||
| 144504 | return pSel->pEList; | ||
| 144505 | } | ||
| 144506 | |||
| 144507 | /* | ||
| 144508 | ** Return true if any of the result-set columns in the compound query | ||
| 144509 | ** have incompatible affinities on one or more arms of the compound. | ||
| 144510 | */ | ||
| 144511 | static int compoundHasDifferentAffinities(Select *p){ | ||
| 144512 | int ii; | ||
| 144513 | ExprList *pList; | ||
| 144514 | assert( p!=0 ); | ||
| 144515 | assert( p->pEList!=0 ); | ||
| 144516 | assert( p->pPrior!=0 ); | ||
| 144517 | pList = p->pEList; | ||
| 144518 | for(ii=0; ii<pList->nExpr; ii++){ | ||
| 144519 | char aff; | ||
| 144520 | Select *pSub1; | ||
| 144521 | assert( pList->a[ii].pExpr!=0 ); | ||
| 144522 | aff = sqlite3ExprAffinity(pList->a[ii].pExpr); | ||
| 144523 | for(pSub1=p->pPrior; pSub1; pSub1=pSub1->pPrior){ | ||
| 144524 | assert( pSub1->pEList!=0 ); | ||
| 144525 | assert( pSub1->pEList->nExpr>ii ); | ||
| 144526 | assert( pSub1->pEList->a[ii].pExpr!=0 ); | ||
| 144527 | if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){ | ||
| 144528 | return 1; | ||
| 144529 | } | ||
| 144530 | } | ||
| 144531 | } | ||
| 144532 | return 0; | ||
| 144533 | } | ||
| 144534 | |||
| 139618 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) | 144535 | #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) |
| 139619 | /* | 144536 | /* |
| 139620 | ** This routine attempts to flatten subqueries as a performance optimization. | 144537 | ** This routine attempts to flatten subqueries as a performance optimization. |
| @@ -139659,7 +144576,8 @@ static void renumberCursors( | |||
| 139659 | ** (3a) the subquery may not be a join and | 144576 | ** (3a) the subquery may not be a join and |
| 139660 | ** (3b) the FROM clause of the subquery may not contain a virtual | 144577 | ** (3b) the FROM clause of the subquery may not contain a virtual |
| 139661 | ** table and | 144578 | ** table and |
| 139662 | ** (3c) the outer query may not be an aggregate. | 144579 | ** (**) Was: "The outer query may not have a GROUP BY." This case |
| 144580 | ** is now managed correctly | ||
| 139663 | ** (3d) the outer query may not be DISTINCT. | 144581 | ** (3d) the outer query may not be DISTINCT. |
| 139664 | ** See also (26) for restrictions on RIGHT JOIN. | 144582 | ** See also (26) for restrictions on RIGHT JOIN. |
| 139665 | ** | 144583 | ** |
| @@ -139682,7 +144600,7 @@ static void renumberCursors( | |||
| 139682 | ** (9) If the subquery uses LIMIT then the outer query may not be aggregate. | 144600 | ** (9) If the subquery uses LIMIT then the outer query may not be aggregate. |
| 139683 | ** | 144601 | ** |
| 139684 | ** (**) Restriction (10) was removed from the code on 2005-02-05 but we | 144602 | ** (**) Restriction (10) was removed from the code on 2005-02-05 but we |
| 139685 | ** accidently carried the comment forward until 2014-09-15. Original | 144603 | ** accidentally carried the comment forward until 2014-09-15. Original |
| 139686 | ** constraint: "If the subquery is aggregate then the outer query | 144604 | ** constraint: "If the subquery is aggregate then the outer query |
| 139687 | ** may not use LIMIT." | 144605 | ** may not use LIMIT." |
| 139688 | ** | 144606 | ** |
| @@ -139716,6 +144634,8 @@ static void renumberCursors( | |||
| 139716 | ** (17g) either the subquery is the first element of the outer | 144634 | ** (17g) either the subquery is the first element of the outer |
| 139717 | ** query or there are no RIGHT or FULL JOINs in any arm | 144635 | ** query or there are no RIGHT or FULL JOINs in any arm |
| 139718 | ** of the subquery. (This is a duplicate of condition (27b).) | 144636 | ** of the subquery. (This is a duplicate of condition (27b).) |
| 144637 | ** (17h) The corresponding result set expressions in all arms of the | ||
| 144638 | ** compound must have the same affinity. | ||
| 139719 | ** | 144639 | ** |
| 139720 | ** The parent and sub-query may contain WHERE clauses. Subject to | 144640 | ** The parent and sub-query may contain WHERE clauses. Subject to |
| 139721 | ** rules (11), (13) and (14), they may also contain ORDER BY, | 144641 | ** rules (11), (13) and (14), they may also contain ORDER BY, |
| @@ -139767,18 +144687,13 @@ static void renumberCursors( | |||
| 139767 | ** See also (3) for restrictions on LEFT JOIN. | 144687 | ** See also (3) for restrictions on LEFT JOIN. |
| 139768 | ** | 144688 | ** |
| 139769 | ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it | 144689 | ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it |
| 139770 | ** is the first element of the parent query. This must be the | 144690 | ** is the first element of the parent query. Two subcases: |
| 139771 | ** the case if: | 144691 | ** (27a) the subquery is not a compound query. |
| 139772 | ** (27a) the subquery is not compound query, and | ||
| 139773 | ** (27b) the subquery is a compound query and the RIGHT JOIN occurs | 144692 | ** (27b) the subquery is a compound query and the RIGHT JOIN occurs |
| 139774 | ** in any arm of the compound query. (See also (17g).) | 144693 | ** in any arm of the compound query. (See also (17g).) |
| 139775 | ** | 144694 | ** |
| 139776 | ** (28) The subquery is not a MATERIALIZED CTE. | 144695 | ** (28) The subquery is not a MATERIALIZED CTE. (This is handled |
| 139777 | ** | 144696 | ** in the caller before ever reaching this routine.) |
| 139778 | ** (29) Either the subquery is not the right-hand operand of a join with an | ||
| 139779 | ** ON or USING clause nor the right-hand operand of a NATURAL JOIN, or | ||
| 139780 | ** the right-most table within the FROM clause of the subquery | ||
| 139781 | ** is not part of an outer join. | ||
| 139782 | ** | 144697 | ** |
| 139783 | ** | 144698 | ** |
| 139784 | ** In this routine, the "p" parameter is a pointer to the outer query. | 144699 | ** In this routine, the "p" parameter is a pointer to the outer query. |
| @@ -139871,16 +144786,10 @@ static int flattenSubquery( | |||
| 139871 | ** | 144786 | ** |
| 139872 | ** which is not at all the same thing. | 144787 | ** which is not at all the same thing. |
| 139873 | ** | 144788 | ** |
| 139874 | ** If the subquery is the right operand of a LEFT JOIN, then the outer | ||
| 139875 | ** query cannot be an aggregate. (3c) This is an artifact of the way | ||
| 139876 | ** aggregates are processed - there is no mechanism to determine if | ||
| 139877 | ** the LEFT JOIN table should be all-NULL. | ||
| 139878 | ** | ||
| 139879 | ** See also tickets #306, #350, and #3300. | 144789 | ** See also tickets #306, #350, and #3300. |
| 139880 | */ | 144790 | */ |
| 139881 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ | 144791 | if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ |
| 139882 | if( pSubSrc->nSrc>1 /* (3a) */ | 144792 | if( pSubSrc->nSrc>1 /* (3a) */ |
| 139883 | || isAgg /* (3c) */ | ||
| 139884 | || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ | 144793 | || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ |
| 139885 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ | 144794 | || (p->selFlags & SF_Distinct)!=0 /* (3d) */ |
| 139886 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ | 144795 | || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ |
| @@ -139889,52 +144798,14 @@ static int flattenSubquery( | |||
| 139889 | } | 144798 | } |
| 139890 | isOuterJoin = 1; | 144799 | isOuterJoin = 1; |
| 139891 | } | 144800 | } |
| 139892 | #ifdef SQLITE_EXTRA_IFNULLROW | ||
| 139893 | else if( iFrom>0 && !isAgg ){ | ||
| 139894 | /* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for | ||
| 139895 | ** every reference to any result column from subquery in a join, even | ||
| 139896 | ** though they are not necessary. This will stress-test the OP_IfNullRow | ||
| 139897 | ** opcode. */ | ||
| 139898 | isOuterJoin = -1; | ||
| 139899 | } | ||
| 139900 | #endif | ||
| 139901 | 144801 | ||
| 139902 | assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ | 144802 | assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ |
| 139903 | if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ | 144803 | if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ |
| 139904 | return 0; /* Restriction (27a) */ | 144804 | return 0; /* Restriction (27a) */ |
| 139905 | } | 144805 | } |
| 139906 | if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ | ||
| 139907 | return 0; /* (28) */ | ||
| 139908 | } | ||
| 139909 | 144806 | ||
| 139910 | /* Restriction (29): | 144807 | /* Condition (28) is blocked by the caller */ |
| 139911 | ** | 144808 | assert( !pSubitem->fg.isCte || pSubitem->u2.pCteUse->eM10d!=M10d_Yes ); |
| 139912 | ** We do not want two constraints on the same term of the flattened | ||
| 139913 | ** query where one constraint has EP_InnerON and the other is EP_OuterON. | ||
| 139914 | ** To prevent this, one or the other of the following conditions must be | ||
| 139915 | ** false: | ||
| 139916 | ** | ||
| 139917 | ** (29a) The right-most entry in the FROM clause of the subquery | ||
| 139918 | ** must not be part of an outer join. | ||
| 139919 | ** | ||
| 139920 | ** (29b) The subquery itself must not be the right operand of a | ||
| 139921 | ** NATURAL join or a join that as an ON or USING clause. | ||
| 139922 | ** | ||
| 139923 | ** These conditions are sufficient to keep an EP_OuterON from being | ||
| 139924 | ** flattened into an EP_InnerON. Restrictions (3a) and (27a) prevent | ||
| 139925 | ** an EP_InnerON from being flattened into an EP_OuterON. | ||
| 139926 | */ | ||
| 139927 | if( pSubSrc->nSrc>=2 | ||
| 139928 | && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0 | ||
| 139929 | ){ | ||
| 139930 | if( (pSubitem->fg.jointype & JT_NATURAL)!=0 | ||
| 139931 | || pSubitem->fg.isUsing | ||
| 139932 | || NEVER(pSubitem->u3.pOn!=0) /* ON clause already shifted into WHERE */ | ||
| 139933 | || pSubitem->fg.isOn | ||
| 139934 | ){ | ||
| 139935 | return 0; | ||
| 139936 | } | ||
| 139937 | } | ||
| 139938 | 144809 | ||
| 139939 | /* Restriction (17): If the sub-query is a compound SELECT, then it must | 144810 | /* Restriction (17): If the sub-query is a compound SELECT, then it must |
| 139940 | ** use only the UNION ALL operator. And none of the simple select queries | 144811 | ** use only the UNION ALL operator. And none of the simple select queries |
| @@ -139942,6 +144813,7 @@ static int flattenSubquery( | |||
| 139942 | ** queries. | 144813 | ** queries. |
| 139943 | */ | 144814 | */ |
| 139944 | if( pSub->pPrior ){ | 144815 | if( pSub->pPrior ){ |
| 144816 | int ii; | ||
| 139945 | if( pSub->pOrderBy ){ | 144817 | if( pSub->pOrderBy ){ |
| 139946 | return 0; /* Restriction (20) */ | 144818 | return 0; /* Restriction (20) */ |
| 139947 | } | 144819 | } |
| @@ -139974,7 +144846,6 @@ static int flattenSubquery( | |||
| 139974 | 144846 | ||
| 139975 | /* Restriction (18). */ | 144847 | /* Restriction (18). */ |
| 139976 | if( p->pOrderBy ){ | 144848 | if( p->pOrderBy ){ |
| 139977 | int ii; | ||
| 139978 | for(ii=0; ii<p->pOrderBy->nExpr; ii++){ | 144849 | for(ii=0; ii<p->pOrderBy->nExpr; ii++){ |
| 139979 | if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; | 144850 | if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; |
| 139980 | } | 144851 | } |
| @@ -139983,6 +144854,9 @@ static int flattenSubquery( | |||
| 139983 | /* Restriction (23) */ | 144854 | /* Restriction (23) */ |
| 139984 | if( (p->selFlags & SF_Recursive) ) return 0; | 144855 | if( (p->selFlags & SF_Recursive) ) return 0; |
| 139985 | 144856 | ||
| 144857 | /* Restriction (17h) */ | ||
| 144858 | if( compoundHasDifferentAffinities(pSub) ) return 0; | ||
| 144859 | |||
| 139986 | if( pSrc->nSrc>1 ){ | 144860 | if( pSrc->nSrc>1 ){ |
| 139987 | if( pParse->nSelect>500 ) return 0; | 144861 | if( pParse->nSelect>500 ) return 0; |
| 139988 | if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0; | 144862 | if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0; |
| @@ -139992,7 +144866,7 @@ static int flattenSubquery( | |||
| 139992 | } | 144866 | } |
| 139993 | 144867 | ||
| 139994 | /***** If we reach this point, flattening is permitted. *****/ | 144868 | /***** If we reach this point, flattening is permitted. *****/ |
| 139995 | SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", | 144869 | TREETRACE(0x4,pParse,p,("flatten %u.%p from term %d\n", |
| 139996 | pSub->selId, pSub, iFrom)); | 144870 | pSub->selId, pSub, iFrom)); |
| 139997 | 144871 | ||
| 139998 | /* Authorize the subquery */ | 144872 | /* Authorize the subquery */ |
| @@ -140001,7 +144875,7 @@ static int flattenSubquery( | |||
| 140001 | testcase( i==SQLITE_DENY ); | 144875 | testcase( i==SQLITE_DENY ); |
| 140002 | pParse->zAuthContext = zSavedAuthContext; | 144876 | pParse->zAuthContext = zSavedAuthContext; |
| 140003 | 144877 | ||
| 140004 | /* Delete the transient structures associated with thesubquery */ | 144878 | /* Delete the transient structures associated with the subquery */ |
| 140005 | pSub1 = pSubitem->pSelect; | 144879 | pSub1 = pSubitem->pSelect; |
| 140006 | sqlite3DbFree(db, pSubitem->zDatabase); | 144880 | sqlite3DbFree(db, pSubitem->zDatabase); |
| 140007 | sqlite3DbFree(db, pSubitem->zName); | 144881 | sqlite3DbFree(db, pSubitem->zName); |
| @@ -140071,7 +144945,7 @@ static int flattenSubquery( | |||
| 140071 | if( pPrior ) pPrior->pNext = pNew; | 144945 | if( pPrior ) pPrior->pNext = pNew; |
| 140072 | pNew->pNext = p; | 144946 | pNew->pNext = p; |
| 140073 | p->pPrior = pNew; | 144947 | p->pPrior = pNew; |
| 140074 | SELECTTRACE(2,pParse,p,("compound-subquery flattener" | 144948 | TREETRACE(0x4,pParse,p,("compound-subquery flattener" |
| 140075 | " creates %u as peer\n",pNew->selId)); | 144949 | " creates %u as peer\n",pNew->selId)); |
| 140076 | } | 144950 | } |
| 140077 | assert( pSubitem->pSelect==0 ); | 144951 | assert( pSubitem->pSelect==0 ); |
| @@ -140183,7 +145057,7 @@ static int flattenSubquery( | |||
| 140183 | ** ORDER BY column expression is identical to the iOrderByCol'th | 145057 | ** ORDER BY column expression is identical to the iOrderByCol'th |
| 140184 | ** expression returned by SELECT statement pSub. Since these values | 145058 | ** expression returned by SELECT statement pSub. Since these values |
| 140185 | ** do not necessarily correspond to columns in SELECT statement pParent, | 145059 | ** do not necessarily correspond to columns in SELECT statement pParent, |
| 140186 | ** zero them before transfering the ORDER BY clause. | 145060 | ** zero them before transferring the ORDER BY clause. |
| 140187 | ** | 145061 | ** |
| 140188 | ** Not doing this may cause an error if a subsequent call to this | 145062 | ** Not doing this may cause an error if a subsequent call to this |
| 140189 | ** function attempts to flatten a compound sub-query into pParent | 145063 | ** function attempts to flatten a compound sub-query into pParent |
| @@ -140216,6 +145090,7 @@ static int flattenSubquery( | |||
| 140216 | x.iNewTable = iNewParent; | 145090 | x.iNewTable = iNewParent; |
| 140217 | x.isOuterJoin = isOuterJoin; | 145091 | x.isOuterJoin = isOuterJoin; |
| 140218 | x.pEList = pSub->pEList; | 145092 | x.pEList = pSub->pEList; |
| 145093 | x.pCList = findLeftmostExprlist(pSub); | ||
| 140219 | substSelect(&x, pParent, 0); | 145094 | substSelect(&x, pParent, 0); |
| 140220 | } | 145095 | } |
| 140221 | 145096 | ||
| @@ -140235,23 +145110,22 @@ static int flattenSubquery( | |||
| 140235 | pSub->pLimit = 0; | 145110 | pSub->pLimit = 0; |
| 140236 | } | 145111 | } |
| 140237 | 145112 | ||
| 140238 | /* Recompute the SrcList_item.colUsed masks for the flattened | 145113 | /* Recompute the SrcItem.colUsed masks for the flattened |
| 140239 | ** tables. */ | 145114 | ** tables. */ |
| 140240 | for(i=0; i<nSubSrc; i++){ | 145115 | for(i=0; i<nSubSrc; i++){ |
| 140241 | recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]); | 145116 | recomputeColumnsUsed(pParent, &pSrc->a[i+iFrom]); |
| 140242 | } | 145117 | } |
| 140243 | } | 145118 | } |
| 140244 | 145119 | ||
| 140245 | /* Finially, delete what is left of the subquery and return | 145120 | /* Finally, delete what is left of the subquery and return success. |
| 140246 | ** success. | ||
| 140247 | */ | 145121 | */ |
| 140248 | sqlite3AggInfoPersistWalkerInit(&w, pParse); | 145122 | sqlite3AggInfoPersistWalkerInit(&w, pParse); |
| 140249 | sqlite3WalkSelect(&w,pSub1); | 145123 | sqlite3WalkSelect(&w,pSub1); |
| 140250 | sqlite3SelectDelete(db, pSub1); | 145124 | sqlite3SelectDelete(db, pSub1); |
| 140251 | 145125 | ||
| 140252 | #if TREETRACE_ENABLED | 145126 | #if TREETRACE_ENABLED |
| 140253 | if( sqlite3TreeTrace & 0x100 ){ | 145127 | if( sqlite3TreeTrace & 0x4 ){ |
| 140254 | SELECTTRACE(0x100,pParse,p,("After flattening:\n")); | 145128 | TREETRACE(0x4,pParse,p,("After flattening:\n")); |
| 140255 | sqlite3TreeViewSelect(0, p, 0); | 145129 | sqlite3TreeViewSelect(0, p, 0); |
| 140256 | } | 145130 | } |
| 140257 | #endif | 145131 | #endif |
| @@ -140278,7 +145152,7 @@ struct WhereConst { | |||
| 140278 | 145152 | ||
| 140279 | /* | 145153 | /* |
| 140280 | ** Add a new entry to the pConst object. Except, do not add duplicate | 145154 | ** Add a new entry to the pConst object. Except, do not add duplicate |
| 140281 | ** pColumn entires. Also, do not add if doing so would not be appropriate. | 145155 | ** pColumn entries. Also, do not add if doing so would not be appropriate. |
| 140282 | ** | 145156 | ** |
| 140283 | ** The caller guarantees the pColumn is a column and pValue is a constant. | 145157 | ** The caller guarantees the pColumn is a column and pValue is a constant. |
| 140284 | ** This routine has to do some additional checks before completing the | 145158 | ** This routine has to do some additional checks before completing the |
| @@ -140464,7 +145338,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ | |||
| 140464 | ** SELECT * FROM t1 WHERE a=123 AND b=123; | 145338 | ** SELECT * FROM t1 WHERE a=123 AND b=123; |
| 140465 | ** | 145339 | ** |
| 140466 | ** The two SELECT statements above should return different answers. b=a | 145340 | ** The two SELECT statements above should return different answers. b=a |
| 140467 | ** is alway true because the comparison uses numeric affinity, but b=123 | 145341 | ** is always true because the comparison uses numeric affinity, but b=123 |
| 140468 | ** is false because it uses text affinity and '0123' is not the same as '123'. | 145342 | ** is false because it uses text affinity and '0123' is not the same as '123'. |
| 140469 | ** To work around this, the expression tree is not actually changed from | 145343 | ** To work around this, the expression tree is not actually changed from |
| 140470 | ** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol | 145344 | ** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol |
| @@ -140548,7 +145422,7 @@ static int propagateConstants( | |||
| 140548 | ** At the time this function is called it is guaranteed that | 145422 | ** At the time this function is called it is guaranteed that |
| 140549 | ** | 145423 | ** |
| 140550 | ** * the sub-query uses only one distinct window frame, and | 145424 | ** * the sub-query uses only one distinct window frame, and |
| 140551 | ** * that the window frame has a PARTITION BY clase. | 145425 | ** * that the window frame has a PARTITION BY clause. |
| 140552 | */ | 145426 | */ |
| 140553 | static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ | 145427 | static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ |
| 140554 | assert( pSubq->pWin->pPartition ); | 145428 | assert( pSubq->pWin->pPartition ); |
| @@ -140625,6 +145499,29 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ | |||
| 140625 | ** be materialized. (This restriction is implemented in the calling | 145499 | ** be materialized. (This restriction is implemented in the calling |
| 140626 | ** routine.) | 145500 | ** routine.) |
| 140627 | ** | 145501 | ** |
| 145502 | ** (8) If the subquery is a compound that uses UNION, INTERSECT, | ||
| 145503 | ** or EXCEPT, then all of the result set columns for all arms of | ||
| 145504 | ** the compound must use the BINARY collating sequence. | ||
| 145505 | ** | ||
| 145506 | ** (9) All three of the following are true: | ||
| 145507 | ** | ||
| 145508 | ** (9a) The WHERE clause expression originates in the ON or USING clause | ||
| 145509 | ** of a join (either an INNER or an OUTER join), and | ||
| 145510 | ** | ||
| 145511 | ** (9b) The subquery is to the right of the ON/USING clause | ||
| 145512 | ** | ||
| 145513 | ** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING | ||
| 145514 | ** clause and the subquery. | ||
| 145515 | ** | ||
| 145516 | ** Without this restriction, the push-down optimization might move | ||
| 145517 | ** the ON/USING filter expression from the left side of a RIGHT JOIN | ||
| 145518 | ** over to the right side, which leads to incorrect answers. See | ||
| 145519 | ** also restriction (6) in sqlite3ExprIsSingleTableConstraint(). | ||
| 145520 | ** | ||
| 145521 | ** (10) The inner query is not the right-hand table of a RIGHT JOIN. | ||
| 145522 | ** | ||
| 145523 | ** (11) The subquery is not a VALUES clause | ||
| 145524 | ** | ||
| 140628 | ** Return 0 if no changes are made and non-zero if one or more WHERE clause | 145525 | ** Return 0 if no changes are made and non-zero if one or more WHERE clause |
| 140629 | ** terms are duplicated into the subquery. | 145526 | ** terms are duplicated into the subquery. |
| 140630 | */ | 145527 | */ |
| @@ -140632,24 +145529,56 @@ static int pushDownWhereTerms( | |||
| 140632 | Parse *pParse, /* Parse context (for malloc() and error reporting) */ | 145529 | Parse *pParse, /* Parse context (for malloc() and error reporting) */ |
| 140633 | Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ | 145530 | Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ |
| 140634 | Expr *pWhere, /* The WHERE clause of the outer query */ | 145531 | Expr *pWhere, /* The WHERE clause of the outer query */ |
| 140635 | SrcItem *pSrc /* The subquery term of the outer FROM clause */ | 145532 | SrcList *pSrcList, /* The complete from clause of the outer query */ |
| 145533 | int iSrc /* Which FROM clause term to try to push into */ | ||
| 140636 | ){ | 145534 | ){ |
| 140637 | Expr *pNew; | 145535 | Expr *pNew; |
| 145536 | SrcItem *pSrc; /* The subquery FROM term into which WHERE is pushed */ | ||
| 140638 | int nChng = 0; | 145537 | int nChng = 0; |
| 145538 | pSrc = &pSrcList->a[iSrc]; | ||
| 140639 | if( pWhere==0 ) return 0; | 145539 | if( pWhere==0 ) return 0; |
| 140640 | if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; | 145540 | if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ){ |
| 140641 | if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0; | 145541 | return 0; /* restrictions (2) and (11) */ |
| 145542 | } | ||
| 145543 | if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ){ | ||
| 145544 | return 0; /* restrictions (10) */ | ||
| 145545 | } | ||
| 140642 | 145546 | ||
| 140643 | #ifndef SQLITE_OMIT_WINDOWFUNC | ||
| 140644 | if( pSubq->pPrior ){ | 145547 | if( pSubq->pPrior ){ |
| 140645 | Select *pSel; | 145548 | Select *pSel; |
| 145549 | int notUnionAll = 0; | ||
| 140646 | for(pSel=pSubq; pSel; pSel=pSel->pPrior){ | 145550 | for(pSel=pSubq; pSel; pSel=pSel->pPrior){ |
| 145551 | u8 op = pSel->op; | ||
| 145552 | assert( op==TK_ALL || op==TK_SELECT | ||
| 145553 | || op==TK_UNION || op==TK_INTERSECT || op==TK_EXCEPT ); | ||
| 145554 | if( op!=TK_ALL && op!=TK_SELECT ){ | ||
| 145555 | notUnionAll = 1; | ||
| 145556 | } | ||
| 145557 | #ifndef SQLITE_OMIT_WINDOWFUNC | ||
| 140647 | if( pSel->pWin ) return 0; /* restriction (6b) */ | 145558 | if( pSel->pWin ) return 0; /* restriction (6b) */ |
| 145559 | #endif | ||
| 145560 | } | ||
| 145561 | if( notUnionAll ){ | ||
| 145562 | /* If any of the compound arms are connected using UNION, INTERSECT, | ||
| 145563 | ** or EXCEPT, then we must ensure that none of the columns use a | ||
| 145564 | ** non-BINARY collating sequence. */ | ||
| 145565 | for(pSel=pSubq; pSel; pSel=pSel->pPrior){ | ||
| 145566 | int ii; | ||
| 145567 | const ExprList *pList = pSel->pEList; | ||
| 145568 | assert( pList!=0 ); | ||
| 145569 | for(ii=0; ii<pList->nExpr; ii++){ | ||
| 145570 | CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[ii].pExpr); | ||
| 145571 | if( !sqlite3IsBinary(pColl) ){ | ||
| 145572 | return 0; /* Restriction (8) */ | ||
| 145573 | } | ||
| 145574 | } | ||
| 145575 | } | ||
| 140648 | } | 145576 | } |
| 140649 | }else{ | 145577 | }else{ |
| 145578 | #ifndef SQLITE_OMIT_WINDOWFUNC | ||
| 140650 | if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; | 145579 | if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; |
| 140651 | } | ||
| 140652 | #endif | 145580 | #endif |
| 145581 | } | ||
| 140653 | 145582 | ||
| 140654 | #ifdef SQLITE_DEBUG | 145583 | #ifdef SQLITE_DEBUG |
| 140655 | /* Only the first term of a compound can have a WITH clause. But make | 145584 | /* Only the first term of a compound can have a WITH clause. But make |
| @@ -140668,11 +145597,28 @@ static int pushDownWhereTerms( | |||
| 140668 | return 0; /* restriction (3) */ | 145597 | return 0; /* restriction (3) */ |
| 140669 | } | 145598 | } |
| 140670 | while( pWhere->op==TK_AND ){ | 145599 | while( pWhere->op==TK_AND ){ |
| 140671 | nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc); | 145600 | nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrcList, iSrc); |
| 140672 | pWhere = pWhere->pLeft; | 145601 | pWhere = pWhere->pLeft; |
| 140673 | } | 145602 | } |
| 140674 | 145603 | ||
| 140675 | #if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */ | 145604 | #if 0 /* These checks now done by sqlite3ExprIsSingleTableConstraint() */ |
| 145605 | if( ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) /* (9a) */ | ||
| 145606 | && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (9c) */ | ||
| 145607 | ){ | ||
| 145608 | int jj; | ||
| 145609 | for(jj=0; jj<iSrc; jj++){ | ||
| 145610 | if( pWhere->w.iJoin==pSrcList->a[jj].iCursor ){ | ||
| 145611 | /* If we reach this point, both (9a) and (9b) are satisfied. | ||
| 145612 | ** The following loop checks (9c): | ||
| 145613 | */ | ||
| 145614 | for(jj++; jj<iSrc; jj++){ | ||
| 145615 | if( (pSrcList->a[jj].fg.jointype & JT_RIGHT)!=0 ){ | ||
| 145616 | return 0; /* restriction (9) */ | ||
| 145617 | } | ||
| 145618 | } | ||
| 145619 | } | ||
| 145620 | } | ||
| 145621 | } | ||
| 140676 | if( isLeftJoin | 145622 | if( isLeftJoin |
| 140677 | && (ExprHasProperty(pWhere,EP_OuterON)==0 | 145623 | && (ExprHasProperty(pWhere,EP_OuterON)==0 |
| 140678 | || pWhere->w.iJoin!=iCursor) | 145624 | || pWhere->w.iJoin!=iCursor) |
| @@ -140686,7 +145632,7 @@ static int pushDownWhereTerms( | |||
| 140686 | } | 145632 | } |
| 140687 | #endif | 145633 | #endif |
| 140688 | 145634 | ||
| 140689 | if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){ | 145635 | if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){ |
| 140690 | nChng++; | 145636 | nChng++; |
| 140691 | pSubq->selFlags |= SF_PushDown; | 145637 | pSubq->selFlags |= SF_PushDown; |
| 140692 | while( pSubq ){ | 145638 | while( pSubq ){ |
| @@ -140698,6 +145644,7 @@ static int pushDownWhereTerms( | |||
| 140698 | x.iNewTable = pSrc->iCursor; | 145644 | x.iNewTable = pSrc->iCursor; |
| 140699 | x.isOuterJoin = 0; | 145645 | x.isOuterJoin = 0; |
| 140700 | x.pEList = pSubq->pEList; | 145646 | x.pEList = pSubq->pEList; |
| 145647 | x.pCList = findLeftmostExprlist(pSubq); | ||
| 140701 | pNew = substExpr(&x, pNew); | 145648 | pNew = substExpr(&x, pNew); |
| 140702 | #ifndef SQLITE_OMIT_WINDOWFUNC | 145649 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 140703 | if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ | 145650 | if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ |
| @@ -140720,6 +145667,78 @@ static int pushDownWhereTerms( | |||
| 140720 | #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ | 145667 | #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ |
| 140721 | 145668 | ||
| 140722 | /* | 145669 | /* |
| 145670 | ** Check to see if a subquery contains result-set columns that are | ||
| 145671 | ** never used. If it does, change the value of those result-set columns | ||
| 145672 | ** to NULL so that they do not cause unnecessary work to compute. | ||
| 145673 | ** | ||
| 145674 | ** Return the number of column that were changed to NULL. | ||
| 145675 | */ | ||
| 145676 | static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ | ||
| 145677 | int nCol; | ||
| 145678 | Select *pSub; /* The subquery to be simplified */ | ||
| 145679 | Select *pX; /* For looping over compound elements of pSub */ | ||
| 145680 | Table *pTab; /* The table that describes the subquery */ | ||
| 145681 | int j; /* Column number */ | ||
| 145682 | int nChng = 0; /* Number of columns converted to NULL */ | ||
| 145683 | Bitmask colUsed; /* Columns that may not be NULLed out */ | ||
| 145684 | |||
| 145685 | assert( pItem!=0 ); | ||
| 145686 | if( pItem->fg.isCorrelated || pItem->fg.isCte ){ | ||
| 145687 | return 0; | ||
| 145688 | } | ||
| 145689 | assert( pItem->pTab!=0 ); | ||
| 145690 | pTab = pItem->pTab; | ||
| 145691 | assert( pItem->pSelect!=0 ); | ||
| 145692 | pSub = pItem->pSelect; | ||
| 145693 | assert( pSub->pEList->nExpr==pTab->nCol ); | ||
| 145694 | if( (pSub->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ | ||
| 145695 | testcase( pSub->selFlags & SF_Distinct ); | ||
| 145696 | testcase( pSub->selFlags & SF_Aggregate ); | ||
| 145697 | return 0; | ||
| 145698 | } | ||
| 145699 | for(pX=pSub; pX; pX=pX->pPrior){ | ||
| 145700 | if( pX->pPrior && pX->op!=TK_ALL ){ | ||
| 145701 | /* This optimization does not work for compound subqueries that | ||
| 145702 | ** use UNION, INTERSECT, or EXCEPT. Only UNION ALL is allowed. */ | ||
| 145703 | return 0; | ||
| 145704 | } | ||
| 145705 | #ifndef SQLITE_OMIT_WINDOWFUNC | ||
| 145706 | if( pX->pWin ){ | ||
| 145707 | /* This optimization does not work for subqueries that use window | ||
| 145708 | ** functions. */ | ||
| 145709 | return 0; | ||
| 145710 | } | ||
| 145711 | #endif | ||
| 145712 | } | ||
| 145713 | colUsed = pItem->colUsed; | ||
| 145714 | if( pSub->pOrderBy ){ | ||
| 145715 | ExprList *pList = pSub->pOrderBy; | ||
| 145716 | for(j=0; j<pList->nExpr; j++){ | ||
| 145717 | u16 iCol = pList->a[j].u.x.iOrderByCol; | ||
| 145718 | if( iCol>0 ){ | ||
| 145719 | iCol--; | ||
| 145720 | colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); | ||
| 145721 | } | ||
| 145722 | } | ||
| 145723 | } | ||
| 145724 | nCol = pTab->nCol; | ||
| 145725 | for(j=0; j<nCol; j++){ | ||
| 145726 | Bitmask m = j<BMS-1 ? MASKBIT(j) : TOPBIT; | ||
| 145727 | if( (m & colUsed)!=0 ) continue; | ||
| 145728 | for(pX=pSub; pX; pX=pX->pPrior) { | ||
| 145729 | Expr *pY = pX->pEList->a[j].pExpr; | ||
| 145730 | if( pY->op==TK_NULL ) continue; | ||
| 145731 | pY->op = TK_NULL; | ||
| 145732 | ExprClearProperty(pY, EP_Skip|EP_Unlikely); | ||
| 145733 | pX->selFlags |= SF_PushDown; | ||
| 145734 | nChng++; | ||
| 145735 | } | ||
| 145736 | } | ||
| 145737 | return nChng; | ||
| 145738 | } | ||
| 145739 | |||
| 145740 | |||
| 145741 | /* | ||
| 140723 | ** The pFunc is the only aggregate function in the query. Check to see | 145742 | ** The pFunc is the only aggregate function in the query. Check to see |
| 140724 | ** if the query is a candidate for the min/max optimization. | 145743 | ** if the query is a candidate for the min/max optimization. |
| 140725 | ** | 145744 | ** |
| @@ -141110,9 +146129,6 @@ static int resolveFromTermToCte( | |||
| 141110 | pFrom->fg.isCte = 1; | 146129 | pFrom->fg.isCte = 1; |
| 141111 | pFrom->u2.pCteUse = pCteUse; | 146130 | pFrom->u2.pCteUse = pCteUse; |
| 141112 | pCteUse->nUse++; | 146131 | pCteUse->nUse++; |
| 141113 | if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){ | ||
| 141114 | pCteUse->eM10d = M10d_Yes; | ||
| 141115 | } | ||
| 141116 | 146132 | ||
| 141117 | /* Check if this is a recursive CTE. */ | 146133 | /* Check if this is a recursive CTE. */ |
| 141118 | pRecTerm = pSel = pFrom->pSelect; | 146134 | pRecTerm = pSel = pFrom->pSelect; |
| @@ -141222,9 +146238,9 @@ SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){ | |||
| 141222 | #endif | 146238 | #endif |
| 141223 | 146239 | ||
| 141224 | /* | 146240 | /* |
| 141225 | ** The SrcList_item structure passed as the second argument represents a | 146241 | ** The SrcItem structure passed as the second argument represents a |
| 141226 | ** sub-query in the FROM clause of a SELECT statement. This function | 146242 | ** sub-query in the FROM clause of a SELECT statement. This function |
| 141227 | ** allocates and populates the SrcList_item.pTab object. If successful, | 146243 | ** allocates and populates the SrcItem.pTab object. If successful, |
| 141228 | ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, | 146244 | ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, |
| 141229 | ** SQLITE_NOMEM. | 146245 | ** SQLITE_NOMEM. |
| 141230 | */ | 146246 | */ |
| @@ -141486,10 +146502,16 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 141486 | ** expanded. */ | 146502 | ** expanded. */ |
| 141487 | int tableSeen = 0; /* Set to 1 when TABLE matches */ | 146503 | int tableSeen = 0; /* Set to 1 when TABLE matches */ |
| 141488 | char *zTName = 0; /* text of name of TABLE */ | 146504 | char *zTName = 0; /* text of name of TABLE */ |
| 146505 | int iErrOfst; | ||
| 141489 | if( pE->op==TK_DOT ){ | 146506 | if( pE->op==TK_DOT ){ |
| 141490 | assert( pE->pLeft!=0 ); | 146507 | assert( pE->pLeft!=0 ); |
| 141491 | assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); | 146508 | assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); |
| 141492 | zTName = pE->pLeft->u.zToken; | 146509 | zTName = pE->pLeft->u.zToken; |
| 146510 | assert( ExprUseWOfst(pE->pLeft) ); | ||
| 146511 | iErrOfst = pE->pRight->w.iOfst; | ||
| 146512 | }else{ | ||
| 146513 | assert( ExprUseWOfst(pE) ); | ||
| 146514 | iErrOfst = pE->w.iOfst; | ||
| 141493 | } | 146515 | } |
| 141494 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ | 146516 | for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){ |
| 141495 | Table *pTab = pFrom->pTab; /* Table for this data source */ | 146517 | Table *pTab = pFrom->pTab; /* Table for this data source */ |
| @@ -141526,6 +146548,7 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 141526 | for(ii=0; ii<pUsing->nId; ii++){ | 146548 | for(ii=0; ii<pUsing->nId; ii++){ |
| 141527 | const char *zUName = pUsing->a[ii].zName; | 146549 | const char *zUName = pUsing->a[ii].zName; |
| 141528 | pRight = sqlite3Expr(db, TK_ID, zUName); | 146550 | pRight = sqlite3Expr(db, TK_ID, zUName); |
| 146551 | sqlite3ExprSetErrorOffset(pRight, iErrOfst); | ||
| 141529 | pNew = sqlite3ExprListAppend(pParse, pNew, pRight); | 146552 | pNew = sqlite3ExprListAppend(pParse, pNew, pRight); |
| 141530 | if( pNew ){ | 146553 | if( pNew ){ |
| 141531 | struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; | 146554 | struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; |
| @@ -141598,6 +146621,7 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 141598 | }else{ | 146621 | }else{ |
| 141599 | pExpr = pRight; | 146622 | pExpr = pRight; |
| 141600 | } | 146623 | } |
| 146624 | sqlite3ExprSetErrorOffset(pExpr, iErrOfst); | ||
| 141601 | pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); | 146625 | pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); |
| 141602 | if( pNew==0 ){ | 146626 | if( pNew==0 ){ |
| 141603 | break; /* OOM */ | 146627 | break; /* OOM */ |
| @@ -141652,8 +146676,8 @@ static int selectExpander(Walker *pWalker, Select *p){ | |||
| 141652 | } | 146676 | } |
| 141653 | } | 146677 | } |
| 141654 | #if TREETRACE_ENABLED | 146678 | #if TREETRACE_ENABLED |
| 141655 | if( sqlite3TreeTrace & 0x100 ){ | 146679 | if( sqlite3TreeTrace & 0x8 ){ |
| 141656 | SELECTTRACE(0x100,pParse,p,("After result-set wildcard expansion:\n")); | 146680 | TREETRACE(0x8,pParse,p,("After result-set wildcard expansion:\n")); |
| 141657 | sqlite3TreeViewSelect(0, p, 0); | 146681 | sqlite3TreeViewSelect(0, p, 0); |
| 141658 | } | 146682 | } |
| 141659 | #endif | 146683 | #endif |
| @@ -141704,14 +146728,14 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ | |||
| 141704 | ** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() | 146728 | ** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() |
| 141705 | ** interface. | 146729 | ** interface. |
| 141706 | ** | 146730 | ** |
| 141707 | ** For each FROM-clause subquery, add Column.zType and Column.zColl | 146731 | ** For each FROM-clause subquery, add Column.zType, Column.zColl, and |
| 141708 | ** information to the Table structure that represents the result set | 146732 | ** Column.affinity information to the Table structure that represents |
| 141709 | ** of that subquery. | 146733 | ** the result set of that subquery. |
| 141710 | ** | 146734 | ** |
| 141711 | ** The Table structure that represents the result set was constructed | 146735 | ** The Table structure that represents the result set was constructed |
| 141712 | ** by selectExpander() but the type and collation information was omitted | 146736 | ** by selectExpander() but the type and collation and affinity information |
| 141713 | ** at that point because identifiers had not yet been resolved. This | 146737 | ** was omitted at that point because identifiers had not yet been resolved. |
| 141714 | ** routine is called after identifier resolution. | 146738 | ** This routine is called after identifier resolution. |
| 141715 | */ | 146739 | */ |
| 141716 | static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ | 146740 | static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ |
| 141717 | Parse *pParse; | 146741 | Parse *pParse; |
| @@ -141731,9 +146755,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ | |||
| 141731 | /* A sub-query in the FROM clause of a SELECT */ | 146755 | /* A sub-query in the FROM clause of a SELECT */ |
| 141732 | Select *pSel = pFrom->pSelect; | 146756 | Select *pSel = pFrom->pSelect; |
| 141733 | if( pSel ){ | 146757 | if( pSel ){ |
| 141734 | while( pSel->pPrior ) pSel = pSel->pPrior; | 146758 | sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); |
| 141735 | sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel, | ||
| 141736 | SQLITE_AFF_NONE); | ||
| 141737 | } | 146759 | } |
| 141738 | } | 146760 | } |
| 141739 | } | 146761 | } |
| @@ -141788,6 +146810,178 @@ SQLITE_PRIVATE void sqlite3SelectPrep( | |||
| 141788 | sqlite3SelectAddTypeInfo(pParse, p); | 146810 | sqlite3SelectAddTypeInfo(pParse, p); |
| 141789 | } | 146811 | } |
| 141790 | 146812 | ||
| 146813 | #if TREETRACE_ENABLED | ||
| 146814 | /* | ||
| 146815 | ** Display all information about an AggInfo object | ||
| 146816 | */ | ||
| 146817 | static void printAggInfo(AggInfo *pAggInfo){ | ||
| 146818 | int ii; | ||
| 146819 | for(ii=0; ii<pAggInfo->nColumn; ii++){ | ||
| 146820 | struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; | ||
| 146821 | sqlite3DebugPrintf( | ||
| 146822 | "agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d" | ||
| 146823 | " iSorterColumn=%d %s\n", | ||
| 146824 | ii, pCol->pTab ? pCol->pTab->zName : "NULL", | ||
| 146825 | pCol->iTable, pCol->iColumn, pAggInfo->iFirstReg+ii, | ||
| 146826 | pCol->iSorterColumn, | ||
| 146827 | ii>=pAggInfo->nAccumulator ? "" : " Accumulator"); | ||
| 146828 | sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); | ||
| 146829 | } | ||
| 146830 | for(ii=0; ii<pAggInfo->nFunc; ii++){ | ||
| 146831 | sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", | ||
| 146832 | ii, pAggInfo->iFirstReg+pAggInfo->nColumn+ii); | ||
| 146833 | sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0); | ||
| 146834 | } | ||
| 146835 | } | ||
| 146836 | #endif /* TREETRACE_ENABLED */ | ||
| 146837 | |||
| 146838 | /* | ||
| 146839 | ** Analyze the arguments to aggregate functions. Create new pAggInfo->aCol[] | ||
| 146840 | ** entries for columns that are arguments to aggregate functions but which | ||
| 146841 | ** are not otherwise used. | ||
| 146842 | ** | ||
| 146843 | ** The aCol[] entries in AggInfo prior to nAccumulator are columns that | ||
| 146844 | ** are referenced outside of aggregate functions. These might be columns | ||
| 146845 | ** that are part of the GROUP by clause, for example. Other database engines | ||
| 146846 | ** would throw an error if there is a column reference that is not in the | ||
| 146847 | ** GROUP BY clause and that is not part of an aggregate function argument. | ||
| 146848 | ** But SQLite allows this. | ||
| 146849 | ** | ||
| 146850 | ** The aCol[] entries beginning with the aCol[nAccumulator] and following | ||
| 146851 | ** are column references that are used exclusively as arguments to | ||
| 146852 | ** aggregate functions. This routine is responsible for computing | ||
| 146853 | ** (or recomputing) those aCol[] entries. | ||
| 146854 | */ | ||
| 146855 | static void analyzeAggFuncArgs( | ||
| 146856 | AggInfo *pAggInfo, | ||
| 146857 | NameContext *pNC | ||
| 146858 | ){ | ||
| 146859 | int i; | ||
| 146860 | assert( pAggInfo!=0 ); | ||
| 146861 | assert( pAggInfo->iFirstReg==0 ); | ||
| 146862 | pNC->ncFlags |= NC_InAggFunc; | ||
| 146863 | for(i=0; i<pAggInfo->nFunc; i++){ | ||
| 146864 | Expr *pExpr = pAggInfo->aFunc[i].pFExpr; | ||
| 146865 | assert( ExprUseXList(pExpr) ); | ||
| 146866 | sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); | ||
| 146867 | #ifndef SQLITE_OMIT_WINDOWFUNC | ||
| 146868 | assert( !IsWindowFunc(pExpr) ); | ||
| 146869 | if( ExprHasProperty(pExpr, EP_WinFunc) ){ | ||
| 146870 | sqlite3ExprAnalyzeAggregates(pNC, pExpr->y.pWin->pFilter); | ||
| 146871 | } | ||
| 146872 | #endif | ||
| 146873 | } | ||
| 146874 | pNC->ncFlags &= ~NC_InAggFunc; | ||
| 146875 | } | ||
| 146876 | |||
| 146877 | /* | ||
| 146878 | ** An index on expressions is being used in the inner loop of an | ||
| 146879 | ** aggregate query with a GROUP BY clause. This routine attempts | ||
| 146880 | ** to adjust the AggInfo object to take advantage of index and to | ||
| 146881 | ** perhaps use the index as a covering index. | ||
| 146882 | ** | ||
| 146883 | */ | ||
| 146884 | static void optimizeAggregateUseOfIndexedExpr( | ||
| 146885 | Parse *pParse, /* Parsing context */ | ||
| 146886 | Select *pSelect, /* The SELECT statement being processed */ | ||
| 146887 | AggInfo *pAggInfo, /* The aggregate info */ | ||
| 146888 | NameContext *pNC /* Name context used to resolve agg-func args */ | ||
| 146889 | ){ | ||
| 146890 | assert( pAggInfo->iFirstReg==0 ); | ||
| 146891 | assert( pSelect!=0 ); | ||
| 146892 | assert( pSelect->pGroupBy!=0 ); | ||
| 146893 | pAggInfo->nColumn = pAggInfo->nAccumulator; | ||
| 146894 | if( ALWAYS(pAggInfo->nSortingColumn>0) ){ | ||
| 146895 | int mx = pSelect->pGroupBy->nExpr - 1; | ||
| 146896 | int j, k; | ||
| 146897 | for(j=0; j<pAggInfo->nColumn; j++){ | ||
| 146898 | k = pAggInfo->aCol[j].iSorterColumn; | ||
| 146899 | if( k>mx ) mx = k; | ||
| 146900 | } | ||
| 146901 | pAggInfo->nSortingColumn = mx+1; | ||
| 146902 | } | ||
| 146903 | analyzeAggFuncArgs(pAggInfo, pNC); | ||
| 146904 | #if TREETRACE_ENABLED | ||
| 146905 | if( sqlite3TreeTrace & 0x20 ){ | ||
| 146906 | IndexedExpr *pIEpr; | ||
| 146907 | TREETRACE(0x20, pParse, pSelect, | ||
| 146908 | ("AggInfo (possibly) adjusted for Indexed Exprs\n")); | ||
| 146909 | sqlite3TreeViewSelect(0, pSelect, 0); | ||
| 146910 | for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ | ||
| 146911 | printf("data-cursor=%d index={%d,%d}\n", | ||
| 146912 | pIEpr->iDataCur, pIEpr->iIdxCur, pIEpr->iIdxCol); | ||
| 146913 | sqlite3TreeViewExpr(0, pIEpr->pExpr, 0); | ||
| 146914 | } | ||
| 146915 | printAggInfo(pAggInfo); | ||
| 146916 | } | ||
| 146917 | #else | ||
| 146918 | UNUSED_PARAMETER(pSelect); | ||
| 146919 | UNUSED_PARAMETER(pParse); | ||
| 146920 | #endif | ||
| 146921 | } | ||
| 146922 | |||
| 146923 | /* | ||
| 146924 | ** Walker callback for aggregateConvertIndexedExprRefToColumn(). | ||
| 146925 | */ | ||
| 146926 | static int aggregateIdxEprRefToColCallback(Walker *pWalker, Expr *pExpr){ | ||
| 146927 | AggInfo *pAggInfo; | ||
| 146928 | struct AggInfo_col *pCol; | ||
| 146929 | UNUSED_PARAMETER(pWalker); | ||
| 146930 | if( pExpr->pAggInfo==0 ) return WRC_Continue; | ||
| 146931 | if( pExpr->op==TK_AGG_COLUMN ) return WRC_Continue; | ||
| 146932 | if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue; | ||
| 146933 | if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue; | ||
| 146934 | pAggInfo = pExpr->pAggInfo; | ||
| 146935 | if( NEVER(pExpr->iAgg>=pAggInfo->nColumn) ) return WRC_Continue; | ||
| 146936 | assert( pExpr->iAgg>=0 ); | ||
| 146937 | pCol = &pAggInfo->aCol[pExpr->iAgg]; | ||
| 146938 | pExpr->op = TK_AGG_COLUMN; | ||
| 146939 | pExpr->iTable = pCol->iTable; | ||
| 146940 | pExpr->iColumn = pCol->iColumn; | ||
| 146941 | ExprClearProperty(pExpr, EP_Skip|EP_Collate|EP_Unlikely); | ||
| 146942 | return WRC_Prune; | ||
| 146943 | } | ||
| 146944 | |||
| 146945 | /* | ||
| 146946 | ** Convert every pAggInfo->aFunc[].pExpr such that any node within | ||
| 146947 | ** those expressions that has pAppInfo set is changed into a TK_AGG_COLUMN | ||
| 146948 | ** opcode. | ||
| 146949 | */ | ||
| 146950 | static void aggregateConvertIndexedExprRefToColumn(AggInfo *pAggInfo){ | ||
| 146951 | int i; | ||
| 146952 | Walker w; | ||
| 146953 | memset(&w, 0, sizeof(w)); | ||
| 146954 | w.xExprCallback = aggregateIdxEprRefToColCallback; | ||
| 146955 | for(i=0; i<pAggInfo->nFunc; i++){ | ||
| 146956 | sqlite3WalkExpr(&w, pAggInfo->aFunc[i].pFExpr); | ||
| 146957 | } | ||
| 146958 | } | ||
| 146959 | |||
| 146960 | |||
| 146961 | /* | ||
| 146962 | ** Allocate a block of registers so that there is one register for each | ||
| 146963 | ** pAggInfo->aCol[] and pAggInfo->aFunc[] entry in pAggInfo. The first | ||
| 146964 | ** register in this block is stored in pAggInfo->iFirstReg. | ||
| 146965 | ** | ||
| 146966 | ** This routine may only be called once for each AggInfo object. Prior | ||
| 146967 | ** to calling this routine: | ||
| 146968 | ** | ||
| 146969 | ** * The aCol[] and aFunc[] arrays may be modified | ||
| 146970 | ** * The AggInfoColumnReg() and AggInfoFuncReg() macros may not be used | ||
| 146971 | ** | ||
| 146972 | ** After calling this routine: | ||
| 146973 | ** | ||
| 146974 | ** * The aCol[] and aFunc[] arrays are fixed | ||
| 146975 | ** * The AggInfoColumnReg() and AggInfoFuncReg() macros may be used | ||
| 146976 | ** | ||
| 146977 | */ | ||
| 146978 | static void assignAggregateRegisters(Parse *pParse, AggInfo *pAggInfo){ | ||
| 146979 | assert( pAggInfo!=0 ); | ||
| 146980 | assert( pAggInfo->iFirstReg==0 ); | ||
| 146981 | pAggInfo->iFirstReg = pParse->nMem + 1; | ||
| 146982 | pParse->nMem += pAggInfo->nColumn + pAggInfo->nFunc; | ||
| 146983 | } | ||
| 146984 | |||
| 141791 | /* | 146985 | /* |
| 141792 | ** Reset the aggregate accumulator. | 146986 | ** Reset the aggregate accumulator. |
| 141793 | ** | 146987 | ** |
| @@ -141801,24 +146995,13 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ | |||
| 141801 | int i; | 146995 | int i; |
| 141802 | struct AggInfo_func *pFunc; | 146996 | struct AggInfo_func *pFunc; |
| 141803 | int nReg = pAggInfo->nFunc + pAggInfo->nColumn; | 146997 | int nReg = pAggInfo->nFunc + pAggInfo->nColumn; |
| 146998 | assert( pAggInfo->iFirstReg>0 ); | ||
| 141804 | assert( pParse->db->pParse==pParse ); | 146999 | assert( pParse->db->pParse==pParse ); |
| 141805 | assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); | 147000 | assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); |
| 141806 | if( nReg==0 ) return; | 147001 | if( nReg==0 ) return; |
| 141807 | if( pParse->nErr ) return; | 147002 | if( pParse->nErr ) return; |
| 141808 | #ifdef SQLITE_DEBUG | 147003 | sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->iFirstReg, |
| 141809 | /* Verify that all AggInfo registers are within the range specified by | 147004 | pAggInfo->iFirstReg+nReg-1); |
| 141810 | ** AggInfo.mnReg..AggInfo.mxReg */ | ||
| 141811 | assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 ); | ||
| 141812 | for(i=0; i<pAggInfo->nColumn; i++){ | ||
| 141813 | assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg | ||
| 141814 | && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg ); | ||
| 141815 | } | ||
| 141816 | for(i=0; i<pAggInfo->nFunc; i++){ | ||
| 141817 | assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg | ||
| 141818 | && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg ); | ||
| 141819 | } | ||
| 141820 | #endif | ||
| 141821 | sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg); | ||
| 141822 | for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){ | 147005 | for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){ |
| 141823 | if( pFunc->iDistinct>=0 ){ | 147006 | if( pFunc->iDistinct>=0 ){ |
| 141824 | Expr *pE = pFunc->pFExpr; | 147007 | Expr *pE = pFunc->pFExpr; |
| @@ -141850,15 +147033,16 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ | |||
| 141850 | ExprList *pList; | 147033 | ExprList *pList; |
| 141851 | assert( ExprUseXList(pF->pFExpr) ); | 147034 | assert( ExprUseXList(pF->pFExpr) ); |
| 141852 | pList = pF->pFExpr->x.pList; | 147035 | pList = pF->pFExpr->x.pList; |
| 141853 | sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0); | 147036 | sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), |
| 147037 | pList ? pList->nExpr : 0); | ||
| 141854 | sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); | 147038 | sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); |
| 141855 | } | 147039 | } |
| 141856 | } | 147040 | } |
| 141857 | 147041 | ||
| 141858 | 147042 | ||
| 141859 | /* | 147043 | /* |
| 141860 | ** Update the accumulator memory cells for an aggregate based on | 147044 | ** Generate code that will update the accumulator memory cells for an |
| 141861 | ** the current cursor position. | 147045 | ** aggregate based on the current cursor position. |
| 141862 | ** | 147046 | ** |
| 141863 | ** If regAcc is non-zero and there are no min() or max() aggregates | 147047 | ** If regAcc is non-zero and there are no min() or max() aggregates |
| 141864 | ** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator | 147048 | ** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator |
| @@ -141878,6 +147062,8 @@ static void updateAccumulator( | |||
| 141878 | struct AggInfo_func *pF; | 147062 | struct AggInfo_func *pF; |
| 141879 | struct AggInfo_col *pC; | 147063 | struct AggInfo_col *pC; |
| 141880 | 147064 | ||
| 147065 | assert( pAggInfo->iFirstReg>0 ); | ||
| 147066 | if( pParse->nErr ) return; | ||
| 141881 | pAggInfo->directMode = 1; | 147067 | pAggInfo->directMode = 1; |
| 141882 | for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ | 147068 | for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){ |
| 141883 | int nArg; | 147069 | int nArg; |
| @@ -141938,7 +147124,7 @@ static void updateAccumulator( | |||
| 141938 | if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; | 147124 | if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; |
| 141939 | sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); | 147125 | sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); |
| 141940 | } | 147126 | } |
| 141941 | sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem); | 147127 | sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); |
| 141942 | sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); | 147128 | sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); |
| 141943 | sqlite3VdbeChangeP5(v, (u8)nArg); | 147129 | sqlite3VdbeChangeP5(v, (u8)nArg); |
| 141944 | sqlite3ReleaseTempRange(pParse, regAgg, nArg); | 147130 | sqlite3ReleaseTempRange(pParse, regAgg, nArg); |
| @@ -141953,7 +147139,7 @@ static void updateAccumulator( | |||
| 141953 | addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); | 147139 | addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); |
| 141954 | } | 147140 | } |
| 141955 | for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ | 147141 | for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){ |
| 141956 | sqlite3ExprCode(pParse, pC->pCExpr, pC->iMem); | 147142 | sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); |
| 141957 | } | 147143 | } |
| 141958 | 147144 | ||
| 141959 | pAggInfo->directMode = 0; | 147145 | pAggInfo->directMode = 0; |
| @@ -142049,26 +147235,31 @@ static void havingToWhere(Parse *pParse, Select *p){ | |||
| 142049 | sqlite3WalkExpr(&sWalker, p->pHaving); | 147235 | sqlite3WalkExpr(&sWalker, p->pHaving); |
| 142050 | #if TREETRACE_ENABLED | 147236 | #if TREETRACE_ENABLED |
| 142051 | if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){ | 147237 | if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){ |
| 142052 | SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); | 147238 | TREETRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); |
| 142053 | sqlite3TreeViewSelect(0, p, 0); | 147239 | sqlite3TreeViewSelect(0, p, 0); |
| 142054 | } | 147240 | } |
| 142055 | #endif | 147241 | #endif |
| 142056 | } | 147242 | } |
| 142057 | 147243 | ||
| 142058 | /* | 147244 | /* |
| 142059 | ** Check to see if the pThis entry of pTabList is a self-join of a prior view. | 147245 | ** Check to see if the pThis entry of pTabList is a self-join of another view. |
| 142060 | ** If it is, then return the SrcList_item for the prior view. If it is not, | 147246 | ** Search FROM-clause entries in the range of iFirst..iEnd, including iFirst |
| 142061 | ** then return 0. | 147247 | ** but stopping before iEnd. |
| 147248 | ** | ||
| 147249 | ** If pThis is a self-join, then return the SrcItem for the first other | ||
| 147250 | ** instance of that view found. If pThis is not a self-join then return 0. | ||
| 142062 | */ | 147251 | */ |
| 142063 | static SrcItem *isSelfJoinView( | 147252 | static SrcItem *isSelfJoinView( |
| 142064 | SrcList *pTabList, /* Search for self-joins in this FROM clause */ | 147253 | SrcList *pTabList, /* Search for self-joins in this FROM clause */ |
| 142065 | SrcItem *pThis /* Search for prior reference to this subquery */ | 147254 | SrcItem *pThis, /* Search for prior reference to this subquery */ |
| 147255 | int iFirst, int iEnd /* Range of FROM-clause entries to search. */ | ||
| 142066 | ){ | 147256 | ){ |
| 142067 | SrcItem *pItem; | 147257 | SrcItem *pItem; |
| 142068 | assert( pThis->pSelect!=0 ); | 147258 | assert( pThis->pSelect!=0 ); |
| 142069 | if( pThis->pSelect->selFlags & SF_PushDown ) return 0; | 147259 | if( pThis->pSelect->selFlags & SF_PushDown ) return 0; |
| 142070 | for(pItem = pTabList->a; pItem<pThis; pItem++){ | 147260 | while( iFirst<iEnd ){ |
| 142071 | Select *pS1; | 147261 | Select *pS1; |
| 147262 | pItem = &pTabList->a[iFirst++]; | ||
| 142072 | if( pItem->pSelect==0 ) continue; | 147263 | if( pItem->pSelect==0 ) continue; |
| 142073 | if( pItem->fg.viaCoroutine ) continue; | 147264 | if( pItem->fg.viaCoroutine ) continue; |
| 142074 | if( pItem->zName==0 ) continue; | 147265 | if( pItem->zName==0 ) continue; |
| @@ -142101,7 +147292,6 @@ static void agginfoFree(sqlite3 *db, AggInfo *p){ | |||
| 142101 | sqlite3DbFreeNN(db, p); | 147292 | sqlite3DbFreeNN(db, p); |
| 142102 | } | 147293 | } |
| 142103 | 147294 | ||
| 142104 | #ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION | ||
| 142105 | /* | 147295 | /* |
| 142106 | ** Attempt to transform a query of the form | 147296 | ** Attempt to transform a query of the form |
| 142107 | ** | 147297 | ** |
| @@ -142129,7 +147319,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ | |||
| 142129 | if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ | 147319 | if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ |
| 142130 | if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ | 147320 | if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ |
| 142131 | if( p->pWhere ) return 0; | 147321 | if( p->pWhere ) return 0; |
| 147322 | if( p->pHaving ) return 0; | ||
| 142132 | if( p->pGroupBy ) return 0; | 147323 | if( p->pGroupBy ) return 0; |
| 147324 | if( p->pOrderBy ) return 0; | ||
| 142133 | pExpr = p->pEList->a[0].pExpr; | 147325 | pExpr = p->pEList->a[0].pExpr; |
| 142134 | if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ | 147326 | if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ |
| 142135 | assert( ExprUseUToken(pExpr) ); | 147327 | assert( ExprUseUToken(pExpr) ); |
| @@ -142137,15 +147329,18 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ | |||
| 142137 | assert( ExprUseXList(pExpr) ); | 147329 | assert( ExprUseXList(pExpr) ); |
| 142138 | if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ | 147330 | if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ |
| 142139 | if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ | 147331 | if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ |
| 147332 | if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ | ||
| 142140 | pSub = p->pSrc->a[0].pSelect; | 147333 | pSub = p->pSrc->a[0].pSelect; |
| 142141 | if( pSub==0 ) return 0; /* The FROM is a subquery */ | 147334 | if( pSub==0 ) return 0; /* The FROM is a subquery */ |
| 142142 | if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */ | 147335 | if( pSub->pPrior==0 ) return 0; /* Must be a compound */ |
| 147336 | if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ | ||
| 142143 | do{ | 147337 | do{ |
| 142144 | if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ | 147338 | if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ |
| 142145 | if( pSub->pWhere ) return 0; /* No WHERE clause */ | 147339 | if( pSub->pWhere ) return 0; /* No WHERE clause */ |
| 142146 | if( pSub->pLimit ) return 0; /* No LIMIT clause */ | 147340 | if( pSub->pLimit ) return 0; /* No LIMIT clause */ |
| 142147 | if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ | 147341 | if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ |
| 142148 | pSub = pSub->pPrior; /* Repeat over compound */ | 147342 | assert( pSub->pHaving==0 ); /* Due to the previous */ |
| 147343 | pSub = pSub->pPrior; /* Repeat over compound */ | ||
| 142149 | }while( pSub ); | 147344 | }while( pSub ); |
| 142150 | 147345 | ||
| 142151 | /* If we reach this point then it is OK to perform the transformation */ | 147346 | /* If we reach this point then it is OK to perform the transformation */ |
| @@ -142181,14 +147376,13 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ | |||
| 142181 | p->selFlags &= ~SF_Aggregate; | 147376 | p->selFlags &= ~SF_Aggregate; |
| 142182 | 147377 | ||
| 142183 | #if TREETRACE_ENABLED | 147378 | #if TREETRACE_ENABLED |
| 142184 | if( sqlite3TreeTrace & 0x400 ){ | 147379 | if( sqlite3TreeTrace & 0x200 ){ |
| 142185 | SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n")); | 147380 | TREETRACE(0x200,pParse,p,("After count-of-view optimization:\n")); |
| 142186 | sqlite3TreeViewSelect(0, p, 0); | 147381 | sqlite3TreeViewSelect(0, p, 0); |
| 142187 | } | 147382 | } |
| 142188 | #endif | 147383 | #endif |
| 142189 | return 1; | 147384 | return 1; |
| 142190 | } | 147385 | } |
| 142191 | #endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */ | ||
| 142192 | 147386 | ||
| 142193 | /* | 147387 | /* |
| 142194 | ** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same | 147388 | ** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same |
| @@ -142214,6 +147408,68 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ | |||
| 142214 | } | 147408 | } |
| 142215 | 147409 | ||
| 142216 | /* | 147410 | /* |
| 147411 | ** Return TRUE (non-zero) if the i-th entry in the pTabList SrcList can | ||
| 147412 | ** be implemented as a co-routine. The i-th entry is guaranteed to be | ||
| 147413 | ** a subquery. | ||
| 147414 | ** | ||
| 147415 | ** The subquery is implemented as a co-routine if all of the following are | ||
| 147416 | ** true: | ||
| 147417 | ** | ||
| 147418 | ** (1) The subquery will likely be implemented in the outer loop of | ||
| 147419 | ** the query. This will be the case if any one of the following | ||
| 147420 | ** conditions hold: | ||
| 147421 | ** (a) The subquery is the only term in the FROM clause | ||
| 147422 | ** (b) The subquery is the left-most term and a CROSS JOIN or similar | ||
| 147423 | ** requires it to be the outer loop | ||
| 147424 | ** (c) All of the following are true: | ||
| 147425 | ** (i) The subquery is the left-most subquery in the FROM clause | ||
| 147426 | ** (ii) There is nothing that would prevent the subquery from | ||
| 147427 | ** being used as the outer loop if the sqlite3WhereBegin() | ||
| 147428 | ** routine nominates it to that position. | ||
| 147429 | ** (iii) The query is not a UPDATE ... FROM | ||
| 147430 | ** (2) The subquery is not a CTE that should be materialized because | ||
| 147431 | ** (a) the AS MATERIALIZED keyword is used, or | ||
| 147432 | ** (b) the CTE is used multiple times and does not have the | ||
| 147433 | ** NOT MATERIALIZED keyword | ||
| 147434 | ** (3) The subquery is not part of a left operand for a RIGHT JOIN | ||
| 147435 | ** (4) The SQLITE_Coroutine optimization disable flag is not set | ||
| 147436 | ** (5) The subquery is not self-joined | ||
| 147437 | */ | ||
| 147438 | static int fromClauseTermCanBeCoroutine( | ||
| 147439 | Parse *pParse, /* Parsing context */ | ||
| 147440 | SrcList *pTabList, /* FROM clause */ | ||
| 147441 | int i, /* Which term of the FROM clause holds the subquery */ | ||
| 147442 | int selFlags /* Flags on the SELECT statement */ | ||
| 147443 | ){ | ||
| 147444 | SrcItem *pItem = &pTabList->a[i]; | ||
| 147445 | if( pItem->fg.isCte ){ | ||
| 147446 | const CteUse *pCteUse = pItem->u2.pCteUse; | ||
| 147447 | if( pCteUse->eM10d==M10d_Yes ) return 0; /* (2a) */ | ||
| 147448 | if( pCteUse->nUse>=2 && pCteUse->eM10d!=M10d_No ) return 0; /* (2b) */ | ||
| 147449 | } | ||
| 147450 | if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0; /* (3) */ | ||
| 147451 | if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4) */ | ||
| 147452 | if( isSelfJoinView(pTabList, pItem, i+1, pTabList->nSrc)!=0 ){ | ||
| 147453 | return 0; /* (5) */ | ||
| 147454 | } | ||
| 147455 | if( i==0 ){ | ||
| 147456 | if( pTabList->nSrc==1 ) return 1; /* (1a) */ | ||
| 147457 | if( pTabList->a[1].fg.jointype & JT_CROSS ) return 1; /* (1b) */ | ||
| 147458 | if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ | ||
| 147459 | return 1; | ||
| 147460 | } | ||
| 147461 | if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ | ||
| 147462 | while( 1 /*exit-by-break*/ ){ | ||
| 147463 | if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */ | ||
| 147464 | if( i==0 ) break; | ||
| 147465 | i--; | ||
| 147466 | pItem--; | ||
| 147467 | if( pItem->pSelect!=0 ) return 0; /* (1c-i) */ | ||
| 147468 | } | ||
| 147469 | return 1; | ||
| 147470 | } | ||
| 147471 | |||
| 147472 | /* | ||
| 142217 | ** Generate code for the SELECT statement given in the p argument. | 147473 | ** Generate code for the SELECT statement given in the p argument. |
| 142218 | ** | 147474 | ** |
| 142219 | ** The results are returned according to the SelectDest structure. | 147475 | ** The results are returned according to the SelectDest structure. |
| @@ -142258,8 +147514,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142258 | assert( db->mallocFailed==0 ); | 147514 | assert( db->mallocFailed==0 ); |
| 142259 | if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; | 147515 | if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; |
| 142260 | #if TREETRACE_ENABLED | 147516 | #if TREETRACE_ENABLED |
| 142261 | SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); | 147517 | TREETRACE(0x1,pParse,p, ("begin processing:\n", pParse->addrExplain)); |
| 142262 | if( sqlite3TreeTrace & 0x10100 ){ | 147518 | if( sqlite3TreeTrace & 0x10000 ){ |
| 142263 | if( (sqlite3TreeTrace & 0x10001)==0x10000 ){ | 147519 | if( (sqlite3TreeTrace & 0x10001)==0x10000 ){ |
| 142264 | sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", | 147520 | sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", |
| 142265 | __FILE__, __LINE__); | 147521 | __FILE__, __LINE__); |
| @@ -142279,8 +147535,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142279 | /* All of these destinations are also able to ignore the ORDER BY clause */ | 147535 | /* All of these destinations are also able to ignore the ORDER BY clause */ |
| 142280 | if( p->pOrderBy ){ | 147536 | if( p->pOrderBy ){ |
| 142281 | #if TREETRACE_ENABLED | 147537 | #if TREETRACE_ENABLED |
| 142282 | SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n")); | 147538 | TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n")); |
| 142283 | if( sqlite3TreeTrace & 0x100 ){ | 147539 | if( sqlite3TreeTrace & 0x800 ){ |
| 142284 | sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); | 147540 | sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); |
| 142285 | } | 147541 | } |
| 142286 | #endif | 147542 | #endif |
| @@ -142300,8 +147556,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142300 | assert( db->mallocFailed==0 ); | 147556 | assert( db->mallocFailed==0 ); |
| 142301 | assert( p->pEList!=0 ); | 147557 | assert( p->pEList!=0 ); |
| 142302 | #if TREETRACE_ENABLED | 147558 | #if TREETRACE_ENABLED |
| 142303 | if( sqlite3TreeTrace & 0x104 ){ | 147559 | if( sqlite3TreeTrace & 0x10 ){ |
| 142304 | SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); | 147560 | TREETRACE(0x10,pParse,p, ("after name resolution:\n")); |
| 142305 | sqlite3TreeViewSelect(0, p, 0); | 147561 | sqlite3TreeViewSelect(0, p, 0); |
| 142306 | } | 147562 | } |
| 142307 | #endif | 147563 | #endif |
| @@ -142342,8 +147598,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142342 | goto select_end; | 147598 | goto select_end; |
| 142343 | } | 147599 | } |
| 142344 | #if TREETRACE_ENABLED | 147600 | #if TREETRACE_ENABLED |
| 142345 | if( p->pWin && (sqlite3TreeTrace & 0x108)!=0 ){ | 147601 | if( p->pWin && (sqlite3TreeTrace & 0x40)!=0 ){ |
| 142346 | SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); | 147602 | TREETRACE(0x40,pParse,p, ("after window rewrite:\n")); |
| 142347 | sqlite3TreeViewSelect(0, p, 0); | 147603 | sqlite3TreeViewSelect(0, p, 0); |
| 142348 | } | 147604 | } |
| 142349 | #endif | 147605 | #endif |
| @@ -142367,22 +147623,59 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142367 | ** to a real table */ | 147623 | ** to a real table */ |
| 142368 | assert( pTab!=0 ); | 147624 | assert( pTab!=0 ); |
| 142369 | 147625 | ||
| 142370 | /* Convert LEFT JOIN into JOIN if there are terms of the right table | 147626 | /* Try to simplify joins: |
| 142371 | ** of the LEFT JOIN used in the WHERE clause. | 147627 | ** |
| 147628 | ** LEFT JOIN -> JOIN | ||
| 147629 | ** RIGHT JOIN -> JOIN | ||
| 147630 | ** FULL JOIN -> RIGHT JOIN | ||
| 147631 | ** | ||
| 147632 | ** If terms of the i-th table are used in the WHERE clause in such a | ||
| 147633 | ** way that the i-th table cannot be the NULL row of a join, then | ||
| 147634 | ** perform the appropriate simplification. This is called | ||
| 147635 | ** "OUTER JOIN strength reduction" in the SQLite documentation. | ||
| 142372 | */ | 147636 | */ |
| 142373 | if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT | 147637 | if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 |
| 142374 | && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) | 147638 | && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, |
| 147639 | pItem->fg.jointype & JT_LTORJ) | ||
| 142375 | && OptimizationEnabled(db, SQLITE_SimplifyJoin) | 147640 | && OptimizationEnabled(db, SQLITE_SimplifyJoin) |
| 142376 | ){ | 147641 | ){ |
| 142377 | SELECTTRACE(0x100,pParse,p, | 147642 | if( pItem->fg.jointype & JT_LEFT ){ |
| 142378 | ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); | 147643 | if( pItem->fg.jointype & JT_RIGHT ){ |
| 142379 | pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); | 147644 | TREETRACE(0x1000,pParse,p, |
| 147645 | ("FULL-JOIN simplifies to RIGHT-JOIN on term %d\n",i)); | ||
| 147646 | pItem->fg.jointype &= ~JT_LEFT; | ||
| 147647 | }else{ | ||
| 147648 | TREETRACE(0x1000,pParse,p, | ||
| 147649 | ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); | ||
| 147650 | pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); | ||
| 147651 | } | ||
| 147652 | } | ||
| 147653 | if( pItem->fg.jointype & JT_LTORJ ){ | ||
| 147654 | for(j=i+1; j<pTabList->nSrc; j++){ | ||
| 147655 | SrcItem *pI2 = &pTabList->a[j]; | ||
| 147656 | if( pI2->fg.jointype & JT_RIGHT ){ | ||
| 147657 | if( pI2->fg.jointype & JT_LEFT ){ | ||
| 147658 | TREETRACE(0x1000,pParse,p, | ||
| 147659 | ("FULL-JOIN simplifies to LEFT-JOIN on term %d\n",j)); | ||
| 147660 | pI2->fg.jointype &= ~JT_RIGHT; | ||
| 147661 | }else{ | ||
| 147662 | TREETRACE(0x1000,pParse,p, | ||
| 147663 | ("RIGHT-JOIN simplifies to JOIN on term %d\n",j)); | ||
| 147664 | pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER); | ||
| 147665 | } | ||
| 147666 | } | ||
| 147667 | } | ||
| 147668 | for(j=pTabList->nSrc-1; j>=i; j--){ | ||
| 147669 | pTabList->a[j].fg.jointype &= ~JT_LTORJ; | ||
| 147670 | if( pTabList->a[j].fg.jointype & JT_RIGHT ) break; | ||
| 147671 | } | ||
| 147672 | } | ||
| 142380 | assert( pItem->iCursor>=0 ); | 147673 | assert( pItem->iCursor>=0 ); |
| 142381 | unsetJoinExpr(p->pWhere, pItem->iCursor, | 147674 | unsetJoinExpr(p->pWhere, pItem->iCursor, |
| 142382 | pTabList->a[0].fg.jointype & JT_LTORJ); | 147675 | pTabList->a[0].fg.jointype & JT_LTORJ); |
| 142383 | } | 147676 | } |
| 142384 | 147677 | ||
| 142385 | /* No futher action if this term of the FROM clause is no a subquery */ | 147678 | /* No further action if this term of the FROM clause is not a subquery */ |
| 142386 | if( pSub==0 ) continue; | 147679 | if( pSub==0 ) continue; |
| 142387 | 147680 | ||
| 142388 | /* Catch mismatch in the declared columns of a view and the number of | 147681 | /* Catch mismatch in the declared columns of a view and the number of |
| @@ -142393,6 +147686,14 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142393 | goto select_end; | 147686 | goto select_end; |
| 142394 | } | 147687 | } |
| 142395 | 147688 | ||
| 147689 | /* Do not attempt the usual optimizations (flattening and ORDER BY | ||
| 147690 | ** elimination) on a MATERIALIZED common table expression because | ||
| 147691 | ** a MATERIALIZED common table expression is an optimization fence. | ||
| 147692 | */ | ||
| 147693 | if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ){ | ||
| 147694 | continue; | ||
| 147695 | } | ||
| 147696 | |||
| 142396 | /* Do not try to flatten an aggregate subquery. | 147697 | /* Do not try to flatten an aggregate subquery. |
| 142397 | ** | 147698 | ** |
| 142398 | ** Flattening an aggregate subquery is only possible if the outer query | 147699 | ** Flattening an aggregate subquery is only possible if the outer query |
| @@ -142422,6 +147723,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142422 | ** (a) The outer query has a different ORDER BY clause | 147723 | ** (a) The outer query has a different ORDER BY clause |
| 142423 | ** (b) The subquery is part of a join | 147724 | ** (b) The subquery is part of a join |
| 142424 | ** See forum post 062d576715d277c8 | 147725 | ** See forum post 062d576715d277c8 |
| 147726 | ** | ||
| 147727 | ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. | ||
| 142425 | */ | 147728 | */ |
| 142426 | if( pSub->pOrderBy!=0 | 147729 | if( pSub->pOrderBy!=0 |
| 142427 | && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ | 147730 | && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ |
| @@ -142430,7 +147733,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142430 | && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ | 147733 | && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ |
| 142431 | && OptimizationEnabled(db, SQLITE_OmitOrderBy) | 147734 | && OptimizationEnabled(db, SQLITE_OmitOrderBy) |
| 142432 | ){ | 147735 | ){ |
| 142433 | SELECTTRACE(0x100,pParse,p, | 147736 | TREETRACE(0x800,pParse,p, |
| 142434 | ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); | 147737 | ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); |
| 142435 | sqlite3ParserAddCleanup(pParse, | 147738 | sqlite3ParserAddCleanup(pParse, |
| 142436 | (void(*)(sqlite3*,void*))sqlite3ExprListDelete, | 147739 | (void(*)(sqlite3*,void*))sqlite3ExprListDelete, |
| @@ -142485,8 +147788,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142485 | if( p->pPrior ){ | 147788 | if( p->pPrior ){ |
| 142486 | rc = multiSelect(pParse, p, pDest); | 147789 | rc = multiSelect(pParse, p, pDest); |
| 142487 | #if TREETRACE_ENABLED | 147790 | #if TREETRACE_ENABLED |
| 142488 | SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); | 147791 | TREETRACE(0x400,pParse,p,("end compound-select processing\n")); |
| 142489 | if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ | 147792 | if( (sqlite3TreeTrace & 0x400)!=0 && ExplainQueryPlanParent(pParse)==0 ){ |
| 142490 | sqlite3TreeViewSelect(0, p, 0); | 147793 | sqlite3TreeViewSelect(0, p, 0); |
| 142491 | } | 147794 | } |
| 142492 | #endif | 147795 | #endif |
| @@ -142506,24 +147809,21 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142506 | && propagateConstants(pParse, p) | 147809 | && propagateConstants(pParse, p) |
| 142507 | ){ | 147810 | ){ |
| 142508 | #if TREETRACE_ENABLED | 147811 | #if TREETRACE_ENABLED |
| 142509 | if( sqlite3TreeTrace & 0x100 ){ | 147812 | if( sqlite3TreeTrace & 0x2000 ){ |
| 142510 | SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); | 147813 | TREETRACE(0x2000,pParse,p,("After constant propagation:\n")); |
| 142511 | sqlite3TreeViewSelect(0, p, 0); | 147814 | sqlite3TreeViewSelect(0, p, 0); |
| 142512 | } | 147815 | } |
| 142513 | #endif | 147816 | #endif |
| 142514 | }else{ | 147817 | }else{ |
| 142515 | SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n")); | 147818 | TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); |
| 142516 | } | 147819 | } |
| 142517 | 147820 | ||
| 142518 | #ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION | ||
| 142519 | if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) | 147821 | if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) |
| 142520 | && countOfViewOptimization(pParse, p) | 147822 | && countOfViewOptimization(pParse, p) |
| 142521 | ){ | 147823 | ){ |
| 142522 | if( db->mallocFailed ) goto select_end; | 147824 | if( db->mallocFailed ) goto select_end; |
| 142523 | pEList = p->pEList; | ||
| 142524 | pTabList = p->pSrc; | 147825 | pTabList = p->pSrc; |
| 142525 | } | 147826 | } |
| 142526 | #endif | ||
| 142527 | 147827 | ||
| 142528 | /* For each term in the FROM clause, do two things: | 147828 | /* For each term in the FROM clause, do two things: |
| 142529 | ** (1) Authorized unreferenced tables | 147829 | ** (1) Authorized unreferenced tables |
| @@ -142582,39 +147882,42 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142582 | if( OptimizationEnabled(db, SQLITE_PushDown) | 147882 | if( OptimizationEnabled(db, SQLITE_PushDown) |
| 142583 | && (pItem->fg.isCte==0 | 147883 | && (pItem->fg.isCte==0 |
| 142584 | || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) | 147884 | || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) |
| 142585 | && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) | 147885 | && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i) |
| 142586 | ){ | 147886 | ){ |
| 142587 | #if TREETRACE_ENABLED | 147887 | #if TREETRACE_ENABLED |
| 142588 | if( sqlite3TreeTrace & 0x100 ){ | 147888 | if( sqlite3TreeTrace & 0x4000 ){ |
| 142589 | SELECTTRACE(0x100,pParse,p, | 147889 | TREETRACE(0x4000,pParse,p, |
| 142590 | ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); | 147890 | ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); |
| 142591 | sqlite3TreeViewSelect(0, p, 0); | 147891 | sqlite3TreeViewSelect(0, p, 0); |
| 142592 | } | 147892 | } |
| 142593 | #endif | 147893 | #endif |
| 142594 | assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); | 147894 | assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); |
| 142595 | }else{ | 147895 | }else{ |
| 142596 | SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); | 147896 | TREETRACE(0x4000,pParse,p,("Push-down not possible\n")); |
| 147897 | } | ||
| 147898 | |||
| 147899 | /* Convert unused result columns of the subquery into simple NULL | ||
| 147900 | ** expressions, to avoid unneeded searching and computation. | ||
| 147901 | */ | ||
| 147902 | if( OptimizationEnabled(db, SQLITE_NullUnusedCols) | ||
| 147903 | && disableUnusedSubqueryResultColumns(pItem) | ||
| 147904 | ){ | ||
| 147905 | #if TREETRACE_ENABLED | ||
| 147906 | if( sqlite3TreeTrace & 0x4000 ){ | ||
| 147907 | TREETRACE(0x4000,pParse,p, | ||
| 147908 | ("Change unused result columns to NULL for subquery %d:\n", | ||
| 147909 | pSub->selId)); | ||
| 147910 | sqlite3TreeViewSelect(0, p, 0); | ||
| 147911 | } | ||
| 147912 | #endif | ||
| 142597 | } | 147913 | } |
| 142598 | 147914 | ||
| 142599 | zSavedAuthContext = pParse->zAuthContext; | 147915 | zSavedAuthContext = pParse->zAuthContext; |
| 142600 | pParse->zAuthContext = pItem->zName; | 147916 | pParse->zAuthContext = pItem->zName; |
| 142601 | 147917 | ||
| 142602 | /* Generate code to implement the subquery | 147918 | /* Generate code to implement the subquery |
| 142603 | ** | ||
| 142604 | ** The subquery is implemented as a co-routine if all of the following are | ||
| 142605 | ** true: | ||
| 142606 | ** | ||
| 142607 | ** (1) the subquery is guaranteed to be the outer loop (so that | ||
| 142608 | ** it does not need to be computed more than once), and | ||
| 142609 | ** (2) the subquery is not a CTE that should be materialized | ||
| 142610 | ** (3) the subquery is not part of a left operand for a RIGHT JOIN | ||
| 142611 | */ | 147919 | */ |
| 142612 | if( i==0 | 147920 | if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ |
| 142613 | && (pTabList->nSrc==1 | ||
| 142614 | || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) /* (1) */ | ||
| 142615 | && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ | ||
| 142616 | && (pTabList->a[0].fg.jointype & JT_LTORJ)==0 /* (3) */ | ||
| 142617 | ){ | ||
| 142618 | /* Implement a co-routine that will return a single row of the result | 147921 | /* Implement a co-routine that will return a single row of the result |
| 142619 | ** set on each invocation. | 147922 | ** set on each invocation. |
| 142620 | */ | 147923 | */ |
| @@ -142636,7 +147939,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142636 | }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ | 147939 | }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ |
| 142637 | /* This is a CTE for which materialization code has already been | 147940 | /* This is a CTE for which materialization code has already been |
| 142638 | ** generated. Invoke the subroutine to compute the materialization, | 147941 | ** generated. Invoke the subroutine to compute the materialization, |
| 142639 | ** the make the pItem->iCursor be a copy of the ephemerial table that | 147942 | ** the make the pItem->iCursor be a copy of the ephemeral table that |
| 142640 | ** holds the result of the materialization. */ | 147943 | ** holds the result of the materialization. */ |
| 142641 | CteUse *pCteUse = pItem->u2.pCteUse; | 147944 | CteUse *pCteUse = pItem->u2.pCteUse; |
| 142642 | sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); | 147945 | sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); |
| @@ -142645,7 +147948,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142645 | VdbeComment((v, "%!S", pItem)); | 147948 | VdbeComment((v, "%!S", pItem)); |
| 142646 | } | 147949 | } |
| 142647 | pSub->nSelectRow = pCteUse->nRowEst; | 147950 | pSub->nSelectRow = pCteUse->nRowEst; |
| 142648 | }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){ | 147951 | }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ |
| 142649 | /* This view has already been materialized by a prior entry in | 147952 | /* This view has already been materialized by a prior entry in |
| 142650 | ** this same FROM clause. Reuse it. */ | 147953 | ** this same FROM clause. Reuse it. */ |
| 142651 | if( pPrior->addrFillSub ){ | 147954 | if( pPrior->addrFillSub ){ |
| @@ -142659,6 +147962,9 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142659 | ** the same view can reuse the materialization. */ | 147962 | ** the same view can reuse the materialization. */ |
| 142660 | int topAddr; | 147963 | int topAddr; |
| 142661 | int onceAddr = 0; | 147964 | int onceAddr = 0; |
| 147965 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 147966 | int addrExplain; | ||
| 147967 | #endif | ||
| 142662 | 147968 | ||
| 142663 | pItem->regReturn = ++pParse->nMem; | 147969 | pItem->regReturn = ++pParse->nMem; |
| 142664 | topAddr = sqlite3VdbeAddOp0(v, OP_Goto); | 147970 | topAddr = sqlite3VdbeAddOp0(v, OP_Goto); |
| @@ -142674,12 +147980,14 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142674 | VdbeNoopComment((v, "materialize %!S", pItem)); | 147980 | VdbeNoopComment((v, "materialize %!S", pItem)); |
| 142675 | } | 147981 | } |
| 142676 | sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); | 147982 | sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); |
| 142677 | ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem)); | 147983 | |
| 147984 | ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); | ||
| 142678 | sqlite3Select(pParse, pSub, &dest); | 147985 | sqlite3Select(pParse, pSub, &dest); |
| 142679 | pItem->pTab->nRowLogEst = pSub->nSelectRow; | 147986 | pItem->pTab->nRowLogEst = pSub->nSelectRow; |
| 142680 | if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); | 147987 | if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); |
| 142681 | sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); | 147988 | sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); |
| 142682 | VdbeComment((v, "end %!S", pItem)); | 147989 | VdbeComment((v, "end %!S", pItem)); |
| 147990 | sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); | ||
| 142683 | sqlite3VdbeJumpHere(v, topAddr); | 147991 | sqlite3VdbeJumpHere(v, topAddr); |
| 142684 | sqlite3ClearTempRegCache(pParse); | 147992 | sqlite3ClearTempRegCache(pParse); |
| 142685 | if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ | 147993 | if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ |
| @@ -142705,8 +148013,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142705 | sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; | 148013 | sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; |
| 142706 | 148014 | ||
| 142707 | #if TREETRACE_ENABLED | 148015 | #if TREETRACE_ENABLED |
| 142708 | if( sqlite3TreeTrace & 0x400 ){ | 148016 | if( sqlite3TreeTrace & 0x8000 ){ |
| 142709 | SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); | 148017 | TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n")); |
| 142710 | sqlite3TreeViewSelect(0, p, 0); | 148018 | sqlite3TreeViewSelect(0, p, 0); |
| 142711 | } | 148019 | } |
| 142712 | #endif | 148020 | #endif |
| @@ -142742,8 +148050,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142742 | sDistinct.isTnct = 2; | 148050 | sDistinct.isTnct = 2; |
| 142743 | 148051 | ||
| 142744 | #if TREETRACE_ENABLED | 148052 | #if TREETRACE_ENABLED |
| 142745 | if( sqlite3TreeTrace & 0x400 ){ | 148053 | if( sqlite3TreeTrace & 0x20000 ){ |
| 142746 | SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); | 148054 | TREETRACE(0x20000,pParse,p,("Transform DISTINCT into GROUP BY:\n")); |
| 142747 | sqlite3TreeViewSelect(0, p, 0); | 148055 | sqlite3TreeViewSelect(0, p, 0); |
| 142748 | } | 148056 | } |
| 142749 | #endif | 148057 | #endif |
| @@ -142795,7 +148103,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142795 | if( (p->selFlags & SF_FixedLimit)==0 ){ | 148103 | if( (p->selFlags & SF_FixedLimit)==0 ){ |
| 142796 | p->nSelectRow = 320; /* 4 billion rows */ | 148104 | p->nSelectRow = 320; /* 4 billion rows */ |
| 142797 | } | 148105 | } |
| 142798 | computeLimitRegisters(pParse, p, iEnd); | 148106 | if( p->pLimit ) computeLimitRegisters(pParse, p, iEnd); |
| 142799 | if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ | 148107 | if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ |
| 142800 | sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); | 148108 | sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); |
| 142801 | sSort.sortFlags |= SORTFLAG_UseSorter; | 148109 | sSort.sortFlags |= SORTFLAG_UseSorter; |
| @@ -142829,7 +148137,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142829 | 148137 | ||
| 142830 | 148138 | ||
| 142831 | /* Begin the database scan. */ | 148139 | /* Begin the database scan. */ |
| 142832 | SELECTTRACE(1,pParse,p,("WhereBegin\n")); | 148140 | TREETRACE(0x2,pParse,p,("WhereBegin\n")); |
| 142833 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, | 148141 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, |
| 142834 | p->pEList, p, wctrlFlags, p->nSelectRow); | 148142 | p->pEList, p, wctrlFlags, p->nSelectRow); |
| 142835 | if( pWInfo==0 ) goto select_end; | 148143 | if( pWInfo==0 ) goto select_end; |
| @@ -142846,7 +148154,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142846 | sSort.pOrderBy = 0; | 148154 | sSort.pOrderBy = 0; |
| 142847 | } | 148155 | } |
| 142848 | } | 148156 | } |
| 142849 | SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); | 148157 | TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); |
| 142850 | 148158 | ||
| 142851 | /* If sorting index that was created by a prior OP_OpenEphemeral | 148159 | /* If sorting index that was created by a prior OP_OpenEphemeral |
| 142852 | ** instruction ended up not being needed, then change the OP_OpenEphemeral | 148160 | ** instruction ended up not being needed, then change the OP_OpenEphemeral |
| @@ -142885,7 +148193,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142885 | 148193 | ||
| 142886 | /* End the database scan loop. | 148194 | /* End the database scan loop. |
| 142887 | */ | 148195 | */ |
| 142888 | SELECTTRACE(1,pParse,p,("WhereEnd\n")); | 148196 | TREETRACE(0x2,pParse,p,("WhereEnd\n")); |
| 142889 | sqlite3WhereEnd(pWInfo); | 148197 | sqlite3WhereEnd(pWInfo); |
| 142890 | } | 148198 | } |
| 142891 | }else{ | 148199 | }else{ |
| @@ -142966,12 +148274,14 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142966 | goto select_end; | 148274 | goto select_end; |
| 142967 | } | 148275 | } |
| 142968 | pAggInfo->selId = p->selId; | 148276 | pAggInfo->selId = p->selId; |
| 148277 | #ifdef SQLITE_DEBUG | ||
| 148278 | pAggInfo->pSelect = p; | ||
| 148279 | #endif | ||
| 142969 | memset(&sNC, 0, sizeof(sNC)); | 148280 | memset(&sNC, 0, sizeof(sNC)); |
| 142970 | sNC.pParse = pParse; | 148281 | sNC.pParse = pParse; |
| 142971 | sNC.pSrcList = pTabList; | 148282 | sNC.pSrcList = pTabList; |
| 142972 | sNC.uNC.pAggInfo = pAggInfo; | 148283 | sNC.uNC.pAggInfo = pAggInfo; |
| 142973 | VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) | 148284 | VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) |
| 142974 | pAggInfo->mnReg = pParse->nMem+1; | ||
| 142975 | pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; | 148285 | pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; |
| 142976 | pAggInfo->pGroupBy = pGroupBy; | 148286 | pAggInfo->pGroupBy = pGroupBy; |
| 142977 | sqlite3ExprAnalyzeAggList(&sNC, pEList); | 148287 | sqlite3ExprAnalyzeAggList(&sNC, pEList); |
| @@ -142992,40 +148302,17 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 142992 | }else{ | 148302 | }else{ |
| 142993 | minMaxFlag = WHERE_ORDERBY_NORMAL; | 148303 | minMaxFlag = WHERE_ORDERBY_NORMAL; |
| 142994 | } | 148304 | } |
| 142995 | for(i=0; i<pAggInfo->nFunc; i++){ | 148305 | analyzeAggFuncArgs(pAggInfo, &sNC); |
| 142996 | Expr *pExpr = pAggInfo->aFunc[i].pFExpr; | ||
| 142997 | assert( ExprUseXList(pExpr) ); | ||
| 142998 | sNC.ncFlags |= NC_InAggFunc; | ||
| 142999 | sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList); | ||
| 143000 | #ifndef SQLITE_OMIT_WINDOWFUNC | ||
| 143001 | assert( !IsWindowFunc(pExpr) ); | ||
| 143002 | if( ExprHasProperty(pExpr, EP_WinFunc) ){ | ||
| 143003 | sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter); | ||
| 143004 | } | ||
| 143005 | #endif | ||
| 143006 | sNC.ncFlags &= ~NC_InAggFunc; | ||
| 143007 | } | ||
| 143008 | pAggInfo->mxReg = pParse->nMem; | ||
| 143009 | if( db->mallocFailed ) goto select_end; | 148306 | if( db->mallocFailed ) goto select_end; |
| 143010 | #if TREETRACE_ENABLED | 148307 | #if TREETRACE_ENABLED |
| 143011 | if( sqlite3TreeTrace & 0x400 ){ | 148308 | if( sqlite3TreeTrace & 0x20 ){ |
| 143012 | int ii; | 148309 | TREETRACE(0x20,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); |
| 143013 | SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); | ||
| 143014 | sqlite3TreeViewSelect(0, p, 0); | 148310 | sqlite3TreeViewSelect(0, p, 0); |
| 143015 | if( minMaxFlag ){ | 148311 | if( minMaxFlag ){ |
| 143016 | sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); | 148312 | sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); |
| 143017 | sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); | 148313 | sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); |
| 143018 | } | 148314 | } |
| 143019 | for(ii=0; ii<pAggInfo->nColumn; ii++){ | 148315 | printAggInfo(pAggInfo); |
| 143020 | sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", | ||
| 143021 | ii, pAggInfo->aCol[ii].iMem); | ||
| 143022 | sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); | ||
| 143023 | } | ||
| 143024 | for(ii=0; ii<pAggInfo->nFunc; ii++){ | ||
| 143025 | sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", | ||
| 143026 | ii, pAggInfo->aFunc[ii].iMem); | ||
| 143027 | sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0); | ||
| 143028 | } | ||
| 143029 | } | 148316 | } |
| 143030 | #endif | 148317 | #endif |
| 143031 | 148318 | ||
| @@ -143035,7 +148322,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143035 | */ | 148322 | */ |
| 143036 | if( pGroupBy ){ | 148323 | if( pGroupBy ){ |
| 143037 | KeyInfo *pKeyInfo; /* Keying information for the group by clause */ | 148324 | KeyInfo *pKeyInfo; /* Keying information for the group by clause */ |
| 143038 | int addr1; /* A-vs-B comparision jump */ | 148325 | int addr1; /* A-vs-B comparison jump */ |
| 143039 | int addrOutputRow; /* Start of subroutine that outputs a result row */ | 148326 | int addrOutputRow; /* Start of subroutine that outputs a result row */ |
| 143040 | int regOutputRow; /* Return address register for output subroutine */ | 148327 | int regOutputRow; /* Return address register for output subroutine */ |
| 143041 | int addrSetAbort; /* Set the abort flag and return */ | 148328 | int addrSetAbort; /* Set the abort flag and return */ |
| @@ -143094,17 +148381,21 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143094 | ** in the right order to begin with. | 148381 | ** in the right order to begin with. |
| 143095 | */ | 148382 | */ |
| 143096 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); | 148383 | sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); |
| 143097 | SELECTTRACE(1,pParse,p,("WhereBegin\n")); | 148384 | TREETRACE(0x2,pParse,p,("WhereBegin\n")); |
| 143098 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, | 148385 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, |
| 143099 | 0, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) | 148386 | p, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) |
| 143100 | | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 | 148387 | | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 |
| 143101 | ); | 148388 | ); |
| 143102 | if( pWInfo==0 ){ | 148389 | if( pWInfo==0 ){ |
| 143103 | sqlite3ExprListDelete(db, pDistinct); | 148390 | sqlite3ExprListDelete(db, pDistinct); |
| 143104 | goto select_end; | 148391 | goto select_end; |
| 143105 | } | 148392 | } |
| 148393 | if( pParse->pIdxEpr ){ | ||
| 148394 | optimizeAggregateUseOfIndexedExpr(pParse, p, pAggInfo, &sNC); | ||
| 148395 | } | ||
| 148396 | assignAggregateRegisters(pParse, pAggInfo); | ||
| 143106 | eDist = sqlite3WhereIsDistinct(pWInfo); | 148397 | eDist = sqlite3WhereIsDistinct(pWInfo); |
| 143107 | SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); | 148398 | TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); |
| 143108 | if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ | 148399 | if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ |
| 143109 | /* The optimizer is able to deliver rows in group by order so | 148400 | /* The optimizer is able to deliver rows in group by order so |
| 143110 | ** we do not have to sort. The OP_OpenEphemeral table will be | 148401 | ** we do not have to sort. The OP_OpenEphemeral table will be |
| @@ -143122,9 +148413,13 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143122 | int nCol; | 148413 | int nCol; |
| 143123 | int nGroupBy; | 148414 | int nGroupBy; |
| 143124 | 148415 | ||
| 143125 | explainTempTable(pParse, | 148416 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| 148417 | int addrExp; /* Address of OP_Explain instruction */ | ||
| 148418 | #endif | ||
| 148419 | ExplainQueryPlan2(addrExp, (pParse, 0, "USE TEMP B-TREE FOR %s", | ||
| 143126 | (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? | 148420 | (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? |
| 143127 | "DISTINCT" : "GROUP BY"); | 148421 | "DISTINCT" : "GROUP BY" |
| 148422 | )); | ||
| 143128 | 148423 | ||
| 143129 | groupBySort = 1; | 148424 | groupBySort = 1; |
| 143130 | nGroupBy = pGroupBy->nExpr; | 148425 | nGroupBy = pGroupBy->nExpr; |
| @@ -143139,28 +148434,50 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143139 | regBase = sqlite3GetTempRange(pParse, nCol); | 148434 | regBase = sqlite3GetTempRange(pParse, nCol); |
| 143140 | sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); | 148435 | sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); |
| 143141 | j = nGroupBy; | 148436 | j = nGroupBy; |
| 148437 | pAggInfo->directMode = 1; | ||
| 143142 | for(i=0; i<pAggInfo->nColumn; i++){ | 148438 | for(i=0; i<pAggInfo->nColumn; i++){ |
| 143143 | struct AggInfo_col *pCol = &pAggInfo->aCol[i]; | 148439 | struct AggInfo_col *pCol = &pAggInfo->aCol[i]; |
| 143144 | if( pCol->iSorterColumn>=j ){ | 148440 | if( pCol->iSorterColumn>=j ){ |
| 143145 | int r1 = j + regBase; | 148441 | sqlite3ExprCode(pParse, pCol->pCExpr, j + regBase); |
| 143146 | sqlite3ExprCodeGetColumnOfTable(v, | ||
| 143147 | pCol->pTab, pCol->iTable, pCol->iColumn, r1); | ||
| 143148 | j++; | 148442 | j++; |
| 143149 | } | 148443 | } |
| 143150 | } | 148444 | } |
| 148445 | pAggInfo->directMode = 0; | ||
| 143151 | regRecord = sqlite3GetTempReg(pParse); | 148446 | regRecord = sqlite3GetTempReg(pParse); |
| 148447 | sqlite3VdbeScanStatusCounters(v, addrExp, 0, sqlite3VdbeCurrentAddr(v)); | ||
| 143152 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); | 148448 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); |
| 143153 | sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); | 148449 | sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); |
| 148450 | sqlite3VdbeScanStatusRange(v, addrExp, sqlite3VdbeCurrentAddr(v)-2, -1); | ||
| 143154 | sqlite3ReleaseTempReg(pParse, regRecord); | 148451 | sqlite3ReleaseTempReg(pParse, regRecord); |
| 143155 | sqlite3ReleaseTempRange(pParse, regBase, nCol); | 148452 | sqlite3ReleaseTempRange(pParse, regBase, nCol); |
| 143156 | SELECTTRACE(1,pParse,p,("WhereEnd\n")); | 148453 | TREETRACE(0x2,pParse,p,("WhereEnd\n")); |
| 143157 | sqlite3WhereEnd(pWInfo); | 148454 | sqlite3WhereEnd(pWInfo); |
| 143158 | pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; | 148455 | pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; |
| 143159 | sortOut = sqlite3GetTempReg(pParse); | 148456 | sortOut = sqlite3GetTempReg(pParse); |
| 148457 | sqlite3VdbeScanStatusCounters(v, addrExp, sqlite3VdbeCurrentAddr(v), 0); | ||
| 143160 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); | 148458 | sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); |
| 143161 | sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); | 148459 | sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); |
| 143162 | VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); | 148460 | VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); |
| 143163 | pAggInfo->useSortingIdx = 1; | 148461 | pAggInfo->useSortingIdx = 1; |
| 148462 | sqlite3VdbeScanStatusRange(v, addrExp, -1, sortPTab); | ||
| 148463 | sqlite3VdbeScanStatusRange(v, addrExp, -1, pAggInfo->sortingIdx); | ||
| 148464 | } | ||
| 148465 | |||
| 148466 | /* If there are entries in pAgggInfo->aFunc[] that contain subexpressions | ||
| 148467 | ** that are indexed (and that were previously identified and tagged | ||
| 148468 | ** in optimizeAggregateUseOfIndexedExpr()) then those subexpressions | ||
| 148469 | ** must now be converted into a TK_AGG_COLUMN node so that the value | ||
| 148470 | ** is correctly pulled from the index rather than being recomputed. */ | ||
| 148471 | if( pParse->pIdxEpr ){ | ||
| 148472 | aggregateConvertIndexedExprRefToColumn(pAggInfo); | ||
| 148473 | #if TREETRACE_ENABLED | ||
| 148474 | if( sqlite3TreeTrace & 0x20 ){ | ||
| 148475 | TREETRACE(0x20, pParse, p, | ||
| 148476 | ("AggInfo function expressions converted to reference index\n")); | ||
| 148477 | sqlite3TreeViewSelect(0, p, 0); | ||
| 148478 | printAggInfo(pAggInfo); | ||
| 148479 | } | ||
| 148480 | #endif | ||
| 143164 | } | 148481 | } |
| 143165 | 148482 | ||
| 143166 | /* If the index or temporary table used by the GROUP BY sort | 148483 | /* If the index or temporary table used by the GROUP BY sort |
| @@ -143231,7 +148548,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143231 | sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); | 148548 | sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); |
| 143232 | VdbeCoverage(v); | 148549 | VdbeCoverage(v); |
| 143233 | }else{ | 148550 | }else{ |
| 143234 | SELECTTRACE(1,pParse,p,("WhereEnd\n")); | 148551 | TREETRACE(0x2,pParse,p,("WhereEnd\n")); |
| 143235 | sqlite3WhereEnd(pWInfo); | 148552 | sqlite3WhereEnd(pWInfo); |
| 143236 | sqlite3VdbeChangeToNoop(v, addrSortingIdx); | 148553 | sqlite3VdbeChangeToNoop(v, addrSortingIdx); |
| 143237 | } | 148554 | } |
| @@ -143341,7 +148658,8 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143341 | if( pKeyInfo ){ | 148658 | if( pKeyInfo ){ |
| 143342 | sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); | 148659 | sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); |
| 143343 | } | 148660 | } |
| 143344 | sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem); | 148661 | assignAggregateRegisters(pParse, pAggInfo); |
| 148662 | sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0)); | ||
| 143345 | sqlite3VdbeAddOp1(v, OP_Close, iCsr); | 148663 | sqlite3VdbeAddOp1(v, OP_Close, iCsr); |
| 143346 | explainSimpleCount(pParse, pTab, pBest); | 148664 | explainSimpleCount(pParse, pTab, pBest); |
| 143347 | }else{ | 148665 | }else{ |
| @@ -143377,6 +148695,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143377 | pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList; | 148695 | pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList; |
| 143378 | distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; | 148696 | distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; |
| 143379 | } | 148697 | } |
| 148698 | assignAggregateRegisters(pParse, pAggInfo); | ||
| 143380 | 148699 | ||
| 143381 | /* This case runs if the aggregate has no GROUP BY clause. The | 148700 | /* This case runs if the aggregate has no GROUP BY clause. The |
| 143382 | ** processing is much simpler since there is only a single row | 148701 | ** processing is much simpler since there is only a single row |
| @@ -143393,13 +148712,13 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143393 | assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); | 148712 | assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); |
| 143394 | assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); | 148713 | assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); |
| 143395 | 148714 | ||
| 143396 | SELECTTRACE(1,pParse,p,("WhereBegin\n")); | 148715 | TREETRACE(0x2,pParse,p,("WhereBegin\n")); |
| 143397 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, | 148716 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, |
| 143398 | pDistinct, 0, minMaxFlag|distFlag, 0); | 148717 | pDistinct, p, minMaxFlag|distFlag, 0); |
| 143399 | if( pWInfo==0 ){ | 148718 | if( pWInfo==0 ){ |
| 143400 | goto select_end; | 148719 | goto select_end; |
| 143401 | } | 148720 | } |
| 143402 | SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); | 148721 | TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); |
| 143403 | eDist = sqlite3WhereIsDistinct(pWInfo); | 148722 | eDist = sqlite3WhereIsDistinct(pWInfo); |
| 143404 | updateAccumulator(pParse, regAcc, pAggInfo, eDist); | 148723 | updateAccumulator(pParse, regAcc, pAggInfo, eDist); |
| 143405 | if( eDist!=WHERE_DISTINCT_NOOP ){ | 148724 | if( eDist!=WHERE_DISTINCT_NOOP ){ |
| @@ -143413,7 +148732,7 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143413 | if( minMaxFlag ){ | 148732 | if( minMaxFlag ){ |
| 143414 | sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); | 148733 | sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); |
| 143415 | } | 148734 | } |
| 143416 | SELECTTRACE(1,pParse,p,("WhereEnd\n")); | 148735 | TREETRACE(0x2,pParse,p,("WhereEnd\n")); |
| 143417 | sqlite3WhereEnd(pWInfo); | 148736 | sqlite3WhereEnd(pWInfo); |
| 143418 | finalizeAggFunctions(pParse, pAggInfo); | 148737 | finalizeAggFunctions(pParse, pAggInfo); |
| 143419 | } | 148738 | } |
| @@ -143435,8 +148754,6 @@ SQLITE_PRIVATE int sqlite3Select( | |||
| 143435 | ** and send them to the callback one by one. | 148754 | ** and send them to the callback one by one. |
| 143436 | */ | 148755 | */ |
| 143437 | if( sSort.pOrderBy ){ | 148756 | if( sSort.pOrderBy ){ |
| 143438 | explainTempTable(pParse, | ||
| 143439 | sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY"); | ||
| 143440 | assert( p->pEList==pEList ); | 148757 | assert( p->pEList==pEList ); |
| 143441 | generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); | 148758 | generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); |
| 143442 | } | 148759 | } |
| @@ -143460,7 +148777,7 @@ select_end: | |||
| 143460 | if( pAggInfo && !db->mallocFailed ){ | 148777 | if( pAggInfo && !db->mallocFailed ){ |
| 143461 | for(i=0; i<pAggInfo->nColumn; i++){ | 148778 | for(i=0; i<pAggInfo->nColumn; i++){ |
| 143462 | Expr *pExpr = pAggInfo->aCol[i].pCExpr; | 148779 | Expr *pExpr = pAggInfo->aCol[i].pCExpr; |
| 143463 | assert( pExpr!=0 ); | 148780 | if( pExpr==0 ) continue; |
| 143464 | assert( pExpr->pAggInfo==pAggInfo ); | 148781 | assert( pExpr->pAggInfo==pAggInfo ); |
| 143465 | assert( pExpr->iAgg==i ); | 148782 | assert( pExpr->iAgg==i ); |
| 143466 | } | 148783 | } |
| @@ -143474,8 +148791,8 @@ select_end: | |||
| 143474 | #endif | 148791 | #endif |
| 143475 | 148792 | ||
| 143476 | #if TREETRACE_ENABLED | 148793 | #if TREETRACE_ENABLED |
| 143477 | SELECTTRACE(0x1,pParse,p,("end processing\n")); | 148794 | TREETRACE(0x1,pParse,p,("end processing\n")); |
| 143478 | if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ | 148795 | if( (sqlite3TreeTrace & 0x40000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ |
| 143479 | sqlite3TreeViewSelect(0, p, 0); | 148796 | sqlite3TreeViewSelect(0, p, 0); |
| 143480 | } | 148797 | } |
| 143481 | #endif | 148798 | #endif |
| @@ -143749,7 +149066,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ | |||
| 143749 | if( pTrig->pTabSchema==pTab->pSchema | 149066 | if( pTrig->pTabSchema==pTab->pSchema |
| 143750 | && pTrig->table | 149067 | && pTrig->table |
| 143751 | && 0==sqlite3StrICmp(pTrig->table, pTab->zName) | 149068 | && 0==sqlite3StrICmp(pTrig->table, pTab->zName) |
| 143752 | && pTrig->pTabSchema!=pTmpSchema | 149069 | && (pTrig->pTabSchema!=pTmpSchema || pTrig->bReturning) |
| 143753 | ){ | 149070 | ){ |
| 143754 | pTrig->pNext = pList; | 149071 | pTrig->pNext = pList; |
| 143755 | pList = pTrig; | 149072 | pList = pTrig; |
| @@ -143890,6 +149207,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( | |||
| 143890 | }else{ | 149207 | }else{ |
| 143891 | assert( !db->init.busy ); | 149208 | assert( !db->init.busy ); |
| 143892 | sqlite3CodeVerifySchema(pParse, iDb); | 149209 | sqlite3CodeVerifySchema(pParse, iDb); |
| 149210 | VVA_ONLY( pParse->ifNotExists = 1; ) | ||
| 143893 | } | 149211 | } |
| 143894 | goto trigger_cleanup; | 149212 | goto trigger_cleanup; |
| 143895 | } | 149213 | } |
| @@ -144039,6 +149357,23 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( | |||
| 144039 | Vdbe *v; | 149357 | Vdbe *v; |
| 144040 | char *z; | 149358 | char *z; |
| 144041 | 149359 | ||
| 149360 | /* If this is a new CREATE TABLE statement, and if shadow tables | ||
| 149361 | ** are read-only, and the trigger makes a change to a shadow table, | ||
| 149362 | ** then raise an error - do not allow the trigger to be created. */ | ||
| 149363 | if( sqlite3ReadOnlyShadowTables(db) ){ | ||
| 149364 | TriggerStep *pStep; | ||
| 149365 | for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){ | ||
| 149366 | if( pStep->zTarget!=0 | ||
| 149367 | && sqlite3ShadowTableName(db, pStep->zTarget) | ||
| 149368 | ){ | ||
| 149369 | sqlite3ErrorMsg(pParse, | ||
| 149370 | "trigger \"%s\" may not write to shadow table \"%s\"", | ||
| 149371 | pTrig->zName, pStep->zTarget); | ||
| 149372 | goto triggerfinish_cleanup; | ||
| 149373 | } | ||
| 149374 | } | ||
| 149375 | } | ||
| 149376 | |||
| 144042 | /* Make an entry in the sqlite_schema table */ | 149377 | /* Make an entry in the sqlite_schema table */ |
| 144043 | v = sqlite3GetVdbe(pParse); | 149378 | v = sqlite3GetVdbe(pParse); |
| 144044 | if( v==0 ) goto triggerfinish_cleanup; | 149379 | if( v==0 ) goto triggerfinish_cleanup; |
| @@ -144654,7 +149989,7 @@ static void codeReturningTrigger( | |||
| 144654 | } | 149989 | } |
| 144655 | sqlite3ExprListDelete(db, sSelect.pEList); | 149990 | sqlite3ExprListDelete(db, sSelect.pEList); |
| 144656 | pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); | 149991 | pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); |
| 144657 | if( !db->mallocFailed ){ | 149992 | if( pParse->nErr==0 ){ |
| 144658 | NameContext sNC; | 149993 | NameContext sNC; |
| 144659 | memset(&sNC, 0, sizeof(sNC)); | 149994 | memset(&sNC, 0, sizeof(sNC)); |
| 144660 | if( pReturning->nRetCol==0 ){ | 149995 | if( pReturning->nRetCol==0 ){ |
| @@ -144862,7 +150197,7 @@ static TriggerPrg *codeRowTrigger( | |||
| 144862 | sSubParse.zAuthContext = pTrigger->zName; | 150197 | sSubParse.zAuthContext = pTrigger->zName; |
| 144863 | sSubParse.eTriggerOp = pTrigger->op; | 150198 | sSubParse.eTriggerOp = pTrigger->op; |
| 144864 | sSubParse.nQueryLoop = pParse->nQueryLoop; | 150199 | sSubParse.nQueryLoop = pParse->nQueryLoop; |
| 144865 | sSubParse.disableVtab = pParse->disableVtab; | 150200 | sSubParse.prepFlags = pParse->prepFlags; |
| 144866 | 150201 | ||
| 144867 | v = sqlite3GetVdbe(&sSubParse); | 150202 | v = sqlite3GetVdbe(&sSubParse); |
| 144868 | if( v ){ | 150203 | if( v ){ |
| @@ -145123,6 +150458,9 @@ SQLITE_PRIVATE u32 sqlite3TriggerColmask( | |||
| 145123 | Trigger *p; | 150458 | Trigger *p; |
| 145124 | 150459 | ||
| 145125 | assert( isNew==1 || isNew==0 ); | 150460 | assert( isNew==1 || isNew==0 ); |
| 150461 | if( IsView(pTab) ){ | ||
| 150462 | return 0xffffffff; | ||
| 150463 | } | ||
| 145126 | for(p=pTrigger; p; p=p->pNext){ | 150464 | for(p=pTrigger; p; p=p->pNext){ |
| 145127 | if( p->op==op | 150465 | if( p->op==op |
| 145128 | && (tr_tm&p->tr_tm) | 150466 | && (tr_tm&p->tr_tm) |
| @@ -145208,11 +150546,14 @@ static void updateVirtualTable( | |||
| 145208 | ** it has been converted into REAL. | 150546 | ** it has been converted into REAL. |
| 145209 | */ | 150547 | */ |
| 145210 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ | 150548 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ |
| 150549 | Column *pCol; | ||
| 145211 | assert( pTab!=0 ); | 150550 | assert( pTab!=0 ); |
| 145212 | if( !IsView(pTab) ){ | 150551 | assert( pTab->nCol>i ); |
| 150552 | pCol = &pTab->aCol[i]; | ||
| 150553 | if( pCol->iDflt ){ | ||
| 145213 | sqlite3_value *pValue = 0; | 150554 | sqlite3_value *pValue = 0; |
| 145214 | u8 enc = ENC(sqlite3VdbeDb(v)); | 150555 | u8 enc = ENC(sqlite3VdbeDb(v)); |
| 145215 | Column *pCol = &pTab->aCol[i]; | 150556 | assert( !IsView(pTab) ); |
| 145216 | VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); | 150557 | VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); |
| 145217 | assert( i<pTab->nCol ); | 150558 | assert( i<pTab->nCol ); |
| 145218 | sqlite3ValueFromExpr(sqlite3VdbeDb(v), | 150559 | sqlite3ValueFromExpr(sqlite3VdbeDb(v), |
| @@ -145223,7 +150564,7 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ | |||
| 145223 | } | 150564 | } |
| 145224 | } | 150565 | } |
| 145225 | #ifndef SQLITE_OMIT_FLOATING_POINT | 150566 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 145226 | if( pTab->aCol[i].affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ | 150567 | if( pCol->affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ |
| 145227 | sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); | 150568 | sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); |
| 145228 | } | 150569 | } |
| 145229 | #endif | 150570 | #endif |
| @@ -145370,7 +150711,7 @@ static void updateFromSelect( | |||
| 145370 | 150711 | ||
| 145371 | assert( pTabList->nSrc>1 ); | 150712 | assert( pTabList->nSrc>1 ); |
| 145372 | if( pSrc ){ | 150713 | if( pSrc ){ |
| 145373 | pSrc->a[0].fg.notCte = 1; | 150714 | assert( pSrc->a[0].fg.notCte ); |
| 145374 | pSrc->a[0].iCursor = -1; | 150715 | pSrc->a[0].iCursor = -1; |
| 145375 | pSrc->a[0].pTab->nTabRef--; | 150716 | pSrc->a[0].pTab->nTabRef--; |
| 145376 | pSrc->a[0].pTab = 0; | 150717 | pSrc->a[0].pTab = 0; |
| @@ -145409,7 +150750,8 @@ static void updateFromSelect( | |||
| 145409 | } | 150750 | } |
| 145410 | } | 150751 | } |
| 145411 | pSelect = sqlite3SelectNew(pParse, pList, | 150752 | pSelect = sqlite3SelectNew(pParse, pList, |
| 145412 | pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UFSrcCheck|SF_IncludeHidden, pLimit2 | 150753 | pSrc, pWhere2, pGrp, 0, pOrderBy2, |
| 150754 | SF_UFSrcCheck|SF_IncludeHidden|SF_UpdateFrom, pLimit2 | ||
| 145413 | ); | 150755 | ); |
| 145414 | if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; | 150756 | if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; |
| 145415 | sqlite3SelectDestInit(&dest, eDest, iEph); | 150757 | sqlite3SelectDestInit(&dest, eDest, iEph); |
| @@ -145553,7 +150895,7 @@ SQLITE_PRIVATE void sqlite3Update( | |||
| 145553 | if( sqlite3ViewGetColumnNames(pParse, pTab) ){ | 150895 | if( sqlite3ViewGetColumnNames(pParse, pTab) ){ |
| 145554 | goto update_cleanup; | 150896 | goto update_cleanup; |
| 145555 | } | 150897 | } |
| 145556 | if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ | 150898 | if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ |
| 145557 | goto update_cleanup; | 150899 | goto update_cleanup; |
| 145558 | } | 150900 | } |
| 145559 | 150901 | ||
| @@ -145872,12 +151214,22 @@ SQLITE_PRIVATE void sqlite3Update( | |||
| 145872 | /* Begin the database scan. | 151214 | /* Begin the database scan. |
| 145873 | ** | 151215 | ** |
| 145874 | ** Do not consider a single-pass strategy for a multi-row update if | 151216 | ** Do not consider a single-pass strategy for a multi-row update if |
| 145875 | ** there are any triggers or foreign keys to process, or rows may | 151217 | ** there is anything that might disrupt the cursor being used to do |
| 145876 | ** be deleted as a result of REPLACE conflict handling. Any of these | 151218 | ** the UPDATE: |
| 145877 | ** things might disturb a cursor being used to scan through the table | 151219 | ** (1) This is a nested UPDATE |
| 145878 | ** or index, causing a single-pass approach to malfunction. */ | 151220 | ** (2) There are triggers |
| 151221 | ** (3) There are FOREIGN KEY constraints | ||
| 151222 | ** (4) There are REPLACE conflict handlers | ||
| 151223 | ** (5) There are subqueries in the WHERE clause | ||
| 151224 | */ | ||
| 145879 | flags = WHERE_ONEPASS_DESIRED; | 151225 | flags = WHERE_ONEPASS_DESIRED; |
| 145880 | if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ | 151226 | if( !pParse->nested |
| 151227 | && !pTrigger | ||
| 151228 | && !hasFK | ||
| 151229 | && !chngKey | ||
| 151230 | && !bReplace | ||
| 151231 | && (pWhere==0 || !ExprHasProperty(pWhere, EP_Subquery)) | ||
| 151232 | ){ | ||
| 145881 | flags |= WHERE_ONEPASS_MULTIROW; | 151233 | flags |= WHERE_ONEPASS_MULTIROW; |
| 145882 | } | 151234 | } |
| 145883 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur); | 151235 | pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur); |
| @@ -145948,6 +151300,8 @@ SQLITE_PRIVATE void sqlite3Update( | |||
| 145948 | 151300 | ||
| 145949 | if( !isView ){ | 151301 | if( !isView ){ |
| 145950 | int addrOnce = 0; | 151302 | int addrOnce = 0; |
| 151303 | int iNotUsed1 = 0; | ||
| 151304 | int iNotUsed2 = 0; | ||
| 145951 | 151305 | ||
| 145952 | /* Open every index that needs updating. */ | 151306 | /* Open every index that needs updating. */ |
| 145953 | if( eOnePass!=ONEPASS_OFF ){ | 151307 | if( eOnePass!=ONEPASS_OFF ){ |
| @@ -145959,7 +151313,7 @@ SQLITE_PRIVATE void sqlite3Update( | |||
| 145959 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); | 151313 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); |
| 145960 | } | 151314 | } |
| 145961 | sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, | 151315 | sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, |
| 145962 | aToOpen, 0, 0); | 151316 | aToOpen, &iNotUsed1, &iNotUsed2); |
| 145963 | if( addrOnce ){ | 151317 | if( addrOnce ){ |
| 145964 | sqlite3VdbeJumpHereOrPopInst(v, addrOnce); | 151318 | sqlite3VdbeJumpHereOrPopInst(v, addrOnce); |
| 145965 | } | 151319 | } |
| @@ -146250,8 +151604,10 @@ SQLITE_PRIVATE void sqlite3Update( | |||
| 146250 | sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); | 151604 | sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); |
| 146251 | } | 151605 | } |
| 146252 | 151606 | ||
| 146253 | sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, | 151607 | if( pTrigger ){ |
| 146254 | TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); | 151608 | sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, |
| 151609 | TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); | ||
| 151610 | } | ||
| 146255 | 151611 | ||
| 146256 | /* Repeat the above with the next record to be updated, until | 151612 | /* Repeat the above with the next record to be updated, until |
| 146257 | ** all record selected by the WHERE clause have been updated. | 151613 | ** all record selected by the WHERE clause have been updated. |
| @@ -146346,7 +151702,7 @@ static void updateVirtualTable( | |||
| 146346 | int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */ | 151702 | int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */ |
| 146347 | int regArg; /* First register in VUpdate arg array */ | 151703 | int regArg; /* First register in VUpdate arg array */ |
| 146348 | int regRec; /* Register in which to assemble record */ | 151704 | int regRec; /* Register in which to assemble record */ |
| 146349 | int regRowid; /* Register for ephem table rowid */ | 151705 | int regRowid; /* Register for ephemeral table rowid */ |
| 146350 | int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ | 151706 | int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ |
| 146351 | int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ | 151707 | int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ |
| 146352 | int eOnePass; /* True to use onepass strategy */ | 151708 | int eOnePass; /* True to use onepass strategy */ |
| @@ -146390,7 +151746,9 @@ static void updateVirtualTable( | |||
| 146390 | sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0) | 151746 | sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0) |
| 146391 | ); | 151747 | ); |
| 146392 | }else{ | 151748 | }else{ |
| 146393 | pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); | 151749 | Expr *pRowExpr = exprRowColumn(pParse, i); |
| 151750 | if( pRowExpr ) pRowExpr->op2 = OPFLAG_NOCHNG; | ||
| 151751 | pList = sqlite3ExprListAppend(pParse, pList, pRowExpr); | ||
| 146394 | } | 151752 | } |
| 146395 | } | 151753 | } |
| 146396 | 151754 | ||
| @@ -146467,7 +151825,7 @@ static void updateVirtualTable( | |||
| 146467 | sqlite3WhereEnd(pWInfo); | 151825 | sqlite3WhereEnd(pWInfo); |
| 146468 | } | 151826 | } |
| 146469 | 151827 | ||
| 146470 | /* Begin scannning through the ephemeral table. */ | 151828 | /* Begin scanning through the ephemeral table. */ |
| 146471 | addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); | 151829 | addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); |
| 146472 | 151830 | ||
| 146473 | /* Extract arguments from the current row of the ephemeral table and | 151831 | /* Extract arguments from the current row of the ephemeral table and |
| @@ -146663,6 +152021,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( | |||
| 146663 | if( pIdx->aiColumn[ii]==XN_EXPR ){ | 152021 | if( pIdx->aiColumn[ii]==XN_EXPR ){ |
| 146664 | assert( pIdx->aColExpr!=0 ); | 152022 | assert( pIdx->aColExpr!=0 ); |
| 146665 | assert( pIdx->aColExpr->nExpr>ii ); | 152023 | assert( pIdx->aColExpr->nExpr>ii ); |
| 152024 | assert( pIdx->bHasExpr ); | ||
| 146666 | pExpr = pIdx->aColExpr->a[ii].pExpr; | 152025 | pExpr = pIdx->aColExpr->a[ii].pExpr; |
| 146667 | if( pExpr->op!=TK_COLLATE ){ | 152026 | if( pExpr->op!=TK_COLLATE ){ |
| 146668 | sCol[0].pLeft = pExpr; | 152027 | sCol[0].pLeft = pExpr; |
| @@ -146674,7 +152033,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( | |||
| 146674 | pExpr = &sCol[0]; | 152033 | pExpr = &sCol[0]; |
| 146675 | } | 152034 | } |
| 146676 | for(jj=0; jj<nn; jj++){ | 152035 | for(jj=0; jj<nn; jj++){ |
| 146677 | if( sqlite3ExprCompare(pParse,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){ | 152036 | if( sqlite3ExprCompare(0,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){ |
| 146678 | break; /* Column ii of the index matches column jj of target */ | 152037 | break; /* Column ii of the index matches column jj of target */ |
| 146679 | } | 152038 | } |
| 146680 | } | 152039 | } |
| @@ -146976,6 +152335,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( | |||
| 146976 | int nDb; /* Number of attached databases */ | 152335 | int nDb; /* Number of attached databases */ |
| 146977 | const char *zDbMain; /* Schema name of database to vacuum */ | 152336 | const char *zDbMain; /* Schema name of database to vacuum */ |
| 146978 | const char *zOut; /* Name of output file */ | 152337 | const char *zOut; /* Name of output file */ |
| 152338 | u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ | ||
| 146979 | 152339 | ||
| 146980 | if( !db->autoCommit ){ | 152340 | if( !db->autoCommit ){ |
| 146981 | sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); | 152341 | sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); |
| @@ -147022,7 +152382,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( | |||
| 147022 | ** (possibly synchronous) transaction opened on the main database before | 152382 | ** (possibly synchronous) transaction opened on the main database before |
| 147023 | ** sqlite3BtreeCopyFile() is called. | 152383 | ** sqlite3BtreeCopyFile() is called. |
| 147024 | ** | 152384 | ** |
| 147025 | ** An optimisation would be to use a non-journaled pager. | 152385 | ** An optimization would be to use a non-journaled pager. |
| 147026 | ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but | 152386 | ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but |
| 147027 | ** that actually made the VACUUM run slower. Very little journalling | 152387 | ** that actually made the VACUUM run slower. Very little journalling |
| 147028 | ** actually occurs when doing a vacuum since the vacuum_db is initially | 152388 | ** actually occurs when doing a vacuum since the vacuum_db is initially |
| @@ -147047,12 +152407,17 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( | |||
| 147047 | goto end_of_vacuum; | 152407 | goto end_of_vacuum; |
| 147048 | } | 152408 | } |
| 147049 | db->mDbFlags |= DBFLAG_VacuumInto; | 152409 | db->mDbFlags |= DBFLAG_VacuumInto; |
| 152410 | |||
| 152411 | /* For a VACUUM INTO, the pager-flags are set to the same values as | ||
| 152412 | ** they are for the database being vacuumed, except that PAGER_CACHESPILL | ||
| 152413 | ** is always set. */ | ||
| 152414 | pgflags = db->aDb[iDb].safety_level | (db->flags & PAGER_FLAGS_MASK); | ||
| 147050 | } | 152415 | } |
| 147051 | nRes = sqlite3BtreeGetRequestedReserve(pMain); | 152416 | nRes = sqlite3BtreeGetRequestedReserve(pMain); |
| 147052 | 152417 | ||
| 147053 | sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); | 152418 | sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); |
| 147054 | sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); | 152419 | sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); |
| 147055 | sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL); | 152420 | sqlite3BtreeSetPagerFlags(pTemp, pgflags|PAGER_CACHESPILL); |
| 147056 | 152421 | ||
| 147057 | /* Begin a transaction and take an exclusive lock on the main database | 152422 | /* Begin a transaction and take an exclusive lock on the main database |
| 147058 | ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, | 152423 | ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, |
| @@ -147436,10 +152801,10 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ | |||
| 147436 | pVTab->nRef--; | 152801 | pVTab->nRef--; |
| 147437 | if( pVTab->nRef==0 ){ | 152802 | if( pVTab->nRef==0 ){ |
| 147438 | sqlite3_vtab *p = pVTab->pVtab; | 152803 | sqlite3_vtab *p = pVTab->pVtab; |
| 147439 | sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); | ||
| 147440 | if( p ){ | 152804 | if( p ){ |
| 147441 | p->pModule->xDisconnect(p); | 152805 | p->pModule->xDisconnect(p); |
| 147442 | } | 152806 | } |
| 152807 | sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); | ||
| 147443 | sqlite3DbFree(db, pVTab); | 152808 | sqlite3DbFree(db, pVTab); |
| 147444 | } | 152809 | } |
| 147445 | } | 152810 | } |
| @@ -147565,7 +152930,8 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ | |||
| 147565 | */ | 152930 | */ |
| 147566 | SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ | 152931 | SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ |
| 147567 | assert( IsVirtual(p) ); | 152932 | assert( IsVirtual(p) ); |
| 147568 | if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); | 152933 | assert( db!=0 ); |
| 152934 | if( db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); | ||
| 147569 | if( p->u.vtab.azArg ){ | 152935 | if( p->u.vtab.azArg ){ |
| 147570 | int i; | 152936 | int i; |
| 147571 | for(i=0; i<p->u.vtab.nArg; i++){ | 152937 | for(i=0; i<p->u.vtab.nArg; i++){ |
| @@ -147705,7 +153071,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ | |||
| 147705 | ** the information we've collected. | 153071 | ** the information we've collected. |
| 147706 | ** | 153072 | ** |
| 147707 | ** The VM register number pParse->regRowid holds the rowid of an | 153073 | ** The VM register number pParse->regRowid holds the rowid of an |
| 147708 | ** entry in the sqlite_schema table tht was created for this vtab | 153074 | ** entry in the sqlite_schema table that was created for this vtab |
| 147709 | ** by sqlite3StartTable(). | 153075 | ** by sqlite3StartTable(). |
| 147710 | */ | 153076 | */ |
| 147711 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | 153077 | iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
| @@ -147834,7 +153200,9 @@ static int vtabCallConstructor( | |||
| 147834 | sCtx.pPrior = db->pVtabCtx; | 153200 | sCtx.pPrior = db->pVtabCtx; |
| 147835 | sCtx.bDeclared = 0; | 153201 | sCtx.bDeclared = 0; |
| 147836 | db->pVtabCtx = &sCtx; | 153202 | db->pVtabCtx = &sCtx; |
| 153203 | pTab->nTabRef++; | ||
| 147837 | rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); | 153204 | rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); |
| 153205 | sqlite3DeleteTable(db, pTab); | ||
| 147838 | db->pVtabCtx = sCtx.pPrior; | 153206 | db->pVtabCtx = sCtx.pPrior; |
| 147839 | if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); | 153207 | if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); |
| 147840 | assert( sCtx.pTab==pTab ); | 153208 | assert( sCtx.pTab==pTab ); |
| @@ -148324,7 +153692,10 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ | |||
| 148324 | break; | 153692 | break; |
| 148325 | } | 153693 | } |
| 148326 | if( xMethod && pVTab->iSavepoint>iSavepoint ){ | 153694 | if( xMethod && pVTab->iSavepoint>iSavepoint ){ |
| 153695 | u64 savedFlags = (db->flags & SQLITE_Defensive); | ||
| 153696 | db->flags &= ~(u64)SQLITE_Defensive; | ||
| 148327 | rc = xMethod(pVTab->pVtab, iSavepoint); | 153697 | rc = xMethod(pVTab->pVtab, iSavepoint); |
| 153698 | db->flags |= savedFlags; | ||
| 148328 | } | 153699 | } |
| 148329 | sqlite3VtabUnlock(pVTab); | 153700 | sqlite3VtabUnlock(pVTab); |
| 148330 | } | 153701 | } |
| @@ -148365,7 +153736,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( | |||
| 148365 | if( pExpr->op!=TK_COLUMN ) return pDef; | 153736 | if( pExpr->op!=TK_COLUMN ) return pDef; |
| 148366 | assert( ExprUseYTab(pExpr) ); | 153737 | assert( ExprUseYTab(pExpr) ); |
| 148367 | pTab = pExpr->y.pTab; | 153738 | pTab = pExpr->y.pTab; |
| 148368 | if( pTab==0 ) return pDef; | 153739 | if( NEVER(pTab==0) ) return pDef; |
| 148369 | if( !IsVirtual(pTab) ) return pDef; | 153740 | if( !IsVirtual(pTab) ) return pDef; |
| 148370 | pVtab = sqlite3GetVTable(db, pTab)->pVtab; | 153741 | pVtab = sqlite3GetVTable(db, pTab)->pVtab; |
| 148371 | assert( pVtab!=0 ); | 153742 | assert( pVtab!=0 ); |
| @@ -148444,7 +153815,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ | |||
| 148444 | ** | 153815 | ** |
| 148445 | ** An eponymous virtual table instance is one that is named after its | 153816 | ** An eponymous virtual table instance is one that is named after its |
| 148446 | ** module, and more importantly, does not require a CREATE VIRTUAL TABLE | 153817 | ** module, and more importantly, does not require a CREATE VIRTUAL TABLE |
| 148447 | ** statement in order to come into existance. Eponymous virtual table | 153818 | ** statement in order to come into existence. Eponymous virtual table |
| 148448 | ** instances always exist. They cannot be DROP-ed. | 153819 | ** instances always exist. They cannot be DROP-ed. |
| 148449 | ** | 153820 | ** |
| 148450 | ** Any virtual table module for which xConnect and xCreate are the same | 153821 | ** Any virtual table module for which xConnect and xCreate are the same |
| @@ -148553,6 +153924,10 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ | |||
| 148553 | p->pVTable->eVtabRisk = SQLITE_VTABRISK_High; | 153924 | p->pVTable->eVtabRisk = SQLITE_VTABRISK_High; |
| 148554 | break; | 153925 | break; |
| 148555 | } | 153926 | } |
| 153927 | case SQLITE_VTAB_USES_ALL_SCHEMAS: { | ||
| 153928 | p->pVTable->bAllSchemas = 1; | ||
| 153929 | break; | ||
| 153930 | } | ||
| 148556 | default: { | 153931 | default: { |
| 148557 | rc = SQLITE_MISUSE_BKPT; | 153932 | rc = SQLITE_MISUSE_BKPT; |
| 148558 | break; | 153933 | break; |
| @@ -148631,7 +154006,7 @@ typedef struct WhereRightJoin WhereRightJoin; | |||
| 148631 | 154006 | ||
| 148632 | /* | 154007 | /* |
| 148633 | ** This object is a header on a block of allocated memory that will be | 154008 | ** This object is a header on a block of allocated memory that will be |
| 148634 | ** automatically freed when its WInfo oject is destructed. | 154009 | ** automatically freed when its WInfo object is destructed. |
| 148635 | */ | 154010 | */ |
| 148636 | struct WhereMemBlock { | 154011 | struct WhereMemBlock { |
| 148637 | WhereMemBlock *pNext; /* Next block in the chain */ | 154012 | WhereMemBlock *pNext; /* Next block in the chain */ |
| @@ -148692,7 +154067,7 @@ struct WhereLevel { | |||
| 148692 | int iCur; /* The VDBE cursor used by this IN operator */ | 154067 | int iCur; /* The VDBE cursor used by this IN operator */ |
| 148693 | int addrInTop; /* Top of the IN loop */ | 154068 | int addrInTop; /* Top of the IN loop */ |
| 148694 | int iBase; /* Base register of multi-key index record */ | 154069 | int iBase; /* Base register of multi-key index record */ |
| 148695 | int nPrefix; /* Number of prior entires in the key */ | 154070 | int nPrefix; /* Number of prior entries in the key */ |
| 148696 | u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ | 154071 | u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ |
| 148697 | } *aInLoop; /* Information about each nested IN operator */ | 154072 | } *aInLoop; /* Information about each nested IN operator */ |
| 148698 | } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ | 154073 | } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ |
| @@ -148942,7 +154317,7 @@ struct WhereClause { | |||
| 148942 | int nTerm; /* Number of terms */ | 154317 | int nTerm; /* Number of terms */ |
| 148943 | int nSlot; /* Number of entries in a[] */ | 154318 | int nSlot; /* Number of entries in a[] */ |
| 148944 | int nBase; /* Number of terms through the last non-Virtual */ | 154319 | int nBase; /* Number of terms through the last non-Virtual */ |
| 148945 | WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ | 154320 | WhereTerm *a; /* Each a[] describes a term of the WHERE clause */ |
| 148946 | #if defined(SQLITE_SMALL_STACK) | 154321 | #if defined(SQLITE_SMALL_STACK) |
| 148947 | WhereTerm aStatic[1]; /* Initial static space for a[] */ | 154322 | WhereTerm aStatic[1]; /* Initial static space for a[] */ |
| 148948 | #else | 154323 | #else |
| @@ -148972,7 +154347,7 @@ struct WhereAndInfo { | |||
| 148972 | ** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. | 154347 | ** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. |
| 148973 | ** | 154348 | ** |
| 148974 | ** The VDBE cursor numbers are small integers contained in | 154349 | ** The VDBE cursor numbers are small integers contained in |
| 148975 | ** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE | 154350 | ** SrcItem.iCursor and Expr.iTable fields. For any given WHERE |
| 148976 | ** clause, the cursor numbers might not begin with 0 and they might | 154351 | ** clause, the cursor numbers might not begin with 0 and they might |
| 148977 | ** contain gaps in the numbering sequence. But we want to make maximum | 154352 | ** contain gaps in the numbering sequence. But we want to make maximum |
| 148978 | ** use of the bits in our bitmasks. This structure provides a mapping | 154353 | ** use of the bits in our bitmasks. This structure provides a mapping |
| @@ -149044,20 +154419,6 @@ struct WhereLoopBuilder { | |||
| 149044 | #endif | 154419 | #endif |
| 149045 | 154420 | ||
| 149046 | /* | 154421 | /* |
| 149047 | ** Each instance of this object records a change to a single node | ||
| 149048 | ** in an expression tree to cause that node to point to a column | ||
| 149049 | ** of an index rather than an expression or a virtual column. All | ||
| 149050 | ** such transformations need to be undone at the end of WHERE clause | ||
| 149051 | ** processing. | ||
| 149052 | */ | ||
| 149053 | typedef struct WhereExprMod WhereExprMod; | ||
| 149054 | struct WhereExprMod { | ||
| 149055 | WhereExprMod *pNext; /* Next translation on a list of them all */ | ||
| 149056 | Expr *pExpr; /* The Expr node that was transformed */ | ||
| 149057 | Expr orig; /* Original value of the Expr node */ | ||
| 149058 | }; | ||
| 149059 | |||
| 149060 | /* | ||
| 149061 | ** The WHERE clause processing routine has two halves. The | 154422 | ** The WHERE clause processing routine has two halves. The |
| 149062 | ** first part does the start of the WHERE loop and the second | 154423 | ** first part does the start of the WHERE loop and the second |
| 149063 | ** half does the tail of the WHERE loop. An instance of | 154424 | ** half does the tail of the WHERE loop. An instance of |
| @@ -149072,10 +154433,10 @@ struct WhereInfo { | |||
| 149072 | SrcList *pTabList; /* List of tables in the join */ | 154433 | SrcList *pTabList; /* List of tables in the join */ |
| 149073 | ExprList *pOrderBy; /* The ORDER BY clause or NULL */ | 154434 | ExprList *pOrderBy; /* The ORDER BY clause or NULL */ |
| 149074 | ExprList *pResultSet; /* Result set of the query */ | 154435 | ExprList *pResultSet; /* Result set of the query */ |
| 154436 | #if WHERETRACE_ENABLED | ||
| 149075 | Expr *pWhere; /* The complete WHERE clause */ | 154437 | Expr *pWhere; /* The complete WHERE clause */ |
| 149076 | #ifndef SQLITE_OMIT_VIRTUALTABLE | ||
| 149077 | Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */ | ||
| 149078 | #endif | 154438 | #endif |
| 154439 | Select *pSelect; /* The entire SELECT statement containing WHERE */ | ||
| 149079 | int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ | 154440 | int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ |
| 149080 | int iContinue; /* Jump here to continue with next record */ | 154441 | int iContinue; /* Jump here to continue with next record */ |
| 149081 | int iBreak; /* Jump here to break out of the loop */ | 154442 | int iBreak; /* Jump here to break out of the loop */ |
| @@ -149094,7 +154455,6 @@ struct WhereInfo { | |||
| 149094 | int iTop; /* The very beginning of the WHERE loop */ | 154455 | int iTop; /* The very beginning of the WHERE loop */ |
| 149095 | int iEndWhere; /* End of the WHERE clause itself */ | 154456 | int iEndWhere; /* End of the WHERE clause itself */ |
| 149096 | WhereLoop *pLoops; /* List of all WhereLoop objects */ | 154457 | WhereLoop *pLoops; /* List of all WhereLoop objects */ |
| 149097 | WhereExprMod *pExprMods; /* Expression modifications */ | ||
| 149098 | WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ | 154458 | WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ |
| 149099 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ | 154459 | Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ |
| 149100 | WhereClause sWC; /* Decomposition of the WHERE clause */ | 154460 | WhereClause sWC; /* Decomposition of the WHERE clause */ |
| @@ -149242,6 +154602,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); | |||
| 149242 | #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ | 154602 | #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ |
| 149243 | #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ | 154603 | #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ |
| 149244 | #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ | 154604 | #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ |
| 154605 | #define WHERE_VIEWSCAN 0x02000000 /* A full-scan of a VIEW or subquery */ | ||
| 154606 | #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ | ||
| 149245 | 154607 | ||
| 149246 | #endif /* !defined(SQLITE_WHEREINT_H) */ | 154608 | #endif /* !defined(SQLITE_WHEREINT_H) */ |
| 149247 | 154609 | ||
| @@ -149339,9 +154701,9 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ | |||
| 149339 | 154701 | ||
| 149340 | /* | 154702 | /* |
| 149341 | ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN | 154703 | ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN |
| 149342 | ** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was | 154704 | ** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG |
| 149343 | ** defined at compile-time. If it is not a no-op, a single OP_Explain opcode | 154705 | ** was defined at compile-time. If it is not a no-op, a single OP_Explain |
| 149344 | ** is added to the output to describe the table scan strategy in pLevel. | 154706 | ** opcode is added to the output to describe the table scan strategy in pLevel. |
| 149345 | ** | 154707 | ** |
| 149346 | ** If an OP_Explain opcode is added to the VM, its address is returned. | 154708 | ** If an OP_Explain opcode is added to the VM, its address is returned. |
| 149347 | ** Otherwise, if no OP_Explain is coded, zero is returned. | 154709 | ** Otherwise, if no OP_Explain is coded, zero is returned. |
| @@ -149353,8 +154715,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( | |||
| 149353 | u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ | 154715 | u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ |
| 149354 | ){ | 154716 | ){ |
| 149355 | int ret = 0; | 154717 | int ret = 0; |
| 149356 | #if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) | 154718 | #if !defined(SQLITE_DEBUG) |
| 149357 | if( sqlite3ParseToplevel(pParse)->explain==2 ) | 154719 | if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) |
| 149358 | #endif | 154720 | #endif |
| 149359 | { | 154721 | { |
| 149360 | SrcItem *pItem = &pTabList->a[pLevel->iFrom]; | 154722 | SrcItem *pItem = &pTabList->a[pLevel->iFrom]; |
| @@ -149498,6 +154860,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( | |||
| 149498 | zMsg = sqlite3StrAccumFinish(&str); | 154860 | zMsg = sqlite3StrAccumFinish(&str); |
| 149499 | ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), | 154861 | ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), |
| 149500 | pParse->addrExplain, 0, zMsg,P4_DYNAMIC); | 154862 | pParse->addrExplain, 0, zMsg,P4_DYNAMIC); |
| 154863 | |||
| 154864 | sqlite3VdbeScanStatus(v, sqlite3VdbeCurrentAddr(v)-1, 0, 0, 0, 0); | ||
| 149501 | return ret; | 154865 | return ret; |
| 149502 | } | 154866 | } |
| 149503 | #endif /* SQLITE_OMIT_EXPLAIN */ | 154867 | #endif /* SQLITE_OMIT_EXPLAIN */ |
| @@ -149518,16 +154882,37 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( | |||
| 149518 | WhereLevel *pLvl, /* Level to add scanstatus() entry for */ | 154882 | WhereLevel *pLvl, /* Level to add scanstatus() entry for */ |
| 149519 | int addrExplain /* Address of OP_Explain (or 0) */ | 154883 | int addrExplain /* Address of OP_Explain (or 0) */ |
| 149520 | ){ | 154884 | ){ |
| 149521 | const char *zObj = 0; | 154885 | if( IS_STMT_SCANSTATUS( sqlite3VdbeDb(v) ) ){ |
| 149522 | WhereLoop *pLoop = pLvl->pWLoop; | 154886 | const char *zObj = 0; |
| 149523 | if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ | 154887 | WhereLoop *pLoop = pLvl->pWLoop; |
| 149524 | zObj = pLoop->u.btree.pIndex->zName; | 154888 | int wsFlags = pLoop->wsFlags; |
| 149525 | }else{ | 154889 | int viaCoroutine = 0; |
| 149526 | zObj = pSrclist->a[pLvl->iFrom].zName; | 154890 | |
| 154891 | if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ | ||
| 154892 | zObj = pLoop->u.btree.pIndex->zName; | ||
| 154893 | }else{ | ||
| 154894 | zObj = pSrclist->a[pLvl->iFrom].zName; | ||
| 154895 | viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine; | ||
| 154896 | } | ||
| 154897 | sqlite3VdbeScanStatus( | ||
| 154898 | v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj | ||
| 154899 | ); | ||
| 154900 | |||
| 154901 | if( viaCoroutine==0 ){ | ||
| 154902 | if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ | ||
| 154903 | sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); | ||
| 154904 | } | ||
| 154905 | if( wsFlags & WHERE_INDEXED ){ | ||
| 154906 | sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); | ||
| 154907 | } | ||
| 154908 | }else{ | ||
| 154909 | int addr = pSrclist->a[pLvl->iFrom].addrFillSub; | ||
| 154910 | VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); | ||
| 154911 | assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); | ||
| 154912 | assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); | ||
| 154913 | sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); | ||
| 154914 | } | ||
| 149527 | } | 154915 | } |
| 149528 | sqlite3VdbeScanStatus( | ||
| 149529 | v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj | ||
| 149530 | ); | ||
| 149531 | } | 154916 | } |
| 149532 | #endif | 154917 | #endif |
| 149533 | 154918 | ||
| @@ -149587,7 +154972,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ | |||
| 149587 | pTerm->wtFlags |= TERM_CODED; | 154972 | pTerm->wtFlags |= TERM_CODED; |
| 149588 | } | 154973 | } |
| 149589 | #ifdef WHERETRACE_ENABLED | 154974 | #ifdef WHERETRACE_ENABLED |
| 149590 | if( sqlite3WhereTrace & 0x20000 ){ | 154975 | if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ |
| 149591 | sqlite3DebugPrintf("DISABLE-"); | 154976 | sqlite3DebugPrintf("DISABLE-"); |
| 149592 | sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a))); | 154977 | sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a))); |
| 149593 | } | 154978 | } |
| @@ -149702,68 +155087,75 @@ static Expr *removeUnindexableInClauseTerms( | |||
| 149702 | Expr *pX /* The IN expression to be reduced */ | 155087 | Expr *pX /* The IN expression to be reduced */ |
| 149703 | ){ | 155088 | ){ |
| 149704 | sqlite3 *db = pParse->db; | 155089 | sqlite3 *db = pParse->db; |
| 155090 | Select *pSelect; /* Pointer to the SELECT on the RHS */ | ||
| 149705 | Expr *pNew; | 155091 | Expr *pNew; |
| 149706 | pNew = sqlite3ExprDup(db, pX, 0); | 155092 | pNew = sqlite3ExprDup(db, pX, 0); |
| 149707 | if( db->mallocFailed==0 ){ | 155093 | if( db->mallocFailed==0 ){ |
| 149708 | ExprList *pOrigRhs; /* Original unmodified RHS */ | 155094 | for(pSelect=pNew->x.pSelect; pSelect; pSelect=pSelect->pPrior){ |
| 149709 | ExprList *pOrigLhs; /* Original unmodified LHS */ | 155095 | ExprList *pOrigRhs; /* Original unmodified RHS */ |
| 149710 | ExprList *pRhs = 0; /* New RHS after modifications */ | 155096 | ExprList *pOrigLhs = 0; /* Original unmodified LHS */ |
| 149711 | ExprList *pLhs = 0; /* New LHS after mods */ | 155097 | ExprList *pRhs = 0; /* New RHS after modifications */ |
| 149712 | int i; /* Loop counter */ | 155098 | ExprList *pLhs = 0; /* New LHS after mods */ |
| 149713 | Select *pSelect; /* Pointer to the SELECT on the RHS */ | 155099 | int i; /* Loop counter */ |
| 149714 | 155100 | ||
| 149715 | assert( ExprUseXSelect(pNew) ); | 155101 | assert( ExprUseXSelect(pNew) ); |
| 149716 | pOrigRhs = pNew->x.pSelect->pEList; | 155102 | pOrigRhs = pSelect->pEList; |
| 149717 | assert( pNew->pLeft!=0 ); | 155103 | assert( pNew->pLeft!=0 ); |
| 149718 | assert( ExprUseXList(pNew->pLeft) ); | 155104 | assert( ExprUseXList(pNew->pLeft) ); |
| 149719 | pOrigLhs = pNew->pLeft->x.pList; | 155105 | if( pSelect==pNew->x.pSelect ){ |
| 149720 | for(i=iEq; i<pLoop->nLTerm; i++){ | 155106 | pOrigLhs = pNew->pLeft->x.pList; |
| 149721 | if( pLoop->aLTerm[i]->pExpr==pX ){ | 155107 | } |
| 149722 | int iField; | 155108 | for(i=iEq; i<pLoop->nLTerm; i++){ |
| 149723 | assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); | 155109 | if( pLoop->aLTerm[i]->pExpr==pX ){ |
| 149724 | iField = pLoop->aLTerm[i]->u.x.iField - 1; | 155110 | int iField; |
| 149725 | if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ | 155111 | assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); |
| 149726 | pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); | 155112 | iField = pLoop->aLTerm[i]->u.x.iField - 1; |
| 149727 | pOrigRhs->a[iField].pExpr = 0; | 155113 | if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ |
| 149728 | assert( pOrigLhs->a[iField].pExpr!=0 ); | 155114 | pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); |
| 149729 | pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr); | 155115 | pOrigRhs->a[iField].pExpr = 0; |
| 149730 | pOrigLhs->a[iField].pExpr = 0; | 155116 | if( pOrigLhs ){ |
| 149731 | } | 155117 | assert( pOrigLhs->a[iField].pExpr!=0 ); |
| 149732 | } | 155118 | pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); |
| 149733 | sqlite3ExprListDelete(db, pOrigRhs); | 155119 | pOrigLhs->a[iField].pExpr = 0; |
| 149734 | sqlite3ExprListDelete(db, pOrigLhs); | 155120 | } |
| 149735 | pNew->pLeft->x.pList = pLhs; | 155121 | } |
| 149736 | pNew->x.pSelect->pEList = pRhs; | 155122 | } |
| 149737 | if( pLhs && pLhs->nExpr==1 ){ | 155123 | sqlite3ExprListDelete(db, pOrigRhs); |
| 149738 | /* Take care here not to generate a TK_VECTOR containing only a | 155124 | if( pOrigLhs ){ |
| 149739 | ** single value. Since the parser never creates such a vector, some | 155125 | sqlite3ExprListDelete(db, pOrigLhs); |
| 149740 | ** of the subroutines do not handle this case. */ | 155126 | pNew->pLeft->x.pList = pLhs; |
| 149741 | Expr *p = pLhs->a[0].pExpr; | 155127 | } |
| 149742 | pLhs->a[0].pExpr = 0; | 155128 | pSelect->pEList = pRhs; |
| 149743 | sqlite3ExprDelete(db, pNew->pLeft); | 155129 | if( pLhs && pLhs->nExpr==1 ){ |
| 149744 | pNew->pLeft = p; | 155130 | /* Take care here not to generate a TK_VECTOR containing only a |
| 149745 | } | 155131 | ** single value. Since the parser never creates such a vector, some |
| 149746 | pSelect = pNew->x.pSelect; | 155132 | ** of the subroutines do not handle this case. */ |
| 149747 | if( pSelect->pOrderBy ){ | 155133 | Expr *p = pLhs->a[0].pExpr; |
| 149748 | /* If the SELECT statement has an ORDER BY clause, zero the | 155134 | pLhs->a[0].pExpr = 0; |
| 149749 | ** iOrderByCol variables. These are set to non-zero when an | 155135 | sqlite3ExprDelete(db, pNew->pLeft); |
| 149750 | ** ORDER BY term exactly matches one of the terms of the | 155136 | pNew->pLeft = p; |
| 149751 | ** result-set. Since the result-set of the SELECT statement may | 155137 | } |
| 149752 | ** have been modified or reordered, these variables are no longer | 155138 | if( pSelect->pOrderBy ){ |
| 149753 | ** set correctly. Since setting them is just an optimization, | 155139 | /* If the SELECT statement has an ORDER BY clause, zero the |
| 149754 | ** it's easiest just to zero them here. */ | 155140 | ** iOrderByCol variables. These are set to non-zero when an |
| 149755 | ExprList *pOrderBy = pSelect->pOrderBy; | 155141 | ** ORDER BY term exactly matches one of the terms of the |
| 149756 | for(i=0; i<pOrderBy->nExpr; i++){ | 155142 | ** result-set. Since the result-set of the SELECT statement may |
| 149757 | pOrderBy->a[i].u.x.iOrderByCol = 0; | 155143 | ** have been modified or reordered, these variables are no longer |
| 155144 | ** set correctly. Since setting them is just an optimization, | ||
| 155145 | ** it's easiest just to zero them here. */ | ||
| 155146 | ExprList *pOrderBy = pSelect->pOrderBy; | ||
| 155147 | for(i=0; i<pOrderBy->nExpr; i++){ | ||
| 155148 | pOrderBy->a[i].u.x.iOrderByCol = 0; | ||
| 155149 | } | ||
| 149758 | } | 155150 | } |
| 149759 | } | ||
| 149760 | 155151 | ||
| 149761 | #if 0 | 155152 | #if 0 |
| 149762 | printf("For indexing, change the IN expr:\n"); | 155153 | printf("For indexing, change the IN expr:\n"); |
| 149763 | sqlite3TreeViewExpr(0, pX, 0); | 155154 | sqlite3TreeViewExpr(0, pX, 0); |
| 149764 | printf("Into:\n"); | 155155 | printf("Into:\n"); |
| 149765 | sqlite3TreeViewExpr(0, pNew, 0); | 155156 | sqlite3TreeViewExpr(0, pNew, 0); |
| 149766 | #endif | 155157 | #endif |
| 155158 | } | ||
| 149767 | } | 155159 | } |
| 149768 | return pNew; | 155160 | return pNew; |
| 149769 | } | 155161 | } |
| @@ -150016,7 +155408,7 @@ static int codeAllEqualityTerms( | |||
| 150016 | /* Figure out how many memory cells we will need then allocate them. | 155408 | /* Figure out how many memory cells we will need then allocate them. |
| 150017 | */ | 155409 | */ |
| 150018 | regBase = pParse->nMem + 1; | 155410 | regBase = pParse->nMem + 1; |
| 150019 | nReg = pLoop->u.btree.nEq + nExtraReg; | 155411 | nReg = nEq + nExtraReg; |
| 150020 | pParse->nMem += nReg; | 155412 | pParse->nMem += nReg; |
| 150021 | 155413 | ||
| 150022 | zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); | 155414 | zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); |
| @@ -150063,9 +155455,6 @@ static int codeAllEqualityTerms( | |||
| 150063 | sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); | 155455 | sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); |
| 150064 | } | 155456 | } |
| 150065 | } | 155457 | } |
| 150066 | } | ||
| 150067 | for(j=nSkip; j<nEq; j++){ | ||
| 150068 | pTerm = pLoop->aLTerm[j]; | ||
| 150069 | if( pTerm->eOperator & WO_IN ){ | 155458 | if( pTerm->eOperator & WO_IN ){ |
| 150070 | if( pTerm->pExpr->flags & EP_xIsSelect ){ | 155459 | if( pTerm->pExpr->flags & EP_xIsSelect ){ |
| 150071 | /* No affinity ever needs to be (or should be) applied to a value | 155460 | /* No affinity ever needs to be (or should be) applied to a value |
| @@ -150121,7 +155510,7 @@ static void whereLikeOptimizationStringFixup( | |||
| 150121 | if( pTerm->wtFlags & TERM_LIKEOPT ){ | 155510 | if( pTerm->wtFlags & TERM_LIKEOPT ){ |
| 150122 | VdbeOp *pOp; | 155511 | VdbeOp *pOp; |
| 150123 | assert( pLevel->iLikeRepCntr>0 ); | 155512 | assert( pLevel->iLikeRepCntr>0 ); |
| 150124 | pOp = sqlite3VdbeGetOp(v, -1); | 155513 | pOp = sqlite3VdbeGetLastOp(v); |
| 150125 | assert( pOp!=0 ); | 155514 | assert( pOp!=0 ); |
| 150126 | assert( pOp->opcode==OP_String8 | 155515 | assert( pOp->opcode==OP_String8 |
| 150127 | || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); | 155516 | || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); |
| @@ -150208,18 +155597,19 @@ static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ | |||
| 150208 | ** 2) transform the expression node to a TK_REGISTER node that reads | 155597 | ** 2) transform the expression node to a TK_REGISTER node that reads |
| 150209 | ** from the newly populated register. | 155598 | ** from the newly populated register. |
| 150210 | ** | 155599 | ** |
| 150211 | ** Also, if the node is a TK_COLUMN that does access the table idenified | 155600 | ** Also, if the node is a TK_COLUMN that does access the table identified |
| 150212 | ** by pCCurHint.iTabCur, and an index is being used (which we will | 155601 | ** by pCCurHint.iTabCur, and an index is being used (which we will |
| 150213 | ** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into | 155602 | ** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into |
| 150214 | ** an access of the index rather than the original table. | 155603 | ** an access of the index rather than the original table. |
| 150215 | */ | 155604 | */ |
| 150216 | static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ | 155605 | static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ |
| 150217 | int rc = WRC_Continue; | 155606 | int rc = WRC_Continue; |
| 155607 | int reg; | ||
| 150218 | struct CCurHint *pHint = pWalker->u.pCCurHint; | 155608 | struct CCurHint *pHint = pWalker->u.pCCurHint; |
| 150219 | if( pExpr->op==TK_COLUMN ){ | 155609 | if( pExpr->op==TK_COLUMN ){ |
| 150220 | if( pExpr->iTable!=pHint->iTabCur ){ | 155610 | if( pExpr->iTable!=pHint->iTabCur ){ |
| 150221 | int reg = ++pWalker->pParse->nMem; /* Register for column value */ | 155611 | reg = ++pWalker->pParse->nMem; /* Register for column value */ |
| 150222 | sqlite3ExprCode(pWalker->pParse, pExpr, reg); | 155612 | reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); |
| 150223 | pExpr->op = TK_REGISTER; | 155613 | pExpr->op = TK_REGISTER; |
| 150224 | pExpr->iTable = reg; | 155614 | pExpr->iTable = reg; |
| 150225 | }else if( pHint->pIdx!=0 ){ | 155615 | }else if( pHint->pIdx!=0 ){ |
| @@ -150227,15 +155617,15 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ | |||
| 150227 | pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); | 155617 | pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); |
| 150228 | assert( pExpr->iColumn>=0 ); | 155618 | assert( pExpr->iColumn>=0 ); |
| 150229 | } | 155619 | } |
| 150230 | }else if( pExpr->op==TK_AGG_FUNCTION ){ | 155620 | }else if( pExpr->pAggInfo ){ |
| 150231 | /* An aggregate function in the WHERE clause of a query means this must | ||
| 150232 | ** be a correlated sub-query, and expression pExpr is an aggregate from | ||
| 150233 | ** the parent context. Do not walk the function arguments in this case. | ||
| 150234 | ** | ||
| 150235 | ** todo: It should be possible to replace this node with a TK_REGISTER | ||
| 150236 | ** expression, as the result of the expression must be stored in a | ||
| 150237 | ** register at this point. The same holds for TK_AGG_COLUMN nodes. */ | ||
| 150238 | rc = WRC_Prune; | 155621 | rc = WRC_Prune; |
| 155622 | reg = ++pWalker->pParse->nMem; /* Register for column value */ | ||
| 155623 | reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); | ||
| 155624 | pExpr->op = TK_REGISTER; | ||
| 155625 | pExpr->iTable = reg; | ||
| 155626 | }else if( pExpr->op==TK_TRUEFALSE ){ | ||
| 155627 | /* Do not walk disabled expressions. tag-20230504-1 */ | ||
| 155628 | return WRC_Prune; | ||
| 150239 | } | 155629 | } |
| 150240 | return rc; | 155630 | return rc; |
| 150241 | } | 155631 | } |
| @@ -150337,7 +155727,7 @@ static void codeCursorHint( | |||
| 150337 | } | 155727 | } |
| 150338 | if( pExpr!=0 ){ | 155728 | if( pExpr!=0 ){ |
| 150339 | sWalker.xExprCallback = codeCursorHintFixExpr; | 155729 | sWalker.xExprCallback = codeCursorHintFixExpr; |
| 150340 | sqlite3WalkExpr(&sWalker, pExpr); | 155730 | if( pParse->nErr==0 ) sqlite3WalkExpr(&sWalker, pExpr); |
| 150341 | sqlite3VdbeAddOp4(v, OP_CursorHint, | 155731 | sqlite3VdbeAddOp4(v, OP_CursorHint, |
| 150342 | (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, | 155732 | (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, |
| 150343 | (const char*)pExpr, P4_EXPR); | 155733 | (const char*)pExpr, P4_EXPR); |
| @@ -150445,143 +155835,6 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ | |||
| 150445 | } | 155835 | } |
| 150446 | } | 155836 | } |
| 150447 | 155837 | ||
| 150448 | /* An instance of the IdxExprTrans object carries information about a | ||
| 150449 | ** mapping from an expression on table columns into a column in an index | ||
| 150450 | ** down through the Walker. | ||
| 150451 | */ | ||
| 150452 | typedef struct IdxExprTrans { | ||
| 150453 | Expr *pIdxExpr; /* The index expression */ | ||
| 150454 | int iTabCur; /* The cursor of the corresponding table */ | ||
| 150455 | int iIdxCur; /* The cursor for the index */ | ||
| 150456 | int iIdxCol; /* The column for the index */ | ||
| 150457 | int iTabCol; /* The column for the table */ | ||
| 150458 | WhereInfo *pWInfo; /* Complete WHERE clause information */ | ||
| 150459 | sqlite3 *db; /* Database connection (for malloc()) */ | ||
| 150460 | } IdxExprTrans; | ||
| 150461 | |||
| 150462 | /* | ||
| 150463 | ** Preserve pExpr on the WhereETrans list of the WhereInfo. | ||
| 150464 | */ | ||
| 150465 | static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ | ||
| 150466 | WhereExprMod *pNew; | ||
| 150467 | pNew = sqlite3DbMallocRaw(pTrans->db, sizeof(*pNew)); | ||
| 150468 | if( pNew==0 ) return; | ||
| 150469 | pNew->pNext = pTrans->pWInfo->pExprMods; | ||
| 150470 | pTrans->pWInfo->pExprMods = pNew; | ||
| 150471 | pNew->pExpr = pExpr; | ||
| 150472 | memcpy(&pNew->orig, pExpr, sizeof(*pExpr)); | ||
| 150473 | } | ||
| 150474 | |||
| 150475 | /* The walker node callback used to transform matching expressions into | ||
| 150476 | ** a reference to an index column for an index on an expression. | ||
| 150477 | ** | ||
| 150478 | ** If pExpr matches, then transform it into a reference to the index column | ||
| 150479 | ** that contains the value of pExpr. | ||
| 150480 | */ | ||
| 150481 | static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ | ||
| 150482 | IdxExprTrans *pX = p->u.pIdxTrans; | ||
| 150483 | if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ | ||
| 150484 | pExpr = sqlite3ExprSkipCollate(pExpr); | ||
| 150485 | preserveExpr(pX, pExpr); | ||
| 150486 | pExpr->affExpr = sqlite3ExprAffinity(pExpr); | ||
| 150487 | pExpr->op = TK_COLUMN; | ||
| 150488 | pExpr->iTable = pX->iIdxCur; | ||
| 150489 | pExpr->iColumn = pX->iIdxCol; | ||
| 150490 | testcase( ExprHasProperty(pExpr, EP_Unlikely) ); | ||
| 150491 | ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn); | ||
| 150492 | pExpr->y.pTab = 0; | ||
| 150493 | return WRC_Prune; | ||
| 150494 | }else{ | ||
| 150495 | return WRC_Continue; | ||
| 150496 | } | ||
| 150497 | } | ||
| 150498 | |||
| 150499 | #ifndef SQLITE_OMIT_GENERATED_COLUMNS | ||
| 150500 | /* A walker node callback that translates a column reference to a table | ||
| 150501 | ** into a corresponding column reference of an index. | ||
| 150502 | */ | ||
| 150503 | static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){ | ||
| 150504 | if( pExpr->op==TK_COLUMN ){ | ||
| 150505 | IdxExprTrans *pX = p->u.pIdxTrans; | ||
| 150506 | if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){ | ||
| 150507 | assert( ExprUseYTab(pExpr) && pExpr->y.pTab!=0 ); | ||
| 150508 | preserveExpr(pX, pExpr); | ||
| 150509 | pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn); | ||
| 150510 | pExpr->iTable = pX->iIdxCur; | ||
| 150511 | pExpr->iColumn = pX->iIdxCol; | ||
| 150512 | pExpr->y.pTab = 0; | ||
| 150513 | } | ||
| 150514 | } | ||
| 150515 | return WRC_Continue; | ||
| 150516 | } | ||
| 150517 | #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ | ||
| 150518 | |||
| 150519 | /* | ||
| 150520 | ** For an indexes on expression X, locate every instance of expression X | ||
| 150521 | ** in pExpr and change that subexpression into a reference to the appropriate | ||
| 150522 | ** column of the index. | ||
| 150523 | ** | ||
| 150524 | ** 2019-10-24: Updated to also translate references to a VIRTUAL column in | ||
| 150525 | ** the table into references to the corresponding (stored) column of the | ||
| 150526 | ** index. | ||
| 150527 | */ | ||
| 150528 | static void whereIndexExprTrans( | ||
| 150529 | Index *pIdx, /* The Index */ | ||
| 150530 | int iTabCur, /* Cursor of the table that is being indexed */ | ||
| 150531 | int iIdxCur, /* Cursor of the index itself */ | ||
| 150532 | WhereInfo *pWInfo /* Transform expressions in this WHERE clause */ | ||
| 150533 | ){ | ||
| 150534 | int iIdxCol; /* Column number of the index */ | ||
| 150535 | ExprList *aColExpr; /* Expressions that are indexed */ | ||
| 150536 | Table *pTab; | ||
| 150537 | Walker w; | ||
| 150538 | IdxExprTrans x; | ||
| 150539 | aColExpr = pIdx->aColExpr; | ||
| 150540 | if( aColExpr==0 && !pIdx->bHasVCol ){ | ||
| 150541 | /* The index does not reference any expressions or virtual columns | ||
| 150542 | ** so no translations are needed. */ | ||
| 150543 | return; | ||
| 150544 | } | ||
| 150545 | pTab = pIdx->pTable; | ||
| 150546 | memset(&w, 0, sizeof(w)); | ||
| 150547 | w.u.pIdxTrans = &x; | ||
| 150548 | x.iTabCur = iTabCur; | ||
| 150549 | x.iIdxCur = iIdxCur; | ||
| 150550 | x.pWInfo = pWInfo; | ||
| 150551 | x.db = pWInfo->pParse->db; | ||
| 150552 | for(iIdxCol=0; iIdxCol<pIdx->nColumn; iIdxCol++){ | ||
| 150553 | i16 iRef = pIdx->aiColumn[iIdxCol]; | ||
| 150554 | if( iRef==XN_EXPR ){ | ||
| 150555 | assert( aColExpr!=0 && aColExpr->a[iIdxCol].pExpr!=0 ); | ||
| 150556 | x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; | ||
| 150557 | if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue; | ||
| 150558 | w.xExprCallback = whereIndexExprTransNode; | ||
| 150559 | #ifndef SQLITE_OMIT_GENERATED_COLUMNS | ||
| 150560 | }else if( iRef>=0 | ||
| 150561 | && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0 | ||
| 150562 | && ((pTab->aCol[iRef].colFlags & COLFLAG_HASCOLL)==0 | ||
| 150563 | || sqlite3StrICmp(sqlite3ColumnColl(&pTab->aCol[iRef]), | ||
| 150564 | sqlite3StrBINARY)==0) | ||
| 150565 | ){ | ||
| 150566 | /* Check to see if there are direct references to generated columns | ||
| 150567 | ** that are contained in the index. Pulling the generated column | ||
| 150568 | ** out of the index is an optimization only - the main table is always | ||
| 150569 | ** available if the index cannot be used. To avoid unnecessary | ||
| 150570 | ** complication, omit this optimization if the collating sequence for | ||
| 150571 | ** the column is non-standard */ | ||
| 150572 | x.iTabCol = iRef; | ||
| 150573 | w.xExprCallback = whereIndexExprTransColumn; | ||
| 150574 | #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ | ||
| 150575 | }else{ | ||
| 150576 | continue; | ||
| 150577 | } | ||
| 150578 | x.iIdxCol = iIdxCol; | ||
| 150579 | sqlite3WalkExpr(&w, pWInfo->pWhere); | ||
| 150580 | sqlite3WalkExprList(&w, pWInfo->pOrderBy); | ||
| 150581 | sqlite3WalkExprList(&w, pWInfo->pResultSet); | ||
| 150582 | } | ||
| 150583 | } | ||
| 150584 | |||
| 150585 | /* | 155838 | /* |
| 150586 | ** The pTruth expression is always true because it is the WHERE clause | 155839 | ** The pTruth expression is always true because it is the WHERE clause |
| 150587 | ** a partial index that is driving a query loop. Look through all of the | 155840 | ** a partial index that is driving a query loop. Look through all of the |
| @@ -150650,6 +155903,8 @@ static SQLITE_NOINLINE void filterPullDown( | |||
| 150650 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); | 155903 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); |
| 150651 | regRowid = sqlite3GetTempReg(pParse); | 155904 | regRowid = sqlite3GetTempReg(pParse); |
| 150652 | regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); | 155905 | regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); |
| 155906 | sqlite3VdbeAddOp2(pParse->pVdbe, OP_MustBeInt, regRowid, addrNxt); | ||
| 155907 | VdbeCoverage(pParse->pVdbe); | ||
| 150653 | sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, | 155908 | sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, |
| 150654 | addrNxt, regRowid, 1); | 155909 | addrNxt, regRowid, 1); |
| 150655 | VdbeCoverage(pParse->pVdbe); | 155910 | VdbeCoverage(pParse->pVdbe); |
| @@ -150709,13 +155964,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 150709 | pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); | 155964 | pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); |
| 150710 | bRev = (pWInfo->revMask>>iLevel)&1; | 155965 | bRev = (pWInfo->revMask>>iLevel)&1; |
| 150711 | VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); | 155966 | VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); |
| 150712 | #if WHERETRACE_ENABLED /* 0x20800 */ | 155967 | #if WHERETRACE_ENABLED /* 0x4001 */ |
| 150713 | if( sqlite3WhereTrace & 0x800 ){ | 155968 | if( sqlite3WhereTrace & 0x1 ){ |
| 150714 | sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", | 155969 | sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", |
| 150715 | iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); | 155970 | iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); |
| 150716 | sqlite3WhereLoopPrint(pLoop, pWC); | 155971 | if( sqlite3WhereTrace & 0x1000 ){ |
| 155972 | sqlite3WhereLoopPrint(pLoop, pWC); | ||
| 155973 | } | ||
| 150717 | } | 155974 | } |
| 150718 | if( sqlite3WhereTrace & 0x20000 ){ | 155975 | if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ |
| 150719 | if( iLevel==0 ){ | 155976 | if( iLevel==0 ){ |
| 150720 | sqlite3DebugPrintf("WHERE clause being coded:\n"); | 155977 | sqlite3DebugPrintf("WHERE clause being coded:\n"); |
| 150721 | sqlite3TreeViewExpr(0, pWInfo->pWhere, 0); | 155978 | sqlite3TreeViewExpr(0, pWInfo->pWhere, 0); |
| @@ -150801,9 +156058,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 150801 | && pLoop->u.vtab.bOmitOffset | 156058 | && pLoop->u.vtab.bOmitOffset |
| 150802 | ){ | 156059 | ){ |
| 150803 | assert( pTerm->eOperator==WO_AUX ); | 156060 | assert( pTerm->eOperator==WO_AUX ); |
| 150804 | assert( pWInfo->pLimit!=0 ); | 156061 | assert( pWInfo->pSelect!=0 ); |
| 150805 | assert( pWInfo->pLimit->iOffset>0 ); | 156062 | assert( pWInfo->pSelect->iOffset>0 ); |
| 150806 | sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset); | 156063 | sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pSelect->iOffset); |
| 150807 | VdbeComment((v,"Zero OFFSET counter")); | 156064 | VdbeComment((v,"Zero OFFSET counter")); |
| 150808 | } | 156065 | } |
| 150809 | } | 156066 | } |
| @@ -150911,6 +156168,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 150911 | if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); | 156168 | if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); |
| 150912 | addrNxt = pLevel->addrNxt; | 156169 | addrNxt = pLevel->addrNxt; |
| 150913 | if( pLevel->regFilter ){ | 156170 | if( pLevel->regFilter ){ |
| 156171 | sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); | ||
| 156172 | VdbeCoverage(v); | ||
| 150914 | sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, | 156173 | sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, |
| 150915 | iRowidReg, 1); | 156174 | iRowidReg, 1); |
| 150916 | VdbeCoverage(v); | 156175 | VdbeCoverage(v); |
| @@ -150956,7 +156215,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 150956 | }; | 156215 | }; |
| 150957 | assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ | 156216 | assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ |
| 150958 | assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ | 156217 | assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ |
| 150959 | assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ | 156218 | assert( TK_GE==TK_GT+3 ); /* ... is correct. */ |
| 150960 | 156219 | ||
| 150961 | assert( (pStart->wtFlags & TERM_VNULL)==0 ); | 156220 | assert( (pStart->wtFlags & TERM_VNULL)==0 ); |
| 150962 | testcase( pStart->wtFlags & TERM_VIRTUAL ); | 156221 | testcase( pStart->wtFlags & TERM_VIRTUAL ); |
| @@ -151262,6 +156521,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151262 | ** guess. */ | 156521 | ** guess. */ |
| 151263 | addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, | 156522 | addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, |
| 151264 | (pIdx->aiRowLogEst[0]+9)/10); | 156523 | (pIdx->aiRowLogEst[0]+9)/10); |
| 156524 | if( pRangeStart || pRangeEnd ){ | ||
| 156525 | sqlite3VdbeChangeP5(v, 1); | ||
| 156526 | sqlite3VdbeChangeP2(v, addrSeekScan, sqlite3VdbeCurrentAddr(v)+1); | ||
| 156527 | addrSeekScan = 0; | ||
| 156528 | } | ||
| 151265 | VdbeCoverage(v); | 156529 | VdbeCoverage(v); |
| 151266 | } | 156530 | } |
| 151267 | sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); | 156531 | sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); |
| @@ -151298,16 +156562,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151298 | assert( pLevel->p2==0 ); | 156562 | assert( pLevel->p2==0 ); |
| 151299 | if( pRangeEnd ){ | 156563 | if( pRangeEnd ){ |
| 151300 | Expr *pRight = pRangeEnd->pExpr->pRight; | 156564 | Expr *pRight = pRangeEnd->pExpr->pRight; |
| 151301 | if( addrSeekScan ){ | 156565 | assert( addrSeekScan==0 ); |
| 151302 | /* For a seek-scan that has a range on the lowest term of the index, | ||
| 151303 | ** we have to make the top of the loop be code that sets the end | ||
| 151304 | ** condition of the range. Otherwise, the OP_SeekScan might jump | ||
| 151305 | ** over that initialization, leaving the range-end value set to the | ||
| 151306 | ** range-start value, resulting in a wrong answer. | ||
| 151307 | ** See ticket 5981a8c041a3c2f3 (2021-11-02). | ||
| 151308 | */ | ||
| 151309 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); | ||
| 151310 | } | ||
| 151311 | codeExprOrVector(pParse, pRight, regBase+nEq, nTop); | 156566 | codeExprOrVector(pParse, pRight, regBase+nEq, nTop); |
| 151312 | whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); | 156567 | whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); |
| 151313 | if( (pRangeEnd->wtFlags & TERM_VNULL)==0 | 156568 | if( (pRangeEnd->wtFlags & TERM_VNULL)==0 |
| @@ -151337,11 +156592,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151337 | } | 156592 | } |
| 151338 | nConstraint++; | 156593 | nConstraint++; |
| 151339 | } | 156594 | } |
| 151340 | sqlite3DbFree(db, zStartAff); | 156595 | if( zStartAff ) sqlite3DbNNFreeNN(db, zStartAff); |
| 151341 | sqlite3DbFree(db, zEndAff); | 156596 | if( zEndAff ) sqlite3DbNNFreeNN(db, zEndAff); |
| 151342 | 156597 | ||
| 151343 | /* Top of the loop body */ | 156598 | /* Top of the loop body */ |
| 151344 | if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v); | 156599 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); |
| 151345 | 156600 | ||
| 151346 | /* Check if the index cursor is past the end of the range. */ | 156601 | /* Check if the index cursor is past the end of the range. */ |
| 151347 | if( nConstraint ){ | 156602 | if( nConstraint ){ |
| @@ -151400,27 +156655,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151400 | } | 156655 | } |
| 151401 | 156656 | ||
| 151402 | if( pLevel->iLeftJoin==0 ){ | 156657 | if( pLevel->iLeftJoin==0 ){ |
| 151403 | /* If pIdx is an index on one or more expressions, then look through | ||
| 151404 | ** all the expressions in pWInfo and try to transform matching expressions | ||
| 151405 | ** into reference to index columns. Also attempt to translate references | ||
| 151406 | ** to virtual columns in the table into references to (stored) columns | ||
| 151407 | ** of the index. | ||
| 151408 | ** | ||
| 151409 | ** Do not do this for the RHS of a LEFT JOIN. This is because the | ||
| 151410 | ** expression may be evaluated after OP_NullRow has been executed on | ||
| 151411 | ** the cursor. In this case it is important to do the full evaluation, | ||
| 151412 | ** as the result of the expression may not be NULL, even if all table | ||
| 151413 | ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a | ||
| 151414 | ** | ||
| 151415 | ** Also, do not do this when processing one index an a multi-index | ||
| 151416 | ** OR clause, since the transformation will become invalid once we | ||
| 151417 | ** move forward to the next index. | ||
| 151418 | ** https://sqlite.org/src/info/4e8e4857d32d401f | ||
| 151419 | */ | ||
| 151420 | if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ){ | ||
| 151421 | whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); | ||
| 151422 | } | ||
| 151423 | |||
| 151424 | /* If a partial index is driving the loop, try to eliminate WHERE clause | 156658 | /* If a partial index is driving the loop, try to eliminate WHERE clause |
| 151425 | ** terms from the query that must be true due to the WHERE clause of | 156659 | ** terms from the query that must be true due to the WHERE clause of |
| 151426 | ** the partial index. | 156660 | ** the partial index. |
| @@ -151533,7 +156767,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151533 | int nNotReady; /* The number of notReady tables */ | 156767 | int nNotReady; /* The number of notReady tables */ |
| 151534 | SrcItem *origSrc; /* Original list of tables */ | 156768 | SrcItem *origSrc; /* Original list of tables */ |
| 151535 | nNotReady = pWInfo->nLevel - iLevel - 1; | 156769 | nNotReady = pWInfo->nLevel - iLevel - 1; |
| 151536 | pOrTab = sqlite3StackAllocRaw(db, | 156770 | pOrTab = sqlite3DbMallocRawNN(db, |
| 151537 | sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); | 156771 | sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); |
| 151538 | if( pOrTab==0 ) return notReady; | 156772 | if( pOrTab==0 ) return notReady; |
| 151539 | pOrTab->nAlloc = (u8)(nNotReady + 1); | 156773 | pOrTab->nAlloc = (u8)(nNotReady + 1); |
| @@ -151653,7 +156887,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151653 | } | 156887 | } |
| 151654 | /* Loop through table entries that match term pOrTerm. */ | 156888 | /* Loop through table entries that match term pOrTerm. */ |
| 151655 | ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); | 156889 | ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); |
| 151656 | WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); | 156890 | WHERETRACE(0xffffffff, ("Subplan for OR-clause:\n")); |
| 151657 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, | 156891 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, |
| 151658 | WHERE_OR_SUBCLAUSE, iCovCur); | 156892 | WHERE_OR_SUBCLAUSE, iCovCur); |
| 151659 | assert( pSubWInfo || pParse->nErr ); | 156893 | assert( pSubWInfo || pParse->nErr ); |
| @@ -151786,7 +157020,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151786 | assert( pLevel->op==OP_Return ); | 157020 | assert( pLevel->op==OP_Return ); |
| 151787 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); | 157021 | pLevel->p2 = sqlite3VdbeCurrentAddr(v); |
| 151788 | 157022 | ||
| 151789 | if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); } | 157023 | if( pWInfo->nLevel>1 ){ sqlite3DbFreeNN(db, pOrTab); } |
| 151790 | if( !untestedTerms ) disableTerm(pLevel, pTerm); | 157024 | if( !untestedTerms ) disableTerm(pLevel, pTerm); |
| 151791 | }else | 157025 | }else |
| 151792 | #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ | 157026 | #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ |
| @@ -151890,12 +157124,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151890 | } | 157124 | } |
| 151891 | #endif | 157125 | #endif |
| 151892 | } | 157126 | } |
| 151893 | #ifdef WHERETRACE_ENABLED /* 0xffff */ | 157127 | #ifdef WHERETRACE_ENABLED /* 0xffffffff */ |
| 151894 | if( sqlite3WhereTrace ){ | 157128 | if( sqlite3WhereTrace ){ |
| 151895 | VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", | 157129 | VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", |
| 151896 | pWC->nTerm-j, pTerm, iLoop)); | 157130 | pWC->nTerm-j, pTerm, iLoop)); |
| 151897 | } | 157131 | } |
| 151898 | if( sqlite3WhereTrace & 0x800 ){ | 157132 | if( sqlite3WhereTrace & 0x4000 ){ |
| 151899 | sqlite3DebugPrintf("Coding auxiliary constraint:\n"); | 157133 | sqlite3DebugPrintf("Coding auxiliary constraint:\n"); |
| 151900 | sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); | 157134 | sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); |
| 151901 | } | 157135 | } |
| @@ -151924,8 +157158,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 151924 | if( pTerm->leftCursor!=iCur ) continue; | 157158 | if( pTerm->leftCursor!=iCur ) continue; |
| 151925 | if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue; | 157159 | if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue; |
| 151926 | pE = pTerm->pExpr; | 157160 | pE = pTerm->pExpr; |
| 151927 | #ifdef WHERETRACE_ENABLED /* 0x800 */ | 157161 | #ifdef WHERETRACE_ENABLED /* 0x4001 */ |
| 151928 | if( sqlite3WhereTrace & 0x800 ){ | 157162 | if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ |
| 151929 | sqlite3DebugPrintf("Coding transitive constraint:\n"); | 157163 | sqlite3DebugPrintf("Coding transitive constraint:\n"); |
| 151930 | sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); | 157164 | sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); |
| 151931 | } | 157165 | } |
| @@ -152040,13 +157274,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( | |||
| 152040 | } | 157274 | } |
| 152041 | } | 157275 | } |
| 152042 | 157276 | ||
| 152043 | #if WHERETRACE_ENABLED /* 0x20800 */ | 157277 | #if WHERETRACE_ENABLED /* 0x4001 */ |
| 152044 | if( sqlite3WhereTrace & 0x20000 ){ | 157278 | if( sqlite3WhereTrace & 0x4000 ){ |
| 152045 | sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", | 157279 | sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", |
| 152046 | iLevel); | 157280 | iLevel); |
| 152047 | sqlite3WhereClausePrint(pWC); | 157281 | sqlite3WhereClausePrint(pWC); |
| 152048 | } | 157282 | } |
| 152049 | if( sqlite3WhereTrace & 0x800 ){ | 157283 | if( sqlite3WhereTrace & 0x1 ){ |
| 152050 | sqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", | 157284 | sqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", |
| 152051 | iLevel, (u64)pLevel->notReady); | 157285 | iLevel, (u64)pLevel->notReady); |
| 152052 | } | 157286 | } |
| @@ -152161,7 +157395,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( | |||
| 152161 | ** the WHERE clause of SQL statements. | 157395 | ** the WHERE clause of SQL statements. |
| 152162 | ** | 157396 | ** |
| 152163 | ** This file was originally part of where.c but was split out to improve | 157397 | ** This file was originally part of where.c but was split out to improve |
| 152164 | ** readability and editabiliity. This file contains utility routines for | 157398 | ** readability and editability. This file contains utility routines for |
| 152165 | ** analyzing Expr objects in the WHERE clause. | 157399 | ** analyzing Expr objects in the WHERE clause. |
| 152166 | */ | 157400 | */ |
| 152167 | /* #include "sqliteInt.h" */ | 157401 | /* #include "sqliteInt.h" */ |
| @@ -152377,7 +157611,7 @@ static int isLikeOrGlob( | |||
| 152377 | ** range search. The third is because the caller assumes that the pattern | 157611 | ** range search. The third is because the caller assumes that the pattern |
| 152378 | ** consists of at least one character after all escapes have been | 157612 | ** consists of at least one character after all escapes have been |
| 152379 | ** removed. */ | 157613 | ** removed. */ |
| 152380 | if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){ | 157614 | if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ |
| 152381 | Expr *pPrefix; | 157615 | Expr *pPrefix; |
| 152382 | 157616 | ||
| 152383 | /* A "complete" match if the pattern ends with "*" or "%" */ | 157617 | /* A "complete" match if the pattern ends with "*" or "%" */ |
| @@ -152414,7 +157648,7 @@ static int isLikeOrGlob( | |||
| 152414 | if( pLeft->op!=TK_COLUMN | 157648 | if( pLeft->op!=TK_COLUMN |
| 152415 | || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT | 157649 | || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT |
| 152416 | || (ALWAYS( ExprUseYTab(pLeft) ) | 157650 | || (ALWAYS( ExprUseYTab(pLeft) ) |
| 152417 | && pLeft->y.pTab | 157651 | && ALWAYS(pLeft->y.pTab) |
| 152418 | && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ | 157652 | && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ |
| 152419 | ){ | 157653 | ){ |
| 152420 | int isNum; | 157654 | int isNum; |
| @@ -152531,8 +157765,7 @@ static int isAuxiliaryVtabOperator( | |||
| 152531 | ** MATCH(expression,vtab_column) | 157765 | ** MATCH(expression,vtab_column) |
| 152532 | */ | 157766 | */ |
| 152533 | pCol = pList->a[1].pExpr; | 157767 | pCol = pList->a[1].pExpr; |
| 152534 | assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); | 157768 | assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); |
| 152535 | testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); | ||
| 152536 | if( ExprIsVtab(pCol) ){ | 157769 | if( ExprIsVtab(pCol) ){ |
| 152537 | for(i=0; i<ArraySize(aOp); i++){ | 157770 | for(i=0; i<ArraySize(aOp); i++){ |
| 152538 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 157771 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| @@ -152557,7 +157790,7 @@ static int isAuxiliaryVtabOperator( | |||
| 152557 | */ | 157790 | */ |
| 152558 | pCol = pList->a[0].pExpr; | 157791 | pCol = pList->a[0].pExpr; |
| 152559 | assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); | 157792 | assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); |
| 152560 | testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); | 157793 | assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); |
| 152561 | if( ExprIsVtab(pCol) ){ | 157794 | if( ExprIsVtab(pCol) ){ |
| 152562 | sqlite3_vtab *pVtab; | 157795 | sqlite3_vtab *pVtab; |
| 152563 | sqlite3_module *pMod; | 157796 | sqlite3_module *pMod; |
| @@ -152582,13 +157815,12 @@ static int isAuxiliaryVtabOperator( | |||
| 152582 | int res = 0; | 157815 | int res = 0; |
| 152583 | Expr *pLeft = pExpr->pLeft; | 157816 | Expr *pLeft = pExpr->pLeft; |
| 152584 | Expr *pRight = pExpr->pRight; | 157817 | Expr *pRight = pExpr->pRight; |
| 152585 | assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); | 157818 | assert( pLeft->op!=TK_COLUMN || (ExprUseYTab(pLeft) && pLeft->y.pTab!=0) ); |
| 152586 | testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); | ||
| 152587 | if( ExprIsVtab(pLeft) ){ | 157819 | if( ExprIsVtab(pLeft) ){ |
| 152588 | res++; | 157820 | res++; |
| 152589 | } | 157821 | } |
| 152590 | assert( pRight==0 || pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); | 157822 | assert( pRight==0 || pRight->op!=TK_COLUMN |
| 152591 | testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); | 157823 | || (ExprUseYTab(pRight) && pRight->y.pTab!=0) ); |
| 152592 | if( pRight && ExprIsVtab(pRight) ){ | 157824 | if( pRight && ExprIsVtab(pRight) ){ |
| 152593 | res++; | 157825 | res++; |
| 152594 | SWAP(Expr*, pLeft, pRight); | 157826 | SWAP(Expr*, pLeft, pRight); |
| @@ -152952,7 +158184,7 @@ static void exprAnalyzeOrTerm( | |||
| 152952 | pOrTerm->leftCursor))==0 ){ | 158184 | pOrTerm->leftCursor))==0 ){ |
| 152953 | /* This term must be of the form t1.a==t2.b where t2 is in the | 158185 | /* This term must be of the form t1.a==t2.b where t2 is in the |
| 152954 | ** chngToIN set but t1 is not. This term will be either preceded | 158186 | ** chngToIN set but t1 is not. This term will be either preceded |
| 152955 | ** or follwed by an inverted copy (t2.b==t1.a). Skip this term | 158187 | ** or followed by an inverted copy (t2.b==t1.a). Skip this term |
| 152956 | ** and use its inversion. */ | 158188 | ** and use its inversion. */ |
| 152957 | testcase( pOrTerm->wtFlags & TERM_COPIED ); | 158189 | testcase( pOrTerm->wtFlags & TERM_COPIED ); |
| 152958 | testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); | 158190 | testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); |
| @@ -153124,35 +158356,40 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ | |||
| 153124 | */ | 158356 | */ |
| 153125 | static SQLITE_NOINLINE int exprMightBeIndexed2( | 158357 | static SQLITE_NOINLINE int exprMightBeIndexed2( |
| 153126 | SrcList *pFrom, /* The FROM clause */ | 158358 | SrcList *pFrom, /* The FROM clause */ |
| 153127 | Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ | ||
| 153128 | int *aiCurCol, /* Write the referenced table cursor and column here */ | 158359 | int *aiCurCol, /* Write the referenced table cursor and column here */ |
| 153129 | Expr *pExpr /* An operand of a comparison operator */ | 158360 | Expr *pExpr, /* An operand of a comparison operator */ |
| 158361 | int j /* Start looking with the j-th pFrom entry */ | ||
| 153130 | ){ | 158362 | ){ |
| 153131 | Index *pIdx; | 158363 | Index *pIdx; |
| 153132 | int i; | 158364 | int i; |
| 153133 | int iCur; | 158365 | int iCur; |
| 153134 | for(i=0; mPrereq>1; i++, mPrereq>>=1){} | 158366 | do{ |
| 153135 | iCur = pFrom->a[i].iCursor; | 158367 | iCur = pFrom->a[j].iCursor; |
| 153136 | for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 158368 | for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 153137 | if( pIdx->aColExpr==0 ) continue; | 158369 | if( pIdx->aColExpr==0 ) continue; |
| 153138 | for(i=0; i<pIdx->nKeyCol; i++){ | 158370 | for(i=0; i<pIdx->nKeyCol; i++){ |
| 153139 | if( pIdx->aiColumn[i]!=XN_EXPR ) continue; | 158371 | if( pIdx->aiColumn[i]!=XN_EXPR ) continue; |
| 153140 | if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ | 158372 | assert( pIdx->bHasExpr ); |
| 153141 | aiCurCol[0] = iCur; | 158373 | if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 |
| 153142 | aiCurCol[1] = XN_EXPR; | 158374 | && pExpr->op!=TK_STRING |
| 153143 | return 1; | 158375 | ){ |
| 158376 | aiCurCol[0] = iCur; | ||
| 158377 | aiCurCol[1] = XN_EXPR; | ||
| 158378 | return 1; | ||
| 158379 | } | ||
| 153144 | } | 158380 | } |
| 153145 | } | 158381 | } |
| 153146 | } | 158382 | }while( ++j < pFrom->nSrc ); |
| 153147 | return 0; | 158383 | return 0; |
| 153148 | } | 158384 | } |
| 153149 | static int exprMightBeIndexed( | 158385 | static int exprMightBeIndexed( |
| 153150 | SrcList *pFrom, /* The FROM clause */ | 158386 | SrcList *pFrom, /* The FROM clause */ |
| 153151 | Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ | ||
| 153152 | int *aiCurCol, /* Write the referenced table cursor & column here */ | 158387 | int *aiCurCol, /* Write the referenced table cursor & column here */ |
| 153153 | Expr *pExpr, /* An operand of a comparison operator */ | 158388 | Expr *pExpr, /* An operand of a comparison operator */ |
| 153154 | int op /* The specific comparison operator */ | 158389 | int op /* The specific comparison operator */ |
| 153155 | ){ | 158390 | ){ |
| 158391 | int i; | ||
| 158392 | |||
| 153156 | /* If this expression is a vector to the left or right of a | 158393 | /* If this expression is a vector to the left or right of a |
| 153157 | ** inequality constraint (>, <, >= or <=), perform the processing | 158394 | ** inequality constraint (>, <, >= or <=), perform the processing |
| 153158 | ** on the first element of the vector. */ | 158395 | ** on the first element of the vector. */ |
| @@ -153162,7 +158399,6 @@ static int exprMightBeIndexed( | |||
| 153162 | if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ | 158399 | if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ |
| 153163 | assert( ExprUseXList(pExpr) ); | 158400 | assert( ExprUseXList(pExpr) ); |
| 153164 | pExpr = pExpr->x.pList->a[0].pExpr; | 158401 | pExpr = pExpr->x.pList->a[0].pExpr; |
| 153165 | |||
| 153166 | } | 158402 | } |
| 153167 | 158403 | ||
| 153168 | if( pExpr->op==TK_COLUMN ){ | 158404 | if( pExpr->op==TK_COLUMN ){ |
| @@ -153170,9 +158406,16 @@ static int exprMightBeIndexed( | |||
| 153170 | aiCurCol[1] = pExpr->iColumn; | 158406 | aiCurCol[1] = pExpr->iColumn; |
| 153171 | return 1; | 158407 | return 1; |
| 153172 | } | 158408 | } |
| 153173 | if( mPrereq==0 ) return 0; /* No table references */ | 158409 | |
| 153174 | if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */ | 158410 | for(i=0; i<pFrom->nSrc; i++){ |
| 153175 | return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr); | 158411 | Index *pIdx; |
| 158412 | for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | ||
| 158413 | if( pIdx->aColExpr ){ | ||
| 158414 | return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); | ||
| 158415 | } | ||
| 158416 | } | ||
| 158417 | } | ||
| 158418 | return 0; | ||
| 153176 | } | 158419 | } |
| 153177 | 158420 | ||
| 153178 | 158421 | ||
| @@ -153203,8 +158446,8 @@ static void exprAnalyze( | |||
| 153203 | WhereTerm *pTerm; /* The term to be analyzed */ | 158446 | WhereTerm *pTerm; /* The term to be analyzed */ |
| 153204 | WhereMaskSet *pMaskSet; /* Set of table index masks */ | 158447 | WhereMaskSet *pMaskSet; /* Set of table index masks */ |
| 153205 | Expr *pExpr; /* The expression to be analyzed */ | 158448 | Expr *pExpr; /* The expression to be analyzed */ |
| 153206 | Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */ | 158449 | Bitmask prereqLeft; /* Prerequisites of the pExpr->pLeft */ |
| 153207 | Bitmask prereqAll; /* Prerequesites of pExpr */ | 158450 | Bitmask prereqAll; /* Prerequisites of pExpr */ |
| 153208 | Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ | 158451 | Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ |
| 153209 | Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ | 158452 | Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ |
| 153210 | int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ | 158453 | int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ |
| @@ -153298,7 +158541,7 @@ static void exprAnalyze( | |||
| 153298 | pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr; | 158541 | pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr; |
| 153299 | } | 158542 | } |
| 153300 | 158543 | ||
| 153301 | if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){ | 158544 | if( exprMightBeIndexed(pSrc, aiCurCol, pLeft, op) ){ |
| 153302 | pTerm->leftCursor = aiCurCol[0]; | 158545 | pTerm->leftCursor = aiCurCol[0]; |
| 153303 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); | 158546 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); |
| 153304 | pTerm->u.x.leftColumn = aiCurCol[1]; | 158547 | pTerm->u.x.leftColumn = aiCurCol[1]; |
| @@ -153306,7 +158549,7 @@ static void exprAnalyze( | |||
| 153306 | } | 158549 | } |
| 153307 | if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; | 158550 | if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; |
| 153308 | if( pRight | 158551 | if( pRight |
| 153309 | && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op) | 158552 | && exprMightBeIndexed(pSrc, aiCurCol, pRight, op) |
| 153310 | && !ExprHasProperty(pRight, EP_FixedCol) | 158553 | && !ExprHasProperty(pRight, EP_FixedCol) |
| 153311 | ){ | 158554 | ){ |
| 153312 | WhereTerm *pNew; | 158555 | WhereTerm *pNew; |
| @@ -153350,7 +158593,7 @@ static void exprAnalyze( | |||
| 153350 | && 0==sqlite3ExprCanBeNull(pLeft) | 158593 | && 0==sqlite3ExprCanBeNull(pLeft) |
| 153351 | ){ | 158594 | ){ |
| 153352 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); | 158595 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 153353 | pExpr->op = TK_TRUEFALSE; | 158596 | pExpr->op = TK_TRUEFALSE; /* See tag-20230504-1 */ |
| 153354 | pExpr->u.zToken = "false"; | 158597 | pExpr->u.zToken = "false"; |
| 153355 | ExprSetProperty(pExpr, EP_IsFalse); | 158598 | ExprSetProperty(pExpr, EP_IsFalse); |
| 153356 | pTerm->prereqAll = 0; | 158599 | pTerm->prereqAll = 0; |
| @@ -153517,7 +158760,6 @@ static void exprAnalyze( | |||
| 153517 | transferJoinMarkings(pNewExpr1, pExpr); | 158760 | transferJoinMarkings(pNewExpr1, pExpr); |
| 153518 | idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); | 158761 | idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); |
| 153519 | testcase( idxNew1==0 ); | 158762 | testcase( idxNew1==0 ); |
| 153520 | exprAnalyze(pSrc, pWC, idxNew1); | ||
| 153521 | pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); | 158763 | pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); |
| 153522 | pNewExpr2 = sqlite3PExpr(pParse, TK_LT, | 158764 | pNewExpr2 = sqlite3PExpr(pParse, TK_LT, |
| 153523 | sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), | 158765 | sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), |
| @@ -153525,6 +158767,7 @@ static void exprAnalyze( | |||
| 153525 | transferJoinMarkings(pNewExpr2, pExpr); | 158767 | transferJoinMarkings(pNewExpr2, pExpr); |
| 153526 | idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); | 158768 | idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); |
| 153527 | testcase( idxNew2==0 ); | 158769 | testcase( idxNew2==0 ); |
| 158770 | exprAnalyze(pSrc, pWC, idxNew1); | ||
| 153528 | exprAnalyze(pSrc, pWC, idxNew2); | 158771 | exprAnalyze(pSrc, pWC, idxNew2); |
| 153529 | pTerm = &pWC->a[idxTerm]; | 158772 | pTerm = &pWC->a[idxTerm]; |
| 153530 | if( isComplete ){ | 158773 | if( isComplete ){ |
| @@ -153581,7 +158824,7 @@ static void exprAnalyze( | |||
| 153581 | && pTerm->u.x.iField==0 | 158824 | && pTerm->u.x.iField==0 |
| 153582 | && pExpr->pLeft->op==TK_VECTOR | 158825 | && pExpr->pLeft->op==TK_VECTOR |
| 153583 | && ALWAYS( ExprUseXSelect(pExpr) ) | 158826 | && ALWAYS( ExprUseXSelect(pExpr) ) |
| 153584 | && pExpr->x.pSelect->pPrior==0 | 158827 | && (pExpr->x.pSelect->pPrior==0 || (pExpr->x.pSelect->selFlags & SF_Values)) |
| 153585 | #ifndef SQLITE_OMIT_WINDOWFUNC | 158828 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 153586 | && pExpr->x.pSelect->pWin==0 | 158829 | && pExpr->x.pSelect->pWin==0 |
| 153587 | #endif | 158830 | #endif |
| @@ -153750,9 +158993,9 @@ static void whereAddLimitExpr( | |||
| 153750 | ** exist only so that they may be passed to the xBestIndex method of the | 158993 | ** exist only so that they may be passed to the xBestIndex method of the |
| 153751 | ** single virtual table in the FROM clause of the SELECT. | 158994 | ** single virtual table in the FROM clause of the SELECT. |
| 153752 | */ | 158995 | */ |
| 153753 | SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ | 158996 | SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ |
| 153754 | assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) ); | 158997 | assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ |
| 153755 | if( (p && p->pLimit) /* 1 */ | 158998 | if( p->pGroupBy==0 |
| 153756 | && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ | 158999 | && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ |
| 153757 | && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ | 159000 | && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ |
| 153758 | ){ | 159001 | ){ |
| @@ -153769,6 +159012,13 @@ SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ | |||
| 153769 | assert( pWC->a[ii].eOperator==WO_ROWVAL ); | 159012 | assert( pWC->a[ii].eOperator==WO_ROWVAL ); |
| 153770 | continue; | 159013 | continue; |
| 153771 | } | 159014 | } |
| 159015 | if( pWC->a[ii].nChild ){ | ||
| 159016 | /* If this term has child terms, then they are also part of the | ||
| 159017 | ** pWC->a[] array. So this term can be ignored, as a LIMIT clause | ||
| 159018 | ** will only be added if each of the child terms passes the | ||
| 159019 | ** (leftCursor==iCsr) test below. */ | ||
| 159020 | continue; | ||
| 159021 | } | ||
| 153772 | if( pWC->a[ii].leftCursor!=iCsr ) return; | 159022 | if( pWC->a[ii].leftCursor!=iCsr ) return; |
| 153773 | } | 159023 | } |
| 153774 | 159024 | ||
| @@ -153988,9 +159238,12 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( | |||
| 153988 | pRhs = sqlite3PExpr(pParse, TK_UPLUS, | 159238 | pRhs = sqlite3PExpr(pParse, TK_UPLUS, |
| 153989 | sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); | 159239 | sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); |
| 153990 | pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); | 159240 | pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); |
| 153991 | if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){ | 159241 | if( pItem->fg.jointype & (JT_LEFT|JT_RIGHT) ){ |
| 159242 | testcase( pItem->fg.jointype & JT_LEFT ); /* testtag-20230227a */ | ||
| 159243 | testcase( pItem->fg.jointype & JT_RIGHT ); /* testtag-20230227b */ | ||
| 153992 | joinType = EP_OuterON; | 159244 | joinType = EP_OuterON; |
| 153993 | }else{ | 159245 | }else{ |
| 159246 | testcase( pItem->fg.jointype & JT_LTORJ ); /* testtag-20230227c */ | ||
| 153994 | joinType = EP_InnerON; | 159247 | joinType = EP_InnerON; |
| 153995 | } | 159248 | } |
| 153996 | sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType); | 159249 | sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType); |
| @@ -154069,7 +159322,7 @@ SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){ | |||
| 154069 | ** block sorting is required. | 159322 | ** block sorting is required. |
| 154070 | */ | 159323 | */ |
| 154071 | SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ | 159324 | SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ |
| 154072 | return pWInfo->nOBSat; | 159325 | return pWInfo->nOBSat<0 ? 0 : pWInfo->nOBSat; |
| 154073 | } | 159326 | } |
| 154074 | 159327 | ||
| 154075 | /* | 159328 | /* |
| @@ -154707,7 +159960,7 @@ static void translateColumnToCopy( | |||
| 154707 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) | 159960 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) |
| 154708 | static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ | 159961 | static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ |
| 154709 | int i; | 159962 | int i; |
| 154710 | if( !sqlite3WhereTrace ) return; | 159963 | if( (sqlite3WhereTrace & 0x10)==0 ) return; |
| 154711 | for(i=0; i<p->nConstraint; i++){ | 159964 | for(i=0; i<p->nConstraint; i++){ |
| 154712 | sqlite3DebugPrintf( | 159965 | sqlite3DebugPrintf( |
| 154713 | " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", | 159966 | " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", |
| @@ -154727,7 +159980,7 @@ static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ | |||
| 154727 | } | 159980 | } |
| 154728 | static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ | 159981 | static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ |
| 154729 | int i; | 159982 | int i; |
| 154730 | if( !sqlite3WhereTrace ) return; | 159983 | if( (sqlite3WhereTrace & 0x10)==0 ) return; |
| 154731 | for(i=0; i<p->nConstraint; i++){ | 159984 | for(i=0; i<p->nConstraint; i++){ |
| 154732 | sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", | 159985 | sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", |
| 154733 | i, | 159986 | i, |
| @@ -154745,6 +159998,43 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ | |||
| 154745 | #define whereTraceIndexInfoOutputs(A) | 159998 | #define whereTraceIndexInfoOutputs(A) |
| 154746 | #endif | 159999 | #endif |
| 154747 | 160000 | ||
| 160001 | /* | ||
| 160002 | ** We know that pSrc is an operand of an outer join. Return true if | ||
| 160003 | ** pTerm is a constraint that is compatible with that join. | ||
| 160004 | ** | ||
| 160005 | ** pTerm must be EP_OuterON if pSrc is the right operand of an | ||
| 160006 | ** outer join. pTerm can be either EP_OuterON or EP_InnerON if pSrc | ||
| 160007 | ** is the left operand of a RIGHT join. | ||
| 160008 | ** | ||
| 160009 | ** See https://sqlite.org/forum/forumpost/206d99a16dd9212f | ||
| 160010 | ** for an example of a WHERE clause constraints that may not be used on | ||
| 160011 | ** the right table of a RIGHT JOIN because the constraint implies a | ||
| 160012 | ** not-NULL condition on the left table of the RIGHT JOIN. | ||
| 160013 | */ | ||
| 160014 | static int constraintCompatibleWithOuterJoin( | ||
| 160015 | const WhereTerm *pTerm, /* WHERE clause term to check */ | ||
| 160016 | const SrcItem *pSrc /* Table we are trying to access */ | ||
| 160017 | ){ | ||
| 160018 | assert( (pSrc->fg.jointype&(JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ); /* By caller */ | ||
| 160019 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); | ||
| 160020 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); | ||
| 160021 | testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) | ||
| 160022 | testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); | ||
| 160023 | if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) | ||
| 160024 | || pTerm->pExpr->w.iJoin != pSrc->iCursor | ||
| 160025 | ){ | ||
| 160026 | return 0; | ||
| 160027 | } | ||
| 160028 | if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 | ||
| 160029 | && ExprHasProperty(pTerm->pExpr, EP_InnerON) | ||
| 160030 | ){ | ||
| 160031 | return 0; | ||
| 160032 | } | ||
| 160033 | return 1; | ||
| 160034 | } | ||
| 160035 | |||
| 160036 | |||
| 160037 | |||
| 154748 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX | 160038 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 154749 | /* | 160039 | /* |
| 154750 | ** Return TRUE if the WHERE clause term pTerm is of a form where it | 160040 | ** Return TRUE if the WHERE clause term pTerm is of a form where it |
| @@ -154760,16 +160050,10 @@ static int termCanDriveIndex( | |||
| 154760 | if( pTerm->leftCursor!=pSrc->iCursor ) return 0; | 160050 | if( pTerm->leftCursor!=pSrc->iCursor ) return 0; |
| 154761 | if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; | 160051 | if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; |
| 154762 | assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); | 160052 | assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); |
| 154763 | if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){ | 160053 | if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 |
| 154764 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); | 160054 | && !constraintCompatibleWithOuterJoin(pTerm,pSrc) |
| 154765 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); | 160055 | ){ |
| 154766 | testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) | 160056 | return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */ |
| 154767 | testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); | ||
| 154768 | if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) | ||
| 154769 | || pTerm->pExpr->w.iJoin != pSrc->iCursor | ||
| 154770 | ){ | ||
| 154771 | return 0; /* See tag-20191211-001 */ | ||
| 154772 | } | ||
| 154773 | } | 160057 | } |
| 154774 | if( (pTerm->prereqRight & notReady)!=0 ) return 0; | 160058 | if( (pTerm->prereqRight & notReady)!=0 ) return 0; |
| 154775 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); | 160059 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); |
| @@ -154783,6 +160067,57 @@ static int termCanDriveIndex( | |||
| 154783 | 160067 | ||
| 154784 | 160068 | ||
| 154785 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX | 160069 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 160070 | |||
| 160071 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 160072 | /* | ||
| 160073 | ** Argument pIdx represents an automatic index that the current statement | ||
| 160074 | ** will create and populate. Add an OP_Explain with text of the form: | ||
| 160075 | ** | ||
| 160076 | ** CREATE AUTOMATIC INDEX ON <table>(<cols>) [WHERE <expr>] | ||
| 160077 | ** | ||
| 160078 | ** This is only required if sqlite3_stmt_scanstatus() is enabled, to | ||
| 160079 | ** associate an SQLITE_SCANSTAT_NCYCLE and SQLITE_SCANSTAT_NLOOP | ||
| 160080 | ** values with. In order to avoid breaking legacy code and test cases, | ||
| 160081 | ** the OP_Explain is not added if this is an EXPLAIN QUERY PLAN command. | ||
| 160082 | */ | ||
| 160083 | static void explainAutomaticIndex( | ||
| 160084 | Parse *pParse, | ||
| 160085 | Index *pIdx, /* Automatic index to explain */ | ||
| 160086 | int bPartial, /* True if pIdx is a partial index */ | ||
| 160087 | int *pAddrExplain /* OUT: Address of OP_Explain */ | ||
| 160088 | ){ | ||
| 160089 | if( IS_STMT_SCANSTATUS(pParse->db) && pParse->explain!=2 ){ | ||
| 160090 | Table *pTab = pIdx->pTable; | ||
| 160091 | const char *zSep = ""; | ||
| 160092 | char *zText = 0; | ||
| 160093 | int ii = 0; | ||
| 160094 | sqlite3_str *pStr = sqlite3_str_new(pParse->db); | ||
| 160095 | sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName); | ||
| 160096 | assert( pIdx->nColumn>1 ); | ||
| 160097 | assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID ); | ||
| 160098 | for(ii=0; ii<(pIdx->nColumn-1); ii++){ | ||
| 160099 | const char *zName = 0; | ||
| 160100 | int iCol = pIdx->aiColumn[ii]; | ||
| 160101 | |||
| 160102 | zName = pTab->aCol[iCol].zCnName; | ||
| 160103 | sqlite3_str_appendf(pStr, "%s%s", zSep, zName); | ||
| 160104 | zSep = ", "; | ||
| 160105 | } | ||
| 160106 | zText = sqlite3_str_finish(pStr); | ||
| 160107 | if( zText==0 ){ | ||
| 160108 | sqlite3OomFault(pParse->db); | ||
| 160109 | }else{ | ||
| 160110 | *pAddrExplain = sqlite3VdbeExplain( | ||
| 160111 | pParse, 0, "%s)%s", zText, (bPartial ? " WHERE <expr>" : "") | ||
| 160112 | ); | ||
| 160113 | sqlite3_free(zText); | ||
| 160114 | } | ||
| 160115 | } | ||
| 160116 | } | ||
| 160117 | #else | ||
| 160118 | # define explainAutomaticIndex(a,b,c,d) | ||
| 160119 | #endif | ||
| 160120 | |||
| 154786 | /* | 160121 | /* |
| 154787 | ** Generate code to construct the Index object for an automatic index | 160122 | ** Generate code to construct the Index object for an automatic index |
| 154788 | ** and to set up the WhereLevel object pLevel so that the code generator | 160123 | ** and to set up the WhereLevel object pLevel so that the code generator |
| @@ -154790,8 +160125,7 @@ static int termCanDriveIndex( | |||
| 154790 | */ | 160125 | */ |
| 154791 | static SQLITE_NOINLINE void constructAutomaticIndex( | 160126 | static SQLITE_NOINLINE void constructAutomaticIndex( |
| 154792 | Parse *pParse, /* The parsing context */ | 160127 | Parse *pParse, /* The parsing context */ |
| 154793 | const WhereClause *pWC, /* The WHERE clause */ | 160128 | WhereClause *pWC, /* The WHERE clause */ |
| 154794 | const SrcItem *pSrc, /* The FROM clause term to get the next index */ | ||
| 154795 | const Bitmask notReady, /* Mask of cursors that are not available */ | 160129 | const Bitmask notReady, /* Mask of cursors that are not available */ |
| 154796 | WhereLevel *pLevel /* Write new index here */ | 160130 | WhereLevel *pLevel /* Write new index here */ |
| 154797 | ){ | 160131 | ){ |
| @@ -154812,12 +160146,17 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 154812 | char *zNotUsed; /* Extra space on the end of pIdx */ | 160146 | char *zNotUsed; /* Extra space on the end of pIdx */ |
| 154813 | Bitmask idxCols; /* Bitmap of columns used for indexing */ | 160147 | Bitmask idxCols; /* Bitmap of columns used for indexing */ |
| 154814 | Bitmask extraCols; /* Bitmap of additional columns */ | 160148 | Bitmask extraCols; /* Bitmap of additional columns */ |
| 154815 | u8 sentWarning = 0; /* True if a warnning has been issued */ | 160149 | u8 sentWarning = 0; /* True if a warning has been issued */ |
| 160150 | u8 useBloomFilter = 0; /* True to also add a Bloom filter */ | ||
| 154816 | Expr *pPartial = 0; /* Partial Index Expression */ | 160151 | Expr *pPartial = 0; /* Partial Index Expression */ |
| 154817 | int iContinue = 0; /* Jump here to skip excluded rows */ | 160152 | int iContinue = 0; /* Jump here to skip excluded rows */ |
| 154818 | SrcItem *pTabItem; /* FROM clause term being indexed */ | 160153 | SrcList *pTabList; /* The complete FROM clause */ |
| 160154 | SrcItem *pSrc; /* The FROM clause term to get the next index */ | ||
| 154819 | int addrCounter = 0; /* Address where integer counter is initialized */ | 160155 | int addrCounter = 0; /* Address where integer counter is initialized */ |
| 154820 | int regBase; /* Array of registers where record is assembled */ | 160156 | int regBase; /* Array of registers where record is assembled */ |
| 160157 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | ||
| 160158 | int addrExp = 0; /* Address of OP_Explain */ | ||
| 160159 | #endif | ||
| 154821 | 160160 | ||
| 154822 | /* Generate code to skip over the creation and initialization of the | 160161 | /* Generate code to skip over the creation and initialization of the |
| 154823 | ** transient index on 2nd and subsequent iterations of the loop. */ | 160162 | ** transient index on 2nd and subsequent iterations of the loop. */ |
| @@ -154828,6 +160167,8 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 154828 | /* Count the number of columns that will be added to the index | 160167 | /* Count the number of columns that will be added to the index |
| 154829 | ** and used to match WHERE clause constraints */ | 160168 | ** and used to match WHERE clause constraints */ |
| 154830 | nKeyCol = 0; | 160169 | nKeyCol = 0; |
| 160170 | pTabList = pWC->pWInfo->pTabList; | ||
| 160171 | pSrc = &pTabList->a[pLevel->iFrom]; | ||
| 154831 | pTable = pSrc->pTab; | 160172 | pTable = pSrc->pTab; |
| 154832 | pWCEnd = &pWC->a[pWC->nTerm]; | 160173 | pWCEnd = &pWC->a[pWC->nTerm]; |
| 154833 | pLoop = pLevel->pWLoop; | 160174 | pLoop = pLevel->pWLoop; |
| @@ -154838,7 +160179,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 154838 | ** WHERE clause (or the ON clause of a LEFT join) that constrain which | 160179 | ** WHERE clause (or the ON clause of a LEFT join) that constrain which |
| 154839 | ** rows of the target table (pSrc) that can be used. */ | 160180 | ** rows of the target table (pSrc) that can be used. */ |
| 154840 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 | 160181 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 |
| 154841 | && sqlite3ExprIsTableConstraint(pExpr, pSrc) | 160182 | && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom) |
| 154842 | ){ | 160183 | ){ |
| 154843 | pPartial = sqlite3ExprAnd(pParse, pPartial, | 160184 | pPartial = sqlite3ExprAnd(pParse, pPartial, |
| 154844 | sqlite3ExprDup(pParse->db, pExpr, 0)); | 160185 | sqlite3ExprDup(pParse->db, pExpr, 0)); |
| @@ -154879,7 +160220,11 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 154879 | ** original table changes and the index and table cannot both be used | 160220 | ** original table changes and the index and table cannot both be used |
| 154880 | ** if they go out of sync. | 160221 | ** if they go out of sync. |
| 154881 | */ | 160222 | */ |
| 154882 | extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); | 160223 | if( IsView(pTable) ){ |
| 160224 | extraCols = ALLBITS; | ||
| 160225 | }else{ | ||
| 160226 | extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); | ||
| 160227 | } | ||
| 154883 | mxBitCol = MIN(BMS-1,pTable->nCol); | 160228 | mxBitCol = MIN(BMS-1,pTable->nCol); |
| 154884 | testcase( pTable->nCol==BMS-1 ); | 160229 | testcase( pTable->nCol==BMS-1 ); |
| 154885 | testcase( pTable->nCol==BMS-2 ); | 160230 | testcase( pTable->nCol==BMS-2 ); |
| @@ -154915,6 +160260,16 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 154915 | assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ | 160260 | assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ |
| 154916 | pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; | 160261 | pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; |
| 154917 | n++; | 160262 | n++; |
| 160263 | if( ALWAYS(pX->pLeft!=0) | ||
| 160264 | && sqlite3ExprAffinity(pX->pLeft)!=SQLITE_AFF_TEXT | ||
| 160265 | ){ | ||
| 160266 | /* TUNING: only use a Bloom filter on an automatic index | ||
| 160267 | ** if one or more key columns has the ability to hold numeric | ||
| 160268 | ** values, since strings all have the same hash in the Bloom | ||
| 160269 | ** filter implementation and hence a Bloom filter on a text column | ||
| 160270 | ** is not usually helpful. */ | ||
| 160271 | useBloomFilter = 1; | ||
| 160272 | } | ||
| 154918 | } | 160273 | } |
| 154919 | } | 160274 | } |
| 154920 | } | 160275 | } |
| @@ -154941,25 +160296,27 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 154941 | pIdx->azColl[n] = sqlite3StrBINARY; | 160296 | pIdx->azColl[n] = sqlite3StrBINARY; |
| 154942 | 160297 | ||
| 154943 | /* Create the automatic index */ | 160298 | /* Create the automatic index */ |
| 160299 | explainAutomaticIndex(pParse, pIdx, pPartial!=0, &addrExp); | ||
| 154944 | assert( pLevel->iIdxCur>=0 ); | 160300 | assert( pLevel->iIdxCur>=0 ); |
| 154945 | pLevel->iIdxCur = pParse->nTab++; | 160301 | pLevel->iIdxCur = pParse->nTab++; |
| 154946 | sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); | 160302 | sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); |
| 154947 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); | 160303 | sqlite3VdbeSetP4KeyInfo(pParse, pIdx); |
| 154948 | VdbeComment((v, "for %s", pTable->zName)); | 160304 | VdbeComment((v, "for %s", pTable->zName)); |
| 154949 | if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ | 160305 | if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) && useBloomFilter ){ |
| 160306 | sqlite3WhereExplainBloomFilter(pParse, pWC->pWInfo, pLevel); | ||
| 154950 | pLevel->regFilter = ++pParse->nMem; | 160307 | pLevel->regFilter = ++pParse->nMem; |
| 154951 | sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); | 160308 | sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); |
| 154952 | } | 160309 | } |
| 154953 | 160310 | ||
| 154954 | /* Fill the automatic index with content */ | 160311 | /* Fill the automatic index with content */ |
| 154955 | pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; | 160312 | assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); |
| 154956 | if( pTabItem->fg.viaCoroutine ){ | 160313 | if( pSrc->fg.viaCoroutine ){ |
| 154957 | int regYield = pTabItem->regReturn; | 160314 | int regYield = pSrc->regReturn; |
| 154958 | addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); | 160315 | addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); |
| 154959 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); | 160316 | sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub); |
| 154960 | addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); | 160317 | addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); |
| 154961 | VdbeCoverage(v); | 160318 | VdbeCoverage(v); |
| 154962 | VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); | 160319 | VdbeComment((v, "next row of %s", pSrc->pTab->zName)); |
| 154963 | }else{ | 160320 | }else{ |
| 154964 | addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); | 160321 | addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); |
| 154965 | } | 160322 | } |
| @@ -154976,17 +160333,18 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 154976 | sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, | 160333 | sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, |
| 154977 | regBase, pLoop->u.btree.nEq); | 160334 | regBase, pLoop->u.btree.nEq); |
| 154978 | } | 160335 | } |
| 160336 | sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v)); | ||
| 154979 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); | 160337 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); |
| 154980 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); | 160338 | sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); |
| 154981 | if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); | 160339 | if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); |
| 154982 | if( pTabItem->fg.viaCoroutine ){ | 160340 | if( pSrc->fg.viaCoroutine ){ |
| 154983 | sqlite3VdbeChangeP2(v, addrCounter, regBase+n); | 160341 | sqlite3VdbeChangeP2(v, addrCounter, regBase+n); |
| 154984 | testcase( pParse->db->mallocFailed ); | 160342 | testcase( pParse->db->mallocFailed ); |
| 154985 | assert( pLevel->iIdxCur>0 ); | 160343 | assert( pLevel->iIdxCur>0 ); |
| 154986 | translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, | 160344 | translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, |
| 154987 | pTabItem->regResult, pLevel->iIdxCur); | 160345 | pSrc->regResult, pLevel->iIdxCur); |
| 154988 | sqlite3VdbeGoto(v, addrTop); | 160346 | sqlite3VdbeGoto(v, addrTop); |
| 154989 | pTabItem->fg.viaCoroutine = 0; | 160347 | pSrc->fg.viaCoroutine = 0; |
| 154990 | }else{ | 160348 | }else{ |
| 154991 | sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); | 160349 | sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); |
| 154992 | sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); | 160350 | sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); |
| @@ -154996,6 +160354,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( | |||
| 154996 | 160354 | ||
| 154997 | /* Jump here when skipping the initialization */ | 160355 | /* Jump here when skipping the initialization */ |
| 154998 | sqlite3VdbeJumpHere(v, addrInit); | 160356 | sqlite3VdbeJumpHere(v, addrInit); |
| 160357 | sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1); | ||
| 154999 | 160358 | ||
| 155000 | end_auto_index_create: | 160359 | end_auto_index_create: |
| 155001 | sqlite3ExprDelete(pParse->db, pPartial); | 160360 | sqlite3ExprDelete(pParse->db, pPartial); |
| @@ -155037,6 +160396,10 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 155037 | Vdbe *v = pParse->pVdbe; /* VDBE under construction */ | 160396 | Vdbe *v = pParse->pVdbe; /* VDBE under construction */ |
| 155038 | WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ | 160397 | WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ |
| 155039 | int iCur; /* Cursor for table getting the filter */ | 160398 | int iCur; /* Cursor for table getting the filter */ |
| 160399 | IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */ | ||
| 160400 | |||
| 160401 | saved_pIdxEpr = pParse->pIdxEpr; | ||
| 160402 | pParse->pIdxEpr = 0; | ||
| 155040 | 160403 | ||
| 155041 | assert( pLoop!=0 ); | 160404 | assert( pLoop!=0 ); |
| 155042 | assert( v!=0 ); | 160405 | assert( v!=0 ); |
| @@ -155044,9 +160407,11 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 155044 | 160407 | ||
| 155045 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); | 160408 | addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); |
| 155046 | do{ | 160409 | do{ |
| 160410 | const SrcList *pTabList; | ||
| 155047 | const SrcItem *pItem; | 160411 | const SrcItem *pItem; |
| 155048 | const Table *pTab; | 160412 | const Table *pTab; |
| 155049 | u64 sz; | 160413 | u64 sz; |
| 160414 | int iSrc; | ||
| 155050 | sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel); | 160415 | sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel); |
| 155051 | addrCont = sqlite3VdbeMakeLabel(pParse); | 160416 | addrCont = sqlite3VdbeMakeLabel(pParse); |
| 155052 | iCur = pLevel->iTabCur; | 160417 | iCur = pLevel->iTabCur; |
| @@ -155060,7 +160425,9 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 155060 | ** testing complicated. By basing the blob size on the value in the | 160425 | ** testing complicated. By basing the blob size on the value in the |
| 155061 | ** sqlite_stat1 table, testing is much easier. | 160426 | ** sqlite_stat1 table, testing is much easier. |
| 155062 | */ | 160427 | */ |
| 155063 | pItem = &pWInfo->pTabList->a[pLevel->iFrom]; | 160428 | pTabList = pWInfo->pTabList; |
| 160429 | iSrc = pLevel->iFrom; | ||
| 160430 | pItem = &pTabList->a[iSrc]; | ||
| 155064 | assert( pItem!=0 ); | 160431 | assert( pItem!=0 ); |
| 155065 | pTab = pItem->pTab; | 160432 | pTab = pItem->pTab; |
| 155066 | assert( pTab!=0 ); | 160433 | assert( pTab!=0 ); |
| @@ -155077,7 +160444,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 155077 | for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){ | 160444 | for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){ |
| 155078 | Expr *pExpr = pTerm->pExpr; | 160445 | Expr *pExpr = pTerm->pExpr; |
| 155079 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 | 160446 | if( (pTerm->wtFlags & TERM_VIRTUAL)==0 |
| 155080 | && sqlite3ExprIsTableConstraint(pExpr, pItem) | 160447 | && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc) |
| 155081 | ){ | 160448 | ){ |
| 155082 | sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); | 160449 | sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); |
| 155083 | } | 160450 | } |
| @@ -155093,9 +160460,8 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 155093 | int r1 = sqlite3GetTempRange(pParse, n); | 160460 | int r1 = sqlite3GetTempRange(pParse, n); |
| 155094 | int jj; | 160461 | int jj; |
| 155095 | for(jj=0; jj<n; jj++){ | 160462 | for(jj=0; jj<n; jj++){ |
| 155096 | int iCol = pIdx->aiColumn[jj]; | ||
| 155097 | assert( pIdx->pTable==pItem->pTab ); | 160463 | assert( pIdx->pTable==pItem->pTab ); |
| 155098 | sqlite3ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iCol,r1+jj); | 160464 | sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); |
| 155099 | } | 160465 | } |
| 155100 | sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); | 160466 | sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); |
| 155101 | sqlite3ReleaseTempRange(pParse, r1, n); | 160467 | sqlite3ReleaseTempRange(pParse, r1, n); |
| @@ -155126,6 +160492,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( | |||
| 155126 | } | 160492 | } |
| 155127 | }while( iLevel < pWInfo->nLevel ); | 160493 | }while( iLevel < pWInfo->nLevel ); |
| 155128 | sqlite3VdbeJumpHere(v, addrOnce); | 160494 | sqlite3VdbeJumpHere(v, addrOnce); |
| 160495 | pParse->pIdxEpr = saved_pIdxEpr; | ||
| 155129 | } | 160496 | } |
| 155130 | 160497 | ||
| 155131 | 160498 | ||
| @@ -155181,22 +160548,10 @@ static sqlite3_index_info *allocateIndexInfo( | |||
| 155181 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); | 160548 | assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); |
| 155182 | assert( pTerm->u.x.leftColumn>=XN_ROWID ); | 160549 | assert( pTerm->u.x.leftColumn>=XN_ROWID ); |
| 155183 | assert( pTerm->u.x.leftColumn<pTab->nCol ); | 160550 | assert( pTerm->u.x.leftColumn<pTab->nCol ); |
| 155184 | 160551 | if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 | |
| 155185 | /* tag-20191211-002: WHERE-clause constraints are not useful to the | 160552 | && !constraintCompatibleWithOuterJoin(pTerm,pSrc) |
| 155186 | ** right-hand table of a LEFT JOIN nor to the either table of a | 160553 | ){ |
| 155187 | ** RIGHT JOIN. See tag-20191211-001 for the | 160554 | continue; |
| 155188 | ** equivalent restriction for ordinary tables. */ | ||
| 155189 | if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){ | ||
| 155190 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); | ||
| 155191 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT ); | ||
| 155192 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); | ||
| 155193 | testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ); | ||
| 155194 | testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); | ||
| 155195 | if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) | ||
| 155196 | || pTerm->pExpr->w.iJoin != pSrc->iCursor | ||
| 155197 | ){ | ||
| 155198 | continue; | ||
| 155199 | } | ||
| 155200 | } | 160555 | } |
| 155201 | nTerm++; | 160556 | nTerm++; |
| 155202 | pTerm->wtFlags |= TERM_OK; | 160557 | pTerm->wtFlags |= TERM_OK; |
| @@ -155393,6 +160748,9 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ | |||
| 155393 | sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); | 160748 | sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); |
| 155394 | } | 160749 | } |
| 155395 | } | 160750 | } |
| 160751 | if( pTab->u.vtab.p->bAllSchemas ){ | ||
| 160752 | sqlite3VtabUsesAllSchemas(pParse); | ||
| 160753 | } | ||
| 155396 | sqlite3_free(pVtab->zErrMsg); | 160754 | sqlite3_free(pVtab->zErrMsg); |
| 155397 | pVtab->zErrMsg = 0; | 160755 | pVtab->zErrMsg = 0; |
| 155398 | return rc; | 160756 | return rc; |
| @@ -155437,6 +160795,7 @@ static int whereKeyStats( | |||
| 155437 | assert( pIdx->nSample>0 ); | 160795 | assert( pIdx->nSample>0 ); |
| 155438 | assert( pRec->nField>0 ); | 160796 | assert( pRec->nField>0 ); |
| 155439 | 160797 | ||
| 160798 | |||
| 155440 | /* Do a binary search to find the first sample greater than or equal | 160799 | /* Do a binary search to find the first sample greater than or equal |
| 155441 | ** to pRec. If pRec contains a single field, the set of samples to search | 160800 | ** to pRec. If pRec contains a single field, the set of samples to search |
| 155442 | ** is simply the aSample[] array. If the samples in aSample[] contain more | 160801 | ** is simply the aSample[] array. If the samples in aSample[] contain more |
| @@ -155481,7 +160840,12 @@ static int whereKeyStats( | |||
| 155481 | ** it is extended to two fields. The duplicates that this creates do not | 160840 | ** it is extended to two fields. The duplicates that this creates do not |
| 155482 | ** cause any problems. | 160841 | ** cause any problems. |
| 155483 | */ | 160842 | */ |
| 155484 | nField = MIN(pRec->nField, pIdx->nSample); | 160843 | if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ |
| 160844 | nField = pIdx->nKeyCol; | ||
| 160845 | }else{ | ||
| 160846 | nField = pIdx->nColumn; | ||
| 160847 | } | ||
| 160848 | nField = MIN(pRec->nField, nField); | ||
| 155485 | iCol = 0; | 160849 | iCol = 0; |
| 155486 | iSample = pIdx->nSample * nField; | 160850 | iSample = pIdx->nSample * nField; |
| 155487 | do{ | 160851 | do{ |
| @@ -155547,12 +160911,12 @@ static int whereKeyStats( | |||
| 155547 | if( iCol>0 ){ | 160911 | if( iCol>0 ){ |
| 155548 | pRec->nField = iCol; | 160912 | pRec->nField = iCol; |
| 155549 | assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 | 160913 | assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 |
| 155550 | || pParse->db->mallocFailed ); | 160914 | || pParse->db->mallocFailed || CORRUPT_DB ); |
| 155551 | } | 160915 | } |
| 155552 | if( i>0 ){ | 160916 | if( i>0 ){ |
| 155553 | pRec->nField = nField; | 160917 | pRec->nField = nField; |
| 155554 | assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 | 160918 | assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 |
| 155555 | || pParse->db->mallocFailed ); | 160919 | || pParse->db->mallocFailed || CORRUPT_DB ); |
| 155556 | } | 160920 | } |
| 155557 | } | 160921 | } |
| 155558 | } | 160922 | } |
| @@ -155569,7 +160933,7 @@ static int whereKeyStats( | |||
| 155569 | ** is larger than all samples in the array. */ | 160933 | ** is larger than all samples in the array. */ |
| 155570 | tRowcnt iUpper, iGap; | 160934 | tRowcnt iUpper, iGap; |
| 155571 | if( i>=pIdx->nSample ){ | 160935 | if( i>=pIdx->nSample ){ |
| 155572 | iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); | 160936 | iUpper = pIdx->nRowEst0; |
| 155573 | }else{ | 160937 | }else{ |
| 155574 | iUpper = aSample[i].anLt[iCol]; | 160938 | iUpper = aSample[i].anLt[iCol]; |
| 155575 | } | 160939 | } |
| @@ -155644,7 +161008,7 @@ SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCo | |||
| 155644 | ** Value pLoop->nOut is currently set to the estimated number of rows | 161008 | ** Value pLoop->nOut is currently set to the estimated number of rows |
| 155645 | ** visited for scanning (a=? AND b=?). This function reduces that estimate | 161009 | ** visited for scanning (a=? AND b=?). This function reduces that estimate |
| 155646 | ** by some factor to account for the (c BETWEEN ? AND ?) expression based | 161010 | ** by some factor to account for the (c BETWEEN ? AND ?) expression based |
| 155647 | ** on the stat4 data for the index. this scan will be peformed multiple | 161011 | ** on the stat4 data for the index. this scan will be performed multiple |
| 155648 | ** times (once for each (a,b) combination that matches a=?) is dealt with | 161012 | ** times (once for each (a,b) combination that matches a=?) is dealt with |
| 155649 | ** by the caller. | 161013 | ** by the caller. |
| 155650 | ** | 161014 | ** |
| @@ -155725,7 +161089,7 @@ static int whereRangeSkipScanEst( | |||
| 155725 | int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); | 161089 | int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); |
| 155726 | pLoop->nOut -= nAdjust; | 161090 | pLoop->nOut -= nAdjust; |
| 155727 | *pbDone = 1; | 161091 | *pbDone = 1; |
| 155728 | WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", | 161092 | WHERETRACE(0x20, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", |
| 155729 | nLower, nUpper, nAdjust*-1, pLoop->nOut)); | 161093 | nLower, nUpper, nAdjust*-1, pLoop->nOut)); |
| 155730 | } | 161094 | } |
| 155731 | 161095 | ||
| @@ -155903,7 +161267,7 @@ static int whereRangeScanEst( | |||
| 155903 | if( nNew<nOut ){ | 161267 | if( nNew<nOut ){ |
| 155904 | nOut = nNew; | 161268 | nOut = nNew; |
| 155905 | } | 161269 | } |
| 155906 | WHERETRACE(0x10, ("STAT4 range scan: %u..%u est=%d\n", | 161270 | WHERETRACE(0x20, ("STAT4 range scan: %u..%u est=%d\n", |
| 155907 | (u32)iLower, (u32)iUpper, nOut)); | 161271 | (u32)iLower, (u32)iUpper, nOut)); |
| 155908 | } | 161272 | } |
| 155909 | }else{ | 161273 | }else{ |
| @@ -155917,7 +161281,7 @@ static int whereRangeScanEst( | |||
| 155917 | UNUSED_PARAMETER(pBuilder); | 161281 | UNUSED_PARAMETER(pBuilder); |
| 155918 | assert( pLower || pUpper ); | 161282 | assert( pLower || pUpper ); |
| 155919 | #endif | 161283 | #endif |
| 155920 | assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 ); | 161284 | assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 || pParse->nErr>0 ); |
| 155921 | nNew = whereRangeAdjust(pLower, nOut); | 161285 | nNew = whereRangeAdjust(pLower, nOut); |
| 155922 | nNew = whereRangeAdjust(pUpper, nNew); | 161286 | nNew = whereRangeAdjust(pUpper, nNew); |
| 155923 | 161287 | ||
| @@ -155936,7 +161300,7 @@ static int whereRangeScanEst( | |||
| 155936 | if( nNew<nOut ) nOut = nNew; | 161300 | if( nNew<nOut ) nOut = nNew; |
| 155937 | #if defined(WHERETRACE_ENABLED) | 161301 | #if defined(WHERETRACE_ENABLED) |
| 155938 | if( pLoop->nOut>nOut ){ | 161302 | if( pLoop->nOut>nOut ){ |
| 155939 | WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n", | 161303 | WHERETRACE(0x20,("Range scan lowers nOut from %d to %d\n", |
| 155940 | pLoop->nOut, nOut)); | 161304 | pLoop->nOut, nOut)); |
| 155941 | } | 161305 | } |
| 155942 | #endif | 161306 | #endif |
| @@ -156001,7 +161365,7 @@ static int whereEqualScanEst( | |||
| 156001 | pBuilder->nRecValid = nEq; | 161365 | pBuilder->nRecValid = nEq; |
| 156002 | 161366 | ||
| 156003 | whereKeyStats(pParse, p, pRec, 0, a); | 161367 | whereKeyStats(pParse, p, pRec, 0, a); |
| 156004 | WHERETRACE(0x10,("equality scan regions %s(%d): %d\n", | 161368 | WHERETRACE(0x20,("equality scan regions %s(%d): %d\n", |
| 156005 | p->zName, nEq-1, (int)a[1])); | 161369 | p->zName, nEq-1, (int)a[1])); |
| 156006 | *pnRow = a[1]; | 161370 | *pnRow = a[1]; |
| 156007 | 161371 | ||
| @@ -156049,9 +161413,9 @@ static int whereInScanEst( | |||
| 156049 | } | 161413 | } |
| 156050 | 161414 | ||
| 156051 | if( rc==SQLITE_OK ){ | 161415 | if( rc==SQLITE_OK ){ |
| 156052 | if( nRowEst > nRow0 ) nRowEst = nRow0; | 161416 | if( nRowEst > (tRowcnt)nRow0 ) nRowEst = nRow0; |
| 156053 | *pnRow = nRowEst; | 161417 | *pnRow = nRowEst; |
| 156054 | WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst)); | 161418 | WHERETRACE(0x20,("IN row estimate: est=%d\n", nRowEst)); |
| 156055 | } | 161419 | } |
| 156056 | assert( pBuilder->nRecValid==nRecValid ); | 161420 | assert( pBuilder->nRecValid==nRecValid ); |
| 156057 | return rc; | 161421 | return rc; |
| @@ -156160,7 +161524,7 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ | |||
| 156160 | sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm); | 161524 | sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm); |
| 156161 | } | 161525 | } |
| 156162 | sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); | 161526 | sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); |
| 156163 | if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ | 161527 | if( p->nLTerm && (sqlite3WhereTrace & 0x4000)!=0 ){ |
| 156164 | int i; | 161528 | int i; |
| 156165 | for(i=0; i<p->nLTerm; i++){ | 161529 | for(i=0; i<p->nLTerm; i++){ |
| 156166 | sqlite3WhereTermPrint(p->aLTerm[i], i); | 161530 | sqlite3WhereTermPrint(p->aLTerm[i], i); |
| @@ -156198,12 +161562,18 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ | |||
| 156198 | } | 161562 | } |
| 156199 | 161563 | ||
| 156200 | /* | 161564 | /* |
| 156201 | ** Deallocate internal memory used by a WhereLoop object | 161565 | ** Deallocate internal memory used by a WhereLoop object. Leave the |
| 161566 | ** object in an initialized state, as if it had been newly allocated. | ||
| 156202 | */ | 161567 | */ |
| 156203 | static void whereLoopClear(sqlite3 *db, WhereLoop *p){ | 161568 | static void whereLoopClear(sqlite3 *db, WhereLoop *p){ |
| 156204 | if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); | 161569 | if( p->aLTerm!=p->aLTermSpace ){ |
| 161570 | sqlite3DbFreeNN(db, p->aLTerm); | ||
| 161571 | p->aLTerm = p->aLTermSpace; | ||
| 161572 | p->nLSlot = ArraySize(p->aLTermSpace); | ||
| 161573 | } | ||
| 156205 | whereLoopClearUnion(db, p); | 161574 | whereLoopClearUnion(db, p); |
| 156206 | whereLoopInit(p); | 161575 | p->nLTerm = 0; |
| 161576 | p->wsFlags = 0; | ||
| 156207 | } | 161577 | } |
| 156208 | 161578 | ||
| 156209 | /* | 161579 | /* |
| @@ -156227,7 +161597,9 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ | |||
| 156227 | */ | 161597 | */ |
| 156228 | static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ | 161598 | static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ |
| 156229 | whereLoopClearUnion(db, pTo); | 161599 | whereLoopClearUnion(db, pTo); |
| 156230 | if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ | 161600 | if( pFrom->nLTerm > pTo->nLSlot |
| 161601 | && whereLoopResize(db, pTo, pFrom->nLTerm) | ||
| 161602 | ){ | ||
| 156231 | memset(pTo, 0, WHERE_LOOP_XFER_SZ); | 161603 | memset(pTo, 0, WHERE_LOOP_XFER_SZ); |
| 156232 | return SQLITE_NOMEM_BKPT; | 161604 | return SQLITE_NOMEM_BKPT; |
| 156233 | } | 161605 | } |
| @@ -156245,8 +161617,9 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ | |||
| 156245 | ** Delete a WhereLoop object | 161617 | ** Delete a WhereLoop object |
| 156246 | */ | 161618 | */ |
| 156247 | static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ | 161619 | static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ |
| 161620 | assert( db!=0 ); | ||
| 156248 | whereLoopClear(db, p); | 161621 | whereLoopClear(db, p); |
| 156249 | sqlite3DbFreeNN(db, p); | 161622 | sqlite3DbNNFreeNN(db, p); |
| 156250 | } | 161623 | } |
| 156251 | 161624 | ||
| 156252 | /* | 161625 | /* |
| @@ -156254,30 +161627,19 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ | |||
| 156254 | */ | 161627 | */ |
| 156255 | static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ | 161628 | static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ |
| 156256 | assert( pWInfo!=0 ); | 161629 | assert( pWInfo!=0 ); |
| 161630 | assert( db!=0 ); | ||
| 156257 | sqlite3WhereClauseClear(&pWInfo->sWC); | 161631 | sqlite3WhereClauseClear(&pWInfo->sWC); |
| 156258 | while( pWInfo->pLoops ){ | 161632 | while( pWInfo->pLoops ){ |
| 156259 | WhereLoop *p = pWInfo->pLoops; | 161633 | WhereLoop *p = pWInfo->pLoops; |
| 156260 | pWInfo->pLoops = p->pNextLoop; | 161634 | pWInfo->pLoops = p->pNextLoop; |
| 156261 | whereLoopDelete(db, p); | 161635 | whereLoopDelete(db, p); |
| 156262 | } | 161636 | } |
| 156263 | assert( pWInfo->pExprMods==0 ); | ||
| 156264 | while( pWInfo->pMemToFree ){ | 161637 | while( pWInfo->pMemToFree ){ |
| 156265 | WhereMemBlock *pNext = pWInfo->pMemToFree->pNext; | 161638 | WhereMemBlock *pNext = pWInfo->pMemToFree->pNext; |
| 156266 | sqlite3DbFreeNN(db, pWInfo->pMemToFree); | 161639 | sqlite3DbNNFreeNN(db, pWInfo->pMemToFree); |
| 156267 | pWInfo->pMemToFree = pNext; | 161640 | pWInfo->pMemToFree = pNext; |
| 156268 | } | 161641 | } |
| 156269 | sqlite3DbFreeNN(db, pWInfo); | 161642 | sqlite3DbNNFreeNN(db, pWInfo); |
| 156270 | } | ||
| 156271 | |||
| 156272 | /* Undo all Expr node modifications | ||
| 156273 | */ | ||
| 156274 | static void whereUndoExprMods(WhereInfo *pWInfo){ | ||
| 156275 | while( pWInfo->pExprMods ){ | ||
| 156276 | WhereExprMod *p = pWInfo->pExprMods; | ||
| 156277 | pWInfo->pExprMods = p->pNext; | ||
| 156278 | memcpy(p->pExpr, &p->orig, sizeof(p->orig)); | ||
| 156279 | sqlite3DbFree(pWInfo->pParse->db, p); | ||
| 156280 | } | ||
| 156281 | } | 161643 | } |
| 156282 | 161644 | ||
| 156283 | /* | 161645 | /* |
| @@ -156401,7 +161763,7 @@ static WhereLoop **whereLoopFindLesser( | |||
| 156401 | ** rSetup. Call this SETUP-INVARIANT */ | 161763 | ** rSetup. Call this SETUP-INVARIANT */ |
| 156402 | assert( p->rSetup>=pTemplate->rSetup ); | 161764 | assert( p->rSetup>=pTemplate->rSetup ); |
| 156403 | 161765 | ||
| 156404 | /* Any loop using an appliation-defined index (or PRIMARY KEY or | 161766 | /* Any loop using an application-defined index (or PRIMARY KEY or |
| 156405 | ** UNIQUE constraint) with one or more == constraints is better | 161767 | ** UNIQUE constraint) with one or more == constraints is better |
| 156406 | ** than an automatic index. Unless it is a skip-scan. */ | 161768 | ** than an automatic index. Unless it is a skip-scan. */ |
| 156407 | if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 | 161769 | if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 |
| @@ -156428,7 +161790,7 @@ static WhereLoop **whereLoopFindLesser( | |||
| 156428 | 161790 | ||
| 156429 | /* If pTemplate is always better than p, then cause p to be overwritten | 161791 | /* If pTemplate is always better than p, then cause p to be overwritten |
| 156430 | ** with pTemplate. pTemplate is better than p if: | 161792 | ** with pTemplate. pTemplate is better than p if: |
| 156431 | ** (1) pTemplate has no more dependences than p, and | 161793 | ** (1) pTemplate has no more dependencies than p, and |
| 156432 | ** (2) pTemplate has an equal or lower cost than p. | 161794 | ** (2) pTemplate has an equal or lower cost than p. |
| 156433 | */ | 161795 | */ |
| 156434 | if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ | 161796 | if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ |
| @@ -156546,7 +161908,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ | |||
| 156546 | }else{ | 161908 | }else{ |
| 156547 | /* We will be overwriting WhereLoop p[]. But before we do, first | 161909 | /* We will be overwriting WhereLoop p[]. But before we do, first |
| 156548 | ** go through the rest of the list and delete any other entries besides | 161910 | ** go through the rest of the list and delete any other entries besides |
| 156549 | ** p[] that are also supplated by pTemplate */ | 161911 | ** p[] that are also supplanted by pTemplate */ |
| 156550 | WhereLoop **ppTail = &p->pNextLoop; | 161912 | WhereLoop **ppTail = &p->pNextLoop; |
| 156551 | WhereLoop *pToDel; | 161913 | WhereLoop *pToDel; |
| 156552 | while( *ppTail ){ | 161914 | while( *ppTail ){ |
| @@ -156626,6 +161988,7 @@ static void whereLoopOutputAdjust( | |||
| 156626 | if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; | 161988 | if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; |
| 156627 | } | 161989 | } |
| 156628 | if( j<0 ){ | 161990 | if( j<0 ){ |
| 161991 | sqlite3ProgressCheck(pWC->pWInfo->pParse); | ||
| 156629 | if( pLoop->maskSelf==pTerm->prereqAll ){ | 161992 | if( pLoop->maskSelf==pTerm->prereqAll ){ |
| 156630 | /* If there are extra terms in the WHERE clause not used by an index | 161993 | /* If there are extra terms in the WHERE clause not used by an index |
| 156631 | ** that depend only on the table being scanned, and that will tend to | 161994 | ** that depend only on the table being scanned, and that will tend to |
| @@ -156745,7 +162108,7 @@ static int whereRangeVectorLen( | |||
| 156745 | } | 162108 | } |
| 156746 | 162109 | ||
| 156747 | /* | 162110 | /* |
| 156748 | ** Adjust the cost C by the costMult facter T. This only occurs if | 162111 | ** Adjust the cost C by the costMult factor T. This only occurs if |
| 156749 | ** compiled with -DSQLITE_ENABLE_COSTMULT | 162112 | ** compiled with -DSQLITE_ENABLE_COSTMULT |
| 156750 | */ | 162113 | */ |
| 156751 | #ifdef SQLITE_ENABLE_COSTMULT | 162114 | #ifdef SQLITE_ENABLE_COSTMULT |
| @@ -156772,7 +162135,7 @@ static int whereLoopAddBtreeIndex( | |||
| 156772 | Index *pProbe, /* An index on pSrc */ | 162135 | Index *pProbe, /* An index on pSrc */ |
| 156773 | LogEst nInMul /* log(Number of iterations due to IN) */ | 162136 | LogEst nInMul /* log(Number of iterations due to IN) */ |
| 156774 | ){ | 162137 | ){ |
| 156775 | WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */ | 162138 | WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyze context */ |
| 156776 | Parse *pParse = pWInfo->pParse; /* Parsing context */ | 162139 | Parse *pParse = pWInfo->pParse; /* Parsing context */ |
| 156777 | sqlite3 *db = pParse->db; /* Database connection malloc context */ | 162140 | sqlite3 *db = pParse->db; /* Database connection malloc context */ |
| 156778 | WhereLoop *pNew; /* Template WhereLoop under construction */ | 162141 | WhereLoop *pNew; /* Template WhereLoop under construction */ |
| @@ -156793,7 +162156,10 @@ static int whereLoopAddBtreeIndex( | |||
| 156793 | WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ | 162156 | WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ |
| 156794 | 162157 | ||
| 156795 | pNew = pBuilder->pNew; | 162158 | pNew = pBuilder->pNew; |
| 156796 | if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; | 162159 | assert( db->mallocFailed==0 || pParse->nErr>0 ); |
| 162160 | if( pParse->nErr ){ | ||
| 162161 | return pParse->rc; | ||
| 162162 | } | ||
| 156797 | WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n", | 162163 | WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n", |
| 156798 | pProbe->pTable->zName,pProbe->zName, | 162164 | pProbe->pTable->zName,pProbe->zName, |
| 156799 | pNew->u.btree.nEq, pNew->nSkip, pNew->rRun)); | 162165 | pNew->u.btree.nEq, pNew->nSkip, pNew->rRun)); |
| @@ -156844,32 +162210,11 @@ static int whereLoopAddBtreeIndex( | |||
| 156844 | ** to mix with a lower range bound from some other source */ | 162210 | ** to mix with a lower range bound from some other source */ |
| 156845 | if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; | 162211 | if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; |
| 156846 | 162212 | ||
| 156847 | /* tag-20191211-001: Do not allow constraints from the WHERE clause to | 162213 | if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 |
| 156848 | ** be used by the right table of a LEFT JOIN nor by the left table of a | 162214 | && !constraintCompatibleWithOuterJoin(pTerm,pSrc) |
| 156849 | ** RIGHT JOIN. Only constraints in the ON clause are allowed. | 162215 | ){ |
| 156850 | ** See tag-20191211-002 for the vtab equivalent. | 162216 | continue; |
| 156851 | ** | ||
| 156852 | ** 2022-06-06: See https://sqlite.org/forum/forumpost/206d99a16dd9212f | ||
| 156853 | ** for an example of a WHERE clause constraints that may not be used on | ||
| 156854 | ** the right table of a RIGHT JOIN because the constraint implies a | ||
| 156855 | ** not-NULL condition on the left table of the RIGHT JOIN. | ||
| 156856 | ** | ||
| 156857 | ** 2022-06-10: The same condition applies to termCanDriveIndex() above. | ||
| 156858 | ** https://sqlite.org/forum/forumpost/51e6959f61 | ||
| 156859 | */ | ||
| 156860 | if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){ | ||
| 156861 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); | ||
| 156862 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT ); | ||
| 156863 | testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); | ||
| 156864 | testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) | ||
| 156865 | testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); | ||
| 156866 | if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) | ||
| 156867 | || pTerm->pExpr->w.iJoin != pSrc->iCursor | ||
| 156868 | ){ | ||
| 156869 | continue; | ||
| 156870 | } | ||
| 156871 | } | 162217 | } |
| 156872 | |||
| 156873 | if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){ | 162218 | if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){ |
| 156874 | pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE; | 162219 | pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE; |
| 156875 | }else{ | 162220 | }else{ |
| @@ -156880,7 +162225,11 @@ static int whereLoopAddBtreeIndex( | |||
| 156880 | pNew->u.btree.nBtm = saved_nBtm; | 162225 | pNew->u.btree.nBtm = saved_nBtm; |
| 156881 | pNew->u.btree.nTop = saved_nTop; | 162226 | pNew->u.btree.nTop = saved_nTop; |
| 156882 | pNew->nLTerm = saved_nLTerm; | 162227 | pNew->nLTerm = saved_nLTerm; |
| 156883 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ | 162228 | if( pNew->nLTerm>=pNew->nLSlot |
| 162229 | && whereLoopResize(db, pNew, pNew->nLTerm+1) | ||
| 162230 | ){ | ||
| 162231 | break; /* OOM while trying to enlarge the pNew->aLTerm array */ | ||
| 162232 | } | ||
| 156884 | pNew->aLTerm[pNew->nLTerm++] = pTerm; | 162233 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| 156885 | pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; | 162234 | pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; |
| 156886 | 162235 | ||
| @@ -156973,38 +162322,39 @@ static int whereLoopAddBtreeIndex( | |||
| 156973 | if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; | 162322 | if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; |
| 156974 | }else if( eOp & WO_ISNULL ){ | 162323 | }else if( eOp & WO_ISNULL ){ |
| 156975 | pNew->wsFlags |= WHERE_COLUMN_NULL; | 162324 | pNew->wsFlags |= WHERE_COLUMN_NULL; |
| 156976 | }else if( eOp & (WO_GT|WO_GE) ){ | 162325 | }else{ |
| 156977 | testcase( eOp & WO_GT ); | 162326 | int nVecLen = whereRangeVectorLen( |
| 156978 | testcase( eOp & WO_GE ); | ||
| 156979 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; | ||
| 156980 | pNew->u.btree.nBtm = whereRangeVectorLen( | ||
| 156981 | pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm | ||
| 156982 | ); | ||
| 156983 | pBtm = pTerm; | ||
| 156984 | pTop = 0; | ||
| 156985 | if( pTerm->wtFlags & TERM_LIKEOPT ){ | ||
| 156986 | /* Range constraints that come from the LIKE optimization are | ||
| 156987 | ** always used in pairs. */ | ||
| 156988 | pTop = &pTerm[1]; | ||
| 156989 | assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm ); | ||
| 156990 | assert( pTop->wtFlags & TERM_LIKEOPT ); | ||
| 156991 | assert( pTop->eOperator==WO_LT ); | ||
| 156992 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ | ||
| 156993 | pNew->aLTerm[pNew->nLTerm++] = pTop; | ||
| 156994 | pNew->wsFlags |= WHERE_TOP_LIMIT; | ||
| 156995 | pNew->u.btree.nTop = 1; | ||
| 156996 | } | ||
| 156997 | }else{ | ||
| 156998 | assert( eOp & (WO_LT|WO_LE) ); | ||
| 156999 | testcase( eOp & WO_LT ); | ||
| 157000 | testcase( eOp & WO_LE ); | ||
| 157001 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; | ||
| 157002 | pNew->u.btree.nTop = whereRangeVectorLen( | ||
| 157003 | pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm | 162327 | pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm |
| 157004 | ); | 162328 | ); |
| 157005 | pTop = pTerm; | 162329 | if( eOp & (WO_GT|WO_GE) ){ |
| 157006 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? | 162330 | testcase( eOp & WO_GT ); |
| 157007 | pNew->aLTerm[pNew->nLTerm-2] : 0; | 162331 | testcase( eOp & WO_GE ); |
| 162332 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; | ||
| 162333 | pNew->u.btree.nBtm = nVecLen; | ||
| 162334 | pBtm = pTerm; | ||
| 162335 | pTop = 0; | ||
| 162336 | if( pTerm->wtFlags & TERM_LIKEOPT ){ | ||
| 162337 | /* Range constraints that come from the LIKE optimization are | ||
| 162338 | ** always used in pairs. */ | ||
| 162339 | pTop = &pTerm[1]; | ||
| 162340 | assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm ); | ||
| 162341 | assert( pTop->wtFlags & TERM_LIKEOPT ); | ||
| 162342 | assert( pTop->eOperator==WO_LT ); | ||
| 162343 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ | ||
| 162344 | pNew->aLTerm[pNew->nLTerm++] = pTop; | ||
| 162345 | pNew->wsFlags |= WHERE_TOP_LIMIT; | ||
| 162346 | pNew->u.btree.nTop = 1; | ||
| 162347 | } | ||
| 162348 | }else{ | ||
| 162349 | assert( eOp & (WO_LT|WO_LE) ); | ||
| 162350 | testcase( eOp & WO_LT ); | ||
| 162351 | testcase( eOp & WO_LE ); | ||
| 162352 | pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; | ||
| 162353 | pNew->u.btree.nTop = nVecLen; | ||
| 162354 | pTop = pTerm; | ||
| 162355 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? | ||
| 162356 | pNew->aLTerm[pNew->nLTerm-2] : 0; | ||
| 162357 | } | ||
| 157008 | } | 162358 | } |
| 157009 | 162359 | ||
| 157010 | /* At this point pNew->nOut is set to the number of rows expected to | 162360 | /* At this point pNew->nOut is set to the number of rows expected to |
| @@ -157056,7 +162406,7 @@ static int whereLoopAddBtreeIndex( | |||
| 157056 | && pNew->nOut+10 > pProbe->aiRowLogEst[0] | 162406 | && pNew->nOut+10 > pProbe->aiRowLogEst[0] |
| 157057 | ){ | 162407 | ){ |
| 157058 | #if WHERETRACE_ENABLED /* 0x01 */ | 162408 | #if WHERETRACE_ENABLED /* 0x01 */ |
| 157059 | if( sqlite3WhereTrace & 0x01 ){ | 162409 | if( sqlite3WhereTrace & 0x20 ){ |
| 157060 | sqlite3DebugPrintf( | 162410 | sqlite3DebugPrintf( |
| 157061 | "STAT4 determines term has low selectivity:\n"); | 162411 | "STAT4 determines term has low selectivity:\n"); |
| 157062 | sqlite3WhereTermPrint(pTerm, 999); | 162412 | sqlite3WhereTermPrint(pTerm, 999); |
| @@ -157093,9 +162443,17 @@ static int whereLoopAddBtreeIndex( | |||
| 157093 | ** seek only. Then, if this is a non-covering index, add the cost of | 162443 | ** seek only. Then, if this is a non-covering index, add the cost of |
| 157094 | ** visiting the rows in the main table. */ | 162444 | ** visiting the rows in the main table. */ |
| 157095 | assert( pSrc->pTab->szTabRow>0 ); | 162445 | assert( pSrc->pTab->szTabRow>0 ); |
| 157096 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; | 162446 | if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ |
| 162447 | /* The pProbe->szIdxRow is low for an IPK table since the interior | ||
| 162448 | ** pages are small. Thus szIdxRow gives a good estimate of seek cost. | ||
| 162449 | ** But the leaf pages are full-size, so pProbe->szIdxRow would badly | ||
| 162450 | ** under-estimate the scanning cost. */ | ||
| 162451 | rCostIdx = pNew->nOut + 16; | ||
| 162452 | }else{ | ||
| 162453 | rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; | ||
| 162454 | } | ||
| 157097 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); | 162455 | pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); |
| 157098 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ | 162456 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ |
| 157099 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); | 162457 | pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); |
| 157100 | } | 162458 | } |
| 157101 | ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); | 162459 | ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); |
| @@ -157117,6 +162475,9 @@ static int whereLoopAddBtreeIndex( | |||
| 157117 | && (pNew->u.btree.nEq<pProbe->nKeyCol || | 162475 | && (pNew->u.btree.nEq<pProbe->nKeyCol || |
| 157118 | pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) | 162476 | pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) |
| 157119 | ){ | 162477 | ){ |
| 162478 | if( pNew->u.btree.nEq>3 ){ | ||
| 162479 | sqlite3ProgressCheck(pParse); | ||
| 162480 | } | ||
| 157120 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); | 162481 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 157121 | } | 162482 | } |
| 157122 | pNew->nOut = saved_nOut; | 162483 | pNew->nOut = saved_nOut; |
| @@ -157249,6 +162610,149 @@ static int whereUsablePartialIndex( | |||
| 157249 | } | 162610 | } |
| 157250 | 162611 | ||
| 157251 | /* | 162612 | /* |
| 162613 | ** pIdx is an index containing expressions. Check it see if any of the | ||
| 162614 | ** expressions in the index match the pExpr expression. | ||
| 162615 | */ | ||
| 162616 | static int exprIsCoveredByIndex( | ||
| 162617 | const Expr *pExpr, | ||
| 162618 | const Index *pIdx, | ||
| 162619 | int iTabCur | ||
| 162620 | ){ | ||
| 162621 | int i; | ||
| 162622 | for(i=0; i<pIdx->nColumn; i++){ | ||
| 162623 | if( pIdx->aiColumn[i]==XN_EXPR | ||
| 162624 | && sqlite3ExprCompare(0, pExpr, pIdx->aColExpr->a[i].pExpr, iTabCur)==0 | ||
| 162625 | ){ | ||
| 162626 | return 1; | ||
| 162627 | } | ||
| 162628 | } | ||
| 162629 | return 0; | ||
| 162630 | } | ||
| 162631 | |||
| 162632 | /* | ||
| 162633 | ** Structure passed to the whereIsCoveringIndex Walker callback. | ||
| 162634 | */ | ||
| 162635 | typedef struct CoveringIndexCheck CoveringIndexCheck; | ||
| 162636 | struct CoveringIndexCheck { | ||
| 162637 | Index *pIdx; /* The index */ | ||
| 162638 | int iTabCur; /* Cursor number for the corresponding table */ | ||
| 162639 | u8 bExpr; /* Uses an indexed expression */ | ||
| 162640 | u8 bUnidx; /* Uses an unindexed column not within an indexed expr */ | ||
| 162641 | }; | ||
| 162642 | |||
| 162643 | /* | ||
| 162644 | ** Information passed in is pWalk->u.pCovIdxCk. Call it pCk. | ||
| 162645 | ** | ||
| 162646 | ** If the Expr node references the table with cursor pCk->iTabCur, then | ||
| 162647 | ** make sure that column is covered by the index pCk->pIdx. We know that | ||
| 162648 | ** all columns less than 63 (really BMS-1) are covered, so we don't need | ||
| 162649 | ** to check them. But we do need to check any column at 63 or greater. | ||
| 162650 | ** | ||
| 162651 | ** If the index does not cover the column, then set pWalk->eCode to | ||
| 162652 | ** non-zero and return WRC_Abort to stop the search. | ||
| 162653 | ** | ||
| 162654 | ** If this node does not disprove that the index can be a covering index, | ||
| 162655 | ** then just return WRC_Continue, to continue the search. | ||
| 162656 | ** | ||
| 162657 | ** If pCk->pIdx contains indexed expressions and one of those expressions | ||
| 162658 | ** matches pExpr, then prune the search. | ||
| 162659 | */ | ||
| 162660 | static int whereIsCoveringIndexWalkCallback(Walker *pWalk, Expr *pExpr){ | ||
| 162661 | int i; /* Loop counter */ | ||
| 162662 | const Index *pIdx; /* The index of interest */ | ||
| 162663 | const i16 *aiColumn; /* Columns contained in the index */ | ||
| 162664 | u16 nColumn; /* Number of columns in the index */ | ||
| 162665 | CoveringIndexCheck *pCk; /* Info about this search */ | ||
| 162666 | |||
| 162667 | pCk = pWalk->u.pCovIdxCk; | ||
| 162668 | pIdx = pCk->pIdx; | ||
| 162669 | if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) ){ | ||
| 162670 | /* if( pExpr->iColumn<(BMS-1) && pIdx->bHasExpr==0 ) return WRC_Continue;*/ | ||
| 162671 | if( pExpr->iTable!=pCk->iTabCur ) return WRC_Continue; | ||
| 162672 | pIdx = pWalk->u.pCovIdxCk->pIdx; | ||
| 162673 | aiColumn = pIdx->aiColumn; | ||
| 162674 | nColumn = pIdx->nColumn; | ||
| 162675 | for(i=0; i<nColumn; i++){ | ||
| 162676 | if( aiColumn[i]==pExpr->iColumn ) return WRC_Continue; | ||
| 162677 | } | ||
| 162678 | pCk->bUnidx = 1; | ||
| 162679 | return WRC_Abort; | ||
| 162680 | }else if( pIdx->bHasExpr | ||
| 162681 | && exprIsCoveredByIndex(pExpr, pIdx, pWalk->u.pCovIdxCk->iTabCur) ){ | ||
| 162682 | pCk->bExpr = 1; | ||
| 162683 | return WRC_Prune; | ||
| 162684 | } | ||
| 162685 | return WRC_Continue; | ||
| 162686 | } | ||
| 162687 | |||
| 162688 | |||
| 162689 | /* | ||
| 162690 | ** pIdx is an index that covers all of the low-number columns used by | ||
| 162691 | ** pWInfo->pSelect (columns from 0 through 62) or an index that has | ||
| 162692 | ** expressions terms. Hence, we cannot determine whether or not it is | ||
| 162693 | ** a covering index by using the colUsed bitmasks. We have to do a search | ||
| 162694 | ** to see if the index is covering. This routine does that search. | ||
| 162695 | ** | ||
| 162696 | ** The return value is one of these: | ||
| 162697 | ** | ||
| 162698 | ** 0 The index is definitely not a covering index | ||
| 162699 | ** | ||
| 162700 | ** WHERE_IDX_ONLY The index is definitely a covering index | ||
| 162701 | ** | ||
| 162702 | ** WHERE_EXPRIDX The index is likely a covering index, but it is | ||
| 162703 | ** difficult to determine precisely because of the | ||
| 162704 | ** expressions that are indexed. Score it as a | ||
| 162705 | ** covering index, but still keep the main table open | ||
| 162706 | ** just in case we need it. | ||
| 162707 | ** | ||
| 162708 | ** This routine is an optimization. It is always safe to return zero. | ||
| 162709 | ** But returning one of the other two values when zero should have been | ||
| 162710 | ** returned can lead to incorrect bytecode and assertion faults. | ||
| 162711 | */ | ||
| 162712 | static SQLITE_NOINLINE u32 whereIsCoveringIndex( | ||
| 162713 | WhereInfo *pWInfo, /* The WHERE clause context */ | ||
| 162714 | Index *pIdx, /* Index that is being tested */ | ||
| 162715 | int iTabCur /* Cursor for the table being indexed */ | ||
| 162716 | ){ | ||
| 162717 | int i, rc; | ||
| 162718 | struct CoveringIndexCheck ck; | ||
| 162719 | Walker w; | ||
| 162720 | if( pWInfo->pSelect==0 ){ | ||
| 162721 | /* We don't have access to the full query, so we cannot check to see | ||
| 162722 | ** if pIdx is covering. Assume it is not. */ | ||
| 162723 | return 0; | ||
| 162724 | } | ||
| 162725 | if( pIdx->bHasExpr==0 ){ | ||
| 162726 | for(i=0; i<pIdx->nColumn; i++){ | ||
| 162727 | if( pIdx->aiColumn[i]>=BMS-1 ) break; | ||
| 162728 | } | ||
| 162729 | if( i>=pIdx->nColumn ){ | ||
| 162730 | /* pIdx does not index any columns greater than 62, but we know from | ||
| 162731 | ** colMask that columns greater than 62 are used, so this is not a | ||
| 162732 | ** covering index */ | ||
| 162733 | return 0; | ||
| 162734 | } | ||
| 162735 | } | ||
| 162736 | ck.pIdx = pIdx; | ||
| 162737 | ck.iTabCur = iTabCur; | ||
| 162738 | ck.bExpr = 0; | ||
| 162739 | ck.bUnidx = 0; | ||
| 162740 | memset(&w, 0, sizeof(w)); | ||
| 162741 | w.xExprCallback = whereIsCoveringIndexWalkCallback; | ||
| 162742 | w.xSelectCallback = sqlite3SelectWalkNoop; | ||
| 162743 | w.u.pCovIdxCk = &ck; | ||
| 162744 | sqlite3WalkSelect(&w, pWInfo->pSelect); | ||
| 162745 | if( ck.bUnidx ){ | ||
| 162746 | rc = 0; | ||
| 162747 | }else if( ck.bExpr ){ | ||
| 162748 | rc = WHERE_EXPRIDX; | ||
| 162749 | }else{ | ||
| 162750 | rc = WHERE_IDX_ONLY; | ||
| 162751 | } | ||
| 162752 | return rc; | ||
| 162753 | } | ||
| 162754 | |||
| 162755 | /* | ||
| 157252 | ** Add all WhereLoop objects for a single table of the join where the table | 162756 | ** Add all WhereLoop objects for a single table of the join where the table |
| 157253 | ** is identified by pBuilder->pNew->iTab. That table is guaranteed to be | 162757 | ** is identified by pBuilder->pNew->iTab. That table is guaranteed to be |
| 157254 | ** a b-tree table, not a virtual table. | 162758 | ** a b-tree table, not a virtual table. |
| @@ -157286,7 +162790,7 @@ static int whereUsablePartialIndex( | |||
| 157286 | */ | 162790 | */ |
| 157287 | static int whereLoopAddBtree( | 162791 | static int whereLoopAddBtree( |
| 157288 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ | 162792 | WhereLoopBuilder *pBuilder, /* WHERE clause information */ |
| 157289 | Bitmask mPrereq /* Extra prerequesites for using this table */ | 162793 | Bitmask mPrereq /* Extra prerequisites for using this table */ |
| 157290 | ){ | 162794 | ){ |
| 157291 | WhereInfo *pWInfo; /* WHERE analysis context */ | 162795 | WhereInfo *pWInfo; /* WHERE analysis context */ |
| 157292 | Index *pProbe; /* An index we are evaluating */ | 162796 | Index *pProbe; /* An index we are evaluating */ |
| @@ -157330,7 +162834,7 @@ static int whereLoopAddBtree( | |||
| 157330 | sPk.aiRowLogEst = aiRowEstPk; | 162834 | sPk.aiRowLogEst = aiRowEstPk; |
| 157331 | sPk.onError = OE_Replace; | 162835 | sPk.onError = OE_Replace; |
| 157332 | sPk.pTable = pTab; | 162836 | sPk.pTable = pTab; |
| 157333 | sPk.szIdxRow = pTab->szTabRow; | 162837 | sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */ |
| 157334 | sPk.idxType = SQLITE_IDXTYPE_IPK; | 162838 | sPk.idxType = SQLITE_IDXTYPE_IPK; |
| 157335 | aiRowEstPk[0] = pTab->nRowLogEst; | 162839 | aiRowEstPk[0] = pTab->nRowLogEst; |
| 157336 | aiRowEstPk[1] = 0; | 162840 | aiRowEstPk[1] = 0; |
| @@ -157381,7 +162885,8 @@ static int whereLoopAddBtree( | |||
| 157381 | if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ | 162885 | if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ |
| 157382 | pNew->rSetup += 28; | 162886 | pNew->rSetup += 28; |
| 157383 | }else{ | 162887 | }else{ |
| 157384 | pNew->rSetup -= 10; | 162888 | pNew->rSetup -= 25; /* Greatly reduced setup cost for auto indexes |
| 162889 | ** on ephemeral materializations of views */ | ||
| 157385 | } | 162890 | } |
| 157386 | ApplyCostMultiplier(pNew->rSetup, pTab->costMult); | 162891 | ApplyCostMultiplier(pNew->rSetup, pTab->costMult); |
| 157387 | if( pNew->rSetup<0 ) pNew->rSetup = 0; | 162892 | if( pNew->rSetup<0 ) pNew->rSetup = 0; |
| @@ -157450,6 +162955,9 @@ static int whereLoopAddBtree( | |||
| 157450 | #else | 162955 | #else |
| 157451 | pNew->rRun = rSize + 16; | 162956 | pNew->rRun = rSize + 16; |
| 157452 | #endif | 162957 | #endif |
| 162958 | if( IsView(pTab) || (pTab->tabFlags & TF_Ephemeral)!=0 ){ | ||
| 162959 | pNew->wsFlags |= WHERE_VIEWSCAN; | ||
| 162960 | } | ||
| 157453 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); | 162961 | ApplyCostMultiplier(pNew->rRun, pTab->costMult); |
| 157454 | whereLoopOutputAdjust(pWC, pNew, rSize); | 162962 | whereLoopOutputAdjust(pWC, pNew, rSize); |
| 157455 | rc = whereLoopInsert(pBuilder, pNew); | 162963 | rc = whereLoopInsert(pBuilder, pNew); |
| @@ -157458,11 +162966,38 @@ static int whereLoopAddBtree( | |||
| 157458 | }else{ | 162966 | }else{ |
| 157459 | Bitmask m; | 162967 | Bitmask m; |
| 157460 | if( pProbe->isCovering ){ | 162968 | if( pProbe->isCovering ){ |
| 157461 | pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; | ||
| 157462 | m = 0; | 162969 | m = 0; |
| 162970 | pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; | ||
| 157463 | }else{ | 162971 | }else{ |
| 157464 | m = pSrc->colUsed & pProbe->colNotIdxed; | 162972 | m = pSrc->colUsed & pProbe->colNotIdxed; |
| 157465 | pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; | 162973 | pNew->wsFlags = WHERE_INDEXED; |
| 162974 | if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ | ||
| 162975 | u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); | ||
| 162976 | if( isCov==0 ){ | ||
| 162977 | WHERETRACE(0x200, | ||
| 162978 | ("-> %s is not a covering index" | ||
| 162979 | " according to whereIsCoveringIndex()\n", pProbe->zName)); | ||
| 162980 | assert( m!=0 ); | ||
| 162981 | }else{ | ||
| 162982 | m = 0; | ||
| 162983 | pNew->wsFlags |= isCov; | ||
| 162984 | if( isCov & WHERE_IDX_ONLY ){ | ||
| 162985 | WHERETRACE(0x200, | ||
| 162986 | ("-> %s is a covering expression index" | ||
| 162987 | " according to whereIsCoveringIndex()\n", pProbe->zName)); | ||
| 162988 | }else{ | ||
| 162989 | assert( isCov==WHERE_EXPRIDX ); | ||
| 162990 | WHERETRACE(0x200, | ||
| 162991 | ("-> %s might be a covering expression index" | ||
| 162992 | " according to whereIsCoveringIndex()\n", pProbe->zName)); | ||
| 162993 | } | ||
| 162994 | } | ||
| 162995 | }else if( m==0 ){ | ||
| 162996 | WHERETRACE(0x200, | ||
| 162997 | ("-> %s a covering index according to bitmasks\n", | ||
| 162998 | pProbe->zName, m==0 ? "is" : "is not")); | ||
| 162999 | pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; | ||
| 163000 | } | ||
| 157466 | } | 163001 | } |
| 157467 | 163002 | ||
| 157468 | /* Full scan via index */ | 163003 | /* Full scan via index */ |
| @@ -157635,7 +163170,7 @@ static int whereLoopAddVirtualOne( | |||
| 157635 | ** that the particular combination of parameters provided is unusable. | 163170 | ** that the particular combination of parameters provided is unusable. |
| 157636 | ** Make no entries in the loop table. | 163171 | ** Make no entries in the loop table. |
| 157637 | */ | 163172 | */ |
| 157638 | WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n")); | 163173 | WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); |
| 157639 | return SQLITE_OK; | 163174 | return SQLITE_OK; |
| 157640 | } | 163175 | } |
| 157641 | return rc; | 163176 | return rc; |
| @@ -157746,7 +163281,7 @@ static int whereLoopAddVirtualOne( | |||
| 157746 | sqlite3_free(pNew->u.vtab.idxStr); | 163281 | sqlite3_free(pNew->u.vtab.idxStr); |
| 157747 | pNew->u.vtab.needFree = 0; | 163282 | pNew->u.vtab.needFree = 0; |
| 157748 | } | 163283 | } |
| 157749 | WHERETRACE(0xffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", | 163284 | WHERETRACE(0xffffffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", |
| 157750 | *pbIn, (sqlite3_uint64)mPrereq, | 163285 | *pbIn, (sqlite3_uint64)mPrereq, |
| 157751 | (sqlite3_uint64)(pNew->prereq & ~mPrereq))); | 163286 | (sqlite3_uint64)(pNew->prereq & ~mPrereq))); |
| 157752 | 163287 | ||
| @@ -157762,7 +163297,7 @@ static int whereLoopAddVirtualOne( | |||
| 157762 | ** | 163297 | ** |
| 157763 | ** Return a pointer to the collation name: | 163298 | ** Return a pointer to the collation name: |
| 157764 | ** | 163299 | ** |
| 157765 | ** 1. If there is an explicit COLLATE operator on the constaint, return it. | 163300 | ** 1. If there is an explicit COLLATE operator on the constraint, return it. |
| 157766 | ** | 163301 | ** |
| 157767 | ** 2. Else, if the column has an alternative collation, return that. | 163302 | ** 2. Else, if the column has an alternative collation, return that. |
| 157768 | ** | 163303 | ** |
| @@ -157847,32 +163382,27 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ | |||
| 157847 | return pHidden->eDistinct; | 163382 | return pHidden->eDistinct; |
| 157848 | } | 163383 | } |
| 157849 | 163384 | ||
| 157850 | #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ | ||
| 157851 | && !defined(SQLITE_OMIT_VIRTUALTABLE) | ||
| 157852 | /* | 163385 | /* |
| 157853 | ** Cause the prepared statement that is associated with a call to | 163386 | ** Cause the prepared statement that is associated with a call to |
| 157854 | ** xBestIndex to potentiall use all schemas. If the statement being | 163387 | ** xBestIndex to potentially use all schemas. If the statement being |
| 157855 | ** prepared is read-only, then just start read transactions on all | 163388 | ** prepared is read-only, then just start read transactions on all |
| 157856 | ** schemas. But if this is a write operation, start writes on all | 163389 | ** schemas. But if this is a write operation, start writes on all |
| 157857 | ** schemas. | 163390 | ** schemas. |
| 157858 | ** | 163391 | ** |
| 157859 | ** This is used by the (built-in) sqlite_dbpage virtual table. | 163392 | ** This is used by the (built-in) sqlite_dbpage virtual table. |
| 157860 | */ | 163393 | */ |
| 157861 | SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info *pIdxInfo){ | 163394 | SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse *pParse){ |
| 157862 | HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; | ||
| 157863 | Parse *pParse = pHidden->pParse; | ||
| 157864 | int nDb = pParse->db->nDb; | 163395 | int nDb = pParse->db->nDb; |
| 157865 | int i; | 163396 | int i; |
| 157866 | for(i=0; i<nDb; i++){ | 163397 | for(i=0; i<nDb; i++){ |
| 157867 | sqlite3CodeVerifySchema(pParse, i); | 163398 | sqlite3CodeVerifySchema(pParse, i); |
| 157868 | } | 163399 | } |
| 157869 | if( pParse->writeMask ){ | 163400 | if( DbMaskNonZero(pParse->writeMask) ){ |
| 157870 | for(i=0; i<nDb; i++){ | 163401 | for(i=0; i<nDb; i++){ |
| 157871 | sqlite3BeginWriteOperation(pParse, 0, i); | 163402 | sqlite3BeginWriteOperation(pParse, 0, i); |
| 157872 | } | 163403 | } |
| 157873 | } | 163404 | } |
| 157874 | } | 163405 | } |
| 157875 | #endif | ||
| 157876 | 163406 | ||
| 157877 | /* | 163407 | /* |
| 157878 | ** Add all WhereLoop objects for a table of the join identified by | 163408 | ** Add all WhereLoop objects for a table of the join identified by |
| @@ -157938,7 +163468,7 @@ static int whereLoopAddVirtual( | |||
| 157938 | 163468 | ||
| 157939 | /* First call xBestIndex() with all constraints usable. */ | 163469 | /* First call xBestIndex() with all constraints usable. */ |
| 157940 | WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); | 163470 | WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); |
| 157941 | WHERETRACE(0x40, (" VirtualOne: all usable\n")); | 163471 | WHERETRACE(0x800, (" VirtualOne: all usable\n")); |
| 157942 | rc = whereLoopAddVirtualOne( | 163472 | rc = whereLoopAddVirtualOne( |
| 157943 | pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry | 163473 | pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry |
| 157944 | ); | 163474 | ); |
| @@ -157963,7 +163493,7 @@ static int whereLoopAddVirtual( | |||
| 157963 | /* If the plan produced by the earlier call uses an IN(...) term, call | 163493 | /* If the plan produced by the earlier call uses an IN(...) term, call |
| 157964 | ** xBestIndex again, this time with IN(...) terms disabled. */ | 163494 | ** xBestIndex again, this time with IN(...) terms disabled. */ |
| 157965 | if( bIn ){ | 163495 | if( bIn ){ |
| 157966 | WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n")); | 163496 | WHERETRACE(0x800, (" VirtualOne: all usable w/o IN\n")); |
| 157967 | rc = whereLoopAddVirtualOne( | 163497 | rc = whereLoopAddVirtualOne( |
| 157968 | pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0); | 163498 | pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0); |
| 157969 | assert( bIn==0 ); | 163499 | assert( bIn==0 ); |
| @@ -157989,7 +163519,7 @@ static int whereLoopAddVirtual( | |||
| 157989 | mPrev = mNext; | 163519 | mPrev = mNext; |
| 157990 | if( mNext==ALLBITS ) break; | 163520 | if( mNext==ALLBITS ) break; |
| 157991 | if( mNext==mBest || mNext==mBestNoIn ) continue; | 163521 | if( mNext==mBest || mNext==mBestNoIn ) continue; |
| 157992 | WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n", | 163522 | WHERETRACE(0x800, (" VirtualOne: mPrev=%04llx mNext=%04llx\n", |
| 157993 | (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext)); | 163523 | (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext)); |
| 157994 | rc = whereLoopAddVirtualOne( | 163524 | rc = whereLoopAddVirtualOne( |
| 157995 | pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0); | 163525 | pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0); |
| @@ -158003,7 +163533,7 @@ static int whereLoopAddVirtual( | |||
| 158003 | ** that requires no source tables at all (i.e. one guaranteed to be | 163533 | ** that requires no source tables at all (i.e. one guaranteed to be |
| 158004 | ** usable), make a call here with all source tables disabled */ | 163534 | ** usable), make a call here with all source tables disabled */ |
| 158005 | if( rc==SQLITE_OK && seenZero==0 ){ | 163535 | if( rc==SQLITE_OK && seenZero==0 ){ |
| 158006 | WHERETRACE(0x40, (" VirtualOne: all disabled\n")); | 163536 | WHERETRACE(0x800, (" VirtualOne: all disabled\n")); |
| 158007 | rc = whereLoopAddVirtualOne( | 163537 | rc = whereLoopAddVirtualOne( |
| 158008 | pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0); | 163538 | pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0); |
| 158009 | if( bIn==0 ) seenZeroNoIN = 1; | 163539 | if( bIn==0 ) seenZeroNoIN = 1; |
| @@ -158013,7 +163543,7 @@ static int whereLoopAddVirtual( | |||
| 158013 | ** that requires no source tables at all and does not use an IN(...) | 163543 | ** that requires no source tables at all and does not use an IN(...) |
| 158014 | ** operator, make a final call to obtain one here. */ | 163544 | ** operator, make a final call to obtain one here. */ |
| 158015 | if( rc==SQLITE_OK && seenZeroNoIN==0 ){ | 163545 | if( rc==SQLITE_OK && seenZeroNoIN==0 ){ |
| 158016 | WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n")); | 163546 | WHERETRACE(0x800, (" VirtualOne: all disabled and w/o IN\n")); |
| 158017 | rc = whereLoopAddVirtualOne( | 163547 | rc = whereLoopAddVirtualOne( |
| 158018 | pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); | 163548 | pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); |
| 158019 | } | 163549 | } |
| @@ -158069,7 +163599,7 @@ static int whereLoopAddOr( | |||
| 158069 | sSubBuild = *pBuilder; | 163599 | sSubBuild = *pBuilder; |
| 158070 | sSubBuild.pOrSet = &sCur; | 163600 | sSubBuild.pOrSet = &sCur; |
| 158071 | 163601 | ||
| 158072 | WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm)); | 163602 | WHERETRACE(0x400, ("Begin processing OR-clause %p\n", pTerm)); |
| 158073 | for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){ | 163603 | for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){ |
| 158074 | if( (pOrTerm->eOperator & WO_AND)!=0 ){ | 163604 | if( (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 158075 | sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; | 163605 | sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; |
| @@ -158086,9 +163616,9 @@ static int whereLoopAddOr( | |||
| 158086 | } | 163616 | } |
| 158087 | sCur.n = 0; | 163617 | sCur.n = 0; |
| 158088 | #ifdef WHERETRACE_ENABLED | 163618 | #ifdef WHERETRACE_ENABLED |
| 158089 | WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", | 163619 | WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", |
| 158090 | (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); | 163620 | (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); |
| 158091 | if( sqlite3WhereTrace & 0x400 ){ | 163621 | if( sqlite3WhereTrace & 0x20000 ){ |
| 158092 | sqlite3WhereClausePrint(sSubBuild.pWC); | 163622 | sqlite3WhereClausePrint(sSubBuild.pWC); |
| 158093 | } | 163623 | } |
| 158094 | #endif | 163624 | #endif |
| @@ -158103,8 +163633,6 @@ static int whereLoopAddOr( | |||
| 158103 | if( rc==SQLITE_OK ){ | 163633 | if( rc==SQLITE_OK ){ |
| 158104 | rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); | 163634 | rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); |
| 158105 | } | 163635 | } |
| 158106 | assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0 | ||
| 158107 | || rc==SQLITE_NOMEM ); | ||
| 158108 | testcase( rc==SQLITE_NOMEM && sCur.n>0 ); | 163636 | testcase( rc==SQLITE_NOMEM && sCur.n>0 ); |
| 158109 | testcase( rc==SQLITE_DONE ); | 163637 | testcase( rc==SQLITE_DONE ); |
| 158110 | if( sCur.n==0 ){ | 163638 | if( sCur.n==0 ){ |
| @@ -158150,7 +163678,7 @@ static int whereLoopAddOr( | |||
| 158150 | pNew->prereq = sSum.a[i].prereq; | 163678 | pNew->prereq = sSum.a[i].prereq; |
| 158151 | rc = whereLoopInsert(pBuilder, pNew); | 163679 | rc = whereLoopInsert(pBuilder, pNew); |
| 158152 | } | 163680 | } |
| 158153 | WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm)); | 163681 | WHERETRACE(0x400, ("End processing OR-clause %p\n", pTerm)); |
| 158154 | } | 163682 | } |
| 158155 | } | 163683 | } |
| 158156 | return rc; | 163684 | return rc; |
| @@ -158176,7 +163704,13 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ | |||
| 158176 | 163704 | ||
| 158177 | /* Loop over the tables in the join, from left to right */ | 163705 | /* Loop over the tables in the join, from left to right */ |
| 158178 | pNew = pBuilder->pNew; | 163706 | pNew = pBuilder->pNew; |
| 158179 | whereLoopInit(pNew); | 163707 | |
| 163708 | /* Verify that pNew has already been initialized */ | ||
| 163709 | assert( pNew->nLTerm==0 ); | ||
| 163710 | assert( pNew->wsFlags==0 ); | ||
| 163711 | assert( pNew->nLSlot>=ArraySize(pNew->aLTermSpace) ); | ||
| 163712 | assert( pNew->aLTerm!=0 ); | ||
| 163713 | |||
| 158180 | pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; | 163714 | pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; |
| 158181 | for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){ | 163715 | for(iTab=0, pItem=pTabList->a; pItem<pEnd; iTab++, pItem++){ |
| 158182 | Bitmask mUnusable = 0; | 163716 | Bitmask mUnusable = 0; |
| @@ -158492,8 +164026,8 @@ static i8 wherePathSatisfiesOrderBy( | |||
| 158492 | if( pOBExpr->iTable!=iCur ) continue; | 164026 | if( pOBExpr->iTable!=iCur ) continue; |
| 158493 | if( pOBExpr->iColumn!=iColumn ) continue; | 164027 | if( pOBExpr->iColumn!=iColumn ) continue; |
| 158494 | }else{ | 164028 | }else{ |
| 158495 | Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr; | 164029 | Expr *pIxExpr = pIndex->aColExpr->a[j].pExpr; |
| 158496 | if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){ | 164030 | if( sqlite3ExprCompareSkip(pOBExpr, pIxExpr, iCur) ){ |
| 158497 | continue; | 164031 | continue; |
| 158498 | } | 164032 | } |
| 158499 | } | 164033 | } |
| @@ -158625,37 +164159,56 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ | |||
| 158625 | ** order. | 164159 | ** order. |
| 158626 | */ | 164160 | */ |
| 158627 | static LogEst whereSortingCost( | 164161 | static LogEst whereSortingCost( |
| 158628 | WhereInfo *pWInfo, | 164162 | WhereInfo *pWInfo, /* Query planning context */ |
| 158629 | LogEst nRow, | 164163 | LogEst nRow, /* Estimated number of rows to sort */ |
| 158630 | int nOrderBy, | 164164 | int nOrderBy, /* Number of ORDER BY clause terms */ |
| 158631 | int nSorted | 164165 | int nSorted /* Number of initial ORDER BY terms naturally in order */ |
| 158632 | ){ | 164166 | ){ |
| 158633 | /* TUNING: Estimated cost of a full external sort, where N is | 164167 | /* Estimated cost of a full external sort, where N is |
| 158634 | ** the number of rows to sort is: | 164168 | ** the number of rows to sort is: |
| 158635 | ** | 164169 | ** |
| 158636 | ** cost = (3.0 * N * log(N)). | 164170 | ** cost = (K * N * log(N)). |
| 158637 | ** | 164171 | ** |
| 158638 | ** Or, if the order-by clause has X terms but only the last Y | 164172 | ** Or, if the order-by clause has X terms but only the last Y |
| 158639 | ** terms are out of order, then block-sorting will reduce the | 164173 | ** terms are out of order, then block-sorting will reduce the |
| 158640 | ** sorting cost to: | 164174 | ** sorting cost to: |
| 158641 | ** | 164175 | ** |
| 158642 | ** cost = (3.0 * N * log(N)) * (Y/X) | 164176 | ** cost = (K * N * log(N)) * (Y/X) |
| 164177 | ** | ||
| 164178 | ** The constant K is at least 2.0 but will be larger if there are a | ||
| 164179 | ** large number of columns to be sorted, as the sorting time is | ||
| 164180 | ** proportional to the amount of content to be sorted. The algorithm | ||
| 164181 | ** does not currently distinguish between fat columns (BLOBs and TEXTs) | ||
| 164182 | ** and skinny columns (INTs). It just uses the number of columns as | ||
| 164183 | ** an approximation for the row width. | ||
| 158643 | ** | 164184 | ** |
| 158644 | ** The (Y/X) term is implemented using stack variable rScale | 164185 | ** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort |
| 158645 | ** below. | 164186 | ** is built using OP_IdxInsert and OP_Sort rather than with OP_SorterInsert. |
| 158646 | */ | 164187 | */ |
| 158647 | LogEst rScale, rSortCost; | 164188 | LogEst rSortCost, nCol; |
| 158648 | assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); | 164189 | assert( pWInfo->pSelect!=0 ); |
| 158649 | rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; | 164190 | assert( pWInfo->pSelect->pEList!=0 ); |
| 158650 | rSortCost = nRow + rScale + 16; | 164191 | /* TUNING: sorting cost proportional to the number of output columns: */ |
| 164192 | nCol = sqlite3LogEst((pWInfo->pSelect->pEList->nExpr+59)/30); | ||
| 164193 | rSortCost = nRow + nCol; | ||
| 164194 | if( nSorted>0 ){ | ||
| 164195 | /* Scale the result by (Y/X) */ | ||
| 164196 | rSortCost += sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; | ||
| 164197 | } | ||
| 158651 | 164198 | ||
| 158652 | /* Multiple by log(M) where M is the number of output rows. | 164199 | /* Multiple by log(M) where M is the number of output rows. |
| 158653 | ** Use the LIMIT for M if it is smaller. Or if this sort is for | 164200 | ** Use the LIMIT for M if it is smaller. Or if this sort is for |
| 158654 | ** a DISTINCT operator, M will be the number of distinct output | 164201 | ** a DISTINCT operator, M will be the number of distinct output |
| 158655 | ** rows, so fudge it downwards a bit. | 164202 | ** rows, so fudge it downwards a bit. |
| 158656 | */ | 164203 | */ |
| 158657 | if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){ | 164204 | if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){ |
| 158658 | nRow = pWInfo->iLimit; | 164205 | rSortCost += 10; /* TUNING: Extra 2.0x if using LIMIT */ |
| 164206 | if( nSorted!=0 ){ | ||
| 164207 | rSortCost += 6; /* TUNING: Extra 1.5x if also using partial sort */ | ||
| 164208 | } | ||
| 164209 | if( pWInfo->iLimit<nRow ){ | ||
| 164210 | nRow = pWInfo->iLimit; | ||
| 164211 | } | ||
| 158659 | }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){ | 164212 | }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){ |
| 158660 | /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT | 164213 | /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT |
| 158661 | ** reduces the number of output rows by a factor of 2 */ | 164214 | ** reduces the number of output rows by a factor of 2 */ |
| @@ -158681,7 +164234,6 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 158681 | int mxChoice; /* Maximum number of simultaneous paths tracked */ | 164234 | int mxChoice; /* Maximum number of simultaneous paths tracked */ |
| 158682 | int nLoop; /* Number of terms in the join */ | 164235 | int nLoop; /* Number of terms in the join */ |
| 158683 | Parse *pParse; /* Parsing context */ | 164236 | Parse *pParse; /* Parsing context */ |
| 158684 | sqlite3 *db; /* The database connection */ | ||
| 158685 | int iLoop; /* Loop counter over the terms of the join */ | 164237 | int iLoop; /* Loop counter over the terms of the join */ |
| 158686 | int ii, jj; /* Loop counters */ | 164238 | int ii, jj; /* Loop counters */ |
| 158687 | int mxI = 0; /* Index of next entry to replace */ | 164239 | int mxI = 0; /* Index of next entry to replace */ |
| @@ -158700,14 +164252,14 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 158700 | int nSpace; /* Bytes of space allocated at pSpace */ | 164252 | int nSpace; /* Bytes of space allocated at pSpace */ |
| 158701 | 164253 | ||
| 158702 | pParse = pWInfo->pParse; | 164254 | pParse = pWInfo->pParse; |
| 158703 | db = pParse->db; | ||
| 158704 | nLoop = pWInfo->nLevel; | 164255 | nLoop = pWInfo->nLevel; |
| 158705 | /* TUNING: For simple queries, only the best path is tracked. | 164256 | /* TUNING: For simple queries, only the best path is tracked. |
| 158706 | ** For 2-way joins, the 5 best paths are followed. | 164257 | ** For 2-way joins, the 5 best paths are followed. |
| 158707 | ** For joins of 3 or more tables, track the 10 best paths */ | 164258 | ** For joins of 3 or more tables, track the 10 best paths */ |
| 158708 | mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); | 164259 | mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); |
| 158709 | assert( nLoop<=pWInfo->pTabList->nSrc ); | 164260 | assert( nLoop<=pWInfo->pTabList->nSrc ); |
| 158710 | WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst)); | 164261 | WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", |
| 164262 | nRowEst, pParse->nQueryLoop)); | ||
| 158711 | 164263 | ||
| 158712 | /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this | 164264 | /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this |
| 158713 | ** case the purpose of this call is to estimate the number of rows returned | 164265 | ** case the purpose of this call is to estimate the number of rows returned |
| @@ -158723,7 +164275,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 158723 | /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ | 164275 | /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ |
| 158724 | nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; | 164276 | nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; |
| 158725 | nSpace += sizeof(LogEst) * nOrderBy; | 164277 | nSpace += sizeof(LogEst) * nOrderBy; |
| 158726 | pSpace = sqlite3DbMallocRawNN(db, nSpace); | 164278 | pSpace = sqlite3StackAllocRawNN(pParse->db, nSpace); |
| 158727 | if( pSpace==0 ) return SQLITE_NOMEM_BKPT; | 164279 | if( pSpace==0 ) return SQLITE_NOMEM_BKPT; |
| 158728 | aTo = (WherePath*)pSpace; | 164280 | aTo = (WherePath*)pSpace; |
| 158729 | aFrom = aTo+mxChoice; | 164281 | aFrom = aTo+mxChoice; |
| @@ -158773,9 +164325,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 158773 | LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ | 164325 | LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ |
| 158774 | LogEst rCost; /* Cost of path (pFrom+pWLoop) */ | 164326 | LogEst rCost; /* Cost of path (pFrom+pWLoop) */ |
| 158775 | LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */ | 164327 | LogEst rUnsorted; /* Unsorted cost of (pFrom+pWLoop) */ |
| 158776 | i8 isOrdered = pFrom->isOrdered; /* isOrdered for (pFrom+pWLoop) */ | 164328 | i8 isOrdered; /* isOrdered for (pFrom+pWLoop) */ |
| 158777 | Bitmask maskNew; /* Mask of src visited by (..) */ | 164329 | Bitmask maskNew; /* Mask of src visited by (..) */ |
| 158778 | Bitmask revMask = 0; /* Mask of rev-order loops for (..) */ | 164330 | Bitmask revMask; /* Mask of rev-order loops for (..) */ |
| 158779 | 164331 | ||
| 158780 | if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; | 164332 | if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; |
| 158781 | if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; | 164333 | if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; |
| @@ -158794,7 +164346,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 158794 | rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); | 164346 | rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); |
| 158795 | nOut = pFrom->nRow + pWLoop->nOut; | 164347 | nOut = pFrom->nRow + pWLoop->nOut; |
| 158796 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; | 164348 | maskNew = pFrom->maskLoop | pWLoop->maskSelf; |
| 164349 | isOrdered = pFrom->isOrdered; | ||
| 158797 | if( isOrdered<0 ){ | 164350 | if( isOrdered<0 ){ |
| 164351 | revMask = 0; | ||
| 158798 | isOrdered = wherePathSatisfiesOrderBy(pWInfo, | 164352 | isOrdered = wherePathSatisfiesOrderBy(pWInfo, |
| 158799 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, | 164353 | pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, |
| 158800 | iLoop, pWLoop, &revMask); | 164354 | iLoop, pWLoop, &revMask); |
| @@ -158807,11 +164361,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 158807 | pWInfo, nRowEst, nOrderBy, isOrdered | 164361 | pWInfo, nRowEst, nOrderBy, isOrdered |
| 158808 | ); | 164362 | ); |
| 158809 | } | 164363 | } |
| 158810 | /* TUNING: Add a small extra penalty (5) to sorting as an | 164364 | /* TUNING: Add a small extra penalty (3) to sorting as an |
| 158811 | ** extra encouragment to the query planner to select a plan | 164365 | ** extra encouragement to the query planner to select a plan |
| 158812 | ** where the rows emerge in the correct order without any sorting | 164366 | ** where the rows emerge in the correct order without any sorting |
| 158813 | ** required. */ | 164367 | ** required. */ |
| 158814 | rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; | 164368 | rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 3; |
| 158815 | 164369 | ||
| 158816 | WHERETRACE(0x002, | 164370 | WHERETRACE(0x002, |
| 158817 | ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", | 164371 | ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", |
| @@ -158822,6 +164376,14 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 158822 | rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */ | 164376 | rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */ |
| 158823 | } | 164377 | } |
| 158824 | 164378 | ||
| 164379 | /* TUNING: A full-scan of a VIEW or subquery in the outer loop | ||
| 164380 | ** is not so bad. */ | ||
| 164381 | if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 && nLoop>1 ){ | ||
| 164382 | rCost += -10; | ||
| 164383 | nOut += -30; | ||
| 164384 | WHERETRACE(0x80,("VIEWSCAN cost reduction for %c\n",pWLoop->cId)); | ||
| 164385 | } | ||
| 164386 | |||
| 158825 | /* Check to see if pWLoop should be added to the set of | 164387 | /* Check to see if pWLoop should be added to the set of |
| 158826 | ** mxChoice best-so-far paths. | 164388 | ** mxChoice best-so-far paths. |
| 158827 | ** | 164389 | ** |
| @@ -158972,7 +164534,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 158972 | 164534 | ||
| 158973 | if( nFrom==0 ){ | 164535 | if( nFrom==0 ){ |
| 158974 | sqlite3ErrorMsg(pParse, "no query solution"); | 164536 | sqlite3ErrorMsg(pParse, "no query solution"); |
| 158975 | sqlite3DbFreeNN(db, pSpace); | 164537 | sqlite3StackFreeNN(pParse->db, pSpace); |
| 158976 | return SQLITE_ERROR; | 164538 | return SQLITE_ERROR; |
| 158977 | } | 164539 | } |
| 158978 | 164540 | ||
| @@ -159008,6 +164570,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 159008 | if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ | 164570 | if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ |
| 159009 | pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; | 164571 | pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; |
| 159010 | } | 164572 | } |
| 164573 | if( pWInfo->pSelect->pOrderBy | ||
| 164574 | && pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){ | ||
| 164575 | pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr; | ||
| 164576 | } | ||
| 159011 | }else{ | 164577 | }else{ |
| 159012 | pWInfo->revMask = pFrom->revLoop; | 164578 | pWInfo->revMask = pFrom->revLoop; |
| 159013 | if( pWInfo->nOBSat<=0 ){ | 164579 | if( pWInfo->nOBSat<=0 ){ |
| @@ -159054,7 +164620,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ | |||
| 159054 | pWInfo->nRowOut = pFrom->nRow; | 164620 | pWInfo->nRowOut = pFrom->nRow; |
| 159055 | 164621 | ||
| 159056 | /* Free temporary memory and return success */ | 164622 | /* Free temporary memory and return success */ |
| 159057 | sqlite3DbFreeNN(db, pSpace); | 164623 | sqlite3StackFreeNN(pParse->db, pSpace); |
| 159058 | return SQLITE_OK; | 164624 | return SQLITE_OK; |
| 159059 | } | 164625 | } |
| 159060 | 164626 | ||
| @@ -159152,7 +164718,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ | |||
| 159152 | pLoop->cId = '0'; | 164718 | pLoop->cId = '0'; |
| 159153 | #endif | 164719 | #endif |
| 159154 | #ifdef WHERETRACE_ENABLED | 164720 | #ifdef WHERETRACE_ENABLED |
| 159155 | if( sqlite3WhereTrace ){ | 164721 | if( sqlite3WhereTrace & 0x02 ){ |
| 159156 | sqlite3DebugPrintf("whereShortCut() used to compute solution\n"); | 164722 | sqlite3DebugPrintf("whereShortCut() used to compute solution\n"); |
| 159157 | } | 164723 | } |
| 159158 | #endif | 164724 | #endif |
| @@ -159219,6 +164785,13 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ | |||
| 159219 | ** at most a single row. | 164785 | ** at most a single row. |
| 159220 | ** 4) The table must not be referenced by any part of the query apart | 164786 | ** 4) The table must not be referenced by any part of the query apart |
| 159221 | ** from its own USING or ON clause. | 164787 | ** from its own USING or ON clause. |
| 164788 | ** 5) The table must not have an inner-join ON or USING clause if there is | ||
| 164789 | ** a RIGHT JOIN anywhere in the query. Otherwise the ON/USING clause | ||
| 164790 | ** might move from the right side to the left side of the RIGHT JOIN. | ||
| 164791 | ** Note: Due to (2), this condition can only arise if the table is | ||
| 164792 | ** the right-most table of a subquery that was flattened into the | ||
| 164793 | ** main query and that subquery was the right-hand operand of an | ||
| 164794 | ** inner join that held an ON or USING clause. | ||
| 159222 | ** | 164795 | ** |
| 159223 | ** For example, given: | 164796 | ** For example, given: |
| 159224 | ** | 164797 | ** |
| @@ -159244,6 +164817,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( | |||
| 159244 | ){ | 164817 | ){ |
| 159245 | int i; | 164818 | int i; |
| 159246 | Bitmask tabUsed; | 164819 | Bitmask tabUsed; |
| 164820 | int hasRightJoin; | ||
| 159247 | 164821 | ||
| 159248 | /* Preconditions checked by the caller */ | 164822 | /* Preconditions checked by the caller */ |
| 159249 | assert( pWInfo->nLevel>=2 ); | 164823 | assert( pWInfo->nLevel>=2 ); |
| @@ -159258,6 +164832,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( | |||
| 159258 | if( pWInfo->pOrderBy ){ | 164832 | if( pWInfo->pOrderBy ){ |
| 159259 | tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); | 164833 | tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); |
| 159260 | } | 164834 | } |
| 164835 | hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0; | ||
| 159261 | for(i=pWInfo->nLevel-1; i>=1; i--){ | 164836 | for(i=pWInfo->nLevel-1; i>=1; i--){ |
| 159262 | WhereTerm *pTerm, *pEnd; | 164837 | WhereTerm *pTerm, *pEnd; |
| 159263 | SrcItem *pItem; | 164838 | SrcItem *pItem; |
| @@ -159280,9 +164855,15 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( | |||
| 159280 | break; | 164855 | break; |
| 159281 | } | 164856 | } |
| 159282 | } | 164857 | } |
| 164858 | if( hasRightJoin | ||
| 164859 | && ExprHasProperty(pTerm->pExpr, EP_InnerON) | ||
| 164860 | && pTerm->pExpr->w.iJoin==pItem->iCursor | ||
| 164861 | ){ | ||
| 164862 | break; /* restriction (5) */ | ||
| 164863 | } | ||
| 159283 | } | 164864 | } |
| 159284 | if( pTerm<pEnd ) continue; | 164865 | if( pTerm<pEnd ) continue; |
| 159285 | WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId)); | 164866 | WHERETRACE(0xffffffff, ("-> drop loop %c not used\n", pLoop->cId)); |
| 159286 | notReady &= ~pLoop->maskSelf; | 164867 | notReady &= ~pLoop->maskSelf; |
| 159287 | for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){ | 164868 | for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){ |
| 159288 | if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ | 164869 | if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){ |
| @@ -159321,28 +164902,27 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( | |||
| 159321 | const WhereInfo *pWInfo | 164902 | const WhereInfo *pWInfo |
| 159322 | ){ | 164903 | ){ |
| 159323 | int i; | 164904 | int i; |
| 159324 | LogEst nSearch; | 164905 | LogEst nSearch = 0; |
| 159325 | 164906 | ||
| 159326 | assert( pWInfo->nLevel>=2 ); | 164907 | assert( pWInfo->nLevel>=2 ); |
| 159327 | assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); | 164908 | assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); |
| 159328 | nSearch = pWInfo->a[0].pWLoop->nOut; | 164909 | for(i=0; i<pWInfo->nLevel; i++){ |
| 159329 | for(i=1; i<pWInfo->nLevel; i++){ | ||
| 159330 | WhereLoop *pLoop = pWInfo->a[i].pWLoop; | 164910 | WhereLoop *pLoop = pWInfo->a[i].pWLoop; |
| 159331 | const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); | 164911 | const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); |
| 159332 | if( (pLoop->wsFlags & reqFlags)==reqFlags | 164912 | SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; |
| 164913 | Table *pTab = pItem->pTab; | ||
| 164914 | if( (pTab->tabFlags & TF_HasStat1)==0 ) break; | ||
| 164915 | pTab->tabFlags |= TF_StatsUsed; | ||
| 164916 | if( i>=1 | ||
| 164917 | && (pLoop->wsFlags & reqFlags)==reqFlags | ||
| 159333 | /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ | 164918 | /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ |
| 159334 | && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) | 164919 | && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) |
| 159335 | ){ | 164920 | ){ |
| 159336 | SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; | 164921 | if( nSearch > pTab->nRowLogEst ){ |
| 159337 | Table *pTab = pItem->pTab; | ||
| 159338 | pTab->tabFlags |= TF_StatsUsed; | ||
| 159339 | if( nSearch > pTab->nRowLogEst | ||
| 159340 | && (pTab->tabFlags & TF_HasStat1)!=0 | ||
| 159341 | ){ | ||
| 159342 | testcase( pItem->fg.jointype & JT_LEFT ); | 164922 | testcase( pItem->fg.jointype & JT_LEFT ); |
| 159343 | pLoop->wsFlags |= WHERE_BLOOMFILTER; | 164923 | pLoop->wsFlags |= WHERE_BLOOMFILTER; |
| 159344 | pLoop->wsFlags &= ~WHERE_IDX_ONLY; | 164924 | pLoop->wsFlags &= ~WHERE_IDX_ONLY; |
| 159345 | WHERETRACE(0xffff, ( | 164925 | WHERETRACE(0xffffffff, ( |
| 159346 | "-> use Bloom-filter on loop %c because there are ~%.1e " | 164926 | "-> use Bloom-filter on loop %c because there are ~%.1e " |
| 159347 | "lookups into %s which has only ~%.1e rows\n", | 164927 | "lookups into %s which has only ~%.1e rows\n", |
| 159348 | pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, | 164928 | pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, |
| @@ -159354,6 +164934,108 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( | |||
| 159354 | } | 164934 | } |
| 159355 | 164935 | ||
| 159356 | /* | 164936 | /* |
| 164937 | ** This is an sqlite3ParserAddCleanup() callback that is invoked to | ||
| 164938 | ** free the Parse->pIdxEpr list when the Parse object is destroyed. | ||
| 164939 | */ | ||
| 164940 | static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ | ||
| 164941 | Parse *pParse = (Parse*)pObject; | ||
| 164942 | while( pParse->pIdxEpr!=0 ){ | ||
| 164943 | IndexedExpr *p = pParse->pIdxEpr; | ||
| 164944 | pParse->pIdxEpr = p->pIENext; | ||
| 164945 | sqlite3ExprDelete(db, p->pExpr); | ||
| 164946 | sqlite3DbFreeNN(db, p); | ||
| 164947 | } | ||
| 164948 | } | ||
| 164949 | |||
| 164950 | /* | ||
| 164951 | ** The index pIdx is used by a query and contains one or more expressions. | ||
| 164952 | ** In other words pIdx is an index on an expression. iIdxCur is the cursor | ||
| 164953 | ** number for the index and iDataCur is the cursor number for the corresponding | ||
| 164954 | ** table. | ||
| 164955 | ** | ||
| 164956 | ** This routine adds IndexedExpr entries to the Parse->pIdxEpr field for | ||
| 164957 | ** each of the expressions in the index so that the expression code generator | ||
| 164958 | ** will know to replace occurrences of the indexed expression with | ||
| 164959 | ** references to the corresponding column of the index. | ||
| 164960 | */ | ||
| 164961 | static SQLITE_NOINLINE void whereAddIndexedExpr( | ||
| 164962 | Parse *pParse, /* Add IndexedExpr entries to pParse->pIdxEpr */ | ||
| 164963 | Index *pIdx, /* The index-on-expression that contains the expressions */ | ||
| 164964 | int iIdxCur, /* Cursor number for pIdx */ | ||
| 164965 | SrcItem *pTabItem /* The FROM clause entry for the table */ | ||
| 164966 | ){ | ||
| 164967 | int i; | ||
| 164968 | IndexedExpr *p; | ||
| 164969 | Table *pTab; | ||
| 164970 | assert( pIdx->bHasExpr ); | ||
| 164971 | pTab = pIdx->pTable; | ||
| 164972 | for(i=0; i<pIdx->nColumn; i++){ | ||
| 164973 | Expr *pExpr; | ||
| 164974 | int j = pIdx->aiColumn[i]; | ||
| 164975 | int bMaybeNullRow; | ||
| 164976 | if( j==XN_EXPR ){ | ||
| 164977 | pExpr = pIdx->aColExpr->a[i].pExpr; | ||
| 164978 | testcase( pTabItem->fg.jointype & JT_LEFT ); | ||
| 164979 | testcase( pTabItem->fg.jointype & JT_RIGHT ); | ||
| 164980 | testcase( pTabItem->fg.jointype & JT_LTORJ ); | ||
| 164981 | bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; | ||
| 164982 | }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ | ||
| 164983 | pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); | ||
| 164984 | bMaybeNullRow = 0; | ||
| 164985 | }else{ | ||
| 164986 | continue; | ||
| 164987 | } | ||
| 164988 | if( sqlite3ExprIsConstant(pExpr) ) continue; | ||
| 164989 | p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); | ||
| 164990 | if( p==0 ) break; | ||
| 164991 | p->pIENext = pParse->pIdxEpr; | ||
| 164992 | #ifdef WHERETRACE_ENABLED | ||
| 164993 | if( sqlite3WhereTrace & 0x200 ){ | ||
| 164994 | sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i); | ||
| 164995 | if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr); | ||
| 164996 | } | ||
| 164997 | #endif | ||
| 164998 | p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); | ||
| 164999 | p->iDataCur = pTabItem->iCursor; | ||
| 165000 | p->iIdxCur = iIdxCur; | ||
| 165001 | p->iIdxCol = i; | ||
| 165002 | p->bMaybeNullRow = bMaybeNullRow; | ||
| 165003 | if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){ | ||
| 165004 | p->aff = pIdx->zColAff[i]; | ||
| 165005 | } | ||
| 165006 | #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS | ||
| 165007 | p->zIdxName = pIdx->zName; | ||
| 165008 | #endif | ||
| 165009 | pParse->pIdxEpr = p; | ||
| 165010 | if( p->pIENext==0 ){ | ||
| 165011 | sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse); | ||
| 165012 | } | ||
| 165013 | } | ||
| 165014 | } | ||
| 165015 | |||
| 165016 | /* | ||
| 165017 | ** Set the reverse-scan order mask to one for all tables in the query | ||
| 165018 | ** with the exception of MATERIALIZED common table expressions that have | ||
| 165019 | ** their own internal ORDER BY clauses. | ||
| 165020 | ** | ||
| 165021 | ** This implements the PRAGMA reverse_unordered_selects=ON setting. | ||
| 165022 | ** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER). | ||
| 165023 | */ | ||
| 165024 | static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ | ||
| 165025 | int ii; | ||
| 165026 | for(ii=0; ii<pWInfo->pTabList->nSrc; ii++){ | ||
| 165027 | SrcItem *pItem = &pWInfo->pTabList->a[ii]; | ||
| 165028 | if( !pItem->fg.isCte | ||
| 165029 | || pItem->u2.pCteUse->eM10d!=M10d_Yes | ||
| 165030 | || NEVER(pItem->pSelect==0) | ||
| 165031 | || pItem->pSelect->pOrderBy==0 | ||
| 165032 | ){ | ||
| 165033 | pWInfo->revMask |= MASKBIT(ii); | ||
| 165034 | } | ||
| 165035 | } | ||
| 165036 | } | ||
| 165037 | |||
| 165038 | /* | ||
| 159357 | ** Generate the beginning of the loop used for WHERE clause processing. | 165039 | ** Generate the beginning of the loop used for WHERE clause processing. |
| 159358 | ** The return value is a pointer to an opaque structure that contains | 165040 | ** The return value is a pointer to an opaque structure that contains |
| 159359 | ** information needed to terminate the loop. Later, the calling routine | 165041 | ** information needed to terminate the loop. Later, the calling routine |
| @@ -159411,7 +165093,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( | |||
| 159411 | ** | 165093 | ** |
| 159412 | ** OUTER JOINS | 165094 | ** OUTER JOINS |
| 159413 | ** | 165095 | ** |
| 159414 | ** An outer join of tables t1 and t2 is conceptally coded as follows: | 165096 | ** An outer join of tables t1 and t2 is conceptually coded as follows: |
| 159415 | ** | 165097 | ** |
| 159416 | ** foreach row1 in t1 do | 165098 | ** foreach row1 in t1 do |
| 159417 | ** flag = 0 | 165099 | ** flag = 0 |
| @@ -159447,7 +165129,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159447 | Expr *pWhere, /* The WHERE clause */ | 165129 | Expr *pWhere, /* The WHERE clause */ |
| 159448 | ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ | 165130 | ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ |
| 159449 | ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ | 165131 | ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ |
| 159450 | Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */ | 165132 | Select *pSelect, /* The entire SELECT statement */ |
| 159451 | u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ | 165133 | u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ |
| 159452 | int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number | 165134 | int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number |
| 159453 | ** If WHERE_USE_LIMIT, then the limit amount */ | 165135 | ** If WHERE_USE_LIMIT, then the limit amount */ |
| @@ -159516,7 +165198,9 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159516 | pWInfo->pParse = pParse; | 165198 | pWInfo->pParse = pParse; |
| 159517 | pWInfo->pTabList = pTabList; | 165199 | pWInfo->pTabList = pTabList; |
| 159518 | pWInfo->pOrderBy = pOrderBy; | 165200 | pWInfo->pOrderBy = pOrderBy; |
| 165201 | #if WHERETRACE_ENABLED | ||
| 159519 | pWInfo->pWhere = pWhere; | 165202 | pWInfo->pWhere = pWhere; |
| 165203 | #endif | ||
| 159520 | pWInfo->pResultSet = pResultSet; | 165204 | pWInfo->pResultSet = pResultSet; |
| 159521 | pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; | 165205 | pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; |
| 159522 | pWInfo->nLevel = nTabList; | 165206 | pWInfo->nLevel = nTabList; |
| @@ -159524,9 +165208,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159524 | pWInfo->wctrlFlags = wctrlFlags; | 165208 | pWInfo->wctrlFlags = wctrlFlags; |
| 159525 | pWInfo->iLimit = iAuxArg; | 165209 | pWInfo->iLimit = iAuxArg; |
| 159526 | pWInfo->savedNQueryLoop = pParse->nQueryLoop; | 165210 | pWInfo->savedNQueryLoop = pParse->nQueryLoop; |
| 159527 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 165211 | pWInfo->pSelect = pSelect; |
| 159528 | pWInfo->pLimit = pLimit; | ||
| 159529 | #endif | ||
| 159530 | memset(&pWInfo->nOBSat, 0, | 165212 | memset(&pWInfo->nOBSat, 0, |
| 159531 | offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); | 165213 | offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); |
| 159532 | memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); | 165214 | memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); |
| @@ -159566,7 +165248,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159566 | ** | 165248 | ** |
| 159567 | ** The N-th term of the FROM clause is assigned a bitmask of 1<<N. | 165249 | ** The N-th term of the FROM clause is assigned a bitmask of 1<<N. |
| 159568 | ** | 165250 | ** |
| 159569 | ** The rule of the previous sentence ensures thta if X is the bitmask for | 165251 | ** The rule of the previous sentence ensures that if X is the bitmask for |
| 159570 | ** a table T, then X-1 is the bitmask for all other tables to the left of T. | 165252 | ** a table T, then X-1 is the bitmask for all other tables to the left of T. |
| 159571 | ** Knowing the bitmask for all tables to the left of a left join is | 165253 | ** Knowing the bitmask for all tables to the left of a left join is |
| 159572 | ** important. Ticket #3015. | 165254 | ** important. Ticket #3015. |
| @@ -159595,25 +165277,50 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159595 | 165277 | ||
| 159596 | /* Analyze all of the subexpressions. */ | 165278 | /* Analyze all of the subexpressions. */ |
| 159597 | sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); | 165279 | sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); |
| 159598 | sqlite3WhereAddLimit(&pWInfo->sWC, pLimit); | 165280 | if( pSelect && pSelect->pLimit ){ |
| 165281 | sqlite3WhereAddLimit(&pWInfo->sWC, pSelect); | ||
| 165282 | } | ||
| 159599 | if( pParse->nErr ) goto whereBeginError; | 165283 | if( pParse->nErr ) goto whereBeginError; |
| 159600 | 165284 | ||
| 159601 | /* Special case: WHERE terms that do not refer to any tables in the join | 165285 | /* The False-WHERE-Term-Bypass optimization: |
| 159602 | ** (constant expressions). Evaluate each such term, and jump over all the | 165286 | ** |
| 159603 | ** generated code if the result is not true. | 165287 | ** If there are WHERE terms that are false, then no rows will be output, |
| 165288 | ** so skip over all of the code generated here. | ||
| 165289 | ** | ||
| 165290 | ** Conditions: | ||
| 159604 | ** | 165291 | ** |
| 159605 | ** Do not do this if the expression contains non-deterministic functions | 165292 | ** (1) The WHERE term must not refer to any tables in the join. |
| 159606 | ** that are not within a sub-select. This is not strictly required, but | 165293 | ** (2) The term must not come from an ON clause on the |
| 159607 | ** preserves SQLite's legacy behaviour in the following two cases: | 165294 | ** right-hand side of a LEFT or FULL JOIN. |
| 165295 | ** (3) The term must not come from an ON clause, or there must be | ||
| 165296 | ** no RIGHT or FULL OUTER joins in pTabList. | ||
| 165297 | ** (4) If the expression contains non-deterministic functions | ||
| 165298 | ** that are not within a sub-select. This is not required | ||
| 165299 | ** for correctness but rather to preserves SQLite's legacy | ||
| 165300 | ** behaviour in the following two cases: | ||
| 159608 | ** | 165301 | ** |
| 159609 | ** FROM ... WHERE random()>0; -- eval random() once per row | 165302 | ** WHERE random()>0; -- eval random() once per row |
| 159610 | ** FROM ... WHERE (SELECT random())>0; -- eval random() once overall | 165303 | ** WHERE (SELECT random())>0; -- eval random() just once overall |
| 165304 | ** | ||
| 165305 | ** Note that the Where term need not be a constant in order for this | ||
| 165306 | ** optimization to apply, though it does need to be constant relative to | ||
| 165307 | ** the current subquery (condition 1). The term might include variables | ||
| 165308 | ** from outer queries so that the value of the term changes from one | ||
| 165309 | ** invocation of the current subquery to the next. | ||
| 159611 | */ | 165310 | */ |
| 159612 | for(ii=0; ii<sWLB.pWC->nBase; ii++){ | 165311 | for(ii=0; ii<sWLB.pWC->nBase; ii++){ |
| 159613 | WhereTerm *pT = &sWLB.pWC->a[ii]; | 165312 | WhereTerm *pT = &sWLB.pWC->a[ii]; /* A term of the WHERE clause */ |
| 165313 | Expr *pX; /* The expression of pT */ | ||
| 159614 | if( pT->wtFlags & TERM_VIRTUAL ) continue; | 165314 | if( pT->wtFlags & TERM_VIRTUAL ) continue; |
| 159615 | if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){ | 165315 | pX = pT->pExpr; |
| 159616 | sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL); | 165316 | assert( pX!=0 ); |
| 165317 | assert( pT->prereqAll!=0 || !ExprHasProperty(pX, EP_OuterON) ); | ||
| 165318 | if( pT->prereqAll==0 /* Conditions (1) and (2) */ | ||
| 165319 | && (nTabList==0 || exprIsDeterministic(pX)) /* Condition (4) */ | ||
| 165320 | && !(ExprHasProperty(pX, EP_InnerON) /* Condition (3) */ | ||
| 165321 | && (pTabList->a[0].fg.jointype & JT_LTORJ)!=0 ) | ||
| 165322 | ){ | ||
| 165323 | sqlite3ExprIfFalse(pParse, pX, pWInfo->iBreak, SQLITE_JUMPIFNULL); | ||
| 159617 | pT->wtFlags |= TERM_CODED; | 165324 | pT->wtFlags |= TERM_CODED; |
| 159618 | } | 165325 | } |
| 159619 | } | 165326 | } |
| @@ -159636,13 +165343,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159636 | 165343 | ||
| 159637 | /* Construct the WhereLoop objects */ | 165344 | /* Construct the WhereLoop objects */ |
| 159638 | #if defined(WHERETRACE_ENABLED) | 165345 | #if defined(WHERETRACE_ENABLED) |
| 159639 | if( sqlite3WhereTrace & 0xffff ){ | 165346 | if( sqlite3WhereTrace & 0xffffffff ){ |
| 159640 | sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); | 165347 | sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); |
| 159641 | if( wctrlFlags & WHERE_USE_LIMIT ){ | 165348 | if( wctrlFlags & WHERE_USE_LIMIT ){ |
| 159642 | sqlite3DebugPrintf(", limit: %d", iAuxArg); | 165349 | sqlite3DebugPrintf(", limit: %d", iAuxArg); |
| 159643 | } | 165350 | } |
| 159644 | sqlite3DebugPrintf(")\n"); | 165351 | sqlite3DebugPrintf(")\n"); |
| 159645 | if( sqlite3WhereTrace & 0x100 ){ | 165352 | if( sqlite3WhereTrace & 0x8000 ){ |
| 159646 | Select sSelect; | 165353 | Select sSelect; |
| 159647 | memset(&sSelect, 0, sizeof(sSelect)); | 165354 | memset(&sSelect, 0, sizeof(sSelect)); |
| 159648 | sSelect.selFlags = SF_WhereBegin; | 165355 | sSelect.selFlags = SF_WhereBegin; |
| @@ -159652,10 +165359,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159652 | sSelect.pEList = pResultSet; | 165359 | sSelect.pEList = pResultSet; |
| 159653 | sqlite3TreeViewSelect(0, &sSelect, 0); | 165360 | sqlite3TreeViewSelect(0, &sSelect, 0); |
| 159654 | } | 165361 | } |
| 159655 | } | 165362 | if( sqlite3WhereTrace & 0x4000 ){ /* Display all WHERE clause terms */ |
| 159656 | if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ | 165363 | sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); |
| 159657 | sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); | 165364 | sqlite3WhereClausePrint(sWLB.pWC); |
| 159658 | sqlite3WhereClausePrint(sWLB.pWC); | 165365 | } |
| 159659 | } | 165366 | } |
| 159660 | #endif | 165367 | #endif |
| 159661 | 165368 | ||
| @@ -159671,7 +165378,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159671 | ** loops will be built using the revised truthProb values. */ | 165378 | ** loops will be built using the revised truthProb values. */ |
| 159672 | if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ | 165379 | if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ |
| 159673 | WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); | 165380 | WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); |
| 159674 | WHERETRACE(0xffff, | 165381 | WHERETRACE(0xffffffff, |
| 159675 | ("**** Redo all loop computations due to" | 165382 | ("**** Redo all loop computations due to" |
| 159676 | " TERM_HIGHTRUTH changes ****\n")); | 165383 | " TERM_HIGHTRUTH changes ****\n")); |
| 159677 | while( pWInfo->pLoops ){ | 165384 | while( pWInfo->pLoops ){ |
| @@ -159692,8 +165399,9 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159692 | if( db->mallocFailed ) goto whereBeginError; | 165399 | if( db->mallocFailed ) goto whereBeginError; |
| 159693 | } | 165400 | } |
| 159694 | } | 165401 | } |
| 165402 | assert( pWInfo->pTabList!=0 ); | ||
| 159695 | if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ | 165403 | if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ |
| 159696 | pWInfo->revMask = ALLBITS; | 165404 | whereReverseScanOrder(pWInfo); |
| 159697 | } | 165405 | } |
| 159698 | if( pParse->nErr ){ | 165406 | if( pParse->nErr ){ |
| 159699 | goto whereBeginError; | 165407 | goto whereBeginError; |
| @@ -159757,11 +165465,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159757 | } | 165465 | } |
| 159758 | 165466 | ||
| 159759 | #if defined(WHERETRACE_ENABLED) | 165467 | #if defined(WHERETRACE_ENABLED) |
| 159760 | if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ | 165468 | if( sqlite3WhereTrace & 0x4000 ){ /* Display all terms of the WHERE clause */ |
| 159761 | sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); | 165469 | sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); |
| 159762 | sqlite3WhereClausePrint(sWLB.pWC); | 165470 | sqlite3WhereClausePrint(sWLB.pWC); |
| 159763 | } | 165471 | } |
| 159764 | WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); | 165472 | WHERETRACE(0xffffffff,("*** Optimizer Finished ***\n")); |
| 159765 | #endif | 165473 | #endif |
| 159766 | pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; | 165474 | pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; |
| 159767 | 165475 | ||
| @@ -159793,6 +165501,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159793 | 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) | 165501 | 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) |
| 159794 | && !IsVirtual(pTabList->a[0].pTab) | 165502 | && !IsVirtual(pTabList->a[0].pTab) |
| 159795 | && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) | 165503 | && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) |
| 165504 | && OptimizationEnabled(db, SQLITE_OnePass) | ||
| 159796 | )){ | 165505 | )){ |
| 159797 | pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; | 165506 | pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; |
| 159798 | if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ | 165507 | if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ |
| @@ -159856,7 +165565,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159856 | assert( n<=pTab->nCol ); | 165565 | assert( n<=pTab->nCol ); |
| 159857 | } | 165566 | } |
| 159858 | #ifdef SQLITE_ENABLE_CURSOR_HINTS | 165567 | #ifdef SQLITE_ENABLE_CURSOR_HINTS |
| 159859 | if( pLoop->u.btree.pIndex!=0 ){ | 165568 | if( pLoop->u.btree.pIndex!=0 && (pTab->tabFlags & TF_WithoutRowid)==0 ){ |
| 159860 | sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); | 165569 | sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); |
| 159861 | }else | 165570 | }else |
| 159862 | #endif | 165571 | #endif |
| @@ -159898,6 +165607,9 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159898 | op = OP_ReopenIdx; | 165607 | op = OP_ReopenIdx; |
| 159899 | }else{ | 165608 | }else{ |
| 159900 | iIndexCur = pParse->nTab++; | 165609 | iIndexCur = pParse->nTab++; |
| 165610 | if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ | ||
| 165611 | whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); | ||
| 165612 | } | ||
| 159901 | } | 165613 | } |
| 159902 | pLevel->iIdxCur = iIndexCur; | 165614 | pLevel->iIdxCur = iIndexCur; |
| 159903 | assert( pIx!=0 ); | 165615 | assert( pIx!=0 ); |
| @@ -159990,11 +165702,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 159990 | sqlite3VdbeJumpHere(v, iOnce); | 165702 | sqlite3VdbeJumpHere(v, iOnce); |
| 159991 | } | 165703 | } |
| 159992 | } | 165704 | } |
| 165705 | assert( pTabList == pWInfo->pTabList ); | ||
| 159993 | if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ | 165706 | if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ |
| 159994 | if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ | 165707 | if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ |
| 159995 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX | 165708 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
| 159996 | constructAutomaticIndex(pParse, &pWInfo->sWC, | 165709 | constructAutomaticIndex(pParse, &pWInfo->sWC, notReady, pLevel); |
| 159997 | &pTabList->a[pLevel->iFrom], notReady, pLevel); | ||
| 159998 | #endif | 165710 | #endif |
| 159999 | }else{ | 165711 | }else{ |
| 160000 | sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady); | 165712 | sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady); |
| @@ -160020,8 +165732,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( | |||
| 160020 | /* Jump here if malloc fails */ | 165732 | /* Jump here if malloc fails */ |
| 160021 | whereBeginError: | 165733 | whereBeginError: |
| 160022 | if( pWInfo ){ | 165734 | if( pWInfo ){ |
| 160023 | testcase( pWInfo->pExprMods!=0 ); | ||
| 160024 | whereUndoExprMods(pWInfo); | ||
| 160025 | pParse->nQueryLoop = pWInfo->savedNQueryLoop; | 165735 | pParse->nQueryLoop = pWInfo->savedNQueryLoop; |
| 160026 | whereInfoFree(db, pWInfo); | 165736 | whereInfoFree(db, pWInfo); |
| 160027 | } | 165737 | } |
| @@ -160240,7 +165950,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 160240 | } | 165950 | } |
| 160241 | 165951 | ||
| 160242 | assert( pWInfo->nLevel<=pTabList->nSrc ); | 165952 | assert( pWInfo->nLevel<=pTabList->nSrc ); |
| 160243 | if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo); | ||
| 160244 | for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){ | 165953 | for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){ |
| 160245 | int k, last; | 165954 | int k, last; |
| 160246 | VdbeOp *pOp, *pLastOp; | 165955 | VdbeOp *pOp, *pLastOp; |
| @@ -160294,10 +166003,28 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 160294 | }else{ | 166003 | }else{ |
| 160295 | last = pWInfo->iEndWhere; | 166004 | last = pWInfo->iEndWhere; |
| 160296 | } | 166005 | } |
| 166006 | if( pIdx->bHasExpr ){ | ||
| 166007 | IndexedExpr *p = pParse->pIdxEpr; | ||
| 166008 | while( p ){ | ||
| 166009 | if( p->iIdxCur==pLevel->iIdxCur ){ | ||
| 166010 | #ifdef WHERETRACE_ENABLED | ||
| 166011 | if( sqlite3WhereTrace & 0x200 ){ | ||
| 166012 | sqlite3DebugPrintf("Disable pParse->pIdxEpr term {%d,%d}\n", | ||
| 166013 | p->iIdxCur, p->iIdxCol); | ||
| 166014 | if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(p->pExpr); | ||
| 166015 | } | ||
| 166016 | #endif | ||
| 166017 | p->iDataCur = -1; | ||
| 166018 | p->iIdxCur = -1; | ||
| 166019 | } | ||
| 166020 | p = p->pIENext; | ||
| 166021 | } | ||
| 166022 | } | ||
| 160297 | k = pLevel->addrBody + 1; | 166023 | k = pLevel->addrBody + 1; |
| 160298 | #ifdef SQLITE_DEBUG | 166024 | #ifdef SQLITE_DEBUG |
| 160299 | if( db->flags & SQLITE_VdbeAddopTrace ){ | 166025 | if( db->flags & SQLITE_VdbeAddopTrace ){ |
| 160300 | printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); | 166026 | printf("TRANSLATE cursor %d->%d in opcode range %d..%d\n", |
| 166027 | pLevel->iTabCur, pLevel->iIdxCur, k, last-1); | ||
| 160301 | } | 166028 | } |
| 160302 | /* Proof that the "+1" on the k value above is safe */ | 166029 | /* Proof that the "+1" on the k value above is safe */ |
| 160303 | pOp = sqlite3VdbeGetOp(v, k - 1); | 166030 | pOp = sqlite3VdbeGetOp(v, k - 1); |
| @@ -160504,7 +166231,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ | |||
| 160504 | ** | 166231 | ** |
| 160505 | ** These are the same built-in window functions supported by Postgres. | 166232 | ** These are the same built-in window functions supported by Postgres. |
| 160506 | ** Although the behaviour of aggregate window functions (functions that | 166233 | ** Although the behaviour of aggregate window functions (functions that |
| 160507 | ** can be used as either aggregates or window funtions) allows them to | 166234 | ** can be used as either aggregates or window functions) allows them to |
| 160508 | ** be implemented using an API, built-in window functions are much more | 166235 | ** be implemented using an API, built-in window functions are much more |
| 160509 | ** esoteric. Additionally, some window functions (e.g. nth_value()) | 166236 | ** esoteric. Additionally, some window functions (e.g. nth_value()) |
| 160510 | ** may only be implemented by caching the entire partition in memory. | 166237 | ** may only be implemented by caching the entire partition in memory. |
| @@ -161034,7 +166761,7 @@ static Window *windowFind(Parse *pParse, Window *pList, const char *zName){ | |||
| 161034 | ** is the Window object representing the associated OVER clause. This | 166761 | ** is the Window object representing the associated OVER clause. This |
| 161035 | ** function updates the contents of pWin as follows: | 166762 | ** function updates the contents of pWin as follows: |
| 161036 | ** | 166763 | ** |
| 161037 | ** * If the OVER clause refered to a named window (as in "max(x) OVER win"), | 166764 | ** * If the OVER clause referred to a named window (as in "max(x) OVER win"), |
| 161038 | ** search list pList for a matching WINDOW definition, and update pWin | 166765 | ** search list pList for a matching WINDOW definition, and update pWin |
| 161039 | ** accordingly. If no such WINDOW clause can be found, leave an error | 166766 | ** accordingly. If no such WINDOW clause can be found, leave an error |
| 161040 | ** in pParse. | 166767 | ** in pParse. |
| @@ -161172,6 +166899,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ | |||
| 161172 | } | 166899 | } |
| 161173 | /* no break */ deliberate_fall_through | 166900 | /* no break */ deliberate_fall_through |
| 161174 | 166901 | ||
| 166902 | case TK_IF_NULL_ROW: | ||
| 161175 | case TK_AGG_FUNCTION: | 166903 | case TK_AGG_FUNCTION: |
| 161176 | case TK_COLUMN: { | 166904 | case TK_COLUMN: { |
| 161177 | int iCol = -1; | 166905 | int iCol = -1; |
| @@ -161287,7 +167015,6 @@ static ExprList *exprListAppendList( | |||
| 161287 | for(i=0; i<pAppend->nExpr; i++){ | 167015 | for(i=0; i<pAppend->nExpr; i++){ |
| 161288 | sqlite3 *db = pParse->db; | 167016 | sqlite3 *db = pParse->db; |
| 161289 | Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0); | 167017 | Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0); |
| 161290 | assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); | ||
| 161291 | if( db->mallocFailed ){ | 167018 | if( db->mallocFailed ){ |
| 161292 | sqlite3ExprDelete(db, pDup); | 167019 | sqlite3ExprDelete(db, pDup); |
| 161293 | break; | 167020 | break; |
| @@ -161457,7 +167184,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ | |||
| 161457 | pSub = sqlite3SelectNew( | 167184 | pSub = sqlite3SelectNew( |
| 161458 | pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 | 167185 | pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 |
| 161459 | ); | 167186 | ); |
| 161460 | SELECTTRACE(1,pParse,pSub, | 167187 | TREETRACE(0x40,pParse,pSub, |
| 161461 | ("New window-function subquery in FROM clause of (%u/%p)\n", | 167188 | ("New window-function subquery in FROM clause of (%u/%p)\n", |
| 161462 | p->selId, p)); | 167189 | p->selId, p)); |
| 161463 | p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); | 167190 | p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); |
| @@ -161467,6 +167194,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ | |||
| 161467 | if( p->pSrc ){ | 167194 | if( p->pSrc ){ |
| 161468 | Table *pTab2; | 167195 | Table *pTab2; |
| 161469 | p->pSrc->a[0].pSelect = pSub; | 167196 | p->pSrc->a[0].pSelect = pSub; |
| 167197 | p->pSrc->a[0].fg.isCorrelated = 1; | ||
| 161470 | sqlite3SrcListAssignCursors(pParse, p->pSrc); | 167198 | sqlite3SrcListAssignCursors(pParse, p->pSrc); |
| 161471 | pSub->selFlags |= SF_Expanded|SF_OrderByReqd; | 167199 | pSub->selFlags |= SF_Expanded|SF_OrderByReqd; |
| 161472 | pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); | 167200 | pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); |
| @@ -161654,7 +167382,7 @@ SQLITE_PRIVATE Window *sqlite3WindowAssemble( | |||
| 161654 | } | 167382 | } |
| 161655 | 167383 | ||
| 161656 | /* | 167384 | /* |
| 161657 | ** Window *pWin has just been created from a WINDOW clause. Tokne pBase | 167385 | ** Window *pWin has just been created from a WINDOW clause. Token pBase |
| 161658 | ** is the base window. Earlier windows from the same WINDOW clause are | 167386 | ** is the base window. Earlier windows from the same WINDOW clause are |
| 161659 | ** stored in the linked list starting at pWin->pNextWin. This function | 167387 | ** stored in the linked list starting at pWin->pNextWin. This function |
| 161660 | ** either updates *pWin according to the base specification, or else | 167388 | ** either updates *pWin according to the base specification, or else |
| @@ -161960,7 +167688,7 @@ struct WindowCsrAndReg { | |||
| 161960 | ** | 167688 | ** |
| 161961 | ** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING) | 167689 | ** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING) |
| 161962 | ** | 167690 | ** |
| 161963 | ** The windows functions implmentation caches the input rows in a temp | 167691 | ** The windows functions implementation caches the input rows in a temp |
| 161964 | ** table, sorted by "a, b" (it actually populates the cache lazily, and | 167692 | ** table, sorted by "a, b" (it actually populates the cache lazily, and |
| 161965 | ** aggressively removes rows once they are no longer required, but that's | 167693 | ** aggressively removes rows once they are no longer required, but that's |
| 161966 | ** a mere detail). It keeps three cursors open on the temp table. One | 167694 | ** a mere detail). It keeps three cursors open on the temp table. One |
| @@ -162558,10 +168286,9 @@ static void windowCodeRangeTest( | |||
| 162558 | 168286 | ||
| 162559 | /* This block runs if reg1 is not NULL, but reg2 is. */ | 168287 | /* This block runs if reg1 is not NULL, but reg2 is. */ |
| 162560 | sqlite3VdbeJumpHere(v, addr); | 168288 | sqlite3VdbeJumpHere(v, addr); |
| 162561 | sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); | 168289 | sqlite3VdbeAddOp2(v, OP_IsNull, reg2, |
| 162562 | if( op==OP_Gt || op==OP_Ge ){ | 168290 | (op==OP_Gt || op==OP_Ge) ? addrDone : lbl); |
| 162563 | sqlite3VdbeChangeP2(v, -1, addrDone); | 168291 | VdbeCoverage(v); |
| 162564 | } | ||
| 162565 | } | 168292 | } |
| 162566 | 168293 | ||
| 162567 | /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). | 168294 | /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). |
| @@ -162970,7 +168697,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ | |||
| 162970 | ** | 168697 | ** |
| 162971 | ** For the most part, the patterns above are adapted to support UNBOUNDED by | 168698 | ** For the most part, the patterns above are adapted to support UNBOUNDED by |
| 162972 | ** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and | 168699 | ** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and |
| 162973 | ** CURRENT ROW by assuming that it is equivilent to "0 PRECEDING/FOLLOWING". | 168700 | ** CURRENT ROW by assuming that it is equivalent to "0 PRECEDING/FOLLOWING". |
| 162974 | ** This is optimized of course - branches that will never be taken and | 168701 | ** This is optimized of course - branches that will never be taken and |
| 162975 | ** conditions that are always true are omitted from the VM code. The only | 168702 | ** conditions that are always true are omitted from the VM code. The only |
| 162976 | ** exceptional case is: | 168703 | ** exceptional case is: |
| @@ -163249,7 +168976,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( | |||
| 163249 | } | 168976 | } |
| 163250 | 168977 | ||
| 163251 | /* Allocate registers for the array of values from the sub-query, the | 168978 | /* Allocate registers for the array of values from the sub-query, the |
| 163252 | ** samve values in record form, and the rowid used to insert said record | 168979 | ** same values in record form, and the rowid used to insert said record |
| 163253 | ** into the ephemeral table. */ | 168980 | ** into the ephemeral table. */ |
| 163254 | regNew = pParse->nMem+1; | 168981 | regNew = pParse->nMem+1; |
| 163255 | pParse->nMem += nInput; | 168982 | pParse->nMem += nInput; |
| @@ -163333,8 +169060,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( | |||
| 163333 | VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */ | 169060 | VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */ |
| 163334 | VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ | 169061 | VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ |
| 163335 | windowAggFinal(&s, 0); | 169062 | windowAggFinal(&s, 0); |
| 163336 | sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); | 169063 | sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); |
| 163337 | VdbeCoverageNeverTaken(v); | ||
| 163338 | windowReturnOneRow(&s); | 169064 | windowReturnOneRow(&s); |
| 163339 | sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); | 169065 | sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); |
| 163340 | sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); | 169066 | sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); |
| @@ -163346,13 +169072,10 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( | |||
| 163346 | } | 169072 | } |
| 163347 | 169073 | ||
| 163348 | if( pMWin->eStart!=TK_UNBOUNDED ){ | 169074 | if( pMWin->eStart!=TK_UNBOUNDED ){ |
| 163349 | sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1); | 169075 | sqlite3VdbeAddOp1(v, OP_Rewind, s.start.csr); |
| 163350 | VdbeCoverageNeverTaken(v); | ||
| 163351 | } | 169076 | } |
| 163352 | sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); | 169077 | sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); |
| 163353 | VdbeCoverageNeverTaken(v); | 169078 | sqlite3VdbeAddOp1(v, OP_Rewind, s.end.csr); |
| 163354 | sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1); | ||
| 163355 | VdbeCoverageNeverTaken(v); | ||
| 163356 | if( regPeer && pOrderBy ){ | 169079 | if( regPeer && pOrderBy ){ |
| 163357 | sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1); | 169080 | sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1); |
| 163358 | sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1); | 169081 | sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1); |
| @@ -163494,7 +169217,8 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( | |||
| 163494 | /************** End of window.c **********************************************/ | 169217 | /************** End of window.c **********************************************/ |
| 163495 | /************** Begin file parse.c *******************************************/ | 169218 | /************** Begin file parse.c *******************************************/ |
| 163496 | /* This file is automatically generated by Lemon from input grammar | 169219 | /* This file is automatically generated by Lemon from input grammar |
| 163497 | ** source file "parse.y". */ | 169220 | ** source file "parse.y". |
| 169221 | */ | ||
| 163498 | /* | 169222 | /* |
| 163499 | ** 2001-09-15 | 169223 | ** 2001-09-15 |
| 163500 | ** | 169224 | ** |
| @@ -163511,7 +169235,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( | |||
| 163511 | ** The canonical source code to this file ("parse.y") is a Lemon grammar | 169235 | ** The canonical source code to this file ("parse.y") is a Lemon grammar |
| 163512 | ** file that specifies the input grammar and actions to take while parsing. | 169236 | ** file that specifies the input grammar and actions to take while parsing. |
| 163513 | ** That input file is processed by Lemon to generate a C-language | 169237 | ** That input file is processed by Lemon to generate a C-language |
| 163514 | ** implementation of a parser for the given grammer. You might be reading | 169238 | ** implementation of a parser for the given grammar. You might be reading |
| 163515 | ** this comment as part of the translated C-code. Edits should be made | 169239 | ** this comment as part of the translated C-code. Edits should be made |
| 163516 | ** to the original parse.y sources. | 169240 | ** to the original parse.y sources. |
| 163517 | */ | 169241 | */ |
| @@ -164005,18 +169729,18 @@ typedef union { | |||
| 164005 | #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; | 169729 | #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; |
| 164006 | #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; | 169730 | #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; |
| 164007 | #define YYFALLBACK 1 | 169731 | #define YYFALLBACK 1 |
| 164008 | #define YYNSTATE 576 | 169732 | #define YYNSTATE 575 |
| 164009 | #define YYNRULE 405 | 169733 | #define YYNRULE 403 |
| 164010 | #define YYNRULE_WITH_ACTION 342 | 169734 | #define YYNRULE_WITH_ACTION 338 |
| 164011 | #define YYNTOKEN 185 | 169735 | #define YYNTOKEN 185 |
| 164012 | #define YY_MAX_SHIFT 575 | 169736 | #define YY_MAX_SHIFT 574 |
| 164013 | #define YY_MIN_SHIFTREDUCE 835 | 169737 | #define YY_MIN_SHIFTREDUCE 833 |
| 164014 | #define YY_MAX_SHIFTREDUCE 1239 | 169738 | #define YY_MAX_SHIFTREDUCE 1235 |
| 164015 | #define YY_ERROR_ACTION 1240 | 169739 | #define YY_ERROR_ACTION 1236 |
| 164016 | #define YY_ACCEPT_ACTION 1241 | 169740 | #define YY_ACCEPT_ACTION 1237 |
| 164017 | #define YY_NO_ACTION 1242 | 169741 | #define YY_NO_ACTION 1238 |
| 164018 | #define YY_MIN_REDUCE 1243 | 169742 | #define YY_MIN_REDUCE 1239 |
| 164019 | #define YY_MAX_REDUCE 1647 | 169743 | #define YY_MAX_REDUCE 1641 |
| 164020 | /************* End control #defines *******************************************/ | 169744 | /************* End control #defines *******************************************/ |
| 164021 | #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) | 169745 | #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) |
| 164022 | 169746 | ||
| @@ -164083,218 +169807,218 @@ typedef union { | |||
| 164083 | ** yy_default[] Default action for each state. | 169807 | ** yy_default[] Default action for each state. |
| 164084 | ** | 169808 | ** |
| 164085 | *********** Begin parsing tables **********************************************/ | 169809 | *********** Begin parsing tables **********************************************/ |
| 164086 | #define YY_ACTTAB_COUNT (2098) | 169810 | #define YY_ACTTAB_COUNT (2096) |
| 164087 | static const YYACTIONTYPE yy_action[] = { | 169811 | static const YYACTIONTYPE yy_action[] = { |
| 164088 | /* 0 */ 568, 208, 568, 118, 115, 229, 568, 118, 115, 229, | 169812 | /* 0 */ 568, 208, 568, 118, 115, 229, 568, 118, 115, 229, |
| 164089 | /* 10 */ 568, 1314, 377, 1293, 408, 562, 562, 562, 568, 409, | 169813 | /* 10 */ 568, 1310, 377, 1289, 408, 562, 562, 562, 568, 409, |
| 164090 | /* 20 */ 378, 1314, 1276, 41, 41, 41, 41, 208, 1526, 71, | 169814 | /* 20 */ 378, 1310, 1272, 41, 41, 41, 41, 208, 1520, 71, |
| 164091 | /* 30 */ 71, 971, 419, 41, 41, 491, 303, 279, 303, 972, | 169815 | /* 30 */ 71, 969, 419, 41, 41, 491, 303, 279, 303, 970, |
| 164092 | /* 40 */ 397, 71, 71, 125, 126, 80, 1217, 1217, 1050, 1053, | 169816 | /* 40 */ 397, 71, 71, 125, 126, 80, 1210, 1210, 1047, 1050, |
| 164093 | /* 50 */ 1040, 1040, 123, 123, 124, 124, 124, 124, 476, 409, | 169817 | /* 50 */ 1037, 1037, 123, 123, 124, 124, 124, 124, 476, 409, |
| 164094 | /* 60 */ 1241, 1, 1, 575, 2, 1245, 550, 118, 115, 229, | 169818 | /* 60 */ 1237, 1, 1, 574, 2, 1241, 550, 118, 115, 229, |
| 164095 | /* 70 */ 317, 480, 146, 480, 524, 118, 115, 229, 529, 1327, | 169819 | /* 70 */ 317, 480, 146, 480, 524, 118, 115, 229, 529, 1323, |
| 164096 | /* 80 */ 417, 523, 142, 125, 126, 80, 1217, 1217, 1050, 1053, | 169820 | /* 80 */ 417, 523, 142, 125, 126, 80, 1210, 1210, 1047, 1050, |
| 164097 | /* 90 */ 1040, 1040, 123, 123, 124, 124, 124, 124, 118, 115, | 169821 | /* 90 */ 1037, 1037, 123, 123, 124, 124, 124, 124, 118, 115, |
| 164098 | /* 100 */ 229, 327, 122, 122, 122, 122, 121, 121, 120, 120, | 169822 | /* 100 */ 229, 327, 122, 122, 122, 122, 121, 121, 120, 120, |
| 164099 | /* 110 */ 120, 119, 116, 444, 284, 284, 284, 284, 442, 442, | 169823 | /* 110 */ 120, 119, 116, 444, 284, 284, 284, 284, 442, 442, |
| 164100 | /* 120 */ 442, 1567, 376, 1569, 1192, 375, 1163, 565, 1163, 565, | 169824 | /* 120 */ 442, 1559, 376, 1561, 1186, 375, 1157, 565, 1157, 565, |
| 164101 | /* 130 */ 409, 1567, 537, 259, 226, 444, 101, 145, 449, 316, | 169825 | /* 130 */ 409, 1559, 537, 259, 226, 444, 101, 145, 449, 316, |
| 164102 | /* 140 */ 559, 240, 122, 122, 122, 122, 121, 121, 120, 120, | 169826 | /* 140 */ 559, 240, 122, 122, 122, 122, 121, 121, 120, 120, |
| 164103 | /* 150 */ 120, 119, 116, 444, 125, 126, 80, 1217, 1217, 1050, | 169827 | /* 150 */ 120, 119, 116, 444, 125, 126, 80, 1210, 1210, 1047, |
| 164104 | /* 160 */ 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, 142, | 169828 | /* 160 */ 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, 142, |
| 164105 | /* 170 */ 294, 1192, 339, 448, 120, 120, 120, 119, 116, 444, | 169829 | /* 170 */ 294, 1186, 339, 448, 120, 120, 120, 119, 116, 444, |
| 164106 | /* 180 */ 127, 1192, 1193, 1194, 148, 441, 440, 568, 119, 116, | 169830 | /* 180 */ 127, 1186, 1187, 1186, 148, 441, 440, 568, 119, 116, |
| 164107 | /* 190 */ 444, 124, 124, 124, 124, 117, 122, 122, 122, 122, | 169831 | /* 190 */ 444, 124, 124, 124, 124, 117, 122, 122, 122, 122, |
| 164108 | /* 200 */ 121, 121, 120, 120, 120, 119, 116, 444, 454, 113, | 169832 | /* 200 */ 121, 121, 120, 120, 120, 119, 116, 444, 454, 113, |
| 164109 | /* 210 */ 13, 13, 546, 122, 122, 122, 122, 121, 121, 120, | 169833 | /* 210 */ 13, 13, 546, 122, 122, 122, 122, 121, 121, 120, |
| 164110 | /* 220 */ 120, 120, 119, 116, 444, 422, 316, 559, 1192, 1193, | 169834 | /* 220 */ 120, 120, 119, 116, 444, 422, 316, 559, 1186, 1187, |
| 164111 | /* 230 */ 1194, 149, 1224, 409, 1224, 124, 124, 124, 124, 122, | 169835 | /* 230 */ 1186, 149, 1218, 409, 1218, 124, 124, 124, 124, 122, |
| 164112 | /* 240 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, | 169836 | /* 240 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, |
| 164113 | /* 250 */ 444, 465, 342, 1037, 1037, 1051, 1054, 125, 126, 80, | 169837 | /* 250 */ 444, 465, 342, 1034, 1034, 1048, 1051, 125, 126, 80, |
| 164114 | /* 260 */ 1217, 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, | 169838 | /* 260 */ 1210, 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, |
| 164115 | /* 270 */ 124, 124, 1279, 522, 222, 1192, 568, 409, 224, 514, | 169839 | /* 270 */ 124, 124, 1275, 522, 222, 1186, 568, 409, 224, 514, |
| 164116 | /* 280 */ 175, 82, 83, 122, 122, 122, 122, 121, 121, 120, | 169840 | /* 280 */ 175, 82, 83, 122, 122, 122, 122, 121, 121, 120, |
| 164117 | /* 290 */ 120, 120, 119, 116, 444, 1007, 16, 16, 1192, 133, | 169841 | /* 290 */ 120, 120, 119, 116, 444, 1005, 16, 16, 1186, 133, |
| 164118 | /* 300 */ 133, 125, 126, 80, 1217, 1217, 1050, 1053, 1040, 1040, | 169842 | /* 300 */ 133, 125, 126, 80, 1210, 1210, 1047, 1050, 1037, 1037, |
| 164119 | /* 310 */ 123, 123, 124, 124, 124, 124, 122, 122, 122, 122, | 169843 | /* 310 */ 123, 123, 124, 124, 124, 124, 122, 122, 122, 122, |
| 164120 | /* 320 */ 121, 121, 120, 120, 120, 119, 116, 444, 1041, 546, | 169844 | /* 320 */ 121, 121, 120, 120, 120, 119, 116, 444, 1038, 546, |
| 164121 | /* 330 */ 1192, 373, 1192, 1193, 1194, 252, 1434, 399, 504, 501, | 169845 | /* 330 */ 1186, 373, 1186, 1187, 1186, 252, 1429, 399, 504, 501, |
| 164122 | /* 340 */ 500, 111, 560, 566, 4, 926, 926, 433, 499, 340, | 169846 | /* 340 */ 500, 111, 560, 566, 4, 924, 924, 433, 499, 340, |
| 164123 | /* 350 */ 460, 328, 360, 394, 1237, 1192, 1193, 1194, 563, 568, | 169847 | /* 350 */ 460, 328, 360, 394, 1231, 1186, 1187, 1186, 563, 568, |
| 164124 | /* 360 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, | 169848 | /* 360 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, |
| 164125 | /* 370 */ 116, 444, 284, 284, 369, 1580, 1607, 441, 440, 154, | 169849 | /* 370 */ 116, 444, 284, 284, 369, 1572, 1598, 441, 440, 154, |
| 164126 | /* 380 */ 409, 445, 71, 71, 1286, 565, 1221, 1192, 1193, 1194, | 169850 | /* 380 */ 409, 445, 71, 71, 1282, 565, 1215, 1186, 1187, 1186, |
| 164127 | /* 390 */ 85, 1223, 271, 557, 543, 515, 1561, 568, 98, 1222, | 169851 | /* 390 */ 85, 1217, 271, 557, 543, 515, 515, 568, 98, 1216, |
| 164128 | /* 400 */ 6, 1278, 472, 142, 125, 126, 80, 1217, 1217, 1050, | 169852 | /* 400 */ 6, 1274, 472, 142, 125, 126, 80, 1210, 1210, 1047, |
| 164129 | /* 410 */ 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, 550, | 169853 | /* 410 */ 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, 550, |
| 164130 | /* 420 */ 13, 13, 1027, 507, 1224, 1192, 1224, 549, 109, 109, | 169854 | /* 420 */ 13, 13, 1024, 507, 1218, 1186, 1218, 549, 109, 109, |
| 164131 | /* 430 */ 222, 568, 1238, 175, 568, 427, 110, 197, 445, 570, | 169855 | /* 430 */ 222, 568, 1232, 175, 568, 427, 110, 197, 445, 569, |
| 164132 | /* 440 */ 569, 430, 1552, 1017, 325, 551, 1192, 270, 287, 368, | 169856 | /* 440 */ 445, 430, 1546, 1014, 325, 551, 1186, 270, 287, 368, |
| 164133 | /* 450 */ 510, 363, 509, 257, 71, 71, 543, 71, 71, 359, | 169857 | /* 450 */ 510, 363, 509, 257, 71, 71, 543, 71, 71, 359, |
| 164134 | /* 460 */ 316, 559, 1613, 122, 122, 122, 122, 121, 121, 120, | 169858 | /* 460 */ 316, 559, 1604, 122, 122, 122, 122, 121, 121, 120, |
| 164135 | /* 470 */ 120, 120, 119, 116, 444, 1017, 1017, 1019, 1020, 27, | 169859 | /* 470 */ 120, 120, 119, 116, 444, 1014, 1014, 1016, 1017, 27, |
| 164136 | /* 480 */ 284, 284, 1192, 1193, 1194, 1158, 568, 1612, 409, 901, | 169860 | /* 480 */ 284, 284, 1186, 1187, 1186, 1152, 568, 1603, 409, 899, |
| 164137 | /* 490 */ 190, 550, 356, 565, 550, 937, 533, 517, 1158, 516, | 169861 | /* 490 */ 190, 550, 356, 565, 550, 935, 533, 517, 1152, 516, |
| 164138 | /* 500 */ 413, 1158, 552, 1192, 1193, 1194, 568, 544, 1554, 51, | 169862 | /* 500 */ 413, 1152, 552, 1186, 1187, 1186, 568, 544, 544, 51, |
| 164139 | /* 510 */ 51, 214, 125, 126, 80, 1217, 1217, 1050, 1053, 1040, | 169863 | /* 510 */ 51, 214, 125, 126, 80, 1210, 1210, 1047, 1050, 1037, |
| 164140 | /* 520 */ 1040, 123, 123, 124, 124, 124, 124, 1192, 474, 135, | 169864 | /* 520 */ 1037, 123, 123, 124, 124, 124, 124, 1186, 474, 135, |
| 164141 | /* 530 */ 135, 409, 284, 284, 1490, 505, 121, 121, 120, 120, | 169865 | /* 530 */ 135, 409, 284, 284, 1484, 505, 121, 121, 120, 120, |
| 164142 | /* 540 */ 120, 119, 116, 444, 1007, 565, 518, 217, 541, 1561, | 169866 | /* 540 */ 120, 119, 116, 444, 1005, 565, 518, 217, 541, 541, |
| 164143 | /* 550 */ 316, 559, 142, 6, 532, 125, 126, 80, 1217, 1217, | 169867 | /* 550 */ 316, 559, 142, 6, 532, 125, 126, 80, 1210, 1210, |
| 164144 | /* 560 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, | 169868 | /* 560 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, |
| 164145 | /* 570 */ 1555, 122, 122, 122, 122, 121, 121, 120, 120, 120, | 169869 | /* 570 */ 1548, 122, 122, 122, 122, 121, 121, 120, 120, 120, |
| 164146 | /* 580 */ 119, 116, 444, 485, 1192, 1193, 1194, 482, 281, 1267, | 169870 | /* 580 */ 119, 116, 444, 485, 1186, 1187, 1186, 482, 281, 1263, |
| 164147 | /* 590 */ 957, 252, 1192, 373, 504, 501, 500, 1192, 340, 571, | 169871 | /* 590 */ 955, 252, 1186, 373, 504, 501, 500, 1186, 340, 570, |
| 164148 | /* 600 */ 1192, 571, 409, 292, 499, 957, 876, 191, 480, 316, | 169872 | /* 600 */ 1186, 570, 409, 292, 499, 955, 874, 191, 480, 316, |
| 164149 | /* 610 */ 559, 384, 290, 380, 122, 122, 122, 122, 121, 121, | 169873 | /* 610 */ 559, 384, 290, 380, 122, 122, 122, 122, 121, 121, |
| 164150 | /* 620 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217, | 169874 | /* 620 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1210, |
| 164151 | /* 630 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, | 169875 | /* 630 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, |
| 164152 | /* 640 */ 124, 409, 394, 1136, 1192, 869, 100, 284, 284, 1192, | 169876 | /* 640 */ 124, 409, 394, 1132, 1186, 867, 100, 284, 284, 1186, |
| 164153 | /* 650 */ 1193, 1194, 373, 1093, 1192, 1193, 1194, 1192, 1193, 1194, | 169877 | /* 650 */ 1187, 1186, 373, 1089, 1186, 1187, 1186, 1186, 1187, 1186, |
| 164154 | /* 660 */ 565, 455, 32, 373, 233, 125, 126, 80, 1217, 1217, | 169878 | /* 660 */ 565, 455, 32, 373, 233, 125, 126, 80, 1210, 1210, |
| 164155 | /* 670 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, | 169879 | /* 670 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, |
| 164156 | /* 680 */ 1433, 959, 568, 228, 958, 122, 122, 122, 122, 121, | 169880 | /* 680 */ 1428, 957, 568, 228, 956, 122, 122, 122, 122, 121, |
| 164157 | /* 690 */ 121, 120, 120, 120, 119, 116, 444, 1158, 228, 1192, | 169881 | /* 690 */ 121, 120, 120, 120, 119, 116, 444, 1152, 228, 1186, |
| 164158 | /* 700 */ 157, 1192, 1193, 1194, 1553, 13, 13, 301, 957, 1232, | 169882 | /* 700 */ 157, 1186, 1187, 1186, 1547, 13, 13, 301, 955, 1226, |
| 164159 | /* 710 */ 1158, 153, 409, 1158, 373, 1583, 1176, 5, 369, 1580, | 169883 | /* 710 */ 1152, 153, 409, 1152, 373, 1575, 1170, 5, 369, 1572, |
| 164160 | /* 720 */ 429, 1238, 3, 957, 122, 122, 122, 122, 121, 121, | 169884 | /* 720 */ 429, 1232, 3, 955, 122, 122, 122, 122, 121, 121, |
| 164161 | /* 730 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217, | 169885 | /* 730 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1210, |
| 164162 | /* 740 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, | 169886 | /* 740 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, |
| 164163 | /* 750 */ 124, 409, 208, 567, 1192, 1028, 1192, 1193, 1194, 1192, | 169887 | /* 750 */ 124, 409, 208, 567, 1186, 1025, 1186, 1187, 1186, 1186, |
| 164164 | /* 760 */ 388, 852, 155, 1552, 286, 402, 1098, 1098, 488, 568, | 169888 | /* 760 */ 388, 850, 155, 1546, 286, 402, 1094, 1094, 488, 568, |
| 164165 | /* 770 */ 465, 342, 1319, 1319, 1552, 125, 126, 80, 1217, 1217, | 169889 | /* 770 */ 465, 342, 1315, 1315, 1546, 125, 126, 80, 1210, 1210, |
| 164166 | /* 780 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, | 169890 | /* 780 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, |
| 164167 | /* 790 */ 129, 568, 13, 13, 374, 122, 122, 122, 122, 121, | 169891 | /* 790 */ 129, 568, 13, 13, 374, 122, 122, 122, 122, 121, |
| 164168 | /* 800 */ 121, 120, 120, 120, 119, 116, 444, 302, 568, 453, | 169892 | /* 800 */ 121, 120, 120, 120, 119, 116, 444, 302, 568, 453, |
| 164169 | /* 810 */ 528, 1192, 1193, 1194, 13, 13, 1192, 1193, 1194, 1297, | 169893 | /* 810 */ 528, 1186, 1187, 1186, 13, 13, 1186, 1187, 1186, 1293, |
| 164170 | /* 820 */ 463, 1267, 409, 1317, 1317, 1552, 1012, 453, 452, 200, | 169894 | /* 820 */ 463, 1263, 409, 1313, 1313, 1546, 1010, 453, 452, 200, |
| 164171 | /* 830 */ 299, 71, 71, 1265, 122, 122, 122, 122, 121, 121, | 169895 | /* 830 */ 299, 71, 71, 1261, 122, 122, 122, 122, 121, 121, |
| 164172 | /* 840 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217, | 169896 | /* 840 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1210, |
| 164173 | /* 850 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, | 169897 | /* 850 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, |
| 164174 | /* 860 */ 124, 409, 227, 1073, 1158, 284, 284, 419, 312, 278, | 169898 | /* 860 */ 124, 409, 227, 1069, 1152, 284, 284, 419, 312, 278, |
| 164175 | /* 870 */ 278, 285, 285, 1419, 406, 405, 382, 1158, 565, 568, | 169899 | /* 870 */ 278, 285, 285, 1415, 406, 405, 382, 1152, 565, 568, |
| 164176 | /* 880 */ 1158, 1196, 565, 1600, 565, 125, 126, 80, 1217, 1217, | 169900 | /* 880 */ 1152, 1189, 565, 1592, 565, 125, 126, 80, 1210, 1210, |
| 164177 | /* 890 */ 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, 124, | 169901 | /* 890 */ 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, 124, |
| 164178 | /* 900 */ 453, 1482, 13, 13, 1536, 122, 122, 122, 122, 121, | 169902 | /* 900 */ 453, 1476, 13, 13, 1530, 122, 122, 122, 122, 121, |
| 164179 | /* 910 */ 121, 120, 120, 120, 119, 116, 444, 201, 568, 354, | 169903 | /* 910 */ 121, 120, 120, 120, 119, 116, 444, 201, 568, 354, |
| 164180 | /* 920 */ 1586, 575, 2, 1245, 840, 841, 842, 1562, 317, 1212, | 169904 | /* 920 */ 1578, 574, 2, 1241, 838, 839, 840, 1554, 317, 1205, |
| 164181 | /* 930 */ 146, 6, 409, 255, 254, 253, 206, 1327, 9, 1196, | 169905 | /* 930 */ 146, 6, 409, 255, 254, 253, 206, 1323, 9, 1189, |
| 164182 | /* 940 */ 262, 71, 71, 424, 122, 122, 122, 122, 121, 121, | 169906 | /* 940 */ 262, 71, 71, 424, 122, 122, 122, 122, 121, 121, |
| 164183 | /* 950 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1217, | 169907 | /* 950 */ 120, 120, 120, 119, 116, 444, 125, 126, 80, 1210, |
| 164184 | /* 960 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, | 169908 | /* 960 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, |
| 164185 | /* 970 */ 124, 568, 284, 284, 568, 1213, 409, 574, 313, 1245, | 169909 | /* 970 */ 124, 568, 284, 284, 568, 1206, 409, 573, 313, 1241, |
| 164186 | /* 980 */ 349, 1296, 352, 419, 317, 565, 146, 491, 525, 1643, | 169910 | /* 980 */ 349, 1292, 352, 419, 317, 565, 146, 491, 525, 1635, |
| 164187 | /* 990 */ 395, 371, 491, 1327, 70, 70, 1295, 71, 71, 240, | 169911 | /* 990 */ 395, 371, 491, 1323, 70, 70, 1291, 71, 71, 240, |
| 164188 | /* 1000 */ 1325, 104, 80, 1217, 1217, 1050, 1053, 1040, 1040, 123, | 169912 | /* 1000 */ 1321, 104, 80, 1210, 1210, 1047, 1050, 1037, 1037, 123, |
| 164189 | /* 1010 */ 123, 124, 124, 124, 124, 122, 122, 122, 122, 121, | 169913 | /* 1010 */ 123, 124, 124, 124, 124, 122, 122, 122, 122, 121, |
| 164190 | /* 1020 */ 121, 120, 120, 120, 119, 116, 444, 1114, 284, 284, | 169914 | /* 1020 */ 121, 120, 120, 120, 119, 116, 444, 1110, 284, 284, |
| 164191 | /* 1030 */ 428, 448, 1525, 1213, 439, 284, 284, 1489, 1352, 311, | 169915 | /* 1030 */ 428, 448, 1519, 1206, 439, 284, 284, 1483, 1348, 311, |
| 164192 | /* 1040 */ 474, 565, 1115, 971, 491, 491, 217, 1263, 565, 1538, | 169916 | /* 1040 */ 474, 565, 1111, 969, 491, 491, 217, 1259, 565, 1532, |
| 164193 | /* 1050 */ 568, 972, 207, 568, 1027, 240, 383, 1116, 519, 122, | 169917 | /* 1050 */ 568, 970, 207, 568, 1024, 240, 383, 1112, 519, 122, |
| 164194 | /* 1060 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, | 169918 | /* 1060 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, |
| 164195 | /* 1070 */ 444, 1018, 107, 71, 71, 1017, 13, 13, 912, 568, | 169919 | /* 1070 */ 444, 1015, 107, 71, 71, 1014, 13, 13, 910, 568, |
| 164196 | /* 1080 */ 1495, 568, 284, 284, 97, 526, 491, 448, 913, 1326, | 169920 | /* 1080 */ 1489, 568, 284, 284, 97, 526, 491, 448, 911, 1322, |
| 164197 | /* 1090 */ 1322, 545, 409, 284, 284, 565, 151, 209, 1495, 1497, | 169921 | /* 1090 */ 1318, 545, 409, 284, 284, 565, 151, 209, 1489, 1491, |
| 164198 | /* 1100 */ 262, 450, 55, 55, 56, 56, 565, 1017, 1017, 1019, | 169922 | /* 1100 */ 262, 450, 55, 55, 56, 56, 565, 1014, 1014, 1016, |
| 164199 | /* 1110 */ 443, 332, 409, 527, 12, 295, 125, 126, 80, 1217, | 169923 | /* 1110 */ 443, 332, 409, 527, 12, 295, 125, 126, 80, 1210, |
| 164200 | /* 1120 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, | 169924 | /* 1120 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, |
| 164201 | /* 1130 */ 124, 347, 409, 864, 1534, 1213, 125, 126, 80, 1217, | 169925 | /* 1130 */ 124, 347, 409, 862, 1528, 1206, 125, 126, 80, 1210, |
| 164202 | /* 1140 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, | 169926 | /* 1140 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, |
| 164203 | /* 1150 */ 124, 1137, 1641, 474, 1641, 371, 125, 114, 80, 1217, | 169927 | /* 1150 */ 124, 1133, 1633, 474, 1633, 371, 125, 114, 80, 1210, |
| 164204 | /* 1160 */ 1217, 1050, 1053, 1040, 1040, 123, 123, 124, 124, 124, | 169928 | /* 1160 */ 1210, 1047, 1050, 1037, 1037, 123, 123, 124, 124, 124, |
| 164205 | /* 1170 */ 124, 1495, 329, 474, 331, 122, 122, 122, 122, 121, | 169929 | /* 1170 */ 124, 1489, 329, 474, 331, 122, 122, 122, 122, 121, |
| 164206 | /* 1180 */ 121, 120, 120, 120, 119, 116, 444, 203, 1419, 568, | 169930 | /* 1180 */ 121, 120, 120, 120, 119, 116, 444, 203, 1415, 568, |
| 164207 | /* 1190 */ 1294, 864, 464, 1213, 436, 122, 122, 122, 122, 121, | 169931 | /* 1190 */ 1290, 862, 464, 1206, 436, 122, 122, 122, 122, 121, |
| 164208 | /* 1200 */ 121, 120, 120, 120, 119, 116, 444, 553, 1137, 1642, | 169932 | /* 1200 */ 121, 120, 120, 120, 119, 116, 444, 553, 1133, 1634, |
| 164209 | /* 1210 */ 539, 1642, 15, 15, 892, 122, 122, 122, 122, 121, | 169933 | /* 1210 */ 539, 1634, 15, 15, 890, 122, 122, 122, 122, 121, |
| 164210 | /* 1220 */ 121, 120, 120, 120, 119, 116, 444, 568, 298, 538, | 169934 | /* 1220 */ 121, 120, 120, 120, 119, 116, 444, 568, 298, 538, |
| 164211 | /* 1230 */ 1135, 1419, 1559, 1560, 1331, 409, 6, 6, 1169, 1268, | 169935 | /* 1230 */ 1131, 1415, 1552, 1553, 1327, 409, 6, 6, 1163, 1264, |
| 164212 | /* 1240 */ 415, 320, 284, 284, 1419, 508, 565, 525, 300, 457, | 169936 | /* 1240 */ 415, 320, 284, 284, 1415, 508, 565, 525, 300, 457, |
| 164213 | /* 1250 */ 43, 43, 568, 893, 12, 565, 330, 478, 425, 407, | 169937 | /* 1250 */ 43, 43, 568, 891, 12, 565, 330, 478, 425, 407, |
| 164214 | /* 1260 */ 126, 80, 1217, 1217, 1050, 1053, 1040, 1040, 123, 123, | 169938 | /* 1260 */ 126, 80, 1210, 1210, 1047, 1050, 1037, 1037, 123, 123, |
| 164215 | /* 1270 */ 124, 124, 124, 124, 568, 57, 57, 288, 1192, 1419, | 169939 | /* 1270 */ 124, 124, 124, 124, 568, 57, 57, 288, 1186, 1415, |
| 164216 | /* 1280 */ 496, 458, 392, 392, 391, 273, 389, 1135, 1558, 849, | 169940 | /* 1280 */ 496, 458, 392, 392, 391, 273, 389, 1131, 1551, 847, |
| 164217 | /* 1290 */ 1169, 407, 6, 568, 321, 1158, 470, 44, 44, 1557, | 169941 | /* 1290 */ 1163, 407, 6, 568, 321, 1152, 470, 44, 44, 1550, |
| 164218 | /* 1300 */ 1114, 426, 234, 6, 323, 256, 540, 256, 1158, 431, | 169942 | /* 1300 */ 1110, 426, 234, 6, 323, 256, 540, 256, 1152, 431, |
| 164219 | /* 1310 */ 568, 1158, 322, 17, 487, 1115, 58, 58, 122, 122, | 169943 | /* 1310 */ 568, 1152, 322, 17, 487, 1111, 58, 58, 122, 122, |
| 164220 | /* 1320 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 444, | 169944 | /* 1320 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 444, |
| 164221 | /* 1330 */ 1116, 216, 481, 59, 59, 1192, 1193, 1194, 111, 560, | 169945 | /* 1330 */ 1112, 216, 481, 59, 59, 1186, 1187, 1186, 111, 560, |
| 164222 | /* 1340 */ 324, 4, 236, 456, 526, 568, 237, 456, 568, 437, | 169946 | /* 1340 */ 324, 4, 236, 456, 526, 568, 237, 456, 568, 437, |
| 164223 | /* 1350 */ 168, 556, 420, 141, 479, 563, 568, 293, 568, 1095, | 169947 | /* 1350 */ 168, 556, 420, 141, 479, 563, 568, 293, 568, 1091, |
| 164224 | /* 1360 */ 568, 293, 568, 1095, 531, 568, 872, 8, 60, 60, | 169948 | /* 1360 */ 568, 293, 568, 1091, 531, 568, 870, 8, 60, 60, |
| 164225 | /* 1370 */ 235, 61, 61, 568, 414, 568, 414, 568, 445, 62, | 169949 | /* 1370 */ 235, 61, 61, 568, 414, 568, 414, 568, 445, 62, |
| 164226 | /* 1380 */ 62, 45, 45, 46, 46, 47, 47, 199, 49, 49, | 169950 | /* 1380 */ 62, 45, 45, 46, 46, 47, 47, 199, 49, 49, |
| 164227 | /* 1390 */ 557, 568, 359, 568, 100, 486, 50, 50, 63, 63, | 169951 | /* 1390 */ 557, 568, 359, 568, 100, 486, 50, 50, 63, 63, |
| 164228 | /* 1400 */ 64, 64, 561, 415, 535, 410, 568, 1027, 568, 534, | 169952 | /* 1400 */ 64, 64, 561, 415, 535, 410, 568, 1024, 568, 534, |
| 164229 | /* 1410 */ 316, 559, 316, 559, 65, 65, 14, 14, 568, 1027, | 169953 | /* 1410 */ 316, 559, 316, 559, 65, 65, 14, 14, 568, 1024, |
| 164230 | /* 1420 */ 568, 512, 932, 872, 1018, 109, 109, 931, 1017, 66, | 169954 | /* 1420 */ 568, 512, 930, 870, 1015, 109, 109, 929, 1014, 66, |
| 164231 | /* 1430 */ 66, 131, 131, 110, 451, 445, 570, 569, 416, 177, | 169955 | /* 1430 */ 66, 131, 131, 110, 451, 445, 569, 445, 416, 177, |
| 164232 | /* 1440 */ 1017, 132, 132, 67, 67, 568, 467, 568, 932, 471, | 169956 | /* 1440 */ 1014, 132, 132, 67, 67, 568, 467, 568, 930, 471, |
| 164233 | /* 1450 */ 1364, 283, 226, 931, 315, 1363, 407, 568, 459, 407, | 169957 | /* 1450 */ 1360, 283, 226, 929, 315, 1359, 407, 568, 459, 407, |
| 164234 | /* 1460 */ 1017, 1017, 1019, 239, 407, 86, 213, 1350, 52, 52, | 169958 | /* 1460 */ 1014, 1014, 1016, 239, 407, 86, 213, 1346, 52, 52, |
| 164235 | /* 1470 */ 68, 68, 1017, 1017, 1019, 1020, 27, 1585, 1180, 447, | 169959 | /* 1470 */ 68, 68, 1014, 1014, 1016, 1017, 27, 1577, 1174, 447, |
| 164236 | /* 1480 */ 69, 69, 288, 97, 108, 1541, 106, 392, 392, 391, | 169960 | /* 1480 */ 69, 69, 288, 97, 108, 1535, 106, 392, 392, 391, |
| 164237 | /* 1490 */ 273, 389, 568, 879, 849, 883, 568, 111, 560, 466, | 169961 | /* 1490 */ 273, 389, 568, 877, 847, 881, 568, 111, 560, 466, |
| 164238 | /* 1500 */ 4, 568, 152, 30, 38, 568, 1132, 234, 396, 323, | 169962 | /* 1500 */ 4, 568, 152, 30, 38, 568, 1128, 234, 396, 323, |
| 164239 | /* 1510 */ 111, 560, 527, 4, 563, 53, 53, 322, 568, 163, | 169963 | /* 1510 */ 111, 560, 527, 4, 563, 53, 53, 322, 568, 163, |
| 164240 | /* 1520 */ 163, 568, 337, 468, 164, 164, 333, 563, 76, 76, | 169964 | /* 1520 */ 163, 568, 337, 468, 164, 164, 333, 563, 76, 76, |
| 164241 | /* 1530 */ 568, 289, 1514, 568, 31, 1513, 568, 445, 338, 483, | 169965 | /* 1530 */ 568, 289, 1508, 568, 31, 1507, 568, 445, 338, 483, |
| 164242 | /* 1540 */ 100, 54, 54, 344, 72, 72, 296, 236, 1080, 557, | 169966 | /* 1540 */ 100, 54, 54, 344, 72, 72, 296, 236, 1076, 557, |
| 164243 | /* 1550 */ 445, 879, 1360, 134, 134, 168, 73, 73, 141, 161, | 169967 | /* 1550 */ 445, 877, 1356, 134, 134, 168, 73, 73, 141, 161, |
| 164244 | /* 1560 */ 161, 1574, 557, 535, 568, 319, 568, 348, 536, 1009, | 169968 | /* 1560 */ 161, 1566, 557, 535, 568, 319, 568, 348, 536, 1007, |
| 164245 | /* 1570 */ 473, 261, 261, 891, 890, 235, 535, 568, 1027, 568, | 169969 | /* 1570 */ 473, 261, 261, 889, 888, 235, 535, 568, 1024, 568, |
| 164246 | /* 1580 */ 475, 534, 261, 367, 109, 109, 521, 136, 136, 130, | 169970 | /* 1580 */ 475, 534, 261, 367, 109, 109, 521, 136, 136, 130, |
| 164247 | /* 1590 */ 130, 1027, 110, 366, 445, 570, 569, 109, 109, 1017, | 169971 | /* 1590 */ 130, 1024, 110, 366, 445, 569, 445, 109, 109, 1014, |
| 164248 | /* 1600 */ 162, 162, 156, 156, 568, 110, 1080, 445, 570, 569, | 169972 | /* 1600 */ 162, 162, 156, 156, 568, 110, 1076, 445, 569, 445, |
| 164249 | /* 1610 */ 410, 351, 1017, 568, 353, 316, 559, 568, 343, 568, | 169973 | /* 1610 */ 410, 351, 1014, 568, 353, 316, 559, 568, 343, 568, |
| 164250 | /* 1620 */ 100, 497, 357, 258, 100, 898, 899, 140, 140, 355, | 169974 | /* 1620 */ 100, 497, 357, 258, 100, 896, 897, 140, 140, 355, |
| 164251 | /* 1630 */ 1310, 1017, 1017, 1019, 1020, 27, 139, 139, 362, 451, | 169975 | /* 1630 */ 1306, 1014, 1014, 1016, 1017, 27, 139, 139, 362, 451, |
| 164252 | /* 1640 */ 137, 137, 138, 138, 1017, 1017, 1019, 1020, 27, 1180, | 169976 | /* 1640 */ 137, 137, 138, 138, 1014, 1014, 1016, 1017, 27, 1174, |
| 164253 | /* 1650 */ 447, 568, 372, 288, 111, 560, 1021, 4, 392, 392, | 169977 | /* 1650 */ 447, 568, 372, 288, 111, 560, 1018, 4, 392, 392, |
| 164254 | /* 1660 */ 391, 273, 389, 568, 1141, 849, 568, 1076, 568, 258, | 169978 | /* 1660 */ 391, 273, 389, 568, 1137, 847, 568, 1072, 568, 258, |
| 164255 | /* 1670 */ 492, 563, 568, 211, 75, 75, 555, 962, 234, 261, | 169979 | /* 1670 */ 492, 563, 568, 211, 75, 75, 555, 960, 234, 261, |
| 164256 | /* 1680 */ 323, 111, 560, 929, 4, 113, 77, 77, 322, 74, | 169980 | /* 1680 */ 323, 111, 560, 927, 4, 113, 77, 77, 322, 74, |
| 164257 | /* 1690 */ 74, 42, 42, 1373, 445, 48, 48, 1418, 563, 974, | 169981 | /* 1690 */ 74, 42, 42, 1369, 445, 48, 48, 1414, 563, 972, |
| 164258 | /* 1700 */ 975, 1092, 1091, 1092, 1091, 862, 557, 150, 930, 1346, | 169982 | /* 1700 */ 973, 1088, 1087, 1088, 1087, 860, 557, 150, 928, 1342, |
| 164259 | /* 1710 */ 113, 1358, 554, 1424, 1021, 1275, 1266, 1254, 236, 1253, | 169983 | /* 1710 */ 113, 1354, 554, 1419, 1018, 1271, 1262, 1250, 236, 1249, |
| 164260 | /* 1720 */ 1255, 445, 1593, 1343, 308, 276, 168, 309, 11, 141, | 169984 | /* 1720 */ 1251, 445, 1585, 1339, 308, 276, 168, 309, 11, 141, |
| 164261 | /* 1730 */ 393, 310, 232, 557, 1405, 1027, 335, 291, 1400, 219, | 169985 | /* 1730 */ 393, 310, 232, 557, 1401, 1024, 335, 291, 1396, 219, |
| 164262 | /* 1740 */ 336, 109, 109, 936, 297, 1410, 235, 341, 477, 110, | 169986 | /* 1740 */ 336, 109, 109, 934, 297, 1406, 235, 341, 477, 110, |
| 164263 | /* 1750 */ 502, 445, 570, 569, 1393, 1409, 1017, 400, 1293, 365, | 169987 | /* 1750 */ 502, 445, 569, 445, 1389, 1405, 1014, 400, 1289, 365, |
| 164264 | /* 1760 */ 223, 1486, 1027, 1485, 1355, 1356, 1354, 1353, 109, 109, | 169988 | /* 1760 */ 223, 1480, 1024, 1479, 1351, 1352, 1350, 1349, 109, 109, |
| 164265 | /* 1770 */ 204, 1596, 1232, 558, 265, 218, 110, 205, 445, 570, | 169989 | /* 1770 */ 204, 1588, 1226, 558, 265, 218, 110, 205, 445, 569, |
| 164266 | /* 1780 */ 569, 410, 387, 1017, 1533, 179, 316, 559, 1017, 1017, | 169990 | /* 1780 */ 445, 410, 387, 1014, 1527, 179, 316, 559, 1014, 1014, |
| 164267 | /* 1790 */ 1019, 1020, 27, 230, 1531, 1229, 79, 560, 85, 4, | 169991 | /* 1790 */ 1016, 1017, 27, 230, 1525, 1223, 79, 560, 85, 4, |
| 164268 | /* 1800 */ 418, 215, 548, 81, 84, 188, 1406, 173, 181, 461, | 169992 | /* 1800 */ 418, 215, 548, 81, 84, 188, 1402, 173, 181, 461, |
| 164269 | /* 1810 */ 451, 35, 462, 563, 183, 1017, 1017, 1019, 1020, 27, | 169993 | /* 1810 */ 451, 35, 462, 563, 183, 1014, 1014, 1016, 1017, 27, |
| 164270 | /* 1820 */ 184, 1491, 185, 186, 495, 242, 98, 398, 1412, 36, | 169994 | /* 1820 */ 184, 1485, 185, 186, 495, 242, 98, 398, 1408, 36, |
| 164271 | /* 1830 */ 1411, 484, 91, 469, 401, 1414, 445, 192, 1480, 246, | 169995 | /* 1830 */ 1407, 484, 91, 469, 401, 1410, 445, 192, 1474, 246, |
| 164272 | /* 1840 */ 1502, 490, 346, 277, 248, 196, 493, 511, 557, 350, | 169996 | /* 1840 */ 1496, 490, 346, 277, 248, 196, 493, 511, 557, 350, |
| 164273 | /* 1850 */ 1256, 249, 250, 403, 1313, 1312, 111, 560, 432, 4, | 169997 | /* 1850 */ 1252, 249, 250, 403, 1309, 1308, 111, 560, 432, 4, |
| 164274 | /* 1860 */ 1311, 1304, 93, 1611, 883, 1610, 224, 404, 434, 520, | 169998 | /* 1860 */ 1307, 1300, 93, 1602, 881, 1601, 224, 404, 434, 520, |
| 164275 | /* 1870 */ 263, 435, 1579, 563, 1283, 1282, 364, 1027, 306, 1281, | 169999 | /* 1870 */ 263, 435, 1571, 563, 1279, 1278, 364, 1024, 306, 1277, |
| 164276 | /* 1880 */ 264, 1609, 1565, 109, 109, 370, 1303, 307, 1564, 438, | 170000 | /* 1880 */ 264, 1600, 1557, 109, 109, 370, 1299, 307, 1556, 438, |
| 164277 | /* 1890 */ 128, 110, 1378, 445, 570, 569, 445, 546, 1017, 10, | 170001 | /* 1890 */ 128, 110, 1374, 445, 569, 445, 445, 546, 1014, 10, |
| 164278 | /* 1900 */ 1466, 105, 381, 1377, 34, 572, 99, 1336, 557, 314, | 170002 | /* 1900 */ 1461, 105, 381, 1373, 34, 571, 99, 1332, 557, 314, |
| 164279 | /* 1910 */ 1186, 530, 272, 274, 379, 210, 1335, 547, 385, 386, | 170003 | /* 1910 */ 1180, 530, 272, 274, 379, 210, 1331, 547, 385, 386, |
| 164280 | /* 1920 */ 275, 573, 1251, 1246, 411, 412, 1518, 165, 178, 1519, | 170004 | /* 1920 */ 275, 572, 1247, 1242, 411, 412, 1512, 165, 178, 1513, |
| 164281 | /* 1930 */ 1017, 1017, 1019, 1020, 27, 1517, 1516, 1027, 78, 147, | 170005 | /* 1930 */ 1014, 1014, 1016, 1017, 27, 1511, 1510, 1024, 78, 147, |
| 164282 | /* 1940 */ 166, 220, 221, 109, 109, 836, 304, 167, 446, 212, | 170006 | /* 1940 */ 166, 220, 221, 109, 109, 834, 304, 167, 446, 212, |
| 164283 | /* 1950 */ 318, 110, 231, 445, 570, 569, 144, 1090, 1017, 1088, | 170007 | /* 1950 */ 318, 110, 231, 445, 569, 445, 144, 1086, 1014, 1084, |
| 164284 | /* 1960 */ 326, 180, 169, 1212, 182, 334, 238, 915, 241, 1104, | 170008 | /* 1960 */ 326, 180, 169, 1205, 182, 334, 238, 913, 241, 1100, |
| 164285 | /* 1970 */ 187, 170, 171, 421, 87, 88, 423, 189, 89, 90, | 170009 | /* 1970 */ 187, 170, 171, 421, 87, 88, 423, 189, 89, 90, |
| 164286 | /* 1980 */ 172, 1107, 243, 1103, 244, 158, 18, 245, 345, 247, | 170010 | /* 1980 */ 172, 1103, 243, 1099, 244, 158, 18, 245, 345, 247, |
| 164287 | /* 1990 */ 1017, 1017, 1019, 1020, 27, 261, 1096, 193, 1226, 489, | 170011 | /* 1990 */ 1014, 1014, 1016, 1017, 27, 261, 1092, 193, 1220, 489, |
| 164288 | /* 2000 */ 194, 37, 366, 851, 494, 251, 195, 506, 92, 19, | 170012 | /* 2000 */ 194, 37, 366, 849, 494, 251, 195, 506, 92, 19, |
| 164289 | /* 2010 */ 498, 358, 20, 503, 881, 361, 94, 894, 305, 159, | 170013 | /* 2010 */ 498, 358, 20, 503, 879, 361, 94, 892, 305, 159, |
| 164290 | /* 2020 */ 513, 39, 95, 1174, 160, 1056, 966, 1143, 96, 174, | 170014 | /* 2020 */ 513, 39, 95, 1168, 160, 1053, 964, 1139, 96, 174, |
| 164291 | /* 2030 */ 1142, 225, 280, 282, 198, 960, 113, 1164, 1160, 260, | 170015 | /* 2030 */ 1138, 225, 280, 282, 198, 958, 113, 1158, 1154, 260, |
| 164292 | /* 2040 */ 21, 22, 23, 1162, 1168, 1167, 1148, 24, 33, 25, | 170016 | /* 2040 */ 21, 22, 23, 1156, 1162, 1161, 1143, 24, 33, 25, |
| 164293 | /* 2050 */ 202, 542, 26, 100, 1071, 102, 1057, 103, 7, 1055, | 170017 | /* 2050 */ 202, 542, 26, 100, 1067, 102, 1054, 103, 7, 1052, |
| 164294 | /* 2060 */ 1059, 1113, 1060, 1112, 266, 267, 28, 40, 390, 1022, | 170018 | /* 2060 */ 1056, 1109, 1057, 1108, 266, 267, 28, 40, 390, 1019, |
| 164295 | /* 2070 */ 863, 112, 29, 564, 1182, 1181, 268, 176, 143, 925, | 170019 | /* 2070 */ 861, 112, 29, 564, 1176, 1175, 268, 176, 143, 923, |
| 164296 | /* 2080 */ 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, | 170020 | /* 2080 */ 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, |
| 164297 | /* 2090 */ 1242, 1242, 1242, 1242, 269, 1602, 1242, 1601, | 170021 | /* 2090 */ 1238, 1238, 1238, 1238, 269, 1593, |
| 164298 | }; | 170022 | }; |
| 164299 | static const YYCODETYPE yy_lookahead[] = { | 170023 | static const YYCODETYPE yy_lookahead[] = { |
| 164300 | /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276, | 170024 | /* 0 */ 193, 193, 193, 274, 275, 276, 193, 274, 275, 276, |
| @@ -164506,7 +170230,7 @@ static const YYCODETYPE yy_lookahead[] = { | |||
| 164506 | /* 2060 */ 23, 23, 11, 23, 25, 22, 22, 22, 15, 23, | 170230 | /* 2060 */ 23, 23, 11, 23, 25, 22, 22, 22, 15, 23, |
| 164507 | /* 2070 */ 23, 22, 22, 25, 1, 1, 141, 25, 23, 135, | 170231 | /* 2070 */ 23, 22, 22, 25, 1, 1, 141, 25, 23, 135, |
| 164508 | /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 170232 | /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, |
| 164509 | /* 2090 */ 319, 319, 319, 319, 141, 141, 319, 141, 319, 319, | 170233 | /* 2090 */ 319, 319, 319, 319, 141, 141, 319, 319, 319, 319, |
| 164510 | /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 170234 | /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, |
| 164511 | /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 170235 | /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, |
| 164512 | /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 170236 | /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, |
| @@ -164525,9 +170249,9 @@ static const YYCODETYPE yy_lookahead[] = { | |||
| 164525 | /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 170249 | /* 2250 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, |
| 164526 | /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 170250 | /* 2260 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, |
| 164527 | /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, | 170251 | /* 2270 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, |
| 164528 | /* 2280 */ 319, 319, 319, | 170252 | /* 2280 */ 319, |
| 164529 | }; | 170253 | }; |
| 164530 | #define YY_SHIFT_COUNT (575) | 170254 | #define YY_SHIFT_COUNT (574) |
| 164531 | #define YY_SHIFT_MIN (0) | 170255 | #define YY_SHIFT_MIN (0) |
| 164532 | #define YY_SHIFT_MAX (2074) | 170256 | #define YY_SHIFT_MAX (2074) |
| 164533 | static const unsigned short int yy_shift_ofst[] = { | 170257 | static const unsigned short int yy_shift_ofst[] = { |
| @@ -164547,12 +170271,12 @@ static const unsigned short int yy_shift_ofst[] = { | |||
| 164547 | /* 130 */ 137, 181, 181, 181, 181, 181, 181, 181, 94, 430, | 170271 | /* 130 */ 137, 181, 181, 181, 181, 181, 181, 181, 94, 430, |
| 164548 | /* 140 */ 66, 65, 112, 366, 533, 533, 740, 1261, 533, 533, | 170272 | /* 140 */ 66, 65, 112, 366, 533, 533, 740, 1261, 533, 533, |
| 164549 | /* 150 */ 79, 79, 533, 412, 412, 412, 77, 412, 123, 113, | 170273 | /* 150 */ 79, 79, 533, 412, 412, 412, 77, 412, 123, 113, |
| 164550 | /* 160 */ 113, 22, 22, 2098, 2098, 328, 328, 328, 239, 468, | 170274 | /* 160 */ 113, 22, 22, 2096, 2096, 328, 328, 328, 239, 468, |
| 164551 | /* 170 */ 468, 468, 468, 1015, 1015, 409, 366, 1129, 1186, 533, | 170275 | /* 170 */ 468, 468, 468, 1015, 1015, 409, 366, 1129, 1186, 533, |
| 164552 | /* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, | 170276 | /* 180 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, |
| 164553 | /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 969, | 170277 | /* 190 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 969, |
| 164554 | /* 200 */ 621, 621, 533, 642, 788, 788, 1228, 1228, 822, 822, | 170278 | /* 200 */ 621, 621, 533, 642, 788, 788, 1228, 1228, 822, 822, |
| 164555 | /* 210 */ 67, 1274, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 1307, | 170279 | /* 210 */ 67, 1274, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 1307, |
| 164556 | /* 220 */ 954, 954, 585, 472, 640, 387, 695, 538, 541, 700, | 170280 | /* 220 */ 954, 954, 585, 472, 640, 387, 695, 538, 541, 700, |
| 164557 | /* 230 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, | 170281 | /* 230 */ 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, |
| 164558 | /* 240 */ 222, 533, 533, 533, 533, 533, 533, 533, 533, 533, | 170282 | /* 240 */ 222, 533, 533, 533, 533, 533, 533, 533, 533, 533, |
| @@ -164570,8 +170294,8 @@ static const unsigned short int yy_shift_ofst[] = { | |||
| 164570 | /* 360 */ 1840, 1840, 1823, 1732, 1738, 1732, 1794, 1732, 1732, 1701, | 170294 | /* 360 */ 1840, 1840, 1823, 1732, 1738, 1732, 1794, 1732, 1732, 1701, |
| 164571 | /* 370 */ 1844, 1758, 1758, 1823, 1633, 1789, 1789, 1807, 1807, 1742, | 170295 | /* 370 */ 1844, 1758, 1758, 1823, 1633, 1789, 1789, 1807, 1807, 1742, |
| 164572 | /* 380 */ 1752, 1877, 1633, 1743, 1742, 1759, 1765, 1677, 1879, 1897, | 170296 | /* 380 */ 1752, 1877, 1633, 1743, 1742, 1759, 1765, 1677, 1879, 1897, |
| 164573 | /* 390 */ 1897, 1914, 1914, 1914, 2098, 2098, 2098, 2098, 2098, 2098, | 170297 | /* 390 */ 1897, 1914, 1914, 1914, 2096, 2096, 2096, 2096, 2096, 2096, |
| 164574 | /* 400 */ 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 207, | 170298 | /* 400 */ 2096, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 207, |
| 164575 | /* 410 */ 1095, 331, 620, 903, 806, 1074, 1483, 1432, 1481, 1322, | 170299 | /* 410 */ 1095, 331, 620, 903, 806, 1074, 1483, 1432, 1481, 1322, |
| 164576 | /* 420 */ 1370, 1394, 1515, 1291, 1546, 1547, 1557, 1595, 1598, 1599, | 170300 | /* 420 */ 1370, 1394, 1515, 1291, 1546, 1547, 1557, 1595, 1598, 1599, |
| 164577 | /* 430 */ 1434, 1453, 1618, 1462, 1567, 1489, 1644, 1654, 1616, 1660, | 170301 | /* 430 */ 1434, 1453, 1618, 1462, 1567, 1489, 1644, 1654, 1616, 1660, |
| @@ -164588,7 +170312,7 @@ static const unsigned short int yy_shift_ofst[] = { | |||
| 164588 | /* 540 */ 2015, 2023, 2026, 2027, 2025, 2028, 2018, 1913, 1915, 2031, | 170312 | /* 540 */ 2015, 2023, 2026, 2027, 2025, 2028, 2018, 1913, 1915, 2031, |
| 164589 | /* 550 */ 2011, 2033, 2036, 2037, 2038, 2039, 2040, 2043, 2051, 2044, | 170313 | /* 550 */ 2011, 2033, 2036, 2037, 2038, 2039, 2040, 2043, 2051, 2044, |
| 164590 | /* 560 */ 2045, 2046, 2047, 2049, 2050, 2048, 1944, 1935, 1953, 1954, | 170314 | /* 560 */ 2045, 2046, 2047, 2049, 2050, 2048, 1944, 1935, 1953, 1954, |
| 164591 | /* 570 */ 1956, 2052, 2055, 2053, 2073, 2074, | 170315 | /* 570 */ 2052, 2055, 2053, 2073, 2074, |
| 164592 | }; | 170316 | }; |
| 164593 | #define YY_REDUCE_COUNT (408) | 170317 | #define YY_REDUCE_COUNT (408) |
| 164594 | #define YY_REDUCE_MIN (-271) | 170318 | #define YY_REDUCE_MIN (-271) |
| @@ -164637,64 +170361,64 @@ static const short yy_reduce_ofst[] = { | |||
| 164637 | /* 400 */ 1722, 1723, 1733, 1717, 1724, 1727, 1728, 1725, 1740, | 170361 | /* 400 */ 1722, 1723, 1733, 1717, 1724, 1727, 1728, 1725, 1740, |
| 164638 | }; | 170362 | }; |
| 164639 | static const YYACTIONTYPE yy_default[] = { | 170363 | static const YYACTIONTYPE yy_default[] = { |
| 164640 | /* 0 */ 1647, 1647, 1647, 1475, 1240, 1351, 1240, 1240, 1240, 1475, | 170364 | /* 0 */ 1639, 1639, 1639, 1469, 1236, 1347, 1236, 1236, 1236, 1469, |
| 164641 | /* 10 */ 1475, 1475, 1240, 1381, 1381, 1528, 1273, 1240, 1240, 1240, | 170365 | /* 10 */ 1469, 1469, 1236, 1377, 1377, 1522, 1269, 1236, 1236, 1236, |
| 164642 | /* 20 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1474, 1240, 1240, | 170366 | /* 20 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1468, 1236, 1236, |
| 164643 | /* 30 */ 1240, 1240, 1563, 1563, 1240, 1240, 1240, 1240, 1240, 1240, | 170367 | /* 30 */ 1236, 1236, 1555, 1555, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164644 | /* 40 */ 1240, 1240, 1390, 1240, 1397, 1240, 1240, 1240, 1240, 1240, | 170368 | /* 40 */ 1236, 1236, 1386, 1236, 1393, 1236, 1236, 1236, 1236, 1236, |
| 164645 | /* 50 */ 1476, 1477, 1240, 1240, 1240, 1527, 1529, 1492, 1404, 1403, | 170369 | /* 50 */ 1470, 1471, 1236, 1236, 1236, 1521, 1523, 1486, 1400, 1399, |
| 164646 | /* 60 */ 1402, 1401, 1510, 1369, 1395, 1388, 1392, 1470, 1471, 1469, | 170370 | /* 60 */ 1398, 1397, 1504, 1365, 1391, 1384, 1388, 1465, 1466, 1464, |
| 164647 | /* 70 */ 1473, 1477, 1476, 1240, 1391, 1438, 1454, 1437, 1240, 1240, | 170371 | /* 70 */ 1617, 1471, 1470, 1236, 1387, 1433, 1449, 1432, 1236, 1236, |
| 164648 | /* 80 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170372 | /* 80 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164649 | /* 90 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170373 | /* 90 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164650 | /* 100 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170374 | /* 100 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164651 | /* 110 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170375 | /* 110 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164652 | /* 120 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170376 | /* 120 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164653 | /* 130 */ 1446, 1453, 1452, 1451, 1460, 1450, 1447, 1440, 1439, 1441, | 170377 | /* 130 */ 1441, 1448, 1447, 1446, 1455, 1445, 1442, 1435, 1434, 1436, |
| 164654 | /* 140 */ 1442, 1240, 1240, 1264, 1240, 1240, 1261, 1315, 1240, 1240, | 170378 | /* 140 */ 1437, 1236, 1236, 1260, 1236, 1236, 1257, 1311, 1236, 1236, |
| 164655 | /* 150 */ 1240, 1240, 1240, 1547, 1546, 1240, 1443, 1240, 1273, 1432, | 170379 | /* 150 */ 1236, 1236, 1236, 1541, 1540, 1236, 1438, 1236, 1269, 1427, |
| 164656 | /* 160 */ 1431, 1457, 1444, 1456, 1455, 1535, 1599, 1598, 1493, 1240, | 170380 | /* 160 */ 1426, 1452, 1439, 1451, 1450, 1529, 1591, 1590, 1487, 1236, |
| 164657 | /* 170 */ 1240, 1240, 1240, 1240, 1240, 1563, 1240, 1240, 1240, 1240, | 170381 | /* 170 */ 1236, 1236, 1236, 1236, 1236, 1555, 1236, 1236, 1236, 1236, |
| 164658 | /* 180 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170382 | /* 180 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164659 | /* 190 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1371, | 170383 | /* 190 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1367, |
| 164660 | /* 200 */ 1563, 1563, 1240, 1273, 1563, 1563, 1372, 1372, 1269, 1269, | 170384 | /* 200 */ 1555, 1555, 1236, 1269, 1555, 1555, 1368, 1368, 1265, 1265, |
| 164661 | /* 210 */ 1375, 1240, 1542, 1342, 1342, 1342, 1342, 1351, 1342, 1240, | 170385 | /* 210 */ 1371, 1236, 1536, 1338, 1338, 1338, 1338, 1347, 1338, 1236, |
| 164662 | /* 220 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170386 | /* 220 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164663 | /* 230 */ 1240, 1240, 1240, 1240, 1532, 1530, 1240, 1240, 1240, 1240, | 170387 | /* 230 */ 1236, 1236, 1236, 1236, 1526, 1524, 1236, 1236, 1236, 1236, |
| 164664 | /* 240 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170388 | /* 240 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164665 | /* 250 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170389 | /* 250 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164666 | /* 260 */ 1240, 1240, 1240, 1347, 1240, 1240, 1240, 1240, 1240, 1240, | 170390 | /* 260 */ 1236, 1236, 1236, 1343, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164667 | /* 270 */ 1240, 1240, 1240, 1240, 1240, 1592, 1240, 1505, 1329, 1347, | 170391 | /* 270 */ 1236, 1236, 1236, 1236, 1236, 1584, 1236, 1499, 1325, 1343, |
| 164668 | /* 280 */ 1347, 1347, 1347, 1349, 1330, 1328, 1341, 1274, 1247, 1639, | 170392 | /* 280 */ 1343, 1343, 1343, 1345, 1326, 1324, 1337, 1270, 1243, 1631, |
| 164669 | /* 290 */ 1407, 1396, 1348, 1396, 1636, 1394, 1407, 1407, 1394, 1407, | 170393 | /* 290 */ 1403, 1392, 1344, 1392, 1628, 1390, 1403, 1403, 1390, 1403, |
| 164670 | /* 300 */ 1348, 1636, 1290, 1615, 1285, 1381, 1381, 1381, 1371, 1371, | 170394 | /* 300 */ 1344, 1628, 1286, 1606, 1281, 1377, 1377, 1377, 1367, 1367, |
| 164671 | /* 310 */ 1371, 1371, 1375, 1375, 1472, 1348, 1341, 1240, 1639, 1639, | 170395 | /* 310 */ 1367, 1367, 1371, 1371, 1467, 1344, 1337, 1236, 1631, 1631, |
| 164672 | /* 320 */ 1357, 1357, 1638, 1638, 1357, 1493, 1623, 1416, 1318, 1324, | 170396 | /* 320 */ 1353, 1353, 1630, 1630, 1353, 1487, 1614, 1412, 1314, 1320, |
| 164673 | /* 330 */ 1324, 1324, 1324, 1357, 1258, 1394, 1623, 1623, 1394, 1416, | 170397 | /* 330 */ 1320, 1320, 1320, 1353, 1254, 1390, 1614, 1614, 1390, 1412, |
| 164674 | /* 340 */ 1318, 1394, 1318, 1394, 1357, 1258, 1509, 1633, 1357, 1258, | 170398 | /* 340 */ 1314, 1390, 1314, 1390, 1353, 1254, 1503, 1625, 1353, 1254, |
| 164675 | /* 350 */ 1483, 1357, 1258, 1357, 1258, 1483, 1316, 1316, 1316, 1305, | 170399 | /* 350 */ 1477, 1353, 1254, 1353, 1254, 1477, 1312, 1312, 1312, 1301, |
| 164676 | /* 360 */ 1240, 1240, 1483, 1316, 1290, 1316, 1305, 1316, 1316, 1581, | 170400 | /* 360 */ 1236, 1236, 1477, 1312, 1286, 1312, 1301, 1312, 1312, 1573, |
| 164677 | /* 370 */ 1240, 1487, 1487, 1483, 1357, 1573, 1573, 1384, 1384, 1389, | 170401 | /* 370 */ 1236, 1481, 1481, 1477, 1353, 1565, 1565, 1380, 1380, 1385, |
| 164678 | /* 380 */ 1375, 1478, 1357, 1240, 1389, 1387, 1385, 1394, 1308, 1595, | 170402 | /* 380 */ 1371, 1472, 1353, 1236, 1385, 1383, 1381, 1390, 1304, 1587, |
| 164679 | /* 390 */ 1595, 1591, 1591, 1591, 1644, 1644, 1542, 1608, 1273, 1273, | 170403 | /* 390 */ 1587, 1583, 1583, 1583, 1636, 1636, 1536, 1599, 1269, 1269, |
| 164680 | /* 400 */ 1273, 1273, 1608, 1292, 1292, 1274, 1274, 1273, 1608, 1240, | 170404 | /* 400 */ 1269, 1269, 1599, 1288, 1288, 1270, 1270, 1269, 1599, 1236, |
| 164681 | /* 410 */ 1240, 1240, 1240, 1240, 1240, 1603, 1240, 1537, 1494, 1361, | 170405 | /* 410 */ 1236, 1236, 1236, 1236, 1236, 1594, 1236, 1531, 1488, 1357, |
| 164682 | /* 420 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170406 | /* 420 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164683 | /* 430 */ 1240, 1240, 1240, 1240, 1548, 1240, 1240, 1240, 1240, 1240, | 170407 | /* 430 */ 1236, 1236, 1236, 1236, 1542, 1236, 1236, 1236, 1236, 1236, |
| 164684 | /* 440 */ 1240, 1240, 1240, 1240, 1240, 1421, 1240, 1243, 1539, 1240, | 170408 | /* 440 */ 1236, 1236, 1236, 1236, 1236, 1417, 1236, 1239, 1533, 1236, |
| 164685 | /* 450 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1398, 1399, 1362, | 170409 | /* 450 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1394, 1395, 1358, |
| 164686 | /* 460 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1413, 1240, 1240, | 170410 | /* 460 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1409, 1236, 1236, |
| 164687 | /* 470 */ 1240, 1408, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170411 | /* 470 */ 1236, 1404, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164688 | /* 480 */ 1635, 1240, 1240, 1240, 1240, 1240, 1240, 1508, 1507, 1240, | 170412 | /* 480 */ 1627, 1236, 1236, 1236, 1236, 1236, 1236, 1502, 1501, 1236, |
| 164689 | /* 490 */ 1240, 1359, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170413 | /* 490 */ 1236, 1355, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164690 | /* 500 */ 1240, 1240, 1240, 1240, 1240, 1288, 1240, 1240, 1240, 1240, | 170414 | /* 500 */ 1236, 1236, 1236, 1236, 1236, 1284, 1236, 1236, 1236, 1236, |
| 164691 | /* 510 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170415 | /* 510 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164692 | /* 520 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1386, | 170416 | /* 520 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1382, |
| 164693 | /* 530 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170417 | /* 530 */ 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164694 | /* 540 */ 1240, 1240, 1240, 1240, 1578, 1376, 1240, 1240, 1240, 1240, | 170418 | /* 540 */ 1236, 1236, 1236, 1236, 1570, 1372, 1236, 1236, 1236, 1236, |
| 164695 | /* 550 */ 1626, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, | 170419 | /* 550 */ 1618, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, |
| 164696 | /* 560 */ 1240, 1240, 1240, 1240, 1240, 1619, 1332, 1423, 1240, 1422, | 170420 | /* 560 */ 1236, 1236, 1236, 1236, 1236, 1610, 1328, 1418, 1236, 1421, |
| 164697 | /* 570 */ 1426, 1262, 1240, 1252, 1240, 1240, | 170421 | /* 570 */ 1258, 1236, 1248, 1236, 1236, |
| 164698 | }; | 170422 | }; |
| 164699 | /********** End of lemon-generated parsing tables *****************************/ | 170423 | /********** End of lemon-generated parsing tables *****************************/ |
| 164700 | 170424 | ||
| @@ -165491,233 +171215,231 @@ static const char *const yyRuleName[] = { | |||
| 165491 | /* 175 */ "idlist ::= idlist COMMA nm", | 171215 | /* 175 */ "idlist ::= idlist COMMA nm", |
| 165492 | /* 176 */ "idlist ::= nm", | 171216 | /* 176 */ "idlist ::= nm", |
| 165493 | /* 177 */ "expr ::= LP expr RP", | 171217 | /* 177 */ "expr ::= LP expr RP", |
| 165494 | /* 178 */ "expr ::= ID|INDEXED", | 171218 | /* 178 */ "expr ::= ID|INDEXED|JOIN_KW", |
| 165495 | /* 179 */ "expr ::= JOIN_KW", | 171219 | /* 179 */ "expr ::= nm DOT nm", |
| 165496 | /* 180 */ "expr ::= nm DOT nm", | 171220 | /* 180 */ "expr ::= nm DOT nm DOT nm", |
| 165497 | /* 181 */ "expr ::= nm DOT nm DOT nm", | 171221 | /* 181 */ "term ::= NULL|FLOAT|BLOB", |
| 165498 | /* 182 */ "term ::= NULL|FLOAT|BLOB", | 171222 | /* 182 */ "term ::= STRING", |
| 165499 | /* 183 */ "term ::= STRING", | 171223 | /* 183 */ "term ::= INTEGER", |
| 165500 | /* 184 */ "term ::= INTEGER", | 171224 | /* 184 */ "expr ::= VARIABLE", |
| 165501 | /* 185 */ "expr ::= VARIABLE", | 171225 | /* 185 */ "expr ::= expr COLLATE ID|STRING", |
| 165502 | /* 186 */ "expr ::= expr COLLATE ID|STRING", | 171226 | /* 186 */ "expr ::= CAST LP expr AS typetoken RP", |
| 165503 | /* 187 */ "expr ::= CAST LP expr AS typetoken RP", | 171227 | /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", |
| 165504 | /* 188 */ "expr ::= ID|INDEXED LP distinct exprlist RP", | 171228 | /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", |
| 165505 | /* 189 */ "expr ::= ID|INDEXED LP STAR RP", | 171229 | /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", |
| 165506 | /* 190 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", | 171230 | /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", |
| 165507 | /* 191 */ "expr ::= ID|INDEXED LP STAR RP filter_over", | 171231 | /* 191 */ "term ::= CTIME_KW", |
| 165508 | /* 192 */ "term ::= CTIME_KW", | 171232 | /* 192 */ "expr ::= LP nexprlist COMMA expr RP", |
| 165509 | /* 193 */ "expr ::= LP nexprlist COMMA expr RP", | 171233 | /* 193 */ "expr ::= expr AND expr", |
| 165510 | /* 194 */ "expr ::= expr AND expr", | 171234 | /* 194 */ "expr ::= expr OR expr", |
| 165511 | /* 195 */ "expr ::= expr OR expr", | 171235 | /* 195 */ "expr ::= expr LT|GT|GE|LE expr", |
| 165512 | /* 196 */ "expr ::= expr LT|GT|GE|LE expr", | 171236 | /* 196 */ "expr ::= expr EQ|NE expr", |
| 165513 | /* 197 */ "expr ::= expr EQ|NE expr", | 171237 | /* 197 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", |
| 165514 | /* 198 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", | 171238 | /* 198 */ "expr ::= expr PLUS|MINUS expr", |
| 165515 | /* 199 */ "expr ::= expr PLUS|MINUS expr", | 171239 | /* 199 */ "expr ::= expr STAR|SLASH|REM expr", |
| 165516 | /* 200 */ "expr ::= expr STAR|SLASH|REM expr", | 171240 | /* 200 */ "expr ::= expr CONCAT expr", |
| 165517 | /* 201 */ "expr ::= expr CONCAT expr", | 171241 | /* 201 */ "likeop ::= NOT LIKE_KW|MATCH", |
| 165518 | /* 202 */ "likeop ::= NOT LIKE_KW|MATCH", | 171242 | /* 202 */ "expr ::= expr likeop expr", |
| 165519 | /* 203 */ "expr ::= expr likeop expr", | 171243 | /* 203 */ "expr ::= expr likeop expr ESCAPE expr", |
| 165520 | /* 204 */ "expr ::= expr likeop expr ESCAPE expr", | 171244 | /* 204 */ "expr ::= expr ISNULL|NOTNULL", |
| 165521 | /* 205 */ "expr ::= expr ISNULL|NOTNULL", | 171245 | /* 205 */ "expr ::= expr NOT NULL", |
| 165522 | /* 206 */ "expr ::= expr NOT NULL", | 171246 | /* 206 */ "expr ::= expr IS expr", |
| 165523 | /* 207 */ "expr ::= expr IS expr", | 171247 | /* 207 */ "expr ::= expr IS NOT expr", |
| 165524 | /* 208 */ "expr ::= expr IS NOT expr", | 171248 | /* 208 */ "expr ::= expr IS NOT DISTINCT FROM expr", |
| 165525 | /* 209 */ "expr ::= expr IS NOT DISTINCT FROM expr", | 171249 | /* 209 */ "expr ::= expr IS DISTINCT FROM expr", |
| 165526 | /* 210 */ "expr ::= expr IS DISTINCT FROM expr", | 171250 | /* 210 */ "expr ::= NOT expr", |
| 165527 | /* 211 */ "expr ::= NOT expr", | 171251 | /* 211 */ "expr ::= BITNOT expr", |
| 165528 | /* 212 */ "expr ::= BITNOT expr", | 171252 | /* 212 */ "expr ::= PLUS|MINUS expr", |
| 165529 | /* 213 */ "expr ::= PLUS|MINUS expr", | 171253 | /* 213 */ "expr ::= expr PTR expr", |
| 165530 | /* 214 */ "expr ::= expr PTR expr", | 171254 | /* 214 */ "between_op ::= BETWEEN", |
| 165531 | /* 215 */ "between_op ::= BETWEEN", | 171255 | /* 215 */ "between_op ::= NOT BETWEEN", |
| 165532 | /* 216 */ "between_op ::= NOT BETWEEN", | 171256 | /* 216 */ "expr ::= expr between_op expr AND expr", |
| 165533 | /* 217 */ "expr ::= expr between_op expr AND expr", | 171257 | /* 217 */ "in_op ::= IN", |
| 165534 | /* 218 */ "in_op ::= IN", | 171258 | /* 218 */ "in_op ::= NOT IN", |
| 165535 | /* 219 */ "in_op ::= NOT IN", | 171259 | /* 219 */ "expr ::= expr in_op LP exprlist RP", |
| 165536 | /* 220 */ "expr ::= expr in_op LP exprlist RP", | 171260 | /* 220 */ "expr ::= LP select RP", |
| 165537 | /* 221 */ "expr ::= LP select RP", | 171261 | /* 221 */ "expr ::= expr in_op LP select RP", |
| 165538 | /* 222 */ "expr ::= expr in_op LP select RP", | 171262 | /* 222 */ "expr ::= expr in_op nm dbnm paren_exprlist", |
| 165539 | /* 223 */ "expr ::= expr in_op nm dbnm paren_exprlist", | 171263 | /* 223 */ "expr ::= EXISTS LP select RP", |
| 165540 | /* 224 */ "expr ::= EXISTS LP select RP", | 171264 | /* 224 */ "expr ::= CASE case_operand case_exprlist case_else END", |
| 165541 | /* 225 */ "expr ::= CASE case_operand case_exprlist case_else END", | 171265 | /* 225 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", |
| 165542 | /* 226 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", | 171266 | /* 226 */ "case_exprlist ::= WHEN expr THEN expr", |
| 165543 | /* 227 */ "case_exprlist ::= WHEN expr THEN expr", | 171267 | /* 227 */ "case_else ::= ELSE expr", |
| 165544 | /* 228 */ "case_else ::= ELSE expr", | 171268 | /* 228 */ "case_else ::=", |
| 165545 | /* 229 */ "case_else ::=", | 171269 | /* 229 */ "case_operand ::=", |
| 165546 | /* 230 */ "case_operand ::= expr", | 171270 | /* 230 */ "exprlist ::=", |
| 165547 | /* 231 */ "case_operand ::=", | 171271 | /* 231 */ "nexprlist ::= nexprlist COMMA expr", |
| 165548 | /* 232 */ "exprlist ::=", | 171272 | /* 232 */ "nexprlist ::= expr", |
| 165549 | /* 233 */ "nexprlist ::= nexprlist COMMA expr", | 171273 | /* 233 */ "paren_exprlist ::=", |
| 165550 | /* 234 */ "nexprlist ::= expr", | 171274 | /* 234 */ "paren_exprlist ::= LP exprlist RP", |
| 165551 | /* 235 */ "paren_exprlist ::=", | 171275 | /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", |
| 165552 | /* 236 */ "paren_exprlist ::= LP exprlist RP", | 171276 | /* 236 */ "uniqueflag ::= UNIQUE", |
| 165553 | /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", | 171277 | /* 237 */ "uniqueflag ::=", |
| 165554 | /* 238 */ "uniqueflag ::= UNIQUE", | 171278 | /* 238 */ "eidlist_opt ::=", |
| 165555 | /* 239 */ "uniqueflag ::=", | 171279 | /* 239 */ "eidlist_opt ::= LP eidlist RP", |
| 165556 | /* 240 */ "eidlist_opt ::=", | 171280 | /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder", |
| 165557 | /* 241 */ "eidlist_opt ::= LP eidlist RP", | 171281 | /* 241 */ "eidlist ::= nm collate sortorder", |
| 165558 | /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder", | 171282 | /* 242 */ "collate ::=", |
| 165559 | /* 243 */ "eidlist ::= nm collate sortorder", | 171283 | /* 243 */ "collate ::= COLLATE ID|STRING", |
| 165560 | /* 244 */ "collate ::=", | 171284 | /* 244 */ "cmd ::= DROP INDEX ifexists fullname", |
| 165561 | /* 245 */ "collate ::= COLLATE ID|STRING", | 171285 | /* 245 */ "cmd ::= VACUUM vinto", |
| 165562 | /* 246 */ "cmd ::= DROP INDEX ifexists fullname", | 171286 | /* 246 */ "cmd ::= VACUUM nm vinto", |
| 165563 | /* 247 */ "cmd ::= VACUUM vinto", | 171287 | /* 247 */ "vinto ::= INTO expr", |
| 165564 | /* 248 */ "cmd ::= VACUUM nm vinto", | 171288 | /* 248 */ "vinto ::=", |
| 165565 | /* 249 */ "vinto ::= INTO expr", | 171289 | /* 249 */ "cmd ::= PRAGMA nm dbnm", |
| 165566 | /* 250 */ "vinto ::=", | 171290 | /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", |
| 165567 | /* 251 */ "cmd ::= PRAGMA nm dbnm", | 171291 | /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", |
| 165568 | /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", | 171292 | /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", |
| 165569 | /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", | 171293 | /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", |
| 165570 | /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", | 171294 | /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT", |
| 165571 | /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", | 171295 | /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT", |
| 165572 | /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT", | 171296 | /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", |
| 165573 | /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT", | 171297 | /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", |
| 165574 | /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", | 171298 | /* 258 */ "trigger_time ::= BEFORE|AFTER", |
| 165575 | /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", | 171299 | /* 259 */ "trigger_time ::= INSTEAD OF", |
| 165576 | /* 260 */ "trigger_time ::= BEFORE|AFTER", | 171300 | /* 260 */ "trigger_time ::=", |
| 165577 | /* 261 */ "trigger_time ::= INSTEAD OF", | 171301 | /* 261 */ "trigger_event ::= DELETE|INSERT", |
| 165578 | /* 262 */ "trigger_time ::=", | 171302 | /* 262 */ "trigger_event ::= UPDATE", |
| 165579 | /* 263 */ "trigger_event ::= DELETE|INSERT", | 171303 | /* 263 */ "trigger_event ::= UPDATE OF idlist", |
| 165580 | /* 264 */ "trigger_event ::= UPDATE", | 171304 | /* 264 */ "when_clause ::=", |
| 165581 | /* 265 */ "trigger_event ::= UPDATE OF idlist", | 171305 | /* 265 */ "when_clause ::= WHEN expr", |
| 165582 | /* 266 */ "when_clause ::=", | 171306 | /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", |
| 165583 | /* 267 */ "when_clause ::= WHEN expr", | 171307 | /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI", |
| 165584 | /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", | 171308 | /* 268 */ "trnm ::= nm DOT nm", |
| 165585 | /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI", | 171309 | /* 269 */ "tridxby ::= INDEXED BY nm", |
| 165586 | /* 270 */ "trnm ::= nm DOT nm", | 171310 | /* 270 */ "tridxby ::= NOT INDEXED", |
| 165587 | /* 271 */ "tridxby ::= INDEXED BY nm", | 171311 | /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", |
| 165588 | /* 272 */ "tridxby ::= NOT INDEXED", | 171312 | /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", |
| 165589 | /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", | 171313 | /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", |
| 165590 | /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", | 171314 | /* 274 */ "trigger_cmd ::= scanpt select scanpt", |
| 165591 | /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", | 171315 | /* 275 */ "expr ::= RAISE LP IGNORE RP", |
| 165592 | /* 276 */ "trigger_cmd ::= scanpt select scanpt", | 171316 | /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP", |
| 165593 | /* 277 */ "expr ::= RAISE LP IGNORE RP", | 171317 | /* 277 */ "raisetype ::= ROLLBACK", |
| 165594 | /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP", | 171318 | /* 278 */ "raisetype ::= ABORT", |
| 165595 | /* 279 */ "raisetype ::= ROLLBACK", | 171319 | /* 279 */ "raisetype ::= FAIL", |
| 165596 | /* 280 */ "raisetype ::= ABORT", | 171320 | /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname", |
| 165597 | /* 281 */ "raisetype ::= FAIL", | 171321 | /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", |
| 165598 | /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname", | 171322 | /* 282 */ "cmd ::= DETACH database_kw_opt expr", |
| 165599 | /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", | 171323 | /* 283 */ "key_opt ::=", |
| 165600 | /* 284 */ "cmd ::= DETACH database_kw_opt expr", | 171324 | /* 284 */ "key_opt ::= KEY expr", |
| 165601 | /* 285 */ "key_opt ::=", | 171325 | /* 285 */ "cmd ::= REINDEX", |
| 165602 | /* 286 */ "key_opt ::= KEY expr", | 171326 | /* 286 */ "cmd ::= REINDEX nm dbnm", |
| 165603 | /* 287 */ "cmd ::= REINDEX", | 171327 | /* 287 */ "cmd ::= ANALYZE", |
| 165604 | /* 288 */ "cmd ::= REINDEX nm dbnm", | 171328 | /* 288 */ "cmd ::= ANALYZE nm dbnm", |
| 165605 | /* 289 */ "cmd ::= ANALYZE", | 171329 | /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", |
| 165606 | /* 290 */ "cmd ::= ANALYZE nm dbnm", | 171330 | /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", |
| 165607 | /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", | 171331 | /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", |
| 165608 | /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", | 171332 | /* 292 */ "add_column_fullname ::= fullname", |
| 165609 | /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", | 171333 | /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", |
| 165610 | /* 294 */ "add_column_fullname ::= fullname", | 171334 | /* 294 */ "cmd ::= create_vtab", |
| 165611 | /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", | 171335 | /* 295 */ "cmd ::= create_vtab LP vtabarglist RP", |
| 165612 | /* 296 */ "cmd ::= create_vtab", | 171336 | /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", |
| 165613 | /* 297 */ "cmd ::= create_vtab LP vtabarglist RP", | 171337 | /* 297 */ "vtabarg ::=", |
| 165614 | /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", | 171338 | /* 298 */ "vtabargtoken ::= ANY", |
| 165615 | /* 299 */ "vtabarg ::=", | 171339 | /* 299 */ "vtabargtoken ::= lp anylist RP", |
| 165616 | /* 300 */ "vtabargtoken ::= ANY", | 171340 | /* 300 */ "lp ::= LP", |
| 165617 | /* 301 */ "vtabargtoken ::= lp anylist RP", | 171341 | /* 301 */ "with ::= WITH wqlist", |
| 165618 | /* 302 */ "lp ::= LP", | 171342 | /* 302 */ "with ::= WITH RECURSIVE wqlist", |
| 165619 | /* 303 */ "with ::= WITH wqlist", | 171343 | /* 303 */ "wqas ::= AS", |
| 165620 | /* 304 */ "with ::= WITH RECURSIVE wqlist", | 171344 | /* 304 */ "wqas ::= AS MATERIALIZED", |
| 165621 | /* 305 */ "wqas ::= AS", | 171345 | /* 305 */ "wqas ::= AS NOT MATERIALIZED", |
| 165622 | /* 306 */ "wqas ::= AS MATERIALIZED", | 171346 | /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP", |
| 165623 | /* 307 */ "wqas ::= AS NOT MATERIALIZED", | 171347 | /* 307 */ "wqlist ::= wqitem", |
| 165624 | /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP", | 171348 | /* 308 */ "wqlist ::= wqlist COMMA wqitem", |
| 165625 | /* 309 */ "wqlist ::= wqitem", | 171349 | /* 309 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", |
| 165626 | /* 310 */ "wqlist ::= wqlist COMMA wqitem", | 171350 | /* 310 */ "windowdefn ::= nm AS LP window RP", |
| 165627 | /* 311 */ "windowdefn_list ::= windowdefn", | 171351 | /* 311 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", |
| 165628 | /* 312 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", | 171352 | /* 312 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", |
| 165629 | /* 313 */ "windowdefn ::= nm AS LP window RP", | 171353 | /* 313 */ "window ::= ORDER BY sortlist frame_opt", |
| 165630 | /* 314 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", | 171354 | /* 314 */ "window ::= nm ORDER BY sortlist frame_opt", |
| 165631 | /* 315 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", | 171355 | /* 315 */ "window ::= nm frame_opt", |
| 165632 | /* 316 */ "window ::= ORDER BY sortlist frame_opt", | 171356 | /* 316 */ "frame_opt ::=", |
| 165633 | /* 317 */ "window ::= nm ORDER BY sortlist frame_opt", | 171357 | /* 317 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", |
| 165634 | /* 318 */ "window ::= frame_opt", | 171358 | /* 318 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", |
| 165635 | /* 319 */ "window ::= nm frame_opt", | 171359 | /* 319 */ "range_or_rows ::= RANGE|ROWS|GROUPS", |
| 165636 | /* 320 */ "frame_opt ::=", | 171360 | /* 320 */ "frame_bound_s ::= frame_bound", |
| 165637 | /* 321 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", | 171361 | /* 321 */ "frame_bound_s ::= UNBOUNDED PRECEDING", |
| 165638 | /* 322 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", | 171362 | /* 322 */ "frame_bound_e ::= frame_bound", |
| 165639 | /* 323 */ "range_or_rows ::= RANGE|ROWS|GROUPS", | 171363 | /* 323 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", |
| 165640 | /* 324 */ "frame_bound_s ::= frame_bound", | 171364 | /* 324 */ "frame_bound ::= expr PRECEDING|FOLLOWING", |
| 165641 | /* 325 */ "frame_bound_s ::= UNBOUNDED PRECEDING", | 171365 | /* 325 */ "frame_bound ::= CURRENT ROW", |
| 165642 | /* 326 */ "frame_bound_e ::= frame_bound", | 171366 | /* 326 */ "frame_exclude_opt ::=", |
| 165643 | /* 327 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", | 171367 | /* 327 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", |
| 165644 | /* 328 */ "frame_bound ::= expr PRECEDING|FOLLOWING", | 171368 | /* 328 */ "frame_exclude ::= NO OTHERS", |
| 165645 | /* 329 */ "frame_bound ::= CURRENT ROW", | 171369 | /* 329 */ "frame_exclude ::= CURRENT ROW", |
| 165646 | /* 330 */ "frame_exclude_opt ::=", | 171370 | /* 330 */ "frame_exclude ::= GROUP|TIES", |
| 165647 | /* 331 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", | 171371 | /* 331 */ "window_clause ::= WINDOW windowdefn_list", |
| 165648 | /* 332 */ "frame_exclude ::= NO OTHERS", | 171372 | /* 332 */ "filter_over ::= filter_clause over_clause", |
| 165649 | /* 333 */ "frame_exclude ::= CURRENT ROW", | 171373 | /* 333 */ "filter_over ::= over_clause", |
| 165650 | /* 334 */ "frame_exclude ::= GROUP|TIES", | 171374 | /* 334 */ "filter_over ::= filter_clause", |
| 165651 | /* 335 */ "window_clause ::= WINDOW windowdefn_list", | 171375 | /* 335 */ "over_clause ::= OVER LP window RP", |
| 165652 | /* 336 */ "filter_over ::= filter_clause over_clause", | 171376 | /* 336 */ "over_clause ::= OVER nm", |
| 165653 | /* 337 */ "filter_over ::= over_clause", | 171377 | /* 337 */ "filter_clause ::= FILTER LP WHERE expr RP", |
| 165654 | /* 338 */ "filter_over ::= filter_clause", | 171378 | /* 338 */ "input ::= cmdlist", |
| 165655 | /* 339 */ "over_clause ::= OVER LP window RP", | 171379 | /* 339 */ "cmdlist ::= cmdlist ecmd", |
| 165656 | /* 340 */ "over_clause ::= OVER nm", | 171380 | /* 340 */ "cmdlist ::= ecmd", |
| 165657 | /* 341 */ "filter_clause ::= FILTER LP WHERE expr RP", | 171381 | /* 341 */ "ecmd ::= SEMI", |
| 165658 | /* 342 */ "input ::= cmdlist", | 171382 | /* 342 */ "ecmd ::= cmdx SEMI", |
| 165659 | /* 343 */ "cmdlist ::= cmdlist ecmd", | 171383 | /* 343 */ "ecmd ::= explain cmdx SEMI", |
| 165660 | /* 344 */ "cmdlist ::= ecmd", | 171384 | /* 344 */ "trans_opt ::=", |
| 165661 | /* 345 */ "ecmd ::= SEMI", | 171385 | /* 345 */ "trans_opt ::= TRANSACTION", |
| 165662 | /* 346 */ "ecmd ::= cmdx SEMI", | 171386 | /* 346 */ "trans_opt ::= TRANSACTION nm", |
| 165663 | /* 347 */ "ecmd ::= explain cmdx SEMI", | 171387 | /* 347 */ "savepoint_opt ::= SAVEPOINT", |
| 165664 | /* 348 */ "trans_opt ::=", | 171388 | /* 348 */ "savepoint_opt ::=", |
| 165665 | /* 349 */ "trans_opt ::= TRANSACTION", | 171389 | /* 349 */ "cmd ::= create_table create_table_args", |
| 165666 | /* 350 */ "trans_opt ::= TRANSACTION nm", | 171390 | /* 350 */ "table_option_set ::= table_option", |
| 165667 | /* 351 */ "savepoint_opt ::= SAVEPOINT", | 171391 | /* 351 */ "columnlist ::= columnlist COMMA columnname carglist", |
| 165668 | /* 352 */ "savepoint_opt ::=", | 171392 | /* 352 */ "columnlist ::= columnname carglist", |
| 165669 | /* 353 */ "cmd ::= create_table create_table_args", | 171393 | /* 353 */ "nm ::= ID|INDEXED|JOIN_KW", |
| 165670 | /* 354 */ "table_option_set ::= table_option", | 171394 | /* 354 */ "nm ::= STRING", |
| 165671 | /* 355 */ "columnlist ::= columnlist COMMA columnname carglist", | 171395 | /* 355 */ "typetoken ::= typename", |
| 165672 | /* 356 */ "columnlist ::= columnname carglist", | 171396 | /* 356 */ "typename ::= ID|STRING", |
| 165673 | /* 357 */ "nm ::= ID|INDEXED", | 171397 | /* 357 */ "signed ::= plus_num", |
| 165674 | /* 358 */ "nm ::= STRING", | 171398 | /* 358 */ "signed ::= minus_num", |
| 165675 | /* 359 */ "nm ::= JOIN_KW", | 171399 | /* 359 */ "carglist ::= carglist ccons", |
| 165676 | /* 360 */ "typetoken ::= typename", | 171400 | /* 360 */ "carglist ::=", |
| 165677 | /* 361 */ "typename ::= ID|STRING", | 171401 | /* 361 */ "ccons ::= NULL onconf", |
| 165678 | /* 362 */ "signed ::= plus_num", | 171402 | /* 362 */ "ccons ::= GENERATED ALWAYS AS generated", |
| 165679 | /* 363 */ "signed ::= minus_num", | 171403 | /* 363 */ "ccons ::= AS generated", |
| 165680 | /* 364 */ "carglist ::= carglist ccons", | 171404 | /* 364 */ "conslist_opt ::= COMMA conslist", |
| 165681 | /* 365 */ "carglist ::=", | 171405 | /* 365 */ "conslist ::= conslist tconscomma tcons", |
| 165682 | /* 366 */ "ccons ::= NULL onconf", | 171406 | /* 366 */ "conslist ::= tcons", |
| 165683 | /* 367 */ "ccons ::= GENERATED ALWAYS AS generated", | 171407 | /* 367 */ "tconscomma ::=", |
| 165684 | /* 368 */ "ccons ::= AS generated", | 171408 | /* 368 */ "defer_subclause_opt ::= defer_subclause", |
| 165685 | /* 369 */ "conslist_opt ::= COMMA conslist", | 171409 | /* 369 */ "resolvetype ::= raisetype", |
| 165686 | /* 370 */ "conslist ::= conslist tconscomma tcons", | 171410 | /* 370 */ "selectnowith ::= oneselect", |
| 165687 | /* 371 */ "conslist ::= tcons", | 171411 | /* 371 */ "oneselect ::= values", |
| 165688 | /* 372 */ "tconscomma ::=", | 171412 | /* 372 */ "sclp ::= selcollist COMMA", |
| 165689 | /* 373 */ "defer_subclause_opt ::= defer_subclause", | 171413 | /* 373 */ "as ::= ID|STRING", |
| 165690 | /* 374 */ "resolvetype ::= raisetype", | 171414 | /* 374 */ "indexed_opt ::= indexed_by", |
| 165691 | /* 375 */ "selectnowith ::= oneselect", | 171415 | /* 375 */ "returning ::=", |
| 165692 | /* 376 */ "oneselect ::= values", | 171416 | /* 376 */ "expr ::= term", |
| 165693 | /* 377 */ "sclp ::= selcollist COMMA", | 171417 | /* 377 */ "likeop ::= LIKE_KW|MATCH", |
| 165694 | /* 378 */ "as ::= ID|STRING", | 171418 | /* 378 */ "case_operand ::= expr", |
| 165695 | /* 379 */ "indexed_opt ::= indexed_by", | 171419 | /* 379 */ "exprlist ::= nexprlist", |
| 165696 | /* 380 */ "returning ::=", | 171420 | /* 380 */ "nmnum ::= plus_num", |
| 165697 | /* 381 */ "expr ::= term", | 171421 | /* 381 */ "nmnum ::= nm", |
| 165698 | /* 382 */ "likeop ::= LIKE_KW|MATCH", | 171422 | /* 382 */ "nmnum ::= ON", |
| 165699 | /* 383 */ "exprlist ::= nexprlist", | 171423 | /* 383 */ "nmnum ::= DELETE", |
| 165700 | /* 384 */ "nmnum ::= plus_num", | 171424 | /* 384 */ "nmnum ::= DEFAULT", |
| 165701 | /* 385 */ "nmnum ::= nm", | 171425 | /* 385 */ "plus_num ::= INTEGER|FLOAT", |
| 165702 | /* 386 */ "nmnum ::= ON", | 171426 | /* 386 */ "foreach_clause ::=", |
| 165703 | /* 387 */ "nmnum ::= DELETE", | 171427 | /* 387 */ "foreach_clause ::= FOR EACH ROW", |
| 165704 | /* 388 */ "nmnum ::= DEFAULT", | 171428 | /* 388 */ "trnm ::= nm", |
| 165705 | /* 389 */ "plus_num ::= INTEGER|FLOAT", | 171429 | /* 389 */ "tridxby ::=", |
| 165706 | /* 390 */ "foreach_clause ::=", | 171430 | /* 390 */ "database_kw_opt ::= DATABASE", |
| 165707 | /* 391 */ "foreach_clause ::= FOR EACH ROW", | 171431 | /* 391 */ "database_kw_opt ::=", |
| 165708 | /* 392 */ "trnm ::= nm", | 171432 | /* 392 */ "kwcolumn_opt ::=", |
| 165709 | /* 393 */ "tridxby ::=", | 171433 | /* 393 */ "kwcolumn_opt ::= COLUMNKW", |
| 165710 | /* 394 */ "database_kw_opt ::= DATABASE", | 171434 | /* 394 */ "vtabarglist ::= vtabarg", |
| 165711 | /* 395 */ "database_kw_opt ::=", | 171435 | /* 395 */ "vtabarglist ::= vtabarglist COMMA vtabarg", |
| 165712 | /* 396 */ "kwcolumn_opt ::=", | 171436 | /* 396 */ "vtabarg ::= vtabarg vtabargtoken", |
| 165713 | /* 397 */ "kwcolumn_opt ::= COLUMNKW", | 171437 | /* 397 */ "anylist ::=", |
| 165714 | /* 398 */ "vtabarglist ::= vtabarg", | 171438 | /* 398 */ "anylist ::= anylist LP anylist RP", |
| 165715 | /* 399 */ "vtabarglist ::= vtabarglist COMMA vtabarg", | 171439 | /* 399 */ "anylist ::= anylist ANY", |
| 165716 | /* 400 */ "vtabarg ::= vtabarg vtabargtoken", | 171440 | /* 400 */ "with ::=", |
| 165717 | /* 401 */ "anylist ::=", | 171441 | /* 401 */ "windowdefn_list ::= windowdefn", |
| 165718 | /* 402 */ "anylist ::= anylist LP anylist RP", | 171442 | /* 402 */ "window ::= frame_opt", |
| 165719 | /* 403 */ "anylist ::= anylist ANY", | ||
| 165720 | /* 404 */ "with ::=", | ||
| 165721 | }; | 171443 | }; |
| 165722 | #endif /* NDEBUG */ | 171444 | #endif /* NDEBUG */ |
| 165723 | 171445 | ||
| @@ -166402,233 +172124,231 @@ static const YYCODETYPE yyRuleInfoLhs[] = { | |||
| 166402 | 263, /* (175) idlist ::= idlist COMMA nm */ | 172124 | 263, /* (175) idlist ::= idlist COMMA nm */ |
| 166403 | 263, /* (176) idlist ::= nm */ | 172125 | 263, /* (176) idlist ::= nm */ |
| 166404 | 217, /* (177) expr ::= LP expr RP */ | 172126 | 217, /* (177) expr ::= LP expr RP */ |
| 166405 | 217, /* (178) expr ::= ID|INDEXED */ | 172127 | 217, /* (178) expr ::= ID|INDEXED|JOIN_KW */ |
| 166406 | 217, /* (179) expr ::= JOIN_KW */ | 172128 | 217, /* (179) expr ::= nm DOT nm */ |
| 166407 | 217, /* (180) expr ::= nm DOT nm */ | 172129 | 217, /* (180) expr ::= nm DOT nm DOT nm */ |
| 166408 | 217, /* (181) expr ::= nm DOT nm DOT nm */ | 172130 | 216, /* (181) term ::= NULL|FLOAT|BLOB */ |
| 166409 | 216, /* (182) term ::= NULL|FLOAT|BLOB */ | 172131 | 216, /* (182) term ::= STRING */ |
| 166410 | 216, /* (183) term ::= STRING */ | 172132 | 216, /* (183) term ::= INTEGER */ |
| 166411 | 216, /* (184) term ::= INTEGER */ | 172133 | 217, /* (184) expr ::= VARIABLE */ |
| 166412 | 217, /* (185) expr ::= VARIABLE */ | 172134 | 217, /* (185) expr ::= expr COLLATE ID|STRING */ |
| 166413 | 217, /* (186) expr ::= expr COLLATE ID|STRING */ | 172135 | 217, /* (186) expr ::= CAST LP expr AS typetoken RP */ |
| 166414 | 217, /* (187) expr ::= CAST LP expr AS typetoken RP */ | 172136 | 217, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ |
| 166415 | 217, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ | 172137 | 217, /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ |
| 166416 | 217, /* (189) expr ::= ID|INDEXED LP STAR RP */ | 172138 | 217, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ |
| 166417 | 217, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ | 172139 | 217, /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ |
| 166418 | 217, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ | 172140 | 216, /* (191) term ::= CTIME_KW */ |
| 166419 | 216, /* (192) term ::= CTIME_KW */ | 172141 | 217, /* (192) expr ::= LP nexprlist COMMA expr RP */ |
| 166420 | 217, /* (193) expr ::= LP nexprlist COMMA expr RP */ | 172142 | 217, /* (193) expr ::= expr AND expr */ |
| 166421 | 217, /* (194) expr ::= expr AND expr */ | 172143 | 217, /* (194) expr ::= expr OR expr */ |
| 166422 | 217, /* (195) expr ::= expr OR expr */ | 172144 | 217, /* (195) expr ::= expr LT|GT|GE|LE expr */ |
| 166423 | 217, /* (196) expr ::= expr LT|GT|GE|LE expr */ | 172145 | 217, /* (196) expr ::= expr EQ|NE expr */ |
| 166424 | 217, /* (197) expr ::= expr EQ|NE expr */ | 172146 | 217, /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ |
| 166425 | 217, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ | 172147 | 217, /* (198) expr ::= expr PLUS|MINUS expr */ |
| 166426 | 217, /* (199) expr ::= expr PLUS|MINUS expr */ | 172148 | 217, /* (199) expr ::= expr STAR|SLASH|REM expr */ |
| 166427 | 217, /* (200) expr ::= expr STAR|SLASH|REM expr */ | 172149 | 217, /* (200) expr ::= expr CONCAT expr */ |
| 166428 | 217, /* (201) expr ::= expr CONCAT expr */ | 172150 | 274, /* (201) likeop ::= NOT LIKE_KW|MATCH */ |
| 166429 | 274, /* (202) likeop ::= NOT LIKE_KW|MATCH */ | 172151 | 217, /* (202) expr ::= expr likeop expr */ |
| 166430 | 217, /* (203) expr ::= expr likeop expr */ | 172152 | 217, /* (203) expr ::= expr likeop expr ESCAPE expr */ |
| 166431 | 217, /* (204) expr ::= expr likeop expr ESCAPE expr */ | 172153 | 217, /* (204) expr ::= expr ISNULL|NOTNULL */ |
| 166432 | 217, /* (205) expr ::= expr ISNULL|NOTNULL */ | 172154 | 217, /* (205) expr ::= expr NOT NULL */ |
| 166433 | 217, /* (206) expr ::= expr NOT NULL */ | 172155 | 217, /* (206) expr ::= expr IS expr */ |
| 166434 | 217, /* (207) expr ::= expr IS expr */ | 172156 | 217, /* (207) expr ::= expr IS NOT expr */ |
| 166435 | 217, /* (208) expr ::= expr IS NOT expr */ | 172157 | 217, /* (208) expr ::= expr IS NOT DISTINCT FROM expr */ |
| 166436 | 217, /* (209) expr ::= expr IS NOT DISTINCT FROM expr */ | 172158 | 217, /* (209) expr ::= expr IS DISTINCT FROM expr */ |
| 166437 | 217, /* (210) expr ::= expr IS DISTINCT FROM expr */ | 172159 | 217, /* (210) expr ::= NOT expr */ |
| 166438 | 217, /* (211) expr ::= NOT expr */ | 172160 | 217, /* (211) expr ::= BITNOT expr */ |
| 166439 | 217, /* (212) expr ::= BITNOT expr */ | 172161 | 217, /* (212) expr ::= PLUS|MINUS expr */ |
| 166440 | 217, /* (213) expr ::= PLUS|MINUS expr */ | 172162 | 217, /* (213) expr ::= expr PTR expr */ |
| 166441 | 217, /* (214) expr ::= expr PTR expr */ | 172163 | 275, /* (214) between_op ::= BETWEEN */ |
| 166442 | 275, /* (215) between_op ::= BETWEEN */ | 172164 | 275, /* (215) between_op ::= NOT BETWEEN */ |
| 166443 | 275, /* (216) between_op ::= NOT BETWEEN */ | 172165 | 217, /* (216) expr ::= expr between_op expr AND expr */ |
| 166444 | 217, /* (217) expr ::= expr between_op expr AND expr */ | 172166 | 276, /* (217) in_op ::= IN */ |
| 166445 | 276, /* (218) in_op ::= IN */ | 172167 | 276, /* (218) in_op ::= NOT IN */ |
| 166446 | 276, /* (219) in_op ::= NOT IN */ | 172168 | 217, /* (219) expr ::= expr in_op LP exprlist RP */ |
| 166447 | 217, /* (220) expr ::= expr in_op LP exprlist RP */ | 172169 | 217, /* (220) expr ::= LP select RP */ |
| 166448 | 217, /* (221) expr ::= LP select RP */ | 172170 | 217, /* (221) expr ::= expr in_op LP select RP */ |
| 166449 | 217, /* (222) expr ::= expr in_op LP select RP */ | 172171 | 217, /* (222) expr ::= expr in_op nm dbnm paren_exprlist */ |
| 166450 | 217, /* (223) expr ::= expr in_op nm dbnm paren_exprlist */ | 172172 | 217, /* (223) expr ::= EXISTS LP select RP */ |
| 166451 | 217, /* (224) expr ::= EXISTS LP select RP */ | 172173 | 217, /* (224) expr ::= CASE case_operand case_exprlist case_else END */ |
| 166452 | 217, /* (225) expr ::= CASE case_operand case_exprlist case_else END */ | 172174 | 279, /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */ |
| 166453 | 279, /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */ | 172175 | 279, /* (226) case_exprlist ::= WHEN expr THEN expr */ |
| 166454 | 279, /* (227) case_exprlist ::= WHEN expr THEN expr */ | 172176 | 280, /* (227) case_else ::= ELSE expr */ |
| 166455 | 280, /* (228) case_else ::= ELSE expr */ | 172177 | 280, /* (228) case_else ::= */ |
| 166456 | 280, /* (229) case_else ::= */ | 172178 | 278, /* (229) case_operand ::= */ |
| 166457 | 278, /* (230) case_operand ::= expr */ | 172179 | 261, /* (230) exprlist ::= */ |
| 166458 | 278, /* (231) case_operand ::= */ | 172180 | 253, /* (231) nexprlist ::= nexprlist COMMA expr */ |
| 166459 | 261, /* (232) exprlist ::= */ | 172181 | 253, /* (232) nexprlist ::= expr */ |
| 166460 | 253, /* (233) nexprlist ::= nexprlist COMMA expr */ | 172182 | 277, /* (233) paren_exprlist ::= */ |
| 166461 | 253, /* (234) nexprlist ::= expr */ | 172183 | 277, /* (234) paren_exprlist ::= LP exprlist RP */ |
| 166462 | 277, /* (235) paren_exprlist ::= */ | 172184 | 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ |
| 166463 | 277, /* (236) paren_exprlist ::= LP exprlist RP */ | 172185 | 281, /* (236) uniqueflag ::= UNIQUE */ |
| 166464 | 190, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ | 172186 | 281, /* (237) uniqueflag ::= */ |
| 166465 | 281, /* (238) uniqueflag ::= UNIQUE */ | 172187 | 221, /* (238) eidlist_opt ::= */ |
| 166466 | 281, /* (239) uniqueflag ::= */ | 172188 | 221, /* (239) eidlist_opt ::= LP eidlist RP */ |
| 166467 | 221, /* (240) eidlist_opt ::= */ | 172189 | 232, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ |
| 166468 | 221, /* (241) eidlist_opt ::= LP eidlist RP */ | 172190 | 232, /* (241) eidlist ::= nm collate sortorder */ |
| 166469 | 232, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ | 172191 | 282, /* (242) collate ::= */ |
| 166470 | 232, /* (243) eidlist ::= nm collate sortorder */ | 172192 | 282, /* (243) collate ::= COLLATE ID|STRING */ |
| 166471 | 282, /* (244) collate ::= */ | 172193 | 190, /* (244) cmd ::= DROP INDEX ifexists fullname */ |
| 166472 | 282, /* (245) collate ::= COLLATE ID|STRING */ | 172194 | 190, /* (245) cmd ::= VACUUM vinto */ |
| 166473 | 190, /* (246) cmd ::= DROP INDEX ifexists fullname */ | 172195 | 190, /* (246) cmd ::= VACUUM nm vinto */ |
| 166474 | 190, /* (247) cmd ::= VACUUM vinto */ | 172196 | 283, /* (247) vinto ::= INTO expr */ |
| 166475 | 190, /* (248) cmd ::= VACUUM nm vinto */ | 172197 | 283, /* (248) vinto ::= */ |
| 166476 | 283, /* (249) vinto ::= INTO expr */ | 172198 | 190, /* (249) cmd ::= PRAGMA nm dbnm */ |
| 166477 | 283, /* (250) vinto ::= */ | 172199 | 190, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ |
| 166478 | 190, /* (251) cmd ::= PRAGMA nm dbnm */ | 172200 | 190, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ |
| 166479 | 190, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ | 172201 | 190, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ |
| 166480 | 190, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ | 172202 | 190, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ |
| 166481 | 190, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ | 172203 | 211, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ |
| 166482 | 190, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ | 172204 | 212, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ |
| 166483 | 211, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ | 172205 | 190, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ |
| 166484 | 212, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ | 172206 | 285, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ |
| 166485 | 190, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ | 172207 | 287, /* (258) trigger_time ::= BEFORE|AFTER */ |
| 166486 | 285, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ | 172208 | 287, /* (259) trigger_time ::= INSTEAD OF */ |
| 166487 | 287, /* (260) trigger_time ::= BEFORE|AFTER */ | 172209 | 287, /* (260) trigger_time ::= */ |
| 166488 | 287, /* (261) trigger_time ::= INSTEAD OF */ | 172210 | 288, /* (261) trigger_event ::= DELETE|INSERT */ |
| 166489 | 287, /* (262) trigger_time ::= */ | 172211 | 288, /* (262) trigger_event ::= UPDATE */ |
| 166490 | 288, /* (263) trigger_event ::= DELETE|INSERT */ | 172212 | 288, /* (263) trigger_event ::= UPDATE OF idlist */ |
| 166491 | 288, /* (264) trigger_event ::= UPDATE */ | 172213 | 290, /* (264) when_clause ::= */ |
| 166492 | 288, /* (265) trigger_event ::= UPDATE OF idlist */ | 172214 | 290, /* (265) when_clause ::= WHEN expr */ |
| 166493 | 290, /* (266) when_clause ::= */ | 172215 | 286, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ |
| 166494 | 290, /* (267) when_clause ::= WHEN expr */ | 172216 | 286, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ |
| 166495 | 286, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ | 172217 | 292, /* (268) trnm ::= nm DOT nm */ |
| 166496 | 286, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ | 172218 | 293, /* (269) tridxby ::= INDEXED BY nm */ |
| 166497 | 292, /* (270) trnm ::= nm DOT nm */ | 172219 | 293, /* (270) tridxby ::= NOT INDEXED */ |
| 166498 | 293, /* (271) tridxby ::= INDEXED BY nm */ | 172220 | 291, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ |
| 166499 | 293, /* (272) tridxby ::= NOT INDEXED */ | 172221 | 291, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ |
| 166500 | 291, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ | 172222 | 291, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ |
| 166501 | 291, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ | 172223 | 291, /* (274) trigger_cmd ::= scanpt select scanpt */ |
| 166502 | 291, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ | 172224 | 217, /* (275) expr ::= RAISE LP IGNORE RP */ |
| 166503 | 291, /* (276) trigger_cmd ::= scanpt select scanpt */ | 172225 | 217, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ |
| 166504 | 217, /* (277) expr ::= RAISE LP IGNORE RP */ | 172226 | 236, /* (277) raisetype ::= ROLLBACK */ |
| 166505 | 217, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ | 172227 | 236, /* (278) raisetype ::= ABORT */ |
| 166506 | 236, /* (279) raisetype ::= ROLLBACK */ | 172228 | 236, /* (279) raisetype ::= FAIL */ |
| 166507 | 236, /* (280) raisetype ::= ABORT */ | 172229 | 190, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ |
| 166508 | 236, /* (281) raisetype ::= FAIL */ | 172230 | 190, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ |
| 166509 | 190, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ | 172231 | 190, /* (282) cmd ::= DETACH database_kw_opt expr */ |
| 166510 | 190, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ | 172232 | 295, /* (283) key_opt ::= */ |
| 166511 | 190, /* (284) cmd ::= DETACH database_kw_opt expr */ | 172233 | 295, /* (284) key_opt ::= KEY expr */ |
| 166512 | 295, /* (285) key_opt ::= */ | 172234 | 190, /* (285) cmd ::= REINDEX */ |
| 166513 | 295, /* (286) key_opt ::= KEY expr */ | 172235 | 190, /* (286) cmd ::= REINDEX nm dbnm */ |
| 166514 | 190, /* (287) cmd ::= REINDEX */ | 172236 | 190, /* (287) cmd ::= ANALYZE */ |
| 166515 | 190, /* (288) cmd ::= REINDEX nm dbnm */ | 172237 | 190, /* (288) cmd ::= ANALYZE nm dbnm */ |
| 166516 | 190, /* (289) cmd ::= ANALYZE */ | 172238 | 190, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ |
| 166517 | 190, /* (290) cmd ::= ANALYZE nm dbnm */ | 172239 | 190, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ |
| 166518 | 190, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ | 172240 | 190, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ |
| 166519 | 190, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ | 172241 | 296, /* (292) add_column_fullname ::= fullname */ |
| 166520 | 190, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ | 172242 | 190, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ |
| 166521 | 296, /* (294) add_column_fullname ::= fullname */ | 172243 | 190, /* (294) cmd ::= create_vtab */ |
| 166522 | 190, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ | 172244 | 190, /* (295) cmd ::= create_vtab LP vtabarglist RP */ |
| 166523 | 190, /* (296) cmd ::= create_vtab */ | 172245 | 298, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ |
| 166524 | 190, /* (297) cmd ::= create_vtab LP vtabarglist RP */ | 172246 | 300, /* (297) vtabarg ::= */ |
| 166525 | 298, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ | 172247 | 301, /* (298) vtabargtoken ::= ANY */ |
| 166526 | 300, /* (299) vtabarg ::= */ | 172248 | 301, /* (299) vtabargtoken ::= lp anylist RP */ |
| 166527 | 301, /* (300) vtabargtoken ::= ANY */ | 172249 | 302, /* (300) lp ::= LP */ |
| 166528 | 301, /* (301) vtabargtoken ::= lp anylist RP */ | 172250 | 266, /* (301) with ::= WITH wqlist */ |
| 166529 | 302, /* (302) lp ::= LP */ | 172251 | 266, /* (302) with ::= WITH RECURSIVE wqlist */ |
| 166530 | 266, /* (303) with ::= WITH wqlist */ | 172252 | 305, /* (303) wqas ::= AS */ |
| 166531 | 266, /* (304) with ::= WITH RECURSIVE wqlist */ | 172253 | 305, /* (304) wqas ::= AS MATERIALIZED */ |
| 166532 | 305, /* (305) wqas ::= AS */ | 172254 | 305, /* (305) wqas ::= AS NOT MATERIALIZED */ |
| 166533 | 305, /* (306) wqas ::= AS MATERIALIZED */ | 172255 | 304, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ |
| 166534 | 305, /* (307) wqas ::= AS NOT MATERIALIZED */ | 172256 | 241, /* (307) wqlist ::= wqitem */ |
| 166535 | 304, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ | 172257 | 241, /* (308) wqlist ::= wqlist COMMA wqitem */ |
| 166536 | 241, /* (309) wqlist ::= wqitem */ | 172258 | 306, /* (309) windowdefn_list ::= windowdefn_list COMMA windowdefn */ |
| 166537 | 241, /* (310) wqlist ::= wqlist COMMA wqitem */ | 172259 | 307, /* (310) windowdefn ::= nm AS LP window RP */ |
| 166538 | 306, /* (311) windowdefn_list ::= windowdefn */ | 172260 | 308, /* (311) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ |
| 166539 | 306, /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */ | 172261 | 308, /* (312) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ |
| 166540 | 307, /* (313) windowdefn ::= nm AS LP window RP */ | 172262 | 308, /* (313) window ::= ORDER BY sortlist frame_opt */ |
| 166541 | 308, /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ | 172263 | 308, /* (314) window ::= nm ORDER BY sortlist frame_opt */ |
| 166542 | 308, /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ | 172264 | 308, /* (315) window ::= nm frame_opt */ |
| 166543 | 308, /* (316) window ::= ORDER BY sortlist frame_opt */ | 172265 | 309, /* (316) frame_opt ::= */ |
| 166544 | 308, /* (317) window ::= nm ORDER BY sortlist frame_opt */ | 172266 | 309, /* (317) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ |
| 166545 | 308, /* (318) window ::= frame_opt */ | 172267 | 309, /* (318) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ |
| 166546 | 308, /* (319) window ::= nm frame_opt */ | 172268 | 313, /* (319) range_or_rows ::= RANGE|ROWS|GROUPS */ |
| 166547 | 309, /* (320) frame_opt ::= */ | 172269 | 315, /* (320) frame_bound_s ::= frame_bound */ |
| 166548 | 309, /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ | 172270 | 315, /* (321) frame_bound_s ::= UNBOUNDED PRECEDING */ |
| 166549 | 309, /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ | 172271 | 316, /* (322) frame_bound_e ::= frame_bound */ |
| 166550 | 313, /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */ | 172272 | 316, /* (323) frame_bound_e ::= UNBOUNDED FOLLOWING */ |
| 166551 | 315, /* (324) frame_bound_s ::= frame_bound */ | 172273 | 314, /* (324) frame_bound ::= expr PRECEDING|FOLLOWING */ |
| 166552 | 315, /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */ | 172274 | 314, /* (325) frame_bound ::= CURRENT ROW */ |
| 166553 | 316, /* (326) frame_bound_e ::= frame_bound */ | 172275 | 317, /* (326) frame_exclude_opt ::= */ |
| 166554 | 316, /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */ | 172276 | 317, /* (327) frame_exclude_opt ::= EXCLUDE frame_exclude */ |
| 166555 | 314, /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */ | 172277 | 318, /* (328) frame_exclude ::= NO OTHERS */ |
| 166556 | 314, /* (329) frame_bound ::= CURRENT ROW */ | 172278 | 318, /* (329) frame_exclude ::= CURRENT ROW */ |
| 166557 | 317, /* (330) frame_exclude_opt ::= */ | 172279 | 318, /* (330) frame_exclude ::= GROUP|TIES */ |
| 166558 | 317, /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */ | 172280 | 251, /* (331) window_clause ::= WINDOW windowdefn_list */ |
| 166559 | 318, /* (332) frame_exclude ::= NO OTHERS */ | 172281 | 273, /* (332) filter_over ::= filter_clause over_clause */ |
| 166560 | 318, /* (333) frame_exclude ::= CURRENT ROW */ | 172282 | 273, /* (333) filter_over ::= over_clause */ |
| 166561 | 318, /* (334) frame_exclude ::= GROUP|TIES */ | 172283 | 273, /* (334) filter_over ::= filter_clause */ |
| 166562 | 251, /* (335) window_clause ::= WINDOW windowdefn_list */ | 172284 | 312, /* (335) over_clause ::= OVER LP window RP */ |
| 166563 | 273, /* (336) filter_over ::= filter_clause over_clause */ | 172285 | 312, /* (336) over_clause ::= OVER nm */ |
| 166564 | 273, /* (337) filter_over ::= over_clause */ | 172286 | 311, /* (337) filter_clause ::= FILTER LP WHERE expr RP */ |
| 166565 | 273, /* (338) filter_over ::= filter_clause */ | 172287 | 185, /* (338) input ::= cmdlist */ |
| 166566 | 312, /* (339) over_clause ::= OVER LP window RP */ | 172288 | 186, /* (339) cmdlist ::= cmdlist ecmd */ |
| 166567 | 312, /* (340) over_clause ::= OVER nm */ | 172289 | 186, /* (340) cmdlist ::= ecmd */ |
| 166568 | 311, /* (341) filter_clause ::= FILTER LP WHERE expr RP */ | 172290 | 187, /* (341) ecmd ::= SEMI */ |
| 166569 | 185, /* (342) input ::= cmdlist */ | 172291 | 187, /* (342) ecmd ::= cmdx SEMI */ |
| 166570 | 186, /* (343) cmdlist ::= cmdlist ecmd */ | 172292 | 187, /* (343) ecmd ::= explain cmdx SEMI */ |
| 166571 | 186, /* (344) cmdlist ::= ecmd */ | 172293 | 192, /* (344) trans_opt ::= */ |
| 166572 | 187, /* (345) ecmd ::= SEMI */ | 172294 | 192, /* (345) trans_opt ::= TRANSACTION */ |
| 166573 | 187, /* (346) ecmd ::= cmdx SEMI */ | 172295 | 192, /* (346) trans_opt ::= TRANSACTION nm */ |
| 166574 | 187, /* (347) ecmd ::= explain cmdx SEMI */ | 172296 | 194, /* (347) savepoint_opt ::= SAVEPOINT */ |
| 166575 | 192, /* (348) trans_opt ::= */ | 172297 | 194, /* (348) savepoint_opt ::= */ |
| 166576 | 192, /* (349) trans_opt ::= TRANSACTION */ | 172298 | 190, /* (349) cmd ::= create_table create_table_args */ |
| 166577 | 192, /* (350) trans_opt ::= TRANSACTION nm */ | 172299 | 203, /* (350) table_option_set ::= table_option */ |
| 166578 | 194, /* (351) savepoint_opt ::= SAVEPOINT */ | 172300 | 201, /* (351) columnlist ::= columnlist COMMA columnname carglist */ |
| 166579 | 194, /* (352) savepoint_opt ::= */ | 172301 | 201, /* (352) columnlist ::= columnname carglist */ |
| 166580 | 190, /* (353) cmd ::= create_table create_table_args */ | 172302 | 193, /* (353) nm ::= ID|INDEXED|JOIN_KW */ |
| 166581 | 203, /* (354) table_option_set ::= table_option */ | 172303 | 193, /* (354) nm ::= STRING */ |
| 166582 | 201, /* (355) columnlist ::= columnlist COMMA columnname carglist */ | 172304 | 208, /* (355) typetoken ::= typename */ |
| 166583 | 201, /* (356) columnlist ::= columnname carglist */ | 172305 | 209, /* (356) typename ::= ID|STRING */ |
| 166584 | 193, /* (357) nm ::= ID|INDEXED */ | 172306 | 210, /* (357) signed ::= plus_num */ |
| 166585 | 193, /* (358) nm ::= STRING */ | 172307 | 210, /* (358) signed ::= minus_num */ |
| 166586 | 193, /* (359) nm ::= JOIN_KW */ | 172308 | 207, /* (359) carglist ::= carglist ccons */ |
| 166587 | 208, /* (360) typetoken ::= typename */ | 172309 | 207, /* (360) carglist ::= */ |
| 166588 | 209, /* (361) typename ::= ID|STRING */ | 172310 | 215, /* (361) ccons ::= NULL onconf */ |
| 166589 | 210, /* (362) signed ::= plus_num */ | 172311 | 215, /* (362) ccons ::= GENERATED ALWAYS AS generated */ |
| 166590 | 210, /* (363) signed ::= minus_num */ | 172312 | 215, /* (363) ccons ::= AS generated */ |
| 166591 | 207, /* (364) carglist ::= carglist ccons */ | 172313 | 202, /* (364) conslist_opt ::= COMMA conslist */ |
| 166592 | 207, /* (365) carglist ::= */ | 172314 | 228, /* (365) conslist ::= conslist tconscomma tcons */ |
| 166593 | 215, /* (366) ccons ::= NULL onconf */ | 172315 | 228, /* (366) conslist ::= tcons */ |
| 166594 | 215, /* (367) ccons ::= GENERATED ALWAYS AS generated */ | 172316 | 229, /* (367) tconscomma ::= */ |
| 166595 | 215, /* (368) ccons ::= AS generated */ | 172317 | 233, /* (368) defer_subclause_opt ::= defer_subclause */ |
| 166596 | 202, /* (369) conslist_opt ::= COMMA conslist */ | 172318 | 235, /* (369) resolvetype ::= raisetype */ |
| 166597 | 228, /* (370) conslist ::= conslist tconscomma tcons */ | 172319 | 239, /* (370) selectnowith ::= oneselect */ |
| 166598 | 228, /* (371) conslist ::= tcons */ | 172320 | 240, /* (371) oneselect ::= values */ |
| 166599 | 229, /* (372) tconscomma ::= */ | 172321 | 254, /* (372) sclp ::= selcollist COMMA */ |
| 166600 | 233, /* (373) defer_subclause_opt ::= defer_subclause */ | 172322 | 255, /* (373) as ::= ID|STRING */ |
| 166601 | 235, /* (374) resolvetype ::= raisetype */ | 172323 | 264, /* (374) indexed_opt ::= indexed_by */ |
| 166602 | 239, /* (375) selectnowith ::= oneselect */ | 172324 | 272, /* (375) returning ::= */ |
| 166603 | 240, /* (376) oneselect ::= values */ | 172325 | 217, /* (376) expr ::= term */ |
| 166604 | 254, /* (377) sclp ::= selcollist COMMA */ | 172326 | 274, /* (377) likeop ::= LIKE_KW|MATCH */ |
| 166605 | 255, /* (378) as ::= ID|STRING */ | 172327 | 278, /* (378) case_operand ::= expr */ |
| 166606 | 264, /* (379) indexed_opt ::= indexed_by */ | 172328 | 261, /* (379) exprlist ::= nexprlist */ |
| 166607 | 272, /* (380) returning ::= */ | 172329 | 284, /* (380) nmnum ::= plus_num */ |
| 166608 | 217, /* (381) expr ::= term */ | 172330 | 284, /* (381) nmnum ::= nm */ |
| 166609 | 274, /* (382) likeop ::= LIKE_KW|MATCH */ | 172331 | 284, /* (382) nmnum ::= ON */ |
| 166610 | 261, /* (383) exprlist ::= nexprlist */ | 172332 | 284, /* (383) nmnum ::= DELETE */ |
| 166611 | 284, /* (384) nmnum ::= plus_num */ | 172333 | 284, /* (384) nmnum ::= DEFAULT */ |
| 166612 | 284, /* (385) nmnum ::= nm */ | 172334 | 211, /* (385) plus_num ::= INTEGER|FLOAT */ |
| 166613 | 284, /* (386) nmnum ::= ON */ | 172335 | 289, /* (386) foreach_clause ::= */ |
| 166614 | 284, /* (387) nmnum ::= DELETE */ | 172336 | 289, /* (387) foreach_clause ::= FOR EACH ROW */ |
| 166615 | 284, /* (388) nmnum ::= DEFAULT */ | 172337 | 292, /* (388) trnm ::= nm */ |
| 166616 | 211, /* (389) plus_num ::= INTEGER|FLOAT */ | 172338 | 293, /* (389) tridxby ::= */ |
| 166617 | 289, /* (390) foreach_clause ::= */ | 172339 | 294, /* (390) database_kw_opt ::= DATABASE */ |
| 166618 | 289, /* (391) foreach_clause ::= FOR EACH ROW */ | 172340 | 294, /* (391) database_kw_opt ::= */ |
| 166619 | 292, /* (392) trnm ::= nm */ | 172341 | 297, /* (392) kwcolumn_opt ::= */ |
| 166620 | 293, /* (393) tridxby ::= */ | 172342 | 297, /* (393) kwcolumn_opt ::= COLUMNKW */ |
| 166621 | 294, /* (394) database_kw_opt ::= DATABASE */ | 172343 | 299, /* (394) vtabarglist ::= vtabarg */ |
| 166622 | 294, /* (395) database_kw_opt ::= */ | 172344 | 299, /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ |
| 166623 | 297, /* (396) kwcolumn_opt ::= */ | 172345 | 300, /* (396) vtabarg ::= vtabarg vtabargtoken */ |
| 166624 | 297, /* (397) kwcolumn_opt ::= COLUMNKW */ | 172346 | 303, /* (397) anylist ::= */ |
| 166625 | 299, /* (398) vtabarglist ::= vtabarg */ | 172347 | 303, /* (398) anylist ::= anylist LP anylist RP */ |
| 166626 | 299, /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ | 172348 | 303, /* (399) anylist ::= anylist ANY */ |
| 166627 | 300, /* (400) vtabarg ::= vtabarg vtabargtoken */ | 172349 | 266, /* (400) with ::= */ |
| 166628 | 303, /* (401) anylist ::= */ | 172350 | 306, /* (401) windowdefn_list ::= windowdefn */ |
| 166629 | 303, /* (402) anylist ::= anylist LP anylist RP */ | 172351 | 308, /* (402) window ::= frame_opt */ |
| 166630 | 303, /* (403) anylist ::= anylist ANY */ | ||
| 166631 | 266, /* (404) with ::= */ | ||
| 166632 | }; | 172352 | }; |
| 166633 | 172353 | ||
| 166634 | /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number | 172354 | /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number |
| @@ -166812,233 +172532,231 @@ static const signed char yyRuleInfoNRhs[] = { | |||
| 166812 | -3, /* (175) idlist ::= idlist COMMA nm */ | 172532 | -3, /* (175) idlist ::= idlist COMMA nm */ |
| 166813 | -1, /* (176) idlist ::= nm */ | 172533 | -1, /* (176) idlist ::= nm */ |
| 166814 | -3, /* (177) expr ::= LP expr RP */ | 172534 | -3, /* (177) expr ::= LP expr RP */ |
| 166815 | -1, /* (178) expr ::= ID|INDEXED */ | 172535 | -1, /* (178) expr ::= ID|INDEXED|JOIN_KW */ |
| 166816 | -1, /* (179) expr ::= JOIN_KW */ | 172536 | -3, /* (179) expr ::= nm DOT nm */ |
| 166817 | -3, /* (180) expr ::= nm DOT nm */ | 172537 | -5, /* (180) expr ::= nm DOT nm DOT nm */ |
| 166818 | -5, /* (181) expr ::= nm DOT nm DOT nm */ | 172538 | -1, /* (181) term ::= NULL|FLOAT|BLOB */ |
| 166819 | -1, /* (182) term ::= NULL|FLOAT|BLOB */ | 172539 | -1, /* (182) term ::= STRING */ |
| 166820 | -1, /* (183) term ::= STRING */ | 172540 | -1, /* (183) term ::= INTEGER */ |
| 166821 | -1, /* (184) term ::= INTEGER */ | 172541 | -1, /* (184) expr ::= VARIABLE */ |
| 166822 | -1, /* (185) expr ::= VARIABLE */ | 172542 | -3, /* (185) expr ::= expr COLLATE ID|STRING */ |
| 166823 | -3, /* (186) expr ::= expr COLLATE ID|STRING */ | 172543 | -6, /* (186) expr ::= CAST LP expr AS typetoken RP */ |
| 166824 | -6, /* (187) expr ::= CAST LP expr AS typetoken RP */ | 172544 | -5, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ |
| 166825 | -5, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ | 172545 | -4, /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ |
| 166826 | -4, /* (189) expr ::= ID|INDEXED LP STAR RP */ | 172546 | -6, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ |
| 166827 | -6, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ | 172547 | -5, /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ |
| 166828 | -5, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ | 172548 | -1, /* (191) term ::= CTIME_KW */ |
| 166829 | -1, /* (192) term ::= CTIME_KW */ | 172549 | -5, /* (192) expr ::= LP nexprlist COMMA expr RP */ |
| 166830 | -5, /* (193) expr ::= LP nexprlist COMMA expr RP */ | 172550 | -3, /* (193) expr ::= expr AND expr */ |
| 166831 | -3, /* (194) expr ::= expr AND expr */ | 172551 | -3, /* (194) expr ::= expr OR expr */ |
| 166832 | -3, /* (195) expr ::= expr OR expr */ | 172552 | -3, /* (195) expr ::= expr LT|GT|GE|LE expr */ |
| 166833 | -3, /* (196) expr ::= expr LT|GT|GE|LE expr */ | 172553 | -3, /* (196) expr ::= expr EQ|NE expr */ |
| 166834 | -3, /* (197) expr ::= expr EQ|NE expr */ | 172554 | -3, /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ |
| 166835 | -3, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ | 172555 | -3, /* (198) expr ::= expr PLUS|MINUS expr */ |
| 166836 | -3, /* (199) expr ::= expr PLUS|MINUS expr */ | 172556 | -3, /* (199) expr ::= expr STAR|SLASH|REM expr */ |
| 166837 | -3, /* (200) expr ::= expr STAR|SLASH|REM expr */ | 172557 | -3, /* (200) expr ::= expr CONCAT expr */ |
| 166838 | -3, /* (201) expr ::= expr CONCAT expr */ | 172558 | -2, /* (201) likeop ::= NOT LIKE_KW|MATCH */ |
| 166839 | -2, /* (202) likeop ::= NOT LIKE_KW|MATCH */ | 172559 | -3, /* (202) expr ::= expr likeop expr */ |
| 166840 | -3, /* (203) expr ::= expr likeop expr */ | 172560 | -5, /* (203) expr ::= expr likeop expr ESCAPE expr */ |
| 166841 | -5, /* (204) expr ::= expr likeop expr ESCAPE expr */ | 172561 | -2, /* (204) expr ::= expr ISNULL|NOTNULL */ |
| 166842 | -2, /* (205) expr ::= expr ISNULL|NOTNULL */ | 172562 | -3, /* (205) expr ::= expr NOT NULL */ |
| 166843 | -3, /* (206) expr ::= expr NOT NULL */ | 172563 | -3, /* (206) expr ::= expr IS expr */ |
| 166844 | -3, /* (207) expr ::= expr IS expr */ | 172564 | -4, /* (207) expr ::= expr IS NOT expr */ |
| 166845 | -4, /* (208) expr ::= expr IS NOT expr */ | 172565 | -6, /* (208) expr ::= expr IS NOT DISTINCT FROM expr */ |
| 166846 | -6, /* (209) expr ::= expr IS NOT DISTINCT FROM expr */ | 172566 | -5, /* (209) expr ::= expr IS DISTINCT FROM expr */ |
| 166847 | -5, /* (210) expr ::= expr IS DISTINCT FROM expr */ | 172567 | -2, /* (210) expr ::= NOT expr */ |
| 166848 | -2, /* (211) expr ::= NOT expr */ | 172568 | -2, /* (211) expr ::= BITNOT expr */ |
| 166849 | -2, /* (212) expr ::= BITNOT expr */ | 172569 | -2, /* (212) expr ::= PLUS|MINUS expr */ |
| 166850 | -2, /* (213) expr ::= PLUS|MINUS expr */ | 172570 | -3, /* (213) expr ::= expr PTR expr */ |
| 166851 | -3, /* (214) expr ::= expr PTR expr */ | 172571 | -1, /* (214) between_op ::= BETWEEN */ |
| 166852 | -1, /* (215) between_op ::= BETWEEN */ | 172572 | -2, /* (215) between_op ::= NOT BETWEEN */ |
| 166853 | -2, /* (216) between_op ::= NOT BETWEEN */ | 172573 | -5, /* (216) expr ::= expr between_op expr AND expr */ |
| 166854 | -5, /* (217) expr ::= expr between_op expr AND expr */ | 172574 | -1, /* (217) in_op ::= IN */ |
| 166855 | -1, /* (218) in_op ::= IN */ | 172575 | -2, /* (218) in_op ::= NOT IN */ |
| 166856 | -2, /* (219) in_op ::= NOT IN */ | 172576 | -5, /* (219) expr ::= expr in_op LP exprlist RP */ |
| 166857 | -5, /* (220) expr ::= expr in_op LP exprlist RP */ | 172577 | -3, /* (220) expr ::= LP select RP */ |
| 166858 | -3, /* (221) expr ::= LP select RP */ | 172578 | -5, /* (221) expr ::= expr in_op LP select RP */ |
| 166859 | -5, /* (222) expr ::= expr in_op LP select RP */ | 172579 | -5, /* (222) expr ::= expr in_op nm dbnm paren_exprlist */ |
| 166860 | -5, /* (223) expr ::= expr in_op nm dbnm paren_exprlist */ | 172580 | -4, /* (223) expr ::= EXISTS LP select RP */ |
| 166861 | -4, /* (224) expr ::= EXISTS LP select RP */ | 172581 | -5, /* (224) expr ::= CASE case_operand case_exprlist case_else END */ |
| 166862 | -5, /* (225) expr ::= CASE case_operand case_exprlist case_else END */ | 172582 | -5, /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */ |
| 166863 | -5, /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */ | 172583 | -4, /* (226) case_exprlist ::= WHEN expr THEN expr */ |
| 166864 | -4, /* (227) case_exprlist ::= WHEN expr THEN expr */ | 172584 | -2, /* (227) case_else ::= ELSE expr */ |
| 166865 | -2, /* (228) case_else ::= ELSE expr */ | 172585 | 0, /* (228) case_else ::= */ |
| 166866 | 0, /* (229) case_else ::= */ | 172586 | 0, /* (229) case_operand ::= */ |
| 166867 | -1, /* (230) case_operand ::= expr */ | 172587 | 0, /* (230) exprlist ::= */ |
| 166868 | 0, /* (231) case_operand ::= */ | 172588 | -3, /* (231) nexprlist ::= nexprlist COMMA expr */ |
| 166869 | 0, /* (232) exprlist ::= */ | 172589 | -1, /* (232) nexprlist ::= expr */ |
| 166870 | -3, /* (233) nexprlist ::= nexprlist COMMA expr */ | 172590 | 0, /* (233) paren_exprlist ::= */ |
| 166871 | -1, /* (234) nexprlist ::= expr */ | 172591 | -3, /* (234) paren_exprlist ::= LP exprlist RP */ |
| 166872 | 0, /* (235) paren_exprlist ::= */ | 172592 | -12, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ |
| 166873 | -3, /* (236) paren_exprlist ::= LP exprlist RP */ | 172593 | -1, /* (236) uniqueflag ::= UNIQUE */ |
| 166874 | -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ | 172594 | 0, /* (237) uniqueflag ::= */ |
| 166875 | -1, /* (238) uniqueflag ::= UNIQUE */ | 172595 | 0, /* (238) eidlist_opt ::= */ |
| 166876 | 0, /* (239) uniqueflag ::= */ | 172596 | -3, /* (239) eidlist_opt ::= LP eidlist RP */ |
| 166877 | 0, /* (240) eidlist_opt ::= */ | 172597 | -5, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ |
| 166878 | -3, /* (241) eidlist_opt ::= LP eidlist RP */ | 172598 | -3, /* (241) eidlist ::= nm collate sortorder */ |
| 166879 | -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ | 172599 | 0, /* (242) collate ::= */ |
| 166880 | -3, /* (243) eidlist ::= nm collate sortorder */ | 172600 | -2, /* (243) collate ::= COLLATE ID|STRING */ |
| 166881 | 0, /* (244) collate ::= */ | 172601 | -4, /* (244) cmd ::= DROP INDEX ifexists fullname */ |
| 166882 | -2, /* (245) collate ::= COLLATE ID|STRING */ | 172602 | -2, /* (245) cmd ::= VACUUM vinto */ |
| 166883 | -4, /* (246) cmd ::= DROP INDEX ifexists fullname */ | 172603 | -3, /* (246) cmd ::= VACUUM nm vinto */ |
| 166884 | -2, /* (247) cmd ::= VACUUM vinto */ | 172604 | -2, /* (247) vinto ::= INTO expr */ |
| 166885 | -3, /* (248) cmd ::= VACUUM nm vinto */ | 172605 | 0, /* (248) vinto ::= */ |
| 166886 | -2, /* (249) vinto ::= INTO expr */ | 172606 | -3, /* (249) cmd ::= PRAGMA nm dbnm */ |
| 166887 | 0, /* (250) vinto ::= */ | 172607 | -5, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ |
| 166888 | -3, /* (251) cmd ::= PRAGMA nm dbnm */ | 172608 | -6, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ |
| 166889 | -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ | 172609 | -5, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ |
| 166890 | -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ | 172610 | -6, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ |
| 166891 | -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ | 172611 | -2, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ |
| 166892 | -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ | 172612 | -2, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ |
| 166893 | -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ | 172613 | -5, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ |
| 166894 | -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ | 172614 | -11, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ |
| 166895 | -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ | 172615 | -1, /* (258) trigger_time ::= BEFORE|AFTER */ |
| 166896 | -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ | 172616 | -2, /* (259) trigger_time ::= INSTEAD OF */ |
| 166897 | -1, /* (260) trigger_time ::= BEFORE|AFTER */ | 172617 | 0, /* (260) trigger_time ::= */ |
| 166898 | -2, /* (261) trigger_time ::= INSTEAD OF */ | 172618 | -1, /* (261) trigger_event ::= DELETE|INSERT */ |
| 166899 | 0, /* (262) trigger_time ::= */ | 172619 | -1, /* (262) trigger_event ::= UPDATE */ |
| 166900 | -1, /* (263) trigger_event ::= DELETE|INSERT */ | 172620 | -3, /* (263) trigger_event ::= UPDATE OF idlist */ |
| 166901 | -1, /* (264) trigger_event ::= UPDATE */ | 172621 | 0, /* (264) when_clause ::= */ |
| 166902 | -3, /* (265) trigger_event ::= UPDATE OF idlist */ | 172622 | -2, /* (265) when_clause ::= WHEN expr */ |
| 166903 | 0, /* (266) when_clause ::= */ | 172623 | -3, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ |
| 166904 | -2, /* (267) when_clause ::= WHEN expr */ | 172624 | -2, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ |
| 166905 | -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ | 172625 | -3, /* (268) trnm ::= nm DOT nm */ |
| 166906 | -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ | 172626 | -3, /* (269) tridxby ::= INDEXED BY nm */ |
| 166907 | -3, /* (270) trnm ::= nm DOT nm */ | 172627 | -2, /* (270) tridxby ::= NOT INDEXED */ |
| 166908 | -3, /* (271) tridxby ::= INDEXED BY nm */ | 172628 | -9, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ |
| 166909 | -2, /* (272) tridxby ::= NOT INDEXED */ | 172629 | -8, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ |
| 166910 | -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ | 172630 | -6, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ |
| 166911 | -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ | 172631 | -3, /* (274) trigger_cmd ::= scanpt select scanpt */ |
| 166912 | -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ | 172632 | -4, /* (275) expr ::= RAISE LP IGNORE RP */ |
| 166913 | -3, /* (276) trigger_cmd ::= scanpt select scanpt */ | 172633 | -6, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ |
| 166914 | -4, /* (277) expr ::= RAISE LP IGNORE RP */ | 172634 | -1, /* (277) raisetype ::= ROLLBACK */ |
| 166915 | -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ | 172635 | -1, /* (278) raisetype ::= ABORT */ |
| 166916 | -1, /* (279) raisetype ::= ROLLBACK */ | 172636 | -1, /* (279) raisetype ::= FAIL */ |
| 166917 | -1, /* (280) raisetype ::= ABORT */ | 172637 | -4, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ |
| 166918 | -1, /* (281) raisetype ::= FAIL */ | 172638 | -6, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ |
| 166919 | -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ | 172639 | -3, /* (282) cmd ::= DETACH database_kw_opt expr */ |
| 166920 | -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ | 172640 | 0, /* (283) key_opt ::= */ |
| 166921 | -3, /* (284) cmd ::= DETACH database_kw_opt expr */ | 172641 | -2, /* (284) key_opt ::= KEY expr */ |
| 166922 | 0, /* (285) key_opt ::= */ | 172642 | -1, /* (285) cmd ::= REINDEX */ |
| 166923 | -2, /* (286) key_opt ::= KEY expr */ | 172643 | -3, /* (286) cmd ::= REINDEX nm dbnm */ |
| 166924 | -1, /* (287) cmd ::= REINDEX */ | 172644 | -1, /* (287) cmd ::= ANALYZE */ |
| 166925 | -3, /* (288) cmd ::= REINDEX nm dbnm */ | 172645 | -3, /* (288) cmd ::= ANALYZE nm dbnm */ |
| 166926 | -1, /* (289) cmd ::= ANALYZE */ | 172646 | -6, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ |
| 166927 | -3, /* (290) cmd ::= ANALYZE nm dbnm */ | 172647 | -7, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ |
| 166928 | -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ | 172648 | -6, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ |
| 166929 | -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ | 172649 | -1, /* (292) add_column_fullname ::= fullname */ |
| 166930 | -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ | 172650 | -8, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ |
| 166931 | -1, /* (294) add_column_fullname ::= fullname */ | 172651 | -1, /* (294) cmd ::= create_vtab */ |
| 166932 | -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ | 172652 | -4, /* (295) cmd ::= create_vtab LP vtabarglist RP */ |
| 166933 | -1, /* (296) cmd ::= create_vtab */ | 172653 | -8, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ |
| 166934 | -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */ | 172654 | 0, /* (297) vtabarg ::= */ |
| 166935 | -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ | 172655 | -1, /* (298) vtabargtoken ::= ANY */ |
| 166936 | 0, /* (299) vtabarg ::= */ | 172656 | -3, /* (299) vtabargtoken ::= lp anylist RP */ |
| 166937 | -1, /* (300) vtabargtoken ::= ANY */ | 172657 | -1, /* (300) lp ::= LP */ |
| 166938 | -3, /* (301) vtabargtoken ::= lp anylist RP */ | 172658 | -2, /* (301) with ::= WITH wqlist */ |
| 166939 | -1, /* (302) lp ::= LP */ | 172659 | -3, /* (302) with ::= WITH RECURSIVE wqlist */ |
| 166940 | -2, /* (303) with ::= WITH wqlist */ | 172660 | -1, /* (303) wqas ::= AS */ |
| 166941 | -3, /* (304) with ::= WITH RECURSIVE wqlist */ | 172661 | -2, /* (304) wqas ::= AS MATERIALIZED */ |
| 166942 | -1, /* (305) wqas ::= AS */ | 172662 | -3, /* (305) wqas ::= AS NOT MATERIALIZED */ |
| 166943 | -2, /* (306) wqas ::= AS MATERIALIZED */ | 172663 | -6, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ |
| 166944 | -3, /* (307) wqas ::= AS NOT MATERIALIZED */ | 172664 | -1, /* (307) wqlist ::= wqitem */ |
| 166945 | -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ | 172665 | -3, /* (308) wqlist ::= wqlist COMMA wqitem */ |
| 166946 | -1, /* (309) wqlist ::= wqitem */ | 172666 | -3, /* (309) windowdefn_list ::= windowdefn_list COMMA windowdefn */ |
| 166947 | -3, /* (310) wqlist ::= wqlist COMMA wqitem */ | 172667 | -5, /* (310) windowdefn ::= nm AS LP window RP */ |
| 166948 | -1, /* (311) windowdefn_list ::= windowdefn */ | 172668 | -5, /* (311) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ |
| 166949 | -3, /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */ | 172669 | -6, /* (312) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ |
| 166950 | -5, /* (313) windowdefn ::= nm AS LP window RP */ | 172670 | -4, /* (313) window ::= ORDER BY sortlist frame_opt */ |
| 166951 | -5, /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ | 172671 | -5, /* (314) window ::= nm ORDER BY sortlist frame_opt */ |
| 166952 | -6, /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ | 172672 | -2, /* (315) window ::= nm frame_opt */ |
| 166953 | -4, /* (316) window ::= ORDER BY sortlist frame_opt */ | 172673 | 0, /* (316) frame_opt ::= */ |
| 166954 | -5, /* (317) window ::= nm ORDER BY sortlist frame_opt */ | 172674 | -3, /* (317) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ |
| 166955 | -1, /* (318) window ::= frame_opt */ | 172675 | -6, /* (318) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ |
| 166956 | -2, /* (319) window ::= nm frame_opt */ | 172676 | -1, /* (319) range_or_rows ::= RANGE|ROWS|GROUPS */ |
| 166957 | 0, /* (320) frame_opt ::= */ | 172677 | -1, /* (320) frame_bound_s ::= frame_bound */ |
| 166958 | -3, /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ | 172678 | -2, /* (321) frame_bound_s ::= UNBOUNDED PRECEDING */ |
| 166959 | -6, /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ | 172679 | -1, /* (322) frame_bound_e ::= frame_bound */ |
| 166960 | -1, /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */ | 172680 | -2, /* (323) frame_bound_e ::= UNBOUNDED FOLLOWING */ |
| 166961 | -1, /* (324) frame_bound_s ::= frame_bound */ | 172681 | -2, /* (324) frame_bound ::= expr PRECEDING|FOLLOWING */ |
| 166962 | -2, /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */ | 172682 | -2, /* (325) frame_bound ::= CURRENT ROW */ |
| 166963 | -1, /* (326) frame_bound_e ::= frame_bound */ | 172683 | 0, /* (326) frame_exclude_opt ::= */ |
| 166964 | -2, /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */ | 172684 | -2, /* (327) frame_exclude_opt ::= EXCLUDE frame_exclude */ |
| 166965 | -2, /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */ | 172685 | -2, /* (328) frame_exclude ::= NO OTHERS */ |
| 166966 | -2, /* (329) frame_bound ::= CURRENT ROW */ | 172686 | -2, /* (329) frame_exclude ::= CURRENT ROW */ |
| 166967 | 0, /* (330) frame_exclude_opt ::= */ | 172687 | -1, /* (330) frame_exclude ::= GROUP|TIES */ |
| 166968 | -2, /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */ | 172688 | -2, /* (331) window_clause ::= WINDOW windowdefn_list */ |
| 166969 | -2, /* (332) frame_exclude ::= NO OTHERS */ | 172689 | -2, /* (332) filter_over ::= filter_clause over_clause */ |
| 166970 | -2, /* (333) frame_exclude ::= CURRENT ROW */ | 172690 | -1, /* (333) filter_over ::= over_clause */ |
| 166971 | -1, /* (334) frame_exclude ::= GROUP|TIES */ | 172691 | -1, /* (334) filter_over ::= filter_clause */ |
| 166972 | -2, /* (335) window_clause ::= WINDOW windowdefn_list */ | 172692 | -4, /* (335) over_clause ::= OVER LP window RP */ |
| 166973 | -2, /* (336) filter_over ::= filter_clause over_clause */ | 172693 | -2, /* (336) over_clause ::= OVER nm */ |
| 166974 | -1, /* (337) filter_over ::= over_clause */ | 172694 | -5, /* (337) filter_clause ::= FILTER LP WHERE expr RP */ |
| 166975 | -1, /* (338) filter_over ::= filter_clause */ | 172695 | -1, /* (338) input ::= cmdlist */ |
| 166976 | -4, /* (339) over_clause ::= OVER LP window RP */ | 172696 | -2, /* (339) cmdlist ::= cmdlist ecmd */ |
| 166977 | -2, /* (340) over_clause ::= OVER nm */ | 172697 | -1, /* (340) cmdlist ::= ecmd */ |
| 166978 | -5, /* (341) filter_clause ::= FILTER LP WHERE expr RP */ | 172698 | -1, /* (341) ecmd ::= SEMI */ |
| 166979 | -1, /* (342) input ::= cmdlist */ | 172699 | -2, /* (342) ecmd ::= cmdx SEMI */ |
| 166980 | -2, /* (343) cmdlist ::= cmdlist ecmd */ | 172700 | -3, /* (343) ecmd ::= explain cmdx SEMI */ |
| 166981 | -1, /* (344) cmdlist ::= ecmd */ | 172701 | 0, /* (344) trans_opt ::= */ |
| 166982 | -1, /* (345) ecmd ::= SEMI */ | 172702 | -1, /* (345) trans_opt ::= TRANSACTION */ |
| 166983 | -2, /* (346) ecmd ::= cmdx SEMI */ | 172703 | -2, /* (346) trans_opt ::= TRANSACTION nm */ |
| 166984 | -3, /* (347) ecmd ::= explain cmdx SEMI */ | 172704 | -1, /* (347) savepoint_opt ::= SAVEPOINT */ |
| 166985 | 0, /* (348) trans_opt ::= */ | 172705 | 0, /* (348) savepoint_opt ::= */ |
| 166986 | -1, /* (349) trans_opt ::= TRANSACTION */ | 172706 | -2, /* (349) cmd ::= create_table create_table_args */ |
| 166987 | -2, /* (350) trans_opt ::= TRANSACTION nm */ | 172707 | -1, /* (350) table_option_set ::= table_option */ |
| 166988 | -1, /* (351) savepoint_opt ::= SAVEPOINT */ | 172708 | -4, /* (351) columnlist ::= columnlist COMMA columnname carglist */ |
| 166989 | 0, /* (352) savepoint_opt ::= */ | 172709 | -2, /* (352) columnlist ::= columnname carglist */ |
| 166990 | -2, /* (353) cmd ::= create_table create_table_args */ | 172710 | -1, /* (353) nm ::= ID|INDEXED|JOIN_KW */ |
| 166991 | -1, /* (354) table_option_set ::= table_option */ | 172711 | -1, /* (354) nm ::= STRING */ |
| 166992 | -4, /* (355) columnlist ::= columnlist COMMA columnname carglist */ | 172712 | -1, /* (355) typetoken ::= typename */ |
| 166993 | -2, /* (356) columnlist ::= columnname carglist */ | 172713 | -1, /* (356) typename ::= ID|STRING */ |
| 166994 | -1, /* (357) nm ::= ID|INDEXED */ | 172714 | -1, /* (357) signed ::= plus_num */ |
| 166995 | -1, /* (358) nm ::= STRING */ | 172715 | -1, /* (358) signed ::= minus_num */ |
| 166996 | -1, /* (359) nm ::= JOIN_KW */ | 172716 | -2, /* (359) carglist ::= carglist ccons */ |
| 166997 | -1, /* (360) typetoken ::= typename */ | 172717 | 0, /* (360) carglist ::= */ |
| 166998 | -1, /* (361) typename ::= ID|STRING */ | 172718 | -2, /* (361) ccons ::= NULL onconf */ |
| 166999 | -1, /* (362) signed ::= plus_num */ | 172719 | -4, /* (362) ccons ::= GENERATED ALWAYS AS generated */ |
| 167000 | -1, /* (363) signed ::= minus_num */ | 172720 | -2, /* (363) ccons ::= AS generated */ |
| 167001 | -2, /* (364) carglist ::= carglist ccons */ | 172721 | -2, /* (364) conslist_opt ::= COMMA conslist */ |
| 167002 | 0, /* (365) carglist ::= */ | 172722 | -3, /* (365) conslist ::= conslist tconscomma tcons */ |
| 167003 | -2, /* (366) ccons ::= NULL onconf */ | 172723 | -1, /* (366) conslist ::= tcons */ |
| 167004 | -4, /* (367) ccons ::= GENERATED ALWAYS AS generated */ | 172724 | 0, /* (367) tconscomma ::= */ |
| 167005 | -2, /* (368) ccons ::= AS generated */ | 172725 | -1, /* (368) defer_subclause_opt ::= defer_subclause */ |
| 167006 | -2, /* (369) conslist_opt ::= COMMA conslist */ | 172726 | -1, /* (369) resolvetype ::= raisetype */ |
| 167007 | -3, /* (370) conslist ::= conslist tconscomma tcons */ | 172727 | -1, /* (370) selectnowith ::= oneselect */ |
| 167008 | -1, /* (371) conslist ::= tcons */ | 172728 | -1, /* (371) oneselect ::= values */ |
| 167009 | 0, /* (372) tconscomma ::= */ | 172729 | -2, /* (372) sclp ::= selcollist COMMA */ |
| 167010 | -1, /* (373) defer_subclause_opt ::= defer_subclause */ | 172730 | -1, /* (373) as ::= ID|STRING */ |
| 167011 | -1, /* (374) resolvetype ::= raisetype */ | 172731 | -1, /* (374) indexed_opt ::= indexed_by */ |
| 167012 | -1, /* (375) selectnowith ::= oneselect */ | 172732 | 0, /* (375) returning ::= */ |
| 167013 | -1, /* (376) oneselect ::= values */ | 172733 | -1, /* (376) expr ::= term */ |
| 167014 | -2, /* (377) sclp ::= selcollist COMMA */ | 172734 | -1, /* (377) likeop ::= LIKE_KW|MATCH */ |
| 167015 | -1, /* (378) as ::= ID|STRING */ | 172735 | -1, /* (378) case_operand ::= expr */ |
| 167016 | -1, /* (379) indexed_opt ::= indexed_by */ | 172736 | -1, /* (379) exprlist ::= nexprlist */ |
| 167017 | 0, /* (380) returning ::= */ | 172737 | -1, /* (380) nmnum ::= plus_num */ |
| 167018 | -1, /* (381) expr ::= term */ | 172738 | -1, /* (381) nmnum ::= nm */ |
| 167019 | -1, /* (382) likeop ::= LIKE_KW|MATCH */ | 172739 | -1, /* (382) nmnum ::= ON */ |
| 167020 | -1, /* (383) exprlist ::= nexprlist */ | 172740 | -1, /* (383) nmnum ::= DELETE */ |
| 167021 | -1, /* (384) nmnum ::= plus_num */ | 172741 | -1, /* (384) nmnum ::= DEFAULT */ |
| 167022 | -1, /* (385) nmnum ::= nm */ | 172742 | -1, /* (385) plus_num ::= INTEGER|FLOAT */ |
| 167023 | -1, /* (386) nmnum ::= ON */ | 172743 | 0, /* (386) foreach_clause ::= */ |
| 167024 | -1, /* (387) nmnum ::= DELETE */ | 172744 | -3, /* (387) foreach_clause ::= FOR EACH ROW */ |
| 167025 | -1, /* (388) nmnum ::= DEFAULT */ | 172745 | -1, /* (388) trnm ::= nm */ |
| 167026 | -1, /* (389) plus_num ::= INTEGER|FLOAT */ | 172746 | 0, /* (389) tridxby ::= */ |
| 167027 | 0, /* (390) foreach_clause ::= */ | 172747 | -1, /* (390) database_kw_opt ::= DATABASE */ |
| 167028 | -3, /* (391) foreach_clause ::= FOR EACH ROW */ | 172748 | 0, /* (391) database_kw_opt ::= */ |
| 167029 | -1, /* (392) trnm ::= nm */ | 172749 | 0, /* (392) kwcolumn_opt ::= */ |
| 167030 | 0, /* (393) tridxby ::= */ | 172750 | -1, /* (393) kwcolumn_opt ::= COLUMNKW */ |
| 167031 | -1, /* (394) database_kw_opt ::= DATABASE */ | 172751 | -1, /* (394) vtabarglist ::= vtabarg */ |
| 167032 | 0, /* (395) database_kw_opt ::= */ | 172752 | -3, /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ |
| 167033 | 0, /* (396) kwcolumn_opt ::= */ | 172753 | -2, /* (396) vtabarg ::= vtabarg vtabargtoken */ |
| 167034 | -1, /* (397) kwcolumn_opt ::= COLUMNKW */ | 172754 | 0, /* (397) anylist ::= */ |
| 167035 | -1, /* (398) vtabarglist ::= vtabarg */ | 172755 | -4, /* (398) anylist ::= anylist LP anylist RP */ |
| 167036 | -3, /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ | 172756 | -2, /* (399) anylist ::= anylist ANY */ |
| 167037 | -2, /* (400) vtabarg ::= vtabarg vtabargtoken */ | 172757 | 0, /* (400) with ::= */ |
| 167038 | 0, /* (401) anylist ::= */ | 172758 | -1, /* (401) windowdefn_list ::= windowdefn */ |
| 167039 | -4, /* (402) anylist ::= anylist LP anylist RP */ | 172759 | -1, /* (402) window ::= frame_opt */ |
| 167040 | -2, /* (403) anylist ::= anylist ANY */ | ||
| 167041 | 0, /* (404) with ::= */ | ||
| 167042 | }; | 172760 | }; |
| 167043 | 172761 | ||
| 167044 | static void yy_accept(yyParser*); /* Forward Declaration */ | 172762 | static void yy_accept(yyParser*); /* Forward Declaration */ |
| @@ -167081,10 +172799,10 @@ static YYACTIONTYPE yy_reduce( | |||
| 167081 | /********** Begin reduce actions **********************************************/ | 172799 | /********** Begin reduce actions **********************************************/ |
| 167082 | YYMINORTYPE yylhsminor; | 172800 | YYMINORTYPE yylhsminor; |
| 167083 | case 0: /* explain ::= EXPLAIN */ | 172801 | case 0: /* explain ::= EXPLAIN */ |
| 167084 | { pParse->explain = 1; } | 172802 | { if( pParse->pReprepare==0 ) pParse->explain = 1; } |
| 167085 | break; | 172803 | break; |
| 167086 | case 1: /* explain ::= EXPLAIN QUERY PLAN */ | 172804 | case 1: /* explain ::= EXPLAIN QUERY PLAN */ |
| 167087 | { pParse->explain = 2; } | 172805 | { if( pParse->pReprepare==0 ) pParse->explain = 2; } |
| 167088 | break; | 172806 | break; |
| 167089 | case 2: /* cmdx ::= cmd */ | 172807 | case 2: /* cmdx ::= cmd */ |
| 167090 | { sqlite3FinishCoding(pParse); } | 172808 | { sqlite3FinishCoding(pParse); } |
| @@ -167098,7 +172816,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 167098 | case 5: /* transtype ::= DEFERRED */ | 172816 | case 5: /* transtype ::= DEFERRED */ |
| 167099 | case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); | 172817 | case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); |
| 167100 | case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); | 172818 | case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); |
| 167101 | case 323: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==323); | 172819 | case 319: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==319); |
| 167102 | {yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} | 172820 | {yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} |
| 167103 | break; | 172821 | break; |
| 167104 | case 8: /* cmd ::= COMMIT|END trans_opt */ | 172822 | case 8: /* cmd ::= COMMIT|END trans_opt */ |
| @@ -167135,7 +172853,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 167135 | case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); | 172853 | case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); |
| 167136 | case 81: /* ifexists ::= */ yytestcase(yyruleno==81); | 172854 | case 81: /* ifexists ::= */ yytestcase(yyruleno==81); |
| 167137 | case 98: /* distinct ::= */ yytestcase(yyruleno==98); | 172855 | case 98: /* distinct ::= */ yytestcase(yyruleno==98); |
| 167138 | case 244: /* collate ::= */ yytestcase(yyruleno==244); | 172856 | case 242: /* collate ::= */ yytestcase(yyruleno==242); |
| 167139 | {yymsp[1].minor.yy394 = 0;} | 172857 | {yymsp[1].minor.yy394 = 0;} |
| 167140 | break; | 172858 | break; |
| 167141 | case 16: /* ifnotexists ::= IF NOT EXISTS */ | 172859 | case 16: /* ifnotexists ::= IF NOT EXISTS */ |
| @@ -167319,9 +173037,9 @@ static YYACTIONTYPE yy_reduce( | |||
| 167319 | break; | 173037 | break; |
| 167320 | case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ | 173038 | case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ |
| 167321 | case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); | 173039 | case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); |
| 167322 | case 216: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==216); | 173040 | case 215: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==215); |
| 167323 | case 219: /* in_op ::= NOT IN */ yytestcase(yyruleno==219); | 173041 | case 218: /* in_op ::= NOT IN */ yytestcase(yyruleno==218); |
| 167324 | case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245); | 173042 | case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243); |
| 167325 | {yymsp[-1].minor.yy394 = 1;} | 173043 | {yymsp[-1].minor.yy394 = 1;} |
| 167326 | break; | 173044 | break; |
| 167327 | case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ | 173045 | case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ |
| @@ -167394,7 +173112,6 @@ static YYACTIONTYPE yy_reduce( | |||
| 167394 | if( p ){ | 173112 | if( p ){ |
| 167395 | parserDoubleLinkSelect(pParse, p); | 173113 | parserDoubleLinkSelect(pParse, p); |
| 167396 | } | 173114 | } |
| 167397 | yymsp[0].minor.yy47 = p; /*A-overwrites-X*/ | ||
| 167398 | } | 173115 | } |
| 167399 | break; | 173116 | break; |
| 167400 | case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ | 173117 | case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ |
| @@ -167471,9 +173188,9 @@ static YYACTIONTYPE yy_reduce( | |||
| 167471 | case 99: /* sclp ::= */ | 173188 | case 99: /* sclp ::= */ |
| 167472 | case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); | 173189 | case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); |
| 167473 | case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); | 173190 | case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); |
| 167474 | case 232: /* exprlist ::= */ yytestcase(yyruleno==232); | 173191 | case 230: /* exprlist ::= */ yytestcase(yyruleno==230); |
| 167475 | case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235); | 173192 | case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233); |
| 167476 | case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240); | 173193 | case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238); |
| 167477 | {yymsp[1].minor.yy322 = 0;} | 173194 | {yymsp[1].minor.yy322 = 0;} |
| 167478 | break; | 173195 | break; |
| 167479 | case 100: /* selcollist ::= sclp scanpt expr scanpt as */ | 173196 | case 100: /* selcollist ::= sclp scanpt expr scanpt as */ |
| @@ -167486,21 +173203,24 @@ static YYACTIONTYPE yy_reduce( | |||
| 167486 | case 101: /* selcollist ::= sclp scanpt STAR */ | 173203 | case 101: /* selcollist ::= sclp scanpt STAR */ |
| 167487 | { | 173204 | { |
| 167488 | Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); | 173205 | Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); |
| 173206 | sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); | ||
| 167489 | yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p); | 173207 | yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p); |
| 167490 | } | 173208 | } |
| 167491 | break; | 173209 | break; |
| 167492 | case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ | 173210 | case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ |
| 167493 | { | 173211 | { |
| 167494 | Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); | 173212 | Expr *pRight, *pLeft, *pDot; |
| 167495 | Expr *pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); | 173213 | pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); |
| 167496 | Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); | 173214 | sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); |
| 173215 | pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); | ||
| 173216 | pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); | ||
| 167497 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); | 173217 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); |
| 167498 | } | 173218 | } |
| 167499 | break; | 173219 | break; |
| 167500 | case 103: /* as ::= AS nm */ | 173220 | case 103: /* as ::= AS nm */ |
| 167501 | case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); | 173221 | case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); |
| 167502 | case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256); | 173222 | case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254); |
| 167503 | case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257); | 173223 | case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255); |
| 167504 | {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} | 173224 | {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} |
| 167505 | break; | 173225 | break; |
| 167506 | case 105: /* from ::= */ | 173226 | case 105: /* from ::= */ |
| @@ -167544,7 +173264,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 167544 | { | 173264 | { |
| 167545 | if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){ | 173265 | if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){ |
| 167546 | yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131; | 173266 | yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131; |
| 167547 | }else if( yymsp[-3].minor.yy131->nSrc==1 ){ | 173267 | }else if( ALWAYS(yymsp[-3].minor.yy131!=0) && yymsp[-3].minor.yy131->nSrc==1 ){ |
| 167548 | yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); | 173268 | yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561); |
| 167549 | if( yymsp[-5].minor.yy131 ){ | 173269 | if( yymsp[-5].minor.yy131 ){ |
| 167550 | SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1]; | 173270 | SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1]; |
| @@ -167672,16 +173392,16 @@ static YYACTIONTYPE yy_reduce( | |||
| 167672 | case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); | 173392 | case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); |
| 167673 | case 151: /* where_opt ::= */ yytestcase(yyruleno==151); | 173393 | case 151: /* where_opt ::= */ yytestcase(yyruleno==151); |
| 167674 | case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); | 173394 | case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); |
| 167675 | case 229: /* case_else ::= */ yytestcase(yyruleno==229); | 173395 | case 228: /* case_else ::= */ yytestcase(yyruleno==228); |
| 167676 | case 231: /* case_operand ::= */ yytestcase(yyruleno==231); | 173396 | case 229: /* case_operand ::= */ yytestcase(yyruleno==229); |
| 167677 | case 250: /* vinto ::= */ yytestcase(yyruleno==250); | 173397 | case 248: /* vinto ::= */ yytestcase(yyruleno==248); |
| 167678 | {yymsp[1].minor.yy528 = 0;} | 173398 | {yymsp[1].minor.yy528 = 0;} |
| 167679 | break; | 173399 | break; |
| 167680 | case 145: /* having_opt ::= HAVING expr */ | 173400 | case 145: /* having_opt ::= HAVING expr */ |
| 167681 | case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); | 173401 | case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); |
| 167682 | case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); | 173402 | case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); |
| 167683 | case 228: /* case_else ::= ELSE expr */ yytestcase(yyruleno==228); | 173403 | case 227: /* case_else ::= ELSE expr */ yytestcase(yyruleno==227); |
| 167684 | case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249); | 173404 | case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247); |
| 167685 | {yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} | 173405 | {yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} |
| 167686 | break; | 173406 | break; |
| 167687 | case 147: /* limit_opt ::= LIMIT expr */ | 173407 | case 147: /* limit_opt ::= LIMIT expr */ |
| @@ -167793,11 +173513,10 @@ static YYACTIONTYPE yy_reduce( | |||
| 167793 | case 177: /* expr ::= LP expr RP */ | 173513 | case 177: /* expr ::= LP expr RP */ |
| 167794 | {yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} | 173514 | {yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} |
| 167795 | break; | 173515 | break; |
| 167796 | case 178: /* expr ::= ID|INDEXED */ | 173516 | case 178: /* expr ::= ID|INDEXED|JOIN_KW */ |
| 167797 | case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179); | ||
| 167798 | {yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} | 173517 | {yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} |
| 167799 | break; | 173518 | break; |
| 167800 | case 180: /* expr ::= nm DOT nm */ | 173519 | case 179: /* expr ::= nm DOT nm */ |
| 167801 | { | 173520 | { |
| 167802 | Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); | 173521 | Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); |
| 167803 | Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); | 173522 | Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); |
| @@ -167805,7 +173524,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 167805 | } | 173524 | } |
| 167806 | yymsp[-2].minor.yy528 = yylhsminor.yy528; | 173525 | yymsp[-2].minor.yy528 = yylhsminor.yy528; |
| 167807 | break; | 173526 | break; |
| 167808 | case 181: /* expr ::= nm DOT nm DOT nm */ | 173527 | case 180: /* expr ::= nm DOT nm DOT nm */ |
| 167809 | { | 173528 | { |
| 167810 | Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); | 173529 | Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); |
| 167811 | Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); | 173530 | Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); |
| @@ -167818,18 +173537,18 @@ static YYACTIONTYPE yy_reduce( | |||
| 167818 | } | 173537 | } |
| 167819 | yymsp[-4].minor.yy528 = yylhsminor.yy528; | 173538 | yymsp[-4].minor.yy528 = yylhsminor.yy528; |
| 167820 | break; | 173539 | break; |
| 167821 | case 182: /* term ::= NULL|FLOAT|BLOB */ | 173540 | case 181: /* term ::= NULL|FLOAT|BLOB */ |
| 167822 | case 183: /* term ::= STRING */ yytestcase(yyruleno==183); | 173541 | case 182: /* term ::= STRING */ yytestcase(yyruleno==182); |
| 167823 | {yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} | 173542 | {yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} |
| 167824 | break; | 173543 | break; |
| 167825 | case 184: /* term ::= INTEGER */ | 173544 | case 183: /* term ::= INTEGER */ |
| 167826 | { | 173545 | { |
| 167827 | yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); | 173546 | yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); |
| 167828 | if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); | 173547 | if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); |
| 167829 | } | 173548 | } |
| 167830 | yymsp[0].minor.yy528 = yylhsminor.yy528; | 173549 | yymsp[0].minor.yy528 = yylhsminor.yy528; |
| 167831 | break; | 173550 | break; |
| 167832 | case 185: /* expr ::= VARIABLE */ | 173551 | case 184: /* expr ::= VARIABLE */ |
| 167833 | { | 173552 | { |
| 167834 | if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ | 173553 | if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ |
| 167835 | u32 n = yymsp[0].minor.yy0.n; | 173554 | u32 n = yymsp[0].minor.yy0.n; |
| @@ -167851,50 +173570,50 @@ static YYACTIONTYPE yy_reduce( | |||
| 167851 | } | 173570 | } |
| 167852 | } | 173571 | } |
| 167853 | break; | 173572 | break; |
| 167854 | case 186: /* expr ::= expr COLLATE ID|STRING */ | 173573 | case 185: /* expr ::= expr COLLATE ID|STRING */ |
| 167855 | { | 173574 | { |
| 167856 | yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); | 173575 | yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); |
| 167857 | } | 173576 | } |
| 167858 | break; | 173577 | break; |
| 167859 | case 187: /* expr ::= CAST LP expr AS typetoken RP */ | 173578 | case 186: /* expr ::= CAST LP expr AS typetoken RP */ |
| 167860 | { | 173579 | { |
| 167861 | yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); | 173580 | yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); |
| 167862 | sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); | 173581 | sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); |
| 167863 | } | 173582 | } |
| 167864 | break; | 173583 | break; |
| 167865 | case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP */ | 173584 | case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ |
| 167866 | { | 173585 | { |
| 167867 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); | 173586 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); |
| 167868 | } | 173587 | } |
| 167869 | yymsp[-4].minor.yy528 = yylhsminor.yy528; | 173588 | yymsp[-4].minor.yy528 = yylhsminor.yy528; |
| 167870 | break; | 173589 | break; |
| 167871 | case 189: /* expr ::= ID|INDEXED LP STAR RP */ | 173590 | case 188: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ |
| 167872 | { | 173591 | { |
| 167873 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); | 173592 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); |
| 167874 | } | 173593 | } |
| 167875 | yymsp[-3].minor.yy528 = yylhsminor.yy528; | 173594 | yymsp[-3].minor.yy528 = yylhsminor.yy528; |
| 167876 | break; | 173595 | break; |
| 167877 | case 190: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ | 173596 | case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ |
| 167878 | { | 173597 | { |
| 167879 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); | 173598 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); |
| 167880 | sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); | 173599 | sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); |
| 167881 | } | 173600 | } |
| 167882 | yymsp[-5].minor.yy528 = yylhsminor.yy528; | 173601 | yymsp[-5].minor.yy528 = yylhsminor.yy528; |
| 167883 | break; | 173602 | break; |
| 167884 | case 191: /* expr ::= ID|INDEXED LP STAR RP filter_over */ | 173603 | case 190: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ |
| 167885 | { | 173604 | { |
| 167886 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); | 173605 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); |
| 167887 | sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); | 173606 | sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); |
| 167888 | } | 173607 | } |
| 167889 | yymsp[-4].minor.yy528 = yylhsminor.yy528; | 173608 | yymsp[-4].minor.yy528 = yylhsminor.yy528; |
| 167890 | break; | 173609 | break; |
| 167891 | case 192: /* term ::= CTIME_KW */ | 173610 | case 191: /* term ::= CTIME_KW */ |
| 167892 | { | 173611 | { |
| 167893 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); | 173612 | yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); |
| 167894 | } | 173613 | } |
| 167895 | yymsp[0].minor.yy528 = yylhsminor.yy528; | 173614 | yymsp[0].minor.yy528 = yylhsminor.yy528; |
| 167896 | break; | 173615 | break; |
| 167897 | case 193: /* expr ::= LP nexprlist COMMA expr RP */ | 173616 | case 192: /* expr ::= LP nexprlist COMMA expr RP */ |
| 167898 | { | 173617 | { |
| 167899 | ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); | 173618 | ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); |
| 167900 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); | 173619 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); |
| @@ -167908,22 +173627,22 @@ static YYACTIONTYPE yy_reduce( | |||
| 167908 | } | 173627 | } |
| 167909 | } | 173628 | } |
| 167910 | break; | 173629 | break; |
| 167911 | case 194: /* expr ::= expr AND expr */ | 173630 | case 193: /* expr ::= expr AND expr */ |
| 167912 | {yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} | 173631 | {yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} |
| 167913 | break; | 173632 | break; |
| 167914 | case 195: /* expr ::= expr OR expr */ | 173633 | case 194: /* expr ::= expr OR expr */ |
| 167915 | case 196: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==196); | 173634 | case 195: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==195); |
| 167916 | case 197: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==197); | 173635 | case 196: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==196); |
| 167917 | case 198: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==198); | 173636 | case 197: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==197); |
| 167918 | case 199: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==199); | 173637 | case 198: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==198); |
| 167919 | case 200: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==200); | 173638 | case 199: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==199); |
| 167920 | case 201: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==201); | 173639 | case 200: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==200); |
| 167921 | {yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} | 173640 | {yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} |
| 167922 | break; | 173641 | break; |
| 167923 | case 202: /* likeop ::= NOT LIKE_KW|MATCH */ | 173642 | case 201: /* likeop ::= NOT LIKE_KW|MATCH */ |
| 167924 | {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} | 173643 | {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} |
| 167925 | break; | 173644 | break; |
| 167926 | case 203: /* expr ::= expr likeop expr */ | 173645 | case 202: /* expr ::= expr likeop expr */ |
| 167927 | { | 173646 | { |
| 167928 | ExprList *pList; | 173647 | ExprList *pList; |
| 167929 | int bNot = yymsp[-1].minor.yy0.n & 0x80000000; | 173648 | int bNot = yymsp[-1].minor.yy0.n & 0x80000000; |
| @@ -167935,7 +173654,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 167935 | if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; | 173654 | if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; |
| 167936 | } | 173655 | } |
| 167937 | break; | 173656 | break; |
| 167938 | case 204: /* expr ::= expr likeop expr ESCAPE expr */ | 173657 | case 203: /* expr ::= expr likeop expr ESCAPE expr */ |
| 167939 | { | 173658 | { |
| 167940 | ExprList *pList; | 173659 | ExprList *pList; |
| 167941 | int bNot = yymsp[-3].minor.yy0.n & 0x80000000; | 173660 | int bNot = yymsp[-3].minor.yy0.n & 0x80000000; |
| @@ -167948,47 +173667,47 @@ static YYACTIONTYPE yy_reduce( | |||
| 167948 | if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; | 173667 | if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; |
| 167949 | } | 173668 | } |
| 167950 | break; | 173669 | break; |
| 167951 | case 205: /* expr ::= expr ISNULL|NOTNULL */ | 173670 | case 204: /* expr ::= expr ISNULL|NOTNULL */ |
| 167952 | {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} | 173671 | {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} |
| 167953 | break; | 173672 | break; |
| 167954 | case 206: /* expr ::= expr NOT NULL */ | 173673 | case 205: /* expr ::= expr NOT NULL */ |
| 167955 | {yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} | 173674 | {yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} |
| 167956 | break; | 173675 | break; |
| 167957 | case 207: /* expr ::= expr IS expr */ | 173676 | case 206: /* expr ::= expr IS expr */ |
| 167958 | { | 173677 | { |
| 167959 | yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); | 173678 | yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); |
| 167960 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); | 173679 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); |
| 167961 | } | 173680 | } |
| 167962 | break; | 173681 | break; |
| 167963 | case 208: /* expr ::= expr IS NOT expr */ | 173682 | case 207: /* expr ::= expr IS NOT expr */ |
| 167964 | { | 173683 | { |
| 167965 | yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); | 173684 | yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); |
| 167966 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); | 173685 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); |
| 167967 | } | 173686 | } |
| 167968 | break; | 173687 | break; |
| 167969 | case 209: /* expr ::= expr IS NOT DISTINCT FROM expr */ | 173688 | case 208: /* expr ::= expr IS NOT DISTINCT FROM expr */ |
| 167970 | { | 173689 | { |
| 167971 | yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528); | 173690 | yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528); |
| 167972 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL); | 173691 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL); |
| 167973 | } | 173692 | } |
| 167974 | break; | 173693 | break; |
| 167975 | case 210: /* expr ::= expr IS DISTINCT FROM expr */ | 173694 | case 209: /* expr ::= expr IS DISTINCT FROM expr */ |
| 167976 | { | 173695 | { |
| 167977 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528); | 173696 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528); |
| 167978 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL); | 173697 | binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL); |
| 167979 | } | 173698 | } |
| 167980 | break; | 173699 | break; |
| 167981 | case 211: /* expr ::= NOT expr */ | 173700 | case 210: /* expr ::= NOT expr */ |
| 167982 | case 212: /* expr ::= BITNOT expr */ yytestcase(yyruleno==212); | 173701 | case 211: /* expr ::= BITNOT expr */ yytestcase(yyruleno==211); |
| 167983 | {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} | 173702 | {yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} |
| 167984 | break; | 173703 | break; |
| 167985 | case 213: /* expr ::= PLUS|MINUS expr */ | 173704 | case 212: /* expr ::= PLUS|MINUS expr */ |
| 167986 | { | 173705 | { |
| 167987 | yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); | 173706 | yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); |
| 167988 | /*A-overwrites-B*/ | 173707 | /*A-overwrites-B*/ |
| 167989 | } | 173708 | } |
| 167990 | break; | 173709 | break; |
| 167991 | case 214: /* expr ::= expr PTR expr */ | 173710 | case 213: /* expr ::= expr PTR expr */ |
| 167992 | { | 173711 | { |
| 167993 | ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); | 173712 | ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); |
| 167994 | pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); | 173713 | pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); |
| @@ -167996,11 +173715,11 @@ static YYACTIONTYPE yy_reduce( | |||
| 167996 | } | 173715 | } |
| 167997 | yymsp[-2].minor.yy528 = yylhsminor.yy528; | 173716 | yymsp[-2].minor.yy528 = yylhsminor.yy528; |
| 167998 | break; | 173717 | break; |
| 167999 | case 215: /* between_op ::= BETWEEN */ | 173718 | case 214: /* between_op ::= BETWEEN */ |
| 168000 | case 218: /* in_op ::= IN */ yytestcase(yyruleno==218); | 173719 | case 217: /* in_op ::= IN */ yytestcase(yyruleno==217); |
| 168001 | {yymsp[0].minor.yy394 = 0;} | 173720 | {yymsp[0].minor.yy394 = 0;} |
| 168002 | break; | 173721 | break; |
| 168003 | case 217: /* expr ::= expr between_op expr AND expr */ | 173722 | case 216: /* expr ::= expr between_op expr AND expr */ |
| 168004 | { | 173723 | { |
| 168005 | ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); | 173724 | ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); |
| 168006 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); | 173725 | pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); |
| @@ -168013,7 +173732,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 168013 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); | 173732 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); |
| 168014 | } | 173733 | } |
| 168015 | break; | 173734 | break; |
| 168016 | case 220: /* expr ::= expr in_op LP exprlist RP */ | 173735 | case 219: /* expr ::= expr in_op LP exprlist RP */ |
| 168017 | { | 173736 | { |
| 168018 | if( yymsp[-1].minor.yy322==0 ){ | 173737 | if( yymsp[-1].minor.yy322==0 ){ |
| 168019 | /* Expressions of the form | 173738 | /* Expressions of the form |
| @@ -168034,6 +173753,11 @@ static YYACTIONTYPE yy_reduce( | |||
| 168034 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); | 173753 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); |
| 168035 | pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); | 173754 | pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); |
| 168036 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); | 173755 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); |
| 173756 | }else if( yymsp[-1].minor.yy322->nExpr==1 && pRHS->op==TK_SELECT ){ | ||
| 173757 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); | ||
| 173758 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pRHS->x.pSelect); | ||
| 173759 | pRHS->x.pSelect = 0; | ||
| 173760 | sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); | ||
| 168037 | }else{ | 173761 | }else{ |
| 168038 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); | 173762 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); |
| 168039 | if( yymsp[-4].minor.yy528==0 ){ | 173763 | if( yymsp[-4].minor.yy528==0 ){ |
| @@ -168054,20 +173778,20 @@ static YYACTIONTYPE yy_reduce( | |||
| 168054 | } | 173778 | } |
| 168055 | } | 173779 | } |
| 168056 | break; | 173780 | break; |
| 168057 | case 221: /* expr ::= LP select RP */ | 173781 | case 220: /* expr ::= LP select RP */ |
| 168058 | { | 173782 | { |
| 168059 | yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); | 173783 | yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); |
| 168060 | sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); | 173784 | sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); |
| 168061 | } | 173785 | } |
| 168062 | break; | 173786 | break; |
| 168063 | case 222: /* expr ::= expr in_op LP select RP */ | 173787 | case 221: /* expr ::= expr in_op LP select RP */ |
| 168064 | { | 173788 | { |
| 168065 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); | 173789 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); |
| 168066 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); | 173790 | sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); |
| 168067 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); | 173791 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); |
| 168068 | } | 173792 | } |
| 168069 | break; | 173793 | break; |
| 168070 | case 223: /* expr ::= expr in_op nm dbnm paren_exprlist */ | 173794 | case 222: /* expr ::= expr in_op nm dbnm paren_exprlist */ |
| 168071 | { | 173795 | { |
| 168072 | SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); | 173796 | SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); |
| 168073 | Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); | 173797 | Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); |
| @@ -168077,14 +173801,14 @@ static YYACTIONTYPE yy_reduce( | |||
| 168077 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); | 173801 | if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); |
| 168078 | } | 173802 | } |
| 168079 | break; | 173803 | break; |
| 168080 | case 224: /* expr ::= EXISTS LP select RP */ | 173804 | case 223: /* expr ::= EXISTS LP select RP */ |
| 168081 | { | 173805 | { |
| 168082 | Expr *p; | 173806 | Expr *p; |
| 168083 | p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); | 173807 | p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); |
| 168084 | sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); | 173808 | sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); |
| 168085 | } | 173809 | } |
| 168086 | break; | 173810 | break; |
| 168087 | case 225: /* expr ::= CASE case_operand case_exprlist case_else END */ | 173811 | case 224: /* expr ::= CASE case_operand case_exprlist case_else END */ |
| 168088 | { | 173812 | { |
| 168089 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); | 173813 | yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); |
| 168090 | if( yymsp[-4].minor.yy528 ){ | 173814 | if( yymsp[-4].minor.yy528 ){ |
| @@ -168096,32 +173820,29 @@ static YYACTIONTYPE yy_reduce( | |||
| 168096 | } | 173820 | } |
| 168097 | } | 173821 | } |
| 168098 | break; | 173822 | break; |
| 168099 | case 226: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ | 173823 | case 225: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ |
| 168100 | { | 173824 | { |
| 168101 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); | 173825 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); |
| 168102 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); | 173826 | yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); |
| 168103 | } | 173827 | } |
| 168104 | break; | 173828 | break; |
| 168105 | case 227: /* case_exprlist ::= WHEN expr THEN expr */ | 173829 | case 226: /* case_exprlist ::= WHEN expr THEN expr */ |
| 168106 | { | 173830 | { |
| 168107 | yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); | 173831 | yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); |
| 168108 | yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); | 173832 | yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); |
| 168109 | } | 173833 | } |
| 168110 | break; | 173834 | break; |
| 168111 | case 230: /* case_operand ::= expr */ | 173835 | case 231: /* nexprlist ::= nexprlist COMMA expr */ |
| 168112 | {yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/} | ||
| 168113 | break; | ||
| 168114 | case 233: /* nexprlist ::= nexprlist COMMA expr */ | ||
| 168115 | {yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} | 173836 | {yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} |
| 168116 | break; | 173837 | break; |
| 168117 | case 234: /* nexprlist ::= expr */ | 173838 | case 232: /* nexprlist ::= expr */ |
| 168118 | {yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} | 173839 | {yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} |
| 168119 | break; | 173840 | break; |
| 168120 | case 236: /* paren_exprlist ::= LP exprlist RP */ | 173841 | case 234: /* paren_exprlist ::= LP exprlist RP */ |
| 168121 | case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241); | 173842 | case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239); |
| 168122 | {yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} | 173843 | {yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} |
| 168123 | break; | 173844 | break; |
| 168124 | case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ | 173845 | case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ |
| 168125 | { | 173846 | { |
| 168126 | sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, | 173847 | sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, |
| 168127 | sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, | 173848 | sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, |
| @@ -168131,48 +173852,48 @@ static YYACTIONTYPE yy_reduce( | |||
| 168131 | } | 173852 | } |
| 168132 | } | 173853 | } |
| 168133 | break; | 173854 | break; |
| 168134 | case 238: /* uniqueflag ::= UNIQUE */ | 173855 | case 236: /* uniqueflag ::= UNIQUE */ |
| 168135 | case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280); | 173856 | case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278); |
| 168136 | {yymsp[0].minor.yy394 = OE_Abort;} | 173857 | {yymsp[0].minor.yy394 = OE_Abort;} |
| 168137 | break; | 173858 | break; |
| 168138 | case 239: /* uniqueflag ::= */ | 173859 | case 237: /* uniqueflag ::= */ |
| 168139 | {yymsp[1].minor.yy394 = OE_None;} | 173860 | {yymsp[1].minor.yy394 = OE_None;} |
| 168140 | break; | 173861 | break; |
| 168141 | case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */ | 173862 | case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */ |
| 168142 | { | 173863 | { |
| 168143 | yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); | 173864 | yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); |
| 168144 | } | 173865 | } |
| 168145 | break; | 173866 | break; |
| 168146 | case 243: /* eidlist ::= nm collate sortorder */ | 173867 | case 241: /* eidlist ::= nm collate sortorder */ |
| 168147 | { | 173868 | { |
| 168148 | yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ | 173869 | yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ |
| 168149 | } | 173870 | } |
| 168150 | break; | 173871 | break; |
| 168151 | case 246: /* cmd ::= DROP INDEX ifexists fullname */ | 173872 | case 244: /* cmd ::= DROP INDEX ifexists fullname */ |
| 168152 | {sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} | 173873 | {sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} |
| 168153 | break; | 173874 | break; |
| 168154 | case 247: /* cmd ::= VACUUM vinto */ | 173875 | case 245: /* cmd ::= VACUUM vinto */ |
| 168155 | {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} | 173876 | {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} |
| 168156 | break; | 173877 | break; |
| 168157 | case 248: /* cmd ::= VACUUM nm vinto */ | 173878 | case 246: /* cmd ::= VACUUM nm vinto */ |
| 168158 | {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} | 173879 | {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} |
| 168159 | break; | 173880 | break; |
| 168160 | case 251: /* cmd ::= PRAGMA nm dbnm */ | 173881 | case 249: /* cmd ::= PRAGMA nm dbnm */ |
| 168161 | {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} | 173882 | {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} |
| 168162 | break; | 173883 | break; |
| 168163 | case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ | 173884 | case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ |
| 168164 | {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} | 173885 | {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} |
| 168165 | break; | 173886 | break; |
| 168166 | case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ | 173887 | case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ |
| 168167 | {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} | 173888 | {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} |
| 168168 | break; | 173889 | break; |
| 168169 | case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ | 173890 | case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ |
| 168170 | {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} | 173891 | {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} |
| 168171 | break; | 173892 | break; |
| 168172 | case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ | 173893 | case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ |
| 168173 | {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} | 173894 | {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} |
| 168174 | break; | 173895 | break; |
| 168175 | case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ | 173896 | case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ |
| 168176 | { | 173897 | { |
| 168177 | Token all; | 173898 | Token all; |
| 168178 | all.z = yymsp[-3].minor.yy0.z; | 173899 | all.z = yymsp[-3].minor.yy0.z; |
| @@ -168180,50 +173901,50 @@ static YYACTIONTYPE yy_reduce( | |||
| 168180 | sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); | 173901 | sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); |
| 168181 | } | 173902 | } |
| 168182 | break; | 173903 | break; |
| 168183 | case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ | 173904 | case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ |
| 168184 | { | 173905 | { |
| 168185 | sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); | 173906 | sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); |
| 168186 | yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ | 173907 | yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ |
| 168187 | } | 173908 | } |
| 168188 | break; | 173909 | break; |
| 168189 | case 260: /* trigger_time ::= BEFORE|AFTER */ | 173910 | case 258: /* trigger_time ::= BEFORE|AFTER */ |
| 168190 | { yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } | 173911 | { yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } |
| 168191 | break; | 173912 | break; |
| 168192 | case 261: /* trigger_time ::= INSTEAD OF */ | 173913 | case 259: /* trigger_time ::= INSTEAD OF */ |
| 168193 | { yymsp[-1].minor.yy394 = TK_INSTEAD;} | 173914 | { yymsp[-1].minor.yy394 = TK_INSTEAD;} |
| 168194 | break; | 173915 | break; |
| 168195 | case 262: /* trigger_time ::= */ | 173916 | case 260: /* trigger_time ::= */ |
| 168196 | { yymsp[1].minor.yy394 = TK_BEFORE; } | 173917 | { yymsp[1].minor.yy394 = TK_BEFORE; } |
| 168197 | break; | 173918 | break; |
| 168198 | case 263: /* trigger_event ::= DELETE|INSERT */ | 173919 | case 261: /* trigger_event ::= DELETE|INSERT */ |
| 168199 | case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264); | 173920 | case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262); |
| 168200 | {yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} | 173921 | {yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} |
| 168201 | break; | 173922 | break; |
| 168202 | case 265: /* trigger_event ::= UPDATE OF idlist */ | 173923 | case 263: /* trigger_event ::= UPDATE OF idlist */ |
| 168203 | {yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} | 173924 | {yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} |
| 168204 | break; | 173925 | break; |
| 168205 | case 266: /* when_clause ::= */ | 173926 | case 264: /* when_clause ::= */ |
| 168206 | case 285: /* key_opt ::= */ yytestcase(yyruleno==285); | 173927 | case 283: /* key_opt ::= */ yytestcase(yyruleno==283); |
| 168207 | { yymsp[1].minor.yy528 = 0; } | 173928 | { yymsp[1].minor.yy528 = 0; } |
| 168208 | break; | 173929 | break; |
| 168209 | case 267: /* when_clause ::= WHEN expr */ | 173930 | case 265: /* when_clause ::= WHEN expr */ |
| 168210 | case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286); | 173931 | case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284); |
| 168211 | { yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } | 173932 | { yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } |
| 168212 | break; | 173933 | break; |
| 168213 | case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ | 173934 | case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ |
| 168214 | { | 173935 | { |
| 168215 | assert( yymsp[-2].minor.yy33!=0 ); | 173936 | assert( yymsp[-2].minor.yy33!=0 ); |
| 168216 | yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; | 173937 | yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; |
| 168217 | yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; | 173938 | yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; |
| 168218 | } | 173939 | } |
| 168219 | break; | 173940 | break; |
| 168220 | case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */ | 173941 | case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */ |
| 168221 | { | 173942 | { |
| 168222 | assert( yymsp[-1].minor.yy33!=0 ); | 173943 | assert( yymsp[-1].minor.yy33!=0 ); |
| 168223 | yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; | 173944 | yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; |
| 168224 | } | 173945 | } |
| 168225 | break; | 173946 | break; |
| 168226 | case 270: /* trnm ::= nm DOT nm */ | 173947 | case 268: /* trnm ::= nm DOT nm */ |
| 168227 | { | 173948 | { |
| 168228 | yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; | 173949 | yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; |
| 168229 | sqlite3ErrorMsg(pParse, | 173950 | sqlite3ErrorMsg(pParse, |
| @@ -168231,39 +173952,39 @@ static YYACTIONTYPE yy_reduce( | |||
| 168231 | "statements within triggers"); | 173952 | "statements within triggers"); |
| 168232 | } | 173953 | } |
| 168233 | break; | 173954 | break; |
| 168234 | case 271: /* tridxby ::= INDEXED BY nm */ | 173955 | case 269: /* tridxby ::= INDEXED BY nm */ |
| 168235 | { | 173956 | { |
| 168236 | sqlite3ErrorMsg(pParse, | 173957 | sqlite3ErrorMsg(pParse, |
| 168237 | "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " | 173958 | "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " |
| 168238 | "within triggers"); | 173959 | "within triggers"); |
| 168239 | } | 173960 | } |
| 168240 | break; | 173961 | break; |
| 168241 | case 272: /* tridxby ::= NOT INDEXED */ | 173962 | case 270: /* tridxby ::= NOT INDEXED */ |
| 168242 | { | 173963 | { |
| 168243 | sqlite3ErrorMsg(pParse, | 173964 | sqlite3ErrorMsg(pParse, |
| 168244 | "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " | 173965 | "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " |
| 168245 | "within triggers"); | 173966 | "within triggers"); |
| 168246 | } | 173967 | } |
| 168247 | break; | 173968 | break; |
| 168248 | case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ | 173969 | case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ |
| 168249 | {yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} | 173970 | {yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} |
| 168250 | yymsp[-8].minor.yy33 = yylhsminor.yy33; | 173971 | yymsp[-8].minor.yy33 = yylhsminor.yy33; |
| 168251 | break; | 173972 | break; |
| 168252 | case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ | 173973 | case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ |
| 168253 | { | 173974 | { |
| 168254 | yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ | 173975 | yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ |
| 168255 | } | 173976 | } |
| 168256 | yymsp[-7].minor.yy33 = yylhsminor.yy33; | 173977 | yymsp[-7].minor.yy33 = yylhsminor.yy33; |
| 168257 | break; | 173978 | break; |
| 168258 | case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ | 173979 | case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ |
| 168259 | {yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} | 173980 | {yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} |
| 168260 | yymsp[-5].minor.yy33 = yylhsminor.yy33; | 173981 | yymsp[-5].minor.yy33 = yylhsminor.yy33; |
| 168261 | break; | 173982 | break; |
| 168262 | case 276: /* trigger_cmd ::= scanpt select scanpt */ | 173983 | case 274: /* trigger_cmd ::= scanpt select scanpt */ |
| 168263 | {yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} | 173984 | {yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} |
| 168264 | yymsp[-2].minor.yy33 = yylhsminor.yy33; | 173985 | yymsp[-2].minor.yy33 = yylhsminor.yy33; |
| 168265 | break; | 173986 | break; |
| 168266 | case 277: /* expr ::= RAISE LP IGNORE RP */ | 173987 | case 275: /* expr ::= RAISE LP IGNORE RP */ |
| 168267 | { | 173988 | { |
| 168268 | yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); | 173989 | yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); |
| 168269 | if( yymsp[-3].minor.yy528 ){ | 173990 | if( yymsp[-3].minor.yy528 ){ |
| @@ -168271,7 +173992,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 168271 | } | 173992 | } |
| 168272 | } | 173993 | } |
| 168273 | break; | 173994 | break; |
| 168274 | case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */ | 173995 | case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */ |
| 168275 | { | 173996 | { |
| 168276 | yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); | 173997 | yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); |
| 168277 | if( yymsp[-5].minor.yy528 ) { | 173998 | if( yymsp[-5].minor.yy528 ) { |
| @@ -168279,118 +174000,114 @@ static YYACTIONTYPE yy_reduce( | |||
| 168279 | } | 174000 | } |
| 168280 | } | 174001 | } |
| 168281 | break; | 174002 | break; |
| 168282 | case 279: /* raisetype ::= ROLLBACK */ | 174003 | case 277: /* raisetype ::= ROLLBACK */ |
| 168283 | {yymsp[0].minor.yy394 = OE_Rollback;} | 174004 | {yymsp[0].minor.yy394 = OE_Rollback;} |
| 168284 | break; | 174005 | break; |
| 168285 | case 281: /* raisetype ::= FAIL */ | 174006 | case 279: /* raisetype ::= FAIL */ |
| 168286 | {yymsp[0].minor.yy394 = OE_Fail;} | 174007 | {yymsp[0].minor.yy394 = OE_Fail;} |
| 168287 | break; | 174008 | break; |
| 168288 | case 282: /* cmd ::= DROP TRIGGER ifexists fullname */ | 174009 | case 280: /* cmd ::= DROP TRIGGER ifexists fullname */ |
| 168289 | { | 174010 | { |
| 168290 | sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); | 174011 | sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); |
| 168291 | } | 174012 | } |
| 168292 | break; | 174013 | break; |
| 168293 | case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ | 174014 | case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ |
| 168294 | { | 174015 | { |
| 168295 | sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); | 174016 | sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); |
| 168296 | } | 174017 | } |
| 168297 | break; | 174018 | break; |
| 168298 | case 284: /* cmd ::= DETACH database_kw_opt expr */ | 174019 | case 282: /* cmd ::= DETACH database_kw_opt expr */ |
| 168299 | { | 174020 | { |
| 168300 | sqlite3Detach(pParse, yymsp[0].minor.yy528); | 174021 | sqlite3Detach(pParse, yymsp[0].minor.yy528); |
| 168301 | } | 174022 | } |
| 168302 | break; | 174023 | break; |
| 168303 | case 287: /* cmd ::= REINDEX */ | 174024 | case 285: /* cmd ::= REINDEX */ |
| 168304 | {sqlite3Reindex(pParse, 0, 0);} | 174025 | {sqlite3Reindex(pParse, 0, 0);} |
| 168305 | break; | 174026 | break; |
| 168306 | case 288: /* cmd ::= REINDEX nm dbnm */ | 174027 | case 286: /* cmd ::= REINDEX nm dbnm */ |
| 168307 | {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} | 174028 | {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} |
| 168308 | break; | 174029 | break; |
| 168309 | case 289: /* cmd ::= ANALYZE */ | 174030 | case 287: /* cmd ::= ANALYZE */ |
| 168310 | {sqlite3Analyze(pParse, 0, 0);} | 174031 | {sqlite3Analyze(pParse, 0, 0);} |
| 168311 | break; | 174032 | break; |
| 168312 | case 290: /* cmd ::= ANALYZE nm dbnm */ | 174033 | case 288: /* cmd ::= ANALYZE nm dbnm */ |
| 168313 | {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} | 174034 | {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} |
| 168314 | break; | 174035 | break; |
| 168315 | case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ | 174036 | case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ |
| 168316 | { | 174037 | { |
| 168317 | sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); | 174038 | sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); |
| 168318 | } | 174039 | } |
| 168319 | break; | 174040 | break; |
| 168320 | case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ | 174041 | case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ |
| 168321 | { | 174042 | { |
| 168322 | yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; | 174043 | yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; |
| 168323 | sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); | 174044 | sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); |
| 168324 | } | 174045 | } |
| 168325 | break; | 174046 | break; |
| 168326 | case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ | 174047 | case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ |
| 168327 | { | 174048 | { |
| 168328 | sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); | 174049 | sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); |
| 168329 | } | 174050 | } |
| 168330 | break; | 174051 | break; |
| 168331 | case 294: /* add_column_fullname ::= fullname */ | 174052 | case 292: /* add_column_fullname ::= fullname */ |
| 168332 | { | 174053 | { |
| 168333 | disableLookaside(pParse); | 174054 | disableLookaside(pParse); |
| 168334 | sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); | 174055 | sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); |
| 168335 | } | 174056 | } |
| 168336 | break; | 174057 | break; |
| 168337 | case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ | 174058 | case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ |
| 168338 | { | 174059 | { |
| 168339 | sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); | 174060 | sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); |
| 168340 | } | 174061 | } |
| 168341 | break; | 174062 | break; |
| 168342 | case 296: /* cmd ::= create_vtab */ | 174063 | case 294: /* cmd ::= create_vtab */ |
| 168343 | {sqlite3VtabFinishParse(pParse,0);} | 174064 | {sqlite3VtabFinishParse(pParse,0);} |
| 168344 | break; | 174065 | break; |
| 168345 | case 297: /* cmd ::= create_vtab LP vtabarglist RP */ | 174066 | case 295: /* cmd ::= create_vtab LP vtabarglist RP */ |
| 168346 | {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} | 174067 | {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} |
| 168347 | break; | 174068 | break; |
| 168348 | case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ | 174069 | case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ |
| 168349 | { | 174070 | { |
| 168350 | sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); | 174071 | sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); |
| 168351 | } | 174072 | } |
| 168352 | break; | 174073 | break; |
| 168353 | case 299: /* vtabarg ::= */ | 174074 | case 297: /* vtabarg ::= */ |
| 168354 | {sqlite3VtabArgInit(pParse);} | 174075 | {sqlite3VtabArgInit(pParse);} |
| 168355 | break; | 174076 | break; |
| 168356 | case 300: /* vtabargtoken ::= ANY */ | 174077 | case 298: /* vtabargtoken ::= ANY */ |
| 168357 | case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301); | 174078 | case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299); |
| 168358 | case 302: /* lp ::= LP */ yytestcase(yyruleno==302); | 174079 | case 300: /* lp ::= LP */ yytestcase(yyruleno==300); |
| 168359 | {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} | 174080 | {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} |
| 168360 | break; | 174081 | break; |
| 168361 | case 303: /* with ::= WITH wqlist */ | 174082 | case 301: /* with ::= WITH wqlist */ |
| 168362 | case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304); | 174083 | case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302); |
| 168363 | { sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } | 174084 | { sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } |
| 168364 | break; | 174085 | break; |
| 168365 | case 305: /* wqas ::= AS */ | 174086 | case 303: /* wqas ::= AS */ |
| 168366 | {yymsp[0].minor.yy516 = M10d_Any;} | 174087 | {yymsp[0].minor.yy516 = M10d_Any;} |
| 168367 | break; | 174088 | break; |
| 168368 | case 306: /* wqas ::= AS MATERIALIZED */ | 174089 | case 304: /* wqas ::= AS MATERIALIZED */ |
| 168369 | {yymsp[-1].minor.yy516 = M10d_Yes;} | 174090 | {yymsp[-1].minor.yy516 = M10d_Yes;} |
| 168370 | break; | 174091 | break; |
| 168371 | case 307: /* wqas ::= AS NOT MATERIALIZED */ | 174092 | case 305: /* wqas ::= AS NOT MATERIALIZED */ |
| 168372 | {yymsp[-2].minor.yy516 = M10d_No;} | 174093 | {yymsp[-2].minor.yy516 = M10d_No;} |
| 168373 | break; | 174094 | break; |
| 168374 | case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */ | 174095 | case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */ |
| 168375 | { | 174096 | { |
| 168376 | yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ | 174097 | yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ |
| 168377 | } | 174098 | } |
| 168378 | break; | 174099 | break; |
| 168379 | case 309: /* wqlist ::= wqitem */ | 174100 | case 307: /* wqlist ::= wqitem */ |
| 168380 | { | 174101 | { |
| 168381 | yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ | 174102 | yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ |
| 168382 | } | 174103 | } |
| 168383 | break; | 174104 | break; |
| 168384 | case 310: /* wqlist ::= wqlist COMMA wqitem */ | 174105 | case 308: /* wqlist ::= wqlist COMMA wqitem */ |
| 168385 | { | 174106 | { |
| 168386 | yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); | 174107 | yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); |
| 168387 | } | 174108 | } |
| 168388 | break; | 174109 | break; |
| 168389 | case 311: /* windowdefn_list ::= windowdefn */ | 174110 | case 309: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ |
| 168390 | { yylhsminor.yy41 = yymsp[0].minor.yy41; } | ||
| 168391 | yymsp[0].minor.yy41 = yylhsminor.yy41; | ||
| 168392 | break; | ||
| 168393 | case 312: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ | ||
| 168394 | { | 174111 | { |
| 168395 | assert( yymsp[0].minor.yy41!=0 ); | 174112 | assert( yymsp[0].minor.yy41!=0 ); |
| 168396 | sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); | 174113 | sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); |
| @@ -168399,7 +174116,7 @@ static YYACTIONTYPE yy_reduce( | |||
| 168399 | } | 174116 | } |
| 168400 | yymsp[-2].minor.yy41 = yylhsminor.yy41; | 174117 | yymsp[-2].minor.yy41 = yylhsminor.yy41; |
| 168401 | break; | 174118 | break; |
| 168402 | case 313: /* windowdefn ::= nm AS LP window RP */ | 174119 | case 310: /* windowdefn ::= nm AS LP window RP */ |
| 168403 | { | 174120 | { |
| 168404 | if( ALWAYS(yymsp[-1].minor.yy41) ){ | 174121 | if( ALWAYS(yymsp[-1].minor.yy41) ){ |
| 168405 | yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); | 174122 | yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); |
| @@ -168408,90 +174125,83 @@ static YYACTIONTYPE yy_reduce( | |||
| 168408 | } | 174125 | } |
| 168409 | yymsp[-4].minor.yy41 = yylhsminor.yy41; | 174126 | yymsp[-4].minor.yy41 = yylhsminor.yy41; |
| 168410 | break; | 174127 | break; |
| 168411 | case 314: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ | 174128 | case 311: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ |
| 168412 | { | 174129 | { |
| 168413 | yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); | 174130 | yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); |
| 168414 | } | 174131 | } |
| 168415 | break; | 174132 | break; |
| 168416 | case 315: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ | 174133 | case 312: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ |
| 168417 | { | 174134 | { |
| 168418 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); | 174135 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); |
| 168419 | } | 174136 | } |
| 168420 | yymsp[-5].minor.yy41 = yylhsminor.yy41; | 174137 | yymsp[-5].minor.yy41 = yylhsminor.yy41; |
| 168421 | break; | 174138 | break; |
| 168422 | case 316: /* window ::= ORDER BY sortlist frame_opt */ | 174139 | case 313: /* window ::= ORDER BY sortlist frame_opt */ |
| 168423 | { | 174140 | { |
| 168424 | yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); | 174141 | yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); |
| 168425 | } | 174142 | } |
| 168426 | break; | 174143 | break; |
| 168427 | case 317: /* window ::= nm ORDER BY sortlist frame_opt */ | 174144 | case 314: /* window ::= nm ORDER BY sortlist frame_opt */ |
| 168428 | { | 174145 | { |
| 168429 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); | 174146 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); |
| 168430 | } | 174147 | } |
| 168431 | yymsp[-4].minor.yy41 = yylhsminor.yy41; | 174148 | yymsp[-4].minor.yy41 = yylhsminor.yy41; |
| 168432 | break; | 174149 | break; |
| 168433 | case 318: /* window ::= frame_opt */ | 174150 | case 315: /* window ::= nm frame_opt */ |
| 168434 | case 337: /* filter_over ::= over_clause */ yytestcase(yyruleno==337); | ||
| 168435 | { | ||
| 168436 | yylhsminor.yy41 = yymsp[0].minor.yy41; | ||
| 168437 | } | ||
| 168438 | yymsp[0].minor.yy41 = yylhsminor.yy41; | ||
| 168439 | break; | ||
| 168440 | case 319: /* window ::= nm frame_opt */ | ||
| 168441 | { | 174151 | { |
| 168442 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); | 174152 | yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); |
| 168443 | } | 174153 | } |
| 168444 | yymsp[-1].minor.yy41 = yylhsminor.yy41; | 174154 | yymsp[-1].minor.yy41 = yylhsminor.yy41; |
| 168445 | break; | 174155 | break; |
| 168446 | case 320: /* frame_opt ::= */ | 174156 | case 316: /* frame_opt ::= */ |
| 168447 | { | 174157 | { |
| 168448 | yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); | 174158 | yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); |
| 168449 | } | 174159 | } |
| 168450 | break; | 174160 | break; |
| 168451 | case 321: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ | 174161 | case 317: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ |
| 168452 | { | 174162 | { |
| 168453 | yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); | 174163 | yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); |
| 168454 | } | 174164 | } |
| 168455 | yymsp[-2].minor.yy41 = yylhsminor.yy41; | 174165 | yymsp[-2].minor.yy41 = yylhsminor.yy41; |
| 168456 | break; | 174166 | break; |
| 168457 | case 322: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ | 174167 | case 318: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ |
| 168458 | { | 174168 | { |
| 168459 | yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); | 174169 | yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); |
| 168460 | } | 174170 | } |
| 168461 | yymsp[-5].minor.yy41 = yylhsminor.yy41; | 174171 | yymsp[-5].minor.yy41 = yylhsminor.yy41; |
| 168462 | break; | 174172 | break; |
| 168463 | case 324: /* frame_bound_s ::= frame_bound */ | 174173 | case 320: /* frame_bound_s ::= frame_bound */ |
| 168464 | case 326: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==326); | 174174 | case 322: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==322); |
| 168465 | {yylhsminor.yy595 = yymsp[0].minor.yy595;} | 174175 | {yylhsminor.yy595 = yymsp[0].minor.yy595;} |
| 168466 | yymsp[0].minor.yy595 = yylhsminor.yy595; | 174176 | yymsp[0].minor.yy595 = yylhsminor.yy595; |
| 168467 | break; | 174177 | break; |
| 168468 | case 325: /* frame_bound_s ::= UNBOUNDED PRECEDING */ | 174178 | case 321: /* frame_bound_s ::= UNBOUNDED PRECEDING */ |
| 168469 | case 327: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==327); | 174179 | case 323: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==323); |
| 168470 | case 329: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==329); | 174180 | case 325: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==325); |
| 168471 | {yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} | 174181 | {yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} |
| 168472 | yymsp[-1].minor.yy595 = yylhsminor.yy595; | 174182 | yymsp[-1].minor.yy595 = yylhsminor.yy595; |
| 168473 | break; | 174183 | break; |
| 168474 | case 328: /* frame_bound ::= expr PRECEDING|FOLLOWING */ | 174184 | case 324: /* frame_bound ::= expr PRECEDING|FOLLOWING */ |
| 168475 | {yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} | 174185 | {yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} |
| 168476 | yymsp[-1].minor.yy595 = yylhsminor.yy595; | 174186 | yymsp[-1].minor.yy595 = yylhsminor.yy595; |
| 168477 | break; | 174187 | break; |
| 168478 | case 330: /* frame_exclude_opt ::= */ | 174188 | case 326: /* frame_exclude_opt ::= */ |
| 168479 | {yymsp[1].minor.yy516 = 0;} | 174189 | {yymsp[1].minor.yy516 = 0;} |
| 168480 | break; | 174190 | break; |
| 168481 | case 331: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ | 174191 | case 327: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ |
| 168482 | {yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} | 174192 | {yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} |
| 168483 | break; | 174193 | break; |
| 168484 | case 332: /* frame_exclude ::= NO OTHERS */ | 174194 | case 328: /* frame_exclude ::= NO OTHERS */ |
| 168485 | case 333: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==333); | 174195 | case 329: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==329); |
| 168486 | {yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} | 174196 | {yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} |
| 168487 | break; | 174197 | break; |
| 168488 | case 334: /* frame_exclude ::= GROUP|TIES */ | 174198 | case 330: /* frame_exclude ::= GROUP|TIES */ |
| 168489 | {yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} | 174199 | {yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} |
| 168490 | break; | 174200 | break; |
| 168491 | case 335: /* window_clause ::= WINDOW windowdefn_list */ | 174201 | case 331: /* window_clause ::= WINDOW windowdefn_list */ |
| 168492 | { yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } | 174202 | { yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } |
| 168493 | break; | 174203 | break; |
| 168494 | case 336: /* filter_over ::= filter_clause over_clause */ | 174204 | case 332: /* filter_over ::= filter_clause over_clause */ |
| 168495 | { | 174205 | { |
| 168496 | if( yymsp[0].minor.yy41 ){ | 174206 | if( yymsp[0].minor.yy41 ){ |
| 168497 | yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; | 174207 | yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; |
| @@ -168502,7 +174212,13 @@ static YYACTIONTYPE yy_reduce( | |||
| 168502 | } | 174212 | } |
| 168503 | yymsp[-1].minor.yy41 = yylhsminor.yy41; | 174213 | yymsp[-1].minor.yy41 = yylhsminor.yy41; |
| 168504 | break; | 174214 | break; |
| 168505 | case 338: /* filter_over ::= filter_clause */ | 174215 | case 333: /* filter_over ::= over_clause */ |
| 174216 | { | ||
| 174217 | yylhsminor.yy41 = yymsp[0].minor.yy41; | ||
| 174218 | } | ||
| 174219 | yymsp[0].minor.yy41 = yylhsminor.yy41; | ||
| 174220 | break; | ||
| 174221 | case 334: /* filter_over ::= filter_clause */ | ||
| 168506 | { | 174222 | { |
| 168507 | yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); | 174223 | yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); |
| 168508 | if( yylhsminor.yy41 ){ | 174224 | if( yylhsminor.yy41 ){ |
| @@ -168514,13 +174230,13 @@ static YYACTIONTYPE yy_reduce( | |||
| 168514 | } | 174230 | } |
| 168515 | yymsp[0].minor.yy41 = yylhsminor.yy41; | 174231 | yymsp[0].minor.yy41 = yylhsminor.yy41; |
| 168516 | break; | 174232 | break; |
| 168517 | case 339: /* over_clause ::= OVER LP window RP */ | 174233 | case 335: /* over_clause ::= OVER LP window RP */ |
| 168518 | { | 174234 | { |
| 168519 | yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; | 174235 | yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; |
| 168520 | assert( yymsp[-3].minor.yy41!=0 ); | 174236 | assert( yymsp[-3].minor.yy41!=0 ); |
| 168521 | } | 174237 | } |
| 168522 | break; | 174238 | break; |
| 168523 | case 340: /* over_clause ::= OVER nm */ | 174239 | case 336: /* over_clause ::= OVER nm */ |
| 168524 | { | 174240 | { |
| 168525 | yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); | 174241 | yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); |
| 168526 | if( yymsp[-1].minor.yy41 ){ | 174242 | if( yymsp[-1].minor.yy41 ){ |
| @@ -168528,73 +174244,75 @@ static YYACTIONTYPE yy_reduce( | |||
| 168528 | } | 174244 | } |
| 168529 | } | 174245 | } |
| 168530 | break; | 174246 | break; |
| 168531 | case 341: /* filter_clause ::= FILTER LP WHERE expr RP */ | 174247 | case 337: /* filter_clause ::= FILTER LP WHERE expr RP */ |
| 168532 | { yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } | 174248 | { yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } |
| 168533 | break; | 174249 | break; |
| 168534 | default: | 174250 | default: |
| 168535 | /* (342) input ::= cmdlist */ yytestcase(yyruleno==342); | 174251 | /* (338) input ::= cmdlist */ yytestcase(yyruleno==338); |
| 168536 | /* (343) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==343); | 174252 | /* (339) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==339); |
| 168537 | /* (344) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=344); | 174253 | /* (340) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=340); |
| 168538 | /* (345) ecmd ::= SEMI */ yytestcase(yyruleno==345); | 174254 | /* (341) ecmd ::= SEMI */ yytestcase(yyruleno==341); |
| 168539 | /* (346) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==346); | 174255 | /* (342) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==342); |
| 168540 | /* (347) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=347); | 174256 | /* (343) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=343); |
| 168541 | /* (348) trans_opt ::= */ yytestcase(yyruleno==348); | 174257 | /* (344) trans_opt ::= */ yytestcase(yyruleno==344); |
| 168542 | /* (349) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==349); | 174258 | /* (345) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==345); |
| 168543 | /* (350) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==350); | 174259 | /* (346) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==346); |
| 168544 | /* (351) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==351); | 174260 | /* (347) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==347); |
| 168545 | /* (352) savepoint_opt ::= */ yytestcase(yyruleno==352); | 174261 | /* (348) savepoint_opt ::= */ yytestcase(yyruleno==348); |
| 168546 | /* (353) cmd ::= create_table create_table_args */ yytestcase(yyruleno==353); | 174262 | /* (349) cmd ::= create_table create_table_args */ yytestcase(yyruleno==349); |
| 168547 | /* (354) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=354); | 174263 | /* (350) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=350); |
| 168548 | /* (355) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==355); | 174264 | /* (351) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==351); |
| 168549 | /* (356) columnlist ::= columnname carglist */ yytestcase(yyruleno==356); | 174265 | /* (352) columnlist ::= columnname carglist */ yytestcase(yyruleno==352); |
| 168550 | /* (357) nm ::= ID|INDEXED */ yytestcase(yyruleno==357); | 174266 | /* (353) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==353); |
| 168551 | /* (358) nm ::= STRING */ yytestcase(yyruleno==358); | 174267 | /* (354) nm ::= STRING */ yytestcase(yyruleno==354); |
| 168552 | /* (359) nm ::= JOIN_KW */ yytestcase(yyruleno==359); | 174268 | /* (355) typetoken ::= typename */ yytestcase(yyruleno==355); |
| 168553 | /* (360) typetoken ::= typename */ yytestcase(yyruleno==360); | 174269 | /* (356) typename ::= ID|STRING */ yytestcase(yyruleno==356); |
| 168554 | /* (361) typename ::= ID|STRING */ yytestcase(yyruleno==361); | 174270 | /* (357) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=357); |
| 168555 | /* (362) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=362); | 174271 | /* (358) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=358); |
| 168556 | /* (363) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=363); | 174272 | /* (359) carglist ::= carglist ccons */ yytestcase(yyruleno==359); |
| 168557 | /* (364) carglist ::= carglist ccons */ yytestcase(yyruleno==364); | 174273 | /* (360) carglist ::= */ yytestcase(yyruleno==360); |
| 168558 | /* (365) carglist ::= */ yytestcase(yyruleno==365); | 174274 | /* (361) ccons ::= NULL onconf */ yytestcase(yyruleno==361); |
| 168559 | /* (366) ccons ::= NULL onconf */ yytestcase(yyruleno==366); | 174275 | /* (362) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==362); |
| 168560 | /* (367) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==367); | 174276 | /* (363) ccons ::= AS generated */ yytestcase(yyruleno==363); |
| 168561 | /* (368) ccons ::= AS generated */ yytestcase(yyruleno==368); | 174277 | /* (364) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==364); |
| 168562 | /* (369) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==369); | 174278 | /* (365) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==365); |
| 168563 | /* (370) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==370); | 174279 | /* (366) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=366); |
| 168564 | /* (371) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=371); | 174280 | /* (367) tconscomma ::= */ yytestcase(yyruleno==367); |
| 168565 | /* (372) tconscomma ::= */ yytestcase(yyruleno==372); | 174281 | /* (368) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=368); |
| 168566 | /* (373) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=373); | 174282 | /* (369) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=369); |
| 168567 | /* (374) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=374); | 174283 | /* (370) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=370); |
| 168568 | /* (375) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=375); | 174284 | /* (371) oneselect ::= values */ yytestcase(yyruleno==371); |
| 168569 | /* (376) oneselect ::= values */ yytestcase(yyruleno==376); | 174285 | /* (372) sclp ::= selcollist COMMA */ yytestcase(yyruleno==372); |
| 168570 | /* (377) sclp ::= selcollist COMMA */ yytestcase(yyruleno==377); | 174286 | /* (373) as ::= ID|STRING */ yytestcase(yyruleno==373); |
| 168571 | /* (378) as ::= ID|STRING */ yytestcase(yyruleno==378); | 174287 | /* (374) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=374); |
| 168572 | /* (379) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=379); | 174288 | /* (375) returning ::= */ yytestcase(yyruleno==375); |
| 168573 | /* (380) returning ::= */ yytestcase(yyruleno==380); | 174289 | /* (376) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=376); |
| 168574 | /* (381) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=381); | 174290 | /* (377) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==377); |
| 168575 | /* (382) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==382); | 174291 | /* (378) case_operand ::= expr */ yytestcase(yyruleno==378); |
| 168576 | /* (383) exprlist ::= nexprlist */ yytestcase(yyruleno==383); | 174292 | /* (379) exprlist ::= nexprlist */ yytestcase(yyruleno==379); |
| 168577 | /* (384) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=384); | 174293 | /* (380) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=380); |
| 168578 | /* (385) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=385); | 174294 | /* (381) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=381); |
| 168579 | /* (386) nmnum ::= ON */ yytestcase(yyruleno==386); | 174295 | /* (382) nmnum ::= ON */ yytestcase(yyruleno==382); |
| 168580 | /* (387) nmnum ::= DELETE */ yytestcase(yyruleno==387); | 174296 | /* (383) nmnum ::= DELETE */ yytestcase(yyruleno==383); |
| 168581 | /* (388) nmnum ::= DEFAULT */ yytestcase(yyruleno==388); | 174297 | /* (384) nmnum ::= DEFAULT */ yytestcase(yyruleno==384); |
| 168582 | /* (389) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==389); | 174298 | /* (385) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==385); |
| 168583 | /* (390) foreach_clause ::= */ yytestcase(yyruleno==390); | 174299 | /* (386) foreach_clause ::= */ yytestcase(yyruleno==386); |
| 168584 | /* (391) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==391); | 174300 | /* (387) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==387); |
| 168585 | /* (392) trnm ::= nm */ yytestcase(yyruleno==392); | 174301 | /* (388) trnm ::= nm */ yytestcase(yyruleno==388); |
| 168586 | /* (393) tridxby ::= */ yytestcase(yyruleno==393); | 174302 | /* (389) tridxby ::= */ yytestcase(yyruleno==389); |
| 168587 | /* (394) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==394); | 174303 | /* (390) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==390); |
| 168588 | /* (395) database_kw_opt ::= */ yytestcase(yyruleno==395); | 174304 | /* (391) database_kw_opt ::= */ yytestcase(yyruleno==391); |
| 168589 | /* (396) kwcolumn_opt ::= */ yytestcase(yyruleno==396); | 174305 | /* (392) kwcolumn_opt ::= */ yytestcase(yyruleno==392); |
| 168590 | /* (397) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==397); | 174306 | /* (393) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==393); |
| 168591 | /* (398) vtabarglist ::= vtabarg */ yytestcase(yyruleno==398); | 174307 | /* (394) vtabarglist ::= vtabarg */ yytestcase(yyruleno==394); |
| 168592 | /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==399); | 174308 | /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==395); |
| 168593 | /* (400) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==400); | 174309 | /* (396) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==396); |
| 168594 | /* (401) anylist ::= */ yytestcase(yyruleno==401); | 174310 | /* (397) anylist ::= */ yytestcase(yyruleno==397); |
| 168595 | /* (402) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==402); | 174311 | /* (398) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==398); |
| 168596 | /* (403) anylist ::= anylist ANY */ yytestcase(yyruleno==403); | 174312 | /* (399) anylist ::= anylist ANY */ yytestcase(yyruleno==399); |
| 168597 | /* (404) with ::= */ yytestcase(yyruleno==404); | 174313 | /* (400) with ::= */ yytestcase(yyruleno==400); |
| 174314 | /* (401) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=401); | ||
| 174315 | /* (402) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=402); | ||
| 168598 | break; | 174316 | break; |
| 168599 | /********** End reduce actions ************************************************/ | 174317 | /********** End reduce actions ************************************************/ |
| 168600 | }; | 174318 | }; |
| @@ -169170,7 +174888,7 @@ static const unsigned char aKWHash[127] = { | |||
| 169170 | /* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 | 174888 | /* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 |
| 169171 | ** then the i-th keyword has no more hash collisions. Otherwise, | 174889 | ** then the i-th keyword has no more hash collisions. Otherwise, |
| 169172 | ** the next keyword with the same hash is aKWHash[i]-1. */ | 174890 | ** the next keyword with the same hash is aKWHash[i]-1. */ |
| 169173 | static const unsigned char aKWNext[147] = { | 174891 | static const unsigned char aKWNext[148] = {0, |
| 169174 | 0, 0, 0, 0, 4, 0, 43, 0, 0, 106, 114, 0, 0, | 174892 | 0, 0, 0, 0, 4, 0, 43, 0, 0, 106, 114, 0, 0, |
| 169175 | 0, 2, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 0, | 174893 | 0, 2, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 0, |
| 169176 | 141, 0, 0, 119, 52, 0, 0, 137, 12, 0, 0, 62, 0, | 174894 | 141, 0, 0, 119, 52, 0, 0, 137, 12, 0, 0, 62, 0, |
| @@ -169185,7 +174903,7 @@ static const unsigned char aKWNext[147] = { | |||
| 169185 | 102, 0, 0, 87, | 174903 | 102, 0, 0, 87, |
| 169186 | }; | 174904 | }; |
| 169187 | /* aKWLen[i] is the length (in bytes) of the i-th keyword */ | 174905 | /* aKWLen[i] is the length (in bytes) of the i-th keyword */ |
| 169188 | static const unsigned char aKWLen[147] = { | 174906 | static const unsigned char aKWLen[148] = {0, |
| 169189 | 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, | 174907 | 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, |
| 169190 | 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7, | 174908 | 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7, |
| 169191 | 6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4, | 174909 | 6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4, |
| @@ -169201,7 +174919,7 @@ static const unsigned char aKWLen[147] = { | |||
| 169201 | }; | 174919 | }; |
| 169202 | /* aKWOffset[i] is the index into zKWText[] of the start of | 174920 | /* aKWOffset[i] is the index into zKWText[] of the start of |
| 169203 | ** the text for the i-th keyword. */ | 174921 | ** the text for the i-th keyword. */ |
| 169204 | static const unsigned short int aKWOffset[147] = { | 174922 | static const unsigned short int aKWOffset[148] = {0, |
| 169205 | 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, | 174923 | 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, |
| 169206 | 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, | 174924 | 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, |
| 169207 | 86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126, | 174925 | 86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126, |
| @@ -169216,7 +174934,7 @@ static const unsigned short int aKWOffset[147] = { | |||
| 169216 | 648, 650, 655, 659, | 174934 | 648, 650, 655, 659, |
| 169217 | }; | 174935 | }; |
| 169218 | /* aKWCode[i] is the parser symbol code for the i-th keyword */ | 174936 | /* aKWCode[i] is the parser symbol code for the i-th keyword */ |
| 169219 | static const unsigned char aKWCode[147] = { | 174937 | static const unsigned char aKWCode[148] = {0, |
| 169220 | TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, | 174938 | TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, |
| 169221 | TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, | 174939 | TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, |
| 169222 | TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, | 174940 | TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, |
| @@ -169383,185 +175101,185 @@ static const unsigned char aKWCode[147] = { | |||
| 169383 | static int keywordCode(const char *z, int n, int *pType){ | 175101 | static int keywordCode(const char *z, int n, int *pType){ |
| 169384 | int i, j; | 175102 | int i, j; |
| 169385 | const char *zKW; | 175103 | const char *zKW; |
| 169386 | if( n>=2 ){ | 175104 | assert( n>=2 ); |
| 169387 | i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; | 175105 | i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; |
| 169388 | for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){ | 175106 | for(i=(int)aKWHash[i]; i>0; i=aKWNext[i]){ |
| 169389 | if( aKWLen[i]!=n ) continue; | 175107 | if( aKWLen[i]!=n ) continue; |
| 169390 | zKW = &zKWText[aKWOffset[i]]; | 175108 | zKW = &zKWText[aKWOffset[i]]; |
| 169391 | #ifdef SQLITE_ASCII | 175109 | #ifdef SQLITE_ASCII |
| 169392 | if( (z[0]&~0x20)!=zKW[0] ) continue; | 175110 | if( (z[0]&~0x20)!=zKW[0] ) continue; |
| 169393 | if( (z[1]&~0x20)!=zKW[1] ) continue; | 175111 | if( (z[1]&~0x20)!=zKW[1] ) continue; |
| 169394 | j = 2; | 175112 | j = 2; |
| 169395 | while( j<n && (z[j]&~0x20)==zKW[j] ){ j++; } | 175113 | while( j<n && (z[j]&~0x20)==zKW[j] ){ j++; } |
| 169396 | #endif | 175114 | #endif |
| 169397 | #ifdef SQLITE_EBCDIC | 175115 | #ifdef SQLITE_EBCDIC |
| 169398 | if( toupper(z[0])!=zKW[0] ) continue; | 175116 | if( toupper(z[0])!=zKW[0] ) continue; |
| 169399 | if( toupper(z[1])!=zKW[1] ) continue; | 175117 | if( toupper(z[1])!=zKW[1] ) continue; |
| 169400 | j = 2; | 175118 | j = 2; |
| 169401 | while( j<n && toupper(z[j])==zKW[j] ){ j++; } | 175119 | while( j<n && toupper(z[j])==zKW[j] ){ j++; } |
| 169402 | #endif | 175120 | #endif |
| 169403 | if( j<n ) continue; | 175121 | if( j<n ) continue; |
| 169404 | testcase( i==0 ); /* REINDEX */ | 175122 | testcase( i==1 ); /* REINDEX */ |
| 169405 | testcase( i==1 ); /* INDEXED */ | 175123 | testcase( i==2 ); /* INDEXED */ |
| 169406 | testcase( i==2 ); /* INDEX */ | 175124 | testcase( i==3 ); /* INDEX */ |
| 169407 | testcase( i==3 ); /* DESC */ | 175125 | testcase( i==4 ); /* DESC */ |
| 169408 | testcase( i==4 ); /* ESCAPE */ | 175126 | testcase( i==5 ); /* ESCAPE */ |
| 169409 | testcase( i==5 ); /* EACH */ | 175127 | testcase( i==6 ); /* EACH */ |
| 169410 | testcase( i==6 ); /* CHECK */ | 175128 | testcase( i==7 ); /* CHECK */ |
| 169411 | testcase( i==7 ); /* KEY */ | 175129 | testcase( i==8 ); /* KEY */ |
| 169412 | testcase( i==8 ); /* BEFORE */ | 175130 | testcase( i==9 ); /* BEFORE */ |
| 169413 | testcase( i==9 ); /* FOREIGN */ | 175131 | testcase( i==10 ); /* FOREIGN */ |
| 169414 | testcase( i==10 ); /* FOR */ | 175132 | testcase( i==11 ); /* FOR */ |
| 169415 | testcase( i==11 ); /* IGNORE */ | 175133 | testcase( i==12 ); /* IGNORE */ |
| 169416 | testcase( i==12 ); /* REGEXP */ | 175134 | testcase( i==13 ); /* REGEXP */ |
| 169417 | testcase( i==13 ); /* EXPLAIN */ | 175135 | testcase( i==14 ); /* EXPLAIN */ |
| 169418 | testcase( i==14 ); /* INSTEAD */ | 175136 | testcase( i==15 ); /* INSTEAD */ |
| 169419 | testcase( i==15 ); /* ADD */ | 175137 | testcase( i==16 ); /* ADD */ |
| 169420 | testcase( i==16 ); /* DATABASE */ | 175138 | testcase( i==17 ); /* DATABASE */ |
| 169421 | testcase( i==17 ); /* AS */ | 175139 | testcase( i==18 ); /* AS */ |
| 169422 | testcase( i==18 ); /* SELECT */ | 175140 | testcase( i==19 ); /* SELECT */ |
| 169423 | testcase( i==19 ); /* TABLE */ | 175141 | testcase( i==20 ); /* TABLE */ |
| 169424 | testcase( i==20 ); /* LEFT */ | 175142 | testcase( i==21 ); /* LEFT */ |
| 169425 | testcase( i==21 ); /* THEN */ | 175143 | testcase( i==22 ); /* THEN */ |
| 169426 | testcase( i==22 ); /* END */ | 175144 | testcase( i==23 ); /* END */ |
| 169427 | testcase( i==23 ); /* DEFERRABLE */ | 175145 | testcase( i==24 ); /* DEFERRABLE */ |
| 169428 | testcase( i==24 ); /* ELSE */ | 175146 | testcase( i==25 ); /* ELSE */ |
| 169429 | testcase( i==25 ); /* EXCLUDE */ | 175147 | testcase( i==26 ); /* EXCLUDE */ |
| 169430 | testcase( i==26 ); /* DELETE */ | 175148 | testcase( i==27 ); /* DELETE */ |
| 169431 | testcase( i==27 ); /* TEMPORARY */ | 175149 | testcase( i==28 ); /* TEMPORARY */ |
| 169432 | testcase( i==28 ); /* TEMP */ | 175150 | testcase( i==29 ); /* TEMP */ |
| 169433 | testcase( i==29 ); /* OR */ | 175151 | testcase( i==30 ); /* OR */ |
| 169434 | testcase( i==30 ); /* ISNULL */ | 175152 | testcase( i==31 ); /* ISNULL */ |
| 169435 | testcase( i==31 ); /* NULLS */ | 175153 | testcase( i==32 ); /* NULLS */ |
| 169436 | testcase( i==32 ); /* SAVEPOINT */ | 175154 | testcase( i==33 ); /* SAVEPOINT */ |
| 169437 | testcase( i==33 ); /* INTERSECT */ | 175155 | testcase( i==34 ); /* INTERSECT */ |
| 169438 | testcase( i==34 ); /* TIES */ | 175156 | testcase( i==35 ); /* TIES */ |
| 169439 | testcase( i==35 ); /* NOTNULL */ | 175157 | testcase( i==36 ); /* NOTNULL */ |
| 169440 | testcase( i==36 ); /* NOT */ | 175158 | testcase( i==37 ); /* NOT */ |
| 169441 | testcase( i==37 ); /* NO */ | 175159 | testcase( i==38 ); /* NO */ |
| 169442 | testcase( i==38 ); /* NULL */ | 175160 | testcase( i==39 ); /* NULL */ |
| 169443 | testcase( i==39 ); /* LIKE */ | 175161 | testcase( i==40 ); /* LIKE */ |
| 169444 | testcase( i==40 ); /* EXCEPT */ | 175162 | testcase( i==41 ); /* EXCEPT */ |
| 169445 | testcase( i==41 ); /* TRANSACTION */ | 175163 | testcase( i==42 ); /* TRANSACTION */ |
| 169446 | testcase( i==42 ); /* ACTION */ | 175164 | testcase( i==43 ); /* ACTION */ |
| 169447 | testcase( i==43 ); /* ON */ | 175165 | testcase( i==44 ); /* ON */ |
| 169448 | testcase( i==44 ); /* NATURAL */ | 175166 | testcase( i==45 ); /* NATURAL */ |
| 169449 | testcase( i==45 ); /* ALTER */ | 175167 | testcase( i==46 ); /* ALTER */ |
| 169450 | testcase( i==46 ); /* RAISE */ | 175168 | testcase( i==47 ); /* RAISE */ |
| 169451 | testcase( i==47 ); /* EXCLUSIVE */ | 175169 | testcase( i==48 ); /* EXCLUSIVE */ |
| 169452 | testcase( i==48 ); /* EXISTS */ | 175170 | testcase( i==49 ); /* EXISTS */ |
| 169453 | testcase( i==49 ); /* CONSTRAINT */ | 175171 | testcase( i==50 ); /* CONSTRAINT */ |
| 169454 | testcase( i==50 ); /* INTO */ | 175172 | testcase( i==51 ); /* INTO */ |
| 169455 | testcase( i==51 ); /* OFFSET */ | 175173 | testcase( i==52 ); /* OFFSET */ |
| 169456 | testcase( i==52 ); /* OF */ | 175174 | testcase( i==53 ); /* OF */ |
| 169457 | testcase( i==53 ); /* SET */ | 175175 | testcase( i==54 ); /* SET */ |
| 169458 | testcase( i==54 ); /* TRIGGER */ | 175176 | testcase( i==55 ); /* TRIGGER */ |
| 169459 | testcase( i==55 ); /* RANGE */ | 175177 | testcase( i==56 ); /* RANGE */ |
| 169460 | testcase( i==56 ); /* GENERATED */ | 175178 | testcase( i==57 ); /* GENERATED */ |
| 169461 | testcase( i==57 ); /* DETACH */ | 175179 | testcase( i==58 ); /* DETACH */ |
| 169462 | testcase( i==58 ); /* HAVING */ | 175180 | testcase( i==59 ); /* HAVING */ |
| 169463 | testcase( i==59 ); /* GLOB */ | 175181 | testcase( i==60 ); /* GLOB */ |
| 169464 | testcase( i==60 ); /* BEGIN */ | 175182 | testcase( i==61 ); /* BEGIN */ |
| 169465 | testcase( i==61 ); /* INNER */ | 175183 | testcase( i==62 ); /* INNER */ |
| 169466 | testcase( i==62 ); /* REFERENCES */ | 175184 | testcase( i==63 ); /* REFERENCES */ |
| 169467 | testcase( i==63 ); /* UNIQUE */ | 175185 | testcase( i==64 ); /* UNIQUE */ |
| 169468 | testcase( i==64 ); /* QUERY */ | 175186 | testcase( i==65 ); /* QUERY */ |
| 169469 | testcase( i==65 ); /* WITHOUT */ | 175187 | testcase( i==66 ); /* WITHOUT */ |
| 169470 | testcase( i==66 ); /* WITH */ | 175188 | testcase( i==67 ); /* WITH */ |
| 169471 | testcase( i==67 ); /* OUTER */ | 175189 | testcase( i==68 ); /* OUTER */ |
| 169472 | testcase( i==68 ); /* RELEASE */ | 175190 | testcase( i==69 ); /* RELEASE */ |
| 169473 | testcase( i==69 ); /* ATTACH */ | 175191 | testcase( i==70 ); /* ATTACH */ |
| 169474 | testcase( i==70 ); /* BETWEEN */ | 175192 | testcase( i==71 ); /* BETWEEN */ |
| 169475 | testcase( i==71 ); /* NOTHING */ | 175193 | testcase( i==72 ); /* NOTHING */ |
| 169476 | testcase( i==72 ); /* GROUPS */ | 175194 | testcase( i==73 ); /* GROUPS */ |
| 169477 | testcase( i==73 ); /* GROUP */ | 175195 | testcase( i==74 ); /* GROUP */ |
| 169478 | testcase( i==74 ); /* CASCADE */ | 175196 | testcase( i==75 ); /* CASCADE */ |
| 169479 | testcase( i==75 ); /* ASC */ | 175197 | testcase( i==76 ); /* ASC */ |
| 169480 | testcase( i==76 ); /* DEFAULT */ | 175198 | testcase( i==77 ); /* DEFAULT */ |
| 169481 | testcase( i==77 ); /* CASE */ | 175199 | testcase( i==78 ); /* CASE */ |
| 169482 | testcase( i==78 ); /* COLLATE */ | 175200 | testcase( i==79 ); /* COLLATE */ |
| 169483 | testcase( i==79 ); /* CREATE */ | 175201 | testcase( i==80 ); /* CREATE */ |
| 169484 | testcase( i==80 ); /* CURRENT_DATE */ | 175202 | testcase( i==81 ); /* CURRENT_DATE */ |
| 169485 | testcase( i==81 ); /* IMMEDIATE */ | 175203 | testcase( i==82 ); /* IMMEDIATE */ |
| 169486 | testcase( i==82 ); /* JOIN */ | 175204 | testcase( i==83 ); /* JOIN */ |
| 169487 | testcase( i==83 ); /* INSERT */ | 175205 | testcase( i==84 ); /* INSERT */ |
| 169488 | testcase( i==84 ); /* MATCH */ | 175206 | testcase( i==85 ); /* MATCH */ |
| 169489 | testcase( i==85 ); /* PLAN */ | 175207 | testcase( i==86 ); /* PLAN */ |
| 169490 | testcase( i==86 ); /* ANALYZE */ | 175208 | testcase( i==87 ); /* ANALYZE */ |
| 169491 | testcase( i==87 ); /* PRAGMA */ | 175209 | testcase( i==88 ); /* PRAGMA */ |
| 169492 | testcase( i==88 ); /* MATERIALIZED */ | 175210 | testcase( i==89 ); /* MATERIALIZED */ |
| 169493 | testcase( i==89 ); /* DEFERRED */ | 175211 | testcase( i==90 ); /* DEFERRED */ |
| 169494 | testcase( i==90 ); /* DISTINCT */ | 175212 | testcase( i==91 ); /* DISTINCT */ |
| 169495 | testcase( i==91 ); /* IS */ | 175213 | testcase( i==92 ); /* IS */ |
| 169496 | testcase( i==92 ); /* UPDATE */ | 175214 | testcase( i==93 ); /* UPDATE */ |
| 169497 | testcase( i==93 ); /* VALUES */ | 175215 | testcase( i==94 ); /* VALUES */ |
| 169498 | testcase( i==94 ); /* VIRTUAL */ | 175216 | testcase( i==95 ); /* VIRTUAL */ |
| 169499 | testcase( i==95 ); /* ALWAYS */ | 175217 | testcase( i==96 ); /* ALWAYS */ |
| 169500 | testcase( i==96 ); /* WHEN */ | 175218 | testcase( i==97 ); /* WHEN */ |
| 169501 | testcase( i==97 ); /* WHERE */ | 175219 | testcase( i==98 ); /* WHERE */ |
| 169502 | testcase( i==98 ); /* RECURSIVE */ | 175220 | testcase( i==99 ); /* RECURSIVE */ |
| 169503 | testcase( i==99 ); /* ABORT */ | 175221 | testcase( i==100 ); /* ABORT */ |
| 169504 | testcase( i==100 ); /* AFTER */ | 175222 | testcase( i==101 ); /* AFTER */ |
| 169505 | testcase( i==101 ); /* RENAME */ | 175223 | testcase( i==102 ); /* RENAME */ |
| 169506 | testcase( i==102 ); /* AND */ | 175224 | testcase( i==103 ); /* AND */ |
| 169507 | testcase( i==103 ); /* DROP */ | 175225 | testcase( i==104 ); /* DROP */ |
| 169508 | testcase( i==104 ); /* PARTITION */ | 175226 | testcase( i==105 ); /* PARTITION */ |
| 169509 | testcase( i==105 ); /* AUTOINCREMENT */ | 175227 | testcase( i==106 ); /* AUTOINCREMENT */ |
| 169510 | testcase( i==106 ); /* TO */ | 175228 | testcase( i==107 ); /* TO */ |
| 169511 | testcase( i==107 ); /* IN */ | 175229 | testcase( i==108 ); /* IN */ |
| 169512 | testcase( i==108 ); /* CAST */ | 175230 | testcase( i==109 ); /* CAST */ |
| 169513 | testcase( i==109 ); /* COLUMN */ | 175231 | testcase( i==110 ); /* COLUMN */ |
| 169514 | testcase( i==110 ); /* COMMIT */ | 175232 | testcase( i==111 ); /* COMMIT */ |
| 169515 | testcase( i==111 ); /* CONFLICT */ | 175233 | testcase( i==112 ); /* CONFLICT */ |
| 169516 | testcase( i==112 ); /* CROSS */ | 175234 | testcase( i==113 ); /* CROSS */ |
| 169517 | testcase( i==113 ); /* CURRENT_TIMESTAMP */ | 175235 | testcase( i==114 ); /* CURRENT_TIMESTAMP */ |
| 169518 | testcase( i==114 ); /* CURRENT_TIME */ | 175236 | testcase( i==115 ); /* CURRENT_TIME */ |
| 169519 | testcase( i==115 ); /* CURRENT */ | 175237 | testcase( i==116 ); /* CURRENT */ |
| 169520 | testcase( i==116 ); /* PRECEDING */ | 175238 | testcase( i==117 ); /* PRECEDING */ |
| 169521 | testcase( i==117 ); /* FAIL */ | 175239 | testcase( i==118 ); /* FAIL */ |
| 169522 | testcase( i==118 ); /* LAST */ | 175240 | testcase( i==119 ); /* LAST */ |
| 169523 | testcase( i==119 ); /* FILTER */ | 175241 | testcase( i==120 ); /* FILTER */ |
| 169524 | testcase( i==120 ); /* REPLACE */ | 175242 | testcase( i==121 ); /* REPLACE */ |
| 169525 | testcase( i==121 ); /* FIRST */ | 175243 | testcase( i==122 ); /* FIRST */ |
| 169526 | testcase( i==122 ); /* FOLLOWING */ | 175244 | testcase( i==123 ); /* FOLLOWING */ |
| 169527 | testcase( i==123 ); /* FROM */ | 175245 | testcase( i==124 ); /* FROM */ |
| 169528 | testcase( i==124 ); /* FULL */ | 175246 | testcase( i==125 ); /* FULL */ |
| 169529 | testcase( i==125 ); /* LIMIT */ | 175247 | testcase( i==126 ); /* LIMIT */ |
| 169530 | testcase( i==126 ); /* IF */ | 175248 | testcase( i==127 ); /* IF */ |
| 169531 | testcase( i==127 ); /* ORDER */ | 175249 | testcase( i==128 ); /* ORDER */ |
| 169532 | testcase( i==128 ); /* RESTRICT */ | 175250 | testcase( i==129 ); /* RESTRICT */ |
| 169533 | testcase( i==129 ); /* OTHERS */ | 175251 | testcase( i==130 ); /* OTHERS */ |
| 169534 | testcase( i==130 ); /* OVER */ | 175252 | testcase( i==131 ); /* OVER */ |
| 169535 | testcase( i==131 ); /* RETURNING */ | 175253 | testcase( i==132 ); /* RETURNING */ |
| 169536 | testcase( i==132 ); /* RIGHT */ | 175254 | testcase( i==133 ); /* RIGHT */ |
| 169537 | testcase( i==133 ); /* ROLLBACK */ | 175255 | testcase( i==134 ); /* ROLLBACK */ |
| 169538 | testcase( i==134 ); /* ROWS */ | 175256 | testcase( i==135 ); /* ROWS */ |
| 169539 | testcase( i==135 ); /* ROW */ | 175257 | testcase( i==136 ); /* ROW */ |
| 169540 | testcase( i==136 ); /* UNBOUNDED */ | 175258 | testcase( i==137 ); /* UNBOUNDED */ |
| 169541 | testcase( i==137 ); /* UNION */ | 175259 | testcase( i==138 ); /* UNION */ |
| 169542 | testcase( i==138 ); /* USING */ | 175260 | testcase( i==139 ); /* USING */ |
| 169543 | testcase( i==139 ); /* VACUUM */ | 175261 | testcase( i==140 ); /* VACUUM */ |
| 169544 | testcase( i==140 ); /* VIEW */ | 175262 | testcase( i==141 ); /* VIEW */ |
| 169545 | testcase( i==141 ); /* WINDOW */ | 175263 | testcase( i==142 ); /* WINDOW */ |
| 169546 | testcase( i==142 ); /* DO */ | 175264 | testcase( i==143 ); /* DO */ |
| 169547 | testcase( i==143 ); /* BY */ | 175265 | testcase( i==144 ); /* BY */ |
| 169548 | testcase( i==144 ); /* INITIALLY */ | 175266 | testcase( i==145 ); /* INITIALLY */ |
| 169549 | testcase( i==145 ); /* ALL */ | 175267 | testcase( i==146 ); /* ALL */ |
| 169550 | testcase( i==146 ); /* PRIMARY */ | 175268 | testcase( i==147 ); /* PRIMARY */ |
| 169551 | *pType = aKWCode[i]; | 175269 | *pType = aKWCode[i]; |
| 169552 | break; | 175270 | break; |
| 169553 | } | ||
| 169554 | } | 175271 | } |
| 169555 | return n; | 175272 | return n; |
| 169556 | } | 175273 | } |
| 169557 | SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ | 175274 | SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ |
| 169558 | int id = TK_ID; | 175275 | int id = TK_ID; |
| 169559 | keywordCode((char*)z, n, &id); | 175276 | if( n>=2 ) keywordCode((char*)z, n, &id); |
| 169560 | return id; | 175277 | return id; |
| 169561 | } | 175278 | } |
| 169562 | #define SQLITE_N_KEYWORD 147 | 175279 | #define SQLITE_N_KEYWORD 147 |
| 169563 | SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ | 175280 | SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ |
| 169564 | if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; | 175281 | if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; |
| 175282 | i++; | ||
| 169565 | *pzName = zKWText + aKWOffset[i]; | 175283 | *pzName = zKWText + aKWOffset[i]; |
| 169566 | *pnName = aKWLen[i]; | 175284 | *pnName = aKWLen[i]; |
| 169567 | return SQLITE_OK; | 175285 | return SQLITE_OK; |
| @@ -169860,7 +175578,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ | |||
| 169860 | testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); | 175578 | testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); |
| 169861 | testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); | 175579 | testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); |
| 169862 | testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); | 175580 | testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); |
| 169863 | testcase( z[0]=='9' ); | 175581 | testcase( z[0]=='9' ); testcase( z[0]=='.' ); |
| 169864 | *tokenType = TK_INTEGER; | 175582 | *tokenType = TK_INTEGER; |
| 169865 | #ifndef SQLITE_OMIT_HEX_INTEGER | 175583 | #ifndef SQLITE_OMIT_HEX_INTEGER |
| 169866 | if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ | 175584 | if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ |
| @@ -169932,7 +175650,8 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ | |||
| 169932 | return i; | 175650 | return i; |
| 169933 | } | 175651 | } |
| 169934 | case CC_KYWD0: { | 175652 | case CC_KYWD0: { |
| 169935 | for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} | 175653 | if( aiClass[z[1]]>CC_KYWD ){ i = 1; break; } |
| 175654 | for(i=2; aiClass[z[i]]<=CC_KYWD; i++){} | ||
| 169936 | if( IdChar(z[i]) ){ | 175655 | if( IdChar(z[i]) ){ |
| 169937 | /* This token started out using characters that can appear in keywords, | 175656 | /* This token started out using characters that can appear in keywords, |
| 169938 | ** but z[i] is a character not allowed within keywords, so this must | 175657 | ** but z[i] is a character not allowed within keywords, so this must |
| @@ -170138,7 +175857,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ | |||
| 170138 | if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ | 175857 | if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ |
| 170139 | sqlite3DeleteTrigger(db, pParse->pNewTrigger); | 175858 | sqlite3DeleteTrigger(db, pParse->pNewTrigger); |
| 170140 | } | 175859 | } |
| 170141 | if( pParse->pVList ) sqlite3DbFreeNN(db, pParse->pVList); | 175860 | if( pParse->pVList ) sqlite3DbNNFreeNN(db, pParse->pVList); |
| 170142 | db->pParse = pParentParse; | 175861 | db->pParse = pParentParse; |
| 170143 | assert( nErr==0 || pParse->rc!=SQLITE_OK ); | 175862 | assert( nErr==0 || pParse->rc!=SQLITE_OK ); |
| 170144 | return nErr; | 175863 | return nErr; |
| @@ -170711,12 +176430,6 @@ static int sqlite3TestExtInit(sqlite3 *db){ | |||
| 170711 | ** Forward declarations of external module initializer functions | 176430 | ** Forward declarations of external module initializer functions |
| 170712 | ** for modules that need them. | 176431 | ** for modules that need them. |
| 170713 | */ | 176432 | */ |
| 170714 | #ifdef SQLITE_ENABLE_FTS1 | ||
| 170715 | SQLITE_PRIVATE int sqlite3Fts1Init(sqlite3*); | ||
| 170716 | #endif | ||
| 170717 | #ifdef SQLITE_ENABLE_FTS2 | ||
| 170718 | SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*); | ||
| 170719 | #endif | ||
| 170720 | #ifdef SQLITE_ENABLE_FTS5 | 176433 | #ifdef SQLITE_ENABLE_FTS5 |
| 170721 | SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); | 176434 | SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); |
| 170722 | #endif | 176435 | #endif |
| @@ -170729,12 +176442,6 @@ SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); | |||
| 170729 | ** built-in extensions. | 176442 | ** built-in extensions. |
| 170730 | */ | 176443 | */ |
| 170731 | static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { | 176444 | static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { |
| 170732 | #ifdef SQLITE_ENABLE_FTS1 | ||
| 170733 | sqlite3Fts1Init, | ||
| 170734 | #endif | ||
| 170735 | #ifdef SQLITE_ENABLE_FTS2 | ||
| 170736 | sqlite3Fts2Init, | ||
| 170737 | #endif | ||
| 170738 | #ifdef SQLITE_ENABLE_FTS3 | 176445 | #ifdef SQLITE_ENABLE_FTS3 |
| 170739 | sqlite3Fts3Init, | 176446 | sqlite3Fts3Init, |
| 170740 | #endif | 176447 | #endif |
| @@ -171100,9 +176807,21 @@ SQLITE_API int sqlite3_config(int op, ...){ | |||
| 171100 | va_list ap; | 176807 | va_list ap; |
| 171101 | int rc = SQLITE_OK; | 176808 | int rc = SQLITE_OK; |
| 171102 | 176809 | ||
| 171103 | /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while | 176810 | /* sqlite3_config() normally returns SQLITE_MISUSE if it is invoked while |
| 171104 | ** the SQLite library is in use. */ | 176811 | ** the SQLite library is in use. Except, a few selected opcodes |
| 171105 | if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; | 176812 | ** are allowed. |
| 176813 | */ | ||
| 176814 | if( sqlite3GlobalConfig.isInit ){ | ||
| 176815 | static const u64 mAnytimeConfigOption = 0 | ||
| 176816 | | MASKBIT64( SQLITE_CONFIG_LOG ) | ||
| 176817 | | MASKBIT64( SQLITE_CONFIG_PCACHE_HDRSZ ) | ||
| 176818 | ; | ||
| 176819 | if( op<0 || op>63 || (MASKBIT64(op) & mAnytimeConfigOption)==0 ){ | ||
| 176820 | return SQLITE_MISUSE_BKPT; | ||
| 176821 | } | ||
| 176822 | testcase( op==SQLITE_CONFIG_LOG ); | ||
| 176823 | testcase( op==SQLITE_CONFIG_PCACHE_HDRSZ ); | ||
| 176824 | } | ||
| 171106 | 176825 | ||
| 171107 | va_start(ap, op); | 176826 | va_start(ap, op); |
| 171108 | switch( op ){ | 176827 | switch( op ){ |
| @@ -171171,6 +176890,7 @@ SQLITE_API int sqlite3_config(int op, ...){ | |||
| 171171 | break; | 176890 | break; |
| 171172 | } | 176891 | } |
| 171173 | case SQLITE_CONFIG_MEMSTATUS: { | 176892 | case SQLITE_CONFIG_MEMSTATUS: { |
| 176893 | assert( !sqlite3GlobalConfig.isInit ); /* Cannot change at runtime */ | ||
| 171174 | /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes | 176894 | /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes |
| 171175 | ** single argument of type int, interpreted as a boolean, which enables | 176895 | ** single argument of type int, interpreted as a boolean, which enables |
| 171176 | ** or disables the collection of memory allocation statistics. */ | 176896 | ** or disables the collection of memory allocation statistics. */ |
| @@ -171294,8 +177014,10 @@ SQLITE_API int sqlite3_config(int op, ...){ | |||
| 171294 | ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); | 177014 | ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); |
| 171295 | */ | 177015 | */ |
| 171296 | typedef void(*LOGFUNC_t)(void*,int,const char*); | 177016 | typedef void(*LOGFUNC_t)(void*,int,const char*); |
| 171297 | sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); | 177017 | LOGFUNC_t xLog = va_arg(ap, LOGFUNC_t); |
| 171298 | sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); | 177018 | void *pLogArg = va_arg(ap, void*); |
| 177019 | AtomicStore(&sqlite3GlobalConfig.xLog, xLog); | ||
| 177020 | AtomicStore(&sqlite3GlobalConfig.pLogArg, pLogArg); | ||
| 171299 | break; | 177021 | break; |
| 171300 | } | 177022 | } |
| 171301 | 177023 | ||
| @@ -171309,7 +177031,8 @@ SQLITE_API int sqlite3_config(int op, ...){ | |||
| 171309 | ** argument of type int. If non-zero, then URI handling is globally | 177031 | ** argument of type int. If non-zero, then URI handling is globally |
| 171310 | ** enabled. If the parameter is zero, then URI handling is globally | 177032 | ** enabled. If the parameter is zero, then URI handling is globally |
| 171311 | ** disabled. */ | 177033 | ** disabled. */ |
| 171312 | sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); | 177034 | int bOpenUri = va_arg(ap, int); |
| 177035 | AtomicStore(&sqlite3GlobalConfig.bOpenUri, bOpenUri); | ||
| 171313 | break; | 177036 | break; |
| 171314 | } | 177037 | } |
| 171315 | 177038 | ||
| @@ -171494,18 +177217,19 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ | |||
| 171494 | db->lookaside.bMalloced = pBuf==0 ?1:0; | 177217 | db->lookaside.bMalloced = pBuf==0 ?1:0; |
| 171495 | db->lookaside.nSlot = nBig+nSm; | 177218 | db->lookaside.nSlot = nBig+nSm; |
| 171496 | }else{ | 177219 | }else{ |
| 171497 | db->lookaside.pStart = db; | 177220 | db->lookaside.pStart = 0; |
| 171498 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE | 177221 | #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE |
| 171499 | db->lookaside.pSmallInit = 0; | 177222 | db->lookaside.pSmallInit = 0; |
| 171500 | db->lookaside.pSmallFree = 0; | 177223 | db->lookaside.pSmallFree = 0; |
| 171501 | db->lookaside.pMiddle = db; | 177224 | db->lookaside.pMiddle = 0; |
| 171502 | #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ | 177225 | #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ |
| 171503 | db->lookaside.pEnd = db; | 177226 | db->lookaside.pEnd = 0; |
| 171504 | db->lookaside.bDisable = 1; | 177227 | db->lookaside.bDisable = 1; |
| 171505 | db->lookaside.sz = 0; | 177228 | db->lookaside.sz = 0; |
| 171506 | db->lookaside.bMalloced = 0; | 177229 | db->lookaside.bMalloced = 0; |
| 171507 | db->lookaside.nSlot = 0; | 177230 | db->lookaside.nSlot = 0; |
| 171508 | } | 177231 | } |
| 177232 | db->lookaside.pTrueEnd = db->lookaside.pEnd; | ||
| 171509 | assert( sqlite3LookasideUsed(db,0)==0 ); | 177233 | assert( sqlite3LookasideUsed(db,0)==0 ); |
| 171510 | #endif /* SQLITE_OMIT_LOOKASIDE */ | 177234 | #endif /* SQLITE_OMIT_LOOKASIDE */ |
| 171511 | return SQLITE_OK; | 177235 | return SQLITE_OK; |
| @@ -171584,6 +177308,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ | |||
| 171584 | SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ | 177308 | SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ |
| 171585 | va_list ap; | 177309 | va_list ap; |
| 171586 | int rc; | 177310 | int rc; |
| 177311 | sqlite3_mutex_enter(db->mutex); | ||
| 171587 | va_start(ap, op); | 177312 | va_start(ap, op); |
| 171588 | switch( op ){ | 177313 | switch( op ){ |
| 171589 | case SQLITE_DBCONFIG_MAINDBNAME: { | 177314 | case SQLITE_DBCONFIG_MAINDBNAME: { |
| @@ -171622,6 +177347,8 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ | |||
| 171622 | { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, | 177347 | { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, |
| 171623 | { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, | 177348 | { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, |
| 171624 | { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema }, | 177349 | { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema }, |
| 177350 | { SQLITE_DBCONFIG_STMT_SCANSTATUS, SQLITE_StmtScanStatus }, | ||
| 177351 | { SQLITE_DBCONFIG_REVERSE_SCANORDER, SQLITE_ReverseOrder }, | ||
| 171625 | }; | 177352 | }; |
| 171626 | unsigned int i; | 177353 | unsigned int i; |
| 171627 | rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ | 177354 | rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ |
| @@ -171649,6 +177376,7 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ | |||
| 171649 | } | 177376 | } |
| 171650 | } | 177377 | } |
| 171651 | va_end(ap); | 177378 | va_end(ap); |
| 177379 | sqlite3_mutex_leave(db->mutex); | ||
| 171652 | return rc; | 177380 | return rc; |
| 171653 | } | 177381 | } |
| 171654 | 177382 | ||
| @@ -172233,6 +177961,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ | |||
| 172233 | case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; | 177961 | case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; |
| 172234 | case SQLITE_NOTICE_RECOVER_ROLLBACK: | 177962 | case SQLITE_NOTICE_RECOVER_ROLLBACK: |
| 172235 | zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; | 177963 | zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; |
| 177964 | case SQLITE_NOTICE_RBU: zName = "SQLITE_NOTICE_RBU"; break; | ||
| 172236 | case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; | 177965 | case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; |
| 172237 | case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; | 177966 | case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; |
| 172238 | case SQLITE_DONE: zName = "SQLITE_DONE"; break; | 177967 | case SQLITE_DONE: zName = "SQLITE_DONE"; break; |
| @@ -172325,9 +178054,9 @@ static int sqliteDefaultBusyCallback( | |||
| 172325 | void *ptr, /* Database connection */ | 178054 | void *ptr, /* Database connection */ |
| 172326 | int count /* Number of times table has been busy */ | 178055 | int count /* Number of times table has been busy */ |
| 172327 | ){ | 178056 | ){ |
| 172328 | #if SQLITE_OS_WIN || HAVE_USLEEP | 178057 | #if SQLITE_OS_WIN || !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP |
| 172329 | /* This case is for systems that have support for sleeping for fractions of | 178058 | /* This case is for systems that have support for sleeping for fractions of |
| 172330 | ** a second. Examples: All windows systems, unix systems with usleep() */ | 178059 | ** a second. Examples: All windows systems, unix systems with nanosleep() */ |
| 172331 | static const u8 delays[] = | 178060 | static const u8 delays[] = |
| 172332 | { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; | 178061 | { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; |
| 172333 | static const u8 totals[] = | 178062 | static const u8 totals[] = |
| @@ -172462,7 +178191,9 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ | |||
| 172462 | */ | 178191 | */ |
| 172463 | SQLITE_API void sqlite3_interrupt(sqlite3 *db){ | 178192 | SQLITE_API void sqlite3_interrupt(sqlite3 *db){ |
| 172464 | #ifdef SQLITE_ENABLE_API_ARMOR | 178193 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 172465 | if( !sqlite3SafetyCheckOk(db) && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) ){ | 178194 | if( !sqlite3SafetyCheckOk(db) |
| 178195 | && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) | ||
| 178196 | ){ | ||
| 172466 | (void)SQLITE_MISUSE_BKPT; | 178197 | (void)SQLITE_MISUSE_BKPT; |
| 172467 | return; | 178198 | return; |
| 172468 | } | 178199 | } |
| @@ -172470,6 +178201,21 @@ SQLITE_API void sqlite3_interrupt(sqlite3 *db){ | |||
| 172470 | AtomicStore(&db->u1.isInterrupted, 1); | 178201 | AtomicStore(&db->u1.isInterrupted, 1); |
| 172471 | } | 178202 | } |
| 172472 | 178203 | ||
| 178204 | /* | ||
| 178205 | ** Return true or false depending on whether or not an interrupt is | ||
| 178206 | ** pending on connection db. | ||
| 178207 | */ | ||
| 178208 | SQLITE_API int sqlite3_is_interrupted(sqlite3 *db){ | ||
| 178209 | #ifdef SQLITE_ENABLE_API_ARMOR | ||
| 178210 | if( !sqlite3SafetyCheckOk(db) | ||
| 178211 | && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) | ||
| 178212 | ){ | ||
| 178213 | (void)SQLITE_MISUSE_BKPT; | ||
| 178214 | return 0; | ||
| 178215 | } | ||
| 178216 | #endif | ||
| 178217 | return AtomicLoad(&db->u1.isInterrupted)!=0; | ||
| 178218 | } | ||
| 172473 | 178219 | ||
| 172474 | /* | 178220 | /* |
| 172475 | ** This function is exactly the same as sqlite3_create_function(), except | 178221 | ** This function is exactly the same as sqlite3_create_function(), except |
| @@ -172514,7 +178260,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( | |||
| 172514 | /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But | 178260 | /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But |
| 172515 | ** the meaning is inverted. So flip the bit. */ | 178261 | ** the meaning is inverted. So flip the bit. */ |
| 172516 | assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS ); | 178262 | assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS ); |
| 172517 | extraFlags ^= SQLITE_FUNC_UNSAFE; | 178263 | extraFlags ^= SQLITE_FUNC_UNSAFE; /* tag-20230109-1 */ |
| 172518 | 178264 | ||
| 172519 | 178265 | ||
| 172520 | #ifndef SQLITE_OMIT_UTF16 | 178266 | #ifndef SQLITE_OMIT_UTF16 |
| @@ -172532,11 +178278,11 @@ SQLITE_PRIVATE int sqlite3CreateFunc( | |||
| 172532 | case SQLITE_ANY: { | 178278 | case SQLITE_ANY: { |
| 172533 | int rc; | 178279 | int rc; |
| 172534 | rc = sqlite3CreateFunc(db, zFunctionName, nArg, | 178280 | rc = sqlite3CreateFunc(db, zFunctionName, nArg, |
| 172535 | (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, | 178281 | (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, /* tag-20230109-1 */ |
| 172536 | pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); | 178282 | pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); |
| 172537 | if( rc==SQLITE_OK ){ | 178283 | if( rc==SQLITE_OK ){ |
| 172538 | rc = sqlite3CreateFunc(db, zFunctionName, nArg, | 178284 | rc = sqlite3CreateFunc(db, zFunctionName, nArg, |
| 172539 | (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, | 178285 | (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, /* tag-20230109-1*/ |
| 172540 | pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); | 178286 | pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); |
| 172541 | } | 178287 | } |
| 172542 | if( rc!=SQLITE_OK ){ | 178288 | if( rc!=SQLITE_OK ){ |
| @@ -172785,7 +178531,7 @@ SQLITE_API int sqlite3_overload_function( | |||
| 172785 | rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; | 178531 | rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; |
| 172786 | sqlite3_mutex_leave(db->mutex); | 178532 | sqlite3_mutex_leave(db->mutex); |
| 172787 | if( rc ) return SQLITE_OK; | 178533 | if( rc ) return SQLITE_OK; |
| 172788 | zCopy = sqlite3_mprintf(zName); | 178534 | zCopy = sqlite3_mprintf("%s", zName); |
| 172789 | if( zCopy==0 ) return SQLITE_NOMEM; | 178535 | if( zCopy==0 ) return SQLITE_NOMEM; |
| 172790 | return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, | 178536 | return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, |
| 172791 | zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); | 178537 | zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); |
| @@ -173588,9 +179334,9 @@ SQLITE_PRIVATE int sqlite3ParseUri( | |||
| 173588 | 179334 | ||
| 173589 | assert( *pzErrMsg==0 ); | 179335 | assert( *pzErrMsg==0 ); |
| 173590 | 179336 | ||
| 173591 | if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ | 179337 | if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ |
| 173592 | || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */ | 179338 | || AtomicLoad(&sqlite3GlobalConfig.bOpenUri)) /* IMP: R-51689-46548 */ |
| 173593 | && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ | 179339 | && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ |
| 173594 | ){ | 179340 | ){ |
| 173595 | char *zOpt; | 179341 | char *zOpt; |
| 173596 | int eState; /* Parser state when parsing URI */ | 179342 | int eState; /* Parser state when parsing URI */ |
| @@ -173948,7 +179694,7 @@ static int openDatabase( | |||
| 173948 | ** 0 off off | 179694 | ** 0 off off |
| 173949 | ** | 179695 | ** |
| 173950 | ** Legacy behavior is 3 (double-quoted string literals are allowed anywhere) | 179696 | ** Legacy behavior is 3 (double-quoted string literals are allowed anywhere) |
| 173951 | ** and so that is the default. But developers are encouranged to use | 179697 | ** and so that is the default. But developers are encouraged to use |
| 173952 | ** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible. | 179698 | ** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible. |
| 173953 | */ | 179699 | */ |
| 173954 | #if !defined(SQLITE_DQS) | 179700 | #if !defined(SQLITE_DQS) |
| @@ -173997,6 +179743,9 @@ static int openDatabase( | |||
| 173997 | #if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE) | 179743 | #if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE) |
| 173998 | | SQLITE_LegacyAlter | 179744 | | SQLITE_LegacyAlter |
| 173999 | #endif | 179745 | #endif |
| 179746 | #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) | ||
| 179747 | | SQLITE_StmtScanStatus | ||
| 179748 | #endif | ||
| 174000 | ; | 179749 | ; |
| 174001 | sqlite3HashInit(&db->aCollSeq); | 179750 | sqlite3HashInit(&db->aCollSeq); |
| 174002 | #ifndef SQLITE_OMIT_VIRTUALTABLE | 179751 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| @@ -174019,6 +179768,19 @@ static int openDatabase( | |||
| 174019 | goto opendb_out; | 179768 | goto opendb_out; |
| 174020 | } | 179769 | } |
| 174021 | 179770 | ||
| 179771 | #if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) | ||
| 179772 | /* Process magic filenames ":localStorage:" and ":sessionStorage:" */ | ||
| 179773 | if( zFilename && zFilename[0]==':' ){ | ||
| 179774 | if( strcmp(zFilename, ":localStorage:")==0 ){ | ||
| 179775 | zFilename = "file:local?vfs=kvvfs"; | ||
| 179776 | flags |= SQLITE_OPEN_URI; | ||
| 179777 | }else if( strcmp(zFilename, ":sessionStorage:")==0 ){ | ||
| 179778 | zFilename = "file:session?vfs=kvvfs"; | ||
| 179779 | flags |= SQLITE_OPEN_URI; | ||
| 179780 | } | ||
| 179781 | } | ||
| 179782 | #endif /* SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) */ | ||
| 179783 | |||
| 174022 | /* Parse the filename/URI argument | 179784 | /* Parse the filename/URI argument |
| 174023 | ** | 179785 | ** |
| 174024 | ** Only allow sensible combinations of bits in the flags argument. | 179786 | ** Only allow sensible combinations of bits in the flags argument. |
| @@ -174049,6 +179811,12 @@ static int openDatabase( | |||
| 174049 | sqlite3_free(zErrMsg); | 179811 | sqlite3_free(zErrMsg); |
| 174050 | goto opendb_out; | 179812 | goto opendb_out; |
| 174051 | } | 179813 | } |
| 179814 | assert( db->pVfs!=0 ); | ||
| 179815 | #if SQLITE_OS_KV || defined(SQLITE_OS_KV_OPTIONAL) | ||
| 179816 | if( sqlite3_stricmp(db->pVfs->zName, "kvvfs")==0 ){ | ||
| 179817 | db->temp_store = 2; | ||
| 179818 | } | ||
| 179819 | #endif | ||
| 174052 | 179820 | ||
| 174053 | /* Open the backend database driver */ | 179821 | /* Open the backend database driver */ |
| 174054 | rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, | 179822 | rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, |
| @@ -174461,7 +180229,7 @@ SQLITE_API int sqlite3_table_column_metadata( | |||
| 174461 | 180229 | ||
| 174462 | /* Find the column for which info is requested */ | 180230 | /* Find the column for which info is requested */ |
| 174463 | if( zColumnName==0 ){ | 180231 | if( zColumnName==0 ){ |
| 174464 | /* Query for existance of table only */ | 180232 | /* Query for existence of table only */ |
| 174465 | }else{ | 180233 | }else{ |
| 174466 | for(iCol=0; iCol<pTab->nCol; iCol++){ | 180234 | for(iCol=0; iCol<pTab->nCol; iCol++){ |
| 174467 | pCol = &pTab->aCol[iCol]; | 180235 | pCol = &pTab->aCol[iCol]; |
| @@ -174542,7 +180310,7 @@ SQLITE_API int sqlite3_sleep(int ms){ | |||
| 174542 | /* This function works in milliseconds, but the underlying OsSleep() | 180310 | /* This function works in milliseconds, but the underlying OsSleep() |
| 174543 | ** API uses microseconds. Hence the 1000's. | 180311 | ** API uses microseconds. Hence the 1000's. |
| 174544 | */ | 180312 | */ |
| 174545 | rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000); | 180313 | rc = (sqlite3OsSleep(pVfs, ms<0 ? 0 : 1000*ms)/1000); |
| 174546 | return rc; | 180314 | return rc; |
| 174547 | } | 180315 | } |
| 174548 | 180316 | ||
| @@ -174598,6 +180366,9 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo | |||
| 174598 | sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0); | 180366 | sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0); |
| 174599 | } | 180367 | } |
| 174600 | rc = SQLITE_OK; | 180368 | rc = SQLITE_OK; |
| 180369 | }else if( op==SQLITE_FCNTL_RESET_CACHE ){ | ||
| 180370 | sqlite3BtreeClearCache(pBtree); | ||
| 180371 | rc = SQLITE_OK; | ||
| 174601 | }else{ | 180372 | }else{ |
| 174602 | int nSave = db->busyHandler.nBusy; | 180373 | int nSave = db->busyHandler.nBusy; |
| 174603 | rc = sqlite3OsFileControl(fd, op, pArg); | 180374 | rc = sqlite3OsFileControl(fd, op, pArg); |
| @@ -174778,10 +180549,12 @@ SQLITE_API int sqlite3_test_control(int op, ...){ | |||
| 174778 | sqlite3ShowSrcList(0); | 180549 | sqlite3ShowSrcList(0); |
| 174779 | sqlite3ShowWith(0); | 180550 | sqlite3ShowWith(0); |
| 174780 | sqlite3ShowUpsert(0); | 180551 | sqlite3ShowUpsert(0); |
| 180552 | #ifndef SQLITE_OMIT_TRIGGER | ||
| 174781 | sqlite3ShowTriggerStep(0); | 180553 | sqlite3ShowTriggerStep(0); |
| 174782 | sqlite3ShowTriggerStepList(0); | 180554 | sqlite3ShowTriggerStepList(0); |
| 174783 | sqlite3ShowTrigger(0); | 180555 | sqlite3ShowTrigger(0); |
| 174784 | sqlite3ShowTriggerList(0); | 180556 | sqlite3ShowTriggerList(0); |
| 180557 | #endif | ||
| 174785 | #ifndef SQLITE_OMIT_WINDOWFUNC | 180558 | #ifndef SQLITE_OMIT_WINDOWFUNC |
| 174786 | sqlite3ShowWindow(0); | 180559 | sqlite3ShowWindow(0); |
| 174787 | sqlite3ShowWinFunc(0); | 180560 | sqlite3ShowWinFunc(0); |
| @@ -174898,7 +180671,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ | |||
| 174898 | ** formed and never corrupt. This flag is clear by default, indicating that | 180671 | ** formed and never corrupt. This flag is clear by default, indicating that |
| 174899 | ** database files might have arbitrary corruption. Setting the flag during | 180672 | ** database files might have arbitrary corruption. Setting the flag during |
| 174900 | ** testing causes certain assert() statements in the code to be activated | 180673 | ** testing causes certain assert() statements in the code to be activated |
| 174901 | ** that demonstrat invariants on well-formed database files. | 180674 | ** that demonstrate invariants on well-formed database files. |
| 174902 | */ | 180675 | */ |
| 174903 | case SQLITE_TESTCTRL_NEVER_CORRUPT: { | 180676 | case SQLITE_TESTCTRL_NEVER_CORRUPT: { |
| 174904 | sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); | 180677 | sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); |
| @@ -175052,7 +180825,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ | |||
| 175052 | ** | 180825 | ** |
| 175053 | ** op==0 Store the current sqlite3TreeTrace in *ptr | 180826 | ** op==0 Store the current sqlite3TreeTrace in *ptr |
| 175054 | ** op==1 Set sqlite3TreeTrace to the value *ptr | 180827 | ** op==1 Set sqlite3TreeTrace to the value *ptr |
| 175055 | ** op==3 Store the current sqlite3WhereTrace in *ptr | 180828 | ** op==2 Store the current sqlite3WhereTrace in *ptr |
| 175056 | ** op==3 Set sqlite3WhereTrace to the value *ptr | 180829 | ** op==3 Set sqlite3WhereTrace to the value *ptr |
| 175057 | */ | 180830 | */ |
| 175058 | case SQLITE_TESTCTRL_TRACEFLAGS: { | 180831 | case SQLITE_TESTCTRL_TRACEFLAGS: { |
| @@ -175088,6 +180861,23 @@ SQLITE_API int sqlite3_test_control(int op, ...){ | |||
| 175088 | break; | 180861 | break; |
| 175089 | } | 180862 | } |
| 175090 | 180863 | ||
| 180864 | #if !defined(SQLITE_OMIT_WSD) | ||
| 180865 | /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); | ||
| 180866 | ** | ||
| 180867 | ** X<0 Make no changes to the bUseLongDouble. Just report value. | ||
| 180868 | ** X==0 Disable bUseLongDouble | ||
| 180869 | ** X==1 Enable bUseLongDouble | ||
| 180870 | ** X==2 Set bUseLongDouble to its default value for this platform | ||
| 180871 | */ | ||
| 180872 | case SQLITE_TESTCTRL_USELONGDOUBLE: { | ||
| 180873 | int b = va_arg(ap, int); | ||
| 180874 | if( b==2 ) b = sizeof(LONGDOUBLE_TYPE)>8; | ||
| 180875 | if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; | ||
| 180876 | rc = sqlite3Config.bUseLongDouble!=0; | ||
| 180877 | break; | ||
| 180878 | } | ||
| 180879 | #endif | ||
| 180880 | |||
| 175091 | 180881 | ||
| 175092 | #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) | 180882 | #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) |
| 175093 | /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) | 180883 | /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) |
| @@ -175158,7 +180948,7 @@ static char *appendText(char *p, const char *z){ | |||
| 175158 | ** Memory layout must be compatible with that generated by the pager | 180948 | ** Memory layout must be compatible with that generated by the pager |
| 175159 | ** and expected by sqlite3_uri_parameter() and databaseName(). | 180949 | ** and expected by sqlite3_uri_parameter() and databaseName(). |
| 175160 | */ | 180950 | */ |
| 175161 | SQLITE_API char *sqlite3_create_filename( | 180951 | SQLITE_API const char *sqlite3_create_filename( |
| 175162 | const char *zDatabase, | 180952 | const char *zDatabase, |
| 175163 | const char *zJournal, | 180953 | const char *zJournal, |
| 175164 | const char *zWal, | 180954 | const char *zWal, |
| @@ -175194,10 +180984,10 @@ SQLITE_API char *sqlite3_create_filename( | |||
| 175194 | ** error to call this routine with any parameter other than a pointer | 180984 | ** error to call this routine with any parameter other than a pointer |
| 175195 | ** previously obtained from sqlite3_create_filename() or a NULL pointer. | 180985 | ** previously obtained from sqlite3_create_filename() or a NULL pointer. |
| 175196 | */ | 180986 | */ |
| 175197 | SQLITE_API void sqlite3_free_filename(char *p){ | 180987 | SQLITE_API void sqlite3_free_filename(const char *p){ |
| 175198 | if( p==0 ) return; | 180988 | if( p==0 ) return; |
| 175199 | p = (char*)databaseName(p); | 180989 | p = databaseName(p); |
| 175200 | sqlite3_free(p - 4); | 180990 | sqlite3_free((char*)p - 4); |
| 175201 | } | 180991 | } |
| 175202 | 180992 | ||
| 175203 | 180993 | ||
| @@ -175388,7 +181178,7 @@ SQLITE_API int sqlite3_snapshot_get( | |||
| 175388 | } | 181178 | } |
| 175389 | 181179 | ||
| 175390 | /* | 181180 | /* |
| 175391 | ** Open a read-transaction on the snapshot idendified by pSnapshot. | 181181 | ** Open a read-transaction on the snapshot identified by pSnapshot. |
| 175392 | */ | 181182 | */ |
| 175393 | SQLITE_API int sqlite3_snapshot_open( | 181183 | SQLITE_API int sqlite3_snapshot_open( |
| 175394 | sqlite3 *db, | 181184 | sqlite3 *db, |
| @@ -175448,8 +181238,8 @@ SQLITE_API int sqlite3_snapshot_open( | |||
| 175448 | */ | 181238 | */ |
| 175449 | SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ | 181239 | SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ |
| 175450 | int rc = SQLITE_ERROR; | 181240 | int rc = SQLITE_ERROR; |
| 175451 | int iDb; | ||
| 175452 | #ifndef SQLITE_OMIT_WAL | 181241 | #ifndef SQLITE_OMIT_WAL |
| 181242 | int iDb; | ||
| 175453 | 181243 | ||
| 175454 | #ifdef SQLITE_ENABLE_API_ARMOR | 181244 | #ifdef SQLITE_ENABLE_API_ARMOR |
| 175455 | if( !sqlite3SafetyCheckOk(db) ){ | 181245 | if( !sqlite3SafetyCheckOk(db) ){ |
| @@ -177004,7 +182794,7 @@ struct Fts3MultiSegReader { | |||
| 177004 | int nAdvance; /* How many seg-readers to advance */ | 182794 | int nAdvance; /* How many seg-readers to advance */ |
| 177005 | Fts3SegFilter *pFilter; /* Pointer to filter object */ | 182795 | Fts3SegFilter *pFilter; /* Pointer to filter object */ |
| 177006 | char *aBuffer; /* Buffer to merge doclists in */ | 182796 | char *aBuffer; /* Buffer to merge doclists in */ |
| 177007 | int nBuffer; /* Allocated size of aBuffer[] in bytes */ | 182797 | i64 nBuffer; /* Allocated size of aBuffer[] in bytes */ |
| 177008 | 182798 | ||
| 177009 | int iColFilter; /* If >=0, filter for this column */ | 182799 | int iColFilter; /* If >=0, filter for this column */ |
| 177010 | int bRestart; | 182800 | int bRestart; |
| @@ -177096,6 +182886,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); | |||
| 177096 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); | 182886 | SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); |
| 177097 | #endif | 182887 | #endif |
| 177098 | 182888 | ||
| 182889 | SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); | ||
| 182890 | |||
| 177099 | #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ | 182891 | #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ |
| 177100 | #endif /* _FTSINT_H */ | 182892 | #endif /* _FTSINT_H */ |
| 177101 | 182893 | ||
| @@ -179700,7 +185492,7 @@ static int fts3TermSelectMerge( | |||
| 179700 | ** | 185492 | ** |
| 179701 | ** Similar padding is added in the fts3DoclistOrMerge() function. | 185493 | ** Similar padding is added in the fts3DoclistOrMerge() function. |
| 179702 | */ | 185494 | */ |
| 179703 | pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1); | 185495 | pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1); |
| 179704 | pTS->anOutput[0] = nDoclist; | 185496 | pTS->anOutput[0] = nDoclist; |
| 179705 | if( pTS->aaOutput[0] ){ | 185497 | if( pTS->aaOutput[0] ){ |
| 179706 | memcpy(pTS->aaOutput[0], aDoclist, nDoclist); | 185498 | memcpy(pTS->aaOutput[0], aDoclist, nDoclist); |
| @@ -181557,7 +187349,7 @@ static int fts3EvalIncrPhraseNext( | |||
| 181557 | if( bEof==0 ){ | 187349 | if( bEof==0 ){ |
| 181558 | int nList = 0; | 187350 | int nList = 0; |
| 181559 | int nByte = a[p->nToken-1].nList; | 187351 | int nByte = a[p->nToken-1].nList; |
| 181560 | char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING); | 187352 | char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING); |
| 181561 | if( !aDoclist ) return SQLITE_NOMEM; | 187353 | if( !aDoclist ) return SQLITE_NOMEM; |
| 181562 | memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); | 187354 | memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); |
| 181563 | memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING); | 187355 | memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING); |
| @@ -182099,9 +187891,8 @@ static void fts3EvalNextRow( | |||
| 182099 | Fts3Expr *pExpr, /* Expr. to advance to next matching row */ | 187891 | Fts3Expr *pExpr, /* Expr. to advance to next matching row */ |
| 182100 | int *pRc /* IN/OUT: Error code */ | 187892 | int *pRc /* IN/OUT: Error code */ |
| 182101 | ){ | 187893 | ){ |
| 182102 | if( *pRc==SQLITE_OK ){ | 187894 | if( *pRc==SQLITE_OK && pExpr->bEof==0 ){ |
| 182103 | int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */ | 187895 | int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */ |
| 182104 | assert( pExpr->bEof==0 ); | ||
| 182105 | pExpr->bStart = 1; | 187896 | pExpr->bStart = 1; |
| 182106 | 187897 | ||
| 182107 | switch( pExpr->eType ){ | 187898 | switch( pExpr->eType ){ |
| @@ -182578,6 +188369,22 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){ | |||
| 182578 | } | 188369 | } |
| 182579 | 188370 | ||
| 182580 | /* | 188371 | /* |
| 188372 | ** This is an sqlite3Fts3ExprIterate() callback. If the Fts3Expr.aMI[] array | ||
| 188373 | ** has not yet been allocated, allocate and zero it. Otherwise, just zero | ||
| 188374 | ** it. | ||
| 188375 | */ | ||
| 188376 | static int fts3AllocateMSI(Fts3Expr *pExpr, int iPhrase, void *pCtx){ | ||
| 188377 | Fts3Table *pTab = (Fts3Table*)pCtx; | ||
| 188378 | UNUSED_PARAMETER(iPhrase); | ||
| 188379 | if( pExpr->aMI==0 ){ | ||
| 188380 | pExpr->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); | ||
| 188381 | if( pExpr->aMI==0 ) return SQLITE_NOMEM; | ||
| 188382 | } | ||
| 188383 | memset(pExpr->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); | ||
| 188384 | return SQLITE_OK; | ||
| 188385 | } | ||
| 188386 | |||
| 188387 | /* | ||
| 182581 | ** Expression pExpr must be of type FTSQUERY_PHRASE. | 188388 | ** Expression pExpr must be of type FTSQUERY_PHRASE. |
| 182582 | ** | 188389 | ** |
| 182583 | ** If it is not already allocated and populated, this function allocates and | 188390 | ** If it is not already allocated and populated, this function allocates and |
| @@ -182598,7 +188405,6 @@ static int fts3EvalGatherStats( | |||
| 182598 | if( pExpr->aMI==0 ){ | 188405 | if( pExpr->aMI==0 ){ |
| 182599 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; | 188406 | Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; |
| 182600 | Fts3Expr *pRoot; /* Root of NEAR expression */ | 188407 | Fts3Expr *pRoot; /* Root of NEAR expression */ |
| 182601 | Fts3Expr *p; /* Iterator used for several purposes */ | ||
| 182602 | 188408 | ||
| 182603 | sqlite3_int64 iPrevId = pCsr->iPrevId; | 188409 | sqlite3_int64 iPrevId = pCsr->iPrevId; |
| 182604 | sqlite3_int64 iDocid; | 188410 | sqlite3_int64 iDocid; |
| @@ -182606,7 +188412,9 @@ static int fts3EvalGatherStats( | |||
| 182606 | 188412 | ||
| 182607 | /* Find the root of the NEAR expression */ | 188413 | /* Find the root of the NEAR expression */ |
| 182608 | pRoot = pExpr; | 188414 | pRoot = pExpr; |
| 182609 | while( pRoot->pParent && pRoot->pParent->eType==FTSQUERY_NEAR ){ | 188415 | while( pRoot->pParent |
| 188416 | && (pRoot->pParent->eType==FTSQUERY_NEAR || pRoot->bDeferred) | ||
| 188417 | ){ | ||
| 182610 | pRoot = pRoot->pParent; | 188418 | pRoot = pRoot->pParent; |
| 182611 | } | 188419 | } |
| 182612 | iDocid = pRoot->iDocid; | 188420 | iDocid = pRoot->iDocid; |
| @@ -182614,14 +188422,8 @@ static int fts3EvalGatherStats( | |||
| 182614 | assert( pRoot->bStart ); | 188422 | assert( pRoot->bStart ); |
| 182615 | 188423 | ||
| 182616 | /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ | 188424 | /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ |
| 182617 | for(p=pRoot; p; p=p->pLeft){ | 188425 | rc = sqlite3Fts3ExprIterate(pRoot, fts3AllocateMSI, (void*)pTab); |
| 182618 | Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight); | 188426 | if( rc!=SQLITE_OK ) return rc; |
| 182619 | assert( pE->aMI==0 ); | ||
| 182620 | pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); | ||
| 182621 | if( !pE->aMI ) return SQLITE_NOMEM; | ||
| 182622 | memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); | ||
| 182623 | } | ||
| 182624 | |||
| 182625 | fts3EvalRestart(pCsr, pRoot, &rc); | 188427 | fts3EvalRestart(pCsr, pRoot, &rc); |
| 182626 | 188428 | ||
| 182627 | while( pCsr->isEof==0 && rc==SQLITE_OK ){ | 188429 | while( pCsr->isEof==0 && rc==SQLITE_OK ){ |
| @@ -182777,6 +188579,7 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( | |||
| 182777 | u8 bTreeEof = 0; | 188579 | u8 bTreeEof = 0; |
| 182778 | Fts3Expr *p; /* Used to iterate from pExpr to root */ | 188580 | Fts3Expr *p; /* Used to iterate from pExpr to root */ |
| 182779 | Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ | 188581 | Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ |
| 188582 | Fts3Expr *pRun; /* Closest non-deferred ancestor of pNear */ | ||
| 182780 | int bMatch; | 188583 | int bMatch; |
| 182781 | 188584 | ||
| 182782 | /* Check if this phrase descends from an OR expression node. If not, | 188585 | /* Check if this phrase descends from an OR expression node. If not, |
| @@ -182791,25 +188594,30 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( | |||
| 182791 | if( p->bEof ) bTreeEof = 1; | 188594 | if( p->bEof ) bTreeEof = 1; |
| 182792 | } | 188595 | } |
| 182793 | if( bOr==0 ) return SQLITE_OK; | 188596 | if( bOr==0 ) return SQLITE_OK; |
| 188597 | pRun = pNear; | ||
| 188598 | while( pRun->bDeferred ){ | ||
| 188599 | assert( pRun->pParent ); | ||
| 188600 | pRun = pRun->pParent; | ||
| 188601 | } | ||
| 182794 | 188602 | ||
| 182795 | /* This is the descendent of an OR node. In this case we cannot use | 188603 | /* This is the descendent of an OR node. In this case we cannot use |
| 182796 | ** an incremental phrase. Load the entire doclist for the phrase | 188604 | ** an incremental phrase. Load the entire doclist for the phrase |
| 182797 | ** into memory in this case. */ | 188605 | ** into memory in this case. */ |
| 182798 | if( pPhrase->bIncr ){ | 188606 | if( pPhrase->bIncr ){ |
| 182799 | int bEofSave = pNear->bEof; | 188607 | int bEofSave = pRun->bEof; |
| 182800 | fts3EvalRestart(pCsr, pNear, &rc); | 188608 | fts3EvalRestart(pCsr, pRun, &rc); |
| 182801 | while( rc==SQLITE_OK && !pNear->bEof ){ | 188609 | while( rc==SQLITE_OK && !pRun->bEof ){ |
| 182802 | fts3EvalNextRow(pCsr, pNear, &rc); | 188610 | fts3EvalNextRow(pCsr, pRun, &rc); |
| 182803 | if( bEofSave==0 && pNear->iDocid==iDocid ) break; | 188611 | if( bEofSave==0 && pRun->iDocid==iDocid ) break; |
| 182804 | } | 188612 | } |
| 182805 | assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); | 188613 | assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); |
| 182806 | if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){ | 188614 | if( rc==SQLITE_OK && pRun->bEof!=bEofSave ){ |
| 182807 | rc = FTS_CORRUPT_VTAB; | 188615 | rc = FTS_CORRUPT_VTAB; |
| 182808 | } | 188616 | } |
| 182809 | } | 188617 | } |
| 182810 | if( bTreeEof ){ | 188618 | if( bTreeEof ){ |
| 182811 | while( rc==SQLITE_OK && !pNear->bEof ){ | 188619 | while( rc==SQLITE_OK && !pRun->bEof ){ |
| 182812 | fts3EvalNextRow(pCsr, pNear, &rc); | 188620 | fts3EvalNextRow(pCsr, pRun, &rc); |
| 182813 | } | 188621 | } |
| 182814 | } | 188622 | } |
| 182815 | if( rc!=SQLITE_OK ) return rc; | 188623 | if( rc!=SQLITE_OK ) return rc; |
| @@ -185793,7 +191601,7 @@ static int porterNext( | |||
| 185793 | if( n>c->nAllocated ){ | 191601 | if( n>c->nAllocated ){ |
| 185794 | char *pNew; | 191602 | char *pNew; |
| 185795 | c->nAllocated = n+20; | 191603 | c->nAllocated = n+20; |
| 185796 | pNew = sqlite3_realloc(c->zToken, c->nAllocated); | 191604 | pNew = sqlite3_realloc64(c->zToken, c->nAllocated); |
| 185797 | if( !pNew ) return SQLITE_NOMEM; | 191605 | if( !pNew ) return SQLITE_NOMEM; |
| 185798 | c->zToken = pNew; | 191606 | c->zToken = pNew; |
| 185799 | } | 191607 | } |
| @@ -186545,7 +192353,7 @@ static int simpleNext( | |||
| 186545 | if( n>c->nTokenAllocated ){ | 192353 | if( n>c->nTokenAllocated ){ |
| 186546 | char *pNew; | 192354 | char *pNew; |
| 186547 | c->nTokenAllocated = n+20; | 192355 | c->nTokenAllocated = n+20; |
| 186548 | pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated); | 192356 | pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated); |
| 186549 | if( !pNew ) return SQLITE_NOMEM; | 192357 | if( !pNew ) return SQLITE_NOMEM; |
| 186550 | c->pToken = pNew; | 192358 | c->pToken = pNew; |
| 186551 | } | 192359 | } |
| @@ -187707,7 +193515,7 @@ static int fts3PendingListAppendVarint( | |||
| 187707 | 193515 | ||
| 187708 | /* Allocate or grow the PendingList as required. */ | 193516 | /* Allocate or grow the PendingList as required. */ |
| 187709 | if( !p ){ | 193517 | if( !p ){ |
| 187710 | p = sqlite3_malloc(sizeof(*p) + 100); | 193518 | p = sqlite3_malloc64(sizeof(*p) + 100); |
| 187711 | if( !p ){ | 193519 | if( !p ){ |
| 187712 | return SQLITE_NOMEM; | 193520 | return SQLITE_NOMEM; |
| 187713 | } | 193521 | } |
| @@ -187716,14 +193524,14 @@ static int fts3PendingListAppendVarint( | |||
| 187716 | p->nData = 0; | 193524 | p->nData = 0; |
| 187717 | } | 193525 | } |
| 187718 | else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){ | 193526 | else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){ |
| 187719 | int nNew = p->nSpace * 2; | 193527 | i64 nNew = p->nSpace * 2; |
| 187720 | p = sqlite3_realloc(p, sizeof(*p) + nNew); | 193528 | p = sqlite3_realloc64(p, sizeof(*p) + nNew); |
| 187721 | if( !p ){ | 193529 | if( !p ){ |
| 187722 | sqlite3_free(*pp); | 193530 | sqlite3_free(*pp); |
| 187723 | *pp = 0; | 193531 | *pp = 0; |
| 187724 | return SQLITE_NOMEM; | 193532 | return SQLITE_NOMEM; |
| 187725 | } | 193533 | } |
| 187726 | p->nSpace = nNew; | 193534 | p->nSpace = (int)nNew; |
| 187727 | p->aData = (char *)&p[1]; | 193535 | p->aData = (char *)&p[1]; |
| 187728 | } | 193536 | } |
| 187729 | 193537 | ||
| @@ -188280,7 +194088,7 @@ SQLITE_PRIVATE int sqlite3Fts3ReadBlock( | |||
| 188280 | int nByte = sqlite3_blob_bytes(p->pSegments); | 194088 | int nByte = sqlite3_blob_bytes(p->pSegments); |
| 188281 | *pnBlob = nByte; | 194089 | *pnBlob = nByte; |
| 188282 | if( paBlob ){ | 194090 | if( paBlob ){ |
| 188283 | char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING); | 194091 | char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING); |
| 188284 | if( !aByte ){ | 194092 | if( !aByte ){ |
| 188285 | rc = SQLITE_NOMEM; | 194093 | rc = SQLITE_NOMEM; |
| 188286 | }else{ | 194094 | }else{ |
| @@ -188397,7 +194205,7 @@ static int fts3SegReaderNext( | |||
| 188397 | int nTerm = fts3HashKeysize(pElem); | 194205 | int nTerm = fts3HashKeysize(pElem); |
| 188398 | if( (nTerm+1)>pReader->nTermAlloc ){ | 194206 | if( (nTerm+1)>pReader->nTermAlloc ){ |
| 188399 | sqlite3_free(pReader->zTerm); | 194207 | sqlite3_free(pReader->zTerm); |
| 188400 | pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2); | 194208 | pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2); |
| 188401 | if( !pReader->zTerm ) return SQLITE_NOMEM; | 194209 | if( !pReader->zTerm ) return SQLITE_NOMEM; |
| 188402 | pReader->nTermAlloc = (nTerm+1)*2; | 194210 | pReader->nTermAlloc = (nTerm+1)*2; |
| 188403 | } | 194211 | } |
| @@ -188405,7 +194213,7 @@ static int fts3SegReaderNext( | |||
| 188405 | pReader->zTerm[nTerm] = '\0'; | 194213 | pReader->zTerm[nTerm] = '\0'; |
| 188406 | pReader->nTerm = nTerm; | 194214 | pReader->nTerm = nTerm; |
| 188407 | 194215 | ||
| 188408 | aCopy = (char*)sqlite3_malloc(nCopy); | 194216 | aCopy = (char*)sqlite3_malloc64(nCopy); |
| 188409 | if( !aCopy ) return SQLITE_NOMEM; | 194217 | if( !aCopy ) return SQLITE_NOMEM; |
| 188410 | memcpy(aCopy, pList->aData, nCopy); | 194218 | memcpy(aCopy, pList->aData, nCopy); |
| 188411 | pReader->nNode = pReader->nDoclist = nCopy; | 194219 | pReader->nNode = pReader->nDoclist = nCopy; |
| @@ -188692,7 +194500,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( | |||
| 188692 | nExtra = nRoot + FTS3_NODE_PADDING; | 194500 | nExtra = nRoot + FTS3_NODE_PADDING; |
| 188693 | } | 194501 | } |
| 188694 | 194502 | ||
| 188695 | pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra); | 194503 | pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra); |
| 188696 | if( !pReader ){ | 194504 | if( !pReader ){ |
| 188697 | return SQLITE_NOMEM; | 194505 | return SQLITE_NOMEM; |
| 188698 | } | 194506 | } |
| @@ -188784,7 +194592,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( | |||
| 188784 | if( nElem==nAlloc ){ | 194592 | if( nElem==nAlloc ){ |
| 188785 | Fts3HashElem **aElem2; | 194593 | Fts3HashElem **aElem2; |
| 188786 | nAlloc += 16; | 194594 | nAlloc += 16; |
| 188787 | aElem2 = (Fts3HashElem **)sqlite3_realloc( | 194595 | aElem2 = (Fts3HashElem **)sqlite3_realloc64( |
| 188788 | aElem, nAlloc*sizeof(Fts3HashElem *) | 194596 | aElem, nAlloc*sizeof(Fts3HashElem *) |
| 188789 | ); | 194597 | ); |
| 188790 | if( !aElem2 ){ | 194598 | if( !aElem2 ){ |
| @@ -189118,7 +194926,7 @@ static int fts3NodeAddTerm( | |||
| 189118 | ** this is not expected to be a serious problem. | 194926 | ** this is not expected to be a serious problem. |
| 189119 | */ | 194927 | */ |
| 189120 | assert( pTree->aData==(char *)&pTree[1] ); | 194928 | assert( pTree->aData==(char *)&pTree[1] ); |
| 189121 | pTree->aData = (char *)sqlite3_malloc(nReq); | 194929 | pTree->aData = (char *)sqlite3_malloc64(nReq); |
| 189122 | if( !pTree->aData ){ | 194930 | if( !pTree->aData ){ |
| 189123 | return SQLITE_NOMEM; | 194931 | return SQLITE_NOMEM; |
| 189124 | } | 194932 | } |
| @@ -189136,7 +194944,7 @@ static int fts3NodeAddTerm( | |||
| 189136 | 194944 | ||
| 189137 | if( isCopyTerm ){ | 194945 | if( isCopyTerm ){ |
| 189138 | if( pTree->nMalloc<nTerm ){ | 194946 | if( pTree->nMalloc<nTerm ){ |
| 189139 | char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2); | 194947 | char *zNew = sqlite3_realloc64(pTree->zMalloc, (i64)nTerm*2); |
| 189140 | if( !zNew ){ | 194948 | if( !zNew ){ |
| 189141 | return SQLITE_NOMEM; | 194949 | return SQLITE_NOMEM; |
| 189142 | } | 194950 | } |
| @@ -189162,7 +194970,7 @@ static int fts3NodeAddTerm( | |||
| 189162 | ** now. Instead, the term is inserted into the parent of pTree. If pTree | 194970 | ** now. Instead, the term is inserted into the parent of pTree. If pTree |
| 189163 | ** has no parent, one is created here. | 194971 | ** has no parent, one is created here. |
| 189164 | */ | 194972 | */ |
| 189165 | pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize); | 194973 | pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize); |
| 189166 | if( !pNew ){ | 194974 | if( !pNew ){ |
| 189167 | return SQLITE_NOMEM; | 194975 | return SQLITE_NOMEM; |
| 189168 | } | 194976 | } |
| @@ -189300,7 +195108,7 @@ static int fts3SegWriterAdd( | |||
| 189300 | ){ | 195108 | ){ |
| 189301 | int nPrefix; /* Size of term prefix in bytes */ | 195109 | int nPrefix; /* Size of term prefix in bytes */ |
| 189302 | int nSuffix; /* Size of term suffix in bytes */ | 195110 | int nSuffix; /* Size of term suffix in bytes */ |
| 189303 | int nReq; /* Number of bytes required on leaf page */ | 195111 | i64 nReq; /* Number of bytes required on leaf page */ |
| 189304 | int nData; | 195112 | int nData; |
| 189305 | SegmentWriter *pWriter = *ppWriter; | 195113 | SegmentWriter *pWriter = *ppWriter; |
| 189306 | 195114 | ||
| @@ -189309,13 +195117,13 @@ static int fts3SegWriterAdd( | |||
| 189309 | sqlite3_stmt *pStmt; | 195117 | sqlite3_stmt *pStmt; |
| 189310 | 195118 | ||
| 189311 | /* Allocate the SegmentWriter structure */ | 195119 | /* Allocate the SegmentWriter structure */ |
| 189312 | pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter)); | 195120 | pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter)); |
| 189313 | if( !pWriter ) return SQLITE_NOMEM; | 195121 | if( !pWriter ) return SQLITE_NOMEM; |
| 189314 | memset(pWriter, 0, sizeof(SegmentWriter)); | 195122 | memset(pWriter, 0, sizeof(SegmentWriter)); |
| 189315 | *ppWriter = pWriter; | 195123 | *ppWriter = pWriter; |
| 189316 | 195124 | ||
| 189317 | /* Allocate a buffer in which to accumulate data */ | 195125 | /* Allocate a buffer in which to accumulate data */ |
| 189318 | pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize); | 195126 | pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize); |
| 189319 | if( !pWriter->aData ) return SQLITE_NOMEM; | 195127 | if( !pWriter->aData ) return SQLITE_NOMEM; |
| 189320 | pWriter->nSize = p->nNodeSize; | 195128 | pWriter->nSize = p->nNodeSize; |
| 189321 | 195129 | ||
| @@ -189390,7 +195198,7 @@ static int fts3SegWriterAdd( | |||
| 189390 | ** the buffer to make it large enough. | 195198 | ** the buffer to make it large enough. |
| 189391 | */ | 195199 | */ |
| 189392 | if( nReq>pWriter->nSize ){ | 195200 | if( nReq>pWriter->nSize ){ |
| 189393 | char *aNew = sqlite3_realloc(pWriter->aData, nReq); | 195201 | char *aNew = sqlite3_realloc64(pWriter->aData, nReq); |
| 189394 | if( !aNew ) return SQLITE_NOMEM; | 195202 | if( !aNew ) return SQLITE_NOMEM; |
| 189395 | pWriter->aData = aNew; | 195203 | pWriter->aData = aNew; |
| 189396 | pWriter->nSize = nReq; | 195204 | pWriter->nSize = nReq; |
| @@ -189415,7 +195223,7 @@ static int fts3SegWriterAdd( | |||
| 189415 | */ | 195223 | */ |
| 189416 | if( isCopyTerm ){ | 195224 | if( isCopyTerm ){ |
| 189417 | if( nTerm>pWriter->nMalloc ){ | 195225 | if( nTerm>pWriter->nMalloc ){ |
| 189418 | char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2); | 195226 | char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2); |
| 189419 | if( !zNew ){ | 195227 | if( !zNew ){ |
| 189420 | return SQLITE_NOMEM; | 195228 | return SQLITE_NOMEM; |
| 189421 | } | 195229 | } |
| @@ -189723,18 +195531,20 @@ static void fts3ColumnFilter( | |||
| 189723 | static int fts3MsrBufferData( | 195531 | static int fts3MsrBufferData( |
| 189724 | Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ | 195532 | Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ |
| 189725 | char *pList, | 195533 | char *pList, |
| 189726 | int nList | 195534 | i64 nList |
| 189727 | ){ | 195535 | ){ |
| 189728 | if( nList>pMsr->nBuffer ){ | 195536 | if( (nList+FTS3_NODE_PADDING)>pMsr->nBuffer ){ |
| 189729 | char *pNew; | 195537 | char *pNew; |
| 189730 | pMsr->nBuffer = nList*2; | 195538 | int nNew = nList*2 + FTS3_NODE_PADDING; |
| 189731 | pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); | 195539 | pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, nNew); |
| 189732 | if( !pNew ) return SQLITE_NOMEM; | 195540 | if( !pNew ) return SQLITE_NOMEM; |
| 189733 | pMsr->aBuffer = pNew; | 195541 | pMsr->aBuffer = pNew; |
| 195542 | pMsr->nBuffer = nNew; | ||
| 189734 | } | 195543 | } |
| 189735 | 195544 | ||
| 189736 | assert( nList>0 ); | 195545 | assert( nList>0 ); |
| 189737 | memcpy(pMsr->aBuffer, pList, nList); | 195546 | memcpy(pMsr->aBuffer, pList, nList); |
| 195547 | memset(&pMsr->aBuffer[nList], 0, FTS3_NODE_PADDING); | ||
| 189738 | return SQLITE_OK; | 195548 | return SQLITE_OK; |
| 189739 | } | 195549 | } |
| 189740 | 195550 | ||
| @@ -189784,7 +195594,7 @@ SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( | |||
| 189784 | fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); | 195594 | fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); |
| 189785 | 195595 | ||
| 189786 | if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){ | 195596 | if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){ |
| 189787 | rc = fts3MsrBufferData(pMsr, pList, nList+1); | 195597 | rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1); |
| 189788 | if( rc!=SQLITE_OK ) return rc; | 195598 | if( rc!=SQLITE_OK ) return rc; |
| 189789 | assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); | 195599 | assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); |
| 189790 | pList = pMsr->aBuffer; | 195600 | pList = pMsr->aBuffer; |
| @@ -189921,11 +195731,11 @@ SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ | |||
| 189921 | return SQLITE_OK; | 195731 | return SQLITE_OK; |
| 189922 | } | 195732 | } |
| 189923 | 195733 | ||
| 189924 | static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, int nReq){ | 195734 | static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){ |
| 189925 | if( nReq>pCsr->nBuffer ){ | 195735 | if( nReq>pCsr->nBuffer ){ |
| 189926 | char *aNew; | 195736 | char *aNew; |
| 189927 | pCsr->nBuffer = nReq*2; | 195737 | pCsr->nBuffer = nReq*2; |
| 189928 | aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer); | 195738 | aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer); |
| 189929 | if( !aNew ){ | 195739 | if( !aNew ){ |
| 189930 | return SQLITE_NOMEM; | 195740 | return SQLITE_NOMEM; |
| 189931 | } | 195741 | } |
| @@ -190016,7 +195826,8 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( | |||
| 190016 | ){ | 195826 | ){ |
| 190017 | pCsr->nDoclist = apSegment[0]->nDoclist; | 195827 | pCsr->nDoclist = apSegment[0]->nDoclist; |
| 190018 | if( fts3SegReaderIsPending(apSegment[0]) ){ | 195828 | if( fts3SegReaderIsPending(apSegment[0]) ){ |
| 190019 | rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist); | 195829 | rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, |
| 195830 | (i64)pCsr->nDoclist); | ||
| 190020 | pCsr->aDoclist = pCsr->aBuffer; | 195831 | pCsr->aDoclist = pCsr->aBuffer; |
| 190021 | }else{ | 195832 | }else{ |
| 190022 | pCsr->aDoclist = apSegment[0]->aDoclist; | 195833 | pCsr->aDoclist = apSegment[0]->aDoclist; |
| @@ -190069,7 +195880,8 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( | |||
| 190069 | 195880 | ||
| 190070 | nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); | 195881 | nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); |
| 190071 | 195882 | ||
| 190072 | rc = fts3GrowSegReaderBuffer(pCsr, nByte+nDoclist+FTS3_NODE_PADDING); | 195883 | rc = fts3GrowSegReaderBuffer(pCsr, |
| 195884 | (i64)nByte+nDoclist+FTS3_NODE_PADDING); | ||
| 190073 | if( rc ) return rc; | 195885 | if( rc ) return rc; |
| 190074 | 195886 | ||
| 190075 | if( isFirst ){ | 195887 | if( isFirst ){ |
| @@ -190095,7 +195907,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( | |||
| 190095 | fts3SegReaderSort(apSegment, nMerge, j, xCmp); | 195907 | fts3SegReaderSort(apSegment, nMerge, j, xCmp); |
| 190096 | } | 195908 | } |
| 190097 | if( nDoclist>0 ){ | 195909 | if( nDoclist>0 ){ |
| 190098 | rc = fts3GrowSegReaderBuffer(pCsr, nDoclist+FTS3_NODE_PADDING); | 195910 | rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING); |
| 190099 | if( rc ) return rc; | 195911 | if( rc ) return rc; |
| 190100 | memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING); | 195912 | memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING); |
| 190101 | pCsr->aDoclist = pCsr->aBuffer; | 195913 | pCsr->aDoclist = pCsr->aBuffer; |
| @@ -190808,7 +196620,7 @@ struct NodeReader { | |||
| 190808 | static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ | 196620 | static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ |
| 190809 | if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ | 196621 | if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ |
| 190810 | int nAlloc = nMin; | 196622 | int nAlloc = nMin; |
| 190811 | char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc); | 196623 | char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc); |
| 190812 | if( a ){ | 196624 | if( a ){ |
| 190813 | pBlob->nAlloc = nAlloc; | 196625 | pBlob->nAlloc = nAlloc; |
| 190814 | pBlob->a = a; | 196626 | pBlob->a = a; |
| @@ -191401,6 +197213,7 @@ static int fts3IncrmergeLoad( | |||
| 191401 | 197213 | ||
| 191402 | for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ | 197214 | for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ |
| 191403 | NodeReader reader; | 197215 | NodeReader reader; |
| 197216 | memset(&reader, 0, sizeof(reader)); | ||
| 191404 | pNode = &pWriter->aNodeWriter[i]; | 197217 | pNode = &pWriter->aNodeWriter[i]; |
| 191405 | 197218 | ||
| 191406 | if( pNode->block.a){ | 197219 | if( pNode->block.a){ |
| @@ -191605,7 +197418,7 @@ static int fts3RepackSegdirLevel( | |||
| 191605 | if( nIdx>=nAlloc ){ | 197418 | if( nIdx>=nAlloc ){ |
| 191606 | int *aNew; | 197419 | int *aNew; |
| 191607 | nAlloc += 16; | 197420 | nAlloc += 16; |
| 191608 | aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int)); | 197421 | aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int)); |
| 191609 | if( !aNew ){ | 197422 | if( !aNew ){ |
| 191610 | rc = SQLITE_NOMEM; | 197423 | rc = SQLITE_NOMEM; |
| 191611 | break; | 197424 | break; |
| @@ -191979,7 +197792,7 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ | |||
| 191979 | 197792 | ||
| 191980 | /* Allocate space for the cursor, filter and writer objects */ | 197793 | /* Allocate space for the cursor, filter and writer objects */ |
| 191981 | const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); | 197794 | const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); |
| 191982 | pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc); | 197795 | pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc); |
| 191983 | if( !pWriter ) return SQLITE_NOMEM; | 197796 | if( !pWriter ) return SQLITE_NOMEM; |
| 191984 | pFilter = (Fts3SegFilter *)&pWriter[1]; | 197797 | pFilter = (Fts3SegFilter *)&pWriter[1]; |
| 191985 | pCsr = (Fts3MultiSegReader *)&pFilter[1]; | 197798 | pCsr = (Fts3MultiSegReader *)&pFilter[1]; |
| @@ -192615,7 +198428,7 @@ SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList( | |||
| 192615 | return SQLITE_OK; | 198428 | return SQLITE_OK; |
| 192616 | } | 198429 | } |
| 192617 | 198430 | ||
| 192618 | pRet = (char *)sqlite3_malloc(p->pList->nData); | 198431 | pRet = (char *)sqlite3_malloc64(p->pList->nData); |
| 192619 | if( !pRet ) return SQLITE_NOMEM; | 198432 | if( !pRet ) return SQLITE_NOMEM; |
| 192620 | 198433 | ||
| 192621 | nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); | 198434 | nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); |
| @@ -192635,7 +198448,7 @@ SQLITE_PRIVATE int sqlite3Fts3DeferToken( | |||
| 192635 | int iCol /* Column that token must appear in (or -1) */ | 198448 | int iCol /* Column that token must appear in (or -1) */ |
| 192636 | ){ | 198449 | ){ |
| 192637 | Fts3DeferredToken *pDeferred; | 198450 | Fts3DeferredToken *pDeferred; |
| 192638 | pDeferred = sqlite3_malloc(sizeof(*pDeferred)); | 198451 | pDeferred = sqlite3_malloc64(sizeof(*pDeferred)); |
| 192639 | if( !pDeferred ){ | 198452 | if( !pDeferred ){ |
| 192640 | return SQLITE_NOMEM; | 198453 | return SQLITE_NOMEM; |
| 192641 | } | 198454 | } |
| @@ -192914,7 +198727,7 @@ typedef sqlite3_int64 i64; | |||
| 192914 | 198727 | ||
| 192915 | 198728 | ||
| 192916 | /* | 198729 | /* |
| 192917 | ** Used as an fts3ExprIterate() context when loading phrase doclists to | 198730 | ** Used as an sqlite3Fts3ExprIterate() context when loading phrase doclists to |
| 192918 | ** Fts3Expr.aDoclist[]/nDoclist. | 198731 | ** Fts3Expr.aDoclist[]/nDoclist. |
| 192919 | */ | 198732 | */ |
| 192920 | typedef struct LoadDoclistCtx LoadDoclistCtx; | 198733 | typedef struct LoadDoclistCtx LoadDoclistCtx; |
| @@ -192958,7 +198771,7 @@ struct SnippetFragment { | |||
| 192958 | }; | 198771 | }; |
| 192959 | 198772 | ||
| 192960 | /* | 198773 | /* |
| 192961 | ** This type is used as an fts3ExprIterate() context object while | 198774 | ** This type is used as an sqlite3Fts3ExprIterate() context object while |
| 192962 | ** accumulating the data returned by the matchinfo() function. | 198775 | ** accumulating the data returned by the matchinfo() function. |
| 192963 | */ | 198776 | */ |
| 192964 | typedef struct MatchInfo MatchInfo; | 198777 | typedef struct MatchInfo MatchInfo; |
| @@ -193117,7 +198930,7 @@ static void fts3GetDeltaPosition(char **pp, i64 *piPos){ | |||
| 193117 | } | 198930 | } |
| 193118 | 198931 | ||
| 193119 | /* | 198932 | /* |
| 193120 | ** Helper function for fts3ExprIterate() (see below). | 198933 | ** Helper function for sqlite3Fts3ExprIterate() (see below). |
| 193121 | */ | 198934 | */ |
| 193122 | static int fts3ExprIterate2( | 198935 | static int fts3ExprIterate2( |
| 193123 | Fts3Expr *pExpr, /* Expression to iterate phrases of */ | 198936 | Fts3Expr *pExpr, /* Expression to iterate phrases of */ |
| @@ -193151,7 +198964,7 @@ static int fts3ExprIterate2( | |||
| 193151 | ** Otherwise, SQLITE_OK is returned after a callback has been made for | 198964 | ** Otherwise, SQLITE_OK is returned after a callback has been made for |
| 193152 | ** all eligible phrase nodes. | 198965 | ** all eligible phrase nodes. |
| 193153 | */ | 198966 | */ |
| 193154 | static int fts3ExprIterate( | 198967 | SQLITE_PRIVATE int sqlite3Fts3ExprIterate( |
| 193155 | Fts3Expr *pExpr, /* Expression to iterate phrases of */ | 198968 | Fts3Expr *pExpr, /* Expression to iterate phrases of */ |
| 193156 | int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ | 198969 | int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ |
| 193157 | void *pCtx /* Second argument to pass to callback */ | 198970 | void *pCtx /* Second argument to pass to callback */ |
| @@ -193160,10 +198973,9 @@ static int fts3ExprIterate( | |||
| 193160 | return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx); | 198973 | return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx); |
| 193161 | } | 198974 | } |
| 193162 | 198975 | ||
| 193163 | |||
| 193164 | /* | 198976 | /* |
| 193165 | ** This is an fts3ExprIterate() callback used while loading the doclists | 198977 | ** This is an sqlite3Fts3ExprIterate() callback used while loading the |
| 193166 | ** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also | 198978 | ** doclists for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also |
| 193167 | ** fts3ExprLoadDoclists(). | 198979 | ** fts3ExprLoadDoclists(). |
| 193168 | */ | 198980 | */ |
| 193169 | static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ | 198981 | static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ |
| @@ -193195,9 +199007,9 @@ static int fts3ExprLoadDoclists( | |||
| 193195 | int *pnToken /* OUT: Number of tokens in query */ | 199007 | int *pnToken /* OUT: Number of tokens in query */ |
| 193196 | ){ | 199008 | ){ |
| 193197 | int rc; /* Return Code */ | 199009 | int rc; /* Return Code */ |
| 193198 | LoadDoclistCtx sCtx = {0,0,0}; /* Context for fts3ExprIterate() */ | 199010 | LoadDoclistCtx sCtx = {0,0,0}; /* Context for sqlite3Fts3ExprIterate() */ |
| 193199 | sCtx.pCsr = pCsr; | 199011 | sCtx.pCsr = pCsr; |
| 193200 | rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx); | 199012 | rc = sqlite3Fts3ExprIterate(pCsr->pExpr,fts3ExprLoadDoclistsCb,(void*)&sCtx); |
| 193201 | if( pnPhrase ) *pnPhrase = sCtx.nPhrase; | 199013 | if( pnPhrase ) *pnPhrase = sCtx.nPhrase; |
| 193202 | if( pnToken ) *pnToken = sCtx.nToken; | 199014 | if( pnToken ) *pnToken = sCtx.nToken; |
| 193203 | return rc; | 199015 | return rc; |
| @@ -193210,7 +199022,7 @@ static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ | |||
| 193210 | } | 199022 | } |
| 193211 | static int fts3ExprPhraseCount(Fts3Expr *pExpr){ | 199023 | static int fts3ExprPhraseCount(Fts3Expr *pExpr){ |
| 193212 | int nPhrase = 0; | 199024 | int nPhrase = 0; |
| 193213 | (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); | 199025 | (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); |
| 193214 | return nPhrase; | 199026 | return nPhrase; |
| 193215 | } | 199027 | } |
| 193216 | 199028 | ||
| @@ -193338,8 +199150,9 @@ static void fts3SnippetDetails( | |||
| 193338 | } | 199150 | } |
| 193339 | 199151 | ||
| 193340 | /* | 199152 | /* |
| 193341 | ** This function is an fts3ExprIterate() callback used by fts3BestSnippet(). | 199153 | ** This function is an sqlite3Fts3ExprIterate() callback used by |
| 193342 | ** Each invocation populates an element of the SnippetIter.aPhrase[] array. | 199154 | ** fts3BestSnippet(). Each invocation populates an element of the |
| 199155 | ** SnippetIter.aPhrase[] array. | ||
| 193343 | */ | 199156 | */ |
| 193344 | static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ | 199157 | static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ |
| 193345 | SnippetIter *p = (SnippetIter *)ctx; | 199158 | SnippetIter *p = (SnippetIter *)ctx; |
| @@ -193429,7 +199242,9 @@ static int fts3BestSnippet( | |||
| 193429 | sIter.nSnippet = nSnippet; | 199242 | sIter.nSnippet = nSnippet; |
| 193430 | sIter.nPhrase = nList; | 199243 | sIter.nPhrase = nList; |
| 193431 | sIter.iCurrent = -1; | 199244 | sIter.iCurrent = -1; |
| 193432 | rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter); | 199245 | rc = sqlite3Fts3ExprIterate( |
| 199246 | pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter | ||
| 199247 | ); | ||
| 193433 | if( rc==SQLITE_OK ){ | 199248 | if( rc==SQLITE_OK ){ |
| 193434 | 199249 | ||
| 193435 | /* Set the *pmSeen output variable. */ | 199250 | /* Set the *pmSeen output variable. */ |
| @@ -193790,10 +199605,10 @@ static int fts3ExprLHitGather( | |||
| 193790 | } | 199605 | } |
| 193791 | 199606 | ||
| 193792 | /* | 199607 | /* |
| 193793 | ** fts3ExprIterate() callback used to collect the "global" matchinfo stats | 199608 | ** sqlite3Fts3ExprIterate() callback used to collect the "global" matchinfo |
| 193794 | ** for a single query. | 199609 | ** stats for a single query. |
| 193795 | ** | 199610 | ** |
| 193796 | ** fts3ExprIterate() callback to load the 'global' elements of a | 199611 | ** sqlite3Fts3ExprIterate() callback to load the 'global' elements of a |
| 193797 | ** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements | 199612 | ** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements |
| 193798 | ** of the matchinfo array that are constant for all rows returned by the | 199613 | ** of the matchinfo array that are constant for all rows returned by the |
| 193799 | ** current query. | 199614 | ** current query. |
| @@ -193828,7 +199643,7 @@ static int fts3ExprGlobalHitsCb( | |||
| 193828 | } | 199643 | } |
| 193829 | 199644 | ||
| 193830 | /* | 199645 | /* |
| 193831 | ** fts3ExprIterate() callback used to collect the "local" part of the | 199646 | ** sqlite3Fts3ExprIterate() callback used to collect the "local" part of the |
| 193832 | ** FTS3_MATCHINFO_HITS array. The local stats are those elements of the | 199647 | ** FTS3_MATCHINFO_HITS array. The local stats are those elements of the |
| 193833 | ** array that are different for each row returned by the query. | 199648 | ** array that are different for each row returned by the query. |
| 193834 | */ | 199649 | */ |
| @@ -194024,7 +199839,7 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ | |||
| 194024 | **/ | 199839 | **/ |
| 194025 | aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase); | 199840 | aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase); |
| 194026 | if( !aIter ) return SQLITE_NOMEM; | 199841 | if( !aIter ) return SQLITE_NOMEM; |
| 194027 | (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); | 199842 | (void)sqlite3Fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); |
| 194028 | 199843 | ||
| 194029 | for(i=0; i<pInfo->nPhrase; i++){ | 199844 | for(i=0; i<pInfo->nPhrase; i++){ |
| 194030 | LcsIterator *pIter = &aIter[i]; | 199845 | LcsIterator *pIter = &aIter[i]; |
| @@ -194201,11 +200016,11 @@ static int fts3MatchinfoValues( | |||
| 194201 | rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0); | 200016 | rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0); |
| 194202 | if( rc!=SQLITE_OK ) break; | 200017 | if( rc!=SQLITE_OK ) break; |
| 194203 | } | 200018 | } |
| 194204 | rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); | 200019 | rc = sqlite3Fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); |
| 194205 | sqlite3Fts3EvalTestDeferred(pCsr, &rc); | 200020 | sqlite3Fts3EvalTestDeferred(pCsr, &rc); |
| 194206 | if( rc!=SQLITE_OK ) break; | 200021 | if( rc!=SQLITE_OK ) break; |
| 194207 | } | 200022 | } |
| 194208 | (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); | 200023 | (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); |
| 194209 | break; | 200024 | break; |
| 194210 | } | 200025 | } |
| 194211 | } | 200026 | } |
| @@ -194428,7 +200243,7 @@ struct TermOffsetCtx { | |||
| 194428 | }; | 200243 | }; |
| 194429 | 200244 | ||
| 194430 | /* | 200245 | /* |
| 194431 | ** This function is an fts3ExprIterate() callback used by sqlite3Fts3Offsets(). | 200246 | ** This function is an sqlite3Fts3ExprIterate() callback used by sqlite3Fts3Offsets(). |
| 194432 | */ | 200247 | */ |
| 194433 | static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ | 200248 | static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ |
| 194434 | TermOffsetCtx *p = (TermOffsetCtx *)ctx; | 200249 | TermOffsetCtx *p = (TermOffsetCtx *)ctx; |
| @@ -194510,7 +200325,9 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( | |||
| 194510 | */ | 200325 | */ |
| 194511 | sCtx.iCol = iCol; | 200326 | sCtx.iCol = iCol; |
| 194512 | sCtx.iTerm = 0; | 200327 | sCtx.iTerm = 0; |
| 194513 | rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx); | 200328 | rc = sqlite3Fts3ExprIterate( |
| 200329 | pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx | ||
| 200330 | ); | ||
| 194514 | if( rc!=SQLITE_OK ) goto offsets_out; | 200331 | if( rc!=SQLITE_OK ) goto offsets_out; |
| 194515 | 200332 | ||
| 194516 | /* Retreive the text stored in column iCol. If an SQL NULL is stored | 200333 | /* Retreive the text stored in column iCol. If an SQL NULL is stored |
| @@ -195443,25 +201260,51 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ | |||
| 195443 | ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). | 201260 | ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). |
| 195444 | */ | 201261 | */ |
| 195445 | static const char jsonIsSpace[] = { | 201262 | static const char jsonIsSpace[] = { |
| 195446 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, | 201263 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, |
| 195447 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201264 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195448 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201265 | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195449 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201266 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195450 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201267 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195451 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201268 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195452 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201269 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195453 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201270 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195454 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201271 | |
| 195455 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201272 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195456 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201273 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195457 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201274 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195458 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201275 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195459 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201276 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195460 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201277 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 195461 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 201278 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 201279 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 195462 | }; | 201280 | }; |
| 195463 | #define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) | 201281 | #define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) |
| 195464 | 201282 | ||
| 201283 | /* | ||
| 201284 | ** Characters that are special to JSON. Control charaters, | ||
| 201285 | ** '"' and '\\'. | ||
| 201286 | */ | ||
| 201287 | static const char jsonIsOk[256] = { | ||
| 201288 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 201289 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 201290 | 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201291 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201292 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201293 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, | ||
| 201294 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201295 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201296 | |||
| 201297 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201298 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201299 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201300 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201301 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201302 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201303 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 201304 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 | ||
| 201305 | }; | ||
| 201306 | |||
| 201307 | |||
| 195465 | #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) | 201308 | #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) |
| 195466 | # define VVA(X) | 201309 | # define VVA(X) |
| 195467 | #else | 201310 | #else |
| @@ -195472,6 +201315,7 @@ static const char jsonIsSpace[] = { | |||
| 195472 | typedef struct JsonString JsonString; | 201315 | typedef struct JsonString JsonString; |
| 195473 | typedef struct JsonNode JsonNode; | 201316 | typedef struct JsonNode JsonNode; |
| 195474 | typedef struct JsonParse JsonParse; | 201317 | typedef struct JsonParse JsonParse; |
| 201318 | typedef struct JsonCleanup JsonCleanup; | ||
| 195475 | 201319 | ||
| 195476 | /* An instance of this object represents a JSON string | 201320 | /* An instance of this object represents a JSON string |
| 195477 | ** under construction. Really, this is a generic string accumulator | 201321 | ** under construction. Really, this is a generic string accumulator |
| @@ -195487,16 +201331,26 @@ struct JsonString { | |||
| 195487 | char zSpace[100]; /* Initial static space */ | 201331 | char zSpace[100]; /* Initial static space */ |
| 195488 | }; | 201332 | }; |
| 195489 | 201333 | ||
| 201334 | /* A deferred cleanup task. A list of JsonCleanup objects might be | ||
| 201335 | ** run when the JsonParse object is destroyed. | ||
| 201336 | */ | ||
| 201337 | struct JsonCleanup { | ||
| 201338 | JsonCleanup *pJCNext; /* Next in a list */ | ||
| 201339 | void (*xOp)(void*); /* Routine to run */ | ||
| 201340 | void *pArg; /* Argument to xOp() */ | ||
| 201341 | }; | ||
| 201342 | |||
| 195490 | /* JSON type values | 201343 | /* JSON type values |
| 195491 | */ | 201344 | */ |
| 195492 | #define JSON_NULL 0 | 201345 | #define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */ |
| 195493 | #define JSON_TRUE 1 | 201346 | #define JSON_NULL 1 |
| 195494 | #define JSON_FALSE 2 | 201347 | #define JSON_TRUE 2 |
| 195495 | #define JSON_INT 3 | 201348 | #define JSON_FALSE 3 |
| 195496 | #define JSON_REAL 4 | 201349 | #define JSON_INT 4 |
| 195497 | #define JSON_STRING 5 | 201350 | #define JSON_REAL 5 |
| 195498 | #define JSON_ARRAY 6 | 201351 | #define JSON_STRING 6 |
| 195499 | #define JSON_OBJECT 7 | 201352 | #define JSON_ARRAY 7 |
| 201353 | #define JSON_OBJECT 8 | ||
| 195500 | 201354 | ||
| 195501 | /* The "subtype" set for JSON values */ | 201355 | /* The "subtype" set for JSON values */ |
| 195502 | #define JSON_SUBTYPE 74 /* Ascii for "J" */ | 201356 | #define JSON_SUBTYPE 74 /* Ascii for "J" */ |
| @@ -195505,59 +201359,97 @@ struct JsonString { | |||
| 195505 | ** Names of the various JSON types: | 201359 | ** Names of the various JSON types: |
| 195506 | */ | 201360 | */ |
| 195507 | static const char * const jsonType[] = { | 201361 | static const char * const jsonType[] = { |
| 201362 | "subst", | ||
| 195508 | "null", "true", "false", "integer", "real", "text", "array", "object" | 201363 | "null", "true", "false", "integer", "real", "text", "array", "object" |
| 195509 | }; | 201364 | }; |
| 195510 | 201365 | ||
| 195511 | /* Bit values for the JsonNode.jnFlag field | 201366 | /* Bit values for the JsonNode.jnFlag field |
| 195512 | */ | 201367 | */ |
| 195513 | #define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ | 201368 | #define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ |
| 195514 | #define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ | 201369 | #define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ |
| 195515 | #define JNODE_REMOVE 0x04 /* Do not output */ | 201370 | #define JNODE_REMOVE 0x04 /* Do not output */ |
| 195516 | #define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ | 201371 | #define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */ |
| 195517 | #define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ | 201372 | #define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */ |
| 195518 | #define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ | 201373 | #define JNODE_LABEL 0x20 /* Is a label of an object */ |
| 195519 | #define JNODE_LABEL 0x40 /* Is a label of an object */ | 201374 | #define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */ |
| 195520 | 201375 | ||
| 195521 | 201376 | ||
| 195522 | /* A single node of parsed JSON | 201377 | /* A single node of parsed JSON. An array of these nodes describes |
| 201378 | ** a parse of JSON + edits. | ||
| 201379 | ** | ||
| 201380 | ** Use the json_parse() SQL function (available when compiled with | ||
| 201381 | ** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including | ||
| 201382 | ** a complete listing and decoding of the array of JsonNodes. | ||
| 195523 | */ | 201383 | */ |
| 195524 | struct JsonNode { | 201384 | struct JsonNode { |
| 195525 | u8 eType; /* One of the JSON_ type values */ | 201385 | u8 eType; /* One of the JSON_ type values */ |
| 195526 | u8 jnFlags; /* JNODE flags */ | 201386 | u8 jnFlags; /* JNODE flags */ |
| 195527 | u8 eU; /* Which union element to use */ | 201387 | u8 eU; /* Which union element to use */ |
| 195528 | u32 n; /* Bytes of content, or number of sub-nodes */ | 201388 | u32 n; /* Bytes of content for INT, REAL or STRING |
| 201389 | ** Number of sub-nodes for ARRAY and OBJECT | ||
| 201390 | ** Node that SUBST applies to */ | ||
| 195529 | union { | 201391 | union { |
| 195530 | const char *zJContent; /* 1: Content for INT, REAL, and STRING */ | 201392 | const char *zJContent; /* 1: Content for INT, REAL, and STRING */ |
| 195531 | u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ | 201393 | u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ |
| 195532 | u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ | 201394 | u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ |
| 195533 | u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */ | 201395 | u32 iPrev; /* 4: Previous SUBST node, or 0 */ |
| 195534 | JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */ | ||
| 195535 | } u; | 201396 | } u; |
| 195536 | }; | 201397 | }; |
| 195537 | 201398 | ||
| 195538 | /* A completely parsed JSON string | 201399 | |
| 201400 | /* A parsed and possibly edited JSON string. Lifecycle: | ||
| 201401 | ** | ||
| 201402 | ** 1. JSON comes in and is parsed into an array aNode[]. The original | ||
| 201403 | ** JSON text is stored in zJson. | ||
| 201404 | ** | ||
| 201405 | ** 2. Zero or more changes are made (via json_remove() or json_replace() | ||
| 201406 | ** or similar) to the aNode[] array. | ||
| 201407 | ** | ||
| 201408 | ** 3. A new, edited and mimified JSON string is generated from aNode | ||
| 201409 | ** and stored in zAlt. The JsonParse object always owns zAlt. | ||
| 201410 | ** | ||
| 201411 | ** Step 1 always happens. Step 2 and 3 may or may not happen, depending | ||
| 201412 | ** on the operation. | ||
| 201413 | ** | ||
| 201414 | ** aNode[].u.zJContent entries typically point into zJson. Hence zJson | ||
| 201415 | ** must remain valid for the lifespan of the parse. For edits, | ||
| 201416 | ** aNode[].u.zJContent might point to malloced space other than zJson. | ||
| 201417 | ** Entries in pClup are responsible for freeing that extra malloced space. | ||
| 201418 | ** | ||
| 201419 | ** When walking the parse tree in aNode[], edits are ignored if useMod is | ||
| 201420 | ** false. | ||
| 195539 | */ | 201421 | */ |
| 195540 | struct JsonParse { | 201422 | struct JsonParse { |
| 195541 | u32 nNode; /* Number of slots of aNode[] used */ | 201423 | u32 nNode; /* Number of slots of aNode[] used */ |
| 195542 | u32 nAlloc; /* Number of slots of aNode[] allocated */ | 201424 | u32 nAlloc; /* Number of slots of aNode[] allocated */ |
| 195543 | JsonNode *aNode; /* Array of nodes containing the parse */ | 201425 | JsonNode *aNode; /* Array of nodes containing the parse */ |
| 195544 | const char *zJson; /* Original JSON string */ | 201426 | char *zJson; /* Original JSON string (before edits) */ |
| 201427 | char *zAlt; /* Revised and/or mimified JSON */ | ||
| 195545 | u32 *aUp; /* Index of parent of each node */ | 201428 | u32 *aUp; /* Index of parent of each node */ |
| 195546 | u8 oom; /* Set to true if out of memory */ | 201429 | JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */ |
| 195547 | u8 nErr; /* Number of errors seen */ | ||
| 195548 | u16 iDepth; /* Nesting depth */ | 201430 | u16 iDepth; /* Nesting depth */ |
| 201431 | u8 nErr; /* Number of errors seen */ | ||
| 201432 | u8 oom; /* Set to true if out of memory */ | ||
| 201433 | u8 bJsonIsRCStr; /* True if zJson is an RCStr */ | ||
| 201434 | u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ | ||
| 201435 | u8 useMod; /* Actually use the edits contain inside aNode */ | ||
| 201436 | u8 hasMod; /* aNode contains edits from the original zJson */ | ||
| 201437 | u32 nJPRef; /* Number of references to this object */ | ||
| 195549 | int nJson; /* Length of the zJson string in bytes */ | 201438 | int nJson; /* Length of the zJson string in bytes */ |
| 195550 | u32 iHold; /* Replace cache line with the lowest iHold value */ | 201439 | int nAlt; /* Length of alternative JSON string zAlt, in bytes */ |
| 201440 | u32 iErr; /* Error location in zJson[] */ | ||
| 201441 | u32 iSubst; /* Last JSON_SUBST entry in aNode[] */ | ||
| 201442 | u32 iHold; /* Age of this entry in the cache for LRU replacement */ | ||
| 195551 | }; | 201443 | }; |
| 195552 | 201444 | ||
| 195553 | /* | 201445 | /* |
| 195554 | ** Maximum nesting depth of JSON for this implementation. | 201446 | ** Maximum nesting depth of JSON for this implementation. |
| 195555 | ** | 201447 | ** |
| 195556 | ** This limit is needed to avoid a stack overflow in the recursive | 201448 | ** This limit is needed to avoid a stack overflow in the recursive |
| 195557 | ** descent parser. A depth of 2000 is far deeper than any sane JSON | 201449 | ** descent parser. A depth of 1000 is far deeper than any sane JSON |
| 195558 | ** should go. | 201450 | ** should go. Historical note: This limit was 2000 prior to version 3.42.0 |
| 195559 | */ | 201451 | */ |
| 195560 | #define JSON_MAX_DEPTH 2000 | 201452 | #define JSON_MAX_DEPTH 1000 |
| 195561 | 201453 | ||
| 195562 | /************************************************************************** | 201454 | /************************************************************************** |
| 195563 | ** Utility routines for dealing with JsonString objects | 201455 | ** Utility routines for dealing with JsonString objects |
| @@ -195580,16 +201472,14 @@ static void jsonInit(JsonString *p, sqlite3_context *pCtx){ | |||
| 195580 | jsonZero(p); | 201472 | jsonZero(p); |
| 195581 | } | 201473 | } |
| 195582 | 201474 | ||
| 195583 | |||
| 195584 | /* Free all allocated memory and reset the JsonString object back to its | 201475 | /* Free all allocated memory and reset the JsonString object back to its |
| 195585 | ** initial state. | 201476 | ** initial state. |
| 195586 | */ | 201477 | */ |
| 195587 | static void jsonReset(JsonString *p){ | 201478 | static void jsonReset(JsonString *p){ |
| 195588 | if( !p->bStatic ) sqlite3_free(p->zBuf); | 201479 | if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); |
| 195589 | jsonZero(p); | 201480 | jsonZero(p); |
| 195590 | } | 201481 | } |
| 195591 | 201482 | ||
| 195592 | |||
| 195593 | /* Report an out-of-memory (OOM) condition | 201483 | /* Report an out-of-memory (OOM) condition |
| 195594 | */ | 201484 | */ |
| 195595 | static void jsonOom(JsonString *p){ | 201485 | static void jsonOom(JsonString *p){ |
| @@ -195606,7 +201496,7 @@ static int jsonGrow(JsonString *p, u32 N){ | |||
| 195606 | char *zNew; | 201496 | char *zNew; |
| 195607 | if( p->bStatic ){ | 201497 | if( p->bStatic ){ |
| 195608 | if( p->bErr ) return 1; | 201498 | if( p->bErr ) return 1; |
| 195609 | zNew = sqlite3_malloc64(nTotal); | 201499 | zNew = sqlite3RCStrNew(nTotal); |
| 195610 | if( zNew==0 ){ | 201500 | if( zNew==0 ){ |
| 195611 | jsonOom(p); | 201501 | jsonOom(p); |
| 195612 | return SQLITE_NOMEM; | 201502 | return SQLITE_NOMEM; |
| @@ -195615,12 +201505,12 @@ static int jsonGrow(JsonString *p, u32 N){ | |||
| 195615 | p->zBuf = zNew; | 201505 | p->zBuf = zNew; |
| 195616 | p->bStatic = 0; | 201506 | p->bStatic = 0; |
| 195617 | }else{ | 201507 | }else{ |
| 195618 | zNew = sqlite3_realloc64(p->zBuf, nTotal); | 201508 | p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); |
| 195619 | if( zNew==0 ){ | 201509 | if( p->zBuf==0 ){ |
| 195620 | jsonOom(p); | 201510 | p->bErr = 1; |
| 201511 | jsonZero(p); | ||
| 195621 | return SQLITE_NOMEM; | 201512 | return SQLITE_NOMEM; |
| 195622 | } | 201513 | } |
| 195623 | p->zBuf = zNew; | ||
| 195624 | } | 201514 | } |
| 195625 | p->nAlloc = nTotal; | 201515 | p->nAlloc = nTotal; |
| 195626 | return SQLITE_OK; | 201516 | return SQLITE_OK; |
| @@ -195628,12 +201518,35 @@ static int jsonGrow(JsonString *p, u32 N){ | |||
| 195628 | 201518 | ||
| 195629 | /* Append N bytes from zIn onto the end of the JsonString string. | 201519 | /* Append N bytes from zIn onto the end of the JsonString string. |
| 195630 | */ | 201520 | */ |
| 195631 | static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ | 201521 | static SQLITE_NOINLINE void jsonAppendExpand( |
| 195632 | if( N==0 ) return; | 201522 | JsonString *p, |
| 195633 | if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; | 201523 | const char *zIn, |
| 201524 | u32 N | ||
| 201525 | ){ | ||
| 201526 | assert( N>0 ); | ||
| 201527 | if( jsonGrow(p,N) ) return; | ||
| 195634 | memcpy(p->zBuf+p->nUsed, zIn, N); | 201528 | memcpy(p->zBuf+p->nUsed, zIn, N); |
| 195635 | p->nUsed += N; | 201529 | p->nUsed += N; |
| 195636 | } | 201530 | } |
| 201531 | static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ | ||
| 201532 | if( N==0 ) return; | ||
| 201533 | if( N+p->nUsed >= p->nAlloc ){ | ||
| 201534 | jsonAppendExpand(p,zIn,N); | ||
| 201535 | }else{ | ||
| 201536 | memcpy(p->zBuf+p->nUsed, zIn, N); | ||
| 201537 | p->nUsed += N; | ||
| 201538 | } | ||
| 201539 | } | ||
| 201540 | static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ | ||
| 201541 | assert( N>0 ); | ||
| 201542 | if( N+p->nUsed >= p->nAlloc ){ | ||
| 201543 | jsonAppendExpand(p,zIn,N); | ||
| 201544 | }else{ | ||
| 201545 | memcpy(p->zBuf+p->nUsed, zIn, N); | ||
| 201546 | p->nUsed += N; | ||
| 201547 | } | ||
| 201548 | } | ||
| 201549 | |||
| 195637 | 201550 | ||
| 195638 | /* Append formatted text (not to exceed N bytes) to the JsonString. | 201551 | /* Append formatted text (not to exceed N bytes) to the JsonString. |
| 195639 | */ | 201552 | */ |
| @@ -195648,10 +201561,35 @@ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ | |||
| 195648 | 201561 | ||
| 195649 | /* Append a single character | 201562 | /* Append a single character |
| 195650 | */ | 201563 | */ |
| 195651 | static void jsonAppendChar(JsonString *p, char c){ | 201564 | static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ |
| 195652 | if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; | 201565 | if( jsonGrow(p,1) ) return; |
| 195653 | p->zBuf[p->nUsed++] = c; | 201566 | p->zBuf[p->nUsed++] = c; |
| 195654 | } | 201567 | } |
| 201568 | static void jsonAppendChar(JsonString *p, char c){ | ||
| 201569 | if( p->nUsed>=p->nAlloc ){ | ||
| 201570 | jsonAppendCharExpand(p,c); | ||
| 201571 | }else{ | ||
| 201572 | p->zBuf[p->nUsed++] = c; | ||
| 201573 | } | ||
| 201574 | } | ||
| 201575 | |||
| 201576 | /* Try to force the string to be a zero-terminated RCStr string. | ||
| 201577 | ** | ||
| 201578 | ** Return true on success. Return false if an OOM prevents this | ||
| 201579 | ** from happening. | ||
| 201580 | */ | ||
| 201581 | static int jsonForceRCStr(JsonString *p){ | ||
| 201582 | jsonAppendChar(p, 0); | ||
| 201583 | if( p->bErr ) return 0; | ||
| 201584 | p->nUsed--; | ||
| 201585 | if( p->bStatic==0 ) return 1; | ||
| 201586 | p->nAlloc = 0; | ||
| 201587 | p->nUsed++; | ||
| 201588 | jsonGrow(p, p->nUsed); | ||
| 201589 | p->nUsed--; | ||
| 201590 | return p->bStatic==0; | ||
| 201591 | } | ||
| 201592 | |||
| 195655 | 201593 | ||
| 195656 | /* Append a comma separator to the output buffer, if the previous | 201594 | /* Append a comma separator to the output buffer, if the previous |
| 195657 | ** character is not '[' or '{'. | 201595 | ** character is not '[' or '{'. |
| @@ -195660,7 +201598,8 @@ static void jsonAppendSeparator(JsonString *p){ | |||
| 195660 | char c; | 201598 | char c; |
| 195661 | if( p->nUsed==0 ) return; | 201599 | if( p->nUsed==0 ) return; |
| 195662 | c = p->zBuf[p->nUsed-1]; | 201600 | c = p->zBuf[p->nUsed-1]; |
| 195663 | if( c!='[' && c!='{' ) jsonAppendChar(p, ','); | 201601 | if( c=='[' || c=='{' ) return; |
| 201602 | jsonAppendChar(p, ','); | ||
| 195664 | } | 201603 | } |
| 195665 | 201604 | ||
| 195666 | /* Append the N-byte string in zIn to the end of the JsonString string | 201605 | /* Append the N-byte string in zIn to the end of the JsonString string |
| @@ -195674,11 +201613,16 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ | |||
| 195674 | p->zBuf[p->nUsed++] = '"'; | 201613 | p->zBuf[p->nUsed++] = '"'; |
| 195675 | for(i=0; i<N; i++){ | 201614 | for(i=0; i<N; i++){ |
| 195676 | unsigned char c = ((unsigned const char*)zIn)[i]; | 201615 | unsigned char c = ((unsigned const char*)zIn)[i]; |
| 195677 | if( c=='"' || c=='\\' ){ | 201616 | if( jsonIsOk[c] ){ |
| 201617 | p->zBuf[p->nUsed++] = c; | ||
| 201618 | }else if( c=='"' || c=='\\' ){ | ||
| 195678 | json_simple_escape: | 201619 | json_simple_escape: |
| 195679 | if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; | 201620 | if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; |
| 195680 | p->zBuf[p->nUsed++] = '\\'; | 201621 | p->zBuf[p->nUsed++] = '\\'; |
| 195681 | }else if( c<=0x1f ){ | 201622 | p->zBuf[p->nUsed++] = c; |
| 201623 | }else if( c=='\'' ){ | ||
| 201624 | p->zBuf[p->nUsed++] = c; | ||
| 201625 | }else{ | ||
| 195682 | static const char aSpecial[] = { | 201626 | static const char aSpecial[] = { |
| 195683 | 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, | 201627 | 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, |
| 195684 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | 201628 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| @@ -195689,6 +201633,7 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ | |||
| 195689 | assert( aSpecial['\n']=='n' ); | 201633 | assert( aSpecial['\n']=='n' ); |
| 195690 | assert( aSpecial['\r']=='r' ); | 201634 | assert( aSpecial['\r']=='r' ); |
| 195691 | assert( aSpecial['\t']=='t' ); | 201635 | assert( aSpecial['\t']=='t' ); |
| 201636 | assert( c>=0 && c<sizeof(aSpecial) ); | ||
| 195692 | if( aSpecial[c] ){ | 201637 | if( aSpecial[c] ){ |
| 195693 | c = aSpecial[c]; | 201638 | c = aSpecial[c]; |
| 195694 | goto json_simple_escape; | 201639 | goto json_simple_escape; |
| @@ -195698,16 +201643,139 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ | |||
| 195698 | p->zBuf[p->nUsed++] = 'u'; | 201643 | p->zBuf[p->nUsed++] = 'u'; |
| 195699 | p->zBuf[p->nUsed++] = '0'; | 201644 | p->zBuf[p->nUsed++] = '0'; |
| 195700 | p->zBuf[p->nUsed++] = '0'; | 201645 | p->zBuf[p->nUsed++] = '0'; |
| 195701 | p->zBuf[p->nUsed++] = '0' + (c>>4); | 201646 | p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; |
| 195702 | c = "0123456789abcdef"[c&0xf]; | 201647 | p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; |
| 195703 | } | 201648 | } |
| 195704 | p->zBuf[p->nUsed++] = c; | ||
| 195705 | } | 201649 | } |
| 195706 | p->zBuf[p->nUsed++] = '"'; | 201650 | p->zBuf[p->nUsed++] = '"'; |
| 195707 | assert( p->nUsed<p->nAlloc ); | 201651 | assert( p->nUsed<p->nAlloc ); |
| 195708 | } | 201652 | } |
| 195709 | 201653 | ||
| 195710 | /* | 201654 | /* |
| 201655 | ** The zIn[0..N] string is a JSON5 string literal. Append to p a translation | ||
| 201656 | ** of the string literal that standard JSON and that omits all JSON5 | ||
| 201657 | ** features. | ||
| 201658 | */ | ||
| 201659 | static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ | ||
| 201660 | u32 i; | ||
| 201661 | jsonAppendChar(p, '"'); | ||
| 201662 | zIn++; | ||
| 201663 | N -= 2; | ||
| 201664 | while( N>0 ){ | ||
| 201665 | for(i=0; i<N && zIn[i]!='\\'; i++){} | ||
| 201666 | if( i>0 ){ | ||
| 201667 | jsonAppendRawNZ(p, zIn, i); | ||
| 201668 | zIn += i; | ||
| 201669 | N -= i; | ||
| 201670 | if( N==0 ) break; | ||
| 201671 | } | ||
| 201672 | assert( zIn[0]=='\\' ); | ||
| 201673 | switch( (u8)zIn[1] ){ | ||
| 201674 | case '\'': | ||
| 201675 | jsonAppendChar(p, '\''); | ||
| 201676 | break; | ||
| 201677 | case 'v': | ||
| 201678 | jsonAppendRawNZ(p, "\\u0009", 6); | ||
| 201679 | break; | ||
| 201680 | case 'x': | ||
| 201681 | jsonAppendRawNZ(p, "\\u00", 4); | ||
| 201682 | jsonAppendRawNZ(p, &zIn[2], 2); | ||
| 201683 | zIn += 2; | ||
| 201684 | N -= 2; | ||
| 201685 | break; | ||
| 201686 | case '0': | ||
| 201687 | jsonAppendRawNZ(p, "\\u0000", 6); | ||
| 201688 | break; | ||
| 201689 | case '\r': | ||
| 201690 | if( zIn[2]=='\n' ){ | ||
| 201691 | zIn++; | ||
| 201692 | N--; | ||
| 201693 | } | ||
| 201694 | break; | ||
| 201695 | case '\n': | ||
| 201696 | break; | ||
| 201697 | case 0xe2: | ||
| 201698 | assert( N>=4 ); | ||
| 201699 | assert( 0x80==(u8)zIn[2] ); | ||
| 201700 | assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] ); | ||
| 201701 | zIn += 2; | ||
| 201702 | N -= 2; | ||
| 201703 | break; | ||
| 201704 | default: | ||
| 201705 | jsonAppendRawNZ(p, zIn, 2); | ||
| 201706 | break; | ||
| 201707 | } | ||
| 201708 | zIn += 2; | ||
| 201709 | N -= 2; | ||
| 201710 | } | ||
| 201711 | jsonAppendChar(p, '"'); | ||
| 201712 | } | ||
| 201713 | |||
| 201714 | /* | ||
| 201715 | ** The zIn[0..N] string is a JSON5 integer literal. Append to p a translation | ||
| 201716 | ** of the string literal that standard JSON and that omits all JSON5 | ||
| 201717 | ** features. | ||
| 201718 | */ | ||
| 201719 | static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){ | ||
| 201720 | if( zIn[0]=='+' ){ | ||
| 201721 | zIn++; | ||
| 201722 | N--; | ||
| 201723 | }else if( zIn[0]=='-' ){ | ||
| 201724 | jsonAppendChar(p, '-'); | ||
| 201725 | zIn++; | ||
| 201726 | N--; | ||
| 201727 | } | ||
| 201728 | if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){ | ||
| 201729 | sqlite3_int64 i = 0; | ||
| 201730 | int rc = sqlite3DecOrHexToI64(zIn, &i); | ||
| 201731 | if( rc<=1 ){ | ||
| 201732 | jsonPrintf(100,p,"%lld",i); | ||
| 201733 | }else{ | ||
| 201734 | assert( rc==2 ); | ||
| 201735 | jsonAppendRawNZ(p, "9.0e999", 7); | ||
| 201736 | } | ||
| 201737 | return; | ||
| 201738 | } | ||
| 201739 | assert( N>0 ); | ||
| 201740 | jsonAppendRawNZ(p, zIn, N); | ||
| 201741 | } | ||
| 201742 | |||
| 201743 | /* | ||
| 201744 | ** The zIn[0..N] string is a JSON5 real literal. Append to p a translation | ||
| 201745 | ** of the string literal that standard JSON and that omits all JSON5 | ||
| 201746 | ** features. | ||
| 201747 | */ | ||
| 201748 | static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){ | ||
| 201749 | u32 i; | ||
| 201750 | if( zIn[0]=='+' ){ | ||
| 201751 | zIn++; | ||
| 201752 | N--; | ||
| 201753 | }else if( zIn[0]=='-' ){ | ||
| 201754 | jsonAppendChar(p, '-'); | ||
| 201755 | zIn++; | ||
| 201756 | N--; | ||
| 201757 | } | ||
| 201758 | if( zIn[0]=='.' ){ | ||
| 201759 | jsonAppendChar(p, '0'); | ||
| 201760 | } | ||
| 201761 | for(i=0; i<N; i++){ | ||
| 201762 | if( zIn[i]=='.' && (i+1==N || !sqlite3Isdigit(zIn[i+1])) ){ | ||
| 201763 | i++; | ||
| 201764 | jsonAppendRaw(p, zIn, i); | ||
| 201765 | zIn += i; | ||
| 201766 | N -= i; | ||
| 201767 | jsonAppendChar(p, '0'); | ||
| 201768 | break; | ||
| 201769 | } | ||
| 201770 | } | ||
| 201771 | if( N>0 ){ | ||
| 201772 | jsonAppendRawNZ(p, zIn, N); | ||
| 201773 | } | ||
| 201774 | } | ||
| 201775 | |||
| 201776 | |||
| 201777 | |||
| 201778 | /* | ||
| 195711 | ** Append a function parameter value to the JSON string under | 201779 | ** Append a function parameter value to the JSON string under |
| 195712 | ** construction. | 201780 | ** construction. |
| 195713 | */ | 201781 | */ |
| @@ -195717,11 +201785,14 @@ static void jsonAppendValue( | |||
| 195717 | ){ | 201785 | ){ |
| 195718 | switch( sqlite3_value_type(pValue) ){ | 201786 | switch( sqlite3_value_type(pValue) ){ |
| 195719 | case SQLITE_NULL: { | 201787 | case SQLITE_NULL: { |
| 195720 | jsonAppendRaw(p, "null", 4); | 201788 | jsonAppendRawNZ(p, "null", 4); |
| 195721 | break; | 201789 | break; |
| 195722 | } | 201790 | } |
| 195723 | case SQLITE_INTEGER: | ||
| 195724 | case SQLITE_FLOAT: { | 201791 | case SQLITE_FLOAT: { |
| 201792 | jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue)); | ||
| 201793 | break; | ||
| 201794 | } | ||
| 201795 | case SQLITE_INTEGER: { | ||
| 195725 | const char *z = (const char*)sqlite3_value_text(pValue); | 201796 | const char *z = (const char*)sqlite3_value_text(pValue); |
| 195726 | u32 n = (u32)sqlite3_value_bytes(pValue); | 201797 | u32 n = (u32)sqlite3_value_bytes(pValue); |
| 195727 | jsonAppendRaw(p, z, n); | 201798 | jsonAppendRaw(p, z, n); |
| @@ -195750,15 +201821,25 @@ static void jsonAppendValue( | |||
| 195750 | 201821 | ||
| 195751 | 201822 | ||
| 195752 | /* Make the JSON in p the result of the SQL function. | 201823 | /* Make the JSON in p the result of the SQL function. |
| 201824 | ** | ||
| 201825 | ** The JSON string is reset. | ||
| 195753 | */ | 201826 | */ |
| 195754 | static void jsonResult(JsonString *p){ | 201827 | static void jsonResult(JsonString *p){ |
| 195755 | if( p->bErr==0 ){ | 201828 | if( p->bErr==0 ){ |
| 195756 | sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, | 201829 | if( p->bStatic ){ |
| 195757 | p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, | 201830 | sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, |
| 195758 | SQLITE_UTF8); | 201831 | SQLITE_TRANSIENT, SQLITE_UTF8); |
| 195759 | jsonZero(p); | 201832 | }else if( jsonForceRCStr(p) ){ |
| 201833 | sqlite3RCStrRef(p->zBuf); | ||
| 201834 | sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, | ||
| 201835 | (void(*)(void*))sqlite3RCStrUnref, | ||
| 201836 | SQLITE_UTF8); | ||
| 201837 | } | ||
| 201838 | } | ||
| 201839 | if( p->bErr==1 ){ | ||
| 201840 | sqlite3_result_error_nomem(p->pCtx); | ||
| 195760 | } | 201841 | } |
| 195761 | assert( p->bStatic ); | 201842 | jsonReset(p); |
| 195762 | } | 201843 | } |
| 195763 | 201844 | ||
| 195764 | /************************************************************************** | 201845 | /************************************************************************** |
| @@ -195783,20 +201864,73 @@ static u32 jsonNodeSize(JsonNode *pNode){ | |||
| 195783 | ** delete the JsonParse object itself. | 201864 | ** delete the JsonParse object itself. |
| 195784 | */ | 201865 | */ |
| 195785 | static void jsonParseReset(JsonParse *pParse){ | 201866 | static void jsonParseReset(JsonParse *pParse){ |
| 195786 | sqlite3_free(pParse->aNode); | 201867 | while( pParse->pClup ){ |
| 195787 | pParse->aNode = 0; | 201868 | JsonCleanup *pTask = pParse->pClup; |
| 201869 | pParse->pClup = pTask->pJCNext; | ||
| 201870 | pTask->xOp(pTask->pArg); | ||
| 201871 | sqlite3_free(pTask); | ||
| 201872 | } | ||
| 201873 | assert( pParse->nJPRef<=1 ); | ||
| 201874 | if( pParse->aNode ){ | ||
| 201875 | sqlite3_free(pParse->aNode); | ||
| 201876 | pParse->aNode = 0; | ||
| 201877 | } | ||
| 195788 | pParse->nNode = 0; | 201878 | pParse->nNode = 0; |
| 195789 | pParse->nAlloc = 0; | 201879 | pParse->nAlloc = 0; |
| 195790 | sqlite3_free(pParse->aUp); | 201880 | if( pParse->aUp ){ |
| 195791 | pParse->aUp = 0; | 201881 | sqlite3_free(pParse->aUp); |
| 201882 | pParse->aUp = 0; | ||
| 201883 | } | ||
| 201884 | if( pParse->bJsonIsRCStr ){ | ||
| 201885 | sqlite3RCStrUnref(pParse->zJson); | ||
| 201886 | pParse->zJson = 0; | ||
| 201887 | pParse->bJsonIsRCStr = 0; | ||
| 201888 | } | ||
| 201889 | if( pParse->zAlt ){ | ||
| 201890 | sqlite3RCStrUnref(pParse->zAlt); | ||
| 201891 | pParse->zAlt = 0; | ||
| 201892 | } | ||
| 195792 | } | 201893 | } |
| 195793 | 201894 | ||
| 195794 | /* | 201895 | /* |
| 195795 | ** Free a JsonParse object that was obtained from sqlite3_malloc(). | 201896 | ** Free a JsonParse object that was obtained from sqlite3_malloc(). |
| 201897 | ** | ||
| 201898 | ** Note that destroying JsonParse might call sqlite3RCStrUnref() to | ||
| 201899 | ** destroy the zJson value. The RCStr object might recursively invoke | ||
| 201900 | ** JsonParse to destroy this pParse object again. Take care to ensure | ||
| 201901 | ** that this recursive destructor sequence terminates harmlessly. | ||
| 195796 | */ | 201902 | */ |
| 195797 | static void jsonParseFree(JsonParse *pParse){ | 201903 | static void jsonParseFree(JsonParse *pParse){ |
| 195798 | jsonParseReset(pParse); | 201904 | if( pParse->nJPRef>1 ){ |
| 195799 | sqlite3_free(pParse); | 201905 | pParse->nJPRef--; |
| 201906 | }else{ | ||
| 201907 | jsonParseReset(pParse); | ||
| 201908 | sqlite3_free(pParse); | ||
| 201909 | } | ||
| 201910 | } | ||
| 201911 | |||
| 201912 | /* | ||
| 201913 | ** Add a cleanup task to the JsonParse object. | ||
| 201914 | ** | ||
| 201915 | ** If an OOM occurs, the cleanup operation happens immediately | ||
| 201916 | ** and this function returns SQLITE_NOMEM. | ||
| 201917 | */ | ||
| 201918 | static int jsonParseAddCleanup( | ||
| 201919 | JsonParse *pParse, /* Add the cleanup task to this parser */ | ||
| 201920 | void(*xOp)(void*), /* The cleanup task */ | ||
| 201921 | void *pArg /* Argument to the cleanup */ | ||
| 201922 | ){ | ||
| 201923 | JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) ); | ||
| 201924 | if( pTask==0 ){ | ||
| 201925 | pParse->oom = 1; | ||
| 201926 | xOp(pArg); | ||
| 201927 | return SQLITE_ERROR; | ||
| 201928 | } | ||
| 201929 | pTask->pJCNext = pParse->pClup; | ||
| 201930 | pParse->pClup = pTask; | ||
| 201931 | pTask->xOp = xOp; | ||
| 201932 | pTask->pArg = pArg; | ||
| 201933 | return SQLITE_OK; | ||
| 195800 | } | 201934 | } |
| 195801 | 201935 | ||
| 195802 | /* | 201936 | /* |
| @@ -195805,46 +201939,76 @@ static void jsonParseFree(JsonParse *pParse){ | |||
| 195805 | ** the number of JsonNode objects that are encoded. | 201939 | ** the number of JsonNode objects that are encoded. |
| 195806 | */ | 201940 | */ |
| 195807 | static void jsonRenderNode( | 201941 | static void jsonRenderNode( |
| 201942 | JsonParse *pParse, /* the complete parse of the JSON */ | ||
| 195808 | JsonNode *pNode, /* The node to render */ | 201943 | JsonNode *pNode, /* The node to render */ |
| 195809 | JsonString *pOut, /* Write JSON here */ | 201944 | JsonString *pOut /* Write JSON here */ |
| 195810 | sqlite3_value **aReplace /* Replacement values */ | ||
| 195811 | ){ | 201945 | ){ |
| 195812 | assert( pNode!=0 ); | 201946 | assert( pNode!=0 ); |
| 195813 | if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ | 201947 | while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){ |
| 195814 | if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){ | 201948 | u32 idx = (u32)(pNode - pParse->aNode); |
| 195815 | assert( pNode->eU==4 ); | 201949 | u32 i = pParse->iSubst; |
| 195816 | jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); | 201950 | while( 1 /*exit-by-break*/ ){ |
| 195817 | return; | 201951 | assert( i<pParse->nNode ); |
| 201952 | assert( pParse->aNode[i].eType==JSON_SUBST ); | ||
| 201953 | assert( pParse->aNode[i].eU==4 ); | ||
| 201954 | assert( pParse->aNode[i].u.iPrev<i ); | ||
| 201955 | if( pParse->aNode[i].n==idx ){ | ||
| 201956 | pNode = &pParse->aNode[i+1]; | ||
| 201957 | break; | ||
| 201958 | } | ||
| 201959 | i = pParse->aNode[i].u.iPrev; | ||
| 195818 | } | 201960 | } |
| 195819 | assert( pNode->eU==5 ); | ||
| 195820 | pNode = pNode->u.pPatch; | ||
| 195821 | } | 201961 | } |
| 195822 | switch( pNode->eType ){ | 201962 | switch( pNode->eType ){ |
| 195823 | default: { | 201963 | default: { |
| 195824 | assert( pNode->eType==JSON_NULL ); | 201964 | assert( pNode->eType==JSON_NULL ); |
| 195825 | jsonAppendRaw(pOut, "null", 4); | 201965 | jsonAppendRawNZ(pOut, "null", 4); |
| 195826 | break; | 201966 | break; |
| 195827 | } | 201967 | } |
| 195828 | case JSON_TRUE: { | 201968 | case JSON_TRUE: { |
| 195829 | jsonAppendRaw(pOut, "true", 4); | 201969 | jsonAppendRawNZ(pOut, "true", 4); |
| 195830 | break; | 201970 | break; |
| 195831 | } | 201971 | } |
| 195832 | case JSON_FALSE: { | 201972 | case JSON_FALSE: { |
| 195833 | jsonAppendRaw(pOut, "false", 5); | 201973 | jsonAppendRawNZ(pOut, "false", 5); |
| 195834 | break; | 201974 | break; |
| 195835 | } | 201975 | } |
| 195836 | case JSON_STRING: { | 201976 | case JSON_STRING: { |
| 201977 | assert( pNode->eU==1 ); | ||
| 195837 | if( pNode->jnFlags & JNODE_RAW ){ | 201978 | if( pNode->jnFlags & JNODE_RAW ){ |
| 195838 | assert( pNode->eU==1 ); | 201979 | if( pNode->jnFlags & JNODE_LABEL ){ |
| 195839 | jsonAppendString(pOut, pNode->u.zJContent, pNode->n); | 201980 | jsonAppendChar(pOut, '"'); |
| 195840 | break; | 201981 | jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); |
| 201982 | jsonAppendChar(pOut, '"'); | ||
| 201983 | }else{ | ||
| 201984 | jsonAppendString(pOut, pNode->u.zJContent, pNode->n); | ||
| 201985 | } | ||
| 201986 | }else if( pNode->jnFlags & JNODE_JSON5 ){ | ||
| 201987 | jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n); | ||
| 201988 | }else{ | ||
| 201989 | assert( pNode->n>0 ); | ||
| 201990 | jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); | ||
| 195841 | } | 201991 | } |
| 195842 | /* no break */ deliberate_fall_through | 201992 | break; |
| 201993 | } | ||
| 201994 | case JSON_REAL: { | ||
| 201995 | assert( pNode->eU==1 ); | ||
| 201996 | if( pNode->jnFlags & JNODE_JSON5 ){ | ||
| 201997 | jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n); | ||
| 201998 | }else{ | ||
| 201999 | assert( pNode->n>0 ); | ||
| 202000 | jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); | ||
| 202001 | } | ||
| 202002 | break; | ||
| 195843 | } | 202003 | } |
| 195844 | case JSON_REAL: | ||
| 195845 | case JSON_INT: { | 202004 | case JSON_INT: { |
| 195846 | assert( pNode->eU==1 ); | 202005 | assert( pNode->eU==1 ); |
| 195847 | jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); | 202006 | if( pNode->jnFlags & JNODE_JSON5 ){ |
| 202007 | jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n); | ||
| 202008 | }else{ | ||
| 202009 | assert( pNode->n>0 ); | ||
| 202010 | jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); | ||
| 202011 | } | ||
| 195848 | break; | 202012 | break; |
| 195849 | } | 202013 | } |
| 195850 | case JSON_ARRAY: { | 202014 | case JSON_ARRAY: { |
| @@ -195852,15 +202016,16 @@ static void jsonRenderNode( | |||
| 195852 | jsonAppendChar(pOut, '['); | 202016 | jsonAppendChar(pOut, '['); |
| 195853 | for(;;){ | 202017 | for(;;){ |
| 195854 | while( j<=pNode->n ){ | 202018 | while( j<=pNode->n ){ |
| 195855 | if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ | 202019 | if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ |
| 195856 | jsonAppendSeparator(pOut); | 202020 | jsonAppendSeparator(pOut); |
| 195857 | jsonRenderNode(&pNode[j], pOut, aReplace); | 202021 | jsonRenderNode(pParse, &pNode[j], pOut); |
| 195858 | } | 202022 | } |
| 195859 | j += jsonNodeSize(&pNode[j]); | 202023 | j += jsonNodeSize(&pNode[j]); |
| 195860 | } | 202024 | } |
| 195861 | if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; | 202025 | if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; |
| 202026 | if( pParse->useMod==0 ) break; | ||
| 195862 | assert( pNode->eU==2 ); | 202027 | assert( pNode->eU==2 ); |
| 195863 | pNode = &pNode[pNode->u.iAppend]; | 202028 | pNode = &pParse->aNode[pNode->u.iAppend]; |
| 195864 | j = 1; | 202029 | j = 1; |
| 195865 | } | 202030 | } |
| 195866 | jsonAppendChar(pOut, ']'); | 202031 | jsonAppendChar(pOut, ']'); |
| @@ -195871,17 +202036,18 @@ static void jsonRenderNode( | |||
| 195871 | jsonAppendChar(pOut, '{'); | 202036 | jsonAppendChar(pOut, '{'); |
| 195872 | for(;;){ | 202037 | for(;;){ |
| 195873 | while( j<=pNode->n ){ | 202038 | while( j<=pNode->n ){ |
| 195874 | if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ | 202039 | if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ |
| 195875 | jsonAppendSeparator(pOut); | 202040 | jsonAppendSeparator(pOut); |
| 195876 | jsonRenderNode(&pNode[j], pOut, aReplace); | 202041 | jsonRenderNode(pParse, &pNode[j], pOut); |
| 195877 | jsonAppendChar(pOut, ':'); | 202042 | jsonAppendChar(pOut, ':'); |
| 195878 | jsonRenderNode(&pNode[j+1], pOut, aReplace); | 202043 | jsonRenderNode(pParse, &pNode[j+1], pOut); |
| 195879 | } | 202044 | } |
| 195880 | j += 1 + jsonNodeSize(&pNode[j+1]); | 202045 | j += 1 + jsonNodeSize(&pNode[j+1]); |
| 195881 | } | 202046 | } |
| 195882 | if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; | 202047 | if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; |
| 202048 | if( pParse->useMod==0 ) break; | ||
| 195883 | assert( pNode->eU==2 ); | 202049 | assert( pNode->eU==2 ); |
| 195884 | pNode = &pNode[pNode->u.iAppend]; | 202050 | pNode = &pParse->aNode[pNode->u.iAppend]; |
| 195885 | j = 1; | 202051 | j = 1; |
| 195886 | } | 202052 | } |
| 195887 | jsonAppendChar(pOut, '}'); | 202053 | jsonAppendChar(pOut, '}'); |
| @@ -195891,18 +202057,29 @@ static void jsonRenderNode( | |||
| 195891 | } | 202057 | } |
| 195892 | 202058 | ||
| 195893 | /* | 202059 | /* |
| 195894 | ** Return a JsonNode and all its descendents as a JSON string. | 202060 | ** Return a JsonNode and all its descendants as a JSON string. |
| 195895 | */ | 202061 | */ |
| 195896 | static void jsonReturnJson( | 202062 | static void jsonReturnJson( |
| 202063 | JsonParse *pParse, /* The complete JSON */ | ||
| 195897 | JsonNode *pNode, /* Node to return */ | 202064 | JsonNode *pNode, /* Node to return */ |
| 195898 | sqlite3_context *pCtx, /* Return value for this function */ | 202065 | sqlite3_context *pCtx, /* Return value for this function */ |
| 195899 | sqlite3_value **aReplace /* Array of replacement values */ | 202066 | int bGenerateAlt /* Also store the rendered text in zAlt */ |
| 195900 | ){ | 202067 | ){ |
| 195901 | JsonString s; | 202068 | JsonString s; |
| 195902 | jsonInit(&s, pCtx); | 202069 | if( pParse->oom ){ |
| 195903 | jsonRenderNode(pNode, &s, aReplace); | 202070 | sqlite3_result_error_nomem(pCtx); |
| 195904 | jsonResult(&s); | 202071 | return; |
| 195905 | sqlite3_result_subtype(pCtx, JSON_SUBTYPE); | 202072 | } |
| 202073 | if( pParse->nErr==0 ){ | ||
| 202074 | jsonInit(&s, pCtx); | ||
| 202075 | jsonRenderNode(pParse, pNode, &s); | ||
| 202076 | if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){ | ||
| 202077 | pParse->zAlt = sqlite3RCStrRef(s.zBuf); | ||
| 202078 | pParse->nAlt = s.nUsed; | ||
| 202079 | } | ||
| 202080 | jsonResult(&s); | ||
| 202081 | sqlite3_result_subtype(pCtx, JSON_SUBTYPE); | ||
| 202082 | } | ||
| 195906 | } | 202083 | } |
| 195907 | 202084 | ||
| 195908 | /* | 202085 | /* |
| @@ -195940,9 +202117,9 @@ static u32 jsonHexToInt4(const char *z){ | |||
| 195940 | ** Make the JsonNode the return value of the function. | 202117 | ** Make the JsonNode the return value of the function. |
| 195941 | */ | 202118 | */ |
| 195942 | static void jsonReturn( | 202119 | static void jsonReturn( |
| 202120 | JsonParse *pParse, /* Complete JSON parse tree */ | ||
| 195943 | JsonNode *pNode, /* Node to return */ | 202121 | JsonNode *pNode, /* Node to return */ |
| 195944 | sqlite3_context *pCtx, /* Return value for this function */ | 202122 | sqlite3_context *pCtx /* Return value for this function */ |
| 195945 | sqlite3_value **aReplace /* Array of replacement values */ | ||
| 195946 | ){ | 202123 | ){ |
| 195947 | switch( pNode->eType ){ | 202124 | switch( pNode->eType ){ |
| 195948 | default: { | 202125 | default: { |
| @@ -195960,59 +202137,40 @@ static void jsonReturn( | |||
| 195960 | } | 202137 | } |
| 195961 | case JSON_INT: { | 202138 | case JSON_INT: { |
| 195962 | sqlite3_int64 i = 0; | 202139 | sqlite3_int64 i = 0; |
| 202140 | int rc; | ||
| 202141 | int bNeg = 0; | ||
| 195963 | const char *z; | 202142 | const char *z; |
| 202143 | |||
| 195964 | assert( pNode->eU==1 ); | 202144 | assert( pNode->eU==1 ); |
| 195965 | z = pNode->u.zJContent; | 202145 | z = pNode->u.zJContent; |
| 195966 | if( z[0]=='-' ){ z++; } | 202146 | if( z[0]=='-' ){ z++; bNeg = 1; } |
| 195967 | while( z[0]>='0' && z[0]<='9' ){ | 202147 | else if( z[0]=='+' ){ z++; } |
| 195968 | unsigned v = *(z++) - '0'; | 202148 | rc = sqlite3DecOrHexToI64(z, &i); |
| 195969 | if( i>=LARGEST_INT64/10 ){ | 202149 | if( rc<=1 ){ |
| 195970 | if( i>LARGEST_INT64/10 ) goto int_as_real; | 202150 | sqlite3_result_int64(pCtx, bNeg ? -i : i); |
| 195971 | if( z[0]>='0' && z[0]<='9' ) goto int_as_real; | 202151 | }else if( rc==3 && bNeg ){ |
| 195972 | if( v==9 ) goto int_as_real; | 202152 | sqlite3_result_int64(pCtx, SMALLEST_INT64); |
| 195973 | if( v==8 ){ | 202153 | }else{ |
| 195974 | if( pNode->u.zJContent[0]=='-' ){ | 202154 | goto to_double; |
| 195975 | sqlite3_result_int64(pCtx, SMALLEST_INT64); | ||
| 195976 | goto int_done; | ||
| 195977 | }else{ | ||
| 195978 | goto int_as_real; | ||
| 195979 | } | ||
| 195980 | } | ||
| 195981 | } | ||
| 195982 | i = i*10 + v; | ||
| 195983 | } | 202155 | } |
| 195984 | if( pNode->u.zJContent[0]=='-' ){ i = -i; } | ||
| 195985 | sqlite3_result_int64(pCtx, i); | ||
| 195986 | int_done: | ||
| 195987 | break; | 202156 | break; |
| 195988 | int_as_real: ; /* no break */ deliberate_fall_through | ||
| 195989 | } | 202157 | } |
| 195990 | case JSON_REAL: { | 202158 | case JSON_REAL: { |
| 195991 | double r; | 202159 | double r; |
| 195992 | #ifdef SQLITE_AMALGAMATION | ||
| 195993 | const char *z; | 202160 | const char *z; |
| 195994 | assert( pNode->eU==1 ); | 202161 | assert( pNode->eU==1 ); |
| 202162 | to_double: | ||
| 195995 | z = pNode->u.zJContent; | 202163 | z = pNode->u.zJContent; |
| 195996 | sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); | 202164 | sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); |
| 195997 | #else | ||
| 195998 | assert( pNode->eU==1 ); | ||
| 195999 | r = strtod(pNode->u.zJContent, 0); | ||
| 196000 | #endif | ||
| 196001 | sqlite3_result_double(pCtx, r); | 202165 | sqlite3_result_double(pCtx, r); |
| 196002 | break; | 202166 | break; |
| 196003 | } | 202167 | } |
| 196004 | case JSON_STRING: { | 202168 | case JSON_STRING: { |
| 196005 | #if 0 /* Never happens because JNODE_RAW is only set by json_set(), | ||
| 196006 | ** json_insert() and json_replace() and those routines do not | ||
| 196007 | ** call jsonReturn() */ | ||
| 196008 | if( pNode->jnFlags & JNODE_RAW ){ | 202169 | if( pNode->jnFlags & JNODE_RAW ){ |
| 196009 | assert( pNode->eU==1 ); | 202170 | assert( pNode->eU==1 ); |
| 196010 | sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, | 202171 | sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, |
| 196011 | SQLITE_TRANSIENT); | 202172 | SQLITE_TRANSIENT); |
| 196012 | }else | 202173 | }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ |
| 196013 | #endif | ||
| 196014 | assert( (pNode->jnFlags & JNODE_RAW)==0 ); | ||
| 196015 | if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ | ||
| 196016 | /* JSON formatted without any backslash-escapes */ | 202174 | /* JSON formatted without any backslash-escapes */ |
| 196017 | assert( pNode->eU==1 ); | 202175 | assert( pNode->eU==1 ); |
| 196018 | sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, | 202176 | sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, |
| @@ -196024,18 +202182,17 @@ static void jsonReturn( | |||
| 196024 | const char *z; | 202182 | const char *z; |
| 196025 | char *zOut; | 202183 | char *zOut; |
| 196026 | u32 j; | 202184 | u32 j; |
| 202185 | u32 nOut = n; | ||
| 196027 | assert( pNode->eU==1 ); | 202186 | assert( pNode->eU==1 ); |
| 196028 | z = pNode->u.zJContent; | 202187 | z = pNode->u.zJContent; |
| 196029 | zOut = sqlite3_malloc( n+1 ); | 202188 | zOut = sqlite3_malloc( nOut+1 ); |
| 196030 | if( zOut==0 ){ | 202189 | if( zOut==0 ){ |
| 196031 | sqlite3_result_error_nomem(pCtx); | 202190 | sqlite3_result_error_nomem(pCtx); |
| 196032 | break; | 202191 | break; |
| 196033 | } | 202192 | } |
| 196034 | for(i=1, j=0; i<n-1; i++){ | 202193 | for(i=1, j=0; i<n-1; i++){ |
| 196035 | char c = z[i]; | 202194 | char c = z[i]; |
| 196036 | if( c!='\\' ){ | 202195 | if( c=='\\' ){ |
| 196037 | zOut[j++] = c; | ||
| 196038 | }else{ | ||
| 196039 | c = z[++i]; | 202196 | c = z[++i]; |
| 196040 | if( c=='u' ){ | 202197 | if( c=='u' ){ |
| 196041 | u32 v = jsonHexToInt4(z+i+1); | 202198 | u32 v = jsonHexToInt4(z+i+1); |
| @@ -196067,22 +202224,40 @@ static void jsonReturn( | |||
| 196067 | zOut[j++] = 0x80 | (v&0x3f); | 202224 | zOut[j++] = 0x80 | (v&0x3f); |
| 196068 | } | 202225 | } |
| 196069 | } | 202226 | } |
| 202227 | continue; | ||
| 202228 | }else if( c=='b' ){ | ||
| 202229 | c = '\b'; | ||
| 202230 | }else if( c=='f' ){ | ||
| 202231 | c = '\f'; | ||
| 202232 | }else if( c=='n' ){ | ||
| 202233 | c = '\n'; | ||
| 202234 | }else if( c=='r' ){ | ||
| 202235 | c = '\r'; | ||
| 202236 | }else if( c=='t' ){ | ||
| 202237 | c = '\t'; | ||
| 202238 | }else if( c=='v' ){ | ||
| 202239 | c = '\v'; | ||
| 202240 | }else if( c=='\'' || c=='"' || c=='/' || c=='\\' ){ | ||
| 202241 | /* pass through unchanged */ | ||
| 202242 | }else if( c=='0' ){ | ||
| 202243 | c = 0; | ||
| 202244 | }else if( c=='x' ){ | ||
| 202245 | c = (jsonHexToInt(z[i+1])<<4) | jsonHexToInt(z[i+2]); | ||
| 202246 | i += 2; | ||
| 202247 | }else if( c=='\r' && z[i+1]=='\n' ){ | ||
| 202248 | i++; | ||
| 202249 | continue; | ||
| 202250 | }else if( 0xe2==(u8)c ){ | ||
| 202251 | assert( 0x80==(u8)z[i+1] ); | ||
| 202252 | assert( 0xa8==(u8)z[i+2] || 0xa9==(u8)z[i+2] ); | ||
| 202253 | i += 2; | ||
| 202254 | continue; | ||
| 196070 | }else{ | 202255 | }else{ |
| 196071 | if( c=='b' ){ | 202256 | continue; |
| 196072 | c = '\b'; | ||
| 196073 | }else if( c=='f' ){ | ||
| 196074 | c = '\f'; | ||
| 196075 | }else if( c=='n' ){ | ||
| 196076 | c = '\n'; | ||
| 196077 | }else if( c=='r' ){ | ||
| 196078 | c = '\r'; | ||
| 196079 | }else if( c=='t' ){ | ||
| 196080 | c = '\t'; | ||
| 196081 | } | ||
| 196082 | zOut[j++] = c; | ||
| 196083 | } | 202257 | } |
| 196084 | } | 202258 | } /* end if( c=='\\' ) */ |
| 196085 | } | 202259 | zOut[j++] = c; |
| 202260 | } /* end for() */ | ||
| 196086 | zOut[j] = 0; | 202261 | zOut[j] = 0; |
| 196087 | sqlite3_result_text(pCtx, zOut, j, sqlite3_free); | 202262 | sqlite3_result_text(pCtx, zOut, j, sqlite3_free); |
| 196088 | } | 202263 | } |
| @@ -196090,7 +202265,7 @@ static void jsonReturn( | |||
| 196090 | } | 202265 | } |
| 196091 | case JSON_ARRAY: | 202266 | case JSON_ARRAY: |
| 196092 | case JSON_OBJECT: { | 202267 | case JSON_OBJECT: { |
| 196093 | jsonReturnJson(pNode, pCtx, aReplace); | 202268 | jsonReturnJson(pParse, pNode, pCtx, 0); |
| 196094 | break; | 202269 | break; |
| 196095 | } | 202270 | } |
| 196096 | } | 202271 | } |
| @@ -196112,6 +202287,12 @@ static int jsonParseAddNode(JsonParse*,u32,u32,const char*); | |||
| 196112 | #endif | 202287 | #endif |
| 196113 | 202288 | ||
| 196114 | 202289 | ||
| 202290 | /* | ||
| 202291 | ** Add a single node to pParse->aNode after first expanding the | ||
| 202292 | ** size of the aNode array. Return the index of the new node. | ||
| 202293 | ** | ||
| 202294 | ** If an OOM error occurs, set pParse->oom and return -1. | ||
| 202295 | */ | ||
| 196115 | static JSON_NOINLINE int jsonParseAddNodeExpand( | 202296 | static JSON_NOINLINE int jsonParseAddNodeExpand( |
| 196116 | JsonParse *pParse, /* Append the node to this object */ | 202297 | JsonParse *pParse, /* Append the node to this object */ |
| 196117 | u32 eType, /* Node type */ | 202298 | u32 eType, /* Node type */ |
| @@ -196128,7 +202309,7 @@ static JSON_NOINLINE int jsonParseAddNodeExpand( | |||
| 196128 | pParse->oom = 1; | 202309 | pParse->oom = 1; |
| 196129 | return -1; | 202310 | return -1; |
| 196130 | } | 202311 | } |
| 196131 | pParse->nAlloc = nNew; | 202312 | pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode); |
| 196132 | pParse->aNode = pNew; | 202313 | pParse->aNode = pNew; |
| 196133 | assert( pParse->nNode<pParse->nAlloc ); | 202314 | assert( pParse->nNode<pParse->nAlloc ); |
| 196134 | return jsonParseAddNode(pParse, eType, n, zContent); | 202315 | return jsonParseAddNode(pParse, eType, n, zContent); |
| @@ -196146,12 +202327,15 @@ static int jsonParseAddNode( | |||
| 196146 | const char *zContent /* Content */ | 202327 | const char *zContent /* Content */ |
| 196147 | ){ | 202328 | ){ |
| 196148 | JsonNode *p; | 202329 | JsonNode *p; |
| 196149 | if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){ | 202330 | assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc ); |
| 202331 | if( pParse->nNode>=pParse->nAlloc ){ | ||
| 196150 | return jsonParseAddNodeExpand(pParse, eType, n, zContent); | 202332 | return jsonParseAddNodeExpand(pParse, eType, n, zContent); |
| 196151 | } | 202333 | } |
| 202334 | assert( pParse->aNode!=0 ); | ||
| 196152 | p = &pParse->aNode[pParse->nNode]; | 202335 | p = &pParse->aNode[pParse->nNode]; |
| 196153 | p->eType = (u8)eType; | 202336 | assert( p!=0 ); |
| 196154 | p->jnFlags = 0; | 202337 | p->eType = (u8)(eType & 0xff); |
| 202338 | p->jnFlags = (u8)(eType >> 8); | ||
| 196155 | VVA( p->eU = zContent ? 1 : 0 ); | 202339 | VVA( p->eU = zContent ? 1 : 0 ); |
| 196156 | p->n = n; | 202340 | p->n = n; |
| 196157 | p->u.zJContent = zContent; | 202341 | p->u.zJContent = zContent; |
| @@ -196159,21 +202343,223 @@ static int jsonParseAddNode( | |||
| 196159 | } | 202343 | } |
| 196160 | 202344 | ||
| 196161 | /* | 202345 | /* |
| 202346 | ** Add an array of new nodes to the current pParse->aNode array. | ||
| 202347 | ** Return the index of the first node added. | ||
| 202348 | ** | ||
| 202349 | ** If an OOM error occurs, set pParse->oom. | ||
| 202350 | */ | ||
| 202351 | static void jsonParseAddNodeArray( | ||
| 202352 | JsonParse *pParse, /* Append the node to this object */ | ||
| 202353 | JsonNode *aNode, /* Array of nodes to add */ | ||
| 202354 | u32 nNode /* Number of elements in aNew */ | ||
| 202355 | ){ | ||
| 202356 | assert( aNode!=0 ); | ||
| 202357 | assert( nNode>=1 ); | ||
| 202358 | if( pParse->nNode + nNode > pParse->nAlloc ){ | ||
| 202359 | u32 nNew = pParse->nNode + nNode; | ||
| 202360 | JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode)); | ||
| 202361 | if( aNew==0 ){ | ||
| 202362 | pParse->oom = 1; | ||
| 202363 | return; | ||
| 202364 | } | ||
| 202365 | pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode); | ||
| 202366 | pParse->aNode = aNew; | ||
| 202367 | } | ||
| 202368 | memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode)); | ||
| 202369 | pParse->nNode += nNode; | ||
| 202370 | } | ||
| 202371 | |||
| 202372 | /* | ||
| 202373 | ** Add a new JSON_SUBST node. The node immediately following | ||
| 202374 | ** this new node will be the substitute content for iNode. | ||
| 202375 | */ | ||
| 202376 | static int jsonParseAddSubstNode( | ||
| 202377 | JsonParse *pParse, /* Add the JSON_SUBST here */ | ||
| 202378 | u32 iNode /* References this node */ | ||
| 202379 | ){ | ||
| 202380 | int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0); | ||
| 202381 | if( pParse->oom ) return -1; | ||
| 202382 | pParse->aNode[iNode].jnFlags |= JNODE_REPLACE; | ||
| 202383 | pParse->aNode[idx].eU = 4; | ||
| 202384 | pParse->aNode[idx].u.iPrev = pParse->iSubst; | ||
| 202385 | pParse->iSubst = idx; | ||
| 202386 | pParse->hasMod = 1; | ||
| 202387 | pParse->useMod = 1; | ||
| 202388 | return idx; | ||
| 202389 | } | ||
| 202390 | |||
| 202391 | /* | ||
| 202392 | ** Return true if z[] begins with 2 (or more) hexadecimal digits | ||
| 202393 | */ | ||
| 202394 | static int jsonIs2Hex(const char *z){ | ||
| 202395 | return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]); | ||
| 202396 | } | ||
| 202397 | |||
| 202398 | /* | ||
| 196162 | ** Return true if z[] begins with 4 (or more) hexadecimal digits | 202399 | ** Return true if z[] begins with 4 (or more) hexadecimal digits |
| 196163 | */ | 202400 | */ |
| 196164 | static int jsonIs4Hex(const char *z){ | 202401 | static int jsonIs4Hex(const char *z){ |
| 196165 | int i; | 202402 | return jsonIs2Hex(z) && jsonIs2Hex(&z[2]); |
| 196166 | for(i=0; i<4; i++) if( !sqlite3Isxdigit(z[i]) ) return 0; | 202403 | } |
| 196167 | return 1; | 202404 | |
| 202405 | /* | ||
| 202406 | ** Return the number of bytes of JSON5 whitespace at the beginning of | ||
| 202407 | ** the input string z[]. | ||
| 202408 | ** | ||
| 202409 | ** JSON5 whitespace consists of any of the following characters: | ||
| 202410 | ** | ||
| 202411 | ** Unicode UTF-8 Name | ||
| 202412 | ** U+0009 09 horizontal tab | ||
| 202413 | ** U+000a 0a line feed | ||
| 202414 | ** U+000b 0b vertical tab | ||
| 202415 | ** U+000c 0c form feed | ||
| 202416 | ** U+000d 0d carriage return | ||
| 202417 | ** U+0020 20 space | ||
| 202418 | ** U+00a0 c2 a0 non-breaking space | ||
| 202419 | ** U+1680 e1 9a 80 ogham space mark | ||
| 202420 | ** U+2000 e2 80 80 en quad | ||
| 202421 | ** U+2001 e2 80 81 em quad | ||
| 202422 | ** U+2002 e2 80 82 en space | ||
| 202423 | ** U+2003 e2 80 83 em space | ||
| 202424 | ** U+2004 e2 80 84 three-per-em space | ||
| 202425 | ** U+2005 e2 80 85 four-per-em space | ||
| 202426 | ** U+2006 e2 80 86 six-per-em space | ||
| 202427 | ** U+2007 e2 80 87 figure space | ||
| 202428 | ** U+2008 e2 80 88 punctuation space | ||
| 202429 | ** U+2009 e2 80 89 thin space | ||
| 202430 | ** U+200a e2 80 8a hair space | ||
| 202431 | ** U+2028 e2 80 a8 line separator | ||
| 202432 | ** U+2029 e2 80 a9 paragraph separator | ||
| 202433 | ** U+202f e2 80 af narrow no-break space (NNBSP) | ||
| 202434 | ** U+205f e2 81 9f medium mathematical space (MMSP) | ||
| 202435 | ** U+3000 e3 80 80 ideographical space | ||
| 202436 | ** U+FEFF ef bb bf byte order mark | ||
| 202437 | ** | ||
| 202438 | ** In addition, comments between '/', '*' and '*', '/' and | ||
| 202439 | ** from '/', '/' to end-of-line are also considered to be whitespace. | ||
| 202440 | */ | ||
| 202441 | static int json5Whitespace(const char *zIn){ | ||
| 202442 | int n = 0; | ||
| 202443 | const u8 *z = (u8*)zIn; | ||
| 202444 | while( 1 /*exit by "goto whitespace_done"*/ ){ | ||
| 202445 | switch( z[n] ){ | ||
| 202446 | case 0x09: | ||
| 202447 | case 0x0a: | ||
| 202448 | case 0x0b: | ||
| 202449 | case 0x0c: | ||
| 202450 | case 0x0d: | ||
| 202451 | case 0x20: { | ||
| 202452 | n++; | ||
| 202453 | break; | ||
| 202454 | } | ||
| 202455 | case '/': { | ||
| 202456 | if( z[n+1]=='*' && z[n+2]!=0 ){ | ||
| 202457 | int j; | ||
| 202458 | for(j=n+3; z[j]!='/' || z[j-1]!='*'; j++){ | ||
| 202459 | if( z[j]==0 ) goto whitespace_done; | ||
| 202460 | } | ||
| 202461 | n = j+1; | ||
| 202462 | break; | ||
| 202463 | }else if( z[n+1]=='/' ){ | ||
| 202464 | int j; | ||
| 202465 | char c; | ||
| 202466 | for(j=n+2; (c = z[j])!=0; j++){ | ||
| 202467 | if( c=='\n' || c=='\r' ) break; | ||
| 202468 | if( 0xe2==(u8)c && 0x80==(u8)z[j+1] | ||
| 202469 | && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]) | ||
| 202470 | ){ | ||
| 202471 | j += 2; | ||
| 202472 | break; | ||
| 202473 | } | ||
| 202474 | } | ||
| 202475 | n = j; | ||
| 202476 | if( z[n] ) n++; | ||
| 202477 | break; | ||
| 202478 | } | ||
| 202479 | goto whitespace_done; | ||
| 202480 | } | ||
| 202481 | case 0xc2: { | ||
| 202482 | if( z[n+1]==0xa0 ){ | ||
| 202483 | n += 2; | ||
| 202484 | break; | ||
| 202485 | } | ||
| 202486 | goto whitespace_done; | ||
| 202487 | } | ||
| 202488 | case 0xe1: { | ||
| 202489 | if( z[n+1]==0x9a && z[n+2]==0x80 ){ | ||
| 202490 | n += 3; | ||
| 202491 | break; | ||
| 202492 | } | ||
| 202493 | goto whitespace_done; | ||
| 202494 | } | ||
| 202495 | case 0xe2: { | ||
| 202496 | if( z[n+1]==0x80 ){ | ||
| 202497 | u8 c = z[n+2]; | ||
| 202498 | if( c<0x80 ) goto whitespace_done; | ||
| 202499 | if( c<=0x8a || c==0xa8 || c==0xa9 || c==0xaf ){ | ||
| 202500 | n += 3; | ||
| 202501 | break; | ||
| 202502 | } | ||
| 202503 | }else if( z[n+1]==0x81 && z[n+2]==0x9f ){ | ||
| 202504 | n += 3; | ||
| 202505 | break; | ||
| 202506 | } | ||
| 202507 | goto whitespace_done; | ||
| 202508 | } | ||
| 202509 | case 0xe3: { | ||
| 202510 | if( z[n+1]==0x80 && z[n+2]==0x80 ){ | ||
| 202511 | n += 3; | ||
| 202512 | break; | ||
| 202513 | } | ||
| 202514 | goto whitespace_done; | ||
| 202515 | } | ||
| 202516 | case 0xef: { | ||
| 202517 | if( z[n+1]==0xbb && z[n+2]==0xbf ){ | ||
| 202518 | n += 3; | ||
| 202519 | break; | ||
| 202520 | } | ||
| 202521 | goto whitespace_done; | ||
| 202522 | } | ||
| 202523 | default: { | ||
| 202524 | goto whitespace_done; | ||
| 202525 | } | ||
| 202526 | } | ||
| 202527 | } | ||
| 202528 | whitespace_done: | ||
| 202529 | return n; | ||
| 196168 | } | 202530 | } |
| 196169 | 202531 | ||
| 196170 | /* | 202532 | /* |
| 202533 | ** Extra floating-point literals to allow in JSON. | ||
| 202534 | */ | ||
| 202535 | static const struct NanInfName { | ||
| 202536 | char c1; | ||
| 202537 | char c2; | ||
| 202538 | char n; | ||
| 202539 | char eType; | ||
| 202540 | char nRepl; | ||
| 202541 | char *zMatch; | ||
| 202542 | char *zRepl; | ||
| 202543 | } aNanInfName[] = { | ||
| 202544 | { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" }, | ||
| 202545 | { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" }, | ||
| 202546 | { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" }, | ||
| 202547 | { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" }, | ||
| 202548 | { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" }, | ||
| 202549 | }; | ||
| 202550 | |||
| 202551 | /* | ||
| 196171 | ** Parse a single JSON value which begins at pParse->zJson[i]. Return the | 202552 | ** Parse a single JSON value which begins at pParse->zJson[i]. Return the |
| 196172 | ** index of the first character past the end of the value parsed. | 202553 | ** index of the first character past the end of the value parsed. |
| 196173 | ** | 202554 | ** |
| 196174 | ** Return negative for a syntax error. Special cases: return -2 if the | 202555 | ** Special return values: |
| 196175 | ** first non-whitespace character is '}' and return -3 if the first | 202556 | ** |
| 196176 | ** non-whitespace character is ']'. | 202557 | ** 0 End of input |
| 202558 | ** -1 Syntax error | ||
| 202559 | ** -2 '}' seen | ||
| 202560 | ** -3 ']' seen | ||
| 202561 | ** -4 ',' seen | ||
| 202562 | ** -5 ':' seen | ||
| 196177 | */ | 202563 | */ |
| 196178 | static int jsonParseValue(JsonParse *pParse, u32 i){ | 202564 | static int jsonParseValue(JsonParse *pParse, u32 i){ |
| 196179 | char c; | 202565 | char c; |
| @@ -196182,175 +202568,457 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ | |||
| 196182 | int x; | 202568 | int x; |
| 196183 | JsonNode *pNode; | 202569 | JsonNode *pNode; |
| 196184 | const char *z = pParse->zJson; | 202570 | const char *z = pParse->zJson; |
| 196185 | while( fast_isspace(z[i]) ){ i++; } | 202571 | json_parse_restart: |
| 196186 | if( (c = z[i])=='{' ){ | 202572 | switch( (u8)z[i] ){ |
| 202573 | case '{': { | ||
| 196187 | /* Parse object */ | 202574 | /* Parse object */ |
| 196188 | iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); | 202575 | iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); |
| 196189 | if( iThis<0 ) return -1; | 202576 | if( iThis<0 ) return -1; |
| 202577 | if( ++pParse->iDepth > JSON_MAX_DEPTH ){ | ||
| 202578 | pParse->iErr = i; | ||
| 202579 | return -1; | ||
| 202580 | } | ||
| 196190 | for(j=i+1;;j++){ | 202581 | for(j=i+1;;j++){ |
| 196191 | while( fast_isspace(z[j]) ){ j++; } | 202582 | u32 nNode = pParse->nNode; |
| 196192 | if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; | ||
| 196193 | x = jsonParseValue(pParse, j); | 202583 | x = jsonParseValue(pParse, j); |
| 196194 | if( x<0 ){ | 202584 | if( x<=0 ){ |
| 196195 | pParse->iDepth--; | 202585 | if( x==(-2) ){ |
| 196196 | if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; | 202586 | j = pParse->iErr; |
| 196197 | return -1; | 202587 | if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; |
| 202588 | break; | ||
| 202589 | } | ||
| 202590 | j += json5Whitespace(&z[j]); | ||
| 202591 | if( sqlite3JsonId1(z[j]) | ||
| 202592 | || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2])) | ||
| 202593 | ){ | ||
| 202594 | int k = j+1; | ||
| 202595 | while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) | ||
| 202596 | || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2])) | ||
| 202597 | ){ | ||
| 202598 | k++; | ||
| 202599 | } | ||
| 202600 | jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]); | ||
| 202601 | pParse->hasNonstd = 1; | ||
| 202602 | x = k; | ||
| 202603 | }else{ | ||
| 202604 | if( x!=-1 ) pParse->iErr = j; | ||
| 202605 | return -1; | ||
| 202606 | } | ||
| 196198 | } | 202607 | } |
| 196199 | if( pParse->oom ) return -1; | 202608 | if( pParse->oom ) return -1; |
| 196200 | pNode = &pParse->aNode[pParse->nNode-1]; | 202609 | pNode = &pParse->aNode[nNode]; |
| 196201 | if( pNode->eType!=JSON_STRING ) return -1; | 202610 | if( pNode->eType!=JSON_STRING ){ |
| 202611 | pParse->iErr = j; | ||
| 202612 | return -1; | ||
| 202613 | } | ||
| 196202 | pNode->jnFlags |= JNODE_LABEL; | 202614 | pNode->jnFlags |= JNODE_LABEL; |
| 196203 | j = x; | 202615 | j = x; |
| 196204 | while( fast_isspace(z[j]) ){ j++; } | 202616 | if( z[j]==':' ){ |
| 196205 | if( z[j]!=':' ) return -1; | 202617 | j++; |
| 196206 | j++; | 202618 | }else{ |
| 202619 | if( fast_isspace(z[j]) ){ | ||
| 202620 | do{ j++; }while( fast_isspace(z[j]) ); | ||
| 202621 | if( z[j]==':' ){ | ||
| 202622 | j++; | ||
| 202623 | goto parse_object_value; | ||
| 202624 | } | ||
| 202625 | } | ||
| 202626 | x = jsonParseValue(pParse, j); | ||
| 202627 | if( x!=(-5) ){ | ||
| 202628 | if( x!=(-1) ) pParse->iErr = j; | ||
| 202629 | return -1; | ||
| 202630 | } | ||
| 202631 | j = pParse->iErr+1; | ||
| 202632 | } | ||
| 202633 | parse_object_value: | ||
| 196207 | x = jsonParseValue(pParse, j); | 202634 | x = jsonParseValue(pParse, j); |
| 196208 | pParse->iDepth--; | 202635 | if( x<=0 ){ |
| 196209 | if( x<0 ) return -1; | 202636 | if( x!=(-1) ) pParse->iErr = j; |
| 202637 | return -1; | ||
| 202638 | } | ||
| 196210 | j = x; | 202639 | j = x; |
| 196211 | while( fast_isspace(z[j]) ){ j++; } | 202640 | if( z[j]==',' ){ |
| 196212 | c = z[j]; | 202641 | continue; |
| 196213 | if( c==',' ) continue; | 202642 | }else if( z[j]=='}' ){ |
| 196214 | if( c!='}' ) return -1; | 202643 | break; |
| 196215 | break; | 202644 | }else{ |
| 202645 | if( fast_isspace(z[j]) ){ | ||
| 202646 | do{ j++; }while( fast_isspace(z[j]) ); | ||
| 202647 | if( z[j]==',' ){ | ||
| 202648 | continue; | ||
| 202649 | }else if( z[j]=='}' ){ | ||
| 202650 | break; | ||
| 202651 | } | ||
| 202652 | } | ||
| 202653 | x = jsonParseValue(pParse, j); | ||
| 202654 | if( x==(-4) ){ | ||
| 202655 | j = pParse->iErr; | ||
| 202656 | continue; | ||
| 202657 | } | ||
| 202658 | if( x==(-2) ){ | ||
| 202659 | j = pParse->iErr; | ||
| 202660 | break; | ||
| 202661 | } | ||
| 202662 | } | ||
| 202663 | pParse->iErr = j; | ||
| 202664 | return -1; | ||
| 196216 | } | 202665 | } |
| 196217 | pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; | 202666 | pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; |
| 202667 | pParse->iDepth--; | ||
| 196218 | return j+1; | 202668 | return j+1; |
| 196219 | }else if( c=='[' ){ | 202669 | } |
| 202670 | case '[': { | ||
| 196220 | /* Parse array */ | 202671 | /* Parse array */ |
| 196221 | iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); | 202672 | iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); |
| 196222 | if( iThis<0 ) return -1; | 202673 | if( iThis<0 ) return -1; |
| 202674 | if( ++pParse->iDepth > JSON_MAX_DEPTH ){ | ||
| 202675 | pParse->iErr = i; | ||
| 202676 | return -1; | ||
| 202677 | } | ||
| 196223 | memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); | 202678 | memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); |
| 196224 | for(j=i+1;;j++){ | 202679 | for(j=i+1;;j++){ |
| 196225 | while( fast_isspace(z[j]) ){ j++; } | ||
| 196226 | if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; | ||
| 196227 | x = jsonParseValue(pParse, j); | 202680 | x = jsonParseValue(pParse, j); |
| 196228 | pParse->iDepth--; | 202681 | if( x<=0 ){ |
| 196229 | if( x<0 ){ | 202682 | if( x==(-3) ){ |
| 196230 | if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; | 202683 | j = pParse->iErr; |
| 202684 | if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; | ||
| 202685 | break; | ||
| 202686 | } | ||
| 202687 | if( x!=(-1) ) pParse->iErr = j; | ||
| 196231 | return -1; | 202688 | return -1; |
| 196232 | } | 202689 | } |
| 196233 | j = x; | 202690 | j = x; |
| 196234 | while( fast_isspace(z[j]) ){ j++; } | 202691 | if( z[j]==',' ){ |
| 196235 | c = z[j]; | 202692 | continue; |
| 196236 | if( c==',' ) continue; | 202693 | }else if( z[j]==']' ){ |
| 196237 | if( c!=']' ) return -1; | 202694 | break; |
| 196238 | break; | 202695 | }else{ |
| 202696 | if( fast_isspace(z[j]) ){ | ||
| 202697 | do{ j++; }while( fast_isspace(z[j]) ); | ||
| 202698 | if( z[j]==',' ){ | ||
| 202699 | continue; | ||
| 202700 | }else if( z[j]==']' ){ | ||
| 202701 | break; | ||
| 202702 | } | ||
| 202703 | } | ||
| 202704 | x = jsonParseValue(pParse, j); | ||
| 202705 | if( x==(-4) ){ | ||
| 202706 | j = pParse->iErr; | ||
| 202707 | continue; | ||
| 202708 | } | ||
| 202709 | if( x==(-3) ){ | ||
| 202710 | j = pParse->iErr; | ||
| 202711 | break; | ||
| 202712 | } | ||
| 202713 | } | ||
| 202714 | pParse->iErr = j; | ||
| 202715 | return -1; | ||
| 196239 | } | 202716 | } |
| 196240 | pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; | 202717 | pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; |
| 202718 | pParse->iDepth--; | ||
| 196241 | return j+1; | 202719 | return j+1; |
| 196242 | }else if( c=='"' ){ | 202720 | } |
| 202721 | case '\'': { | ||
| 202722 | u8 jnFlags; | ||
| 202723 | char cDelim; | ||
| 202724 | pParse->hasNonstd = 1; | ||
| 202725 | jnFlags = JNODE_JSON5; | ||
| 202726 | goto parse_string; | ||
| 202727 | case '"': | ||
| 196243 | /* Parse string */ | 202728 | /* Parse string */ |
| 196244 | u8 jnFlags = 0; | 202729 | jnFlags = 0; |
| 196245 | j = i+1; | 202730 | parse_string: |
| 196246 | for(;;){ | 202731 | cDelim = z[i]; |
| 202732 | for(j=i+1; 1; j++){ | ||
| 202733 | if( jsonIsOk[(unsigned char)z[j]] ) continue; | ||
| 196247 | c = z[j]; | 202734 | c = z[j]; |
| 196248 | if( (c & ~0x1f)==0 ){ | 202735 | if( c==cDelim ){ |
| 196249 | /* Control characters are not allowed in strings */ | 202736 | break; |
| 196250 | return -1; | 202737 | }else if( c=='\\' ){ |
| 196251 | } | ||
| 196252 | if( c=='\\' ){ | ||
| 196253 | c = z[++j]; | 202738 | c = z[++j]; |
| 196254 | if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' | 202739 | if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' |
| 196255 | || c=='n' || c=='r' || c=='t' | 202740 | || c=='n' || c=='r' || c=='t' |
| 196256 | || (c=='u' && jsonIs4Hex(z+j+1)) ){ | 202741 | || (c=='u' && jsonIs4Hex(&z[j+1])) ){ |
| 196257 | jnFlags = JNODE_ESCAPE; | 202742 | jnFlags |= JNODE_ESCAPE; |
| 202743 | }else if( c=='\'' || c=='0' || c=='v' || c=='\n' | ||
| 202744 | || (0xe2==(u8)c && 0x80==(u8)z[j+1] | ||
| 202745 | && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) | ||
| 202746 | || (c=='x' && jsonIs2Hex(&z[j+1])) ){ | ||
| 202747 | jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); | ||
| 202748 | pParse->hasNonstd = 1; | ||
| 202749 | }else if( c=='\r' ){ | ||
| 202750 | if( z[j+1]=='\n' ) j++; | ||
| 202751 | jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); | ||
| 202752 | pParse->hasNonstd = 1; | ||
| 196258 | }else{ | 202753 | }else{ |
| 202754 | pParse->iErr = j; | ||
| 196259 | return -1; | 202755 | return -1; |
| 196260 | } | 202756 | } |
| 196261 | }else if( c=='"' ){ | 202757 | }else if( c<=0x1f ){ |
| 196262 | break; | 202758 | /* Control characters are not allowed in strings */ |
| 202759 | pParse->iErr = j; | ||
| 202760 | return -1; | ||
| 196263 | } | 202761 | } |
| 196264 | j++; | ||
| 196265 | } | 202762 | } |
| 196266 | jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); | 202763 | jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]); |
| 196267 | if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; | ||
| 196268 | return j+1; | 202764 | return j+1; |
| 196269 | }else if( c=='n' | 202765 | } |
| 196270 | && strncmp(z+i,"null",4)==0 | 202766 | case 't': { |
| 196271 | && !sqlite3Isalnum(z[i+4]) ){ | 202767 | if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ |
| 196272 | jsonParseAddNode(pParse, JSON_NULL, 0, 0); | 202768 | jsonParseAddNode(pParse, JSON_TRUE, 0, 0); |
| 196273 | return i+4; | 202769 | return i+4; |
| 196274 | }else if( c=='t' | 202770 | } |
| 196275 | && strncmp(z+i,"true",4)==0 | 202771 | pParse->iErr = i; |
| 196276 | && !sqlite3Isalnum(z[i+4]) ){ | 202772 | return -1; |
| 196277 | jsonParseAddNode(pParse, JSON_TRUE, 0, 0); | 202773 | } |
| 196278 | return i+4; | 202774 | case 'f': { |
| 196279 | }else if( c=='f' | 202775 | if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ |
| 196280 | && strncmp(z+i,"false",5)==0 | 202776 | jsonParseAddNode(pParse, JSON_FALSE, 0, 0); |
| 196281 | && !sqlite3Isalnum(z[i+5]) ){ | 202777 | return i+5; |
| 196282 | jsonParseAddNode(pParse, JSON_FALSE, 0, 0); | 202778 | } |
| 196283 | return i+5; | 202779 | pParse->iErr = i; |
| 196284 | }else if( c=='-' || (c>='0' && c<='9') ){ | 202780 | return -1; |
| 202781 | } | ||
| 202782 | case '+': { | ||
| 202783 | u8 seenDP, seenE, jnFlags; | ||
| 202784 | pParse->hasNonstd = 1; | ||
| 202785 | jnFlags = JNODE_JSON5; | ||
| 202786 | goto parse_number; | ||
| 202787 | case '.': | ||
| 202788 | if( sqlite3Isdigit(z[i+1]) ){ | ||
| 202789 | pParse->hasNonstd = 1; | ||
| 202790 | jnFlags = JNODE_JSON5; | ||
| 202791 | seenE = 0; | ||
| 202792 | seenDP = JSON_REAL; | ||
| 202793 | goto parse_number_2; | ||
| 202794 | } | ||
| 202795 | pParse->iErr = i; | ||
| 202796 | return -1; | ||
| 202797 | case '-': | ||
| 202798 | case '0': | ||
| 202799 | case '1': | ||
| 202800 | case '2': | ||
| 202801 | case '3': | ||
| 202802 | case '4': | ||
| 202803 | case '5': | ||
| 202804 | case '6': | ||
| 202805 | case '7': | ||
| 202806 | case '8': | ||
| 202807 | case '9': | ||
| 196285 | /* Parse number */ | 202808 | /* Parse number */ |
| 196286 | u8 seenDP = 0; | 202809 | jnFlags = 0; |
| 196287 | u8 seenE = 0; | 202810 | parse_number: |
| 202811 | seenDP = JSON_INT; | ||
| 202812 | seenE = 0; | ||
| 196288 | assert( '-' < '0' ); | 202813 | assert( '-' < '0' ); |
| 202814 | assert( '+' < '0' ); | ||
| 202815 | assert( '.' < '0' ); | ||
| 202816 | c = z[i]; | ||
| 202817 | |||
| 196289 | if( c<='0' ){ | 202818 | if( c<='0' ){ |
| 196290 | j = c=='-' ? i+1 : i; | 202819 | if( c=='0' ){ |
| 196291 | if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; | 202820 | if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ |
| 202821 | assert( seenDP==JSON_INT ); | ||
| 202822 | pParse->hasNonstd = 1; | ||
| 202823 | jnFlags |= JNODE_JSON5; | ||
| 202824 | for(j=i+3; sqlite3Isxdigit(z[j]); j++){} | ||
| 202825 | goto parse_number_finish; | ||
| 202826 | }else if( sqlite3Isdigit(z[i+1]) ){ | ||
| 202827 | pParse->iErr = i+1; | ||
| 202828 | return -1; | ||
| 202829 | } | ||
| 202830 | }else{ | ||
| 202831 | if( !sqlite3Isdigit(z[i+1]) ){ | ||
| 202832 | /* JSON5 allows for "+Infinity" and "-Infinity" using exactly | ||
| 202833 | ** that case. SQLite also allows these in any case and it allows | ||
| 202834 | ** "+inf" and "-inf". */ | ||
| 202835 | if( (z[i+1]=='I' || z[i+1]=='i') | ||
| 202836 | && sqlite3StrNICmp(&z[i+1], "inf",3)==0 | ||
| 202837 | ){ | ||
| 202838 | pParse->hasNonstd = 1; | ||
| 202839 | if( z[i]=='-' ){ | ||
| 202840 | jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999"); | ||
| 202841 | }else{ | ||
| 202842 | jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999"); | ||
| 202843 | } | ||
| 202844 | return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); | ||
| 202845 | } | ||
| 202846 | if( z[i+1]=='.' ){ | ||
| 202847 | pParse->hasNonstd = 1; | ||
| 202848 | jnFlags |= JNODE_JSON5; | ||
| 202849 | goto parse_number_2; | ||
| 202850 | } | ||
| 202851 | pParse->iErr = i; | ||
| 202852 | return -1; | ||
| 202853 | } | ||
| 202854 | if( z[i+1]=='0' ){ | ||
| 202855 | if( sqlite3Isdigit(z[i+2]) ){ | ||
| 202856 | pParse->iErr = i+1; | ||
| 202857 | return -1; | ||
| 202858 | }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ | ||
| 202859 | pParse->hasNonstd = 1; | ||
| 202860 | jnFlags |= JNODE_JSON5; | ||
| 202861 | for(j=i+4; sqlite3Isxdigit(z[j]); j++){} | ||
| 202862 | goto parse_number_finish; | ||
| 202863 | } | ||
| 202864 | } | ||
| 202865 | } | ||
| 196292 | } | 202866 | } |
| 196293 | j = i+1; | 202867 | parse_number_2: |
| 196294 | for(;; j++){ | 202868 | for(j=i+1;; j++){ |
| 196295 | c = z[j]; | 202869 | c = z[j]; |
| 196296 | if( c>='0' && c<='9' ) continue; | 202870 | if( sqlite3Isdigit(c) ) continue; |
| 196297 | if( c=='.' ){ | 202871 | if( c=='.' ){ |
| 196298 | if( z[j-1]=='-' ) return -1; | 202872 | if( seenDP==JSON_REAL ){ |
| 196299 | if( seenDP ) return -1; | 202873 | pParse->iErr = j; |
| 196300 | seenDP = 1; | 202874 | return -1; |
| 202875 | } | ||
| 202876 | seenDP = JSON_REAL; | ||
| 196301 | continue; | 202877 | continue; |
| 196302 | } | 202878 | } |
| 196303 | if( c=='e' || c=='E' ){ | 202879 | if( c=='e' || c=='E' ){ |
| 196304 | if( z[j-1]<'0' ) return -1; | 202880 | if( z[j-1]<'0' ){ |
| 196305 | if( seenE ) return -1; | 202881 | if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ |
| 196306 | seenDP = seenE = 1; | 202882 | pParse->hasNonstd = 1; |
| 202883 | jnFlags |= JNODE_JSON5; | ||
| 202884 | }else{ | ||
| 202885 | pParse->iErr = j; | ||
| 202886 | return -1; | ||
| 202887 | } | ||
| 202888 | } | ||
| 202889 | if( seenE ){ | ||
| 202890 | pParse->iErr = j; | ||
| 202891 | return -1; | ||
| 202892 | } | ||
| 202893 | seenDP = JSON_REAL; | ||
| 202894 | seenE = 1; | ||
| 196307 | c = z[j+1]; | 202895 | c = z[j+1]; |
| 196308 | if( c=='+' || c=='-' ){ | 202896 | if( c=='+' || c=='-' ){ |
| 196309 | j++; | 202897 | j++; |
| 196310 | c = z[j+1]; | 202898 | c = z[j+1]; |
| 196311 | } | 202899 | } |
| 196312 | if( c<'0' || c>'9' ) return -1; | 202900 | if( c<'0' || c>'9' ){ |
| 202901 | pParse->iErr = j; | ||
| 202902 | return -1; | ||
| 202903 | } | ||
| 196313 | continue; | 202904 | continue; |
| 196314 | } | 202905 | } |
| 196315 | break; | 202906 | break; |
| 196316 | } | 202907 | } |
| 196317 | if( z[j-1]<'0' ) return -1; | 202908 | if( z[j-1]<'0' ){ |
| 196318 | jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, | 202909 | if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ |
| 196319 | j - i, &z[i]); | 202910 | pParse->hasNonstd = 1; |
| 202911 | jnFlags |= JNODE_JSON5; | ||
| 202912 | }else{ | ||
| 202913 | pParse->iErr = j; | ||
| 202914 | return -1; | ||
| 202915 | } | ||
| 202916 | } | ||
| 202917 | parse_number_finish: | ||
| 202918 | jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]); | ||
| 196320 | return j; | 202919 | return j; |
| 196321 | }else if( c=='}' ){ | 202920 | } |
| 202921 | case '}': { | ||
| 202922 | pParse->iErr = i; | ||
| 196322 | return -2; /* End of {...} */ | 202923 | return -2; /* End of {...} */ |
| 196323 | }else if( c==']' ){ | 202924 | } |
| 202925 | case ']': { | ||
| 202926 | pParse->iErr = i; | ||
| 196324 | return -3; /* End of [...] */ | 202927 | return -3; /* End of [...] */ |
| 196325 | }else if( c==0 ){ | 202928 | } |
| 202929 | case ',': { | ||
| 202930 | pParse->iErr = i; | ||
| 202931 | return -4; /* List separator */ | ||
| 202932 | } | ||
| 202933 | case ':': { | ||
| 202934 | pParse->iErr = i; | ||
| 202935 | return -5; /* Object label/value separator */ | ||
| 202936 | } | ||
| 202937 | case 0: { | ||
| 196326 | return 0; /* End of file */ | 202938 | return 0; /* End of file */ |
| 196327 | }else{ | 202939 | } |
| 202940 | case 0x09: | ||
| 202941 | case 0x0a: | ||
| 202942 | case 0x0d: | ||
| 202943 | case 0x20: { | ||
| 202944 | do{ | ||
| 202945 | i++; | ||
| 202946 | }while( fast_isspace(z[i]) ); | ||
| 202947 | goto json_parse_restart; | ||
| 202948 | } | ||
| 202949 | case 0x0b: | ||
| 202950 | case 0x0c: | ||
| 202951 | case '/': | ||
| 202952 | case 0xc2: | ||
| 202953 | case 0xe1: | ||
| 202954 | case 0xe2: | ||
| 202955 | case 0xe3: | ||
| 202956 | case 0xef: { | ||
| 202957 | j = json5Whitespace(&z[i]); | ||
| 202958 | if( j>0 ){ | ||
| 202959 | i += j; | ||
| 202960 | pParse->hasNonstd = 1; | ||
| 202961 | goto json_parse_restart; | ||
| 202962 | } | ||
| 202963 | pParse->iErr = i; | ||
| 202964 | return -1; | ||
| 202965 | } | ||
| 202966 | case 'n': { | ||
| 202967 | if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ | ||
| 202968 | jsonParseAddNode(pParse, JSON_NULL, 0, 0); | ||
| 202969 | return i+4; | ||
| 202970 | } | ||
| 202971 | /* fall-through into the default case that checks for NaN */ | ||
| 202972 | } | ||
| 202973 | default: { | ||
| 202974 | u32 k; | ||
| 202975 | int nn; | ||
| 202976 | c = z[i]; | ||
| 202977 | for(k=0; k<sizeof(aNanInfName)/sizeof(aNanInfName[0]); k++){ | ||
| 202978 | if( c!=aNanInfName[k].c1 && c!=aNanInfName[k].c2 ) continue; | ||
| 202979 | nn = aNanInfName[k].n; | ||
| 202980 | if( sqlite3StrNICmp(&z[i], aNanInfName[k].zMatch, nn)!=0 ){ | ||
| 202981 | continue; | ||
| 202982 | } | ||
| 202983 | if( sqlite3Isalnum(z[i+nn]) ) continue; | ||
| 202984 | jsonParseAddNode(pParse, aNanInfName[k].eType, | ||
| 202985 | aNanInfName[k].nRepl, aNanInfName[k].zRepl); | ||
| 202986 | pParse->hasNonstd = 1; | ||
| 202987 | return i + nn; | ||
| 202988 | } | ||
| 202989 | pParse->iErr = i; | ||
| 196328 | return -1; /* Syntax error */ | 202990 | return -1; /* Syntax error */ |
| 196329 | } | 202991 | } |
| 202992 | } /* End switch(z[i]) */ | ||
| 196330 | } | 202993 | } |
| 196331 | 202994 | ||
| 196332 | /* | 202995 | /* |
| 196333 | ** Parse a complete JSON string. Return 0 on success or non-zero if there | 202996 | ** Parse a complete JSON string. Return 0 on success or non-zero if there |
| 196334 | ** are any errors. If an error occurs, free all memory associated with | 202997 | ** are any errors. If an error occurs, free all memory held by pParse, |
| 196335 | ** pParse. | 202998 | ** but not pParse itself. |
| 196336 | ** | 202999 | ** |
| 196337 | ** pParse is uninitialized when this routine is called. | 203000 | ** pParse must be initialized to an empty parse object prior to calling |
| 203001 | ** this routine. | ||
| 196338 | */ | 203002 | */ |
| 196339 | static int jsonParse( | 203003 | static int jsonParse( |
| 196340 | JsonParse *pParse, /* Initialize and fill this JsonParse object */ | 203004 | JsonParse *pParse, /* Initialize and fill this JsonParse object */ |
| 196341 | sqlite3_context *pCtx, /* Report errors here */ | 203005 | sqlite3_context *pCtx /* Report errors here */ |
| 196342 | const char *zJson /* Input JSON text to be parsed */ | ||
| 196343 | ){ | 203006 | ){ |
| 196344 | int i; | 203007 | int i; |
| 196345 | memset(pParse, 0, sizeof(*pParse)); | 203008 | const char *zJson = pParse->zJson; |
| 196346 | if( zJson==0 ) return 1; | ||
| 196347 | pParse->zJson = zJson; | ||
| 196348 | i = jsonParseValue(pParse, 0); | 203009 | i = jsonParseValue(pParse, 0); |
| 196349 | if( pParse->oom ) i = -1; | 203010 | if( pParse->oom ) i = -1; |
| 196350 | if( i>0 ){ | 203011 | if( i>0 ){ |
| 196351 | assert( pParse->iDepth==0 ); | 203012 | assert( pParse->iDepth==0 ); |
| 196352 | while( fast_isspace(zJson[i]) ) i++; | 203013 | while( fast_isspace(zJson[i]) ) i++; |
| 196353 | if( zJson[i] ) i = -1; | 203014 | if( zJson[i] ){ |
| 203015 | i += json5Whitespace(&zJson[i]); | ||
| 203016 | if( zJson[i] ){ | ||
| 203017 | jsonParseReset(pParse); | ||
| 203018 | return 1; | ||
| 203019 | } | ||
| 203020 | pParse->hasNonstd = 1; | ||
| 203021 | } | ||
| 196354 | } | 203022 | } |
| 196355 | if( i<=0 ){ | 203023 | if( i<=0 ){ |
| 196356 | if( pCtx!=0 ){ | 203024 | if( pCtx!=0 ){ |
| @@ -196366,6 +203034,7 @@ static int jsonParse( | |||
| 196366 | return 0; | 203034 | return 0; |
| 196367 | } | 203035 | } |
| 196368 | 203036 | ||
| 203037 | |||
| 196369 | /* Mark node i of pParse as being a child of iParent. Call recursively | 203038 | /* Mark node i of pParse as being a child of iParent. Call recursively |
| 196370 | ** to fill in all the descendants of node i. | 203039 | ** to fill in all the descendants of node i. |
| 196371 | */ | 203040 | */ |
| @@ -196415,26 +203084,49 @@ static int jsonParseFindParents(JsonParse *pParse){ | |||
| 196415 | #define JSON_CACHE_SZ 4 /* Max number of cache entries */ | 203084 | #define JSON_CACHE_SZ 4 /* Max number of cache entries */ |
| 196416 | 203085 | ||
| 196417 | /* | 203086 | /* |
| 196418 | ** Obtain a complete parse of the JSON found in the first argument | 203087 | ** Obtain a complete parse of the JSON found in the pJson argument |
| 196419 | ** of the argv array. Use the sqlite3_get_auxdata() cache for this | 203088 | ** |
| 196420 | ** parse if it is available. If the cache is not available or if it | 203089 | ** Use the sqlite3_get_auxdata() cache to find a preexisting parse |
| 196421 | ** is no longer valid, parse the JSON again and return the new parse, | 203090 | ** if it is available. If the cache is not available or if it |
| 196422 | ** and also register the new parse so that it will be available for | 203091 | ** is no longer valid, parse the JSON again and return the new parse. |
| 203092 | ** Also register the new parse so that it will be available for | ||
| 196423 | ** future sqlite3_get_auxdata() calls. | 203093 | ** future sqlite3_get_auxdata() calls. |
| 203094 | ** | ||
| 203095 | ** If an error occurs and pErrCtx!=0 then report the error on pErrCtx | ||
| 203096 | ** and return NULL. | ||
| 203097 | ** | ||
| 203098 | ** The returned pointer (if it is not NULL) is owned by the cache in | ||
| 203099 | ** most cases, not the caller. The caller does NOT need to invoke | ||
| 203100 | ** jsonParseFree(), in most cases. | ||
| 203101 | ** | ||
| 203102 | ** Except, if an error occurs and pErrCtx==0 then return the JsonParse | ||
| 203103 | ** object with JsonParse.nErr non-zero and the caller will own the JsonParse | ||
| 203104 | ** object. In that case, it will be the responsibility of the caller to | ||
| 203105 | ** invoke jsonParseFree(). To summarize: | ||
| 203106 | ** | ||
| 203107 | ** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the | ||
| 203108 | ** cache. Call does not need to | ||
| 203109 | ** free it. | ||
| 203110 | ** | ||
| 203111 | ** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller | ||
| 203112 | ** and so the caller must free it. | ||
| 196424 | */ | 203113 | */ |
| 196425 | static JsonParse *jsonParseCached( | 203114 | static JsonParse *jsonParseCached( |
| 196426 | sqlite3_context *pCtx, | 203115 | sqlite3_context *pCtx, /* Context to use for cache search */ |
| 196427 | sqlite3_value **argv, | 203116 | sqlite3_value *pJson, /* Function param containing JSON text */ |
| 196428 | sqlite3_context *pErrCtx | 203117 | sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */ |
| 203118 | int bUnedited /* No prior edits allowed */ | ||
| 196429 | ){ | 203119 | ){ |
| 196430 | const char *zJson = (const char*)sqlite3_value_text(argv[0]); | 203120 | char *zJson = (char*)sqlite3_value_text(pJson); |
| 196431 | int nJson = sqlite3_value_bytes(argv[0]); | 203121 | int nJson = sqlite3_value_bytes(pJson); |
| 196432 | JsonParse *p; | 203122 | JsonParse *p; |
| 196433 | JsonParse *pMatch = 0; | 203123 | JsonParse *pMatch = 0; |
| 196434 | int iKey; | 203124 | int iKey; |
| 196435 | int iMinKey = 0; | 203125 | int iMinKey = 0; |
| 196436 | u32 iMinHold = 0xffffffff; | 203126 | u32 iMinHold = 0xffffffff; |
| 196437 | u32 iMaxHold = 0; | 203127 | u32 iMaxHold = 0; |
| 203128 | int bJsonRCStr; | ||
| 203129 | |||
| 196438 | if( zJson==0 ) return 0; | 203130 | if( zJson==0 ) return 0; |
| 196439 | for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){ | 203131 | for(iKey=0; iKey<JSON_CACHE_SZ; iKey++){ |
| 196440 | p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey); | 203132 | p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iKey); |
| @@ -196444,9 +203136,21 @@ static JsonParse *jsonParseCached( | |||
| 196444 | } | 203136 | } |
| 196445 | if( pMatch==0 | 203137 | if( pMatch==0 |
| 196446 | && p->nJson==nJson | 203138 | && p->nJson==nJson |
| 196447 | && memcmp(p->zJson,zJson,nJson)==0 | 203139 | && (p->hasMod==0 || bUnedited==0) |
| 203140 | && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0) | ||
| 203141 | ){ | ||
| 203142 | p->nErr = 0; | ||
| 203143 | p->useMod = 0; | ||
| 203144 | pMatch = p; | ||
| 203145 | }else | ||
| 203146 | if( pMatch==0 | ||
| 203147 | && p->zAlt!=0 | ||
| 203148 | && bUnedited==0 | ||
| 203149 | && p->nAlt==nJson | ||
| 203150 | && memcmp(p->zAlt, zJson, nJson)==0 | ||
| 196448 | ){ | 203151 | ){ |
| 196449 | p->nErr = 0; | 203152 | p->nErr = 0; |
| 203153 | p->useMod = 1; | ||
| 196450 | pMatch = p; | 203154 | pMatch = p; |
| 196451 | }else if( p->iHold<iMinHold ){ | 203155 | }else if( p->iHold<iMinHold ){ |
| 196452 | iMinHold = p->iHold; | 203156 | iMinHold = p->iHold; |
| @@ -196457,24 +203161,44 @@ static JsonParse *jsonParseCached( | |||
| 196457 | } | 203161 | } |
| 196458 | } | 203162 | } |
| 196459 | if( pMatch ){ | 203163 | if( pMatch ){ |
| 203164 | /* The input JSON text was found in the cache. Use the preexisting | ||
| 203165 | ** parse of this JSON */ | ||
| 196460 | pMatch->nErr = 0; | 203166 | pMatch->nErr = 0; |
| 196461 | pMatch->iHold = iMaxHold+1; | 203167 | pMatch->iHold = iMaxHold+1; |
| 203168 | assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */ | ||
| 196462 | return pMatch; | 203169 | return pMatch; |
| 196463 | } | 203170 | } |
| 196464 | p = sqlite3_malloc64( sizeof(*p) + nJson + 1 ); | 203171 | |
| 203172 | /* The input JSON was not found anywhere in the cache. We will need | ||
| 203173 | ** to parse it ourselves and generate a new JsonParse object. | ||
| 203174 | */ | ||
| 203175 | bJsonRCStr = sqlite3ValueIsOfClass(pJson,(void(*)(void*))sqlite3RCStrUnref); | ||
| 203176 | p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); | ||
| 196465 | if( p==0 ){ | 203177 | if( p==0 ){ |
| 196466 | sqlite3_result_error_nomem(pCtx); | 203178 | sqlite3_result_error_nomem(pCtx); |
| 196467 | return 0; | 203179 | return 0; |
| 196468 | } | 203180 | } |
| 196469 | memset(p, 0, sizeof(*p)); | 203181 | memset(p, 0, sizeof(*p)); |
| 196470 | p->zJson = (char*)&p[1]; | 203182 | if( bJsonRCStr ){ |
| 196471 | memcpy((char*)p->zJson, zJson, nJson+1); | 203183 | p->zJson = sqlite3RCStrRef(zJson); |
| 196472 | if( jsonParse(p, pErrCtx, p->zJson) ){ | 203184 | p->bJsonIsRCStr = 1; |
| 196473 | sqlite3_free(p); | 203185 | }else{ |
| 203186 | p->zJson = (char*)&p[1]; | ||
| 203187 | memcpy(p->zJson, zJson, nJson+1); | ||
| 203188 | } | ||
| 203189 | p->nJPRef = 1; | ||
| 203190 | if( jsonParse(p, pErrCtx) ){ | ||
| 203191 | if( pErrCtx==0 ){ | ||
| 203192 | p->nErr = 1; | ||
| 203193 | assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */ | ||
| 203194 | return p; | ||
| 203195 | } | ||
| 203196 | jsonParseFree(p); | ||
| 196474 | return 0; | 203197 | return 0; |
| 196475 | } | 203198 | } |
| 196476 | p->nJson = nJson; | 203199 | p->nJson = nJson; |
| 196477 | p->iHold = iMaxHold+1; | 203200 | p->iHold = iMaxHold+1; |
| 203201 | /* Transfer ownership of the new JsonParse to the cache */ | ||
| 196478 | sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, | 203202 | sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, |
| 196479 | (void(*)(void*))jsonParseFree); | 203203 | (void(*)(void*))jsonParseFree); |
| 196480 | return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); | 203204 | return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); |
| @@ -196484,7 +203208,7 @@ static JsonParse *jsonParseCached( | |||
| 196484 | ** Compare the OBJECT label at pNode against zKey,nKey. Return true on | 203208 | ** Compare the OBJECT label at pNode against zKey,nKey. Return true on |
| 196485 | ** a match. | 203209 | ** a match. |
| 196486 | */ | 203210 | */ |
| 196487 | static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ | 203211 | static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){ |
| 196488 | assert( pNode->eU==1 ); | 203212 | assert( pNode->eU==1 ); |
| 196489 | if( pNode->jnFlags & JNODE_RAW ){ | 203213 | if( pNode->jnFlags & JNODE_RAW ){ |
| 196490 | if( pNode->n!=nKey ) return 0; | 203214 | if( pNode->n!=nKey ) return 0; |
| @@ -196494,6 +203218,15 @@ static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ | |||
| 196494 | return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; | 203218 | return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; |
| 196495 | } | 203219 | } |
| 196496 | } | 203220 | } |
| 203221 | static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){ | ||
| 203222 | if( p1->jnFlags & JNODE_RAW ){ | ||
| 203223 | return jsonLabelCompare(p2, p1->u.zJContent, p1->n); | ||
| 203224 | }else if( p2->jnFlags & JNODE_RAW ){ | ||
| 203225 | return jsonLabelCompare(p1, p2->u.zJContent, p2->n); | ||
| 203226 | }else{ | ||
| 203227 | return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0; | ||
| 203228 | } | ||
| 203229 | } | ||
| 196497 | 203230 | ||
| 196498 | /* forward declaration */ | 203231 | /* forward declaration */ |
| 196499 | static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); | 203232 | static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); |
| @@ -196516,9 +203249,31 @@ static JsonNode *jsonLookupStep( | |||
| 196516 | ){ | 203249 | ){ |
| 196517 | u32 i, j, nKey; | 203250 | u32 i, j, nKey; |
| 196518 | const char *zKey; | 203251 | const char *zKey; |
| 196519 | JsonNode *pRoot = &pParse->aNode[iRoot]; | 203252 | JsonNode *pRoot; |
| 203253 | if( pParse->oom ) return 0; | ||
| 203254 | pRoot = &pParse->aNode[iRoot]; | ||
| 203255 | if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){ | ||
| 203256 | while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){ | ||
| 203257 | u32 idx = (u32)(pRoot - pParse->aNode); | ||
| 203258 | i = pParse->iSubst; | ||
| 203259 | while( 1 /*exit-by-break*/ ){ | ||
| 203260 | assert( i<pParse->nNode ); | ||
| 203261 | assert( pParse->aNode[i].eType==JSON_SUBST ); | ||
| 203262 | assert( pParse->aNode[i].eU==4 ); | ||
| 203263 | assert( pParse->aNode[i].u.iPrev<i ); | ||
| 203264 | if( pParse->aNode[i].n==idx ){ | ||
| 203265 | pRoot = &pParse->aNode[i+1]; | ||
| 203266 | iRoot = i+1; | ||
| 203267 | break; | ||
| 203268 | } | ||
| 203269 | i = pParse->aNode[i].u.iPrev; | ||
| 203270 | } | ||
| 203271 | } | ||
| 203272 | if( pRoot->jnFlags & JNODE_REMOVE ){ | ||
| 203273 | return 0; | ||
| 203274 | } | ||
| 203275 | } | ||
| 196520 | if( zPath[0]==0 ) return pRoot; | 203276 | if( zPath[0]==0 ) return pRoot; |
| 196521 | if( pRoot->jnFlags & JNODE_REPLACE ) return 0; | ||
| 196522 | if( zPath[0]=='.' ){ | 203277 | if( zPath[0]=='.' ){ |
| 196523 | if( pRoot->eType!=JSON_OBJECT ) return 0; | 203278 | if( pRoot->eType!=JSON_OBJECT ) return 0; |
| 196524 | zPath++; | 203279 | zPath++; |
| @@ -196552,14 +203307,16 @@ static JsonNode *jsonLookupStep( | |||
| 196552 | j += jsonNodeSize(&pRoot[j]); | 203307 | j += jsonNodeSize(&pRoot[j]); |
| 196553 | } | 203308 | } |
| 196554 | if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; | 203309 | if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; |
| 203310 | if( pParse->useMod==0 ) break; | ||
| 196555 | assert( pRoot->eU==2 ); | 203311 | assert( pRoot->eU==2 ); |
| 196556 | iRoot += pRoot->u.iAppend; | 203312 | iRoot = pRoot->u.iAppend; |
| 196557 | pRoot = &pParse->aNode[iRoot]; | 203313 | pRoot = &pParse->aNode[iRoot]; |
| 196558 | j = 1; | 203314 | j = 1; |
| 196559 | } | 203315 | } |
| 196560 | if( pApnd ){ | 203316 | if( pApnd ){ |
| 196561 | u32 iStart, iLabel; | 203317 | u32 iStart, iLabel; |
| 196562 | JsonNode *pNode; | 203318 | JsonNode *pNode; |
| 203319 | assert( pParse->useMod ); | ||
| 196563 | iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); | 203320 | iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); |
| 196564 | iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); | 203321 | iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); |
| 196565 | zPath += i; | 203322 | zPath += i; |
| @@ -196568,7 +203325,7 @@ static JsonNode *jsonLookupStep( | |||
| 196568 | if( pNode ){ | 203325 | if( pNode ){ |
| 196569 | pRoot = &pParse->aNode[iRoot]; | 203326 | pRoot = &pParse->aNode[iRoot]; |
| 196570 | assert( pRoot->eU==0 ); | 203327 | assert( pRoot->eU==0 ); |
| 196571 | pRoot->u.iAppend = iStart - iRoot; | 203328 | pRoot->u.iAppend = iStart; |
| 196572 | pRoot->jnFlags |= JNODE_APPEND; | 203329 | pRoot->jnFlags |= JNODE_APPEND; |
| 196573 | VVA( pRoot->eU = 2 ); | 203330 | VVA( pRoot->eU = 2 ); |
| 196574 | pParse->aNode[iLabel].jnFlags |= JNODE_RAW; | 203331 | pParse->aNode[iLabel].jnFlags |= JNODE_RAW; |
| @@ -196589,12 +203346,13 @@ static JsonNode *jsonLookupStep( | |||
| 196589 | if( pRoot->eType!=JSON_ARRAY ) return 0; | 203346 | if( pRoot->eType!=JSON_ARRAY ) return 0; |
| 196590 | for(;;){ | 203347 | for(;;){ |
| 196591 | while( j<=pBase->n ){ | 203348 | while( j<=pBase->n ){ |
| 196592 | if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++; | 203349 | if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++; |
| 196593 | j += jsonNodeSize(&pBase[j]); | 203350 | j += jsonNodeSize(&pBase[j]); |
| 196594 | } | 203351 | } |
| 196595 | if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; | 203352 | if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; |
| 203353 | if( pParse->useMod==0 ) break; | ||
| 196596 | assert( pBase->eU==2 ); | 203354 | assert( pBase->eU==2 ); |
| 196597 | iBase += pBase->u.iAppend; | 203355 | iBase = pBase->u.iAppend; |
| 196598 | pBase = &pParse->aNode[iBase]; | 203356 | pBase = &pParse->aNode[iBase]; |
| 196599 | j = 1; | 203357 | j = 1; |
| 196600 | } | 203358 | } |
| @@ -196622,13 +203380,16 @@ static JsonNode *jsonLookupStep( | |||
| 196622 | zPath += j + 1; | 203380 | zPath += j + 1; |
| 196623 | j = 1; | 203381 | j = 1; |
| 196624 | for(;;){ | 203382 | for(;;){ |
| 196625 | while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ | 203383 | while( j<=pRoot->n |
| 196626 | if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; | 203384 | && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod)) |
| 203385 | ){ | ||
| 203386 | if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; | ||
| 196627 | j += jsonNodeSize(&pRoot[j]); | 203387 | j += jsonNodeSize(&pRoot[j]); |
| 196628 | } | 203388 | } |
| 196629 | if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; | 203389 | if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; |
| 203390 | if( pParse->useMod==0 ) break; | ||
| 196630 | assert( pRoot->eU==2 ); | 203391 | assert( pRoot->eU==2 ); |
| 196631 | iRoot += pRoot->u.iAppend; | 203392 | iRoot = pRoot->u.iAppend; |
| 196632 | pRoot = &pParse->aNode[iRoot]; | 203393 | pRoot = &pParse->aNode[iRoot]; |
| 196633 | j = 1; | 203394 | j = 1; |
| 196634 | } | 203395 | } |
| @@ -196638,13 +203399,14 @@ static JsonNode *jsonLookupStep( | |||
| 196638 | if( i==0 && pApnd ){ | 203399 | if( i==0 && pApnd ){ |
| 196639 | u32 iStart; | 203400 | u32 iStart; |
| 196640 | JsonNode *pNode; | 203401 | JsonNode *pNode; |
| 203402 | assert( pParse->useMod ); | ||
| 196641 | iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); | 203403 | iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); |
| 196642 | pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); | 203404 | pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); |
| 196643 | if( pParse->oom ) return 0; | 203405 | if( pParse->oom ) return 0; |
| 196644 | if( pNode ){ | 203406 | if( pNode ){ |
| 196645 | pRoot = &pParse->aNode[iRoot]; | 203407 | pRoot = &pParse->aNode[iRoot]; |
| 196646 | assert( pRoot->eU==0 ); | 203408 | assert( pRoot->eU==0 ); |
| 196647 | pRoot->u.iAppend = iStart - iRoot; | 203409 | pRoot->u.iAppend = iStart; |
| 196648 | pRoot->jnFlags |= JNODE_APPEND; | 203410 | pRoot->jnFlags |= JNODE_APPEND; |
| 196649 | VVA( pRoot->eU = 2 ); | 203411 | VVA( pRoot->eU = 2 ); |
| 196650 | } | 203412 | } |
| @@ -196771,47 +203533,90 @@ static void jsonRemoveAllNulls(JsonNode *pNode){ | |||
| 196771 | ** SQL functions used for testing and debugging | 203533 | ** SQL functions used for testing and debugging |
| 196772 | ****************************************************************************/ | 203534 | ****************************************************************************/ |
| 196773 | 203535 | ||
| 203536 | #if SQLITE_DEBUG | ||
| 203537 | /* | ||
| 203538 | ** Print N node entries. | ||
| 203539 | */ | ||
| 203540 | static void jsonDebugPrintNodeEntries( | ||
| 203541 | JsonNode *aNode, /* First node entry to print */ | ||
| 203542 | int N /* Number of node entries to print */ | ||
| 203543 | ){ | ||
| 203544 | int i; | ||
| 203545 | for(i=0; i<N; i++){ | ||
| 203546 | const char *zType; | ||
| 203547 | if( aNode[i].jnFlags & JNODE_LABEL ){ | ||
| 203548 | zType = "label"; | ||
| 203549 | }else{ | ||
| 203550 | zType = jsonType[aNode[i].eType]; | ||
| 203551 | } | ||
| 203552 | printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n); | ||
| 203553 | if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){ | ||
| 203554 | u8 f = aNode[i].jnFlags; | ||
| 203555 | if( f & JNODE_RAW ) printf(" RAW"); | ||
| 203556 | if( f & JNODE_ESCAPE ) printf(" ESCAPE"); | ||
| 203557 | if( f & JNODE_REMOVE ) printf(" REMOVE"); | ||
| 203558 | if( f & JNODE_REPLACE ) printf(" REPLACE"); | ||
| 203559 | if( f & JNODE_APPEND ) printf(" APPEND"); | ||
| 203560 | if( f & JNODE_JSON5 ) printf(" JSON5"); | ||
| 203561 | } | ||
| 203562 | switch( aNode[i].eU ){ | ||
| 203563 | case 1: printf(" zJContent=[%.*s]\n", | ||
| 203564 | aNode[i].n, aNode[i].u.zJContent); break; | ||
| 203565 | case 2: printf(" iAppend=%u\n", aNode[i].u.iAppend); break; | ||
| 203566 | case 3: printf(" iKey=%u\n", aNode[i].u.iKey); break; | ||
| 203567 | case 4: printf(" iPrev=%u\n", aNode[i].u.iPrev); break; | ||
| 203568 | default: printf("\n"); | ||
| 203569 | } | ||
| 203570 | } | ||
| 203571 | } | ||
| 203572 | #endif /* SQLITE_DEBUG */ | ||
| 203573 | |||
| 203574 | |||
| 203575 | #if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */ | ||
| 203576 | static void jsonDebugPrintParse(JsonParse *p){ | ||
| 203577 | jsonDebugPrintNodeEntries(p->aNode, p->nNode); | ||
| 203578 | } | ||
| 203579 | static void jsonDebugPrintNode(JsonNode *pNode){ | ||
| 203580 | jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode)); | ||
| 203581 | } | ||
| 203582 | #else | ||
| 203583 | /* The usual case */ | ||
| 203584 | # define jsonDebugPrintNode(X) | ||
| 203585 | # define jsonDebugPrintParse(X) | ||
| 203586 | #endif | ||
| 203587 | |||
| 196774 | #ifdef SQLITE_DEBUG | 203588 | #ifdef SQLITE_DEBUG |
| 196775 | /* | 203589 | /* |
| 196776 | ** The json_parse(JSON) function returns a string which describes | 203590 | ** SQL function: json_parse(JSON) |
| 196777 | ** a parse of the JSON provided. Or it returns NULL if JSON is not | 203591 | ** |
| 196778 | ** well-formed. | 203592 | ** Parse JSON using jsonParseCached(). Then print a dump of that |
| 203593 | ** parse on standard output. Return the mimified JSON result, just | ||
| 203594 | ** like the json() function. | ||
| 196779 | */ | 203595 | */ |
| 196780 | static void jsonParseFunc( | 203596 | static void jsonParseFunc( |
| 196781 | sqlite3_context *ctx, | 203597 | sqlite3_context *ctx, |
| 196782 | int argc, | 203598 | int argc, |
| 196783 | sqlite3_value **argv | 203599 | sqlite3_value **argv |
| 196784 | ){ | 203600 | ){ |
| 196785 | JsonString s; /* Output string - not real JSON */ | 203601 | JsonParse *p; /* The parse */ |
| 196786 | JsonParse x; /* The parse */ | ||
| 196787 | u32 i; | ||
| 196788 | 203602 | ||
| 196789 | assert( argc==1 ); | 203603 | assert( argc==1 ); |
| 196790 | if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; | 203604 | p = jsonParseCached(ctx, argv[0], ctx, 0); |
| 196791 | jsonParseFindParents(&x); | 203605 | if( p==0 ) return; |
| 196792 | jsonInit(&s, ctx); | 203606 | printf("nNode = %u\n", p->nNode); |
| 196793 | for(i=0; i<x.nNode; i++){ | 203607 | printf("nAlloc = %u\n", p->nAlloc); |
| 196794 | const char *zType; | 203608 | printf("nJson = %d\n", p->nJson); |
| 196795 | if( x.aNode[i].jnFlags & JNODE_LABEL ){ | 203609 | printf("nAlt = %d\n", p->nAlt); |
| 196796 | assert( x.aNode[i].eType==JSON_STRING ); | 203610 | printf("nErr = %u\n", p->nErr); |
| 196797 | zType = "label"; | 203611 | printf("oom = %u\n", p->oom); |
| 196798 | }else{ | 203612 | printf("hasNonstd = %u\n", p->hasNonstd); |
| 196799 | zType = jsonType[x.aNode[i].eType]; | 203613 | printf("useMod = %u\n", p->useMod); |
| 196800 | } | 203614 | printf("hasMod = %u\n", p->hasMod); |
| 196801 | jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d", | 203615 | printf("nJPRef = %u\n", p->nJPRef); |
| 196802 | i, zType, x.aNode[i].n, x.aUp[i]); | 203616 | printf("iSubst = %u\n", p->iSubst); |
| 196803 | assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 ); | 203617 | printf("iHold = %u\n", p->iHold); |
| 196804 | if( x.aNode[i].u.zJContent!=0 ){ | 203618 | jsonDebugPrintNodeEntries(p->aNode, p->nNode); |
| 196805 | assert( x.aNode[i].eU==1 ); | 203619 | jsonReturnJson(p, p->aNode, ctx, 1); |
| 196806 | jsonAppendRaw(&s, " ", 1); | ||
| 196807 | jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n); | ||
| 196808 | }else{ | ||
| 196809 | assert( x.aNode[i].eU==0 ); | ||
| 196810 | } | ||
| 196811 | jsonAppendRaw(&s, "\n", 1); | ||
| 196812 | } | ||
| 196813 | jsonParseReset(&x); | ||
| 196814 | jsonResult(&s); | ||
| 196815 | } | 203620 | } |
| 196816 | 203621 | ||
| 196817 | /* | 203622 | /* |
| @@ -196895,7 +203700,7 @@ static void jsonArrayLengthFunc( | |||
| 196895 | u32 i; | 203700 | u32 i; |
| 196896 | JsonNode *pNode; | 203701 | JsonNode *pNode; |
| 196897 | 203702 | ||
| 196898 | p = jsonParseCached(ctx, argv, ctx); | 203703 | p = jsonParseCached(ctx, argv[0], ctx, 0); |
| 196899 | if( p==0 ) return; | 203704 | if( p==0 ) return; |
| 196900 | assert( p->nNode ); | 203705 | assert( p->nNode ); |
| 196901 | if( argc==2 ){ | 203706 | if( argc==2 ){ |
| @@ -196908,9 +203713,14 @@ static void jsonArrayLengthFunc( | |||
| 196908 | return; | 203713 | return; |
| 196909 | } | 203714 | } |
| 196910 | if( pNode->eType==JSON_ARRAY ){ | 203715 | if( pNode->eType==JSON_ARRAY ){ |
| 196911 | assert( (pNode->jnFlags & JNODE_APPEND)==0 ); | 203716 | while( 1 /*exit-by-break*/ ){ |
| 196912 | for(i=1; i<=pNode->n; n++){ | 203717 | for(i=1; i<=pNode->n; n++){ |
| 196913 | i += jsonNodeSize(&pNode[i]); | 203718 | i += jsonNodeSize(&pNode[i]); |
| 203719 | } | ||
| 203720 | if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; | ||
| 203721 | if( p->useMod==0 ) break; | ||
| 203722 | assert( pNode->eU==2 ); | ||
| 203723 | pNode = &p->aNode[pNode->u.iAppend]; | ||
| 196914 | } | 203724 | } |
| 196915 | } | 203725 | } |
| 196916 | sqlite3_result_int64(ctx, n); | 203726 | sqlite3_result_int64(ctx, n); |
| @@ -196957,14 +203767,14 @@ static void jsonExtractFunc( | |||
| 196957 | JsonString jx; | 203767 | JsonString jx; |
| 196958 | 203768 | ||
| 196959 | if( argc<2 ) return; | 203769 | if( argc<2 ) return; |
| 196960 | p = jsonParseCached(ctx, argv, ctx); | 203770 | p = jsonParseCached(ctx, argv[0], ctx, 0); |
| 196961 | if( p==0 ) return; | 203771 | if( p==0 ) return; |
| 196962 | if( argc==2 ){ | 203772 | if( argc==2 ){ |
| 196963 | /* With a single PATH argument */ | 203773 | /* With a single PATH argument */ |
| 196964 | zPath = (const char*)sqlite3_value_text(argv[1]); | 203774 | zPath = (const char*)sqlite3_value_text(argv[1]); |
| 196965 | if( zPath==0 ) return; | 203775 | if( zPath==0 ) return; |
| 196966 | if( flags & JSON_ABPATH ){ | 203776 | if( flags & JSON_ABPATH ){ |
| 196967 | if( zPath[0]!='$' ){ | 203777 | if( zPath[0]!='$' || (zPath[1]!='.' && zPath[1]!='[' && zPath[1]!=0) ){ |
| 196968 | /* The -> and ->> operators accept abbreviated PATH arguments. This | 203778 | /* The -> and ->> operators accept abbreviated PATH arguments. This |
| 196969 | ** is mostly for compatibility with PostgreSQL, but also for | 203779 | ** is mostly for compatibility with PostgreSQL, but also for |
| 196970 | ** convenience. | 203780 | ** convenience. |
| @@ -196975,11 +203785,11 @@ static void jsonExtractFunc( | |||
| 196975 | */ | 203785 | */ |
| 196976 | jsonInit(&jx, ctx); | 203786 | jsonInit(&jx, ctx); |
| 196977 | if( sqlite3Isdigit(zPath[0]) ){ | 203787 | if( sqlite3Isdigit(zPath[0]) ){ |
| 196978 | jsonAppendRaw(&jx, "$[", 2); | 203788 | jsonAppendRawNZ(&jx, "$[", 2); |
| 196979 | jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); | 203789 | jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); |
| 196980 | jsonAppendRaw(&jx, "]", 2); | 203790 | jsonAppendRawNZ(&jx, "]", 2); |
| 196981 | }else{ | 203791 | }else{ |
| 196982 | jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='[')); | 203792 | jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='[')); |
| 196983 | jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); | 203793 | jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); |
| 196984 | jsonAppendChar(&jx, 0); | 203794 | jsonAppendChar(&jx, 0); |
| 196985 | } | 203795 | } |
| @@ -196990,15 +203800,15 @@ static void jsonExtractFunc( | |||
| 196990 | } | 203800 | } |
| 196991 | if( pNode ){ | 203801 | if( pNode ){ |
| 196992 | if( flags & JSON_JSON ){ | 203802 | if( flags & JSON_JSON ){ |
| 196993 | jsonReturnJson(pNode, ctx, 0); | 203803 | jsonReturnJson(p, pNode, ctx, 0); |
| 196994 | }else{ | 203804 | }else{ |
| 196995 | jsonReturn(pNode, ctx, 0); | 203805 | jsonReturn(p, pNode, ctx); |
| 196996 | sqlite3_result_subtype(ctx, 0); | 203806 | sqlite3_result_subtype(ctx, 0); |
| 196997 | } | 203807 | } |
| 196998 | } | 203808 | } |
| 196999 | }else{ | 203809 | }else{ |
| 197000 | pNode = jsonLookup(p, zPath, 0, ctx); | 203810 | pNode = jsonLookup(p, zPath, 0, ctx); |
| 197001 | if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0); | 203811 | if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx); |
| 197002 | } | 203812 | } |
| 197003 | }else{ | 203813 | }else{ |
| 197004 | /* Two or more PATH arguments results in a JSON array with each | 203814 | /* Two or more PATH arguments results in a JSON array with each |
| @@ -197012,9 +203822,9 @@ static void jsonExtractFunc( | |||
| 197012 | if( p->nErr ) break; | 203822 | if( p->nErr ) break; |
| 197013 | jsonAppendSeparator(&jx); | 203823 | jsonAppendSeparator(&jx); |
| 197014 | if( pNode ){ | 203824 | if( pNode ){ |
| 197015 | jsonRenderNode(pNode, &jx, 0); | 203825 | jsonRenderNode(p, pNode, &jx); |
| 197016 | }else{ | 203826 | }else{ |
| 197017 | jsonAppendRaw(&jx, "null", 4); | 203827 | jsonAppendRawNZ(&jx, "null", 4); |
| 197018 | } | 203828 | } |
| 197019 | } | 203829 | } |
| 197020 | if( i==argc ){ | 203830 | if( i==argc ){ |
| @@ -197055,51 +203865,42 @@ static JsonNode *jsonMergePatch( | |||
| 197055 | assert( pPatch[i].eU==1 ); | 203865 | assert( pPatch[i].eU==1 ); |
| 197056 | nKey = pPatch[i].n; | 203866 | nKey = pPatch[i].n; |
| 197057 | zKey = pPatch[i].u.zJContent; | 203867 | zKey = pPatch[i].u.zJContent; |
| 197058 | assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); | ||
| 197059 | for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){ | 203868 | for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){ |
| 197060 | assert( pTarget[j].eType==JSON_STRING ); | 203869 | assert( pTarget[j].eType==JSON_STRING ); |
| 197061 | assert( pTarget[j].jnFlags & JNODE_LABEL ); | 203870 | assert( pTarget[j].jnFlags & JNODE_LABEL ); |
| 197062 | assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); | 203871 | if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){ |
| 197063 | if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ | 203872 | if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break; |
| 197064 | if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; | ||
| 197065 | if( pPatch[i+1].eType==JSON_NULL ){ | 203873 | if( pPatch[i+1].eType==JSON_NULL ){ |
| 197066 | pTarget[j+1].jnFlags |= JNODE_REMOVE; | 203874 | pTarget[j+1].jnFlags |= JNODE_REMOVE; |
| 197067 | }else{ | 203875 | }else{ |
| 197068 | JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); | 203876 | JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); |
| 197069 | if( pNew==0 ) return 0; | 203877 | if( pNew==0 ) return 0; |
| 197070 | pTarget = &pParse->aNode[iTarget]; | 203878 | if( pNew!=&pParse->aNode[iTarget+j+1] ){ |
| 197071 | if( pNew!=&pTarget[j+1] ){ | 203879 | jsonParseAddSubstNode(pParse, iTarget+j+1); |
| 197072 | assert( pTarget[j+1].eU==0 | 203880 | jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew)); |
| 197073 | || pTarget[j+1].eU==1 | ||
| 197074 | || pTarget[j+1].eU==2 ); | ||
| 197075 | testcase( pTarget[j+1].eU==1 ); | ||
| 197076 | testcase( pTarget[j+1].eU==2 ); | ||
| 197077 | VVA( pTarget[j+1].eU = 5 ); | ||
| 197078 | pTarget[j+1].u.pPatch = pNew; | ||
| 197079 | pTarget[j+1].jnFlags |= JNODE_PATCH; | ||
| 197080 | } | 203881 | } |
| 203882 | pTarget = &pParse->aNode[iTarget]; | ||
| 197081 | } | 203883 | } |
| 197082 | break; | 203884 | break; |
| 197083 | } | 203885 | } |
| 197084 | } | 203886 | } |
| 197085 | if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ | 203887 | if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ |
| 197086 | int iStart, iPatch; | 203888 | int iStart; |
| 197087 | iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); | 203889 | JsonNode *pApnd; |
| 203890 | u32 nApnd; | ||
| 203891 | iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); | ||
| 197088 | jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); | 203892 | jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); |
| 197089 | iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); | 203893 | pApnd = &pPatch[i+1]; |
| 203894 | if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd); | ||
| 203895 | nApnd = jsonNodeSize(pApnd); | ||
| 203896 | jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd)); | ||
| 197090 | if( pParse->oom ) return 0; | 203897 | if( pParse->oom ) return 0; |
| 197091 | jsonRemoveAllNulls(pPatch); | 203898 | pParse->aNode[iStart].n = 1+nApnd; |
| 197092 | pTarget = &pParse->aNode[iTarget]; | ||
| 197093 | assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 ); | ||
| 197094 | testcase( pParse->aNode[iRoot].eU==2 ); | ||
| 197095 | pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; | 203899 | pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; |
| 203900 | pParse->aNode[iRoot].u.iAppend = iStart; | ||
| 197096 | VVA( pParse->aNode[iRoot].eU = 2 ); | 203901 | VVA( pParse->aNode[iRoot].eU = 2 ); |
| 197097 | pParse->aNode[iRoot].u.iAppend = iStart - iRoot; | ||
| 197098 | iRoot = iStart; | 203902 | iRoot = iStart; |
| 197099 | assert( pParse->aNode[iPatch].eU==0 ); | 203903 | pTarget = &pParse->aNode[iTarget]; |
| 197100 | VVA( pParse->aNode[iPatch].eU = 5 ); | ||
| 197101 | pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; | ||
| 197102 | pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; | ||
| 197103 | } | 203904 | } |
| 197104 | } | 203905 | } |
| 197105 | return pTarget; | 203906 | return pTarget; |
| @@ -197115,25 +203916,28 @@ static void jsonPatchFunc( | |||
| 197115 | int argc, | 203916 | int argc, |
| 197116 | sqlite3_value **argv | 203917 | sqlite3_value **argv |
| 197117 | ){ | 203918 | ){ |
| 197118 | JsonParse x; /* The JSON that is being patched */ | 203919 | JsonParse *pX; /* The JSON that is being patched */ |
| 197119 | JsonParse y; /* The patch */ | 203920 | JsonParse *pY; /* The patch */ |
| 197120 | JsonNode *pResult; /* The result of the merge */ | 203921 | JsonNode *pResult; /* The result of the merge */ |
| 197121 | 203922 | ||
| 197122 | UNUSED_PARAMETER(argc); | 203923 | UNUSED_PARAMETER(argc); |
| 197123 | if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; | 203924 | pX = jsonParseCached(ctx, argv[0], ctx, 1); |
| 197124 | if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ | 203925 | if( pX==0 ) return; |
| 197125 | jsonParseReset(&x); | 203926 | assert( pX->hasMod==0 ); |
| 197126 | return; | 203927 | pX->hasMod = 1; |
| 197127 | } | 203928 | pY = jsonParseCached(ctx, argv[1], ctx, 1); |
| 197128 | pResult = jsonMergePatch(&x, 0, y.aNode); | 203929 | if( pY==0 ) return; |
| 197129 | assert( pResult!=0 || x.oom ); | 203930 | pX->useMod = 1; |
| 197130 | if( pResult ){ | 203931 | pY->useMod = 1; |
| 197131 | jsonReturnJson(pResult, ctx, 0); | 203932 | pResult = jsonMergePatch(pX, 0, pY->aNode); |
| 203933 | assert( pResult!=0 || pX->oom ); | ||
| 203934 | if( pResult && pX->oom==0 ){ | ||
| 203935 | jsonDebugPrintParse(pX); | ||
| 203936 | jsonDebugPrintNode(pResult); | ||
| 203937 | jsonReturnJson(pX, pResult, ctx, 0); | ||
| 197132 | }else{ | 203938 | }else{ |
| 197133 | sqlite3_result_error_nomem(ctx); | 203939 | sqlite3_result_error_nomem(ctx); |
| 197134 | } | 203940 | } |
| 197135 | jsonParseReset(&x); | ||
| 197136 | jsonParseReset(&y); | ||
| 197137 | } | 203941 | } |
| 197138 | 203942 | ||
| 197139 | 203943 | ||
| @@ -197189,26 +203993,118 @@ static void jsonRemoveFunc( | |||
| 197189 | int argc, | 203993 | int argc, |
| 197190 | sqlite3_value **argv | 203994 | sqlite3_value **argv |
| 197191 | ){ | 203995 | ){ |
| 197192 | JsonParse x; /* The parse */ | 203996 | JsonParse *pParse; /* The parse */ |
| 197193 | JsonNode *pNode; | 203997 | JsonNode *pNode; |
| 197194 | const char *zPath; | 203998 | const char *zPath; |
| 197195 | u32 i; | 203999 | u32 i; |
| 197196 | 204000 | ||
| 197197 | if( argc<1 ) return; | 204001 | if( argc<1 ) return; |
| 197198 | if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; | 204002 | pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); |
| 197199 | assert( x.nNode ); | 204003 | if( pParse==0 ) return; |
| 197200 | for(i=1; i<(u32)argc; i++){ | 204004 | for(i=1; i<(u32)argc; i++){ |
| 197201 | zPath = (const char*)sqlite3_value_text(argv[i]); | 204005 | zPath = (const char*)sqlite3_value_text(argv[i]); |
| 197202 | if( zPath==0 ) goto remove_done; | 204006 | if( zPath==0 ) goto remove_done; |
| 197203 | pNode = jsonLookup(&x, zPath, 0, ctx); | 204007 | pNode = jsonLookup(pParse, zPath, 0, ctx); |
| 197204 | if( x.nErr ) goto remove_done; | 204008 | if( pParse->nErr ) goto remove_done; |
| 197205 | if( pNode ) pNode->jnFlags |= JNODE_REMOVE; | 204009 | if( pNode ){ |
| 204010 | pNode->jnFlags |= JNODE_REMOVE; | ||
| 204011 | pParse->hasMod = 1; | ||
| 204012 | pParse->useMod = 1; | ||
| 204013 | } | ||
| 197206 | } | 204014 | } |
| 197207 | if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ | 204015 | if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){ |
| 197208 | jsonReturnJson(x.aNode, ctx, 0); | 204016 | jsonReturnJson(pParse, pParse->aNode, ctx, 1); |
| 197209 | } | 204017 | } |
| 197210 | remove_done: | 204018 | remove_done: |
| 197211 | jsonParseReset(&x); | 204019 | jsonDebugPrintParse(p); |
| 204020 | } | ||
| 204021 | |||
| 204022 | /* | ||
| 204023 | ** Substitute the value at iNode with the pValue parameter. | ||
| 204024 | */ | ||
| 204025 | static void jsonReplaceNode( | ||
| 204026 | sqlite3_context *pCtx, | ||
| 204027 | JsonParse *p, | ||
| 204028 | int iNode, | ||
| 204029 | sqlite3_value *pValue | ||
| 204030 | ){ | ||
| 204031 | int idx = jsonParseAddSubstNode(p, iNode); | ||
| 204032 | if( idx<=0 ){ | ||
| 204033 | assert( p->oom ); | ||
| 204034 | return; | ||
| 204035 | } | ||
| 204036 | switch( sqlite3_value_type(pValue) ){ | ||
| 204037 | case SQLITE_NULL: { | ||
| 204038 | jsonParseAddNode(p, JSON_NULL, 0, 0); | ||
| 204039 | break; | ||
| 204040 | } | ||
| 204041 | case SQLITE_FLOAT: { | ||
| 204042 | char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue)); | ||
| 204043 | int n; | ||
| 204044 | if( z==0 ){ | ||
| 204045 | p->oom = 1; | ||
| 204046 | break; | ||
| 204047 | } | ||
| 204048 | n = sqlite3Strlen30(z); | ||
| 204049 | jsonParseAddNode(p, JSON_REAL, n, z); | ||
| 204050 | jsonParseAddCleanup(p, sqlite3_free, z); | ||
| 204051 | break; | ||
| 204052 | } | ||
| 204053 | case SQLITE_INTEGER: { | ||
| 204054 | char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue)); | ||
| 204055 | int n; | ||
| 204056 | if( z==0 ){ | ||
| 204057 | p->oom = 1; | ||
| 204058 | break; | ||
| 204059 | } | ||
| 204060 | n = sqlite3Strlen30(z); | ||
| 204061 | jsonParseAddNode(p, JSON_INT, n, z); | ||
| 204062 | jsonParseAddCleanup(p, sqlite3_free, z); | ||
| 204063 | |||
| 204064 | break; | ||
| 204065 | } | ||
| 204066 | case SQLITE_TEXT: { | ||
| 204067 | const char *z = (const char*)sqlite3_value_text(pValue); | ||
| 204068 | u32 n = (u32)sqlite3_value_bytes(pValue); | ||
| 204069 | if( z==0 ){ | ||
| 204070 | p->oom = 1; | ||
| 204071 | break; | ||
| 204072 | } | ||
| 204073 | if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ | ||
| 204074 | char *zCopy = sqlite3DbStrDup(0, z); | ||
| 204075 | int k; | ||
| 204076 | if( zCopy ){ | ||
| 204077 | jsonParseAddCleanup(p, sqlite3_free, zCopy); | ||
| 204078 | }else{ | ||
| 204079 | p->oom = 1; | ||
| 204080 | sqlite3_result_error_nomem(pCtx); | ||
| 204081 | } | ||
| 204082 | k = jsonParseAddNode(p, JSON_STRING, n, zCopy); | ||
| 204083 | assert( k>0 || p->oom ); | ||
| 204084 | if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW; | ||
| 204085 | }else{ | ||
| 204086 | JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1); | ||
| 204087 | if( pPatch==0 ){ | ||
| 204088 | p->oom = 1; | ||
| 204089 | break; | ||
| 204090 | } | ||
| 204091 | jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode); | ||
| 204092 | /* The nodes copied out of pPatch and into p likely contain | ||
| 204093 | ** u.zJContent pointers into pPatch->zJson. So preserve the | ||
| 204094 | ** content of pPatch until p is destroyed. */ | ||
| 204095 | assert( pPatch->nJPRef>=1 ); | ||
| 204096 | pPatch->nJPRef++; | ||
| 204097 | jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch); | ||
| 204098 | } | ||
| 204099 | break; | ||
| 204100 | } | ||
| 204101 | default: { | ||
| 204102 | jsonParseAddNode(p, JSON_NULL, 0, 0); | ||
| 204103 | sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1); | ||
| 204104 | p->nErr++; | ||
| 204105 | break; | ||
| 204106 | } | ||
| 204107 | } | ||
| 197212 | } | 204108 | } |
| 197213 | 204109 | ||
| 197214 | /* | 204110 | /* |
| @@ -197222,7 +204118,7 @@ static void jsonReplaceFunc( | |||
| 197222 | int argc, | 204118 | int argc, |
| 197223 | sqlite3_value **argv | 204119 | sqlite3_value **argv |
| 197224 | ){ | 204120 | ){ |
| 197225 | JsonParse x; /* The parse */ | 204121 | JsonParse *pParse; /* The parse */ |
| 197226 | JsonNode *pNode; | 204122 | JsonNode *pNode; |
| 197227 | const char *zPath; | 204123 | const char *zPath; |
| 197228 | u32 i; | 204124 | u32 i; |
| @@ -197232,28 +204128,20 @@ static void jsonReplaceFunc( | |||
| 197232 | jsonWrongNumArgs(ctx, "replace"); | 204128 | jsonWrongNumArgs(ctx, "replace"); |
| 197233 | return; | 204129 | return; |
| 197234 | } | 204130 | } |
| 197235 | if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; | 204131 | pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); |
| 197236 | assert( x.nNode ); | 204132 | if( pParse==0 ) return; |
| 197237 | for(i=1; i<(u32)argc; i+=2){ | 204133 | for(i=1; i<(u32)argc; i+=2){ |
| 197238 | zPath = (const char*)sqlite3_value_text(argv[i]); | 204134 | zPath = (const char*)sqlite3_value_text(argv[i]); |
| 197239 | pNode = jsonLookup(&x, zPath, 0, ctx); | 204135 | pParse->useMod = 1; |
| 197240 | if( x.nErr ) goto replace_err; | 204136 | pNode = jsonLookup(pParse, zPath, 0, ctx); |
| 204137 | if( pParse->nErr ) goto replace_err; | ||
| 197241 | if( pNode ){ | 204138 | if( pNode ){ |
| 197242 | assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 ); | 204139 | jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); |
| 197243 | testcase( pNode->eU!=0 && pNode->eU!=1 ); | ||
| 197244 | pNode->jnFlags |= (u8)JNODE_REPLACE; | ||
| 197245 | VVA( pNode->eU = 4 ); | ||
| 197246 | pNode->u.iReplace = i + 1; | ||
| 197247 | } | 204140 | } |
| 197248 | } | 204141 | } |
| 197249 | if( x.aNode[0].jnFlags & JNODE_REPLACE ){ | 204142 | jsonReturnJson(pParse, pParse->aNode, ctx, 1); |
| 197250 | assert( x.aNode[0].eU==4 ); | ||
| 197251 | sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); | ||
| 197252 | }else{ | ||
| 197253 | jsonReturnJson(x.aNode, ctx, argv); | ||
| 197254 | } | ||
| 197255 | replace_err: | 204143 | replace_err: |
| 197256 | jsonParseReset(&x); | 204144 | jsonDebugPrintParse(pParse); |
| 197257 | } | 204145 | } |
| 197258 | 204146 | ||
| 197259 | 204147 | ||
| @@ -197274,7 +204162,7 @@ static void jsonSetFunc( | |||
| 197274 | int argc, | 204162 | int argc, |
| 197275 | sqlite3_value **argv | 204163 | sqlite3_value **argv |
| 197276 | ){ | 204164 | ){ |
| 197277 | JsonParse x; /* The parse */ | 204165 | JsonParse *pParse; /* The parse */ |
| 197278 | JsonNode *pNode; | 204166 | JsonNode *pNode; |
| 197279 | const char *zPath; | 204167 | const char *zPath; |
| 197280 | u32 i; | 204168 | u32 i; |
| @@ -197286,33 +204174,27 @@ static void jsonSetFunc( | |||
| 197286 | jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); | 204174 | jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); |
| 197287 | return; | 204175 | return; |
| 197288 | } | 204176 | } |
| 197289 | if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; | 204177 | pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); |
| 197290 | assert( x.nNode ); | 204178 | if( pParse==0 ) return; |
| 197291 | for(i=1; i<(u32)argc; i+=2){ | 204179 | for(i=1; i<(u32)argc; i+=2){ |
| 197292 | zPath = (const char*)sqlite3_value_text(argv[i]); | 204180 | zPath = (const char*)sqlite3_value_text(argv[i]); |
| 197293 | bApnd = 0; | 204181 | bApnd = 0; |
| 197294 | pNode = jsonLookup(&x, zPath, &bApnd, ctx); | 204182 | pParse->useMod = 1; |
| 197295 | if( x.oom ){ | 204183 | pNode = jsonLookup(pParse, zPath, &bApnd, ctx); |
| 204184 | if( pParse->oom ){ | ||
| 197296 | sqlite3_result_error_nomem(ctx); | 204185 | sqlite3_result_error_nomem(ctx); |
| 197297 | goto jsonSetDone; | 204186 | goto jsonSetDone; |
| 197298 | }else if( x.nErr ){ | 204187 | }else if( pParse->nErr ){ |
| 197299 | goto jsonSetDone; | 204188 | goto jsonSetDone; |
| 197300 | }else if( pNode && (bApnd || bIsSet) ){ | 204189 | }else if( pNode && (bApnd || bIsSet) ){ |
| 197301 | testcase( pNode->eU!=0 && pNode->eU!=1 ); | 204190 | jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); |
| 197302 | assert( pNode->eU!=3 && pNode->eU!=5 ); | ||
| 197303 | VVA( pNode->eU = 4 ); | ||
| 197304 | pNode->jnFlags |= (u8)JNODE_REPLACE; | ||
| 197305 | pNode->u.iReplace = i + 1; | ||
| 197306 | } | 204191 | } |
| 197307 | } | 204192 | } |
| 197308 | if( x.aNode[0].jnFlags & JNODE_REPLACE ){ | 204193 | jsonDebugPrintParse(pParse); |
| 197309 | assert( x.aNode[0].eU==4 ); | 204194 | jsonReturnJson(pParse, pParse->aNode, ctx, 1); |
| 197310 | sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); | 204195 | |
| 197311 | }else{ | ||
| 197312 | jsonReturnJson(x.aNode, ctx, argv); | ||
| 197313 | } | ||
| 197314 | jsonSetDone: | 204196 | jsonSetDone: |
| 197315 | jsonParseReset(&x); | 204197 | /* no cleanup required */; |
| 197316 | } | 204198 | } |
| 197317 | 204199 | ||
| 197318 | /* | 204200 | /* |
| @@ -197331,7 +204213,7 @@ static void jsonTypeFunc( | |||
| 197331 | const char *zPath; | 204213 | const char *zPath; |
| 197332 | JsonNode *pNode; | 204214 | JsonNode *pNode; |
| 197333 | 204215 | ||
| 197334 | p = jsonParseCached(ctx, argv, ctx); | 204216 | p = jsonParseCached(ctx, argv[0], ctx, 0); |
| 197335 | if( p==0 ) return; | 204217 | if( p==0 ) return; |
| 197336 | if( argc==2 ){ | 204218 | if( argc==2 ){ |
| 197337 | zPath = (const char*)sqlite3_value_text(argv[1]); | 204219 | zPath = (const char*)sqlite3_value_text(argv[1]); |
| @@ -197347,8 +204229,8 @@ static void jsonTypeFunc( | |||
| 197347 | /* | 204229 | /* |
| 197348 | ** json_valid(JSON) | 204230 | ** json_valid(JSON) |
| 197349 | ** | 204231 | ** |
| 197350 | ** Return 1 if JSON is a well-formed JSON string according to RFC-7159. | 204232 | ** Return 1 if JSON is a well-formed canonical JSON string according |
| 197351 | ** Return 0 otherwise. | 204233 | ** to RFC-7159. Return 0 otherwise. |
| 197352 | */ | 204234 | */ |
| 197353 | static void jsonValidFunc( | 204235 | static void jsonValidFunc( |
| 197354 | sqlite3_context *ctx, | 204236 | sqlite3_context *ctx, |
| @@ -197357,8 +204239,75 @@ static void jsonValidFunc( | |||
| 197357 | ){ | 204239 | ){ |
| 197358 | JsonParse *p; /* The parse */ | 204240 | JsonParse *p; /* The parse */ |
| 197359 | UNUSED_PARAMETER(argc); | 204241 | UNUSED_PARAMETER(argc); |
| 197360 | p = jsonParseCached(ctx, argv, 0); | 204242 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ |
| 197361 | sqlite3_result_int(ctx, p!=0); | 204243 | #ifdef SQLITE_LEGACY_JSON_VALID |
| 204244 | /* Incorrect legacy behavior was to return FALSE for a NULL input */ | ||
| 204245 | sqlite3_result_int(ctx, 0); | ||
| 204246 | #endif | ||
| 204247 | return; | ||
| 204248 | } | ||
| 204249 | p = jsonParseCached(ctx, argv[0], 0, 0); | ||
| 204250 | if( p==0 || p->oom ){ | ||
| 204251 | sqlite3_result_error_nomem(ctx); | ||
| 204252 | sqlite3_free(p); | ||
| 204253 | }else{ | ||
| 204254 | sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod)); | ||
| 204255 | if( p->nErr ) jsonParseFree(p); | ||
| 204256 | } | ||
| 204257 | } | ||
| 204258 | |||
| 204259 | /* | ||
| 204260 | ** json_error_position(JSON) | ||
| 204261 | ** | ||
| 204262 | ** If the argument is not an interpretable JSON string, then return the 1-based | ||
| 204263 | ** character position at which the parser first recognized that the input | ||
| 204264 | ** was in error. The left-most character is 1. If the string is valid | ||
| 204265 | ** JSON, then return 0. | ||
| 204266 | ** | ||
| 204267 | ** Note that json_valid() is only true for strictly conforming canonical JSON. | ||
| 204268 | ** But this routine returns zero if the input contains extension. Thus: | ||
| 204269 | ** | ||
| 204270 | ** (1) If the input X is strictly conforming canonical JSON: | ||
| 204271 | ** | ||
| 204272 | ** json_valid(X) returns true | ||
| 204273 | ** json_error_position(X) returns 0 | ||
| 204274 | ** | ||
| 204275 | ** (2) If the input X is JSON but it includes extension (such as JSON5) that | ||
| 204276 | ** are not part of RFC-8259: | ||
| 204277 | ** | ||
| 204278 | ** json_valid(X) returns false | ||
| 204279 | ** json_error_position(X) return 0 | ||
| 204280 | ** | ||
| 204281 | ** (3) If the input X cannot be interpreted as JSON even taking extensions | ||
| 204282 | ** into account: | ||
| 204283 | ** | ||
| 204284 | ** json_valid(X) return false | ||
| 204285 | ** json_error_position(X) returns 1 or more | ||
| 204286 | */ | ||
| 204287 | static void jsonErrorFunc( | ||
| 204288 | sqlite3_context *ctx, | ||
| 204289 | int argc, | ||
| 204290 | sqlite3_value **argv | ||
| 204291 | ){ | ||
| 204292 | JsonParse *p; /* The parse */ | ||
| 204293 | UNUSED_PARAMETER(argc); | ||
| 204294 | if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; | ||
| 204295 | p = jsonParseCached(ctx, argv[0], 0, 0); | ||
| 204296 | if( p==0 || p->oom ){ | ||
| 204297 | sqlite3_result_error_nomem(ctx); | ||
| 204298 | sqlite3_free(p); | ||
| 204299 | }else if( p->nErr==0 ){ | ||
| 204300 | sqlite3_result_int(ctx, 0); | ||
| 204301 | }else{ | ||
| 204302 | int n = 1; | ||
| 204303 | u32 i; | ||
| 204304 | const char *z = (const char*)sqlite3_value_text(argv[0]); | ||
| 204305 | for(i=0; i<p->iErr && ALWAYS(z[i]); i++){ | ||
| 204306 | if( (z[i]&0xc0)!=0x80 ) n++; | ||
| 204307 | } | ||
| 204308 | sqlite3_result_int(ctx, n); | ||
| 204309 | jsonParseFree(p); | ||
| 204310 | } | ||
| 197362 | } | 204311 | } |
| 197363 | 204312 | ||
| 197364 | 204313 | ||
| @@ -197400,7 +204349,8 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ | |||
| 197400 | assert( pStr->bStatic ); | 204349 | assert( pStr->bStatic ); |
| 197401 | }else if( isFinal ){ | 204350 | }else if( isFinal ){ |
| 197402 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, | 204351 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, |
| 197403 | pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); | 204352 | pStr->bStatic ? SQLITE_TRANSIENT : |
| 204353 | (void(*)(void*))sqlite3RCStrUnref); | ||
| 197404 | pStr->bStatic = 1; | 204354 | pStr->bStatic = 1; |
| 197405 | }else{ | 204355 | }else{ |
| 197406 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); | 204356 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); |
| @@ -197441,7 +204391,7 @@ static void jsonGroupInverse( | |||
| 197441 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); | 204391 | pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); |
| 197442 | #ifdef NEVER | 204392 | #ifdef NEVER |
| 197443 | /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will | 204393 | /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will |
| 197444 | ** always have been called to initalize it */ | 204394 | ** always have been called to initialize it */ |
| 197445 | if( NEVER(!pStr) ) return; | 204395 | if( NEVER(!pStr) ) return; |
| 197446 | #endif | 204396 | #endif |
| 197447 | z = pStr->zBuf; | 204397 | z = pStr->zBuf; |
| @@ -197508,7 +204458,8 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ | |||
| 197508 | assert( pStr->bStatic ); | 204458 | assert( pStr->bStatic ); |
| 197509 | }else if( isFinal ){ | 204459 | }else if( isFinal ){ |
| 197510 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, | 204460 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, |
| 197511 | pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); | 204461 | pStr->bStatic ? SQLITE_TRANSIENT : |
| 204462 | (void(*)(void*))sqlite3RCStrUnref); | ||
| 197512 | pStr->bStatic = 1; | 204463 | pStr->bStatic = 1; |
| 197513 | }else{ | 204464 | }else{ |
| 197514 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); | 204465 | sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); |
| @@ -197619,7 +204570,6 @@ static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ | |||
| 197619 | /* Reset a JsonEachCursor back to its original state. Free any memory | 204570 | /* Reset a JsonEachCursor back to its original state. Free any memory |
| 197620 | ** held. */ | 204571 | ** held. */ |
| 197621 | static void jsonEachCursorReset(JsonEachCursor *p){ | 204572 | static void jsonEachCursorReset(JsonEachCursor *p){ |
| 197622 | sqlite3_free(p->zJson); | ||
| 197623 | sqlite3_free(p->zRoot); | 204573 | sqlite3_free(p->zRoot); |
| 197624 | jsonParseReset(&p->sParse); | 204574 | jsonParseReset(&p->sParse); |
| 197625 | p->iRowid = 0; | 204575 | p->iRowid = 0; |
| @@ -197702,14 +204652,16 @@ static void jsonAppendObjectPathElement( | |||
| 197702 | assert( pNode->eU==1 ); | 204652 | assert( pNode->eU==1 ); |
| 197703 | z = pNode->u.zJContent; | 204653 | z = pNode->u.zJContent; |
| 197704 | nn = pNode->n; | 204654 | nn = pNode->n; |
| 197705 | assert( nn>=2 ); | 204655 | if( (pNode->jnFlags & JNODE_RAW)==0 ){ |
| 197706 | assert( z[0]=='"' ); | 204656 | assert( nn>=2 ); |
| 197707 | assert( z[nn-1]=='"' ); | 204657 | assert( z[0]=='"' || z[0]=='\'' ); |
| 197708 | if( nn>2 && sqlite3Isalpha(z[1]) ){ | 204658 | assert( z[nn-1]=='"' || z[0]=='\'' ); |
| 197709 | for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){} | 204659 | if( nn>2 && sqlite3Isalpha(z[1]) ){ |
| 197710 | if( jj==nn-1 ){ | 204660 | for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){} |
| 197711 | z++; | 204661 | if( jj==nn-1 ){ |
| 197712 | nn -= 2; | 204662 | z++; |
| 204663 | nn -= 2; | ||
| 204664 | } | ||
| 197713 | } | 204665 | } |
| 197714 | } | 204666 | } |
| 197715 | jsonPrintf(nn+2, pStr, ".%.*s", nn, z); | 204667 | jsonPrintf(nn+2, pStr, ".%.*s", nn, z); |
| @@ -197755,7 +204707,7 @@ static int jsonEachColumn( | |||
| 197755 | case JEACH_KEY: { | 204707 | case JEACH_KEY: { |
| 197756 | if( p->i==0 ) break; | 204708 | if( p->i==0 ) break; |
| 197757 | if( p->eType==JSON_OBJECT ){ | 204709 | if( p->eType==JSON_OBJECT ){ |
| 197758 | jsonReturn(pThis, ctx, 0); | 204710 | jsonReturn(&p->sParse, pThis, ctx); |
| 197759 | }else if( p->eType==JSON_ARRAY ){ | 204711 | }else if( p->eType==JSON_ARRAY ){ |
| 197760 | u32 iKey; | 204712 | u32 iKey; |
| 197761 | if( p->bRecursive ){ | 204713 | if( p->bRecursive ){ |
| @@ -197771,7 +204723,7 @@ static int jsonEachColumn( | |||
| 197771 | } | 204723 | } |
| 197772 | case JEACH_VALUE: { | 204724 | case JEACH_VALUE: { |
| 197773 | if( pThis->jnFlags & JNODE_LABEL ) pThis++; | 204725 | if( pThis->jnFlags & JNODE_LABEL ) pThis++; |
| 197774 | jsonReturn(pThis, ctx, 0); | 204726 | jsonReturn(&p->sParse, pThis, ctx); |
| 197775 | break; | 204727 | break; |
| 197776 | } | 204728 | } |
| 197777 | case JEACH_TYPE: { | 204729 | case JEACH_TYPE: { |
| @@ -197782,7 +204734,7 @@ static int jsonEachColumn( | |||
| 197782 | case JEACH_ATOM: { | 204734 | case JEACH_ATOM: { |
| 197783 | if( pThis->jnFlags & JNODE_LABEL ) pThis++; | 204735 | if( pThis->jnFlags & JNODE_LABEL ) pThis++; |
| 197784 | if( pThis->eType>=JSON_ARRAY ) break; | 204736 | if( pThis->eType>=JSON_ARRAY ) break; |
| 197785 | jsonReturn(pThis, ctx, 0); | 204737 | jsonReturn(&p->sParse, pThis, ctx); |
| 197786 | break; | 204738 | break; |
| 197787 | } | 204739 | } |
| 197788 | case JEACH_ID: { | 204740 | case JEACH_ID: { |
| @@ -197886,6 +204838,13 @@ static int jsonEachBestIndex( | |||
| 197886 | idxMask |= iMask; | 204838 | idxMask |= iMask; |
| 197887 | } | 204839 | } |
| 197888 | } | 204840 | } |
| 204841 | if( pIdxInfo->nOrderBy>0 | ||
| 204842 | && pIdxInfo->aOrderBy[0].iColumn<0 | ||
| 204843 | && pIdxInfo->aOrderBy[0].desc==0 | ||
| 204844 | ){ | ||
| 204845 | pIdxInfo->orderByConsumed = 1; | ||
| 204846 | } | ||
| 204847 | |||
| 197889 | if( (unusableMask & ~idxMask)!=0 ){ | 204848 | if( (unusableMask & ~idxMask)!=0 ){ |
| 197890 | /* If there are any unusable constraints on JSON or ROOT, then reject | 204849 | /* If there are any unusable constraints on JSON or ROOT, then reject |
| 197891 | ** this entire plan */ | 204850 | ** this entire plan */ |
| @@ -197930,11 +204889,19 @@ static int jsonEachFilter( | |||
| 197930 | if( idxNum==0 ) return SQLITE_OK; | 204889 | if( idxNum==0 ) return SQLITE_OK; |
| 197931 | z = (const char*)sqlite3_value_text(argv[0]); | 204890 | z = (const char*)sqlite3_value_text(argv[0]); |
| 197932 | if( z==0 ) return SQLITE_OK; | 204891 | if( z==0 ) return SQLITE_OK; |
| 197933 | n = sqlite3_value_bytes(argv[0]); | 204892 | memset(&p->sParse, 0, sizeof(p->sParse)); |
| 197934 | p->zJson = sqlite3_malloc64( n+1 ); | 204893 | p->sParse.nJPRef = 1; |
| 197935 | if( p->zJson==0 ) return SQLITE_NOMEM; | 204894 | if( sqlite3ValueIsOfClass(argv[0], (void(*)(void*))sqlite3RCStrUnref) ){ |
| 197936 | memcpy(p->zJson, z, (size_t)n+1); | 204895 | p->sParse.zJson = sqlite3RCStrRef((char*)z); |
| 197937 | if( jsonParse(&p->sParse, 0, p->zJson) ){ | 204896 | }else{ |
| 204897 | n = sqlite3_value_bytes(argv[0]); | ||
| 204898 | p->sParse.zJson = sqlite3RCStrNew( n+1 ); | ||
| 204899 | if( p->sParse.zJson==0 ) return SQLITE_NOMEM; | ||
| 204900 | memcpy(p->sParse.zJson, z, (size_t)n+1); | ||
| 204901 | } | ||
| 204902 | p->sParse.bJsonIsRCStr = 1; | ||
| 204903 | p->zJson = p->sParse.zJson; | ||
| 204904 | if( jsonParse(&p->sParse, 0) ){ | ||
| 197938 | int rc = SQLITE_NOMEM; | 204905 | int rc = SQLITE_NOMEM; |
| 197939 | if( p->sParse.oom==0 ){ | 204906 | if( p->sParse.oom==0 ){ |
| 197940 | sqlite3_free(cur->pVtab->zErrMsg); | 204907 | sqlite3_free(cur->pVtab->zErrMsg); |
| @@ -198062,6 +205029,7 @@ SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ | |||
| 198062 | JFUNCTION(json_array, -1, 0, jsonArrayFunc), | 205029 | JFUNCTION(json_array, -1, 0, jsonArrayFunc), |
| 198063 | JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc), | 205030 | JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc), |
| 198064 | JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc), | 205031 | JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc), |
| 205032 | JFUNCTION(json_error_position,1, 0, jsonErrorFunc), | ||
| 198065 | JFUNCTION(json_extract, -1, 0, jsonExtractFunc), | 205033 | JFUNCTION(json_extract, -1, 0, jsonExtractFunc), |
| 198066 | JFUNCTION(->, 2, JSON_JSON, jsonExtractFunc), | 205034 | JFUNCTION(->, 2, JSON_JSON, jsonExtractFunc), |
| 198067 | JFUNCTION(->>, 2, JSON_SQL, jsonExtractFunc), | 205035 | JFUNCTION(->>, 2, JSON_SQL, jsonExtractFunc), |
| @@ -198081,10 +205049,10 @@ SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ | |||
| 198081 | #endif | 205049 | #endif |
| 198082 | WAGGREGATE(json_group_array, 1, 0, 0, | 205050 | WAGGREGATE(json_group_array, 1, 0, 0, |
| 198083 | jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, | 205051 | jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, |
| 198084 | SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS), | 205052 | SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), |
| 198085 | WAGGREGATE(json_group_object, 2, 0, 0, | 205053 | WAGGREGATE(json_group_object, 2, 0, 0, |
| 198086 | jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, | 205054 | jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, |
| 198087 | SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS) | 205055 | SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC) |
| 198088 | }; | 205056 | }; |
| 198089 | sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); | 205057 | sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); |
| 198090 | #endif | 205058 | #endif |
| @@ -198211,6 +205179,11 @@ typedef unsigned int u32; | |||
| 198211 | #endif | 205179 | #endif |
| 198212 | #endif /* !defined(SQLITE_AMALGAMATION) */ | 205180 | #endif /* !defined(SQLITE_AMALGAMATION) */ |
| 198213 | 205181 | ||
| 205182 | /* Macro to check for 4-byte alignment. Only used inside of assert() */ | ||
| 205183 | #ifdef SQLITE_DEBUG | ||
| 205184 | # define FOUR_BYTE_ALIGNED(X) ((((char*)(X) - (char*)0) & 3)==0) | ||
| 205185 | #endif | ||
| 205186 | |||
| 198214 | /* #include <string.h> */ | 205187 | /* #include <string.h> */ |
| 198215 | /* #include <stdio.h> */ | 205188 | /* #include <stdio.h> */ |
| 198216 | /* #include <assert.h> */ | 205189 | /* #include <assert.h> */ |
| @@ -198586,16 +205559,17 @@ struct RtreeMatchArg { | |||
| 198586 | ** at run-time. | 205559 | ** at run-time. |
| 198587 | */ | 205560 | */ |
| 198588 | #ifndef SQLITE_BYTEORDER | 205561 | #ifndef SQLITE_BYTEORDER |
| 198589 | #if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ | 205562 | # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ |
| 198590 | defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ | 205563 | defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ |
| 198591 | defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ | 205564 | defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ |
| 198592 | defined(__arm__) | 205565 | defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) |
| 198593 | # define SQLITE_BYTEORDER 1234 | 205566 | # define SQLITE_BYTEORDER 1234 |
| 198594 | #elif defined(sparc) || defined(__ppc__) | 205567 | # elif defined(sparc) || defined(__ppc__) || \ |
| 198595 | # define SQLITE_BYTEORDER 4321 | 205568 | defined(__ARMEB__) || defined(__AARCH64EB__) |
| 198596 | #else | 205569 | # define SQLITE_BYTEORDER 4321 |
| 198597 | # define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ | 205570 | # else |
| 198598 | #endif | 205571 | # define SQLITE_BYTEORDER 0 |
| 205572 | # endif | ||
| 198599 | #endif | 205573 | #endif |
| 198600 | 205574 | ||
| 198601 | 205575 | ||
| @@ -198616,7 +205590,7 @@ static int readInt16(u8 *p){ | |||
| 198616 | return (p[0]<<8) + p[1]; | 205590 | return (p[0]<<8) + p[1]; |
| 198617 | } | 205591 | } |
| 198618 | static void readCoord(u8 *p, RtreeCoord *pCoord){ | 205592 | static void readCoord(u8 *p, RtreeCoord *pCoord){ |
| 198619 | assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ | 205593 | assert( FOUR_BYTE_ALIGNED(p) ); |
| 198620 | #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 | 205594 | #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 |
| 198621 | pCoord->u = _byteswap_ulong(*(u32*)p); | 205595 | pCoord->u = _byteswap_ulong(*(u32*)p); |
| 198622 | #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 | 205596 | #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 |
| @@ -198670,7 +205644,7 @@ static void writeInt16(u8 *p, int i){ | |||
| 198670 | } | 205644 | } |
| 198671 | static int writeCoord(u8 *p, RtreeCoord *pCoord){ | 205645 | static int writeCoord(u8 *p, RtreeCoord *pCoord){ |
| 198672 | u32 i; | 205646 | u32 i; |
| 198673 | assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */ | 205647 | assert( FOUR_BYTE_ALIGNED(p) ); |
| 198674 | assert( sizeof(RtreeCoord)==4 ); | 205648 | assert( sizeof(RtreeCoord)==4 ); |
| 198675 | assert( sizeof(u32)==4 ); | 205649 | assert( sizeof(u32)==4 ); |
| 198676 | #if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 | 205650 | #if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 |
| @@ -199398,7 +206372,7 @@ static void rtreeNonleafConstraint( | |||
| 199398 | assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE | 206372 | assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE |
| 199399 | || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE | 206373 | || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE |
| 199400 | || p->op==RTREE_FALSE ); | 206374 | || p->op==RTREE_FALSE ); |
| 199401 | assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ | 206375 | assert( FOUR_BYTE_ALIGNED(pCellData) ); |
| 199402 | switch( p->op ){ | 206376 | switch( p->op ){ |
| 199403 | case RTREE_TRUE: return; /* Always satisfied */ | 206377 | case RTREE_TRUE: return; /* Always satisfied */ |
| 199404 | case RTREE_FALSE: break; /* Never satisfied */ | 206378 | case RTREE_FALSE: break; /* Never satisfied */ |
| @@ -199451,7 +206425,7 @@ static void rtreeLeafConstraint( | |||
| 199451 | || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE | 206425 | || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE |
| 199452 | || p->op==RTREE_FALSE ); | 206426 | || p->op==RTREE_FALSE ); |
| 199453 | pCellData += 8 + p->iCoord*4; | 206427 | pCellData += 8 + p->iCoord*4; |
| 199454 | assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */ | 206428 | assert( FOUR_BYTE_ALIGNED(pCellData) ); |
| 199455 | RTREE_DECODE_COORD(eInt, pCellData, xN); | 206429 | RTREE_DECODE_COORD(eInt, pCellData, xN); |
| 199456 | switch( p->op ){ | 206430 | switch( p->op ){ |
| 199457 | case RTREE_TRUE: return; /* Always satisfied */ | 206431 | case RTREE_TRUE: return; /* Always satisfied */ |
| @@ -200021,7 +206995,20 @@ static int rtreeFilter( | |||
| 200021 | p->pInfo->nCoord = pRtree->nDim2; | 206995 | p->pInfo->nCoord = pRtree->nDim2; |
| 200022 | p->pInfo->anQueue = pCsr->anQueue; | 206996 | p->pInfo->anQueue = pCsr->anQueue; |
| 200023 | p->pInfo->mxLevel = pRtree->iDepth + 1; | 206997 | p->pInfo->mxLevel = pRtree->iDepth + 1; |
| 200024 | }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ | 206998 | }else if( eType==SQLITE_INTEGER ){ |
| 206999 | sqlite3_int64 iVal = sqlite3_value_int64(argv[ii]); | ||
| 207000 | #ifdef SQLITE_RTREE_INT_ONLY | ||
| 207001 | p->u.rValue = iVal; | ||
| 207002 | #else | ||
| 207003 | p->u.rValue = (double)iVal; | ||
| 207004 | if( iVal>=((sqlite3_int64)1)<<48 | ||
| 207005 | || iVal<=-(((sqlite3_int64)1)<<48) | ||
| 207006 | ){ | ||
| 207007 | if( p->op==RTREE_LT ) p->op = RTREE_LE; | ||
| 207008 | if( p->op==RTREE_GT ) p->op = RTREE_GE; | ||
| 207009 | } | ||
| 207010 | #endif | ||
| 207011 | }else if( eType==SQLITE_FLOAT ){ | ||
| 200025 | #ifdef SQLITE_RTREE_INT_ONLY | 207012 | #ifdef SQLITE_RTREE_INT_ONLY |
| 200026 | p->u.rValue = sqlite3_value_int64(argv[ii]); | 207013 | p->u.rValue = sqlite3_value_int64(argv[ii]); |
| 200027 | #else | 207014 | #else |
| @@ -200152,11 +207139,12 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | |||
| 200152 | || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) | 207139 | || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) |
| 200153 | ){ | 207140 | ){ |
| 200154 | u8 op; | 207141 | u8 op; |
| 207142 | u8 doOmit = 1; | ||
| 200155 | switch( p->op ){ | 207143 | switch( p->op ){ |
| 200156 | case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; | 207144 | case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; doOmit = 0; break; |
| 200157 | case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; | 207145 | case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; doOmit = 0; break; |
| 200158 | case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; | 207146 | case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; |
| 200159 | case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; | 207147 | case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; doOmit = 0; break; |
| 200160 | case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; | 207148 | case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; |
| 200161 | case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break; | 207149 | case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break; |
| 200162 | default: op = 0; break; | 207150 | default: op = 0; break; |
| @@ -200165,7 +207153,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | |||
| 200165 | zIdxStr[iIdx++] = op; | 207153 | zIdxStr[iIdx++] = op; |
| 200166 | zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); | 207154 | zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); |
| 200167 | pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); | 207155 | pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); |
| 200168 | pIdxInfo->aConstraintUsage[ii].omit = 1; | 207156 | pIdxInfo->aConstraintUsage[ii].omit = doOmit; |
| 200169 | } | 207157 | } |
| 200170 | } | 207158 | } |
| 200171 | } | 207159 | } |
| @@ -201350,7 +208338,7 @@ static int rtreeUpdate( | |||
| 201350 | rtreeReference(pRtree); | 208338 | rtreeReference(pRtree); |
| 201351 | assert(nData>=1); | 208339 | assert(nData>=1); |
| 201352 | 208340 | ||
| 201353 | cell.iRowid = 0; /* Used only to suppress a compiler warning */ | 208341 | memset(&cell, 0, sizeof(cell)); |
| 201354 | 208342 | ||
| 201355 | /* Constraint handling. A write operation on an r-tree table may return | 208343 | /* Constraint handling. A write operation on an r-tree table may return |
| 201356 | ** SQLITE_CONSTRAINT for two reasons: | 208344 | ** SQLITE_CONSTRAINT for two reasons: |
| @@ -202823,7 +209811,7 @@ static GeoPoly *geopolyFuncParam( | |||
| 202823 | int nByte; | 209811 | int nByte; |
| 202824 | testcase( pCtx==0 ); | 209812 | testcase( pCtx==0 ); |
| 202825 | if( sqlite3_value_type(pVal)==SQLITE_BLOB | 209813 | if( sqlite3_value_type(pVal)==SQLITE_BLOB |
| 202826 | && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) | 209814 | && (nByte = sqlite3_value_bytes(pVal))>=(int)(4+6*sizeof(GeoCoord)) |
| 202827 | ){ | 209815 | ){ |
| 202828 | const unsigned char *a = sqlite3_value_blob(pVal); | 209816 | const unsigned char *a = sqlite3_value_blob(pVal); |
| 202829 | int nVertex; | 209817 | int nVertex; |
| @@ -202881,6 +209869,7 @@ static void geopolyBlobFunc( | |||
| 202881 | sqlite3_value **argv | 209869 | sqlite3_value **argv |
| 202882 | ){ | 209870 | ){ |
| 202883 | GeoPoly *p = geopolyFuncParam(context, argv[0], 0); | 209871 | GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 209872 | (void)argc; | ||
| 202884 | if( p ){ | 209873 | if( p ){ |
| 202885 | sqlite3_result_blob(context, p->hdr, | 209874 | sqlite3_result_blob(context, p->hdr, |
| 202886 | 4+8*p->nVertex, SQLITE_TRANSIENT); | 209875 | 4+8*p->nVertex, SQLITE_TRANSIENT); |
| @@ -202900,6 +209889,7 @@ static void geopolyJsonFunc( | |||
| 202900 | sqlite3_value **argv | 209889 | sqlite3_value **argv |
| 202901 | ){ | 209890 | ){ |
| 202902 | GeoPoly *p = geopolyFuncParam(context, argv[0], 0); | 209891 | GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 209892 | (void)argc; | ||
| 202903 | if( p ){ | 209893 | if( p ){ |
| 202904 | sqlite3 *db = sqlite3_context_db_handle(context); | 209894 | sqlite3 *db = sqlite3_context_db_handle(context); |
| 202905 | sqlite3_str *x = sqlite3_str_new(db); | 209895 | sqlite3_str *x = sqlite3_str_new(db); |
| @@ -202981,6 +209971,7 @@ static void geopolyXformFunc( | |||
| 202981 | double F = sqlite3_value_double(argv[6]); | 209971 | double F = sqlite3_value_double(argv[6]); |
| 202982 | GeoCoord x1, y1, x0, y0; | 209972 | GeoCoord x1, y1, x0, y0; |
| 202983 | int ii; | 209973 | int ii; |
| 209974 | (void)argc; | ||
| 202984 | if( p ){ | 209975 | if( p ){ |
| 202985 | for(ii=0; ii<p->nVertex; ii++){ | 209976 | for(ii=0; ii<p->nVertex; ii++){ |
| 202986 | x0 = GeoX(p,ii); | 209977 | x0 = GeoX(p,ii); |
| @@ -203031,6 +210022,7 @@ static void geopolyAreaFunc( | |||
| 203031 | sqlite3_value **argv | 210022 | sqlite3_value **argv |
| 203032 | ){ | 210023 | ){ |
| 203033 | GeoPoly *p = geopolyFuncParam(context, argv[0], 0); | 210024 | GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 210025 | (void)argc; | ||
| 203034 | if( p ){ | 210026 | if( p ){ |
| 203035 | sqlite3_result_double(context, geopolyArea(p)); | 210027 | sqlite3_result_double(context, geopolyArea(p)); |
| 203036 | sqlite3_free(p); | 210028 | sqlite3_free(p); |
| @@ -203056,6 +210048,7 @@ static void geopolyCcwFunc( | |||
| 203056 | sqlite3_value **argv | 210048 | sqlite3_value **argv |
| 203057 | ){ | 210049 | ){ |
| 203058 | GeoPoly *p = geopolyFuncParam(context, argv[0], 0); | 210050 | GeoPoly *p = geopolyFuncParam(context, argv[0], 0); |
| 210051 | (void)argc; | ||
| 203059 | if( p ){ | 210052 | if( p ){ |
| 203060 | if( geopolyArea(p)<0.0 ){ | 210053 | if( geopolyArea(p)<0.0 ){ |
| 203061 | int ii, jj; | 210054 | int ii, jj; |
| @@ -203110,6 +210103,7 @@ static void geopolyRegularFunc( | |||
| 203110 | int n = sqlite3_value_int(argv[3]); | 210103 | int n = sqlite3_value_int(argv[3]); |
| 203111 | int i; | 210104 | int i; |
| 203112 | GeoPoly *p; | 210105 | GeoPoly *p; |
| 210106 | (void)argc; | ||
| 203113 | 210107 | ||
| 203114 | if( n<3 || r<=0.0 ) return; | 210108 | if( n<3 || r<=0.0 ) return; |
| 203115 | if( n>1000 ) n = 1000; | 210109 | if( n>1000 ) n = 1000; |
| @@ -203219,6 +210213,7 @@ static void geopolyBBoxFunc( | |||
| 203219 | sqlite3_value **argv | 210213 | sqlite3_value **argv |
| 203220 | ){ | 210214 | ){ |
| 203221 | GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); | 210215 | GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); |
| 210216 | (void)argc; | ||
| 203222 | if( p ){ | 210217 | if( p ){ |
| 203223 | sqlite3_result_blob(context, p->hdr, | 210218 | sqlite3_result_blob(context, p->hdr, |
| 203224 | 4+8*p->nVertex, SQLITE_TRANSIENT); | 210219 | 4+8*p->nVertex, SQLITE_TRANSIENT); |
| @@ -203246,6 +210241,7 @@ static void geopolyBBoxStep( | |||
| 203246 | ){ | 210241 | ){ |
| 203247 | RtreeCoord a[4]; | 210242 | RtreeCoord a[4]; |
| 203248 | int rc = SQLITE_OK; | 210243 | int rc = SQLITE_OK; |
| 210244 | (void)argc; | ||
| 203249 | (void)geopolyBBox(context, argv[0], a, &rc); | 210245 | (void)geopolyBBox(context, argv[0], a, &rc); |
| 203250 | if( rc==SQLITE_OK ){ | 210246 | if( rc==SQLITE_OK ){ |
| 203251 | GeoBBox *pBBox; | 210247 | GeoBBox *pBBox; |
| @@ -203334,6 +210330,8 @@ static void geopolyContainsPointFunc( | |||
| 203334 | int v = 0; | 210330 | int v = 0; |
| 203335 | int cnt = 0; | 210331 | int cnt = 0; |
| 203336 | int ii; | 210332 | int ii; |
| 210333 | (void)argc; | ||
| 210334 | |||
| 203337 | if( p1==0 ) return; | 210335 | if( p1==0 ) return; |
| 203338 | for(ii=0; ii<p1->nVertex-1; ii++){ | 210336 | for(ii=0; ii<p1->nVertex-1; ii++){ |
| 203339 | v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), | 210337 | v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), |
| @@ -203373,6 +210371,7 @@ static void geopolyWithinFunc( | |||
| 203373 | ){ | 210371 | ){ |
| 203374 | GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); | 210372 | GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); |
| 203375 | GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); | 210373 | GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); |
| 210374 | (void)argc; | ||
| 203376 | if( p1 && p2 ){ | 210375 | if( p1 && p2 ){ |
| 203377 | int x = geopolyOverlap(p1, p2); | 210376 | int x = geopolyOverlap(p1, p2); |
| 203378 | if( x<0 ){ | 210377 | if( x<0 ){ |
| @@ -203703,6 +210702,7 @@ static void geopolyOverlapFunc( | |||
| 203703 | ){ | 210702 | ){ |
| 203704 | GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); | 210703 | GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); |
| 203705 | GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); | 210704 | GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); |
| 210705 | (void)argc; | ||
| 203706 | if( p1 && p2 ){ | 210706 | if( p1 && p2 ){ |
| 203707 | int x = geopolyOverlap(p1, p2); | 210707 | int x = geopolyOverlap(p1, p2); |
| 203708 | if( x<0 ){ | 210708 | if( x<0 ){ |
| @@ -203723,8 +210723,12 @@ static void geopolyDebugFunc( | |||
| 203723 | int argc, | 210723 | int argc, |
| 203724 | sqlite3_value **argv | 210724 | sqlite3_value **argv |
| 203725 | ){ | 210725 | ){ |
| 210726 | (void)context; | ||
| 210727 | (void)argc; | ||
| 203726 | #ifdef GEOPOLY_ENABLE_DEBUG | 210728 | #ifdef GEOPOLY_ENABLE_DEBUG |
| 203727 | geo_debug = sqlite3_value_int(argv[0]); | 210729 | geo_debug = sqlite3_value_int(argv[0]); |
| 210730 | #else | ||
| 210731 | (void)argv; | ||
| 203728 | #endif | 210732 | #endif |
| 203729 | } | 210733 | } |
| 203730 | 210734 | ||
| @@ -203752,6 +210756,7 @@ static int geopolyInit( | |||
| 203752 | sqlite3_str *pSql; | 210756 | sqlite3_str *pSql; |
| 203753 | char *zSql; | 210757 | char *zSql; |
| 203754 | int ii; | 210758 | int ii; |
| 210759 | (void)pAux; | ||
| 203755 | 210760 | ||
| 203756 | sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); | 210761 | sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); |
| 203757 | 210762 | ||
| @@ -203868,6 +210873,7 @@ static int geopolyFilter( | |||
| 203868 | RtreeNode *pRoot = 0; | 210873 | RtreeNode *pRoot = 0; |
| 203869 | int rc = SQLITE_OK; | 210874 | int rc = SQLITE_OK; |
| 203870 | int iCell = 0; | 210875 | int iCell = 0; |
| 210876 | (void)idxStr; | ||
| 203871 | 210877 | ||
| 203872 | rtreeReference(pRtree); | 210878 | rtreeReference(pRtree); |
| 203873 | 210879 | ||
| @@ -203994,6 +211000,7 @@ static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | |||
| 203994 | int iRowidTerm = -1; | 211000 | int iRowidTerm = -1; |
| 203995 | int iFuncTerm = -1; | 211001 | int iFuncTerm = -1; |
| 203996 | int idxNum = 0; | 211002 | int idxNum = 0; |
| 211003 | (void)tab; | ||
| 203997 | 211004 | ||
| 203998 | for(ii=0; ii<pIdxInfo->nConstraint; ii++){ | 211005 | for(ii=0; ii<pIdxInfo->nConstraint; ii++){ |
| 203999 | struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; | 211006 | struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; |
| @@ -204240,6 +211247,8 @@ static int geopolyFindFunction( | |||
| 204240 | void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), | 211247 | void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), |
| 204241 | void **ppArg | 211248 | void **ppArg |
| 204242 | ){ | 211249 | ){ |
| 211250 | (void)pVtab; | ||
| 211251 | (void)nArg; | ||
| 204243 | if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ | 211252 | if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ |
| 204244 | *pxFunc = geopolyOverlapFunc; | 211253 | *pxFunc = geopolyOverlapFunc; |
| 204245 | *ppArg = 0; | 211254 | *ppArg = 0; |
| @@ -204309,7 +211318,7 @@ static int sqlite3_geopoly_init(sqlite3 *db){ | |||
| 204309 | } aAgg[] = { | 211318 | } aAgg[] = { |
| 204310 | { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, | 211319 | { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, |
| 204311 | }; | 211320 | }; |
| 204312 | int i; | 211321 | unsigned int i; |
| 204313 | for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ | 211322 | for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ |
| 204314 | int enc; | 211323 | int enc; |
| 204315 | if( aFunc[i].bPure ){ | 211324 | if( aFunc[i].bPure ){ |
| @@ -204817,8 +211826,9 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ | |||
| 204817 | 211826 | ||
| 204818 | if( U_SUCCESS(status) ){ | 211827 | if( U_SUCCESS(status) ){ |
| 204819 | sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); | 211828 | sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); |
| 204820 | }else{ | 211829 | pExpr = sqlite3_get_auxdata(p, 0); |
| 204821 | assert(!pExpr); | 211830 | } |
| 211831 | if( !pExpr ){ | ||
| 204822 | icuFunctionError(p, "uregex_open", status); | 211832 | icuFunctionError(p, "uregex_open", status); |
| 204823 | return; | 211833 | return; |
| 204824 | } | 211834 | } |
| @@ -205529,7 +212539,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( | |||
| 205529 | ** The order of the columns in the data_% table does not matter. | 212539 | ** The order of the columns in the data_% table does not matter. |
| 205530 | ** | 212540 | ** |
| 205531 | ** Instead of a regular table, the RBU database may also contain virtual | 212541 | ** Instead of a regular table, the RBU database may also contain virtual |
| 205532 | ** tables or view named using the data_<target> naming scheme. | 212542 | ** tables or views named using the data_<target> naming scheme. |
| 205533 | ** | 212543 | ** |
| 205534 | ** Instead of the plain data_<target> naming scheme, RBU database tables | 212544 | ** Instead of the plain data_<target> naming scheme, RBU database tables |
| 205535 | ** may also be named data<integer>_<target>, where <integer> is any sequence | 212545 | ** may also be named data<integer>_<target>, where <integer> is any sequence |
| @@ -205542,7 +212552,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( | |||
| 205542 | ** | 212552 | ** |
| 205543 | ** If the target database table is a virtual table or a table that has no | 212553 | ** If the target database table is a virtual table or a table that has no |
| 205544 | ** PRIMARY KEY declaration, the data_% table must also contain a column | 212554 | ** PRIMARY KEY declaration, the data_% table must also contain a column |
| 205545 | ** named "rbu_rowid". This column is mapped to the tables implicit primary | 212555 | ** named "rbu_rowid". This column is mapped to the table's implicit primary |
| 205546 | ** key column - "rowid". Virtual tables for which the "rowid" column does | 212556 | ** key column - "rowid". Virtual tables for which the "rowid" column does |
| 205547 | ** not function like a primary key value cannot be updated using RBU. For | 212557 | ** not function like a primary key value cannot be updated using RBU. For |
| 205548 | ** example, if the target db contains either of the following: | 212558 | ** example, if the target db contains either of the following: |
| @@ -205976,6 +212986,34 @@ SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo); | |||
| 205976 | SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu); | 212986 | SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu); |
| 205977 | 212987 | ||
| 205978 | /* | 212988 | /* |
| 212989 | ** As part of applying an RBU update or performing an RBU vacuum operation, | ||
| 212990 | ** the system must at one point move the *-oal file to the equivalent *-wal | ||
| 212991 | ** path. Normally, it does this by invoking POSIX function rename(2) directly. | ||
| 212992 | ** Except on WINCE platforms, where it uses win32 API MoveFileW(). This | ||
| 212993 | ** function may be used to register a callback that the RBU module will invoke | ||
| 212994 | ** instead of one of these APIs. | ||
| 212995 | ** | ||
| 212996 | ** If a callback is registered with an RBU handle, it invokes it instead | ||
| 212997 | ** of rename(2) when it needs to move a file within the file-system. The | ||
| 212998 | ** first argument passed to the xRename() callback is a copy of the second | ||
| 212999 | ** argument (pArg) passed to this function. The second is the full path | ||
| 213000 | ** to the file to move and the third the full path to which it should be | ||
| 213001 | ** moved. The callback function should return SQLITE_OK to indicate | ||
| 213002 | ** success. If an error occurs, it should return an SQLite error code. | ||
| 213003 | ** In this case the RBU operation will be abandoned and the error returned | ||
| 213004 | ** to the RBU user. | ||
| 213005 | ** | ||
| 213006 | ** Passing a NULL pointer in place of the xRename argument to this function | ||
| 213007 | ** restores the default behaviour. | ||
| 213008 | */ | ||
| 213009 | SQLITE_API void sqlite3rbu_rename_handler( | ||
| 213010 | sqlite3rbu *pRbu, | ||
| 213011 | void *pArg, | ||
| 213012 | int (*xRename)(void *pArg, const char *zOld, const char *zNew) | ||
| 213013 | ); | ||
| 213014 | |||
| 213015 | |||
| 213016 | /* | ||
| 205979 | ** Create an RBU VFS named zName that accesses the underlying file-system | 213017 | ** Create an RBU VFS named zName that accesses the underlying file-system |
| 205980 | ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, | 213018 | ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, |
| 205981 | ** then the new RBU VFS uses the default system VFS to access the file-system. | 213019 | ** then the new RBU VFS uses the default system VFS to access the file-system. |
| @@ -206342,6 +213380,8 @@ struct sqlite3rbu { | |||
| 206342 | int nPagePerSector; /* Pages per sector for pTargetFd */ | 213380 | int nPagePerSector; /* Pages per sector for pTargetFd */ |
| 206343 | i64 iOalSz; | 213381 | i64 iOalSz; |
| 206344 | i64 nPhaseOneStep; | 213382 | i64 nPhaseOneStep; |
| 213383 | void *pRenameArg; | ||
| 213384 | int (*xRename)(void*, const char*, const char*); | ||
| 206345 | 213385 | ||
| 206346 | /* The following state variables are used as part of the incremental | 213386 | /* The following state variables are used as part of the incremental |
| 206347 | ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding | 213387 | ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding |
| @@ -208730,7 +215770,7 @@ static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){ | |||
| 208730 | sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); | 215770 | sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); |
| 208731 | if( p->zState==0 ){ | 215771 | if( p->zState==0 ){ |
| 208732 | const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); | 215772 | const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); |
| 208733 | p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile); | 215773 | p->zState = rbuMPrintf(p, "file:///%s-vacuum?modeof=%s", zFile, zFile); |
| 208734 | } | 215774 | } |
| 208735 | } | 215775 | } |
| 208736 | 215776 | ||
| @@ -208978,11 +216018,11 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ | |||
| 208978 | ** no-ops. These locks will not be released until the connection | 216018 | ** no-ops. These locks will not be released until the connection |
| 208979 | ** is closed. | 216019 | ** is closed. |
| 208980 | ** | 216020 | ** |
| 208981 | ** * Attempting to xSync() the database file causes an SQLITE_INTERNAL | 216021 | ** * Attempting to xSync() the database file causes an SQLITE_NOTICE |
| 208982 | ** error. | 216022 | ** error. |
| 208983 | ** | 216023 | ** |
| 208984 | ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the | 216024 | ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the |
| 208985 | ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[] | 216025 | ** checkpoint below fails with SQLITE_NOTICE, and leaves the aFrame[] |
| 208986 | ** array populated with a set of (frame -> page) mappings. Because the | 216026 | ** array populated with a set of (frame -> page) mappings. Because the |
| 208987 | ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy | 216027 | ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy |
| 208988 | ** data from the wal file into the database file according to the | 216028 | ** data from the wal file into the database file according to the |
| @@ -208992,7 +216032,7 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ | |||
| 208992 | int rc2; | 216032 | int rc2; |
| 208993 | p->eStage = RBU_STAGE_CAPTURE; | 216033 | p->eStage = RBU_STAGE_CAPTURE; |
| 208994 | rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); | 216034 | rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); |
| 208995 | if( rc2!=SQLITE_INTERNAL ) p->rc = rc2; | 216035 | if( rc2!=SQLITE_NOTICE ) p->rc = rc2; |
| 208996 | } | 216036 | } |
| 208997 | 216037 | ||
| 208998 | if( p->rc==SQLITE_OK && p->nFrame>0 ){ | 216038 | if( p->rc==SQLITE_OK && p->nFrame>0 ){ |
| @@ -209038,7 +216078,7 @@ static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){ | |||
| 209038 | 216078 | ||
| 209039 | if( pRbu->mLock!=mReq ){ | 216079 | if( pRbu->mLock!=mReq ){ |
| 209040 | pRbu->rc = SQLITE_BUSY; | 216080 | pRbu->rc = SQLITE_BUSY; |
| 209041 | return SQLITE_INTERNAL; | 216081 | return SQLITE_NOTICE_RBU; |
| 209042 | } | 216082 | } |
| 209043 | 216083 | ||
| 209044 | pRbu->pgsz = iAmt; | 216084 | pRbu->pgsz = iAmt; |
| @@ -209088,6 +216128,11 @@ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){ | |||
| 209088 | p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff); | 216128 | p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff); |
| 209089 | } | 216129 | } |
| 209090 | 216130 | ||
| 216131 | /* | ||
| 216132 | ** This value is copied from the definition of ZIPVFS_CTRL_FILE_POINTER | ||
| 216133 | ** in zipvfs.h. | ||
| 216134 | */ | ||
| 216135 | #define RBU_ZIPVFS_CTRL_FILE_POINTER 230439 | ||
| 209091 | 216136 | ||
| 209092 | /* | 216137 | /* |
| 209093 | ** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if | 216138 | ** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if |
| @@ -209096,9 +216141,20 @@ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){ | |||
| 209096 | static int rbuLockDatabase(sqlite3 *db){ | 216141 | static int rbuLockDatabase(sqlite3 *db){ |
| 209097 | int rc = SQLITE_OK; | 216142 | int rc = SQLITE_OK; |
| 209098 | sqlite3_file *fd = 0; | 216143 | sqlite3_file *fd = 0; |
| 209099 | sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); | ||
| 209100 | 216144 | ||
| 209101 | if( fd->pMethods ){ | 216145 | sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd); |
| 216146 | if( fd ){ | ||
| 216147 | sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); | ||
| 216148 | rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); | ||
| 216149 | if( rc==SQLITE_OK ){ | ||
| 216150 | rc = fd->pMethods->xUnlock(fd, SQLITE_LOCK_NONE); | ||
| 216151 | } | ||
| 216152 | sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd); | ||
| 216153 | }else{ | ||
| 216154 | sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); | ||
| 216155 | } | ||
| 216156 | |||
| 216157 | if( rc==SQLITE_OK && fd->pMethods ){ | ||
| 209102 | rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); | 216158 | rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); |
| 209103 | if( rc==SQLITE_OK ){ | 216159 | if( rc==SQLITE_OK ){ |
| 209104 | rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE); | 216160 | rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE); |
| @@ -209190,32 +216246,7 @@ static void rbuMoveOalFile(sqlite3rbu *p){ | |||
| 209190 | } | 216246 | } |
| 209191 | 216247 | ||
| 209192 | if( p->rc==SQLITE_OK ){ | 216248 | if( p->rc==SQLITE_OK ){ |
| 209193 | #if defined(_WIN32_WCE) | 216249 | p->rc = p->xRename(p->pRenameArg, zOal, zWal); |
| 209194 | { | ||
| 209195 | LPWSTR zWideOal; | ||
| 209196 | LPWSTR zWideWal; | ||
| 209197 | |||
| 209198 | zWideOal = rbuWinUtf8ToUnicode(zOal); | ||
| 209199 | if( zWideOal ){ | ||
| 209200 | zWideWal = rbuWinUtf8ToUnicode(zWal); | ||
| 209201 | if( zWideWal ){ | ||
| 209202 | if( MoveFileW(zWideOal, zWideWal) ){ | ||
| 209203 | p->rc = SQLITE_OK; | ||
| 209204 | }else{ | ||
| 209205 | p->rc = SQLITE_IOERR; | ||
| 209206 | } | ||
| 209207 | sqlite3_free(zWideWal); | ||
| 209208 | }else{ | ||
| 209209 | p->rc = SQLITE_IOERR_NOMEM; | ||
| 209210 | } | ||
| 209211 | sqlite3_free(zWideOal); | ||
| 209212 | }else{ | ||
| 209213 | p->rc = SQLITE_IOERR_NOMEM; | ||
| 209214 | } | ||
| 209215 | } | ||
| 209216 | #else | ||
| 209217 | p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK; | ||
| 209218 | #endif | ||
| 209219 | } | 216250 | } |
| 209220 | 216251 | ||
| 209221 | if( p->rc!=SQLITE_OK | 216252 | if( p->rc!=SQLITE_OK |
| @@ -209802,7 +216833,8 @@ static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){ | |||
| 209802 | static void rbuDeleteOalFile(sqlite3rbu *p){ | 216833 | static void rbuDeleteOalFile(sqlite3rbu *p){ |
| 209803 | char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget); | 216834 | char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget); |
| 209804 | if( zOal ){ | 216835 | if( zOal ){ |
| 209805 | sqlite3_vfs *pVfs = sqlite3_vfs_find(0); | 216836 | sqlite3_vfs *pVfs = 0; |
| 216837 | sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_VFS_POINTER, &pVfs); | ||
| 209806 | assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 ); | 216838 | assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 ); |
| 209807 | pVfs->xDelete(pVfs, zOal, 0); | 216839 | pVfs->xDelete(pVfs, zOal, 0); |
| 209808 | sqlite3_free(zOal); | 216840 | sqlite3_free(zOal); |
| @@ -209954,6 +216986,7 @@ static sqlite3rbu *openRbuHandle( | |||
| 209954 | 216986 | ||
| 209955 | /* Create the custom VFS. */ | 216987 | /* Create the custom VFS. */ |
| 209956 | memset(p, 0, sizeof(sqlite3rbu)); | 216988 | memset(p, 0, sizeof(sqlite3rbu)); |
| 216989 | sqlite3rbu_rename_handler(p, 0, 0); | ||
| 209957 | rbuCreateVfs(p); | 216990 | rbuCreateVfs(p); |
| 209958 | 216991 | ||
| 209959 | /* Open the target, RBU and state databases */ | 216992 | /* Open the target, RBU and state databases */ |
| @@ -210345,6 +217378,54 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){ | |||
| 210345 | return rc; | 217378 | return rc; |
| 210346 | } | 217379 | } |
| 210347 | 217380 | ||
| 217381 | /* | ||
| 217382 | ** Default xRename callback for RBU. | ||
| 217383 | */ | ||
| 217384 | static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ | ||
| 217385 | int rc = SQLITE_OK; | ||
| 217386 | #if defined(_WIN32_WCE) | ||
| 217387 | { | ||
| 217388 | LPWSTR zWideOld; | ||
| 217389 | LPWSTR zWideNew; | ||
| 217390 | |||
| 217391 | zWideOld = rbuWinUtf8ToUnicode(zOld); | ||
| 217392 | if( zWideOld ){ | ||
| 217393 | zWideNew = rbuWinUtf8ToUnicode(zNew); | ||
| 217394 | if( zWideNew ){ | ||
| 217395 | if( MoveFileW(zWideOld, zWideNew) ){ | ||
| 217396 | rc = SQLITE_OK; | ||
| 217397 | }else{ | ||
| 217398 | rc = SQLITE_IOERR; | ||
| 217399 | } | ||
| 217400 | sqlite3_free(zWideNew); | ||
| 217401 | }else{ | ||
| 217402 | rc = SQLITE_IOERR_NOMEM; | ||
| 217403 | } | ||
| 217404 | sqlite3_free(zWideOld); | ||
| 217405 | }else{ | ||
| 217406 | rc = SQLITE_IOERR_NOMEM; | ||
| 217407 | } | ||
| 217408 | } | ||
| 217409 | #else | ||
| 217410 | rc = rename(zOld, zNew) ? SQLITE_IOERR : SQLITE_OK; | ||
| 217411 | #endif | ||
| 217412 | return rc; | ||
| 217413 | } | ||
| 217414 | |||
| 217415 | SQLITE_API void sqlite3rbu_rename_handler( | ||
| 217416 | sqlite3rbu *pRbu, | ||
| 217417 | void *pArg, | ||
| 217418 | int (*xRename)(void *pArg, const char *zOld, const char *zNew) | ||
| 217419 | ){ | ||
| 217420 | if( xRename ){ | ||
| 217421 | pRbu->xRename = xRename; | ||
| 217422 | pRbu->pRenameArg = pArg; | ||
| 217423 | }else{ | ||
| 217424 | pRbu->xRename = xDefaultRename; | ||
| 217425 | pRbu->pRenameArg = 0; | ||
| 217426 | } | ||
| 217427 | } | ||
| 217428 | |||
| 210348 | /************************************************************************** | 217429 | /************************************************************************** |
| 210349 | ** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour | 217430 | ** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour |
| 210350 | ** of a standard VFS in the following ways: | 217431 | ** of a standard VFS in the following ways: |
| @@ -210401,7 +217482,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){ | |||
| 210401 | ** database file are recorded. xShmLock() calls to unlock the same | 217482 | ** database file are recorded. xShmLock() calls to unlock the same |
| 210402 | ** locks are no-ops (so that once obtained, these locks are never | 217483 | ** locks are no-ops (so that once obtained, these locks are never |
| 210403 | ** relinquished). Finally, calls to xSync() on the target database | 217484 | ** relinquished). Finally, calls to xSync() on the target database |
| 210404 | ** file fail with SQLITE_INTERNAL errors. | 217485 | ** file fail with SQLITE_NOTICE errors. |
| 210405 | */ | 217486 | */ |
| 210406 | 217487 | ||
| 210407 | static void rbuUnlockShm(rbu_file *p){ | 217488 | static void rbuUnlockShm(rbu_file *p){ |
| @@ -210510,9 +217591,12 @@ static int rbuVfsClose(sqlite3_file *pFile){ | |||
| 210510 | sqlite3_free(p->zDel); | 217591 | sqlite3_free(p->zDel); |
| 210511 | 217592 | ||
| 210512 | if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ | 217593 | if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ |
| 217594 | const sqlite3_io_methods *pMeth = p->pReal->pMethods; | ||
| 210513 | rbuMainlistRemove(p); | 217595 | rbuMainlistRemove(p); |
| 210514 | rbuUnlockShm(p); | 217596 | rbuUnlockShm(p); |
| 210515 | p->pReal->pMethods->xShmUnmap(p->pReal, 0); | 217597 | if( pMeth->iVersion>1 && pMeth->xShmUnmap ){ |
| 217598 | pMeth->xShmUnmap(p->pReal, 0); | ||
| 217599 | } | ||
| 210516 | } | 217600 | } |
| 210517 | else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ | 217601 | else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ |
| 210518 | rbuUpdateTempSize(p, 0); | 217602 | rbuUpdateTempSize(p, 0); |
| @@ -210680,7 +217764,7 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){ | |||
| 210680 | rbu_file *p = (rbu_file *)pFile; | 217764 | rbu_file *p = (rbu_file *)pFile; |
| 210681 | if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){ | 217765 | if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){ |
| 210682 | if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ | 217766 | if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ |
| 210683 | return SQLITE_INTERNAL; | 217767 | return SQLITE_NOTICE_RBU; |
| 210684 | } | 217768 | } |
| 210685 | return SQLITE_OK; | 217769 | return SQLITE_OK; |
| 210686 | } | 217770 | } |
| @@ -210971,6 +218055,25 @@ static int rbuVfsOpen( | |||
| 210971 | rbuVfsShmUnmap, /* xShmUnmap */ | 218055 | rbuVfsShmUnmap, /* xShmUnmap */ |
| 210972 | 0, 0 /* xFetch, xUnfetch */ | 218056 | 0, 0 /* xFetch, xUnfetch */ |
| 210973 | }; | 218057 | }; |
| 218058 | static sqlite3_io_methods rbuvfs_io_methods1 = { | ||
| 218059 | 1, /* iVersion */ | ||
| 218060 | rbuVfsClose, /* xClose */ | ||
| 218061 | rbuVfsRead, /* xRead */ | ||
| 218062 | rbuVfsWrite, /* xWrite */ | ||
| 218063 | rbuVfsTruncate, /* xTruncate */ | ||
| 218064 | rbuVfsSync, /* xSync */ | ||
| 218065 | rbuVfsFileSize, /* xFileSize */ | ||
| 218066 | rbuVfsLock, /* xLock */ | ||
| 218067 | rbuVfsUnlock, /* xUnlock */ | ||
| 218068 | rbuVfsCheckReservedLock, /* xCheckReservedLock */ | ||
| 218069 | rbuVfsFileControl, /* xFileControl */ | ||
| 218070 | rbuVfsSectorSize, /* xSectorSize */ | ||
| 218071 | rbuVfsDeviceCharacteristics, /* xDeviceCharacteristics */ | ||
| 218072 | 0, 0, 0, 0, 0, 0 | ||
| 218073 | }; | ||
| 218074 | |||
| 218075 | |||
| 218076 | |||
| 210974 | rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; | 218077 | rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; |
| 210975 | sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; | 218078 | sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; |
| 210976 | rbu_file *pFd = (rbu_file *)pFile; | 218079 | rbu_file *pFd = (rbu_file *)pFile; |
| @@ -211025,10 +218128,15 @@ static int rbuVfsOpen( | |||
| 211025 | rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags); | 218128 | rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags); |
| 211026 | } | 218129 | } |
| 211027 | if( pFd->pReal->pMethods ){ | 218130 | if( pFd->pReal->pMethods ){ |
| 218131 | const sqlite3_io_methods *pMeth = pFd->pReal->pMethods; | ||
| 211028 | /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods | 218132 | /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods |
| 211029 | ** pointer and, if the file is a main database file, link it into the | 218133 | ** pointer and, if the file is a main database file, link it into the |
| 211030 | ** mutex protected linked list of all such files. */ | 218134 | ** mutex protected linked list of all such files. */ |
| 211031 | pFile->pMethods = &rbuvfs_io_methods; | 218135 | if( pMeth->iVersion<2 || pMeth->xShmLock==0 ){ |
| 218136 | pFile->pMethods = &rbuvfs_io_methods1; | ||
| 218137 | }else{ | ||
| 218138 | pFile->pMethods = &rbuvfs_io_methods; | ||
| 218139 | } | ||
| 211032 | if( flags & SQLITE_OPEN_MAIN_DB ){ | 218140 | if( flags & SQLITE_OPEN_MAIN_DB ){ |
| 211033 | rbuMainlistAdd(pFd); | 218141 | rbuMainlistAdd(pFd); |
| 211034 | } | 218142 | } |
| @@ -211461,6 +218569,7 @@ static int statConnect( | |||
| 211461 | StatTable *pTab = 0; | 218569 | StatTable *pTab = 0; |
| 211462 | int rc = SQLITE_OK; | 218570 | int rc = SQLITE_OK; |
| 211463 | int iDb; | 218571 | int iDb; |
| 218572 | (void)pAux; | ||
| 211464 | 218573 | ||
| 211465 | if( argc>=4 ){ | 218574 | if( argc>=4 ){ |
| 211466 | Token nm; | 218575 | Token nm; |
| @@ -211514,6 +218623,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | |||
| 211514 | int iSchema = -1; | 218623 | int iSchema = -1; |
| 211515 | int iName = -1; | 218624 | int iName = -1; |
| 211516 | int iAgg = -1; | 218625 | int iAgg = -1; |
| 218626 | (void)tab; | ||
| 211517 | 218627 | ||
| 211518 | /* Look for a valid schema=? constraint. If found, change the idxNum to | 218628 | /* Look for a valid schema=? constraint. If found, change the idxNum to |
| 211519 | ** 1 and request the value of that constraint be sent to xFilter. And | 218629 | ** 1 and request the value of that constraint be sent to xFilter. And |
| @@ -212039,6 +219149,8 @@ static int statFilter( | |||
| 212039 | int iArg = 0; /* Count of argv[] parameters used so far */ | 219149 | int iArg = 0; /* Count of argv[] parameters used so far */ |
| 212040 | int rc = SQLITE_OK; /* Result of this operation */ | 219150 | int rc = SQLITE_OK; /* Result of this operation */ |
| 212041 | const char *zName = 0; /* Only provide analysis of this table */ | 219151 | const char *zName = 0; /* Only provide analysis of this table */ |
| 219152 | (void)argc; | ||
| 219153 | (void)idxStr; | ||
| 212042 | 219154 | ||
| 212043 | statResetCsr(pCsr); | 219155 | statResetCsr(pCsr); |
| 212044 | sqlite3_finalize(pCsr->pStmt); | 219156 | sqlite3_finalize(pCsr->pStmt); |
| @@ -212122,16 +219234,16 @@ static int statColumn( | |||
| 212122 | } | 219234 | } |
| 212123 | break; | 219235 | break; |
| 212124 | case 4: /* ncell */ | 219236 | case 4: /* ncell */ |
| 212125 | sqlite3_result_int(ctx, pCsr->nCell); | 219237 | sqlite3_result_int64(ctx, pCsr->nCell); |
| 212126 | break; | 219238 | break; |
| 212127 | case 5: /* payload */ | 219239 | case 5: /* payload */ |
| 212128 | sqlite3_result_int(ctx, pCsr->nPayload); | 219240 | sqlite3_result_int64(ctx, pCsr->nPayload); |
| 212129 | break; | 219241 | break; |
| 212130 | case 6: /* unused */ | 219242 | case 6: /* unused */ |
| 212131 | sqlite3_result_int(ctx, pCsr->nUnused); | 219243 | sqlite3_result_int64(ctx, pCsr->nUnused); |
| 212132 | break; | 219244 | break; |
| 212133 | case 7: /* mx_payload */ | 219245 | case 7: /* mx_payload */ |
| 212134 | sqlite3_result_int(ctx, pCsr->nMxPayload); | 219246 | sqlite3_result_int64(ctx, pCsr->nMxPayload); |
| 212135 | break; | 219247 | break; |
| 212136 | case 8: /* pgoffset */ | 219248 | case 8: /* pgoffset */ |
| 212137 | if( !pCsr->isAgg ){ | 219249 | if( !pCsr->isAgg ){ |
| @@ -212139,7 +219251,7 @@ static int statColumn( | |||
| 212139 | } | 219251 | } |
| 212140 | break; | 219252 | break; |
| 212141 | case 9: /* pgsize */ | 219253 | case 9: /* pgsize */ |
| 212142 | sqlite3_result_int(ctx, pCsr->szPage); | 219254 | sqlite3_result_int64(ctx, pCsr->szPage); |
| 212143 | break; | 219255 | break; |
| 212144 | case 10: { /* schema */ | 219256 | case 10: { /* schema */ |
| 212145 | sqlite3 *db = sqlite3_context_db_handle(ctx); | 219257 | sqlite3 *db = sqlite3_context_db_handle(ctx); |
| @@ -212273,8 +219385,13 @@ static int dbpageConnect( | |||
| 212273 | ){ | 219385 | ){ |
| 212274 | DbpageTable *pTab = 0; | 219386 | DbpageTable *pTab = 0; |
| 212275 | int rc = SQLITE_OK; | 219387 | int rc = SQLITE_OK; |
| 219388 | (void)pAux; | ||
| 219389 | (void)argc; | ||
| 219390 | (void)argv; | ||
| 219391 | (void)pzErr; | ||
| 212276 | 219392 | ||
| 212277 | sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); | 219393 | sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); |
| 219394 | sqlite3_vtab_config(db, SQLITE_VTAB_USES_ALL_SCHEMAS); | ||
| 212278 | rc = sqlite3_declare_vtab(db, | 219395 | rc = sqlite3_declare_vtab(db, |
| 212279 | "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); | 219396 | "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); |
| 212280 | if( rc==SQLITE_OK ){ | 219397 | if( rc==SQLITE_OK ){ |
| @@ -212311,6 +219428,7 @@ static int dbpageDisconnect(sqlite3_vtab *pVtab){ | |||
| 212311 | static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | 219428 | static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ |
| 212312 | int i; | 219429 | int i; |
| 212313 | int iPlan = 0; | 219430 | int iPlan = 0; |
| 219431 | (void)tab; | ||
| 212314 | 219432 | ||
| 212315 | /* If there is a schema= constraint, it must be honored. Report a | 219433 | /* If there is a schema= constraint, it must be honored. Report a |
| 212316 | ** ridiculously large estimated cost if the schema= constraint is | 219434 | ** ridiculously large estimated cost if the schema= constraint is |
| @@ -212357,7 +219475,6 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ | |||
| 212357 | ){ | 219475 | ){ |
| 212358 | pIdxInfo->orderByConsumed = 1; | 219476 | pIdxInfo->orderByConsumed = 1; |
| 212359 | } | 219477 | } |
| 212360 | sqlite3VtabUsesAllSchemas(pIdxInfo); | ||
| 212361 | return SQLITE_OK; | 219478 | return SQLITE_OK; |
| 212362 | } | 219479 | } |
| 212363 | 219480 | ||
| @@ -212426,6 +219543,8 @@ static int dbpageFilter( | |||
| 212426 | sqlite3 *db = pTab->db; | 219543 | sqlite3 *db = pTab->db; |
| 212427 | Btree *pBt; | 219544 | Btree *pBt; |
| 212428 | 219545 | ||
| 219546 | (void)idxStr; | ||
| 219547 | |||
| 212429 | /* Default setting is no rows of result */ | 219548 | /* Default setting is no rows of result */ |
| 212430 | pCsr->pgno = 1; | 219549 | pCsr->pgno = 1; |
| 212431 | pCsr->mxPgno = 0; | 219550 | pCsr->mxPgno = 0; |
| @@ -212440,7 +219559,7 @@ static int dbpageFilter( | |||
| 212440 | pCsr->iDb = 0; | 219559 | pCsr->iDb = 0; |
| 212441 | } | 219560 | } |
| 212442 | pBt = db->aDb[pCsr->iDb].pBt; | 219561 | pBt = db->aDb[pCsr->iDb].pBt; |
| 212443 | if( pBt==0 ) return SQLITE_OK; | 219562 | if( NEVER(pBt==0) ) return SQLITE_OK; |
| 212444 | pCsr->pPager = sqlite3BtreePager(pBt); | 219563 | pCsr->pPager = sqlite3BtreePager(pBt); |
| 212445 | pCsr->szPage = sqlite3BtreeGetPageSize(pBt); | 219564 | pCsr->szPage = sqlite3BtreeGetPageSize(pBt); |
| 212446 | pCsr->mxPgno = sqlite3BtreeLastPage(pBt); | 219565 | pCsr->mxPgno = sqlite3BtreeLastPage(pBt); |
| @@ -212475,12 +219594,18 @@ static int dbpageColumn( | |||
| 212475 | } | 219594 | } |
| 212476 | case 1: { /* data */ | 219595 | case 1: { /* data */ |
| 212477 | DbPage *pDbPage = 0; | 219596 | DbPage *pDbPage = 0; |
| 212478 | rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); | 219597 | if( pCsr->pgno==((PENDING_BYTE/pCsr->szPage)+1) ){ |
| 212479 | if( rc==SQLITE_OK ){ | 219598 | /* The pending byte page. Assume it is zeroed out. Attempting to |
| 212480 | sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, | 219599 | ** request this page from the page is an SQLITE_CORRUPT error. */ |
| 212481 | SQLITE_TRANSIENT); | 219600 | sqlite3_result_zeroblob(ctx, pCsr->szPage); |
| 219601 | }else{ | ||
| 219602 | rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); | ||
| 219603 | if( rc==SQLITE_OK ){ | ||
| 219604 | sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, | ||
| 219605 | SQLITE_TRANSIENT); | ||
| 219606 | } | ||
| 219607 | sqlite3PagerUnref(pDbPage); | ||
| 212482 | } | 219608 | } |
| 212483 | sqlite3PagerUnref(pDbPage); | ||
| 212484 | break; | 219609 | break; |
| 212485 | } | 219610 | } |
| 212486 | default: { /* schema */ | 219611 | default: { /* schema */ |
| @@ -212489,7 +219614,7 @@ static int dbpageColumn( | |||
| 212489 | break; | 219614 | break; |
| 212490 | } | 219615 | } |
| 212491 | } | 219616 | } |
| 212492 | return SQLITE_OK; | 219617 | return rc; |
| 212493 | } | 219618 | } |
| 212494 | 219619 | ||
| 212495 | static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ | 219620 | static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ |
| @@ -212515,6 +219640,7 @@ static int dbpageUpdate( | |||
| 212515 | Pager *pPager; | 219640 | Pager *pPager; |
| 212516 | int szPage; | 219641 | int szPage; |
| 212517 | 219642 | ||
| 219643 | (void)pRowid; | ||
| 212518 | if( pTab->db->flags & SQLITE_Defensive ){ | 219644 | if( pTab->db->flags & SQLITE_Defensive ){ |
| 212519 | zErr = "read-only"; | 219645 | zErr = "read-only"; |
| 212520 | goto update_fail; | 219646 | goto update_fail; |
| @@ -212524,18 +219650,20 @@ static int dbpageUpdate( | |||
| 212524 | goto update_fail; | 219650 | goto update_fail; |
| 212525 | } | 219651 | } |
| 212526 | pgno = sqlite3_value_int(argv[0]); | 219652 | pgno = sqlite3_value_int(argv[0]); |
| 212527 | if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ | 219653 | if( sqlite3_value_type(argv[0])==SQLITE_NULL |
| 219654 | || (Pgno)sqlite3_value_int(argv[1])!=pgno | ||
| 219655 | ){ | ||
| 212528 | zErr = "cannot insert"; | 219656 | zErr = "cannot insert"; |
| 212529 | goto update_fail; | 219657 | goto update_fail; |
| 212530 | } | 219658 | } |
| 212531 | zSchema = (const char*)sqlite3_value_text(argv[4]); | 219659 | zSchema = (const char*)sqlite3_value_text(argv[4]); |
| 212532 | iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1; | 219660 | iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1; |
| 212533 | if( iDb<0 ){ | 219661 | if( NEVER(iDb<0) ){ |
| 212534 | zErr = "no such schema"; | 219662 | zErr = "no such schema"; |
| 212535 | goto update_fail; | 219663 | goto update_fail; |
| 212536 | } | 219664 | } |
| 212537 | pBt = pTab->db->aDb[iDb].pBt; | 219665 | pBt = pTab->db->aDb[iDb].pBt; |
| 212538 | if( pgno<1 || pBt==0 || pgno>sqlite3BtreeLastPage(pBt) ){ | 219666 | if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){ |
| 212539 | zErr = "bad page number"; | 219667 | zErr = "bad page number"; |
| 212540 | goto update_fail; | 219668 | goto update_fail; |
| 212541 | } | 219669 | } |
| @@ -212549,11 +219677,12 @@ static int dbpageUpdate( | |||
| 212549 | pPager = sqlite3BtreePager(pBt); | 219677 | pPager = sqlite3BtreePager(pBt); |
| 212550 | rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); | 219678 | rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); |
| 212551 | if( rc==SQLITE_OK ){ | 219679 | if( rc==SQLITE_OK ){ |
| 212552 | rc = sqlite3PagerWrite(pDbPage); | 219680 | const void *pData = sqlite3_value_blob(argv[3]); |
| 212553 | if( rc==SQLITE_OK ){ | 219681 | assert( pData!=0 || pTab->db->mallocFailed ); |
| 212554 | memcpy(sqlite3PagerGetData(pDbPage), | 219682 | if( pData |
| 212555 | sqlite3_value_blob(argv[3]), | 219683 | && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK |
| 212556 | szPage); | 219684 | ){ |
| 219685 | memcpy(sqlite3PagerGetData(pDbPage), pData, szPage); | ||
| 212557 | } | 219686 | } |
| 212558 | } | 219687 | } |
| 212559 | sqlite3PagerUnref(pDbPage); | 219688 | sqlite3PagerUnref(pDbPage); |
| @@ -212575,7 +219704,7 @@ static int dbpageBegin(sqlite3_vtab *pVtab){ | |||
| 212575 | int i; | 219704 | int i; |
| 212576 | for(i=0; i<db->nDb; i++){ | 219705 | for(i=0; i<db->nDb; i++){ |
| 212577 | Btree *pBt = db->aDb[i].pBt; | 219706 | Btree *pBt = db->aDb[i].pBt; |
| 212578 | if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); | 219707 | if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); |
| 212579 | } | 219708 | } |
| 212580 | return SQLITE_OK; | 219709 | return SQLITE_OK; |
| 212581 | } | 219710 | } |
| @@ -212646,6 +219775,8 @@ typedef struct SessionInput SessionInput; | |||
| 212646 | # endif | 219775 | # endif |
| 212647 | #endif | 219776 | #endif |
| 212648 | 219777 | ||
| 219778 | #define SESSIONS_ROWID "_rowid_" | ||
| 219779 | |||
| 212649 | static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE; | 219780 | static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE; |
| 212650 | 219781 | ||
| 212651 | typedef struct SessionHook SessionHook; | 219782 | typedef struct SessionHook SessionHook; |
| @@ -212667,6 +219798,7 @@ struct sqlite3_session { | |||
| 212667 | int bEnable; /* True if currently recording */ | 219798 | int bEnable; /* True if currently recording */ |
| 212668 | int bIndirect; /* True if all changes are indirect */ | 219799 | int bIndirect; /* True if all changes are indirect */ |
| 212669 | int bAutoAttach; /* True to auto-attach tables */ | 219800 | int bAutoAttach; /* True to auto-attach tables */ |
| 219801 | int bImplicitPK; /* True to handle tables with implicit PK */ | ||
| 212670 | int rc; /* Non-zero if an error has occurred */ | 219802 | int rc; /* Non-zero if an error has occurred */ |
| 212671 | void *pFilterCtx; /* First argument to pass to xTableFilter */ | 219803 | void *pFilterCtx; /* First argument to pass to xTableFilter */ |
| 212672 | int (*xTableFilter)(void *pCtx, const char *zTab); | 219804 | int (*xTableFilter)(void *pCtx, const char *zTab); |
| @@ -212743,6 +219875,7 @@ struct SessionTable { | |||
| 212743 | char *zName; /* Local name of table */ | 219875 | char *zName; /* Local name of table */ |
| 212744 | int nCol; /* Number of columns in table zName */ | 219876 | int nCol; /* Number of columns in table zName */ |
| 212745 | int bStat1; /* True if this is sqlite_stat1 */ | 219877 | int bStat1; /* True if this is sqlite_stat1 */ |
| 219878 | int bRowid; /* True if this table uses rowid for PK */ | ||
| 212746 | const char **azCol; /* Column names */ | 219879 | const char **azCol; /* Column names */ |
| 212747 | u8 *abPK; /* Array of primary key flags */ | 219880 | u8 *abPK; /* Array of primary key flags */ |
| 212748 | int nEntry; /* Total number of entries in hash table */ | 219881 | int nEntry; /* Total number of entries in hash table */ |
| @@ -213135,6 +220268,7 @@ static unsigned int sessionHashAppendType(unsigned int h, int eType){ | |||
| 213135 | */ | 220268 | */ |
| 213136 | static int sessionPreupdateHash( | 220269 | static int sessionPreupdateHash( |
| 213137 | sqlite3_session *pSession, /* Session object that owns pTab */ | 220270 | sqlite3_session *pSession, /* Session object that owns pTab */ |
| 220271 | i64 iRowid, | ||
| 213138 | SessionTable *pTab, /* Session table handle */ | 220272 | SessionTable *pTab, /* Session table handle */ |
| 213139 | int bNew, /* True to hash the new.* PK */ | 220273 | int bNew, /* True to hash the new.* PK */ |
| 213140 | int *piHash, /* OUT: Hash value */ | 220274 | int *piHash, /* OUT: Hash value */ |
| @@ -213143,48 +220277,53 @@ static int sessionPreupdateHash( | |||
| 213143 | unsigned int h = 0; /* Hash value to return */ | 220277 | unsigned int h = 0; /* Hash value to return */ |
| 213144 | int i; /* Used to iterate through columns */ | 220278 | int i; /* Used to iterate through columns */ |
| 213145 | 220279 | ||
| 213146 | assert( *pbNullPK==0 ); | 220280 | if( pTab->bRowid ){ |
| 213147 | assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) ); | 220281 | assert( pTab->nCol-1==pSession->hook.xCount(pSession->hook.pCtx) ); |
| 213148 | for(i=0; i<pTab->nCol; i++){ | 220282 | h = sessionHashAppendI64(h, iRowid); |
| 213149 | if( pTab->abPK[i] ){ | 220283 | }else{ |
| 213150 | int rc; | 220284 | assert( *pbNullPK==0 ); |
| 213151 | int eType; | 220285 | assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) ); |
| 213152 | sqlite3_value *pVal; | 220286 | for(i=0; i<pTab->nCol; i++){ |
| 213153 | 220287 | if( pTab->abPK[i] ){ | |
| 213154 | if( bNew ){ | 220288 | int rc; |
| 213155 | rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal); | 220289 | int eType; |
| 213156 | }else{ | 220290 | sqlite3_value *pVal; |
| 213157 | rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal); | ||
| 213158 | } | ||
| 213159 | if( rc!=SQLITE_OK ) return rc; | ||
| 213160 | 220291 | ||
| 213161 | eType = sqlite3_value_type(pVal); | 220292 | if( bNew ){ |
| 213162 | h = sessionHashAppendType(h, eType); | 220293 | rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal); |
| 213163 | if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ | ||
| 213164 | i64 iVal; | ||
| 213165 | if( eType==SQLITE_INTEGER ){ | ||
| 213166 | iVal = sqlite3_value_int64(pVal); | ||
| 213167 | }else{ | 220294 | }else{ |
| 213168 | double rVal = sqlite3_value_double(pVal); | 220295 | rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal); |
| 213169 | assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); | ||
| 213170 | memcpy(&iVal, &rVal, 8); | ||
| 213171 | } | 220296 | } |
| 213172 | h = sessionHashAppendI64(h, iVal); | 220297 | if( rc!=SQLITE_OK ) return rc; |
| 213173 | }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ | 220298 | |
| 213174 | const u8 *z; | 220299 | eType = sqlite3_value_type(pVal); |
| 213175 | int n; | 220300 | h = sessionHashAppendType(h, eType); |
| 213176 | if( eType==SQLITE_TEXT ){ | 220301 | if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ |
| 213177 | z = (const u8 *)sqlite3_value_text(pVal); | 220302 | i64 iVal; |
| 220303 | if( eType==SQLITE_INTEGER ){ | ||
| 220304 | iVal = sqlite3_value_int64(pVal); | ||
| 220305 | }else{ | ||
| 220306 | double rVal = sqlite3_value_double(pVal); | ||
| 220307 | assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); | ||
| 220308 | memcpy(&iVal, &rVal, 8); | ||
| 220309 | } | ||
| 220310 | h = sessionHashAppendI64(h, iVal); | ||
| 220311 | }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ | ||
| 220312 | const u8 *z; | ||
| 220313 | int n; | ||
| 220314 | if( eType==SQLITE_TEXT ){ | ||
| 220315 | z = (const u8 *)sqlite3_value_text(pVal); | ||
| 220316 | }else{ | ||
| 220317 | z = (const u8 *)sqlite3_value_blob(pVal); | ||
| 220318 | } | ||
| 220319 | n = sqlite3_value_bytes(pVal); | ||
| 220320 | if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; | ||
| 220321 | h = sessionHashAppendBlob(h, n, z); | ||
| 213178 | }else{ | 220322 | }else{ |
| 213179 | z = (const u8 *)sqlite3_value_blob(pVal); | 220323 | assert( eType==SQLITE_NULL ); |
| 220324 | assert( pTab->bStat1==0 || i!=1 ); | ||
| 220325 | *pbNullPK = 1; | ||
| 213180 | } | 220326 | } |
| 213181 | n = sqlite3_value_bytes(pVal); | ||
| 213182 | if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; | ||
| 213183 | h = sessionHashAppendBlob(h, n, z); | ||
| 213184 | }else{ | ||
| 213185 | assert( eType==SQLITE_NULL ); | ||
| 213186 | assert( pTab->bStat1==0 || i!=1 ); | ||
| 213187 | *pbNullPK = 1; | ||
| 213188 | } | 220327 | } |
| 213189 | } | 220328 | } |
| 213190 | } | 220329 | } |
| @@ -213467,6 +220606,7 @@ static int sessionMergeUpdate( | |||
| 213467 | */ | 220606 | */ |
| 213468 | static int sessionPreupdateEqual( | 220607 | static int sessionPreupdateEqual( |
| 213469 | sqlite3_session *pSession, /* Session object that owns SessionTable */ | 220608 | sqlite3_session *pSession, /* Session object that owns SessionTable */ |
| 220609 | i64 iRowid, /* Rowid value if pTab->bRowid */ | ||
| 213470 | SessionTable *pTab, /* Table associated with change */ | 220610 | SessionTable *pTab, /* Table associated with change */ |
| 213471 | SessionChange *pChange, /* Change to compare to */ | 220611 | SessionChange *pChange, /* Change to compare to */ |
| 213472 | int op /* Current pre-update operation */ | 220612 | int op /* Current pre-update operation */ |
| @@ -213474,6 +220614,11 @@ static int sessionPreupdateEqual( | |||
| 213474 | int iCol; /* Used to iterate through columns */ | 220614 | int iCol; /* Used to iterate through columns */ |
| 213475 | u8 *a = pChange->aRecord; /* Cursor used to scan change record */ | 220615 | u8 *a = pChange->aRecord; /* Cursor used to scan change record */ |
| 213476 | 220616 | ||
| 220617 | if( pTab->bRowid ){ | ||
| 220618 | if( a[0]!=SQLITE_INTEGER ) return 0; | ||
| 220619 | return sessionGetI64(&a[1])==iRowid; | ||
| 220620 | } | ||
| 220621 | |||
| 213477 | assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); | 220622 | assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); |
| 213478 | for(iCol=0; iCol<pTab->nCol; iCol++){ | 220623 | for(iCol=0; iCol<pTab->nCol; iCol++){ |
| 213479 | if( !pTab->abPK[iCol] ){ | 220624 | if( !pTab->abPK[iCol] ){ |
| @@ -213496,6 +220641,7 @@ static int sessionPreupdateEqual( | |||
| 213496 | rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal); | 220641 | rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal); |
| 213497 | } | 220642 | } |
| 213498 | assert( rc==SQLITE_OK ); | 220643 | assert( rc==SQLITE_OK ); |
| 220644 | (void)rc; /* Suppress warning about unused variable */ | ||
| 213499 | if( sqlite3_value_type(pVal)!=eType ) return 0; | 220645 | if( sqlite3_value_type(pVal)!=eType ) return 0; |
| 213500 | 220646 | ||
| 213501 | /* A SessionChange object never has a NULL value in a PK column */ | 220647 | /* A SessionChange object never has a NULL value in a PK column */ |
| @@ -213618,7 +220764,8 @@ static int sessionTableInfo( | |||
| 213618 | int *pnCol, /* OUT: number of columns */ | 220764 | int *pnCol, /* OUT: number of columns */ |
| 213619 | const char **pzTab, /* OUT: Copy of zThis */ | 220765 | const char **pzTab, /* OUT: Copy of zThis */ |
| 213620 | const char ***pazCol, /* OUT: Array of column names for table */ | 220766 | const char ***pazCol, /* OUT: Array of column names for table */ |
| 213621 | u8 **pabPK /* OUT: Array of booleans - true for PK col */ | 220767 | u8 **pabPK, /* OUT: Array of booleans - true for PK col */ |
| 220768 | int *pbRowid /* OUT: True if only PK is a rowid */ | ||
| 213622 | ){ | 220769 | ){ |
| 213623 | char *zPragma; | 220770 | char *zPragma; |
| 213624 | sqlite3_stmt *pStmt; | 220771 | sqlite3_stmt *pStmt; |
| @@ -213630,6 +220777,7 @@ static int sessionTableInfo( | |||
| 213630 | u8 *pAlloc = 0; | 220777 | u8 *pAlloc = 0; |
| 213631 | char **azCol = 0; | 220778 | char **azCol = 0; |
| 213632 | u8 *abPK = 0; | 220779 | u8 *abPK = 0; |
| 220780 | int bRowid = 0; /* Set to true to use rowid as PK */ | ||
| 213633 | 220781 | ||
| 213634 | assert( pazCol && pabPK ); | 220782 | assert( pazCol && pabPK ); |
| 213635 | 220783 | ||
| @@ -213674,10 +220822,15 @@ static int sessionTableInfo( | |||
| 213674 | } | 220822 | } |
| 213675 | 220823 | ||
| 213676 | nByte = nThis + 1; | 220824 | nByte = nThis + 1; |
| 220825 | bRowid = (pbRowid!=0); | ||
| 213677 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ | 220826 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 213678 | nByte += sqlite3_column_bytes(pStmt, 1); | 220827 | nByte += sqlite3_column_bytes(pStmt, 1); |
| 213679 | nDbCol++; | 220828 | nDbCol++; |
| 220829 | if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; | ||
| 213680 | } | 220830 | } |
| 220831 | if( nDbCol==0 ) bRowid = 0; | ||
| 220832 | nDbCol += bRowid; | ||
| 220833 | nByte += strlen(SESSIONS_ROWID); | ||
| 213681 | rc = sqlite3_reset(pStmt); | 220834 | rc = sqlite3_reset(pStmt); |
| 213682 | 220835 | ||
| 213683 | if( rc==SQLITE_OK ){ | 220836 | if( rc==SQLITE_OK ){ |
| @@ -213699,6 +220852,14 @@ static int sessionTableInfo( | |||
| 213699 | } | 220852 | } |
| 213700 | 220853 | ||
| 213701 | i = 0; | 220854 | i = 0; |
| 220855 | if( bRowid ){ | ||
| 220856 | size_t nName = strlen(SESSIONS_ROWID); | ||
| 220857 | memcpy(pAlloc, SESSIONS_ROWID, nName+1); | ||
| 220858 | azCol[i] = (char*)pAlloc; | ||
| 220859 | pAlloc += nName+1; | ||
| 220860 | abPK[i] = 1; | ||
| 220861 | i++; | ||
| 220862 | } | ||
| 213702 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ | 220863 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 213703 | int nName = sqlite3_column_bytes(pStmt, 1); | 220864 | int nName = sqlite3_column_bytes(pStmt, 1); |
| 213704 | const unsigned char *zName = sqlite3_column_text(pStmt, 1); | 220865 | const unsigned char *zName = sqlite3_column_text(pStmt, 1); |
| @@ -213710,7 +220871,6 @@ static int sessionTableInfo( | |||
| 213710 | i++; | 220871 | i++; |
| 213711 | } | 220872 | } |
| 213712 | rc = sqlite3_reset(pStmt); | 220873 | rc = sqlite3_reset(pStmt); |
| 213713 | |||
| 213714 | } | 220874 | } |
| 213715 | 220875 | ||
| 213716 | /* If successful, populate the output variables. Otherwise, zero them and | 220876 | /* If successful, populate the output variables. Otherwise, zero them and |
| @@ -213727,6 +220887,7 @@ static int sessionTableInfo( | |||
| 213727 | if( pzTab ) *pzTab = 0; | 220887 | if( pzTab ) *pzTab = 0; |
| 213728 | sessionFree(pSession, azCol); | 220888 | sessionFree(pSession, azCol); |
| 213729 | } | 220889 | } |
| 220890 | if( pbRowid ) *pbRowid = bRowid; | ||
| 213730 | sqlite3_finalize(pStmt); | 220891 | sqlite3_finalize(pStmt); |
| 213731 | return rc; | 220892 | return rc; |
| 213732 | } | 220893 | } |
| @@ -213748,7 +220909,8 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ | |||
| 213748 | u8 *abPK; | 220909 | u8 *abPK; |
| 213749 | assert( pTab->azCol==0 || pTab->abPK==0 ); | 220910 | assert( pTab->azCol==0 || pTab->abPK==0 ); |
| 213750 | pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, | 220911 | pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, |
| 213751 | pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK | 220912 | pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK, |
| 220913 | (pSession->bImplicitPK ? &pTab->bRowid : 0) | ||
| 213752 | ); | 220914 | ); |
| 213753 | if( pSession->rc==SQLITE_OK ){ | 220915 | if( pSession->rc==SQLITE_OK ){ |
| 213754 | int i; | 220916 | int i; |
| @@ -213820,6 +220982,7 @@ static int sessionUpdateMaxSize( | |||
| 213820 | ){ | 220982 | ){ |
| 213821 | i64 nNew = 2; | 220983 | i64 nNew = 2; |
| 213822 | if( pC->op==SQLITE_INSERT ){ | 220984 | if( pC->op==SQLITE_INSERT ){ |
| 220985 | if( pTab->bRowid ) nNew += 9; | ||
| 213823 | if( op!=SQLITE_DELETE ){ | 220986 | if( op!=SQLITE_DELETE ){ |
| 213824 | int ii; | 220987 | int ii; |
| 213825 | for(ii=0; ii<pTab->nCol; ii++){ | 220988 | for(ii=0; ii<pTab->nCol; ii++){ |
| @@ -213836,12 +220999,16 @@ static int sessionUpdateMaxSize( | |||
| 213836 | }else{ | 220999 | }else{ |
| 213837 | int ii; | 221000 | int ii; |
| 213838 | u8 *pCsr = pC->aRecord; | 221001 | u8 *pCsr = pC->aRecord; |
| 213839 | for(ii=0; ii<pTab->nCol; ii++){ | 221002 | if( pTab->bRowid ){ |
| 221003 | nNew += 9 + 1; | ||
| 221004 | pCsr += 9; | ||
| 221005 | } | ||
| 221006 | for(ii=pTab->bRowid; ii<pTab->nCol; ii++){ | ||
| 213840 | int bChanged = 1; | 221007 | int bChanged = 1; |
| 213841 | int nOld = 0; | 221008 | int nOld = 0; |
| 213842 | int eType; | 221009 | int eType; |
| 213843 | sqlite3_value *p = 0; | 221010 | sqlite3_value *p = 0; |
| 213844 | pSession->hook.xNew(pSession->hook.pCtx, ii, &p); | 221011 | pSession->hook.xNew(pSession->hook.pCtx, ii-pTab->bRowid, &p); |
| 213845 | if( p==0 ){ | 221012 | if( p==0 ){ |
| 213846 | return SQLITE_NOMEM; | 221013 | return SQLITE_NOMEM; |
| 213847 | } | 221014 | } |
| @@ -213920,6 +221087,7 @@ static int sessionUpdateMaxSize( | |||
| 213920 | */ | 221087 | */ |
| 213921 | static void sessionPreupdateOneChange( | 221088 | static void sessionPreupdateOneChange( |
| 213922 | int op, /* One of SQLITE_UPDATE, INSERT, DELETE */ | 221089 | int op, /* One of SQLITE_UPDATE, INSERT, DELETE */ |
| 221090 | i64 iRowid, | ||
| 213923 | sqlite3_session *pSession, /* Session object pTab is attached to */ | 221091 | sqlite3_session *pSession, /* Session object pTab is attached to */ |
| 213924 | SessionTable *pTab /* Table that change applies to */ | 221092 | SessionTable *pTab /* Table that change applies to */ |
| 213925 | ){ | 221093 | ){ |
| @@ -213935,7 +221103,7 @@ static void sessionPreupdateOneChange( | |||
| 213935 | 221103 | ||
| 213936 | /* Check the number of columns in this xPreUpdate call matches the | 221104 | /* Check the number of columns in this xPreUpdate call matches the |
| 213937 | ** number of columns in the table. */ | 221105 | ** number of columns in the table. */ |
| 213938 | if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){ | 221106 | if( (pTab->nCol-pTab->bRowid)!=pSession->hook.xCount(pSession->hook.pCtx) ){ |
| 213939 | pSession->rc = SQLITE_SCHEMA; | 221107 | pSession->rc = SQLITE_SCHEMA; |
| 213940 | return; | 221108 | return; |
| 213941 | } | 221109 | } |
| @@ -213968,14 +221136,16 @@ static void sessionPreupdateOneChange( | |||
| 213968 | /* Calculate the hash-key for this change. If the primary key of the row | 221136 | /* Calculate the hash-key for this change. If the primary key of the row |
| 213969 | ** includes a NULL value, exit early. Such changes are ignored by the | 221137 | ** includes a NULL value, exit early. Such changes are ignored by the |
| 213970 | ** session module. */ | 221138 | ** session module. */ |
| 213971 | rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull); | 221139 | rc = sessionPreupdateHash( |
| 221140 | pSession, iRowid, pTab, op==SQLITE_INSERT, &iHash, &bNull | ||
| 221141 | ); | ||
| 213972 | if( rc!=SQLITE_OK ) goto error_out; | 221142 | if( rc!=SQLITE_OK ) goto error_out; |
| 213973 | 221143 | ||
| 213974 | if( bNull==0 ){ | 221144 | if( bNull==0 ){ |
| 213975 | /* Search the hash table for an existing record for this row. */ | 221145 | /* Search the hash table for an existing record for this row. */ |
| 213976 | SessionChange *pC; | 221146 | SessionChange *pC; |
| 213977 | for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ | 221147 | for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ |
| 213978 | if( sessionPreupdateEqual(pSession, pTab, pC, op) ) break; | 221148 | if( sessionPreupdateEqual(pSession, iRowid, pTab, pC, op) ) break; |
| 213979 | } | 221149 | } |
| 213980 | 221150 | ||
| 213981 | if( pC==0 ){ | 221151 | if( pC==0 ){ |
| @@ -213990,7 +221160,7 @@ static void sessionPreupdateOneChange( | |||
| 213990 | 221160 | ||
| 213991 | /* Figure out how large an allocation is required */ | 221161 | /* Figure out how large an allocation is required */ |
| 213992 | nByte = sizeof(SessionChange); | 221162 | nByte = sizeof(SessionChange); |
| 213993 | for(i=0; i<pTab->nCol; i++){ | 221163 | for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ |
| 213994 | sqlite3_value *p = 0; | 221164 | sqlite3_value *p = 0; |
| 213995 | if( op!=SQLITE_INSERT ){ | 221165 | if( op!=SQLITE_INSERT ){ |
| 213996 | TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); | 221166 | TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); |
| @@ -214005,6 +221175,9 @@ static void sessionPreupdateOneChange( | |||
| 214005 | rc = sessionSerializeValue(0, p, &nByte); | 221175 | rc = sessionSerializeValue(0, p, &nByte); |
| 214006 | if( rc!=SQLITE_OK ) goto error_out; | 221176 | if( rc!=SQLITE_OK ) goto error_out; |
| 214007 | } | 221177 | } |
| 221178 | if( pTab->bRowid ){ | ||
| 221179 | nByte += 9; /* Size of rowid field - an integer */ | ||
| 221180 | } | ||
| 214008 | 221181 | ||
| 214009 | /* Allocate the change object */ | 221182 | /* Allocate the change object */ |
| 214010 | pC = (SessionChange *)sessionMalloc64(pSession, nByte); | 221183 | pC = (SessionChange *)sessionMalloc64(pSession, nByte); |
| @@ -214021,7 +221194,12 @@ static void sessionPreupdateOneChange( | |||
| 214021 | ** required values and encodings have already been cached in memory. | 221194 | ** required values and encodings have already been cached in memory. |
| 214022 | ** It is not possible for an OOM to occur in this block. */ | 221195 | ** It is not possible for an OOM to occur in this block. */ |
| 214023 | nByte = 0; | 221196 | nByte = 0; |
| 214024 | for(i=0; i<pTab->nCol; i++){ | 221197 | if( pTab->bRowid ){ |
| 221198 | pC->aRecord[0] = SQLITE_INTEGER; | ||
| 221199 | sessionPutI64(&pC->aRecord[1], iRowid); | ||
| 221200 | nByte = 9; | ||
| 221201 | } | ||
| 221202 | for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ | ||
| 214025 | sqlite3_value *p = 0; | 221203 | sqlite3_value *p = 0; |
| 214026 | if( op!=SQLITE_INSERT ){ | 221204 | if( op!=SQLITE_INSERT ){ |
| 214027 | pSession->hook.xOld(pSession->hook.pCtx, i, &p); | 221205 | pSession->hook.xOld(pSession->hook.pCtx, i, &p); |
| @@ -214120,6 +221298,8 @@ static void xPreUpdate( | |||
| 214120 | int nDb = sqlite3Strlen30(zDb); | 221298 | int nDb = sqlite3Strlen30(zDb); |
| 214121 | 221299 | ||
| 214122 | assert( sqlite3_mutex_held(db->mutex) ); | 221300 | assert( sqlite3_mutex_held(db->mutex) ); |
| 221301 | (void)iKey1; | ||
| 221302 | (void)iKey2; | ||
| 214123 | 221303 | ||
| 214124 | for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ | 221304 | for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ |
| 214125 | SessionTable *pTab; | 221305 | SessionTable *pTab; |
| @@ -214134,9 +221314,10 @@ static void xPreUpdate( | |||
| 214134 | pSession->rc = sessionFindTable(pSession, zName, &pTab); | 221314 | pSession->rc = sessionFindTable(pSession, zName, &pTab); |
| 214135 | if( pTab ){ | 221315 | if( pTab ){ |
| 214136 | assert( pSession->rc==SQLITE_OK ); | 221316 | assert( pSession->rc==SQLITE_OK ); |
| 214137 | sessionPreupdateOneChange(op, pSession, pTab); | 221317 | assert( op==SQLITE_UPDATE || iKey1==iKey2 ); |
| 221318 | sessionPreupdateOneChange(op, iKey1, pSession, pTab); | ||
| 214138 | if( op==SQLITE_UPDATE ){ | 221319 | if( op==SQLITE_UPDATE ){ |
| 214139 | sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab); | 221320 | sessionPreupdateOneChange(SQLITE_INSERT, iKey2, pSession, pTab); |
| 214140 | } | 221321 | } |
| 214141 | } | 221322 | } |
| 214142 | } | 221323 | } |
| @@ -214175,6 +221356,7 @@ static void sessionPreupdateHooks( | |||
| 214175 | typedef struct SessionDiffCtx SessionDiffCtx; | 221356 | typedef struct SessionDiffCtx SessionDiffCtx; |
| 214176 | struct SessionDiffCtx { | 221357 | struct SessionDiffCtx { |
| 214177 | sqlite3_stmt *pStmt; | 221358 | sqlite3_stmt *pStmt; |
| 221359 | int bRowid; | ||
| 214178 | int nOldOff; | 221360 | int nOldOff; |
| 214179 | }; | 221361 | }; |
| 214180 | 221362 | ||
| @@ -214183,19 +221365,20 @@ struct SessionDiffCtx { | |||
| 214183 | */ | 221365 | */ |
| 214184 | static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){ | 221366 | static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){ |
| 214185 | SessionDiffCtx *p = (SessionDiffCtx*)pCtx; | 221367 | SessionDiffCtx *p = (SessionDiffCtx*)pCtx; |
| 214186 | *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff); | 221368 | *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff+p->bRowid); |
| 214187 | return SQLITE_OK; | 221369 | return SQLITE_OK; |
| 214188 | } | 221370 | } |
| 214189 | static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){ | 221371 | static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){ |
| 214190 | SessionDiffCtx *p = (SessionDiffCtx*)pCtx; | 221372 | SessionDiffCtx *p = (SessionDiffCtx*)pCtx; |
| 214191 | *ppVal = sqlite3_column_value(p->pStmt, iVal); | 221373 | *ppVal = sqlite3_column_value(p->pStmt, iVal+p->bRowid); |
| 214192 | return SQLITE_OK; | 221374 | return SQLITE_OK; |
| 214193 | } | 221375 | } |
| 214194 | static int sessionDiffCount(void *pCtx){ | 221376 | static int sessionDiffCount(void *pCtx){ |
| 214195 | SessionDiffCtx *p = (SessionDiffCtx*)pCtx; | 221377 | SessionDiffCtx *p = (SessionDiffCtx*)pCtx; |
| 214196 | return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt); | 221378 | return (p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt)) - p->bRowid; |
| 214197 | } | 221379 | } |
| 214198 | static int sessionDiffDepth(void *pCtx){ | 221380 | static int sessionDiffDepth(void *pCtx){ |
| 221381 | (void)pCtx; | ||
| 214199 | return 0; | 221382 | return 0; |
| 214200 | } | 221383 | } |
| 214201 | 221384 | ||
| @@ -214269,17 +221452,18 @@ static char *sessionExprCompareOther( | |||
| 214269 | } | 221452 | } |
| 214270 | 221453 | ||
| 214271 | static char *sessionSelectFindNew( | 221454 | static char *sessionSelectFindNew( |
| 214272 | int nCol, | ||
| 214273 | const char *zDb1, /* Pick rows in this db only */ | 221455 | const char *zDb1, /* Pick rows in this db only */ |
| 214274 | const char *zDb2, /* But not in this one */ | 221456 | const char *zDb2, /* But not in this one */ |
| 221457 | int bRowid, | ||
| 214275 | const char *zTbl, /* Table name */ | 221458 | const char *zTbl, /* Table name */ |
| 214276 | const char *zExpr | 221459 | const char *zExpr |
| 214277 | ){ | 221460 | ){ |
| 221461 | const char *zSel = (bRowid ? SESSIONS_ROWID ", *" : "*"); | ||
| 214278 | char *zRet = sqlite3_mprintf( | 221462 | char *zRet = sqlite3_mprintf( |
| 214279 | "SELECT * FROM \"%w\".\"%w\" WHERE NOT EXISTS (" | 221463 | "SELECT %s FROM \"%w\".\"%w\" WHERE NOT EXISTS (" |
| 214280 | " SELECT 1 FROM \"%w\".\"%w\" WHERE %s" | 221464 | " SELECT 1 FROM \"%w\".\"%w\" WHERE %s" |
| 214281 | ")", | 221465 | ")", |
| 214282 | zDb1, zTbl, zDb2, zTbl, zExpr | 221466 | zSel, zDb1, zTbl, zDb2, zTbl, zExpr |
| 214283 | ); | 221467 | ); |
| 214284 | return zRet; | 221468 | return zRet; |
| 214285 | } | 221469 | } |
| @@ -214293,7 +221477,9 @@ static int sessionDiffFindNew( | |||
| 214293 | char *zExpr | 221477 | char *zExpr |
| 214294 | ){ | 221478 | ){ |
| 214295 | int rc = SQLITE_OK; | 221479 | int rc = SQLITE_OK; |
| 214296 | char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr); | 221480 | char *zStmt = sessionSelectFindNew( |
| 221481 | zDb1, zDb2, pTab->bRowid, pTab->zName, zExpr | ||
| 221482 | ); | ||
| 214297 | 221483 | ||
| 214298 | if( zStmt==0 ){ | 221484 | if( zStmt==0 ){ |
| 214299 | rc = SQLITE_NOMEM; | 221485 | rc = SQLITE_NOMEM; |
| @@ -214304,8 +221490,10 @@ static int sessionDiffFindNew( | |||
| 214304 | SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; | 221490 | SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; |
| 214305 | pDiffCtx->pStmt = pStmt; | 221491 | pDiffCtx->pStmt = pStmt; |
| 214306 | pDiffCtx->nOldOff = 0; | 221492 | pDiffCtx->nOldOff = 0; |
| 221493 | pDiffCtx->bRowid = pTab->bRowid; | ||
| 214307 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ | 221494 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 214308 | sessionPreupdateOneChange(op, pSession, pTab); | 221495 | i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0); |
| 221496 | sessionPreupdateOneChange(op, iRowid, pSession, pTab); | ||
| 214309 | } | 221497 | } |
| 214310 | rc = sqlite3_finalize(pStmt); | 221498 | rc = sqlite3_finalize(pStmt); |
| 214311 | } | 221499 | } |
| @@ -214315,6 +221503,27 @@ static int sessionDiffFindNew( | |||
| 214315 | return rc; | 221503 | return rc; |
| 214316 | } | 221504 | } |
| 214317 | 221505 | ||
| 221506 | /* | ||
| 221507 | ** Return a comma-separated list of the fully-qualified (with both database | ||
| 221508 | ** and table name) column names from table pTab. e.g. | ||
| 221509 | ** | ||
| 221510 | ** "main"."t1"."a", "main"."t1"."b", "main"."t1"."c" | ||
| 221511 | */ | ||
| 221512 | static char *sessionAllCols( | ||
| 221513 | const char *zDb, | ||
| 221514 | SessionTable *pTab | ||
| 221515 | ){ | ||
| 221516 | int ii; | ||
| 221517 | char *zRet = 0; | ||
| 221518 | for(ii=0; ii<pTab->nCol; ii++){ | ||
| 221519 | zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"", | ||
| 221520 | zRet, (zRet ? ", " : ""), zDb, pTab->zName, pTab->azCol[ii] | ||
| 221521 | ); | ||
| 221522 | if( !zRet ) break; | ||
| 221523 | } | ||
| 221524 | return zRet; | ||
| 221525 | } | ||
| 221526 | |||
| 214318 | static int sessionDiffFindModified( | 221527 | static int sessionDiffFindModified( |
| 214319 | sqlite3_session *pSession, | 221528 | sqlite3_session *pSession, |
| 214320 | SessionTable *pTab, | 221529 | SessionTable *pTab, |
| @@ -214329,11 +221538,13 @@ static int sessionDiffFindModified( | |||
| 214329 | if( zExpr2==0 ){ | 221538 | if( zExpr2==0 ){ |
| 214330 | rc = SQLITE_NOMEM; | 221539 | rc = SQLITE_NOMEM; |
| 214331 | }else{ | 221540 | }else{ |
| 221541 | char *z1 = sessionAllCols(pSession->zDb, pTab); | ||
| 221542 | char *z2 = sessionAllCols(zFrom, pTab); | ||
| 214332 | char *zStmt = sqlite3_mprintf( | 221543 | char *zStmt = sqlite3_mprintf( |
| 214333 | "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)", | 221544 | "SELECT %s,%s FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)", |
| 214334 | pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2 | 221545 | z1, z2, pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2 |
| 214335 | ); | 221546 | ); |
| 214336 | if( zStmt==0 ){ | 221547 | if( zStmt==0 || z1==0 || z2==0 ){ |
| 214337 | rc = SQLITE_NOMEM; | 221548 | rc = SQLITE_NOMEM; |
| 214338 | }else{ | 221549 | }else{ |
| 214339 | sqlite3_stmt *pStmt; | 221550 | sqlite3_stmt *pStmt; |
| @@ -214344,12 +221555,15 @@ static int sessionDiffFindModified( | |||
| 214344 | pDiffCtx->pStmt = pStmt; | 221555 | pDiffCtx->pStmt = pStmt; |
| 214345 | pDiffCtx->nOldOff = pTab->nCol; | 221556 | pDiffCtx->nOldOff = pTab->nCol; |
| 214346 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ | 221557 | while( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 214347 | sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab); | 221558 | i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0); |
| 221559 | sessionPreupdateOneChange(SQLITE_UPDATE, iRowid, pSession, pTab); | ||
| 214348 | } | 221560 | } |
| 214349 | rc = sqlite3_finalize(pStmt); | 221561 | rc = sqlite3_finalize(pStmt); |
| 214350 | } | 221562 | } |
| 214351 | sqlite3_free(zStmt); | ||
| 214352 | } | 221563 | } |
| 221564 | sqlite3_free(zStmt); | ||
| 221565 | sqlite3_free(z1); | ||
| 221566 | sqlite3_free(z2); | ||
| 214353 | } | 221567 | } |
| 214354 | 221568 | ||
| 214355 | return rc; | 221569 | return rc; |
| @@ -214388,9 +221602,12 @@ SQLITE_API int sqlite3session_diff( | |||
| 214388 | int bHasPk = 0; | 221602 | int bHasPk = 0; |
| 214389 | int bMismatch = 0; | 221603 | int bMismatch = 0; |
| 214390 | int nCol; /* Columns in zFrom.zTbl */ | 221604 | int nCol; /* Columns in zFrom.zTbl */ |
| 221605 | int bRowid = 0; | ||
| 214391 | u8 *abPK; | 221606 | u8 *abPK; |
| 214392 | const char **azCol = 0; | 221607 | const char **azCol = 0; |
| 214393 | rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); | 221608 | rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK, |
| 221609 | pSession->bImplicitPK ? &bRowid : 0 | ||
| 221610 | ); | ||
| 214394 | if( rc==SQLITE_OK ){ | 221611 | if( rc==SQLITE_OK ){ |
| 214395 | if( pTo->nCol!=nCol ){ | 221612 | if( pTo->nCol!=nCol ){ |
| 214396 | bMismatch = 1; | 221613 | bMismatch = 1; |
| @@ -214732,9 +221949,10 @@ static void sessionAppendStr( | |||
| 214732 | int *pRc | 221949 | int *pRc |
| 214733 | ){ | 221950 | ){ |
| 214734 | int nStr = sqlite3Strlen30(zStr); | 221951 | int nStr = sqlite3Strlen30(zStr); |
| 214735 | if( 0==sessionBufferGrow(p, nStr, pRc) ){ | 221952 | if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ |
| 214736 | memcpy(&p->aBuf[p->nBuf], zStr, nStr); | 221953 | memcpy(&p->aBuf[p->nBuf], zStr, nStr); |
| 214737 | p->nBuf += nStr; | 221954 | p->nBuf += nStr; |
| 221955 | p->aBuf[p->nBuf] = 0x00; | ||
| 214738 | } | 221956 | } |
| 214739 | } | 221957 | } |
| 214740 | 221958 | ||
| @@ -214756,6 +221974,27 @@ static void sessionAppendInteger( | |||
| 214756 | sessionAppendStr(p, aBuf, pRc); | 221974 | sessionAppendStr(p, aBuf, pRc); |
| 214757 | } | 221975 | } |
| 214758 | 221976 | ||
| 221977 | static void sessionAppendPrintf( | ||
| 221978 | SessionBuffer *p, /* Buffer to append to */ | ||
| 221979 | int *pRc, | ||
| 221980 | const char *zFmt, | ||
| 221981 | ... | ||
| 221982 | ){ | ||
| 221983 | if( *pRc==SQLITE_OK ){ | ||
| 221984 | char *zApp = 0; | ||
| 221985 | va_list ap; | ||
| 221986 | va_start(ap, zFmt); | ||
| 221987 | zApp = sqlite3_vmprintf(zFmt, ap); | ||
| 221988 | if( zApp==0 ){ | ||
| 221989 | *pRc = SQLITE_NOMEM; | ||
| 221990 | }else{ | ||
| 221991 | sessionAppendStr(p, zApp, pRc); | ||
| 221992 | } | ||
| 221993 | va_end(ap); | ||
| 221994 | sqlite3_free(zApp); | ||
| 221995 | } | ||
| 221996 | } | ||
| 221997 | |||
| 214759 | /* | 221998 | /* |
| 214760 | ** This function is a no-op if *pRc is other than SQLITE_OK when it is | 221999 | ** This function is a no-op if *pRc is other than SQLITE_OK when it is |
| 214761 | ** called. Otherwise, append the string zStr enclosed in quotes (") and | 222000 | ** called. Otherwise, append the string zStr enclosed in quotes (") and |
| @@ -214770,7 +222009,7 @@ static void sessionAppendIdent( | |||
| 214770 | const char *zStr, /* String to quote, escape and append */ | 222009 | const char *zStr, /* String to quote, escape and append */ |
| 214771 | int *pRc /* IN/OUT: Error code */ | 222010 | int *pRc /* IN/OUT: Error code */ |
| 214772 | ){ | 222011 | ){ |
| 214773 | int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1; | 222012 | int nStr = sqlite3Strlen30(zStr)*2 + 2 + 2; |
| 214774 | if( 0==sessionBufferGrow(p, nStr, pRc) ){ | 222013 | if( 0==sessionBufferGrow(p, nStr, pRc) ){ |
| 214775 | char *zOut = (char *)&p->aBuf[p->nBuf]; | 222014 | char *zOut = (char *)&p->aBuf[p->nBuf]; |
| 214776 | const char *zIn = zStr; | 222015 | const char *zIn = zStr; |
| @@ -214781,6 +222020,7 @@ static void sessionAppendIdent( | |||
| 214781 | } | 222020 | } |
| 214782 | *zOut++ = '"'; | 222021 | *zOut++ = '"'; |
| 214783 | p->nBuf = (int)((u8 *)zOut - p->aBuf); | 222022 | p->nBuf = (int)((u8 *)zOut - p->aBuf); |
| 222023 | p->aBuf[p->nBuf] = 0x00; | ||
| 214784 | } | 222024 | } |
| 214785 | } | 222025 | } |
| 214786 | 222026 | ||
| @@ -214916,7 +222156,7 @@ static int sessionAppendUpdate( | |||
| 214916 | /* If at least one field has been modified, this is not a no-op. */ | 222156 | /* If at least one field has been modified, this is not a no-op. */ |
| 214917 | if( bChanged ) bNoop = 0; | 222157 | if( bChanged ) bNoop = 0; |
| 214918 | 222158 | ||
| 214919 | /* Add a field to the old.* record. This is omitted if this modules is | 222159 | /* Add a field to the old.* record. This is omitted if this module is |
| 214920 | ** currently generating a patchset. */ | 222160 | ** currently generating a patchset. */ |
| 214921 | if( bPatchset==0 ){ | 222161 | if( bPatchset==0 ){ |
| 214922 | if( bChanged || abPK[i] ){ | 222162 | if( bChanged || abPK[i] ){ |
| @@ -215005,12 +222245,20 @@ static int sessionAppendDelete( | |||
| 215005 | ** Formulate and prepare a SELECT statement to retrieve a row from table | 222245 | ** Formulate and prepare a SELECT statement to retrieve a row from table |
| 215006 | ** zTab in database zDb based on its primary key. i.e. | 222246 | ** zTab in database zDb based on its primary key. i.e. |
| 215007 | ** | 222247 | ** |
| 215008 | ** SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ... | 222248 | ** SELECT *, <noop-test> FROM zDb.zTab WHERE (pk1, pk2,...) IS (?1, ?2,...) |
| 222249 | ** | ||
| 222250 | ** where <noop-test> is: | ||
| 222251 | ** | ||
| 222252 | ** 1 AND (?A OR ?1 IS <column>) AND ... | ||
| 222253 | ** | ||
| 222254 | ** for each non-pk <column>. | ||
| 215009 | */ | 222255 | */ |
| 215010 | static int sessionSelectStmt( | 222256 | static int sessionSelectStmt( |
| 215011 | sqlite3 *db, /* Database handle */ | 222257 | sqlite3 *db, /* Database handle */ |
| 222258 | int bIgnoreNoop, | ||
| 215012 | const char *zDb, /* Database name */ | 222259 | const char *zDb, /* Database name */ |
| 215013 | const char *zTab, /* Table name */ | 222260 | const char *zTab, /* Table name */ |
| 222261 | int bRowid, | ||
| 215014 | int nCol, /* Number of columns in table */ | 222262 | int nCol, /* Number of columns in table */ |
| 215015 | const char **azCol, /* Names of table columns */ | 222263 | const char **azCol, /* Names of table columns */ |
| 215016 | u8 *abPK, /* PRIMARY KEY array */ | 222264 | u8 *abPK, /* PRIMARY KEY array */ |
| @@ -215018,8 +222266,50 @@ static int sessionSelectStmt( | |||
| 215018 | ){ | 222266 | ){ |
| 215019 | int rc = SQLITE_OK; | 222267 | int rc = SQLITE_OK; |
| 215020 | char *zSql = 0; | 222268 | char *zSql = 0; |
| 222269 | const char *zSep = ""; | ||
| 222270 | const char *zCols = bRowid ? SESSIONS_ROWID ", *" : "*"; | ||
| 215021 | int nSql = -1; | 222271 | int nSql = -1; |
| 222272 | int i; | ||
| 222273 | |||
| 222274 | SessionBuffer nooptest = {0, 0, 0}; | ||
| 222275 | SessionBuffer pkfield = {0, 0, 0}; | ||
| 222276 | SessionBuffer pkvar = {0, 0, 0}; | ||
| 222277 | |||
| 222278 | sessionAppendStr(&nooptest, ", 1", &rc); | ||
| 222279 | |||
| 222280 | if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){ | ||
| 222281 | sessionAppendStr(&nooptest, " AND (?6 OR ?3 IS stat)", &rc); | ||
| 222282 | sessionAppendStr(&pkfield, "tbl, idx", &rc); | ||
| 222283 | sessionAppendStr(&pkvar, | ||
| 222284 | "?1, (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", &rc | ||
| 222285 | ); | ||
| 222286 | zCols = "tbl, ?2, stat"; | ||
| 222287 | }else{ | ||
| 222288 | for(i=0; i<nCol; i++){ | ||
| 222289 | if( abPK[i] ){ | ||
| 222290 | sessionAppendStr(&pkfield, zSep, &rc); | ||
| 222291 | sessionAppendStr(&pkvar, zSep, &rc); | ||
| 222292 | zSep = ", "; | ||
| 222293 | sessionAppendIdent(&pkfield, azCol[i], &rc); | ||
| 222294 | sessionAppendPrintf(&pkvar, &rc, "?%d", i+1); | ||
| 222295 | }else{ | ||
| 222296 | sessionAppendPrintf(&nooptest, &rc, | ||
| 222297 | " AND (?%d OR ?%d IS %w.%w)", i+1+nCol, i+1, zTab, azCol[i] | ||
| 222298 | ); | ||
| 222299 | } | ||
| 222300 | } | ||
| 222301 | } | ||
| 222302 | |||
| 222303 | if( rc==SQLITE_OK ){ | ||
| 222304 | zSql = sqlite3_mprintf( | ||
| 222305 | "SELECT %s%s FROM %Q.%Q WHERE (%s) IS (%s)", | ||
| 222306 | zCols, (bIgnoreNoop ? (char*)nooptest.aBuf : ""), | ||
| 222307 | zDb, zTab, (char*)pkfield.aBuf, (char*)pkvar.aBuf | ||
| 222308 | ); | ||
| 222309 | if( zSql==0 ) rc = SQLITE_NOMEM; | ||
| 222310 | } | ||
| 215022 | 222311 | ||
| 222312 | #if 0 | ||
| 215023 | if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){ | 222313 | if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){ |
| 215024 | zSql = sqlite3_mprintf( | 222314 | zSql = sqlite3_mprintf( |
| 215025 | "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND " | 222315 | "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND " |
| @@ -215027,7 +222317,6 @@ static int sessionSelectStmt( | |||
| 215027 | ); | 222317 | ); |
| 215028 | if( zSql==0 ) rc = SQLITE_NOMEM; | 222318 | if( zSql==0 ) rc = SQLITE_NOMEM; |
| 215029 | }else{ | 222319 | }else{ |
| 215030 | int i; | ||
| 215031 | const char *zSep = ""; | 222320 | const char *zSep = ""; |
| 215032 | SessionBuffer buf = {0, 0, 0}; | 222321 | SessionBuffer buf = {0, 0, 0}; |
| 215033 | 222322 | ||
| @@ -215048,11 +222337,15 @@ static int sessionSelectStmt( | |||
| 215048 | zSql = (char*)buf.aBuf; | 222337 | zSql = (char*)buf.aBuf; |
| 215049 | nSql = buf.nBuf; | 222338 | nSql = buf.nBuf; |
| 215050 | } | 222339 | } |
| 222340 | #endif | ||
| 215051 | 222341 | ||
| 215052 | if( rc==SQLITE_OK ){ | 222342 | if( rc==SQLITE_OK ){ |
| 215053 | rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0); | 222343 | rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0); |
| 215054 | } | 222344 | } |
| 215055 | sqlite3_free(zSql); | 222345 | sqlite3_free(zSql); |
| 222346 | sqlite3_free(nooptest.aBuf); | ||
| 222347 | sqlite3_free(pkfield.aBuf); | ||
| 222348 | sqlite3_free(pkvar.aBuf); | ||
| 215056 | return rc; | 222349 | return rc; |
| 215057 | } | 222350 | } |
| 215058 | 222351 | ||
| @@ -215199,10 +222492,18 @@ static int sessionGenerateChangeset( | |||
| 215199 | sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ | 222492 | sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ |
| 215200 | int nRewind = buf.nBuf; /* Initial size of write buffer */ | 222493 | int nRewind = buf.nBuf; /* Initial size of write buffer */ |
| 215201 | int nNoop; /* Size of buffer after writing tbl header */ | 222494 | int nNoop; /* Size of buffer after writing tbl header */ |
| 222495 | int bRowid = 0; | ||
| 215202 | 222496 | ||
| 215203 | /* Check the table schema is still Ok. */ | 222497 | /* Check the table schema is still Ok. */ |
| 215204 | rc = sessionTableInfo(0, db, pSession->zDb, zName, &nCol, 0,&azCol,&abPK); | 222498 | rc = sessionTableInfo( |
| 215205 | if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){ | 222499 | 0, db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK, |
| 222500 | (pSession->bImplicitPK ? &bRowid : 0) | ||
| 222501 | ); | ||
| 222502 | if( rc==SQLITE_OK && ( | ||
| 222503 | pTab->nCol!=nCol | ||
| 222504 | || pTab->bRowid!=bRowid | ||
| 222505 | || memcmp(abPK, pTab->abPK, nCol) | ||
| 222506 | )){ | ||
| 215206 | rc = SQLITE_SCHEMA; | 222507 | rc = SQLITE_SCHEMA; |
| 215207 | } | 222508 | } |
| 215208 | 222509 | ||
| @@ -215212,7 +222513,8 @@ static int sessionGenerateChangeset( | |||
| 215212 | /* Build and compile a statement to execute: */ | 222513 | /* Build and compile a statement to execute: */ |
| 215213 | if( rc==SQLITE_OK ){ | 222514 | if( rc==SQLITE_OK ){ |
| 215214 | rc = sessionSelectStmt( | 222515 | rc = sessionSelectStmt( |
| 215215 | db, pSession->zDb, zName, nCol, azCol, abPK, &pSel); | 222516 | db, 0, pSession->zDb, zName, bRowid, nCol, azCol, abPK, &pSel |
| 222517 | ); | ||
| 215216 | } | 222518 | } |
| 215217 | 222519 | ||
| 215218 | nNoop = buf.nBuf; | 222520 | nNoop = buf.nBuf; |
| @@ -215295,7 +222597,7 @@ SQLITE_API int sqlite3session_changeset( | |||
| 215295 | int rc; | 222597 | int rc; |
| 215296 | 222598 | ||
| 215297 | if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE; | 222599 | if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE; |
| 215298 | rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset); | 222600 | rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset, ppChangeset); |
| 215299 | assert( rc || pnChangeset==0 | 222601 | assert( rc || pnChangeset==0 |
| 215300 | || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize | 222602 | || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize |
| 215301 | ); | 222603 | ); |
| @@ -215413,6 +222715,19 @@ SQLITE_API int sqlite3session_object_config(sqlite3_session *pSession, int op, v | |||
| 215413 | break; | 222715 | break; |
| 215414 | } | 222716 | } |
| 215415 | 222717 | ||
| 222718 | case SQLITE_SESSION_OBJCONFIG_ROWID: { | ||
| 222719 | int iArg = *(int*)pArg; | ||
| 222720 | if( iArg>=0 ){ | ||
| 222721 | if( pSession->pTable ){ | ||
| 222722 | rc = SQLITE_MISUSE; | ||
| 222723 | }else{ | ||
| 222724 | pSession->bImplicitPK = (iArg!=0); | ||
| 222725 | } | ||
| 222726 | } | ||
| 222727 | *(int*)pArg = pSession->bImplicitPK; | ||
| 222728 | break; | ||
| 222729 | } | ||
| 222730 | |||
| 215416 | default: | 222731 | default: |
| 215417 | rc = SQLITE_MISUSE; | 222732 | rc = SQLITE_MISUSE; |
| 215418 | } | 222733 | } |
| @@ -215948,6 +223263,22 @@ static int sessionChangesetNextOne( | |||
| 215948 | if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE; | 223263 | if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE; |
| 215949 | else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT; | 223264 | else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT; |
| 215950 | } | 223265 | } |
| 223266 | |||
| 223267 | /* If this is an UPDATE that is part of a changeset, then check that | ||
| 223268 | ** there are no fields in the old.* record that are not (a) PK fields, | ||
| 223269 | ** or (b) also present in the new.* record. | ||
| 223270 | ** | ||
| 223271 | ** Such records are technically corrupt, but the rebaser was at one | ||
| 223272 | ** point generating them. Under most circumstances this is benign, but | ||
| 223273 | ** can cause spurious SQLITE_RANGE errors when applying the changeset. */ | ||
| 223274 | if( p->bPatchset==0 && p->op==SQLITE_UPDATE){ | ||
| 223275 | for(i=0; i<p->nCol; i++){ | ||
| 223276 | if( p->abPK[i]==0 && p->apValue[i+p->nCol]==0 ){ | ||
| 223277 | sqlite3ValueFree(p->apValue[i]); | ||
| 223278 | p->apValue[i] = 0; | ||
| 223279 | } | ||
| 223280 | } | ||
| 223281 | } | ||
| 215951 | } | 223282 | } |
| 215952 | 223283 | ||
| 215953 | return SQLITE_ROW; | 223284 | return SQLITE_ROW; |
| @@ -216385,6 +223716,8 @@ struct SessionApplyCtx { | |||
| 216385 | SessionBuffer rebase; /* Rebase information (if any) here */ | 223716 | SessionBuffer rebase; /* Rebase information (if any) here */ |
| 216386 | u8 bRebaseStarted; /* If table header is already in rebase */ | 223717 | u8 bRebaseStarted; /* If table header is already in rebase */ |
| 216387 | u8 bRebase; /* True to collect rebase information */ | 223718 | u8 bRebase; /* True to collect rebase information */ |
| 223719 | u8 bIgnoreNoop; /* True to ignore no-op conflicts */ | ||
| 223720 | int bRowid; | ||
| 216388 | }; | 223721 | }; |
| 216389 | 223722 | ||
| 216390 | /* Number of prepared UPDATE statements to cache. */ | 223723 | /* Number of prepared UPDATE statements to cache. */ |
| @@ -216635,8 +223968,10 @@ static int sessionSelectRow( | |||
| 216635 | const char *zTab, /* Table name */ | 223968 | const char *zTab, /* Table name */ |
| 216636 | SessionApplyCtx *p /* Session changeset-apply context */ | 223969 | SessionApplyCtx *p /* Session changeset-apply context */ |
| 216637 | ){ | 223970 | ){ |
| 216638 | return sessionSelectStmt( | 223971 | /* TODO */ |
| 216639 | db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect); | 223972 | return sessionSelectStmt(db, p->bIgnoreNoop, |
| 223973 | "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect | ||
| 223974 | ); | ||
| 216640 | } | 223975 | } |
| 216641 | 223976 | ||
| 216642 | /* | 223977 | /* |
| @@ -216794,22 +224129,34 @@ static int sessionBindRow( | |||
| 216794 | ** UPDATE, bind values from the old.* record. | 224129 | ** UPDATE, bind values from the old.* record. |
| 216795 | */ | 224130 | */ |
| 216796 | static int sessionSeekToRow( | 224131 | static int sessionSeekToRow( |
| 216797 | sqlite3 *db, /* Database handle */ | ||
| 216798 | sqlite3_changeset_iter *pIter, /* Changeset iterator */ | 224132 | sqlite3_changeset_iter *pIter, /* Changeset iterator */ |
| 216799 | u8 *abPK, /* Primary key flags array */ | 224133 | SessionApplyCtx *p |
| 216800 | sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */ | ||
| 216801 | ){ | 224134 | ){ |
| 224135 | sqlite3_stmt *pSelect = p->pSelect; | ||
| 216802 | int rc; /* Return code */ | 224136 | int rc; /* Return code */ |
| 216803 | int nCol; /* Number of columns in table */ | 224137 | int nCol; /* Number of columns in table */ |
| 216804 | int op; /* Changset operation (SQLITE_UPDATE etc.) */ | 224138 | int op; /* Changset operation (SQLITE_UPDATE etc.) */ |
| 216805 | const char *zDummy; /* Unused */ | 224139 | const char *zDummy; /* Unused */ |
| 216806 | 224140 | ||
| 224141 | sqlite3_clear_bindings(pSelect); | ||
| 216807 | sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); | 224142 | sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); |
| 216808 | rc = sessionBindRow(pIter, | 224143 | rc = sessionBindRow(pIter, |
| 216809 | op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old, | 224144 | op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old, |
| 216810 | nCol, abPK, pSelect | 224145 | nCol, p->abPK, pSelect |
| 216811 | ); | 224146 | ); |
| 216812 | 224147 | ||
| 224148 | if( op!=SQLITE_DELETE && p->bIgnoreNoop ){ | ||
| 224149 | int ii; | ||
| 224150 | for(ii=0; rc==SQLITE_OK && ii<nCol; ii++){ | ||
| 224151 | if( p->abPK[ii]==0 ){ | ||
| 224152 | sqlite3_value *pVal = 0; | ||
| 224153 | sqlite3changeset_new(pIter, ii, &pVal); | ||
| 224154 | sqlite3_bind_int(pSelect, ii+1+nCol, (pVal==0)); | ||
| 224155 | if( pVal ) rc = sessionBindValue(pSelect, ii+1, pVal); | ||
| 224156 | } | ||
| 224157 | } | ||
| 224158 | } | ||
| 224159 | |||
| 216813 | if( rc==SQLITE_OK ){ | 224160 | if( rc==SQLITE_OK ){ |
| 216814 | rc = sqlite3_step(pSelect); | 224161 | rc = sqlite3_step(pSelect); |
| 216815 | if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect); | 224162 | if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect); |
| @@ -216924,16 +224271,22 @@ static int sessionConflictHandler( | |||
| 216924 | 224271 | ||
| 216925 | /* Bind the new.* PRIMARY KEY values to the SELECT statement. */ | 224272 | /* Bind the new.* PRIMARY KEY values to the SELECT statement. */ |
| 216926 | if( pbReplace ){ | 224273 | if( pbReplace ){ |
| 216927 | rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); | 224274 | rc = sessionSeekToRow(pIter, p); |
| 216928 | }else{ | 224275 | }else{ |
| 216929 | rc = SQLITE_OK; | 224276 | rc = SQLITE_OK; |
| 216930 | } | 224277 | } |
| 216931 | 224278 | ||
| 216932 | if( rc==SQLITE_ROW ){ | 224279 | if( rc==SQLITE_ROW ){ |
| 216933 | /* There exists another row with the new.* primary key. */ | 224280 | /* There exists another row with the new.* primary key. */ |
| 216934 | pIter->pConflict = p->pSelect; | 224281 | if( p->bIgnoreNoop |
| 216935 | res = xConflict(pCtx, eType, pIter); | 224282 | && sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1) |
| 216936 | pIter->pConflict = 0; | 224283 | ){ |
| 224284 | res = SQLITE_CHANGESET_OMIT; | ||
| 224285 | }else{ | ||
| 224286 | pIter->pConflict = p->pSelect; | ||
| 224287 | res = xConflict(pCtx, eType, pIter); | ||
| 224288 | pIter->pConflict = 0; | ||
| 224289 | } | ||
| 216937 | rc = sqlite3_reset(p->pSelect); | 224290 | rc = sqlite3_reset(p->pSelect); |
| 216938 | }else if( rc==SQLITE_OK ){ | 224291 | }else if( rc==SQLITE_OK ){ |
| 216939 | if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){ | 224292 | if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){ |
| @@ -217041,7 +224394,7 @@ static int sessionApplyOneOp( | |||
| 217041 | 224394 | ||
| 217042 | sqlite3_step(p->pDelete); | 224395 | sqlite3_step(p->pDelete); |
| 217043 | rc = sqlite3_reset(p->pDelete); | 224396 | rc = sqlite3_reset(p->pDelete); |
| 217044 | if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ | 224397 | if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 && p->bIgnoreNoop==0 ){ |
| 217045 | rc = sessionConflictHandler( | 224398 | rc = sessionConflictHandler( |
| 217046 | SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry | 224399 | SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry |
| 217047 | ); | 224400 | ); |
| @@ -217098,7 +224451,7 @@ static int sessionApplyOneOp( | |||
| 217098 | /* Check if there is a conflicting row. For sqlite_stat1, this needs | 224451 | /* Check if there is a conflicting row. For sqlite_stat1, this needs |
| 217099 | ** to be done using a SELECT, as there is no PRIMARY KEY in the | 224452 | ** to be done using a SELECT, as there is no PRIMARY KEY in the |
| 217100 | ** database schema to throw an exception if a duplicate is inserted. */ | 224453 | ** database schema to throw an exception if a duplicate is inserted. */ |
| 217101 | rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); | 224454 | rc = sessionSeekToRow(pIter, p); |
| 217102 | if( rc==SQLITE_ROW ){ | 224455 | if( rc==SQLITE_ROW ){ |
| 217103 | rc = SQLITE_CONSTRAINT; | 224456 | rc = SQLITE_CONSTRAINT; |
| 217104 | sqlite3_reset(p->pSelect); | 224457 | sqlite3_reset(p->pSelect); |
| @@ -217275,6 +224628,7 @@ static int sessionChangesetApply( | |||
| 217275 | memset(&sApply, 0, sizeof(sApply)); | 224628 | memset(&sApply, 0, sizeof(sApply)); |
| 217276 | sApply.bRebase = (ppRebase && pnRebase); | 224629 | sApply.bRebase = (ppRebase && pnRebase); |
| 217277 | sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); | 224630 | sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); |
| 224631 | sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); | ||
| 217278 | sqlite3_mutex_enter(sqlite3_db_mutex(db)); | 224632 | sqlite3_mutex_enter(sqlite3_db_mutex(db)); |
| 217279 | if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ | 224633 | if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ |
| 217280 | rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); | 224634 | rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); |
| @@ -217312,6 +224666,7 @@ static int sessionChangesetApply( | |||
| 217312 | sApply.bStat1 = 0; | 224666 | sApply.bStat1 = 0; |
| 217313 | sApply.bDeferConstraints = 1; | 224667 | sApply.bDeferConstraints = 1; |
| 217314 | sApply.bRebaseStarted = 0; | 224668 | sApply.bRebaseStarted = 0; |
| 224669 | sApply.bRowid = 0; | ||
| 217315 | memset(&sApply.constraints, 0, sizeof(SessionBuffer)); | 224670 | memset(&sApply.constraints, 0, sizeof(SessionBuffer)); |
| 217316 | 224671 | ||
| 217317 | /* If an xFilter() callback was specified, invoke it now. If the | 224672 | /* If an xFilter() callback was specified, invoke it now. If the |
| @@ -217331,8 +224686,8 @@ static int sessionChangesetApply( | |||
| 217331 | int i; | 224686 | int i; |
| 217332 | 224687 | ||
| 217333 | sqlite3changeset_pk(pIter, &abPK, 0); | 224688 | sqlite3changeset_pk(pIter, &abPK, 0); |
| 217334 | rc = sessionTableInfo(0, | 224689 | rc = sessionTableInfo(0, db, "main", zNew, |
| 217335 | db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK | 224690 | &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK, &sApply.bRowid |
| 217336 | ); | 224691 | ); |
| 217337 | if( rc!=SQLITE_OK ) break; | 224692 | if( rc!=SQLITE_OK ) break; |
| 217338 | for(i=0; i<sApply.nCol; i++){ | 224693 | for(i=0; i<sApply.nCol; i++){ |
| @@ -218144,7 +225499,7 @@ static void sessionAppendPartialUpdate( | |||
| 218144 | if( !pIter->abPK[i] && a1[0] ) bData = 1; | 225499 | if( !pIter->abPK[i] && a1[0] ) bData = 1; |
| 218145 | memcpy(pOut, a1, n1); | 225500 | memcpy(pOut, a1, n1); |
| 218146 | pOut += n1; | 225501 | pOut += n1; |
| 218147 | }else if( a2[0]!=0xFF ){ | 225502 | }else if( a2[0]!=0xFF && a1[0] ){ |
| 218148 | bData = 1; | 225503 | bData = 1; |
| 218149 | memcpy(pOut, a2, n2); | 225504 | memcpy(pOut, a2, n2); |
| 218150 | pOut += n2; | 225505 | pOut += n2; |
| @@ -218702,7 +226057,7 @@ struct Fts5PhraseIter { | |||
| 218702 | ** See xPhraseFirstColumn above. | 226057 | ** See xPhraseFirstColumn above. |
| 218703 | */ | 226058 | */ |
| 218704 | struct Fts5ExtensionApi { | 226059 | struct Fts5ExtensionApi { |
| 218705 | int iVersion; /* Currently always set to 3 */ | 226060 | int iVersion; /* Currently always set to 2 */ |
| 218706 | 226061 | ||
| 218707 | void *(*xUserData)(Fts5Context*); | 226062 | void *(*xUserData)(Fts5Context*); |
| 218708 | 226063 | ||
| @@ -218931,8 +226286,8 @@ struct Fts5ExtensionApi { | |||
| 218931 | ** as separate queries of the FTS index are required for each synonym. | 226286 | ** as separate queries of the FTS index are required for each synonym. |
| 218932 | ** | 226287 | ** |
| 218933 | ** When using methods (2) or (3), it is important that the tokenizer only | 226288 | ** When using methods (2) or (3), it is important that the tokenizer only |
| 218934 | ** provide synonyms when tokenizing document text (method (2)) or query | 226289 | ** provide synonyms when tokenizing document text (method (3)) or query |
| 218935 | ** text (method (3)), not both. Doing so will not cause any errors, but is | 226290 | ** text (method (2)), not both. Doing so will not cause any errors, but is |
| 218936 | ** inefficient. | 226291 | ** inefficient. |
| 218937 | */ | 226292 | */ |
| 218938 | typedef struct Fts5Tokenizer Fts5Tokenizer; | 226293 | typedef struct Fts5Tokenizer Fts5Tokenizer; |
| @@ -218980,7 +226335,7 @@ struct fts5_api { | |||
| 218980 | int (*xCreateTokenizer)( | 226335 | int (*xCreateTokenizer)( |
| 218981 | fts5_api *pApi, | 226336 | fts5_api *pApi, |
| 218982 | const char *zName, | 226337 | const char *zName, |
| 218983 | void *pContext, | 226338 | void *pUserData, |
| 218984 | fts5_tokenizer *pTokenizer, | 226339 | fts5_tokenizer *pTokenizer, |
| 218985 | void (*xDestroy)(void*) | 226340 | void (*xDestroy)(void*) |
| 218986 | ); | 226341 | ); |
| @@ -218989,7 +226344,7 @@ struct fts5_api { | |||
| 218989 | int (*xFindTokenizer)( | 226344 | int (*xFindTokenizer)( |
| 218990 | fts5_api *pApi, | 226345 | fts5_api *pApi, |
| 218991 | const char *zName, | 226346 | const char *zName, |
| 218992 | void **ppContext, | 226347 | void **ppUserData, |
| 218993 | fts5_tokenizer *pTokenizer | 226348 | fts5_tokenizer *pTokenizer |
| 218994 | ); | 226349 | ); |
| 218995 | 226350 | ||
| @@ -218997,7 +226352,7 @@ struct fts5_api { | |||
| 218997 | int (*xCreateFunction)( | 226352 | int (*xCreateFunction)( |
| 218998 | fts5_api *pApi, | 226353 | fts5_api *pApi, |
| 218999 | const char *zName, | 226354 | const char *zName, |
| 219000 | void *pContext, | 226355 | void *pUserData, |
| 219001 | fts5_extension_function xFunction, | 226356 | fts5_extension_function xFunction, |
| 219002 | void (*xDestroy)(void*) | 226357 | void (*xDestroy)(void*) |
| 219003 | ); | 226358 | ); |
| @@ -219169,6 +226524,10 @@ typedef struct Fts5Config Fts5Config; | |||
| 219169 | ** attempt to merge together. A value of 1 sets the object to use the | 226524 | ** attempt to merge together. A value of 1 sets the object to use the |
| 219170 | ** compile time default. Zero disables auto-merge altogether. | 226525 | ** compile time default. Zero disables auto-merge altogether. |
| 219171 | ** | 226526 | ** |
| 226527 | ** bContentlessDelete: | ||
| 226528 | ** True if the contentless_delete option was present in the CREATE | ||
| 226529 | ** VIRTUAL TABLE statement. | ||
| 226530 | ** | ||
| 219172 | ** zContent: | 226531 | ** zContent: |
| 219173 | ** | 226532 | ** |
| 219174 | ** zContentRowid: | 226533 | ** zContentRowid: |
| @@ -219203,6 +226562,7 @@ struct Fts5Config { | |||
| 219203 | int nPrefix; /* Number of prefix indexes */ | 226562 | int nPrefix; /* Number of prefix indexes */ |
| 219204 | int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ | 226563 | int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ |
| 219205 | int eContent; /* An FTS5_CONTENT value */ | 226564 | int eContent; /* An FTS5_CONTENT value */ |
| 226565 | int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ | ||
| 219206 | char *zContent; /* content table */ | 226566 | char *zContent; /* content table */ |
| 219207 | char *zContentRowid; /* "content_rowid=" option value */ | 226567 | char *zContentRowid; /* "content_rowid=" option value */ |
| 219208 | int bColumnsize; /* "columnsize=" option value (dflt==1) */ | 226568 | int bColumnsize; /* "columnsize=" option value (dflt==1) */ |
| @@ -219214,6 +226574,7 @@ struct Fts5Config { | |||
| 219214 | int ePattern; /* FTS_PATTERN_XXX constant */ | 226574 | int ePattern; /* FTS_PATTERN_XXX constant */ |
| 219215 | 226575 | ||
| 219216 | /* Values loaded from the %_config table */ | 226576 | /* Values loaded from the %_config table */ |
| 226577 | int iVersion; /* fts5 file format 'version' */ | ||
| 219217 | int iCookie; /* Incremented when %_config is modified */ | 226578 | int iCookie; /* Incremented when %_config is modified */ |
| 219218 | int pgsz; /* Approximate page size used in %_data */ | 226579 | int pgsz; /* Approximate page size used in %_data */ |
| 219219 | int nAutomerge; /* 'automerge' setting */ | 226580 | int nAutomerge; /* 'automerge' setting */ |
| @@ -219222,6 +226583,8 @@ struct Fts5Config { | |||
| 219222 | int nHashSize; /* Bytes of memory for in-memory hash */ | 226583 | int nHashSize; /* Bytes of memory for in-memory hash */ |
| 219223 | char *zRank; /* Name of rank function */ | 226584 | char *zRank; /* Name of rank function */ |
| 219224 | char *zRankArgs; /* Arguments to rank function */ | 226585 | char *zRankArgs; /* Arguments to rank function */ |
| 226586 | int bSecureDelete; /* 'secure-delete' */ | ||
| 226587 | int nDeleteMerge; /* 'deletemerge' */ | ||
| 219225 | 226588 | ||
| 219226 | /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ | 226589 | /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ |
| 219227 | char **pzErrmsg; | 226590 | char **pzErrmsg; |
| @@ -219231,8 +226594,11 @@ struct Fts5Config { | |||
| 219231 | #endif | 226594 | #endif |
| 219232 | }; | 226595 | }; |
| 219233 | 226596 | ||
| 219234 | /* Current expected value of %_config table 'version' field */ | 226597 | /* Current expected value of %_config table 'version' field. And |
| 219235 | #define FTS5_CURRENT_VERSION 4 | 226598 | ** the expected version if the 'secure-delete' option has ever been |
| 226599 | ** set on the table. */ | ||
| 226600 | #define FTS5_CURRENT_VERSION 4 | ||
| 226601 | #define FTS5_CURRENT_VERSION_SECUREDELETE 5 | ||
| 219236 | 226602 | ||
| 219237 | #define FTS5_CONTENT_NORMAL 0 | 226603 | #define FTS5_CONTENT_NORMAL 0 |
| 219238 | #define FTS5_CONTENT_NONE 1 | 226604 | #define FTS5_CONTENT_NONE 1 |
| @@ -219301,7 +226667,7 @@ static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...); | |||
| 219301 | static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); | 226667 | static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); |
| 219302 | 226668 | ||
| 219303 | #define fts5BufferZero(x) sqlite3Fts5BufferZero(x) | 226669 | #define fts5BufferZero(x) sqlite3Fts5BufferZero(x) |
| 219304 | #define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c) | 226670 | #define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,(i64)c) |
| 219305 | #define fts5BufferFree(a) sqlite3Fts5BufferFree(a) | 226671 | #define fts5BufferFree(a) sqlite3Fts5BufferFree(a) |
| 219306 | #define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d) | 226672 | #define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d) |
| 219307 | #define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) | 226673 | #define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) |
| @@ -219398,6 +226764,7 @@ struct Fts5IndexIter { | |||
| 219398 | ** above. */ | 226764 | ** above. */ |
| 219399 | #define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 | 226765 | #define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 |
| 219400 | #define FTS5INDEX_QUERY_NOOUTPUT 0x0020 | 226766 | #define FTS5INDEX_QUERY_NOOUTPUT 0x0020 |
| 226767 | #define FTS5INDEX_QUERY_SKIPHASH 0x0040 | ||
| 219401 | 226768 | ||
| 219402 | /* | 226769 | /* |
| 219403 | ** Create/destroy an Fts5Index object. | 226770 | ** Create/destroy an Fts5Index object. |
| @@ -219540,6 +226907,9 @@ static int sqlite3Fts5IndexReset(Fts5Index *p); | |||
| 219540 | 226907 | ||
| 219541 | static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); | 226908 | static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); |
| 219542 | 226909 | ||
| 226910 | static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin); | ||
| 226911 | static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid); | ||
| 226912 | |||
| 219543 | /* | 226913 | /* |
| 219544 | ** End of interface to code in fts5_index.c. | 226914 | ** End of interface to code in fts5_index.c. |
| 219545 | **************************************************************************/ | 226915 | **************************************************************************/ |
| @@ -219552,7 +226922,7 @@ static int sqlite3Fts5GetVarintLen(u32 iVal); | |||
| 219552 | static u8 sqlite3Fts5GetVarint(const unsigned char*, u64*); | 226922 | static u8 sqlite3Fts5GetVarint(const unsigned char*, u64*); |
| 219553 | static int sqlite3Fts5PutVarint(unsigned char *p, u64 v); | 226923 | static int sqlite3Fts5PutVarint(unsigned char *p, u64 v); |
| 219554 | 226924 | ||
| 219555 | #define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b) | 226925 | #define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&(b)) |
| 219556 | #define fts5GetVarint sqlite3Fts5GetVarint | 226926 | #define fts5GetVarint sqlite3Fts5GetVarint |
| 219557 | 226927 | ||
| 219558 | #define fts5FastGetVarint32(a, iOff, nVal) { \ | 226928 | #define fts5FastGetVarint32(a, iOff, nVal) { \ |
| @@ -219624,6 +226994,11 @@ static int sqlite3Fts5HashWrite( | |||
| 219624 | */ | 226994 | */ |
| 219625 | static void sqlite3Fts5HashClear(Fts5Hash*); | 226995 | static void sqlite3Fts5HashClear(Fts5Hash*); |
| 219626 | 226996 | ||
| 226997 | /* | ||
| 226998 | ** Return true if the hash is empty, false otherwise. | ||
| 226999 | */ | ||
| 227000 | static int sqlite3Fts5HashIsEmpty(Fts5Hash*); | ||
| 227001 | |||
| 219627 | static int sqlite3Fts5HashQuery( | 227002 | static int sqlite3Fts5HashQuery( |
| 219628 | Fts5Hash*, /* Hash table to query */ | 227003 | Fts5Hash*, /* Hash table to query */ |
| 219629 | int nPre, | 227004 | int nPre, |
| @@ -219645,6 +227020,7 @@ static void sqlite3Fts5HashScanEntry(Fts5Hash *, | |||
| 219645 | ); | 227020 | ); |
| 219646 | 227021 | ||
| 219647 | 227022 | ||
| 227023 | |||
| 219648 | /* | 227024 | /* |
| 219649 | ** End of interface to code in fts5_hash.c. | 227025 | ** End of interface to code in fts5_hash.c. |
| 219650 | **************************************************************************/ | 227026 | **************************************************************************/ |
| @@ -219888,7 +227264,8 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); | |||
| 219888 | #define FTS5_STAR 15 | 227264 | #define FTS5_STAR 15 |
| 219889 | 227265 | ||
| 219890 | /* This file is automatically generated by Lemon from input grammar | 227266 | /* This file is automatically generated by Lemon from input grammar |
| 219891 | ** source file "fts5parse.y". */ | 227267 | ** source file "fts5parse.y". |
| 227268 | */ | ||
| 219892 | /* | 227269 | /* |
| 219893 | ** 2000-05-29 | 227270 | ** 2000-05-29 |
| 219894 | ** | 227271 | ** |
| @@ -221531,7 +228908,7 @@ static int fts5HighlightCb( | |||
| 221531 | if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK; | 228908 | if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK; |
| 221532 | iPos = p->iPos++; | 228909 | iPos = p->iPos++; |
| 221533 | 228910 | ||
| 221534 | if( p->iRangeEnd>0 ){ | 228911 | if( p->iRangeEnd>=0 ){ |
| 221535 | if( iPos<p->iRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK; | 228912 | if( iPos<p->iRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK; |
| 221536 | if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff; | 228913 | if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff; |
| 221537 | } | 228914 | } |
| @@ -221543,7 +228920,7 @@ static int fts5HighlightCb( | |||
| 221543 | } | 228920 | } |
| 221544 | 228921 | ||
| 221545 | if( iPos==p->iter.iEnd ){ | 228922 | if( iPos==p->iter.iEnd ){ |
| 221546 | if( p->iRangeEnd && p->iter.iStart<p->iRangeStart ){ | 228923 | if( p->iRangeEnd>=0 && p->iter.iStart<p->iRangeStart ){ |
| 221547 | fts5HighlightAppend(&rc, p, p->zOpen, -1); | 228924 | fts5HighlightAppend(&rc, p, p->zOpen, -1); |
| 221548 | } | 228925 | } |
| 221549 | fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); | 228926 | fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); |
| @@ -221554,7 +228931,7 @@ static int fts5HighlightCb( | |||
| 221554 | } | 228931 | } |
| 221555 | } | 228932 | } |
| 221556 | 228933 | ||
| 221557 | if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){ | 228934 | if( p->iRangeEnd>=0 && iPos==p->iRangeEnd ){ |
| 221558 | fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); | 228935 | fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); |
| 221559 | p->iOff = iEndOff; | 228936 | p->iOff = iEndOff; |
| 221560 | if( iPos>=p->iter.iStart && iPos<p->iter.iEnd ){ | 228937 | if( iPos>=p->iter.iStart && iPos<p->iter.iEnd ){ |
| @@ -221589,6 +228966,7 @@ static void fts5HighlightFunction( | |||
| 221589 | memset(&ctx, 0, sizeof(HighlightContext)); | 228966 | memset(&ctx, 0, sizeof(HighlightContext)); |
| 221590 | ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); | 228967 | ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); |
| 221591 | ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); | 228968 | ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); |
| 228969 | ctx.iRangeEnd = -1; | ||
| 221592 | rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); | 228970 | rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); |
| 221593 | 228971 | ||
| 221594 | if( ctx.zIn ){ | 228972 | if( ctx.zIn ){ |
| @@ -221774,6 +229152,7 @@ static void fts5SnippetFunction( | |||
| 221774 | iCol = sqlite3_value_int(apVal[0]); | 229152 | iCol = sqlite3_value_int(apVal[0]); |
| 221775 | ctx.zOpen = fts5ValueToText(apVal[1]); | 229153 | ctx.zOpen = fts5ValueToText(apVal[1]); |
| 221776 | ctx.zClose = fts5ValueToText(apVal[2]); | 229154 | ctx.zClose = fts5ValueToText(apVal[2]); |
| 229155 | ctx.iRangeEnd = -1; | ||
| 221777 | zEllips = fts5ValueToText(apVal[3]); | 229156 | zEllips = fts5ValueToText(apVal[3]); |
| 221778 | nToken = sqlite3_value_int(apVal[4]); | 229157 | nToken = sqlite3_value_int(apVal[4]); |
| 221779 | 229158 | ||
| @@ -222514,6 +229893,8 @@ static void sqlite3Fts5TermsetFree(Fts5Termset *p){ | |||
| 222514 | #define FTS5_DEFAULT_CRISISMERGE 16 | 229893 | #define FTS5_DEFAULT_CRISISMERGE 16 |
| 222515 | #define FTS5_DEFAULT_HASHSIZE (1024*1024) | 229894 | #define FTS5_DEFAULT_HASHSIZE (1024*1024) |
| 222516 | 229895 | ||
| 229896 | #define FTS5_DEFAULT_DELETE_AUTOMERGE 10 /* default 10% */ | ||
| 229897 | |||
| 222517 | /* Maximum allowed page size */ | 229898 | /* Maximum allowed page size */ |
| 222518 | #define FTS5_MAX_PAGE_SIZE (64*1024) | 229899 | #define FTS5_MAX_PAGE_SIZE (64*1024) |
| 222519 | 229900 | ||
| @@ -222844,6 +230225,16 @@ static int fts5ConfigParseSpecial( | |||
| 222844 | return rc; | 230225 | return rc; |
| 222845 | } | 230226 | } |
| 222846 | 230227 | ||
| 230228 | if( sqlite3_strnicmp("contentless_delete", zCmd, nCmd)==0 ){ | ||
| 230229 | if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ | ||
| 230230 | *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive"); | ||
| 230231 | rc = SQLITE_ERROR; | ||
| 230232 | }else{ | ||
| 230233 | pConfig->bContentlessDelete = (zArg[0]=='1'); | ||
| 230234 | } | ||
| 230235 | return rc; | ||
| 230236 | } | ||
| 230237 | |||
| 222847 | if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ | 230238 | if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ |
| 222848 | if( pConfig->zContentRowid ){ | 230239 | if( pConfig->zContentRowid ){ |
| 222849 | *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); | 230240 | *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); |
| @@ -223042,6 +230433,7 @@ static int sqlite3Fts5ConfigParse( | |||
| 223042 | rc = SQLITE_ERROR; | 230433 | rc = SQLITE_ERROR; |
| 223043 | } | 230434 | } |
| 223044 | 230435 | ||
| 230436 | assert( (pRet->abUnindexed && pRet->azCol) || rc!=SQLITE_OK ); | ||
| 223045 | for(i=3; rc==SQLITE_OK && i<nArg; i++){ | 230437 | for(i=3; rc==SQLITE_OK && i<nArg; i++){ |
| 223046 | const char *zOrig = azArg[i]; | 230438 | const char *zOrig = azArg[i]; |
| 223047 | const char *z; | 230439 | const char *z; |
| @@ -223087,6 +230479,28 @@ static int sqlite3Fts5ConfigParse( | |||
| 223087 | sqlite3_free(zTwo); | 230479 | sqlite3_free(zTwo); |
| 223088 | } | 230480 | } |
| 223089 | 230481 | ||
| 230482 | /* We only allow contentless_delete=1 if the table is indeed contentless. */ | ||
| 230483 | if( rc==SQLITE_OK | ||
| 230484 | && pRet->bContentlessDelete | ||
| 230485 | && pRet->eContent!=FTS5_CONTENT_NONE | ||
| 230486 | ){ | ||
| 230487 | *pzErr = sqlite3_mprintf( | ||
| 230488 | "contentless_delete=1 requires a contentless table" | ||
| 230489 | ); | ||
| 230490 | rc = SQLITE_ERROR; | ||
| 230491 | } | ||
| 230492 | |||
| 230493 | /* We only allow contentless_delete=1 if columnsize=0 is not present. | ||
| 230494 | ** | ||
| 230495 | ** This restriction may be removed at some point. | ||
| 230496 | */ | ||
| 230497 | if( rc==SQLITE_OK && pRet->bContentlessDelete && pRet->bColumnsize==0 ){ | ||
| 230498 | *pzErr = sqlite3_mprintf( | ||
| 230499 | "contentless_delete=1 is incompatible with columnsize=0" | ||
| 230500 | ); | ||
| 230501 | rc = SQLITE_ERROR; | ||
| 230502 | } | ||
| 230503 | |||
| 223090 | /* If a tokenizer= option was successfully parsed, the tokenizer has | 230504 | /* If a tokenizer= option was successfully parsed, the tokenizer has |
| 223091 | ** already been allocated. Otherwise, allocate an instance of the default | 230505 | ** already been allocated. Otherwise, allocate an instance of the default |
| 223092 | ** tokenizer (unicode61) now. */ | 230506 | ** tokenizer (unicode61) now. */ |
| @@ -223381,6 +230795,18 @@ static int sqlite3Fts5ConfigSetValue( | |||
| 223381 | } | 230795 | } |
| 223382 | } | 230796 | } |
| 223383 | 230797 | ||
| 230798 | else if( 0==sqlite3_stricmp(zKey, "deletemerge") ){ | ||
| 230799 | int nVal = -1; | ||
| 230800 | if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ | ||
| 230801 | nVal = sqlite3_value_int(pVal); | ||
| 230802 | }else{ | ||
| 230803 | *pbBadkey = 1; | ||
| 230804 | } | ||
| 230805 | if( nVal<0 ) nVal = FTS5_DEFAULT_DELETE_AUTOMERGE; | ||
| 230806 | if( nVal>100 ) nVal = 0; | ||
| 230807 | pConfig->nDeleteMerge = nVal; | ||
| 230808 | } | ||
| 230809 | |||
| 223384 | else if( 0==sqlite3_stricmp(zKey, "rank") ){ | 230810 | else if( 0==sqlite3_stricmp(zKey, "rank") ){ |
| 223385 | const char *zIn = (const char*)sqlite3_value_text(pVal); | 230811 | const char *zIn = (const char*)sqlite3_value_text(pVal); |
| 223386 | char *zRank; | 230812 | char *zRank; |
| @@ -223395,6 +230821,18 @@ static int sqlite3Fts5ConfigSetValue( | |||
| 223395 | rc = SQLITE_OK; | 230821 | rc = SQLITE_OK; |
| 223396 | *pbBadkey = 1; | 230822 | *pbBadkey = 1; |
| 223397 | } | 230823 | } |
| 230824 | } | ||
| 230825 | |||
| 230826 | else if( 0==sqlite3_stricmp(zKey, "secure-delete") ){ | ||
| 230827 | int bVal = -1; | ||
| 230828 | if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ | ||
| 230829 | bVal = sqlite3_value_int(pVal); | ||
| 230830 | } | ||
| 230831 | if( bVal<0 ){ | ||
| 230832 | *pbBadkey = 1; | ||
| 230833 | }else{ | ||
| 230834 | pConfig->bSecureDelete = (bVal ? 1 : 0); | ||
| 230835 | } | ||
| 223398 | }else{ | 230836 | }else{ |
| 223399 | *pbBadkey = 1; | 230837 | *pbBadkey = 1; |
| 223400 | } | 230838 | } |
| @@ -223417,6 +230855,7 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ | |||
| 223417 | pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE; | 230855 | pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE; |
| 223418 | pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE; | 230856 | pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE; |
| 223419 | pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE; | 230857 | pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE; |
| 230858 | pConfig->nDeleteMerge = FTS5_DEFAULT_DELETE_AUTOMERGE; | ||
| 223420 | 230859 | ||
| 223421 | zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName); | 230860 | zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName); |
| 223422 | if( zSql ){ | 230861 | if( zSql ){ |
| @@ -223439,15 +230878,20 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ | |||
| 223439 | rc = sqlite3_finalize(p); | 230878 | rc = sqlite3_finalize(p); |
| 223440 | } | 230879 | } |
| 223441 | 230880 | ||
| 223442 | if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){ | 230881 | if( rc==SQLITE_OK |
| 230882 | && iVersion!=FTS5_CURRENT_VERSION | ||
| 230883 | && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE | ||
| 230884 | ){ | ||
| 223443 | rc = SQLITE_ERROR; | 230885 | rc = SQLITE_ERROR; |
| 223444 | if( pConfig->pzErrmsg ){ | 230886 | if( pConfig->pzErrmsg ){ |
| 223445 | assert( 0==*pConfig->pzErrmsg ); | 230887 | assert( 0==*pConfig->pzErrmsg ); |
| 223446 | *pConfig->pzErrmsg = sqlite3_mprintf( | 230888 | *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format " |
| 223447 | "invalid fts5 file format (found %d, expected %d) - run 'rebuild'", | 230889 | "(found %d, expected %d or %d) - run 'rebuild'", |
| 223448 | iVersion, FTS5_CURRENT_VERSION | 230890 | iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE |
| 223449 | ); | 230891 | ); |
| 223450 | } | 230892 | } |
| 230893 | }else{ | ||
| 230894 | pConfig->iVersion = iVersion; | ||
| 223451 | } | 230895 | } |
| 223452 | 230896 | ||
| 223453 | if( rc==SQLITE_OK ){ | 230897 | if( rc==SQLITE_OK ){ |
| @@ -223475,6 +230919,10 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ | |||
| 223475 | /* #include "fts5Int.h" */ | 230919 | /* #include "fts5Int.h" */ |
| 223476 | /* #include "fts5parse.h" */ | 230920 | /* #include "fts5parse.h" */ |
| 223477 | 230921 | ||
| 230922 | #ifndef SQLITE_FTS5_MAX_EXPR_DEPTH | ||
| 230923 | # define SQLITE_FTS5_MAX_EXPR_DEPTH 256 | ||
| 230924 | #endif | ||
| 230925 | |||
| 223478 | /* | 230926 | /* |
| 223479 | ** All token types in the generated fts5parse.h file are greater than 0. | 230927 | ** All token types in the generated fts5parse.h file are greater than 0. |
| 223480 | */ | 230928 | */ |
| @@ -223515,11 +230963,17 @@ struct Fts5Expr { | |||
| 223515 | ** FTS5_NOT (nChild, apChild valid) | 230963 | ** FTS5_NOT (nChild, apChild valid) |
| 223516 | ** FTS5_STRING (pNear valid) | 230964 | ** FTS5_STRING (pNear valid) |
| 223517 | ** FTS5_TERM (pNear valid) | 230965 | ** FTS5_TERM (pNear valid) |
| 230966 | ** | ||
| 230967 | ** iHeight: | ||
| 230968 | ** Distance from this node to furthest leaf. This is always 0 for nodes | ||
| 230969 | ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one | ||
| 230970 | ** greater than the largest child value. | ||
| 223518 | */ | 230971 | */ |
| 223519 | struct Fts5ExprNode { | 230972 | struct Fts5ExprNode { |
| 223520 | int eType; /* Node type */ | 230973 | int eType; /* Node type */ |
| 223521 | int bEof; /* True at EOF */ | 230974 | int bEof; /* True at EOF */ |
| 223522 | int bNomatch; /* True if entry is not a match */ | 230975 | int bNomatch; /* True if entry is not a match */ |
| 230976 | int iHeight; /* Distance to tree leaf nodes */ | ||
| 223523 | 230977 | ||
| 223524 | /* Next method for this node. */ | 230978 | /* Next method for this node. */ |
| 223525 | int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64); | 230979 | int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64); |
| @@ -223589,6 +231043,31 @@ struct Fts5Parse { | |||
| 223589 | int bPhraseToAnd; /* Convert "a+b" to "a AND b" */ | 231043 | int bPhraseToAnd; /* Convert "a+b" to "a AND b" */ |
| 223590 | }; | 231044 | }; |
| 223591 | 231045 | ||
| 231046 | /* | ||
| 231047 | ** Check that the Fts5ExprNode.iHeight variables are set correctly in | ||
| 231048 | ** the expression tree passed as the only argument. | ||
| 231049 | */ | ||
| 231050 | #ifndef NDEBUG | ||
| 231051 | static void assert_expr_depth_ok(int rc, Fts5ExprNode *p){ | ||
| 231052 | if( rc==SQLITE_OK ){ | ||
| 231053 | if( p->eType==FTS5_TERM || p->eType==FTS5_STRING || p->eType==0 ){ | ||
| 231054 | assert( p->iHeight==0 ); | ||
| 231055 | }else{ | ||
| 231056 | int ii; | ||
| 231057 | int iMaxChild = 0; | ||
| 231058 | for(ii=0; ii<p->nChild; ii++){ | ||
| 231059 | Fts5ExprNode *pChild = p->apChild[ii]; | ||
| 231060 | iMaxChild = MAX(iMaxChild, pChild->iHeight); | ||
| 231061 | assert_expr_depth_ok(SQLITE_OK, pChild); | ||
| 231062 | } | ||
| 231063 | assert( p->iHeight==iMaxChild+1 ); | ||
| 231064 | } | ||
| 231065 | } | ||
| 231066 | } | ||
| 231067 | #else | ||
| 231068 | # define assert_expr_depth_ok(rc, p) | ||
| 231069 | #endif | ||
| 231070 | |||
| 223592 | static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){ | 231071 | static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){ |
| 223593 | va_list ap; | 231072 | va_list ap; |
| 223594 | va_start(ap, zFmt); | 231073 | va_start(ap, zFmt); |
| @@ -223703,6 +231182,8 @@ static int sqlite3Fts5ExprNew( | |||
| 223703 | }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); | 231182 | }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); |
| 223704 | sqlite3Fts5ParserFree(pEngine, fts5ParseFree); | 231183 | sqlite3Fts5ParserFree(pEngine, fts5ParseFree); |
| 223705 | 231184 | ||
| 231185 | assert_expr_depth_ok(sParse.rc, sParse.pExpr); | ||
| 231186 | |||
| 223706 | /* If the LHS of the MATCH expression was a user column, apply the | 231187 | /* If the LHS of the MATCH expression was a user column, apply the |
| 223707 | ** implicit column-filter. */ | 231188 | ** implicit column-filter. */ |
| 223708 | if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ | 231189 | if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ |
| @@ -223748,6 +231229,19 @@ static int sqlite3Fts5ExprNew( | |||
| 223748 | } | 231229 | } |
| 223749 | 231230 | ||
| 223750 | /* | 231231 | /* |
| 231232 | ** Assuming that buffer z is at least nByte bytes in size and contains a | ||
| 231233 | ** valid utf-8 string, return the number of characters in the string. | ||
| 231234 | */ | ||
| 231235 | static int fts5ExprCountChar(const char *z, int nByte){ | ||
| 231236 | int nRet = 0; | ||
| 231237 | int ii; | ||
| 231238 | for(ii=0; ii<nByte; ii++){ | ||
| 231239 | if( (z[ii] & 0xC0)!=0x80 ) nRet++; | ||
| 231240 | } | ||
| 231241 | return nRet; | ||
| 231242 | } | ||
| 231243 | |||
| 231244 | /* | ||
| 223751 | ** This function is only called when using the special 'trigram' tokenizer. | 231245 | ** This function is only called when using the special 'trigram' tokenizer. |
| 223752 | ** Argument zText contains the text of a LIKE or GLOB pattern matched | 231246 | ** Argument zText contains the text of a LIKE or GLOB pattern matched |
| 223753 | ** against column iCol. This function creates and compiles an FTS5 MATCH | 231247 | ** against column iCol. This function creates and compiles an FTS5 MATCH |
| @@ -223784,7 +231278,8 @@ static int sqlite3Fts5ExprPattern( | |||
| 223784 | if( i==nText | 231278 | if( i==nText |
| 223785 | || zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2] | 231279 | || zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2] |
| 223786 | ){ | 231280 | ){ |
| 223787 | if( i-iFirst>=3 ){ | 231281 | |
| 231282 | if( fts5ExprCountChar(&zText[iFirst], i-iFirst)>=3 ){ | ||
| 223788 | int jj; | 231283 | int jj; |
| 223789 | zExpr[iOut++] = '"'; | 231284 | zExpr[iOut++] = '"'; |
| 223790 | for(jj=iFirst; jj<i; jj++){ | 231285 | for(jj=iFirst; jj<i; jj++){ |
| @@ -223851,7 +231346,7 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ | |||
| 223851 | Fts5Parse sParse; | 231346 | Fts5Parse sParse; |
| 223852 | memset(&sParse, 0, sizeof(sParse)); | 231347 | memset(&sParse, 0, sizeof(sParse)); |
| 223853 | 231348 | ||
| 223854 | if( *pp1 ){ | 231349 | if( *pp1 && p2 ){ |
| 223855 | Fts5Expr *p1 = *pp1; | 231350 | Fts5Expr *p1 = *pp1; |
| 223856 | int nPhrase = p1->nPhrase + p2->nPhrase; | 231351 | int nPhrase = p1->nPhrase + p2->nPhrase; |
| 223857 | 231352 | ||
| @@ -223876,7 +231371,7 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ | |||
| 223876 | } | 231371 | } |
| 223877 | sqlite3_free(p2->apExprPhrase); | 231372 | sqlite3_free(p2->apExprPhrase); |
| 223878 | sqlite3_free(p2); | 231373 | sqlite3_free(p2); |
| 223879 | }else{ | 231374 | }else if( p2 ){ |
| 223880 | *pp1 = p2; | 231375 | *pp1 = p2; |
| 223881 | } | 231376 | } |
| 223882 | 231377 | ||
| @@ -225650,6 +233145,7 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ | |||
| 225650 | } | 233145 | } |
| 225651 | 233146 | ||
| 225652 | static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ | 233147 | static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ |
| 233148 | int ii = p->nChild; | ||
| 225653 | if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ | 233149 | if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ |
| 225654 | int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; | 233150 | int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; |
| 225655 | memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); | 233151 | memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); |
| @@ -225658,6 +233154,9 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ | |||
| 225658 | }else{ | 233154 | }else{ |
| 225659 | p->apChild[p->nChild++] = pSub; | 233155 | p->apChild[p->nChild++] = pSub; |
| 225660 | } | 233156 | } |
| 233157 | for( ; ii<p->nChild; ii++){ | ||
| 233158 | p->iHeight = MAX(p->iHeight, p->apChild[ii]->iHeight + 1); | ||
| 233159 | } | ||
| 225661 | } | 233160 | } |
| 225662 | 233161 | ||
| 225663 | /* | 233162 | /* |
| @@ -225688,6 +233187,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( | |||
| 225688 | if( pRet ){ | 233187 | if( pRet ){ |
| 225689 | pRet->eType = FTS5_AND; | 233188 | pRet->eType = FTS5_AND; |
| 225690 | pRet->nChild = nTerm; | 233189 | pRet->nChild = nTerm; |
| 233190 | pRet->iHeight = 1; | ||
| 225691 | fts5ExprAssignXNext(pRet); | 233191 | fts5ExprAssignXNext(pRet); |
| 225692 | pParse->nPhrase--; | 233192 | pParse->nPhrase--; |
| 225693 | for(ii=0; ii<nTerm; ii++){ | 233193 | for(ii=0; ii<nTerm; ii++){ |
| @@ -225793,6 +233293,14 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( | |||
| 225793 | }else{ | 233293 | }else{ |
| 225794 | fts5ExprAddChildren(pRet, pLeft); | 233294 | fts5ExprAddChildren(pRet, pLeft); |
| 225795 | fts5ExprAddChildren(pRet, pRight); | 233295 | fts5ExprAddChildren(pRet, pRight); |
| 233296 | if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ | ||
| 233297 | sqlite3Fts5ParseError(pParse, | ||
| 233298 | "fts5 expression tree is too large (maximum depth %d)", | ||
| 233299 | SQLITE_FTS5_MAX_EXPR_DEPTH | ||
| 233300 | ); | ||
| 233301 | sqlite3_free(pRet); | ||
| 233302 | pRet = 0; | ||
| 233303 | } | ||
| 225796 | } | 233304 | } |
| 225797 | } | 233305 | } |
| 225798 | } | 233306 | } |
| @@ -225871,7 +233379,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( | |||
| 225871 | return pRet; | 233379 | return pRet; |
| 225872 | } | 233380 | } |
| 225873 | 233381 | ||
| 225874 | #ifdef SQLITE_TEST | 233382 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 225875 | static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ | 233383 | static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ |
| 225876 | sqlite3_int64 nByte = 0; | 233384 | sqlite3_int64 nByte = 0; |
| 225877 | Fts5ExprTerm *p; | 233385 | Fts5ExprTerm *p; |
| @@ -225977,6 +233485,8 @@ static char *fts5ExprPrintTcl( | |||
| 225977 | if( zRet==0 ) return 0; | 233485 | if( zRet==0 ) return 0; |
| 225978 | } | 233486 | } |
| 225979 | 233487 | ||
| 233488 | }else if( pExpr->eType==0 ){ | ||
| 233489 | zRet = sqlite3_mprintf("{}"); | ||
| 225980 | }else{ | 233490 | }else{ |
| 225981 | char const *zOp = 0; | 233491 | char const *zOp = 0; |
| 225982 | int i; | 233492 | int i; |
| @@ -226238,14 +233748,14 @@ static void fts5ExprFold( | |||
| 226238 | sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics)); | 233748 | sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics)); |
| 226239 | } | 233749 | } |
| 226240 | } | 233750 | } |
| 226241 | #endif /* ifdef SQLITE_TEST */ | 233751 | #endif /* if SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 226242 | 233752 | ||
| 226243 | /* | 233753 | /* |
| 226244 | ** This is called during initialization to register the fts5_expr() scalar | 233754 | ** This is called during initialization to register the fts5_expr() scalar |
| 226245 | ** UDF with the SQLite handle passed as the only argument. | 233755 | ** UDF with the SQLite handle passed as the only argument. |
| 226246 | */ | 233756 | */ |
| 226247 | static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ | 233757 | static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ |
| 226248 | #ifdef SQLITE_TEST | 233758 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 226249 | struct Fts5ExprFunc { | 233759 | struct Fts5ExprFunc { |
| 226250 | const char *z; | 233760 | const char *z; |
| 226251 | void (*x)(sqlite3_context*,int,sqlite3_value**); | 233761 | void (*x)(sqlite3_context*,int,sqlite3_value**); |
| @@ -227005,7 +234515,6 @@ static int fts5HashEntrySort( | |||
| 227005 | pList = fts5HashEntryMerge(pList, ap[i]); | 234515 | pList = fts5HashEntryMerge(pList, ap[i]); |
| 227006 | } | 234516 | } |
| 227007 | 234517 | ||
| 227008 | pHash->nEntry = 0; | ||
| 227009 | sqlite3_free(ap); | 234518 | sqlite3_free(ap); |
| 227010 | *ppSorted = pList; | 234519 | *ppSorted = pList; |
| 227011 | return SQLITE_OK; | 234520 | return SQLITE_OK; |
| @@ -227059,6 +234568,28 @@ static int sqlite3Fts5HashScanInit( | |||
| 227059 | return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan); | 234568 | return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan); |
| 227060 | } | 234569 | } |
| 227061 | 234570 | ||
| 234571 | #ifdef SQLITE_DEBUG | ||
| 234572 | static int fts5HashCount(Fts5Hash *pHash){ | ||
| 234573 | int nEntry = 0; | ||
| 234574 | int ii; | ||
| 234575 | for(ii=0; ii<pHash->nSlot; ii++){ | ||
| 234576 | Fts5HashEntry *p = 0; | ||
| 234577 | for(p=pHash->aSlot[ii]; p; p=p->pHashNext){ | ||
| 234578 | nEntry++; | ||
| 234579 | } | ||
| 234580 | } | ||
| 234581 | return nEntry; | ||
| 234582 | } | ||
| 234583 | #endif | ||
| 234584 | |||
| 234585 | /* | ||
| 234586 | ** Return true if the hash table is empty, false otherwise. | ||
| 234587 | */ | ||
| 234588 | static int sqlite3Fts5HashIsEmpty(Fts5Hash *pHash){ | ||
| 234589 | assert( pHash->nEntry==fts5HashCount(pHash) ); | ||
| 234590 | return pHash->nEntry==0; | ||
| 234591 | } | ||
| 234592 | |||
| 227062 | static void sqlite3Fts5HashScanNext(Fts5Hash *p){ | 234593 | static void sqlite3Fts5HashScanNext(Fts5Hash *p){ |
| 227063 | assert( !sqlite3Fts5HashScanEof(p) ); | 234594 | assert( !sqlite3Fts5HashScanEof(p) ); |
| 227064 | p->pScan = p->pScan->pScanNext; | 234595 | p->pScan = p->pScan->pScanNext; |
| @@ -227145,6 +234676,26 @@ static void sqlite3Fts5HashScanEntry( | |||
| 227145 | # error "FTS5_MAX_PREFIX_INDEXES is too large" | 234676 | # error "FTS5_MAX_PREFIX_INDEXES is too large" |
| 227146 | #endif | 234677 | #endif |
| 227147 | 234678 | ||
| 234679 | #define FTS5_MAX_LEVEL 64 | ||
| 234680 | |||
| 234681 | /* | ||
| 234682 | ** There are two versions of the format used for the structure record: | ||
| 234683 | ** | ||
| 234684 | ** 1. the legacy format, that may be read by all fts5 versions, and | ||
| 234685 | ** | ||
| 234686 | ** 2. the V2 format, which is used by contentless_delete=1 databases. | ||
| 234687 | ** | ||
| 234688 | ** Both begin with a 4-byte "configuration cookie" value. Then, a legacy | ||
| 234689 | ** format structure record contains a varint - the number of levels in | ||
| 234690 | ** the structure. Whereas a V2 structure record contains the constant | ||
| 234691 | ** 4 bytes [0xff 0x00 0x00 0x01]. This is unambiguous as the value of a | ||
| 234692 | ** varint has to be at least 16256 to begin with "0xFF". And the default | ||
| 234693 | ** maximum number of levels is 64. | ||
| 234694 | ** | ||
| 234695 | ** See below for more on structure record formats. | ||
| 234696 | */ | ||
| 234697 | #define FTS5_STRUCTURE_V2 "\xFF\x00\x00\x01" | ||
| 234698 | |||
| 227148 | /* | 234699 | /* |
| 227149 | ** Details: | 234700 | ** Details: |
| 227150 | ** | 234701 | ** |
| @@ -227152,7 +234703,7 @@ static void sqlite3Fts5HashScanEntry( | |||
| 227152 | ** | 234703 | ** |
| 227153 | ** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB); | 234704 | ** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB); |
| 227154 | ** | 234705 | ** |
| 227155 | ** , contains the following 5 types of records. See the comments surrounding | 234706 | ** , contains the following 6 types of records. See the comments surrounding |
| 227156 | ** the FTS5_*_ROWID macros below for a description of how %_data rowids are | 234707 | ** the FTS5_*_ROWID macros below for a description of how %_data rowids are |
| 227157 | ** assigned to each fo them. | 234708 | ** assigned to each fo them. |
| 227158 | ** | 234709 | ** |
| @@ -227161,12 +234712,12 @@ static void sqlite3Fts5HashScanEntry( | |||
| 227161 | ** The set of segments that make up an index - the index structure - are | 234712 | ** The set of segments that make up an index - the index structure - are |
| 227162 | ** recorded in a single record within the %_data table. The record consists | 234713 | ** recorded in a single record within the %_data table. The record consists |
| 227163 | ** of a single 32-bit configuration cookie value followed by a list of | 234714 | ** of a single 32-bit configuration cookie value followed by a list of |
| 227164 | ** SQLite varints. If the FTS table features more than one index (because | 234715 | ** SQLite varints. |
| 227165 | ** there are one or more prefix indexes), it is guaranteed that all share | 234716 | ** |
| 227166 | ** the same cookie value. | 234717 | ** If the structure record is a V2 record, the configuration cookie is |
| 234718 | ** followed by the following 4 bytes: [0xFF 0x00 0x00 0x01]. | ||
| 227167 | ** | 234719 | ** |
| 227168 | ** Immediately following the configuration cookie, the record begins with | 234720 | ** Next, the record continues with three varints: |
| 227169 | ** three varints: | ||
| 227170 | ** | 234721 | ** |
| 227171 | ** + number of levels, | 234722 | ** + number of levels, |
| 227172 | ** + total number of segments on all levels, | 234723 | ** + total number of segments on all levels, |
| @@ -227181,6 +234732,12 @@ static void sqlite3Fts5HashScanEntry( | |||
| 227181 | ** + first leaf page number (often 1, always greater than 0) | 234732 | ** + first leaf page number (often 1, always greater than 0) |
| 227182 | ** + final leaf page number | 234733 | ** + final leaf page number |
| 227183 | ** | 234734 | ** |
| 234735 | ** Then, for V2 structures only: | ||
| 234736 | ** | ||
| 234737 | ** + lower origin counter value, | ||
| 234738 | ** + upper origin counter value, | ||
| 234739 | ** + the number of tombstone hash pages. | ||
| 234740 | ** | ||
| 227184 | ** 2. The Averages Record: | 234741 | ** 2. The Averages Record: |
| 227185 | ** | 234742 | ** |
| 227186 | ** A single record within the %_data table. The data is a list of varints. | 234743 | ** A single record within the %_data table. The data is a list of varints. |
| @@ -227296,6 +234853,38 @@ static void sqlite3Fts5HashScanEntry( | |||
| 227296 | ** * A list of delta-encoded varints - the first rowid on each subsequent | 234853 | ** * A list of delta-encoded varints - the first rowid on each subsequent |
| 227297 | ** child page. | 234854 | ** child page. |
| 227298 | ** | 234855 | ** |
| 234856 | ** 6. Tombstone Hash Page | ||
| 234857 | ** | ||
| 234858 | ** These records are only ever present in contentless_delete=1 tables. | ||
| 234859 | ** There are zero or more of these associated with each segment. They | ||
| 234860 | ** are used to store the tombstone rowids for rows contained in the | ||
| 234861 | ** associated segments. | ||
| 234862 | ** | ||
| 234863 | ** The set of nHashPg tombstone hash pages associated with a single | ||
| 234864 | ** segment together form a single hash table containing tombstone rowids. | ||
| 234865 | ** To find the page of the hash on which a key might be stored: | ||
| 234866 | ** | ||
| 234867 | ** iPg = (rowid % nHashPg) | ||
| 234868 | ** | ||
| 234869 | ** Then, within page iPg, which has nSlot slots: | ||
| 234870 | ** | ||
| 234871 | ** iSlot = (rowid / nHashPg) % nSlot | ||
| 234872 | ** | ||
| 234873 | ** Each tombstone hash page begins with an 8 byte header: | ||
| 234874 | ** | ||
| 234875 | ** 1-byte: Key-size (the size in bytes of each slot). Either 4 or 8. | ||
| 234876 | ** 1-byte: rowid-0-tombstone flag. This flag is only valid on the | ||
| 234877 | ** first tombstone hash page for each segment (iPg=0). If set, | ||
| 234878 | ** the hash table contains rowid 0. If clear, it does not. | ||
| 234879 | ** Rowid 0 is handled specially. | ||
| 234880 | ** 2-bytes: unused. | ||
| 234881 | ** 4-bytes: Big-endian integer containing number of entries on page. | ||
| 234882 | ** | ||
| 234883 | ** Following this are nSlot 4 or 8 byte slots (depending on the key-size | ||
| 234884 | ** in the first byte of the page header). The number of slots may be | ||
| 234885 | ** determined based on the size of the page record and the key-size: | ||
| 234886 | ** | ||
| 234887 | ** nSlot = (nByte - 8) / key-size | ||
| 227299 | */ | 234888 | */ |
| 227300 | 234889 | ||
| 227301 | /* | 234890 | /* |
| @@ -227329,6 +234918,7 @@ static void sqlite3Fts5HashScanEntry( | |||
| 227329 | 234918 | ||
| 227330 | #define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno) | 234919 | #define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno) |
| 227331 | #define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno) | 234920 | #define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno) |
| 234921 | #define FTS5_TOMBSTONE_ROWID(segid,ipg) fts5_dri(segid+(1<<16), 0, 0, ipg) | ||
| 227332 | 234922 | ||
| 227333 | #ifdef SQLITE_DEBUG | 234923 | #ifdef SQLITE_DEBUG |
| 227334 | static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; } | 234924 | static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; } |
| @@ -227364,6 +234954,12 @@ struct Fts5Data { | |||
| 227364 | 234954 | ||
| 227365 | /* | 234955 | /* |
| 227366 | ** One object per %_data table. | 234956 | ** One object per %_data table. |
| 234957 | ** | ||
| 234958 | ** nContentlessDelete: | ||
| 234959 | ** The number of contentless delete operations since the most recent | ||
| 234960 | ** call to fts5IndexFlush() or fts5IndexDiscardData(). This is tracked | ||
| 234961 | ** so that extra auto-merge work can be done by fts5IndexFlush() to | ||
| 234962 | ** account for the delete operations. | ||
| 227367 | */ | 234963 | */ |
| 227368 | struct Fts5Index { | 234964 | struct Fts5Index { |
| 227369 | Fts5Config *pConfig; /* Virtual table configuration */ | 234965 | Fts5Config *pConfig; /* Virtual table configuration */ |
| @@ -227378,6 +234974,8 @@ struct Fts5Index { | |||
| 227378 | int nPendingData; /* Current bytes of pending data */ | 234974 | int nPendingData; /* Current bytes of pending data */ |
| 227379 | i64 iWriteRowid; /* Rowid for current doc being written */ | 234975 | i64 iWriteRowid; /* Rowid for current doc being written */ |
| 227380 | int bDelete; /* Current write is a delete */ | 234976 | int bDelete; /* Current write is a delete */ |
| 234977 | int nContentlessDelete; /* Number of contentless delete ops */ | ||
| 234978 | int nPendingRow; /* Number of INSERT in hash table */ | ||
| 227381 | 234979 | ||
| 227382 | /* Error state. */ | 234980 | /* Error state. */ |
| 227383 | int rc; /* Current error code */ | 234981 | int rc; /* Current error code */ |
| @@ -227391,6 +234989,8 @@ struct Fts5Index { | |||
| 227391 | sqlite3_stmt *pIdxSelect; | 234989 | sqlite3_stmt *pIdxSelect; |
| 227392 | int nRead; /* Total number of blocks read */ | 234990 | int nRead; /* Total number of blocks read */ |
| 227393 | 234991 | ||
| 234992 | sqlite3_stmt *pDeleteFromIdx; | ||
| 234993 | |||
| 227394 | sqlite3_stmt *pDataVersion; | 234994 | sqlite3_stmt *pDataVersion; |
| 227395 | i64 iStructVersion; /* data_version when pStruct read */ | 234995 | i64 iStructVersion; /* data_version when pStruct read */ |
| 227396 | Fts5Structure *pStruct; /* Current db structure (or NULL) */ | 234996 | Fts5Structure *pStruct; /* Current db structure (or NULL) */ |
| @@ -227410,11 +235010,23 @@ struct Fts5DoclistIter { | |||
| 227410 | ** The contents of the "structure" record for each index are represented | 235010 | ** The contents of the "structure" record for each index are represented |
| 227411 | ** using an Fts5Structure record in memory. Which uses instances of the | 235011 | ** using an Fts5Structure record in memory. Which uses instances of the |
| 227412 | ** other Fts5StructureXXX types as components. | 235012 | ** other Fts5StructureXXX types as components. |
| 235013 | ** | ||
| 235014 | ** nOriginCntr: | ||
| 235015 | ** This value is set to non-zero for structure records created for | ||
| 235016 | ** contentlessdelete=1 tables only. In that case it represents the | ||
| 235017 | ** origin value to apply to the next top-level segment created. | ||
| 227413 | */ | 235018 | */ |
| 227414 | struct Fts5StructureSegment { | 235019 | struct Fts5StructureSegment { |
| 227415 | int iSegid; /* Segment id */ | 235020 | int iSegid; /* Segment id */ |
| 227416 | int pgnoFirst; /* First leaf page number in segment */ | 235021 | int pgnoFirst; /* First leaf page number in segment */ |
| 227417 | int pgnoLast; /* Last leaf page number in segment */ | 235022 | int pgnoLast; /* Last leaf page number in segment */ |
| 235023 | |||
| 235024 | /* contentlessdelete=1 tables only: */ | ||
| 235025 | u64 iOrigin1; | ||
| 235026 | u64 iOrigin2; | ||
| 235027 | int nPgTombstone; /* Number of tombstone hash table pages */ | ||
| 235028 | u64 nEntryTombstone; /* Number of tombstone entries that "count" */ | ||
| 235029 | u64 nEntry; /* Number of rows in this segment */ | ||
| 227418 | }; | 235030 | }; |
| 227419 | struct Fts5StructureLevel { | 235031 | struct Fts5StructureLevel { |
| 227420 | int nMerge; /* Number of segments in incr-merge */ | 235032 | int nMerge; /* Number of segments in incr-merge */ |
| @@ -227424,6 +235036,7 @@ struct Fts5StructureLevel { | |||
| 227424 | struct Fts5Structure { | 235036 | struct Fts5Structure { |
| 227425 | int nRef; /* Object reference count */ | 235037 | int nRef; /* Object reference count */ |
| 227426 | u64 nWriteCounter; /* Total leaves written to level 0 */ | 235038 | u64 nWriteCounter; /* Total leaves written to level 0 */ |
| 235039 | u64 nOriginCntr; /* Origin value for next top-level segment */ | ||
| 227427 | int nSegment; /* Total segments in this structure */ | 235040 | int nSegment; /* Total segments in this structure */ |
| 227428 | int nLevel; /* Number of levels in this index */ | 235041 | int nLevel; /* Number of levels in this index */ |
| 227429 | Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */ | 235042 | Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */ |
| @@ -227483,9 +235096,6 @@ struct Fts5CResult { | |||
| 227483 | ** iLeafOffset: | 235096 | ** iLeafOffset: |
| 227484 | ** Byte offset within the current leaf that is the first byte of the | 235097 | ** Byte offset within the current leaf that is the first byte of the |
| 227485 | ** position list data (one byte passed the position-list size field). | 235098 | ** position list data (one byte passed the position-list size field). |
| 227486 | ** rowid field of the current entry. Usually this is the size field of the | ||
| 227487 | ** position list data. The exception is if the rowid for the current entry | ||
| 227488 | ** is the last thing on the leaf page. | ||
| 227489 | ** | 235099 | ** |
| 227490 | ** pLeaf: | 235100 | ** pLeaf: |
| 227491 | ** Buffer containing current leaf page data. Set to NULL at EOF. | 235101 | ** Buffer containing current leaf page data. Set to NULL at EOF. |
| @@ -227515,6 +235125,13 @@ struct Fts5CResult { | |||
| 227515 | ** | 235125 | ** |
| 227516 | ** iTermIdx: | 235126 | ** iTermIdx: |
| 227517 | ** Index of current term on iTermLeafPgno. | 235127 | ** Index of current term on iTermLeafPgno. |
| 235128 | ** | ||
| 235129 | ** apTombstone/nTombstone: | ||
| 235130 | ** These are used for contentless_delete=1 tables only. When the cursor | ||
| 235131 | ** is first allocated, the apTombstone[] array is allocated so that it | ||
| 235132 | ** is large enough for all tombstones hash pages associated with the | ||
| 235133 | ** segment. The pages themselves are loaded lazily from the database as | ||
| 235134 | ** they are required. | ||
| 227518 | */ | 235135 | */ |
| 227519 | struct Fts5SegIter { | 235136 | struct Fts5SegIter { |
| 227520 | Fts5StructureSegment *pSeg; /* Segment to iterate through */ | 235137 | Fts5StructureSegment *pSeg; /* Segment to iterate through */ |
| @@ -227523,6 +235140,8 @@ struct Fts5SegIter { | |||
| 227523 | Fts5Data *pLeaf; /* Current leaf data */ | 235140 | Fts5Data *pLeaf; /* Current leaf data */ |
| 227524 | Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ | 235141 | Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ |
| 227525 | i64 iLeafOffset; /* Byte offset within current leaf */ | 235142 | i64 iLeafOffset; /* Byte offset within current leaf */ |
| 235143 | Fts5Data **apTombstone; /* Array of tombstone pages */ | ||
| 235144 | int nTombstone; | ||
| 227526 | 235145 | ||
| 227527 | /* Next method */ | 235146 | /* Next method */ |
| 227528 | void (*xNext)(Fts5Index*, Fts5SegIter*, int*); | 235147 | void (*xNext)(Fts5Index*, Fts5SegIter*, int*); |
| @@ -227653,6 +235272,60 @@ static u16 fts5GetU16(const u8 *aIn){ | |||
| 227653 | } | 235272 | } |
| 227654 | 235273 | ||
| 227655 | /* | 235274 | /* |
| 235275 | ** The only argument points to a buffer at least 8 bytes in size. This | ||
| 235276 | ** function interprets the first 8 bytes of the buffer as a 64-bit big-endian | ||
| 235277 | ** unsigned integer and returns the result. | ||
| 235278 | */ | ||
| 235279 | static u64 fts5GetU64(u8 *a){ | ||
| 235280 | return ((u64)a[0] << 56) | ||
| 235281 | + ((u64)a[1] << 48) | ||
| 235282 | + ((u64)a[2] << 40) | ||
| 235283 | + ((u64)a[3] << 32) | ||
| 235284 | + ((u64)a[4] << 24) | ||
| 235285 | + ((u64)a[5] << 16) | ||
| 235286 | + ((u64)a[6] << 8) | ||
| 235287 | + ((u64)a[7] << 0); | ||
| 235288 | } | ||
| 235289 | |||
| 235290 | /* | ||
| 235291 | ** The only argument points to a buffer at least 4 bytes in size. This | ||
| 235292 | ** function interprets the first 4 bytes of the buffer as a 32-bit big-endian | ||
| 235293 | ** unsigned integer and returns the result. | ||
| 235294 | */ | ||
| 235295 | static u32 fts5GetU32(const u8 *a){ | ||
| 235296 | return ((u32)a[0] << 24) | ||
| 235297 | + ((u32)a[1] << 16) | ||
| 235298 | + ((u32)a[2] << 8) | ||
| 235299 | + ((u32)a[3] << 0); | ||
| 235300 | } | ||
| 235301 | |||
| 235302 | /* | ||
| 235303 | ** Write iVal, formated as a 64-bit big-endian unsigned integer, to the | ||
| 235304 | ** buffer indicated by the first argument. | ||
| 235305 | */ | ||
| 235306 | static void fts5PutU64(u8 *a, u64 iVal){ | ||
| 235307 | a[0] = ((iVal >> 56) & 0xFF); | ||
| 235308 | a[1] = ((iVal >> 48) & 0xFF); | ||
| 235309 | a[2] = ((iVal >> 40) & 0xFF); | ||
| 235310 | a[3] = ((iVal >> 32) & 0xFF); | ||
| 235311 | a[4] = ((iVal >> 24) & 0xFF); | ||
| 235312 | a[5] = ((iVal >> 16) & 0xFF); | ||
| 235313 | a[6] = ((iVal >> 8) & 0xFF); | ||
| 235314 | a[7] = ((iVal >> 0) & 0xFF); | ||
| 235315 | } | ||
| 235316 | |||
| 235317 | /* | ||
| 235318 | ** Write iVal, formated as a 32-bit big-endian unsigned integer, to the | ||
| 235319 | ** buffer indicated by the first argument. | ||
| 235320 | */ | ||
| 235321 | static void fts5PutU32(u8 *a, u32 iVal){ | ||
| 235322 | a[0] = ((iVal >> 24) & 0xFF); | ||
| 235323 | a[1] = ((iVal >> 16) & 0xFF); | ||
| 235324 | a[2] = ((iVal >> 8) & 0xFF); | ||
| 235325 | a[3] = ((iVal >> 0) & 0xFF); | ||
| 235326 | } | ||
| 235327 | |||
| 235328 | /* | ||
| 227656 | ** Allocate and return a buffer at least nByte bytes in size. | 235329 | ** Allocate and return a buffer at least nByte bytes in size. |
| 227657 | ** | 235330 | ** |
| 227658 | ** If an OOM error is encountered, return NULL and set the error code in | 235331 | ** If an OOM error is encountered, return NULL and set the error code in |
| @@ -227879,10 +235552,17 @@ static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){ | |||
| 227879 | /* | 235552 | /* |
| 227880 | ** Remove all records associated with segment iSegid. | 235553 | ** Remove all records associated with segment iSegid. |
| 227881 | */ | 235554 | */ |
| 227882 | static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){ | 235555 | static void fts5DataRemoveSegment(Fts5Index *p, Fts5StructureSegment *pSeg){ |
| 235556 | int iSegid = pSeg->iSegid; | ||
| 227883 | i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0); | 235557 | i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0); |
| 227884 | i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1; | 235558 | i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1; |
| 227885 | fts5DataDelete(p, iFirst, iLast); | 235559 | fts5DataDelete(p, iFirst, iLast); |
| 235560 | |||
| 235561 | if( pSeg->nPgTombstone ){ | ||
| 235562 | i64 iTomb1 = FTS5_TOMBSTONE_ROWID(iSegid, 0); | ||
| 235563 | i64 iTomb2 = FTS5_TOMBSTONE_ROWID(iSegid, pSeg->nPgTombstone-1); | ||
| 235564 | fts5DataDelete(p, iTomb1, iTomb2); | ||
| 235565 | } | ||
| 227886 | if( p->pIdxDeleter==0 ){ | 235566 | if( p->pIdxDeleter==0 ){ |
| 227887 | Fts5Config *pConfig = p->pConfig; | 235567 | Fts5Config *pConfig = p->pConfig; |
| 227888 | fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf( | 235568 | fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf( |
| @@ -227993,11 +235673,19 @@ static int fts5StructureDecode( | |||
| 227993 | int nSegment = 0; | 235673 | int nSegment = 0; |
| 227994 | sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */ | 235674 | sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */ |
| 227995 | Fts5Structure *pRet = 0; /* Structure object to return */ | 235675 | Fts5Structure *pRet = 0; /* Structure object to return */ |
| 235676 | int bStructureV2 = 0; /* True for FTS5_STRUCTURE_V2 */ | ||
| 235677 | u64 nOriginCntr = 0; /* Largest origin value seen so far */ | ||
| 227996 | 235678 | ||
| 227997 | /* Grab the cookie value */ | 235679 | /* Grab the cookie value */ |
| 227998 | if( piCookie ) *piCookie = sqlite3Fts5Get32(pData); | 235680 | if( piCookie ) *piCookie = sqlite3Fts5Get32(pData); |
| 227999 | i = 4; | 235681 | i = 4; |
| 228000 | 235682 | ||
| 235683 | /* Check if this is a V2 structure record. Set bStructureV2 if it is. */ | ||
| 235684 | if( 0==memcmp(&pData[i], FTS5_STRUCTURE_V2, 4) ){ | ||
| 235685 | i += 4; | ||
| 235686 | bStructureV2 = 1; | ||
| 235687 | } | ||
| 235688 | |||
| 228001 | /* Read the total number of levels and segments from the start of the | 235689 | /* Read the total number of levels and segments from the start of the |
| 228002 | ** structure record. */ | 235690 | ** structure record. */ |
| 228003 | i += fts5GetVarint32(&pData[i], nLevel); | 235691 | i += fts5GetVarint32(&pData[i], nLevel); |
| @@ -228044,9 +235732,18 @@ static int fts5StructureDecode( | |||
| 228044 | rc = FTS5_CORRUPT; | 235732 | rc = FTS5_CORRUPT; |
| 228045 | break; | 235733 | break; |
| 228046 | } | 235734 | } |
| 235735 | assert( pSeg!=0 ); | ||
| 228047 | i += fts5GetVarint32(&pData[i], pSeg->iSegid); | 235736 | i += fts5GetVarint32(&pData[i], pSeg->iSegid); |
| 228048 | i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst); | 235737 | i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst); |
| 228049 | i += fts5GetVarint32(&pData[i], pSeg->pgnoLast); | 235738 | i += fts5GetVarint32(&pData[i], pSeg->pgnoLast); |
| 235739 | if( bStructureV2 ){ | ||
| 235740 | i += fts5GetVarint(&pData[i], &pSeg->iOrigin1); | ||
| 235741 | i += fts5GetVarint(&pData[i], &pSeg->iOrigin2); | ||
| 235742 | i += fts5GetVarint32(&pData[i], pSeg->nPgTombstone); | ||
| 235743 | i += fts5GetVarint(&pData[i], &pSeg->nEntryTombstone); | ||
| 235744 | i += fts5GetVarint(&pData[i], &pSeg->nEntry); | ||
| 235745 | nOriginCntr = MAX(nOriginCntr, pSeg->iOrigin2); | ||
| 235746 | } | ||
| 228050 | if( pSeg->pgnoLast<pSeg->pgnoFirst ){ | 235747 | if( pSeg->pgnoLast<pSeg->pgnoFirst ){ |
| 228051 | rc = FTS5_CORRUPT; | 235748 | rc = FTS5_CORRUPT; |
| 228052 | break; | 235749 | break; |
| @@ -228057,6 +235754,9 @@ static int fts5StructureDecode( | |||
| 228057 | } | 235754 | } |
| 228058 | } | 235755 | } |
| 228059 | if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT; | 235756 | if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT; |
| 235757 | if( bStructureV2 ){ | ||
| 235758 | pRet->nOriginCntr = nOriginCntr+1; | ||
| 235759 | } | ||
| 228060 | 235760 | ||
| 228061 | if( rc!=SQLITE_OK ){ | 235761 | if( rc!=SQLITE_OK ){ |
| 228062 | fts5StructureRelease(pRet); | 235762 | fts5StructureRelease(pRet); |
| @@ -228074,6 +235774,7 @@ static int fts5StructureDecode( | |||
| 228074 | */ | 235774 | */ |
| 228075 | static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ | 235775 | static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ |
| 228076 | fts5StructureMakeWritable(pRc, ppStruct); | 235776 | fts5StructureMakeWritable(pRc, ppStruct); |
| 235777 | assert( (ppStruct!=0 && (*ppStruct)!=0) || (*pRc)!=SQLITE_OK ); | ||
| 228077 | if( *pRc==SQLITE_OK ){ | 235778 | if( *pRc==SQLITE_OK ){ |
| 228078 | Fts5Structure *pStruct = *ppStruct; | 235779 | Fts5Structure *pStruct = *ppStruct; |
| 228079 | int nLevel = pStruct->nLevel; | 235780 | int nLevel = pStruct->nLevel; |
| @@ -228268,6 +235969,7 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){ | |||
| 228268 | Fts5Buffer buf; /* Buffer to serialize record into */ | 235969 | Fts5Buffer buf; /* Buffer to serialize record into */ |
| 228269 | int iLvl; /* Used to iterate through levels */ | 235970 | int iLvl; /* Used to iterate through levels */ |
| 228270 | int iCookie; /* Cookie value to store */ | 235971 | int iCookie; /* Cookie value to store */ |
| 235972 | int nHdr = (pStruct->nOriginCntr>0 ? (4+4+9+9+9) : (4+9+9)); | ||
| 228271 | 235973 | ||
| 228272 | assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); | 235974 | assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); |
| 228273 | memset(&buf, 0, sizeof(Fts5Buffer)); | 235975 | memset(&buf, 0, sizeof(Fts5Buffer)); |
| @@ -228276,9 +235978,12 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){ | |||
| 228276 | iCookie = p->pConfig->iCookie; | 235978 | iCookie = p->pConfig->iCookie; |
| 228277 | if( iCookie<0 ) iCookie = 0; | 235979 | if( iCookie<0 ) iCookie = 0; |
| 228278 | 235980 | ||
| 228279 | if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){ | 235981 | if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, nHdr) ){ |
| 228280 | sqlite3Fts5Put32(buf.p, iCookie); | 235982 | sqlite3Fts5Put32(buf.p, iCookie); |
| 228281 | buf.n = 4; | 235983 | buf.n = 4; |
| 235984 | if( pStruct->nOriginCntr>0 ){ | ||
| 235985 | fts5BufferSafeAppendBlob(&buf, FTS5_STRUCTURE_V2, 4); | ||
| 235986 | } | ||
| 228282 | fts5BufferSafeAppendVarint(&buf, pStruct->nLevel); | 235987 | fts5BufferSafeAppendVarint(&buf, pStruct->nLevel); |
| 228283 | fts5BufferSafeAppendVarint(&buf, pStruct->nSegment); | 235988 | fts5BufferSafeAppendVarint(&buf, pStruct->nSegment); |
| 228284 | fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter); | 235989 | fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter); |
| @@ -228292,9 +235997,17 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){ | |||
| 228292 | assert( pLvl->nMerge<=pLvl->nSeg ); | 235997 | assert( pLvl->nMerge<=pLvl->nSeg ); |
| 228293 | 235998 | ||
| 228294 | for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){ | 235999 | for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){ |
| 228295 | fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid); | 236000 | Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; |
| 228296 | fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst); | 236001 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->iSegid); |
| 228297 | fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast); | 236002 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoFirst); |
| 236003 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoLast); | ||
| 236004 | if( pStruct->nOriginCntr>0 ){ | ||
| 236005 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin1); | ||
| 236006 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin2); | ||
| 236007 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->nPgTombstone); | ||
| 236008 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntryTombstone); | ||
| 236009 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntry); | ||
| 236010 | } | ||
| 228298 | } | 236011 | } |
| 228299 | } | 236012 | } |
| 228300 | 236013 | ||
| @@ -228532,42 +236245,25 @@ static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){ | |||
| 228532 | pLvl->bEof = 1; | 236245 | pLvl->bEof = 1; |
| 228533 | }else{ | 236246 | }else{ |
| 228534 | u8 *a = pLvl->pData->p; | 236247 | u8 *a = pLvl->pData->p; |
| 228535 | i64 iVal; | 236248 | |
| 228536 | int iLimit; | 236249 | pLvl->iOff = 0; |
| 228537 | int ii; | 236250 | fts5DlidxLvlNext(pLvl); |
| 228538 | int nZero = 0; | 236251 | while( 1 ){ |
| 228539 | 236252 | int nZero = 0; | |
| 228540 | /* Currently iOff points to the first byte of a varint. This block | 236253 | int ii = pLvl->iOff; |
| 228541 | ** decrements iOff until it points to the first byte of the previous | 236254 | u64 delta = 0; |
| 228542 | ** varint. Taking care not to read any memory locations that occur | 236255 | |
| 228543 | ** before the buffer in memory. */ | 236256 | while( a[ii]==0 ){ |
| 228544 | iLimit = (iOff>9 ? iOff-9 : 0); | 236257 | nZero++; |
| 228545 | for(iOff--; iOff>iLimit; iOff--){ | 236258 | ii++; |
| 228546 | if( (a[iOff-1] & 0x80)==0 ) break; | ||
| 228547 | } | ||
| 228548 | |||
| 228549 | fts5GetVarint(&a[iOff], (u64*)&iVal); | ||
| 228550 | pLvl->iRowid -= iVal; | ||
| 228551 | pLvl->iLeafPgno--; | ||
| 228552 | |||
| 228553 | /* Skip backwards past any 0x00 varints. */ | ||
| 228554 | for(ii=iOff-1; ii>=pLvl->iFirstOff && a[ii]==0x00; ii--){ | ||
| 228555 | nZero++; | ||
| 228556 | } | ||
| 228557 | if( ii>=pLvl->iFirstOff && (a[ii] & 0x80) ){ | ||
| 228558 | /* The byte immediately before the last 0x00 byte has the 0x80 bit | ||
| 228559 | ** set. So the last 0x00 is only a varint 0 if there are 8 more 0x80 | ||
| 228560 | ** bytes before a[ii]. */ | ||
| 228561 | int bZero = 0; /* True if last 0x00 counts */ | ||
| 228562 | if( (ii-8)>=pLvl->iFirstOff ){ | ||
| 228563 | int j; | ||
| 228564 | for(j=1; j<=8 && (a[ii-j] & 0x80); j++); | ||
| 228565 | bZero = (j>8); | ||
| 228566 | } | 236259 | } |
| 228567 | if( bZero==0 ) nZero--; | 236260 | ii += sqlite3Fts5GetVarint(&a[ii], &delta); |
| 236261 | |||
| 236262 | if( ii>=iOff ) break; | ||
| 236263 | pLvl->iLeafPgno += nZero+1; | ||
| 236264 | pLvl->iRowid += delta; | ||
| 236265 | pLvl->iOff = ii; | ||
| 228568 | } | 236266 | } |
| 228569 | pLvl->iLeafPgno -= nZero; | ||
| 228570 | pLvl->iOff = iOff - nZero; | ||
| 228571 | } | 236267 | } |
| 228572 | 236268 | ||
| 228573 | return pLvl->bEof; | 236269 | return pLvl->bEof; |
| @@ -228763,7 +236459,7 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){ | |||
| 228763 | i64 iOff = pIter->iLeafOffset; | 236459 | i64 iOff = pIter->iLeafOffset; |
| 228764 | 236460 | ||
| 228765 | ASSERT_SZLEAF_OK(pIter->pLeaf); | 236461 | ASSERT_SZLEAF_OK(pIter->pLeaf); |
| 228766 | if( iOff>=pIter->pLeaf->szLeaf ){ | 236462 | while( iOff>=pIter->pLeaf->szLeaf ){ |
| 228767 | fts5SegIterNextPage(p, pIter); | 236463 | fts5SegIterNextPage(p, pIter); |
| 228768 | if( pIter->pLeaf==0 ){ | 236464 | if( pIter->pLeaf==0 ){ |
| 228769 | if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; | 236465 | if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; |
| @@ -228835,6 +236531,23 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ | |||
| 228835 | } | 236531 | } |
| 228836 | 236532 | ||
| 228837 | /* | 236533 | /* |
| 236534 | ** Allocate a tombstone hash page array (pIter->apTombstone) for the | ||
| 236535 | ** iterator passed as the second argument. If an OOM error occurs, leave | ||
| 236536 | ** an error in the Fts5Index object. | ||
| 236537 | */ | ||
| 236538 | static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ | ||
| 236539 | const int nTomb = pIter->pSeg->nPgTombstone; | ||
| 236540 | if( nTomb>0 ){ | ||
| 236541 | Fts5Data **apTomb = 0; | ||
| 236542 | apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb); | ||
| 236543 | if( apTomb ){ | ||
| 236544 | pIter->apTombstone = apTomb; | ||
| 236545 | pIter->nTombstone = nTomb; | ||
| 236546 | } | ||
| 236547 | } | ||
| 236548 | } | ||
| 236549 | |||
| 236550 | /* | ||
| 228838 | ** Initialize the iterator object pIter to iterate through the entries in | 236551 | ** Initialize the iterator object pIter to iterate through the entries in |
| 228839 | ** segment pSeg. The iterator is left pointing to the first entry when | 236552 | ** segment pSeg. The iterator is left pointing to the first entry when |
| 228840 | ** this function returns. | 236553 | ** this function returns. |
| @@ -228862,10 +236575,12 @@ static void fts5SegIterInit( | |||
| 228862 | fts5SegIterSetNext(p, pIter); | 236575 | fts5SegIterSetNext(p, pIter); |
| 228863 | pIter->pSeg = pSeg; | 236576 | pIter->pSeg = pSeg; |
| 228864 | pIter->iLeafPgno = pSeg->pgnoFirst-1; | 236577 | pIter->iLeafPgno = pSeg->pgnoFirst-1; |
| 228865 | fts5SegIterNextPage(p, pIter); | 236578 | do { |
| 236579 | fts5SegIterNextPage(p, pIter); | ||
| 236580 | }while( p->rc==SQLITE_OK && pIter->pLeaf && pIter->pLeaf->nn==4 ); | ||
| 228866 | } | 236581 | } |
| 228867 | 236582 | ||
| 228868 | if( p->rc==SQLITE_OK ){ | 236583 | if( p->rc==SQLITE_OK && pIter->pLeaf ){ |
| 228869 | pIter->iLeafOffset = 4; | 236584 | pIter->iLeafOffset = 4; |
| 228870 | assert( pIter->pLeaf!=0 ); | 236585 | assert( pIter->pLeaf!=0 ); |
| 228871 | assert_nc( pIter->pLeaf->nn>4 ); | 236586 | assert_nc( pIter->pLeaf->nn>4 ); |
| @@ -228873,6 +236588,7 @@ static void fts5SegIterInit( | |||
| 228873 | pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; | 236588 | pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; |
| 228874 | fts5SegIterLoadTerm(p, pIter, 0); | 236589 | fts5SegIterLoadTerm(p, pIter, 0); |
| 228875 | fts5SegIterLoadNPos(p, pIter); | 236590 | fts5SegIterLoadNPos(p, pIter); |
| 236591 | fts5SegIterAllocTombstone(p, pIter); | ||
| 228876 | } | 236592 | } |
| 228877 | } | 236593 | } |
| 228878 | 236594 | ||
| @@ -229059,7 +236775,7 @@ static void fts5SegIterNext_None( | |||
| 229059 | iOff = pIter->iLeafOffset; | 236775 | iOff = pIter->iLeafOffset; |
| 229060 | 236776 | ||
| 229061 | /* Next entry is on the next page */ | 236777 | /* Next entry is on the next page */ |
| 229062 | if( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){ | 236778 | while( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){ |
| 229063 | fts5SegIterNextPage(p, pIter); | 236779 | fts5SegIterNextPage(p, pIter); |
| 229064 | if( p->rc || pIter->pLeaf==0 ) return; | 236780 | if( p->rc || pIter->pLeaf==0 ) return; |
| 229065 | pIter->iRowid = 0; | 236781 | pIter->iRowid = 0; |
| @@ -229252,7 +236968,7 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ | |||
| 229252 | Fts5Data *pLast = 0; | 236968 | Fts5Data *pLast = 0; |
| 229253 | int pgnoLast = 0; | 236969 | int pgnoLast = 0; |
| 229254 | 236970 | ||
| 229255 | if( pDlidx ){ | 236971 | if( pDlidx && p->pConfig->iVersion==FTS5_CURRENT_VERSION ){ |
| 229256 | int iSegid = pIter->pSeg->iSegid; | 236972 | int iSegid = pIter->pSeg->iSegid; |
| 229257 | pgnoLast = fts5DlidxIterPgno(pDlidx); | 236973 | pgnoLast = fts5DlidxIterPgno(pDlidx); |
| 229258 | pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast)); | 236974 | pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast)); |
| @@ -229574,6 +237290,7 @@ static void fts5SegIterSeekInit( | |||
| 229574 | } | 237290 | } |
| 229575 | 237291 | ||
| 229576 | fts5SegIterSetNext(p, pIter); | 237292 | fts5SegIterSetNext(p, pIter); |
| 237293 | fts5SegIterAllocTombstone(p, pIter); | ||
| 229577 | 237294 | ||
| 229578 | /* Either: | 237295 | /* Either: |
| 229579 | ** | 237296 | ** |
| @@ -229655,12 +237372,27 @@ static void fts5SegIterHashInit( | |||
| 229655 | } | 237372 | } |
| 229656 | 237373 | ||
| 229657 | /* | 237374 | /* |
| 237375 | ** Array ap[] contains n elements. Release each of these elements using | ||
| 237376 | ** fts5DataRelease(). Then free the array itself using sqlite3_free(). | ||
| 237377 | */ | ||
| 237378 | static void fts5IndexFreeArray(Fts5Data **ap, int n){ | ||
| 237379 | if( ap ){ | ||
| 237380 | int ii; | ||
| 237381 | for(ii=0; ii<n; ii++){ | ||
| 237382 | fts5DataRelease(ap[ii]); | ||
| 237383 | } | ||
| 237384 | sqlite3_free(ap); | ||
| 237385 | } | ||
| 237386 | } | ||
| 237387 | |||
| 237388 | /* | ||
| 229658 | ** Zero the iterator passed as the only argument. | 237389 | ** Zero the iterator passed as the only argument. |
| 229659 | */ | 237390 | */ |
| 229660 | static void fts5SegIterClear(Fts5SegIter *pIter){ | 237391 | static void fts5SegIterClear(Fts5SegIter *pIter){ |
| 229661 | fts5BufferFree(&pIter->term); | 237392 | fts5BufferFree(&pIter->term); |
| 229662 | fts5DataRelease(pIter->pLeaf); | 237393 | fts5DataRelease(pIter->pLeaf); |
| 229663 | fts5DataRelease(pIter->pNextLeaf); | 237394 | fts5DataRelease(pIter->pNextLeaf); |
| 237395 | fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone); | ||
| 229664 | fts5DlidxIterFree(pIter->pDlidx); | 237396 | fts5DlidxIterFree(pIter->pDlidx); |
| 229665 | sqlite3_free(pIter->aRowidOffset); | 237397 | sqlite3_free(pIter->aRowidOffset); |
| 229666 | memset(pIter, 0, sizeof(Fts5SegIter)); | 237398 | memset(pIter, 0, sizeof(Fts5SegIter)); |
| @@ -229813,7 +237545,8 @@ static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){ | |||
| 229813 | 237545 | ||
| 229814 | /* | 237546 | /* |
| 229815 | ** Move the seg-iter so that it points to the first rowid on page iLeafPgno. | 237547 | ** Move the seg-iter so that it points to the first rowid on page iLeafPgno. |
| 229816 | ** It is an error if leaf iLeafPgno does not exist or contains no rowids. | 237548 | ** It is an error if leaf iLeafPgno does not exist. Unless the db is |
| 237549 | ** a 'secure-delete' db, if it contains no rowids then this is also an error. | ||
| 229817 | */ | 237550 | */ |
| 229818 | static void fts5SegIterGotoPage( | 237551 | static void fts5SegIterGotoPage( |
| 229819 | Fts5Index *p, /* FTS5 backend object */ | 237552 | Fts5Index *p, /* FTS5 backend object */ |
| @@ -229828,21 +237561,23 @@ static void fts5SegIterGotoPage( | |||
| 229828 | fts5DataRelease(pIter->pNextLeaf); | 237561 | fts5DataRelease(pIter->pNextLeaf); |
| 229829 | pIter->pNextLeaf = 0; | 237562 | pIter->pNextLeaf = 0; |
| 229830 | pIter->iLeafPgno = iLeafPgno-1; | 237563 | pIter->iLeafPgno = iLeafPgno-1; |
| 229831 | fts5SegIterNextPage(p, pIter); | ||
| 229832 | assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno ); | ||
| 229833 | 237564 | ||
| 229834 | if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){ | 237565 | while( p->rc==SQLITE_OK ){ |
| 229835 | int iOff; | 237566 | int iOff; |
| 229836 | u8 *a = pIter->pLeaf->p; | 237567 | fts5SegIterNextPage(p, pIter); |
| 229837 | int n = pIter->pLeaf->szLeaf; | 237568 | if( pIter->pLeaf==0 ) break; |
| 229838 | |||
| 229839 | iOff = fts5LeafFirstRowidOff(pIter->pLeaf); | 237569 | iOff = fts5LeafFirstRowidOff(pIter->pLeaf); |
| 229840 | if( iOff<4 || iOff>=n ){ | 237570 | if( iOff>0 ){ |
| 229841 | p->rc = FTS5_CORRUPT; | 237571 | u8 *a = pIter->pLeaf->p; |
| 229842 | }else{ | 237572 | int n = pIter->pLeaf->szLeaf; |
| 229843 | iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); | 237573 | if( iOff<4 || iOff>=n ){ |
| 229844 | pIter->iLeafOffset = iOff; | 237574 | p->rc = FTS5_CORRUPT; |
| 229845 | fts5SegIterLoadNPos(p, pIter); | 237575 | }else{ |
| 237576 | iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); | ||
| 237577 | pIter->iLeafOffset = iOff; | ||
| 237578 | fts5SegIterLoadNPos(p, pIter); | ||
| 237579 | } | ||
| 237580 | break; | ||
| 229846 | } | 237581 | } |
| 229847 | } | 237582 | } |
| 229848 | } | 237583 | } |
| @@ -229996,6 +237731,84 @@ static void fts5MultiIterSetEof(Fts5Iter *pIter){ | |||
| 229996 | } | 237731 | } |
| 229997 | 237732 | ||
| 229998 | /* | 237733 | /* |
| 237734 | ** The argument to this macro must be an Fts5Data structure containing a | ||
| 237735 | ** tombstone hash page. This macro returns the key-size of the hash-page. | ||
| 237736 | */ | ||
| 237737 | #define TOMBSTONE_KEYSIZE(pPg) (pPg->p[0]==4 ? 4 : 8) | ||
| 237738 | |||
| 237739 | #define TOMBSTONE_NSLOT(pPg) \ | ||
| 237740 | ((pPg->nn > 16) ? ((pPg->nn-8) / TOMBSTONE_KEYSIZE(pPg)) : 1) | ||
| 237741 | |||
| 237742 | /* | ||
| 237743 | ** Query a single tombstone hash table for rowid iRowid. Return true if | ||
| 237744 | ** it is found or false otherwise. The tombstone hash table is one of | ||
| 237745 | ** nHashTable tables. | ||
| 237746 | */ | ||
| 237747 | static int fts5IndexTombstoneQuery( | ||
| 237748 | Fts5Data *pHash, /* Hash table page to query */ | ||
| 237749 | int nHashTable, /* Number of pages attached to segment */ | ||
| 237750 | u64 iRowid /* Rowid to query hash for */ | ||
| 237751 | ){ | ||
| 237752 | const int szKey = TOMBSTONE_KEYSIZE(pHash); | ||
| 237753 | const int nSlot = TOMBSTONE_NSLOT(pHash); | ||
| 237754 | int iSlot = (iRowid / nHashTable) % nSlot; | ||
| 237755 | int nCollide = nSlot; | ||
| 237756 | |||
| 237757 | if( iRowid==0 ){ | ||
| 237758 | return pHash->p[1]; | ||
| 237759 | }else if( szKey==4 ){ | ||
| 237760 | u32 *aSlot = (u32*)&pHash->p[8]; | ||
| 237761 | while( aSlot[iSlot] ){ | ||
| 237762 | if( fts5GetU32((u8*)&aSlot[iSlot])==iRowid ) return 1; | ||
| 237763 | if( nCollide--==0 ) break; | ||
| 237764 | iSlot = (iSlot+1)%nSlot; | ||
| 237765 | } | ||
| 237766 | }else{ | ||
| 237767 | u64 *aSlot = (u64*)&pHash->p[8]; | ||
| 237768 | while( aSlot[iSlot] ){ | ||
| 237769 | if( fts5GetU64((u8*)&aSlot[iSlot])==iRowid ) return 1; | ||
| 237770 | if( nCollide--==0 ) break; | ||
| 237771 | iSlot = (iSlot+1)%nSlot; | ||
| 237772 | } | ||
| 237773 | } | ||
| 237774 | |||
| 237775 | return 0; | ||
| 237776 | } | ||
| 237777 | |||
| 237778 | /* | ||
| 237779 | ** Return true if the iterator passed as the only argument points | ||
| 237780 | ** to an segment entry for which there is a tombstone. Return false | ||
| 237781 | ** if there is no tombstone or if the iterator is already at EOF. | ||
| 237782 | */ | ||
| 237783 | static int fts5MultiIterIsDeleted(Fts5Iter *pIter){ | ||
| 237784 | int iFirst = pIter->aFirst[1].iFirst; | ||
| 237785 | Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; | ||
| 237786 | |||
| 237787 | if( pSeg->pLeaf && pSeg->nTombstone ){ | ||
| 237788 | /* Figure out which page the rowid might be present on. */ | ||
| 237789 | int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone; | ||
| 237790 | assert( iPg>=0 ); | ||
| 237791 | |||
| 237792 | /* If tombstone hash page iPg has not yet been loaded from the | ||
| 237793 | ** database, load it now. */ | ||
| 237794 | if( pSeg->apTombstone[iPg]==0 ){ | ||
| 237795 | pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex, | ||
| 237796 | FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) | ||
| 237797 | ); | ||
| 237798 | if( pSeg->apTombstone[iPg]==0 ) return 0; | ||
| 237799 | } | ||
| 237800 | |||
| 237801 | return fts5IndexTombstoneQuery( | ||
| 237802 | pSeg->apTombstone[iPg], | ||
| 237803 | pSeg->nTombstone, | ||
| 237804 | pSeg->iRowid | ||
| 237805 | ); | ||
| 237806 | } | ||
| 237807 | |||
| 237808 | return 0; | ||
| 237809 | } | ||
| 237810 | |||
| 237811 | /* | ||
| 229999 | ** Move the iterator to the next entry. | 237812 | ** Move the iterator to the next entry. |
| 230000 | ** | 237813 | ** |
| 230001 | ** If an error occurs, an error code is left in Fts5Index.rc. It is not | 237814 | ** If an error occurs, an error code is left in Fts5Index.rc. It is not |
| @@ -230032,7 +237845,9 @@ static void fts5MultiIterNext( | |||
| 230032 | 237845 | ||
| 230033 | fts5AssertMultiIterSetup(p, pIter); | 237846 | fts5AssertMultiIterSetup(p, pIter); |
| 230034 | assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf ); | 237847 | assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf ); |
| 230035 | if( pIter->bSkipEmpty==0 || pSeg->nPos ){ | 237848 | if( (pIter->bSkipEmpty==0 || pSeg->nPos) |
| 237849 | && 0==fts5MultiIterIsDeleted(pIter) | ||
| 237850 | ){ | ||
| 230036 | pIter->xSetOutputs(pIter, pSeg); | 237851 | pIter->xSetOutputs(pIter, pSeg); |
| 230037 | return; | 237852 | return; |
| 230038 | } | 237853 | } |
| @@ -230064,7 +237879,9 @@ static void fts5MultiIterNext2( | |||
| 230064 | } | 237879 | } |
| 230065 | fts5AssertMultiIterSetup(p, pIter); | 237880 | fts5AssertMultiIterSetup(p, pIter); |
| 230066 | 237881 | ||
| 230067 | }while( fts5MultiIterIsEmpty(p, pIter) ); | 237882 | }while( (fts5MultiIterIsEmpty(p, pIter) || fts5MultiIterIsDeleted(pIter)) |
| 237883 | && (p->rc==SQLITE_OK) | ||
| 237884 | ); | ||
| 230068 | } | 237885 | } |
| 230069 | } | 237886 | } |
| 230070 | 237887 | ||
| @@ -230557,7 +238374,7 @@ static void fts5MultiIterNew( | |||
| 230557 | if( iLevel<0 ){ | 238374 | if( iLevel<0 ){ |
| 230558 | assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); | 238375 | assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); |
| 230559 | nSeg = pStruct->nSegment; | 238376 | nSeg = pStruct->nSegment; |
| 230560 | nSeg += (p->pHash ? 1 : 0); | 238377 | nSeg += (p->pHash && 0==(flags & FTS5INDEX_QUERY_SKIPHASH)); |
| 230561 | }else{ | 238378 | }else{ |
| 230562 | nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment); | 238379 | nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment); |
| 230563 | } | 238380 | } |
| @@ -230578,7 +238395,7 @@ static void fts5MultiIterNew( | |||
| 230578 | if( p->rc==SQLITE_OK ){ | 238395 | if( p->rc==SQLITE_OK ){ |
| 230579 | if( iLevel<0 ){ | 238396 | if( iLevel<0 ){ |
| 230580 | Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel]; | 238397 | Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel]; |
| 230581 | if( p->pHash ){ | 238398 | if( p->pHash && 0==(flags & FTS5INDEX_QUERY_SKIPHASH) ){ |
| 230582 | /* Add a segment iterator for the current contents of the hash table. */ | 238399 | /* Add a segment iterator for the current contents of the hash table. */ |
| 230583 | Fts5SegIter *pIter = &pNew->aSeg[iIter++]; | 238400 | Fts5SegIter *pIter = &pNew->aSeg[iIter++]; |
| 230584 | fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter); | 238401 | fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter); |
| @@ -230619,7 +238436,9 @@ static void fts5MultiIterNew( | |||
| 230619 | fts5MultiIterSetEof(pNew); | 238436 | fts5MultiIterSetEof(pNew); |
| 230620 | fts5AssertMultiIterSetup(p, pNew); | 238437 | fts5AssertMultiIterSetup(p, pNew); |
| 230621 | 238438 | ||
| 230622 | if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){ | 238439 | if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew)) |
| 238440 | || fts5MultiIterIsDeleted(pNew) | ||
| 238441 | ){ | ||
| 230623 | fts5MultiIterNext(p, pNew, 0, 0); | 238442 | fts5MultiIterNext(p, pNew, 0, 0); |
| 230624 | }else if( pNew->base.bEof==0 ){ | 238443 | }else if( pNew->base.bEof==0 ){ |
| 230625 | Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; | 238444 | Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; |
| @@ -230797,7 +238616,9 @@ static void fts5IndexDiscardData(Fts5Index *p){ | |||
| 230797 | if( p->pHash ){ | 238616 | if( p->pHash ){ |
| 230798 | sqlite3Fts5HashClear(p->pHash); | 238617 | sqlite3Fts5HashClear(p->pHash); |
| 230799 | p->nPendingData = 0; | 238618 | p->nPendingData = 0; |
| 238619 | p->nPendingRow = 0; | ||
| 230800 | } | 238620 | } |
| 238621 | p->nContentlessDelete = 0; | ||
| 230801 | } | 238622 | } |
| 230802 | 238623 | ||
| 230803 | /* | 238624 | /* |
| @@ -231178,7 +238999,9 @@ static void fts5WriteAppendRowid( | |||
| 231178 | fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid); | 238999 | fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid); |
| 231179 | }else{ | 239000 | }else{ |
| 231180 | assert_nc( p->rc || iRowid>pWriter->iPrevRowid ); | 239001 | assert_nc( p->rc || iRowid>pWriter->iPrevRowid ); |
| 231181 | fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid); | 239002 | fts5BufferAppendVarint(&p->rc, &pPage->buf, |
| 239003 | (u64)iRowid - (u64)pWriter->iPrevRowid | ||
| 239004 | ); | ||
| 231182 | } | 239005 | } |
| 231183 | pWriter->iPrevRowid = iRowid; | 239006 | pWriter->iPrevRowid = iRowid; |
| 231184 | pWriter->bFirstRowidInDoclist = 0; | 239007 | pWriter->bFirstRowidInDoclist = 0; |
| @@ -231331,7 +239154,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){ | |||
| 231331 | fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr); | 239154 | fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr); |
| 231332 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n); | 239155 | fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n); |
| 231333 | fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p); | 239156 | fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p); |
| 231334 | fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff,&pData->p[iOff]); | 239157 | fts5BufferAppendBlob(&p->rc, &buf,pData->szLeaf-iOff,&pData->p[iOff]); |
| 231335 | if( p->rc==SQLITE_OK ){ | 239158 | if( p->rc==SQLITE_OK ){ |
| 231336 | /* Set the szLeaf field */ | 239159 | /* Set the szLeaf field */ |
| 231337 | fts5PutU16(&buf.p[2], (u16)buf.n); | 239160 | fts5PutU16(&buf.p[2], (u16)buf.n); |
| @@ -231432,6 +239255,12 @@ static void fts5IndexMergeLevel( | |||
| 231432 | 239255 | ||
| 231433 | /* Read input from all segments in the input level */ | 239256 | /* Read input from all segments in the input level */ |
| 231434 | nInput = pLvl->nSeg; | 239257 | nInput = pLvl->nSeg; |
| 239258 | |||
| 239259 | /* Set the range of origins that will go into the output segment. */ | ||
| 239260 | if( pStruct->nOriginCntr>0 ){ | ||
| 239261 | pSeg->iOrigin1 = pLvl->aSeg[0].iOrigin1; | ||
| 239262 | pSeg->iOrigin2 = pLvl->aSeg[pLvl->nSeg-1].iOrigin2; | ||
| 239263 | } | ||
| 231435 | } | 239264 | } |
| 231436 | bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2); | 239265 | bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2); |
| 231437 | 239266 | ||
| @@ -231491,8 +239320,11 @@ static void fts5IndexMergeLevel( | |||
| 231491 | int i; | 239320 | int i; |
| 231492 | 239321 | ||
| 231493 | /* Remove the redundant segments from the %_data table */ | 239322 | /* Remove the redundant segments from the %_data table */ |
| 239323 | assert( pSeg->nEntry==0 ); | ||
| 231494 | for(i=0; i<nInput; i++){ | 239324 | for(i=0; i<nInput; i++){ |
| 231495 | fts5DataRemoveSegment(p, pLvl->aSeg[i].iSegid); | 239325 | Fts5StructureSegment *pOld = &pLvl->aSeg[i]; |
| 239326 | pSeg->nEntry += (pOld->nEntry - pOld->nEntryTombstone); | ||
| 239327 | fts5DataRemoveSegment(p, pOld); | ||
| 231496 | } | 239328 | } |
| 231497 | 239329 | ||
| 231498 | /* Remove the redundant segments from the input level */ | 239330 | /* Remove the redundant segments from the input level */ |
| @@ -231519,6 +239351,43 @@ static void fts5IndexMergeLevel( | |||
| 231519 | } | 239351 | } |
| 231520 | 239352 | ||
| 231521 | /* | 239353 | /* |
| 239354 | ** If this is not a contentless_delete=1 table, or if the 'deletemerge' | ||
| 239355 | ** configuration option is set to 0, then this function always returns -1. | ||
| 239356 | ** Otherwise, it searches the structure object passed as the second argument | ||
| 239357 | ** for a level suitable for merging due to having a large number of | ||
| 239358 | ** tombstones in the tombstone hash. If one is found, its index is returned. | ||
| 239359 | ** Otherwise, if there is no suitable level, -1. | ||
| 239360 | */ | ||
| 239361 | static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){ | ||
| 239362 | Fts5Config *pConfig = p->pConfig; | ||
| 239363 | int iRet = -1; | ||
| 239364 | if( pConfig->bContentlessDelete && pConfig->nDeleteMerge>0 ){ | ||
| 239365 | int ii; | ||
| 239366 | int nBest = 0; | ||
| 239367 | |||
| 239368 | for(ii=0; ii<pStruct->nLevel; ii++){ | ||
| 239369 | Fts5StructureLevel *pLvl = &pStruct->aLevel[ii]; | ||
| 239370 | i64 nEntry = 0; | ||
| 239371 | i64 nTomb = 0; | ||
| 239372 | int iSeg; | ||
| 239373 | for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){ | ||
| 239374 | nEntry += pLvl->aSeg[iSeg].nEntry; | ||
| 239375 | nTomb += pLvl->aSeg[iSeg].nEntryTombstone; | ||
| 239376 | } | ||
| 239377 | assert_nc( nEntry>0 || pLvl->nSeg==0 ); | ||
| 239378 | if( nEntry>0 ){ | ||
| 239379 | int nPercent = (nTomb * 100) / nEntry; | ||
| 239380 | if( nPercent>=pConfig->nDeleteMerge && nPercent>nBest ){ | ||
| 239381 | iRet = ii; | ||
| 239382 | nBest = nPercent; | ||
| 239383 | } | ||
| 239384 | } | ||
| 239385 | } | ||
| 239386 | } | ||
| 239387 | return iRet; | ||
| 239388 | } | ||
| 239389 | |||
| 239390 | /* | ||
| 231522 | ** Do up to nPg pages of automerge work on the index. | 239391 | ** Do up to nPg pages of automerge work on the index. |
| 231523 | ** | 239392 | ** |
| 231524 | ** Return true if any changes were actually made, or false otherwise. | 239393 | ** Return true if any changes were actually made, or false otherwise. |
| @@ -231537,14 +239406,15 @@ static int fts5IndexMerge( | |||
| 231537 | int iBestLvl = 0; /* Level offering the most input segments */ | 239406 | int iBestLvl = 0; /* Level offering the most input segments */ |
| 231538 | int nBest = 0; /* Number of input segments on best level */ | 239407 | int nBest = 0; /* Number of input segments on best level */ |
| 231539 | 239408 | ||
| 231540 | /* Set iBestLvl to the level to read input segments from. */ | 239409 | /* Set iBestLvl to the level to read input segments from. Or to -1 if |
| 239410 | ** there is no level suitable to merge segments from. */ | ||
| 231541 | assert( pStruct->nLevel>0 ); | 239411 | assert( pStruct->nLevel>0 ); |
| 231542 | for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ | 239412 | for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ |
| 231543 | Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; | 239413 | Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; |
| 231544 | if( pLvl->nMerge ){ | 239414 | if( pLvl->nMerge ){ |
| 231545 | if( pLvl->nMerge>nBest ){ | 239415 | if( pLvl->nMerge>nBest ){ |
| 231546 | iBestLvl = iLvl; | 239416 | iBestLvl = iLvl; |
| 231547 | nBest = pLvl->nMerge; | 239417 | nBest = nMin; |
| 231548 | } | 239418 | } |
| 231549 | break; | 239419 | break; |
| 231550 | } | 239420 | } |
| @@ -231553,22 +239423,18 @@ static int fts5IndexMerge( | |||
| 231553 | iBestLvl = iLvl; | 239423 | iBestLvl = iLvl; |
| 231554 | } | 239424 | } |
| 231555 | } | 239425 | } |
| 231556 | 239426 | if( nBest<nMin ){ | |
| 231557 | /* If nBest is still 0, then the index must be empty. */ | 239427 | iBestLvl = fts5IndexFindDeleteMerge(p, pStruct); |
| 231558 | #ifdef SQLITE_DEBUG | ||
| 231559 | for(iLvl=0; nBest==0 && iLvl<pStruct->nLevel; iLvl++){ | ||
| 231560 | assert( pStruct->aLevel[iLvl].nSeg==0 ); | ||
| 231561 | } | 239428 | } |
| 231562 | #endif | ||
| 231563 | 239429 | ||
| 231564 | if( nBest<nMin && pStruct->aLevel[iBestLvl].nMerge==0 ){ | 239430 | if( iBestLvl<0 ) break; |
| 231565 | break; | ||
| 231566 | } | ||
| 231567 | bRet = 1; | 239431 | bRet = 1; |
| 231568 | fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem); | 239432 | fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem); |
| 231569 | if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){ | 239433 | if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){ |
| 231570 | fts5StructurePromote(p, iBestLvl+1, pStruct); | 239434 | fts5StructurePromote(p, iBestLvl+1, pStruct); |
| 231571 | } | 239435 | } |
| 239436 | |||
| 239437 | if( nMin==1 ) nMin = 2; | ||
| 231572 | } | 239438 | } |
| 231573 | *ppStruct = pStruct; | 239439 | *ppStruct = pStruct; |
| 231574 | return bRet; | 239440 | return bRet; |
| @@ -231609,16 +239475,16 @@ static void fts5IndexCrisismerge( | |||
| 231609 | ){ | 239475 | ){ |
| 231610 | const int nCrisis = p->pConfig->nCrisisMerge; | 239476 | const int nCrisis = p->pConfig->nCrisisMerge; |
| 231611 | Fts5Structure *pStruct = *ppStruct; | 239477 | Fts5Structure *pStruct = *ppStruct; |
| 231612 | int iLvl = 0; | 239478 | if( pStruct && pStruct->nLevel>0 ){ |
| 231613 | 239479 | int iLvl = 0; | |
| 231614 | assert( p->rc!=SQLITE_OK || pStruct->nLevel>0 ); | 239480 | while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){ |
| 231615 | while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){ | 239481 | fts5IndexMergeLevel(p, &pStruct, iLvl, 0); |
| 231616 | fts5IndexMergeLevel(p, &pStruct, iLvl, 0); | 239482 | assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) ); |
| 231617 | assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) ); | 239483 | fts5StructurePromote(p, iLvl+1, pStruct); |
| 231618 | fts5StructurePromote(p, iLvl+1, pStruct); | 239484 | iLvl++; |
| 231619 | iLvl++; | 239485 | } |
| 239486 | *ppStruct = pStruct; | ||
| 231620 | } | 239487 | } |
| 231621 | *ppStruct = pStruct; | ||
| 231622 | } | 239488 | } |
| 231623 | 239489 | ||
| 231624 | static int fts5IndexReturn(Fts5Index *p){ | 239490 | static int fts5IndexReturn(Fts5Index *p){ |
| @@ -231653,6 +239519,419 @@ static int fts5PoslistPrefix(const u8 *aBuf, int nMax){ | |||
| 231653 | } | 239519 | } |
| 231654 | 239520 | ||
| 231655 | /* | 239521 | /* |
| 239522 | ** Execute the SQL statement: | ||
| 239523 | ** | ||
| 239524 | ** DELETE FROM %_idx WHERE (segid, (pgno/2)) = ($iSegid, $iPgno); | ||
| 239525 | ** | ||
| 239526 | ** This is used when a secure-delete operation removes the last term | ||
| 239527 | ** from a segment leaf page. In that case the %_idx entry is removed | ||
| 239528 | ** too. This is done to ensure that if all instances of a token are | ||
| 239529 | ** removed from an fts5 database in secure-delete mode, no trace of | ||
| 239530 | ** the token itself remains in the database. | ||
| 239531 | */ | ||
| 239532 | static void fts5SecureDeleteIdxEntry( | ||
| 239533 | Fts5Index *p, /* FTS5 backend object */ | ||
| 239534 | int iSegid, /* Id of segment to delete entry for */ | ||
| 239535 | int iPgno /* Page number within segment */ | ||
| 239536 | ){ | ||
| 239537 | if( iPgno!=1 ){ | ||
| 239538 | assert( p->pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE ); | ||
| 239539 | if( p->pDeleteFromIdx==0 ){ | ||
| 239540 | fts5IndexPrepareStmt(p, &p->pDeleteFromIdx, sqlite3_mprintf( | ||
| 239541 | "DELETE FROM '%q'.'%q_idx' WHERE (segid, (pgno/2)) = (?1, ?2)", | ||
| 239542 | p->pConfig->zDb, p->pConfig->zName | ||
| 239543 | )); | ||
| 239544 | } | ||
| 239545 | if( p->rc==SQLITE_OK ){ | ||
| 239546 | sqlite3_bind_int(p->pDeleteFromIdx, 1, iSegid); | ||
| 239547 | sqlite3_bind_int(p->pDeleteFromIdx, 2, iPgno); | ||
| 239548 | sqlite3_step(p->pDeleteFromIdx); | ||
| 239549 | p->rc = sqlite3_reset(p->pDeleteFromIdx); | ||
| 239550 | } | ||
| 239551 | } | ||
| 239552 | } | ||
| 239553 | |||
| 239554 | /* | ||
| 239555 | ** This is called when a secure-delete operation removes a position-list | ||
| 239556 | ** that overflows onto segment page iPgno of segment pSeg. This function | ||
| 239557 | ** rewrites node iPgno, and possibly one or more of its right-hand peers, | ||
| 239558 | ** to remove this portion of the position list. | ||
| 239559 | ** | ||
| 239560 | ** Output variable (*pbLastInDoclist) is set to true if the position-list | ||
| 239561 | ** removed is followed by a new term or the end-of-segment, or false if | ||
| 239562 | ** it is followed by another rowid/position list. | ||
| 239563 | */ | ||
| 239564 | static void fts5SecureDeleteOverflow( | ||
| 239565 | Fts5Index *p, | ||
| 239566 | Fts5StructureSegment *pSeg, | ||
| 239567 | int iPgno, | ||
| 239568 | int *pbLastInDoclist | ||
| 239569 | ){ | ||
| 239570 | const int bDetailNone = (p->pConfig->eDetail==FTS5_DETAIL_NONE); | ||
| 239571 | int pgno; | ||
| 239572 | Fts5Data *pLeaf = 0; | ||
| 239573 | assert( iPgno!=1 ); | ||
| 239574 | |||
| 239575 | *pbLastInDoclist = 1; | ||
| 239576 | for(pgno=iPgno; p->rc==SQLITE_OK && pgno<=pSeg->pgnoLast; pgno++){ | ||
| 239577 | i64 iRowid = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno); | ||
| 239578 | int iNext = 0; | ||
| 239579 | u8 *aPg = 0; | ||
| 239580 | |||
| 239581 | pLeaf = fts5DataRead(p, iRowid); | ||
| 239582 | if( pLeaf==0 ) break; | ||
| 239583 | aPg = pLeaf->p; | ||
| 239584 | |||
| 239585 | iNext = fts5GetU16(&aPg[0]); | ||
| 239586 | if( iNext!=0 ){ | ||
| 239587 | *pbLastInDoclist = 0; | ||
| 239588 | } | ||
| 239589 | if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){ | ||
| 239590 | fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext); | ||
| 239591 | } | ||
| 239592 | |||
| 239593 | if( iNext==0 ){ | ||
| 239594 | /* The page contains no terms or rowids. Replace it with an empty | ||
| 239595 | ** page and move on to the right-hand peer. */ | ||
| 239596 | const u8 aEmpty[] = {0x00, 0x00, 0x00, 0x04}; | ||
| 239597 | assert_nc( bDetailNone==0 || pLeaf->nn==4 ); | ||
| 239598 | if( bDetailNone==0 ) fts5DataWrite(p, iRowid, aEmpty, sizeof(aEmpty)); | ||
| 239599 | fts5DataRelease(pLeaf); | ||
| 239600 | pLeaf = 0; | ||
| 239601 | }else if( bDetailNone ){ | ||
| 239602 | break; | ||
| 239603 | }else if( iNext>=pLeaf->szLeaf || pLeaf->nn<pLeaf->szLeaf || iNext<4 ){ | ||
| 239604 | p->rc = FTS5_CORRUPT; | ||
| 239605 | break; | ||
| 239606 | }else{ | ||
| 239607 | int nShift = iNext - 4; | ||
| 239608 | int nPg; | ||
| 239609 | |||
| 239610 | int nIdx = 0; | ||
| 239611 | u8 *aIdx = 0; | ||
| 239612 | |||
| 239613 | /* Unless the current page footer is 0 bytes in size (in which case | ||
| 239614 | ** the new page footer will be as well), allocate and populate a | ||
| 239615 | ** buffer containing the new page footer. Set stack variables aIdx | ||
| 239616 | ** and nIdx accordingly. */ | ||
| 239617 | if( pLeaf->nn>pLeaf->szLeaf ){ | ||
| 239618 | int iFirst = 0; | ||
| 239619 | int i1 = pLeaf->szLeaf; | ||
| 239620 | int i2 = 0; | ||
| 239621 | |||
| 239622 | i1 += fts5GetVarint32(&aPg[i1], iFirst); | ||
| 239623 | if( iFirst<iNext ){ | ||
| 239624 | p->rc = FTS5_CORRUPT; | ||
| 239625 | break; | ||
| 239626 | } | ||
| 239627 | aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2); | ||
| 239628 | if( aIdx==0 ) break; | ||
| 239629 | i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift); | ||
| 239630 | if( i1<pLeaf->nn ){ | ||
| 239631 | memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1); | ||
| 239632 | i2 += (pLeaf->nn-i1); | ||
| 239633 | } | ||
| 239634 | nIdx = i2; | ||
| 239635 | } | ||
| 239636 | |||
| 239637 | /* Modify the contents of buffer aPg[]. Set nPg to the new size | ||
| 239638 | ** in bytes. The new page is always smaller than the old. */ | ||
| 239639 | nPg = pLeaf->szLeaf - nShift; | ||
| 239640 | memmove(&aPg[4], &aPg[4+nShift], nPg-4); | ||
| 239641 | fts5PutU16(&aPg[2], nPg); | ||
| 239642 | if( fts5GetU16(&aPg[0]) ) fts5PutU16(&aPg[0], 4); | ||
| 239643 | if( nIdx>0 ){ | ||
| 239644 | memcpy(&aPg[nPg], aIdx, nIdx); | ||
| 239645 | nPg += nIdx; | ||
| 239646 | } | ||
| 239647 | sqlite3_free(aIdx); | ||
| 239648 | |||
| 239649 | /* Write the new page to disk and exit the loop */ | ||
| 239650 | assert( nPg>4 || fts5GetU16(aPg)==0 ); | ||
| 239651 | fts5DataWrite(p, iRowid, aPg, nPg); | ||
| 239652 | break; | ||
| 239653 | } | ||
| 239654 | } | ||
| 239655 | fts5DataRelease(pLeaf); | ||
| 239656 | } | ||
| 239657 | |||
| 239658 | /* | ||
| 239659 | ** Completely remove the entry that pSeg currently points to from | ||
| 239660 | ** the database. | ||
| 239661 | */ | ||
| 239662 | static void fts5DoSecureDelete( | ||
| 239663 | Fts5Index *p, | ||
| 239664 | Fts5SegIter *pSeg | ||
| 239665 | ){ | ||
| 239666 | const int bDetailNone = (p->pConfig->eDetail==FTS5_DETAIL_NONE); | ||
| 239667 | int iSegid = pSeg->pSeg->iSegid; | ||
| 239668 | u8 *aPg = pSeg->pLeaf->p; | ||
| 239669 | int nPg = pSeg->pLeaf->nn; | ||
| 239670 | int iPgIdx = pSeg->pLeaf->szLeaf; | ||
| 239671 | |||
| 239672 | u64 iDelta = 0; | ||
| 239673 | u64 iNextDelta = 0; | ||
| 239674 | int iNextOff = 0; | ||
| 239675 | int iOff = 0; | ||
| 239676 | int nIdx = 0; | ||
| 239677 | u8 *aIdx = 0; | ||
| 239678 | int bLastInDoclist = 0; | ||
| 239679 | int iIdx = 0; | ||
| 239680 | int iStart = 0; | ||
| 239681 | int iKeyOff = 0; | ||
| 239682 | int iPrevKeyOff = 0; | ||
| 239683 | int iDelKeyOff = 0; /* Offset of deleted key, if any */ | ||
| 239684 | |||
| 239685 | nIdx = nPg-iPgIdx; | ||
| 239686 | aIdx = sqlite3Fts5MallocZero(&p->rc, nIdx+16); | ||
| 239687 | if( p->rc ) return; | ||
| 239688 | memcpy(aIdx, &aPg[iPgIdx], nIdx); | ||
| 239689 | |||
| 239690 | /* At this point segment iterator pSeg points to the entry | ||
| 239691 | ** this function should remove from the b-tree segment. | ||
| 239692 | ** | ||
| 239693 | ** In detail=full or detail=column mode, pSeg->iLeafOffset is the | ||
| 239694 | ** offset of the first byte in the position-list for the entry to | ||
| 239695 | ** remove. Immediately before this comes two varints that will also | ||
| 239696 | ** need to be removed: | ||
| 239697 | ** | ||
| 239698 | ** + the rowid or delta rowid value for the entry, and | ||
| 239699 | ** + the size of the position list in bytes. | ||
| 239700 | ** | ||
| 239701 | ** Or, in detail=none mode, there is a single varint prior to | ||
| 239702 | ** pSeg->iLeafOffset - the rowid or delta rowid value. | ||
| 239703 | ** | ||
| 239704 | ** This block sets the following variables: | ||
| 239705 | ** | ||
| 239706 | ** iStart: | ||
| 239707 | ** iDelta: | ||
| 239708 | */ | ||
| 239709 | { | ||
| 239710 | int iSOP; | ||
| 239711 | if( pSeg->iLeafPgno==pSeg->iTermLeafPgno ){ | ||
| 239712 | iStart = pSeg->iTermLeafOffset; | ||
| 239713 | }else{ | ||
| 239714 | iStart = fts5GetU16(&aPg[0]); | ||
| 239715 | } | ||
| 239716 | |||
| 239717 | iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); | ||
| 239718 | assert_nc( iSOP<=pSeg->iLeafOffset ); | ||
| 239719 | |||
| 239720 | if( bDetailNone ){ | ||
| 239721 | while( iSOP<pSeg->iLeafOffset ){ | ||
| 239722 | if( aPg[iSOP]==0x00 ) iSOP++; | ||
| 239723 | if( aPg[iSOP]==0x00 ) iSOP++; | ||
| 239724 | iStart = iSOP; | ||
| 239725 | iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); | ||
| 239726 | } | ||
| 239727 | |||
| 239728 | iNextOff = iSOP; | ||
| 239729 | if( iNextOff<pSeg->iEndofDoclist && aPg[iNextOff]==0x00 ) iNextOff++; | ||
| 239730 | if( iNextOff<pSeg->iEndofDoclist && aPg[iNextOff]==0x00 ) iNextOff++; | ||
| 239731 | |||
| 239732 | }else{ | ||
| 239733 | int nPos = 0; | ||
| 239734 | iSOP += fts5GetVarint32(&aPg[iSOP], nPos); | ||
| 239735 | while( iSOP<pSeg->iLeafOffset ){ | ||
| 239736 | iStart = iSOP + (nPos/2); | ||
| 239737 | iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); | ||
| 239738 | iSOP += fts5GetVarint32(&aPg[iSOP], nPos); | ||
| 239739 | } | ||
| 239740 | assert_nc( iSOP==pSeg->iLeafOffset ); | ||
| 239741 | iNextOff = pSeg->iLeafOffset + pSeg->nPos; | ||
| 239742 | } | ||
| 239743 | } | ||
| 239744 | |||
| 239745 | iOff = iStart; | ||
| 239746 | if( iNextOff>=iPgIdx ){ | ||
| 239747 | int pgno = pSeg->iLeafPgno+1; | ||
| 239748 | fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); | ||
| 239749 | iNextOff = iPgIdx; | ||
| 239750 | }else{ | ||
| 239751 | /* Set bLastInDoclist to true if the entry being removed is the last | ||
| 239752 | ** in its doclist. */ | ||
| 239753 | for(iIdx=0, iKeyOff=0; iIdx<nIdx; /* no-op */){ | ||
| 239754 | u32 iVal = 0; | ||
| 239755 | iIdx += fts5GetVarint32(&aIdx[iIdx], iVal); | ||
| 239756 | iKeyOff += iVal; | ||
| 239757 | if( iKeyOff==iNextOff ){ | ||
| 239758 | bLastInDoclist = 1; | ||
| 239759 | } | ||
| 239760 | } | ||
| 239761 | } | ||
| 239762 | |||
| 239763 | if( fts5GetU16(&aPg[0])==iStart && (bLastInDoclist||iNextOff==iPgIdx) ){ | ||
| 239764 | fts5PutU16(&aPg[0], 0); | ||
| 239765 | } | ||
| 239766 | |||
| 239767 | if( bLastInDoclist==0 ){ | ||
| 239768 | if( iNextOff!=iPgIdx ){ | ||
| 239769 | iNextOff += fts5GetVarint(&aPg[iNextOff], &iNextDelta); | ||
| 239770 | iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta + iNextDelta); | ||
| 239771 | } | ||
| 239772 | }else if( | ||
| 239773 | iStart==pSeg->iTermLeafOffset && pSeg->iLeafPgno==pSeg->iTermLeafPgno | ||
| 239774 | ){ | ||
| 239775 | /* The entry being removed was the only position list in its | ||
| 239776 | ** doclist. Therefore the term needs to be removed as well. */ | ||
| 239777 | int iKey = 0; | ||
| 239778 | for(iIdx=0, iKeyOff=0; iIdx<nIdx; iKey++){ | ||
| 239779 | u32 iVal = 0; | ||
| 239780 | iIdx += fts5GetVarint32(&aIdx[iIdx], iVal); | ||
| 239781 | if( (iKeyOff+iVal)>(u32)iStart ) break; | ||
| 239782 | iKeyOff += iVal; | ||
| 239783 | } | ||
| 239784 | |||
| 239785 | iDelKeyOff = iOff = iKeyOff; | ||
| 239786 | if( iNextOff!=iPgIdx ){ | ||
| 239787 | int nPrefix = 0; | ||
| 239788 | int nSuffix = 0; | ||
| 239789 | int nPrefix2 = 0; | ||
| 239790 | int nSuffix2 = 0; | ||
| 239791 | |||
| 239792 | iDelKeyOff = iNextOff; | ||
| 239793 | iNextOff += fts5GetVarint32(&aPg[iNextOff], nPrefix2); | ||
| 239794 | iNextOff += fts5GetVarint32(&aPg[iNextOff], nSuffix2); | ||
| 239795 | |||
| 239796 | if( iKey!=1 ){ | ||
| 239797 | iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nPrefix); | ||
| 239798 | } | ||
| 239799 | iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix); | ||
| 239800 | |||
| 239801 | nPrefix = MIN(nPrefix, nPrefix2); | ||
| 239802 | nSuffix = (nPrefix2 + nSuffix2) - nPrefix; | ||
| 239803 | |||
| 239804 | if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){ | ||
| 239805 | p->rc = FTS5_CORRUPT; | ||
| 239806 | }else{ | ||
| 239807 | if( iKey!=1 ){ | ||
| 239808 | iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix); | ||
| 239809 | } | ||
| 239810 | iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix); | ||
| 239811 | if( nPrefix2>pSeg->term.n ){ | ||
| 239812 | p->rc = FTS5_CORRUPT; | ||
| 239813 | }else if( nPrefix2>nPrefix ){ | ||
| 239814 | memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix); | ||
| 239815 | iOff += (nPrefix2-nPrefix); | ||
| 239816 | } | ||
| 239817 | memmove(&aPg[iOff], &aPg[iNextOff], nSuffix2); | ||
| 239818 | iOff += nSuffix2; | ||
| 239819 | iNextOff += nSuffix2; | ||
| 239820 | } | ||
| 239821 | } | ||
| 239822 | }else if( iStart==4 ){ | ||
| 239823 | int iPgno; | ||
| 239824 | |||
| 239825 | assert_nc( pSeg->iLeafPgno>pSeg->iTermLeafPgno ); | ||
| 239826 | /* The entry being removed may be the only position list in | ||
| 239827 | ** its doclist. */ | ||
| 239828 | for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){ | ||
| 239829 | Fts5Data *pPg = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno)); | ||
| 239830 | int bEmpty = (pPg && pPg->nn==4); | ||
| 239831 | fts5DataRelease(pPg); | ||
| 239832 | if( bEmpty==0 ) break; | ||
| 239833 | } | ||
| 239834 | |||
| 239835 | if( iPgno==pSeg->iTermLeafPgno ){ | ||
| 239836 | i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno); | ||
| 239837 | Fts5Data *pTerm = fts5DataRead(p, iId); | ||
| 239838 | if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){ | ||
| 239839 | u8 *aTermIdx = &pTerm->p[pTerm->szLeaf]; | ||
| 239840 | int nTermIdx = pTerm->nn - pTerm->szLeaf; | ||
| 239841 | int iTermIdx = 0; | ||
| 239842 | int iTermOff = 0; | ||
| 239843 | |||
| 239844 | while( 1 ){ | ||
| 239845 | u32 iVal = 0; | ||
| 239846 | int nByte = fts5GetVarint32(&aTermIdx[iTermIdx], iVal); | ||
| 239847 | iTermOff += iVal; | ||
| 239848 | if( (iTermIdx+nByte)>=nTermIdx ) break; | ||
| 239849 | iTermIdx += nByte; | ||
| 239850 | } | ||
| 239851 | nTermIdx = iTermIdx; | ||
| 239852 | |||
| 239853 | memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx); | ||
| 239854 | fts5PutU16(&pTerm->p[2], iTermOff); | ||
| 239855 | |||
| 239856 | fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); | ||
| 239857 | if( nTermIdx==0 ){ | ||
| 239858 | fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); | ||
| 239859 | } | ||
| 239860 | } | ||
| 239861 | fts5DataRelease(pTerm); | ||
| 239862 | } | ||
| 239863 | } | ||
| 239864 | |||
| 239865 | if( p->rc==SQLITE_OK ){ | ||
| 239866 | const int nMove = nPg - iNextOff; | ||
| 239867 | int nShift = 0; | ||
| 239868 | |||
| 239869 | memmove(&aPg[iOff], &aPg[iNextOff], nMove); | ||
| 239870 | iPgIdx -= (iNextOff - iOff); | ||
| 239871 | nPg = iPgIdx; | ||
| 239872 | fts5PutU16(&aPg[2], iPgIdx); | ||
| 239873 | |||
| 239874 | nShift = iNextOff - iOff; | ||
| 239875 | for(iIdx=0, iKeyOff=0, iPrevKeyOff=0; iIdx<nIdx; /* no-op */){ | ||
| 239876 | u32 iVal = 0; | ||
| 239877 | iIdx += fts5GetVarint32(&aIdx[iIdx], iVal); | ||
| 239878 | iKeyOff += iVal; | ||
| 239879 | if( iKeyOff!=iDelKeyOff ){ | ||
| 239880 | if( iKeyOff>iOff ){ | ||
| 239881 | iKeyOff -= nShift; | ||
| 239882 | nShift = 0; | ||
| 239883 | } | ||
| 239884 | nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOff - iPrevKeyOff); | ||
| 239885 | iPrevKeyOff = iKeyOff; | ||
| 239886 | } | ||
| 239887 | } | ||
| 239888 | |||
| 239889 | if( iPgIdx==nPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ | ||
| 239890 | fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iLeafPgno); | ||
| 239891 | } | ||
| 239892 | |||
| 239893 | assert_nc( nPg>4 || fts5GetU16(aPg)==0 ); | ||
| 239894 | fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg,nPg); | ||
| 239895 | } | ||
| 239896 | sqlite3_free(aIdx); | ||
| 239897 | } | ||
| 239898 | |||
| 239899 | /* | ||
| 239900 | ** This is called as part of flushing a delete to disk in 'secure-delete' | ||
| 239901 | ** mode. It edits the segments within the database described by argument | ||
| 239902 | ** pStruct to remove the entries for term zTerm, rowid iRowid. | ||
| 239903 | */ | ||
| 239904 | static void fts5FlushSecureDelete( | ||
| 239905 | Fts5Index *p, | ||
| 239906 | Fts5Structure *pStruct, | ||
| 239907 | const char *zTerm, | ||
| 239908 | i64 iRowid | ||
| 239909 | ){ | ||
| 239910 | const int f = FTS5INDEX_QUERY_SKIPHASH; | ||
| 239911 | int nTerm = (int)strlen(zTerm); | ||
| 239912 | Fts5Iter *pIter = 0; /* Used to find term instance */ | ||
| 239913 | |||
| 239914 | fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); | ||
| 239915 | if( fts5MultiIterEof(p, pIter)==0 ){ | ||
| 239916 | i64 iThis = fts5MultiIterRowid(pIter); | ||
| 239917 | if( iThis<iRowid ){ | ||
| 239918 | fts5MultiIterNextFrom(p, pIter, iRowid); | ||
| 239919 | } | ||
| 239920 | |||
| 239921 | if( p->rc==SQLITE_OK | ||
| 239922 | && fts5MultiIterEof(p, pIter)==0 | ||
| 239923 | && iRowid==fts5MultiIterRowid(pIter) | ||
| 239924 | ){ | ||
| 239925 | Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; | ||
| 239926 | fts5DoSecureDelete(p, pSeg); | ||
| 239927 | } | ||
| 239928 | } | ||
| 239929 | |||
| 239930 | fts5MultiIterFree(pIter); | ||
| 239931 | } | ||
| 239932 | |||
| 239933 | |||
| 239934 | /* | ||
| 231656 | ** Flush the contents of in-memory hash table iHash to a new level-0 | 239935 | ** Flush the contents of in-memory hash table iHash to a new level-0 |
| 231657 | ** segment on disk. Also update the corresponding structure record. | 239936 | ** segment on disk. Also update the corresponding structure record. |
| 231658 | ** | 239937 | ** |
| @@ -231668,146 +239947,197 @@ static void fts5FlushOneHash(Fts5Index *p){ | |||
| 231668 | /* Obtain a reference to the index structure and allocate a new segment-id | 239947 | /* Obtain a reference to the index structure and allocate a new segment-id |
| 231669 | ** for the new level-0 segment. */ | 239948 | ** for the new level-0 segment. */ |
| 231670 | pStruct = fts5StructureRead(p); | 239949 | pStruct = fts5StructureRead(p); |
| 231671 | iSegid = fts5AllocateSegid(p, pStruct); | ||
| 231672 | fts5StructureInvalidate(p); | 239950 | fts5StructureInvalidate(p); |
| 231673 | 239951 | ||
| 231674 | if( iSegid ){ | 239952 | if( sqlite3Fts5HashIsEmpty(pHash)==0 ){ |
| 231675 | const int pgsz = p->pConfig->pgsz; | 239953 | iSegid = fts5AllocateSegid(p, pStruct); |
| 231676 | int eDetail = p->pConfig->eDetail; | 239954 | if( iSegid ){ |
| 231677 | Fts5StructureSegment *pSeg; /* New segment within pStruct */ | 239955 | const int pgsz = p->pConfig->pgsz; |
| 231678 | Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ | 239956 | int eDetail = p->pConfig->eDetail; |
| 231679 | Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ | 239957 | int bSecureDelete = p->pConfig->bSecureDelete; |
| 231680 | 239958 | Fts5StructureSegment *pSeg; /* New segment within pStruct */ | |
| 231681 | Fts5SegWriter writer; | 239959 | Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ |
| 231682 | fts5WriteInit(p, &writer, iSegid); | 239960 | Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ |
| 231683 | 239961 | ||
| 231684 | pBuf = &writer.writer.buf; | 239962 | Fts5SegWriter writer; |
| 231685 | pPgidx = &writer.writer.pgidx; | 239963 | fts5WriteInit(p, &writer, iSegid); |
| 239964 | |||
| 239965 | pBuf = &writer.writer.buf; | ||
| 239966 | pPgidx = &writer.writer.pgidx; | ||
| 239967 | |||
| 239968 | /* fts5WriteInit() should have initialized the buffers to (most likely) | ||
| 239969 | ** the maximum space required. */ | ||
| 239970 | assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) ); | ||
| 239971 | assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) ); | ||
| 239972 | |||
| 239973 | /* Begin scanning through hash table entries. This loop runs once for each | ||
| 239974 | ** term/doclist currently stored within the hash table. */ | ||
| 239975 | if( p->rc==SQLITE_OK ){ | ||
| 239976 | p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); | ||
| 239977 | } | ||
| 239978 | while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ | ||
| 239979 | const char *zTerm; /* Buffer containing term */ | ||
| 239980 | int nTerm; /* Size of zTerm in bytes */ | ||
| 239981 | const u8 *pDoclist; /* Pointer to doclist for this term */ | ||
| 239982 | int nDoclist; /* Size of doclist in bytes */ | ||
| 239983 | |||
| 239984 | /* Get the term and doclist for this entry. */ | ||
| 239985 | sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); | ||
| 239986 | nTerm = (int)strlen(zTerm); | ||
| 239987 | if( bSecureDelete==0 ){ | ||
| 239988 | fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); | ||
| 239989 | if( p->rc!=SQLITE_OK ) break; | ||
| 239990 | assert( writer.bFirstRowidInPage==0 ); | ||
| 239991 | } | ||
| 239992 | |||
| 239993 | if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ | ||
| 239994 | /* The entire doclist will fit on the current leaf. */ | ||
| 239995 | fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); | ||
| 239996 | }else{ | ||
| 239997 | int bTermWritten = !bSecureDelete; | ||
| 239998 | i64 iRowid = 0; | ||
| 239999 | i64 iPrev = 0; | ||
| 240000 | int iOff = 0; | ||
| 240001 | |||
| 240002 | /* The entire doclist will not fit on this leaf. The following | ||
| 240003 | ** loop iterates through the poslists that make up the current | ||
| 240004 | ** doclist. */ | ||
| 240005 | while( p->rc==SQLITE_OK && iOff<nDoclist ){ | ||
| 240006 | u64 iDelta = 0; | ||
| 240007 | iOff += fts5GetVarint(&pDoclist[iOff], &iDelta); | ||
| 240008 | iRowid += iDelta; | ||
| 240009 | |||
| 240010 | /* If in secure delete mode, and if this entry in the poslist is | ||
| 240011 | ** in fact a delete, then edit the existing segments directly | ||
| 240012 | ** using fts5FlushSecureDelete(). */ | ||
| 240013 | if( bSecureDelete ){ | ||
| 240014 | if( eDetail==FTS5_DETAIL_NONE ){ | ||
| 240015 | if( iOff<nDoclist && pDoclist[iOff]==0x00 ){ | ||
| 240016 | fts5FlushSecureDelete(p, pStruct, zTerm, iRowid); | ||
| 240017 | iOff++; | ||
| 240018 | if( iOff<nDoclist && pDoclist[iOff]==0x00 ){ | ||
| 240019 | iOff++; | ||
| 240020 | nDoclist = 0; | ||
| 240021 | }else{ | ||
| 240022 | continue; | ||
| 240023 | } | ||
| 240024 | } | ||
| 240025 | }else if( (pDoclist[iOff] & 0x01) ){ | ||
| 240026 | fts5FlushSecureDelete(p, pStruct, zTerm, iRowid); | ||
| 240027 | if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ | ||
| 240028 | iOff++; | ||
| 240029 | continue; | ||
| 240030 | } | ||
| 240031 | } | ||
| 240032 | } | ||
| 231686 | 240033 | ||
| 231687 | /* fts5WriteInit() should have initialized the buffers to (most likely) | 240034 | if( p->rc==SQLITE_OK && bTermWritten==0 ){ |
| 231688 | ** the maximum space required. */ | 240035 | fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); |
| 231689 | assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) ); | 240036 | bTermWritten = 1; |
| 231690 | assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) ); | 240037 | assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 ); |
| 240038 | } | ||
| 231691 | 240039 | ||
| 231692 | /* Begin scanning through hash table entries. This loop runs once for each | 240040 | if( writer.bFirstRowidInPage ){ |
| 231693 | ** term/doclist currently stored within the hash table. */ | 240041 | fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */ |
| 231694 | if( p->rc==SQLITE_OK ){ | 240042 | pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); |
| 231695 | p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); | 240043 | writer.bFirstRowidInPage = 0; |
| 231696 | } | 240044 | fts5WriteDlidxAppend(p, &writer, iRowid); |
| 231697 | while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ | 240045 | }else{ |
| 231698 | const char *zTerm; /* Buffer containing term */ | 240046 | u64 iRowidDelta = (u64)iRowid - (u64)iPrev; |
| 231699 | const u8 *pDoclist; /* Pointer to doclist for this term */ | 240047 | pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowidDelta); |
| 231700 | int nDoclist; /* Size of doclist in bytes */ | 240048 | } |
| 231701 | |||
| 231702 | /* Write the term for this entry to disk. */ | ||
| 231703 | sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); | ||
| 231704 | fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm); | ||
| 231705 | if( p->rc!=SQLITE_OK ) break; | ||
| 231706 | |||
| 231707 | assert( writer.bFirstRowidInPage==0 ); | ||
| 231708 | if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ | ||
| 231709 | /* The entire doclist will fit on the current leaf. */ | ||
| 231710 | fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); | ||
| 231711 | }else{ | ||
| 231712 | i64 iRowid = 0; | ||
| 231713 | u64 iDelta = 0; | ||
| 231714 | int iOff = 0; | ||
| 231715 | |||
| 231716 | /* The entire doclist will not fit on this leaf. The following | ||
| 231717 | ** loop iterates through the poslists that make up the current | ||
| 231718 | ** doclist. */ | ||
| 231719 | while( p->rc==SQLITE_OK && iOff<nDoclist ){ | ||
| 231720 | iOff += fts5GetVarint(&pDoclist[iOff], &iDelta); | ||
| 231721 | iRowid += iDelta; | ||
| 231722 | |||
| 231723 | if( writer.bFirstRowidInPage ){ | ||
| 231724 | fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */ | ||
| 231725 | pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); | ||
| 231726 | writer.bFirstRowidInPage = 0; | ||
| 231727 | fts5WriteDlidxAppend(p, &writer, iRowid); | ||
| 231728 | if( p->rc!=SQLITE_OK ) break; | 240049 | if( p->rc!=SQLITE_OK ) break; |
| 231729 | }else{ | 240050 | assert( pBuf->n<=pBuf->nSpace ); |
| 231730 | pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta); | 240051 | iPrev = iRowid; |
| 231731 | } | ||
| 231732 | assert( pBuf->n<=pBuf->nSpace ); | ||
| 231733 | 240052 | ||
| 231734 | if( eDetail==FTS5_DETAIL_NONE ){ | 240053 | if( eDetail==FTS5_DETAIL_NONE ){ |
| 231735 | if( iOff<nDoclist && pDoclist[iOff]==0 ){ | ||
| 231736 | pBuf->p[pBuf->n++] = 0; | ||
| 231737 | iOff++; | ||
| 231738 | if( iOff<nDoclist && pDoclist[iOff]==0 ){ | 240054 | if( iOff<nDoclist && pDoclist[iOff]==0 ){ |
| 231739 | pBuf->p[pBuf->n++] = 0; | 240055 | pBuf->p[pBuf->n++] = 0; |
| 231740 | iOff++; | 240056 | iOff++; |
| 240057 | if( iOff<nDoclist && pDoclist[iOff]==0 ){ | ||
| 240058 | pBuf->p[pBuf->n++] = 0; | ||
| 240059 | iOff++; | ||
| 240060 | } | ||
| 240061 | } | ||
| 240062 | if( (pBuf->n + pPgidx->n)>=pgsz ){ | ||
| 240063 | fts5WriteFlushLeaf(p, &writer); | ||
| 231741 | } | 240064 | } |
| 231742 | } | ||
| 231743 | if( (pBuf->n + pPgidx->n)>=pgsz ){ | ||
| 231744 | fts5WriteFlushLeaf(p, &writer); | ||
| 231745 | } | ||
| 231746 | }else{ | ||
| 231747 | int bDummy; | ||
| 231748 | int nPos; | ||
| 231749 | int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy); | ||
| 231750 | nCopy += nPos; | ||
| 231751 | if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){ | ||
| 231752 | /* The entire poslist will fit on the current leaf. So copy | ||
| 231753 | ** it in one go. */ | ||
| 231754 | fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy); | ||
| 231755 | }else{ | 240065 | }else{ |
| 231756 | /* The entire poslist will not fit on this leaf. So it needs | 240066 | int bDummy; |
| 231757 | ** to be broken into sections. The only qualification being | 240067 | int nPos; |
| 231758 | ** that each varint must be stored contiguously. */ | 240068 | int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy); |
| 231759 | const u8 *pPoslist = &pDoclist[iOff]; | 240069 | nCopy += nPos; |
| 231760 | int iPos = 0; | 240070 | if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){ |
| 231761 | while( p->rc==SQLITE_OK ){ | 240071 | /* The entire poslist will fit on the current leaf. So copy |
| 231762 | int nSpace = pgsz - pBuf->n - pPgidx->n; | 240072 | ** it in one go. */ |
| 231763 | int n = 0; | 240073 | fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy); |
| 231764 | if( (nCopy - iPos)<=nSpace ){ | 240074 | }else{ |
| 231765 | n = nCopy - iPos; | 240075 | /* The entire poslist will not fit on this leaf. So it needs |
| 231766 | }else{ | 240076 | ** to be broken into sections. The only qualification being |
| 231767 | n = fts5PoslistPrefix(&pPoslist[iPos], nSpace); | 240077 | ** that each varint must be stored contiguously. */ |
| 231768 | } | 240078 | const u8 *pPoslist = &pDoclist[iOff]; |
| 231769 | assert( n>0 ); | 240079 | int iPos = 0; |
| 231770 | fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n); | 240080 | while( p->rc==SQLITE_OK ){ |
| 231771 | iPos += n; | 240081 | int nSpace = pgsz - pBuf->n - pPgidx->n; |
| 231772 | if( (pBuf->n + pPgidx->n)>=pgsz ){ | 240082 | int n = 0; |
| 231773 | fts5WriteFlushLeaf(p, &writer); | 240083 | if( (nCopy - iPos)<=nSpace ){ |
| 240084 | n = nCopy - iPos; | ||
| 240085 | }else{ | ||
| 240086 | n = fts5PoslistPrefix(&pPoslist[iPos], nSpace); | ||
| 240087 | } | ||
| 240088 | assert( n>0 ); | ||
| 240089 | fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n); | ||
| 240090 | iPos += n; | ||
| 240091 | if( (pBuf->n + pPgidx->n)>=pgsz ){ | ||
| 240092 | fts5WriteFlushLeaf(p, &writer); | ||
| 240093 | } | ||
| 240094 | if( iPos>=nCopy ) break; | ||
| 231774 | } | 240095 | } |
| 231775 | if( iPos>=nCopy ) break; | ||
| 231776 | } | 240096 | } |
| 240097 | iOff += nCopy; | ||
| 231777 | } | 240098 | } |
| 231778 | iOff += nCopy; | ||
| 231779 | } | 240099 | } |
| 231780 | } | 240100 | } |
| 231781 | } | ||
| 231782 | 240101 | ||
| 231783 | /* TODO2: Doclist terminator written here. */ | 240102 | /* TODO2: Doclist terminator written here. */ |
| 231784 | /* pBuf->p[pBuf->n++] = '\0'; */ | 240103 | /* pBuf->p[pBuf->n++] = '\0'; */ |
| 231785 | assert( pBuf->n<=pBuf->nSpace ); | 240104 | assert( pBuf->n<=pBuf->nSpace ); |
| 231786 | if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); | 240105 | if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); |
| 231787 | } | 240106 | } |
| 231788 | sqlite3Fts5HashClear(pHash); | 240107 | sqlite3Fts5HashClear(pHash); |
| 231789 | fts5WriteFinish(p, &writer, &pgnoLast); | 240108 | fts5WriteFinish(p, &writer, &pgnoLast); |
| 231790 | 240109 | ||
| 231791 | /* Update the Fts5Structure. It is written back to the database by the | 240110 | assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 ); |
| 231792 | ** fts5StructureRelease() call below. */ | 240111 | if( pgnoLast>0 ){ |
| 231793 | if( pStruct->nLevel==0 ){ | 240112 | /* Update the Fts5Structure. It is written back to the database by the |
| 231794 | fts5StructureAddLevel(&p->rc, &pStruct); | 240113 | ** fts5StructureRelease() call below. */ |
| 231795 | } | 240114 | if( pStruct->nLevel==0 ){ |
| 231796 | fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0); | 240115 | fts5StructureAddLevel(&p->rc, &pStruct); |
| 231797 | if( p->rc==SQLITE_OK ){ | 240116 | } |
| 231798 | pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ]; | 240117 | fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0); |
| 231799 | pSeg->iSegid = iSegid; | 240118 | if( p->rc==SQLITE_OK ){ |
| 231800 | pSeg->pgnoFirst = 1; | 240119 | pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ]; |
| 231801 | pSeg->pgnoLast = pgnoLast; | 240120 | pSeg->iSegid = iSegid; |
| 231802 | pStruct->nSegment++; | 240121 | pSeg->pgnoFirst = 1; |
| 240122 | pSeg->pgnoLast = pgnoLast; | ||
| 240123 | if( pStruct->nOriginCntr>0 ){ | ||
| 240124 | pSeg->iOrigin1 = pStruct->nOriginCntr; | ||
| 240125 | pSeg->iOrigin2 = pStruct->nOriginCntr; | ||
| 240126 | pSeg->nEntry = p->nPendingRow; | ||
| 240127 | pStruct->nOriginCntr++; | ||
| 240128 | } | ||
| 240129 | pStruct->nSegment++; | ||
| 240130 | } | ||
| 240131 | fts5StructurePromote(p, 0, pStruct); | ||
| 240132 | } | ||
| 231803 | } | 240133 | } |
| 231804 | fts5StructurePromote(p, 0, pStruct); | ||
| 231805 | } | 240134 | } |
| 231806 | 240135 | ||
| 231807 | fts5IndexAutomerge(p, &pStruct, pgnoLast); | 240136 | fts5IndexAutomerge(p, &pStruct, pgnoLast + p->nContentlessDelete); |
| 231808 | fts5IndexCrisismerge(p, &pStruct); | 240137 | fts5IndexCrisismerge(p, &pStruct); |
| 231809 | fts5StructureWrite(p, pStruct); | 240138 | fts5StructureWrite(p, pStruct); |
| 231810 | fts5StructureRelease(pStruct); | 240139 | fts5StructureRelease(pStruct); |
| 240140 | p->nContentlessDelete = 0; | ||
| 231811 | } | 240141 | } |
| 231812 | 240142 | ||
| 231813 | /* | 240143 | /* |
| @@ -231815,10 +240145,11 @@ static void fts5FlushOneHash(Fts5Index *p){ | |||
| 231815 | */ | 240145 | */ |
| 231816 | static void fts5IndexFlush(Fts5Index *p){ | 240146 | static void fts5IndexFlush(Fts5Index *p){ |
| 231817 | /* Unless it is empty, flush the hash table to disk */ | 240147 | /* Unless it is empty, flush the hash table to disk */ |
| 231818 | if( p->nPendingData ){ | 240148 | if( p->nPendingData || p->nContentlessDelete ){ |
| 231819 | assert( p->pHash ); | 240149 | assert( p->pHash ); |
| 231820 | p->nPendingData = 0; | ||
| 231821 | fts5FlushOneHash(p); | 240150 | fts5FlushOneHash(p); |
| 240151 | p->nPendingData = 0; | ||
| 240152 | p->nPendingRow = 0; | ||
| 231822 | } | 240153 | } |
| 231823 | } | 240154 | } |
| 231824 | 240155 | ||
| @@ -231834,17 +240165,22 @@ static Fts5Structure *fts5IndexOptimizeStruct( | |||
| 231834 | /* Figure out if this structure requires optimization. A structure does | 240165 | /* Figure out if this structure requires optimization. A structure does |
| 231835 | ** not require optimization if either: | 240166 | ** not require optimization if either: |
| 231836 | ** | 240167 | ** |
| 231837 | ** + it consists of fewer than two segments, or | 240168 | ** 1. it consists of fewer than two segments, or |
| 231838 | ** + all segments are on the same level, or | 240169 | ** 2. all segments are on the same level, or |
| 231839 | ** + all segments except one are currently inputs to a merge operation. | 240170 | ** 3. all segments except one are currently inputs to a merge operation. |
| 231840 | ** | 240171 | ** |
| 231841 | ** In the first case, return NULL. In the second, increment the ref-count | 240172 | ** In the first case, if there are no tombstone hash pages, return NULL. In |
| 231842 | ** on *pStruct and return a copy of the pointer to it. | 240173 | ** the second, increment the ref-count on *pStruct and return a copy of the |
| 240174 | ** pointer to it. | ||
| 231843 | */ | 240175 | */ |
| 231844 | if( nSeg<2 ) return 0; | 240176 | if( nSeg==0 ) return 0; |
| 231845 | for(i=0; i<pStruct->nLevel; i++){ | 240177 | for(i=0; i<pStruct->nLevel; i++){ |
| 231846 | int nThis = pStruct->aLevel[i].nSeg; | 240178 | int nThis = pStruct->aLevel[i].nSeg; |
| 231847 | if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){ | 240179 | int nMerge = pStruct->aLevel[i].nMerge; |
| 240180 | if( nThis>0 && (nThis==nSeg || (nThis==nSeg-1 && nMerge==nThis)) ){ | ||
| 240181 | if( nSeg==1 && nThis==1 && pStruct->aLevel[i].aSeg[0].nPgTombstone==0 ){ | ||
| 240182 | return 0; | ||
| 240183 | } | ||
| 231848 | fts5StructureRef(pStruct); | 240184 | fts5StructureRef(pStruct); |
| 231849 | return pStruct; | 240185 | return pStruct; |
| 231850 | } | 240186 | } |
| @@ -231857,10 +240193,11 @@ static Fts5Structure *fts5IndexOptimizeStruct( | |||
| 231857 | if( pNew ){ | 240193 | if( pNew ){ |
| 231858 | Fts5StructureLevel *pLvl; | 240194 | Fts5StructureLevel *pLvl; |
| 231859 | nByte = nSeg * sizeof(Fts5StructureSegment); | 240195 | nByte = nSeg * sizeof(Fts5StructureSegment); |
| 231860 | pNew->nLevel = pStruct->nLevel+1; | 240196 | pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL); |
| 231861 | pNew->nRef = 1; | 240197 | pNew->nRef = 1; |
| 231862 | pNew->nWriteCounter = pStruct->nWriteCounter; | 240198 | pNew->nWriteCounter = pStruct->nWriteCounter; |
| 231863 | pLvl = &pNew->aLevel[pStruct->nLevel]; | 240199 | pNew->nOriginCntr = pStruct->nOriginCntr; |
| 240200 | pLvl = &pNew->aLevel[pNew->nLevel-1]; | ||
| 231864 | pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte); | 240201 | pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte); |
| 231865 | if( pLvl->aSeg ){ | 240202 | if( pLvl->aSeg ){ |
| 231866 | int iLvl, iSeg; | 240203 | int iLvl, iSeg; |
| @@ -231890,6 +240227,7 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){ | |||
| 231890 | 240227 | ||
| 231891 | assert( p->rc==SQLITE_OK ); | 240228 | assert( p->rc==SQLITE_OK ); |
| 231892 | fts5IndexFlush(p); | 240229 | fts5IndexFlush(p); |
| 240230 | assert( p->nContentlessDelete==0 ); | ||
| 231893 | pStruct = fts5StructureRead(p); | 240231 | pStruct = fts5StructureRead(p); |
| 231894 | fts5StructureInvalidate(p); | 240232 | fts5StructureInvalidate(p); |
| 231895 | 240233 | ||
| @@ -231919,7 +240257,10 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){ | |||
| 231919 | ** INSERT command. | 240257 | ** INSERT command. |
| 231920 | */ | 240258 | */ |
| 231921 | static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ | 240259 | static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ |
| 231922 | Fts5Structure *pStruct = fts5StructureRead(p); | 240260 | Fts5Structure *pStruct = 0; |
| 240261 | |||
| 240262 | fts5IndexFlush(p); | ||
| 240263 | pStruct = fts5StructureRead(p); | ||
| 231923 | if( pStruct ){ | 240264 | if( pStruct ){ |
| 231924 | int nMin = p->pConfig->nUsermerge; | 240265 | int nMin = p->pConfig->nUsermerge; |
| 231925 | fts5StructureInvalidate(p); | 240266 | fts5StructureInvalidate(p); |
| @@ -231927,7 +240268,7 @@ static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ | |||
| 231927 | Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct); | 240268 | Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct); |
| 231928 | fts5StructureRelease(pStruct); | 240269 | fts5StructureRelease(pStruct); |
| 231929 | pStruct = pNew; | 240270 | pStruct = pNew; |
| 231930 | nMin = 2; | 240271 | nMin = 1; |
| 231931 | nMerge = nMerge*-1; | 240272 | nMerge = nMerge*-1; |
| 231932 | } | 240273 | } |
| 231933 | if( pStruct && pStruct->nLevel ){ | 240274 | if( pStruct && pStruct->nLevel ){ |
| @@ -231942,7 +240283,7 @@ static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ | |||
| 231942 | 240283 | ||
| 231943 | static void fts5AppendRowid( | 240284 | static void fts5AppendRowid( |
| 231944 | Fts5Index *p, | 240285 | Fts5Index *p, |
| 231945 | i64 iDelta, | 240286 | u64 iDelta, |
| 231946 | Fts5Iter *pUnused, | 240287 | Fts5Iter *pUnused, |
| 231947 | Fts5Buffer *pBuf | 240288 | Fts5Buffer *pBuf |
| 231948 | ){ | 240289 | ){ |
| @@ -231952,7 +240293,7 @@ static void fts5AppendRowid( | |||
| 231952 | 240293 | ||
| 231953 | static void fts5AppendPoslist( | 240294 | static void fts5AppendPoslist( |
| 231954 | Fts5Index *p, | 240295 | Fts5Index *p, |
| 231955 | i64 iDelta, | 240296 | u64 iDelta, |
| 231956 | Fts5Iter *pMulti, | 240297 | Fts5Iter *pMulti, |
| 231957 | Fts5Buffer *pBuf | 240298 | Fts5Buffer *pBuf |
| 231958 | ){ | 240299 | ){ |
| @@ -232027,10 +240368,10 @@ static void fts5MergeAppendDocid( | |||
| 232027 | } | 240368 | } |
| 232028 | #endif | 240369 | #endif |
| 232029 | 240370 | ||
| 232030 | #define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \ | 240371 | #define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) { \ |
| 232031 | assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \ | 240372 | assert( (pBuf)->n!=0 || (iLastRowid)==0 ); \ |
| 232032 | fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \ | 240373 | fts5BufferSafeAppendVarint((pBuf), (u64)(iRowid) - (u64)(iLastRowid)); \ |
| 232033 | (iLastRowid) = (iRowid); \ | 240374 | (iLastRowid) = (iRowid); \ |
| 232034 | } | 240375 | } |
| 232035 | 240376 | ||
| 232036 | /* | 240377 | /* |
| @@ -232162,7 +240503,7 @@ static void fts5MergePrefixLists( | |||
| 232162 | /* Initialize a doclist-iterator for each input buffer. Arrange them in | 240503 | /* Initialize a doclist-iterator for each input buffer. Arrange them in |
| 232163 | ** a linked-list starting at pHead in ascending order of rowid. Avoid | 240504 | ** a linked-list starting at pHead in ascending order of rowid. Avoid |
| 232164 | ** linking any iterators already at EOF into the linked list at all. */ | 240505 | ** linking any iterators already at EOF into the linked list at all. */ |
| 232165 | assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) ); | 240506 | assert( nBuf+1<=(int)(sizeof(aMerger)/sizeof(aMerger[0])) ); |
| 232166 | memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1)); | 240507 | memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1)); |
| 232167 | pHead = &aMerger[nBuf]; | 240508 | pHead = &aMerger[nBuf]; |
| 232168 | fts5DoclistIterInit(p1, &pHead->iter); | 240509 | fts5DoclistIterInit(p1, &pHead->iter); |
| @@ -232301,7 +240642,7 @@ static void fts5SetupPrefixIter( | |||
| 232301 | int nMerge = 1; | 240642 | int nMerge = 1; |
| 232302 | 240643 | ||
| 232303 | void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); | 240644 | void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); |
| 232304 | void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*); | 240645 | void (*xAppend)(Fts5Index*, u64, Fts5Iter*, Fts5Buffer*); |
| 232305 | if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ | 240646 | if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ |
| 232306 | xMerge = fts5MergeRowidLists; | 240647 | xMerge = fts5MergeRowidLists; |
| 232307 | xAppend = fts5AppendRowid; | 240648 | xAppend = fts5AppendRowid; |
| @@ -232340,7 +240681,7 @@ static void fts5SetupPrefixIter( | |||
| 232340 | Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; | 240681 | Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; |
| 232341 | p1->xSetOutputs(p1, pSeg); | 240682 | p1->xSetOutputs(p1, pSeg); |
| 232342 | if( p1->base.nData ){ | 240683 | if( p1->base.nData ){ |
| 232343 | xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); | 240684 | xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); |
| 232344 | iLastRowid = p1->base.iRowid; | 240685 | iLastRowid = p1->base.iRowid; |
| 232345 | } | 240686 | } |
| 232346 | } | 240687 | } |
| @@ -232388,7 +240729,7 @@ static void fts5SetupPrefixIter( | |||
| 232388 | iLastRowid = 0; | 240729 | iLastRowid = 0; |
| 232389 | } | 240730 | } |
| 232390 | 240731 | ||
| 232391 | xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); | 240732 | xAppend(p, (u64)p1->base.iRowid-(u64)iLastRowid, p1, &doclist); |
| 232392 | iLastRowid = p1->base.iRowid; | 240733 | iLastRowid = p1->base.iRowid; |
| 232393 | } | 240734 | } |
| 232394 | 240735 | ||
| @@ -232441,6 +240782,9 @@ static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ | |||
| 232441 | 240782 | ||
| 232442 | p->iWriteRowid = iRowid; | 240783 | p->iWriteRowid = iRowid; |
| 232443 | p->bDelete = bDelete; | 240784 | p->bDelete = bDelete; |
| 240785 | if( bDelete==0 ){ | ||
| 240786 | p->nPendingRow++; | ||
| 240787 | } | ||
| 232444 | return fts5IndexReturn(p); | 240788 | return fts5IndexReturn(p); |
| 232445 | } | 240789 | } |
| 232446 | 240790 | ||
| @@ -232478,6 +240822,9 @@ static int sqlite3Fts5IndexReinit(Fts5Index *p){ | |||
| 232478 | fts5StructureInvalidate(p); | 240822 | fts5StructureInvalidate(p); |
| 232479 | fts5IndexDiscardData(p); | 240823 | fts5IndexDiscardData(p); |
| 232480 | memset(&s, 0, sizeof(Fts5Structure)); | 240824 | memset(&s, 0, sizeof(Fts5Structure)); |
| 240825 | if( p->pConfig->bContentlessDelete ){ | ||
| 240826 | s.nOriginCntr = 1; | ||
| 240827 | } | ||
| 232481 | fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); | 240828 | fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); |
| 232482 | fts5StructureWrite(p, &s); | 240829 | fts5StructureWrite(p, &s); |
| 232483 | return fts5IndexReturn(p); | 240830 | return fts5IndexReturn(p); |
| @@ -232542,6 +240889,7 @@ static int sqlite3Fts5IndexClose(Fts5Index *p){ | |||
| 232542 | sqlite3_finalize(p->pIdxDeleter); | 240889 | sqlite3_finalize(p->pIdxDeleter); |
| 232543 | sqlite3_finalize(p->pIdxSelect); | 240890 | sqlite3_finalize(p->pIdxSelect); |
| 232544 | sqlite3_finalize(p->pDataVersion); | 240891 | sqlite3_finalize(p->pDataVersion); |
| 240892 | sqlite3_finalize(p->pDeleteFromIdx); | ||
| 232545 | sqlite3Fts5HashFree(p->pHash); | 240893 | sqlite3Fts5HashFree(p->pHash); |
| 232546 | sqlite3_free(p->zDataTbl); | 240894 | sqlite3_free(p->zDataTbl); |
| 232547 | sqlite3_free(p); | 240895 | sqlite3_free(p); |
| @@ -232868,6 +241216,347 @@ static int sqlite3Fts5IndexLoadConfig(Fts5Index *p){ | |||
| 232868 | return fts5IndexReturn(p); | 241216 | return fts5IndexReturn(p); |
| 232869 | } | 241217 | } |
| 232870 | 241218 | ||
| 241219 | /* | ||
| 241220 | ** Retrieve the origin value that will be used for the segment currently | ||
| 241221 | ** being accumulated in the in-memory hash table when it is flushed to | ||
| 241222 | ** disk. If successful, SQLITE_OK is returned and (*piOrigin) set to | ||
| 241223 | ** the queried value. Or, if an error occurs, an error code is returned | ||
| 241224 | ** and the final value of (*piOrigin) is undefined. | ||
| 241225 | */ | ||
| 241226 | static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin){ | ||
| 241227 | Fts5Structure *pStruct; | ||
| 241228 | pStruct = fts5StructureRead(p); | ||
| 241229 | if( pStruct ){ | ||
| 241230 | *piOrigin = pStruct->nOriginCntr; | ||
| 241231 | fts5StructureRelease(pStruct); | ||
| 241232 | } | ||
| 241233 | return fts5IndexReturn(p); | ||
| 241234 | } | ||
| 241235 | |||
| 241236 | /* | ||
| 241237 | ** Buffer pPg contains a page of a tombstone hash table - one of nPg pages | ||
| 241238 | ** associated with the same segment. This function adds rowid iRowid to | ||
| 241239 | ** the hash table. The caller is required to guarantee that there is at | ||
| 241240 | ** least one free slot on the page. | ||
| 241241 | ** | ||
| 241242 | ** If parameter bForce is false and the hash table is deemed to be full | ||
| 241243 | ** (more than half of the slots are occupied), then non-zero is returned | ||
| 241244 | ** and iRowid not inserted. Or, if bForce is true or if the hash table page | ||
| 241245 | ** is not full, iRowid is inserted and zero returned. | ||
| 241246 | */ | ||
| 241247 | static int fts5IndexTombstoneAddToPage( | ||
| 241248 | Fts5Data *pPg, | ||
| 241249 | int bForce, | ||
| 241250 | int nPg, | ||
| 241251 | u64 iRowid | ||
| 241252 | ){ | ||
| 241253 | const int szKey = TOMBSTONE_KEYSIZE(pPg); | ||
| 241254 | const int nSlot = TOMBSTONE_NSLOT(pPg); | ||
| 241255 | const int nElem = fts5GetU32(&pPg->p[4]); | ||
| 241256 | int iSlot = (iRowid / nPg) % nSlot; | ||
| 241257 | int nCollide = nSlot; | ||
| 241258 | |||
| 241259 | if( szKey==4 && iRowid>0xFFFFFFFF ) return 2; | ||
| 241260 | if( iRowid==0 ){ | ||
| 241261 | pPg->p[1] = 0x01; | ||
| 241262 | return 0; | ||
| 241263 | } | ||
| 241264 | |||
| 241265 | if( bForce==0 && nElem>=(nSlot/2) ){ | ||
| 241266 | return 1; | ||
| 241267 | } | ||
| 241268 | |||
| 241269 | fts5PutU32(&pPg->p[4], nElem+1); | ||
| 241270 | if( szKey==4 ){ | ||
| 241271 | u32 *aSlot = (u32*)&pPg->p[8]; | ||
| 241272 | while( aSlot[iSlot] ){ | ||
| 241273 | iSlot = (iSlot + 1) % nSlot; | ||
| 241274 | if( nCollide--==0 ) return 0; | ||
| 241275 | } | ||
| 241276 | fts5PutU32((u8*)&aSlot[iSlot], (u32)iRowid); | ||
| 241277 | }else{ | ||
| 241278 | u64 *aSlot = (u64*)&pPg->p[8]; | ||
| 241279 | while( aSlot[iSlot] ){ | ||
| 241280 | iSlot = (iSlot + 1) % nSlot; | ||
| 241281 | if( nCollide--==0 ) return 0; | ||
| 241282 | } | ||
| 241283 | fts5PutU64((u8*)&aSlot[iSlot], iRowid); | ||
| 241284 | } | ||
| 241285 | |||
| 241286 | return 0; | ||
| 241287 | } | ||
| 241288 | |||
| 241289 | /* | ||
| 241290 | ** This function attempts to build a new hash containing all the keys | ||
| 241291 | ** currently in the tombstone hash table for segment pSeg. The new | ||
| 241292 | ** hash will be stored in the nOut buffers passed in array apOut[]. | ||
| 241293 | ** All pages of the new hash use key-size szKey (4 or 8). | ||
| 241294 | ** | ||
| 241295 | ** Return 0 if the hash is successfully rebuilt into the nOut pages. | ||
| 241296 | ** Or non-zero if it is not (because one page became overfull). In this | ||
| 241297 | ** case the caller should retry with a larger nOut parameter. | ||
| 241298 | ** | ||
| 241299 | ** Parameter pData1 is page iPg1 of the hash table being rebuilt. | ||
| 241300 | */ | ||
| 241301 | static int fts5IndexTombstoneRehash( | ||
| 241302 | Fts5Index *p, | ||
| 241303 | Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */ | ||
| 241304 | Fts5Data *pData1, /* One page of current hash - or NULL */ | ||
| 241305 | int iPg1, /* Which page of the current hash is pData1 */ | ||
| 241306 | int szKey, /* 4 or 8, the keysize */ | ||
| 241307 | int nOut, /* Number of output pages */ | ||
| 241308 | Fts5Data **apOut /* Array of output hash pages */ | ||
| 241309 | ){ | ||
| 241310 | int ii; | ||
| 241311 | int res = 0; | ||
| 241312 | |||
| 241313 | /* Initialize the headers of all the output pages */ | ||
| 241314 | for(ii=0; ii<nOut; ii++){ | ||
| 241315 | apOut[ii]->p[0] = szKey; | ||
| 241316 | fts5PutU32(&apOut[ii]->p[4], 0); | ||
| 241317 | } | ||
| 241318 | |||
| 241319 | /* Loop through the current pages of the hash table. */ | ||
| 241320 | for(ii=0; res==0 && ii<pSeg->nPgTombstone; ii++){ | ||
| 241321 | Fts5Data *pData = 0; /* Page ii of the current hash table */ | ||
| 241322 | Fts5Data *pFree = 0; /* Free this at the end of the loop */ | ||
| 241323 | |||
| 241324 | if( iPg1==ii ){ | ||
| 241325 | pData = pData1; | ||
| 241326 | }else{ | ||
| 241327 | pFree = pData = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid, ii)); | ||
| 241328 | } | ||
| 241329 | |||
| 241330 | if( pData ){ | ||
| 241331 | int szKeyIn = TOMBSTONE_KEYSIZE(pData); | ||
| 241332 | int nSlotIn = (pData->nn - 8) / szKeyIn; | ||
| 241333 | int iIn; | ||
| 241334 | for(iIn=0; iIn<nSlotIn; iIn++){ | ||
| 241335 | u64 iVal = 0; | ||
| 241336 | |||
| 241337 | /* Read the value from slot iIn of the input page into iVal. */ | ||
| 241338 | if( szKeyIn==4 ){ | ||
| 241339 | u32 *aSlot = (u32*)&pData->p[8]; | ||
| 241340 | if( aSlot[iIn] ) iVal = fts5GetU32((u8*)&aSlot[iIn]); | ||
| 241341 | }else{ | ||
| 241342 | u64 *aSlot = (u64*)&pData->p[8]; | ||
| 241343 | if( aSlot[iIn] ) iVal = fts5GetU64((u8*)&aSlot[iIn]); | ||
| 241344 | } | ||
| 241345 | |||
| 241346 | /* If iVal is not 0 at this point, insert it into the new hash table */ | ||
| 241347 | if( iVal ){ | ||
| 241348 | Fts5Data *pPg = apOut[(iVal % nOut)]; | ||
| 241349 | res = fts5IndexTombstoneAddToPage(pPg, 0, nOut, iVal); | ||
| 241350 | if( res ) break; | ||
| 241351 | } | ||
| 241352 | } | ||
| 241353 | |||
| 241354 | /* If this is page 0 of the old hash, copy the rowid-0-flag from the | ||
| 241355 | ** old hash to the new. */ | ||
| 241356 | if( ii==0 ){ | ||
| 241357 | apOut[0]->p[1] = pData->p[1]; | ||
| 241358 | } | ||
| 241359 | } | ||
| 241360 | fts5DataRelease(pFree); | ||
| 241361 | } | ||
| 241362 | |||
| 241363 | return res; | ||
| 241364 | } | ||
| 241365 | |||
| 241366 | /* | ||
| 241367 | ** This is called to rebuild the hash table belonging to segment pSeg. | ||
| 241368 | ** If parameter pData1 is not NULL, then one page of the existing hash table | ||
| 241369 | ** has already been loaded - pData1, which is page iPg1. The key-size for | ||
| 241370 | ** the new hash table is szKey (4 or 8). | ||
| 241371 | ** | ||
| 241372 | ** If successful, the new hash table is not written to disk. Instead, | ||
| 241373 | ** output parameter (*pnOut) is set to the number of pages in the new | ||
| 241374 | ** hash table, and (*papOut) to point to an array of buffers containing | ||
| 241375 | ** the new page data. | ||
| 241376 | ** | ||
| 241377 | ** If an error occurs, an error code is left in the Fts5Index object and | ||
| 241378 | ** both output parameters set to 0 before returning. | ||
| 241379 | */ | ||
| 241380 | static void fts5IndexTombstoneRebuild( | ||
| 241381 | Fts5Index *p, | ||
| 241382 | Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */ | ||
| 241383 | Fts5Data *pData1, /* One page of current hash - or NULL */ | ||
| 241384 | int iPg1, /* Which page of the current hash is pData1 */ | ||
| 241385 | int szKey, /* 4 or 8, the keysize */ | ||
| 241386 | int *pnOut, /* OUT: Number of output pages */ | ||
| 241387 | Fts5Data ***papOut /* OUT: Output hash pages */ | ||
| 241388 | ){ | ||
| 241389 | const int MINSLOT = 32; | ||
| 241390 | int nSlotPerPage = MAX(MINSLOT, (p->pConfig->pgsz - 8) / szKey); | ||
| 241391 | int nSlot = 0; /* Number of slots in each output page */ | ||
| 241392 | int nOut = 0; | ||
| 241393 | |||
| 241394 | /* Figure out how many output pages (nOut) and how many slots per | ||
| 241395 | ** page (nSlot). There are three possibilities: | ||
| 241396 | ** | ||
| 241397 | ** 1. The hash table does not yet exist. In this case the new hash | ||
| 241398 | ** table will consist of a single page with MINSLOT slots. | ||
| 241399 | ** | ||
| 241400 | ** 2. The hash table exists but is currently a single page. In this | ||
| 241401 | ** case an attempt is made to grow the page to accommodate the new | ||
| 241402 | ** entry. The page is allowed to grow up to nSlotPerPage (see above) | ||
| 241403 | ** slots. | ||
| 241404 | ** | ||
| 241405 | ** 3. The hash table already consists of more than one page, or of | ||
| 241406 | ** a single page already so large that it cannot be grown. In this | ||
| 241407 | ** case the new hash consists of (nPg*2+1) pages of nSlotPerPage | ||
| 241408 | ** slots each, where nPg is the current number of pages in the | ||
| 241409 | ** hash table. | ||
| 241410 | */ | ||
| 241411 | if( pSeg->nPgTombstone==0 ){ | ||
| 241412 | /* Case 1. */ | ||
| 241413 | nOut = 1; | ||
| 241414 | nSlot = MINSLOT; | ||
| 241415 | }else if( pSeg->nPgTombstone==1 ){ | ||
| 241416 | /* Case 2. */ | ||
| 241417 | int nElem = (int)fts5GetU32(&pData1->p[4]); | ||
| 241418 | assert( pData1 && iPg1==0 ); | ||
| 241419 | nOut = 1; | ||
| 241420 | nSlot = MAX(nElem*4, MINSLOT); | ||
| 241421 | if( nSlot>nSlotPerPage ) nOut = 0; | ||
| 241422 | } | ||
| 241423 | if( nOut==0 ){ | ||
| 241424 | /* Case 3. */ | ||
| 241425 | nOut = (pSeg->nPgTombstone * 2 + 1); | ||
| 241426 | nSlot = nSlotPerPage; | ||
| 241427 | } | ||
| 241428 | |||
| 241429 | /* Allocate the required array and output pages */ | ||
| 241430 | while( 1 ){ | ||
| 241431 | int res = 0; | ||
| 241432 | int ii = 0; | ||
| 241433 | int szPage = 0; | ||
| 241434 | Fts5Data **apOut = 0; | ||
| 241435 | |||
| 241436 | /* Allocate space for the new hash table */ | ||
| 241437 | assert( nSlot>=MINSLOT ); | ||
| 241438 | apOut = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data*) * nOut); | ||
| 241439 | szPage = 8 + nSlot*szKey; | ||
| 241440 | for(ii=0; ii<nOut; ii++){ | ||
| 241441 | Fts5Data *pNew = (Fts5Data*)sqlite3Fts5MallocZero(&p->rc, | ||
| 241442 | sizeof(Fts5Data)+szPage | ||
| 241443 | ); | ||
| 241444 | if( pNew ){ | ||
| 241445 | pNew->nn = szPage; | ||
| 241446 | pNew->p = (u8*)&pNew[1]; | ||
| 241447 | apOut[ii] = pNew; | ||
| 241448 | } | ||
| 241449 | } | ||
| 241450 | |||
| 241451 | /* Rebuild the hash table. */ | ||
| 241452 | if( p->rc==SQLITE_OK ){ | ||
| 241453 | res = fts5IndexTombstoneRehash(p, pSeg, pData1, iPg1, szKey, nOut, apOut); | ||
| 241454 | } | ||
| 241455 | if( res==0 ){ | ||
| 241456 | if( p->rc ){ | ||
| 241457 | fts5IndexFreeArray(apOut, nOut); | ||
| 241458 | apOut = 0; | ||
| 241459 | nOut = 0; | ||
| 241460 | } | ||
| 241461 | *pnOut = nOut; | ||
| 241462 | *papOut = apOut; | ||
| 241463 | break; | ||
| 241464 | } | ||
| 241465 | |||
| 241466 | /* If control flows to here, it was not possible to rebuild the hash | ||
| 241467 | ** table. Free all buffers and then try again with more pages. */ | ||
| 241468 | assert( p->rc==SQLITE_OK ); | ||
| 241469 | fts5IndexFreeArray(apOut, nOut); | ||
| 241470 | nSlot = nSlotPerPage; | ||
| 241471 | nOut = nOut*2 + 1; | ||
| 241472 | } | ||
| 241473 | } | ||
| 241474 | |||
| 241475 | |||
| 241476 | /* | ||
| 241477 | ** Add a tombstone for rowid iRowid to segment pSeg. | ||
| 241478 | */ | ||
| 241479 | static void fts5IndexTombstoneAdd( | ||
| 241480 | Fts5Index *p, | ||
| 241481 | Fts5StructureSegment *pSeg, | ||
| 241482 | u64 iRowid | ||
| 241483 | ){ | ||
| 241484 | Fts5Data *pPg = 0; | ||
| 241485 | int iPg = -1; | ||
| 241486 | int szKey = 0; | ||
| 241487 | int nHash = 0; | ||
| 241488 | Fts5Data **apHash = 0; | ||
| 241489 | |||
| 241490 | p->nContentlessDelete++; | ||
| 241491 | |||
| 241492 | if( pSeg->nPgTombstone>0 ){ | ||
| 241493 | iPg = iRowid % pSeg->nPgTombstone; | ||
| 241494 | pPg = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg)); | ||
| 241495 | if( pPg==0 ){ | ||
| 241496 | assert( p->rc!=SQLITE_OK ); | ||
| 241497 | return; | ||
| 241498 | } | ||
| 241499 | |||
| 241500 | if( 0==fts5IndexTombstoneAddToPage(pPg, 0, pSeg->nPgTombstone, iRowid) ){ | ||
| 241501 | fts5DataWrite(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg), pPg->p, pPg->nn); | ||
| 241502 | fts5DataRelease(pPg); | ||
| 241503 | return; | ||
| 241504 | } | ||
| 241505 | } | ||
| 241506 | |||
| 241507 | /* Have to rebuild the hash table. First figure out the key-size (4 or 8). */ | ||
| 241508 | szKey = pPg ? TOMBSTONE_KEYSIZE(pPg) : 4; | ||
| 241509 | if( iRowid>0xFFFFFFFF ) szKey = 8; | ||
| 241510 | |||
| 241511 | /* Rebuild the hash table */ | ||
| 241512 | fts5IndexTombstoneRebuild(p, pSeg, pPg, iPg, szKey, &nHash, &apHash); | ||
| 241513 | assert( p->rc==SQLITE_OK || (nHash==0 && apHash==0) ); | ||
| 241514 | |||
| 241515 | /* If all has succeeded, write the new rowid into one of the new hash | ||
| 241516 | ** table pages, then write them all out to disk. */ | ||
| 241517 | if( nHash ){ | ||
| 241518 | int ii = 0; | ||
| 241519 | fts5IndexTombstoneAddToPage(apHash[iRowid % nHash], 1, nHash, iRowid); | ||
| 241520 | for(ii=0; ii<nHash; ii++){ | ||
| 241521 | i64 iTombstoneRowid = FTS5_TOMBSTONE_ROWID(pSeg->iSegid, ii); | ||
| 241522 | fts5DataWrite(p, iTombstoneRowid, apHash[ii]->p, apHash[ii]->nn); | ||
| 241523 | } | ||
| 241524 | pSeg->nPgTombstone = nHash; | ||
| 241525 | fts5StructureWrite(p, p->pStruct); | ||
| 241526 | } | ||
| 241527 | |||
| 241528 | fts5DataRelease(pPg); | ||
| 241529 | fts5IndexFreeArray(apHash, nHash); | ||
| 241530 | } | ||
| 241531 | |||
| 241532 | /* | ||
| 241533 | ** Add iRowid to the tombstone list of the segment or segments that contain | ||
| 241534 | ** rows from origin iOrigin. Return SQLITE_OK if successful, or an SQLite | ||
| 241535 | ** error code otherwise. | ||
| 241536 | */ | ||
| 241537 | static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid){ | ||
| 241538 | Fts5Structure *pStruct; | ||
| 241539 | pStruct = fts5StructureRead(p); | ||
| 241540 | if( pStruct ){ | ||
| 241541 | int bFound = 0; /* True after pSeg->nEntryTombstone incr. */ | ||
| 241542 | int iLvl; | ||
| 241543 | for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){ | ||
| 241544 | int iSeg; | ||
| 241545 | for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){ | ||
| 241546 | Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; | ||
| 241547 | if( pSeg->iOrigin1<=(u64)iOrigin && pSeg->iOrigin2>=(u64)iOrigin ){ | ||
| 241548 | if( bFound==0 ){ | ||
| 241549 | pSeg->nEntryTombstone++; | ||
| 241550 | bFound = 1; | ||
| 241551 | } | ||
| 241552 | fts5IndexTombstoneAdd(p, pSeg, iRowid); | ||
| 241553 | } | ||
| 241554 | } | ||
| 241555 | } | ||
| 241556 | fts5StructureRelease(pStruct); | ||
| 241557 | } | ||
| 241558 | return fts5IndexReturn(p); | ||
| 241559 | } | ||
| 232871 | 241560 | ||
| 232872 | /************************************************************************* | 241561 | /************************************************************************* |
| 232873 | ************************************************************************** | 241562 | ************************************************************************** |
| @@ -233172,6 +241861,7 @@ static void fts5IndexIntegrityCheckSegment( | |||
| 233172 | Fts5StructureSegment *pSeg /* Segment to check internal consistency */ | 241861 | Fts5StructureSegment *pSeg /* Segment to check internal consistency */ |
| 233173 | ){ | 241862 | ){ |
| 233174 | Fts5Config *pConfig = p->pConfig; | 241863 | Fts5Config *pConfig = p->pConfig; |
| 241864 | int bSecureDelete = (pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE); | ||
| 233175 | sqlite3_stmt *pStmt = 0; | 241865 | sqlite3_stmt *pStmt = 0; |
| 233176 | int rc2; | 241866 | int rc2; |
| 233177 | int iIdxPrevLeaf = pSeg->pgnoFirst-1; | 241867 | int iIdxPrevLeaf = pSeg->pgnoFirst-1; |
| @@ -233207,7 +241897,19 @@ static void fts5IndexIntegrityCheckSegment( | |||
| 233207 | ** is also a rowid pointer within the leaf page header, it points to a | 241897 | ** is also a rowid pointer within the leaf page header, it points to a |
| 233208 | ** location before the term. */ | 241898 | ** location before the term. */ |
| 233209 | if( pLeaf->nn<=pLeaf->szLeaf ){ | 241899 | if( pLeaf->nn<=pLeaf->szLeaf ){ |
| 233210 | p->rc = FTS5_CORRUPT; | 241900 | |
| 241901 | if( nIdxTerm==0 | ||
| 241902 | && pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE | ||
| 241903 | && pLeaf->nn==pLeaf->szLeaf | ||
| 241904 | && pLeaf->nn==4 | ||
| 241905 | ){ | ||
| 241906 | /* special case - the very first page in a segment keeps its %_idx | ||
| 241907 | ** entry even if all the terms are removed from it by secure-delete | ||
| 241908 | ** operations. */ | ||
| 241909 | }else{ | ||
| 241910 | p->rc = FTS5_CORRUPT; | ||
| 241911 | } | ||
| 241912 | |||
| 233211 | }else{ | 241913 | }else{ |
| 233212 | int iOff; /* Offset of first term on leaf */ | 241914 | int iOff; /* Offset of first term on leaf */ |
| 233213 | int iRowidOff; /* Offset of first rowid on leaf */ | 241915 | int iRowidOff; /* Offset of first rowid on leaf */ |
| @@ -233271,9 +241973,12 @@ static void fts5IndexIntegrityCheckSegment( | |||
| 233271 | ASSERT_SZLEAF_OK(pLeaf); | 241973 | ASSERT_SZLEAF_OK(pLeaf); |
| 233272 | if( iRowidOff>=pLeaf->szLeaf ){ | 241974 | if( iRowidOff>=pLeaf->szLeaf ){ |
| 233273 | p->rc = FTS5_CORRUPT; | 241975 | p->rc = FTS5_CORRUPT; |
| 233274 | }else{ | 241976 | }else if( bSecureDelete==0 || iRowidOff>0 ){ |
| 241977 | i64 iDlRowid = fts5DlidxIterRowid(pDlidx); | ||
| 233275 | fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid); | 241978 | fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid); |
| 233276 | if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT; | 241979 | if( iRowid<iDlRowid || (bSecureDelete==0 && iRowid!=iDlRowid) ){ |
| 241980 | p->rc = FTS5_CORRUPT; | ||
| 241981 | } | ||
| 233277 | } | 241982 | } |
| 233278 | fts5DataRelease(pLeaf); | 241983 | fts5DataRelease(pLeaf); |
| 233279 | } | 241984 | } |
| @@ -233367,6 +242072,7 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum | |||
| 233367 | 242072 | ||
| 233368 | /* If this is a new term, query for it. Update cksum3 with the results. */ | 242073 | /* If this is a new term, query for it. Update cksum3 with the results. */ |
| 233369 | fts5TestTerm(p, &term, z, n, cksum2, &cksum3); | 242074 | fts5TestTerm(p, &term, z, n, cksum2, &cksum3); |
| 242075 | if( p->rc ) break; | ||
| 233370 | 242076 | ||
| 233371 | if( eDetail==FTS5_DETAIL_NONE ){ | 242077 | if( eDetail==FTS5_DETAIL_NONE ){ |
| 233372 | if( 0==fts5MultiIterIsEmpty(p, pIter) ){ | 242078 | if( 0==fts5MultiIterIsEmpty(p, pIter) ){ |
| @@ -233402,13 +242108,14 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum | |||
| 233402 | ** function only. | 242108 | ** function only. |
| 233403 | */ | 242109 | */ |
| 233404 | 242110 | ||
| 233405 | #ifdef SQLITE_TEST | 242111 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233406 | /* | 242112 | /* |
| 233407 | ** Decode a segment-data rowid from the %_data table. This function is | 242113 | ** Decode a segment-data rowid from the %_data table. This function is |
| 233408 | ** the opposite of macro FTS5_SEGMENT_ROWID(). | 242114 | ** the opposite of macro FTS5_SEGMENT_ROWID(). |
| 233409 | */ | 242115 | */ |
| 233410 | static void fts5DecodeRowid( | 242116 | static void fts5DecodeRowid( |
| 233411 | i64 iRowid, /* Rowid from %_data table */ | 242117 | i64 iRowid, /* Rowid from %_data table */ |
| 242118 | int *pbTombstone, /* OUT: Tombstone hash flag */ | ||
| 233412 | int *piSegid, /* OUT: Segment id */ | 242119 | int *piSegid, /* OUT: Segment id */ |
| 233413 | int *pbDlidx, /* OUT: Dlidx flag */ | 242120 | int *pbDlidx, /* OUT: Dlidx flag */ |
| 233414 | int *piHeight, /* OUT: Height */ | 242121 | int *piHeight, /* OUT: Height */ |
| @@ -233424,13 +242131,16 @@ static void fts5DecodeRowid( | |||
| 233424 | iRowid >>= FTS5_DATA_DLI_B; | 242131 | iRowid >>= FTS5_DATA_DLI_B; |
| 233425 | 242132 | ||
| 233426 | *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1)); | 242133 | *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1)); |
| 242134 | iRowid >>= FTS5_DATA_ID_B; | ||
| 242135 | |||
| 242136 | *pbTombstone = (int)(iRowid & 0x0001); | ||
| 233427 | } | 242137 | } |
| 233428 | #endif /* SQLITE_TEST */ | 242138 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233429 | 242139 | ||
| 233430 | #ifdef SQLITE_TEST | 242140 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233431 | static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ | 242141 | static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ |
| 233432 | int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */ | 242142 | int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */ |
| 233433 | fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno); | 242143 | fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); |
| 233434 | 242144 | ||
| 233435 | if( iSegid==0 ){ | 242145 | if( iSegid==0 ){ |
| 233436 | if( iKey==FTS5_AVERAGES_ROWID ){ | 242146 | if( iKey==FTS5_AVERAGES_ROWID ){ |
| @@ -233440,14 +242150,16 @@ static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ | |||
| 233440 | } | 242150 | } |
| 233441 | } | 242151 | } |
| 233442 | else{ | 242152 | else{ |
| 233443 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}", | 242153 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%s%ssegid=%d h=%d pgno=%d}", |
| 233444 | bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno | 242154 | bDlidx ? "dlidx " : "", |
| 242155 | bTomb ? "tombstone " : "", | ||
| 242156 | iSegid, iHeight, iPgno | ||
| 233445 | ); | 242157 | ); |
| 233446 | } | 242158 | } |
| 233447 | } | 242159 | } |
| 233448 | #endif /* SQLITE_TEST */ | 242160 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233449 | 242161 | ||
| 233450 | #ifdef SQLITE_TEST | 242162 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233451 | static void fts5DebugStructure( | 242163 | static void fts5DebugStructure( |
| 233452 | int *pRc, /* IN/OUT: error code */ | 242164 | int *pRc, /* IN/OUT: error code */ |
| 233453 | Fts5Buffer *pBuf, | 242165 | Fts5Buffer *pBuf, |
| @@ -233462,16 +242174,22 @@ static void fts5DebugStructure( | |||
| 233462 | ); | 242174 | ); |
| 233463 | for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){ | 242175 | for(iSeg=0; iSeg<pLvl->nSeg; iSeg++){ |
| 233464 | Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; | 242176 | Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; |
| 233465 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}", | 242177 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d", |
| 233466 | pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast | 242178 | pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast |
| 233467 | ); | 242179 | ); |
| 242180 | if( pSeg->iOrigin1>0 ){ | ||
| 242181 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " origin=%lld..%lld", | ||
| 242182 | pSeg->iOrigin1, pSeg->iOrigin2 | ||
| 242183 | ); | ||
| 242184 | } | ||
| 242185 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); | ||
| 233468 | } | 242186 | } |
| 233469 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); | 242187 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); |
| 233470 | } | 242188 | } |
| 233471 | } | 242189 | } |
| 233472 | #endif /* SQLITE_TEST */ | 242190 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233473 | 242191 | ||
| 233474 | #ifdef SQLITE_TEST | 242192 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233475 | /* | 242193 | /* |
| 233476 | ** This is part of the fts5_decode() debugging aid. | 242194 | ** This is part of the fts5_decode() debugging aid. |
| 233477 | ** | 242195 | ** |
| @@ -233496,9 +242214,9 @@ static void fts5DecodeStructure( | |||
| 233496 | fts5DebugStructure(pRc, pBuf, p); | 242214 | fts5DebugStructure(pRc, pBuf, p); |
| 233497 | fts5StructureRelease(p); | 242215 | fts5StructureRelease(p); |
| 233498 | } | 242216 | } |
| 233499 | #endif /* SQLITE_TEST */ | 242217 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233500 | 242218 | ||
| 233501 | #ifdef SQLITE_TEST | 242219 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233502 | /* | 242220 | /* |
| 233503 | ** This is part of the fts5_decode() debugging aid. | 242221 | ** This is part of the fts5_decode() debugging aid. |
| 233504 | ** | 242222 | ** |
| @@ -233521,9 +242239,9 @@ static void fts5DecodeAverages( | |||
| 233521 | zSpace = " "; | 242239 | zSpace = " "; |
| 233522 | } | 242240 | } |
| 233523 | } | 242241 | } |
| 233524 | #endif /* SQLITE_TEST */ | 242242 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233525 | 242243 | ||
| 233526 | #ifdef SQLITE_TEST | 242244 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233527 | /* | 242245 | /* |
| 233528 | ** Buffer (a/n) is assumed to contain a list of serialized varints. Read | 242246 | ** Buffer (a/n) is assumed to contain a list of serialized varints. Read |
| 233529 | ** each varint and append its string representation to buffer pBuf. Return | 242247 | ** each varint and append its string representation to buffer pBuf. Return |
| @@ -233540,9 +242258,9 @@ static int fts5DecodePoslist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ | |||
| 233540 | } | 242258 | } |
| 233541 | return iOff; | 242259 | return iOff; |
| 233542 | } | 242260 | } |
| 233543 | #endif /* SQLITE_TEST */ | 242261 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233544 | 242262 | ||
| 233545 | #ifdef SQLITE_TEST | 242263 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233546 | /* | 242264 | /* |
| 233547 | ** The start of buffer (a/n) contains the start of a doclist. The doclist | 242265 | ** The start of buffer (a/n) contains the start of a doclist. The doclist |
| 233548 | ** may or may not finish within the buffer. This function appends a text | 242266 | ** may or may not finish within the buffer. This function appends a text |
| @@ -233575,9 +242293,9 @@ static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ | |||
| 233575 | 242293 | ||
| 233576 | return iOff; | 242294 | return iOff; |
| 233577 | } | 242295 | } |
| 233578 | #endif /* SQLITE_TEST */ | 242296 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233579 | 242297 | ||
| 233580 | #ifdef SQLITE_TEST | 242298 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233581 | /* | 242299 | /* |
| 233582 | ** This function is part of the fts5_decode() debugging function. It is | 242300 | ** This function is part of the fts5_decode() debugging function. It is |
| 233583 | ** only ever used with detail=none tables. | 242301 | ** only ever used with detail=none tables. |
| @@ -233618,9 +242336,9 @@ static void fts5DecodeRowidList( | |||
| 233618 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp); | 242336 | sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp); |
| 233619 | } | 242337 | } |
| 233620 | } | 242338 | } |
| 233621 | #endif /* SQLITE_TEST */ | 242339 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233622 | 242340 | ||
| 233623 | #ifdef SQLITE_TEST | 242341 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233624 | /* | 242342 | /* |
| 233625 | ** The implementation of user-defined scalar function fts5_decode(). | 242343 | ** The implementation of user-defined scalar function fts5_decode(). |
| 233626 | */ | 242344 | */ |
| @@ -233631,6 +242349,7 @@ static void fts5DecodeFunction( | |||
| 233631 | ){ | 242349 | ){ |
| 233632 | i64 iRowid; /* Rowid for record being decoded */ | 242350 | i64 iRowid; /* Rowid for record being decoded */ |
| 233633 | int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */ | 242351 | int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */ |
| 242352 | int bTomb; | ||
| 233634 | const u8 *aBlob; int n; /* Record to decode */ | 242353 | const u8 *aBlob; int n; /* Record to decode */ |
| 233635 | u8 *a = 0; | 242354 | u8 *a = 0; |
| 233636 | Fts5Buffer s; /* Build up text to return here */ | 242355 | Fts5Buffer s; /* Build up text to return here */ |
| @@ -233653,7 +242372,7 @@ static void fts5DecodeFunction( | |||
| 233653 | if( a==0 ) goto decode_out; | 242372 | if( a==0 ) goto decode_out; |
| 233654 | if( n>0 ) memcpy(a, aBlob, n); | 242373 | if( n>0 ) memcpy(a, aBlob, n); |
| 233655 | 242374 | ||
| 233656 | fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno); | 242375 | fts5DecodeRowid(iRowid, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); |
| 233657 | 242376 | ||
| 233658 | fts5DebugRowid(&rc, &s, iRowid); | 242377 | fts5DebugRowid(&rc, &s, iRowid); |
| 233659 | if( bDlidx ){ | 242378 | if( bDlidx ){ |
| @@ -233672,6 +242391,28 @@ static void fts5DecodeFunction( | |||
| 233672 | " %d(%lld)", lvl.iLeafPgno, lvl.iRowid | 242391 | " %d(%lld)", lvl.iLeafPgno, lvl.iRowid |
| 233673 | ); | 242392 | ); |
| 233674 | } | 242393 | } |
| 242394 | }else if( bTomb ){ | ||
| 242395 | u32 nElem = fts5GetU32(&a[4]); | ||
| 242396 | int szKey = (aBlob[0]==4 || aBlob[0]==8) ? aBlob[0] : 8; | ||
| 242397 | int nSlot = (n - 8) / szKey; | ||
| 242398 | int ii; | ||
| 242399 | sqlite3Fts5BufferAppendPrintf(&rc, &s, " nElem=%d", (int)nElem); | ||
| 242400 | if( aBlob[1] ){ | ||
| 242401 | sqlite3Fts5BufferAppendPrintf(&rc, &s, " 0"); | ||
| 242402 | } | ||
| 242403 | for(ii=0; ii<nSlot; ii++){ | ||
| 242404 | u64 iVal = 0; | ||
| 242405 | if( szKey==4 ){ | ||
| 242406 | u32 *aSlot = (u32*)&aBlob[8]; | ||
| 242407 | if( aSlot[ii] ) iVal = fts5GetU32((u8*)&aSlot[ii]); | ||
| 242408 | }else{ | ||
| 242409 | u64 *aSlot = (u64*)&aBlob[8]; | ||
| 242410 | if( aSlot[ii] ) iVal = fts5GetU64((u8*)&aSlot[ii]); | ||
| 242411 | } | ||
| 242412 | if( iVal!=0 ){ | ||
| 242413 | sqlite3Fts5BufferAppendPrintf(&rc, &s, " %lld", (i64)iVal); | ||
| 242414 | } | ||
| 242415 | } | ||
| 233675 | }else if( iSegid==0 ){ | 242416 | }else if( iSegid==0 ){ |
| 233676 | if( iRowid==FTS5_AVERAGES_ROWID ){ | 242417 | if( iRowid==FTS5_AVERAGES_ROWID ){ |
| 233677 | fts5DecodeAverages(&rc, &s, a, n); | 242418 | fts5DecodeAverages(&rc, &s, a, n); |
| @@ -233697,7 +242438,7 @@ static void fts5DecodeFunction( | |||
| 233697 | fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4); | 242438 | fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4); |
| 233698 | 242439 | ||
| 233699 | iOff = iTermOff; | 242440 | iOff = iTermOff; |
| 233700 | while( iOff<szLeaf ){ | 242441 | while( iOff<szLeaf && rc==SQLITE_OK ){ |
| 233701 | int nAppend; | 242442 | int nAppend; |
| 233702 | 242443 | ||
| 233703 | /* Read the term data for the next term*/ | 242444 | /* Read the term data for the next term*/ |
| @@ -233717,8 +242458,11 @@ static void fts5DecodeFunction( | |||
| 233717 | }else{ | 242458 | }else{ |
| 233718 | iTermOff = szLeaf; | 242459 | iTermOff = szLeaf; |
| 233719 | } | 242460 | } |
| 233720 | 242461 | if( iTermOff>szLeaf ){ | |
| 233721 | fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff); | 242462 | rc = FTS5_CORRUPT; |
| 242463 | }else{ | ||
| 242464 | fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff); | ||
| 242465 | } | ||
| 233722 | iOff = iTermOff; | 242466 | iOff = iTermOff; |
| 233723 | if( iOff<szLeaf ){ | 242467 | if( iOff<szLeaf ){ |
| 233724 | iOff += fts5GetVarint32(&a[iOff], nKeep); | 242468 | iOff += fts5GetVarint32(&a[iOff], nKeep); |
| @@ -233829,9 +242573,9 @@ static void fts5DecodeFunction( | |||
| 233829 | } | 242573 | } |
| 233830 | fts5BufferFree(&s); | 242574 | fts5BufferFree(&s); |
| 233831 | } | 242575 | } |
| 233832 | #endif /* SQLITE_TEST */ | 242576 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 233833 | 242577 | ||
| 233834 | #ifdef SQLITE_TEST | 242578 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233835 | /* | 242579 | /* |
| 233836 | ** The implementation of user-defined scalar function fts5_rowid(). | 242580 | ** The implementation of user-defined scalar function fts5_rowid(). |
| 233837 | */ | 242581 | */ |
| @@ -233865,7 +242609,235 @@ static void fts5RowidFunction( | |||
| 233865 | } | 242609 | } |
| 233866 | } | 242610 | } |
| 233867 | } | 242611 | } |
| 233868 | #endif /* SQLITE_TEST */ | 242612 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ |
| 242613 | |||
| 242614 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) | ||
| 242615 | |||
| 242616 | typedef struct Fts5StructVtab Fts5StructVtab; | ||
| 242617 | struct Fts5StructVtab { | ||
| 242618 | sqlite3_vtab base; | ||
| 242619 | }; | ||
| 242620 | |||
| 242621 | typedef struct Fts5StructVcsr Fts5StructVcsr; | ||
| 242622 | struct Fts5StructVcsr { | ||
| 242623 | sqlite3_vtab_cursor base; | ||
| 242624 | Fts5Structure *pStruct; | ||
| 242625 | int iLevel; | ||
| 242626 | int iSeg; | ||
| 242627 | int iRowid; | ||
| 242628 | }; | ||
| 242629 | |||
| 242630 | /* | ||
| 242631 | ** Create a new fts5_structure() table-valued function. | ||
| 242632 | */ | ||
| 242633 | static int fts5structConnectMethod( | ||
| 242634 | sqlite3 *db, | ||
| 242635 | void *pAux, | ||
| 242636 | int argc, const char *const*argv, | ||
| 242637 | sqlite3_vtab **ppVtab, | ||
| 242638 | char **pzErr | ||
| 242639 | ){ | ||
| 242640 | Fts5StructVtab *pNew = 0; | ||
| 242641 | int rc = SQLITE_OK; | ||
| 242642 | |||
| 242643 | rc = sqlite3_declare_vtab(db, | ||
| 242644 | "CREATE TABLE xyz(" | ||
| 242645 | "level, segment, merge, segid, leaf1, leaf2, loc1, loc2, " | ||
| 242646 | "npgtombstone, nentrytombstone, nentry, struct HIDDEN);" | ||
| 242647 | ); | ||
| 242648 | if( rc==SQLITE_OK ){ | ||
| 242649 | pNew = sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); | ||
| 242650 | } | ||
| 242651 | |||
| 242652 | *ppVtab = (sqlite3_vtab*)pNew; | ||
| 242653 | return rc; | ||
| 242654 | } | ||
| 242655 | |||
| 242656 | /* | ||
| 242657 | ** We must have a single struct=? constraint that will be passed through | ||
| 242658 | ** into the xFilter method. If there is no valid stmt=? constraint, | ||
| 242659 | ** then return an SQLITE_CONSTRAINT error. | ||
| 242660 | */ | ||
| 242661 | static int fts5structBestIndexMethod( | ||
| 242662 | sqlite3_vtab *tab, | ||
| 242663 | sqlite3_index_info *pIdxInfo | ||
| 242664 | ){ | ||
| 242665 | int i; | ||
| 242666 | int rc = SQLITE_CONSTRAINT; | ||
| 242667 | struct sqlite3_index_constraint *p; | ||
| 242668 | pIdxInfo->estimatedCost = (double)100; | ||
| 242669 | pIdxInfo->estimatedRows = 100; | ||
| 242670 | pIdxInfo->idxNum = 0; | ||
| 242671 | for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){ | ||
| 242672 | if( p->usable==0 ) continue; | ||
| 242673 | if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==11 ){ | ||
| 242674 | rc = SQLITE_OK; | ||
| 242675 | pIdxInfo->aConstraintUsage[i].omit = 1; | ||
| 242676 | pIdxInfo->aConstraintUsage[i].argvIndex = 1; | ||
| 242677 | break; | ||
| 242678 | } | ||
| 242679 | } | ||
| 242680 | return rc; | ||
| 242681 | } | ||
| 242682 | |||
| 242683 | /* | ||
| 242684 | ** This method is the destructor for bytecodevtab objects. | ||
| 242685 | */ | ||
| 242686 | static int fts5structDisconnectMethod(sqlite3_vtab *pVtab){ | ||
| 242687 | Fts5StructVtab *p = (Fts5StructVtab*)pVtab; | ||
| 242688 | sqlite3_free(p); | ||
| 242689 | return SQLITE_OK; | ||
| 242690 | } | ||
| 242691 | |||
| 242692 | /* | ||
| 242693 | ** Constructor for a new bytecodevtab_cursor object. | ||
| 242694 | */ | ||
| 242695 | static int fts5structOpenMethod(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){ | ||
| 242696 | int rc = SQLITE_OK; | ||
| 242697 | Fts5StructVcsr *pNew = 0; | ||
| 242698 | |||
| 242699 | pNew = sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); | ||
| 242700 | *ppCsr = (sqlite3_vtab_cursor*)pNew; | ||
| 242701 | |||
| 242702 | return SQLITE_OK; | ||
| 242703 | } | ||
| 242704 | |||
| 242705 | /* | ||
| 242706 | ** Destructor for a bytecodevtab_cursor. | ||
| 242707 | */ | ||
| 242708 | static int fts5structCloseMethod(sqlite3_vtab_cursor *cur){ | ||
| 242709 | Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; | ||
| 242710 | fts5StructureRelease(pCsr->pStruct); | ||
| 242711 | sqlite3_free(pCsr); | ||
| 242712 | return SQLITE_OK; | ||
| 242713 | } | ||
| 242714 | |||
| 242715 | |||
| 242716 | /* | ||
| 242717 | ** Advance a bytecodevtab_cursor to its next row of output. | ||
| 242718 | */ | ||
| 242719 | static int fts5structNextMethod(sqlite3_vtab_cursor *cur){ | ||
| 242720 | Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; | ||
| 242721 | Fts5Structure *p = pCsr->pStruct; | ||
| 242722 | |||
| 242723 | assert( pCsr->pStruct ); | ||
| 242724 | pCsr->iSeg++; | ||
| 242725 | pCsr->iRowid++; | ||
| 242726 | while( pCsr->iLevel<p->nLevel && pCsr->iSeg>=p->aLevel[pCsr->iLevel].nSeg ){ | ||
| 242727 | pCsr->iLevel++; | ||
| 242728 | pCsr->iSeg = 0; | ||
| 242729 | } | ||
| 242730 | if( pCsr->iLevel>=p->nLevel ){ | ||
| 242731 | fts5StructureRelease(pCsr->pStruct); | ||
| 242732 | pCsr->pStruct = 0; | ||
| 242733 | } | ||
| 242734 | return SQLITE_OK; | ||
| 242735 | } | ||
| 242736 | |||
| 242737 | /* | ||
| 242738 | ** Return TRUE if the cursor has been moved off of the last | ||
| 242739 | ** row of output. | ||
| 242740 | */ | ||
| 242741 | static int fts5structEofMethod(sqlite3_vtab_cursor *cur){ | ||
| 242742 | Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; | ||
| 242743 | return pCsr->pStruct==0; | ||
| 242744 | } | ||
| 242745 | |||
| 242746 | static int fts5structRowidMethod( | ||
| 242747 | sqlite3_vtab_cursor *cur, | ||
| 242748 | sqlite_int64 *piRowid | ||
| 242749 | ){ | ||
| 242750 | Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; | ||
| 242751 | *piRowid = pCsr->iRowid; | ||
| 242752 | return SQLITE_OK; | ||
| 242753 | } | ||
| 242754 | |||
| 242755 | /* | ||
| 242756 | ** Return values of columns for the row at which the bytecodevtab_cursor | ||
| 242757 | ** is currently pointing. | ||
| 242758 | */ | ||
| 242759 | static int fts5structColumnMethod( | ||
| 242760 | sqlite3_vtab_cursor *cur, /* The cursor */ | ||
| 242761 | sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ | ||
| 242762 | int i /* Which column to return */ | ||
| 242763 | ){ | ||
| 242764 | Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; | ||
| 242765 | Fts5Structure *p = pCsr->pStruct; | ||
| 242766 | Fts5StructureSegment *pSeg = &p->aLevel[pCsr->iLevel].aSeg[pCsr->iSeg]; | ||
| 242767 | |||
| 242768 | switch( i ){ | ||
| 242769 | case 0: /* level */ | ||
| 242770 | sqlite3_result_int(ctx, pCsr->iLevel); | ||
| 242771 | break; | ||
| 242772 | case 1: /* segment */ | ||
| 242773 | sqlite3_result_int(ctx, pCsr->iSeg); | ||
| 242774 | break; | ||
| 242775 | case 2: /* merge */ | ||
| 242776 | sqlite3_result_int(ctx, pCsr->iSeg < p->aLevel[pCsr->iLevel].nMerge); | ||
| 242777 | break; | ||
| 242778 | case 3: /* segid */ | ||
| 242779 | sqlite3_result_int(ctx, pSeg->iSegid); | ||
| 242780 | break; | ||
| 242781 | case 4: /* leaf1 */ | ||
| 242782 | sqlite3_result_int(ctx, pSeg->pgnoFirst); | ||
| 242783 | break; | ||
| 242784 | case 5: /* leaf2 */ | ||
| 242785 | sqlite3_result_int(ctx, pSeg->pgnoLast); | ||
| 242786 | break; | ||
| 242787 | case 6: /* origin1 */ | ||
| 242788 | sqlite3_result_int64(ctx, pSeg->iOrigin1); | ||
| 242789 | break; | ||
| 242790 | case 7: /* origin2 */ | ||
| 242791 | sqlite3_result_int64(ctx, pSeg->iOrigin2); | ||
| 242792 | break; | ||
| 242793 | case 8: /* npgtombstone */ | ||
| 242794 | sqlite3_result_int(ctx, pSeg->nPgTombstone); | ||
| 242795 | break; | ||
| 242796 | case 9: /* nentrytombstone */ | ||
| 242797 | sqlite3_result_int64(ctx, pSeg->nEntryTombstone); | ||
| 242798 | break; | ||
| 242799 | case 10: /* nentry */ | ||
| 242800 | sqlite3_result_int64(ctx, pSeg->nEntry); | ||
| 242801 | break; | ||
| 242802 | } | ||
| 242803 | return SQLITE_OK; | ||
| 242804 | } | ||
| 242805 | |||
| 242806 | /* | ||
| 242807 | ** Initialize a cursor. | ||
| 242808 | ** | ||
| 242809 | ** idxNum==0 means show all subprograms | ||
| 242810 | ** idxNum==1 means show only the main bytecode and omit subprograms. | ||
| 242811 | */ | ||
| 242812 | static int fts5structFilterMethod( | ||
| 242813 | sqlite3_vtab_cursor *pVtabCursor, | ||
| 242814 | int idxNum, const char *idxStr, | ||
| 242815 | int argc, sqlite3_value **argv | ||
| 242816 | ){ | ||
| 242817 | Fts5StructVcsr *pCsr = (Fts5StructVcsr *)pVtabCursor; | ||
| 242818 | int rc = SQLITE_OK; | ||
| 242819 | |||
| 242820 | const u8 *aBlob = 0; | ||
| 242821 | int nBlob = 0; | ||
| 242822 | |||
| 242823 | assert( argc==1 ); | ||
| 242824 | fts5StructureRelease(pCsr->pStruct); | ||
| 242825 | pCsr->pStruct = 0; | ||
| 242826 | |||
| 242827 | nBlob = sqlite3_value_bytes(argv[0]); | ||
| 242828 | aBlob = (const u8*)sqlite3_value_blob(argv[0]); | ||
| 242829 | rc = fts5StructureDecode(aBlob, nBlob, 0, &pCsr->pStruct); | ||
| 242830 | if( rc==SQLITE_OK ){ | ||
| 242831 | pCsr->iLevel = 0; | ||
| 242832 | pCsr->iRowid = 0; | ||
| 242833 | pCsr->iSeg = -1; | ||
| 242834 | rc = fts5structNextMethod(pVtabCursor); | ||
| 242835 | } | ||
| 242836 | |||
| 242837 | return rc; | ||
| 242838 | } | ||
| 242839 | |||
| 242840 | #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ | ||
| 233869 | 242841 | ||
| 233870 | /* | 242842 | /* |
| 233871 | ** This is called as part of registering the FTS5 module with database | 242843 | ** This is called as part of registering the FTS5 module with database |
| @@ -233876,7 +242848,7 @@ static void fts5RowidFunction( | |||
| 233876 | ** SQLite error code is returned instead. | 242848 | ** SQLite error code is returned instead. |
| 233877 | */ | 242849 | */ |
| 233878 | static int sqlite3Fts5IndexInit(sqlite3 *db){ | 242850 | static int sqlite3Fts5IndexInit(sqlite3 *db){ |
| 233879 | #ifdef SQLITE_TEST | 242851 | #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) |
| 233880 | int rc = sqlite3_create_function( | 242852 | int rc = sqlite3_create_function( |
| 233881 | db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0 | 242853 | db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0 |
| 233882 | ); | 242854 | ); |
| @@ -233893,6 +242865,36 @@ static int sqlite3Fts5IndexInit(sqlite3 *db){ | |||
| 233893 | db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0 | 242865 | db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0 |
| 233894 | ); | 242866 | ); |
| 233895 | } | 242867 | } |
| 242868 | |||
| 242869 | if( rc==SQLITE_OK ){ | ||
| 242870 | static const sqlite3_module fts5structure_module = { | ||
| 242871 | 0, /* iVersion */ | ||
| 242872 | 0, /* xCreate */ | ||
| 242873 | fts5structConnectMethod, /* xConnect */ | ||
| 242874 | fts5structBestIndexMethod, /* xBestIndex */ | ||
| 242875 | fts5structDisconnectMethod, /* xDisconnect */ | ||
| 242876 | 0, /* xDestroy */ | ||
| 242877 | fts5structOpenMethod, /* xOpen */ | ||
| 242878 | fts5structCloseMethod, /* xClose */ | ||
| 242879 | fts5structFilterMethod, /* xFilter */ | ||
| 242880 | fts5structNextMethod, /* xNext */ | ||
| 242881 | fts5structEofMethod, /* xEof */ | ||
| 242882 | fts5structColumnMethod, /* xColumn */ | ||
| 242883 | fts5structRowidMethod, /* xRowid */ | ||
| 242884 | 0, /* xUpdate */ | ||
| 242885 | 0, /* xBegin */ | ||
| 242886 | 0, /* xSync */ | ||
| 242887 | 0, /* xCommit */ | ||
| 242888 | 0, /* xRollback */ | ||
| 242889 | 0, /* xFindFunction */ | ||
| 242890 | 0, /* xRename */ | ||
| 242891 | 0, /* xSavepoint */ | ||
| 242892 | 0, /* xRelease */ | ||
| 242893 | 0, /* xRollbackTo */ | ||
| 242894 | 0 /* xShadowName */ | ||
| 242895 | }; | ||
| 242896 | rc = sqlite3_create_module(db, "fts5_structure", &fts5structure_module, 0); | ||
| 242897 | } | ||
| 233896 | return rc; | 242898 | return rc; |
| 233897 | #else | 242899 | #else |
| 233898 | return SQLITE_OK; | 242900 | return SQLITE_OK; |
| @@ -234171,7 +243173,7 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ | |||
| 234171 | break; | 243173 | break; |
| 234172 | 243174 | ||
| 234173 | case FTS5_SYNC: | 243175 | case FTS5_SYNC: |
| 234174 | assert( p->ts.eState==1 ); | 243176 | assert( p->ts.eState==1 || p->ts.eState==2 ); |
| 234175 | p->ts.eState = 2; | 243177 | p->ts.eState = 2; |
| 234176 | break; | 243178 | break; |
| 234177 | 243179 | ||
| @@ -234186,21 +243188,21 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ | |||
| 234186 | break; | 243188 | break; |
| 234187 | 243189 | ||
| 234188 | case FTS5_SAVEPOINT: | 243190 | case FTS5_SAVEPOINT: |
| 234189 | assert( p->ts.eState==1 ); | 243191 | assert( p->ts.eState>=1 ); |
| 234190 | assert( iSavepoint>=0 ); | 243192 | assert( iSavepoint>=0 ); |
| 234191 | assert( iSavepoint>=p->ts.iSavepoint ); | 243193 | assert( iSavepoint>=p->ts.iSavepoint ); |
| 234192 | p->ts.iSavepoint = iSavepoint; | 243194 | p->ts.iSavepoint = iSavepoint; |
| 234193 | break; | 243195 | break; |
| 234194 | 243196 | ||
| 234195 | case FTS5_RELEASE: | 243197 | case FTS5_RELEASE: |
| 234196 | assert( p->ts.eState==1 ); | 243198 | assert( p->ts.eState>=1 ); |
| 234197 | assert( iSavepoint>=0 ); | 243199 | assert( iSavepoint>=0 ); |
| 234198 | assert( iSavepoint<=p->ts.iSavepoint ); | 243200 | assert( iSavepoint<=p->ts.iSavepoint ); |
| 234199 | p->ts.iSavepoint = iSavepoint-1; | 243201 | p->ts.iSavepoint = iSavepoint-1; |
| 234200 | break; | 243202 | break; |
| 234201 | 243203 | ||
| 234202 | case FTS5_ROLLBACKTO: | 243204 | case FTS5_ROLLBACKTO: |
| 234203 | assert( p->ts.eState==1 ); | 243205 | assert( p->ts.eState>=1 ); |
| 234204 | assert( iSavepoint>=-1 ); | 243206 | assert( iSavepoint>=-1 ); |
| 234205 | /* The following assert() can fail if another vtab strikes an error | 243207 | /* The following assert() can fail if another vtab strikes an error |
| 234206 | ** within an xSavepoint() call then SQLite calls xRollbackTo() - without | 243208 | ** within an xSavepoint() call then SQLite calls xRollbackTo() - without |
| @@ -235534,9 +244536,10 @@ static int fts5UpdateMethod( | |||
| 235534 | Fts5Config *pConfig = pTab->p.pConfig; | 244536 | Fts5Config *pConfig = pTab->p.pConfig; |
| 235535 | int eType0; /* value_type() of apVal[0] */ | 244537 | int eType0; /* value_type() of apVal[0] */ |
| 235536 | int rc = SQLITE_OK; /* Return code */ | 244538 | int rc = SQLITE_OK; /* Return code */ |
| 244539 | int bUpdateOrDelete = 0; | ||
| 235537 | 244540 | ||
| 235538 | /* A transaction must be open when this is called. */ | 244541 | /* A transaction must be open when this is called. */ |
| 235539 | assert( pTab->ts.eState==1 ); | 244542 | assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); |
| 235540 | 244543 | ||
| 235541 | assert( pVtab->zErrMsg==0 ); | 244544 | assert( pVtab->zErrMsg==0 ); |
| 235542 | assert( nArg==1 || nArg==(2+pConfig->nCol+2) ); | 244545 | assert( nArg==1 || nArg==(2+pConfig->nCol+2) ); |
| @@ -235544,6 +244547,11 @@ static int fts5UpdateMethod( | |||
| 235544 | || sqlite3_value_type(apVal[0])==SQLITE_NULL | 244547 | || sqlite3_value_type(apVal[0])==SQLITE_NULL |
| 235545 | ); | 244548 | ); |
| 235546 | assert( pTab->p.pConfig->pzErrmsg==0 ); | 244549 | assert( pTab->p.pConfig->pzErrmsg==0 ); |
| 244550 | if( pConfig->pgsz==0 ){ | ||
| 244551 | rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); | ||
| 244552 | if( rc!=SQLITE_OK ) return rc; | ||
| 244553 | } | ||
| 244554 | |||
| 235547 | pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; | 244555 | pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; |
| 235548 | 244556 | ||
| 235549 | /* Put any active cursors into REQUIRE_SEEK state. */ | 244557 | /* Put any active cursors into REQUIRE_SEEK state. */ |
| @@ -235558,7 +244566,14 @@ static int fts5UpdateMethod( | |||
| 235558 | if( pConfig->eContent!=FTS5_CONTENT_NORMAL | 244566 | if( pConfig->eContent!=FTS5_CONTENT_NORMAL |
| 235559 | && 0==sqlite3_stricmp("delete", z) | 244567 | && 0==sqlite3_stricmp("delete", z) |
| 235560 | ){ | 244568 | ){ |
| 235561 | rc = fts5SpecialDelete(pTab, apVal); | 244569 | if( pConfig->bContentlessDelete ){ |
| 244570 | fts5SetVtabError(pTab, | ||
| 244571 | "'delete' may not be used with a contentless_delete=1 table" | ||
| 244572 | ); | ||
| 244573 | rc = SQLITE_ERROR; | ||
| 244574 | }else{ | ||
| 244575 | rc = fts5SpecialDelete(pTab, apVal); | ||
| 244576 | } | ||
| 235562 | }else{ | 244577 | }else{ |
| 235563 | rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); | 244578 | rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); |
| 235564 | } | 244579 | } |
| @@ -235575,7 +244590,7 @@ static int fts5UpdateMethod( | |||
| 235575 | ** Cases 3 and 4 may violate the rowid constraint. | 244590 | ** Cases 3 and 4 may violate the rowid constraint. |
| 235576 | */ | 244591 | */ |
| 235577 | int eConflict = SQLITE_ABORT; | 244592 | int eConflict = SQLITE_ABORT; |
| 235578 | if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ | 244593 | if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->bContentlessDelete ){ |
| 235579 | eConflict = sqlite3_vtab_on_conflict(pConfig->db); | 244594 | eConflict = sqlite3_vtab_on_conflict(pConfig->db); |
| 235580 | } | 244595 | } |
| 235581 | 244596 | ||
| @@ -235583,8 +244598,12 @@ static int fts5UpdateMethod( | |||
| 235583 | assert( nArg!=1 || eType0==SQLITE_INTEGER ); | 244598 | assert( nArg!=1 || eType0==SQLITE_INTEGER ); |
| 235584 | 244599 | ||
| 235585 | /* Filter out attempts to run UPDATE or DELETE on contentless tables. | 244600 | /* Filter out attempts to run UPDATE or DELETE on contentless tables. |
| 235586 | ** This is not suported. */ | 244601 | ** This is not suported. Except - DELETE is supported if the CREATE |
| 235587 | if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){ | 244602 | ** VIRTUAL TABLE statement contained "contentless_delete=1". */ |
| 244603 | if( eType0==SQLITE_INTEGER | ||
| 244604 | && pConfig->eContent==FTS5_CONTENT_NONE | ||
| 244605 | && pConfig->bContentlessDelete==0 | ||
| 244606 | ){ | ||
| 235588 | pTab->p.base.zErrMsg = sqlite3_mprintf( | 244607 | pTab->p.base.zErrMsg = sqlite3_mprintf( |
| 235589 | "cannot %s contentless fts5 table: %s", | 244608 | "cannot %s contentless fts5 table: %s", |
| 235590 | (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName | 244609 | (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName |
| @@ -235596,6 +244615,7 @@ static int fts5UpdateMethod( | |||
| 235596 | else if( nArg==1 ){ | 244615 | else if( nArg==1 ){ |
| 235597 | i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ | 244616 | i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ |
| 235598 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); | 244617 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); |
| 244618 | bUpdateOrDelete = 1; | ||
| 235599 | } | 244619 | } |
| 235600 | 244620 | ||
| 235601 | /* INSERT or UPDATE */ | 244621 | /* INSERT or UPDATE */ |
| @@ -235611,6 +244631,7 @@ static int fts5UpdateMethod( | |||
| 235611 | if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ | 244631 | if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ |
| 235612 | i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ | 244632 | i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ |
| 235613 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); | 244633 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); |
| 244634 | bUpdateOrDelete = 1; | ||
| 235614 | } | 244635 | } |
| 235615 | fts5StorageInsert(&rc, pTab, apVal, pRowid); | 244636 | fts5StorageInsert(&rc, pTab, apVal, pRowid); |
| 235616 | } | 244637 | } |
| @@ -235639,10 +244660,24 @@ static int fts5UpdateMethod( | |||
| 235639 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); | 244660 | rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); |
| 235640 | fts5StorageInsert(&rc, pTab, apVal, pRowid); | 244661 | fts5StorageInsert(&rc, pTab, apVal, pRowid); |
| 235641 | } | 244662 | } |
| 244663 | bUpdateOrDelete = 1; | ||
| 235642 | } | 244664 | } |
| 235643 | } | 244665 | } |
| 235644 | } | 244666 | } |
| 235645 | 244667 | ||
| 244668 | if( rc==SQLITE_OK | ||
| 244669 | && bUpdateOrDelete | ||
| 244670 | && pConfig->bSecureDelete | ||
| 244671 | && pConfig->iVersion==FTS5_CURRENT_VERSION | ||
| 244672 | ){ | ||
| 244673 | rc = sqlite3Fts5StorageConfigValue( | ||
| 244674 | pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE | ||
| 244675 | ); | ||
| 244676 | if( rc==SQLITE_OK ){ | ||
| 244677 | pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; | ||
| 244678 | } | ||
| 244679 | } | ||
| 244680 | |||
| 235646 | pTab->p.pConfig->pzErrmsg = 0; | 244681 | pTab->p.pConfig->pzErrmsg = 0; |
| 235647 | return rc; | 244682 | return rc; |
| 235648 | } | 244683 | } |
| @@ -235655,8 +244690,7 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ | |||
| 235655 | Fts5FullTable *pTab = (Fts5FullTable*)pVtab; | 244690 | Fts5FullTable *pTab = (Fts5FullTable*)pVtab; |
| 235656 | fts5CheckTransactionState(pTab, FTS5_SYNC, 0); | 244691 | fts5CheckTransactionState(pTab, FTS5_SYNC, 0); |
| 235657 | pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; | 244692 | pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; |
| 235658 | fts5TripCursors(pTab); | 244693 | rc = sqlite3Fts5FlushToDisk(&pTab->p); |
| 235659 | rc = sqlite3Fts5StorageSync(pTab->pStorage); | ||
| 235660 | pTab->p.pConfig->pzErrmsg = 0; | 244694 | pTab->p.pConfig->pzErrmsg = 0; |
| 235661 | return rc; | 244695 | return rc; |
| 235662 | } | 244696 | } |
| @@ -236423,6 +245457,12 @@ static int fts5ColumnMethod( | |||
| 236423 | sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); | 245457 | sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); |
| 236424 | } | 245458 | } |
| 236425 | pConfig->pzErrmsg = 0; | 245459 | pConfig->pzErrmsg = 0; |
| 245460 | }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){ | ||
| 245461 | char *zErr = sqlite3_mprintf("cannot UPDATE a subset of " | ||
| 245462 | "columns on fts5 contentless-delete table: %s", pConfig->zName | ||
| 245463 | ); | ||
| 245464 | sqlite3_result_error(pCtx, zErr, -1); | ||
| 245465 | sqlite3_free(zErr); | ||
| 236426 | } | 245466 | } |
| 236427 | return rc; | 245467 | return rc; |
| 236428 | } | 245468 | } |
| @@ -236502,6 +245542,7 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ | |||
| 236502 | UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ | 245542 | UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ |
| 236503 | fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); | 245543 | fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); |
| 236504 | fts5TripCursors(pTab); | 245544 | fts5TripCursors(pTab); |
| 245545 | pTab->p.pConfig->pgsz = 0; | ||
| 236505 | return sqlite3Fts5StorageRollback(pTab->pStorage); | 245546 | return sqlite3Fts5StorageRollback(pTab->pStorage); |
| 236506 | } | 245547 | } |
| 236507 | 245548 | ||
| @@ -236704,7 +245745,7 @@ static void fts5SourceIdFunc( | |||
| 236704 | ){ | 245745 | ){ |
| 236705 | assert( nArg==0 ); | 245746 | assert( nArg==0 ); |
| 236706 | UNUSED_PARAM2(nArg, apUnused); | 245747 | UNUSED_PARAM2(nArg, apUnused); |
| 236707 | sqlite3_result_text(pCtx, "fts5: 2022-09-05 11:02:23 4635f4a69c8c2a8df242b384a992aea71224e39a2ccab42d8c0b0602f1e826e8", -1, SQLITE_TRANSIENT); | 245748 | sqlite3_result_text(pCtx, "fts5: 2023-08-24 12:36:59 0f80b798b3f4b81a7bb4233c58294edd0f1156f36b6ecf5ab8e83631d468778c", -1, SQLITE_TRANSIENT); |
| 236708 | } | 245749 | } |
| 236709 | 245750 | ||
| 236710 | /* | 245751 | /* |
| @@ -236777,7 +245818,9 @@ static int fts5Init(sqlite3 *db){ | |||
| 236777 | } | 245818 | } |
| 236778 | if( rc==SQLITE_OK ){ | 245819 | if( rc==SQLITE_OK ){ |
| 236779 | rc = sqlite3_create_function( | 245820 | rc = sqlite3_create_function( |
| 236780 | db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0 | 245821 | db, "fts5_source_id", 0, |
| 245822 | SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS, | ||
| 245823 | p, fts5SourceIdFunc, 0, 0 | ||
| 236781 | ); | 245824 | ); |
| 236782 | } | 245825 | } |
| 236783 | } | 245826 | } |
| @@ -236915,10 +245958,10 @@ static int fts5StorageGetStmt( | |||
| 236915 | "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ | 245958 | "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ |
| 236916 | "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ | 245959 | "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ |
| 236917 | "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */ | 245960 | "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */ |
| 236918 | "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* REPLACE_DOCSIZE */ | 245961 | "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */ |
| 236919 | "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */ | 245962 | "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */ |
| 236920 | 245963 | ||
| 236921 | "SELECT sz FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ | 245964 | "SELECT sz%s FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ |
| 236922 | 245965 | ||
| 236923 | "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */ | 245966 | "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */ |
| 236924 | "SELECT %s FROM %s AS T", /* SCAN */ | 245967 | "SELECT %s FROM %s AS T", /* SCAN */ |
| @@ -236966,6 +246009,19 @@ static int fts5StorageGetStmt( | |||
| 236966 | break; | 246009 | break; |
| 236967 | } | 246010 | } |
| 236968 | 246011 | ||
| 246012 | case FTS5_STMT_REPLACE_DOCSIZE: | ||
| 246013 | zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, | ||
| 246014 | (pC->bContentlessDelete ? ",?" : "") | ||
| 246015 | ); | ||
| 246016 | break; | ||
| 246017 | |||
| 246018 | case FTS5_STMT_LOOKUP_DOCSIZE: | ||
| 246019 | zSql = sqlite3_mprintf(azStmt[eStmt], | ||
| 246020 | (pC->bContentlessDelete ? ",origin" : ""), | ||
| 246021 | pC->zDb, pC->zName | ||
| 246022 | ); | ||
| 246023 | break; | ||
| 246024 | |||
| 236969 | default: | 246025 | default: |
| 236970 | zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName); | 246026 | zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName); |
| 236971 | break; | 246027 | break; |
| @@ -237155,9 +246211,11 @@ static int sqlite3Fts5StorageOpen( | |||
| 237155 | } | 246211 | } |
| 237156 | 246212 | ||
| 237157 | if( rc==SQLITE_OK && pConfig->bColumnsize ){ | 246213 | if( rc==SQLITE_OK && pConfig->bColumnsize ){ |
| 237158 | rc = sqlite3Fts5CreateTable( | 246214 | const char *zCols = "id INTEGER PRIMARY KEY, sz BLOB"; |
| 237159 | pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr | 246215 | if( pConfig->bContentlessDelete ){ |
| 237160 | ); | 246216 | zCols = "id INTEGER PRIMARY KEY, sz BLOB, origin INTEGER"; |
| 246217 | } | ||
| 246218 | rc = sqlite3Fts5CreateTable(pConfig, "docsize", zCols, 0, pzErr); | ||
| 237161 | } | 246219 | } |
| 237162 | if( rc==SQLITE_OK ){ | 246220 | if( rc==SQLITE_OK ){ |
| 237163 | rc = sqlite3Fts5CreateTable( | 246221 | rc = sqlite3Fts5CreateTable( |
| @@ -237234,7 +246292,7 @@ static int fts5StorageDeleteFromIndex( | |||
| 237234 | ){ | 246292 | ){ |
| 237235 | Fts5Config *pConfig = p->pConfig; | 246293 | Fts5Config *pConfig = p->pConfig; |
| 237236 | sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ | 246294 | sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ |
| 237237 | int rc; /* Return code */ | 246295 | int rc = SQLITE_OK; /* Return code */ |
| 237238 | int rc2; /* sqlite3_reset() return code */ | 246296 | int rc2; /* sqlite3_reset() return code */ |
| 237239 | int iCol; | 246297 | int iCol; |
| 237240 | Fts5InsertCtx ctx; | 246298 | Fts5InsertCtx ctx; |
| @@ -237250,7 +246308,6 @@ static int fts5StorageDeleteFromIndex( | |||
| 237250 | 246308 | ||
| 237251 | ctx.pStorage = p; | 246309 | ctx.pStorage = p; |
| 237252 | ctx.iCol = -1; | 246310 | ctx.iCol = -1; |
| 237253 | rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); | ||
| 237254 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ | 246311 | for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ |
| 237255 | if( pConfig->abUnindexed[iCol-1]==0 ){ | 246312 | if( pConfig->abUnindexed[iCol-1]==0 ){ |
| 237256 | const char *zText; | 246313 | const char *zText; |
| @@ -237287,6 +246344,37 @@ static int fts5StorageDeleteFromIndex( | |||
| 237287 | return rc; | 246344 | return rc; |
| 237288 | } | 246345 | } |
| 237289 | 246346 | ||
| 246347 | /* | ||
| 246348 | ** This function is called to process a DELETE on a contentless_delete=1 | ||
| 246349 | ** table. It adds the tombstone required to delete the entry with rowid | ||
| 246350 | ** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs, | ||
| 246351 | ** an SQLite error code. | ||
| 246352 | */ | ||
| 246353 | static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ | ||
| 246354 | i64 iOrigin = 0; | ||
| 246355 | sqlite3_stmt *pLookup = 0; | ||
| 246356 | int rc = SQLITE_OK; | ||
| 246357 | |||
| 246358 | assert( p->pConfig->bContentlessDelete ); | ||
| 246359 | assert( p->pConfig->eContent==FTS5_CONTENT_NONE ); | ||
| 246360 | |||
| 246361 | /* Look up the origin of the document in the %_docsize table. Store | ||
| 246362 | ** this in stack variable iOrigin. */ | ||
| 246363 | rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0); | ||
| 246364 | if( rc==SQLITE_OK ){ | ||
| 246365 | sqlite3_bind_int64(pLookup, 1, iDel); | ||
| 246366 | if( SQLITE_ROW==sqlite3_step(pLookup) ){ | ||
| 246367 | iOrigin = sqlite3_column_int64(pLookup, 1); | ||
| 246368 | } | ||
| 246369 | rc = sqlite3_reset(pLookup); | ||
| 246370 | } | ||
| 246371 | |||
| 246372 | if( rc==SQLITE_OK && iOrigin!=0 ){ | ||
| 246373 | rc = sqlite3Fts5IndexContentlessDelete(p->pIndex, iOrigin, iDel); | ||
| 246374 | } | ||
| 246375 | |||
| 246376 | return rc; | ||
| 246377 | } | ||
| 237290 | 246378 | ||
| 237291 | /* | 246379 | /* |
| 237292 | ** Insert a record into the %_docsize table. Specifically, do: | 246380 | ** Insert a record into the %_docsize table. Specifically, do: |
| @@ -237307,10 +246395,17 @@ static int fts5StorageInsertDocsize( | |||
| 237307 | rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0); | 246395 | rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0); |
| 237308 | if( rc==SQLITE_OK ){ | 246396 | if( rc==SQLITE_OK ){ |
| 237309 | sqlite3_bind_int64(pReplace, 1, iRowid); | 246397 | sqlite3_bind_int64(pReplace, 1, iRowid); |
| 237310 | sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); | 246398 | if( p->pConfig->bContentlessDelete ){ |
| 237311 | sqlite3_step(pReplace); | 246399 | i64 iOrigin = 0; |
| 237312 | rc = sqlite3_reset(pReplace); | 246400 | rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); |
| 237313 | sqlite3_bind_null(pReplace, 2); | 246401 | sqlite3_bind_int64(pReplace, 3, iOrigin); |
| 246402 | } | ||
| 246403 | if( rc==SQLITE_OK ){ | ||
| 246404 | sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); | ||
| 246405 | sqlite3_step(pReplace); | ||
| 246406 | rc = sqlite3_reset(pReplace); | ||
| 246407 | sqlite3_bind_null(pReplace, 2); | ||
| 246408 | } | ||
| 237314 | } | 246409 | } |
| 237315 | } | 246410 | } |
| 237316 | return rc; | 246411 | return rc; |
| @@ -237374,7 +246469,15 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap | |||
| 237374 | 246469 | ||
| 237375 | /* Delete the index records */ | 246470 | /* Delete the index records */ |
| 237376 | if( rc==SQLITE_OK ){ | 246471 | if( rc==SQLITE_OK ){ |
| 237377 | rc = fts5StorageDeleteFromIndex(p, iDel, apVal); | 246472 | rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); |
| 246473 | } | ||
| 246474 | |||
| 246475 | if( rc==SQLITE_OK ){ | ||
| 246476 | if( p->pConfig->bContentlessDelete ){ | ||
| 246477 | rc = fts5StorageContentlessDelete(p, iDel); | ||
| 246478 | }else{ | ||
| 246479 | rc = fts5StorageDeleteFromIndex(p, iDel, apVal); | ||
| 246480 | } | ||
| 237378 | } | 246481 | } |
| 237379 | 246482 | ||
| 237380 | /* Delete the %_docsize record */ | 246483 | /* Delete the %_docsize record */ |
| @@ -241442,6 +250545,10 @@ static int stmtConnect( | |||
| 241442 | #define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */ | 250545 | #define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */ |
| 241443 | 250546 | ||
| 241444 | 250547 | ||
| 250548 | (void)pAux; | ||
| 250549 | (void)argc; | ||
| 250550 | (void)argv; | ||
| 250551 | (void)pzErr; | ||
| 241445 | rc = sqlite3_declare_vtab(db, | 250552 | rc = sqlite3_declare_vtab(db, |
| 241446 | "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep," | 250553 | "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep," |
| 241447 | "reprep,run,mem)"); | 250554 | "reprep,run,mem)"); |
| @@ -241561,6 +250668,10 @@ static int stmtFilter( | |||
| 241561 | sqlite3_int64 iRowid = 1; | 250668 | sqlite3_int64 iRowid = 1; |
| 241562 | StmtRow **ppRow = 0; | 250669 | StmtRow **ppRow = 0; |
| 241563 | 250670 | ||
| 250671 | (void)idxNum; | ||
| 250672 | (void)idxStr; | ||
| 250673 | (void)argc; | ||
| 250674 | (void)argv; | ||
| 241564 | stmtCsrReset(pCur); | 250675 | stmtCsrReset(pCur); |
| 241565 | ppRow = &pCur->pRow; | 250676 | ppRow = &pCur->pRow; |
| 241566 | for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){ | 250677 | for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){ |
| @@ -241616,6 +250727,7 @@ static int stmtBestIndex( | |||
| 241616 | sqlite3_vtab *tab, | 250727 | sqlite3_vtab *tab, |
| 241617 | sqlite3_index_info *pIdxInfo | 250728 | sqlite3_index_info *pIdxInfo |
| 241618 | ){ | 250729 | ){ |
| 250730 | (void)tab; | ||
| 241619 | pIdxInfo->estimatedCost = (double)500; | 250731 | pIdxInfo->estimatedCost = (double)500; |
| 241620 | pIdxInfo->estimatedRows = 500; | 250732 | pIdxInfo->estimatedRows = 500; |
| 241621 | return SQLITE_OK; | 250733 | return SQLITE_OK; |