From ca5968eb635ca6950f644a0192fd71c29b1bc236 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 7 Oct 2025 07:17:32 +0000 Subject: [PATCH] import UBI nodejs-22.19.0-2.module+el8.10.0+23474+222d264a --- .gitignore | 2 +- .nodejs.metadata | 2 +- SOURCES/0001-sqlite-CVE-2025-6965.patch | 11039 ---------------------- SOURCES/0002-fips-disable-options.patch | 84 + SPECS/nodejs.spec | 23 +- 5 files changed, 100 insertions(+), 11050 deletions(-) delete mode 100644 SOURCES/0001-sqlite-CVE-2025-6965.patch create mode 100644 SOURCES/0002-fips-disable-options.patch diff --git a/.gitignore b/.gitignore index 48bbad3..1a8c733 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ SOURCES/cjs-module-lexer-2.1.0.tar.gz SOURCES/icu4c-77_1-data-bin-b.zip SOURCES/icu4c-77_1-data-bin-l.zip -SOURCES/node-v22.16.0-stripped.tar.gz +SOURCES/node-v22.19.0-stripped.tar.gz SOURCES/undici-6.21.2.tar.gz SOURCES/wasi-sdk-wasi-sdk-12.tar.gz SOURCES/wasi-sdk-wasi-sdk-20.tar.gz diff --git a/.nodejs.metadata b/.nodejs.metadata index 35f0de8..714ae21 100644 --- a/.nodejs.metadata +++ b/.nodejs.metadata @@ -1,7 +1,7 @@ aecfb2810d05c3cef0e65a512dd980d6ba751076 SOURCES/cjs-module-lexer-2.1.0.tar.gz c459faa36dedc60af6a0c6d5b9b84b6198389bf0 SOURCES/icu4c-77_1-data-bin-b.zip c602459f93a43dfe7440686b46430e93a85dfc06 SOURCES/icu4c-77_1-data-bin-l.zip -c9013d945eeb65b80fcb17fb2a55eacdbb0db286 SOURCES/node-v22.16.0-stripped.tar.gz +6e43b5b68ecdff7997552f60f9fc6906e244a63a SOURCES/node-v22.19.0-stripped.tar.gz 6d6793d539b3ffcfb2924f3f5ad328240031361a SOURCES/undici-6.21.2.tar.gz 5ea3a1deb65a52a36ceb41324da690f54b2a4805 SOURCES/wasi-sdk-wasi-sdk-12.tar.gz da40abcb73a6dddafced6174d24ed49e414cda3c SOURCES/wasi-sdk-wasi-sdk-20.tar.gz diff --git a/SOURCES/0001-sqlite-CVE-2025-6965.patch b/SOURCES/0001-sqlite-CVE-2025-6965.patch deleted file mode 100644 index 2376d20..0000000 --- a/SOURCES/0001-sqlite-CVE-2025-6965.patch +++ /dev/null @@ -1,11039 +0,0 @@ -From f3fae6728c57615fcdf1831f7a6907637e5e18e9 Mon Sep 17 00:00:00 2001 -From: Andrei Radchenko -Date: Thu, 17 Jul 2025 16:51:12 +0200 -Subject: [PATCH] sqlite CVE-2025-6965 - ---- - deps/sqlite/sqlite3.c | 4716 +++++++++++++++++++++++++------------- - deps/sqlite/sqlite3.h | 316 +-- - deps/sqlite/sqlite3ext.h | 4 + - 3 files changed, 3259 insertions(+), 1777 deletions(-) - -diff --git a/deps/sqlite/sqlite3.c b/deps/sqlite/sqlite3.c -index 37b534af..e8a0bf11 100644 ---- a/deps/sqlite/sqlite3.c -+++ b/deps/sqlite/sqlite3.c -@@ -1,6 +1,6 @@ - /****************************************************************************** - ** This file is an amalgamation of many separate C source files from SQLite --** version 3.49.1. By combining all the individual C code files into this -+** version 3.50.3. By combining all the individual C code files into this - ** single large file, the entire code can be compiled as a single translation - ** unit. This allows many compilers to do optimizations that would not be - ** possible if the files were compiled separately. Performance improvements -@@ -18,7 +18,7 @@ - ** separate file. This file contains only code for the core SQLite library. - ** - ** The content in this amalgamation comes from Fossil check-in --** 873d4e274b4988d260ba8354a9718324a1c2 with changes in files: -+** 3ce993b8657d6d9deda380a93cdd6404a8c8 with changes in files: - ** - ** - */ -@@ -452,7 +452,7 @@ extern "C" { - ** - ** Since [version 3.6.18] ([dateof:3.6.18]), - ** SQLite source code has been stored in the --** Fossil configuration management -+** Fossil configuration management - ** system. ^The SQLITE_SOURCE_ID macro evaluates to - ** a string which identifies a particular check-in of SQLite - ** within its configuration management system. ^The SQLITE_SOURCE_ID -@@ -465,9 +465,9 @@ extern "C" { - ** [sqlite3_libversion_number()], [sqlite3_sourceid()], - ** [sqlite_version()] and [sqlite_source_id()]. - */ --#define SQLITE_VERSION "3.49.1" --#define SQLITE_VERSION_NUMBER 3049001 --#define SQLITE_SOURCE_ID "2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70" -+#define SQLITE_VERSION "3.50.3" -+#define SQLITE_VERSION_NUMBER 3050003 -+#define SQLITE_SOURCE_ID "2025-07-17 13:25:10 3ce993b8657d6d9deda380a93cdd6404a8c8ba1b185b2bc423703e41ae5f2543" - - /* - ** CAPI3REF: Run-Time Library Version Numbers -@@ -1482,6 +1482,12 @@ struct sqlite3_io_methods { - ** the value that M is to be set to. Before returning, the 32-bit signed - ** integer is overwritten with the previous value of M. - ** -+**
  • [[SQLITE_FCNTL_BLOCK_ON_CONNECT]] -+** The [SQLITE_FCNTL_BLOCK_ON_CONNECT] opcode is used to configure the -+** VFS to block when taking a SHARED lock to connect to a wal mode database. -+** This is used to implement the functionality associated with -+** SQLITE_SETLK_BLOCK_ON_CONNECT. -+** - **
  • [[SQLITE_FCNTL_DATA_VERSION]] - ** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to - ** a database file. The argument is a pointer to a 32-bit unsigned integer. -@@ -1578,6 +1584,7 @@ struct sqlite3_io_methods { - #define SQLITE_FCNTL_CKSM_FILE 41 - #define SQLITE_FCNTL_RESET_CACHE 42 - #define SQLITE_FCNTL_NULL_IO 43 -+#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 - - /* deprecated names */ - #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE -@@ -2308,13 +2315,16 @@ struct sqlite3_mem_methods { - ** - ** [[SQLITE_CONFIG_LOOKASIDE]]
    SQLITE_CONFIG_LOOKASIDE
    - **
    ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine --** the default size of lookaside memory on each [database connection]. -+** the default size of [lookaside memory] on each [database connection]. - ** The first argument is the --** size of each lookaside buffer slot and the second is the number of --** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE --** sets the default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] --** option to [sqlite3_db_config()] can be used to change the lookaside --** configuration on individual connections.)^
    -+** size of each lookaside buffer slot ("sz") and the second is the number of -+** slots allocated to each database connection ("cnt").)^ -+** ^(SQLITE_CONFIG_LOOKASIDE sets the default lookaside size. -+** The [SQLITE_DBCONFIG_LOOKASIDE] option to [sqlite3_db_config()] can -+** be used to change the lookaside configuration on individual connections.)^ -+** The [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to change the -+** default lookaside configuration at compile-time. -+** - ** - ** [[SQLITE_CONFIG_PCACHE2]]
    SQLITE_CONFIG_PCACHE2
    - **
    ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is -@@ -2551,31 +2561,50 @@ struct sqlite3_mem_methods { - ** [[SQLITE_DBCONFIG_LOOKASIDE]] - **
    SQLITE_DBCONFIG_LOOKASIDE
    - **
    The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the --** configuration of the lookaside memory allocator within a database -+** configuration of the [lookaside memory allocator] within a database - ** connection. - ** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are not - ** in the [DBCONFIG arguments|usual format]. - ** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two, - ** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE - ** should have a total of five parameters. --** ^The first argument (the third parameter to [sqlite3_db_config()] is a -+**
      -+**
    1. The first argument ("buf") is a - ** pointer to a memory buffer to use for lookaside memory. --** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb --** may be NULL in which case SQLite will allocate the --** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the --** size of each lookaside buffer slot. ^The third argument is the number of --** slots. The size of the buffer in the first argument must be greater than --** or equal to the product of the second and third arguments. The buffer --** must be aligned to an 8-byte boundary. ^If the second argument to --** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally --** rounded down to the next smaller multiple of 8. ^(The lookaside memory -+** The first argument may be NULL in which case SQLite will allocate the -+** lookaside buffer itself using [sqlite3_malloc()]. -+**

    2. The second argument ("sz") is the -+** size of each lookaside buffer slot. Lookaside is disabled if "sz" -+** is less than 8. The "sz" argument should be a multiple of 8 less than -+** 65536. If "sz" does not meet this constraint, it is reduced in size until -+** it does. -+**

    3. The third argument ("cnt") is the number of slots. Lookaside is disabled -+** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so -+** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" -+** parameter is usually chosen so that the product of "sz" and "cnt" is less -+** than 1,000,000. -+**

    -+**

    If the "buf" argument is not NULL, then it must -+** point to a memory buffer with a size that is greater than -+** or equal to the product of "sz" and "cnt". -+** The buffer must be aligned to an 8-byte boundary. -+** The lookaside memory - ** configuration for a database connection can only be changed when that - ** connection is not currently using lookaside memory, or in other words --** when the "current value" returned by --** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. -+** when the value returned by [SQLITE_DBSTATUS_LOOKASIDE_USED] is zero. - ** Any attempt to change the lookaside memory configuration when lookaside - ** memory is in use leaves the configuration unchanged and returns --** [SQLITE_BUSY].)^

    -+** [SQLITE_BUSY]. -+** If the "buf" argument is NULL and an attempt -+** to allocate memory based on "sz" and "cnt" fails, then -+** lookaside is silently disabled. -+**

    -+** The [SQLITE_CONFIG_LOOKASIDE] configuration option can be used to set the -+** default lookaside configuration at initialization. The -+** [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to set the default lookaside -+** configuration at compile-time. Typical values for lookaside are 1200 for -+** "sz" and 40 to 100 for "cnt". -+** - ** - ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] - **

    SQLITE_DBCONFIG_ENABLE_FKEY
    -@@ -3312,6 +3341,44 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); - */ - SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); - -+/* -+** CAPI3REF: Set the Setlk Timeout -+** METHOD: sqlite3 -+** -+** This routine is only useful in SQLITE_ENABLE_SETLK_TIMEOUT builds. If -+** the VFS supports blocking locks, it sets the timeout in ms used by -+** eligible locks taken on wal mode databases by the specified database -+** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does -+** not support blocking locks, this function is a no-op. -+** -+** Passing 0 to this function disables blocking locks altogether. Passing -+** -1 to this function requests that the VFS blocks for a long time - -+** indefinitely if possible. The results of passing any other negative value -+** are undefined. -+** -+** Internally, each SQLite database handle store two timeout values - the -+** busy-timeout (used for rollback mode databases, or if the VFS does not -+** support blocking locks) and the setlk-timeout (used for blocking locks -+** on wal-mode databases). The sqlite3_busy_timeout() method sets both -+** values, this function sets only the setlk-timeout value. Therefore, -+** to configure separate busy-timeout and setlk-timeout values for a single -+** database handle, call sqlite3_busy_timeout() followed by this function. -+** -+** Whenever the number of connections to a wal mode database falls from -+** 1 to 0, the last connection takes an exclusive lock on the database, -+** then checkpoints and deletes the wal file. While it is doing this, any -+** new connection that tries to read from the database fails with an -+** SQLITE_BUSY error. Or, if the SQLITE_SETLK_BLOCK_ON_CONNECT flag is -+** passed to this API, the new connection blocks until the exclusive lock -+** has been released. -+*/ -+SQLITE_API int sqlite3_setlk_timeout(sqlite3*, int ms, int flags); -+ -+/* -+** CAPI3REF: Flags for sqlite3_setlk_timeout() -+*/ -+#define SQLITE_SETLK_BLOCK_ON_CONNECT 0x01 -+ - /* - ** CAPI3REF: Convenience Routines For Running Queries - ** METHOD: sqlite3 -@@ -4331,7 +4398,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); - ** - ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of - ** database filename D with corresponding journal file J and WAL file W and --** with N URI parameters key/values pairs in the array P. The result from -+** an array P of N URI Key/Value pairs. The result from - ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that - ** is safe to pass to routines like: - **
      -@@ -5012,7 +5079,7 @@ typedef struct sqlite3_context sqlite3_context; - ** METHOD: sqlite3_stmt - ** - ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, --** literals may be replaced by a [parameter] that matches one of following -+** literals may be replaced by a [parameter] that matches one of the following - ** templates: - ** - **
        -@@ -5057,7 +5124,7 @@ typedef struct sqlite3_context sqlite3_context; - ** - ** [[byte-order determination rules]] ^The byte-order of - ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) --** found in first character, which is removed, or in the absence of a BOM -+** found in the first character, which is removed, or in the absence of a BOM - ** the byte order is the native byte order of the host - ** machine for sqlite3_bind_text16() or the byte order specified in - ** the 6th parameter for sqlite3_bind_text64().)^ -@@ -5077,7 +5144,7 @@ typedef struct sqlite3_context sqlite3_context; - ** or sqlite3_bind_text16() or sqlite3_bind_text64() then - ** that parameter must be the byte offset - ** where the NUL terminator would occur assuming the string were NUL --** terminated. If any NUL characters occurs at byte offsets less than -+** terminated. If any NUL characters occur at byte offsets less than - ** the value of the fourth parameter then the resulting string value will - ** contain embedded NULs. The result of expressions involving strings - ** with embedded NULs is undefined. -@@ -5289,7 +5356,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); - ** METHOD: sqlite3_stmt - ** - ** ^These routines provide a means to determine the database, table, and --** table column that is the origin of a particular result column in -+** table column that is the origin of a particular result column in a - ** [SELECT] statement. - ** ^The name of the database or table or column can be returned as - ** either a UTF-8 or UTF-16 string. ^The _database_ routines return -@@ -5427,7 +5494,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); - ** other than [SQLITE_ROW] before any subsequent invocation of - ** sqlite3_step(). Failure to reset the prepared statement using - ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from --** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], -+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), - ** sqlite3_step() began - ** calling [sqlite3_reset()] automatically in this circumstance rather - ** than returning [SQLITE_MISUSE]. This is not considered a compatibility -@@ -5858,8 +5925,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); - ** - ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for - ** all application-defined SQL functions that do not need to be --** used inside of triggers, view, CHECK constraints, or other elements of --** the database schema. This flags is especially recommended for SQL -+** used inside of triggers, views, CHECK constraints, or other elements of -+** the database schema. This flag is especially recommended for SQL - ** functions that have side effects or reveal internal application state. - ** Without this flag, an attacker might be able to modify the schema of - ** a database file to include invocations of the function with parameters -@@ -5890,7 +5957,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); - ** [user-defined window functions|available here]. - ** - ** ^(If the final parameter to sqlite3_create_function_v2() or --** sqlite3_create_window_function() is not NULL, then it is destructor for -+** sqlite3_create_window_function() is not NULL, then it is the destructor for - ** the application data pointer. The destructor is invoked when the function - ** is deleted, either by being overloaded or when the database connection - ** closes.)^ ^The destructor is also invoked if the call to -@@ -6290,7 +6357,7 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); - ** METHOD: sqlite3_value - ** - ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] --** object D and returns a pointer to that copy. ^The [sqlite3_value] returned -+** object V and returns a pointer to that copy. ^The [sqlite3_value] returned - ** is a [protected sqlite3_value] object even if the input is not. - ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a - ** memory allocation fails. ^If V is a [pointer value], then the result -@@ -6328,7 +6395,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); - ** allocation error occurs. - ** - ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is --** determined by the N parameter on first successful call. Changing the -+** determined by the N parameter on the first successful call. Changing the - ** value of N in any subsequent call to sqlite3_aggregate_context() within - ** the same aggregate function instance will not resize the memory - ** allocation.)^ Within the xFinal callback, it is customary to set -@@ -6490,7 +6557,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi - ** - ** Security Warning: These interfaces should not be exposed in scripting - ** languages or in other circumstances where it might be possible for an --** an attacker to invoke them. Any agent that can invoke these interfaces -+** attacker to invoke them. Any agent that can invoke these interfaces - ** can probably also take control of the process. - ** - ** Database connection client data is only available for SQLite -@@ -6604,7 +6671,7 @@ typedef void (*sqlite3_destructor_type)(void*); - ** pointed to by the 2nd parameter are taken as the application-defined - ** function result. If the 3rd parameter is non-negative, then it - ** must be the byte offset into the string where the NUL terminator would --** appear if the string where NUL terminated. If any NUL characters occur -+** appear if the string were NUL terminated. If any NUL characters occur - ** in the string at a byte offset that is less than the value of the 3rd - ** parameter, then the resulting string will contain embedded NULs and the - ** result of expressions operating on strings with embedded NULs is undefined. -@@ -6662,7 +6729,7 @@ typedef void (*sqlite3_destructor_type)(void*); - ** string and preferably a string literal. The sqlite3_result_pointer() - ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. - ** --** If these routines are called from within the different thread -+** If these routines are called from within a different thread - ** than the one containing the application-defined function that received - ** the [sqlite3_context] pointer, the results are undefined. - */ -@@ -7068,7 +7135,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); - ** METHOD: sqlite3 - ** - ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name --** for the N-th database on database connection D, or a NULL pointer of N is -+** for the N-th database on database connection D, or a NULL pointer if N is - ** out of range. An N value of 0 means the main database file. An N of 1 is - ** the "temp" schema. Larger values of N correspond to various ATTACH-ed - ** databases. -@@ -7163,7 +7230,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); - **
        The SQLITE_TXN_READ state means that the database is currently - ** in a read transaction. Content has been read from the database file - ** but nothing in the database file has changed. The transaction state --** will advanced to SQLITE_TXN_WRITE if any changes occur and there are -+** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are - ** no other conflicting concurrent write transactions. The transaction - ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or - ** [COMMIT].
        -@@ -7172,7 +7239,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); - **
        The SQLITE_TXN_WRITE state means that the database is currently - ** in a write transaction. Content has been written to the database file - ** but has not yet committed. The transaction state will change to --** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
        -+** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT]. - */ - #define SQLITE_TXN_NONE 0 - #define SQLITE_TXN_READ 1 -@@ -7323,6 +7390,8 @@ SQLITE_API int sqlite3_autovacuum_pages( - ** - ** ^The second argument is a pointer to the function to invoke when a - ** row is updated, inserted or deleted in a rowid table. -+** ^The update hook is disabled by invoking sqlite3_update_hook() -+** with a NULL pointer as the second parameter. - ** ^The first argument to the callback is a copy of the third argument - ** to sqlite3_update_hook(). - ** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], -@@ -7451,7 +7520,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); - ** CAPI3REF: Impose A Limit On Heap Size - ** - ** These interfaces impose limits on the amount of heap memory that will be --** by all database connections within a single process. -+** used by all database connections within a single process. - ** - ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the - ** soft limit on the amount of heap memory that may be allocated by SQLite. -@@ -7509,7 +7578,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); - **
      )^ - ** - ** The circumstances under which SQLite will enforce the heap limits may --** changes in future releases of SQLite. -+** change in future releases of SQLite. - */ - SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); - SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); -@@ -7624,8 +7693,8 @@ SQLITE_API int sqlite3_table_column_metadata( - ** ^The entry point is zProc. - ** ^(zProc may be 0, in which case SQLite will try to come up with an - ** entry point name on its own. It first tries "sqlite3_extension_init". --** If that does not work, it constructs a name "sqlite3_X_init" where the --** X is consists of the lower-case equivalent of all ASCII alphabetic -+** If that does not work, it constructs a name "sqlite3_X_init" where -+** X consists of the lower-case equivalent of all ASCII alphabetic - ** characters in the filename from the last "/" to the first following - ** "." and omitting any initial "lib".)^ - ** ^The sqlite3_load_extension() interface returns -@@ -7696,7 +7765,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); - ** ^(Even though the function prototype shows that xEntryPoint() takes - ** no arguments and returns void, SQLite invokes xEntryPoint() with three - ** arguments and expects an integer result as if the signature of the --** entry point where as follows: -+** entry point were as follows: - ** - **
      - **    int xEntryPoint(
      -@@ -7860,7 +7929,7 @@ struct sqlite3_module {
      - ** virtual table and might not be checked again by the byte code.)^ ^(The
      - ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
      - ** is left in its default setting of false, the constraint will always be
      --** checked separately in byte code.  If the omit flag is change to true, then
      -+** checked separately in byte code.  If the omit flag is changed to true, then
      - ** the constraint may or may not be checked in byte code.  In other words,
      - ** when the omit flag is true there is no guarantee that the constraint will
      - ** not be checked again using byte code.)^
      -@@ -7886,7 +7955,7 @@ struct sqlite3_module {
      - ** The xBestIndex method may optionally populate the idxFlags field with a
      - ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
      - ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
      --** output to show the idxNum has hex instead of as decimal.  Another flag is
      -+** output to show the idxNum as hex instead of as decimal.  Another flag is
      - ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
      - ** return at most one row.
      - **
      -@@ -8027,7 +8096,7 @@ struct sqlite3_index_info {
      - ** the implementation of the [virtual table module].   ^The fourth
      - ** parameter is an arbitrary client data pointer that is passed through
      - ** into the [xCreate] and [xConnect] methods of the virtual table module
      --** when a new virtual table is be being created or reinitialized.
      -+** when a new virtual table is being created or reinitialized.
      - **
      - ** ^The sqlite3_create_module_v2() interface has a fifth parameter which
      - ** is a pointer to a destructor for the pClientData.  ^SQLite will
      -@@ -8192,7 +8261,7 @@ typedef struct sqlite3_blob sqlite3_blob;
      - ** in *ppBlob. Otherwise an [error code] is returned and, unless the error
      - ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
      - ** the API is not misused, it is always safe to call [sqlite3_blob_close()]
      --** on *ppBlob after this function it returns.
      -+** on *ppBlob after this function returns.
      - **
      - ** This function fails with SQLITE_ERROR if any of the following are true:
      - ** 
        -@@ -8312,7 +8381,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); - ** - ** ^Returns the size in bytes of the BLOB accessible via the - ** successfully opened [BLOB handle] in its only argument. ^The --** incremental blob I/O routines can only read or overwriting existing -+** incremental blob I/O routines can only read or overwrite existing - ** blob content; they cannot change the size of a blob. - ** - ** This routine only works on a [BLOB handle] which has been created -@@ -8462,7 +8531,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); - ** ^The sqlite3_mutex_alloc() routine allocates a new - ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() - ** routine returns NULL if it is unable to allocate the requested --** mutex. The argument to sqlite3_mutex_alloc() must one of these -+** mutex. The argument to sqlite3_mutex_alloc() must be one of these - ** integer constants: - ** - **
          -@@ -8695,7 +8764,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); - ** CAPI3REF: Retrieve the mutex for a database connection - ** METHOD: sqlite3 - ** --** ^This interface returns a pointer the [sqlite3_mutex] object that -+** ^This interface returns a pointer to the [sqlite3_mutex] object that - ** serializes access to the [database connection] given in the argument - ** when the [threading mode] is Serialized. - ** ^If the [threading mode] is Single-thread or Multi-thread then this -@@ -8818,7 +8887,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); - ** CAPI3REF: SQL Keyword Checking - ** - ** These routines provide access to the set of SQL language keywords --** recognized by SQLite. Applications can uses these routines to determine -+** recognized by SQLite. Applications can use these routines to determine - ** whether or not a specific identifier needs to be escaped (for example, - ** by enclosing in double-quotes) so as not to confuse the parser. - ** -@@ -8986,7 +9055,7 @@ SQLITE_API void sqlite3_str_reset(sqlite3_str*); - ** content of the dynamic string under construction in X. The value - ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X - ** and might be freed or altered by any subsequent method on the same --** [sqlite3_str] object. Applications must not used the pointer returned -+** [sqlite3_str] object. Applications must not use the pointer returned by - ** [sqlite3_str_value(X)] after any subsequent method call on the same - ** object. ^Applications may change the content of the string returned - ** by [sqlite3_str_value(X)] as long as they do not write into any bytes -@@ -9072,7 +9141,7 @@ SQLITE_API int sqlite3_status64( - ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] - ** buffer and where forced to overflow to [sqlite3_malloc()]. The - ** returned value includes allocations that overflowed because they --** where too large (they were larger than the "sz" parameter to -+** were too large (they were larger than the "sz" parameter to - ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because - ** no space was left in the page cache.)^ - ** -@@ -9156,28 +9225,29 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r - ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
          SQLITE_DBSTATUS_LOOKASIDE_HIT
          - **
          This parameter returns the number of malloc attempts that were - ** satisfied using lookaside memory. Only the high-water value is meaningful; --** the current value is always zero.)^ -+** the current value is always zero.
          )^ - ** - ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] - ** ^(
          SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
          --**
          This parameter returns the number malloc attempts that might have -+**
          This parameter returns the number of malloc attempts that might have - ** been satisfied using lookaside memory but failed due to the amount of - ** memory requested being larger than the lookaside slot size. - ** Only the high-water value is meaningful; --** the current value is always zero.)^ -+** the current value is always zero.
          )^ - ** - ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] - ** ^(
          SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
          --**
          This parameter returns the number malloc attempts that might have -+**
          This parameter returns the number of malloc attempts that might have - ** been satisfied using lookaside memory but failed due to all lookaside - ** memory already being in use. - ** Only the high-water value is meaningful; --** the current value is always zero.)^ -+** the current value is always zero.
          )^ - ** - ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
          SQLITE_DBSTATUS_CACHE_USED
          - **
          This parameter returns the approximate number of bytes of heap - ** memory used by all pager caches associated with the database connection.)^ - ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. -+**
          - ** - ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] - ** ^(
          SQLITE_DBSTATUS_CACHE_USED_SHARED
          -@@ -9186,10 +9256,10 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r - ** memory used by that pager cache is divided evenly between the attached - ** connections.)^ In other words, if none of the pager caches associated - ** with the database connection are shared, this request returns the same --** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are -+** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are - ** shared, the value returned by this call will be smaller than that returned - ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with --** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. -+** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. - ** - ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
          SQLITE_DBSTATUS_SCHEMA_USED
          - **
          This parameter returns the approximate number of bytes of heap -@@ -9199,6 +9269,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r - ** schema memory is shared with other database connections due to - ** [shared cache mode] being enabled. - ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. -+**
          - ** - ** [[SQLITE_DBSTATUS_STMT_USED]] ^(
          SQLITE_DBSTATUS_STMT_USED
          - **
          This parameter returns the approximate number of bytes of heap -@@ -9235,7 +9306,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r - ** been written to disk in the middle of a transaction due to the page - ** cache overflowing. Transactions are more efficient if they are written - ** to disk all at once. When pages spill mid-transaction, that introduces --** additional overhead. This parameter can be used help identify -+** additional overhead. This parameter can be used to help identify - ** inefficiencies that can be resolved by increasing the cache size. - **
          - ** -@@ -9306,13 +9377,13 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); - ** [[SQLITE_STMTSTATUS_SORT]]
          SQLITE_STMTSTATUS_SORT
          - **
          ^This is the number of sort operations that have occurred. - ** A non-zero value in this counter may indicate an opportunity to --** improvement performance through careful use of indices.
          -+** improve performance through careful use of indices. - ** - ** [[SQLITE_STMTSTATUS_AUTOINDEX]]
          SQLITE_STMTSTATUS_AUTOINDEX
          - **
          ^This is the number of rows inserted into transient indices that - ** were created automatically in order to help joins run faster. - ** A non-zero value in this counter may indicate an opportunity to --** improvement performance by adding permanent indices that do not -+** improve performance by adding permanent indices that do not - ** need to be reinitialized each time the statement is run.
          - ** - ** [[SQLITE_STMTSTATUS_VM_STEP]]
          SQLITE_STMTSTATUS_VM_STEP
          -@@ -9321,19 +9392,19 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); - ** to 2147483647. The number of virtual machine operations can be - ** used as a proxy for the total work done by the prepared statement. - ** If the number of virtual machine operations exceeds 2147483647 --** then the value returned by this statement status code is undefined. -+** then the value returned by this statement status code is undefined. - ** - ** [[SQLITE_STMTSTATUS_REPREPARE]]
          SQLITE_STMTSTATUS_REPREPARE
          - **
          ^This is the number of times that the prepare statement has been - ** automatically regenerated due to schema changes or changes to --** [bound parameters] that might affect the query plan. -+** [bound parameters] that might affect the query plan.
          - ** - ** [[SQLITE_STMTSTATUS_RUN]]
          SQLITE_STMTSTATUS_RUN
          - **
          ^This is the number of times that the prepared statement has - ** been run. A single "run" for the purposes of this counter is one - ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. - ** The counter is incremented on the first [sqlite3_step()] call of each --** cycle. -+** cycle.
          - ** - ** [[SQLITE_STMTSTATUS_FILTER_MISS]] - ** [[SQLITE_STMTSTATUS_FILTER HIT]] -@@ -9343,7 +9414,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); - ** step was bypassed because a Bloom filter returned not-found. The - ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of - ** times that the Bloom filter returned a find, and thus the join step --** had to be processed as normal. -+** had to be processed as normal. - ** - ** [[SQLITE_STMTSTATUS_MEMUSED]]
          SQLITE_STMTSTATUS_MEMUSED
          - **
          ^This is the approximate number of bytes of heap memory -@@ -9448,9 +9519,9 @@ struct sqlite3_pcache_page { - ** SQLite will typically create one cache instance for each open database file, - ** though this is not guaranteed. ^The - ** first parameter, szPage, is the size in bytes of the pages that must --** be allocated by the cache. ^szPage will always a power of two. ^The -+** be allocated by the cache. ^szPage will always be a power of two. ^The - ** second parameter szExtra is a number of bytes of extra storage --** associated with each page cache entry. ^The szExtra parameter will -+** associated with each page cache entry. ^The szExtra parameter will be - ** a number less than 250. SQLite will use the - ** extra szExtra bytes on each page to store metadata about the underlying - ** database page on disk. The value passed into szExtra depends -@@ -9458,17 +9529,17 @@ struct sqlite3_pcache_page { - ** ^The third argument to xCreate(), bPurgeable, is true if the cache being - ** created will be used to cache database pages of a file stored on disk, or - ** false if it is used for an in-memory database. The cache implementation --** does not have to do anything special based with the value of bPurgeable; -+** does not have to do anything special based upon the value of bPurgeable; - ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will - ** never invoke xUnpin() except to deliberately delete a page. - ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to - ** false will always have the "discard" flag set to true. --** ^Hence, a cache created with bPurgeable false will -+** ^Hence, a cache created with bPurgeable set to false will - ** never contain any unpinned pages. - ** - ** [[the xCachesize() page cache method]] - ** ^(The xCachesize() method may be called at any time by SQLite to set the --** suggested maximum cache-size (number of pages stored by) the cache -+** suggested maximum cache-size (number of pages stored) for the cache - ** instance passed as the first argument. This is the value configured using - ** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable - ** parameter, the implementation is not required to do anything with this -@@ -9495,12 +9566,12 @@ struct sqlite3_pcache_page { - ** implementation must return a pointer to the page buffer with its content - ** intact. If the requested page is not already in the cache, then the - ** cache implementation should use the value of the createFlag --** parameter to help it determined what action to take: -+** parameter to help it determine what action to take: - ** - ** - **
          createFlag Behavior when page is not already in cache - **
          0 Do not allocate a new page. Return NULL. --**
          1 Allocate a new page if it easy and convenient to do so. -+**
          1 Allocate a new page if it is easy and convenient to do so. - ** Otherwise return NULL. - **
          2 Make every effort to allocate a new page. Only return - ** NULL if allocating a new page is effectively impossible. -@@ -9517,7 +9588,7 @@ struct sqlite3_pcache_page { - ** as its second argument. If the third parameter, discard, is non-zero, - ** then the page must be evicted from the cache. - ** ^If the discard parameter is --** zero, then the page may be discarded or retained at the discretion of -+** zero, then the page may be discarded or retained at the discretion of the - ** page cache implementation. ^The page cache implementation - ** may choose to evict unpinned pages at any time. - ** -@@ -9535,7 +9606,7 @@ struct sqlite3_pcache_page { - ** When SQLite calls the xTruncate() method, the cache must discard all - ** existing cache entries with page numbers (keys) greater than or equal - ** to the value of the iLimit parameter passed to xTruncate(). If any --** of these pages are pinned, they are implicitly unpinned, meaning that -+** of these pages are pinned, they become implicitly unpinned, meaning that - ** they can be safely discarded. - ** - ** [[the xDestroy() page cache method]] -@@ -9715,7 +9786,7 @@ typedef struct sqlite3_backup sqlite3_backup; - ** external process or via a database connection other than the one being - ** used by the backup operation, then the backup will be automatically - ** restarted by the next call to sqlite3_backup_step(). ^If the source --** database is modified by the using the same database connection as is used -+** database is modified by using the same database connection as is used - ** by the backup operation, then the backup database is automatically - ** updated at the same time. - ** -@@ -9732,7 +9803,7 @@ typedef struct sqlite3_backup sqlite3_backup; - ** and may not be used following a call to sqlite3_backup_finish(). - ** - ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no --** sqlite3_backup_step() errors occurred, regardless or whether or not -+** sqlite3_backup_step() errors occurred, regardless of whether or not - ** sqlite3_backup_step() completed. - ** ^If an out-of-memory condition or IO error occurred during any prior - ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then -@@ -9834,7 +9905,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); - ** application receives an SQLITE_LOCKED error, it may call the - ** sqlite3_unlock_notify() method with the blocked connection handle as - ** the first argument to register for a callback that will be invoked --** when the blocking connections current transaction is concluded. ^The -+** when the blocking connection's current transaction is concluded. ^The - ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] - ** call that concludes the blocking connection's transaction. - ** -@@ -9854,7 +9925,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); - ** blocked connection already has a registered unlock-notify callback, - ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is - ** called with a NULL pointer as its second argument, then any existing --** unlock-notify callback is canceled. ^The blocked connections -+** unlock-notify callback is canceled. ^The blocked connection's - ** unlock-notify callback may also be canceled by closing the blocked - ** connection using [sqlite3_close()]. - ** -@@ -10252,7 +10323,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); - ** support constraints. In this configuration (which is the default) if - ** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire - ** statement is rolled back as if [ON CONFLICT | OR ABORT] had been --** specified as part of the users SQL statement, regardless of the actual -+** specified as part of the user's SQL statement, regardless of the actual - ** ON CONFLICT mode specified. - ** - ** If X is non-zero, then the virtual table implementation guarantees -@@ -10286,7 +10357,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); - ** [[SQLITE_VTAB_INNOCUOUS]]
          SQLITE_VTAB_INNOCUOUS
          - **
          Calls of the form - ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the --** the [xConnect] or [xCreate] methods of a [virtual table] implementation -+** [xConnect] or [xCreate] methods of a [virtual table] implementation - ** identify that virtual table as being safe to use from within triggers - ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the - ** virtual table can do no serious harm even if it is controlled by a -@@ -10454,7 +10525,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); - **
          - ** - ** ^For the purposes of comparing virtual table output values to see if the --** values are same value for sorting purposes, two NULL values are considered -+** values are the same value for sorting purposes, two NULL values are considered - ** to be the same. In other words, the comparison operator is "IS" - ** (or "IS NOT DISTINCT FROM") and not "==". - ** -@@ -10464,7 +10535,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); - ** - ** ^A virtual table implementation is always free to return rows in any order - ** it wants, as long as the "orderByConsumed" flag is not set. ^When the --** the "orderByConsumed" flag is unset, the query planner will add extra -+** "orderByConsumed" flag is unset, the query planner will add extra - ** [bytecode] to ensure that the final results returned by the SQL query are - ** ordered correctly. The use of the "orderByConsumed" flag and the - ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful -@@ -10561,7 +10632,7 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); - ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the - ** xFilter method which invokes these routines, and specifically - ** a parameter that was previously selected for all-at-once IN constraint --** processing use the [sqlite3_vtab_in()] interface in the -+** processing using the [sqlite3_vtab_in()] interface in the - ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not - ** an xFilter argument that was selected for all-at-once IN constraint - ** processing, then these routines return [SQLITE_ERROR].)^ -@@ -10616,7 +10687,7 @@ SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); - ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) - ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th - ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface --** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if -+** can return a result code other than SQLITE_OK or SQLITE_NOTFOUND if - ** something goes wrong. - ** - ** The sqlite3_vtab_rhs_value() interface is usually only successful if -@@ -10644,8 +10715,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** - ** KEYWORDS: {conflict resolution mode} - ** - ** These constants are returned by [sqlite3_vtab_on_conflict()] to --** inform a [virtual table] implementation what the [ON CONFLICT] mode --** is for the SQL statement being evaluated. -+** inform a [virtual table] implementation of the [ON CONFLICT] mode -+** for the SQL statement being evaluated. - ** - ** Note that the [SQLITE_IGNORE] constant is also used as a potential - ** return value from the [sqlite3_set_authorizer()] callback and that -@@ -10685,39 +10756,39 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** - ** [[SQLITE_SCANSTAT_EST]]
          SQLITE_SCANSTAT_EST
          - **
          ^The "double" variable pointed to by the V parameter will be set to the - ** query planner's estimate for the average number of rows output from each --** iteration of the X-th loop. If the query planner's estimates was accurate, -+** iteration of the X-th loop. If the query planner's estimate was accurate, - ** then this value will approximate the quotient NVISIT/NLOOP and the - ** product of this value for all prior loops with the same SELECTID will --** be the NLOOP value for the current loop. -+** be the NLOOP value for the current loop.
          - ** - ** [[SQLITE_SCANSTAT_NAME]]
          SQLITE_SCANSTAT_NAME
          - **
          ^The "const char *" variable pointed to by the V parameter will be set - ** to a zero-terminated UTF-8 string containing the name of the index or table --** used for the X-th loop. -+** used for the X-th loop.
          - ** - ** [[SQLITE_SCANSTAT_EXPLAIN]]
          SQLITE_SCANSTAT_EXPLAIN
          - **
          ^The "const char *" variable pointed to by the V parameter will be set - ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] --** description for the X-th loop. -+** description for the X-th loop.
          - ** - ** [[SQLITE_SCANSTAT_SELECTID]]
          SQLITE_SCANSTAT_SELECTID
          - **
          ^The "int" variable pointed to by the V parameter will be set to the - ** id for the X-th query plan element. The id value is unique within the - ** statement. The select-id is the same value as is output in the first --** column of an [EXPLAIN QUERY PLAN] query. -+** column of an [EXPLAIN QUERY PLAN] query.
          - ** - ** [[SQLITE_SCANSTAT_PARENTID]]
          SQLITE_SCANSTAT_PARENTID
          - **
          The "int" variable pointed to by the V parameter will be set to the --** the id of the parent of the current query element, if applicable, or -+** id of the parent of the current query element, if applicable, or - ** to zero if the query element has no parent. This is the same value as --** returned in the second column of an [EXPLAIN QUERY PLAN] query. -+** returned in the second column of an [EXPLAIN QUERY PLAN] query.
          - ** - ** [[SQLITE_SCANSTAT_NCYCLE]]
          SQLITE_SCANSTAT_NCYCLE
          - **
          The sqlite3_int64 output value is set to the number of cycles, - ** according to the processor time-stamp counter, that elapsed while the - ** query element was being processed. This value is not available for - ** all query elements - if it is unavailable the output variable is --** set to -1. -+** set to -1.
          - ** - */ - #define SQLITE_SCANSTAT_NLOOP 0 -@@ -10758,8 +10829,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** - ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. - ** - ** Parameter "idx" identifies the specific query element to retrieve statistics --** for. Query elements are numbered starting from zero. A value of -1 may be --** to query for statistics regarding the entire query. ^If idx is out of range -+** for. Query elements are numbered starting from zero. A value of -1 may -+** retrieve statistics for the entire query. ^If idx is out of range - ** - less than -1 or greater than or equal to the total number of query - ** elements used to implement the statement - a non-zero value is returned and - ** the variable that pOut points to is unchanged. -@@ -10802,7 +10873,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); - ** METHOD: sqlite3 - ** - ** ^If a write-transaction is open on [database connection] D when the --** [sqlite3_db_cacheflush(D)] interface invoked, any dirty -+** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty - ** pages in the pager-cache that are not currently in use are written out - ** to disk. A dirty page may be in use if a database cursor created by an - ** active SQL statement is reading from it, or if it is page 1 of a database -@@ -10916,8 +10987,8 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); - ** triggers; and so forth. - ** - ** When the [sqlite3_blob_write()] API is used to update a blob column, --** the pre-update hook is invoked with SQLITE_DELETE. This is because the --** in this case the new values are not available. In this case, when a -+** the pre-update hook is invoked with SQLITE_DELETE, because -+** the new values are not yet available. In this case, when a - ** callback made with op==SQLITE_DELETE is actually a write using the - ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns - ** the index of the column being written. In other cases, where the -@@ -11170,7 +11241,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c - ** For an ordinary on-disk database file, the serialization is just a - ** copy of the disk file. For an in-memory database or a "TEMP" database, - ** the serialization is the same sequence of bytes which would be written --** to disk if that database where backed up to disk. -+** to disk if that database were backed up to disk. - ** - ** The usual case is that sqlite3_serialize() copies the serialization of - ** the database into memory obtained from [sqlite3_malloc64()] and returns -@@ -11179,7 +11250,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c - ** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations - ** are made, and the sqlite3_serialize() function will return a pointer - ** to the contiguous memory representation of the database that SQLite --** is currently using for that database, or NULL if the no such contiguous -+** is currently using for that database, or NULL if no such contiguous - ** memory representation of the database exists. A contiguous memory - ** representation of the database will usually only exist if there has - ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same -@@ -11250,7 +11321,7 @@ SQLITE_API unsigned char *sqlite3_serialize( - ** database is currently in a read transaction or is involved in a backup - ** operation. - ** --** It is not possible to deserialized into the TEMP database. If the -+** It is not possible to deserialize into the TEMP database. If the - ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the - ** function returns SQLITE_ERROR. - ** -@@ -11272,7 +11343,7 @@ SQLITE_API int sqlite3_deserialize( - sqlite3 *db, /* The database connection */ - const char *zSchema, /* Which DB to reopen with the deserialization */ - unsigned char *pData, /* The serialized database content */ -- sqlite3_int64 szDb, /* Number bytes in the deserialization */ -+ sqlite3_int64 szDb, /* Number of bytes in the deserialization */ - sqlite3_int64 szBuf, /* Total size of buffer pData[] */ - unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ - ); -@@ -11280,7 +11351,7 @@ SQLITE_API int sqlite3_deserialize( - /* - ** CAPI3REF: Flags for sqlite3_deserialize() - ** --** The following are allowed values for 6th argument (the F argument) to -+** The following are allowed values for the 6th argument (the F argument) to - ** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. - ** - ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization -@@ -11805,9 +11876,10 @@ SQLITE_API void sqlite3session_table_filter( - ** is inserted while a session object is enabled, then later deleted while - ** the same session object is disabled, no INSERT record will appear in the - ** changeset, even though the delete took place while the session was disabled. --** Or, if one field of a row is updated while a session is disabled, and --** another field of the same row is updated while the session is enabled, the --** resulting changeset will contain an UPDATE change that updates both fields. -+** Or, if one field of a row is updated while a session is enabled, and -+** then another field of the same row is updated while the session is disabled, -+** the resulting changeset will contain an UPDATE change that updates both -+** fields. - */ - SQLITE_API int sqlite3session_changeset( - sqlite3_session *pSession, /* Session object */ -@@ -11879,8 +11951,9 @@ SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession - ** database zFrom the contents of the two compatible tables would be - ** identical. - ** --** It an error if database zFrom does not exist or does not contain the --** required compatible table. -+** Unless the call to this function is a no-op as described above, it is an -+** error if database zFrom does not exist or does not contain the required -+** compatible table. - ** - ** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite - ** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg -@@ -12015,7 +12088,7 @@ SQLITE_API int sqlite3changeset_start_v2( - ** The following flags may passed via the 4th parameter to - ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: - ** --**
          SQLITE_CHANGESETAPPLY_INVERT
          -+**
          SQLITE_CHANGESETSTART_INVERT
          - ** Invert the changeset while iterating through it. This is equivalent to - ** inverting a changeset using sqlite3changeset_invert() before applying it. - ** It is an error to specify this flag with a patchset. -@@ -12330,19 +12403,6 @@ SQLITE_API int sqlite3changeset_concat( - void **ppOut /* OUT: Buffer containing output changeset */ - ); - -- --/* --** CAPI3REF: Upgrade the Schema of a Changeset/Patchset --*/ --SQLITE_API int sqlite3changeset_upgrade( -- sqlite3 *db, -- const char *zDb, -- int nIn, const void *pIn, /* Input changeset */ -- int *pnOut, void **ppOut /* OUT: Inverse of input */ --); -- -- -- - /* - ** CAPI3REF: Changegroup Handle - ** -@@ -14090,14 +14150,22 @@ struct fts5_api { - ** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. - ** * Terms in the VALUES clause of an INSERT statement - ** --** The hard upper limit here is 32676. Most database people will -+** The hard upper limit here is 32767. Most database people will - ** tell you that in a well-normalized database, you usually should - ** not have more than a dozen or so columns in any table. And if - ** that is the case, there is no point in having more than a few - ** dozen values in any of the other situations described above. -+** -+** An index can only have SQLITE_MAX_COLUMN columns from the user -+** point of view, but the underlying b-tree that implements the index -+** might have up to twice as many columns in a WITHOUT ROWID table, -+** since must also store the primary key at the end. Hence the -+** column count for Index is u16 instead of i16. - */ --#ifndef SQLITE_MAX_COLUMN -+#if !defined(SQLITE_MAX_COLUMN) - # define SQLITE_MAX_COLUMN 2000 -+#elif SQLITE_MAX_COLUMN>32767 -+# error SQLITE_MAX_COLUMN may not exceed 32767 - #endif - - /* -@@ -14749,6 +14817,7 @@ struct HashElem { - HashElem *next, *prev; /* Next and previous elements in the table */ - void *data; /* Data associated with this element */ - const char *pKey; /* Key associated with this element */ -+ unsigned int h; /* hash for pKey */ - }; - - /* -@@ -15109,7 +15178,17 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); - ** ourselves. - */ - #ifndef offsetof --#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) -+#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) -+#endif -+ -+/* -+** Work around C99 "flex-array" syntax for pre-C99 compilers, so as -+** to avoid complaints from -fsanitize=strict-bounds. -+*/ -+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -+# define FLEXARRAY -+#else -+# define FLEXARRAY 1 - #endif - - /* -@@ -15187,6 +15266,11 @@ typedef INT16_TYPE i16; /* 2-byte signed integer */ - typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ - typedef INT8_TYPE i8; /* 1-byte signed integer */ - -+/* A bitfield type for use inside of structures. Always follow with :N where -+** N is the number of bits. -+*/ -+typedef unsigned bft; /* Bit Field Type */ -+ - /* - ** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value - ** that can be stored in a u32 without loss of data. The value -@@ -15355,6 +15439,14 @@ typedef INT16_TYPE LogEst; - #define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32)) - #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) - -+/* -+** Macro SMXV(n) return the maximum value that can be held in variable n, -+** assuming n is a signed integer type. UMXV(n) is similar for unsigned -+** integer types. -+*/ -+#define SMXV(n) ((((i64)1)<<(sizeof(n)*8-1))-1) -+#define UMXV(n) ((((i64)1)<<(sizeof(n)*8))-1) -+ - /* - ** Round up a number to the next larger multiple of 8. This is used - ** to force 8-byte alignment on 64-bit architectures. -@@ -17331,8 +17423,8 @@ SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); - SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); - #endif - --/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on --** each VDBE opcode. -+/* Use SQLITE_ENABLE_EXPLAIN_COMMENTS to enable generation of extra -+** comments on each VDBE opcode. - ** - ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op - ** comments in VDBE programs that show key decision points in the code -@@ -18055,6 +18147,10 @@ struct sqlite3 { - Savepoint *pSavepoint; /* List of active savepoints */ - int nAnalysisLimit; /* Number of index rows to ANALYZE */ - int busyTimeout; /* Busy handler timeout, in msec */ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ int setlkTimeout; /* Blocking lock timeout, in msec. -1 -> inf. */ -+ int setlkFlags; /* Flags passed to setlk_timeout() */ -+#endif - int nSavepoint; /* Number of non-transaction savepoints */ - int nStatement; /* Number of nested statement-transactions */ - i64 nDeferredCons; /* Net deferred constraints this transaction. */ -@@ -18609,6 +18705,7 @@ struct CollSeq { - #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ - #define SQLITE_AFF_REAL 0x45 /* 'E' */ - #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ -+#define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ - - #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) - -@@ -18733,6 +18830,7 @@ struct Table { - } u; - Trigger *pTrigger; /* List of triggers on this object */ - Schema *pSchema; /* Schema that contains this table */ -+ u8 aHx[16]; /* Column aHt[K%sizeof(aHt)] might have hash K */ - }; - - /* -@@ -18866,9 +18964,13 @@ struct FKey { - struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ - int iFrom; /* Index of column in pFrom */ - char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */ -- } aCol[1]; /* One entry for each of nCol columns */ -+ } aCol[FLEXARRAY]; /* One entry for each of nCol columns */ - }; - -+/* The size (in bytes) of an FKey object holding N columns. The answer -+** does NOT include space to hold the zTo name. */ -+#define SZ_FKEY(N) (offsetof(FKey,aCol)+(N)*sizeof(struct sColMap)) -+ - /* - ** SQLite supports many different ways to resolve a constraint - ** error. ROLLBACK processing means that a constraint violation -@@ -18930,9 +19032,12 @@ struct KeyInfo { - u16 nAllField; /* Total columns, including key plus others */ - sqlite3 *db; /* The database connection */ - u8 *aSortFlags; /* Sort order for each column. */ -- CollSeq *aColl[1]; /* Collating sequence for each term of the key */ -+ CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ - }; - -+/* The size (in bytes) of a KeyInfo object with up to N fields */ -+#define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) -+ - /* - ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. - */ -@@ -19052,7 +19157,7 @@ struct Index { - Pgno tnum; /* DB Page containing root of this index */ - LogEst szIdxRow; /* Estimated average row size in bytes */ - u16 nKeyCol; /* Number of columns forming the key */ -- u16 nColumn; /* Number of columns stored in the index */ -+ u16 nColumn; /* Nr columns in btree. Can be 2*Table.nCol */ - u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */ - unsigned bUnordered:1; /* Use this index for == or IN queries only */ -@@ -19061,7 +19166,6 @@ struct Index { - unsigned isCovering:1; /* True if this is a covering index */ - unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ - unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ -- unsigned bLowQual:1; /* sqlite_stat1 says this is a low-quality index */ - unsigned bNoQuery:1; /* Do not use this index to optimize queries */ - unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ - unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ -@@ -19151,7 +19255,7 @@ struct AggInfo { - ** from source tables rather than from accumulators */ - u8 useSortingIdx; /* In direct mode, reference the sorting index rather - ** than the source table */ -- u16 nSortingColumn; /* Number of columns in the sorting index */ -+ u32 nSortingColumn; /* Number of columns in the sorting index */ - int sortingIdx; /* Cursor number of the sorting index */ - int sortingIdxPTab; /* Cursor number of pseudo-table */ - int iFirstReg; /* First register in range for aCol[] and aFunc[] */ -@@ -19160,8 +19264,8 @@ struct AggInfo { - Table *pTab; /* Source table */ - Expr *pCExpr; /* The original expression */ - int iTable; /* Cursor number of the source table */ -- i16 iColumn; /* Column number within the source table */ -- i16 iSorterColumn; /* Column number in the sorting index */ -+ int iColumn; /* Column number within the source table */ -+ int iSorterColumn; /* Column number in the sorting index */ - } *aCol; - int nColumn; /* Number of used entries in aCol[] */ - int nAccumulator; /* Number of columns that show through to the output. -@@ -19390,10 +19494,10 @@ struct Expr { - /* Macros can be used to test, set, or clear bits in the - ** Expr.flags field. - */ --#define ExprHasProperty(E,P) (((E)->flags&(P))!=0) --#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P)) --#define ExprSetProperty(E,P) (E)->flags|=(P) --#define ExprClearProperty(E,P) (E)->flags&=~(P) -+#define ExprHasProperty(E,P) (((E)->flags&(u32)(P))!=0) -+#define ExprHasAllProperty(E,P) (((E)->flags&(u32)(P))==(u32)(P)) -+#define ExprSetProperty(E,P) (E)->flags|=(u32)(P) -+#define ExprClearProperty(E,P) (E)->flags&=~(u32)(P) - #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) - #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) - #define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) -@@ -19505,9 +19609,14 @@ struct ExprList { - int iConstExprReg; /* Register in which Expr value is cached. Used only - ** by Parse.pConstExpr */ - } u; -- } a[1]; /* One slot for each expression in the list */ -+ } a[FLEXARRAY]; /* One slot for each expression in the list */ - }; - -+/* The size (in bytes) of an ExprList object that is big enough to hold -+** as many as N expressions. */ -+#define SZ_EXPRLIST(N) \ -+ (offsetof(ExprList,a) + (N)*sizeof(struct ExprList_item)) -+ - /* - ** Allowed values for Expr.a.eEName - */ -@@ -19535,9 +19644,12 @@ struct IdList { - int nId; /* Number of identifiers on the list */ - struct IdList_item { - char *zName; /* Name of the identifier */ -- } a[1]; -+ } a[FLEXARRAY]; - }; - -+/* The size (in bytes) of an IdList object that can hold up to N IDs. */ -+#define SZ_IDLIST(N) (offsetof(IdList,a)+(N)*sizeof(struct IdList_item)) -+ - /* - ** Allowed values for IdList.eType, which determines which value of the a.u4 - ** is valid. -@@ -19657,11 +19769,19 @@ struct OnOrUsing { - ** - */ - struct SrcList { -- int nSrc; /* Number of tables or subqueries in the FROM clause */ -- u32 nAlloc; /* Number of entries allocated in a[] below */ -- SrcItem a[1]; /* One entry for each identifier on the list */ -+ int nSrc; /* Number of tables or subqueries in the FROM clause */ -+ u32 nAlloc; /* Number of entries allocated in a[] below */ -+ SrcItem a[FLEXARRAY]; /* One entry for each identifier on the list */ - }; - -+/* Size (in bytes) of a SrcList object that can hold as many as N -+** SrcItem objects. */ -+#define SZ_SRCLIST(N) (offsetof(SrcList,a)+(N)*sizeof(SrcItem)) -+ -+/* Size (in bytes( of a SrcList object that holds 1 SrcItem. This is a -+** special case of SZ_SRCITEM(1) that comes up often. */ -+#define SZ_SRCLIST_1 (offsetof(SrcList,a)+sizeof(SrcItem)) -+ - /* - ** Permitted values of the SrcList.a.jointype field - */ -@@ -20130,25 +20250,32 @@ struct Parse { - char *zErrMsg; /* An error message */ - Vdbe *pVdbe; /* An engine for executing database bytecode */ - int rc; /* Return code from execution */ -- u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ -- u8 checkSchema; /* Causes schema cookie check after an error */ -+ LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ - u8 nested; /* Number of nested calls to the parser/code generator */ - u8 nTempReg; /* Number of temporary registers in aTempReg[] */ - u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ - u8 mayAbort; /* True if statement may throw an ABORT exception */ - u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ -- u8 okConstFactor; /* OK to factor out constants */ - u8 disableLookaside; /* Number of times lookaside has been disabled */ - u8 prepFlags; /* SQLITE_PREPARE_* flags */ - u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ -- u8 bHasWith; /* True if statement contains WITH */ - u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ -+ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ -+ u8 bReturning; /* Coding a RETURNING trigger */ -+ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ -+ u8 disableTriggers; /* True to disable triggers */ - #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) - u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ - #endif - #ifdef SQLITE_DEBUG - u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */ -+ u8 isCreate; /* CREATE TABLE, INDEX, or VIEW (but not TRIGGER) -+ ** and ALTER TABLE ADD COLUMN. */ - #endif -+ bft colNamesSet :1; /* TRUE after OP_ColumnName has been issued to pVdbe */ -+ bft bHasWith :1; /* True if statement contains WITH */ -+ bft okConstFactor :1; /* OK to factor out constants */ -+ bft checkSchema :1; /* Causes schema cookie check after an error */ - int nRangeReg; /* Size of the temporary register block */ - int iRangeReg; /* First register in temporary register block */ - int nErr; /* Number of errors seen */ -@@ -20163,12 +20290,9 @@ struct Parse { - ExprList *pConstExpr;/* Constant expressions */ - IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ - IndexedExpr *pIdxPartExpr; /* Exprs constrained by index WHERE clauses */ -- Token constraintName;/* Name of the constraint currently being parsed */ - yDbMask writeMask; /* Start a write transaction on these databases */ - yDbMask cookieMask; /* Bitmask of schema verified databases */ -- int regRowid; /* Register holding rowid of CREATE TABLE entry */ -- int regRoot; /* Register holding root page number for new objects */ -- int nMaxArg; /* Max args passed to user function by sub-program */ -+ int nMaxArg; /* Max args to xUpdate and xFilter vtab methods */ - int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ - #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ -@@ -20182,17 +20306,6 @@ struct Parse { - Table *pTriggerTab; /* Table triggers are being coded for */ - TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ - ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ -- union { -- int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ -- Returning *pReturning; /* The RETURNING clause */ -- } u1; -- u32 oldmask; /* Mask of old.* columns referenced */ -- u32 newmask; /* Mask of new.* columns referenced */ -- LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ -- u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ -- u8 bReturning; /* Coding a RETURNING trigger */ -- u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ -- u8 disableTriggers; /* True to disable triggers */ - - /************************************************************************** - ** Fields above must be initialized to zero. The fields that follow, -@@ -20204,6 +20317,19 @@ struct Parse { - int aTempReg[8]; /* Holding area for temporary registers */ - Parse *pOuterParse; /* Outer Parse object when nested */ - Token sNameToken; /* Token with unqualified schema object name */ -+ u32 oldmask; /* Mask of old.* columns referenced */ -+ u32 newmask; /* Mask of new.* columns referenced */ -+ union { -+ struct { /* These fields available when isCreate is true */ -+ int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ -+ int regRowid; /* Register holding rowid of CREATE TABLE entry */ -+ int regRoot; /* Register holding root page for new objects */ -+ Token constraintName; /* Name of the constraint currently being parsed */ -+ } cr; -+ struct { /* These fields available to all other statements */ -+ Returning *pReturning; /* The RETURNING clause */ -+ } d; -+ } u1; - - /************************************************************************ - ** Above is constant between recursions. Below is reset before and after -@@ -20719,9 +20845,13 @@ struct With { - int nCte; /* Number of CTEs in the WITH clause */ - int bView; /* Belongs to the outermost Select of a view */ - With *pOuter; /* Containing WITH clause, or NULL */ -- Cte a[1]; /* For each CTE in the WITH clause.... */ -+ Cte a[FLEXARRAY]; /* For each CTE in the WITH clause.... */ - }; - -+/* The size (in bytes) of a With object that can hold as many -+** as N different CTEs. */ -+#define SZ_WITH(N) (offsetof(With,a) + (N)*sizeof(Cte)) -+ - /* - ** The Cte object is not guaranteed to persist for the entire duration - ** of code generation. (The query flattener or other parser tree -@@ -20750,9 +20880,13 @@ struct DbClientData { - DbClientData *pNext; /* Next in a linked list */ - void *pData; /* The data */ - void (*xDestructor)(void*); /* Destructor. Might be NULL */ -- char zName[1]; /* Name of this client data. MUST BE LAST */ -+ char zName[FLEXARRAY]; /* Name of this client data. MUST BE LAST */ - }; - -+/* The size (in bytes) of a DbClientData object that can has a name -+** that is N bytes long, including the zero-terminator. */ -+#define SZ_DBCLIENTDATA(N) (offsetof(DbClientData,zName)+(N)) -+ - #ifdef SQLITE_DEBUG - /* - ** An instance of the TreeView object is used for printing the content of -@@ -21195,7 +21329,7 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); - SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); - SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); - SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); --SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index*, i16); -+SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index*, int); - #ifdef SQLITE_OMIT_GENERATED_COLUMNS - # define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ - # define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ -@@ -21293,7 +21427,7 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); - SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); - SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); - SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); --SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); -+SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,int,int,char**); - SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, - Expr*, int, int, u8); - SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); -@@ -21429,7 +21563,8 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,const Select*,int); - SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); - SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); - SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); --SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*); -+SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*,int); -+SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char*, u32); - SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); - SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); - SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); -@@ -22294,6 +22429,9 @@ static const char * const sqlite3azCompileOpt[] = { - #ifdef SQLITE_BUG_COMPATIBLE_20160819 - "BUG_COMPATIBLE_20160819", - #endif -+#ifdef SQLITE_BUG_COMPATIBLE_20250510 -+ "BUG_COMPATIBLE_20250510", -+#endif - #ifdef SQLITE_CASE_SENSITIVE_LIKE - "CASE_SENSITIVE_LIKE", - #endif -@@ -22530,6 +22668,9 @@ static const char * const sqlite3azCompileOpt[] = { - #ifdef SQLITE_ENABLE_SESSION - "ENABLE_SESSION", - #endif -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ "ENABLE_SETLK_TIMEOUT", -+#endif - #ifdef SQLITE_ENABLE_SNAPSHOT - "ENABLE_SNAPSHOT", - #endif -@@ -22584,6 +22725,9 @@ static const char * const sqlite3azCompileOpt[] = { - #ifdef SQLITE_EXTRA_INIT - "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT), - #endif -+#ifdef SQLITE_EXTRA_INIT_MUTEXED -+ "EXTRA_INIT_MUTEXED=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT_MUTEXED), -+#endif - #ifdef SQLITE_EXTRA_SHUTDOWN - "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN), - #endif -@@ -23568,12 +23712,19 @@ struct VdbeCursor { - #endif - VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ - -- /* 2*nField extra array elements allocated for aType[], beyond the one -- ** static element declared in the structure. nField total array slots for -- ** aType[] and nField+1 array slots for aOffset[] */ -- u32 aType[1]; /* Type values record decode. MUST BE LAST */ -+ /* Space is allocated for aType to hold at least 2*nField+1 entries: -+ ** nField slots for aType[] and nField+1 array slots for aOffset[] */ -+ u32 aType[FLEXARRAY]; /* Type values record decode. MUST BE LAST */ - }; - -+/* -+** The size (in bytes) of a VdbeCursor object that has an nField value of N -+** or less. The value of SZ_VDBECURSOR(n) is guaranteed to be a multiple -+** of 8. -+*/ -+#define SZ_VDBECURSOR(N) \ -+ (ROUND8(offsetof(VdbeCursor,aType)) + ((N)+1)*sizeof(u64)) -+ - /* Return true if P is a null-only cursor - */ - #define IsNullCursor(P) \ -@@ -23830,13 +23981,16 @@ struct sqlite3_context { - u8 enc; /* Encoding to use for results */ - u8 skipFlag; /* Skip accumulator loading if true */ - u16 argc; /* Number of arguments */ -- sqlite3_value *argv[1]; /* Argument set */ -+ sqlite3_value *argv[FLEXARRAY]; /* Argument set */ - }; - --/* A bitfield type for use inside of structures. Always follow with :N where --** N is the number of bits. -+/* -+** The size (in bytes) of an sqlite3_context object that holds N -+** argv[] arguments. - */ --typedef unsigned bft; /* Bit Field Type */ -+#define SZ_CONTEXT(N) \ -+ (offsetof(sqlite3_context,argv)+(N)*sizeof(sqlite3_value*)) -+ - - /* The ScanStatus object holds a single value for the - ** sqlite3_stmt_scanstatus() interface. -@@ -23897,7 +24051,7 @@ struct Vdbe { - i64 nStmtDefCons; /* Number of def. constraints when stmt started */ - i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ - Mem *aMem; /* The memory locations */ -- Mem **apArg; /* Arguments to currently executing user function */ -+ Mem **apArg; /* Arguments xUpdate and xFilter vtab methods */ - VdbeCursor **apCsr; /* One element of this array for each open cursor */ - Mem *aVar; /* Values for the OP_Variable opcode. */ - -@@ -23917,6 +24071,7 @@ struct Vdbe { - #ifdef SQLITE_DEBUG - int rcApp; /* errcode set by sqlite3_result_error_code() */ - u32 nWrite; /* Number of write operations that have occurred */ -+ int napArg; /* Size of the apArg[] array */ - #endif - u16 nResColumn; /* Number of columns in one row of the result set */ - u16 nResAlloc; /* Column slots allocated to aColName[] */ -@@ -23969,7 +24124,7 @@ struct PreUpdate { - VdbeCursor *pCsr; /* Cursor to read old values from */ - int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ - u8 *aRecord; /* old.* database record */ -- KeyInfo keyinfo; -+ KeyInfo *pKeyinfo; /* Key information */ - UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ - UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ - int iNewReg; /* Register for new.* values */ -@@ -23981,6 +24136,7 @@ struct PreUpdate { - Table *pTab; /* Schema object being updated */ - Index *pPk; /* PK index if pTab is WITHOUT ROWID */ - sqlite3_value **apDflt; /* Array of default values, if required */ -+ u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ - }; - - /* -@@ -24347,8 +24503,9 @@ SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ - nInit += countLookasideSlots(db->lookaside.pSmallInit); - nFree += countLookasideSlots(db->lookaside.pSmallFree); - #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ -- if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit; -- return db->lookaside.nSlot - (nInit+nFree); -+ assert( db->lookaside.nSlot >= nInit+nFree ); -+ if( pHighwater ) *pHighwater = (int)(db->lookaside.nSlot - nInit); -+ return (int)(db->lookaside.nSlot - (nInit+nFree)); - } - - /* -@@ -24401,7 +24558,7 @@ SQLITE_API int sqlite3_db_status( - assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); - assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); - *pCurrent = 0; -- *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; -+ *pHighwater = (int)db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT]; - if( resetFlag ){ - db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; - } -@@ -25913,7 +26070,7 @@ static int daysAfterMonday(DateTime *pDate){ - ** In other words, return the day of the week according - ** to this code: - ** --** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday -+** 0=Sunday, 1=Monday, 2=Tuesday, ..., 6=Saturday - */ - static int daysAfterSunday(DateTime *pDate){ - assert( pDate->validJD ); -@@ -30122,6 +30279,8 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ - - #ifdef __CYGWIN__ - # include -+# include /* amalgamator: dontcache */ -+# include /* amalgamator: dontcache */ - # include /* amalgamator: dontcache */ - #endif - -@@ -31516,17 +31675,17 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ - #define etPERCENT 7 /* Percent symbol. %% */ - #define etCHARX 8 /* Characters. %c */ - /* The rest are extensions, not normally found in printf() */ --#define etSQLESCAPE 9 /* Strings with '\'' doubled. %q */ --#define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '', -- NULL pointers replaced by SQL NULL. %Q */ --#define etTOKEN 11 /* a pointer to a Token structure */ --#define etSRCITEM 12 /* a pointer to a SrcItem */ --#define etPOINTER 13 /* The %p conversion */ --#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */ --#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ --#define etDECIMAL 16 /* %d or %u, but not %x, %o */ -+#define etESCAPE_q 9 /* Strings with '\'' doubled. %q */ -+#define etESCAPE_Q 10 /* Strings with '\'' doubled and enclosed in '', -+ NULL pointers replaced by SQL NULL. %Q */ -+#define etTOKEN 11 /* a pointer to a Token structure */ -+#define etSRCITEM 12 /* a pointer to a SrcItem */ -+#define etPOINTER 13 /* The %p conversion */ -+#define etESCAPE_w 14 /* %w -> Strings with '\"' doubled */ -+#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ -+#define etDECIMAL 16 /* %d or %u, but not %x, %o */ - --#define etINVALID 17 /* Any unrecognized conversion type */ -+#define etINVALID 17 /* Any unrecognized conversion type */ - - - /* -@@ -31565,9 +31724,9 @@ static const et_info fmtinfo[] = { - { 's', 0, 4, etSTRING, 0, 0 }, - { 'g', 0, 1, etGENERIC, 30, 0 }, - { 'z', 0, 4, etDYNSTRING, 0, 0 }, -- { 'q', 0, 4, etSQLESCAPE, 0, 0 }, -- { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, -- { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, -+ { 'q', 0, 4, etESCAPE_q, 0, 0 }, -+ { 'Q', 0, 4, etESCAPE_Q, 0, 0 }, -+ { 'w', 0, 4, etESCAPE_w, 0, 0 }, - { 'c', 0, 0, etCHARX, 0, 0 }, - { 'o', 8, 0, etRADIX, 0, 2 }, - { 'u', 10, 0, etDECIMAL, 0, 0 }, -@@ -32164,25 +32323,7 @@ SQLITE_API void sqlite3_str_vappendf( - } - }else{ - unsigned int ch = va_arg(ap,unsigned int); -- if( ch<0x00080 ){ -- buf[0] = ch & 0xff; -- length = 1; -- }else if( ch<0x00800 ){ -- buf[0] = 0xc0 + (u8)((ch>>6)&0x1f); -- buf[1] = 0x80 + (u8)(ch & 0x3f); -- length = 2; -- }else if( ch<0x10000 ){ -- buf[0] = 0xe0 + (u8)((ch>>12)&0x0f); -- buf[1] = 0x80 + (u8)((ch>>6) & 0x3f); -- buf[2] = 0x80 + (u8)(ch & 0x3f); -- length = 3; -- }else{ -- buf[0] = 0xf0 + (u8)((ch>>18) & 0x07); -- buf[1] = 0x80 + (u8)((ch>>12) & 0x3f); -- buf[2] = 0x80 + (u8)((ch>>6) & 0x3f); -- buf[3] = 0x80 + (u8)(ch & 0x3f); -- length = 4; -- } -+ length = sqlite3AppendOneUtf8Character(buf, ch); - } - if( precision>1 ){ - i64 nPrior = 1; -@@ -32262,22 +32403,31 @@ SQLITE_API void sqlite3_str_vappendf( - while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; - } - break; -- case etSQLESCAPE: /* %q: Escape ' characters */ -- case etSQLESCAPE2: /* %Q: Escape ' and enclose in '...' */ -- case etSQLESCAPE3: { /* %w: Escape " characters */ -+ case etESCAPE_q: /* %q: Escape ' characters */ -+ case etESCAPE_Q: /* %Q: Escape ' and enclose in '...' */ -+ case etESCAPE_w: { /* %w: Escape " characters */ - i64 i, j, k, n; -- int needQuote, isnull; -+ int needQuote = 0; - char ch; -- char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */ - char *escarg; -+ char q; - - if( bArgList ){ - escarg = getTextArg(pArgList); - }else{ - escarg = va_arg(ap,char*); - } -- isnull = escarg==0; -- if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); -+ if( escarg==0 ){ -+ escarg = (xtype==etESCAPE_Q ? "NULL" : "(NULL)"); -+ }else if( xtype==etESCAPE_Q ){ -+ needQuote = 1; -+ } -+ if( xtype==etESCAPE_w ){ -+ q = '"'; -+ flag_alternateform = 0; -+ }else{ -+ q = '\''; -+ } - /* For %q, %Q, and %w, the precision is the number of bytes (or - ** characters if the ! flags is present) to use from the input. - ** Because of the extra quoting characters inserted, the number -@@ -32290,7 +32440,30 @@ SQLITE_API void sqlite3_str_vappendf( - while( (escarg[i+1]&0xc0)==0x80 ){ i++; } - } - } -- needQuote = !isnull && xtype==etSQLESCAPE2; -+ if( flag_alternateform ){ -+ /* For %#q, do unistr()-style backslash escapes for -+ ** all control characters, and for backslash itself. -+ ** For %#Q, do the same but only if there is at least -+ ** one control character. */ -+ u32 nBack = 0; -+ u32 nCtrl = 0; -+ for(k=0; ketBUFSIZE ){ - bufpt = zExtra = printfTempBuf(pAccum, n); -@@ -32299,13 +32472,41 @@ SQLITE_API void sqlite3_str_vappendf( - bufpt = buf; - } - j = 0; -- if( needQuote ) bufpt[j++] = q; -+ if( needQuote ){ -+ if( needQuote==2 ){ -+ memcpy(&bufpt[j], "unistr('", 8); -+ j += 8; -+ }else{ -+ bufpt[j++] = '\''; -+ } -+ } - k = i; -- for(i=0; i=0x10 ? '1' : '0'; -+ bufpt[j++] = "0123456789abcdef"[ch&0xf]; -+ } -+ } -+ }else{ -+ for(i=0; imxAlloc>0 && !isMalloced(p) ); -- zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); -+ zText = sqlite3DbMallocRaw(p->db, 1+(u64)p->nChar ); - if( zText ){ - memcpy(zText, p->zText, p->nChar+1); - p->printfFlags |= SQLITE_PRINTF_MALLOCED; -@@ -32793,6 +32994,15 @@ SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ - return zBuf; - } - -+/* Maximum size of an sqlite3_log() message. */ -+#if defined(SQLITE_MAX_LOG_MESSAGE) -+ /* Leave the definition as supplied */ -+#elif SQLITE_PRINT_BUF_SIZE*10>10000 -+# define SQLITE_MAX_LOG_MESSAGE 10000 -+#else -+# define SQLITE_MAX_LOG_MESSAGE (SQLITE_PRINT_BUF_SIZE*10) -+#endif -+ - /* - ** This is the routine that actually formats the sqlite3_log() message. - ** We house it in a separate routine from sqlite3_log() to avoid using -@@ -32809,7 +33019,7 @@ SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ - */ - static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ - StrAccum acc; /* String accumulator */ -- char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ -+ char zMsg[SQLITE_MAX_LOG_MESSAGE]; /* Complete log message */ - - sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); - sqlite3_str_vappendf(&acc, zFormat, ap); -@@ -34804,6 +35014,35 @@ static const unsigned char sqlite3Utf8Trans1[] = { - } \ - } - -+/* -+** Write a single UTF8 character whose value is v into the -+** buffer starting at zOut. zOut must be sized to hold at -+** least four bytes. Return the number of bytes needed -+** to encode the new character. -+*/ -+SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ -+ if( v<0x00080 ){ -+ zOut[0] = (u8)(v & 0xff); -+ return 1; -+ } -+ if( v<0x00800 ){ -+ zOut[0] = 0xc0 + (u8)((v>>6) & 0x1f); -+ zOut[1] = 0x80 + (u8)(v & 0x3f); -+ return 2; -+ } -+ if( v<0x10000 ){ -+ zOut[0] = 0xe0 + (u8)((v>>12) & 0x0f); -+ zOut[1] = 0x80 + (u8)((v>>6) & 0x3f); -+ zOut[2] = 0x80 + (u8)(v & 0x3f); -+ return 3; -+ } -+ zOut[0] = 0xf0 + (u8)((v>>18) & 0x07); -+ zOut[1] = 0x80 + (u8)((v>>12) & 0x3f); -+ zOut[2] = 0x80 + (u8)((v>>6) & 0x3f); -+ zOut[3] = 0x80 + (u8)(v & 0x3f); -+ return 4; -+} -+ - /* - ** Translate a single UTF-8 character. Return the unicode value. - ** -@@ -35225,7 +35464,7 @@ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){ - int n = 0; - - if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; -- while( n=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; -@@ -36400,7 +36639,11 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou - } - p->z = &p->zBuf[i+1]; - assert( i+p->n < sizeof(p->zBuf) ); -- while( ALWAYS(p->n>0) && p->z[p->n-1]=='0' ){ p->n--; } -+ assert( p->n>0 ); -+ while( p->z[p->n-1]=='0' ){ -+ p->n--; -+ assert( p->n>0 ); -+ } - } - - /* -@@ -36905,7 +37148,7 @@ SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ - } - - /* --** Compute the absolute value of a 32-bit signed integer, of possible. Or -+** Compute the absolute value of a 32-bit signed integer, if possible. Or - ** if the integer has a value of -2147483648, return +2147483647 - */ - SQLITE_PRIVATE int sqlite3AbsInt32(int x){ -@@ -37186,12 +37429,19 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){ - */ - static unsigned int strHash(const char *z){ - unsigned int h = 0; -- unsigned char c; -- while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/ -+ while( z[0] ){ /*OPTIMIZATION-IF-TRUE*/ - /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). - ** 0x9e3779b1 is 2654435761 which is the closest prime number to -- ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ -- h += sqlite3UpperToLower[c]; -+ ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. -+ ** -+ ** Only bits 0xdf for ASCII and bits 0xbf for EBCDIC each octet are -+ ** hashed since the omitted bits determine the upper/lower case difference. -+ */ -+#ifdef SQLITE_EBCDIC -+ h += 0xbf & (unsigned char)*(z++); -+#else -+ h += 0xdf & (unsigned char)*(z++); -+#endif - h *= 0x9e3779b1; - } - return h; -@@ -37264,9 +37514,8 @@ static int rehash(Hash *pH, unsigned int new_size){ - pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); - memset(new_ht, 0, new_size*sizeof(struct _ht)); - for(elem=pH->first, pH->first=0; elem; elem = next_elem){ -- unsigned int h = strHash(elem->pKey) % new_size; - next_elem = elem->next; -- insertElement(pH, &new_ht[h], elem); -+ insertElement(pH, &new_ht[elem->h % new_size], elem); - } - return 1; - } -@@ -37284,23 +37533,22 @@ static HashElem *findElementWithHash( - HashElem *elem; /* Used to loop thru the element list */ - unsigned int count; /* Number of elements left to test */ - unsigned int h; /* The computed hash */ -- static HashElem nullElement = { 0, 0, 0, 0 }; -+ static HashElem nullElement = { 0, 0, 0, 0, 0 }; - -+ h = strHash(pKey); - if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ - struct _ht *pEntry; -- h = strHash(pKey) % pH->htsize; -- pEntry = &pH->ht[h]; -+ pEntry = &pH->ht[h % pH->htsize]; - elem = pEntry->chain; - count = pEntry->count; - }else{ -- h = 0; - elem = pH->first; - count = pH->count; - } - if( pHash ) *pHash = h; - while( count ){ - assert( elem!=0 ); -- if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ -+ if( h==elem->h && sqlite3StrICmp(elem->pKey,pKey)==0 ){ - return elem; - } - elem = elem->next; -@@ -37312,10 +37560,9 @@ static HashElem *findElementWithHash( - /* Remove a single entry from the hash table given a pointer to that - ** element and a hash on the element's key. - */ --static void removeElementGivenHash( -+static void removeElement( - Hash *pH, /* The pH containing "elem" */ -- HashElem* elem, /* The element to be removed from the pH */ -- unsigned int h /* Hash value for the element */ -+ HashElem *elem /* The element to be removed from the pH */ - ){ - struct _ht *pEntry; - if( elem->prev ){ -@@ -37327,7 +37574,7 @@ static void removeElementGivenHash( - elem->next->prev = elem->prev; - } - if( pH->ht ){ -- pEntry = &pH->ht[h]; -+ pEntry = &pH->ht[elem->h % pH->htsize]; - if( pEntry->chain==elem ){ - pEntry->chain = elem->next; - } -@@ -37378,7 +37625,7 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ - if( elem->data ){ - void *old_data = elem->data; - if( data==0 ){ -- removeElementGivenHash(pH,elem,h); -+ removeElement(pH,elem); - }else{ - elem->data = data; - elem->pKey = pKey; -@@ -37389,15 +37636,13 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ - new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); - if( new_elem==0 ) return data; - new_elem->pKey = pKey; -+ new_elem->h = h; - new_elem->data = data; - pH->count++; -- if( pH->count>=10 && pH->count > 2*pH->htsize ){ -- if( rehash(pH, pH->count*2) ){ -- assert( pH->htsize>0 ); -- h = strHash(pKey) % pH->htsize; -- } -+ if( pH->count>=5 && pH->count > 2*pH->htsize ){ -+ rehash(pH, pH->count*3); - } -- insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem); -+ insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem); - return 0; - } - -@@ -38880,6 +39125,7 @@ struct unixFile { - #endif - #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - unsigned iBusyTimeout; /* Wait this many millisec on locks */ -+ int bBlockOnConnect; /* True to block for SHARED locks */ - #endif - #if OS_VXWORKS - struct vxworksFileId *pId; /* Unique file ID */ -@@ -40273,6 +40519,13 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ - rc = 0; - } - }else{ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ if( pFile->bBlockOnConnect && pLock->l_type==F_RDLCK -+ && pLock->l_start==SHARED_FIRST && pLock->l_len==SHARED_SIZE -+ ){ -+ rc = osFcntl(pFile->h, F_SETLKW, pLock); -+ }else -+#endif - rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); - } - return rc; -@@ -42634,8 +42887,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ - #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - case SQLITE_FCNTL_LOCK_TIMEOUT: { - int iOld = pFile->iBusyTimeout; -+ int iNew = *(int*)pArg; - #if SQLITE_ENABLE_SETLK_TIMEOUT==1 -- pFile->iBusyTimeout = *(int*)pArg; -+ pFile->iBusyTimeout = iNew<0 ? 0x7FFFFFFF : (unsigned)iNew; - #elif SQLITE_ENABLE_SETLK_TIMEOUT==2 - pFile->iBusyTimeout = !!(*(int*)pArg); - #else -@@ -42644,7 +42898,12 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ - *(int*)pArg = iOld; - return SQLITE_OK; - } --#endif -+ case SQLITE_FCNTL_BLOCK_ON_CONNECT: { -+ int iNew = *(int*)pArg; -+ pFile->bBlockOnConnect = iNew; -+ return SQLITE_OK; -+ } -+#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ - #if SQLITE_MAX_MMAP_SIZE>0 - case SQLITE_FCNTL_MMAP_SIZE: { - i64 newLimit = *(i64*)pArg; -@@ -43617,21 +43876,20 @@ static int unixShmLock( - /* Check that, if this to be a blocking lock, no locks that occur later - ** in the following list than the lock being obtained are already held: - ** -- ** 1. Checkpointer lock (ofst==1). -- ** 2. Write lock (ofst==0). -- ** 3. Read locks (ofst>=3 && ofst=3 && ofstexclMask|p->sharedMask); - assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( -- (ofst!=2) /* not RECOVER */ -+ (ofst!=2 || lockMask==0) - && (ofst!=1 || lockMask==0 || lockMask==2) - && (ofst!=0 || lockMask<3) - && (ofst<3 || lockMask<(1<iBusyTimeout -+#else -+# define winFileBusyTimeout(pDbFd) 0 -+#endif -+ - /* - ** The winVfsAppData structure is used for the pAppData member for all of the - ** Win32 VFS variants. -@@ -47477,7 +47745,7 @@ static struct win_syscall { - { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, - #endif - --#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \ -+#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(const FILETIME*, \ - LPFILETIME))aSyscall[11].pCurrent) - - #if SQLITE_OS_WINCE -@@ -47486,7 +47754,7 @@ static struct win_syscall { - { "FileTimeToSystemTime", (SYSCALL)0, 0 }, - #endif - --#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \ -+#define osFileTimeToSystemTime ((BOOL(WINAPI*)(const FILETIME*, \ - LPSYSTEMTIME))aSyscall[12].pCurrent) - - { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, -@@ -47592,6 +47860,12 @@ static struct win_syscall { - #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ - LPWSTR*))aSyscall[25].pCurrent) - -+/* -+** For GetLastError(), MSDN says: -+** -+** Minimum supported client: Windows XP [desktop apps | UWP apps] -+** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] -+*/ - { "GetLastError", (SYSCALL)GetLastError, 0 }, - - #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) -@@ -47760,7 +48034,7 @@ static struct win_syscall { - { "LockFile", (SYSCALL)0, 0 }, - #endif - --#ifndef osLockFile -+#if !defined(osLockFile) && defined(SQLITE_WIN32_HAS_ANSI) - #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - DWORD))aSyscall[47].pCurrent) - #endif -@@ -47824,7 +48098,7 @@ static struct win_syscall { - - { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, - --#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \ -+#define osSystemTimeToFileTime ((BOOL(WINAPI*)(const SYSTEMTIME*, \ - LPFILETIME))aSyscall[56].pCurrent) - - #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT -@@ -47833,7 +48107,7 @@ static struct win_syscall { - { "UnlockFile", (SYSCALL)0, 0 }, - #endif - --#ifndef osUnlockFile -+#if !defined(osUnlockFile) && defined(SQLITE_WIN32_HAS_ANSI) - #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - DWORD))aSyscall[57].pCurrent) - #endif -@@ -47874,11 +48148,13 @@ static struct win_syscall { - #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ - DWORD,DWORD))aSyscall[62].pCurrent) - --#if !SQLITE_OS_WINRT -+/* -+** For WaitForSingleObject(), MSDN says: -+** -+** Minimum supported client: Windows XP [desktop apps | UWP apps] -+** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] -+*/ - { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, --#else -- { "WaitForSingleObject", (SYSCALL)0, 0 }, --#endif - - #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ - DWORD))aSyscall[63].pCurrent) -@@ -48025,6 +48301,97 @@ static struct win_syscall { - #define osFlushViewOfFile \ - ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) - -+/* -+** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CreateEvent() -+** to implement blocking locks with timeouts. MSDN says: -+** -+** Minimum supported client: Windows XP [desktop apps | UWP apps] -+** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] -+*/ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ { "CreateEvent", (SYSCALL)CreateEvent, 0 }, -+#else -+ { "CreateEvent", (SYSCALL)0, 0 }, -+#endif -+ -+#define osCreateEvent ( \ -+ (HANDLE(WINAPI*) (LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR)) \ -+ aSyscall[80].pCurrent \ -+) -+ -+/* -+** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CancelIo() -+** for the case where a timeout expires and a lock request must be -+** cancelled. -+** -+** Minimum supported client: Windows XP [desktop apps | UWP apps] -+** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] -+*/ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ { "CancelIo", (SYSCALL)CancelIo, 0 }, -+#else -+ { "CancelIo", (SYSCALL)0, 0 }, -+#endif -+ -+#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[81].pCurrent) -+ -+#if defined(SQLITE_WIN32_HAS_WIDE) && defined(_WIN32) -+ { "GetModuleHandleW", (SYSCALL)GetModuleHandleW, 0 }, -+#else -+ { "GetModuleHandleW", (SYSCALL)0, 0 }, -+#endif -+ -+#define osGetModuleHandleW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[82].pCurrent) -+ -+#ifndef _WIN32 -+ { "getenv", (SYSCALL)getenv, 0 }, -+#else -+ { "getenv", (SYSCALL)0, 0 }, -+#endif -+ -+#define osGetenv ((const char *(*)(const char *))aSyscall[83].pCurrent) -+ -+#ifndef _WIN32 -+ { "getcwd", (SYSCALL)getcwd, 0 }, -+#else -+ { "getcwd", (SYSCALL)0, 0 }, -+#endif -+ -+#define osGetcwd ((char*(*)(char*,size_t))aSyscall[84].pCurrent) -+ -+#ifndef _WIN32 -+ { "readlink", (SYSCALL)readlink, 0 }, -+#else -+ { "readlink", (SYSCALL)0, 0 }, -+#endif -+ -+#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[85].pCurrent) -+ -+#ifndef _WIN32 -+ { "lstat", (SYSCALL)lstat, 0 }, -+#else -+ { "lstat", (SYSCALL)0, 0 }, -+#endif -+ -+#define osLstat ((int(*)(const char*,struct stat*))aSyscall[86].pCurrent) -+ -+#ifndef _WIN32 -+ { "__errno", (SYSCALL)__errno, 0 }, -+#else -+ { "__errno", (SYSCALL)0, 0 }, -+#endif -+ -+#define osErrno (*((int*(*)(void))aSyscall[87].pCurrent)()) -+ -+#ifndef _WIN32 -+ { "cygwin_conv_path", (SYSCALL)cygwin_conv_path, 0 }, -+#else -+ { "cygwin_conv_path", (SYSCALL)0, 0 }, -+#endif -+ -+#define osCygwin_conv_path ((size_t(*)(unsigned int, \ -+ const void *, void *, size_t))aSyscall[88].pCurrent) -+ - }; /* End of the overrideable system calls */ - - /* -@@ -48198,6 +48565,7 @@ SQLITE_API int sqlite3_win32_reset_heap(){ - } - #endif /* SQLITE_WIN32_MALLOC */ - -+#ifdef _WIN32 - /* - ** This function outputs the specified (ANSI) string to the Win32 debugger - ** (if available). -@@ -48240,6 +48608,7 @@ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ - } - #endif - } -+#endif /* _WIN32 */ - - /* - ** The following routine suspends the current thread for at least ms -@@ -48323,7 +48692,9 @@ SQLITE_API int sqlite3_win32_is_nt(void){ - } - return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; - #elif SQLITE_TEST -- return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; -+ return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2 -+ || osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 -+ ; - #else - /* - ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are -@@ -48538,6 +48909,7 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){ - } - #endif /* SQLITE_WIN32_MALLOC */ - -+#ifdef _WIN32 - /* - ** Convert a UTF-8 string to Microsoft Unicode. - ** -@@ -48563,6 +48935,7 @@ static LPWSTR winUtf8ToUnicode(const char *zText){ - } - return zWideText; - } -+#endif /* _WIN32 */ - - /* - ** Convert a Microsoft Unicode string to UTF-8. -@@ -48597,28 +48970,29 @@ static char *winUnicodeToUtf8(LPCWSTR zWideText){ - ** Space to hold the returned string is obtained from sqlite3_malloc(). - */ - static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ -- int nByte; -+ int nWideChar; - LPWSTR zMbcsText; - int codepage = useAnsi ? CP_ACP : CP_OEMCP; - -- nByte = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, -- 0)*sizeof(WCHAR); -- if( nByte==0 ){ -+ nWideChar = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, -+ 0); -+ if( nWideChar==0 ){ - return 0; - } -- zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) ); -+ zMbcsText = sqlite3MallocZero( nWideChar*sizeof(WCHAR) ); - if( zMbcsText==0 ){ - return 0; - } -- nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, -- nByte); -- if( nByte==0 ){ -+ nWideChar = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, -+ nWideChar); -+ if( nWideChar==0 ){ - sqlite3_free(zMbcsText); - zMbcsText = 0; - } - return zMbcsText; - } - -+#ifdef _WIN32 - /* - ** Convert a Microsoft Unicode string to a multi-byte character string, - ** using the ANSI or OEM code page. -@@ -48646,6 +49020,7 @@ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ - } - return zText; - } -+#endif /* _WIN32 */ - - /* - ** Convert a multi-byte character string to UTF-8. -@@ -48665,6 +49040,7 @@ static char *winMbcsToUtf8(const char *zText, int useAnsi){ - return zTextUtf8; - } - -+#ifdef _WIN32 - /* - ** Convert a UTF-8 string to a multi-byte character string. - ** -@@ -48714,6 +49090,7 @@ SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ - #endif - return winUnicodeToUtf8(zWideText); - } -+#endif /* _WIN32 */ - - /* - ** This is a public wrapper for the winMbcsToUtf8() function. -@@ -48731,6 +49108,7 @@ SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ - return winMbcsToUtf8(zText, osAreFileApisANSI()); - } - -+#ifdef _WIN32 - /* - ** This is a public wrapper for the winMbcsToUtf8() function. - */ -@@ -48855,6 +49233,7 @@ SQLITE_API int sqlite3_win32_set_directory( - ){ - return sqlite3_win32_set_directory16(type, zValue); - } -+#endif /* _WIN32 */ - - /* - ** The return value of winGetLastErrorMsg -@@ -49403,13 +49782,98 @@ static BOOL winLockFile( - ovlp.Offset = offsetLow; - ovlp.OffsetHigh = offsetHigh; - return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); -+#ifdef SQLITE_WIN32_HAS_ANSI - }else{ - return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, - numBytesHigh); -+#endif - } - #endif - } - -+/* -+** Lock a region of nByte bytes starting at offset offset of file hFile. -+** Take an EXCLUSIVE lock if parameter bExclusive is true, or a SHARED lock -+** otherwise. If nMs is greater than zero and the lock cannot be obtained -+** immediately, block for that many ms before giving up. -+** -+** This function returns SQLITE_OK if the lock is obtained successfully. If -+** some other process holds the lock, SQLITE_BUSY is returned if nMs==0, or -+** SQLITE_BUSY_TIMEOUT otherwise. Or, if an error occurs, SQLITE_IOERR. -+*/ -+static int winHandleLockTimeout( -+ HANDLE hFile, -+ DWORD offset, -+ DWORD nByte, -+ int bExcl, -+ DWORD nMs -+){ -+ DWORD flags = LOCKFILE_FAIL_IMMEDIATELY | (bExcl?LOCKFILE_EXCLUSIVE_LOCK:0); -+ int rc = SQLITE_OK; -+ BOOL ret; -+ -+ if( !osIsNT() ){ -+ ret = winLockFile(&hFile, flags, offset, 0, nByte, 0); -+ }else{ -+ OVERLAPPED ovlp; -+ memset(&ovlp, 0, sizeof(OVERLAPPED)); -+ ovlp.Offset = offset; -+ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ if( nMs!=0 ){ -+ flags &= ~LOCKFILE_FAIL_IMMEDIATELY; -+ } -+ ovlp.hEvent = osCreateEvent(NULL, TRUE, FALSE, NULL); -+ if( ovlp.hEvent==NULL ){ -+ return SQLITE_IOERR_LOCK; -+ } -+#endif -+ -+ ret = osLockFileEx(hFile, flags, 0, nByte, 0, &ovlp); -+ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ /* If SQLITE_ENABLE_SETLK_TIMEOUT is defined, then the file-handle was -+ ** opened with FILE_FLAG_OVERHEAD specified. In this case, the call to -+ ** LockFileEx() may fail because the request is still pending. This can -+ ** happen even if LOCKFILE_FAIL_IMMEDIATELY was specified. -+ ** -+ ** If nMs is 0, then LOCKFILE_FAIL_IMMEDIATELY was set in the flags -+ ** passed to LockFileEx(). In this case, if the operation is pending, -+ ** block indefinitely until it is finished. -+ ** -+ ** Otherwise, wait for up to nMs ms for the operation to finish. nMs -+ ** may be set to INFINITE. -+ */ -+ if( !ret && GetLastError()==ERROR_IO_PENDING ){ -+ DWORD nDelay = (nMs==0 ? INFINITE : nMs); -+ DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); -+ if( res==WAIT_OBJECT_0 ){ -+ ret = TRUE; -+ }else if( res==WAIT_TIMEOUT ){ -+#if SQLITE_ENABLE_SETLK_TIMEOUT==1 -+ rc = SQLITE_BUSY_TIMEOUT; -+#else -+ rc = SQLITE_BUSY; -+#endif -+ }else{ -+ /* Some other error has occurred */ -+ rc = SQLITE_IOERR_LOCK; -+ } -+ -+ /* If it is still pending, cancel the LockFileEx() call. */ -+ osCancelIo(hFile); -+ } -+ -+ osCloseHandle(ovlp.hEvent); -+#endif -+ } -+ -+ if( rc==SQLITE_OK && !ret ){ -+ rc = SQLITE_BUSY; -+ } -+ return rc; -+} -+ - /* - ** Unlock a file region. - */ -@@ -49434,13 +49898,23 @@ static BOOL winUnlockFile( - ovlp.Offset = offsetLow; - ovlp.OffsetHigh = offsetHigh; - return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); -+#ifdef SQLITE_WIN32_HAS_ANSI - }else{ - return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, - numBytesHigh); -+#endif - } - #endif - } - -+/* -+** Remove an nByte lock starting at offset iOff from HANDLE h. -+*/ -+static int winHandleUnlock(HANDLE h, int iOff, int nByte){ -+ BOOL ret = winUnlockFile(&h, iOff, 0, nByte, 0); -+ return (ret ? SQLITE_OK : SQLITE_IOERR_UNLOCK); -+} -+ - /***************************************************************************** - ** The next group of routines implement the I/O methods specified - ** by the sqlite3_io_methods object. -@@ -49454,66 +49928,70 @@ static BOOL winUnlockFile( - #endif - - /* --** Move the current position of the file handle passed as the first --** argument to offset iOffset within the file. If successful, return 0. --** Otherwise, set pFile->lastErrno and return non-zero. -+** Seek the file handle h to offset nByte of the file. -+** -+** If successful, return SQLITE_OK. Or, if an error occurs, return an SQLite -+** error code. - */ --static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ -+static int winHandleSeek(HANDLE h, sqlite3_int64 iOffset){ -+ int rc = SQLITE_OK; /* Return value */ -+ - #if !SQLITE_OS_WINRT - LONG upperBits; /* Most sig. 32 bits of new offset */ - LONG lowerBits; /* Least sig. 32 bits of new offset */ - DWORD dwRet; /* Value returned by SetFilePointer() */ -- DWORD lastErrno; /* Value returned by GetLastError() */ -- -- OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset)); - - upperBits = (LONG)((iOffset>>32) & 0x7fffffff); - lowerBits = (LONG)(iOffset & 0xffffffff); - -+ dwRet = osSetFilePointer(h, lowerBits, &upperBits, FILE_BEGIN); -+ - /* API oddity: If successful, SetFilePointer() returns a dword - ** containing the lower 32-bits of the new file-offset. Or, if it fails, - ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, - ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine - ** whether an error has actually occurred, it is also necessary to call -- ** GetLastError(). -- */ -- dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); -- -- if( (dwRet==INVALID_SET_FILE_POINTER -- && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ -- pFile->lastErrno = lastErrno; -- winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, -- "winSeekFile", pFile->zPath); -- OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); -- return 1; -+ ** GetLastError(). */ -+ if( dwRet==INVALID_SET_FILE_POINTER ){ -+ DWORD lastErrno = osGetLastError(); -+ if( lastErrno!=NO_ERROR ){ -+ rc = SQLITE_IOERR_SEEK; -+ } - } -- -- OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); -- return 0; - #else -- /* -- ** Same as above, except that this implementation works for WinRT. -- */ -- -+ /* This implementation works for WinRT. */ - LARGE_INTEGER x; /* The new offset */ - BOOL bRet; /* Value returned by SetFilePointerEx() */ - - x.QuadPart = iOffset; -- bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); -+ bRet = osSetFilePointerEx(h, x, 0, FILE_BEGIN); - - if(!bRet){ -- pFile->lastErrno = osGetLastError(); -- winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, -- "winSeekFile", pFile->zPath); -- OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); -- return 1; -+ rc = SQLITE_IOERR_SEEK; - } -- -- OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); -- return 0; - #endif -+ -+ OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset, sqlite3ErrName(rc))); -+ return rc; - } - -+/* -+** Move the current position of the file handle passed as the first -+** argument to offset iOffset within the file. If successful, return 0. -+** Otherwise, set pFile->lastErrno and return non-zero. -+*/ -+static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ -+ int rc; -+ -+ rc = winHandleSeek(pFile->h, iOffset); -+ if( rc!=SQLITE_OK ){ -+ pFile->lastErrno = osGetLastError(); -+ winLogError(rc, pFile->lastErrno, "winSeekFile", pFile->zPath); -+ } -+ return rc; -+} -+ -+ - #if SQLITE_MAX_MMAP_SIZE>0 - /* Forward references to VFS helper methods used for memory mapped files */ - static int winMapfile(winFile*, sqlite3_int64); -@@ -49773,6 +50251,60 @@ static int winWrite( - return SQLITE_OK; - } - -+/* -+** Truncate the file opened by handle h to nByte bytes in size. -+*/ -+static int winHandleTruncate(HANDLE h, sqlite3_int64 nByte){ -+ int rc = SQLITE_OK; /* Return code */ -+ rc = winHandleSeek(h, nByte); -+ if( rc==SQLITE_OK ){ -+ if( 0==osSetEndOfFile(h) ){ -+ rc = SQLITE_IOERR_TRUNCATE; -+ } -+ } -+ return rc; -+} -+ -+/* -+** Determine the size in bytes of the file opened by the handle passed as -+** the first argument. -+*/ -+static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){ -+ int rc = SQLITE_OK; -+ -+#if SQLITE_OS_WINRT -+ FILE_STANDARD_INFO info; -+ BOOL b; -+ b = osGetFileInformationByHandleEx(h, FileStandardInfo, &info, sizeof(info)); -+ if( b ){ -+ *pnByte = info.EndOfFile.QuadPart; -+ }else{ -+ rc = SQLITE_IOERR_FSTAT; -+ } -+#else -+ DWORD upperBits = 0; -+ DWORD lowerBits = 0; -+ -+ assert( pnByte ); -+ lowerBits = osGetFileSize(h, &upperBits); -+ *pnByte = (((sqlite3_int64)upperBits)<<32) + lowerBits; -+ if( lowerBits==INVALID_FILE_SIZE && osGetLastError()!=NO_ERROR ){ -+ rc = SQLITE_IOERR_FSTAT; -+ } -+#endif -+ -+ return rc; -+} -+ -+/* -+** Close the handle passed as the only argument. -+*/ -+static void winHandleClose(HANDLE h){ -+ if( h!=INVALID_HANDLE_VALUE ){ -+ osCloseHandle(h); -+ } -+} -+ - /* - ** Truncate an open file to a specified size - */ -@@ -50028,8 +50560,9 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ - ** Different API routines are called depending on whether or not this - ** is Win9x or WinNT. - */ --static int winGetReadLock(winFile *pFile){ -+static int winGetReadLock(winFile *pFile, int bBlock){ - int res; -+ DWORD mask = ~(bBlock ? LOCKFILE_FAIL_IMMEDIATELY : 0); - OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); - if( osIsNT() ){ - #if SQLITE_OS_WINCE -@@ -50039,7 +50572,7 @@ static int winGetReadLock(winFile *pFile){ - */ - res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); - #else -- res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, -+ res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS&mask, SHARED_FIRST, 0, - SHARED_SIZE, 0); - #endif - } -@@ -50048,7 +50581,7 @@ static int winGetReadLock(winFile *pFile){ - int lk; - sqlite3_randomness(sizeof(lk), &lk); - pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); -- res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, -+ res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS&mask, - SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); - } - #endif -@@ -50143,46 +50676,62 @@ static int winLock(sqlite3_file *id, int locktype){ - assert( locktype!=PENDING_LOCK ); - assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); - -- /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or -+ /* Lock the PENDING_LOCK byte if we need to acquire an EXCLUSIVE lock or - ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of - ** the PENDING_LOCK byte is temporary. - */ - newLocktype = pFile->locktype; -- if( pFile->locktype==NO_LOCK -- || (locktype==EXCLUSIVE_LOCK && pFile->locktype<=RESERVED_LOCK) -+ if( locktype==SHARED_LOCK -+ || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) - ){ - int cnt = 3; -- while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, -- PENDING_BYTE, 0, 1, 0))==0 ){ -+ -+ /* Flags for the LockFileEx() call. This should be an exclusive lock if -+ ** this call is to obtain EXCLUSIVE, or a shared lock if this call is to -+ ** obtain SHARED. */ -+ int flags = LOCKFILE_FAIL_IMMEDIATELY; -+ if( locktype==EXCLUSIVE_LOCK ){ -+ flags |= LOCKFILE_EXCLUSIVE_LOCK; -+ } -+ while( cnt>0 ){ - /* Try 3 times to get the pending lock. This is needed to work - ** around problems caused by indexing and/or anti-virus software on - ** Windows systems. -+ ** - ** If you are using this code as a model for alternative VFSes, do not -- ** copy this retry logic. It is a hack intended for Windows only. -- */ -+ ** copy this retry logic. It is a hack intended for Windows only. */ -+ res = winLockFile(&pFile->h, flags, PENDING_BYTE, 0, 1, 0); -+ if( res ) break; -+ - lastErrno = osGetLastError(); - OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", -- pFile->h, cnt, res)); -+ pFile->h, cnt, res -+ )); -+ - if( lastErrno==ERROR_INVALID_HANDLE ){ - pFile->lastErrno = lastErrno; - rc = SQLITE_IOERR_LOCK; - OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", -- pFile->h, cnt, sqlite3ErrName(rc))); -+ pFile->h, cnt, sqlite3ErrName(rc) -+ )); - return rc; - } -- if( cnt ) sqlite3_win32_sleep(1); -+ -+ cnt--; -+ if( cnt>0 ) sqlite3_win32_sleep(1); - } - gotPendingLock = res; -- if( !res ){ -- lastErrno = osGetLastError(); -- } - } - - /* Acquire a shared lock - */ - if( locktype==SHARED_LOCK && res ){ - assert( pFile->locktype==NO_LOCK ); -- res = winGetReadLock(pFile); -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ res = winGetReadLock(pFile, pFile->bBlockOnConnect); -+#else -+ res = winGetReadLock(pFile, 0); -+#endif - if( res ){ - newLocktype = SHARED_LOCK; - }else{ -@@ -50220,7 +50769,7 @@ static int winLock(sqlite3_file *id, int locktype){ - newLocktype = EXCLUSIVE_LOCK; - }else{ - lastErrno = osGetLastError(); -- winGetReadLock(pFile); -+ winGetReadLock(pFile, 0); - } - } - -@@ -50300,7 +50849,7 @@ static int winUnlock(sqlite3_file *id, int locktype){ - type = pFile->locktype; - if( type>=EXCLUSIVE_LOCK ){ - winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); -- if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ -+ if( locktype==SHARED_LOCK && !winGetReadLock(pFile, 0) ){ - /* This should never happen. We should always be able to - ** reacquire the read lock */ - rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), -@@ -50510,6 +51059,28 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){ - return rc; - } - #endif -+ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ case SQLITE_FCNTL_LOCK_TIMEOUT: { -+ int iOld = pFile->iBusyTimeout; -+ int iNew = *(int*)pArg; -+#if SQLITE_ENABLE_SETLK_TIMEOUT==1 -+ pFile->iBusyTimeout = (iNew < 0) ? INFINITE : (DWORD)iNew; -+#elif SQLITE_ENABLE_SETLK_TIMEOUT==2 -+ pFile->iBusyTimeout = (DWORD)(!!iNew); -+#else -+# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" -+#endif -+ *(int*)pArg = iOld; -+ return SQLITE_OK; -+ } -+ case SQLITE_FCNTL_BLOCK_ON_CONNECT: { -+ int iNew = *(int*)pArg; -+ pFile->bBlockOnConnect = iNew; -+ return SQLITE_OK; -+ } -+#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ -+ - } - OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); - return SQLITE_NOTFOUND; -@@ -50590,23 +51161,27 @@ static int winShmMutexHeld(void) { - ** - ** The following fields are read-only after the object is created: - ** --** fid - ** zFilename - ** - ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and - ** winShmMutexHeld() is true when reading or writing any other field - ** in this structure. - ** -+** File-handle hSharedShm is used to (a) take the DMS lock, (b) truncate -+** the *-shm file if the DMS-locking protocol demands it, and (c) map -+** regions of the *-shm file into memory using MapViewOfFile() or -+** similar. Other locks are taken by individual clients using the -+** winShm.hShm handles. - */ - struct winShmNode { - sqlite3_mutex *mutex; /* Mutex to access this object */ - char *zFilename; /* Name of the file */ -- winFile hFile; /* File handle from winOpen */ -+ HANDLE hSharedShm; /* File handle open on zFilename */ - -+ int isUnlocked; /* DMS lock has not yet been obtained */ -+ int isReadonly; /* True if read-only */ - int szRegion; /* Size of shared-memory regions */ - int nRegion; /* Size of array apRegion */ -- u8 isReadonly; /* True if read-only */ -- u8 isUnlocked; /* True if no DMS lock held */ - - struct ShmRegion { - HANDLE hMap; /* File handle from CreateFileMapping */ -@@ -50615,7 +51190,6 @@ struct winShmNode { - DWORD lastErrno; /* The Windows errno from the last I/O error */ - - int nRef; /* Number of winShm objects pointing to this */ -- winShm *pFirst; /* All winShm objects pointing to this */ - winShmNode *pNext; /* Next in list of all winShmNode objects */ - #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) - u8 nextShmId; /* Next available winShm.id value */ -@@ -50631,23 +51205,15 @@ static winShmNode *winShmNodeList = 0; - - /* - ** Structure used internally by this VFS to record the state of an --** open shared memory connection. --** --** The following fields are initialized when this object is created and --** are read-only thereafter: --** --** winShm.pShmNode --** winShm.id --** --** All other fields are read/write. The winShm.pShmNode->mutex must be held --** while accessing any read/write fields. -+** open shared memory connection. There is one such structure for each -+** winFile open on a wal mode database. - */ - struct winShm { - winShmNode *pShmNode; /* The underlying winShmNode object */ -- winShm *pNext; /* Next winShm with the same winShmNode */ -- u8 hasMutex; /* True if holding the winShmNode mutex */ - u16 sharedMask; /* Mask of shared locks held */ - u16 exclMask; /* Mask of exclusive locks held */ -+ HANDLE hShm; /* File-handle on *-shm file. For locking. */ -+ int bReadonly; /* True if hShm is opened read-only */ - #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) - u8 id; /* Id of this connection with its winShmNode */ - #endif -@@ -50659,50 +51225,6 @@ struct winShm { - #define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ - #define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ - --/* --** Apply advisory locks for all n bytes beginning at ofst. --*/ --#define WINSHM_UNLCK 1 --#define WINSHM_RDLCK 2 --#define WINSHM_WRLCK 3 --static int winShmSystemLock( -- winShmNode *pFile, /* Apply locks to this open shared-memory segment */ -- int lockType, /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */ -- int ofst, /* Offset to first byte to be locked/unlocked */ -- int nByte /* Number of bytes to lock or unlock */ --){ -- int rc = 0; /* Result code form Lock/UnlockFileEx() */ -- -- /* Access to the winShmNode object is serialized by the caller */ -- assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); -- -- OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", -- pFile->hFile.h, lockType, ofst, nByte)); -- -- /* Release/Acquire the system-level lock */ -- if( lockType==WINSHM_UNLCK ){ -- rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); -- }else{ -- /* Initialize the locking parameters */ -- DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; -- if( lockType == WINSHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; -- rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); -- } -- -- if( rc!= 0 ){ -- rc = SQLITE_OK; -- }else{ -- pFile->lastErrno = osGetLastError(); -- rc = SQLITE_BUSY; -- } -- -- OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", -- pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : -- "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); -- -- return rc; --} -- - /* Forward references to VFS methods */ - static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); - static int winDelete(sqlite3_vfs *,const char*,int); -@@ -50734,11 +51256,7 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ - osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); - UNUSED_VARIABLE_VALUE(bRc); - } -- if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ -- SimulateIOErrorBenign(1); -- winClose((sqlite3_file *)&p->hFile); -- SimulateIOErrorBenign(0); -- } -+ winHandleClose(p->hSharedShm); - if( deleteFlag ){ - SimulateIOErrorBenign(1); - sqlite3BeginBenignMalloc(); -@@ -50756,42 +51274,239 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ - } - - /* --** The DMS lock has not yet been taken on shm file pShmNode. Attempt to --** take it now. Return SQLITE_OK if successful, or an SQLite error --** code otherwise. --** --** If the DMS cannot be locked because this is a readonly_shm=1 --** connection and no other process already holds a lock, return --** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. -+** The DMS lock has not yet been taken on the shm file associated with -+** pShmNode. Take the lock. Truncate the *-shm file if required. -+** Return SQLITE_OK if successful, or an SQLite error code otherwise. - */ --static int winLockSharedMemory(winShmNode *pShmNode){ -- int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1); -+static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){ -+ HANDLE h = pShmNode->hSharedShm; -+ int rc = SQLITE_OK; - -+ assert( sqlite3_mutex_held(pShmNode->mutex) ); -+ rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 1, 0); - if( rc==SQLITE_OK ){ -+ /* We have an EXCLUSIVE lock on the DMS byte. This means that this -+ ** is the first process to open the file. Truncate it to zero bytes -+ ** in this case. */ - if( pShmNode->isReadonly ){ -- pShmNode->isUnlocked = 1; -- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); -- return SQLITE_READONLY_CANTINIT; -- }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ -- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); -- return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), -- "winLockSharedMemory", pShmNode->zFilename); -+ rc = SQLITE_READONLY_CANTINIT; -+ }else{ -+ rc = winHandleTruncate(h, 0); - } -+ -+ /* Release the EXCLUSIVE lock acquired above. */ -+ winUnlockFile(&h, WIN_SHM_DMS, 0, 1, 0); -+ }else if( (rc & 0xFF)==SQLITE_BUSY ){ -+ rc = SQLITE_OK; - } - - if( rc==SQLITE_OK ){ -- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); -+ /* Take a SHARED lock on the DMS byte. */ -+ rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 0, nMs); -+ if( rc==SQLITE_OK ){ -+ pShmNode->isUnlocked = 0; -+ } - } - -- return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1); -+ return rc; - } - -+ - /* --** Open the shared-memory area associated with database file pDbFd. -+** Convert a UTF-8 filename into whatever form the underlying -+** operating system wants filenames in. Space to hold the result -+** is obtained from malloc and must be freed by the calling -+** function -+** -+** On Cygwin, 3 possible input forms are accepted: -+** - If the filename starts with ":/" or ":\", -+** it is converted to UTF-16 as-is. -+** - If the filename contains '/', it is assumed to be a -+** Cygwin absolute path, it is converted to a win32 -+** absolute path in UTF-16. -+** - Otherwise it must be a filename only, the win32 filename -+** is returned in UTF-16. -+** Note: If the function cygwin_conv_path() fails, only -+** UTF-8 -> UTF-16 conversion will be done. This can only -+** happen when the file path >32k, in which case winUtf8ToUnicode() -+** will fail too. -+*/ -+static void *winConvertFromUtf8Filename(const char *zFilename){ -+ void *zConverted = 0; -+ if( osIsNT() ){ -+#ifdef __CYGWIN__ -+ int nChar; -+ LPWSTR zWideFilename; -+ -+ if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) -+ && winIsDirSep(zFilename[2])) ){ -+ i64 nByte; -+ int convertflag = CCP_POSIX_TO_WIN_W; -+ if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; -+ nByte = (i64)osCygwin_conv_path(convertflag, -+ zFilename, 0, 0); -+ if( nByte>0 ){ -+ zConverted = sqlite3MallocZero(12+(u64)nByte); -+ if ( zConverted==0 ){ -+ return zConverted; -+ } -+ zWideFilename = zConverted; -+ /* Filenames should be prefixed, except when converted -+ * full path already starts with "\\?\". */ -+ if( osCygwin_conv_path(convertflag, zFilename, -+ zWideFilename+4, nByte)==0 ){ -+ if( (convertflag&CCP_RELATIVE) ){ -+ memmove(zWideFilename, zWideFilename+4, nByte); -+ }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){ -+ memcpy(zWideFilename, L"\\\\?\\", 8); -+ }else if( zWideFilename[6]!='?' ){ -+ memmove(zWideFilename+6, zWideFilename+4, nByte); -+ memcpy(zWideFilename, L"\\\\?\\UNC", 14); -+ }else{ -+ memmove(zWideFilename, zWideFilename+4, nByte); -+ } -+ return zConverted; -+ } -+ sqlite3_free(zConverted); -+ } -+ } -+ nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); -+ if( nChar==0 ){ -+ return 0; -+ } -+ zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); -+ if( zWideFilename==0 ){ -+ return 0; -+ } -+ nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, -+ zWideFilename, nChar); -+ if( nChar==0 ){ -+ sqlite3_free(zWideFilename); -+ zWideFilename = 0; -+ }else if( nChar>MAX_PATH -+ && winIsDriveLetterAndColon(zFilename) -+ && winIsDirSep(zFilename[2]) ){ -+ memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); -+ zWideFilename[2] = '\\'; -+ memcpy(zWideFilename, L"\\\\?\\", 8); -+ }else if( nChar>MAX_PATH -+ && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) -+ && zFilename[2] != '?' ){ -+ memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); -+ memcpy(zWideFilename, L"\\\\?\\UNC", 14); -+ } -+ zConverted = zWideFilename; -+#else -+ zConverted = winUtf8ToUnicode(zFilename); -+#endif /* __CYGWIN__ */ -+ } -+#if defined(SQLITE_WIN32_HAS_ANSI) && defined(_WIN32) -+ else{ -+ zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); -+ } -+#endif -+ /* caller will handle out of memory */ -+ return zConverted; -+} -+ -+/* -+** This function is used to open a handle on a *-shm file. - ** --** When opening a new shared-memory file, if no other instances of that --** file are currently open, in this process or in other processes, then --** the file must be truncated to zero length or have its header cleared. -+** If SQLITE_ENABLE_SETLK_TIMEOUT is defined at build time, then the file -+** is opened with FILE_FLAG_OVERLAPPED specified. If not, it is not. -+*/ -+static int winHandleOpen( -+ const char *zUtf8, /* File to open */ -+ int *pbReadonly, /* IN/OUT: True for readonly handle */ -+ HANDLE *ph /* OUT: New HANDLE for file */ -+){ -+ int rc = SQLITE_OK; -+ void *zConverted = 0; -+ int bReadonly = *pbReadonly; -+ HANDLE h = INVALID_HANDLE_VALUE; -+ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ const DWORD flag_overlapped = FILE_FLAG_OVERLAPPED; -+#else -+ const DWORD flag_overlapped = 0; -+#endif -+ -+ /* Convert the filename to the system encoding. */ -+ zConverted = winConvertFromUtf8Filename(zUtf8); -+ if( zConverted==0 ){ -+ OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8)); -+ rc = SQLITE_IOERR_NOMEM_BKPT; -+ goto winopenfile_out; -+ } -+ -+ /* Ensure the file we are trying to open is not actually a directory. */ -+ if( winIsDir(zConverted) ){ -+ OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8)); -+ rc = SQLITE_CANTOPEN_ISDIR; -+ goto winopenfile_out; -+ } -+ -+ /* TODO: platforms. -+ ** TODO: retry-on-ioerr. -+ */ -+ if( osIsNT() ){ -+#if SQLITE_OS_WINRT -+ CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; -+ memset(&extendedParameters, 0, sizeof(extendedParameters)); -+ extendedParameters.dwSize = sizeof(extendedParameters); -+ extendedParameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; -+ extendedParameters.dwFileFlags = flag_overlapped; -+ extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; -+ h = osCreateFile2((LPCWSTR)zConverted, -+ (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)),/* dwDesiredAccess */ -+ FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ -+ OPEN_ALWAYS, /* dwCreationDisposition */ -+ &extendedParameters -+ ); -+#else -+ h = osCreateFileW((LPCWSTR)zConverted, /* lpFileName */ -+ (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ -+ FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ -+ NULL, /* lpSecurityAttributes */ -+ OPEN_ALWAYS, /* dwCreationDisposition */ -+ FILE_ATTRIBUTE_NORMAL|flag_overlapped, -+ NULL -+ ); -+#endif -+ }else{ -+ /* Due to pre-processor directives earlier in this file, -+ ** SQLITE_WIN32_HAS_ANSI is always defined if osIsNT() is false. */ -+#ifdef SQLITE_WIN32_HAS_ANSI -+ h = osCreateFileA((LPCSTR)zConverted, -+ (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ -+ FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ -+ NULL, /* lpSecurityAttributes */ -+ OPEN_ALWAYS, /* dwCreationDisposition */ -+ FILE_ATTRIBUTE_NORMAL|flag_overlapped, -+ NULL -+ ); -+#endif -+ } -+ -+ if( h==INVALID_HANDLE_VALUE ){ -+ if( bReadonly==0 ){ -+ bReadonly = 1; -+ rc = winHandleOpen(zUtf8, &bReadonly, &h); -+ }else{ -+ rc = SQLITE_CANTOPEN_BKPT; -+ } -+ } -+ -+ winopenfile_out: -+ sqlite3_free(zConverted); -+ *pbReadonly = bReadonly; -+ *ph = h; -+ return rc; -+} -+ -+ -+/* -+** Open the shared-memory area associated with database file pDbFd. - */ - static int winOpenSharedMemory(winFile *pDbFd){ - struct winShm *p; /* The connection to be opened */ -@@ -50803,98 +51518,83 @@ static int winOpenSharedMemory(winFile *pDbFd){ - assert( pDbFd->pShm==0 ); /* Not previously opened */ - - /* Allocate space for the new sqlite3_shm object. Also speculatively -- ** allocate space for a new winShmNode and filename. -- */ -+ ** allocate space for a new winShmNode and filename. */ - p = sqlite3MallocZero( sizeof(*p) ); - if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; - nName = sqlite3Strlen30(pDbFd->zPath); -- pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); -+ pNew = sqlite3MallocZero( sizeof(*pShmNode) + (i64)nName + 17 ); - if( pNew==0 ){ - sqlite3_free(p); - return SQLITE_IOERR_NOMEM_BKPT; - } - pNew->zFilename = (char*)&pNew[1]; -+ pNew->hSharedShm = INVALID_HANDLE_VALUE; -+ pNew->isUnlocked = 1; - sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); - sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); - -+ /* Open a file-handle on the *-shm file for this connection. This file-handle -+ ** is only used for locking. The mapping of the *-shm file is created using -+ ** the shared file handle in winShmNode.hSharedShm. */ -+ p->bReadonly = sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0); -+ rc = winHandleOpen(pNew->zFilename, &p->bReadonly, &p->hShm); -+ - /* Look to see if there is an existing winShmNode that can be used. -- ** If no matching winShmNode currently exists, create a new one. -- */ -+ ** If no matching winShmNode currently exists, then create a new one. */ - winShmEnterMutex(); - for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ - /* TBD need to come up with better match here. Perhaps -- ** use FILE_ID_BOTH_DIR_INFO Structure. -- */ -+ ** use FILE_ID_BOTH_DIR_INFO Structure. */ - if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; - } -- if( pShmNode ){ -- sqlite3_free(pNew); -- }else{ -- int inFlags = SQLITE_OPEN_WAL; -- int outFlags = 0; -- -+ if( pShmNode==0 ){ - pShmNode = pNew; -- pNew = 0; -- ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE; -- pShmNode->pNext = winShmNodeList; -- winShmNodeList = pShmNode; - -+ /* Allocate a mutex for this winShmNode object, if one is required. */ - if( sqlite3GlobalConfig.bCoreMutex ){ - pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); -- if( pShmNode->mutex==0 ){ -- rc = SQLITE_IOERR_NOMEM_BKPT; -- goto shm_open_err; -- } -+ if( pShmNode->mutex==0 ) rc = SQLITE_IOERR_NOMEM_BKPT; - } - -- if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ -- inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; -- }else{ -- inFlags |= SQLITE_OPEN_READONLY; -- } -- rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, -- (sqlite3_file*)&pShmNode->hFile, -- inFlags, &outFlags); -- if( rc!=SQLITE_OK ){ -- rc = winLogError(rc, osGetLastError(), "winOpenShm", -- pShmNode->zFilename); -- goto shm_open_err; -+ /* Open a file-handle to use for mappings, and for the DMS lock. */ -+ if( rc==SQLITE_OK ){ -+ HANDLE h = INVALID_HANDLE_VALUE; -+ pShmNode->isReadonly = p->bReadonly; -+ rc = winHandleOpen(pNew->zFilename, &pShmNode->isReadonly, &h); -+ pShmNode->hSharedShm = h; - } -- if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1; - -- rc = winLockSharedMemory(pShmNode); -- if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; -+ /* If successful, link the new winShmNode into the global list. If an -+ ** error occurred, free the object. */ -+ if( rc==SQLITE_OK ){ -+ pShmNode->pNext = winShmNodeList; -+ winShmNodeList = pShmNode; -+ pNew = 0; -+ }else{ -+ sqlite3_mutex_free(pShmNode->mutex); -+ if( pShmNode->hSharedShm!=INVALID_HANDLE_VALUE ){ -+ osCloseHandle(pShmNode->hSharedShm); -+ } -+ } - } - -- /* Make the new connection a child of the winShmNode */ -- p->pShmNode = pShmNode; -+ /* If no error has occurred, link the winShm object to the winShmNode and -+ ** the winShm to pDbFd. */ -+ if( rc==SQLITE_OK ){ -+ p->pShmNode = pShmNode; -+ pShmNode->nRef++; - #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) -- p->id = pShmNode->nextShmId++; -+ p->id = pShmNode->nextShmId++; - #endif -- pShmNode->nRef++; -- pDbFd->pShm = p; -- winShmLeaveMutex(); -- -- /* The reference count on pShmNode has already been incremented under -- ** the cover of the winShmEnterMutex() mutex and the pointer from the -- ** new (struct winShm) object to the pShmNode has been set. All that is -- ** left to do is to link the new object into the linked list starting -- ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex -- ** mutex. -- */ -- sqlite3_mutex_enter(pShmNode->mutex); -- p->pNext = pShmNode->pFirst; -- pShmNode->pFirst = p; -- sqlite3_mutex_leave(pShmNode->mutex); -- return rc; -+ pDbFd->pShm = p; -+ }else if( p ){ -+ winHandleClose(p->hShm); -+ sqlite3_free(p); -+ } - -- /* Jump here on any error */ --shm_open_err: -- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); -- winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ -- sqlite3_free(p); -- sqlite3_free(pNew); -+ assert( rc!=SQLITE_OK || pShmNode->isUnlocked==0 || pShmNode->nRegion==0 ); - winShmLeaveMutex(); -+ sqlite3_free(pNew); - return rc; - } - -@@ -50909,27 +51609,19 @@ static int winShmUnmap( - winFile *pDbFd; /* Database holding shared-memory */ - winShm *p; /* The connection to be closed */ - winShmNode *pShmNode; /* The underlying shared-memory file */ -- winShm **pp; /* For looping over sibling connections */ - - pDbFd = (winFile*)fd; - p = pDbFd->pShm; - if( p==0 ) return SQLITE_OK; -- pShmNode = p->pShmNode; -- -- /* Remove connection p from the set of connections associated -- ** with pShmNode */ -- sqlite3_mutex_enter(pShmNode->mutex); -- for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} -- *pp = p->pNext; -+ if( p->hShm!=INVALID_HANDLE_VALUE ){ -+ osCloseHandle(p->hShm); -+ } - -- /* Free the connection p */ -- sqlite3_free(p); -- pDbFd->pShm = 0; -- sqlite3_mutex_leave(pShmNode->mutex); -+ pShmNode = p->pShmNode; -+ winShmEnterMutex(); - - /* If pShmNode->nRef has reached 0, then close the underlying -- ** shared-memory file, too */ -- winShmEnterMutex(); -+ ** shared-memory file, too. */ - assert( pShmNode->nRef>0 ); - pShmNode->nRef--; - if( pShmNode->nRef==0 ){ -@@ -50937,6 +51629,9 @@ static int winShmUnmap( - } - winShmLeaveMutex(); - -+ /* Free the connection p */ -+ sqlite3_free(p); -+ pDbFd->pShm = 0; - return SQLITE_OK; - } - -@@ -50951,10 +51646,9 @@ static int winShmLock( - ){ - winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ - winShm *p = pDbFd->pShm; /* The shared memory being locked */ -- winShm *pX; /* For looping over all siblings */ - winShmNode *pShmNode; - int rc = SQLITE_OK; /* Result code */ -- u16 mask; /* Mask of locks to take or release */ -+ u16 mask = (u16)((1U<<(ofst+n)) - (1U<pShmNode; -@@ -50968,85 +51662,81 @@ static int winShmLock( - || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); - assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); - -- mask = (u16)((1U<<(ofst+n)) - (1U<1 || mask==(1<mutex); -- if( flags & SQLITE_SHM_UNLOCK ){ -- u16 allMask = 0; /* Mask of locks held by siblings */ -- -- /* See if any siblings hold this same lock */ -- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ -- if( pX==p ) continue; -- assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); -- allMask |= pX->sharedMask; -- } -+ /* Check that, if this to be a blocking lock, no locks that occur later -+ ** in the following list than the lock being obtained are already held: -+ ** -+ ** 1. Recovery lock (ofst==2). -+ ** 2. Checkpointer lock (ofst==1). -+ ** 3. Write lock (ofst==0). -+ ** 4. Read locks (ofst>=3 && ofstexclMask|p->sharedMask); -+ assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( -+ (ofst!=2 || lockMask==0) -+ && (ofst!=1 || lockMask==0 || lockMask==2) -+ && (ofst!=0 || lockMask<3) -+ && (ofst<3 || lockMask<(1<exclMask & mask) -+ ); -+ if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) -+ || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) -+ || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) -+ ){ - -- /* Undo the local locks */ -- if( rc==SQLITE_OK ){ -- p->exclMask &= ~mask; -- p->sharedMask &= ~mask; -- } -- }else if( flags & SQLITE_SHM_SHARED ){ -- u16 allShared = 0; /* Union of locks held by connections other than "p" */ -+ if( flags & SQLITE_SHM_UNLOCK ){ -+ /* Case (a) - unlock. */ - -- /* Find out which shared locks are already held by sibling connections. -- ** If any sibling already holds an exclusive lock, go ahead and return -- ** SQLITE_BUSY. -- */ -- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ -- if( (pX->exclMask & mask)!=0 ){ -- rc = SQLITE_BUSY; -- break; -- } -- allShared |= pX->sharedMask; -- } -+ assert( (p->exclMask & p->sharedMask)==0 ); -+ assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); -+ assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); - -- /* Get shared locks at the system level, if necessary */ -- if( rc==SQLITE_OK ){ -- if( (allShared & mask)==0 ){ -- rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, ofst+WIN_SHM_BASE, n); -- }else{ -- rc = SQLITE_OK; -- } -- } -+ rc = winHandleUnlock(p->hShm, ofst+WIN_SHM_BASE, n); - -- /* Get the local shared locks */ -- if( rc==SQLITE_OK ){ -- p->sharedMask |= mask; -- } -- }else{ -- /* Make sure no sibling connections hold locks that will block this -- ** lock. If any do, return SQLITE_BUSY right away. -- */ -- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ -- if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ -- rc = SQLITE_BUSY; -- break; -+ /* If successful, also clear the bits in sharedMask/exclMask */ -+ if( rc==SQLITE_OK ){ -+ p->exclMask = (p->exclMask & ~mask); -+ p->sharedMask = (p->sharedMask & ~mask); - } -- } -- -- /* Get the exclusive locks at the system level. Then if successful -- ** also mark the local connection as being locked. -- */ -- if( rc==SQLITE_OK ){ -- rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, ofst+WIN_SHM_BASE, n); -+ }else{ -+ int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0); -+ DWORD nMs = winFileBusyTimeout(pDbFd); -+ rc = winHandleLockTimeout(p->hShm, ofst+WIN_SHM_BASE, n, bExcl, nMs); - if( rc==SQLITE_OK ){ -- assert( (p->sharedMask & mask)==0 ); -- p->exclMask |= mask; -+ if( bExcl ){ -+ p->exclMask = (p->exclMask | mask); -+ }else{ -+ p->sharedMask = (p->sharedMask | mask); -+ } - } - } - } -- sqlite3_mutex_leave(pShmNode->mutex); -- OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", -- osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, -- sqlite3ErrName(rc))); -+ -+ OSTRACE(( -+ "SHM-LOCK(%d,%d,%d) pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x," -+ " rc=%s\n", -+ ofst, n, flags, -+ osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, -+ sqlite3ErrName(rc)) -+ ); - return rc; - } - -@@ -51108,13 +51798,15 @@ static int winShmMap( - - sqlite3_mutex_enter(pShmNode->mutex); - if( pShmNode->isUnlocked ){ -- rc = winLockSharedMemory(pShmNode); -+ /* Take the DMS lock. */ -+ assert( pShmNode->nRegion==0 ); -+ rc = winLockSharedMemory(pShmNode, winFileBusyTimeout(pDbFd)); - if( rc!=SQLITE_OK ) goto shmpage_out; -- pShmNode->isUnlocked = 0; - } -- assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); - -+ assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); - if( pShmNode->nRegion<=iRegion ){ -+ HANDLE hShared = pShmNode->hSharedShm; - struct ShmRegion *apNew; /* New aRegion[] array */ - int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ - sqlite3_int64 sz; /* Current size of wal-index file */ -@@ -51125,10 +51817,9 @@ static int winShmMap( - ** Check to see if it has been allocated (i.e. if the wal-index file is - ** large enough to contain the requested region). - */ -- rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); -+ rc = winHandleSize(hShared, &sz); - if( rc!=SQLITE_OK ){ -- rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), -- "winShmMap1", pDbFd->zPath); -+ rc = winLogError(rc, osGetLastError(), "winShmMap1", pDbFd->zPath); - goto shmpage_out; - } - -@@ -51137,19 +51828,17 @@ static int winShmMap( - ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned. - ** - ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate -- ** the requested memory region. -- */ -+ ** the requested memory region. */ - if( !isWrite ) goto shmpage_out; -- rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); -+ rc = winHandleTruncate(hShared, nByte); - if( rc!=SQLITE_OK ){ -- rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), -- "winShmMap2", pDbFd->zPath); -+ rc = winLogError(rc, osGetLastError(), "winShmMap2", pDbFd->zPath); - goto shmpage_out; - } - } - - /* Map the requested memory region into this processes address space. */ -- apNew = (struct ShmRegion *)sqlite3_realloc64( -+ apNew = (struct ShmRegion*)sqlite3_realloc64( - pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) - ); - if( !apNew ){ -@@ -51168,18 +51857,13 @@ static int winShmMap( - void *pMap = 0; /* Mapped memory region */ - - #if SQLITE_OS_WINRT -- hMap = osCreateFileMappingFromApp(pShmNode->hFile.h, -- NULL, protect, nByte, NULL -- ); -+ hMap = osCreateFileMappingFromApp(hShared, NULL, protect, nByte, NULL); - #elif defined(SQLITE_WIN32_HAS_WIDE) -- hMap = osCreateFileMappingW(pShmNode->hFile.h, -- NULL, protect, 0, nByte, NULL -- ); -+ hMap = osCreateFileMappingW(hShared, NULL, protect, 0, nByte, NULL); - #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA -- hMap = osCreateFileMappingA(pShmNode->hFile.h, -- NULL, protect, 0, nByte, NULL -- ); -+ hMap = osCreateFileMappingA(hShared, NULL, protect, 0, nByte, NULL); - #endif -+ - OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", - osGetCurrentProcessId(), pShmNode->nRegion, nByte, - hMap ? "ok" : "failed")); -@@ -51222,7 +51906,9 @@ shmpage_out: - }else{ - *pp = 0; - } -- if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; -+ if( pShmNode->isReadonly && rc==SQLITE_OK ){ -+ rc = SQLITE_READONLY; -+ } - sqlite3_mutex_leave(pShmNode->mutex); - return rc; - } -@@ -51542,47 +52228,6 @@ static winVfsAppData winNolockAppData = { - ** sqlite3_vfs object. - */ - --#if defined(__CYGWIN__) --/* --** Convert a filename from whatever the underlying operating system --** supports for filenames into UTF-8. Space to hold the result is --** obtained from malloc and must be freed by the calling function. --*/ --static char *winConvertToUtf8Filename(const void *zFilename){ -- char *zConverted = 0; -- if( osIsNT() ){ -- zConverted = winUnicodeToUtf8(zFilename); -- } --#ifdef SQLITE_WIN32_HAS_ANSI -- else{ -- zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); -- } --#endif -- /* caller will handle out of memory */ -- return zConverted; --} --#endif -- --/* --** Convert a UTF-8 filename into whatever form the underlying --** operating system wants filenames in. Space to hold the result --** is obtained from malloc and must be freed by the calling --** function. --*/ --static void *winConvertFromUtf8Filename(const char *zFilename){ -- void *zConverted = 0; -- if( osIsNT() ){ -- zConverted = winUtf8ToUnicode(zFilename); -- } --#ifdef SQLITE_WIN32_HAS_ANSI -- else{ -- zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); -- } --#endif -- /* caller will handle out of memory */ -- return zConverted; --} -- - /* - ** This function returns non-zero if the specified UTF-8 string buffer - ** ends with a directory separator character or one was successfully -@@ -51595,7 +52240,14 @@ static int winMakeEndInDirSep(int nBuf, char *zBuf){ - if( winIsDirSep(zBuf[nLen-1]) ){ - return 1; - }else if( nLen+1mxPathname; nBuf = nMax + 2; -+ nMax = pVfs->mxPathname; -+ nBuf = 2 + (i64)nMax; - zBuf = sqlite3MallocZero( nBuf ); - if( !zBuf ){ - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); -@@ -51672,7 +52325,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ - } - - #if defined(__CYGWIN__) -- else{ -+ else if( osGetenv!=NULL ){ - static const char *azDirs[] = { - 0, /* getenv("SQLITE_TMPDIR") */ - 0, /* getenv("TMPDIR") */ -@@ -51688,11 +52341,11 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ - unsigned int i; - const char *zDir = 0; - -- if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); -- if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); -- if( !azDirs[2] ) azDirs[2] = getenv("TMP"); -- if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); -- if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); -+ if( !azDirs[0] ) azDirs[0] = osGetenv("SQLITE_TMPDIR"); -+ if( !azDirs[1] ) azDirs[1] = osGetenv("TMPDIR"); -+ if( !azDirs[2] ) azDirs[2] = osGetenv("TMP"); -+ if( !azDirs[3] ) azDirs[3] = osGetenv("TEMP"); -+ if( !azDirs[4] ) azDirs[4] = osGetenv("USERPROFILE"); - for(i=0; inOut ){ -+ /* SQLite assumes that xFullPathname() nul-terminates the output buffer -+ ** even if it returns an error. */ -+ zOut[iOff] = '\0'; -+ return SQLITE_CANTOPEN_BKPT; -+ } -+ sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); -+ return SQLITE_OK; -+} -+#endif /* __CYGWIN__ */ - - /* - ** Turn a relative pathname into a full pathname. Write the full -@@ -52475,8 +53177,8 @@ static int winFullPathnameNoMutex( - int nFull, /* Size of output buffer in bytes */ - char *zFull /* Output buffer */ - ){ --#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) -- DWORD nByte; -+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT -+ int nByte; - void *zConverted; - char *zOut; - #endif -@@ -52489,64 +53191,82 @@ static int winFullPathnameNoMutex( - zRelative++; - } - --#if defined(__CYGWIN__) - SimulateIOError( return SQLITE_ERROR ); -- UNUSED_PARAMETER(nFull); -- assert( nFull>=pVfs->mxPathname ); -- if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ -- /* -- ** NOTE: We are dealing with a relative path name and the data -- ** directory has been set. Therefore, use it as the basis -- ** for converting the relative path name to an absolute -- ** one by prepending the data directory and a slash. -- */ -- char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); -- if( !zOut ){ -- return SQLITE_IOERR_NOMEM_BKPT; -- } -- if( cygwin_conv_path( -- (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | -- CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ -- sqlite3_free(zOut); -- return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, -- "winFullPathname1", zRelative); -- }else{ -- char *zUtf8 = winConvertToUtf8Filename(zOut); -- if( !zUtf8 ){ -- sqlite3_free(zOut); -- return SQLITE_IOERR_NOMEM_BKPT; -- } -- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", -- sqlite3_data_directory, winGetDirSep(), zUtf8); -- sqlite3_free(zUtf8); -- sqlite3_free(zOut); -- } -- }else{ -- char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); -- if( !zOut ){ -- return SQLITE_IOERR_NOMEM_BKPT; -- } -- if( cygwin_conv_path( -- (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), -- zRelative, zOut, pVfs->mxPathname+1)<0 ){ -- sqlite3_free(zOut); -- return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, -- "winFullPathname2", zRelative); -- }else{ -- char *zUtf8 = winConvertToUtf8Filename(zOut); -- if( !zUtf8 ){ -- sqlite3_free(zOut); -- return SQLITE_IOERR_NOMEM_BKPT; -- } -- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); -- sqlite3_free(zUtf8); -- sqlite3_free(zOut); -+ -+#ifdef __CYGWIN__ -+ if( osGetcwd ){ -+ zFull[nFull-1] = '\0'; -+ if( !winIsDriveLetterAndColon(zRelative) || !winIsDirSep(zRelative[2]) ){ -+ int rc = SQLITE_OK; -+ int nLink = 1; /* Number of symbolic links followed so far */ -+ const char *zIn = zRelative; /* Input path for each iteration of loop */ -+ char *zDel = 0; -+ struct stat buf; -+ -+ UNUSED_PARAMETER(pVfs); -+ -+ do { -+ /* Call lstat() on path zIn. Set bLink to true if the path is a symbolic -+ ** link, or false otherwise. */ -+ int bLink = 0; -+ if( osLstat && osReadlink ) { -+ if( osLstat(zIn, &buf)!=0 ){ -+ int myErrno = osErrno; -+ if( myErrno!=ENOENT ){ -+ rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)myErrno, "lstat", zIn); -+ } -+ }else{ -+ bLink = ((buf.st_mode & 0170000) == 0120000); -+ } -+ -+ if( bLink ){ -+ if( zDel==0 ){ -+ zDel = sqlite3MallocZero(nFull); -+ if( zDel==0 ) rc = SQLITE_NOMEM; -+ }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ -+ rc = SQLITE_CANTOPEN_BKPT; -+ } -+ -+ if( rc==SQLITE_OK ){ -+ nByte = osReadlink(zIn, zDel, nFull-1); -+ if( nByte ==(DWORD)-1 ){ -+ rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "readlink", zIn); -+ }else{ -+ if( zDel[0]!='/' ){ -+ int n; -+ for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); -+ if( nByte+n+1>nFull ){ -+ rc = SQLITE_CANTOPEN_BKPT; -+ }else{ -+ memmove(&zDel[n], zDel, nByte+1); -+ memcpy(zDel, zIn, n); -+ nByte += n; -+ } -+ } -+ zDel[nByte] = '\0'; -+ } -+ } -+ -+ zIn = zDel; -+ } -+ } -+ -+ assert( rc!=SQLITE_OK || zIn!=zFull || zIn[0]=='/' ); -+ if( rc==SQLITE_OK && zIn!=zFull ){ -+ rc = mkFullPathname(zIn, zFull, nFull); -+ } -+ if( bLink==0 ) break; -+ zIn = zFull; -+ }while( rc==SQLITE_OK ); -+ -+ sqlite3_free(zDel); -+ winSimplifyName(zFull); -+ return rc; - } - } -- return SQLITE_OK; --#endif -+#endif /* __CYGWIN__ */ - --#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__) -+#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) - SimulateIOError( return SQLITE_ERROR ); - /* WinCE has no concept of a relative pathname, or so I am told. */ - /* WinRT has no way to convert a relative path to an absolute one. */ -@@ -52565,7 +53285,8 @@ static int winFullPathnameNoMutex( - return SQLITE_OK; - #endif - --#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__) -+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT -+#if defined(_WIN32) - /* It's odd to simulate an io-error here, but really this is just - ** using the io-error infrastructure to test that SQLite handles this - ** function failing. This function could fail if, for example, the -@@ -52583,6 +53304,7 @@ static int winFullPathnameNoMutex( - sqlite3_data_directory, winGetDirSep(), zRelative); - return SQLITE_OK; - } -+#endif - zConverted = winConvertFromUtf8Filename(zRelative); - if( zConverted==0 ){ - return SQLITE_IOERR_NOMEM_BKPT; -@@ -52621,13 +53343,12 @@ static int winFullPathnameNoMutex( - return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), - "winFullPathname3", zRelative); - } -- nByte += 3; -- zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); -+ zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) + 3*sizeof(zTemp[0]) ); - if( zTemp==0 ){ - sqlite3_free(zConverted); - return SQLITE_IOERR_NOMEM_BKPT; - } -- nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); -+ nByte = osGetFullPathNameA((char*)zConverted, nByte+3, zTemp, 0); - if( nByte==0 ){ - sqlite3_free(zConverted); - sqlite3_free(zTemp); -@@ -52640,7 +53361,26 @@ static int winFullPathnameNoMutex( - } - #endif - if( zOut ){ -+#ifdef __CYGWIN__ -+ if( memcmp(zOut, "\\\\?\\", 4) ){ -+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); -+ }else if( memcmp(zOut+4, "UNC\\", 4) ){ -+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut+4); -+ }else{ -+ char *p = zOut+6; -+ *p = '\\'; -+ if( osGetcwd ){ -+ /* On Cygwin, UNC paths use forward slashes */ -+ while( *p ){ -+ if( *p=='\\' ) *p = '/'; -+ ++p; -+ } -+ } -+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut+6); -+ } -+#else - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); -+#endif /* __CYGWIN__ */ - sqlite3_free(zOut); - return SQLITE_OK; - }else{ -@@ -52670,25 +53410,8 @@ static int winFullPathname( - */ - static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ - HANDLE h; --#if defined(__CYGWIN__) -- int nFull = pVfs->mxPathname+1; -- char *zFull = sqlite3MallocZero( nFull ); -- void *zConverted = 0; -- if( zFull==0 ){ -- OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); -- return 0; -- } -- if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ -- sqlite3_free(zFull); -- OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); -- return 0; -- } -- zConverted = winConvertFromUtf8Filename(zFull); -- sqlite3_free(zFull); --#else - void *zConverted = winConvertFromUtf8Filename(zFilename); - UNUSED_PARAMETER(pVfs); --#endif - if( zConverted==0 ){ - OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); - return 0; -@@ -53037,7 +53760,7 @@ SQLITE_API int sqlite3_os_init(void){ - - /* Double-check that the aSyscall[] array has been constructed - ** correctly. See ticket [bb3a86e890c8e96ab] */ -- assert( ArraySize(aSyscall)==80 ); -+ assert( ArraySize(aSyscall)==89 ); - - /* get memory map allocation granularity */ - memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); -@@ -53656,13 +54379,13 @@ static int memdbOpen( - } - if( p==0 ){ - MemStore **apNew; -- p = sqlite3Malloc( sizeof(*p) + szName + 3 ); -+ p = sqlite3Malloc( sizeof(*p) + (i64)szName + 3 ); - if( p==0 ){ - sqlite3_mutex_leave(pVfsMutex); - return SQLITE_NOMEM; - } - apNew = sqlite3Realloc(memdb_g.apMemStore, -- sizeof(apNew[0])*(memdb_g.nMemStore+1) ); -+ sizeof(apNew[0])*(1+(i64)memdb_g.nMemStore) ); - if( apNew==0 ){ - sqlite3_free(p); - sqlite3_mutex_leave(pVfsMutex); -@@ -54095,7 +54818,7 @@ SQLITE_PRIVATE int sqlite3MemdbInit(void){ - ** no fewer collisions than the no-op *1. */ - #define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) - --#define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *)) -+#define BITVEC_NPTR ((u32)(BITVEC_USIZE/sizeof(Bitvec *))) - - - /* -@@ -54244,7 +54967,9 @@ bitvec_set_rehash: - }else{ - memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); - memset(p->u.apSub, 0, sizeof(p->u.apSub)); -- p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; -+ p->iDivisor = p->iSize/BITVEC_NPTR; -+ if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++; -+ if( p->iDivisoriDivisor = BITVEC_NBIT; - rc = sqlite3BitvecSet(p, i); - for(j=0; jiSize<=BITVEC_NBIT ){ -- p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1))); -+ p->u.aBitmap[i/BITVEC_SZELEM] &= ~(BITVEC_TELEM)(1<<(i&(BITVEC_SZELEM-1))); - }else{ - unsigned int j; - u32 *aiValues = pBuf; -@@ -54329,7 +55054,7 @@ SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ - ** individual bits within V. - */ - #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) --#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7)) -+#define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) - #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 - - /* -@@ -54372,7 +55097,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ - /* Allocate the Bitvec to be tested and a linear array of - ** bits to act as the reference */ - pBitvec = sqlite3BitvecCreate( sz ); -- pV = sqlite3MallocZero( (sz+7)/8 + 1 ); -+ pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); - pTmpSpace = sqlite3_malloc64(BITVEC_SZ); - if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; - -@@ -55613,10 +56338,6 @@ static SQLITE_WSD struct PCacheGlobal { - sqlite3_mutex *mutex; /* Mutex for accessing the following: */ - PgFreeslot *pFree; /* Free page blocks */ - int nFreeSlot; /* Number of unused pcache slots */ -- /* The following value requires a mutex to change. We skip the mutex on -- ** reading because (1) most platforms read a 32-bit integer atomically and -- ** (2) even if an incorrect value is read, no great harm is done since this -- ** is really just an optimization. */ - int bUnderPressure; /* True if low on PAGECACHE memory */ - } pcache1_g; - -@@ -55664,7 +56385,7 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ - pcache1.nReserve = n>90 ? 10 : (n/10 + 1); - pcache1.pStart = pBuf; - pcache1.pFree = 0; -- pcache1.bUnderPressure = 0; -+ AtomicStore(&pcache1.bUnderPressure,0); - while( n-- ){ - p = (PgFreeslot*)pBuf; - p->pNext = pcache1.pFree; -@@ -55732,7 +56453,7 @@ static void *pcache1Alloc(int nByte){ - if( p ){ - pcache1.pFree = pcache1.pFree->pNext; - pcache1.nFreeSlot--; -- pcache1.bUnderPressure = pcache1.nFreeSlot=0 ); - sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); - sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); -@@ -55771,7 +56492,7 @@ static void pcache1Free(void *p){ - pSlot->pNext = pcache1.pFree; - pcache1.pFree = pSlot; - pcache1.nFreeSlot++; -- pcache1.bUnderPressure = pcache1.nFreeSlotszPage+pCache->szExtra)<=pcache1.szSlot ){ -- return pcache1.bUnderPressure; -+ return AtomicLoad(&pcache1.bUnderPressure); - }else{ - return sqlite3HeapNearlyFull(); - } -@@ -55919,12 +56640,12 @@ static int pcache1UnderMemoryPressure(PCache1 *pCache){ - */ - static void pcache1ResizeHash(PCache1 *p){ - PgHdr1 **apNew; -- unsigned int nNew; -- unsigned int i; -+ u64 nNew; -+ u32 i; - - assert( sqlite3_mutex_held(p->pGroup->mutex) ); - -- nNew = p->nHash*2; -+ nNew = 2*(u64)p->nHash; - if( nNew<256 ){ - nNew = 256; - } -@@ -56147,7 +56868,7 @@ static void pcache1Destroy(sqlite3_pcache *p); - static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ - PCache1 *pCache; /* The newly created page cache */ - PGroup *pGroup; /* The group the new page cache will belong to */ -- int sz; /* Bytes of memory required to allocate the new cache */ -+ i64 sz; /* Bytes of memory required to allocate the new cache */ - - assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); - assert( szExtra < 300 ); -@@ -58035,6 +58756,9 @@ struct Pager { - Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ - char *zWal; /* File name for write-ahead log */ - #endif -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ sqlite3 *dbWal; -+#endif - }; - - /* -@@ -58626,7 +59350,7 @@ static void checkPage(PgHdr *pPg){ - ** If an error occurs while reading from the journal file, an SQLite - ** error code is returned. - */ --static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u32 nSuper){ -+static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u64 nSuper){ - int rc; /* Return code */ - u32 len; /* Length in bytes of super-journal name */ - i64 szJ; /* Total size in bytes of journal file pJrnl */ -@@ -59181,6 +59905,15 @@ static void pager_unlock(Pager *pPager){ - - if( pagerUseWal(pPager) ){ - assert( !isOpen(pPager->jfd) ); -+ if( pPager->eState==PAGER_ERROR ){ -+ /* If an IO error occurs in wal.c while attempting to wrap the wal file, -+ ** then the Wal object may be holding a write-lock but no read-lock. -+ ** This call ensures that the write-lock is dropped as well. We cannot -+ ** have sqlite3WalEndReadTransaction() drop the write-lock, as it once -+ ** did, because this would break "BEGIN EXCLUSIVE" handling for -+ ** SQLITE_ENABLE_SETLK_TIMEOUT builds. */ -+ sqlite3WalEndWriteTransaction(pPager->pWal); -+ } - sqlite3WalEndReadTransaction(pPager->pWal); - pPager->eState = PAGER_OPEN; - }else if( !pPager->exclusiveMode ){ -@@ -59862,12 +60595,12 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ - char *zJournal; /* Pointer to one journal within MJ file */ - char *zSuperPtr; /* Space to hold super-journal filename */ - char *zFree = 0; /* Free this buffer */ -- int nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ -+ i64 nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ - - /* Allocate space for both the pJournal and pSuper file descriptors. - ** If successful, open the super-journal file for reading. - */ -- pSuper = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); -+ pSuper = (sqlite3_file *)sqlite3MallocZero(2 * (i64)pVfs->szOsFile); - if( !pSuper ){ - rc = SQLITE_NOMEM_BKPT; - pJournal = 0; -@@ -59885,11 +60618,14 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ - */ - rc = sqlite3OsFileSize(pSuper, &nSuperJournal); - if( rc!=SQLITE_OK ) goto delsuper_out; -- nSuperPtr = pVfs->mxPathname+1; -+ nSuperPtr = 1 + (i64)pVfs->mxPathname; -+ assert( nSuperJournal>=0 && nSuperPtr>0 ); - zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2); - if( !zFree ){ - rc = SQLITE_NOMEM_BKPT; - goto delsuper_out; -+ }else{ -+ assert( nSuperJournal<=0x7fffffff ); - } - zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0; - zSuperJournal = &zFree[4]; -@@ -60150,7 +60886,7 @@ static int pager_playback(Pager *pPager, int isHot){ - ** for pageSize. - */ - zSuper = pPager->pTmpSpace; -- rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); -+ rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname); - if( rc==SQLITE_OK && zSuper[0] ){ - rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); - } -@@ -60289,7 +61025,7 @@ end_playback: - ** which case it requires 4 0x00 bytes in memory immediately before - ** the filename. */ - zSuper = &pPager->pTmpSpace[4]; -- rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); -+ rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname); - testcase( rc!=SQLITE_OK ); - } - if( rc==SQLITE_OK -@@ -62060,6 +62796,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( - const char *zUri = 0; /* URI args to copy */ - int nUriByte = 1; /* Number of bytes of URI args at *zUri */ - -+ - /* Figure out how much space is required for each journal file-handle - ** (there are two of them, the main journal and the sub-journal). */ - journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); -@@ -62085,8 +62822,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen( - */ - if( zFilename && zFilename[0] ){ - const char *z; -- nPathname = pVfs->mxPathname+1; -- zPathname = sqlite3DbMallocRaw(0, nPathname*2); -+ nPathname = pVfs->mxPathname + 1; -+ zPathname = sqlite3DbMallocRaw(0, 2*(i64)nPathname); - if( zPathname==0 ){ - return SQLITE_NOMEM_BKPT; - } -@@ -62173,14 +62910,14 @@ SQLITE_PRIVATE int sqlite3PagerOpen( - ROUND8(sizeof(*pPager)) + /* Pager structure */ - ROUND8(pcacheSize) + /* PCache object */ - ROUND8(pVfs->szOsFile) + /* The main db file */ -- journalFileSize * 2 + /* The two journal files */ -+ (u64)journalFileSize * 2 + /* The two journal files */ - SQLITE_PTRSIZE + /* Space to hold a pointer */ - 4 + /* Database prefix */ -- nPathname + 1 + /* database filename */ -- nUriByte + /* query parameters */ -- nPathname + 8 + 1 + /* Journal filename */ -+ (u64)nPathname + 1 + /* database filename */ -+ (u64)nUriByte + /* query parameters */ -+ (u64)nPathname + 8 + 1 + /* Journal filename */ - #ifndef SQLITE_OMIT_WAL -- nPathname + 4 + 1 + /* WAL filename */ -+ (u64)nPathname + 4 + 1 + /* WAL filename */ - #endif - 3 /* Terminator */ - ); -@@ -64903,6 +65640,11 @@ static int pagerOpenWal(Pager *pPager){ - pPager->fd, pPager->zWal, pPager->exclusiveMode, - pPager->journalSizeLimit, &pPager->pWal - ); -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ if( rc==SQLITE_OK ){ -+ sqlite3WalDb(pPager->pWal, pPager->dbWal); -+ } -+#endif - } - pagerFixMaplimit(pPager); - -@@ -65022,6 +65764,7 @@ SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ - ** blocking locks are required. - */ - SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ -+ pPager->dbWal = db; - if( pagerUseWal(pPager) ){ - sqlite3WalDb(pPager->pWal, db); - } -@@ -65635,6 +66378,11 @@ struct WalCkptInfo { - /* - ** An open write-ahead log file is represented by an instance of the - ** following object. -+** -+** writeLock: -+** This is usually set to 1 whenever the WRITER lock is held. However, -+** if it is set to 2, then the WRITER lock is held but must be released -+** by walHandleException() if a SEH exception is thrown. - */ - struct Wal { - sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ -@@ -65725,9 +66473,13 @@ struct WalIterator { - u32 *aPgno; /* Array of page numbers. */ - int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ - int iZero; /* Frame number associated with aPgno[0] */ -- } aSegment[1]; /* One for every 32KB page in the wal-index */ -+ } aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */ - }; - -+/* Size (in bytes) of a WalIterator object suitable for N or fewer segments */ -+#define SZ_WALITERATOR(N) \ -+ (offsetof(WalIterator,aSegment)*(N)*sizeof(struct WalSegment)) -+ - /* - ** Define the parameters of the hash tables in the wal-index file. There - ** is a hash-table following every HASHTABLE_NPAGE page numbers in the -@@ -65886,7 +66638,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc( - - /* Enlarge the pWal->apWiData[] array if required */ - if( pWal->nWiData<=iPage ){ -- sqlite3_int64 nByte = sizeof(u32*)*(iPage+1); -+ sqlite3_int64 nByte = sizeof(u32*)*(1+(i64)iPage); - volatile u32 **apNew; - apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte); - if( !apNew ){ -@@ -65995,10 +66747,8 @@ static void walChecksumBytes( - s1 = s2 = 0; - } - -- assert( nByte>=8 ); -- assert( (nByte&0x00000007)==0 ); -- assert( nByte<=65536 ); -- assert( nByte%4==0 ); -+ /* nByte is a multiple of 8 between 8 and 65536 */ -+ assert( nByte>=8 && (nByte&7)==0 && nByte<=65536 ); - - if( !nativeCksum ){ - do { -@@ -67088,8 +67838,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ - - /* Allocate space for the WalIterator object. */ - nSegment = walFramePage(iLast) + 1; -- nByte = sizeof(WalIterator) -- + (nSegment-1)*sizeof(struct WalSegment) -+ nByte = SZ_WALITERATOR(nSegment) - + iLast*sizeof(ht_slot); - p = (WalIterator *)sqlite3_malloc64(nByte - + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) -@@ -67160,7 +67909,7 @@ static int walEnableBlockingMs(Wal *pWal, int nMs){ - static int walEnableBlocking(Wal *pWal){ - int res = 0; - if( pWal->db ){ -- int tmout = pWal->db->busyTimeout; -+ int tmout = pWal->db->setlkTimeout; - if( tmout ){ - res = walEnableBlockingMs(pWal, tmout); - } -@@ -67546,7 +68295,9 @@ static int walHandleException(Wal *pWal){ - static const int S = 1; - static const int E = (1<lockMask & ~( -+ u32 mUnlock; -+ if( pWal->writeLock==2 ) pWal->writeLock = 0; -+ mUnlock = pWal->lockMask & ~( - (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) - | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) - | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) -@@ -67818,7 +68569,12 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ - if( bWriteLock - || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) - ){ -- pWal->writeLock = 1; -+ /* If the write-lock was just obtained, set writeLock to 2 instead of -+ ** the usual 1. This causes walIndexPage() to behave as if the -+ ** write-lock were held (so that it allocates new pages as required), -+ ** and walHandleException() to unlock the write-lock if a SEH exception -+ ** is thrown. */ -+ if( !bWriteLock ) pWal->writeLock = 2; - if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ - badHdr = walIndexTryHdr(pWal, pChanged); - if( badHdr ){ -@@ -68182,7 +68938,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ - rc = walIndexReadHdr(pWal, pChanged); - } - #ifdef SQLITE_ENABLE_SETLK_TIMEOUT -- walDisableBlocking(pWal); - if( rc==SQLITE_BUSY_TIMEOUT ){ - rc = SQLITE_BUSY; - *pCnt |= WAL_RETRY_BLOCKED_MASK; -@@ -68197,6 +68952,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ - ** WAL_RETRY this routine will be called again and will probably be - ** right on the second iteration. - */ -+ (void)walEnableBlocking(pWal); - if( pWal->apWiData[0]==0 ){ - /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. - ** We assume this is a transient condition, so return WAL_RETRY. The -@@ -68213,6 +68969,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ - rc = SQLITE_BUSY_RECOVERY; - } - } -+ walDisableBlocking(pWal); - if( rc!=SQLITE_OK ){ - return rc; - } -@@ -68603,8 +69360,11 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ - ** read-lock. - */ - SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ -- sqlite3WalEndWriteTransaction(pWal); -+#ifndef SQLITE_ENABLE_SETLK_TIMEOUT -+ assert( pWal->writeLock==0 || pWal->readLock<0 ); -+#endif - if( pWal->readLock>=0 ){ -+ sqlite3WalEndWriteTransaction(pWal); - walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); - pWal->readLock = -1; - } -@@ -68797,7 +69557,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ - ** read-transaction was even opened, making this call a no-op. - ** Return early. */ - if( pWal->writeLock ){ -- assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) ); -+ assert( !memcmp(&pWal->hdr,(void*)pWal->apWiData[0],sizeof(WalIndexHdr)) ); - return SQLITE_OK; - } - #endif -@@ -68897,6 +69657,7 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p - if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); - } - SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) -+ pWal->iReCksum = 0; - } - return rc; - } -@@ -68944,6 +69705,9 @@ SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ - walCleanupHash(pWal); - } - SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) -+ if( pWal->iReCksum>pWal->hdr.mxFrame ){ -+ pWal->iReCksum = 0; -+ } - } - - return rc; -@@ -70246,6 +71010,12 @@ struct CellInfo { - */ - #define BTCURSOR_MAX_DEPTH 20 - -+/* -+** Maximum amount of storage local to a database page, regardless of -+** page size. -+*/ -+#define BT_MAX_LOCAL 65501 /* 65536 - 35 */ -+ - /* - ** A cursor is a pointer to a particular entry within a particular - ** b-tree within a database file. -@@ -70654,7 +71424,7 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ - */ - static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ - int i; -- int skipOk = 1; -+ u8 skipOk = 1; - Btree *p; - assert( sqlite3_mutex_held(db->mutex) ); - for(i=0; inDb; i++){ -@@ -71510,7 +72280,7 @@ static int saveCursorKey(BtCursor *pCur){ - ** below. */ - void *pKey; - pCur->nKey = sqlite3BtreePayloadSize(pCur); -- pKey = sqlite3Malloc( pCur->nKey + 9 + 8 ); -+ pKey = sqlite3Malloc( ((i64)pCur->nKey) + 9 + 8 ); - if( pKey ){ - rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); - if( rc==SQLITE_OK ){ -@@ -71800,7 +72570,7 @@ SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ - */ - SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ - assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); -- pCur->hints = x; -+ pCur->hints = (u8)x; - } - - -@@ -71994,14 +72764,15 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( - static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ - int maxLocal; /* Maximum amount of payload held locally */ - maxLocal = pPage->maxLocal; -+ assert( nPayload>=0 ); - if( nPayload<=maxLocal ){ -- return nPayload; -+ return (int)nPayload; - }else{ - int minLocal; /* Minimum amount of payload held locally */ - int surplus; /* Overflow payload available for local storage */ - minLocal = pPage->minLocal; -- surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize-4); -- return ( surplus <= maxLocal ) ? surplus : minLocal; -+ surplus = (int)(minLocal +(nPayload - minLocal)%(pPage->pBt->usableSize-4)); -+ return (surplus <= maxLocal) ? surplus : minLocal; - } - } - -@@ -72111,11 +72882,13 @@ static void btreeParseCellPtr( - pInfo->pPayload = pIter; - testcase( nPayload==pPage->maxLocal ); - testcase( nPayload==(u32)pPage->maxLocal+1 ); -+ assert( nPayload>=0 ); -+ assert( pPage->maxLocal <= BT_MAX_LOCAL ); - if( nPayload<=pPage->maxLocal ){ - /* This is the (easy) common case where the entire payload fits - ** on the local page. No overflow is required. - */ -- pInfo->nSize = nPayload + (u16)(pIter - pCell); -+ pInfo->nSize = (u16)nPayload + (u16)(pIter - pCell); - if( pInfo->nSize<4 ) pInfo->nSize = 4; - pInfo->nLocal = (u16)nPayload; - }else{ -@@ -72148,11 +72921,13 @@ static void btreeParseCellPtrIndex( - pInfo->pPayload = pIter; - testcase( nPayload==pPage->maxLocal ); - testcase( nPayload==(u32)pPage->maxLocal+1 ); -+ assert( nPayload>=0 ); -+ assert( pPage->maxLocal <= BT_MAX_LOCAL ); - if( nPayload<=pPage->maxLocal ){ - /* This is the (easy) common case where the entire payload fits - ** on the local page. No overflow is required. - */ -- pInfo->nSize = nPayload + (u16)(pIter - pCell); -+ pInfo->nSize = (u16)nPayload + (u16)(pIter - pCell); - if( pInfo->nSize<4 ) pInfo->nSize = 4; - pInfo->nLocal = (u16)nPayload; - }else{ -@@ -72691,14 +73466,14 @@ static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ - ** at the end of the page. So do additional corruption checks inside this - ** routine and return SQLITE_CORRUPT if any problems are found. - */ --static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ -- u16 iPtr; /* Address of ptr to next freeblock */ -- u16 iFreeBlk; /* Address of the next freeblock */ -+static int freeSpace(MemPage *pPage, int iStart, int iSize){ -+ int iPtr; /* Address of ptr to next freeblock */ -+ int iFreeBlk; /* Address of the next freeblock */ - u8 hdr; /* Page header size. 0 or 100 */ -- u8 nFrag = 0; /* Reduction in fragmentation */ -- u16 iOrigSize = iSize; /* Original value of iSize */ -- u16 x; /* Offset to cell content area */ -- u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ -+ int nFrag = 0; /* Reduction in fragmentation */ -+ int iOrigSize = iSize; /* Original value of iSize */ -+ int x; /* Offset to cell content area */ -+ int iEnd = iStart + iSize; /* First byte past the iStart buffer */ - unsigned char *data = pPage->aData; /* Page content */ - u8 *pTmp; /* Temporary ptr into data[] */ - -@@ -72725,7 +73500,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ - } - iPtr = iFreeBlk; - } -- if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ -+ if( iFreeBlk>(int)pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ - return SQLITE_CORRUPT_PAGE(pPage); - } - assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB ); -@@ -72740,7 +73515,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ - nFrag = iFreeBlk - iEnd; - if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage); - iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); -- if( iEnd > pPage->pBt->usableSize ){ -+ if( iEnd > (int)pPage->pBt->usableSize ){ - return SQLITE_CORRUPT_PAGE(pPage); - } - iSize = iEnd - iStart; -@@ -72761,7 +73536,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ - } - } - if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); -- data[hdr+7] -= nFrag; -+ data[hdr+7] -= (u8)nFrag; - } - pTmp = &data[hdr+5]; - x = get2byte(pTmp); -@@ -72782,7 +73557,8 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ - /* Insert the new freeblock into the freelist */ - put2byte(&data[iPtr], iStart); - put2byte(&data[iStart], iFreeBlk); -- put2byte(&data[iStart+2], iSize); -+ assert( iSize>=0 && iSize<=0xffff ); -+ put2byte(&data[iStart+2], (u16)iSize); - } - pPage->nFree += iOrigSize; - return SQLITE_OK; -@@ -73008,7 +73784,7 @@ static int btreeInitPage(MemPage *pPage){ - assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); - pPage->maskPage = (u16)(pBt->pageSize - 1); - pPage->nOverflow = 0; -- pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize; -+ pPage->cellOffset = (u16)(pPage->hdrOffset + 8 + pPage->childPtrSize); - pPage->aCellIdx = data + pPage->childPtrSize + 8; - pPage->aDataEnd = pPage->aData + pBt->pageSize; - pPage->aDataOfst = pPage->aData + pPage->childPtrSize; -@@ -73042,8 +73818,8 @@ static int btreeInitPage(MemPage *pPage){ - static void zeroPage(MemPage *pPage, int flags){ - unsigned char *data = pPage->aData; - BtShared *pBt = pPage->pBt; -- u8 hdr = pPage->hdrOffset; -- u16 first; -+ int hdr = pPage->hdrOffset; -+ int first; - - assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB ); - assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); -@@ -73060,7 +73836,7 @@ static void zeroPage(MemPage *pPage, int flags){ - put2byte(&data[hdr+5], pBt->usableSize); - pPage->nFree = (u16)(pBt->usableSize - first); - decodeFlags(pPage, flags); -- pPage->cellOffset = first; -+ pPage->cellOffset = (u16)first; - pPage->aDataEnd = &data[pBt->pageSize]; - pPage->aCellIdx = &data[first]; - pPage->aDataOfst = &data[pPage->childPtrSize]; -@@ -73846,7 +74622,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, - BtShared *pBt = p->pBt; - assert( nReserve>=0 && nReserve<=255 ); - sqlite3BtreeEnter(p); -- pBt->nReserveWanted = nReserve; -+ pBt->nReserveWanted = (u8)nReserve; - x = pBt->pageSize - pBt->usableSize; - if( nReservebtsFlags & BTS_PAGESIZE_FIXED ){ -@@ -73952,7 +74728,7 @@ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ - assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) ); - if( newFlag>=0 ){ - p->pBt->btsFlags &= ~BTS_FAST_SECURE; -- p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag; -+ p->pBt->btsFlags |= (u16)(BTS_SECURE_DELETE*newFlag); - } - b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE; - sqlite3BtreeLeave(p); -@@ -74472,6 +75248,13 @@ static SQLITE_NOINLINE int btreeBeginTrans( - (void)sqlite3PagerWalWriteLock(pPager, 0); - unlockBtreeIfUnused(pBt); - } -+#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) -+ if( rc==SQLITE_BUSY_TIMEOUT ){ -+ /* If a blocking lock timed out, break out of the loop here so that -+ ** the busy-handler is not invoked. */ -+ break; -+ } -+#endif - }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && - btreeInvokeBusyHandler(pBt) ); - sqlite3PagerWalDb(pPager, 0); -@@ -76881,7 +77664,7 @@ bypass_moveto_root: - rc = SQLITE_CORRUPT_PAGE(pPage); - goto moveto_index_finish; - } -- pCellKey = sqlite3Malloc( nCell+nOverrun ); -+ pCellKey = sqlite3Malloc( (u64)nCell+(u64)nOverrun ); - if( pCellKey==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto moveto_index_finish; -@@ -78400,7 +79183,8 @@ static int rebuildPage( - } - - /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ -- pPg->nCell = nCell; -+ assert( nCell < 10922 ); -+ pPg->nCell = (u16)nCell; - pPg->nOverflow = 0; - - put2byte(&aData[hdr+1], 0); -@@ -78647,9 +79431,13 @@ static int editPage( - if( pageInsertArray( - pPg, pBegin, &pData, pCellptr, - iNew+nCell, nNew-nCell, pCArray -- ) ) goto editpage_fail; -+ ) -+ ){ -+ goto editpage_fail; -+ } - -- pPg->nCell = nNew; -+ assert( nNew < 10922 ); -+ pPg->nCell = (u16)nNew; - pPg->nOverflow = 0; - - put2byte(&aData[hdr+3], pPg->nCell); -@@ -78958,7 +79746,7 @@ static int balance_nonroot( - int pageFlags; /* Value of pPage->aData[0] */ - int iSpace1 = 0; /* First unused byte of aSpace1[] */ - int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ -- int szScratch; /* Size of scratch memory requested */ -+ u64 szScratch; /* Size of scratch memory requested */ - MemPage *apOld[NB]; /* pPage and up to two siblings */ - MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ - u8 *pRight; /* Location in parent of right-sibling pointer */ -@@ -80243,7 +81031,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( - if( pCur->info.nKey==pX->nKey ){ - BtreePayload x2; - x2.pData = pX->pKey; -- x2.nData = pX->nKey; -+ x2.nData = (int)pX->nKey; assert( pX->nKey<=0x7fffffff ); - x2.nZero = 0; - return btreeOverwriteCell(pCur, &x2); - } -@@ -80424,7 +81212,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 - - getCellInfo(pSrc); - if( pSrc->info.nPayload<0x80 ){ -- *(aOut++) = pSrc->info.nPayload; -+ *(aOut++) = (u8)pSrc->info.nPayload; - }else{ - aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); - } -@@ -80437,7 +81225,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 - nRem = pSrc->info.nPayload; - if( nIn==nRem && nInpPage->maxLocal ){ - memcpy(aOut, aIn, nIn); -- pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); -+ pBt->nPreformatSize = nIn + (int)(aOut - pBt->pTmpSpace); - return SQLITE_OK; - }else{ - int rc = SQLITE_OK; -@@ -80449,7 +81237,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 - u32 nOut; /* Size of output buffer aOut[] */ - - nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); -- pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace); -+ pBt->nPreformatSize = (int)nOut + (int)(aOut - pBt->pTmpSpace); - if( nOutinfo.nPayload ){ - pPgnoOut = &aOut[nOut]; - pBt->nPreformatSize += 4; -@@ -82070,6 +82858,7 @@ SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ - */ - SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ - BtShared *pBt = p->pBt; -+ assert( nBytes==0 || nBytes==sizeof(Schema) ); - sqlite3BtreeEnter(p); - if( !pBt->pSchema && nBytes ){ - pBt->pSchema = sqlite3DbMallocZero(0, nBytes); -@@ -83186,7 +83975,7 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ - ** corresponding string value, then it is important that the string be - ** derived from the numeric value, not the other way around, to ensure - ** that the index and table are consistent. See ticket --** https://www.sqlite.org/src/info/343634942dd54ab (2018-01-31) for -+** https://sqlite.org/src/info/343634942dd54ab (2018-01-31) for - ** an example. - ** - ** This routine looks at pMem to verify that if it has both a numeric -@@ -83372,7 +84161,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ - return; - } - if( pMem->enc!=SQLITE_UTF8 ) return; -- if( NEVER(pMem->z==0) ) return; -+ assert( pMem->z!=0 ); - if( pMem->flags & MEM_Dyn ){ - if( pMem->xDel==sqlite3_free - && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1) -@@ -84485,7 +85274,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ - - if( pRec==0 ){ - Index *pIdx = p->pIdx; /* Index being probed */ -- int nByte; /* Bytes of space to allocate */ -+ i64 nByte; /* Bytes of space to allocate */ - int i; /* Counter variable */ - int nCol = pIdx->nColumn; /* Number of index columns including rowid */ - -@@ -84551,7 +85340,7 @@ static int valueFromFunction( - ){ - sqlite3_context ctx; /* Context object for function invocation */ - sqlite3_value **apVal = 0; /* Function arguments */ -- int nVal = 0; /* Size of apVal[] array */ -+ int nVal = 0; /* Number of function arguments */ - FuncDef *pFunc = 0; /* Function definition */ - sqlite3_value *pVal = 0; /* New value */ - int rc = SQLITE_OK; /* Return code */ -@@ -85549,12 +86338,10 @@ SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall( - int eCallCtx /* Calling context */ - ){ - Vdbe *v = pParse->pVdbe; -- int nByte; - int addr; - sqlite3_context *pCtx; - assert( v ); -- nByte = sizeof(*pCtx) + (nArg-1)*sizeof(sqlite3_value*); -- pCtx = sqlite3DbMallocRawNN(pParse->db, nByte); -+ pCtx = sqlite3DbMallocRawNN(pParse->db, SZ_CONTEXT(nArg)); - if( pCtx==0 ){ - assert( pParse->db->mallocFailed ); - freeEphemeralFunction(pParse->db, (FuncDef*)pFunc); -@@ -85830,7 +86617,7 @@ static Op *opIterNext(VdbeOpIter *p){ - } - - if( pRet->p4type==P4_SUBPROGRAM ){ -- int nByte = (p->nSub+1)*sizeof(SubProgram*); -+ i64 nByte = (1+(u64)p->nSub)*sizeof(SubProgram*); - int j; - for(j=0; jnSub; j++){ - if( p->apSub[j]==pRet->p4.pProgram ) break; -@@ -85960,8 +86747,8 @@ SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){ - ** (1) For each jump instruction with a negative P2 value (a label) - ** resolve the P2 value to an actual address. - ** --** (2) Compute the maximum number of arguments used by any SQL function --** and store that value in *pMaxFuncArgs. -+** (2) Compute the maximum number of arguments used by the xUpdate/xFilter -+** methods of any virtual table and store that value in *pMaxVtabArgs. - ** - ** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately - ** indicate what the prepared statement actually does. -@@ -85974,8 +86761,8 @@ SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){ - ** script numbers the opcodes correctly. Changes to this routine must be - ** coordinated with changes to mkopcodeh.tcl. - */ --static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ -- int nMaxArgs = *pMaxFuncArgs; -+static void resolveP2Values(Vdbe *p, int *pMaxVtabArgs){ -+ int nMaxVtabArgs = *pMaxVtabArgs; - Op *pOp; - Parse *pParse = p->pParse; - int *aLabel = pParse->aLabel; -@@ -86020,15 +86807,19 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ - } - #ifndef SQLITE_OMIT_VIRTUALTABLE - case OP_VUpdate: { -- if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; -+ if( pOp->p2>nMaxVtabArgs ) nMaxVtabArgs = pOp->p2; - break; - } - case OP_VFilter: { - int n; -+ /* The instruction immediately prior to VFilter will be an -+ ** OP_Integer that sets the "argc" value for the VFilter. See -+ ** the code where OP_VFilter is generated at tag-20250207a. */ - assert( (pOp - p->aOp) >= 3 ); - assert( pOp[-1].opcode==OP_Integer ); -+ assert( pOp[-1].p2==pOp->p3+1 ); - n = pOp[-1].p1; -- if( n>nMaxArgs ) nMaxArgs = n; -+ if( n>nMaxVtabArgs ) nMaxVtabArgs = n; - /* Fall through into the default case */ - /* no break */ deliberate_fall_through - } -@@ -86069,7 +86860,7 @@ resolve_p2_values_loop_exit: - pParse->aLabel = 0; - } - pParse->nLabel = 0; -- *pMaxFuncArgs = nMaxArgs; -+ *pMaxVtabArgs = nMaxVtabArgs; - assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); - } - -@@ -86298,7 +87089,7 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus( - const char *zName /* Name of table or index being scanned */ - ){ - if( IS_STMT_SCANSTATUS(p->db) ){ -- sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); -+ i64 nByte = (1+(i64)p->nScan) * sizeof(ScanStatus); - ScanStatus *aNew; - aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); - if( aNew ){ -@@ -86408,6 +87199,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ - */ - SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ - VdbeOp *pOp = sqlite3VdbeGetLastOp(p); -+#ifdef SQLITE_DEBUG -+ while( pOp->opcode==OP_ReleaseReg ) pOp--; -+#endif - if( pOp->p3==iDest && pOp->opcode==OP_Column ){ - pOp->p5 |= OPFLAG_TYPEOFARG; - } -@@ -87747,7 +88541,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( - int nVar; /* Number of parameters */ - int nMem; /* Number of VM memory registers */ - int nCursor; /* Number of cursors required */ -- int nArg; /* Number of arguments in subprograms */ -+ int nArg; /* Max number args to xFilter or xUpdate */ - int n; /* Loop counter */ - struct ReusableSpace x; /* Reusable bulk memory */ - -@@ -87819,6 +88613,9 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( - p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); - } - } -+#ifdef SQLITE_DEBUG -+ p->napArg = nArg; -+#endif - - if( db->mallocFailed ){ - p->nVar = 0; -@@ -89316,6 +90113,7 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( - ){ - UnpackedRecord *p; /* Unpacked record to return */ - int nByte; /* Number of bytes required for *p */ -+ assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); - nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); - p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); - if( !p ) return 0; -@@ -90622,10 +91420,11 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( - preupdate.pCsr = pCsr; - preupdate.op = op; - preupdate.iNewReg = iReg; -- preupdate.keyinfo.db = db; -- preupdate.keyinfo.enc = ENC(db); -- preupdate.keyinfo.nKeyField = pTab->nCol; -- preupdate.keyinfo.aSortFlags = (u8*)&fakeSortOrder; -+ preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; -+ preupdate.pKeyinfo->db = db; -+ preupdate.pKeyinfo->enc = ENC(db); -+ preupdate.pKeyinfo->nKeyField = pTab->nCol; -+ preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; - preupdate.iKey1 = iKey1; - preupdate.iKey2 = iKey2; - preupdate.pTab = pTab; -@@ -90635,8 +91434,8 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( - db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); - db->pPreUpdate = 0; - sqlite3DbFree(db, preupdate.aRecord); -- vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); -- vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); -+ vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pUnpacked); -+ vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pNewUnpacked); - sqlite3VdbeMemRelease(&preupdate.oldipk); - if( preupdate.aNew ){ - int i; -@@ -92467,7 +93266,7 @@ SQLITE_API int sqlite3_bind_text64( - assert( xDel!=SQLITE_DYNAMIC ); - if( enc!=SQLITE_UTF8 ){ - if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; -- nData &= ~(u16)1; -+ nData &= ~(u64)1; - } - return bindText(pStmt, i, zData, nData, xDel, enc); - } -@@ -92875,7 +93674,7 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa - if( !aRec ) goto preupdate_old_out; - rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); - if( rc==SQLITE_OK ){ -- p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); -+ p->pUnpacked = vdbeUnpackRecord(p->pKeyinfo, nRec, aRec); - if( !p->pUnpacked ) rc = SQLITE_NOMEM; - } - if( rc!=SQLITE_OK ){ -@@ -92892,7 +93691,9 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa - Column *pCol = &p->pTab->aCol[iIdx]; - if( pCol->iDflt>0 ){ - if( p->apDflt==0 ){ -- int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; -+ int nByte; -+ assert( sizeof(sqlite3_value*)*UMXV(p->pTab->nCol) < 0x7fffffff ); -+ nByte = sizeof(sqlite3_value*)*p->pTab->nCol; - p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); - if( p->apDflt==0 ) goto preupdate_old_out; - } -@@ -92938,7 +93739,7 @@ SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ - #else - p = db->pPreUpdate; - #endif -- return (p ? p->keyinfo.nKeyField : 0); -+ return (p ? p->pKeyinfo->nKeyField : 0); - } - #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ - -@@ -93021,7 +93822,7 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppVa - Mem *pData = &p->v->aMem[p->iNewReg]; - rc = ExpandBlob(pData); - if( rc!=SQLITE_OK ) goto preupdate_new_out; -- pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z); -+ pUnpack = vdbeUnpackRecord(p->pKeyinfo, pData->n, pData->z); - if( !pUnpack ){ - rc = SQLITE_NOMEM; - goto preupdate_new_out; -@@ -93042,7 +93843,8 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppVa - */ - assert( p->op==SQLITE_UPDATE ); - if( !p->aNew ){ -- p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField); -+ assert( sizeof(Mem)*UMXV(p->pCsr->nField) < 0x7fffffff ); -+ p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem)*p->pCsr->nField); - if( !p->aNew ){ - rc = SQLITE_NOMEM; - goto preupdate_new_out; -@@ -93812,11 +94614,11 @@ static VdbeCursor *allocateCursor( - */ - Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; - -- int nByte; -+ i64 nByte; - VdbeCursor *pCx = 0; -- nByte = -- ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + -- (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); -+ nByte = SZ_VDBECURSOR(nField); -+ assert( ROUND8(nByte)==nByte ); -+ if( eCurType==CURTYPE_BTREE ) nByte += sqlite3BtreeCursorSize(); - - assert( iCur>=0 && iCurnCursor ); - if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ -@@ -93840,7 +94642,7 @@ static VdbeCursor *allocateCursor( - pMem->szMalloc = 0; - return 0; - } -- pMem->szMalloc = nByte; -+ pMem->szMalloc = (int)nByte; - } - - p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; -@@ -93849,8 +94651,8 @@ static VdbeCursor *allocateCursor( - pCx->nField = nField; - pCx->aOffset = &pCx->aType[nField]; - if( eCurType==CURTYPE_BTREE ){ -- pCx->uc.pCursor = (BtCursor*) -- &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; -+ assert( ROUND8(SZ_VDBECURSOR(nField))==SZ_VDBECURSOR(nField) ); -+ pCx->uc.pCursor = (BtCursor*)&pMem->z[SZ_VDBECURSOR(nField)]; - sqlite3BtreeCursorZero(pCx->uc.pCursor); - } - return pCx; -@@ -94854,7 +95656,7 @@ case OP_Halt: { - sqlite3VdbeError(p, "%s", pOp->p4.z); - } - pcx = (int)(pOp - aOp); -- sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); -+ sqlite3_log(pOp->p1, "abort at %d: %s; [%s]", pcx, p->zErrMsg, p->zSql); - } - rc = sqlite3VdbeHalt(p); - assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); -@@ -96180,7 +96982,7 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ - break; - } - --/* Opcode: Once P1 P2 * * * -+/* Opcode: Once P1 P2 P3 * * - ** - ** Fall through to the next instruction the first time this opcode is - ** encountered on each invocation of the byte-code program. Jump to P2 -@@ -96196,6 +96998,12 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ - ** whether or not the jump should be taken. The bitmask is necessary - ** because the self-altering code trick does not work for recursive - ** triggers. -+** -+** The P3 operand is not used directly by this opcode. However P3 is -+** used by the code generator as follows: If this opcode is the start -+** of a subroutine and that subroutine uses a Bloom filter, then P3 will -+** be the register that holds that Bloom filter. See tag-202407032019 -+** in the source code for implementation details. - */ - case OP_Once: { /* jump */ - u32 iAddr; /* Address of this instruction */ -@@ -97241,6 +98049,7 @@ case OP_MakeRecord: { - zHdr += sqlite3PutVarint(zHdr, serial_type); - if( pRec->n ){ - assert( pRec->z!=0 ); -+ assert( pRec->z!=(const char*)sqlite3CtypeMap ); - memcpy(zPayload, pRec->z, pRec->n); - zPayload += pRec->n; - } -@@ -99592,7 +100401,7 @@ case OP_RowData: { - /* The OP_RowData opcodes always follow OP_NotExists or - ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions - ** that might invalidate the cursor. -- ** If this where not the case, on of the following assert()s -+ ** If this were not the case, one of the following assert()s - ** would fail. Should this ever change (because of changes in the code - ** generator) then the fix would be to insert a call to - ** sqlite3VdbeCursorMoveto(). -@@ -100861,7 +101670,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */ - */ - case OP_Program: { /* jump0 */ - int nMem; /* Number of memory registers for sub-program */ -- int nByte; /* Bytes of runtime space required for sub-program */ -+ i64 nByte; /* Bytes of runtime space required for sub-program */ - Mem *pRt; /* Register to allocate runtime space */ - Mem *pMem; /* Used to iterate through memory cells */ - Mem *pEnd; /* Last memory cell in new array */ -@@ -100912,7 +101721,7 @@ case OP_Program: { /* jump0 */ - nByte = ROUND8(sizeof(VdbeFrame)) - + nMem * sizeof(Mem) - + pProgram->nCsr * sizeof(VdbeCursor*) -- + (pProgram->nOp + 7)/8; -+ + (7 + (i64)pProgram->nOp)/8; - pFrame = sqlite3DbMallocZero(db, nByte); - if( !pFrame ){ - goto no_mem; -@@ -100920,7 +101729,7 @@ case OP_Program: { /* jump0 */ - sqlite3VdbeMemRelease(pRt); - pRt->flags = MEM_Blob|MEM_Dyn; - pRt->z = (char*)pFrame; -- pRt->n = nByte; -+ pRt->n = (int)nByte; - pRt->xDel = sqlite3VdbeFrameMemDel; - - pFrame->v = p; -@@ -101019,12 +101828,14 @@ case OP_Param: { /* out2 */ - ** statement counter is incremented (immediate foreign key constraints). - */ - case OP_FkCounter: { -- if( db->flags & SQLITE_DeferFKs ){ -- db->nDeferredImmCons += pOp->p2; -- }else if( pOp->p1 ){ -+ if( pOp->p1 ){ - db->nDeferredCons += pOp->p2; - }else{ -- p->nFkConstraint += pOp->p2; -+ if( db->flags & SQLITE_DeferFKs ){ -+ db->nDeferredImmCons += pOp->p2; -+ }else{ -+ p->nFkConstraint += pOp->p2; -+ } - } - break; - } -@@ -101239,7 +102050,7 @@ case OP_AggStep: { - ** - ** Note: We could avoid this by using a regular memory cell from aMem[] for - ** the accumulator, instead of allocating one here. */ -- nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); -+ nAlloc = ROUND8P( SZ_CONTEXT(n) ); - pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); - if( pCtx==0 ) goto no_mem; - pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); -@@ -101899,6 +102710,7 @@ case OP_VFilter: { /* jump, ncycle */ - - /* Invoke the xFilter method */ - apArg = p->apArg; -+ assert( nArg<=p->napArg ); - for(i = 0; ivtabOnConflict; - apArg = p->apArg; - pX = &aMem[pOp->p3]; -+ assert( nArg<=p->napArg ); - for(i=0; irc = rc; - sqlite3SystemError(db, rc); - testcase( sqlite3GlobalConfig.xLog!=0 ); -- sqlite3_log(rc, "statement aborts at %d: [%s] %s", -- (int)(pOp - aOp), p->zSql, p->zErrMsg); -+ sqlite3_log(rc, "statement aborts at %d: %s; [%s]", -+ (int)(pOp - aOp), p->zErrMsg, p->zSql); - if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); - if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); - if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){ -@@ -102895,6 +103708,7 @@ SQLITE_API int sqlite3_blob_open( - char *zErr = 0; - Table *pTab; - Incrblob *pBlob = 0; -+ int iDb; - Parse sParse; - - #ifdef SQLITE_ENABLE_API_ARMOR -@@ -102940,7 +103754,10 @@ SQLITE_API int sqlite3_blob_open( - sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); - } - #endif -- if( !pTab ){ -+ if( pTab==0 -+ || ((iDb = sqlite3SchemaToIndex(db, pTab->pSchema))==1 && -+ sqlite3OpenTempDatabase(&sParse)) -+ ){ - if( sParse.zErrMsg ){ - sqlite3DbFree(db, zErr); - zErr = sParse.zErrMsg; -@@ -102951,15 +103768,11 @@ SQLITE_API int sqlite3_blob_open( - goto blob_open_out; - } - pBlob->pTab = pTab; -- pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; -+ pBlob->zDb = db->aDb[iDb].zDbSName; - - /* Now search pTab for the exact column. */ -- for(iCol=0; iColnCol; iCol++) { -- if( sqlite3StrICmp(pTab->aCol[iCol].zCnName, zColumn)==0 ){ -- break; -- } -- } -- if( iCol==pTab->nCol ){ -+ iCol = sqlite3ColumnIndex(pTab, zColumn); -+ if( iCol<0 ){ - sqlite3DbFree(db, zErr); - zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); - rc = SQLITE_ERROR; -@@ -103039,7 +103852,6 @@ SQLITE_API int sqlite3_blob_open( - {OP_Halt, 0, 0, 0}, /* 5 */ - }; - Vdbe *v = (Vdbe *)pBlob->pStmt; -- int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - VdbeOp *aOp; - - sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, -@@ -103617,9 +104429,12 @@ struct VdbeSorter { - u8 iPrev; /* Previous thread used to flush PMA */ - u8 nTask; /* Size of aTask[] array */ - u8 typeMask; -- SortSubtask aTask[1]; /* One or more subtasks */ -+ SortSubtask aTask[FLEXARRAY]; /* One or more subtasks */ - }; - -+/* Size (in bytes) of a VdbeSorter object that works with N or fewer subtasks */ -+#define SZ_VDBESORTER(N) (offsetof(VdbeSorter,aTask)+(N)*sizeof(SortSubtask)) -+ - #define SORTER_TYPE_INTEGER 0x01 - #define SORTER_TYPE_TEXT 0x02 - -@@ -104221,7 +105036,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( - VdbeSorter *pSorter; /* The new sorter */ - KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */ - int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */ -- int sz; /* Size of pSorter in bytes */ -+ i64 sz; /* Size of pSorter in bytes */ - int rc = SQLITE_OK; - #if SQLITE_MAX_WORKER_THREADS==0 - # define nWorker 0 -@@ -104249,8 +105064,10 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( - assert( pCsr->pKeyInfo ); - assert( !pCsr->isEphemeral ); - assert( pCsr->eCurType==CURTYPE_SORTER ); -- szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); -- sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); -+ assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) -+ < 0x7fffffff ); -+ szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField); -+ sz = SZ_VDBESORTER(nWorker+1); - - pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); - pCsr->uc.pSorter = pSorter; -@@ -104462,7 +105279,7 @@ static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){ - */ - static MergeEngine *vdbeMergeEngineNew(int nReader){ - int N = 2; /* Smallest power of two >= nReader */ -- int nByte; /* Total bytes of space to allocate */ -+ i64 nByte; /* Total bytes of space to allocate */ - MergeEngine *pNew; /* Pointer to allocated object to return */ - - assert( nReader<=SORTER_MAX_MERGE_COUNT ); -@@ -104714,6 +105531,10 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ - p->u.pNext = 0; - for(i=0; aSlot[i]; i++){ - p = vdbeSorterMerge(pTask, p, aSlot[i]); -+ /* ,--Each aSlot[] holds twice as much as the previous. So we cannot use -+ ** | up all 64 aSlots[] with only a 64-bit address space. -+ ** v */ -+ assert( iop on success */ - Table *pTab = 0; /* Table holding the row */ -- Column *pCol; /* A column of pTab */ - ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ - const char *zCol = pRight->u.zToken; - -@@ -107556,7 +108376,6 @@ static int lookupName( - - if( pSrcList ){ - for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ -- u8 hCol; - pTab = pItem->pSTab; - assert( pTab!=0 && pTab->zName!=0 ); - assert( pTab->nCol>0 || pParse->nErr ); -@@ -107644,43 +108463,38 @@ static int lookupName( - sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); - } - } -- hCol = sqlite3StrIHash(zCol); -- for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ -- if( pCol->hName==hCol -- && sqlite3StrICmp(pCol->zCnName, zCol)==0 -- ){ -- if( cnt>0 ){ -- if( pItem->fg.isUsing==0 -- || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 -- ){ -- /* Two or more tables have the same column name which is -- ** not joined by USING. This is an error. Signal as much -- ** by clearing pFJMatch and letting cnt go above 1. */ -- sqlite3ExprListDelete(db, pFJMatch); -- pFJMatch = 0; -- }else -- if( (pItem->fg.jointype & JT_RIGHT)==0 ){ -- /* An INNER or LEFT JOIN. Use the left-most table */ -- continue; -- }else -- if( (pItem->fg.jointype & JT_LEFT)==0 ){ -- /* A RIGHT JOIN. Use the right-most table */ -- cnt = 0; -- sqlite3ExprListDelete(db, pFJMatch); -- pFJMatch = 0; -- }else{ -- /* For a FULL JOIN, we must construct a coalesce() func */ -- extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); -- } -- } -- cnt++; -- pMatch = pItem; -- /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ -- pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; -- if( pItem->fg.isNestedFrom ){ -- sqlite3SrcItemColumnUsed(pItem, j); -+ j = sqlite3ColumnIndex(pTab, zCol); -+ if( j>=0 ){ -+ if( cnt>0 ){ -+ if( pItem->fg.isUsing==0 -+ || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 -+ ){ -+ /* Two or more tables have the same column name which is -+ ** not joined by USING. This is an error. Signal as much -+ ** by clearing pFJMatch and letting cnt go above 1. */ -+ sqlite3ExprListDelete(db, pFJMatch); -+ pFJMatch = 0; -+ }else -+ if( (pItem->fg.jointype & JT_RIGHT)==0 ){ -+ /* An INNER or LEFT JOIN. Use the left-most table */ -+ continue; -+ }else -+ if( (pItem->fg.jointype & JT_LEFT)==0 ){ -+ /* A RIGHT JOIN. Use the right-most table */ -+ cnt = 0; -+ sqlite3ExprListDelete(db, pFJMatch); -+ pFJMatch = 0; -+ }else{ -+ /* For a FULL JOIN, we must construct a coalesce() func */ -+ extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); - } -- break; -+ } -+ cnt++; -+ pMatch = pItem; -+ /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ -+ pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; -+ if( pItem->fg.isNestedFrom ){ -+ sqlite3SrcItemColumnUsed(pItem, j); - } - } - if( 0==cnt && VisibleRowid(pTab) ){ -@@ -107770,23 +108584,18 @@ static int lookupName( - - if( pTab ){ - int iCol; -- u8 hCol = sqlite3StrIHash(zCol); - pSchema = pTab->pSchema; - cntTab++; -- for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){ -- if( pCol->hName==hCol -- && sqlite3StrICmp(pCol->zCnName, zCol)==0 -- ){ -- if( iCol==pTab->iPKey ){ -- iCol = -1; -- } -- break; -+ iCol = sqlite3ColumnIndex(pTab, zCol); -+ if( iCol>=0 ){ -+ if( pTab->iPKey==iCol ) iCol = -1; -+ }else{ -+ if( sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ -+ iCol = -1; -+ }else{ -+ iCol = pTab->nCol; - } - } -- if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ -- /* IMP: R-51414-32910 */ -- iCol = -1; -- } - if( iColnCol ){ - cnt++; - pMatch = 0; -@@ -108425,13 +109234,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ - ** sqlite_version() that might change over time cannot be used - ** in an index or generated column. Curiously, they can be used - ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all -- ** all this. */ -+ ** allow this. */ - sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", - NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr); - }else{ - assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */ - pExpr->op2 = pNC->ncFlags & NC_SelfRef; -- if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL); - } - if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 - && pParse->nested==0 -@@ -108447,6 +109255,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ - if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 - && !IN_RENAME_OBJECT - ){ -+ if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL); - sqlite3ExprFunctionUsable(pParse, pExpr, pDef); - } - } -@@ -109500,20 +110309,22 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference( - Expr *pExpr, /* Expression to resolve. May be NULL. */ - ExprList *pList /* Expression list to resolve. May be NULL. */ - ){ -- SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ -+ SrcList *pSrc; /* Fake SrcList for pParse->pNewTable */ - NameContext sNC; /* Name context for pParse->pNewTable */ - int rc; -+ u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */ - - assert( type==0 || pTab!=0 ); - assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr - || type==NC_GenCol || pTab==0 ); - memset(&sNC, 0, sizeof(sNC)); -- memset(&sSrc, 0, sizeof(sSrc)); -+ pSrc = (SrcList*)srcSpace; -+ memset(pSrc, 0, SZ_SRCLIST_1); - if( pTab ){ -- sSrc.nSrc = 1; -- sSrc.a[0].zName = pTab->zName; -- sSrc.a[0].pSTab = pTab; -- sSrc.a[0].iCursor = -1; -+ pSrc->nSrc = 1; -+ pSrc->a[0].zName = pTab->zName; -+ pSrc->a[0].pSTab = pTab; -+ pSrc->a[0].iCursor = -1; - if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ - /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP - ** schema elements */ -@@ -109521,7 +110332,7 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference( - } - } - sNC.pParse = pParse; -- sNC.pSrcList = &sSrc; -+ sNC.pSrcList = pSrc; - sNC.ncFlags = type | NC_IsDDL; - if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; - if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList); -@@ -109605,7 +110416,9 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ - pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr - ); - } -- if( op==TK_VECTOR ){ -+ if( op==TK_VECTOR -+ || (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER) -+ ){ - assert( ExprUseXList(pExpr) ); - return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); - } -@@ -109798,7 +110611,9 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ - p = p->pLeft; - continue; - } -- if( op==TK_VECTOR ){ -+ if( op==TK_VECTOR -+ || (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER) -+ ){ - assert( ExprUseXList(p) ); - p = p->x.pList->a[0].pExpr; - continue; -@@ -110672,7 +111487,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ - return pLeft; - }else{ - u32 f = pLeft->flags | pRight->flags; -- if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse -+ if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse|EP_HasFunc))==EP_IsFalse - && !IN_RENAME_OBJECT - ){ - sqlite3ExprDeferredDelete(pParse, pLeft); -@@ -111270,7 +112085,7 @@ static Expr *exprDup( - SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){ - With *pRet = 0; - if( p ){ -- sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); -+ sqlite3_int64 nByte = SZ_WITH(p->nCte); - pRet = sqlite3DbMallocZero(db, nByte); - if( pRet ){ - int i; -@@ -111381,7 +112196,6 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int - } - pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); - pItem->fg = pOldItem->fg; -- pItem->fg.done = 0; - pItem->u = pOldItem->u; - } - return pNew; -@@ -111398,11 +112212,9 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int - SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ - SrcList *pNew; - int i; -- int nByte; - assert( db!=0 ); - if( p==0 ) return 0; -- nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); -- pNew = sqlite3DbMallocRawNN(db, nByte ); -+ pNew = sqlite3DbMallocRawNN(db, SZ_SRCLIST(p->nSrc) ); - if( pNew==0 ) return 0; - pNew->nSrc = pNew->nAlloc = p->nSrc; - for(i=0; inSrc; i++){ -@@ -111464,7 +112276,7 @@ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ - int i; - assert( db!=0 ); - if( p==0 ) return 0; -- pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) ); -+ pNew = sqlite3DbMallocRawNN(db, SZ_IDLIST(p->nId)); - if( pNew==0 ) return 0; - pNew->nId = p->nId; - for(i=0; inId; i++){ -@@ -111496,7 +112308,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla - pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); - pNew->iLimit = 0; - pNew->iOffset = 0; -- pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; -+ pNew->selFlags = p->selFlags & ~(u32)SF_UsesEphemeral; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->nSelectRow = p->nSelectRow; -@@ -111548,7 +112360,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew( - struct ExprList_item *pItem; - ExprList *pList; - -- pList = sqlite3DbMallocRawNN(db, sizeof(ExprList)+sizeof(pList->a[0])*4 ); -+ pList = sqlite3DbMallocRawNN(db, SZ_EXPRLIST(4)); - if( pList==0 ){ - sqlite3ExprDelete(db, pExpr); - return 0; -@@ -111568,8 +112380,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendGrow( - struct ExprList_item *pItem; - ExprList *pNew; - pList->nAlloc *= 2; -- pNew = sqlite3DbRealloc(db, pList, -- sizeof(*pList)+(pList->nAlloc-1)*sizeof(pList->a[0])); -+ pNew = sqlite3DbRealloc(db, pList, SZ_EXPRLIST(pList->nAlloc)); - if( pNew==0 ){ - sqlite3ExprListDelete(db, pList); - sqlite3ExprDelete(db, pExpr); -@@ -112498,13 +113309,7 @@ SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab){ - int ii; - assert( VisibleRowid(pTab) ); - for(ii=0; iinCol; iCol++){ -- if( sqlite3_stricmp(azOpt[ii], pTab->aCol[iCol].zCnName)==0 ) break; -- } -- if( iCol==pTab->nCol ){ -- return azOpt[ii]; -- } -+ if( sqlite3ColumnIndex(pTab, azOpt[ii])<0 ) return azOpt[ii]; - } - return 0; - } -@@ -112908,7 +113713,7 @@ static char *exprINAffinity(Parse *pParse, const Expr *pExpr){ - char *zRet; - - assert( pExpr->op==TK_IN ); -- zRet = sqlite3DbMallocRaw(pParse->db, nVal+1); -+ zRet = sqlite3DbMallocRaw(pParse->db, 1+(i64)nVal); - if( zRet ){ - int i; - for(i=0; idb, pCopy); - sqlite3DbFree(pParse->db, dest.zAffSdst); - if( addrBloom ){ -+ /* Remember that location of the Bloom filter in the P3 operand -+ ** of the OP_Once that began this subroutine. tag-202407032019 */ - sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; - if( dest.iSDParm2==0 ){ -- sqlite3VdbeChangeToNoop(v, addrBloom); -- }else{ -- sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; -+ /* If the Bloom filter won't actually be used, keep it small */ -+ sqlite3VdbeGetOp(v, addrBloom)->p1 = 10; - } - } - if( rc ){ -@@ -113619,7 +114425,7 @@ static void sqlite3ExprCodeIN( - if( ExprHasProperty(pExpr, EP_Subrtn) ){ - const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); - assert( pOp->opcode==OP_Once || pParse->nErr ); -- if( pOp->opcode==OP_Once && pOp->p3>0 ){ -+ if( pOp->opcode==OP_Once && pOp->p3>0 ){ /* tag-202407032019 */ - assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); - sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, - rLhs, nVector); VdbeCoverage(v); -@@ -114211,7 +115017,7 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( - - - /* --** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This -+** Expression pExpr is guaranteed to be a TK_COLUMN or equivalent. This - ** function checks the Parse.pIdxPartExpr list to see if this column - ** can be replaced with a constant value. If so, it generates code to - ** put the constant value in a register (ideally, but not necessarily, -@@ -115468,11 +116274,11 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int - assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); - assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); -- sqlite3VdbeTypeofColumn(v, r1); -+ assert( regFree1==0 || regFree1==r1 ); -+ if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1); - sqlite3VdbeAddOp2(v, op, r1, dest); - VdbeCoverageIf(v, op==TK_ISNULL); - VdbeCoverageIf(v, op==TK_NOTNULL); -- testcase( regFree1==0 ); - break; - } - case TK_BETWEEN: { -@@ -115643,11 +116449,11 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int - case TK_ISNULL: - case TK_NOTNULL: { - r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); -- sqlite3VdbeTypeofColumn(v, r1); -+ assert( regFree1==0 || regFree1==r1 ); -+ if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1); - sqlite3VdbeAddOp2(v, op, r1, dest); - testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); - testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); -- testcase( regFree1==0 ); - break; - } - case TK_BETWEEN: { -@@ -116547,7 +117353,9 @@ static void findOrCreateAggInfoColumn( - ){ - struct AggInfo_col *pCol; - int k; -+ int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; - -+ assert( mxTerm <= SMXV(i16) ); - assert( pAggInfo->iFirstReg==0 ); - pCol = pAggInfo->aCol; - for(k=0; knColumn; k++, pCol++){ -@@ -116565,6 +117373,10 @@ static void findOrCreateAggInfoColumn( - assert( pParse->db->mallocFailed ); - return; - } -+ if( k>mxTerm ){ -+ sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); -+ k = mxTerm; -+ } - pCol = &pAggInfo->aCol[k]; - assert( ExprUseYTab(pExpr) ); - pCol->pTab = pExpr->y.pTab; -@@ -116598,6 +117410,7 @@ fix_up_expr: - if( pExpr->op==TK_COLUMN ){ - pExpr->op = TK_AGG_COLUMN; - } -+ assert( k <= SMXV(pExpr->iAgg) ); - pExpr->iAgg = (i16)k; - } - -@@ -116682,13 +117495,19 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ - ** function that is already in the pAggInfo structure - */ - struct AggInfo_func *pItem = pAggInfo->aFunc; -+ int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; -+ assert( mxTerm <= SMXV(i16) ); - for(i=0; inFunc; i++, pItem++){ - if( NEVER(pItem->pFExpr==pExpr) ) break; - if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ - break; - } - } -- if( i>=pAggInfo->nFunc ){ -+ if( i>mxTerm ){ -+ sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); -+ i = mxTerm; -+ assert( inFunc ); -+ }else if( i>=pAggInfo->nFunc ){ - /* pExpr is original. Make a new entry in pAggInfo->aFunc[] - */ - u8 enc = ENC(pParse->db); -@@ -116742,6 +117561,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ - */ - assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); - ExprSetVVAProperty(pExpr, EP_NoReduce); -+ assert( i <= SMXV(pExpr->iAgg) ); - pExpr->iAgg = (i16)i; - pExpr->pAggInfo = pAggInfo; - return WRC_Prune; -@@ -117452,13 +118272,13 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ - assert( pNew->nCol>0 ); - nAlloc = (((pNew->nCol-1)/8)*8)+8; - assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); -- pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); -+ pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*(u32)nAlloc); - pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); - if( !pNew->aCol || !pNew->zName ){ - assert( db->mallocFailed ); - goto exit_begin_add_column; - } -- memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); -+ memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*(size_t)pNew->nCol); - for(i=0; inCol; i++){ - Column *pCol = &pNew->aCol[i]; - pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); -@@ -117553,10 +118373,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( - ** altered. Set iCol to be the index of the column being renamed */ - zOld = sqlite3NameFromToken(db, pOld); - if( !zOld ) goto exit_rename_column; -- for(iCol=0; iColnCol; iCol++){ -- if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break; -- } -- if( iCol==pTab->nCol ){ -+ iCol = sqlite3ColumnIndex(pTab, zOld); -+ if( iCol<0 ){ - sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld); - goto exit_rename_column; - } -@@ -118059,6 +118877,7 @@ static int renameParseSql( - int bTemp /* True if SQL is from temp schema */ - ){ - int rc; -+ u64 flags; - - sqlite3ParseObjectInit(p, db); - if( zSql==0 ){ -@@ -118067,11 +118886,21 @@ static int renameParseSql( - if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ - return SQLITE_CORRUPT_BKPT; - } -- db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); -+ if( bTemp ){ -+ db->init.iDb = 1; -+ }else{ -+ int iDb = sqlite3FindDbName(db, zDb); -+ assert( iDb>=0 && iDb<=0xff ); -+ db->init.iDb = (u8)iDb; -+ } - p->eParseMode = PARSE_MODE_RENAME; - p->db = db; - p->nQueryLoop = 1; -+ flags = db->flags; -+ testcase( (db->flags & SQLITE_Comments)==0 && strstr(zSql," /* ")!=0 ); -+ db->flags |= SQLITE_Comments; - rc = sqlite3RunParser(p, zSql); -+ db->flags = flags; - if( db->mallocFailed ) rc = SQLITE_NOMEM; - if( rc==SQLITE_OK - && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) -@@ -118134,10 +118963,11 @@ static int renameEditSql( - nQuot = sqlite3Strlen30(zQuot)-1; - } - -- assert( nQuot>=nNew ); -- zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); -+ assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); -+ zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1); - }else{ -- zOut = (char*)sqlite3DbMallocZero(db, (nSql*2+1) * 3); -+ assert( nSql>0 ); -+ zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3); - if( zOut ){ - zBuf1 = &zOut[nSql*2+1]; - zBuf2 = &zOut[nSql*4+2]; -@@ -118149,16 +118979,17 @@ static int renameEditSql( - ** with the new column name, or with single-quoted versions of themselves. - ** All that remains is to construct and return the edited SQL string. */ - if( zOut ){ -- int nOut = nSql; -- memcpy(zOut, zSql, nSql); -+ i64 nOut = nSql; -+ assert( nSql>0 ); -+ memcpy(zOut, zSql, (size_t)nSql); - while( pRename->pList ){ - int iOff; /* Offset of token to replace in zOut */ -- u32 nReplace; -+ i64 nReplace; - const char *zReplace; - RenameToken *pBest = renameColumnTokenNext(pRename); - - if( zNew ){ -- if( bQuote==0 && sqlite3IsIdChar(*pBest->t.z) ){ -+ if( bQuote==0 && sqlite3IsIdChar(*(u8*)pBest->t.z) ){ - nReplace = nNew; - zReplace = zNew; - }else{ -@@ -118176,14 +119007,15 @@ static int renameEditSql( - memcpy(zBuf1, pBest->t.z, pBest->t.n); - zBuf1[pBest->t.n] = 0; - sqlite3Dequote(zBuf1); -- sqlite3_snprintf(nSql*2, zBuf2, "%Q%s", zBuf1, -+ assert( nSql < 0x15555554 /* otherwise malloc would have failed */ ); -+ sqlite3_snprintf((int)(nSql*2), zBuf2, "%Q%s", zBuf1, - pBest->t.z[pBest->t.n]=='\'' ? " " : "" - ); - zReplace = zBuf2; - nReplace = sqlite3Strlen30(zReplace); - } - -- iOff = pBest->t.z - zSql; -+ iOff = (int)(pBest->t.z - zSql); - if( pBest->t.n!=nReplace ){ - memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], - nOut - (iOff + pBest->t.n) -@@ -118209,11 +119041,12 @@ static int renameEditSql( - ** Set all pEList->a[].fg.eEName fields in the expression-list to val. - */ - static void renameSetENames(ExprList *pEList, int val){ -+ assert( val==ENAME_NAME || val==ENAME_TAB || val==ENAME_SPAN ); - if( pEList ){ - int i; - for(i=0; inExpr; i++){ - assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); -- pEList->a[i].fg.eEName = val; -+ pEList->a[i].fg.eEName = val&0x3; - } - } - } -@@ -118470,7 +119303,7 @@ static void renameColumnFunc( - if( sParse.pNewTable ){ - if( IsView(sParse.pNewTable) ){ - Select *pSelect = sParse.pNewTable->u.view.pSelect; -- pSelect->selFlags &= ~SF_View; -+ pSelect->selFlags &= ~(u32)SF_View; - sParse.rc = SQLITE_OK; - sqlite3SelectPrep(&sParse, pSelect, 0); - rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); -@@ -118688,7 +119521,7 @@ static void renameTableFunc( - sNC.pParse = &sParse; - - assert( pSelect->selFlags & SF_View ); -- pSelect->selFlags &= ~SF_View; -+ pSelect->selFlags &= ~(u32)SF_View; - sqlite3SelectPrep(&sParse, pTab->u.view.pSelect, &sNC); - if( sParse.nErr ){ - rc = sParse.rc; -@@ -118861,7 +119694,7 @@ static void renameQuotefixFunc( - if( sParse.pNewTable ){ - if( IsView(sParse.pNewTable) ){ - Select *pSelect = sParse.pNewTable->u.view.pSelect; -- pSelect->selFlags &= ~SF_View; -+ pSelect->selFlags &= ~(u32)SF_View; - sParse.rc = SQLITE_OK; - sqlite3SelectPrep(&sParse, pSelect, 0); - rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); -@@ -118960,10 +119793,10 @@ static void renameTableTest( - if( zDb && zInput ){ - int rc; - Parse sParse; -- int flags = db->flags; -+ u64 flags = db->flags; - if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL); - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); -- db->flags |= (flags & (SQLITE_DqsDML|SQLITE_DqsDDL)); -+ db->flags = flags; - if( rc==SQLITE_OK ){ - if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){ - NameContext sNC; -@@ -119455,7 +120288,8 @@ static void openStatTable( - sqlite3NestedParse(pParse, - "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols - ); -- aRoot[i] = (u32)pParse->regRoot; -+ assert( pParse->isCreate || pParse->nErr ); -+ aRoot[i] = (u32)pParse->u1.cr.regRoot; - aCreateTbl[i] = OPFLAG_P2ISREG; - } - }else{ -@@ -119646,7 +120480,7 @@ static void statInit( - int nCol; /* Number of columns in index being sampled */ - int nKeyCol; /* Number of key columns */ - int nColUp; /* nCol rounded up for alignment */ -- int n; /* Bytes of space to allocate */ -+ i64 n; /* Bytes of space to allocate */ - sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */ - #ifdef SQLITE_ENABLE_STAT4 - /* Maximum number of samples. 0 if STAT4 data is not collected */ -@@ -119682,7 +120516,7 @@ static void statInit( - p->db = db; - p->nEst = sqlite3_value_int64(argv[2]); - p->nRow = 0; -- p->nLimit = sqlite3_value_int64(argv[3]); -+ p->nLimit = sqlite3_value_int(argv[3]); - p->nCol = nCol; - p->nKeyCol = nKeyCol; - p->nSkipAhead = 0; -@@ -120815,16 +121649,6 @@ static void decodeIntArray( - while( z[0]!=0 && z[0]!=' ' ) z++; - while( z[0]==' ' ) z++; - } -- -- /* Set the bLowQual flag if the peak number of rows obtained -- ** from a full equality match is so large that a full table scan -- ** seems likely to be faster than using the index. -- */ -- if( aLog[0] > 66 /* Index has more than 100 rows */ -- && aLog[0] <= aLog[nOut-1] /* And only a single value seen */ -- ){ -- pIndex->bLowQual = 1; -- } - } - } - -@@ -121420,7 +122244,7 @@ static void attachFunc( - if( aNew==0 ) return; - memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); - }else{ -- aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); -+ aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(1+(i64)db->nDb)); - if( aNew==0 ) return; - } - db->aDb = aNew; -@@ -121491,6 +122315,13 @@ static void attachFunc( - sqlite3BtreeEnterAll(db); - db->init.iDb = 0; - db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ if( db->setlkFlags & SQLITE_SETLK_BLOCK_ON_CONNECT ){ -+ int val = 1; -+ sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pNew->pBt)); -+ sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, &val); -+ } -+#endif - if( !REOPEN_AS_MEMDB(db) ){ - rc = sqlite3Init(db, &zErrDyn); - } -@@ -122213,6 +123044,7 @@ static SQLITE_NOINLINE void lockTable( - } - } - -+ assert( pToplevel->nTableLock < 0x7fff0000 ); - nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); - pToplevel->aTableLock = - sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); -@@ -122313,10 +123145,12 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ - || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); - if( v ){ - if( pParse->bReturning ){ -- Returning *pReturning = pParse->u1.pReturning; -+ Returning *pReturning; - int addrRewind; - int reg; - -+ assert( !pParse->isCreate ); -+ pReturning = pParse->u1.d.pReturning; - if( pReturning->nRetCol ){ - sqlite3VdbeAddOp0(v, OP_FkCheck); - addrRewind = -@@ -122392,7 +123226,9 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ - } - - if( pParse->bReturning ){ -- Returning *pRet = pParse->u1.pReturning; -+ Returning *pRet; -+ assert( !pParse->isCreate ); -+ pRet = pParse->u1.d.pReturning; - if( pRet->nRetCol ){ - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); - } -@@ -123207,10 +124043,16 @@ SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){ - ** find the (first) offset of that column in index pIdx. Or return -1 - ** if column iCol is not used in index pIdx. - */ --SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ -+SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){ - int i; -+ i16 iCol16; -+ assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN ); -+ assert( pIdx->nColumn<=SQLITE_MAX_COLUMN+1 ); -+ iCol16 = iCol; - for(i=0; inColumn; i++){ -- if( iCol==pIdx->aiColumn[i] ) return i; -+ if( iCol16==pIdx->aiColumn[i] ){ -+ return i; -+ } - } - return -1; - } -@@ -123464,8 +124306,9 @@ SQLITE_PRIVATE void sqlite3StartTable( - /* If the file format and encoding in the database have not been set, - ** set them now. - */ -- reg1 = pParse->regRowid = ++pParse->nMem; -- reg2 = pParse->regRoot = ++pParse->nMem; -+ assert( pParse->isCreate ); -+ reg1 = pParse->u1.cr.regRowid = ++pParse->nMem; -+ reg2 = pParse->u1.cr.regRoot = ++pParse->nMem; - reg3 = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); - sqlite3VdbeUsesBtree(v, iDb); -@@ -123480,8 +124323,8 @@ SQLITE_PRIVATE void sqlite3StartTable( - ** The record created does not contain anything yet. It will be replaced - ** by the real entry in code generated at sqlite3EndTable(). - ** -- ** The rowid for the new entry is left in register pParse->regRowid. -- ** The root page number of the new table is left in reg pParse->regRoot. -+ ** The rowid for the new entry is left in register pParse->u1.cr.regRowid. -+ ** The root page of the new table is left in reg pParse->u1.cr.regRoot. - ** The rowid and root page number values are needed by the code that - ** sqlite3EndTable will generate. - */ -@@ -123492,7 +124335,7 @@ SQLITE_PRIVATE void sqlite3StartTable( - #endif - { - assert( !pParse->bReturning ); -- pParse->u1.addrCrTab = -+ pParse->u1.cr.addrCrTab = - sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); - } - sqlite3OpenSchemaTable(pParse, iDb); -@@ -123570,7 +124413,8 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ - sqlite3ExprListDelete(db, pList); - return; - } -- pParse->u1.pReturning = pRet; -+ assert( !pParse->isCreate ); -+ pParse->u1.d.pReturning = pRet; - pRet->pParse = pParse; - pRet->pReturnEL = pList; - sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet); -@@ -123612,7 +124456,6 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ - char *zType; - Column *pCol; - sqlite3 *db = pParse->db; -- u8 hName; - Column *aNew; - u8 eType = COLTYPE_CUSTOM; - u8 szEst = 1; -@@ -123666,13 +124509,10 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ - memcpy(z, sName.z, sName.n); - z[sName.n] = 0; - sqlite3Dequote(z); -- hName = sqlite3StrIHash(z); -- for(i=0; inCol; i++){ -- if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zCnName)==0 ){ -- sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); -- sqlite3DbFree(db, z); -- return; -- } -+ if( p->nCol && sqlite3ColumnIndex(p, z)>=0 ){ -+ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); -+ sqlite3DbFree(db, z); -+ return; - } - aNew = sqlite3DbRealloc(db,p->aCol,((i64)p->nCol+1)*sizeof(p->aCol[0])); - if( aNew==0 ){ -@@ -123683,7 +124523,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ - pCol = &p->aCol[p->nCol]; - memset(pCol, 0, sizeof(p->aCol[0])); - pCol->zCnName = z; -- pCol->hName = hName; -+ pCol->hName = sqlite3StrIHash(z); - sqlite3ColumnPropertiesFromName(p, pCol); - - if( sType.n==0 ){ -@@ -123707,9 +124547,14 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ - pCol->affinity = sqlite3AffinityType(zType, pCol); - pCol->colFlags |= COLFLAG_HASTYPE; - } -+ if( p->nCol<=0xff ){ -+ u8 h = pCol->hName % sizeof(p->aHx); -+ p->aHx[h] = p->nCol; -+ } - p->nCol++; - p->nNVCol++; -- pParse->constraintName.n = 0; -+ assert( pParse->isCreate ); -+ pParse->u1.cr.constraintName.n = 0; - } - - /* -@@ -123973,15 +124818,11 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( - assert( pCExpr!=0 ); - sqlite3StringToId(pCExpr); - if( pCExpr->op==TK_ID ){ -- const char *zCName; - assert( !ExprHasProperty(pCExpr, EP_IntValue) ); -- zCName = pCExpr->u.zToken; -- for(iCol=0; iColnCol; iCol++){ -- if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){ -- pCol = &pTab->aCol[iCol]; -- makeColumnPartOfPrimaryKey(pParse, pCol); -- break; -- } -+ iCol = sqlite3ColumnIndex(pTab, pCExpr->u.zToken); -+ if( iCol>=0 ){ -+ pCol = &pTab->aCol[iCol]; -+ makeColumnPartOfPrimaryKey(pParse, pCol); - } - } - } -@@ -124033,8 +124874,10 @@ SQLITE_PRIVATE void sqlite3AddCheckConstraint( - && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) - ){ - pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); -- if( pParse->constraintName.n ){ -- sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); -+ assert( pParse->isCreate ); -+ if( pParse->u1.cr.constraintName.n ){ -+ sqlite3ExprListSetName(pParse, pTab->pCheck, -+ &pParse->u1.cr.constraintName, 1); - }else{ - Token t; - for(zStart++; sqlite3Isspace(zStart[0]); zStart++){} -@@ -124229,7 +125072,8 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){ - ** from sqliteMalloc() and must be freed by the calling function. - */ - static char *createTableStmt(sqlite3 *db, Table *p){ -- int i, k, n; -+ int i, k, len; -+ i64 n; - char *zStmt; - char *zSep, *zSep2, *zEnd; - Column *pCol; -@@ -124253,8 +125097,9 @@ static char *createTableStmt(sqlite3 *db, Table *p){ - sqlite3OomFault(db); - return 0; - } -- sqlite3_snprintf(n, zStmt, "CREATE TABLE "); -- k = sqlite3Strlen30(zStmt); -+ assert( n>14 && n<=0x7fffffff ); -+ memcpy(zStmt, "CREATE TABLE ", 13); -+ k = 13; - identPut(zStmt, &k, p->zName); - zStmt[k++] = '('; - for(pCol=p->aCol, i=0; inCol; i++, pCol++){ -@@ -124266,13 +125111,15 @@ static char *createTableStmt(sqlite3 *db, Table *p){ - /* SQLITE_AFF_REAL */ " REAL", - /* SQLITE_AFF_FLEXNUM */ " NUM", - }; -- int len; - const char *zType; - -- sqlite3_snprintf(n-k, &zStmt[k], zSep); -- k += sqlite3Strlen30(&zStmt[k]); -+ len = sqlite3Strlen30(zSep); -+ assert( k+lenzCnName); -+ assert( kaffinity-SQLITE_AFF_BLOB >= 0 ); - assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) ); - testcase( pCol->affinity==SQLITE_AFF_BLOB ); -@@ -124287,11 +125134,14 @@ static char *createTableStmt(sqlite3 *db, Table *p){ - assert( pCol->affinity==SQLITE_AFF_BLOB - || pCol->affinity==SQLITE_AFF_FLEXNUM - || pCol->affinity==sqlite3AffinityType(zType, 0) ); -+ assert( k+lennColumn>=N ) return SQLITE_OK; -+ db = pParse->db; -+ assert( N>0 ); -+ assert( N <= SQLITE_MAX_COLUMN*2 /* tag-20250221-1 */ ); -+ testcase( N==2*pParse->db->aLimit[SQLITE_LIMIT_COLUMN] ); - assert( pIdx->isResized==0 ); -- nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N; -+ nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*(u64)N; - zExtra = sqlite3DbMallocZero(db, nByte); - if( zExtra==0 ) return SQLITE_NOMEM_BKPT; - memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); -@@ -124318,7 +125173,7 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){ - zExtra += sizeof(i16)*N; - memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn); - pIdx->aSortOrder = (u8*)zExtra; -- pIdx->nColumn = N; -+ pIdx->nColumn = (u16)N; /* See tag-20250221-1 above for proof of safety */ - pIdx->isResized = 1; - return SQLITE_OK; - } -@@ -124484,9 +125339,9 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ - ** into BTREE_BLOBKEY. - */ - assert( !pParse->bReturning ); -- if( pParse->u1.addrCrTab ){ -+ if( pParse->u1.cr.addrCrTab ){ - assert( v ); -- sqlite3VdbeChangeP3(v, pParse->u1.addrCrTab, BTREE_BLOBKEY); -+ sqlite3VdbeChangeP3(v, pParse->u1.cr.addrCrTab, BTREE_BLOBKEY); - } - - /* Locate the PRIMARY KEY index. Or, if this table was originally -@@ -124572,14 +125427,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ - pIdx->nColumn = pIdx->nKeyCol; - continue; - } -- if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return; -+ if( resizeIndexObject(pParse, pIdx, pIdx->nKeyCol+n) ) return; - for(i=0, j=pIdx->nKeyCol; inKeyCol, pPk, i) ){ - testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); - pIdx->aiColumn[j] = pPk->aiColumn[i]; - pIdx->azColl[j] = pPk->azColl[i]; - if( pPk->aSortOrder[i] ){ -- /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */ -+ /* See ticket https://sqlite.org/src/info/bba7b69f9849b5bf */ - pIdx->bAscKeyBug = 1; - } - j++; -@@ -124596,7 +125451,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ - if( !hasColumn(pPk->aiColumn, nPk, i) - && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++; - } -- if( resizeIndexObject(db, pPk, nPk+nExtra) ) return; -+ if( resizeIndexObject(pParse, pPk, nPk+nExtra) ) return; - for(i=0, j=nPk; inCol; i++){ - if( !hasColumn(pPk->aiColumn, j, i) - && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 -@@ -124926,7 +125781,7 @@ SQLITE_PRIVATE void sqlite3EndTable( - - /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT - ** statement to populate the new table. The root-page number for the -- ** new table is in register pParse->regRoot. -+ ** new table is in register pParse->u1.cr.regRoot. - ** - ** Once the SELECT has been coded by sqlite3Select(), it is in a - ** suitable state to query for the column names and types to be used -@@ -124957,7 +125812,8 @@ SQLITE_PRIVATE void sqlite3EndTable( - regRec = ++pParse->nMem; - regRowid = ++pParse->nMem; - sqlite3MayAbort(pParse); -- sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->regRoot, iDb); -+ assert( pParse->isCreate ); -+ sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->u1.cr.regRoot, iDb); - sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); - addrTop = sqlite3VdbeCurrentAddr(v) + 1; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); -@@ -125002,6 +125858,7 @@ SQLITE_PRIVATE void sqlite3EndTable( - ** schema table. We just need to update that slot with all - ** the information we've collected. - */ -+ assert( pParse->isCreate ); - sqlite3NestedParse(pParse, - "UPDATE %Q." LEGACY_SCHEMA_TABLE - " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q" -@@ -125010,9 +125867,9 @@ SQLITE_PRIVATE void sqlite3EndTable( - zType, - p->zName, - p->zName, -- pParse->regRoot, -+ pParse->u1.cr.regRoot, - zStmt, -- pParse->regRowid -+ pParse->u1.cr.regRowid - ); - sqlite3DbFree(db, zStmt); - sqlite3ChangeCookie(pParse, iDb); -@@ -125752,7 +126609,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( - }else{ - nCol = pFromCol->nExpr; - } -- nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; -+ nByte = SZ_FKEY(nCol) + pTo->n + 1; - if( pToCol ){ - for(i=0; inExpr; i++){ - nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1; -@@ -125954,7 +126811,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ - ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables - ** with DESC primary keys, since those indexes have there keys in - ** a different order from the main table. -- ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf -+ ** See ticket: https://sqlite.org/src/info/bba7b69f9849b5bf - */ - sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); - } -@@ -125978,13 +126835,14 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ - */ - SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( - sqlite3 *db, /* Database connection */ -- i16 nCol, /* Total number of columns in the index */ -+ int nCol, /* Total number of columns in the index */ - int nExtra, /* Number of bytes of extra space to alloc */ - char **ppExtra /* Pointer to the "extra" space */ - ){ - Index *p; /* Allocated index object */ -- int nByte; /* Bytes of space for Index object + arrays */ -+ i64 nByte; /* Bytes of space for Index object + arrays */ - -+ assert( nCol <= 2*db->aLimit[SQLITE_LIMIT_COLUMN] ); - nByte = ROUND8(sizeof(Index)) + /* Index structure */ - ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ - ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ -@@ -125997,8 +126855,9 @@ SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( - p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); - p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; - p->aSortOrder = (u8*)pExtra; -- p->nColumn = nCol; -- p->nKeyCol = nCol - 1; -+ assert( nCol>0 ); -+ p->nColumn = (u16)nCol; -+ p->nKeyCol = (u16)(nCol - 1); - *ppExtra = ((char*)p) + nByte; - } - return p; -@@ -126809,12 +127668,11 @@ SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token * - sqlite3 *db = pParse->db; - int i; - if( pList==0 ){ -- pList = sqlite3DbMallocZero(db, sizeof(IdList) ); -+ pList = sqlite3DbMallocZero(db, SZ_IDLIST(1)); - if( pList==0 ) return 0; - }else{ - IdList *pNew; -- pNew = sqlite3DbRealloc(db, pList, -- sizeof(IdList) + pList->nId*sizeof(pList->a)); -+ pNew = sqlite3DbRealloc(db, pList, SZ_IDLIST(pList->nId+1)); - if( pNew==0 ){ - sqlite3IdListDelete(db, pList); - return 0; -@@ -126913,8 +127771,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( - return 0; - } - if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; -- pNew = sqlite3DbRealloc(db, pSrc, -- sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); -+ pNew = sqlite3DbRealloc(db, pSrc, SZ_SRCLIST(nAlloc)); - if( pNew==0 ){ - assert( db->mallocFailed ); - return 0; -@@ -126989,7 +127846,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( - assert( pParse->db!=0 ); - db = pParse->db; - if( pList==0 ){ -- pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) ); -+ pList = sqlite3DbMallocRawNN(pParse->db, SZ_SRCLIST(1)); - if( pList==0 ) return 0; - pList->nAlloc = 1; - pList->nSrc = 1; -@@ -127875,10 +128732,9 @@ SQLITE_PRIVATE With *sqlite3WithAdd( - } - - if( pWith ){ -- sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); -- pNew = sqlite3DbRealloc(db, pWith, nByte); -+ pNew = sqlite3DbRealloc(db, pWith, SZ_WITH(pWith->nCte+1)); - }else{ -- pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); -+ pNew = sqlite3DbMallocZero(db, SZ_WITH(1)); - } - assert( (pNew!=0 && zName!=0) || db->mallocFailed ); - -@@ -129852,11 +130708,6 @@ static void substrFunc( - i64 p1, p2; - - assert( argc==3 || argc==2 ); -- if( sqlite3_value_type(argv[1])==SQLITE_NULL -- || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL) -- ){ -- return; -- } - p0type = sqlite3_value_type(argv[0]); - p1 = sqlite3_value_int64(argv[1]); - if( p0type==SQLITE_BLOB ){ -@@ -129874,19 +130725,23 @@ static void substrFunc( - } - } - } --#ifdef SQLITE_SUBSTR_COMPATIBILITY -- /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as -- ** as substr(X,1,N) - it returns the first N characters of X. This -- ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] -- ** from 2009-02-02 for compatibility of applications that exploited the -- ** old buggy behavior. */ -- if( p1==0 ) p1 = 1; /* */ --#endif - if( argc==3 ){ - p2 = sqlite3_value_int64(argv[2]); -+ if( p2==0 && sqlite3_value_type(argv[2])==SQLITE_NULL ) return; - }else{ - p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; - } -+ if( p1==0 ){ -+#ifdef SQLITE_SUBSTR_COMPATIBILITY -+ /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as -+ ** as substr(X,1,N) - it returns the first N characters of X. This -+ ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] -+ ** from 2009-02-02 for compatibility of applications that exploited the -+ ** old buggy behavior. */ -+ p1 = 1; /* */ -+#endif -+ if( sqlite3_value_type(argv[1])==SQLITE_NULL ) return; -+ } - if( p1<0 ){ - p1 += len; - if( p1<0 ){ -@@ -130587,7 +131442,7 @@ static const char hexdigits[] = { - ** Append to pStr text that is the SQL literal representation of the - ** value contained in pValue. - */ --SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ -+SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue, int bEscape){ - /* As currently implemented, the string must be initially empty. - ** we might relax this requirement in the future, but that will - ** require enhancements to the implementation. */ -@@ -130635,7 +131490,7 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ - } - case SQLITE_TEXT: { - const unsigned char *zArg = sqlite3_value_text(pValue); -- sqlite3_str_appendf(pStr, "%Q", zArg); -+ sqlite3_str_appendf(pStr, bEscape ? "%#Q" : "%Q", zArg); - break; - } - default: { -@@ -130646,6 +131501,105 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ - } - } - -+/* -+** Return true if z[] begins with N hexadecimal digits, and write -+** a decoding of those digits into *pVal. Or return false if any -+** one of the first N characters in z[] is not a hexadecimal digit. -+*/ -+static int isNHex(const char *z, int N, u32 *pVal){ -+ int i; -+ int v = 0; -+ for(i=0; i0 ){ -+ memmove(&zOut[j], &zIn[i], n); -+ j += n; -+ i += n; -+ } -+ if( zIn[i+1]=='\\' ){ -+ i += 2; -+ zOut[j++] = '\\'; -+ }else if( sqlite3Isxdigit(zIn[i+1]) ){ -+ if( !isNHex(&zIn[i+1], 4, &v) ) goto unistr_error; -+ i += 5; -+ j += sqlite3AppendOneUtf8Character(&zOut[j], v); -+ }else if( zIn[i+1]=='+' ){ -+ if( !isNHex(&zIn[i+2], 6, &v) ) goto unistr_error; -+ i += 8; -+ j += sqlite3AppendOneUtf8Character(&zOut[j], v); -+ }else if( zIn[i+1]=='u' ){ -+ if( !isNHex(&zIn[i+2], 4, &v) ) goto unistr_error; -+ i += 6; -+ j += sqlite3AppendOneUtf8Character(&zOut[j], v); -+ }else if( zIn[i+1]=='U' ){ -+ if( !isNHex(&zIn[i+2], 8, &v) ) goto unistr_error; -+ i += 10; -+ j += sqlite3AppendOneUtf8Character(&zOut[j], v); -+ }else{ -+ goto unistr_error; -+ } -+ } -+ zOut[j] = 0; -+ sqlite3_result_text64(context, zOut, j, sqlite3_free, SQLITE_UTF8); -+ return; -+ -+unistr_error: -+ sqlite3_free(zOut); -+ sqlite3_result_error(context, "invalid Unicode escape", -1); -+ return; -+} -+ -+ - /* - ** Implementation of the QUOTE() function. - ** -@@ -130655,6 +131609,10 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ - ** as needed. BLOBs are encoded as hexadecimal literals. Strings with - ** embedded NUL characters cannot be represented as string literals in SQL - ** and hence the returned string literal is truncated prior to the first NUL. -+** -+** If sqlite3_user_data() is non-zero, then the UNISTR_QUOTE() function is -+** implemented instead. The difference is that UNISTR_QUOTE() uses the -+** UNISTR() function to escape control characters. - */ - static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - sqlite3_str str; -@@ -130662,7 +131620,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - assert( argc==1 ); - UNUSED_PARAMETER(argc); - sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); -- sqlite3QuoteValue(&str,argv[0]); -+ sqlite3QuoteValue(&str,argv[0],SQLITE_PTR_TO_INT(sqlite3_user_data(context))); - sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar, - SQLITE_DYNAMIC); - if( str.accError!=SQLITE_OK ){ -@@ -130917,7 +131875,7 @@ static void replaceFunc( - assert( zRep==sqlite3_value_text(argv[2]) ); - nOut = nStr + 1; - assert( nOut0 ){ -+ if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){ -+ int k = sqlite3_value_bytes(argv[i]); - const char *v = (const char*)sqlite3_value_text(argv[i]); - if( v!=0 ){ - if( j>0 && nSep>0 ){ -@@ -131313,7 +132271,7 @@ static void kahanBabuskaNeumaierInit( - ** that it returns NULL if it sums over no inputs. TOTAL returns - ** 0.0 in that case. In addition, TOTAL always returns a float where - ** SUM might return an integer if it never encounters a floating point --** value. TOTAL never fails, but SUM might through an exception if -+** value. TOTAL never fails, but SUM might throw an exception if - ** it overflows an integer. - */ - static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ -@@ -132233,7 +133191,9 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ - DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ), - DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), - FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), -+ FUNCTION(unistr, 1, 0, 0, unistrFunc ), - FUNCTION(quote, 1, 0, 0, quoteFunc ), -+ FUNCTION(unistr_quote, 1, 1, 0, quoteFunc ), - VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), - VFUNCTION(changes, 0, 0, 0, changes ), - VFUNCTION(total_changes, 0, 0, 0, total_changes ), -@@ -134520,7 +135480,7 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList - f = (f & pLeft->selFlags); - } - pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); -- pLeft->selFlags &= ~SF_MultiValue; -+ pLeft->selFlags &= ~(u32)SF_MultiValue; - if( pSelect ){ - pSelect->op = TK_ALL; - pSelect->pPrior = pLeft; -@@ -134902,28 +135862,22 @@ SQLITE_PRIVATE void sqlite3Insert( - aTabColMap = sqlite3DbMallocZero(db, pTab->nCol*sizeof(int)); - if( aTabColMap==0 ) goto insert_cleanup; - for(i=0; inId; i++){ -- const char *zCName = pColumn->a[i].zName; -- u8 hName = sqlite3StrIHash(zCName); -- for(j=0; jnCol; j++){ -- if( pTab->aCol[j].hName!=hName ) continue; -- if( sqlite3StrICmp(zCName, pTab->aCol[j].zCnName)==0 ){ -- if( aTabColMap[j]==0 ) aTabColMap[j] = i+1; -- if( i!=j ) bIdListInOrder = 0; -- if( j==pTab->iPKey ){ -- ipkColumn = i; assert( !withoutRowid ); -- } -+ j = sqlite3ColumnIndex(pTab, pColumn->a[i].zName); -+ if( j>=0 ){ -+ if( aTabColMap[j]==0 ) aTabColMap[j] = i+1; -+ if( i!=j ) bIdListInOrder = 0; -+ if( j==pTab->iPKey ){ -+ ipkColumn = i; assert( !withoutRowid ); -+ } - #ifndef SQLITE_OMIT_GENERATED_COLUMNS -- if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ -- sqlite3ErrorMsg(pParse, -- "cannot INSERT into generated column \"%s\"", -- pTab->aCol[j].zCnName); -- goto insert_cleanup; -- } --#endif -- break; -+ if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ -+ sqlite3ErrorMsg(pParse, -+ "cannot INSERT into generated column \"%s\"", -+ pTab->aCol[j].zCnName); -+ goto insert_cleanup; - } -- } -- if( j>=pTab->nCol ){ -+#endif -+ }else{ - if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ - ipkColumn = i; - bIdListInOrder = 0; -@@ -135221,7 +136175,7 @@ SQLITE_PRIVATE void sqlite3Insert( - continue; - }else if( pColumn==0 ){ - /* Hidden columns that are not explicitly named in the INSERT -- ** get there default value */ -+ ** get their default value */ - sqlite3ExprCodeFactorable(pParse, - sqlite3ColumnExpr(pTab, &pTab->aCol[i]), - iRegStore); -@@ -135946,7 +136900,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( - ** could happen in any order, but they are grouped up front for - ** convenience. - ** -- ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43 -+ ** 2018-08-14: Ticket https://sqlite.org/src/info/908f001483982c43 - ** The order of constraints used to have OE_Update as (2) and OE_Abort - ** and so forth as (1). But apparently PostgreSQL checks the OE_Update - ** constraint before any others, so it had to be moved. -@@ -137756,6 +138710,8 @@ struct sqlite3_api_routines { - /* Version 3.44.0 and later */ - void *(*get_clientdata)(sqlite3*,const char*); - int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); -+ /* Version 3.50.0 and later */ -+ int (*setlk_timeout)(sqlite3*,int,int); - }; - - /* -@@ -138089,6 +139045,8 @@ typedef int (*sqlite3_loadext_entry)( - /* Version 3.44.0 and later */ - #define sqlite3_get_clientdata sqlite3_api->get_clientdata - #define sqlite3_set_clientdata sqlite3_api->set_clientdata -+/* Version 3.50.0 and later */ -+#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout - #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ - - #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) -@@ -138610,7 +139568,9 @@ static const sqlite3_api_routines sqlite3Apis = { - sqlite3_stmt_explain, - /* Version 3.44.0 and later */ - sqlite3_get_clientdata, -- sqlite3_set_clientdata -+ sqlite3_set_clientdata, -+ /* Version 3.50.0 and later */ -+ sqlite3_setlk_timeout - }; - - /* True if x is the directory separator character -@@ -139132,48 +140092,48 @@ static const char *const pragCName[] = { - /* 13 */ "pk", - /* 14 */ "hidden", - /* table_info reuses 8 */ -- /* 15 */ "schema", /* Used by: table_list */ -- /* 16 */ "name", -+ /* 15 */ "name", /* Used by: function_list */ -+ /* 16 */ "builtin", - /* 17 */ "type", -- /* 18 */ "ncol", -- /* 19 */ "wr", -- /* 20 */ "strict", -- /* 21 */ "seqno", /* Used by: index_xinfo */ -- /* 22 */ "cid", -- /* 23 */ "name", -- /* 24 */ "desc", -- /* 25 */ "coll", -- /* 26 */ "key", -- /* 27 */ "name", /* Used by: function_list */ -- /* 28 */ "builtin", -- /* 29 */ "type", -- /* 30 */ "enc", -- /* 31 */ "narg", -- /* 32 */ "flags", -- /* 33 */ "tbl", /* Used by: stats */ -- /* 34 */ "idx", -- /* 35 */ "wdth", -- /* 36 */ "hght", -- /* 37 */ "flgs", -- /* 38 */ "seq", /* Used by: index_list */ -- /* 39 */ "name", -- /* 40 */ "unique", -- /* 41 */ "origin", -- /* 42 */ "partial", -+ /* 18 */ "enc", -+ /* 19 */ "narg", -+ /* 20 */ "flags", -+ /* 21 */ "schema", /* Used by: table_list */ -+ /* 22 */ "name", -+ /* 23 */ "type", -+ /* 24 */ "ncol", -+ /* 25 */ "wr", -+ /* 26 */ "strict", -+ /* 27 */ "seqno", /* Used by: index_xinfo */ -+ /* 28 */ "cid", -+ /* 29 */ "name", -+ /* 30 */ "desc", -+ /* 31 */ "coll", -+ /* 32 */ "key", -+ /* 33 */ "seq", /* Used by: index_list */ -+ /* 34 */ "name", -+ /* 35 */ "unique", -+ /* 36 */ "origin", -+ /* 37 */ "partial", -+ /* 38 */ "tbl", /* Used by: stats */ -+ /* 39 */ "idx", -+ /* 40 */ "wdth", -+ /* 41 */ "hght", -+ /* 42 */ "flgs", - /* 43 */ "table", /* Used by: foreign_key_check */ - /* 44 */ "rowid", - /* 45 */ "parent", - /* 46 */ "fkid", -- /* index_info reuses 21 */ -- /* 47 */ "seq", /* Used by: database_list */ -- /* 48 */ "name", -- /* 49 */ "file", -- /* 50 */ "busy", /* Used by: wal_checkpoint */ -- /* 51 */ "log", -- /* 52 */ "checkpointed", -- /* collation_list reuses 38 */ -+ /* 47 */ "busy", /* Used by: wal_checkpoint */ -+ /* 48 */ "log", -+ /* 49 */ "checkpointed", -+ /* 50 */ "seq", /* Used by: database_list */ -+ /* 51 */ "name", -+ /* 52 */ "file", -+ /* index_info reuses 27 */ - /* 53 */ "database", /* Used by: lock_status */ - /* 54 */ "status", -+ /* collation_list reuses 33 */ - /* 55 */ "cache_size", /* Used by: default_cache_size */ - /* module_list pragma_list reuses 9 */ - /* 56 */ "timeout", /* Used by: busy_timeout */ -@@ -139266,7 +140226,7 @@ static const PragmaName aPragmaName[] = { - {/* zName: */ "collation_list", - /* ePragTyp: */ PragTyp_COLLATION_LIST, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 38, 2, -+ /* ColNames: */ 33, 2, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) -@@ -139301,7 +140261,7 @@ static const PragmaName aPragmaName[] = { - {/* zName: */ "database_list", - /* ePragTyp: */ PragTyp_DATABASE_LIST, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 47, 3, -+ /* ColNames: */ 50, 3, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) -@@ -139381,7 +140341,7 @@ static const PragmaName aPragmaName[] = { - {/* zName: */ "function_list", - /* ePragTyp: */ PragTyp_FUNCTION_LIST, - /* ePragFlg: */ PragFlg_Result0, -- /* ColNames: */ 27, 6, -+ /* ColNames: */ 15, 6, - /* iArg: */ 0 }, - #endif - #endif -@@ -139410,17 +140370,17 @@ static const PragmaName aPragmaName[] = { - {/* zName: */ "index_info", - /* ePragTyp: */ PragTyp_INDEX_INFO, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, -- /* ColNames: */ 21, 3, -+ /* ColNames: */ 27, 3, - /* iArg: */ 0 }, - {/* zName: */ "index_list", - /* ePragTyp: */ PragTyp_INDEX_LIST, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, -- /* ColNames: */ 38, 5, -+ /* ColNames: */ 33, 5, - /* iArg: */ 0 }, - {/* zName: */ "index_xinfo", - /* ePragTyp: */ PragTyp_INDEX_INFO, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, -- /* ColNames: */ 21, 6, -+ /* ColNames: */ 27, 6, - /* iArg: */ 1 }, - #endif - #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) -@@ -139599,7 +140559,7 @@ static const PragmaName aPragmaName[] = { - {/* zName: */ "stats", - /* ePragTyp: */ PragTyp_STATS, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, -- /* ColNames: */ 33, 5, -+ /* ColNames: */ 38, 5, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) -@@ -139618,7 +140578,7 @@ static const PragmaName aPragmaName[] = { - {/* zName: */ "table_list", - /* ePragTyp: */ PragTyp_TABLE_LIST, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1, -- /* ColNames: */ 15, 6, -+ /* ColNames: */ 21, 6, - /* iArg: */ 0 }, - {/* zName: */ "table_xinfo", - /* ePragTyp: */ PragTyp_TABLE_INFO, -@@ -139695,7 +140655,7 @@ static const PragmaName aPragmaName[] = { - {/* zName: */ "wal_checkpoint", - /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, - /* ePragFlg: */ PragFlg_NeedSchema, -- /* ColNames: */ 50, 3, -+ /* ColNames: */ 47, 3, - /* iArg: */ 0 }, - #endif - #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) -@@ -139717,7 +140677,7 @@ static const PragmaName aPragmaName[] = { - ** the following macro or to the actual analysis_limit if it is non-zero, - ** in order to prevent PRAGMA optimize from running for too long. - ** --** The value of 2000 is chosen emperically so that the worst-case run-time -+** The value of 2000 is chosen empirically so that the worst-case run-time - ** for PRAGMA optimize does not exceed 100 milliseconds against a variety - ** of test databases on a RaspberryPI-4 compiled using -Os and without - ** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of -@@ -140834,7 +141794,10 @@ SQLITE_PRIVATE void sqlite3Pragma( - } - }else{ - db->flags &= ~mask; -- if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; -+ if( mask==SQLITE_DeferFKs ){ -+ db->nDeferredImmCons = 0; -+ db->nDeferredCons = 0; -+ } - if( (mask & SQLITE_WriteSchema)!=0 - && sqlite3_stricmp(zRight, "reset")==0 - ){ -@@ -144003,7 +144966,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; - pNew->nSelectRow = 0; -- if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); -+ if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); - pNew->pSrc = pSrc; - pNew->pWhere = pWhere; - pNew->pGroupBy = pGroupBy; -@@ -144168,10 +145131,33 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p - */ - SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ - int i; -- u8 h = sqlite3StrIHash(zCol); -- Column *pCol; -- for(pCol=pTab->aCol, i=0; inCol; pCol++, i++){ -- if( pCol->hName==h && sqlite3StrICmp(pCol->zCnName, zCol)==0 ) return i; -+ u8 h; -+ const Column *aCol; -+ int nCol; -+ -+ h = sqlite3StrIHash(zCol); -+ aCol = pTab->aCol; -+ nCol = pTab->nCol; -+ -+ /* See if the aHx gives us a lucky match */ -+ i = pTab->aHx[h % sizeof(pTab->aHx)]; -+ assert( i=nCol ) break; - } - return -1; - } -@@ -144422,7 +145408,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ - } - pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); - sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); -- if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ -+ if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){ - /* This branch runs if the query contains one or more RIGHT or FULL - ** JOINs. If only a single table on the left side of this join - ** contains the zName column, then this branch is a no-op. -@@ -144438,6 +145424,8 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ - */ - ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ - static const Token tkCoalesce = { "coalesce", 8 }; -+ assert( pE1!=0 ); -+ ExprSetProperty(pE1, EP_CanBeNull); - while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, - pRight->fg.isSynthUsing)!=0 ){ - if( pSrc->a[iLeft].fg.isUsing==0 -@@ -144454,7 +145442,13 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ - if( pFuncArgs ){ - pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); - pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); -+ if( pE1 ){ -+ pE1->affExpr = SQLITE_AFF_DEFER; -+ } - } -+ }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ -+ assert( pE1!=0 ); -+ ExprSetProperty(pE1, EP_CanBeNull); - } - pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); - sqlite3SrcItemColumnUsed(pRight, iRightCol); -@@ -145363,8 +146357,8 @@ static void selectInnerLoop( - ** X extra columns. - */ - SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ -- int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*); -- KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); -+ int nExtra = (N+X)*(sizeof(CollSeq*)+1); -+ KeyInfo *p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra); - if( p ){ - p->aSortFlags = (u8*)&p->aColl[N+X]; - p->nKeyField = (u16)N; -@@ -145372,7 +146366,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ - p->enc = ENC(db); - p->db = db; - p->nRef = 1; -- memset(&p[1], 0, nExtra); -+ memset(p->aColl, 0, nExtra); - }else{ - return (KeyInfo*)sqlite3OomFault(db); - } -@@ -147073,6 +148067,7 @@ static int multiSelect( - multi_select_end: - pDest->iSdst = dest.iSdst; - pDest->nSdst = dest.nSdst; -+ pDest->iSDParm2 = dest.iSDParm2; - if( pDelete ){ - sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); - } -@@ -148061,9 +149056,9 @@ static int compoundHasDifferentAffinities(Select *p){ - ** from 2015-02-09.) - ** - ** (3) If the subquery is the right operand of a LEFT JOIN then --** (3a) the subquery may not be a join and --** (3b) the FROM clause of the subquery may not contain a virtual --** table and -+** (3a) the subquery may not be a join -+** (**) Was (3b): "the FROM clause of the subquery may not contain -+** a virtual table" - ** (**) Was: "The outer query may not have a GROUP BY." This case - ** is now managed correctly - ** (3d) the outer query may not be DISTINCT. -@@ -148279,7 +149274,7 @@ static int flattenSubquery( - */ - if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ - if( pSubSrc->nSrc>1 /* (3a) */ -- || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ -+ /**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */ - || (p->selFlags & SF_Distinct)!=0 /* (3d) */ - || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ - ){ -@@ -148683,7 +149678,8 @@ static void constInsert( - return; /* Already present. Return without doing anything. */ - } - } -- if( sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){ -+ assert( SQLITE_AFF_NONEbHasAffBlob = 1; - } - -@@ -148758,7 +149754,8 @@ static int propagateConstantExprRewriteOne( - if( pColumn==pExpr ) continue; - if( pColumn->iTable!=pExpr->iTable ) continue; - if( pColumn->iColumn!=pExpr->iColumn ) continue; -- if( bIgnoreAffBlob && sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){ -+ assert( SQLITE_AFF_NONEpWinDefn = 0; - #endif -- p->selFlags &= ~SF_Compound; -+ p->selFlags &= ~(u32)SF_Compound; - assert( (p->selFlags & SF_Converted)==0 ); - p->selFlags |= SF_Converted; - assert( pNew->pPrior!=0 ); -@@ -149888,7 +150885,7 @@ static int selectExpander(Walker *pWalker, Select *p){ - pEList = p->pEList; - if( pParse->pWith && (p->selFlags & SF_View) ){ - if( p->pWith==0 ){ -- p->pWith = (With*)sqlite3DbMallocZero(db, sizeof(With)); -+ p->pWith = (With*)sqlite3DbMallocZero(db, SZ_WITH(1) ); - if( p->pWith==0 ){ - return WRC_Abort; - } -@@ -151027,6 +152024,7 @@ static void agginfoFree(sqlite3 *db, void *pArg){ - ** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries - ** * The outer query is a simple count(*) with no WHERE clause or other - ** extraneous syntax. -+** * None of the subqueries are DISTINCT (forumpost/a860f5fb2e 2025-03-10) - ** - ** Return TRUE if the optimization is undertaken. - */ -@@ -151059,7 +152057,11 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ - if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ - if( pSub->pWhere ) return 0; /* No WHERE clause */ - if( pSub->pLimit ) return 0; /* No LIMIT clause */ -- if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ -+ if( pSub->selFlags & (SF_Aggregate|SF_Distinct) ){ -+ testcase( pSub->selFlags & SF_Aggregate ); -+ testcase( pSub->selFlags & SF_Distinct ); -+ return 0; /* Not an aggregate nor DISTINCT */ -+ } - assert( pSub->pHaving==0 ); /* Due to the previous */ - pSub = pSub->pPrior; /* Repeat over compound */ - }while( pSub ); -@@ -151071,14 +152073,14 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ - pExpr = 0; - pSub = sqlite3SubqueryDetach(db, pFrom); - sqlite3SrcListDelete(db, p->pSrc); -- p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); -+ p->pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); - while( pSub ){ - Expr *pTerm; - pPrior = pSub->pPrior; - pSub->pPrior = 0; - pSub->pNext = 0; - pSub->selFlags |= SF_Aggregate; -- pSub->selFlags &= ~SF_Compound; -+ pSub->selFlags &= ~(u32)SF_Compound; - pSub->nSelectRow = 0; - sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); - pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; -@@ -151093,7 +152095,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ - pSub = pPrior; - } - p->pEList->a[0].pExpr = pExpr; -- p->selFlags &= ~SF_Aggregate; -+ p->selFlags &= ~(u32)SF_Aggregate; - - #if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x200 ){ -@@ -151300,7 +152302,7 @@ SQLITE_PRIVATE int sqlite3Select( - testcase( pParse->earlyCleanup ); - p->pOrderBy = 0; - } -- p->selFlags &= ~SF_Distinct; -+ p->selFlags &= ~(u32)SF_Distinct; - p->selFlags |= SF_NoopOrderBy; - } - sqlite3SelectPrep(pParse, p, 0); -@@ -151339,7 +152341,7 @@ SQLITE_PRIVATE int sqlite3Select( - ** and leaving this flag set can cause errors if a compound sub-query - ** in p->pSrc is flattened into this query and this function called - ** again as part of compound SELECT processing. */ -- p->selFlags &= ~SF_UFSrcCheck; -+ p->selFlags &= ~(u32)SF_UFSrcCheck; - } - - if( pDest->eDest==SRT_Output ){ -@@ -151828,7 +152830,7 @@ SQLITE_PRIVATE int sqlite3Select( - && p->pWin==0 - #endif - ){ -- p->selFlags &= ~SF_Distinct; -+ p->selFlags &= ~(u32)SF_Distinct; - pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); - if( pGroupBy ){ - for(i=0; inExpr; i++){ -@@ -151937,6 +152939,12 @@ SQLITE_PRIVATE int sqlite3Select( - if( pWInfo==0 ) goto select_end; - if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ - p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); -+ if( pDest->eDest<=SRT_DistQueue && pDest->eDest>=SRT_DistFifo ){ -+ /* TUNING: For a UNION CTE, because UNION is implies DISTINCT, -+ ** reduce the estimated output row count by 8 (LogEst 30). -+ ** Search for tag-20250414a to see other cases */ -+ p->nSelectRow -= 30; -+ } - } - if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ - sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); -@@ -152310,6 +153318,10 @@ SQLITE_PRIVATE int sqlite3Select( - if( iOrderByCol ){ - Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; - Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); -+ while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){ -+ pX = pBase->pLeft; -+ pBase = sqlite3ExprSkipCollateAndLikely(pX); -+ } - if( ALWAYS(pBase!=0) - && pBase->op!=TK_AGG_COLUMN - && pBase->op!=TK_REGISTER -@@ -152893,7 +153905,8 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ - assert( pParse->db->pVtabCtx==0 ); - #endif - assert( pParse->bReturning ); -- assert( &(pParse->u1.pReturning->retTrig) == pTrig ); -+ assert( !pParse->isCreate ); -+ assert( &(pParse->u1.d.pReturning->retTrig) == pTrig ); - pTrig->table = pTab->zName; - pTrig->pTabSchema = pTab->pSchema; - pTrig->pNext = pList; -@@ -153861,7 +154874,8 @@ static void codeReturningTrigger( - ExprList *pNew; - Returning *pReturning; - Select sSelect; -- SrcList sFrom; -+ SrcList *pFrom; -+ u8 fromSpace[SZ_SRCLIST_1]; - - assert( v!=0 ); - if( !pParse->bReturning ){ -@@ -153870,19 +154884,21 @@ static void codeReturningTrigger( - return; - } - assert( db->pParse==pParse ); -- pReturning = pParse->u1.pReturning; -+ assert( !pParse->isCreate ); -+ pReturning = pParse->u1.d.pReturning; - if( pTrigger != &(pReturning->retTrig) ){ - /* This RETURNING trigger is for a different statement */ - return; - } - memset(&sSelect, 0, sizeof(sSelect)); -- memset(&sFrom, 0, sizeof(sFrom)); -+ pFrom = (SrcList*)fromSpace; -+ memset(pFrom, 0, SZ_SRCLIST_1); - sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); -- sSelect.pSrc = &sFrom; -- sFrom.nSrc = 1; -- sFrom.a[0].pSTab = pTab; -- sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ -- sFrom.a[0].iCursor = -1; -+ sSelect.pSrc = pFrom; -+ pFrom->nSrc = 1; -+ pFrom->a[0].pSTab = pTab; -+ pFrom->a[0].zName = pTab->zName; /* tag-20240424-1 */ -+ pFrom->a[0].iCursor = -1; - sqlite3SelectPrep(pParse, &sSelect, 0); - if( pParse->nErr==0 ){ - assert( db->mallocFailed==0 ); -@@ -154100,6 +155116,8 @@ static TriggerPrg *codeRowTrigger( - sSubParse.eTriggerOp = pTrigger->op; - sSubParse.nQueryLoop = pParse->nQueryLoop; - sSubParse.prepFlags = pParse->prepFlags; -+ sSubParse.oldmask = 0; -+ sSubParse.newmask = 0; - - v = sqlite3GetVdbe(&sSubParse); - if( v ){ -@@ -154854,38 +155872,32 @@ SQLITE_PRIVATE void sqlite3Update( - */ - chngRowid = chngPk = 0; - for(i=0; inExpr; i++){ -- u8 hCol = sqlite3StrIHash(pChanges->a[i].zEName); - /* If this is an UPDATE with a FROM clause, do not resolve expressions - ** here. The call to sqlite3Select() below will do that. */ - if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ - goto update_cleanup; - } -- for(j=0; jnCol; j++){ -- if( pTab->aCol[j].hName==hCol -- && sqlite3StrICmp(pTab->aCol[j].zCnName, pChanges->a[i].zEName)==0 -- ){ -- if( j==pTab->iPKey ){ -- chngRowid = 1; -- pRowidExpr = pChanges->a[i].pExpr; -- iRowidExpr = i; -- }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ -- chngPk = 1; -- } -+ j = sqlite3ColumnIndex(pTab, pChanges->a[i].zEName); -+ if( j>=0 ){ -+ if( j==pTab->iPKey ){ -+ chngRowid = 1; -+ pRowidExpr = pChanges->a[i].pExpr; -+ iRowidExpr = i; -+ }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ -+ chngPk = 1; -+ } - #ifndef SQLITE_OMIT_GENERATED_COLUMNS -- else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ -- testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); -- testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); -- sqlite3ErrorMsg(pParse, -- "cannot UPDATE generated column \"%s\"", -- pTab->aCol[j].zCnName); -- goto update_cleanup; -- } --#endif -- aXRef[j] = i; -- break; -+ else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ -+ testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); -+ testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); -+ sqlite3ErrorMsg(pParse, -+ "cannot UPDATE generated column \"%s\"", -+ pTab->aCol[j].zCnName); -+ goto update_cleanup; - } -- } -- if( j>=pTab->nCol ){ -+#endif -+ aXRef[j] = i; -+ }else{ - if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zEName) ){ - j = -1; - chngRowid = 1; -@@ -156208,7 +157220,7 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ - #else - /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments - ** to VACUUM are silently ignored. This is a back-out of a bug fix that -- ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270). -+ ** occurred on 2016-08-19 (https://sqlite.org/src/info/083f9e6270). - ** The buggy behavior is required for binary compatibility with some - ** legacy applications. */ - iDb = sqlite3FindDb(pParse->db, pNm); -@@ -156287,7 +157299,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( - saved_nChange = db->nChange; - saved_nTotalChange = db->nTotalChange; - saved_mTrace = db->mTrace; -- db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; -+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; - db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; - db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder - | SQLITE_Defensive | SQLITE_CountRows); -@@ -156992,11 +158004,12 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ - ** schema table. We just need to update that slot with all - ** the information we've collected. - ** -- ** The VM register number pParse->regRowid holds the rowid of an -+ ** The VM register number pParse->u1.cr.regRowid holds the rowid of an - ** entry in the sqlite_schema table that was created for this vtab - ** by sqlite3StartTable(). - */ - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); -+ assert( pParse->isCreate ); - sqlite3NestedParse(pParse, - "UPDATE %Q." LEGACY_SCHEMA_TABLE " " - "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " -@@ -157005,7 +158018,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ - pTab->zName, - pTab->zName, - zStmt, -- pParse->regRowid -+ pParse->u1.cr.regRowid - ); - v = sqlite3GetVdbe(pParse); - sqlite3ChangeCookie(pParse, iDb); -@@ -158415,9 +159428,14 @@ struct WhereInfo { - Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ - WhereClause sWC; /* Decomposition of the WHERE clause */ - WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ -- WhereLevel a[1]; /* Information about each nest loop in WHERE */ -+ WhereLevel a[FLEXARRAY]; /* Information about each nest loop in WHERE */ - }; - -+/* -+** The size (in bytes) of a WhereInfo object that holds N WhereLevels. -+*/ -+#define SZ_WHEREINFO(N) ROUND8(offsetof(WhereInfo,a)+(N)*sizeof(WhereLevel)) -+ - /* - ** Private interfaces - callable only by other where.c routines. - ** -@@ -159097,7 +160115,7 @@ static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){ - /* - ** pX is an expression of the form: (vector) IN (SELECT ...) - ** In other words, it is a vector IN operator with a SELECT clause on the --** LHS. But not all terms in the vector are indexable and the terms might -+** RHS. But not all terms in the vector are indexable and the terms might - ** not be in the correct order for indexing. - ** - ** This routine makes a copy of the input pX expression and then adjusts -@@ -159153,7 +160171,9 @@ static Expr *removeUnindexableInClauseTerms( - int iField; - assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); - iField = pLoop->aLTerm[i]->u.x.iField - 1; -- if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ -+ if( NEVER(pOrigRhs->a[iField].pExpr==0) ){ -+ continue; /* Duplicate PK column */ -+ } - pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); - pOrigRhs->a[iField].pExpr = 0; - if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; -@@ -159250,7 +160270,7 @@ static SQLITE_NOINLINE void codeINTerm( - return; - } - } -- for(i=iEq;inLTerm; i++){ -+ for(i=iEq; inLTerm; i++){ - assert( pLoop->aLTerm[i]!=0 ); - if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; - } -@@ -159259,22 +160279,13 @@ static SQLITE_NOINLINE void codeINTerm( - if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); - }else{ -- Expr *pExpr = pTerm->pExpr; -- if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ -- sqlite3 *db = pParse->db; -- pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); -- if( !db->mallocFailed ){ -- aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); -- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); -- pExpr->iTable = iTab; -- } -- sqlite3ExprDelete(db, pX); -- }else{ -- int n = sqlite3ExprVectorSize(pX->pLeft); -- aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); -- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); -+ sqlite3 *db = pParse->db; -+ Expr *pXMod = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); -+ if( !db->mallocFailed ){ -+ aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nEq); -+ eType = sqlite3FindInIndex(pParse, pXMod, IN_INDEX_LOOP, 0, aiMap, &iTab); - } -- pX = pExpr; -+ sqlite3ExprDelete(db, pXMod); - } - - if( eType==IN_INDEX_INDEX_DESC ){ -@@ -159304,7 +160315,7 @@ static SQLITE_NOINLINE void codeINTerm( - if( pIn ){ - int iMap = 0; /* Index in aiMap[] */ - pIn += i; -- for(i=iEq;inLTerm; i++){ -+ for(i=iEq; inLTerm; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - int iOut = iTarget + i - iEq; - if( eType==IN_INDEX_ROWID ){ -@@ -160163,6 +161174,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( - } - sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); - sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); -+ /* The instruction immediately prior to OP_VFilter must be an OP_Integer -+ ** that sets the "argc" value for xVFilter. This is necessary for -+ ** resolveP2() to work correctly. See tag-20250207a. */ - sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, - pLoop->u.vtab.idxStr, - pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC); -@@ -160753,12 +161767,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( - if( pLevel->iLeftJoin==0 ){ - /* If a partial index is driving the loop, try to eliminate WHERE clause - ** terms from the query that must be true due to the WHERE clause of -- ** the partial index. -+ ** the partial index. This optimization does not work on an outer join, -+ ** as shown by: - ** -- ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work -- ** for a LEFT JOIN. -+ ** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN) -+ ** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN) - */ -- if( pIdx->pPartIdxWhere ){ -+ if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){ - whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); - } - }else{ -@@ -160865,8 +161880,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( - int nNotReady; /* The number of notReady tables */ - SrcItem *origSrc; /* Original list of tables */ - nNotReady = pWInfo->nLevel - iLevel - 1; -- pOrTab = sqlite3DbMallocRawNN(db, -- sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); -+ pOrTab = sqlite3DbMallocRawNN(db, SZ_SRCLIST(nNotReady+1)); - if( pOrTab==0 ) return notReady; - pOrTab->nAlloc = (u8)(nNotReady + 1); - pOrTab->nSrc = pOrTab->nAlloc; -@@ -160917,7 +161931,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( - ** - ** This optimization also only applies if the (x1 OR x2 OR ...) term - ** is not contained in the ON clause of a LEFT JOIN. -- ** See ticket http://www.sqlite.org/src/info/f2369304e4 -+ ** See ticket http://sqlite.org/src/info/f2369304e4 - ** - ** 2022-02-04: Do not push down slices of a row-value comparison. - ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, -@@ -161409,7 +162423,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( - WhereInfo *pSubWInfo; - WhereLoop *pLoop = pLevel->pWLoop; - SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; -- SrcList sFrom; -+ SrcList *pFrom; -+ u8 fromSpace[SZ_SRCLIST_1]; - Bitmask mAll = 0; - int k; - -@@ -161453,13 +162468,14 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( - sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); - } - } -- sFrom.nSrc = 1; -- sFrom.nAlloc = 1; -- memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); -- sFrom.a[0].fg.jointype = 0; -+ pFrom = (SrcList*)fromSpace; -+ pFrom->nSrc = 1; -+ pFrom->nAlloc = 1; -+ memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem)); -+ pFrom->a[0].fg.jointype = 0; - assert( pParse->withinRJSubrtn < 100 ); - pParse->withinRJSubrtn++; -- pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, -+ pSubWInfo = sqlite3WhereBegin(pParse, pFrom, pSubWhere, 0, 0, 0, - WHERE_RIGHT_JOIN, 0); - if( pSubWInfo ){ - int iCur = pLevel->iTabCur; -@@ -162430,30 +163446,42 @@ static void exprAnalyzeOrTerm( - ** 1. The SQLITE_Transitive optimization must be enabled - ** 2. Must be either an == or an IS operator - ** 3. Not originating in the ON clause of an OUTER JOIN --** 4. The affinities of A and B must be compatible --** 5a. Both operands use the same collating sequence OR --** 5b. The overall collating sequence is BINARY -+** 4. The operator is not IS or else the query does not contain RIGHT JOIN -+** 5. The affinities of A and B must be compatible -+** 6a. Both operands use the same collating sequence OR -+** 6b. The overall collating sequence is BINARY - ** If this routine returns TRUE, that means that the RHS can be substituted - ** for the LHS anyplace else in the WHERE clause where the LHS column occurs. - ** This is an optimization. No harm comes from returning 0. But if 1 is - ** returned when it should not be, then incorrect answers might result. - */ --static int termIsEquivalence(Parse *pParse, Expr *pExpr){ -+static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ - char aff1, aff2; - CollSeq *pColl; -- if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; -- if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; -- if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; -+ if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ -+ if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ -+ if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* (3) */ -+ assert( pSrc!=0 ); -+ if( pExpr->op==TK_IS -+ && pSrc->nSrc -+ && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 -+ ){ -+ return 0; /* (4) */ -+ } - aff1 = sqlite3ExprAffinity(pExpr->pLeft); - aff2 = sqlite3ExprAffinity(pExpr->pRight); - if( aff1!=aff2 - && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) - ){ -- return 0; -+ return 0; /* (5) */ - } - pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); -- if( sqlite3IsBinary(pColl) ) return 1; -- return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); -+ if( !sqlite3IsBinary(pColl) -+ && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) -+ ){ -+ return 0; /* (6) */ -+ } -+ return 1; - } - - /* -@@ -162718,8 +163746,8 @@ static void exprAnalyze( - if( op==TK_IS ) pNew->wtFlags |= TERM_IS; - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; -- -- if( termIsEquivalence(pParse, pDup) ){ -+ assert( pWInfo->pTabList!=0 ); -+ if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){ - pTerm->eOperator |= WO_EQUIV; - eExtraOp = WO_EQUIV; - } -@@ -163447,11 +164475,16 @@ struct HiddenIndexInfo { - int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ - u32 mIn; /* Mask of terms that are IN (...) */ - u32 mHandleIn; /* Terms that vtab will handle as IN (...) */ -- sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST -- ** because extra space is allocated to hold up -- ** to nTerm such values */ -+ sqlite3_value *aRhs[FLEXARRAY]; /* RHS values for constraints. MUST BE LAST -+ ** Extra space is allocated to hold up -+ ** to nTerm such values */ - }; - -+/* Size (in bytes) of a HiddenIndeInfo object sufficient to hold as -+** many as N constraints */ -+#define SZ_HIDDENINDEXINFO(N) \ -+ (offsetof(HiddenIndexInfo,aRhs) + (N)*sizeof(sqlite3_value*)) -+ - /* Forward declaration of methods */ - static int whereLoopResize(sqlite3*, WhereLoop*, int); - -@@ -164516,6 +165549,8 @@ static SQLITE_NOINLINE void constructAutomaticIndex( - } - - /* Construct the Index object to describe this index */ -+ assert( nKeyCol <= pTable->nCol + MAX(0, pTable->nCol - BMS + 1) ); -+ /* ^-- This guarantees that the number of index columns will fit in the u16 */ - pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+HasRowid(pTable), - 0, &zNotUsed); - if( pIdx==0 ) goto end_auto_index_create; -@@ -164927,8 +165962,8 @@ static sqlite3_index_info *allocateIndexInfo( - */ - pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) - + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm -- + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) -- + sizeof(sqlite3_value*)*nTerm ); -+ + sizeof(*pIdxOrderBy)*nOrderBy -+ + SZ_HIDDENINDEXINFO(nTerm) ); - if( pIdxInfo==0 ){ - sqlite3ErrorMsg(pParse, "out of memory"); - return 0; -@@ -166564,11 +167599,8 @@ static int whereLoopAddBtreeIndex( - assert( pNew->u.btree.nBtm==0 ); - opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; - } -- if( pProbe->bUnordered || pProbe->bLowQual ){ -- if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); -- if( pProbe->bLowQual && pSrc->fg.isIndexedBy==0 ){ -- opMask &= ~(WO_EQ|WO_IN|WO_IS); -- } -+ if( pProbe->bUnordered ){ -+ opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); - } - - assert( pNew->u.btree.nEqnColumn ); -@@ -166641,6 +167673,7 @@ static int whereLoopAddBtreeIndex( - if( ExprUseXSelect(pExpr) ){ - /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ - int i; -+ int bRedundant = 0; - nIn = 46; assert( 46==sqlite3LogEst(25) ); - - /* The expression may actually be of the form (x, y) IN (SELECT...). -@@ -166649,7 +167682,20 @@ static int whereLoopAddBtreeIndex( - ** for each such term. The following loop checks that pTerm is the - ** first such term in use, and sets nIn back to 0 if it is not. */ - for(i=0; inLTerm-1; i++){ -- if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0; -+ if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ){ -+ nIn = 0; -+ if( pNew->aLTerm[i]->u.x.iField == pTerm->u.x.iField ){ -+ /* Detect when two or more columns of an index match the same -+ ** column of a vector IN operater, and avoid adding the column -+ ** to the WhereLoop more than once. See tag-20250707-01 -+ ** in test/rowvalue.test */ -+ bRedundant = 1; -+ } -+ } -+ } -+ if( bRedundant ){ -+ pNew->nLTerm--; -+ continue; - } - }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ - /* "x IN (value, value, ...)" */ -@@ -166881,7 +167927,7 @@ static int whereLoopAddBtreeIndex( - if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 - && pNew->u.btree.nEqnColumn - && (pNew->u.btree.nEqnKeyCol || -- pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) -+ pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) - ){ - if( pNew->u.btree.nEq>3 ){ - sqlite3ProgressCheck(pParse); -@@ -167010,6 +168056,7 @@ static int whereUsablePartialIndex( - if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) - && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) - && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) -+ && !sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, -1) - && (pTerm->wtFlags & TERM_VNULL)==0 - ){ - return 1; -@@ -167505,7 +168552,7 @@ static int whereLoopAddBtree( - && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700)) - ){ - WHERETRACE(0x200, -- ("-> %s a covering index according to bitmasks\n", -+ ("-> %s is a covering index according to bitmasks\n", - pProbe->zName, m==0 ? "is" : "is not")); - pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; - } -@@ -170122,10 +171169,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( - ** field (type Bitmask) it must be aligned on an 8-byte boundary on - ** some architectures. Hence the ROUND8() below. - */ -- nByteWInfo = ROUND8P(sizeof(WhereInfo)); -- if( nTabList>1 ){ -- nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel)); -- } -+ nByteWInfo = SZ_WHEREINFO(nTabList); - pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); - if( db->mallocFailed ){ - sqlite3DbFree(db, pWInfo); -@@ -170342,7 +171386,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( - } - - /* TUNING: Assume that a DISTINCT clause on a subquery reduces -- ** the output size by a factor of 8 (LogEst -30). -+ ** the output size by a factor of 8 (LogEst -30). Search for -+ ** tag-20250414a to see other cases. - */ - if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ - WHERETRACE(0x0080,("nRowOut reduced from %d to %d due to DISTINCT\n", -@@ -172077,7 +173122,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ - p->pWhere = 0; - p->pGroupBy = 0; - p->pHaving = 0; -- p->selFlags &= ~SF_Aggregate; -+ p->selFlags &= ~(u32)SF_Aggregate; - p->selFlags |= SF_WinRewrite; - - /* Create the ORDER BY clause for the sub-select. This is the concatenation -@@ -174217,6 +175262,11 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( - - /* #include "sqliteInt.h" */ - -+/* -+** Verify that the pParse->isCreate field is set -+*/ -+#define ASSERT_IS_CREATE assert(pParse->isCreate) -+ - /* - ** Disable all error recovery processing in the parser push-down - ** automaton. -@@ -174280,6 +175330,10 @@ static void parserSyntaxError(Parse *pParse, Token *p){ - static void disableLookaside(Parse *pParse){ - sqlite3 *db = pParse->db; - pParse->disableLookaside++; -+#ifdef SQLITE_DEBUG -+ pParse->isCreate = 1; -+#endif -+ memset(&pParse->u1.cr, 0, sizeof(pParse->u1.cr)); - DisableLookaside; - } - -@@ -177916,7 +178970,9 @@ static YYACTIONTYPE yy_reduce( - } - break; - case 14: /* createkw ::= CREATE */ --{disableLookaside(pParse);} -+{ -+ disableLookaside(pParse); -+} - break; - case 15: /* ifnotexists ::= */ - case 18: /* temp ::= */ yytestcase(yyruleno==18); -@@ -178008,7 +179064,7 @@ static YYACTIONTYPE yy_reduce( - break; - case 32: /* ccons ::= CONSTRAINT nm */ - case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67); --{pParse->constraintName = yymsp[0].minor.yy0;} -+{ASSERT_IS_CREATE; pParse->u1.cr.constraintName = yymsp[0].minor.yy0;} - break; - case 33: /* ccons ::= DEFAULT scantok term */ - {sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} -@@ -178118,7 +179174,7 @@ static YYACTIONTYPE yy_reduce( - {yymsp[-1].minor.yy502 = 0;} - break; - case 66: /* tconscomma ::= COMMA */ --{pParse->constraintName.n = 0;} -+{ASSERT_IS_CREATE; pParse->u1.cr.constraintName.n = 0;} - break; - case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy402,yymsp[0].minor.yy502,yymsp[-2].minor.yy502,0);} -@@ -178205,8 +179261,8 @@ static YYACTIONTYPE yy_reduce( - if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy502; - pRhs->pPrior = pLhs; -- if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; -- pRhs->selFlags &= ~SF_MultiValue; -+ if( ALWAYS(pLhs) ) pLhs->selFlags &= ~(u32)SF_MultiValue; -+ pRhs->selFlags &= ~(u32)SF_MultiValue; - if( yymsp[-1].minor.yy502!=TK_ALL ) pParse->hasCompound = 1; - }else{ - sqlite3SelectDelete(pParse->db, pLhs); -@@ -178846,12 +179902,21 @@ static YYACTIONTYPE yy_reduce( - ** expr1 IN () - ** expr1 NOT IN () - ** -- ** simplify to constants 0 (false) and 1 (true), respectively, -- ** regardless of the value of expr1. -+ ** simplify to constants 0 (false) and 1 (true), respectively. -+ ** -+ ** Except, do not apply this optimization if expr1 contains a function -+ ** because that function might be an aggregate (we don't know yet whether -+ ** it is or not) and if it is an aggregate, that could change the meaning -+ ** of the whole query. - */ -- sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590); -- yymsp[-4].minor.yy590 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false"); -- if( yymsp[-4].minor.yy590 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy590); -+ Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false"); -+ if( pB ) sqlite3ExprIdToTrueFalse(pB); -+ if( !ExprHasProperty(yymsp[-4].minor.yy590, EP_HasFunc) ){ -+ sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590); -+ yymsp[-4].minor.yy590 = pB; -+ }else{ -+ yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, yymsp[-3].minor.yy502 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy590); -+ } - }else{ - Expr *pRHS = yymsp[-1].minor.yy402->a[0].pExpr; - if( yymsp[-1].minor.yy402->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy590->op!=TK_VECTOR ){ -@@ -179011,6 +180076,10 @@ static YYACTIONTYPE yy_reduce( - { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy502, yymsp[-4].minor.yy28.a, yymsp[-4].minor.yy28.b, yymsp[-2].minor.yy563, yymsp[0].minor.yy590, yymsp[-10].minor.yy502, yymsp[-8].minor.yy502); - yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ -+#ifdef SQLITE_DEBUG -+ assert( pParse->isCreate ); /* Set by createkw reduce action */ -+ pParse->isCreate = 0; /* But, should not be set for CREATE TRIGGER */ -+#endif - } - break; - case 262: /* trigger_time ::= BEFORE|AFTER */ -@@ -180453,7 +181522,7 @@ static int getToken(const unsigned char **pz){ - int t; /* Token type to return */ - do { - z += sqlite3GetToken(z, &t); -- }while( t==TK_SPACE ); -+ }while( t==TK_SPACE || t==TK_COMMENT ); - if( t==TK_ID - || t==TK_STRING - || t==TK_JOIN_KW -@@ -180946,7 +182015,11 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ - assert( n==6 ); - tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); - #endif /* SQLITE_OMIT_WINDOWFUNC */ -- }else if( tokenType==TK_COMMENT && (db->flags & SQLITE_Comments)!=0 ){ -+ }else if( tokenType==TK_COMMENT -+ && (db->init.busy || (db->flags & SQLITE_Comments)!=0) -+ ){ -+ /* Ignore SQL comments if either (1) we are reparsing the schema or -+ ** (2) SQLITE_DBCONFIG_ENABLE_COMMENTS is turned on (the default). */ - zSql += n; - continue; - }else if( tokenType!=TK_QNUMBER ){ -@@ -181841,6 +182914,14 @@ SQLITE_API int sqlite3_initialize(void){ - if( rc==SQLITE_OK ){ - sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, - sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); -+#ifdef SQLITE_EXTRA_INIT_MUTEXED -+ { -+ int SQLITE_EXTRA_INIT_MUTEXED(const char*); -+ rc = SQLITE_EXTRA_INIT_MUTEXED(0); -+ } -+#endif -+ } -+ if( rc==SQLITE_OK ){ - sqlite3MemoryBarrier(); - sqlite3GlobalConfig.isInit = 1; - #ifdef SQLITE_EXTRA_INIT -@@ -182297,17 +183378,22 @@ SQLITE_API int sqlite3_config(int op, ...){ - ** If lookaside is already active, return SQLITE_BUSY. - ** - ** The sz parameter is the number of bytes in each lookaside slot. --** The cnt parameter is the number of slots. If pStart is NULL the --** space for the lookaside memory is obtained from sqlite3_malloc(). --** If pStart is not NULL then it is sz*cnt bytes of memory to use for --** the lookaside memory. -+** The cnt parameter is the number of slots. If pBuf is NULL the -+** space for the lookaside memory is obtained from sqlite3_malloc() -+** or similar. If pBuf is not NULL then it is sz*cnt bytes of memory -+** to use for the lookaside memory. - */ --static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ -+static int setupLookaside( -+ sqlite3 *db, /* Database connection being configured */ -+ void *pBuf, /* Memory to use for lookaside. May be NULL */ -+ int sz, /* Desired size of each lookaside memory slot */ -+ int cnt /* Number of slots to allocate */ -+){ - #ifndef SQLITE_OMIT_LOOKASIDE -- void *pStart; -- sqlite3_int64 szAlloc; -- int nBig; /* Number of full-size slots */ -- int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ -+ void *pStart; /* Start of the lookaside buffer */ -+ sqlite3_int64 szAlloc; /* Total space set aside for lookaside memory */ -+ int nBig; /* Number of full-size slots */ -+ int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ - - if( sqlite3LookasideUsed(db,0)>0 ){ - return SQLITE_BUSY; -@@ -182320,19 +183406,22 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ - sqlite3_free(db->lookaside.pStart); - } - /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger -- ** than a pointer to be useful. -+ ** than a pointer and small enough to fit in a u16. - */ -- sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ -+ sz = ROUNDDOWN8(sz); - if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; - if( sz>65528 ) sz = 65528; -- if( cnt<0 ) cnt = 0; -+ /* Count must be at least 1 to be useful, but not so large as to use -+ ** more than 0x7fff0000 total bytes for lookaside. */ -+ if( cnt<1 ) cnt = 0; -+ if( sz>0 && cnt>(0x7fff0000/sz) ) cnt = 0x7fff0000/sz; - szAlloc = (i64)sz*(i64)cnt; -- if( sz==0 || cnt==0 ){ -+ if( szAlloc==0 ){ - sz = 0; - pStart = 0; - }else if( pBuf==0 ){ - sqlite3BeginBenignMalloc(); -- pStart = sqlite3Malloc( szAlloc ); /* IMP: R-61949-35727 */ -+ pStart = sqlite3Malloc( szAlloc ); - sqlite3EndBenignMalloc(); - if( pStart ) szAlloc = sqlite3MallocSize(pStart); - }else{ -@@ -183309,6 +184398,9 @@ SQLITE_API int sqlite3_busy_handler( - db->busyHandler.pBusyArg = pArg; - db->busyHandler.nBusy = 0; - db->busyTimeout = 0; -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ db->setlkTimeout = 0; -+#endif - sqlite3_mutex_leave(db->mutex); - return SQLITE_OK; - } -@@ -183358,12 +184450,49 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ - sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, - (void*)db); - db->busyTimeout = ms; -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ db->setlkTimeout = ms; -+#endif - }else{ - sqlite3_busy_handler(db, 0, 0); - } - return SQLITE_OK; - } - -+/* -+** Set the setlk timeout value. -+*/ -+SQLITE_API int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){ -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ int iDb; -+ int bBOC = ((flags & SQLITE_SETLK_BLOCK_ON_CONNECT) ? 1 : 0); -+#endif -+#ifdef SQLITE_ENABLE_API_ARMOR -+ if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; -+#endif -+ if( ms<-1 ) return SQLITE_RANGE; -+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT -+ sqlite3_mutex_enter(db->mutex); -+ db->setlkTimeout = ms; -+ db->setlkFlags = flags; -+ sqlite3BtreeEnterAll(db); -+ for(iDb=0; iDbnDb; iDb++){ -+ Btree *pBt = db->aDb[iDb].pBt; -+ if( pBt ){ -+ sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); -+ sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); -+ } -+ } -+ sqlite3BtreeLeaveAll(db); -+ sqlite3_mutex_leave(db->mutex); -+#endif -+#if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) -+ UNUSED_PARAMETER(db); -+ UNUSED_PARAMETER(flags); -+#endif -+ return SQLITE_OK; -+} -+ - /* - ** Cause any pending operation to stop at its earliest opportunity. - */ -@@ -185329,7 +186458,7 @@ SQLITE_API int sqlite3_set_clientdata( - return SQLITE_OK; - }else{ - size_t n = strlen(zName); -- p = sqlite3_malloc64( sizeof(DbClientData)+n+1 ); -+ p = sqlite3_malloc64( SZ_DBCLIENTDATA(n+1) ); - if( p==0 ){ - if( xDestructor ) xDestructor(pData); - sqlite3_mutex_leave(db->mutex); -@@ -185483,13 +186612,10 @@ SQLITE_API int sqlite3_table_column_metadata( - if( zColumnName==0 ){ - /* Query for existence of table only */ - }else{ -- for(iCol=0; iColnCol; iCol++){ -+ iCol = sqlite3ColumnIndex(pTab, zColumnName); -+ if( iCol>=0 ){ - pCol = &pTab->aCol[iCol]; -- if( 0==sqlite3StrICmp(pCol->zCnName, zColumnName) ){ -- break; -- } -- } -- if( iCol==pTab->nCol ){ -+ }else{ - if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){ - iCol = pTab->iPKey; - pCol = iCol>=0 ? &pTab->aCol[iCol] : 0; -@@ -185698,8 +186824,8 @@ SQLITE_API int sqlite3_test_control(int op, ...){ - /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); - ** - ** If b is true, then activate the SQLITE_FkNoAction setting. If b is -- ** false then clearn that setting. If the SQLITE_FkNoAction setting is -- ** abled, all foreign key ON DELETE and ON UPDATE actions behave as if -+ ** false then clear that setting. If the SQLITE_FkNoAction setting is -+ ** enabled, all foreign key ON DELETE and ON UPDATE actions behave as if - ** they were NO ACTION, regardless of how they are defined. - ** - ** NB: One must usually run "PRAGMA writable_schema=RESET" after -@@ -187046,7 +188172,7 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ - ** Here, array { X } means zero or more occurrences of X, adjacent in - ** memory. A "position" is an index of a token in the token stream - ** generated by the tokenizer. Note that POS_END and POS_COLUMN occur --** in the same logical place as the position element, and act as sentinals -+** in the same logical place as the position element, and act as sentinels - ** ending a position list array. POS_END is 0. POS_COLUMN is 1. - ** The positions numbers are not stored literally but rather as two more - ** than the difference from the prior position, or the just the position plus -@@ -187265,6 +188391,13 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ - #ifndef _FTSINT_H - #define _FTSINT_H - -+/* #include */ -+/* #include */ -+/* #include */ -+/* #include */ -+/* #include */ -+/* #include */ -+ - #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) - # define NDEBUG 1 - #endif -@@ -187734,6 +188867,19 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */ - - #define deliberate_fall_through - -+/* -+** Macros needed to provide flexible arrays in a portable way -+*/ -+#ifndef offsetof -+# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) -+#endif -+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -+# define FLEXARRAY -+#else -+# define FLEXARRAY 1 -+#endif -+ -+ - #endif /* SQLITE_AMALGAMATION */ - - #ifdef SQLITE_DEBUG -@@ -187838,7 +188984,7 @@ struct Fts3Table { - #endif - - #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) -- /* True to disable the incremental doclist optimization. This is controled -+ /* True to disable the incremental doclist optimization. This is controlled - ** by special insert command 'test-no-incr-doclist'. */ - int bNoIncrDoclist; - -@@ -187890,7 +189036,7 @@ struct Fts3Cursor { - - /* - ** The Fts3Cursor.eSearch member is always set to one of the following. --** Actualy, Fts3Cursor.eSearch can be greater than or equal to -+** Actually, Fts3Cursor.eSearch can be greater than or equal to - ** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index - ** of the column to be searched. For example, in - ** -@@ -187963,9 +189109,13 @@ struct Fts3Phrase { - */ - int nToken; /* Number of tokens in the phrase */ - int iColumn; /* Index of column this phrase must match */ -- Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */ -+ Fts3PhraseToken aToken[FLEXARRAY]; /* One for each token in the phrase */ - }; - -+/* Size (in bytes) of an Fts3Phrase object large enough to hold N tokens */ -+#define SZ_FTS3PHRASE(N) \ -+ (offsetof(Fts3Phrase,aToken)+(N)*sizeof(Fts3PhraseToken)) -+ - /* - ** A tree of these objects forms the RHS of a MATCH operator. - ** -@@ -188199,12 +189349,6 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); - # define SQLITE_CORE 1 - #endif - --/* #include */ --/* #include */ --/* #include */ --/* #include */ --/* #include */ --/* #include */ - - /* #include "fts3.h" */ - #ifndef SQLITE_CORE -@@ -190543,7 +191687,7 @@ static int fts3DoclistOrMerge( - ** sizes of the two inputs, plus enough space for exactly one of the input - ** docids to grow. - ** -- ** A symetric argument may be made if the doclists are in descending -+ ** A symmetric argument may be made if the doclists are in descending - ** order. - */ - aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); -@@ -192342,7 +193486,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ - nDistance = iPrev - nMaxUndeferred; - } - -- aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING); -+ aOut = (char *)sqlite3Fts3MallocZero(((i64)nPoslist)+FTS3_BUFFER_PADDING); - if( !aOut ){ - sqlite3_free(aPoslist); - return SQLITE_NOMEM; -@@ -192641,7 +193785,7 @@ static int incrPhraseTokenNext( - ** - ** * does not contain any deferred tokens. - ** --** Advance it to the next matching documnent in the database and populate -+** Advance it to the next matching document in the database and populate - ** the Fts3Doclist.pList and nList fields. - ** - ** If there is no "next" entry and no error occurs, then *pbEof is set to -@@ -193648,7 +194792,7 @@ static int fts3EvalNext(Fts3Cursor *pCsr){ - } - - /* --** Restart interation for expression pExpr so that the next call to -+** Restart iteration for expression pExpr so that the next call to - ** fts3EvalNext() visits the first row. Do not allow incremental - ** loading or merging of phrase doclists for this iteration. - ** -@@ -194840,6 +195984,23 @@ SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer( - */ - static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); - -+/* -+** Search buffer z[], size n, for a '"' character. Or, if enable_parenthesis -+** is defined, search for '(' and ')' as well. Return the index of the first -+** such character in the buffer. If there is no such character, return -1. -+*/ -+static int findBarredChar(const char *z, int n){ -+ int ii; -+ for(ii=0; iiiLangid, z, i, &pCursor); -+ *pnConsumed = n; -+ rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); - if( rc==SQLITE_OK ){ - const char *zToken; - int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; -@@ -194881,7 +196035,18 @@ static int getNextToken( - - rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); - if( rc==SQLITE_OK ){ -- nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; -+ /* Check that this tokenization did not gobble up any " characters. Or, -+ ** if enable_parenthesis is true, that it did not gobble up any -+ ** open or close parenthesis characters either. If it did, call -+ ** getNextToken() again, but pass only that part of the input buffer -+ ** up to the first such character. */ -+ int iBarred = findBarredChar(z, iEnd); -+ if( iBarred>=0 ){ -+ pModule->xClose(pCursor); -+ return getNextToken(pParse, iCol, z, iBarred, ppExpr, pnConsumed); -+ } -+ -+ nByte = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1) + nToken; - pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte); - if( !pRet ){ - rc = SQLITE_NOMEM; -@@ -194891,7 +196056,7 @@ static int getNextToken( - pRet->pPhrase->nToken = 1; - pRet->pPhrase->iColumn = iCol; - pRet->pPhrase->aToken[0].n = nToken; -- pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1]; -+ pRet->pPhrase->aToken[0].z = (char*)&pRet->pPhrase->aToken[1]; - memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken); - - if( iEnd=0 ){ -+ *pnConsumed = iBarred; -+ } - rc = SQLITE_OK; - } - -@@ -194962,9 +196131,9 @@ static int getNextString( - Fts3Expr *p = 0; - sqlite3_tokenizer_cursor *pCursor = 0; - char *zTemp = 0; -- int nTemp = 0; -+ i64 nTemp = 0; - -- const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase); -+ const int nSpace = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1); - int nToken = 0; - - /* The final Fts3Expr data structure, including the Fts3Phrase, -@@ -195336,7 +196505,7 @@ static int fts3ExprParse( - - /* The isRequirePhrase variable is set to true if a phrase or - ** an expression contained in parenthesis is required. If a -- ** binary operator (AND, OR, NOT or NEAR) is encounted when -+ ** binary operator (AND, OR, NOT or NEAR) is encountered when - ** isRequirePhrase is set, this is a syntax error. - */ - if( !isPhrase && isRequirePhrase ){ -@@ -195918,7 +197087,6 @@ static void fts3ExprTestCommon( - } - - if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ -- sqlite3Fts3ExprFree(pExpr); - sqlite3_result_error(context, "Error parsing expression", -1); - }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){ - sqlite3_result_error_nomem(context); -@@ -196161,7 +197329,7 @@ static void fts3HashInsertElement( - } - - --/* Resize the hash table so that it cantains "new_size" buckets. -+/* Resize the hash table so that it contains "new_size" buckets. - ** "new_size" must be a power of 2. The hash table might fail - ** to resize if sqliteMalloc() fails. - ** -@@ -196616,7 +197784,7 @@ static int star_oh(const char *z){ - - /* - ** If the word ends with zFrom and xCond() is true for the stem --** of the word that preceeds the zFrom ending, then change the -+** of the word that precedes the zFrom ending, then change the - ** ending to zTo. - ** - ** The input word *pz and zFrom are both in reverse order. zTo -@@ -198127,7 +199295,7 @@ static int fts3tokFilterMethod( - fts3tokResetCursor(pCsr); - if( idxNum==1 ){ - const char *zByte = (const char *)sqlite3_value_text(apVal[0]); -- int nByte = sqlite3_value_bytes(apVal[0]); -+ sqlite3_int64 nByte = sqlite3_value_bytes(apVal[0]); - pCsr->zInput = sqlite3_malloc64(nByte+1); - if( pCsr->zInput==0 ){ - rc = SQLITE_NOMEM; -@@ -202199,7 +203367,7 @@ static int fts3IncrmergePush( - ** - ** It is assumed that the buffer associated with pNode is already large - ** enough to accommodate the new entry. The buffer associated with pPrev --** is extended by this function if requrired. -+** is extended by this function if required. - ** - ** If an error (i.e. OOM condition) occurs, an SQLite error code is - ** returned. Otherwise, SQLITE_OK. -@@ -203862,7 +205030,7 @@ SQLITE_PRIVATE int sqlite3Fts3DeferToken( - /* - ** SQLite value pRowid contains the rowid of a row that may or may not be - ** present in the FTS3 table. If it is, delete it and adjust the contents --** of subsiduary data structures accordingly. -+** of subsidiary data structures accordingly. - */ - static int fts3DeleteByRowid( - Fts3Table *p, -@@ -204188,9 +205356,13 @@ struct MatchinfoBuffer { - int nElem; - int bGlobal; /* Set if global data is loaded */ - char *zMatchinfo; -- u32 aMatchinfo[1]; -+ u32 aMI[FLEXARRAY]; - }; - -+/* Size (in bytes) of a MatchinfoBuffer sufficient for N elements */ -+#define SZ_MATCHINFOBUFFER(N) \ -+ (offsetof(MatchinfoBuffer,aMI)+(((N)+1)/2)*sizeof(u64)) -+ - - /* - ** The snippet() and offsets() functions both return text values. An instance -@@ -204215,13 +205387,13 @@ struct StrBuffer { - static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ - MatchinfoBuffer *pRet; - sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) -- + sizeof(MatchinfoBuffer); -+ + SZ_MATCHINFOBUFFER(1); - sqlite3_int64 nStr = strlen(zMatchinfo); - - pRet = sqlite3Fts3MallocZero(nByte + nStr+1); - if( pRet ){ -- pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet; -- pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] -+ pRet->aMI[0] = (u8*)(&pRet->aMI[1]) - (u8*)pRet; -+ pRet->aMI[1+nElem] = pRet->aMI[0] - + sizeof(u32)*((int)nElem+1); - pRet->nElem = (int)nElem; - pRet->zMatchinfo = ((char*)pRet) + nByte; -@@ -204235,10 +205407,10 @@ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ - static void fts3MIBufferFree(void *p){ - MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]); - -- assert( (u32*)p==&pBuf->aMatchinfo[1] -- || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2] -+ assert( (u32*)p==&pBuf->aMI[1] -+ || (u32*)p==&pBuf->aMI[pBuf->nElem+2] - ); -- if( (u32*)p==&pBuf->aMatchinfo[1] ){ -+ if( (u32*)p==&pBuf->aMI[1] ){ - pBuf->aRef[1] = 0; - }else{ - pBuf->aRef[2] = 0; -@@ -204255,18 +205427,18 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ - - if( p->aRef[1]==0 ){ - p->aRef[1] = 1; -- aOut = &p->aMatchinfo[1]; -+ aOut = &p->aMI[1]; - xRet = fts3MIBufferFree; - } - else if( p->aRef[2]==0 ){ - p->aRef[2] = 1; -- aOut = &p->aMatchinfo[p->nElem+2]; -+ aOut = &p->aMI[p->nElem+2]; - xRet = fts3MIBufferFree; - }else{ - aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32)); - if( aOut ){ - xRet = sqlite3_free; -- if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32)); -+ if( p->bGlobal ) memcpy(aOut, &p->aMI[1], p->nElem*sizeof(u32)); - } - } - -@@ -204276,7 +205448,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ - - static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){ - p->bGlobal = 1; -- memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32)); -+ memcpy(&p->aMI[2+p->nElem], &p->aMI[1], p->nElem*sizeof(u32)); - } - - /* -@@ -204691,7 +205863,7 @@ static int fts3StringAppend( - } - - /* If there is insufficient space allocated at StrBuffer.z, use realloc() -- ** to grow the buffer until so that it is big enough to accomadate the -+ ** to grow the buffer until so that it is big enough to accommodate the - ** appended data. - */ - if( pStr->n+nAppend+1>=pStr->nAlloc ){ -@@ -205103,16 +206275,16 @@ static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ - break; - - case FTS3_MATCHINFO_LHITS: -- nVal = pInfo->nCol * pInfo->nPhrase; -+ nVal = (size_t)pInfo->nCol * pInfo->nPhrase; - break; - - case FTS3_MATCHINFO_LHITS_BM: -- nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32); -+ nVal = (size_t)pInfo->nPhrase * ((pInfo->nCol + 31) / 32); - break; - - default: - assert( cArg==FTS3_MATCHINFO_HITS ); -- nVal = pInfo->nCol * pInfo->nPhrase * 3; -+ nVal = (size_t)pInfo->nCol * pInfo->nPhrase * 3; - break; - } - -@@ -206670,8 +207842,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ - ** Beginning with version 3.45.0 (circa 2024-01-01), these routines also - ** accept BLOB values that have JSON encoded using a binary representation - ** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk --** format SQLite JSONB is completely different and incompatible with --** PostgreSQL JSONB. -+** format for SQLite-JSONB is completely different and incompatible with -+** PostgreSQL-JSONB. - ** - ** Decoding and interpreting JSONB is still O(N) where N is the size of - ** the input, the same as text JSON. However, the constant of proportionality -@@ -206728,7 +207900,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ - ** - ** The payload size need not be expressed in its minimal form. For example, - ** if the payload size is 10, the size can be expressed in any of 5 different --** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte, -+** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by one 0x0a byte, - ** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by - ** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and - ** a single byte of 0x0a. The shorter forms are preferred, of course, but -@@ -206738,7 +207910,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ - ** the size when it becomes known, resulting in a non-minimal encoding. - ** - ** The value (X>>4)==15 is not actually used in the current implementation --** (as SQLite is currently unable handle BLOBs larger than about 2GB) -+** (as SQLite is currently unable to handle BLOBs larger than about 2GB) - ** but is included in the design to allow for future enhancements. - ** - ** The payload follows the header. NULL, TRUE, and FALSE have no payload and -@@ -206798,23 +207970,47 @@ static const char * const jsonbType[] = { - ** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). - */ - static const char jsonIsSpace[] = { -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+#ifdef SQLITE_ASCII -+/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ -+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ -+ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */ -+#endif -+#ifdef SQLITE_EBCDIC -+/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ -+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ -+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ -+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ -+ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */ -+#endif -+ - }; - #define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) - -@@ -206822,7 +208018,13 @@ static const char jsonIsSpace[] = { - ** The set of all space characters recognized by jsonIsspace(). - ** Useful as the second argument to strspn(). - */ -+#ifdef SQLITE_ASCII - static const char jsonSpaces[] = "\011\012\015\040"; -+#endif -+#ifdef SQLITE_EBCDIC -+static const char jsonSpaces[] = "\005\045\015\100"; -+#endif -+ - - /* - ** Characters that are special to JSON. Control characters, -@@ -206831,23 +208033,46 @@ static const char jsonSpaces[] = "\011\012\015\040"; - ** it in the set of special characters. - */ - static const char jsonIsOk[256] = { -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 -+#ifdef SQLITE_ASCII -+/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ -+ 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 5 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */ -+ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */ -+#endif -+#ifdef SQLITE_EBCDIC -+/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ -+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 3 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, /* 7 */ -+ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */ -+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */ -+#endif - }; - - /* Objects */ -@@ -206992,7 +208217,7 @@ struct JsonParse { - ** Forward references - **************************************************************************/ - static void jsonReturnStringAsBlob(JsonString*); --static int jsonFuncArgMightBeBinary(sqlite3_value *pJson); -+static int jsonArgIsJsonb(sqlite3_value *pJson, JsonParse *p); - static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); - static void jsonReturnParse(sqlite3_context*,JsonParse*); - static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); -@@ -207066,7 +208291,7 @@ static int jsonCacheInsert( - ** most-recently used entry if it isn't so already. - ** - ** The JsonParse object returned still belongs to the Cache and might --** be deleted at any moment. If the caller whants the JsonParse to -+** be deleted at any moment. If the caller wants the JsonParse to - ** linger, it needs to increment the nPJRef reference counter. - */ - static JsonParse *jsonCacheSearch( -@@ -207410,11 +208635,9 @@ static void jsonAppendSqlValue( - break; - } - default: { -- if( jsonFuncArgMightBeBinary(pValue) ){ -- JsonParse px; -- memset(&px, 0, sizeof(px)); -- px.aBlob = (u8*)sqlite3_value_blob(pValue); -- px.nBlob = sqlite3_value_bytes(pValue); -+ JsonParse px; -+ memset(&px, 0, sizeof(px)); -+ if( jsonArgIsJsonb(pValue, &px) ){ - jsonTranslateBlobToText(&px, 0, p); - }else if( p->eErr==0 ){ - sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); -@@ -207733,7 +208956,7 @@ static void jsonWrongNumArgs( - */ - static int jsonBlobExpand(JsonParse *pParse, u32 N){ - u8 *aNew; -- u32 t; -+ u64 t; - assert( N>pParse->nBlobAlloc ); - if( pParse->nBlobAlloc==0 ){ - t = 100; -@@ -207743,8 +208966,9 @@ static int jsonBlobExpand(JsonParse *pParse, u32 N){ - if( tdb, pParse->aBlob, t); - if( aNew==0 ){ pParse->oom = 1; return 1; } -+ assert( t<0x7fffffff ); - pParse->aBlob = aNew; -- pParse->nBlobAlloc = t; -+ pParse->nBlobAlloc = (u32)t; - return 0; - } - -@@ -207811,7 +209035,7 @@ static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( - } - - --/* Append an node type byte together with the payload size and -+/* Append a node type byte together with the payload size and - ** possibly also the payload. - ** - ** If aPayload is not NULL, then it is a pointer to the payload which -@@ -207880,8 +209104,10 @@ static int jsonBlobChangePayloadSize( - nExtra = 1; - }else if( szType==13 ){ - nExtra = 2; -- }else{ -+ }else if( szType==14 ){ - nExtra = 4; -+ }else{ -+ nExtra = 8; - } - if( szPayload<=11 ){ - nNeeded = 0; -@@ -208351,7 +209577,12 @@ json_parse_restart: - || c=='n' || c=='r' || c=='t' - || (c=='u' && jsonIs4Hex(&z[j+1])) ){ - if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ; -- }else if( c=='\'' || c=='0' || c=='v' || c=='\n' -+ }else if( c=='\'' || c=='v' || c=='\n' -+#ifdef SQLITE_BUG_COMPATIBLE_20250510 -+ || (c=='0') /* Legacy bug compatible */ -+#else -+ || (c=='0' && !sqlite3Isdigit(z[j+1])) /* Correct implementation */ -+#endif - || (0xe2==(u8)c && 0x80==(u8)z[j+1] - && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) - || (c=='x' && jsonIs2Hex(&z[j+1])) ){ -@@ -208701,10 +209932,7 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ - u8 x; - u32 sz; - u32 n; -- if( NEVER(i>pParse->nBlob) ){ -- *pSz = 0; -- return 0; -- } -+ assert( i<=pParse->nBlob ); - x = pParse->aBlob[i]>>4; - if( x<=11 ){ - sz = x; -@@ -208741,15 +209969,15 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ - *pSz = 0; - return 0; - } -- sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + -+ sz = ((u32)pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + - (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; - n = 9; - } - if( (i64)i+sz+n > pParse->nBlob - && (i64)i+sz+n > pParse->nBlob-pParse->delta - ){ -- sz = 0; -- n = 0; -+ *pSz = 0; -+ return 0; - } - *pSz = sz; - return n; -@@ -208846,9 +210074,12 @@ static u32 jsonTranslateBlobToText( - } - case JSONB_TEXT: - case JSONB_TEXTJ: { -- jsonAppendChar(pOut, '"'); -- jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); -- jsonAppendChar(pOut, '"'); -+ if( pOut->nUsed+sz+2<=pOut->nAlloc || jsonStringGrow(pOut, sz+2)==0 ){ -+ pOut->zBuf[pOut->nUsed] = '"'; -+ memcpy(pOut->zBuf+pOut->nUsed+1,(const char*)&pParse->aBlob[i+n],sz); -+ pOut->zBuf[pOut->nUsed+sz+1] = '"'; -+ pOut->nUsed += sz+2; -+ } - break; - } - case JSONB_TEXT5: { -@@ -209087,33 +210318,6 @@ static u32 jsonTranslateBlobToPrettyText( - return i; - } - -- --/* Return true if the input pJson --** --** For performance reasons, this routine does not do a detailed check of the --** input BLOB to ensure that it is well-formed. Hence, false positives are --** possible. False negatives should never occur, however. --*/ --static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){ -- u32 sz, n; -- const u8 *aBlob; -- int nBlob; -- JsonParse s; -- if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0; -- aBlob = sqlite3_value_blob(pJson); -- nBlob = sqlite3_value_bytes(pJson); -- if( nBlob<1 ) return 0; -- if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0; -- memset(&s, 0, sizeof(s)); -- s.aBlob = (u8*)aBlob; -- s.nBlob = nBlob; -- n = jsonbPayloadSize(&s, 0, &sz); -- if( n==0 ) return 0; -- if( sz+n!=(u32)nBlob ) return 0; -- if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0; -- return sz+n==(u32)nBlob; --} -- - /* - ** Given that a JSONB_ARRAY object starts at offset i, return - ** the number of entries in that array. -@@ -209146,6 +210350,82 @@ static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){ - pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); - } - -+/* -+** If the JSONB at aIns[0..nIns-1] can be expanded (by denormalizing the -+** size field) by d bytes, then write the expansion into aOut[] and -+** return true. In this way, an overwrite happens without changing the -+** size of the JSONB, which reduces memcpy() operations and also make it -+** faster and easier to update the B-Tree entry that contains the JSONB -+** in the database. -+** -+** If the expansion of aIns[] by d bytes cannot be (easily) accomplished -+** then return false. -+** -+** The d parameter is guaranteed to be between 1 and 8. -+** -+** This routine is an optimization. A correct answer is obtained if it -+** always leaves the output unchanged and returns false. -+*/ -+static int jsonBlobOverwrite( -+ u8 *aOut, /* Overwrite here */ -+ const u8 *aIns, /* New content */ -+ u32 nIns, /* Bytes of new content */ -+ u32 d /* Need to expand new content by this much */ -+){ -+ u32 szPayload; /* Bytes of payload */ -+ u32 i; /* New header size, after expansion & a loop counter */ -+ u8 szHdr; /* Size of header before expansion */ -+ -+ /* Lookup table for finding the upper 4 bits of the first byte of the -+ ** expanded aIns[], based on the size of the expanded aIns[] header: -+ ** -+ ** 2 3 4 5 6 7 8 9 */ -+ static const u8 aType[] = { 0xc0, 0xd0, 0, 0xe0, 0, 0, 0, 0xf0 }; -+ -+ if( (aIns[0]&0x0f)<=2 ) return 0; /* Cannot enlarge NULL, true, false */ -+ switch( aIns[0]>>4 ){ -+ default: { /* aIns[] header size 1 */ -+ if( ((1<=2 && i<=9 && aType[i-2]!=0 ); -+ aOut[0] = (aIns[0] & 0x0f) | aType[i-2]; -+ memcpy(&aOut[i], &aIns[szHdr], nIns-szHdr); -+ szPayload = nIns - szHdr; -+ while( 1/*edit-by-break*/ ){ -+ i--; -+ aOut[i] = szPayload & 0xff; -+ if( i==1 ) break; -+ szPayload >>= 8; -+ } -+ assert( (szPayload>>8)==0 ); -+ return 1; -+} -+ - /* - ** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of - ** content beginning at iDel, and replacing them with nIns bytes of -@@ -209167,6 +210447,11 @@ static void jsonBlobEdit( - u32 nIns /* Bytes of content to insert */ - ){ - i64 d = (i64)nIns - (i64)nDel; -+ if( d<0 && d>=(-8) && aIns!=0 -+ && jsonBlobOverwrite(&pParse->aBlob[iDel], aIns, nIns, (int)-d) -+ ){ -+ return; -+ } - if( d!=0 ){ - if( pParse->nBlob + d > pParse->nBlobAlloc ){ - jsonBlobExpand(pParse, pParse->nBlob+d); -@@ -209178,7 +210463,9 @@ static void jsonBlobEdit( - pParse->nBlob += d; - pParse->delta += d; - } -- if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns); -+ if( nIns && aIns ){ -+ memcpy(&pParse->aBlob[iDel], aIns, nIns); -+ } - } - - /* -@@ -209263,7 +210550,21 @@ static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){ - case 'r': { *piOut = '\r'; return 2; } - case 't': { *piOut = '\t'; return 2; } - case 'v': { *piOut = '\v'; return 2; } -- case '0': { *piOut = 0; return 2; } -+ case '0': { -+ /* JSON5 requires that the \0 escape not be followed by a digit. -+ ** But SQLite did not enforce this restriction in versions 3.42.0 -+ ** through 3.49.2. That was a bug. But some applications might have -+ ** come to depend on that bug. Use the SQLITE_BUG_COMPATIBLE_20250510 -+ ** option to restore the old buggy behavior. */ -+#ifdef SQLITE_BUG_COMPATIBLE_20250510 -+ /* Legacy bug-compatible behavior */ -+ *piOut = 0; -+#else -+ /* Correct behavior */ -+ *piOut = (n>2 && sqlite3Isdigit(z[2])) ? JSON_INVALID_CHAR : 0; -+#endif -+ return 2; -+ } - case '\'': - case '"': - case '/': -@@ -209763,7 +211064,7 @@ static void jsonReturnFromBlob( - char *zOut; - u32 nOut = sz; - z = (const char*)&pParse->aBlob[i+n]; -- zOut = sqlite3DbMallocRaw(db, nOut+1); -+ zOut = sqlite3DbMallocRaw(db, ((u64)nOut)+1); - if( zOut==0 ) goto returnfromblob_oom; - for(iIn=iOut=0; iInaBlob = (u8*)sqlite3_value_blob(pArg); -- pParse->nBlob = sqlite3_value_bytes(pArg); -- }else{ -+ if( !jsonArgIsJsonb(pArg, pParse) ){ - sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); - return 1; - } -@@ -209941,7 +211239,7 @@ static char *jsonBadPathError( - } - - /* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent --** arguments come in parse where each pair contains a JSON path and -+** arguments come in pairs where each pair contains a JSON path and - ** content to insert or set at that patch. Do the updates - ** and return the result. - ** -@@ -210012,27 +211310,46 @@ jsonInsertIntoBlob_patherror: - /* - ** If pArg is a blob that seems like a JSONB blob, then initialize - ** p to point to that JSONB and return TRUE. If pArg does not seem like --** a JSONB blob, then return FALSE; --** --** This routine is only called if it is already known that pArg is a --** blob. The only open question is whether or not the blob appears --** to be a JSONB blob. -+** a JSONB blob, then return FALSE. -+** -+** For small BLOBs (having no more than 7 bytes of payload) a full -+** validity check is done. So for small BLOBs this routine only returns -+** true if the value is guaranteed to be a valid JSONB. For larger BLOBs -+** (8 byte or more of payload) only the size of the outermost element is -+** checked to verify that the BLOB is superficially valid JSONB. -+** -+** A full JSONB validation is done on smaller BLOBs because those BLOBs might -+** also be text JSON that has been incorrectly cast into a BLOB. -+** (See tag-20240123-a and https://sqlite.org/forum/forumpost/012136abd5) -+** If the BLOB is 9 bytes are larger, then it is not possible for the -+** superficial size check done here to pass if the input is really text -+** JSON so we do not need to look deeper in that case. -+** -+** Why we only need to do full JSONB validation for smaller BLOBs: -+** -+** The first byte of valid JSON text must be one of: '{', '[', '"', ' ', '\n', -+** '\r', '\t', '-', or a digit '0' through '9'. Of these, only a subset -+** can also be the first byte of JSONB: '{', '[', and digits '3' -+** through '9'. In every one of those cases, the payload size is 7 bytes -+** or less. So if we do full JSONB validation for every BLOB where the -+** payload is less than 7 bytes, we will never get a false positive for -+** JSONB on an input that is really text JSON. - */ - static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ - u32 n, sz = 0; -+ u8 c; -+ if( sqlite3_value_type(pArg)!=SQLITE_BLOB ) return 0; - p->aBlob = (u8*)sqlite3_value_blob(pArg); - p->nBlob = (u32)sqlite3_value_bytes(pArg); -- if( p->nBlob==0 ){ -- p->aBlob = 0; -- return 0; -- } -- if( NEVER(p->aBlob==0) ){ -- return 0; -- } -- if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT -+ if( p->nBlob>0 -+ && ALWAYS(p->aBlob!=0) -+ && ((c = p->aBlob[0]) & 0x0f)<=JSONB_OBJECT - && (n = jsonbPayloadSize(p, 0, &sz))>0 - && sz+n==p->nBlob -- && ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0) -+ && ((c & 0x0f)>JSONB_FALSE || sz==0) -+ && (sz>7 -+ || (c!=0x7b && c!=0x5b && !sqlite3Isdigit(c)) -+ || jsonbValidityCheck(p, 0, p->nBlob, 1)==0) - ){ - return 1; - } -@@ -210110,7 +211427,7 @@ rebuild_from_cache: - ** JSON functions were suppose to work. From the beginning, blob was - ** reserved for expansion and a blob value should have raised an error. - ** But it did not, due to a bug. And many applications came to depend -- ** upon this buggy behavior, espeically when using the CLI and reading -+ ** upon this buggy behavior, especially when using the CLI and reading - ** JSON text using readfile(), which returns a blob. For this reason - ** we will continue to support the bug moving forward. - ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d -@@ -211125,21 +212442,17 @@ static void jsonValidFunc( - return; - } - case SQLITE_BLOB: { -- if( jsonFuncArgMightBeBinary(argv[0]) ){ -+ JsonParse py; -+ memset(&py, 0, sizeof(py)); -+ if( jsonArgIsJsonb(argv[0], &py) ){ - if( flags & 0x04 ){ - /* Superficial checking only - accomplished by the -- ** jsonFuncArgMightBeBinary() call above. */ -+ ** jsonArgIsJsonb() call above. */ - res = 1; - }else if( flags & 0x08 ){ - /* Strict checking. Check by translating BLOB->TEXT->BLOB. If - ** no errors occur, call that a "strict check". */ -- JsonParse px; -- u32 iErr; -- memset(&px, 0, sizeof(px)); -- px.aBlob = (u8*)sqlite3_value_blob(argv[0]); -- px.nBlob = sqlite3_value_bytes(argv[0]); -- iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1); -- res = iErr==0; -+ res = 0==jsonbValidityCheck(&py, 0, py.nBlob, 1); - } - break; - } -@@ -211197,9 +212510,7 @@ static void jsonErrorFunc( - UNUSED_PARAMETER(argc); - memset(&s, 0, sizeof(s)); - s.db = sqlite3_context_db_handle(ctx); -- if( jsonFuncArgMightBeBinary(argv[0]) ){ -- s.aBlob = (u8*)sqlite3_value_blob(argv[0]); -- s.nBlob = sqlite3_value_bytes(argv[0]); -+ if( jsonArgIsJsonb(argv[0], &s) ){ - iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); - }else{ - s.zJson = (char*)sqlite3_value_text(argv[0]); -@@ -211360,18 +212671,20 @@ static void jsonObjectStep( - UNUSED_PARAMETER(argc); - pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); - if( pStr ){ -+ z = (const char*)sqlite3_value_text(argv[0]); -+ n = sqlite3Strlen30(z); - if( pStr->zBuf==0 ){ - jsonStringInit(pStr, ctx); - jsonAppendChar(pStr, '{'); -- }else if( pStr->nUsed>1 ){ -+ }else if( pStr->nUsed>1 && z!=0 ){ - jsonAppendChar(pStr, ','); - } - pStr->pCtx = ctx; -- z = (const char*)sqlite3_value_text(argv[0]); -- n = sqlite3Strlen30(z); -- jsonAppendString(pStr, z, n); -- jsonAppendChar(pStr, ':'); -- jsonAppendSqlValue(pStr, argv[1]); -+ if( z!=0 ){ -+ jsonAppendString(pStr, z, n); -+ jsonAppendChar(pStr, ':'); -+ jsonAppendSqlValue(pStr, argv[1]); -+ } - } - } - static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ -@@ -211884,9 +213197,8 @@ static int jsonEachFilter( - memset(&p->sParse, 0, sizeof(p->sParse)); - p->sParse.nJPRef = 1; - p->sParse.db = p->db; -- if( jsonFuncArgMightBeBinary(argv[0]) ){ -- p->sParse.nBlob = sqlite3_value_bytes(argv[0]); -- p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); -+ if( jsonArgIsJsonb(argv[0], &p->sParse) ){ -+ /* We have JSONB */ - }else{ - p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); - p->sParse.nJson = sqlite3_value_bytes(argv[0]); -@@ -212180,6 +213492,8 @@ SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3 *db){ - #endif - SQLITE_PRIVATE int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ - -+/* #include */ -+ - /* - ** If building separately, we will need some setup that is normally - ** found in sqliteInt.h -@@ -212210,6 +213524,14 @@ typedef unsigned int u32; - # define ALWAYS(X) (X) - # define NEVER(X) (X) - #endif -+#ifndef offsetof -+#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) -+#endif -+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -+# define FLEXARRAY -+#else -+# define FLEXARRAY 1 -+#endif - #endif /* !defined(SQLITE_AMALGAMATION) */ - - /* Macro to check for 4-byte alignment. Only used inside of assert() */ -@@ -212530,9 +213852,13 @@ struct RtreeMatchArg { - RtreeGeomCallback cb; /* Info about the callback functions */ - int nParam; /* Number of parameters to the SQL function */ - sqlite3_value **apSqlParam; /* Original SQL parameter values */ -- RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ -+ RtreeDValue aParam[FLEXARRAY]; /* Values for parameters to the SQL function */ - }; - -+/* Size of an RtreeMatchArg object with N parameters */ -+#define SZ_RTREEMATCHARG(N) \ -+ (offsetof(RtreeMatchArg,aParam)+(N)*sizeof(RtreeDValue)) -+ - #ifndef MAX - # define MAX(x,y) ((x) < (y) ? (y) : (x)) - #endif -@@ -214221,7 +215547,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ - } - - /* --** Return the N-dimensional volumn of the cell stored in *p. -+** Return the N-dimensional volume of the cell stored in *p. - */ - static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ - RtreeDValue area = (RtreeDValue)1; -@@ -215987,7 +217313,7 @@ static sqlite3_stmt *rtreeCheckPrepare( - /* - ** The second and subsequent arguments to this function are a printf() - ** style format string and arguments. This function formats the string and --** appends it to the report being accumuated in pCheck. -+** appends it to the report being accumulated in pCheck. - */ - static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ - va_list ap; -@@ -217175,7 +218501,7 @@ static void geopolyBBoxFinal( - ** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). - ** Returns: - ** --** +2 x0,y0 is on the line segement -+** +2 x0,y0 is on the line segment - ** - ** +1 x0,y0 is beneath line segment - ** -@@ -217281,7 +218607,7 @@ static void geopolyWithinFunc( - sqlite3_free(p2); - } - --/* Objects used by the overlap algorihm. */ -+/* Objects used by the overlap algorithm. */ - typedef struct GeoEvent GeoEvent; - typedef struct GeoSegment GeoSegment; - typedef struct GeoOverlap GeoOverlap; -@@ -218328,8 +219654,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ - sqlite3_int64 nBlob; - int memErr = 0; - -- nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) -- + nArg*sizeof(sqlite3_value*); -+ nBlob = SZ_RTREEMATCHARG(nArg) + nArg*sizeof(sqlite3_value*); - pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob); - if( !pBlob ){ - sqlite3_result_error_nomem(ctx); -@@ -219424,7 +220749,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( - ** - ** "RBU" stands for "Resumable Bulk Update". As in a large database update - ** transmitted via a wireless network to a mobile device. A transaction --** applied using this extension is hence refered to as an "RBU update". -+** applied using this extension is hence referred to as an "RBU update". - ** - ** - ** LIMITATIONS -@@ -219721,7 +221046,7 @@ SQLITE_API sqlite3rbu *sqlite3rbu_open( - ** the next call to sqlite3rbu_vacuum() opens a handle that starts a - ** new RBU vacuum operation. - ** --** As with sqlite3rbu_open(), Zipvfs users should rever to the comment -+** As with sqlite3rbu_open(), Zipvfs users should refer to the comment - ** describing the sqlite3rbu_create_vfs() API function below for - ** a description of the complications associated with using RBU with - ** zipvfs databases. -@@ -219817,7 +221142,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); - ** - ** If the RBU update has been completely applied, mark the RBU database - ** as fully applied. Otherwise, assuming no error has occurred, save the --** current state of the RBU update appliation to the RBU database. -+** current state of the RBU update application to the RBU database. - ** - ** If an error has already occurred as part of an sqlite3rbu_step() - ** or sqlite3rbu_open() call, or if one occurs within this function, an -@@ -224743,7 +226068,7 @@ static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ - - /* If this is an RBU vacuum operation and this is the target database, - ** pretend that it has at least one page. Otherwise, SQLite will not -- ** check for the existance of a *-wal file. rbuVfsRead() contains -+ ** check for the existence of a *-wal file. rbuVfsRead() contains - ** similar logic. */ - if( rc==SQLITE_OK && *pSize==0 - && p->pRbu && rbuIsVacuum(p->pRbu) -@@ -226675,8 +228000,8 @@ static int dbpageUpdate( - /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and - ** all subsequent pages to be deleted. */ - pTab->iDbTrunc = iDb; -- pgno--; -- pTab->pgnoTrunc = pgno; -+ pTab->pgnoTrunc = pgno-1; -+ pgno = 1; - }else{ - zErr = "bad page value"; - goto update_fail; -@@ -227973,7 +229298,7 @@ static int sessionTableInfo( - /* - ** This function is called to initialize the SessionTable.nCol, azCol[] - ** abPK[] and azDflt[] members of SessionTable object pTab. If these --** fields are already initilialized, this function is a no-op. -+** fields are already initialized, this function is a no-op. - ** - ** If an error occurs, an error code is stored in sqlite3_session.rc and - ** non-zero returned. Or, if no error occurs but the table has no primary -@@ -227992,6 +229317,8 @@ static int sessionInitTable( - if( pTab->nCol==0 ){ - u8 *abPK; - assert( pTab->azCol==0 || pTab->abPK==0 ); -+ sqlite3_free(pTab->azCol); -+ pTab->abPK = 0; - rc = sessionTableInfo(pSession, db, zDb, - pTab->zName, &pTab->nCol, &pTab->nTotalCol, 0, &pTab->azCol, - &pTab->azDflt, &pTab->aiIdx, &abPK, -@@ -228999,7 +230326,9 @@ SQLITE_API int sqlite3session_diff( - SessionTable *pTo; /* Table zTbl */ - - /* Locate and if necessary initialize the target table object */ -+ pSession->bAutoAttach++; - rc = sessionFindTable(pSession, zTbl, &pTo); -+ pSession->bAutoAttach--; - if( pTo==0 ) goto diff_out; - if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){ - rc = pSession->rc; -@@ -229010,17 +230339,43 @@ SQLITE_API int sqlite3session_diff( - if( rc==SQLITE_OK ){ - int bHasPk = 0; - int bMismatch = 0; -- int nCol; /* Columns in zFrom.zTbl */ -+ int nCol = 0; /* Columns in zFrom.zTbl */ - int bRowid = 0; -- u8 *abPK; -+ u8 *abPK = 0; - const char **azCol = 0; -- rc = sessionTableInfo(0, db, zFrom, zTbl, -- &nCol, 0, 0, &azCol, 0, 0, &abPK, -- pSession->bImplicitPK ? &bRowid : 0 -- ); -+ char *zDbExists = 0; -+ -+ /* Check that database zFrom is attached. */ -+ zDbExists = sqlite3_mprintf("SELECT * FROM %Q.sqlite_schema", zFrom); -+ if( zDbExists==0 ){ -+ rc = SQLITE_NOMEM; -+ }else{ -+ sqlite3_stmt *pDbExists = 0; -+ rc = sqlite3_prepare_v2(db, zDbExists, -1, &pDbExists, 0); -+ if( rc==SQLITE_ERROR ){ -+ rc = SQLITE_OK; -+ nCol = -1; -+ } -+ sqlite3_finalize(pDbExists); -+ sqlite3_free(zDbExists); -+ } -+ -+ if( rc==SQLITE_OK && nCol==0 ){ -+ rc = sessionTableInfo(0, db, zFrom, zTbl, -+ &nCol, 0, 0, &azCol, 0, 0, &abPK, -+ pSession->bImplicitPK ? &bRowid : 0 -+ ); -+ } - if( rc==SQLITE_OK ){ - if( pTo->nCol!=nCol ){ -- bMismatch = 1; -+ if( nCol<=0 ){ -+ rc = SQLITE_SCHEMA; -+ if( pzErrMsg ){ -+ *pzErrMsg = sqlite3_mprintf("no such table: %s.%s", zFrom, zTbl); -+ } -+ }else{ -+ bMismatch = 1; -+ } - }else{ - int i; - for(i=0; idb; /* Source database handle */ - SessionTable *pTab; /* Used to iterate through attached tables */ -- SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ -+ SessionBuffer buf = {0,0,0}; /* Buffer in which to accumulate changeset */ - int rc; /* Return code */ - - assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) ); -@@ -230149,14 +231504,15 @@ SQLITE_API int sqlite3changeset_start_v2_strm( - ** object and the buffer is full, discard some data to free up space. - */ - static void sessionDiscardData(SessionInput *pIn){ -- if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){ -- int nMove = pIn->buf.nBuf - pIn->iNext; -+ if( pIn->xInput && pIn->iCurrent>=sessions_strm_chunk_size ){ -+ int nMove = pIn->buf.nBuf - pIn->iCurrent; - assert( nMove>=0 ); - if( nMove>0 ){ -- memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); -+ memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iCurrent], nMove); - } -- pIn->buf.nBuf -= pIn->iNext; -- pIn->iNext = 0; -+ pIn->buf.nBuf -= pIn->iCurrent; -+ pIn->iNext -= pIn->iCurrent; -+ pIn->iCurrent = 0; - pIn->nData = pIn->buf.nBuf; - } - } -@@ -230510,8 +231866,8 @@ static int sessionChangesetNextOne( - p->rc = sessionInputBuffer(&p->in, 2); - if( p->rc!=SQLITE_OK ) return p->rc; - -- sessionDiscardData(&p->in); - p->in.iCurrent = p->in.iNext; -+ sessionDiscardData(&p->in); - - /* If the iterator is already at the end of the changeset, return DONE. */ - if( p->in.iNext>=p->in.nData ){ -@@ -232870,14 +234226,19 @@ SQLITE_API int sqlite3changegroup_add_change( - sqlite3_changegroup *pGrp, - sqlite3_changeset_iter *pIter - ){ -+ int rc = SQLITE_OK; -+ - if( pIter->in.iCurrent==pIter->in.iNext - || pIter->rc!=SQLITE_OK - || pIter->bInvert - ){ - /* Iterator does not point to any valid entry or is an INVERT iterator. */ -- return SQLITE_ERROR; -+ rc = SQLITE_ERROR; -+ }else{ -+ pIter->in.bNoDiscard = 1; -+ rc = sessionOneChangeToHash(pGrp, pIter, 0); - } -- return sessionOneChangeToHash(pGrp, pIter, 0); -+ return rc; - } - - /* -@@ -234175,6 +235536,7 @@ SQLITE_EXTENSION_INIT1 - - /* #include */ - /* #include */ -+/* #include */ - - #ifndef SQLITE_AMALGAMATION - -@@ -234230,6 +235592,18 @@ typedef sqlite3_uint64 u64; - # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) - #endif - -+/* -+** Macros needed to provide flexible arrays in a portable way -+*/ -+#ifndef offsetof -+# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) -+#endif -+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -+# define FLEXARRAY -+#else -+# define FLEXARRAY 1 -+#endif -+ - #endif - - /* Truncate very long tokens to this many bytes. Hard limit is -@@ -234302,10 +235676,11 @@ typedef struct Fts5Colset Fts5Colset; - */ - struct Fts5Colset { - int nCol; -- int aiCol[1]; -+ int aiCol[FLEXARRAY]; - }; - -- -+/* Size (int bytes) of a complete Fts5Colset object with N columns. */ -+#define SZ_FTS5COLSET(N) (sizeof(i64)*((N+2)/2)) - - /************************************************************************** - ** Interface to code in fts5_config.c. fts5_config.c contains contains code -@@ -235134,7 +236509,7 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); - ** - ** The "lemon" program processes an LALR(1) input grammar file, then uses - ** this template to construct a parser. The "lemon" program inserts text --** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the -+** at each "%%" line. Also, any "P-a-r-s-e" identifier prefix (without the - ** interstitial "-" characters) contained in this template is changed into - ** the value of the %name directive from the grammar. Otherwise, the content - ** of this template is copied straight through into the generate parser -@@ -237288,7 +238663,7 @@ static int fts5Bm25GetData( - ** under consideration. - ** - ** The problem with this is that if (N < 2*nHit), the IDF is -- ** negative. Which is undesirable. So the mimimum allowable IDF is -+ ** negative. Which is undesirable. So the minimum allowable IDF is - ** (1e-6) - roughly the same as a term that appears in just over - ** half of set of 5,000,000 documents. */ - double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) ); -@@ -237751,7 +239126,7 @@ static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ - ** * The 52 upper and lower case ASCII characters, and - ** * The 10 integer ASCII characters. - ** * The underscore character "_" (0x5F). --** * The unicode "subsitute" character (0x1A). -+** * The unicode "substitute" character (0x1A). - */ - static int sqlite3Fts5IsBareword(char t){ - u8 aBareword[128] = { -@@ -239069,9 +240444,13 @@ struct Fts5ExprNode { - /* Child nodes. For a NOT node, this array always contains 2 entries. For - ** AND or OR nodes, it contains 2 or more entries. */ - int nChild; /* Number of child nodes */ -- Fts5ExprNode *apChild[1]; /* Array of child nodes */ -+ Fts5ExprNode *apChild[FLEXARRAY]; /* Array of child nodes */ - }; - -+/* Size (in bytes) of an Fts5ExprNode object that holds up to N children */ -+#define SZ_FTS5EXPRNODE(N) \ -+ (offsetof(Fts5ExprNode,apChild) + (N)*sizeof(Fts5ExprNode*)) -+ - #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING) - - /* -@@ -239102,9 +240481,13 @@ struct Fts5ExprPhrase { - Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */ - Fts5Buffer poslist; /* Current position list */ - int nTerm; /* Number of entries in aTerm[] */ -- Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */ -+ Fts5ExprTerm aTerm[FLEXARRAY]; /* Terms that make up this phrase */ - }; - -+/* Size (in bytes) of an Fts5ExprPhrase object that holds up to N terms */ -+#define SZ_FTS5EXPRPHRASE(N) \ -+ (offsetof(Fts5ExprPhrase,aTerm) + (N)*sizeof(Fts5ExprTerm)) -+ - /* - ** One or more phrases that must appear within a certain token distance of - ** each other within each matching document. -@@ -239113,9 +240496,12 @@ struct Fts5ExprNearset { - int nNear; /* NEAR parameter */ - Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */ - int nPhrase; /* Number of entries in aPhrase[] array */ -- Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */ -+ Fts5ExprPhrase *apPhrase[FLEXARRAY]; /* Array of phrase pointers */ - }; - -+/* Size (in bytes) of an Fts5ExprNearset object covering up to N phrases */ -+#define SZ_FTS5EXPRNEARSET(N) \ -+ (offsetof(Fts5ExprNearset,apPhrase)+(N)*sizeof(Fts5ExprPhrase*)) - - /* - ** Parse context. -@@ -239275,7 +240661,7 @@ static int sqlite3Fts5ExprNew( - /* If the LHS of the MATCH expression was a user column, apply the - ** implicit column-filter. */ - if( sParse.rc==SQLITE_OK && iColnCol ){ -- int n = sizeof(Fts5Colset); -+ int n = SZ_FTS5COLSET(1); - Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); - if( pColset ){ - pColset->nCol = 1; -@@ -240633,7 +242019,7 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( - if( pParse->rc==SQLITE_OK ){ - if( pNear==0 ){ - sqlite3_int64 nByte; -- nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); -+ nByte = SZ_FTS5EXPRNEARSET(SZALLOC+1); - pRet = sqlite3_malloc64(nByte); - if( pRet==0 ){ - pParse->rc = SQLITE_NOMEM; -@@ -240644,7 +242030,7 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( - int nNew = pNear->nPhrase + SZALLOC; - sqlite3_int64 nByte; - -- nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*); -+ nByte = SZ_FTS5EXPRNEARSET(nNew+1); - pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte); - if( pRet==0 ){ - pParse->rc = SQLITE_NOMEM; -@@ -240735,12 +242121,12 @@ static int fts5ParseTokenize( - int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0); - - pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase, -- sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew -+ SZ_FTS5EXPRPHRASE(nNew+1) - ); - if( pNew==0 ){ - rc = SQLITE_NOMEM; - }else{ -- if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase)); -+ if( pPhrase==0 ) memset(pNew, 0, SZ_FTS5EXPRPHRASE(1)); - pCtx->pPhrase = pPhrase = pNew; - pNew->nTerm = nNew - SZALLOC; - } -@@ -240848,7 +242234,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( - if( sCtx.pPhrase==0 ){ - /* This happens when parsing a token or quoted phrase that contains - ** no token characters at all. (e.g ... MATCH '""'). */ -- sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); -+ sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, SZ_FTS5EXPRPHRASE(1)); - }else if( sCtx.pPhrase->nTerm ){ - sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; - } -@@ -240883,19 +242269,18 @@ static int sqlite3Fts5ExprClonePhrase( - sizeof(Fts5ExprPhrase*)); - } - if( rc==SQLITE_OK ){ -- pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, -- sizeof(Fts5ExprNode)); -+ pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRNODE(1)); - } - if( rc==SQLITE_OK ){ - pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, -- sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); -+ SZ_FTS5EXPRNEARSET(2)); - } - if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){ - Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; - if( pColsetOrig ){ - sqlite3_int64 nByte; - Fts5Colset *pColset; -- nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int); -+ nByte = SZ_FTS5COLSET(pColsetOrig->nCol); - pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); - if( pColset ){ - memcpy(pColset, pColsetOrig, (size_t)nByte); -@@ -240923,7 +242308,7 @@ static int sqlite3Fts5ExprClonePhrase( - }else{ - /* This happens when parsing a token or quoted phrase that contains - ** no token characters at all. (e.g ... MATCH '""'). */ -- sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); -+ sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRPHRASE(1)); - } - } - -@@ -240988,7 +242373,8 @@ static void sqlite3Fts5ParseSetDistance( - ); - return; - } -- nNear = nNear * 10 + (p->p[i] - '0'); -+ if( nNear<214748363 ) nNear = nNear * 10 + (p->p[i] - '0'); -+ /* ^^^^^^^^^^^^^^^--- Prevent integer overflow */ - } - }else{ - nNear = FTS5_DEFAULT_NEARDIST; -@@ -241017,7 +242403,7 @@ static Fts5Colset *fts5ParseColset( - assert( pParse->rc==SQLITE_OK ); - assert( iCol>=0 && iColpConfig->nCol ); - -- pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol); -+ pNew = sqlite3_realloc64(p, SZ_FTS5COLSET(nCol+1)); - if( pNew==0 ){ - pParse->rc = SQLITE_NOMEM; - }else{ -@@ -241052,7 +242438,7 @@ static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p - int nCol = pParse->pConfig->nCol; - - pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, -- sizeof(Fts5Colset) + sizeof(int)*nCol -+ SZ_FTS5COLSET(nCol+1) - ); - if( pRet ){ - int i; -@@ -241113,7 +242499,7 @@ static Fts5Colset *sqlite3Fts5ParseColset( - static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ - Fts5Colset *pRet; - if( pOrig ){ -- sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); -+ sqlite3_int64 nByte = SZ_FTS5COLSET(pOrig->nCol); - pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte); - if( pRet ){ - memcpy(pRet, pOrig, (size_t)nByte); -@@ -241281,7 +242667,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( - assert( pNear->nPhrase==1 ); - assert( pParse->bPhraseToAnd ); - -- nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*); -+ nByte = SZ_FTS5EXPRNODE(nTerm+1); - pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); - if( pRet ){ - pRet->eType = FTS5_AND; -@@ -241291,7 +242677,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( - pParse->nPhrase--; - for(ii=0; iirc, sizeof(Fts5ExprPhrase) -+ &pParse->rc, SZ_FTS5EXPRPHRASE(1) - ); - if( pPhrase ){ - if( parseGrowPhraseArray(pParse) ){ -@@ -241360,7 +242746,7 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( - if( pRight->eType==eType ) nChild += pRight->nChild-1; - } - -- nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); -+ nByte = SZ_FTS5EXPRNODE(nChild); - pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); - - if( pRet ){ -@@ -242235,7 +243621,7 @@ static int sqlite3Fts5ExprInstToken( - } - - /* --** Clear the token mappings for all Fts5IndexIter objects mannaged by -+** Clear the token mappings for all Fts5IndexIter objects managed by - ** the expression passed as the only argument. - */ - static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){ -@@ -242270,7 +243656,7 @@ typedef struct Fts5HashEntry Fts5HashEntry; - - /* - ** This file contains the implementation of an in-memory hash table used --** to accumuluate "term -> doclist" content before it is flused to a level-0 -+** to accumulate "term -> doclist" content before it is flushed to a level-0 - ** segment. - */ - -@@ -242327,7 +243713,7 @@ struct Fts5HashEntry { - }; - - /* --** Eqivalent to: -+** Equivalent to: - ** - ** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; } - */ -@@ -243263,9 +244649,13 @@ struct Fts5Structure { - u64 nOriginCntr; /* Origin value for next top-level segment */ - int nSegment; /* Total segments in this structure */ - int nLevel; /* Number of levels in this index */ -- Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */ -+ Fts5StructureLevel aLevel[FLEXARRAY]; /* Array of nLevel level objects */ - }; - -+/* Size (in bytes) of an Fts5Structure object holding up to N levels */ -+#define SZ_FTS5STRUCTURE(N) \ -+ (offsetof(Fts5Structure,aLevel) + (N)*sizeof(Fts5StructureLevel)) -+ - /* - ** An object of type Fts5SegWriter is used to write to segments. - */ -@@ -243395,11 +244785,15 @@ struct Fts5SegIter { - ** Array of tombstone pages. Reference counted. - */ - struct Fts5TombstoneArray { -- int nRef; /* Number of pointers to this object */ -+ int nRef; /* Number of pointers to this object */ - int nTombstone; -- Fts5Data *apTombstone[1]; /* Array of tombstone pages */ -+ Fts5Data *apTombstone[FLEXARRAY]; /* Array of tombstone pages */ - }; - -+/* Size (in bytes) of an Fts5TombstoneArray holding up to N tombstones */ -+#define SZ_FTS5TOMBSTONEARRAY(N) \ -+ (offsetof(Fts5TombstoneArray,apTombstone)+(N)*sizeof(Fts5Data*)) -+ - /* - ** Argument is a pointer to an Fts5Data structure that contains a - ** leaf page. -@@ -243468,9 +244862,12 @@ struct Fts5Iter { - - i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */ - Fts5CResult *aFirst; /* Current merge state (see above) */ -- Fts5SegIter aSeg[1]; /* Array of segment iterators */ -+ Fts5SegIter aSeg[FLEXARRAY]; /* Array of segment iterators */ - }; - -+/* Size (in bytes) of an Fts5Iter object holding up to N segment iterators */ -+#define SZ_FTS5ITER(N) (offsetof(Fts5Iter,aSeg)+(N)*sizeof(Fts5SegIter)) -+ - /* - ** An instance of the following type is used to iterate through the contents - ** of a doclist-index record. -@@ -243497,9 +244894,13 @@ struct Fts5DlidxLvl { - struct Fts5DlidxIter { - int nLvl; - int iSegid; -- Fts5DlidxLvl aLvl[1]; -+ Fts5DlidxLvl aLvl[FLEXARRAY]; - }; - -+/* Size (in bytes) of an Fts5DlidxIter object with up to N levels */ -+#define SZ_FTS5DLIDXITER(N) \ -+ (offsetof(Fts5DlidxIter,aLvl)+(N)*sizeof(Fts5DlidxLvl)) -+ - static void fts5PutU16(u8 *aOut, u16 iVal){ - aOut[0] = (iVal>>8); - aOut[1] = (iVal&0xFF); -@@ -243867,7 +245268,7 @@ static int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){ - static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){ - Fts5Structure *p = *pp; - if( *pRc==SQLITE_OK && p->nRef>1 ){ -- i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel); -+ i64 nByte = SZ_FTS5STRUCTURE(p->nLevel); - Fts5Structure *pNew; - pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte); - if( pNew ){ -@@ -243941,10 +245342,7 @@ static int fts5StructureDecode( - ){ - return FTS5_CORRUPT; - } -- nByte = ( -- sizeof(Fts5Structure) + /* Main structure */ -- sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */ -- ); -+ nByte = SZ_FTS5STRUCTURE(nLevel); - pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte); - - if( pRet ){ -@@ -244024,10 +245422,7 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ - if( *pRc==SQLITE_OK ){ - Fts5Structure *pStruct = *ppStruct; - int nLevel = pStruct->nLevel; -- sqlite3_int64 nByte = ( -- sizeof(Fts5Structure) + /* Main structure */ -- sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */ -- ); -+ sqlite3_int64 nByte = SZ_FTS5STRUCTURE(nLevel+2); - - pStruct = sqlite3_realloc64(pStruct, nByte); - if( pStruct ){ -@@ -244566,7 +245961,7 @@ static Fts5DlidxIter *fts5DlidxIterInit( - int bDone = 0; - - for(i=0; p->rc==SQLITE_OK && bDone==0; i++){ -- sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl); -+ sqlite3_int64 nByte = SZ_FTS5DLIDXITER(i+1); - Fts5DlidxIter *pNew; - - pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte); -@@ -244782,9 +246177,9 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ - ** leave an error in the Fts5Index object. - */ - static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ -- const int nTomb = pIter->pSeg->nPgTombstone; -+ const i64 nTomb = (i64)pIter->pSeg->nPgTombstone; - if( nTomb>0 ){ -- int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray); -+ i64 nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1); - Fts5TombstoneArray *pNew; - pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); - if( pNew ){ -@@ -246245,8 +247640,7 @@ static Fts5Iter *fts5MultiIterAlloc( - - for(nSlot=2; nSlotaSeg[] */ -+ SZ_FTS5ITER(nSlot) + /* pNew + pNew->aSeg[] */ - sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */ - ); - if( pNew ){ -@@ -248047,7 +249441,7 @@ static void fts5DoSecureDelete( - int iDelKeyOff = 0; /* Offset of deleted key, if any */ - - nIdx = nPg-iPgIdx; -- aIdx = sqlite3Fts5MallocZero(&p->rc, nIdx+16); -+ aIdx = sqlite3Fts5MallocZero(&p->rc, ((i64)nIdx)+16); - if( p->rc ) return; - memcpy(aIdx, &aPg[iPgIdx], nIdx); - -@@ -248612,7 +250006,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( - Fts5Structure *pStruct - ){ - Fts5Structure *pNew = 0; -- sqlite3_int64 nByte = sizeof(Fts5Structure); -+ sqlite3_int64 nByte = SZ_FTS5STRUCTURE(1); - int nSeg = pStruct->nSegment; - int i; - -@@ -248641,7 +250035,8 @@ static Fts5Structure *fts5IndexOptimizeStruct( - assert( pStruct->aLevel[i].nMerge<=nThis ); - } - -- nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel); -+ nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel); -+ assert( nByte==SZ_FTS5STRUCTURE(pStruct->nLevel+2) ); - pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); - - if( pNew ){ -@@ -249218,9 +250613,13 @@ struct Fts5TokenDataIter { - int nIterAlloc; - Fts5PoslistReader *aPoslistReader; - int *aPoslistToIter; -- Fts5Iter *apIter[1]; -+ Fts5Iter *apIter[FLEXARRAY]; - }; - -+/* Size in bytes of an Fts5TokenDataIter object holding up to N iterators */ -+#define SZ_FTS5TOKENDATAITER(N) \ -+ (offsetof(Fts5TokenDataIter,apIter) + (N)*sizeof(Fts5Iter)) -+ - /* - ** The two input arrays - a1[] and a2[] - are in sorted order. This function - ** merges the two arrays together and writes the result to output array -@@ -249292,7 +250691,7 @@ static void fts5TokendataIterAppendMap( - /* - ** Sort the contents of the pT->aMap[] array. - ** --** The sorting algorithm requries a malloc(). If this fails, an error code -+** The sorting algorithm requires a malloc(). If this fails, an error code - ** is left in Fts5Index.rc before returning. - */ - static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ -@@ -249483,7 +250882,7 @@ static void fts5SetupPrefixIter( - && p->pConfig->bPrefixInsttoken - ){ - s.pTokendata = &s2; -- s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT)); -+ s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, SZ_FTS5TOKENDATAITER(1)); - } - - if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ -@@ -249529,7 +250928,8 @@ static void fts5SetupPrefixIter( - } - } - -- pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING); -+ pData = fts5IdxMalloc(p, sizeof(*pData) -+ + ((i64)s.doclist.n)+FTS5_DATA_ZERO_PADDING); - assert( pData!=0 || p->rc!=SQLITE_OK ); - if( pData ){ - pData->p = (u8*)&pData[1]; -@@ -249610,15 +251010,17 @@ static int sqlite3Fts5IndexRollback(Fts5Index *p){ - ** and the initial version of the "averages" record (a zero-byte blob). - */ - static int sqlite3Fts5IndexReinit(Fts5Index *p){ -- Fts5Structure s; -+ Fts5Structure *pTmp; -+ u8 tmpSpace[SZ_FTS5STRUCTURE(1)]; - fts5StructureInvalidate(p); - fts5IndexDiscardData(p); -- memset(&s, 0, sizeof(Fts5Structure)); -+ pTmp = (Fts5Structure*)tmpSpace; -+ memset(pTmp, 0, SZ_FTS5STRUCTURE(1)); - if( p->pConfig->bContentlessDelete ){ -- s.nOriginCntr = 1; -+ pTmp->nOriginCntr = 1; - } - fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); -- fts5StructureWrite(p, &s); -+ fts5StructureWrite(p, pTmp); - return fts5IndexReturn(p); - } - -@@ -249826,7 +251228,7 @@ static Fts5TokenDataIter *fts5AppendTokendataIter( - if( p->rc==SQLITE_OK ){ - if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ - int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; -- int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter); -+ int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1); - Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); - - if( pNew==0 ){ -@@ -250342,7 +251744,8 @@ static int fts5SetupPrefixIterTokendata( - - fts5BufferGrow(&p->rc, &token, nToken+1); - assert( token.p!=0 || p->rc!=SQLITE_OK ); -- ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT)); -+ ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, -+ SZ_FTS5TOKENDATAITER(1)); - - if( p->rc==SQLITE_OK ){ - -@@ -250473,7 +251876,8 @@ static int sqlite3Fts5IndexIterWriteTokendata( - if( pIter->nSeg>0 ){ - /* This is a prefix term iterator. */ - if( pT==0 ){ -- pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT)); -+ pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, -+ SZ_FTS5TOKENDATAITER(1)); - pIter->pTokenDataIter = pT; - } - if( pT ){ -@@ -251507,7 +252911,7 @@ static void fts5DecodeRowid( - - #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) - static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ -- int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */ -+ int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid components */ - fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); - - if( iSegid==0 ){ -@@ -251753,7 +253157,7 @@ static void fts5DecodeFunction( - ** buffer overreads even if the record is corrupt. */ - n = sqlite3_value_bytes(apVal[1]); - aBlob = sqlite3_value_blob(apVal[1]); -- nSpace = n + FTS5_DATA_ZERO_PADDING; -+ nSpace = ((i64)n) + FTS5_DATA_ZERO_PADDING; - a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace); - if( a==0 ) goto decode_out; - if( n>0 ) memcpy(a, aBlob, n); -@@ -252468,9 +253872,11 @@ struct Fts5Sorter { - i64 iRowid; /* Current rowid */ - const u8 *aPoslist; /* Position lists for current row */ - int nIdx; /* Number of entries in aIdx[] */ -- int aIdx[1]; /* Offsets into aPoslist for current row */ -+ int aIdx[FLEXARRAY]; /* Offsets into aPoslist for current row */ - }; - -+/* Size (int bytes) of an Fts5Sorter object with N indexes */ -+#define SZ_FTS5SORTER(N) (offsetof(Fts5Sorter,nIdx)+((N+2)/2)*sizeof(i64)) - - /* - ** Virtual-table cursor object. -@@ -253348,7 +254754,7 @@ static int fts5CursorFirstSorted( - const char *zRankArgs = pCsr->zRankArgs; - - nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); -- nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1); -+ nByte = SZ_FTS5SORTER(nPhrase); - pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte); - if( pSorter==0 ) return SQLITE_NOMEM; - memset(pSorter, 0, (size_t)nByte); -@@ -255874,7 +257280,7 @@ static void fts5SourceIdFunc( - ){ - assert( nArg==0 ); - UNUSED_PARAM2(nArg, apUnused); -- sqlite3_result_text(pCtx, "fts5: 2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70", -1, SQLITE_TRANSIENT); -+ sqlite3_result_text(pCtx, "fts5: 2025-07-17 13:25:10 3ce993b8657d6d9deda380a93cdd6404a8c8ba1b185b2bc423703e41ae5f2543", -1, SQLITE_TRANSIENT); - } - - /* -@@ -256099,8 +257505,8 @@ static int fts5Init(sqlite3 *db){ - ** its entry point to enable the matchinfo() demo. */ - #ifdef SQLITE_FTS5_ENABLE_TEST_MI - if( rc==SQLITE_OK ){ -- extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*); -- rc = sqlite3Fts5TestRegisterMatchinfo(db); -+ extern int sqlite3Fts5TestRegisterMatchinfoAPI(fts5_api*); -+ rc = sqlite3Fts5TestRegisterMatchinfoAPI(&pGlobal->api); - } - #endif - -@@ -256689,6 +258095,7 @@ static int fts5StorageDeleteFromIndex( - for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ - if( pConfig->abUnindexed[iCol-1]==0 ){ - sqlite3_value *pVal = 0; -+ sqlite3_value *pFree = 0; - const char *pText = 0; - int nText = 0; - const char *pLoc = 0; -@@ -256705,11 +258112,22 @@ static int fts5StorageDeleteFromIndex( - if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ - rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); - }else{ -- pText = (const char*)sqlite3_value_text(pVal); -- nText = sqlite3_value_bytes(pVal); -- if( pConfig->bLocale && pSeek ){ -- pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); -- nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); -+ if( sqlite3_value_type(pVal)!=SQLITE_TEXT ){ -+ /* Make a copy of the value to work with. This is because the call -+ ** to sqlite3_value_text() below forces the type of the value to -+ ** SQLITE_TEXT, and we may need to use it again later. */ -+ pFree = pVal = sqlite3_value_dup(pVal); -+ if( pVal==0 ){ -+ rc = SQLITE_NOMEM; -+ } -+ } -+ if( rc==SQLITE_OK ){ -+ pText = (const char*)sqlite3_value_text(pVal); -+ nText = sqlite3_value_bytes(pVal); -+ if( pConfig->bLocale && pSeek ){ -+ pLoc = (const char*)sqlite3_column_text(pSeek, iCol+pConfig->nCol); -+ nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); -+ } - } - } - -@@ -256725,6 +258143,7 @@ static int fts5StorageDeleteFromIndex( - } - sqlite3Fts5ClearLocale(pConfig); - } -+ sqlite3_value_free(pFree); - } - } - if( rc==SQLITE_OK && p->nTotalRow<1 ){ -@@ -259938,7 +261357,6 @@ static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ - aAscii[0] = 0; /* 0x00 is never a token character */ - } - -- - /* - ** 2015 May 30 - ** -@@ -260479,12 +261897,12 @@ static int fts5VocabInitVtab( - *pzErr = sqlite3_mprintf("wrong number of vtable arguments"); - rc = SQLITE_ERROR; - }else{ -- int nByte; /* Bytes of space to allocate */ -+ i64 nByte; /* Bytes of space to allocate */ - const char *zDb = bDb ? argv[3] : argv[1]; - const char *zTab = bDb ? argv[4] : argv[3]; - const char *zType = bDb ? argv[5] : argv[4]; -- int nDb = (int)strlen(zDb)+1; -- int nTab = (int)strlen(zTab)+1; -+ i64 nDb = strlen(zDb)+1; -+ i64 nTab = strlen(zTab)+1; - int eType = 0; - - rc = fts5VocabTableType(zType, pzErr, &eType); -diff --git a/deps/sqlite/sqlite3.h b/deps/sqlite/sqlite3.h -index 082a9f9d..d2ec9030 100644 ---- a/deps/sqlite/sqlite3.h -+++ b/deps/sqlite/sqlite3.h -@@ -133,7 +133,7 @@ extern "C" { - ** - ** Since [version 3.6.18] ([dateof:3.6.18]), - ** SQLite source code has been stored in the --** Fossil configuration management -+** Fossil configuration management - ** system. ^The SQLITE_SOURCE_ID macro evaluates to - ** a string which identifies a particular check-in of SQLite - ** within its configuration management system. ^The SQLITE_SOURCE_ID -@@ -146,9 +146,9 @@ extern "C" { - ** [sqlite3_libversion_number()], [sqlite3_sourceid()], - ** [sqlite_version()] and [sqlite_source_id()]. - */ --#define SQLITE_VERSION "3.49.1" --#define SQLITE_VERSION_NUMBER 3049001 --#define SQLITE_SOURCE_ID "2025-02-18 13:38:58 873d4e274b4988d260ba8354a9718324a1c26187a4ab4c1cc0227c03d0f10e70" -+#define SQLITE_VERSION "3.50.3" -+#define SQLITE_VERSION_NUMBER 3050003 -+#define SQLITE_SOURCE_ID "2025-07-17 13:25:10 3ce993b8657d6d9deda380a93cdd6404a8c8ba1b185b2bc423703e41ae5f2543" - - /* - ** CAPI3REF: Run-Time Library Version Numbers -@@ -1163,6 +1163,12 @@ struct sqlite3_io_methods { - ** the value that M is to be set to. Before returning, the 32-bit signed - ** integer is overwritten with the previous value of M. - ** -+**
        • [[SQLITE_FCNTL_BLOCK_ON_CONNECT]] -+** The [SQLITE_FCNTL_BLOCK_ON_CONNECT] opcode is used to configure the -+** VFS to block when taking a SHARED lock to connect to a wal mode database. -+** This is used to implement the functionality associated with -+** SQLITE_SETLK_BLOCK_ON_CONNECT. -+** - **
        • [[SQLITE_FCNTL_DATA_VERSION]] - ** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to - ** a database file. The argument is a pointer to a 32-bit unsigned integer. -@@ -1259,6 +1265,7 @@ struct sqlite3_io_methods { - #define SQLITE_FCNTL_CKSM_FILE 41 - #define SQLITE_FCNTL_RESET_CACHE 42 - #define SQLITE_FCNTL_NULL_IO 43 -+#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 - - /* deprecated names */ - #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE -@@ -1989,13 +1996,16 @@ struct sqlite3_mem_methods { - ** - ** [[SQLITE_CONFIG_LOOKASIDE]]
          SQLITE_CONFIG_LOOKASIDE
          - **
          ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine --** the default size of lookaside memory on each [database connection]. -+** the default size of [lookaside memory] on each [database connection]. - ** The first argument is the --** size of each lookaside buffer slot and the second is the number of --** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE --** sets the default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] --** option to [sqlite3_db_config()] can be used to change the lookaside --** configuration on individual connections.)^
          -+** size of each lookaside buffer slot ("sz") and the second is the number of -+** slots allocated to each database connection ("cnt").)^ -+** ^(SQLITE_CONFIG_LOOKASIDE sets the default lookaside size. -+** The [SQLITE_DBCONFIG_LOOKASIDE] option to [sqlite3_db_config()] can -+** be used to change the lookaside configuration on individual connections.)^ -+** The [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to change the -+** default lookaside configuration at compile-time. -+**
        • - ** - ** [[SQLITE_CONFIG_PCACHE2]]
          SQLITE_CONFIG_PCACHE2
          - **
          ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is -@@ -2232,31 +2242,50 @@ struct sqlite3_mem_methods { - ** [[SQLITE_DBCONFIG_LOOKASIDE]] - **
          SQLITE_DBCONFIG_LOOKASIDE
          - **
          The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the --** configuration of the lookaside memory allocator within a database -+** configuration of the [lookaside memory allocator] within a database - ** connection. - ** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are not - ** in the [DBCONFIG arguments|usual format]. - ** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two, - ** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE - ** should have a total of five parameters. --** ^The first argument (the third parameter to [sqlite3_db_config()] is a -+**
            -+**
          1. The first argument ("buf") is a - ** pointer to a memory buffer to use for lookaside memory. --** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb --** may be NULL in which case SQLite will allocate the --** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the --** size of each lookaside buffer slot. ^The third argument is the number of --** slots. The size of the buffer in the first argument must be greater than --** or equal to the product of the second and third arguments. The buffer --** must be aligned to an 8-byte boundary. ^If the second argument to --** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally --** rounded down to the next smaller multiple of 8. ^(The lookaside memory -+** The first argument may be NULL in which case SQLite will allocate the -+** lookaside buffer itself using [sqlite3_malloc()]. -+**

          2. The second argument ("sz") is the -+** size of each lookaside buffer slot. Lookaside is disabled if "sz" -+** is less than 8. The "sz" argument should be a multiple of 8 less than -+** 65536. If "sz" does not meet this constraint, it is reduced in size until -+** it does. -+**

          3. The third argument ("cnt") is the number of slots. Lookaside is disabled -+** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so -+** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" -+** parameter is usually chosen so that the product of "sz" and "cnt" is less -+** than 1,000,000. -+**

          -+**

          If the "buf" argument is not NULL, then it must -+** point to a memory buffer with a size that is greater than -+** or equal to the product of "sz" and "cnt". -+** The buffer must be aligned to an 8-byte boundary. -+** The lookaside memory - ** configuration for a database connection can only be changed when that - ** connection is not currently using lookaside memory, or in other words --** when the "current value" returned by --** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero. -+** when the value returned by [SQLITE_DBSTATUS_LOOKASIDE_USED] is zero. - ** Any attempt to change the lookaside memory configuration when lookaside - ** memory is in use leaves the configuration unchanged and returns --** [SQLITE_BUSY].)^

          -+** [SQLITE_BUSY]. -+** If the "buf" argument is NULL and an attempt -+** to allocate memory based on "sz" and "cnt" fails, then -+** lookaside is silently disabled. -+**

          -+** The [SQLITE_CONFIG_LOOKASIDE] configuration option can be used to set the -+** default lookaside configuration at initialization. The -+** [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to set the default lookaside -+** configuration at compile-time. Typical values for lookaside are 1200 for -+** "sz" and 40 to 100 for "cnt". -+** - ** - ** [[SQLITE_DBCONFIG_ENABLE_FKEY]] - **

          SQLITE_DBCONFIG_ENABLE_FKEY
          -@@ -2993,6 +3022,44 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); - */ - SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); - -+/* -+** CAPI3REF: Set the Setlk Timeout -+** METHOD: sqlite3 -+** -+** This routine is only useful in SQLITE_ENABLE_SETLK_TIMEOUT builds. If -+** the VFS supports blocking locks, it sets the timeout in ms used by -+** eligible locks taken on wal mode databases by the specified database -+** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does -+** not support blocking locks, this function is a no-op. -+** -+** Passing 0 to this function disables blocking locks altogether. Passing -+** -1 to this function requests that the VFS blocks for a long time - -+** indefinitely if possible. The results of passing any other negative value -+** are undefined. -+** -+** Internally, each SQLite database handle store two timeout values - the -+** busy-timeout (used for rollback mode databases, or if the VFS does not -+** support blocking locks) and the setlk-timeout (used for blocking locks -+** on wal-mode databases). The sqlite3_busy_timeout() method sets both -+** values, this function sets only the setlk-timeout value. Therefore, -+** to configure separate busy-timeout and setlk-timeout values for a single -+** database handle, call sqlite3_busy_timeout() followed by this function. -+** -+** Whenever the number of connections to a wal mode database falls from -+** 1 to 0, the last connection takes an exclusive lock on the database, -+** then checkpoints and deletes the wal file. While it is doing this, any -+** new connection that tries to read from the database fails with an -+** SQLITE_BUSY error. Or, if the SQLITE_SETLK_BLOCK_ON_CONNECT flag is -+** passed to this API, the new connection blocks until the exclusive lock -+** has been released. -+*/ -+SQLITE_API int sqlite3_setlk_timeout(sqlite3*, int ms, int flags); -+ -+/* -+** CAPI3REF: Flags for sqlite3_setlk_timeout() -+*/ -+#define SQLITE_SETLK_BLOCK_ON_CONNECT 0x01 -+ - /* - ** CAPI3REF: Convenience Routines For Running Queries - ** METHOD: sqlite3 -@@ -4012,7 +4079,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); - ** - ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of - ** database filename D with corresponding journal file J and WAL file W and --** with N URI parameters key/values pairs in the array P. The result from -+** an array P of N URI Key/Value pairs. The result from - ** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that - ** is safe to pass to routines like: - **
            -@@ -4693,7 +4760,7 @@ typedef struct sqlite3_context sqlite3_context; - ** METHOD: sqlite3_stmt - ** - ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, --** literals may be replaced by a [parameter] that matches one of following -+** literals may be replaced by a [parameter] that matches one of the following - ** templates: - ** - **
              -@@ -4738,7 +4805,7 @@ typedef struct sqlite3_context sqlite3_context; - ** - ** [[byte-order determination rules]] ^The byte-order of - ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) --** found in first character, which is removed, or in the absence of a BOM -+** found in the first character, which is removed, or in the absence of a BOM - ** the byte order is the native byte order of the host - ** machine for sqlite3_bind_text16() or the byte order specified in - ** the 6th parameter for sqlite3_bind_text64().)^ -@@ -4758,7 +4825,7 @@ typedef struct sqlite3_context sqlite3_context; - ** or sqlite3_bind_text16() or sqlite3_bind_text64() then - ** that parameter must be the byte offset - ** where the NUL terminator would occur assuming the string were NUL --** terminated. If any NUL characters occurs at byte offsets less than -+** terminated. If any NUL characters occur at byte offsets less than - ** the value of the fourth parameter then the resulting string value will - ** contain embedded NULs. The result of expressions involving strings - ** with embedded NULs is undefined. -@@ -4970,7 +5037,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); - ** METHOD: sqlite3_stmt - ** - ** ^These routines provide a means to determine the database, table, and --** table column that is the origin of a particular result column in -+** table column that is the origin of a particular result column in a - ** [SELECT] statement. - ** ^The name of the database or table or column can be returned as - ** either a UTF-8 or UTF-16 string. ^The _database_ routines return -@@ -5108,7 +5175,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); - ** other than [SQLITE_ROW] before any subsequent invocation of - ** sqlite3_step(). Failure to reset the prepared statement using - ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from --** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], -+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), - ** sqlite3_step() began - ** calling [sqlite3_reset()] automatically in this circumstance rather - ** than returning [SQLITE_MISUSE]. This is not considered a compatibility -@@ -5539,8 +5606,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); - ** - ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for - ** all application-defined SQL functions that do not need to be --** used inside of triggers, view, CHECK constraints, or other elements of --** the database schema. This flags is especially recommended for SQL -+** used inside of triggers, views, CHECK constraints, or other elements of -+** the database schema. This flag is especially recommended for SQL - ** functions that have side effects or reveal internal application state. - ** Without this flag, an attacker might be able to modify the schema of - ** a database file to include invocations of the function with parameters -@@ -5571,7 +5638,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); - ** [user-defined window functions|available here]. - ** - ** ^(If the final parameter to sqlite3_create_function_v2() or --** sqlite3_create_window_function() is not NULL, then it is destructor for -+** sqlite3_create_window_function() is not NULL, then it is the destructor for - ** the application data pointer. The destructor is invoked when the function - ** is deleted, either by being overloaded or when the database connection - ** closes.)^ ^The destructor is also invoked if the call to -@@ -5971,7 +6038,7 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); - ** METHOD: sqlite3_value - ** - ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] --** object D and returns a pointer to that copy. ^The [sqlite3_value] returned -+** object V and returns a pointer to that copy. ^The [sqlite3_value] returned - ** is a [protected sqlite3_value] object even if the input is not. - ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a - ** memory allocation fails. ^If V is a [pointer value], then the result -@@ -6009,7 +6076,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*); - ** allocation error occurs. - ** - ** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is --** determined by the N parameter on first successful call. Changing the -+** determined by the N parameter on the first successful call. Changing the - ** value of N in any subsequent call to sqlite3_aggregate_context() within - ** the same aggregate function instance will not resize the memory - ** allocation.)^ Within the xFinal callback, it is customary to set -@@ -6171,7 +6238,7 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi - ** - ** Security Warning: These interfaces should not be exposed in scripting - ** languages or in other circumstances where it might be possible for an --** an attacker to invoke them. Any agent that can invoke these interfaces -+** attacker to invoke them. Any agent that can invoke these interfaces - ** can probably also take control of the process. - ** - ** Database connection client data is only available for SQLite -@@ -6285,7 +6352,7 @@ typedef void (*sqlite3_destructor_type)(void*); - ** pointed to by the 2nd parameter are taken as the application-defined - ** function result. If the 3rd parameter is non-negative, then it - ** must be the byte offset into the string where the NUL terminator would --** appear if the string where NUL terminated. If any NUL characters occur -+** appear if the string were NUL terminated. If any NUL characters occur - ** in the string at a byte offset that is less than the value of the 3rd - ** parameter, then the resulting string will contain embedded NULs and the - ** result of expressions operating on strings with embedded NULs is undefined. -@@ -6343,7 +6410,7 @@ typedef void (*sqlite3_destructor_type)(void*); - ** string and preferably a string literal. The sqlite3_result_pointer() - ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. - ** --** If these routines are called from within the different thread -+** If these routines are called from within a different thread - ** than the one containing the application-defined function that received - ** the [sqlite3_context] pointer, the results are undefined. - */ -@@ -6749,7 +6816,7 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); - ** METHOD: sqlite3 - ** - ** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name --** for the N-th database on database connection D, or a NULL pointer of N is -+** for the N-th database on database connection D, or a NULL pointer if N is - ** out of range. An N value of 0 means the main database file. An N of 1 is - ** the "temp" schema. Larger values of N correspond to various ATTACH-ed - ** databases. -@@ -6844,7 +6911,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); - **
              The SQLITE_TXN_READ state means that the database is currently - ** in a read transaction. Content has been read from the database file - ** but nothing in the database file has changed. The transaction state --** will advanced to SQLITE_TXN_WRITE if any changes occur and there are -+** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are - ** no other conflicting concurrent write transactions. The transaction - ** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or - ** [COMMIT].
              -@@ -6853,7 +6920,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); - **
              The SQLITE_TXN_WRITE state means that the database is currently - ** in a write transaction. Content has been written to the database file - ** but has not yet committed. The transaction state will change to --** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
              -+** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT]. - */ - #define SQLITE_TXN_NONE 0 - #define SQLITE_TXN_READ 1 -@@ -7004,6 +7071,8 @@ SQLITE_API int sqlite3_autovacuum_pages( - ** - ** ^The second argument is a pointer to the function to invoke when a - ** row is updated, inserted or deleted in a rowid table. -+** ^The update hook is disabled by invoking sqlite3_update_hook() -+** with a NULL pointer as the second parameter. - ** ^The first argument to the callback is a copy of the third argument - ** to sqlite3_update_hook(). - ** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], -@@ -7132,7 +7201,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); - ** CAPI3REF: Impose A Limit On Heap Size - ** - ** These interfaces impose limits on the amount of heap memory that will be --** by all database connections within a single process. -+** used by all database connections within a single process. - ** - ** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the - ** soft limit on the amount of heap memory that may be allocated by SQLite. -@@ -7190,7 +7259,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*); - **
            )^ - ** - ** The circumstances under which SQLite will enforce the heap limits may --** changes in future releases of SQLite. -+** change in future releases of SQLite. - */ - SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); - SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); -@@ -7305,8 +7374,8 @@ SQLITE_API int sqlite3_table_column_metadata( - ** ^The entry point is zProc. - ** ^(zProc may be 0, in which case SQLite will try to come up with an - ** entry point name on its own. It first tries "sqlite3_extension_init". --** If that does not work, it constructs a name "sqlite3_X_init" where the --** X is consists of the lower-case equivalent of all ASCII alphabetic -+** If that does not work, it constructs a name "sqlite3_X_init" where -+** X consists of the lower-case equivalent of all ASCII alphabetic - ** characters in the filename from the last "/" to the first following - ** "." and omitting any initial "lib".)^ - ** ^The sqlite3_load_extension() interface returns -@@ -7377,7 +7446,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); - ** ^(Even though the function prototype shows that xEntryPoint() takes - ** no arguments and returns void, SQLite invokes xEntryPoint() with three - ** arguments and expects an integer result as if the signature of the --** entry point where as follows: -+** entry point were as follows: - ** - **
            - **    int xEntryPoint(
            -@@ -7541,7 +7610,7 @@ struct sqlite3_module {
            - ** virtual table and might not be checked again by the byte code.)^ ^(The
            - ** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
            - ** is left in its default setting of false, the constraint will always be
            --** checked separately in byte code.  If the omit flag is change to true, then
            -+** checked separately in byte code.  If the omit flag is changed to true, then
            - ** the constraint may or may not be checked in byte code.  In other words,
            - ** when the omit flag is true there is no guarantee that the constraint will
            - ** not be checked again using byte code.)^
            -@@ -7567,7 +7636,7 @@ struct sqlite3_module {
            - ** The xBestIndex method may optionally populate the idxFlags field with a
            - ** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
            - ** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
            --** output to show the idxNum has hex instead of as decimal.  Another flag is
            -+** output to show the idxNum as hex instead of as decimal.  Another flag is
            - ** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
            - ** return at most one row.
            - **
            -@@ -7708,7 +7777,7 @@ struct sqlite3_index_info {
            - ** the implementation of the [virtual table module].   ^The fourth
            - ** parameter is an arbitrary client data pointer that is passed through
            - ** into the [xCreate] and [xConnect] methods of the virtual table module
            --** when a new virtual table is be being created or reinitialized.
            -+** when a new virtual table is being created or reinitialized.
            - **
            - ** ^The sqlite3_create_module_v2() interface has a fifth parameter which
            - ** is a pointer to a destructor for the pClientData.  ^SQLite will
            -@@ -7873,7 +7942,7 @@ typedef struct sqlite3_blob sqlite3_blob;
            - ** in *ppBlob. Otherwise an [error code] is returned and, unless the error
            - ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
            - ** the API is not misused, it is always safe to call [sqlite3_blob_close()]
            --** on *ppBlob after this function it returns.
            -+** on *ppBlob after this function returns.
            - **
            - ** This function fails with SQLITE_ERROR if any of the following are true:
            - ** 
              -@@ -7993,7 +8062,7 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *); - ** - ** ^Returns the size in bytes of the BLOB accessible via the - ** successfully opened [BLOB handle] in its only argument. ^The --** incremental blob I/O routines can only read or overwriting existing -+** incremental blob I/O routines can only read or overwrite existing - ** blob content; they cannot change the size of a blob. - ** - ** This routine only works on a [BLOB handle] which has been created -@@ -8143,7 +8212,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); - ** ^The sqlite3_mutex_alloc() routine allocates a new - ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() - ** routine returns NULL if it is unable to allocate the requested --** mutex. The argument to sqlite3_mutex_alloc() must one of these -+** mutex. The argument to sqlite3_mutex_alloc() must be one of these - ** integer constants: - ** - **
                -@@ -8376,7 +8445,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); - ** CAPI3REF: Retrieve the mutex for a database connection - ** METHOD: sqlite3 - ** --** ^This interface returns a pointer the [sqlite3_mutex] object that -+** ^This interface returns a pointer to the [sqlite3_mutex] object that - ** serializes access to the [database connection] given in the argument - ** when the [threading mode] is Serialized. - ** ^If the [threading mode] is Single-thread or Multi-thread then this -@@ -8499,7 +8568,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); - ** CAPI3REF: SQL Keyword Checking - ** - ** These routines provide access to the set of SQL language keywords --** recognized by SQLite. Applications can uses these routines to determine -+** recognized by SQLite. Applications can use these routines to determine - ** whether or not a specific identifier needs to be escaped (for example, - ** by enclosing in double-quotes) so as not to confuse the parser. - ** -@@ -8667,7 +8736,7 @@ SQLITE_API void sqlite3_str_reset(sqlite3_str*); - ** content of the dynamic string under construction in X. The value - ** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X - ** and might be freed or altered by any subsequent method on the same --** [sqlite3_str] object. Applications must not used the pointer returned -+** [sqlite3_str] object. Applications must not use the pointer returned by - ** [sqlite3_str_value(X)] after any subsequent method call on the same - ** object. ^Applications may change the content of the string returned - ** by [sqlite3_str_value(X)] as long as they do not write into any bytes -@@ -8753,7 +8822,7 @@ SQLITE_API int sqlite3_status64( - ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] - ** buffer and where forced to overflow to [sqlite3_malloc()]. The - ** returned value includes allocations that overflowed because they --** where too large (they were larger than the "sz" parameter to -+** were too large (they were larger than the "sz" parameter to - ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because - ** no space was left in the page cache.)^ - ** -@@ -8837,28 +8906,29 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r - ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
                SQLITE_DBSTATUS_LOOKASIDE_HIT
                - **
                This parameter returns the number of malloc attempts that were - ** satisfied using lookaside memory. Only the high-water value is meaningful; --** the current value is always zero.)^ -+** the current value is always zero.
                )^ - ** - ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] - ** ^(
                SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
                --**
                This parameter returns the number malloc attempts that might have -+**
                This parameter returns the number of malloc attempts that might have - ** been satisfied using lookaside memory but failed due to the amount of - ** memory requested being larger than the lookaside slot size. - ** Only the high-water value is meaningful; --** the current value is always zero.)^ -+** the current value is always zero.
                )^ - ** - ** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] - ** ^(
                SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
                --**
                This parameter returns the number malloc attempts that might have -+**
                This parameter returns the number of malloc attempts that might have - ** been satisfied using lookaside memory but failed due to all lookaside - ** memory already being in use. - ** Only the high-water value is meaningful; --** the current value is always zero.)^ -+** the current value is always zero.
                )^ - ** - ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
                SQLITE_DBSTATUS_CACHE_USED
                - **
                This parameter returns the approximate number of bytes of heap - ** memory used by all pager caches associated with the database connection.)^ - ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. -+**
                - ** - ** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] - ** ^(
                SQLITE_DBSTATUS_CACHE_USED_SHARED
                -@@ -8867,10 +8937,10 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r - ** memory used by that pager cache is divided evenly between the attached - ** connections.)^ In other words, if none of the pager caches associated - ** with the database connection are shared, this request returns the same --** value as DBSTATUS_CACHE_USED. Or, if one or more or the pager caches are -+** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are - ** shared, the value returned by this call will be smaller than that returned - ** by DBSTATUS_CACHE_USED. ^The highwater mark associated with --** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. -+** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. - ** - ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
                SQLITE_DBSTATUS_SCHEMA_USED
                - **
                This parameter returns the approximate number of bytes of heap -@@ -8880,6 +8950,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r - ** schema memory is shared with other database connections due to - ** [shared cache mode] being enabled. - ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. -+**
                - ** - ** [[SQLITE_DBSTATUS_STMT_USED]] ^(
                SQLITE_DBSTATUS_STMT_USED
                - **
                This parameter returns the approximate number of bytes of heap -@@ -8916,7 +8987,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r - ** been written to disk in the middle of a transaction due to the page - ** cache overflowing. Transactions are more efficient if they are written - ** to disk all at once. When pages spill mid-transaction, that introduces --** additional overhead. This parameter can be used help identify -+** additional overhead. This parameter can be used to help identify - ** inefficiencies that can be resolved by increasing the cache size. - **
                - ** -@@ -8987,13 +9058,13 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); - ** [[SQLITE_STMTSTATUS_SORT]]
                SQLITE_STMTSTATUS_SORT
                - **
                ^This is the number of sort operations that have occurred. - ** A non-zero value in this counter may indicate an opportunity to --** improvement performance through careful use of indices.
                -+** improve performance through careful use of indices. - ** - ** [[SQLITE_STMTSTATUS_AUTOINDEX]]
                SQLITE_STMTSTATUS_AUTOINDEX
                - **
                ^This is the number of rows inserted into transient indices that - ** were created automatically in order to help joins run faster. - ** A non-zero value in this counter may indicate an opportunity to --** improvement performance by adding permanent indices that do not -+** improve performance by adding permanent indices that do not - ** need to be reinitialized each time the statement is run.
                - ** - ** [[SQLITE_STMTSTATUS_VM_STEP]]
                SQLITE_STMTSTATUS_VM_STEP
                -@@ -9002,19 +9073,19 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); - ** to 2147483647. The number of virtual machine operations can be - ** used as a proxy for the total work done by the prepared statement. - ** If the number of virtual machine operations exceeds 2147483647 --** then the value returned by this statement status code is undefined. -+** then the value returned by this statement status code is undefined. - ** - ** [[SQLITE_STMTSTATUS_REPREPARE]]
                SQLITE_STMTSTATUS_REPREPARE
                - **
                ^This is the number of times that the prepare statement has been - ** automatically regenerated due to schema changes or changes to --** [bound parameters] that might affect the query plan. -+** [bound parameters] that might affect the query plan.
                - ** - ** [[SQLITE_STMTSTATUS_RUN]]
                SQLITE_STMTSTATUS_RUN
                - **
                ^This is the number of times that the prepared statement has - ** been run. A single "run" for the purposes of this counter is one - ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. - ** The counter is incremented on the first [sqlite3_step()] call of each --** cycle. -+** cycle.
                - ** - ** [[SQLITE_STMTSTATUS_FILTER_MISS]] - ** [[SQLITE_STMTSTATUS_FILTER HIT]] -@@ -9024,7 +9095,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); - ** step was bypassed because a Bloom filter returned not-found. The - ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of - ** times that the Bloom filter returned a find, and thus the join step --** had to be processed as normal. -+** had to be processed as normal. - ** - ** [[SQLITE_STMTSTATUS_MEMUSED]]
                SQLITE_STMTSTATUS_MEMUSED
                - **
                ^This is the approximate number of bytes of heap memory -@@ -9129,9 +9200,9 @@ struct sqlite3_pcache_page { - ** SQLite will typically create one cache instance for each open database file, - ** though this is not guaranteed. ^The - ** first parameter, szPage, is the size in bytes of the pages that must --** be allocated by the cache. ^szPage will always a power of two. ^The -+** be allocated by the cache. ^szPage will always be a power of two. ^The - ** second parameter szExtra is a number of bytes of extra storage --** associated with each page cache entry. ^The szExtra parameter will -+** associated with each page cache entry. ^The szExtra parameter will be - ** a number less than 250. SQLite will use the - ** extra szExtra bytes on each page to store metadata about the underlying - ** database page on disk. The value passed into szExtra depends -@@ -9139,17 +9210,17 @@ struct sqlite3_pcache_page { - ** ^The third argument to xCreate(), bPurgeable, is true if the cache being - ** created will be used to cache database pages of a file stored on disk, or - ** false if it is used for an in-memory database. The cache implementation --** does not have to do anything special based with the value of bPurgeable; -+** does not have to do anything special based upon the value of bPurgeable; - ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will - ** never invoke xUnpin() except to deliberately delete a page. - ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to - ** false will always have the "discard" flag set to true. --** ^Hence, a cache created with bPurgeable false will -+** ^Hence, a cache created with bPurgeable set to false will - ** never contain any unpinned pages. - ** - ** [[the xCachesize() page cache method]] - ** ^(The xCachesize() method may be called at any time by SQLite to set the --** suggested maximum cache-size (number of pages stored by) the cache -+** suggested maximum cache-size (number of pages stored) for the cache - ** instance passed as the first argument. This is the value configured using - ** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable - ** parameter, the implementation is not required to do anything with this -@@ -9176,12 +9247,12 @@ struct sqlite3_pcache_page { - ** implementation must return a pointer to the page buffer with its content - ** intact. If the requested page is not already in the cache, then the - ** cache implementation should use the value of the createFlag --** parameter to help it determined what action to take: -+** parameter to help it determine what action to take: - ** - ** - **
                createFlag Behavior when page is not already in cache - **
                0 Do not allocate a new page. Return NULL. --**
                1 Allocate a new page if it easy and convenient to do so. -+**
                1 Allocate a new page if it is easy and convenient to do so. - ** Otherwise return NULL. - **
                2 Make every effort to allocate a new page. Only return - ** NULL if allocating a new page is effectively impossible. -@@ -9198,7 +9269,7 @@ struct sqlite3_pcache_page { - ** as its second argument. If the third parameter, discard, is non-zero, - ** then the page must be evicted from the cache. - ** ^If the discard parameter is --** zero, then the page may be discarded or retained at the discretion of -+** zero, then the page may be discarded or retained at the discretion of the - ** page cache implementation. ^The page cache implementation - ** may choose to evict unpinned pages at any time. - ** -@@ -9216,7 +9287,7 @@ struct sqlite3_pcache_page { - ** When SQLite calls the xTruncate() method, the cache must discard all - ** existing cache entries with page numbers (keys) greater than or equal - ** to the value of the iLimit parameter passed to xTruncate(). If any --** of these pages are pinned, they are implicitly unpinned, meaning that -+** of these pages are pinned, they become implicitly unpinned, meaning that - ** they can be safely discarded. - ** - ** [[the xDestroy() page cache method]] -@@ -9396,7 +9467,7 @@ typedef struct sqlite3_backup sqlite3_backup; - ** external process or via a database connection other than the one being - ** used by the backup operation, then the backup will be automatically - ** restarted by the next call to sqlite3_backup_step(). ^If the source --** database is modified by the using the same database connection as is used -+** database is modified by using the same database connection as is used - ** by the backup operation, then the backup database is automatically - ** updated at the same time. - ** -@@ -9413,7 +9484,7 @@ typedef struct sqlite3_backup sqlite3_backup; - ** and may not be used following a call to sqlite3_backup_finish(). - ** - ** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no --** sqlite3_backup_step() errors occurred, regardless or whether or not -+** sqlite3_backup_step() errors occurred, regardless of whether or not - ** sqlite3_backup_step() completed. - ** ^If an out-of-memory condition or IO error occurred during any prior - ** sqlite3_backup_step() call on the same [sqlite3_backup] object, then -@@ -9515,7 +9586,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); - ** application receives an SQLITE_LOCKED error, it may call the - ** sqlite3_unlock_notify() method with the blocked connection handle as - ** the first argument to register for a callback that will be invoked --** when the blocking connections current transaction is concluded. ^The -+** when the blocking connection's current transaction is concluded. ^The - ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] - ** call that concludes the blocking connection's transaction. - ** -@@ -9535,7 +9606,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); - ** blocked connection already has a registered unlock-notify callback, - ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is - ** called with a NULL pointer as its second argument, then any existing --** unlock-notify callback is canceled. ^The blocked connections -+** unlock-notify callback is canceled. ^The blocked connection's - ** unlock-notify callback may also be canceled by closing the blocked - ** connection using [sqlite3_close()]. - ** -@@ -9933,7 +10004,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); - ** support constraints. In this configuration (which is the default) if - ** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire - ** statement is rolled back as if [ON CONFLICT | OR ABORT] had been --** specified as part of the users SQL statement, regardless of the actual -+** specified as part of the user's SQL statement, regardless of the actual - ** ON CONFLICT mode specified. - ** - ** If X is non-zero, then the virtual table implementation guarantees -@@ -9967,7 +10038,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); - ** [[SQLITE_VTAB_INNOCUOUS]]
                SQLITE_VTAB_INNOCUOUS
                - **
                Calls of the form - ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the --** the [xConnect] or [xCreate] methods of a [virtual table] implementation -+** [xConnect] or [xCreate] methods of a [virtual table] implementation - ** identify that virtual table as being safe to use from within triggers - ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the - ** virtual table can do no serious harm even if it is controlled by a -@@ -10135,7 +10206,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); - **
                - ** - ** ^For the purposes of comparing virtual table output values to see if the --** values are same value for sorting purposes, two NULL values are considered -+** values are the same value for sorting purposes, two NULL values are considered - ** to be the same. In other words, the comparison operator is "IS" - ** (or "IS NOT DISTINCT FROM") and not "==". - ** -@@ -10145,7 +10216,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); - ** - ** ^A virtual table implementation is always free to return rows in any order - ** it wants, as long as the "orderByConsumed" flag is not set. ^When the --** the "orderByConsumed" flag is unset, the query planner will add extra -+** "orderByConsumed" flag is unset, the query planner will add extra - ** [bytecode] to ensure that the final results returned by the SQL query are - ** ordered correctly. The use of the "orderByConsumed" flag and the - ** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful -@@ -10242,7 +10313,7 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); - ** sqlite3_vtab_in_next(X,P) should be one of the parameters to the - ** xFilter method which invokes these routines, and specifically - ** a parameter that was previously selected for all-at-once IN constraint --** processing use the [sqlite3_vtab_in()] interface in the -+** processing using the [sqlite3_vtab_in()] interface in the - ** [xBestIndex|xBestIndex method]. ^(If the X parameter is not - ** an xFilter argument that was selected for all-at-once IN constraint - ** processing, then these routines return [SQLITE_ERROR].)^ -@@ -10297,7 +10368,7 @@ SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); - ** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) - ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th - ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface --** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if -+** can return a result code other than SQLITE_OK or SQLITE_NOTFOUND if - ** something goes wrong. - ** - ** The sqlite3_vtab_rhs_value() interface is usually only successful if -@@ -10325,8 +10396,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** - ** KEYWORDS: {conflict resolution mode} - ** - ** These constants are returned by [sqlite3_vtab_on_conflict()] to --** inform a [virtual table] implementation what the [ON CONFLICT] mode --** is for the SQL statement being evaluated. -+** inform a [virtual table] implementation of the [ON CONFLICT] mode -+** for the SQL statement being evaluated. - ** - ** Note that the [SQLITE_IGNORE] constant is also used as a potential - ** return value from the [sqlite3_set_authorizer()] callback and that -@@ -10366,39 +10437,39 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** - ** [[SQLITE_SCANSTAT_EST]]
                SQLITE_SCANSTAT_EST
                - **
                ^The "double" variable pointed to by the V parameter will be set to the - ** query planner's estimate for the average number of rows output from each --** iteration of the X-th loop. If the query planner's estimates was accurate, -+** iteration of the X-th loop. If the query planner's estimate was accurate, - ** then this value will approximate the quotient NVISIT/NLOOP and the - ** product of this value for all prior loops with the same SELECTID will --** be the NLOOP value for the current loop. -+** be the NLOOP value for the current loop.
                - ** - ** [[SQLITE_SCANSTAT_NAME]]
                SQLITE_SCANSTAT_NAME
                - **
                ^The "const char *" variable pointed to by the V parameter will be set - ** to a zero-terminated UTF-8 string containing the name of the index or table --** used for the X-th loop. -+** used for the X-th loop.
                - ** - ** [[SQLITE_SCANSTAT_EXPLAIN]]
                SQLITE_SCANSTAT_EXPLAIN
                - **
                ^The "const char *" variable pointed to by the V parameter will be set - ** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] --** description for the X-th loop. -+** description for the X-th loop.
                - ** - ** [[SQLITE_SCANSTAT_SELECTID]]
                SQLITE_SCANSTAT_SELECTID
                - **
                ^The "int" variable pointed to by the V parameter will be set to the - ** id for the X-th query plan element. The id value is unique within the - ** statement. The select-id is the same value as is output in the first --** column of an [EXPLAIN QUERY PLAN] query. -+** column of an [EXPLAIN QUERY PLAN] query.
                - ** - ** [[SQLITE_SCANSTAT_PARENTID]]
                SQLITE_SCANSTAT_PARENTID
                - **
                The "int" variable pointed to by the V parameter will be set to the --** the id of the parent of the current query element, if applicable, or -+** id of the parent of the current query element, if applicable, or - ** to zero if the query element has no parent. This is the same value as --** returned in the second column of an [EXPLAIN QUERY PLAN] query. -+** returned in the second column of an [EXPLAIN QUERY PLAN] query.
                - ** - ** [[SQLITE_SCANSTAT_NCYCLE]]
                SQLITE_SCANSTAT_NCYCLE
                - **
                The sqlite3_int64 output value is set to the number of cycles, - ** according to the processor time-stamp counter, that elapsed while the - ** query element was being processed. This value is not available for - ** all query elements - if it is unavailable the output variable is --** set to -1. -+** set to -1.
                - ** - */ - #define SQLITE_SCANSTAT_NLOOP 0 -@@ -10439,8 +10510,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** - ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. - ** - ** Parameter "idx" identifies the specific query element to retrieve statistics --** for. Query elements are numbered starting from zero. A value of -1 may be --** to query for statistics regarding the entire query. ^If idx is out of range -+** for. Query elements are numbered starting from zero. A value of -1 may -+** retrieve statistics for the entire query. ^If idx is out of range - ** - less than -1 or greater than or equal to the total number of query - ** elements used to implement the statement - a non-zero value is returned and - ** the variable that pOut points to is unchanged. -@@ -10483,7 +10554,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); - ** METHOD: sqlite3 - ** - ** ^If a write-transaction is open on [database connection] D when the --** [sqlite3_db_cacheflush(D)] interface invoked, any dirty -+** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty - ** pages in the pager-cache that are not currently in use are written out - ** to disk. A dirty page may be in use if a database cursor created by an - ** active SQL statement is reading from it, or if it is page 1 of a database -@@ -10597,8 +10668,8 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); - ** triggers; and so forth. - ** - ** When the [sqlite3_blob_write()] API is used to update a blob column, --** the pre-update hook is invoked with SQLITE_DELETE. This is because the --** in this case the new values are not available. In this case, when a -+** the pre-update hook is invoked with SQLITE_DELETE, because -+** the new values are not yet available. In this case, when a - ** callback made with op==SQLITE_DELETE is actually a write using the - ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns - ** the index of the column being written. In other cases, where the -@@ -10851,7 +10922,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c - ** For an ordinary on-disk database file, the serialization is just a - ** copy of the disk file. For an in-memory database or a "TEMP" database, - ** the serialization is the same sequence of bytes which would be written --** to disk if that database where backed up to disk. -+** to disk if that database were backed up to disk. - ** - ** The usual case is that sqlite3_serialize() copies the serialization of - ** the database into memory obtained from [sqlite3_malloc64()] and returns -@@ -10860,7 +10931,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c - ** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations - ** are made, and the sqlite3_serialize() function will return a pointer - ** to the contiguous memory representation of the database that SQLite --** is currently using for that database, or NULL if the no such contiguous -+** is currently using for that database, or NULL if no such contiguous - ** memory representation of the database exists. A contiguous memory - ** representation of the database will usually only exist if there has - ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same -@@ -10931,7 +11002,7 @@ SQLITE_API unsigned char *sqlite3_serialize( - ** database is currently in a read transaction or is involved in a backup - ** operation. - ** --** It is not possible to deserialized into the TEMP database. If the -+** It is not possible to deserialize into the TEMP database. If the - ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the - ** function returns SQLITE_ERROR. - ** -@@ -10953,7 +11024,7 @@ SQLITE_API int sqlite3_deserialize( - sqlite3 *db, /* The database connection */ - const char *zSchema, /* Which DB to reopen with the deserialization */ - unsigned char *pData, /* The serialized database content */ -- sqlite3_int64 szDb, /* Number bytes in the deserialization */ -+ sqlite3_int64 szDb, /* Number of bytes in the deserialization */ - sqlite3_int64 szBuf, /* Total size of buffer pData[] */ - unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ - ); -@@ -10961,7 +11032,7 @@ SQLITE_API int sqlite3_deserialize( - /* - ** CAPI3REF: Flags for sqlite3_deserialize() - ** --** The following are allowed values for 6th argument (the F argument) to -+** The following are allowed values for the 6th argument (the F argument) to - ** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. - ** - ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization -@@ -11486,9 +11557,10 @@ SQLITE_API void sqlite3session_table_filter( - ** is inserted while a session object is enabled, then later deleted while - ** the same session object is disabled, no INSERT record will appear in the - ** changeset, even though the delete took place while the session was disabled. --** Or, if one field of a row is updated while a session is disabled, and --** another field of the same row is updated while the session is enabled, the --** resulting changeset will contain an UPDATE change that updates both fields. -+** Or, if one field of a row is updated while a session is enabled, and -+** then another field of the same row is updated while the session is disabled, -+** the resulting changeset will contain an UPDATE change that updates both -+** fields. - */ - SQLITE_API int sqlite3session_changeset( - sqlite3_session *pSession, /* Session object */ -@@ -11560,8 +11632,9 @@ SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession - ** database zFrom the contents of the two compatible tables would be - ** identical. - ** --** It an error if database zFrom does not exist or does not contain the --** required compatible table. -+** Unless the call to this function is a no-op as described above, it is an -+** error if database zFrom does not exist or does not contain the required -+** compatible table. - ** - ** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite - ** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg -@@ -11696,7 +11769,7 @@ SQLITE_API int sqlite3changeset_start_v2( - ** The following flags may passed via the 4th parameter to - ** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: - ** --**
                SQLITE_CHANGESETAPPLY_INVERT
                -+**
                SQLITE_CHANGESETSTART_INVERT
                - ** Invert the changeset while iterating through it. This is equivalent to - ** inverting a changeset using sqlite3changeset_invert() before applying it. - ** It is an error to specify this flag with a patchset. -@@ -12011,19 +12084,6 @@ SQLITE_API int sqlite3changeset_concat( - void **ppOut /* OUT: Buffer containing output changeset */ - ); - -- --/* --** CAPI3REF: Upgrade the Schema of a Changeset/Patchset --*/ --SQLITE_API int sqlite3changeset_upgrade( -- sqlite3 *db, -- const char *zDb, -- int nIn, const void *pIn, /* Input changeset */ -- int *pnOut, void **ppOut /* OUT: Inverse of input */ --); -- -- -- - /* - ** CAPI3REF: Changegroup Handle - ** -diff --git a/deps/sqlite/sqlite3ext.h b/deps/sqlite/sqlite3ext.h -index ae0949ba..cf775dfb 100644 ---- a/deps/sqlite/sqlite3ext.h -+++ b/deps/sqlite/sqlite3ext.h -@@ -366,6 +366,8 @@ struct sqlite3_api_routines { - /* Version 3.44.0 and later */ - void *(*get_clientdata)(sqlite3*,const char*); - int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); -+ /* Version 3.50.0 and later */ -+ int (*setlk_timeout)(sqlite3*,int,int); - }; - - /* -@@ -699,6 +701,8 @@ typedef int (*sqlite3_loadext_entry)( - /* Version 3.44.0 and later */ - #define sqlite3_get_clientdata sqlite3_api->get_clientdata - #define sqlite3_set_clientdata sqlite3_api->set_clientdata -+/* Version 3.50.0 and later */ -+#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout - #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ - - #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) --- -2.49.0 - diff --git a/SOURCES/0002-fips-disable-options.patch b/SOURCES/0002-fips-disable-options.patch new file mode 100644 index 0000000..56482a2 --- /dev/null +++ b/SOURCES/0002-fips-disable-options.patch @@ -0,0 +1,84 @@ +From 98738d27288bd9ca634e29181ef665e812e7bbd3 Mon Sep 17 00:00:00 2001 +From: Michael Dawson +Date: Fri, 23 Feb 2024 13:43:56 +0100 +Subject: [PATCH] Disable FIPS options + +On RHEL, FIPS should be configured only on system level. +Additionally, the related options may cause segfault when used on RHEL. + +This patch causes the option processing to end sooner +than the problematic code gets executed. +Additionally, the JS-level options to mess with FIPS settings +are similarly disabled. + +Upstream report: https://github.com/nodejs/node/pull/48950 +RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=2226726 +--- + lib/crypto.js | 10 ++++++++++ + lib/internal/errors.js | 6 ++++++ + src/crypto/crypto_util.cc | 2 ++ + 3 files changed, 18 insertions(+) + +diff --git a/lib/crypto.js b/lib/crypto.js +index 41adecc..b2627ac 100644 +--- a/lib/crypto.js ++++ b/lib/crypto.js +@@ -36,7 +36,10 @@ const { + assertCrypto(); + + const { ++ // RHEL specific error ++ ERR_CRYPTO_FIPS_SYSTEM_CONTROLLED, ++ + ERR_CRYPTO_FIPS_FORCED, + ERR_WORKER_UNSUPPORTED_OPERATION, + } = require('internal/errors').codes; + const constants = internalBinding('constants').crypto; +@@ -251,6 +254,13 @@ function getFips() { + } + + function setFips(val) { ++ // in RHEL FIPS enable/disable should only be done at system level ++ if (getFips() != val) { ++ throw new ERR_CRYPTO_FIPS_SYSTEM_CONTROLLED(); ++ } else { ++ return; ++ } ++ + if (getOptionValue('--force-fips')) { + if (val) return; + throw new ERR_CRYPTO_FIPS_FORCED(); +diff --git a/lib/internal/errors.js b/lib/internal/errors.js +index a722360..04d8a53 100644 +--- a/lib/internal/errors.js ++++ b/lib/internal/errors.js +@@ -1111,6 +1111,12 @@ module.exports = { + // + // Note: Node.js specific errors must begin with the prefix ERR_ + ++// insert RHEL specific erro ++E('ERR_CRYPTO_FIPS_SYSTEM_CONTROLLED', ++ 'Cannot set FIPS mode. FIPS should be enabled/disabled at system level. See' + ++ 'https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening/assembly_installing-the-system-in-fips-mode_security-hardening for more details.\n', ++ Error); ++ + E('ERR_ACCESS_DENIED', + function(msg, permission = '', resource = '') { + this.permission = permission; +diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc +index 5734d8f..ef9d1b1 100644 +--- a/src/crypto/crypto_util.cc ++++ b/src/crypto/crypto_util.cc +@@ -121,6 +121,8 @@ bool ProcessFipsOptions() { + /* Override FIPS settings in configuration file, if needed. */ + if (per_process::cli_options->enable_fips_crypto || + per_process::cli_options->force_fips_crypto) { ++ fprintf(stderr, "ERROR: Using options related to FIPS is not recommended, configure FIPS in openssl instead. See https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening/assembly_installing-the-system-in-fips-mode_security-hardening for more details.\n"); ++ return false; + #if OPENSSL_VERSION_MAJOR >= 3 + OSSL_PROVIDER* fips_provider = OSSL_PROVIDER_load(nullptr, "fips"); + if (fips_provider == nullptr) +-- +2.43.2 + + diff --git a/SPECS/nodejs.spec b/SPECS/nodejs.spec index ecf06e3..6d544bc 100644 --- a/SPECS/nodejs.spec +++ b/SPECS/nodejs.spec @@ -78,7 +78,7 @@ # than a Fedora release lifecycle. %global nodejs_epoch 1 %global nodejs_major 22 -%global nodejs_minor 16 +%global nodejs_minor 19 %global nodejs_patch 0 # nodejs_soversion - from NODE_MODULE_VERSION in src/node_version.h %global nodejs_soversion 127 @@ -102,17 +102,17 @@ %global v8_release %{nodejs_epoch}.%{nodejs_major}.%{nodejs_minor}.%{nodejs_patch}.%{nodejs_release} # zlib - from deps/zlib/zlib.h -%global zlib_version 1.3.0.1-motley +%global zlib_version 1.3.1 # c-ares - from deps/cares/include/ares_version.h # https://github.com/nodejs/node/pull/9332 %global c_ares_version 1.34.5 # llhttp - from deps/llhttp/include/llhttp.h -%global llhttp_version 9.2.1 +%global llhttp_version 9.3.0 # libuv - from deps/uv/include/uv/version.h -%global libuv_version 1.49.2 +%global libuv_version 1.51.0 # nghttp2 - from deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h %global nghttp2_version 1.64.0 @@ -146,7 +146,7 @@ # npm - from deps/npm/package.json %global npm_epoch 1 -%global npm_version 10.9.2 +%global npm_version 10.9.3 # In order to avoid needing to keep incrementing the release version for the # main package forever, we will just construct one for npm that is guaranteed @@ -163,7 +163,7 @@ %global histogram_version 0.11.8 # sqlite - from deps/sqlite/sqlite3.h -%global sqlite_version 3.50.3 +%global sqlite_version 3.50.4 Name: nodejs @@ -218,7 +218,7 @@ Source212: https://github.com/WebAssembly/wasi-sdk/archive/wasi-sdk-20/wasi-sdk- Source300: test-runner.sh Source301: test-should-pass.txt Patch1: 0001-Remove-unused-OpenSSL-config.patch -Patch2: 0001-sqlite-CVE-2025-6965.patch +Patch2: 0002-fips-disable-options.patch %global pkgname nodejs @@ -626,7 +626,8 @@ export PATH="${PWD}/.bin:$PATH" --with-intl=small-icu \ --with-icu-default-data-dir=%{icudatadir} \ --without-corepack \ - --openssl-use-def-ca-store + --openssl-use-def-ca-store \ + --use-prefix-to-find-headers %ninja_build -C out/Release @@ -949,11 +950,15 @@ end %changelog +* Fri Aug 29 2025 Tomas Juhasz - 1:22.19.0-1 +- Update to 22.19.0 + Resolves: RHEL-100424 + * Thu Jul 17 2025 Andrei Radchenko - 1:22.16.0-2 - Patch fix for sqlite CVE-2025-6965 Resolves: RHEL-103835 -* Tue May 20 2025 Tomas Juhasz - 1:22.15-1-1 +* Tue May 20 2025 Tomas Juhasz - 1:22.16.0-1 - Update to 22.16.0 Fixes: CVE-2025-23166 - Resolves: RHEL-91596 RHEL-92859