From 266f57d4808bee8c0b43dfaf0269ff8bbca62484 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Mon, 28 Jul 2025 06:22:24 +0000 Subject: [PATCH] import UBI nodejs-22.16.0-2.module+el8.10.0+23338+c5a38893 --- SOURCES/0001-sqlite-CVE-2025-6965.patch | 11039 ++++++++++++++++++++++ SPECS/nodejs.spec | 9 +- 2 files changed, 11046 insertions(+), 2 deletions(-) create mode 100644 SOURCES/0001-sqlite-CVE-2025-6965.patch diff --git a/SOURCES/0001-sqlite-CVE-2025-6965.patch b/SOURCES/0001-sqlite-CVE-2025-6965.patch new file mode 100644 index 0000000..2376d20 --- /dev/null +++ b/SOURCES/0001-sqlite-CVE-2025-6965.patch @@ -0,0 +1,11039 @@ +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/SPECS/nodejs.spec b/SPECS/nodejs.spec index dc424d2..ecf06e3 100644 --- a/SPECS/nodejs.spec +++ b/SPECS/nodejs.spec @@ -67,7 +67,7 @@ # This is used by both the nodejs package and the npm subpackage that # has a separate version - the name is special so that rpmdev-bumpspec # will bump this rather than adding .1 to the end. -%global baserelease 1 +%global baserelease 2 %{?!_pkgdocdir:%global _pkgdocdir %{_docdir}/%{name}-%{version}} @@ -163,7 +163,7 @@ %global histogram_version 0.11.8 # sqlite - from deps/sqlite/sqlite3.h -%global sqlite_version 3.49.1 +%global sqlite_version 3.50.3 Name: nodejs @@ -218,6 +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 %global pkgname nodejs @@ -948,6 +949,10 @@ end %changelog +* 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 - Update to 22.16.0 Fixes: CVE-2025-23166