From d970f324c90a99a87222e1635e81e2e9e66b5a4b Mon Sep 17 00:00:00 2001 From: wrongnull <65823030+wrongnull@users.noreply.github.com> Date: Sun, 18 Oct 2026 10:23:29 +0000 Subject: [PATCH] deps: update sqlite to 3.54.100 --- src/bun.js/bindings/sqlite/sqlite3.c | 20749 ++++++++++++------- src/bun.js/bindings/sqlite/sqlite3_local.h | 735 +- 2 files changed, 13572 insertions(+), 7912 deletions(-) diff --git a/src/bun.js/bindings/sqlite/sqlite3.c b/src/bun.js/bindings/sqlite/sqlite3.c index 4f145d7beb4b..acb3a7853241 100644 --- a/src/bun.js/bindings/sqlite/sqlite3.c +++ b/src/bun.js/bindings/sqlite/sqlite3.c @@ -1,7 +1,7 @@ // clang-format off /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.51.2. By combining all the individual C code files into this +** version 3.54.1. 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 @@ -19,7 +19,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** b270f8339eb13b504d0b2ba154ebca966b7d with changes in files: +** 555e07ef33f69a0957d24d8e555b702464a1 with changes in files: ** ** */ @@ -469,12 +469,12 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.51.2" -#define SQLITE_VERSION_NUMBER 3051002 -#define SQLITE_SOURCE_ID "2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075" -#define SQLITE_SCM_BRANCH "branch-3.51" -#define SQLITE_SCM_TAGS "release version-3.51.2" -#define SQLITE_SCM_DATETIME "2026-01-09T17:27:48.405Z" +#define SQLITE_VERSION "3.54.1" +#define SQLITE_VERSION_NUMBER 3054001 +#define SQLITE_SOURCE_ID "2026-10-16 14:45:20 555e07ef33f69a0957d24d8e555b702464a131d6f1607f4c3c1e4551e8e6ca76" +#define SQLITE_SCM_BRANCH "branch-3.54" +#define SQLITE_SCM_TAGS "release version-3.54.1" +#define SQLITE_SCM_DATETIME "2026-10-16T14:45:20.546Z" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -786,7 +786,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Internal use only */ +#define SQLITE_EMPTY 16 /* No content */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ @@ -901,7 +901,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) -#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ +#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal only */ /* ** CAPI3REF: Flags For File Open Operations @@ -1613,6 +1613,12 @@ struct sqlite3_io_methods { #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO +/* reserved file-control numbers: +** 101 +** 102 +** 103 +*/ + /* ** CAPI3REF: Mutex Handle @@ -1813,7 +1819,7 @@ typedef const char *sqlite3_filename; ** greater and the function pointer is not NULL) and will fall back ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. ** -** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** ^The xSetSystemCall(), xGetSystemCall(), and xNextSystemCall() interfaces ** are not used by the SQLite core. These optional interfaces are provided ** by some VFSes to facilitate testing of the VFS code. By overriding ** system calls with functions under its control, a test program can @@ -2034,7 +2040,8 @@ SQLITE_API int sqlite3_os_end(void); ** are called "anytime configuration options". ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before ** [sqlite3_shutdown()] with a first argument that is not an anytime -** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. +** configuration option, then the sqlite3_config() call will +** return SQLITE_MISUSE. ** Note, however, that ^sqlite3_config() can be called as part of the ** implementation of an application-defined [sqlite3_os_init()]. ** @@ -2600,9 +2607,10 @@ struct sqlite3_mem_methods { ** 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. -**
  • 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" +**

  • 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. ** @@ -2890,12 +2898,15 @@ struct sqlite3_mem_methods { ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] **

    SQLITE_DBCONFIG_STMT_SCANSTATUS
    **
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in -** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears -** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() -** statistics. For statistics to be collected, the flag must be set on -** the database handle both when the SQL statement is prepared and when it -** is stepped. The flag is set (collection of statistics is enabled) -** by default.

    This option takes two arguments: an integer and a pointer to +** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears +** a flag that enables collection of run-time performance statistics +** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle] +** columns of the [bytecode virtual table]. +** For statistics to be collected, the flag must be set on +** the database handle both when the SQL statement is +** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped]. +** The flag is set (collection of statistics is enabled) by default. +**

    This option takes two arguments: an integer and a pointer to ** an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the statement scanstatus option. If the second argument ** is not NULL, then the value of the statement scanstatus setting after @@ -2968,16 +2979,34 @@ struct sqlite3_mem_methods { ** comments are allowed in SQL text after processing the first argument. **

    ** +** [[SQLITE_DBCONFIG_FP_DIGITS]] +**
    SQLITE_DBCONFIG_FP_DIGITS
    +**
    The SQLITE_DBCONFIG_FP_DIGITS setting is a small integer that determines +** the number of significant digits that SQLite will attempt to preserve when +** converting floating point numbers (IEEE 754 "doubles") into text. The +** default value 17, as of SQLite version 3.52.0. The value was 15 in all +** prior versions.

    +** This option takes two arguments which are an integer and a pointer +** to an integer. The first argument is a small integer, between 3 and 23, or +** zero. The FP_DIGITS setting is changed to that small integer, or left +** unaltered if the first argument is zero or out of range. The second argument +** is a pointer to an integer. If the pointer is not NULL, then the value of +** the FP_DIGITS setting, after possibly being modified by the first +** arguments, is written into the integer to which the second argument points. +**

    +** ** ** ** [[DBCONFIG arguments]]

    Arguments To SQLITE_DBCONFIG Options

    ** **

    Most of the SQLITE_DBCONFIG options take two arguments, so that the ** overall call to [sqlite3_db_config()] has a total of four parameters. -** The first argument (the third parameter to sqlite3_db_config()) is an integer. -** The second argument is a pointer to an integer. If the first argument is 1, -** then the option becomes enabled. If the first integer argument is 0, then the -** option is disabled. If the first argument is -1, then the option setting +** The first argument (the third parameter to sqlite3_db_config()) is +** an integer. +** The second argument is a pointer to an integer. If the first argument is 1, +** then the option becomes enabled. If the first integer argument is 0, +** then the option is disabled. +** If the first argument is -1, then the option setting ** is unchanged. The second argument, the pointer to an integer, may be NULL. ** If the second argument is not NULL, then a value of 0 or 1 is written into ** the integer to which the second argument points, depending on whether the @@ -2985,9 +3014,10 @@ struct sqlite3_mem_methods { ** the first argument. ** **

    While most SQLITE_DBCONFIG options use the argument format -** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME] -** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the -** documentation of those exceptional options for details. +** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME], +** [SQLITE_DBCONFIG_LOOKASIDE], and [SQLITE_DBCONFIG_FP_DIGITS] options +** are different. See the documentation of those exceptional options for +** details. */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ @@ -3012,7 +3042,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_FP_DIGITS 1023 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1023 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -3252,8 +3283,9 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*); ** These routines are useful during command-line input to determine if the ** currently entered text seems to form a complete SQL statement or ** if additional input is needed before sending the text into -** SQLite for parsing. ^These routines return 1 if the input string -** appears to be a complete SQL statement. ^A statement is judged to be +** SQLite for parsing. ^The sqlite3_complete(X) and sqlite3_complete16(X) +** routines return 1 if the input string X appears to be a complete SQL +** statement. ^A statement is judged to be ** complete if it ends with a semicolon token and is not a prefix of a ** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within ** string literals or quoted identifier names or comments are not @@ -3261,11 +3293,25 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*); ** embedded) and thus do not count as a statement terminator. ^Whitespace ** and comments that follow the final semicolon are ignored. ** -** ^These routines return 0 if the statement is incomplete. ^If a -** memory allocation fails, then SQLITE_NOMEM is returned. +** ^The sqlite3_complete(X) and sqlite3_complete16(X) routines return 0 +** if the statement is incomplete. ^If a memory allocation fails, then +** SQLITE_NOMEM is returned. ** -** ^These routines do not parse the SQL statements and thus -** will not detect syntactically incorrect SQL. +** The [sqlite3_incomplete(X)] routine is similar to [sqlite3_complete(X)] +** except that sqlite3_incomplete(X) returns SQLITE_OK if the input X is +** complete, SQLITE_EMPTY if input X consists entirely of whitespace and/or +** comments, SQLITE_MISUSE if X is a NULL pointer, and some other non-zero +** value if X is incomplete. The non-zero return from +** sqlite3_incomplete(X) contains additional information about what is +** needed to complete the input X. See the header comment on the +** implemenation of the sqlite3_incomplete() routine for a full description +** of its non-zero return values. The sqlite3_incomplete(X) interface +** is only available for UTF-8 text. +** +** ^None of these routines do a full parse the SQL statements and thus +** will not detect syntactically incorrect SQL. They only determine if +** input text has properly terminated comments, string literals, and +** quoted identifiers, and if the statement ends with a semicolon. ** ** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior ** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked @@ -3273,14 +3319,15 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*); ** then the return value from sqlite3_complete16() will be non-zero ** regardless of whether or not the input SQL is complete.)^ ** -** The input to [sqlite3_complete()] must be a zero-terminated -** UTF-8 string. +** The X input to [sqlite3_complete(X)] and [sqlite3_incomplete(X)] +** must be a zero-terminated UTF-8 string. ** ** The input to [sqlite3_complete16()] must be a zero-terminated ** UTF-16 string in native byte order. */ SQLITE_API int sqlite3_complete(const char *sql); SQLITE_API int sqlite3_complete16(const void *sql); +SQLITE_API sqlite3_int64 sqlite3_incomplete(const char *sql); /* ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors @@ -3693,7 +3740,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** ** ^The first parameter to the authorizer callback is a copy of the third ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter -** to the callback is an integer [SQLITE_COPY | action code] that specifies +** to the callback is an integer [SQLITE_READ | action code] that specifies ** the particular action to be authorized. ^The third through sixth parameters ** to the callback are either NULL pointers or zero-terminated strings ** that contain additional details about the action to be authorized. @@ -3736,21 +3783,33 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** previous call.)^ ^Disable the authorizer by installing a NULL callback. ** The authorizer is disabled by default. ** -** The authorizer callback must not do anything that will modify +**

    Limitations And Caveats

    */ SQLITE_API int sqlite3_set_authorizer( sqlite3*, @@ -3791,6 +3850,11 @@ SQLITE_API int sqlite3_set_authorizer( ** is the name of the inner-most trigger or view that is responsible for ** the access attempt or NULL if this access attempt is directly from ** top-level SQL code. +** +** The case of strings in the 3rd through the 6th argument to the +** authorization callback is arbitrary. Authorization callbacks +** implementations should use [sqlite3_stricmp()] or similar when +** doing comparisons against those values. */ /******************************************* 3rd ************ 4th ***********/ #define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ @@ -3825,9 +3889,14 @@ SQLITE_API int sqlite3_set_authorizer( #define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ #define SQLITE_FUNCTION 31 /* NULL Function Name */ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ -#define SQLITE_COPY 0 /* No longer used */ #define SQLITE_RECURSIVE 33 /* NULL NULL */ +/* +** Note: The SQLITE_COPY macro (with value 0) used to be one of the +** action codes above. That macro has now been repurposed as a possible +** value to the 3rd argument to sqlite3_result_str(). +*/ + /* ** CAPI3REF: Deprecated Tracing And Profiling Functions ** DEPRECATED @@ -4334,8 +4403,7 @@ SQLITE_API int sqlite3_open_v2( ** ** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a ** 64-bit signed integer and returns that integer, or D if P does not -** exist. If the value of P is something other than an integer, then -** zero is returned. +** exist or if the value of P is something other than an integer. ** ** The sqlite3_uri_key(F,N) returns a pointer to the name (not ** the value) of the N-th query parameter for filename F, or a NULL @@ -4494,6 +4562,7 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); **
  • sqlite3_errmsg() **
  • sqlite3_errmsg16() **
  • sqlite3_error_offset() +**
  • sqlite3_db_handle() ** ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language @@ -4540,7 +4609,7 @@ SQLITE_API const char *sqlite3_errstr(int); SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* -** CAPI3REF: Set Error Codes And Message +** CAPI3REF: Set Error Code And Message ** METHOD: sqlite3 ** ** Set the error code of the database handle passed as the first argument @@ -4657,7 +4726,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** or in an ORDER BY or GROUP BY clause.)^ ** ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
    SQLITE_LIMIT_EXPR_DEPTH
    -**
    The maximum depth of the parse tree on any expression.
    )^ +**
    The maximum depth of the parse tree on any expression and +** the maximum nesting depth for subqueries and VIEWs
    )^ +** +** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(
    SQLITE_LIMIT_PARSER_DEPTH
    +**
    The maximum depth of the LALR(1) parser stack used to analyze +** input SQL statements.
    )^ ** ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
    SQLITE_LIMIT_COMPOUND_SELECT
    **
    The maximum number of terms in a compound SELECT statement.
    )^ @@ -4684,11 +4758,20 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); **
    The maximum index number of any [parameter] in an SQL statement.)^ ** ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
    SQLITE_LIMIT_TRIGGER_DEPTH
    -**
    The maximum depth of recursion for triggers.
    )^ +**
    The maximum depth of recursion for triggers, and the maximum +** nesting depth for separate triggers.
    )^ ** ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
    SQLITE_LIMIT_WORKER_THREADS
    **
    The maximum number of auxiliary worker threads that a single ** [prepared statement] may start.
    )^ +** +** [[SQLITE_LIMIT_SCHEMA]] ^(
    SQLITE_LIMIT_SCHEMA
    +**
    The maximum number of objects (tables, indexes, triggers, and views) +** defined by the database schema.
    )^ +** +** [[SQLITE_LIMIT_TRIGGER_STEPS]] ^(
    SQLITE_LIMIT_TRIGGER_STEPS
    +**
    The maximum number of SQL statements that can be contained within +** a single trigger.
    )^ ** */ #define SQLITE_LIMIT_LENGTH 0 @@ -4703,6 +4786,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 +#define SQLITE_LIMIT_PARSER_DEPTH 12 +#define SQLITE_LIMIT_SCHEMA 13 +#define SQLITE_LIMIT_TRIGGER_STEPS 14 /* ** CAPI3REF: Prepare Flags @@ -4747,12 +4833,29 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** fails, the sqlite3_prepare_v3() call returns the same error indications ** with or without this flag; it just omits the call to [sqlite3_log()] that ** logs the error. +** +** [[SQLITE_PREPARE_FROM_DDL]]
    SQLITE_PREPARE_FROM_DDL
    +**
    The SQLITE_PREPARE_FROM_DDL flag causes the SQL compiler to enforce +** security constraints that would otherwise only be enforced when parsing +** the database schema. In other words, the SQLITE_PREPARE_FROM_DDL flag +** causes the SQL compiler to treat the SQL statement being prepared as if +** it had come from an attacker. When SQLITE_PREPARE_FROM_DDL is used and +** [SQLITE_DBCONFIG_TRUSTED_SCHEMA] is off, SQL functions may only be called +** if they are tagged with [SQLITE_INNOCUOUS] and virtual tables may only +** be used if they are tagged with [SQLITE_VTAB_INNOCUOUS]. Best practice +** is to use the SQLITE_PREPARE_FROM_DDL option when preparing any SQL that +** is derived from parts of the database schema. In particular, virtual +** table implementations that run SQL statements that are derived from +** arguments to their CREATE VIRTUAL TABLE statement should always use +** [sqlite3_prepare_v3()] and set the SQLITE_PREPARE_FROM_DDL flag to +** prevent bypass of the [SQLITE_DBCONFIG_TRUSTED_SCHEMA] security checks. ** */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 #define SQLITE_PREPARE_NO_VTAB 0x04 #define SQLITE_PREPARE_DONT_LOG 0x10 +#define SQLITE_PREPARE_FROM_DDL 0x20 /* ** CAPI3REF: Compiling An SQL Statement @@ -4766,8 +4869,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** ** The preferred routine to use is [sqlite3_prepare_v2()]. The ** [sqlite3_prepare()] interface is legacy and should be avoided. -** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used -** for special purposes. +** [sqlite3_prepare_v3()] has an extra +** [SQLITE_PREPARE_FROM_DDL|"prepFlags" option] that is sometimes +** needed for special purpose or to pass along security restrictions. ** ** The use of the UTF-8 interfaces is preferred, as SQLite currently ** does all parsing using UTF-8. The UTF-16 interfaces are provided @@ -4796,6 +4900,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** the nul-terminator. ** Note that nByte measures the length of the input in bytes, not ** characters, even for the UTF-16 interfaces. +** For the sqlite3_prepare16() and sqlite3_prepare16_v2() interfaces, +** the nByte value must be even or undefined behavior can result. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only @@ -5172,8 +5278,8 @@ typedef struct sqlite3_context sqlite3_context; ** it should be a pointer to well-formed UTF16 text. ** ^If the third parameter to sqlite3_bind_text64() is not NULL, then ** it should be a pointer to a well-formed unicode string that is -** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 -** otherwise. +** either UTF8 if the sixth parameter is SQLITE_UTF8 or SQLITE_UTF8_ZT, +** or UTF16 otherwise. ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) @@ -5219,10 +5325,15 @@ typedef struct sqlite3_context sqlite3_context; ** object and pointer to it must remain valid until then. ^SQLite will then ** manage the lifetime of its private copy. ** -** ^The sixth argument to sqlite3_bind_text64() must be one of -** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] -** to specify the encoding of the text in the third parameter. If -** the sixth argument to sqlite3_bind_text64() is not one of the +** ^The sixth argument (the E argument) +** to sqlite3_bind_text64(S,K,Z,N,D,E) must be one of +** [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE] to specify the encoding of the text in the +** third parameter, Z. The special value [SQLITE_UTF8_ZT] means that the +** string argument is both UTF-8 encoded and is zero-terminated. In other +** words, SQLITE_UTF8_ZT means that the Z array is allocated to hold at +** least N+1 bytes and that the Z[N] byte is zero. If +** the E argument to sqlite3_bind_text64(S,K,Z,N,D,E) is not one of the ** allowed values shown above, or if the text encoding is different ** from the encoding specified by the sixth parameter, then the behavior ** is undefined. @@ -5537,7 +5648,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** [prepared statement]. ^In the "v2" interface, ** the more specific error code is returned directly by sqlite3_step(). ** -** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** [SQLITE_MISUSE] means that this routine was called inappropriately. ** Perhaps it was called on a [prepared statement] that has ** already been [sqlite3_finalize | finalized] or on one that had ** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could @@ -6089,6 +6200,52 @@ SQLITE_API int sqlite3_create_window_function( ** ** These constants define integer codes that represent the various ** text encodings supported by SQLite. +** +**
    +** [[SQLITE_UTF8]]
    SQLITE_UTF8
    Text is encoding as UTF-8
    +** +** [[SQLITE_UTF16LE]]
    SQLITE_UTF16LE
    Text is encoding as UTF-16 +** with each code point being expressed "little endian" - the least significant +** byte first. This is the usual encoding, for example on Windows.
    +** +** [[SQLITE_UTF16BE]]
    SQLITE_UTF16BE
    Text is encoding as UTF-16 +** with each code point being expressed "big endian" - the most significant +** byte first. This encoding is less common, but is still sometimes seen, +** specially on older systems. +** +** [[SQLITE_UTF16]]
    SQLITE_UTF16
    Text is encoding as UTF-16 +** with each code point being expressed either little endian or as big +** endian, according to the native endianness of the host computer. +** +** [[SQLITE_ANY]]
    SQLITE_ANY
    This encoding value may only be used +** to declare the preferred text for [application-defined SQL functions] +** created using [sqlite3_create_function()] and similar. If the preferred +** encoding (the 4th parameter to sqlite3_create_function() - the eTextRep +** parameter) is SQLITE_ANY, that indicates that the function does not have +** a preference regarding the text encoding of its parameters and can take +** any text encoding that the SQLite core find convenient to supply. This +** option is deprecated. Please do not use it in new applications. +** +** [[SQLITE_UTF16_ALIGNED]]
    SQLITE_UTF16_ALIGNED
    This encoding +** value may be used as the 3rd parameter (the eTextRep parameter) to +** [sqlite3_create_collation()] and similar. This encoding value means +** that the application-defined collating sequence created expects its +** input strings to be in UTF16 in native byte order, and that the start +** of the strings must be aligned to a 2-byte boundary. +** +** [[SQLITE_UTF8_ZT]]
    SQLITE_UTF8_ZT
    This option can only be +** used to specify the text encoding to strings input to +** [sqlite3_result_text64()] and [sqlite3_bind_text64()]. +** The SQLITE_UTF8_ZT encoding means that the input string (call it "z") +** is UTF-8 encoded and that it is zero-terminated. If the length parameter +** (call it "n") is non-negative, this encoding option means that the caller +** guarantees that z array contains at least n+1 bytes and that the z[n] +** byte has a value of zero. +** This option gives the same output as SQLITE_UTF8, but can be more efficient +** by avoiding the need to make a copy of the input string, in some cases. +** However, if z is allocated to hold fewer than n+1 bytes or if the +** z[n] byte is not zero, undefined behavior may result. +**
    */ #define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ #define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ @@ -6096,6 +6253,7 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_ANY 5 /* Deprecated */ #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ +#define SQLITE_UTF8_ZT 16 /* Zero-terminated UTF8 */ /* ** CAPI3REF: Function Flags @@ -6330,26 +6488,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** the SQL function that supplied the [sqlite3_value*] parameters. ** ** As long as the input parameter is correct, these routines can only -** fail if an out-of-memory error occurs during a format conversion. -** Only the following subset of interfaces are subject to out-of-memory -** errors: -** -** -** +** fail if an out-of-memory error occurs while trying to do a +** UTF8→UTF16 or UTF16→UTF8 conversion. ** If an out-of-memory error occurs, then the return value from these ** routines is the same as if the column had contained an SQL NULL value. -** Valid SQL NULL returns can be distinguished from out-of-memory errors -** by invoking the [sqlite3_errcode()] immediately after the suspect +** If the input sqlite3_value was not obtained from [sqlite3_value_dup()], +** then valid SQL NULL returns can also be distinguished from +** out-of-memory errors after extracting the value +** by invoking the [sqlite3_errcode()] immediately after the suspicious ** return value is obtained and before any ** other SQLite interface is called on the same [database connection]. +** If the input sqlite3_value was obtained from sqlite3_value_dup() then +** it is disconnected from the database connection and so sqlite3_errcode() +** will not work. +** In that case, the only way to distinguish an out-of-memory +** condition from a true SQL NULL is to invoke sqlite3_value_type() on the +** input to see if it is NULL prior to trying to extract the value. */ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); SQLITE_API double sqlite3_value_double(sqlite3_value*); @@ -6376,7 +6530,8 @@ SQLITE_API int sqlite3_value_frombind(sqlite3_value*); ** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) ** returns something other than SQLITE_TEXT, then the return value from ** sqlite3_value_encoding(X) is meaningless. ^Calls to -** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], +** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], +** [sqlite3_value_text16be(X)], ** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or ** [sqlite3_value_bytes16(X)] might change the encoding of the value X and ** thus change the return from subsequent calls to sqlite3_value_encoding(X). @@ -6507,17 +6662,17 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** query execution, under some circumstances the associated auxiliary data ** might be preserved. An example of where this might be useful is in a ** regular-expression matching function. The compiled version of the regular -** expression can be stored as auxiliary data associated with the pattern string. -** Then as long as the pattern string remains the same, +** expression can be stored as auxiliary data associated with the pattern +** string. Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data -** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument -** value to the application-defined function. ^N is zero for the left-most -** function argument. ^If there is no auxiliary data -** associated with the function argument, the sqlite3_get_auxdata(C,N) interface -** returns a NULL pointer. +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary +** data associated by the sqlite3_set_auxdata(C,N,P,X) function with the +** Nth argument value to the application-defined function. ^N is zero +** for the left-most function argument. ^If there is no auxiliary data +** associated with the function argument, the sqlite3_get_auxdata(C,N) +** interface returns a NULL pointer. ** ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the ** N-th argument of the application-defined function. ^Subsequent @@ -6601,10 +6756,14 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi ** ** There is no limit (other than available memory) on the number of different ** client data pointers (with different names) that can be attached to a -** single database connection. However, the implementation is optimized -** for the case of having only one or two different client data names. -** Applications and wrapper libraries are discouraged from using more than -** one client data name each. +** single database connection. However, the current implementation stores +** the content on a linked list. Insert and retrieval performance will +** be proportional to the number of entries. The design use case, and +** the use case for which the implementation is optimized, is +** that an application will store only small number of client data names, +** typically just one or two. This interface is not intended to be a +** generalized key/value store for thousands or millions of keys. It +** will work for that, but performance might be disappointing. ** ** There is no way to enumerate the client data pointers ** associated with a database connection. The N parameter can be thought @@ -6662,7 +6821,11 @@ typedef void (*sqlite3_destructor_type)(void*); ** ** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N) ** interfaces set the result of the application-defined function to be -** a BLOB containing all zero bytes and N bytes in size. +** a BLOB containing all zero bytes and N bytes in size. The +** zeroblob64(C,N) interface returns a [result code], which is normally +** [SQLITE_OK] but might be some other value if the requested operation +** could not be complete, for example if insufficient memory is available +** or if the value of N is out of range. ** ** ^The sqlite3_result_double() interface sets the result from ** an application-defined function to be a floating point value specified @@ -6712,10 +6875,14 @@ typedef void (*sqlite3_destructor_type)(void*); ** set the return value of the application-defined function to be ** a text string which is represented as UTF-8, UTF-16 native byte order, ** UTF-16 little endian, or UTF-16 big endian, respectively. -** ^The sqlite3_result_text64() interface sets the return value of an +** ^The sqlite3_result_text64(C,Z,N,D,E) interface sets the return value of an ** application-defined function to be a text string in an encoding -** specified by the fifth (and last) parameter, which must be one -** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. +** specified the E parameter, which must be one +** of [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE]. ^The special value [SQLITE_UTF8_ZT] means that +** the result text is both UTF-8 and zero-terminated. In other words, +** SQLITE_UTF8_ZT means that the Z array holds at least N+1 bytes and that +** the Z[N] is zero. ** ^SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. ** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces @@ -6802,7 +6969,7 @@ SQLITE_API void sqlite3_result_int(sqlite3_context*, int); SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); SQLITE_API void sqlite3_result_null(sqlite3_context*); SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, +SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char *z, sqlite3_uint64 n, void(*)(void*), unsigned char encoding); SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); @@ -7741,7 +7908,7 @@ SQLITE_API int sqlite3_table_column_metadata( ** ^The sqlite3_load_extension() interface attempts to load an ** [SQLite extension] library contained in the file zFile. If ** the file cannot be loaded directly, attempts are made to load -** with various operating-system specific extensions added. +** with various operating-system specific filename extensions added. ** So for example, if "samplelib" cannot be loaded, then names like ** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might ** be tried also. @@ -7749,10 +7916,10 @@ 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 -** 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".)^ +** If that does not work, it tries names of the form "sqlite3_X_init" +** where X consists of the lower-case equivalent of all ASCII alphabetic +** characters or all ASCII alphanumeric characters in the filename from +** the last "/" to the first following "." and omitting any initial "lib".)^ ** ^The sqlite3_load_extension() interface returns ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. ** ^If an error occurs and pzErrMsg is not 0, then the @@ -7826,7 +7993,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); **
     **    int xEntryPoint(
     **      sqlite3 *db,
    -**      const char **pzErrMsg,
    +**      char **pzErrMsg,
     **      const struct sqlite3_api_routines *pThunk
     **    );
     ** 
    )^ @@ -8576,13 +8743,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix ** and Windows. ** -** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor -** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex -** implementation is included with the library. In this case the -** application must supply a custom mutex implementation using the -** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function -** before calling sqlite3_initialize() or any other public sqlite3_ -** function that calls sqlite3_initialize(). ** ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() @@ -8937,6 +9097,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ +#define SQLITE_TESTCTRL_ATOF 34 #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* @@ -9002,8 +9163,8 @@ SQLITE_API int sqlite3_keyword_check(const char*,int); **
  • ^The sqlite3_str object is created using [sqlite3_str_new()]. **
  • ^Text is appended to the sqlite3_str object using various ** methods, such as [sqlite3_str_appendf()]. -**
  • ^The sqlite3_str object is destroyed and the string it created -** is returned using the [sqlite3_str_finish()] interface. +**
  • The sqlite3_str object is destroyed and the string it created +** is returned using [sqlite3_str_finish()] or [sqlite3_result_str()]. ** */ typedef struct sqlite3_str sqlite3_str; @@ -9045,17 +9206,56 @@ SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); ** pass the returned value to [sqlite3_free()] to avoid a memory leak. ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any ** errors were encountered during construction of the string. ^The -** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the +** [sqlite3_str_finish(X)] interface might also return a NULL pointer if the ** string in [sqlite3_str] object X is zero bytes long. +** +** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object +** X and the string content it contains. Calling sqlite3_str_free(X) is +** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)). */ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); +SQLITE_API void sqlite3_str_free(sqlite3_str*); + +/* +** CAPI3REF: Return A Dynamic String From an SQL Function +** +** The [sqlite3_result_str(C,S,F)] interface causes the +** [sqlite3_str|dynamic string] S to become the return value for the +** application-defined function or virtual table that uses +** [sqlite3_context] C. The F flag can be one of [SQLITE_COPY] +** or [SQLITE_XFER] or [SQLITE_FINISH]. +** +** If the dynamic string is invalid or incomplete due to an out-of-memory +** or string-too-large error, then this routine transfers that error +** over to the SQL function. +** +** If the F argument is SQLITE_COPY, then a copy of the dynamic string +** content is made and the dynamic string object is unchanged. +** If the F argument is SQLITE_XFER, then ownership of the content +** in the dynamic is transferred to the SQL function (via a pointer copy +** rather than a string copy) and the dynamic string is reset to an +** empty string. The SQLITE_FINISH value for F works like SQLITE_RESET +** except that it also invokes the [sqlite3_str_free(S)] destructor +** on the dynamic string object. +*/ +SQLITE_API void sqlite3_result_str(sqlite3_context*, sqlite3_str*, int); + +/* +** CAPI3REF: Control Flags For sqlite3_result_str() +** +** The following integers can be used as the third "F" argument +** to [sqlite3_result_str(C,S,F)]. +*/ +#define SQLITE_COPY 0 /* Results copied. Dynamic string unchanged */ +#define SQLITE_XFER 1 /* Results transfered. Dynamic string reset */ +#define SQLITE_FINISH 2 /* Like SQLITE_XFER, plus dynamic string freed */ /* ** CAPI3REF: Add Content To A Dynamic String ** METHOD: sqlite3_str ** -** These interfaces add content to an sqlite3_str object previously obtained -** from [sqlite3_str_new()]. +** These interfaces add or remove content to an sqlite3_str object +** previously obtained from [sqlite3_str_new()]. ** ** ^The [sqlite3_str_appendf(X,F,...)] and ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] @@ -9078,6 +9278,10 @@ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); ** ^The [sqlite3_str_reset(X)] method resets the string under construction ** inside [sqlite3_str] object X back to zero bytes in length. ** +** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string +** under construction to be N bytes or less. This routine is a no-op if +** N is negative or if the string is already N bytes or smaller in size. +** ** These methods do not return a result code. ^If an error occurs, that fact ** is recorded in the [sqlite3_str] object and can be recovered by a ** subsequent call to [sqlite3_str_errcode(X)]. @@ -9088,6 +9292,7 @@ SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); SQLITE_API void sqlite3_str_reset(sqlite3_str*); +SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N); /* ** CAPI3REF: Status Of A Dynamic String @@ -10618,7 +10823,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** ** sqlite3_vtab_distinct() return value ** Rows are returned in aOrderBy order -** Rows with the same value in all aOrderBy columns are adjacent +** Rows with the same value in all aOrderBy columns are +** adjacent ** Duplicates over all colUsed columns may be omitted ** 0yesyesno ** 1noyesno @@ -10627,8 +10833,8 @@ 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 the same value for sorting purposes, two NULL values are considered -** to be the same. In other words, the comparison operator is "IS" +** 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 "==". ** ** If a virtual table implementation is unable to meet the requirements @@ -10921,9 +11127,9 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** a variable pointed to by the "pOut" parameter. ** ** The "flags" parameter must be passed a mask of flags. At present only -** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX +** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX ** is specified, then status information is available for all elements -** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If +** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API @@ -10937,7 +11143,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. ** -** See also: [sqlite3_stmt_scanstatus_reset()] +** See also: [sqlite3_stmt_scanstatus_reset()] and the +** [nexec and ncycle] columns of the [bytecode virtual table]. */ SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ @@ -11408,8 +11615,19 @@ SQLITE_API unsigned char *sqlite3_serialize( ** used. The serialized database P is N bytes in size. M is the size ** of the buffer P, which might be larger than N. If M is larger than ** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then -** SQLite is permitted to add content to the in-memory database as -** long as the total size does not exceed M bytes. +** SQLite is permitted to add content to the in-memory database, in +** page-sized chunks, as long as the total size does not exceed M bytes. +** +** The parameter M must be greater than or equal to N. Ideally, M +** should have a value which is N+(512×K)+20 where K determines how +** must extra space is available to hold new content as the database +** grows. K can be 0 if the database is read-only. +** +** If the database content in P is malformed in a malicious way then +** it is possible that SQLite might try to read a few more than N bytes +** from P. If the veracity of the database content P is uncertain, +** then applications are advised to allocate about 20 extra bytes on +** the end of the P buffer to avoid a memory error. ** ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will ** invoke sqlite3_free() on the serialization buffer when the database @@ -11479,19 +11697,42 @@ SQLITE_API int sqlite3_deserialize( /* ** CAPI3REF: Bind array values to the CARRAY table-valued function ** -** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to -** one of the first argument of the [carray() table-valued function]. The -** S parameter is a pointer to the [prepared statement] that uses the carray() -** functions. I is the parameter index to be bound. P is a pointer to the -** array to be bound, and N is the number of eements in the array. The -** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], -** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to -** indicate the datatype of the array being bound. The X argument is not a -** NULL pointer, then SQLite will invoke the function X on the P parameter -** after it has finished using P, even if the call to -** sqlite3_carray_bind() fails. The special-case finalizer -** SQLITE_TRANSIENT has no effect here. -*/ +** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to +** parameter that is the first argument of the [carray() table-valued function]. +** The S parameter is a pointer to the [prepared statement] that uses the +** carray() functions. I is the parameter index to be bound. I must be the +** index of the parameter that is the first argument to the carray() +** table-valued function. P is a pointer to the array to be bound, and N +** is the number of elements in the array. The F argument is one of +** constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], +** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], +** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P. +** +** If the X argument is not a NULL pointer or one of the special +** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke +** the function X with argument D when it is finished using the data in P. +** The call to X(D) is a destructor for the array P. The destructor X(D) +** is invoked even if the call to sqlite3_carray_bind_v2() fails. If the X +** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes +** that the data static and the destructor is never invoked. If the X +** parameter is the special-case value [SQLITE_TRANSIENT], then +** sqlite3_carray_bind_v2() makes its own private copy of the data prior +** to returning and never invokes the destructor X. +** +** The sqlite3_carray_bind() function works the same as sqlite3_carray_bind_v2() +** with a D parameter set to P. In other words, +** sqlite3_carray_bind(S,I,P,N,F,X) is same as +** sqlite3_carray_bind_v2(S,I,P,N,F,X,P). +*/ +SQLITE_API int sqlite3_carray_bind_v2( + sqlite3_stmt *pStmt, /* Statement to be bound */ + int i, /* Parameter index */ + void *aData, /* Pointer to array data */ + int nData, /* Number of data elements */ + int mFlags, /* CARRAY flags */ + void (*xDel)(void*), /* Destructor for aData */ + void *pDel /* Optional argument to xDel() */ +); SQLITE_API int sqlite3_carray_bind( sqlite3_stmt *pStmt, /* Statement to be bound */ int i, /* Parameter index */ @@ -13035,11 +13276,23 @@ SQLITE_API int sqlite3changeset_apply_v3( ** database behave as if they were declared with "ON UPDATE NO ACTION ON ** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL ** or SET DEFAULT. +** +**
    SQLITE_CHANGESETAPPLY_NOUPDATELOOP
    +** Sometimes, a changeset contains two or more update statements such that +** although after applying all updates the database will contain no +** constraint violations, no single update can be applied before the others. +** The simplest example of this is a pair of UPDATEs that have "swapped" +** two column values with a UNIQUE constraint. +**

    +** Usually, sqlite3changeset_apply() and similar functions work hard to try +** to find a way to apply such a changeset. However, if this flag is set, +** then all such updates are considered CONSTRAINT conflicts. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 #define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 +#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -13522,6 +13775,232 @@ SQLITE_API int sqlite3session_config(int op, void *pArg); */ #define SQLITE_SESSION_CONFIG_STRMSIZE 1 +/* +** CAPI3REF: Configure a changegroup object +** +** Configure the changegroup object passed as the first argument. +** At present the only valid value for the second parameter is +** [SQLITE_CHANGEGROUP_CONFIG_PATCHSET]. +*/ +SQLITE_API int sqlite3changegroup_config(sqlite3_changegroup*, int, void *pArg); + +/* +** CAPI3REF: Options for sqlite3changegroup_config(). +** +** The following values may be passed as the 2nd parameter to +** sqlite3changegroup_config(). +** +**

    SQLITE_CHANGEGROUP_CONFIG_PATCHSET
    +** A changegroup object generates either a changeset or patchset. Usually, +** this is determined by whether the first call to sqlite3changegroup_add() +** is passed a changeset or a patchset. Or, if the first changes are added +** to the changegroup object using the sqlite3changegroup_change_xxx() +** APIs, then this option may be used to configure whether the changegroup +** object generates a changeset or patchset. +** +** When this option is invoked, parameter pArg must point to a value of +** type int. If the changegroup currently contains zero changes, and the +** value of the int variable is zero or greater than zero, then the +** changegroup is configured to generate a changeset or patchset, +** respectively. It is a no-op, not an error, if the changegroup is not +** configured because it has already started accumulating changes. +** +** Before returning, the int variable is set to 0 if the changegroup is +** configured to generate a changeset, or 1 if it is configured to generate +** a patchset. +*/ +#define SQLITE_CHANGEGROUP_CONFIG_PATCHSET 1 + + +/* +** CAPI3REF: Begin adding a change to a changegroup +** +** This API is used, in concert with other sqlite3changegroup_change_xxx() +** APIs, to add changes to a changegroup object one at a time. To add a +** single change, the caller must: +** +** 1. Invoke sqlite3changegroup_change_begin() to indicate the type of +** change (INSERT, UPDATE or DELETE), the affected table and whether +** or not the change should be marked as indirect. +** +** 2. Invoke sqlite3changegroup_change_int64() or one of the other four +** value functions - _null(), _double(), _text() or _blob() - one or +** more times to specify old.* and new.* values for the change being +** constructed. +** +** 3. Invoke sqlite3changegroup_change_finish() to either finish adding +** the change to the group, or to discard the change altogether. +** +** The first argument to this function must be a pointer to the existing +** changegroup object that the change will be added to. The second argument +** must be SQLITE_INSERT, SQLITE_UPDATE or SQLITE_DELETE. The third is the +** name of the table that the change affects, and the fourth is a boolean +** flag specifying whether the change should be marked as "indirect" (if +** bIndirect is non-zero) or not indirect (if bIndirect is zero). +** +** Following a successful call to this function, this function may not be +** called again on the same changegroup object until after +** sqlite3changegroup_change_finish() has been called. Doing so is an +** SQLITE_MISUSE error. +** +** The changegroup object passed as the first argument must be already +** configured with schema data for the specified table. It may be configured +** either by calling sqlite3changegroup_schema() with a database that contains +** the table, or sqlite3changegroup_add() with a changeset that contains the +** table. If the changegroup object has not been configured with a schema for +** the specified table when this function is called, SQLITE_ERROR is returned. +** +** If successful, SQLITE_OK is returned. Otherwise, if an error occurs, an +** SQLite error code is returned. In this case, if argument pzErr is non-NULL, +** then (*pzErr) may be set to point to a buffer containing a utf-8 formated, +** nul-terminated, English language error message. It is the responsibility +** of the caller to eventually free this buffer using sqlite3_free(). +*/ +SQLITE_API int sqlite3changegroup_change_begin( + sqlite3_changegroup*, + int eOp, + const char *zTab, + int bIndirect, + char **pzErr +); + +/* +** CAPI3REF: Add a 64-bit integer to a changegroup +** +** This function may only be called between a successful call to +** sqlite3changegroup_change_begin() and its matching +** sqlite3changegroup_change_finish() call. If it is called at any +** other time, it is an SQLITE_MISUSE error. Calling this function +** specifies a 64-bit integer value to be used in the change currently being +** added to the changegroup object passed as the first argument. +** +** The second parameter, bNew, specifies whether the value is to be part of +** the new.* (if bNew is non-zero) or old.* (if bNew is zero) record of +** the change under construction. If this does not match the type of change +** specified by the preceding call to sqlite3changegroup_change_begin() (i.e. +** an old.* value for an SQLITE_INSERT change, or a new.* value for an +** SQLITE_DELETE), then SQLITE_ERROR is returned. +** +** The third parameter specifies the column of the old.* or new.* record that +** the value will be a part of. If the specified table has an explicit primary +** key, then this is the index of the table column, numbered from 0 in the order +** specified within the CREATE TABLE statement. Or, if the table uses an +** implicit rowid key, then the column 0 is the rowid and the explicit columns +** are numbered starting from 1. If the iCol parameter is less than 0 or greater +** than the index of the last column in the table, SQLITE_RANGE is returned. +** +** The fourth parameter is the integer value to use as part of the old.* or +** new.* record. +** +** If this call is successful, SQLITE_OK is returned. Otherwise, if an +** error occurs, an SQLite error code is returned. +*/ +SQLITE_API int sqlite3changegroup_change_int64( + sqlite3_changegroup*, + int bNew, + int iCol, + sqlite3_int64 iVal +); + +/* +** CAPI3REF: Add a NULL to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). Except that +** it configures the change currently under construction with a NULL value +** instead of a 64-bit integer. +*/ +SQLITE_API int sqlite3changegroup_change_null(sqlite3_changegroup*, int, int); + +/* +** CAPI3REF: Add an double to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). Except that +** it configures the change currently being constructed with a real value +** instead of a 64-bit integer. +*/ +SQLITE_API int sqlite3changegroup_change_double(sqlite3_changegroup*, int, int, double); + +/* +** CAPI3REF: Add a text value to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). It configures +** the currently accumulated change with a text value instead of a 64-bit +** integer. Parameter pVal points to a buffer containing the text encoded using +** utf-8. Parameter nVal may either be the size of the text value in bytes, or +** else a negative value, in which case the buffer pVal points to is assumed to +** be nul-terminated. +*/ +SQLITE_API int sqlite3changegroup_change_text( + sqlite3_changegroup*, int, int, const char *pVal, int nVal +); + +/* +** CAPI3REF: Add a blob to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). It configures +** the currently accumulated change with a blob value instead of a 64-bit +** integer. Parameter pVal points to a buffer containing the blob. Parameter +** nVal is the size of the blob in bytes. +*/ +SQLITE_API int sqlite3changegroup_change_blob( + sqlite3_changegroup*, int, int, const void *pVal, int nVal +); + +/* +** CAPI3REF: Finish adding one-at-at-time changes to a changegroup +** +** This function may only be called following a successful call to +** sqlite3changegroup_change_begin(). Otherwise, it is an SQLITE_MISUSE error. +** +** If parameter bDiscard is non-zero, then the current change is simply +** discarded. In this case this function is always successful and SQLITE_OK +** returned. +** +** If parameter bDiscard is zero, then an attempt is made to add the current +** change to the changegroup. Assuming the changegroup is configured to +** produce a changeset (not a patchset), this requires that: +** +** * If the change is an INSERT or DELETE, then a value must be specified +** for all columns of the new.* or old.* record, respectively. +** +** * If the change is an UPDATE record, then values must be provided for +** the PRIMARY KEY columns of the old.* record, but must not be provided +** for PRIMARY KEY columns of the new.* record. +** +** * If the change is an UPDATE record, then for each non-PRIMARY KEY +** column in the old.* record for which a value has been provided, a +** value must also be provided for the same column in the new.* record. +** Similarly, for each non-PK column in the old.* record for which +** a value is not provided, a value must not be provided for the same +** column in the new.* record. +** +** * All values specified for PRIMARY KEY columns must be non-NULL. +** +** Otherwise, it is an error. +** +** If the changegroup already contains a change for the same row (identified +** by PRIMARY KEY columns), then the current change is combined with the +** existing change in the same way as for sqlite3changegroup_add(). +** +** For a patchset, all of the above rules apply except that it doesn't matter +** whether or not values are provided for the non-PK old.* record columns +** for an UPDATE or DELETE change. This means that code used to produce +** a changeset using the sqlite3changegroup_change_xxx() APIs may also +** be used to produce patchsets. +** +** If the call is successful, SQLITE_OK is returned. Otherwise, if an error +** occurs, an SQLite error code is returned. If an error is returned and +** parameter pzErr is not NULL, then (*pzErr) may be set to point to a buffer +** containing a nul-terminated, utf-8 encoded, English language error message. +** It is the responsibility of the caller to eventually free any such error +** message buffer using sqlite3_free(). +*/ +SQLITE_API int sqlite3changegroup_change_finish( + sqlite3_changegroup*, + int bDiscard, + char **pzErr +); + /* ** Make sure we can call this stuff from C++. */ @@ -14294,7 +14773,7 @@ struct fts5_api { /************** Continuing where we left off in sqliteInt.h ******************/ /* -** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory. +** Reuse the STATIC_VFS1 for mutex access to sqlite3_temp_directory. */ #define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1 @@ -14336,6 +14815,27 @@ struct fts5_api { #endif #define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */ +/* +** Maximum size of any single memory allocation. +** +** This is not a limit on the total amount of memory used. This is +** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). +** +** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 +** This provides a 256-byte safety margin for defense against 32-bit +** signed integer overflow bugs when computing memory allocation sizes. +** Paranoid applications might want to reduce the maximum allocation size +** further for an even larger safety margin. 0x3fffffff or 0x0fffffff +** or even smaller would be reasonable upper bounds on the size of a memory +** allocations for most applications. +*/ +#ifndef SQLITE_MAX_ALLOCATION_SIZE +# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 +#endif +#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 +# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 +#endif + /* ** This is the maximum number of ** @@ -14371,21 +14871,42 @@ struct fts5_api { ** It used to be the case that setting this value to zero would ** turn the limit off. That is no longer true. It is not possible ** to turn this limit off. +** +** The hard limit is the largest possible 32-bit signed integer less +** 1024, or 2147482624. */ #ifndef SQLITE_MAX_SQL_LENGTH # define SQLITE_MAX_SQL_LENGTH 1000000000 #endif /* -** The maximum depth of an expression tree. This is limited to -** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might -** want to place more severe limits on the complexity of an -** expression. A value of 0 means that there is no limit. +** The maximum depth of an expression tree. The expression tree depth +** is also limited indirectly by SQLITE_MAX_SQL_LENGTH and by +** SQLITE_MAX_PARSER_DEPTH. Reducing the maximum complexity of +** expressions can help prevent excess memory usage by hostile SQL. +** +** A value of 0 for this compile-time option causes all expression +** depth limiting code to be omitted. */ #ifndef SQLITE_MAX_EXPR_DEPTH # define SQLITE_MAX_EXPR_DEPTH 1000 #endif +/* +** The maximum depth of the LALR(1) stack used in the parser that +** interprets SQL inputs. The parser stack depth can also be limited +** indirectly by SQLITE_MAX_SQL_LENGTH. Limiting the parser stack +** depth can help prevent excess memory usage and excess CPU stack +** usage when processing hostile SQL. +** +** Prior to version 3.45.0 (2024-01-15), the parser stack was +** hard-coded to 100 entries, and that worked fine for almost all +** applications. So the upper bound on this limit need not be large. +*/ +#ifndef SQLITE_MAX_PARSER_DEPTH +# define SQLITE_MAX_PARSER_DEPTH 2500 +#endif + /* ** The maximum number of terms in a compound SELECT statement. ** The code generator for compound SELECT statements does one @@ -14501,6 +15022,10 @@ struct fts5_api { # undef SQLITE_MAX_DEFAULT_PAGE_SIZE # define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE #endif +#if SQLITE_MAX_DEFAULT_PAGE_SIZE -#endif #ifdef HAVE_INTTYPES_H #include #endif @@ -14603,22 +15161,50 @@ struct fts5_api { #endif /* -** Macros to hint to the compiler that a function should or should not be -** inlined. +** Hint to the compiler that a function should or should not be inlined: +** +** SQLITE_NOINLINE Never in-line this function +** +** SQLITE_INLINE Strive to in-line this function +** +** SQLITE_OPT_INLINE In-line this function if building the +** amalgamation. +** +** SQLITE_USES_INLINE Set to 1 or 0 according to whether or not +** inline functions are supported. */ -#if defined(__GNUC__) -# define SQLITE_NOINLINE __attribute__((noinline)) -# define SQLITE_INLINE __attribute__((always_inline)) inline +#if defined(SQLITE_DISABLE_INLINE) +# define SQLITE_NOINLINE +# define SQLITE_INLINE +# define SQLITE_OPT_INLINE +# define SQLITE_USES_INLINE 0 +#elif defined(__GNUC__) +# define SQLITE_NOINLINE __attribute__((noinline)) +# define SQLITE_INLINE __attribute__((always_inline)) inline +# define SQLITE_OPT_INLINE __attribute__((always_inline)) inline +# define SQLITE_USES_INLINE 1 #elif defined(_MSC_VER) && _MSC_VER>=1310 -# define SQLITE_NOINLINE __declspec(noinline) -# define SQLITE_INLINE __forceinline +# define SQLITE_NOINLINE __declspec(noinline) +# define SQLITE_INLINE __forceinline +# define SQLITE_OPT_INLINE __forceinline +# define SQLITE_USES_INLINE 1 #else # define SQLITE_NOINLINE # define SQLITE_INLINE +# define SQLITE_OPT_INLINE +# define SQLITE_USES_INLINE 0 #endif #if defined(SQLITE_COVERAGE_TEST) || defined(__STRICT_ANSI__) # undef SQLITE_INLINE # define SQLITE_INLINE +# undef SQLITE_OPT_INLINE +# define SQLITE_OPT_INLINE +# undef SQLITE_USES_INLINE +# define SQLITE_USES_INLINE 0 +#endif +#if !defined(SQLITE_AMALGAMATION) +# undef SQLITE_OPT_INLINE +# define SQLITE_OPT_INLINE #endif /* @@ -14793,7 +15379,9 @@ struct fts5_api { ** where multiple cases go to the same block of code, testcase() ** can insure that all cases are evaluated. */ -#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +#if defined(SQLITE_MUTATION_TEST) +# define testcase(X) +#elif defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) # ifndef SQLITE_AMALGAMATION extern unsigned int sqlite3CoverageCounter; # endif @@ -15271,6 +15859,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); # define float sqlite_int64 # define fabs(X) ((X)<0?-(X):(X)) # define sqlite3IsOverflow(X) 0 +# define INFINITY (9223372036854775807LL) # ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) # endif @@ -15378,6 +15967,13 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); # define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif +/* +** sizeof64() is like sizeof(), but always returns a 64-bit value, even +** on 32-bit builds. This can help to avoid overflow by ensuring 64-bit +** arithmetic is used consistently in both 32-bit and 64-bit builds. +*/ +#define sizeof64(X) ((sqlite3_int64)sizeof(X)) + /* ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as ** to avoid complaints from -fsanitize=strict-bounds. @@ -15680,6 +16276,7 @@ typedef INT16_TYPE LogEst; #else # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) #endif +#define TWO_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&1)==0) /* ** Disable MMAP on platforms where it is known to not work @@ -16625,6 +17222,10 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager*); #endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) +SQLITE_PRIVATE void sqlite3PagerWalStat(Pager*,sqlite3_str*); +#endif + #endif /* SQLITE_PAGER_H */ /************** End of pager.h ***********************************************/ @@ -16738,7 +17339,7 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); -SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree*, Btree*); SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); @@ -16815,12 +17416,19 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p); ** implementations with limits on what needs to be prefetched and thereby ** reduce network bandwidth. ** +** BTREE_HINT_TABLECURSOR (arguments: BtCursor*) +** +** This hint is invoked on a non-covering index cursor soon after it +** is opened. The only argument is a pointer to the table cursor used to +** obtain non-covered fields from the database. +** ** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by ** standard SQLite. The other hints are provided for extensions that use ** the SQLite parser and code generator but substitute their own storage ** engine. */ #define BTREE_HINT_RANGE 0 /* Range constraints on queries */ +#define BTREE_HINT_TABLECURSOR 1 /* Table csr associated with this index csr */ /* ** Values that may be OR'd together to form the argument to the @@ -16880,6 +17488,9 @@ SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...); + #ifdef SQLITE_DEBUG +SQLITE_PRIVATE BtCursor *sqlite3BtreeCursorHintTblCsr(BtCursor*); + #endif #endif SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); @@ -17126,8 +17737,6 @@ struct VdbeOp { int i; /* Integer value if p4type==P4_INT32 */ void *p; /* Generic pointer */ char *z; /* Pointer to data for string (char array) types */ - i64 *pI64; /* Used when p4type is P4_INT64 */ - double *pReal; /* Used when p4type is P4_REAL */ FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */ sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */ CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ @@ -17138,6 +17747,7 @@ struct VdbeOp { SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ + Index *pIdx; /* Used when p4type is P4_INDEX */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif @@ -17182,6 +17792,19 @@ struct VdbeOpList { }; typedef struct VdbeOpList VdbeOpList; +/* +** Combine two int32 values into a single int64. The least significant +** term comes first. +*/ +#define INT32_TO_64(a,b) (i64)(((u64)(u32)(b)<<32)|(u32)(a)) + +/* +** Return an int32 that is the lower or upper 32-bits of an int64. +*/ +#define LOWER32(x) (int)(((u64)(x))&0xffffffff) +#define UPPER32(x) (int)(((u64)(x))>>32) + + /* ** Allowed values of VdbeOp.p4type */ @@ -17192,20 +17815,19 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT32 (-3) /* P4 is a 32-bit signed integer */ #define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */ #define P4_TABLE (-5) /* P4 is a pointer to a Table structure */ +#define P4_INDEX (-6) /* P4 is a pointer to an Index structure */ /* Above do not own any resources. Must free those below */ -#define P4_FREE_IF_LE (-6) -#define P4_DYNAMIC (-6) /* Pointer to memory from sqliteMalloc() */ -#define P4_FUNCDEF (-7) /* P4 is a pointer to a FuncDef structure */ -#define P4_KEYINFO (-8) /* P4 is a pointer to a KeyInfo structure */ -#define P4_EXPR (-9) /* P4 is a pointer to an Expr tree */ -#define P4_MEM (-10) /* P4 is a pointer to a Mem* structure */ -#define P4_VTAB (-11) /* P4 is a pointer to an sqlite3_vtab structure */ -#define P4_REAL (-12) /* P4 is a 64-bit floating point value */ -#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ -#define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ -#define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ -#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ -#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ +#define P4_FREE_IF_LE (-7) +#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */ +#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */ +#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */ +#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */ +#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */ +#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */ +#define P4_INTARRAY (-13) /* P4 is a vector of 32-bit integers */ +#define P4_FUNCCTX (-14) /* P4 is a pointer to an sqlite3_context object */ +#define P4_TABLEREF (-15) /* Like P4_TABLE, but reference counted */ +#define P4_SUBRTNSIG (-16) /* P4 is a SubrtnSig pointer */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 @@ -17272,28 +17894,28 @@ typedef struct VdbeOpList VdbeOpList; #define OP_SeekLE 22 /* jump0, synopsis: key=r[P3@P4] */ #define OP_SeekGE 23 /* jump0, synopsis: key=r[P3@P4] */ #define OP_SeekGT 24 /* jump0, synopsis: key=r[P3@P4] */ -#define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ -#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ -#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekRowid 30 /* jump0, synopsis: intkey=r[P3] */ -#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ -#define OP_Last 32 /* jump0 */ -#define OP_IfSizeBetween 33 /* jump */ -#define OP_SorterSort 34 /* jump */ -#define OP_Sort 35 /* jump */ -#define OP_Rewind 36 /* jump0 */ -#define OP_IfEmpty 37 /* jump, synopsis: if( empty(P1) ) goto P2 */ -#define OP_SorterNext 38 /* jump */ -#define OP_Prev 39 /* jump */ -#define OP_Next 40 /* jump */ -#define OP_IdxLE 41 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxGT 42 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IfNoHope 25 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NoConflict 26 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NotFound 27 /* jump, synopsis: key=r[P3@P4] */ +#define OP_Found 28 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekRowid 29 /* jump0, synopsis: intkey=r[P3] */ +#define OP_NotExists 30 /* jump, synopsis: intkey=r[P3] */ +#define OP_Last 31 /* jump0 */ +#define OP_IfSizeBetween 32 /* jump */ +#define OP_SorterSort 33 /* jump */ +#define OP_Sort 34 /* jump */ +#define OP_Rewind 35 /* jump0 */ +#define OP_IfEmpty 36 /* jump, synopsis: if( empty(P1) ) goto P2 */ +#define OP_SorterNext 37 /* jump */ +#define OP_Prev 38 /* jump */ +#define OP_Next 39 /* jump */ +#define OP_IdxLE 40 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGT 41 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxLT 42 /* jump, synopsis: key=r[P3@P4] */ #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ -#define OP_IdxLT 45 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxGE 46 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGE 45 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IFindKey 46 /* jump */ #define OP_RowSetRead 47 /* jump, synopsis: r[P3]=rowset(P1) */ #define OP_RowSetTest 48 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ #define OP_Program 49 /* jump0 */ @@ -17320,7 +17942,7 @@ typedef struct VdbeOpList VdbeOpList; #define OP_HaltIfNull 70 /* synopsis: if r[P3]=null halt */ #define OP_Halt 71 #define OP_Integer 72 /* synopsis: r[P2]=P1 */ -#define OP_Int64 73 /* synopsis: r[P2]=P4 */ +#define OP_Int64 73 /* synopsis: r[P2]=PINT13 */ #define OP_String 74 /* synopsis: r[P2]='P4' (len=P1) */ #define OP_BeginSubrtn 75 /* synopsis: r[P2]=NULL */ #define OP_Null 76 /* synopsis: r[P2..P3]=NULL */ @@ -17371,7 +17993,7 @@ typedef struct VdbeOpList VdbeOpList; #define OP_SequenceTest 121 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ #define OP_OpenPseudo 122 /* synopsis: P3 columns in r[P2] */ #define OP_Close 123 -#define OP_ColumnsUsed 124 +#define OP_ColumnsUsed 124 /* synopsis: Cursor P1 uses columns PHEX23 */ #define OP_SeekScan 125 /* synopsis: Scan-ahead up to P1 rows */ #define OP_SeekHit 126 /* synopsis: set P2<=seekHit<=P3 */ #define OP_Sequence 127 /* synopsis: r[P2]=cursor[P1].ctr++ */ @@ -17388,7 +18010,7 @@ typedef struct VdbeOpList VdbeOpList; #define OP_SeekEnd 138 #define OP_IdxInsert 139 /* synopsis: key=r[P2] */ #define OP_SorterInsert 140 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 141 /* synopsis: key=r[P2@P3] */ +#define OP_IdxDelete 141 /* synopsis: key=r[P2@P5] */ #define OP_DeferredSeek 142 /* synopsis: Move P3 to P1.rowid if needed */ #define OP_IdxRowid 143 /* synopsis: r[P2]=rowid */ #define OP_FinishSeek 144 @@ -17401,7 +18023,7 @@ typedef struct VdbeOpList VdbeOpList; #define OP_LoadAnalysis 151 #define OP_DropTable 152 #define OP_DropIndex 153 -#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=PDBL13 */ #define OP_DropTrigger 155 #define OP_IntegrityCk 156 #define OP_RowSetAdd 157 /* synopsis: rowset(P1)=r[P2] */ @@ -17455,9 +18077,9 @@ typedef struct VdbeOpList VdbeOpList; /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ /* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\ /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\ -/* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ -/* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x01, 0x41,\ -/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x41, 0x23,\ +/* 24 */ 0xc9, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49, 0xc1,\ +/* 32 */ 0x01, 0x41, 0x41, 0xc1, 0x01, 0x01, 0x41, 0x41,\ +/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x09, 0x23,\ /* 48 */ 0x0b, 0x81, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ /* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01,\ /* 64 */ 0x41, 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00,\ @@ -17492,7 +18114,7 @@ typedef struct VdbeOpList VdbeOpList; ** Additional non-public SQLITE_PREPARE_* flags */ #define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */ -#define SQLITE_PREPARE_MASK 0x1f /* Mask of public flags */ +#define SQLITE_PREPARE_MASK 0x3f /* Mask of public flags */ /* ** Prototypes for the VDBE interface. See comments on the implementation @@ -17507,8 +18129,9 @@ SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*); SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...); SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddInt64(Vdbe*,int,i64); +SQLITE_PRIVATE int sqlite3VdbeAddDouble(Vdbe*,int,double); SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); -SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int); SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int); @@ -17600,7 +18223,7 @@ SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*); SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); -SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); +SQLITE_PRIVATE void sqlite3VdbeReprepareOnBind(Vdbe*, int, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif @@ -17759,6 +18382,7 @@ SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr) */ #ifndef _PCACHE_H_ +#define _PCACHE_H_ typedef struct PgHdr PgHdr; typedef struct PCache PCache; @@ -17774,10 +18398,10 @@ struct PgHdr { PCache *pCache; /* PRIVATE: Cache that owns this page */ PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ Pager *pPager; /* The pager this page is part of */ - Pgno pgno; /* Page number for this page */ #ifdef SQLITE_CHECK_PAGES - u32 pageHash; /* Hash of page content */ + u64 pageHash; /* Hash of page content */ #endif + Pgno pgno; /* Page number for this page */ u16 flags; /* PGHDR flags defined below */ /********************************************************************** @@ -17981,7 +18605,7 @@ SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache); # define SQLITE_MUTEX_OMIT #endif #if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) -# if SQLITE_OS_UNIX +# if SQLITE_OS_UNIX || defined(__CYGWIN__) # define SQLITE_MUTEX_PTHREADS # elif SQLITE_OS_WIN # define SQLITE_MUTEX_W32 @@ -18117,7 +18741,7 @@ struct Schema { ** The number of different kinds of things that can be limited ** using the sqlite3_limit() interface. */ -#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1) +#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_STEPS+1) /* ** Lookaside malloc is a set of fixed-size buffers that can be used @@ -18271,6 +18895,7 @@ struct sqlite3 { u8 noSharedCache; /* True if no shared-cache backends */ u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ u8 eOpenState; /* Current condition of the connection */ + u8 nFpDigit; /* Significant digits to keep on double->text */ int nextPagesize; /* Pagesize after VACUUM if >0 */ i64 nChange; /* Value returned by sqlite3_changes() */ i64 nTotalChange; /* Value returned by sqlite3_total_changes() */ @@ -18279,7 +18904,7 @@ struct sqlite3 { struct sqlite3InitInfo { /* Information used during initialization */ Pgno newTnum; /* Rootpage of table being initialized */ u8 iDb; /* Which db file is being initialized */ - u8 busy; /* TRUE if currently initializing */ + u8 busy; /* TRUE if initing. 2 if due to ADD COLUMN */ unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ unsigned imposterTable : 2; /* Building an imposter table */ unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ @@ -18478,7 +19103,7 @@ struct sqlite3 { #define SQLITE_QueryFlattener 0x00000001 /* Query flattening */ #define SQLITE_WindowFunc 0x00000002 /* Use xInverse for window functions */ #define SQLITE_GroupByOrder 0x00000004 /* GROUPBY cover of ORDERBY */ -#define SQLITE_FactorOutConst 0x00000008 /* Constant factoring */ + /* 0x00000008 -- Available for reuse */ #define SQLITE_DistinctOpt 0x00000010 /* DISTINCT using indexes */ #define SQLITE_CoverIdxScan 0x00000020 /* Covering index scans */ #define SQLITE_OrderByIdxJoin 0x00000040 /* ORDER BY of joins via index */ @@ -18487,7 +19112,7 @@ struct sqlite3 { #define SQLITE_CountOfView 0x00000200 /* The count-of-view optimization */ #define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ #define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ - /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ + /* TH3 expects this value ^^^^^^^^^^ */ #define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */ #define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ #define SQLITE_SkipScan 0x00004000 /* Skip-scans */ @@ -18495,13 +19120,14 @@ struct sqlite3 { #define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */ #define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */ #define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */ - /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */ -#define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ -#define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ + /* TH3 expects this value ^^^^^^^^^^ */ +#define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filters */ + /* TH3 expects this value ^^^^^^^^^^ */ + /* 0x00100000 -- Available for reuse */ #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ - /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ + /* TH3 expects this value ^^^^^^^^^^ */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ @@ -18509,6 +19135,7 @@ struct sqlite3 { #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_StarQuery 0x20000000 /* Heurists for star queries */ #define SQLITE_ExistsToJoin 0x40000000 /* The EXISTS-to-JOIN optimization */ +#define SQLITE_UnionLimit 0x80000000 /* Optimizations for UNION + LIMIT */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -20165,19 +20792,6 @@ struct Upsert { /* ** An instance of the following structure contains all information ** needed to generate code for a single SELECT statement. -** -** See the header comment on the computeLimitRegisters() routine for a -** detailed description of the meaning of the iLimit and iOffset fields. -** -** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes. -** These addresses must be stored so that we can go back and fill in -** the P4_KEYINFO and P2 parameters later. Neither the KeyInfo nor -** the number of columns in P2 can be computed at the same time -** as the OP_OpenEphm instruction is coded because not -** enough information about the compound query is known at that point. -** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences -** for the result set. The KeyInfo for addrOpenEphm[2] contains collating -** sequences for the ORDER BY clause. */ struct Select { u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ @@ -20185,7 +20799,6 @@ struct Select { u32 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ u32 selId; /* Unique identifier number for this SELECT */ - int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ ExprList *pEList; /* The fields of the result */ SrcList *pSrc; /* The FROM clause */ Expr *pWhere; /* The WHERE clause */ @@ -20217,7 +20830,7 @@ struct Select { #define SF_Resolved 0x0000004 /* Identifiers have been resolved */ #define SF_Aggregate 0x0000008 /* Contains agg functions or a GROUP BY */ #define SF_HasAgg 0x0000010 /* Contains aggregate functions */ -#define SF_UsesEphemeral 0x0000020 /* Uses the OpenEphemeral opcode */ +#define SF_ClonedRhsIn 0x0000020 /* Cloned RHS of an IN operator */ #define SF_Expanded 0x0000040 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0000080 /* FROM subqueries have Table metadata */ #define SF_Compound 0x0000100 /* Part of a compound query */ @@ -20227,14 +20840,14 @@ struct Select { #define SF_MinMaxAgg 0x0001000 /* Aggregate containing min() or max() */ #define SF_Recursive 0x0002000 /* The recursive part of a recursive CTE */ #define SF_FixedLimit 0x0004000 /* nSelectRow set by a constant LIMIT */ -#define SF_MaybeConvert 0x0008000 /* Need convertCompoundSelectToSubquery() */ +/* 0x0008000 // available for reuse */ #define SF_Converted 0x0010000 /* By convertCompoundSelectToSubquery() */ #define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */ #define SF_ComplexResult 0x0040000 /* Result contains subquery or function */ #define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */ #define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ #define SF_View 0x0200000 /* SELECT statement is a view */ -#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ +/* 0x0400000 // available for reuse */ #define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ #define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ @@ -20254,11 +20867,6 @@ struct Select { ** by one of the following macros. The "SRT" prefix means "SELECT Result ** Type". ** -** SRT_Union Store results as a key in a temporary index -** identified by pDest->iSDParm. -** -** SRT_Except Remove results from the temporary index pDest->iSDParm. -** ** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result ** set is not empty. ** @@ -20322,30 +20930,28 @@ struct Select { ** table. (pDest->iSDParm) is the number of key columns in ** each index record in this case. */ -#define SRT_Union 1 /* Store result as keys in an index */ -#define SRT_Except 2 /* Remove result from a UNION index */ -#define SRT_Exists 3 /* Store 1 if the result is not empty */ -#define SRT_Discard 4 /* Do not save the results anywhere */ -#define SRT_DistFifo 5 /* Like SRT_Fifo, but unique results only */ -#define SRT_DistQueue 6 /* Like SRT_Queue, but unique results only */ +#define SRT_Exists 1 /* Store 1 if the result is not empty */ +#define SRT_Discard 2 /* Do not save the results anywhere */ +#define SRT_DistFifo 3 /* Like SRT_Fifo, but unique results only */ +#define SRT_DistQueue 4 /* Like SRT_Queue, but unique results only */ /* The DISTINCT clause is ignored for all of the above. Not that ** IgnorableDistinct() implies IgnorableOrderby() */ #define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue) -#define SRT_Queue 7 /* Store result in an queue */ -#define SRT_Fifo 8 /* Store result as data with an automatic rowid */ +#define SRT_Queue 5 /* Store result in an queue */ +#define SRT_Fifo 6 /* Store result as data with an automatic rowid */ /* The ORDER BY clause is ignored for all of the above */ #define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo) -#define SRT_Output 9 /* Output each row of result */ -#define SRT_Mem 10 /* Store result in a memory cell */ -#define SRT_Set 11 /* Store results as keys in an index */ -#define SRT_EphemTab 12 /* Create transient tab and store like SRT_Table */ -#define SRT_Coroutine 13 /* Generate a single row of result */ -#define SRT_Table 14 /* Store result as data with an automatic rowid */ -#define SRT_Upfrom 15 /* Store result as data with rowid */ +#define SRT_Output 7 /* Output each row of result */ +#define SRT_Mem 8 /* Store result in a memory cell */ +#define SRT_Set 9 /* Store results as keys in an index */ +#define SRT_EphemTab 10 /* Create transient tab and store like SRT_Table */ +#define SRT_Coroutine 11 /* Generate a single row of result */ +#define SRT_Table 12 /* Store result as data with an automatic rowid */ +#define SRT_Upfrom 13 /* Store result as data with rowid */ /* ** An instance of this object describes where to put of the results of @@ -20456,6 +21062,13 @@ struct ParseCleanup { void (*xCleanup)(sqlite3*,void*); /* Deallocation routine */ }; +/* +** Number of 64-bit entried in the variable number bitmap cache (VNBMC). +*/ +#ifndef SQLITE_VNBMC +# define SQLITE_VNBMC 2 +#endif + /* ** An SQL parser context. A copy of this structure is passed through ** the parser and down into all the parser action routine in order to @@ -20481,17 +21094,12 @@ struct Parse { 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 disableLookaside; /* Number of times lookaside has been disabled */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ - u8 bHasExists; /* Has a correlated "EXISTS (SELECT ....)" expression */ 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 @@ -20500,10 +21108,16 @@ struct Parse { 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 */ + bft disableTriggers:1; /* True to disable triggers */ + bft mayAbort :1; /* True if statement may throw an ABORT exception */ + bft hasCompound :1; /* Need to invoke convertCompoundSelectToSubquery() */ + bft bReturning :1; /* Coding a RETURNING trigger */ + bft bHasExists :1; /* Has a correlated "EXISTS (SELECT ....)" expression */ + 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 */ + bft usesAinc :1; /* True if pAinc is valid */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ @@ -20512,6 +21126,7 @@ struct Parse { int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int iSelfTab; /* Table associated with an index on expr, or negative ** of the base register during check-constraint eval */ + int nNestSel; /* Number of nested SELECT statements and/or VIEWs */ int nLabel; /* The *negative* of the number of labels used */ int nLabelAlloc; /* Number of slots in aLabel */ int *aLabel; /* Space to hold the labels */ @@ -20527,9 +21142,7 @@ struct Parse { #endif #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ - TableLock *aTableLock; /* Required table locks for shared-cache mode */ #endif - AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ @@ -20558,6 +21171,13 @@ struct Parse { Returning *pReturning; /* The RETURNING clause */ } d; } u1; + AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters. Only + ** valid if Parse.usesAinc is true */ +#ifndef SQLITE_OMIT_SHARED_CACHE + TableLock *aTableLock; /* Required table locks for shared-cache mode. Only + ** valid if Parse.nTableLock>0 */ +#endif + /************************************************************************ ** Above is constant between recursions. Below is reset before and after @@ -20568,6 +21188,7 @@ struct Parse { Token sLastToken; /* The last token parsed */ ynVar nVar; /* Number of '?' variables seen in the SQL so far */ + u64 aVnbmc[SQLITE_VNBMC]; /* Varible Number Bitmap Cache */ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ u8 explain; /* True if the EXPLAIN flag is found on the query */ u8 eParseMode; /* PARSE_MODE_XXX constant */ @@ -20732,19 +21353,19 @@ struct Trigger { ** orconf -> stores the ON CONFLICT algorithm ** pSelect -> The content to be inserted - either a SELECT statement or ** a VALUES clause. -** zTarget -> Dequoted name of the table to insert into. +** pSrc -> Table to insert into. ** pIdList -> If this is an INSERT INTO ... () VALUES ... ** statement, then this stores the column-names to be ** inserted into. ** pUpsert -> The ON CONFLICT clauses for an Upsert ** ** (op == TK_DELETE) -** zTarget -> Dequoted name of the table to delete from. +** pSrc -> Table to delete from ** pWhere -> The WHERE clause of the DELETE statement if one is specified. ** Otherwise NULL. ** ** (op == TK_UPDATE) -** zTarget -> Dequoted name of the table to update. +** pSrc -> Table to update, followed by any FROM clause tables. ** pWhere -> The WHERE clause of the UPDATE statement if one is specified. ** Otherwise NULL. ** pExprList -> A list of the columns to update and the expressions to update @@ -20764,8 +21385,7 @@ struct TriggerStep { u8 orconf; /* OE_Rollback etc. */ Trigger *pTrig; /* The trigger that this step is a part of */ Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ - char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ - SrcList *pFrom; /* FROM clause for UPDATE statement (if any) */ + SrcList *pSrc; /* Table to insert/update/delete */ Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ ExprList *pExprList; /* SET clause for UPDATE, or RETURNING clause */ IdList *pIdList; /* Column names for INSERT */ @@ -20848,10 +21468,11 @@ typedef struct { /* ** Allowed values for mInitFlags */ -#define INITFLAG_AlterMask 0x0003 /* Types of ALTER */ +#define INITFLAG_AlterMask 0x0007 /* Types of ALTER */ #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ #define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */ +#define INITFLAG_AlterDropCons 0x0004 /* Reparse after a DROP CONSTRAINT */ /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning @@ -20981,6 +21602,7 @@ struct Walker { NameContext *pNC; /* Naming context */ int n; /* A counter */ int iCur; /* A cursor number */ + int sz; /* String literal length */ SrcList *pSrcList; /* FROM clause */ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ @@ -21211,6 +21833,57 @@ SQLITE_PRIVATE Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprLis /* ** Assuming zIn points to the first byte of a UTF-8 character, ** advance zIn to point to the first byte of the next UTF-8 character. +** +** # Dividing malformed UTF-8 into characters (tag-20260418-01) +** +** If a text input is malformed UTF-8, SQLite does not make any guarantees +** about how the bytes are divided up into characters. The system promises +** to not overflow an array or cause other memory errors when presented +** with malformed UTF-8. And it promises to preserve the specific +** sequence of bytes as long as no conversion occur. But beyond that, +** there are no guarantees. Results can vary from one version to the +** next. +** +** The SQLITE_SKIP_UTF8 macro below is one technique for dividing UTF-8 +** into characters. The length() and substr() SQL functions use a +** different technique when searching across multiple characters, a +** technique that exchanges a subtraction for comparison of z and results +** in faster machine code on some compilers and architectures. The code +** in substr() to skip over p1 characters goes something like this: +** +** for( ; p1>0; p1--){ +** // vvvv--- tag-20260418-01 +** if( (u8)(z[0]-1)<(0x80-1) ){ +** z++; +** }else if( z[0]==0 ){ +** break; +** }else{ +** do{ z++; }while( (z[0]&0xc0)==0x80 ); +** } +** } +** +** In valid UTF-8, multibyte characters always begin with a byte with the +** two most significant bits set and that is followed by one or more bytes +** for which the two most significant bits are 10. In other words: +** +** First byte: (BYTE & 0xc0)==0xc0 +** Following bytes: (BYTE & 0xc0)==0x80 +** +** What to do if the input byte sequence contain a "following byte" that +** is not preceded by a "first byte"? How many characters are in the +** byte sequence: 0x61 0x81 0x82 0x7a? 3 or 4 or something else? +** +** If you use the macro below, the answer will be 4. If you use the code +** snippet demonstrated at tag-20260418-01, then answer is 3. If you +** use a variant of tag-20260418-01 where the constant of comparison is +** 0xc0-1 instead of 0x80-1 then the answer is again 4. The key point is +** that because the input is malformed UTF-8, so is no "correct" answer. +** SQLite is free to use either value. +** +** It turns out that GCC 13.3.0 is able to generate faster code (at least +** on x86-64) if the constant at tag-20260418-01 is (0x80-1). If you make +** that constant (0xc0-1) instead, gcc 13.3.0 generates code that runs slower. +** So the (0x80-1) constant is used for substr() and length(). */ #define SQLITE_SKIP_UTF8(zIn) { \ if( (*(zIn++))>=0xc0 ){ \ @@ -21385,7 +22058,20 @@ SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*); SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); -#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT) + +/* The SQLITE_THREAD_MISUSE_WARNINGS compile-time option used to be called +** SQLITE_ENABLE_MULTITHREADED_CHECKS. Keep that older macro for backwards +** compatibility, at least for a while... */ +#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS +# define SQLITE_THREAD_MISUSE_WARNINGS 1 +#endif + +/* SQLITE_THREAD_MISUSE_ABORT implies SQLITE_THREAD_MISUSE_WARNINGS */ +#ifdef SQLITE_THREAD_MISUSE_ABORT +# define SQLITE_THREAD_MISUSE_WARNINGS 1 +#endif + +#if defined(SQLITE_THREAD_MISUSE_WARNINGS) && !defined(SQLITE_MUTEX_OMIT) SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*); #else # define sqlite3MutexWarnOnContention(x) @@ -21414,17 +22100,22 @@ struct PrintfArguments { sqlite3_value **apArg; /* The argument values */ }; +/* +** Maxium number of base-10 digits in an unsigned 64-bit integer +*/ +#define SQLITE_U64_DIGITS 20 + /* ** An instance of this object receives the decoding of a floating point ** value into an approximate decimal representation. */ struct FpDecode { - char sign; /* '+' or '-' */ - char isSpecial; /* 1: Infinity 2: NaN */ - int n; /* Significant digits in the decode */ - int iDP; /* Location of the decimal point */ - char *z; /* Start of significant digits */ - char zBuf[24]; /* Storage for significant digits */ + int n; /* Significant digits in the decode */ + int iDP; /* Location of the decimal point */ + char *z; /* Start of significant digits */ + char zBuf[SQLITE_U64_DIGITS+1]; /* Storage for significant digits */ + char sign; /* '+' or '-' */ + char isSpecial; /* 1: Infinity 2: NaN */ }; SQLITE_PRIVATE void sqlite3FpDecode(FpDecode*,double,int,int); @@ -21435,6 +22126,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); #endif #if defined(SQLITE_TEST) SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); +SQLITE_PRIVATE const char *sqlite3TestPtrToText(void*); #endif #if defined(SQLITE_DEBUG) @@ -21513,6 +22205,7 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); #endif SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*); +SQLITE_PRIVATE Expr *sqlite3ExprInt32(sqlite3*,int); SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); @@ -21535,6 +22228,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*); +SQLITE_PRIVATE int sqlite3ExprCanReturnSubtype(Parse*,Expr*); SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); @@ -21550,6 +22244,7 @@ SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); SQLITE_PRIVATE void sqlite3ColumnSetExpr(Parse*,Table*,Column*,Expr*); SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table*,Column*); +SQLITE_PRIVATE Expr *sqlite3ColumnExprAuth(Table*,Column*,Parse*); SQLITE_PRIVATE void sqlite3ColumnSetColl(sqlite3*,Column*,const char*zColl); SQLITE_PRIVATE const char *sqlite3ColumnColl(Column*); SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); @@ -21658,6 +22353,7 @@ SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,int,int,char**); +SQLITE_PRIVATE int sqlite3IndexBloomable(const Index*,int); SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Expr*, int, int, u8); SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); @@ -21666,6 +22362,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList Expr*,ExprList*,u32,Expr*); SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*); +SQLITE_PRIVATE void sqlite3SelectCheckOnClauses(Parse *pParse, Select *pSelect); SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); @@ -21757,12 +22454,14 @@ SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int); +SQLITE_PRIVATE int sqlite3ExprListIsConstant(Parse *pParse, ExprList *pList, int bNoIs); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif -SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*, int); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); +SQLITE_PRIVATE int sqlite3ExprIsLikeOperator(const Expr*); SQLITE_PRIVATE int sqlite3IsRowid(const char*); SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab); SQLITE_PRIVATE void sqlite3GenerateRowDelete( @@ -21831,17 +22530,16 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, i SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*, const char*,const char*); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,SrcList*, IdList*, Select*,u8,Upsert*, const char*,const char*); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,SrcList*,ExprList*, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,SrcList*,SrcList*,ExprList*, Expr*, u8, const char*,const char*); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,SrcList*, Expr*, const char*,const char*); SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); -SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*); # define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p)) # define sqlite3IsToplevel(p) ((p)->pToplevel==0) #else @@ -21855,7 +22553,6 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*); # define sqlite3ParseToplevel(p) p # define sqlite3IsToplevel(p) 1 # define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0 -# define sqlite3TriggerStepSrc(A,B) 0 #endif SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); @@ -21888,7 +22585,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); SQLITE_PRIVATE i64 sqlite3RealToI64(double); SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*); -SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*); SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); SQLITE_PRIVATE int sqlite3Atoi(const char*); @@ -21913,6 +22610,7 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int); */ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *); +SQLITE_PRIVATE i64 sqlite3VarintValue(const unsigned char*); SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *); SQLITE_PRIVATE int sqlite3VarintLen(u64 v); @@ -21928,9 +22626,6 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v); #define putVarint32(A,B) \ (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\ sqlite3PutVarint((A),(B))) -#define getVarint sqlite3GetVarint -#define putVarint sqlite3PutVarint - SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3*,const Table*); @@ -21966,14 +22661,23 @@ SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs*); SQLITE_PRIVATE const char *sqlite3ErrStr(int); SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); +SQLITE_PRIVATE int sqlite3BinaryCompare(void*,int,const void*,int,const void*); +#if SQLITE_USES_INLINE +static SQLITE_INLINE int sqlite3IsBinary(const CollSeq *p){ + assert( p==0 || p->xCmp!=sqlite3BinaryCompare + || strcmp(p->zName,"BINARY")==0 ); + return p==0 || p->xCmp==sqlite3BinaryCompare; +} +#else SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*); +#endif SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8); SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr); SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr); SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*); -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(const Parse *pParse, Expr*, const Token*, int); -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(const Parse*,Expr*,const char*); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr*); SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); @@ -22020,6 +22724,7 @@ SQLITE_PRIVATE const unsigned char *sqlite3aGTb; SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; +SQLITE_PRIVATE const sqlite3_str sqlite3OomStr; #ifndef SQLITE_OMIT_WSD SQLITE_PRIVATE int sqlite3PendingByte; #endif @@ -22032,10 +22737,21 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); SQLITE_PRIVATE void sqlite3AlterFunctions(void); SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE void sqlite3AlterDropConstraint(Parse*,SrcList*,Token*,Token*); +SQLITE_PRIVATE void sqlite3AlterAddConstraint( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* Table to add constraint to */ + Token *pFirst, /* First token of new constraint */ + Token *pName, /* Name of new constraint. NULL if name omitted. */ + const char *zExpr, /* Text of CHECK expression */ + int nExpr, /* Size of pExpr in bytes */ + Expr *pExpr /* The parsed CHECK expression */ +); +SQLITE_PRIVATE void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *, int *); SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); -SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int); +SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int, int); SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*); SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, SrcItem*); @@ -22108,9 +22824,9 @@ SQLITE_PRIVATE char *sqlite3RCStrResize(char*,u64); SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64); +SQLITE_PRIVATE int sqlite3StrAccumEnlargeIfNeeded(StrAccum*, i64); SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); -SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*); @@ -22203,10 +22919,12 @@ SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db); SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName); SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*); SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*); +SQLITE_PRIVATE void sqlite3VtabEponymousTableClearAll(sqlite3*); #else # define sqlite3ShadowTableName(A,B) 0 # define sqlite3IsShadowTableOf(A,B,C) 0 # define sqlite3MarkAllShadowTablesOf(A,B) +# define sqlite3VtabEponymousTableClearAll(X) #endif SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*); SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*); @@ -22361,6 +23079,10 @@ SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr*,int); SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*); +SQLITE_PRIVATE SQLITE_OPT_INLINE u64 sqlite3Get8byte(const u8*); +#if SQLITE_BYTEORDER!=4321 +SQLITE_PRIVATE SQLITE_OPT_INLINE u64 sqlite3BSwap64(u64); +#endif SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32); #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY @@ -23058,6 +23780,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_MAX_PAGE_SIZE "MAX_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_SIZE), #endif +#ifdef SQLITE_MAX_SCHEMA + "MAX_SCHEMA=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA), +#endif #ifdef SQLITE_MAX_SCHEMA_RETRY "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), #endif @@ -23335,6 +24060,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_STMTJRNL_SPILL "STMTJRNL_SPILL=" CTIMEOPT_VAL(SQLITE_STMTJRNL_SPILL), #endif +#ifdef SQLITE_STRICT_SUBTYPE + "STRICT_SUBTYPE", +#endif #ifdef SQLITE_SUBSTR_COMPATIBILITY "SUBSTR_COMPATIBILITY", #endif @@ -23706,6 +24434,16 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { */ SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; +/* +** This singleton is an sqlite3_str object that is returned if +** sqlite3_malloc() fails to provide space for a real one. This +** sqlite3_str object accepts no new text and always returns +** an SQLITE_NOMEM error. +*/ +SQLITE_PRIVATE const sqlite3_str sqlite3OomStr = { + 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 +}; + #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) /* ** Counter used for coverage testing. Does not come into play for @@ -24339,7 +25077,9 @@ struct Vdbe { VdbeFrame *pFrame; /* Parent frame */ VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ int nFrame; /* Number of frames in pFrame list */ - u32 expmask; /* Binding to these vars invalidates VM */ + u32 expmask; /* Binding to these vars might invalidate VM */ + u32 smimask; /* Only invalid if changing to/from small integer */ + /* Note: smimask is always a subset of expmask */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ AuxData *pAuxData; /* Linked list of auxdata allocations */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -24407,6 +25147,17 @@ struct ValueList { SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[]; #endif +/* Input "x" is a sequence of unsigned characters that represent a +** big-endian integer. Return the equivalent native integer +*/ +#define ONE_BYTE_INT(x) ((i8)(x)[0]) +#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1]) +#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2]) +#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) +#define FOUR_BYTE_U64(x) (((u64)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) +#define FOUR_BYTE_INT(x) ((int)FOUR_BYTE_UINT(x)) +#define SIX_BYTE_INT(x) (FOUR_BYTE_UINT(x+2)+4294967296LL*TWO_BYTE_INT(x)) + /* ** Function prototypes */ @@ -24450,6 +25201,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, i64, u8, void(*)(void*)); +SQLITE_PRIVATE int sqlite3VdbeMemSetText(Mem*, const char*, i64, void(*)(void*)); SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); #ifdef SQLITE_OMIT_FLOATING_POINT # define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 @@ -24468,13 +25220,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int); SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); #endif SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); -SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemZeroTerminateIfAble(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*); SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); +SQLITE_PRIVATE int sqlite3MemRealValueRC(Mem*, double*); SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull); SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); @@ -24505,6 +25258,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int,int); #endif SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); +SQLITE_PRIVATE int sqlite3VdbeFindIndexKey(BtCursor*, Index*, UnpackedRecord*, int*, int); SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); @@ -25238,6 +25992,7 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ }else{ s = 0; } + if( h==24 && (m!=0 || s!=0 || ms!=0.0) ) return 1; p->validJD = 0; p->rawS = 0; p->validHMS = 1; @@ -25274,6 +26029,10 @@ static void computeJD(DateTime *p){ Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */ M = 1; D = 1; + if( p->validHMS && p->h==24 ){ + p->h = 0; + D = 2; + } } if( Y<-4713 || Y>9999 || p->rawS ){ datetimeError(p); @@ -25302,6 +26061,21 @@ static void computeJD(DateTime *p){ } } +/* +** Return the number of dates in a specific month. +*/ +static int daysOfMonth(int Y, int M){ + if( (1<validYMD || p->isError ); - assert( p->D>=0 && p->D<=31 ); + assert( p->D>=0 && p->D<=32 ); assert( p->M>=0 && p->M<=12 ); - if( p->D<=28 ){ - p->nFloor = 0; - }else if( (1<M) & 0x15aa ){ - p->nFloor = 0; - }else if( p->M!=2 ){ - p->nFloor = (p->D==31); - }else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){ - p->nFloor = p->D - 28; - }else{ - p->nFloor = p->D - 29; - } + mxD = daysOfMonth(p->Y, p->M); + p->nFloor = p->D>mxD ? p->D - mxD : 0; } /* @@ -25352,7 +26118,19 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ zDate += 10; while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; } if( parseHhMmSs(zDate, p)==0 ){ - /* We got the time */ + if( p->h==24 ){ + int mxD = daysOfMonth(Y,M); + p->h = 0; + D++; + if( D>mxD ){ + D -= mxD; + M++; + if( M>12 ){ + M = 1; + Y++; + } + } + } }else if( *zDate==0 ){ p->validHMS = 0; }else{ @@ -25434,7 +26212,7 @@ static int parseDateOrTime( return 0; }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){ return setDateTimeToCurrent(context, p); - }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ + }else if( sqlite3AtoF(zDate, &r)>0 ){ setRawDateNumber(p, r); return 0; }else if( (sqlite3StrICmp(zDate,"subsec")==0 @@ -25772,6 +26550,49 @@ static int parseModifier( } break; } + case 'e': { + /* + ** end of day + ** end of month + ** end of year + ** + ** Move the date forwards to the last millisecond of the current + ** day, month or year. + */ + if( sqlite3_strnicmp(z, "end of ", 7)!=0 ){ + break; + } + if( !p->validJD && !p->validYMD && !p->validHMS ) break; + z += 7; + computeYMD(p); + p->validHMS = 1; + p->h = 23; + p->m = 59; + p->s = 59.999; + p->rawS = 0; + p->tz = 0; + p->validJD = 0; + if( sqlite3_stricmp(z,"month")==0 ){ + p->D = 1; + p->M++; + if( p->M>12 ){ + p->Y++; + p->M = 1; + } + computeFloor(p); + computeJD(p); + p->iJD -= (p->nFloor+1)*86400000; + clearYMD_HMS_TZ(p); + rc = 0; + }else if( sqlite3_stricmp(z,"year")==0 ){ + p->M = 12; + p->D = 31; + rc = 0; + }else if( sqlite3_stricmp(z,"day")==0 ){ + rc = 0; + } + break; + } case 'f': { /* ** floor @@ -25874,22 +26695,30 @@ static int parseModifier( case 'w': { /* ** weekday N + ** weekday -N ** - ** Move the date to the same time on the next occurrence of - ** weekday N where 0==Sunday, 1==Monday, and so forth. If the - ** date is already on the appropriate weekday, this is a no-op. + ** Move the date forward (for N>=0) or backward (for N<=-0) to the + ** same time on the next/previous occurrence of weekday abs(N) + ** where 0==Sunday, 1==Monday, and so forth. If the date is already + ** on the appropriate weekday, this is a no-op. */ if( sqlite3_strnicmp(z, "weekday ", 8)==0 - && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 - && r>=0.0 && r<7.0 && (n=(int)r)==r ){ + && sqlite3AtoF(&z[8], &r)>0 + && r>=-6.0 && r<=6.0 + && sqlite3RealSameAsInt(r,(i64)(n=(int)r)) + ){ sqlite3_int64 Z; computeYMD_HMS(p); p->tz = 0; p->validJD = 0; computeJD(p); Z = ((p->iJD + 129600000)/86400000) % 7; - if( Z>n ) Z -= 7; - p->iJD += (n - Z)*86400000; + if( n<0 ) n = -n; + if( Z!=n ){ + if( Z>n ) Z -= 7; + p->iJD += (n - Z)*86400000; + if( strchr(z+8,'-')!=0 ) p->iJD -= 7*86400000; + } clearYMD_HMS_TZ(p); rc = 0; } @@ -25897,7 +26726,9 @@ static int parseModifier( } case 's': { /* - ** start of TTTTT + ** start of day + ** start of month + ** start of year ** ** Move the date backwards to the beginning of the current day, ** or month or year. @@ -25951,9 +26782,11 @@ static int parseModifier( case '8': case '9': { double rRounder; - int i; + int i, rx; int Y,M,D,h,m,x; const char *z2 = z; + char *zCopy; + sqlite3 *db = sqlite3_context_db_handle(pCtx); char z0 = z[0]; for(n=1; z[n]; n++){ if( z[n]==':' ) break; @@ -25963,7 +26796,11 @@ static int parseModifier( if( n==6 && getDigits(&z[1], "50f", &Y)==1 ) break; } } - if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ + zCopy = sqlite3DbStrNDup(db, z, n); + if( zCopy==0 ) break; + rx = sqlite3AtoF(zCopy, &r)<=0; + sqlite3DbFree(db, zCopy); + if( rx ){ assert( rc==1 ); break; } @@ -26415,38 +27252,38 @@ static void strftimeFunc( size_t i,j; sqlite3 *db; const char *zFmt; - sqlite3_str sRes; + sqlite3_str *pRes; if( argc==0 ) return; zFmt = (const char*)sqlite3_value_text(argv[0]); if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return; db = sqlite3_context_db_handle(context); - sqlite3StrAccumInit(&sRes, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + pRes = sqlite3_str_new(db); computeJD(&x); computeYMD_HMS(&x); for(i=j=0; zFmt[i]; i++){ char cf; if( zFmt[i]!='%' ) continue; - if( j59.999) ) s = 59.999; - sqlite3_str_appendf(&sRes, "%06.3f", s); + sqlite3_str_appendf(pRes, "%06.3f", s); break; } case 'F': { - sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D); + sqlite3_str_appendf(pRes, "%04d-%02d-%02d", x.Y, x.M, x.D); break; } case 'G': /* Fall thru */ @@ -26458,15 +27295,15 @@ static void strftimeFunc( y.validYMD = 0; computeYMD(&y); if( cf=='g' ){ - sqlite3_str_appendf(&sRes, "%02d", y.Y%100); + sqlite3_str_appendf(pRes, "%02d", y.Y%100); }else{ - sqlite3_str_appendf(&sRes, "%04d", y.Y); + sqlite3_str_appendf(pRes, "%04d", y.Y); } break; } case 'H': case 'k': { - sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h); + sqlite3_str_appendf(pRes, cf=='H' ? "%02d" : "%2d", x.h); break; } case 'I': /* Fall thru */ @@ -26474,65 +27311,65 @@ static void strftimeFunc( int h = x.h; if( h>12 ) h -= 12; if( h==0 ) h = 12; - sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); + sqlite3_str_appendf(pRes, cf=='I' ? "%02d" : "%2d", h); break; } case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */ - sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1); + sqlite3_str_appendf(pRes,"%03d",daysAfterJan01(&x)+1); break; } case 'J': { /* Julian day number. (Non-standard) */ - sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0); + sqlite3_str_appendf(pRes,"%.16g",x.iJD/86400000.0); break; } case 'm': { - sqlite3_str_appendf(&sRes,"%02d",x.M); + sqlite3_str_appendf(pRes,"%02d",x.M); break; } case 'M': { - sqlite3_str_appendf(&sRes,"%02d",x.m); + sqlite3_str_appendf(pRes,"%02d",x.m); break; } case 'p': /* Fall thru */ case 'P': { if( x.h>=12 ){ - sqlite3_str_append(&sRes, cf=='p' ? "PM" : "pm", 2); + sqlite3_str_append(pRes, cf=='p' ? "PM" : "pm", 2); }else{ - sqlite3_str_append(&sRes, cf=='p' ? "AM" : "am", 2); + sqlite3_str_append(pRes, cf=='p' ? "AM" : "am", 2); } break; } case 'R': { - sqlite3_str_appendf(&sRes, "%02d:%02d", x.h, x.m); + sqlite3_str_appendf(pRes, "%02d:%02d", x.h, x.m); break; } case 's': { if( x.useSubsec ){ - sqlite3_str_appendf(&sRes,"%.3f", + sqlite3_str_appendf(pRes,"%.3f", (x.iJD - 21086676*(i64)10000000)/1000.0); }else{ i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); - sqlite3_str_appendf(&sRes,"%lld",iS); + sqlite3_str_appendf(pRes,"%lld",iS); } break; } case 'S': { - sqlite3_str_appendf(&sRes,"%02d",(int)x.s); + sqlite3_str_appendf(pRes,"%02d",(int)x.s); break; } case 'T': { - sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); + sqlite3_str_appendf(pRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); break; } case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */ case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */ char c = (char)daysAfterSunday(&x) + '0'; if( c=='0' && cf=='u' ) c = '7'; - sqlite3_str_appendchar(&sRes, 1, c); + sqlite3_str_appendchar(pRes, 1, c); break; } case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */ - sqlite3_str_appendf(&sRes,"%02d", + sqlite3_str_appendf(pRes,"%02d", (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7); break; } @@ -26543,30 +27380,30 @@ static void strftimeFunc( y.iJD += (3 - daysAfterMonday(&x))*86400000; y.validYMD = 0; computeYMD(&y); - sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1); + sqlite3_str_appendf(pRes,"%02d", daysAfterJan01(&y)/7+1); break; } case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */ - sqlite3_str_appendf(&sRes,"%02d", + sqlite3_str_appendf(pRes,"%02d", (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7); break; } case 'Y': { - sqlite3_str_appendf(&sRes,"%04d",x.Y); + sqlite3_str_appendf(pRes,"%04d",x.Y); break; } case '%': { - sqlite3_str_appendchar(&sRes, 1, '%'); + sqlite3_str_appendchar(pRes, 1, '%'); break; } default: { - sqlite3_str_reset(&sRes); + sqlite3_str_free(pRes); return; } } } - if( jxCurrentTime(pVfs, &r); - *pTimeOut = (sqlite3_int64)(r*86400000.0); + *pTimeOut = sqlite3RealToI64(r*86400000.0); } return rc; } @@ -29562,23 +30399,28 @@ static SQLITE_WSD int mutexIsInit = 0; #ifndef SQLITE_MUTEX_OMIT -#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS +#ifdef SQLITE_THREAD_MISUSE_WARNINGS /* -** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains +** This block (enclosed by SQLITE_THREAD_MISUSE_WARNINGS) contains ** the implementation of a wrapper around the system default mutex ** implementation (sqlite3DefaultMutex()). ** ** Most calls are passed directly through to the underlying default ** mutex implementation. Except, if a mutex is configured by calling ** sqlite3MutexWarnOnContention() on it, then if contention is ever -** encountered within xMutexEnter() a warning is emitted via sqlite3_log(). +** encountered within xMutexEnter() then a warning is emitted via +** sqlite3_log(). Furthermore, if SQLITE_THREAD_MISUSE_ABORT is +** defined then abort() is called after the sqlite3_log() warning. ** -** This type of mutex is used as the database handle mutex when testing -** apps that usually use SQLITE_CONFIG_MULTITHREAD mode. +** This type of mutex is used on the database handle mutex when testing +** apps that usually use SQLITE_CONFIG_MULTITHREAD mode. A failure +** indicates that the app ought to be using SQLITE_OPEN_FULLMUTEX or +** similar because it is trying to use the same database handle from +** two different connections at the same time. */ /* -** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS +** Type for all mutexes used when SQLITE_THREAD_MISUSE_WARNINGS ** is defined. Variable CheckMutex.mutex is a pointer to the real mutex ** allocated by the system mutex implementation. Variable iType is usually set ** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST @@ -29614,11 +30456,12 @@ static int checkMutexNotheld(sqlite3_mutex *p){ */ static int checkMutexInit(void){ pGlobalMutexMethods = sqlite3DefaultMutex(); - return SQLITE_OK; + return pGlobalMutexMethods->xMutexInit(); } static int checkMutexEnd(void){ + int rc = pGlobalMutexMethods->xMutexEnd(); pGlobalMutexMethods = 0; - return SQLITE_OK; + return rc; } /* @@ -29695,6 +30538,9 @@ static void checkMutexEnter(sqlite3_mutex *p){ sqlite3_log(SQLITE_MISUSE, "illegal multi-threaded access to database connection" ); +#if SQLITE_THREAD_MISUSE_ABORT + abort(); +#endif } pGlobalMutexMethods->xMutexEnter(pCheck->mutex); } @@ -29746,7 +30592,7 @@ SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){ pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION; } } -#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */ +#endif /* ifdef SQLITE_THREAD_MISUSE_WARNINGS */ /* ** Initialize the mutex system. @@ -29763,7 +30609,7 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){ sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; if( sqlite3GlobalConfig.bCoreMutex ){ -#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS +#ifdef SQLITE_THREAD_MISUSE_WARNINGS pFrom = multiThreadedCheckMutex(); #else pFrom = sqlite3DefaultMutex(); @@ -30165,8 +31011,15 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ # define SQLITE_MUTEX_NREF 0 #endif +#if GCC_VERSION>0 +# define ALIGN128 __attribute__((aligned(128))) +#else +# define ALIGN128 +#endif + /* -** Each recursive mutex is an instance of the following structure. +** Each SQLite mutex is an instance of the following structure. +** */ struct sqlite3_mutex { pthread_mutex_t mutex; /* Mutex controlling the lock */ @@ -30281,19 +31134,31 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } ** the same type number. */ static sqlite3_mutex *pthreadMutexAlloc(int iType){ - static sqlite3_mutex staticMutexes[] = { - SQLITE3_MUTEX_INITIALIZER(2), - SQLITE3_MUTEX_INITIALIZER(3), - SQLITE3_MUTEX_INITIALIZER(4), - SQLITE3_MUTEX_INITIALIZER(5), - SQLITE3_MUTEX_INITIALIZER(6), - SQLITE3_MUTEX_INITIALIZER(7), - SQLITE3_MUTEX_INITIALIZER(8), - SQLITE3_MUTEX_INITIALIZER(9), - SQLITE3_MUTEX_INITIALIZER(10), - SQLITE3_MUTEX_INITIALIZER(11), - SQLITE3_MUTEX_INITIALIZER(12), - SQLITE3_MUTEX_INITIALIZER(13) + /* Static mutexes - those with IDs of 2 or more... + ** + ** The ALIGN128 macro attempts to force 128-byte alignment on mutexes, + ** so that adjacent mutex objects are always on different cache lines + ** in the CPU. This is CPU-dependent, of course, but 128-byte alignment + ** seems to work well for all contemporary processors. Experiments show + ** that 64 works just as well most of the time, but the internet says + ** that 128-byte alignment works better. + */ + static ALIGN128 union staticMutex { + sqlite3_mutex m; + char aSpacer[128]; + } aMutex[] = { + { .m = SQLITE3_MUTEX_INITIALIZER(2) }, + { .m = SQLITE3_MUTEX_INITIALIZER(3) }, + { .m = SQLITE3_MUTEX_INITIALIZER(4) }, + { .m = SQLITE3_MUTEX_INITIALIZER(5) }, + { .m = SQLITE3_MUTEX_INITIALIZER(6) }, + { .m = SQLITE3_MUTEX_INITIALIZER(7) }, + { .m = SQLITE3_MUTEX_INITIALIZER(8) }, + { .m = SQLITE3_MUTEX_INITIALIZER(9) }, + { .m = SQLITE3_MUTEX_INITIALIZER(10) }, + { .m = SQLITE3_MUTEX_INITIALIZER(11) }, + { .m = SQLITE3_MUTEX_INITIALIZER(12) }, + { .m = SQLITE3_MUTEX_INITIALIZER(13) }, }; sqlite3_mutex *p; switch( iType ){ @@ -30330,12 +31195,12 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){ } default: { #ifdef SQLITE_ENABLE_API_ARMOR - if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){ + if( iType-2<0 || iType-2>=ArraySize(aMutex) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - p = &staticMutexes[iType-2]; + p = &aMutex[iType-2].m; break; } } @@ -30580,61 +31445,11 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ # include /* amalgamator: dontcache */ #endif -/* -** Determine if we are dealing with Windows NT. -** -** We ought to be able to determine if we are compiling for Windows 9x or -** Windows NT using the _WIN32_WINNT macro as follows: -** -** #if defined(_WIN32_WINNT) -** # define SQLITE_OS_WINNT 1 -** #else -** # define SQLITE_OS_WINNT 0 -** #endif -** -** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as -** it ought to, so the above test does not work. We'll just assume that -** everything is Windows NT unless the programmer explicitly says otherwise -** by setting SQLITE_OS_WINNT to 0. -*/ -#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) -# define SQLITE_OS_WINNT 1 -#endif - -/* -** Determine if we are dealing with Windows CE - which has a much reduced -** API. -*/ -#if defined(_WIN32_WCE) -# define SQLITE_OS_WINCE 1 -#else -# define SQLITE_OS_WINCE 0 -#endif - -/* -** Determine if we are dealing with WinRT, which provides only a subset of -** the full Win32 API. -*/ -#if !defined(SQLITE_OS_WINRT) -# define SQLITE_OS_WINRT 0 -#endif - -/* -** For WinCE, some API function parameters do not appear to be declared as -** volatile. -*/ -#if SQLITE_OS_WINCE -# define SQLITE_WIN32_VOLATILE -#else -# define SQLITE_WIN32_VOLATILE volatile -#endif - /* ** For some Windows sub-platforms, the _beginthreadex() / _endthreadex() ** functions are not available (e.g. those not using MSVC, Cygwin, etc). */ -#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ - SQLITE_THREADSAFE>0 && !defined(__CYGWIN__) +#if SQLITE_OS_WIN && SQLITE_THREADSAFE>0 && !defined(__CYGWIN__) # define SQLITE_OS_WIN_THREADS 1 #else # define SQLITE_OS_WIN_THREADS 0 @@ -30652,11 +31467,32 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ */ #ifdef SQLITE_MUTEX_W32 +#if MSVC_VERSION>0 +# define ALIGN128 __declspec(align(128)) +#else +# define ALIGN128 +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4324) +#endif /* _MSC_VER */ + /* -** Each recursive mutex is an instance of the following structure. +** Each SQLite mutex is an instance of the following structure. +** +** The ALIGN128 macro attempts to force 128-byte alignment on mutexes, +** so that adjacent mutex objects are always on different cache lines +** in the CPU. This is CPU-dependent, of course, but 128-byte alignment +** seems to work well for all contemporary processors. Experiments show +** that 64 works just as well most of the time, but the internet says +** that 128-byte alignment works better. */ struct sqlite3_mutex { - CRITICAL_SECTION mutex; /* Mutex controlling the lock */ + union { + CRITICAL_SECTION cs; /* The CRITICAL_SECTION mutex. id==1 */ + SRWLOCK srwl; /* The Slim reader/writer lock. id!=1 */ + } u; int id; /* Mutex type */ #ifdef SQLITE_DEBUG volatile int nRef; /* Number of entrances */ @@ -30664,20 +31500,9 @@ struct sqlite3_mutex { volatile LONG trace; /* True to trace changes */ #endif }; - -/* -** These are the initializer values used when declaring a "static" mutex -** on Win32. It should be noted that all mutexes require initialization -** on the Win32 platform. -*/ -#define SQLITE_W32_MUTEX_INITIALIZER { 0 } - -#ifdef SQLITE_DEBUG -#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \ - 0L, (DWORD)0, 0 } -#else -#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id } -#endif +#ifdef _MSC_VER +#pragma warning(pop) +#endif /* _MSC_VER */ #ifdef SQLITE_DEBUG /* @@ -30688,13 +31513,8 @@ static int winMutexHeld(sqlite3_mutex *p){ return p->nRef!=0 && p->owner==GetCurrentThreadId(); } -static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ - return p->nRef==0 || p->owner!=tid; -} - static int winMutexNotheld(sqlite3_mutex *p){ - DWORD tid = GetCurrentThreadId(); - return winMutexNotheld2(p, tid); + return p->nRef==0 || p->owner!=GetCurrentThreadId(); } #endif @@ -30716,44 +31536,41 @@ SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ } /* -** Initialize and deinitialize the mutex subsystem. +** Static mutexes. +** +** The ALIGN128 macro on the static mutex array forces 128-byte alignment +** on the mutexes so that adjacent mutex objects are always on different +** cache lines in the CPU. This is CPU-dependent, of course, but 128-byte +** alignment seems to work well for all contemporary processors. +** Experiments show that 64 works just as well most of the time, but +** the internet says that 128-byte alignment works better. */ -static sqlite3_mutex winMutex_staticMutexes[] = { - SQLITE3_MUTEX_INITIALIZER(2), - SQLITE3_MUTEX_INITIALIZER(3), - SQLITE3_MUTEX_INITIALIZER(4), - SQLITE3_MUTEX_INITIALIZER(5), - SQLITE3_MUTEX_INITIALIZER(6), - SQLITE3_MUTEX_INITIALIZER(7), - SQLITE3_MUTEX_INITIALIZER(8), - SQLITE3_MUTEX_INITIALIZER(9), - SQLITE3_MUTEX_INITIALIZER(10), - SQLITE3_MUTEX_INITIALIZER(11), - SQLITE3_MUTEX_INITIALIZER(12), - SQLITE3_MUTEX_INITIALIZER(13) -}; - +static ALIGN128 union staticMutexes { + sqlite3_mutex m; + char spacer[128]; +} aWindowsMutex[12]; static int winMutex_isInit = 0; -static int winMutex_isNt = -1; /* <0 means "need to query" */ /* As the winMutexInit() and winMutexEnd() functions are called as part ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the ** "interlocked" magic used here is probably not strictly necessary. */ -static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; +static LONG volatile winMutex_lock = 0; -SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ static int winMutexInit(void){ /* The first to increment to 1 does actual initialization */ if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ int i; - for(i=0; iid = i+2; + InitializeSRWLock(&p->u.srwl); +#ifdef SQLITE_DEBUG + p->nRef = 0; + p->owner = 0; + p->trace = 0; #endif } winMutex_isInit = 1; @@ -30772,10 +31589,6 @@ static int winMutexEnd(void){ ** (which should be the last to shutdown.) */ if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ if( winMutex_isInit==1 ){ - int i; - for(i=0; itrace = 1; #endif #endif -#if SQLITE_OS_WINRT - InitializeCriticalSectionEx(&p->mutex, 0, 0); -#else - InitializeCriticalSection(&p->mutex); -#endif + if( iType==SQLITE_MUTEX_RECURSIVE ){ + InitializeCriticalSection(&p->u.cs); + }else{ + InitializeSRWLock(&p->u.srwl); + } } break; } default: { #ifdef SQLITE_ENABLE_API_ARMOR - if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){ + if( iType-2<0 || iType-2>=ArraySize(aWindowsMutex) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - p = &winMutex_staticMutexes[iType-2]; + p = &aWindowsMutex[iType-2].m; #ifdef SQLITE_DEBUG #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC InterlockedCompareExchange(&p->trace, 1, 0); @@ -30881,8 +31694,10 @@ static sqlite3_mutex *winMutexAlloc(int iType){ static void winMutexFree(sqlite3_mutex *p){ assert( p ); assert( p->nRef==0 && p->owner==0 ); - if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ - DeleteCriticalSection(&p->mutex); + if( p->id==SQLITE_MUTEX_FAST ){ + sqlite3_free(p); + }else if( p->id==SQLITE_MUTEX_RECURSIVE ){ + DeleteCriticalSection(&p->u.cs); sqlite3_free(p); }else{ #ifdef SQLITE_ENABLE_API_ARMOR @@ -30903,67 +31718,56 @@ static void winMutexFree(sqlite3_mutex *p){ ** more than once, the behavior is undefined. */ static void winMutexEnter(sqlite3_mutex *p){ -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - DWORD tid = GetCurrentThreadId(); -#endif -#ifdef SQLITE_DEBUG - assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); -#else assert( p ); +#ifdef SQLITE_DEBUG + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); #endif assert( winMutex_isInit==1 ); - EnterCriticalSection(&p->mutex); + if( p->id==SQLITE_MUTEX_RECURSIVE ){ + EnterCriticalSection(&p->u.cs); + }else{ + AcquireSRWLockExclusive(&p->u.srwl); + } #ifdef SQLITE_DEBUG assert( p->nRef>0 || p->owner==0 ); - p->owner = tid; + p->owner = GetCurrentThreadId(); p->nRef++; if( p->trace ){ OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", - tid, p->id, p, p->trace, p->nRef)); + GetCurrentThreadId(), p->id, p, p->trace, p->nRef)); } #endif } static int winMutexTry(sqlite3_mutex *p){ -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - DWORD tid = GetCurrentThreadId(); -#endif int rc = SQLITE_BUSY; assert( p ); - assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); /* - ** The sqlite3_mutex_try() routine is very rarely used, and when it - ** is used it is merely an optimization. So it is OK for it to always + ** The sqlite3_mutex_try() routine is seldom used, and when it is + ** used it is merely an optimization. So it is OK for it to always ** fail. - ** - ** The TryEnterCriticalSection() interface is only available on WinNT. - ** And some windows compilers complain if you try to use it without - ** first doing some #defines that prevent SQLite from building on Win98. - ** For that reason, we will omit this optimization for now. See - ** ticket #2685. */ -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 - assert( winMutex_isInit==1 ); - assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); - if( winMutex_isNt<0 ){ - winMutex_isNt = sqlite3_win32_is_nt(); + if( p->id==SQLITE_MUTEX_RECURSIVE ){ + rc = TryEnterCriticalSection(&p->u.cs); + }else{ + rc = TryAcquireSRWLockExclusive(&p->u.srwl); } - assert( winMutex_isNt==0 || winMutex_isNt==1 ); - if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ + if( rc ){ #ifdef SQLITE_DEBUG - p->owner = tid; + p->owner = GetCurrentThreadId(); p->nRef++; #endif rc = SQLITE_OK; + }else{ + rc = SQLITE_BUSY; } -#else - UNUSED_PARAMETER(p); -#endif #ifdef SQLITE_DEBUG if( p->trace ){ - OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n", - tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); + OSTRACE(( + "TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n", + GetCurrentThreadId(), p->id, p, p->trace, p->owner, p->nRef, + sqlite3ErrName(rc))); } #endif return rc; @@ -30976,23 +31780,24 @@ static int winMutexTry(sqlite3_mutex *p){ ** is not currently allocated. SQLite will never do either. */ static void winMutexLeave(sqlite3_mutex *p){ -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - DWORD tid = GetCurrentThreadId(); -#endif assert( p ); #ifdef SQLITE_DEBUG assert( p->nRef>0 ); - assert( p->owner==tid ); + assert( p->owner==GetCurrentThreadId() ); p->nRef--; if( p->nRef==0 ) p->owner = 0; assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); #endif assert( winMutex_isInit==1 ); - LeaveCriticalSection(&p->mutex); + if( p->id==SQLITE_MUTEX_RECURSIVE ){ + LeaveCriticalSection(&p->u.cs); + }else{ + ReleaseSRWLockExclusive(&p->u.srwl); + } #ifdef SQLITE_DEBUG if( p->trace ){ OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", - tid, p->id, p, p->trace, p->nRef)); + GetCurrentThreadId(), p->id, p, p->trace, p->nRef)); } #endif } @@ -31312,27 +32117,6 @@ static void mallocWithAlarm(int n, void **pp){ *pp = p; } -/* -** Maximum size of any single memory allocation. -** -** This is not a limit on the total amount of memory used. This is -** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). -** -** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 -** This provides a 256-byte safety margin for defense against 32-bit -** signed integer overflow bugs when computing memory allocation sizes. -** Paranoid applications might want to reduce the maximum allocation size -** further for an even larger safety margin. 0x3fffffff or 0x0fffffff -** or even smaller would be reasonable upper bounds on the size of a memory -** allocations for most applications. -*/ -#ifndef SQLITE_MAX_ALLOCATION_SIZE -# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 -#endif -#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 -# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 -#endif - /* ** Allocate memory. This routine is like sqlite3_malloc() except that it ** assumes the memory subsystem has already been initialized. @@ -31556,8 +32340,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ sqlite3_free(pOld); /* IMP: R-26507-47431 */ return 0; } - if( nBytes>=0x7fffff00 ){ - /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ + if( nBytes>SQLITE_MAX_ALLOCATION_SIZE ){ return 0; } nOld = sqlite3MallocSize(pOld); @@ -31980,8 +32763,10 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ #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 etESCAPE_j 17 /* %j -> JSON string literal w/o "..." */ +#define etESCAPE_J 18 /* %J -> JSON string literal with "..." */ -#define etINVALID 17 /* Any unrecognized conversion type */ +#define etINVALID 19 /* Any unrecognized conversion type */ /* @@ -32011,20 +32796,20 @@ typedef struct et_info { /* Information about each format field */ /* ** The table is searched by hash. In the case of %C where C is the character -** and that character has ASCII value j, then the hash is j%23. +** and that character has ASCII value j, then the hash is j%25. ** ** The order of the entries in fmtinfo[] and the hash chain was entered ** manually, but based on the output of the following TCL script: */ #if 0 /***** Beginning of script ******/ -foreach c {d s g z q Q w c o u x X f e E G i n % p T S r} { +foreach c {d s g z q Q w c o u x X f e E G i n % p T S r J j} { scan $c %c x set n($c) $x } set mx [llength [array names n]] puts "count: $mx" -set mx 27 +set mx 25 puts "*********** mx=$mx ************" for {set r 0} {$r<$mx} {incr r} { puts -nonewline [format %2d: $r] @@ -32036,31 +32821,34 @@ for {set r 0} {$r<$mx} {incr r} { #endif /***** End of script ********/ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; +static const char aHex[] = "0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; -static const et_info fmtinfo[23] = { - /* 0 */ { 's', 0, 4, etSTRING, 0, 0, 1 }, - /* 1 */ { 'E', 0, 1, etEXP, 14, 0, 0 }, /* Hash: 0 */ - /* 2 */ { 'u', 10, 0, etDECIMAL, 0, 0, 3 }, - /* 3 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, /* Hash: 2 */ - /* 4 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 }, - /* 5 */ { 'x', 16, 0, etRADIX, 16, 1, 0 }, - /* 6 */ { 'c', 0, 0, etCHARX, 0, 0, 0 }, /* Hash: 7 */ - /* 7 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 6 }, - /* 8 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 }, - /* 9 */ { 'e', 0, 1, etEXP, 30, 0, 0 }, - /* 10 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 }, - /* 11 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 }, - /* 12 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 0 }, - /* 13 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 }, - /* 14 */ { '%', 0, 0, etPERCENT, 0, 0, 16 }, - /* 15 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 }, - /* 16 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, /* Hash: 14 */ - /* 17 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 19 */ - /* 18 */ { 'n', 0, 0, etSIZE, 0, 0, 0 }, - /* 19 */ { 'o', 8, 0, etRADIX, 0, 2, 17 }, - /* 20 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 }, - /* 21 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 0 }, - /* 22 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 } +static const et_info fmtinfo[25] = { + /* 0 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 }, + /* 1 */ { 'e', 0, 1, etEXP, 30, 0, 0 }, + /* 2 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 }, + /* 3 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 }, + /* 4 */ { 'j', 0, 0, etESCAPE_j, 0, 0, 0 }, /* Hash: 6 */ + /* 5 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 }, + /* 6 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 4 }, + /* 7 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 }, /* Hash: 12 */ + /* 8 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, + /* 9 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 }, + /* 10 */ { 'n', 0, 0, etSIZE, 0, 0, 0 }, + /* 11 */ { 'o', 8, 0, etRADIX, 0, 2, 0 }, + /* 12 */ { '%', 0, 0, etPERCENT, 0, 0, 7 }, + /* 13 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 16 }, + /* 14 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 }, + /* 15 */ { 's', 0, 4, etSTRING, 0, 0, 0 }, + /* 16 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 13 */ + /* 17 */ { 'u', 10, 0, etDECIMAL, 0, 0, 0 }, + /* 18 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 }, /* Hash: 19 */ + /* 19 */ { 'E', 0, 1, etEXP, 14, 0, 18 }, + /* 20 */ { 'x', 16, 0, etRADIX, 16, 1, 0 }, + /* 21 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, + /* 22 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 0 }, + /* 23 */ { 'J', 0, 0, etESCAPE_J, 0, 0, 0 }, /* Hash: 24 */ + /* 24 */ { 'c', 0, 0, etCHARX, 0, 0, 23 } }; /* Additional Notes: @@ -32111,7 +32899,7 @@ static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){ sqlite3StrAccumSetError(pAccum, SQLITE_TOOBIG); return 0; } - z = sqlite3DbMallocRaw(pAccum->db, n); + z = sqlite3_malloc(n); if( z==0 ){ sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); } @@ -32128,12 +32916,23 @@ static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){ #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ /* -** Hard limit on the precision of floating-point conversions. +** Hard limit on the precision of floating-point conversions to +** the minimum of SQLITE_PRINTF_PRECISION_LIMIT and 100 million. */ -#ifndef SQLITE_PRINTF_PRECISION_LIMIT +#ifdef SQLITE_PRINTF_PRECISION_LIMIT +# if SQLITE_PRINTF_PRECISION_LIMIT<100000000 +# define SQLITE_FP_PRECISION_LIMIT SQLITE_PRINTF_PRECISION_LIMIT +# else +# define SQLITE_FP_PRECISION_LIMIT 100000000 +# endif +#else # define SQLITE_FP_PRECISION_LIMIT 100000000 #endif +/* Forward reference */ +static void sqlite3StrAppend64(sqlite3_str *p, const char *z, i64 N); +static void sqlite3StrAppendchar64(sqlite3_str *p, i64 N, char c); + /* ** Render a string given by "fmt" into the StrAccum object. */ @@ -32144,10 +32943,10 @@ SQLITE_API void sqlite3_str_vappendf( ){ int c; /* Next character in the format string */ char *bufpt; /* Pointer to the conversion buffer */ - int precision; /* Precision of the current field */ - int length; /* Length of the field */ + i64 precision; /* Precision of the current field */ + i64 length; /* Length of the field */ int idx; /* A general purpose loop counter */ - int width; /* Width of the current field */ + i64 width; /* Width of the current field */ etByte flag_leftjustify; /* True if "-" flag is present */ etByte flag_prefix; /* '+' or ' ' or 0 for prefix */ etByte flag_alternateform; /* True if "#" flag is present */ @@ -32195,7 +32994,7 @@ SQLITE_API void sqlite3_str_vappendf( fmt = bufpt + strlen(bufpt); } #endif - sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); + sqlite3StrAppend64(pAccum, bufpt, fmt - bufpt); if( *fmt==0 ) break; } if( (c=(*++fmt))==0 ){ @@ -32321,8 +33120,8 @@ SQLITE_API void sqlite3_str_vappendf( } #else /* Fast hash-table lookup */ - assert( ArraySize(fmtinfo)==23 ); - idx = ((unsigned)c) % 23; + assert( ArraySize(fmtinfo)==25 ); + idx = ((unsigned)c) % 25; if( fmtinfo[idx].fmttype==c || fmtinfo[idx = fmtinfo[idx].iNxt].fmttype==c ){ @@ -32441,20 +33240,23 @@ SQLITE_API void sqlite3_str_vappendf( longvalue = longvalue/base; }while( longvalue>0 ); } - length = (int)(&zOut[nOut-1]-bufpt); - while( precision>length ){ - *(--bufpt) = '0'; /* Zero pad */ - length++; + length = &zOut[nOut-1] - bufpt; + if( precision>length ){ /* zero pad */ + i64 nn = precision-length; + bufpt -= nn; + memset(bufpt,'0',nn); + length = precision; } if( cThousand ){ - int nn = (length - 1)/3; /* Number of "," to insert */ - int ix = (length - 1)%3 + 1; + i64 nn = (length - 1)/3; /* Number of "," to insert */ + i64 ix = (length - 1)%3 + 1; + int ii; bufpt -= nn; - for(idx=0; nn>0; idx++){ - bufpt[idx] = bufpt[idx+nn]; + for(ii=0; nn>0; ii++){ + bufpt[ii] = bufpt[ii+nn]; ix--; if( ix==0 ){ - bufpt[++idx] = cThousand; + bufpt[++ii] = cThousand; nn--; ix = 3; } @@ -32467,7 +33269,7 @@ SQLITE_API void sqlite3_str_vappendf( pre = &aPrefix[infop->prefix]; for(; (x=(*pre))!=0; pre++) *(--bufpt) = x; } - length = (int)(&zOut[nOut-1]-bufpt); + length = &zOut[nOut-1] - bufpt; break; case etFLOAT: case etEXP: @@ -32475,6 +33277,7 @@ SQLITE_API void sqlite3_str_vappendf( FpDecode s; int iRound; int j; + i64 szBufNeeded; /* Size needed to hold the output */ if( bArgList ){ realvalue = getDoubleArg(pArgList); @@ -32482,11 +33285,9 @@ SQLITE_API void sqlite3_str_vappendf( realvalue = va_arg(ap,double); } if( precision<0 ) precision = 6; /* Set default precision */ -#ifdef SQLITE_FP_PRECISION_LIMIT if( precision>SQLITE_FP_PRECISION_LIMIT ){ precision = SQLITE_FP_PRECISION_LIMIT; } -#endif if( xtype==etFLOAT ){ iRound = -precision; }else if( xtype==etGENERIC ){ @@ -32495,11 +33296,16 @@ SQLITE_API void sqlite3_str_vappendf( }else{ iRound = precision+1; } - sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16); + sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 20 : 16); if( s.isSpecial ){ if( s.isSpecial==2 ){ - bufpt = flag_zeropad ? "null" : "NaN"; - length = sqlite3Strlen30(bufpt); + if( flag_zeropad ){ + bufpt = "null"; + length = 4; + }else{ + bufpt = "NaN"; + length = 3; + } break; }else if( flag_zeropad ){ s.z[0] = '9'; @@ -32515,7 +33321,7 @@ SQLITE_API void sqlite3_str_vappendf( }else{ bufpt++; } - length = sqlite3Strlen30(bufpt); + length = strlen(bufpt); break; } } @@ -32563,17 +33369,31 @@ SQLITE_API void sqlite3_str_vappendf( }else{ e2 = s.iDP - 1; } - bufpt = buf; - { - i64 szBufNeeded; /* Size of a temporary buffer needed */ - szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15; - if( cThousand && e2>0 ) szBufNeeded += (e2+2)/3; - if( szBufNeeded > etBUFSIZE ){ - bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded); - if( bufpt==0 ) return; + + szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+10; + if( cThousand && e2>0 ) szBufNeeded += (e2+2)/3; + if( szBufNeeded + pAccum->nChar >= pAccum->nAlloc ){ + if( pAccum->mxAlloc==0 && pAccum->accError==0 ){ + /* Unable to allocate space in pAccum, perhaps because it + ** is coming from sqlite3_snprintf() or similar. We'll have + ** to render into temporary space and the memcpy() it over. */ + bufpt = sqlite3_malloc64(szBufNeeded); + if( bufpt==0 ){ + sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); + return; + } + zExtra = bufpt; + }else if( sqlite3StrAccumEnlarge(pAccum, szBufNeeded)zText + pAccum->nChar; } + }else{ + bufpt = pAccum->zText + pAccum->nChar; } zOut = bufpt; + flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; /* The sign in front of the number */ if( prefix ){ @@ -32581,12 +33401,24 @@ SQLITE_API void sqlite3_str_vappendf( } /* Digits prior to the decimal point */ j = 0; + assert( s.n>0 ); if( e2<0 ){ *(bufpt++) = '0'; - }else{ + }else if( cThousand ){ for(; e2>=0; e2--){ *(bufpt++) = j1 ) *(bufpt++) = ','; + if( (e2%3)==0 && e2>1 ) *(bufpt++) = ','; + } + }else{ + j = e2+1; + if( j>s.n ) j = s.n; + memcpy(bufpt, s.z, j); + bufpt += j; + e2 -= j; + if( e2>=0 ){ + memset(bufpt, '0', e2+1); + bufpt += e2+1; + e2 = -1; } } /* The decimal point */ @@ -32595,12 +33427,26 @@ SQLITE_API void sqlite3_str_vappendf( } /* "0" digits after the decimal point but before the first ** significant digit of the number */ - for(e2++; e2<0 && precision>0; precision--, e2++){ - *(bufpt++) = '0'; + if( e2<(-1) && precision>0 ){ + int nn = -1-e2; + if( nn>precision ) nn = precision; + memset(bufpt, '0', nn); + bufpt += nn; + precision -= nn; } /* Significant digits after the decimal point */ - while( (precision--)>0 ){ - *(bufpt++) = j0 ){ + int nn = s.n - j; + if( NEVER(nn>precision) ) nn = precision; + if( nn>0 ){ + memcpy(bufpt, s.z+j, nn); + bufpt += nn; + precision -= nn; + } + if( precision>0 && !flag_rtz ){ + memset(bufpt, '0', precision); + bufpt += precision; + } } /* Remove trailing zeros and the "." if no digits follow the "." */ if( flag_rtz && flag_dp ){ @@ -32630,27 +33476,40 @@ SQLITE_API void sqlite3_str_vappendf( *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */ } - *bufpt = 0; - /* The converted number is in buf[] and zero terminated. Output it. - ** Note that the number is in the usual order, not reversed as with - ** integer conversions. */ - length = (int)(bufpt-zOut); - bufpt = zOut; - - /* Special case: Add leading zeros if the flag_zeropad flag is - ** set and we are not left justified */ - if( flag_zeropad && !flag_leftjustify && length < width){ - int i; - int nPad = width - length; - for(i=width; i>=nPad; i--){ - bufpt[i] = bufpt[i-nPad]; + length = bufpt - zOut; + assert( length <= szBufNeeded ); + if( lengthnChar + length < SMXV(pAccum->nChar) ); + pAccum->nChar += length; + zOut[length] = 0; + continue; + }else{ + /* We were unable to render directly into pAccum because we + ** couldn't allocate sufficient memory. We need to memcpy() + ** the rendering (or some prefix thereof) into the output + ** buffer. */ + bufpt[0] = 0; + bufpt = zExtra; + break; + } } case etSIZE: if( !bArgList ){ @@ -32685,19 +33544,18 @@ SQLITE_API void sqlite3_str_vappendf( i64 nPrior = 1; width -= precision-1; if( width>1 && !flag_leftjustify ){ - sqlite3_str_appendchar(pAccum, width-1, ' '); + sqlite3StrAppendchar64(pAccum, width-1, ' '); width = 0; } - sqlite3_str_append(pAccum, buf, length); + sqlite3StrAppend64(pAccum, buf, length); precision--; while( precision > 1 ){ i64 nCopyBytes; if( nPrior > precision-1 ) nPrior = precision - 1; nCopyBytes = length*nPrior; - if( nCopyBytes + pAccum->nChar >= pAccum->nAlloc ){ - sqlite3StrAccumEnlarge(pAccum, nCopyBytes); + if( sqlite3StrAccumEnlargeIfNeeded(pAccum, nCopyBytes) ){ + break; } - if( pAccum->accError ) break; sqlite3_str_append(pAccum, &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes); precision -= nPrior; @@ -32745,20 +33603,97 @@ SQLITE_API void sqlite3_str_vappendf( while( precision-- > 0 && z[0] ){ SQLITE_SKIP_UTF8(z); } - length = (int)(z - (unsigned char*)bufpt); + length = z - (unsigned char*)bufpt; }else{ for(length=0; length0 ){ /* Adjust width to account for extra bytes in UTF-8 characters */ - int ii = length - 1; + i64 ii = length - 1; while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; } break; + case etESCAPE_j: /* %j: JSON string literal w/o "..." */ + case etESCAPE_J: { /* %J: Generate a JSON string literal */ + char *escarg; + i64 i, j, px, iStart; + unsigned char ch; + + if( bArgList ){ + escarg = getTextArg(pArgList); + }else{ + escarg = va_arg(ap,char*); + } + iStart = sqlite3_str_length(pAccum); + if( escarg==0 ){ + if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "null", 4); + }else{ + if( xtype==etESCAPE_J ) sqlite3_str_append(pAccum, "\"", 1); + px = precision; + testcase( px==0 ); + if( px<0 ){ + px = 0x7fffffff; + }else if( flag_altform2 ){ + /* Convert precision from code-points to bytes */ + for(i=0; i0x1f ){ + sqlite3_str_appendchar(pAccum, 1, ch); + }else if( ((1u<>4]); + sqlite3_str_appendchar(pAccum, 1, aHex[ch&0xf]); + } + } + } + if( j0 && sqlite3_str_errcode(pAccum)==SQLITE_OK ){ + sqlite3_int64 n = sqlite3_str_length(pAccum) - iStart; + sqlite3_int64 len = n; + char *zz; + if( flag_altform2 && n>0 ){ + zz = sqlite3_str_value(pAccum); + for(i=iStart; zz[i]; i++){ + if( (zz[i]&0xc0)==0x80 ) len--; + } + } + if( width>len ){ + sqlite3_int64 sp = width-len; + assert( sp>0 && sp<0x7fffffff ); + sqlite3StrAppendchar64(pAccum, (int)sp, ' '); + if( !flag_leftjustify + && n>0 + && sqlite3_str_errcode(pAccum)==0 + ){ + zz = sqlite3_str_value(pAccum); + zz += iStart; + memmove(zz+sp, zz, n); + memset(zz, ' ', sp); + } + } + } + continue; + } case etESCAPE_q: /* %q: Escape ' characters */ case etESCAPE_Q: /* %Q: Escape ' and enclose in '...' */ case etESCAPE_w: { /* %w: Escape " characters */ @@ -32801,8 +33736,8 @@ SQLITE_API void sqlite3_str_vappendf( ** 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; + i64 nBack = 0; + i64 nCtrl = 0; for(k=0; k=0x10 ? '1' : '0'; - bufpt[j++] = "0123456789abcdef"[ch&0xf]; + bufpt[j++] = aHex[ch&0xf]; } } }else{ @@ -32937,11 +33872,11 @@ SQLITE_API void sqlite3_str_vappendf( */ width -= length; if( width>0 ){ - if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); - sqlite3_str_append(pAccum, bufpt, length); - if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); + if( !flag_leftjustify ) sqlite3StrAppendchar64(pAccum, width, ' '); + sqlite3StrAppend64(pAccum, bufpt, length); + if( flag_leftjustify ) sqlite3StrAppendchar64(pAccum, width, ' '); }else{ - sqlite3_str_append(pAccum, bufpt, length); + sqlite3StrAppend64(pAccum, bufpt, length); } if( zExtra ){ @@ -32980,10 +33915,13 @@ SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3 *db, const char *z){ ** as the error offset. */ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){ - while( pExpr - && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0) - ){ - pExpr = pExpr->pLeft; + while( pExpr ){ + if( ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ) return; + if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0 ){ + pExpr = pExpr->pLeft; + }else{ + break; + } } if( pExpr==0 ) return; if( ExprHasProperty(pExpr, EP_FromDDL) ) return; @@ -33044,6 +33982,13 @@ SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, i64 N){ return (int)N; } +SQLITE_PRIVATE int sqlite3StrAccumEnlargeIfNeeded(StrAccum *p, i64 N){ + if( N + p->nChar >= p->nAlloc ){ + sqlite3StrAccumEnlarge(p, N); + } + return p->accError; +} + /* ** Append N copies of character c to the given string buffer. */ @@ -33054,6 +33999,13 @@ SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){ } while( (N--)>0 ) p->zText[p->nChar++] = c; } +static void sqlite3StrAppendchar64(sqlite3_str *p, i64 N, char c){ + testcase( p->nChar + N > 0x7fffffff ); + if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ + return; + } + while( (N--)>0 ) p->zText[p->nChar++] = c; +} /* ** The StrAccum "p" is not large enough to accept N new bytes of z[]. @@ -33065,6 +34017,7 @@ SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){ */ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ N = sqlite3StrAccumEnlarge(p, N); + assert( z!=0 || N==0 ); if( N>0 ){ memcpy(&p->zText[p->nChar], z, N); p->nChar += N; @@ -33088,6 +34041,20 @@ SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){ memcpy(&p->zText[p->nChar-N], z, N); } } +static void sqlite3StrAppend64(sqlite3_str *p, const char *z, i64 N){ + assert( z!=0 || N==0 ); + assert( p->zText!=0 || p->nChar==0 || p->accError ); + assert( N>=0 ); + assert( p->accError==0 || p->nAlloc==0 || p->mxAlloc==0 ); + if( p->nChar+N >= (i64)p->nAlloc ){ + enlargeAndAppend(p,z,N); + }else if( N ){ + assert( p->zText ); + p->nChar += N; + memcpy(&p->zText[p->nChar-N], z, N); + } +} + /* ** Append the complete text of zero-terminated string z[] to the p string. @@ -33125,37 +34092,11 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ return p->zText; } -/* -** Use the content of the StrAccum passed as the second argument -** as the result of an SQL function. -*/ -SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context *pCtx, StrAccum *p){ - if( p->accError ){ - sqlite3_result_error_code(pCtx, p->accError); - sqlite3_str_reset(p); - }else if( isMalloced(p) ){ - sqlite3_result_text(pCtx, p->zText, p->nChar, SQLITE_DYNAMIC); - }else{ - sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); - sqlite3_str_reset(p); - } -} - -/* -** This singleton is an sqlite3_str object that is returned if -** sqlite3_malloc() fails to provide space for a real one. This -** sqlite3_str object accepts no new text and always returns -** an SQLITE_NOMEM error. -*/ -static sqlite3_str sqlite3OomStr = { - 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 -}; - /* Finalize a string created using sqlite3_str_new(). */ SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){ char *z; - if( p!=0 && p!=&sqlite3OomStr ){ + if( p!=0 && p!=(sqlite3_str*)&sqlite3OomStr ){ z = sqlite3StrAccumFinish(p); sqlite3_free(p); }else{ @@ -33174,6 +34115,14 @@ SQLITE_API int sqlite3_str_length(sqlite3_str *p){ return p ? p->nChar : 0; } +/* Truncate the text of the string to be no more than N bytes. */ +SQLITE_API void sqlite3_str_truncate(sqlite3_str *p, int N){ + if( p!=0 && N>=0 && (u32)NnChar ){ + p->nChar = N; + p->zText[p->nChar] = 0; + } +} + /* Return the current value for p */ SQLITE_API char *sqlite3_str_value(sqlite3_str *p){ if( p==0 || p->nChar==0 ) return 0; @@ -33188,12 +34137,25 @@ SQLITE_API void sqlite3_str_reset(StrAccum *p){ if( isMalloced(p) ){ sqlite3DbFree(p->db, p->zText); p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; + }else if( p==(sqlite3_str*)&sqlite3OomStr ){ + return; } p->nAlloc = 0; p->nChar = 0; p->zText = 0; } +/* +** Destroy a dynamically allocate sqlite3_str object and all +** of its content, all in one call. +*/ +SQLITE_API void sqlite3_str_free(sqlite3_str *p){ + if( p!=0 && p!=(sqlite3_str*)&sqlite3OomStr ){ + sqlite3_str_reset(p); + sqlite3_free(p); + } +} + /* ** Initialize a string accumulator. ** @@ -33225,7 +34187,7 @@ SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3 *db){ sqlite3StrAccumInit(p, 0, 0, 0, db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH); }else{ - p = &sqlite3OomStr; + p = (sqlite3_str*)&sqlite3OomStr; } return p; } @@ -34118,6 +35080,10 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); break; } + case TK_ASTERISK: { + sqlite3TreeViewLine(pView,"ASKTERISK"); + break; + } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ @@ -34807,7 +35773,13 @@ SQLITE_PRIVATE void sqlite3TreeViewTrigger( SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); } -SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); } +SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ + TreeView *pView = 0; + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, "SRCLIST"); + sqlite3TreeViewSrcList(pView,p); + sqlite3TreeViewPop(&pView); +} SQLITE_PRIVATE void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); } SQLITE_PRIVATE void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); } SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); } @@ -35188,6 +36160,7 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ rc = sqlite3Win32Wait((HANDLE)p->tid); assert( rc!=WAIT_IO_COMPLETION ); bRc = CloseHandle((HANDLE)p->tid); + (void)bRc; /* Prevent warning when assert() is a no-op */ assert( bRc ); } if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; @@ -35437,9 +36410,7 @@ SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ while( zIn=0xD800 && i<=0xDFFF ) t = 0xFFFD; - if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; assert( c==t ); assert( (z-zBuf)==n ); } @@ -35888,8 +36856,15 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ /* #include */ #ifndef SQLITE_OMIT_FLOATING_POINT #include + +/* Work around a bug in older Microsoft compilers +** Forum post 2026-04-10T06:33:11z */ +#if !defined(INFINITY) && defined(_MSC_VER) +# define INFINITY HUGE_VAL #endif +#endif /* SQLITE_OMIT_FLOATING_POINT */ + /* ** Calls to sqlite3FaultSim() are used to simulate a failure during testing, ** or to bypass normal error detection during testing in order to let @@ -36327,266 +37302,618 @@ SQLITE_PRIVATE u8 sqlite3StrIHash(const char *z){ return h; } -/* Double-Double multiplication. (x[0],x[1]) *= (y,yy) -** -** Reference: -** T. J. Dekker, "A Floating-Point Technique for Extending the -** Available Precision". 1971-07-26. +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && (defined(__GNUC__) || defined(__clang__)) \ + && (defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && defined(__riscv_xlen) && (__riscv_xlen>32))) +#define SQLITE_USE_UINT128 +#endif + +/* +** Two inputs are multiplied to get a 128-bit result. Write the +** lower 64-bits of the result into *pLo, and return the high-order +** 64 bits. */ -static void dekkerMul2(volatile double *x, double y, double yy){ - /* - ** The "volatile" keywords on parameter x[] and on local variables - ** below are needed force intermediate results to be truncated to - ** binary64 rather than be carried around in an extended-precision - ** format. The truncation is necessary for the Dekker algorithm to - ** work. Intel x86 floating point might omit the truncation without - ** the use of volatile. - */ - volatile double tx, ty, p, q, c, cc; - double hx, hy; - u64 m; - memcpy(&m, (void*)&x[0], 8); - m &= 0xfffffffffc000000LL; - memcpy(&hx, &m, 8); - tx = x[0] - hx; - memcpy(&m, &y, 8); - m &= 0xfffffffffc000000LL; - memcpy(&hy, &m, 8); - ty = y - hy; - p = hx*hy; - q = hx*ty + tx*hy; - c = p+q; - cc = p - c + q + tx*ty; - cc = x[0]*yy + x[1]*y + cc; - x[0] = c + cc; - x[1] = c - x[0]; - x[1] += cc; +static u64 sqlite3Multiply128(u64 a, u64 b, u64 *pLo){ +#if defined(SQLITE_USE_UINT128) + __uint128_t r = (__uint128_t)a * b; + *pLo = (u64)r; + return (u64)(r>>64); +#elif defined(_WIN64) && !defined(SQLITE_DISABLE_INTRINSIC) + *pLo = a*b; + return __umulh(a, b); +#else + u64 a0 = (u32)a; + u64 a1 = a >> 32; + u64 b0 = (u32)b; + u64 b1 = b >> 32; + u64 a0b0 = a0 * b0; + u64 a1b1 = a1 * b1; + u64 a0b1 = a0 * b1; + u64 a1b0 = a1 * b0; + u64 t = (a0b0 >> 32) + (u32)a0b1 + (u32)a1b0; + *pLo = (a0b0 & UINT64_C(0xffffffff)) | (t << 32); + return a1b1 + (a0b1>>32) + (a1b0>>32) + (t>>32); +#endif +} + +/* +** A is an unsigned 96-bit integer formed by (a<<32)+aLo. +** B is an unsigned 64-bit integer. +** +** Compute the upper 96 bits of 160-bit result of A*B. +** +** Write ((A*B)>>64 & 0xffffffff) (the middle 32 bits of A*B) +** into *pLo. Return the upper 64 bits of A*B. +** +** The lower 64 bits of A*B are discarded. +*/ +static u64 sqlite3Multiply160(u64 a, u32 aLo, u64 b, u32 *pLo){ +#if defined(SQLITE_USE_UINT128) + __uint128_t r = (__uint128_t)a * b; + r += ((__uint128_t)aLo * b) >> 32; + *pLo = (r>>32)&0xffffffff; + return r>>64; +#elif defined(_WIN64) && !defined(SQLITE_DISABLE_INTRINSIC) + u64 r1_hi = __umulh(a,b); + u64 r1_lo = a*b; + u64 r2 = (__umulh((u64)aLo,b)<<32) + ((aLo*b)>>32); + u64 t = r1_lo + r2; + if( t>32; + return r1_hi; +#else + u64 x2 = a>>32; + u64 x1 = a&0xffffffff; + u64 x0 = aLo; + u64 y1 = b>>32; + u64 y0 = b&0xffffffff; + u64 x2y1 = x2*y1; + u64 r4 = x2y1>>32; + u64 x2y0 = x2*y0; + u64 x1y1 = x1*y1; + u64 r3 = (x2y1 & 0xffffffff) + (x2y0 >>32) + (x1y1 >>32); + u64 x1y0 = x1*y0; + u64 x0y1 = x0*y1; + u64 r2 = (x2y0 & 0xffffffff) + (x1y1 & 0xffffffff) + + (x1y0 >>32) + (x0y1>>32); + u64 x0y0 = x0*y0; + u64 r1 = (x1y0 & 0xffffffff) + (x0y1 & 0xffffffff) + + (x0y0 >>32); + r2 += r1>>32; + r3 += r2>>32; + *pLo = r2&0xffffffff; + return (r4<<32) + r3; +#endif } +#undef SQLITE_USE_UINT128 + /* -** The string z[] is an text representation of a real number. -** Convert this string to a double and write it into *pResult. +** Return a u64 with the N-th bit set. +*/ +#define U64_BIT(N) (((u64)1)<<(N)) + +/* +** Range of powers of 10 that we need to deal with when converting +** IEEE754 doubles to and from decimal. +*/ +#define POWERSOF10_FIRST (-348) +#define POWERSOF10_LAST (+347) + +/* +** For any p between -348 and +347, return the integer part of ** -** The string z[] is length bytes in length (bytes, not characters) and -** uses the encoding enc. The string is not necessarily zero-terminated. +** pow(10,p) * pow(2,63-pow10to2(p)) ** -** Return TRUE if the result is a valid real number (or integer) and FALSE -** if the string is empty or contains extraneous text. More specifically -** return -** 1 => The input string is a pure integer -** 2 or more => The input has a decimal point or eNNN clause -** 0 or less => The input string is not a valid number -** -1 => Not a valid number, but has a valid prefix which -** includes a decimal point and/or an eNNN clause +** Or, in other words, for any p in range, return the most significant +** 64 bits of pow(10,p). The pow(10,p) value is shifted left or right, +** as appropriate so the most significant 64 bits fit exactly into a +** 64-bit unsigned integer. ** -** Valid numbers are in one of these formats: +** Write into *pLo the next 32 significant bits of the answer after +** the first 64. ** -** [+-]digits[E[+-]digits] -** [+-]digits.[digits][E[+-]digits] -** [+-].digits[E[+-]digits] +** Algorithm: ** -** Leading and trailing whitespace is ignored for the purpose of determining -** validity. +** (1) For p between 0 and 26, return the value directly from the aBase[] +** lookup table. +** +** (2) For p outside the range 0 to 26, use aScale[] for the initial value +** then refine that result (if necessary) by a single multiplication +** against aBase[]. +** +** The constant tables aBase[], aScale[], and aScaleLo[] are generated +** by the C program at ../tool/mkfptab.c run with the --round option. +*/ +static u64 powerOfTen(int p, u32 *pLo){ + static const u64 aBase[] = { + UINT64_C(0x8000000000000000), /* 0: 1.0e+0 << 63 */ + UINT64_C(0xa000000000000000), /* 1: 1.0e+1 << 60 */ + UINT64_C(0xc800000000000000), /* 2: 1.0e+2 << 57 */ + UINT64_C(0xfa00000000000000), /* 3: 1.0e+3 << 54 */ + UINT64_C(0x9c40000000000000), /* 4: 1.0e+4 << 50 */ + UINT64_C(0xc350000000000000), /* 5: 1.0e+5 << 47 */ + UINT64_C(0xf424000000000000), /* 6: 1.0e+6 << 44 */ + UINT64_C(0x9896800000000000), /* 7: 1.0e+7 << 40 */ + UINT64_C(0xbebc200000000000), /* 8: 1.0e+8 << 37 */ + UINT64_C(0xee6b280000000000), /* 9: 1.0e+9 << 34 */ + UINT64_C(0x9502f90000000000), /* 10: 1.0e+10 << 30 */ + UINT64_C(0xba43b74000000000), /* 11: 1.0e+11 << 27 */ + UINT64_C(0xe8d4a51000000000), /* 12: 1.0e+12 << 24 */ + UINT64_C(0x9184e72a00000000), /* 13: 1.0e+13 << 20 */ + UINT64_C(0xb5e620f480000000), /* 14: 1.0e+14 << 17 */ + UINT64_C(0xe35fa931a0000000), /* 15: 1.0e+15 << 14 */ + UINT64_C(0x8e1bc9bf04000000), /* 16: 1.0e+16 << 10 */ + UINT64_C(0xb1a2bc2ec5000000), /* 17: 1.0e+17 << 7 */ + UINT64_C(0xde0b6b3a76400000), /* 18: 1.0e+18 << 4 */ + UINT64_C(0x8ac7230489e80000), /* 19: 1.0e+19 >> 0 */ + UINT64_C(0xad78ebc5ac620000), /* 20: 1.0e+20 >> 3 */ + UINT64_C(0xd8d726b7177a8000), /* 21: 1.0e+21 >> 6 */ + UINT64_C(0x878678326eac9000), /* 22: 1.0e+22 >> 10 */ + UINT64_C(0xa968163f0a57b400), /* 23: 1.0e+23 >> 13 */ + UINT64_C(0xd3c21bcecceda100), /* 24: 1.0e+24 >> 16 */ + UINT64_C(0x84595161401484a0), /* 25: 1.0e+25 >> 20 */ + UINT64_C(0xa56fa5b99019a5c8), /* 26: 1.0e+26 >> 23 */ + }; + static const u64 aScale[] = { + UINT64_C(0x8049a4ac0c5811ae), /* 0: 1.0e-351 << 1229 */ + UINT64_C(0xcf42894a5dce35ea), /* 1: 1.0e-324 << 1140 */ + UINT64_C(0xa76c582338ed2621), /* 2: 1.0e-297 << 1050 */ + UINT64_C(0x873e4f75e2224e68), /* 3: 1.0e-270 << 960 */ + UINT64_C(0xda7f5bf590966848), /* 4: 1.0e-243 << 871 */ + UINT64_C(0xb080392cc4349dec), /* 5: 1.0e-216 << 781 */ + UINT64_C(0x8e938662882af53e), /* 6: 1.0e-189 << 691 */ + UINT64_C(0xe65829b3046b0afa), /* 7: 1.0e-162 << 602 */ + UINT64_C(0xba121a4650e4ddeb), /* 8: 1.0e-135 << 512 */ + UINT64_C(0x964e858c91ba2655), /* 9: 1.0e-108 << 422 */ + UINT64_C(0xf2d56790ab41c2a2), /* 10: 1.0e-81 << 333 */ + UINT64_C(0xc428d05aa4751e4c), /* 11: 1.0e-54 << 243 */ + UINT64_C(0x9e74d1b791e07e48), /* 12: 1.0e-27 << 153 */ + UINT64_C(0xcccccccccccccccc), /* 13: 1.0e-1 << 67 (special case) */ + UINT64_C(0xcecb8f27f4200f3a), /* 14: 1.0e+27 >> 26 */ + UINT64_C(0xa70c3c40a64e6c51), /* 15: 1.0e+54 >> 116 */ + UINT64_C(0x86f0ac99b4e8dafd), /* 16: 1.0e+81 >> 206 */ + UINT64_C(0xda01ee641a708de9), /* 17: 1.0e+108 >> 295 */ + UINT64_C(0xb01ae745b101e9e4), /* 18: 1.0e+135 >> 385 */ + UINT64_C(0x8e41ade9fbebc27d), /* 19: 1.0e+162 >> 475 */ + UINT64_C(0xe5d3ef282a242e81), /* 20: 1.0e+189 >> 564 */ + UINT64_C(0xb9a74a0637ce2ee1), /* 21: 1.0e+216 >> 654 */ + UINT64_C(0x95f83d0a1fb69cd9), /* 22: 1.0e+243 >> 744 */ + UINT64_C(0xf24a01a73cf2dccf), /* 23: 1.0e+270 >> 833 */ + UINT64_C(0xc3b8358109e84f07), /* 24: 1.0e+297 >> 923 */ + UINT64_C(0x9e19db92b4e31ba9), /* 25: 1.0e+324 >> 1013 */ + }; + static const unsigned int aScaleLo[] = { + 0x205b896d, /* 0: 1.0e-351 << 1229 */ + 0x52064cad, /* 1: 1.0e-324 << 1140 */ + 0xaf2af2b8, /* 2: 1.0e-297 << 1050 */ + 0x5a7744a7, /* 3: 1.0e-270 << 960 */ + 0xaf39a475, /* 4: 1.0e-243 << 871 */ + 0xbd8d794e, /* 5: 1.0e-216 << 781 */ + 0x547eb47b, /* 6: 1.0e-189 << 691 */ + 0x0cb4a5a3, /* 7: 1.0e-162 << 602 */ + 0x92f34d62, /* 8: 1.0e-135 << 512 */ + 0x3a6a07f9, /* 9: 1.0e-108 << 422 */ + 0xfae27299, /* 10: 1.0e-81 << 333 */ + 0xaa97e14c, /* 11: 1.0e-54 << 243 */ + 0x775ea265, /* 12: 1.0e-27 << 153 */ + 0xcccccccc, /* 13: 1.0e-1 << 67 (special case) */ + 0x00000000, /* 14: 1.0e+27 >> 26 */ + 0x999090b6, /* 15: 1.0e+54 >> 116 */ + 0x69a028bb, /* 16: 1.0e+81 >> 206 */ + 0xe80e6f48, /* 17: 1.0e+108 >> 295 */ + 0x5ec05dd0, /* 18: 1.0e+135 >> 385 */ + 0x14588f14, /* 19: 1.0e+162 >> 475 */ + 0x8f1668c9, /* 20: 1.0e+189 >> 564 */ + 0x6d953e2c, /* 21: 1.0e+216 >> 654 */ + 0x4abdaf10, /* 22: 1.0e+243 >> 744 */ + 0xbc633b39, /* 23: 1.0e+270 >> 833 */ + 0x0a862f81, /* 24: 1.0e+297 >> 923 */ + 0x6c07a2c2, /* 25: 1.0e+324 >> 1013 */ + }; + int g, n; + u64 s, x; + u32 lo; + + assert( p>=POWERSOF10_FIRST && p<=POWERSOF10_LAST ); + if( p<0 ){ + if( p==(-1) ){ + *pLo = aScaleLo[13]; + return aScale[13]; + } + g = p/27; + n = p%27; + if( n ){ + g--; + n += 27; + } + }else if( p<27 ){ + *pLo = 0; + return aBase[p]; + }else{ + g = p/27; + n = p%27; + } + s = aScale[g+13]; + if( n==0 ){ + *pLo = aScaleLo[g+13]; + return s; + } + x = sqlite3Multiply160(s,aScaleLo[g+13],aBase[n],&lo); + if( (U64_BIT(63) & x)==0 ){ + x = x<<1 | ((lo>>31)&1); + lo = (lo<<1) | 1; + } + *pLo = lo; + return x; +} + +/* +** pow10to2(x) computes floor(log2(pow(10,x))). +** pow2to10(y) computes floor(log10(pow(2,y))). ** -** If some prefix of the input string is a valid number, this routine -** returns FALSE but it still converts the prefix and writes the result -** into *pResult. +** Conceptually, pow10to2(p) converts a base-10 exponent p into +** a corresponding base-2 exponent, and pow2to10(e) converts a base-2 +** exponent into a base-10 exponent. +** +** The conversions are based on the observation that: +** +** ln(10.0)/ln(2.0) == 108853/32768 (approximately) +** ln(2.0)/ln(10.0) == 78913/262144 (approximately) +** +** These ratios are approximate, but they are accurate to 5 digits, +** which is close enough for the usage here. Right-shift is used +** for division so that rounding of negative numbers happens in the +** right direction. */ -#if defined(_MSC_VER) -#pragma warning(disable : 4756) -#endif -SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ -#ifndef SQLITE_OMIT_FLOATING_POINT - int incr; - const char *zEnd; - /* sign * significand * (10 ^ (esign * exponent)) */ - int sign = 1; /* sign of significand */ - u64 s = 0; /* significand */ - int d = 0; /* adjust exponent for shifting decimal point */ - int esign = 1; /* sign of exponent */ - int e = 0; /* exponent */ - int eValid = 1; /* True exponent is either not used or is well-formed */ - int nDigit = 0; /* Number of digits processed */ - int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ - u64 s2; /* round-tripped significand */ - double rr[2]; +static int pwr10to2(int p){ return (p*108853) >> 15; } +static int pwr2to10(int p){ return (p*78913) >> 18; } - assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); - *pResult = 0.0; /* Default return value, in case of an error */ - if( length==0 ) return 0; +/* +** Count leading zeros for a 64-bit unsigned integer. +*/ +static int countLeadingZeros(u64 m){ +#if (defined(__GNUC__) || defined(__clang__)) \ + && !defined(SQLITE_DISABLE_INTRINSIC) + return __builtin_clzll(m); +#else + int n = 0; + if( m <= 0x00000000ffffffffULL) { n += 32; m <<= 32; } + if( m <= 0x0000ffffffffffffULL) { n += 16; m <<= 16; } + if( m <= 0x00ffffffffffffffULL) { n += 8; m <<= 8; } + if( m <= 0x0fffffffffffffffULL) { n += 4; m <<= 4; } + if( m <= 0x3fffffffffffffffULL) { n += 2; m <<= 2; } + if( m <= 0x7fffffffffffffffULL) { n += 1; } + return n; +#endif +} - if( enc==SQLITE_UTF8 ){ - incr = 1; - zEnd = z + length; +/* +** Given m and e, which represent a quantity r == m*pow(2,e), +** return values *pD and *pP such that r == (*pD)*pow(10,*pP), +** approximately. *pD should contain at least n significant digits. +** +** The input m is required to have its highest bit set. In other words, +** m should be left-shifted, and e decremented, to maximize the value of m. +*/ +static void sqlite3Fp2Convert10(u64 m, int e, int n, u64 *pD, int *pP){ + int p; + u64 h, d1; + u32 d2; + assert( n>=1 && n<=18 ); + p = n - 1 - pwr2to10(e+63); + h = sqlite3Multiply128(m, powerOfTen(p,&d2), &d1); + assert( -(e + pwr10to2(p) + 2) >= 0 ); + assert( -(e + pwr10to2(p) + 1) <= 63 ); + if( n==18 ){ + h >>= -(e + pwr10to2(p) + 2); + *pD = (h + ((h<<1)&2))>>1; }else{ - int i; - incr = 2; - length &= ~1; - assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); - testcase( enc==SQLITE_UTF16LE ); - testcase( enc==SQLITE_UTF16BE ); - for(i=3-enc; i> -(e + pwr10to2(p) + 1); } + *pP = -p; +} - /* skip leading spaces */ - while( z=zEnd ) return 0; - - /* get sign of significand */ - if( *z=='-' ){ - sign = -1; - z+=incr; - }else if( *z=='+' ){ - z+=incr; - } +/* +** Return an IEEE754 floating point value that approximates d*pow(10,p). +** +** The (current) algorithm is adapted from the work of Ross Cox at +** https://github.com/rsc/fpfmt +*/ +static double sqlite3Fp10Convert2(u64 d, int p){ + int b, lp, e, adj, s; + u32 pwr10l, mid1; + u64 pwr10h, x, hi, lo, sticky, u, m; + double r; + if( pPOWERSOF10_LAST ) return (double)INFINITY; + b = 64 - countLeadingZeros(d); + lp = pwr10to2(p); + e = 53 - b - lp; + if( e > 1074 ){ + if( e>=1130 ) return 0.0; + e = 1074; + } + s = -(e-(64-b) + lp + 3); + pwr10h = powerOfTen(p, &pwr10l); + if( pwr10l!=0 ){ + pwr10h++; + pwr10l = ~pwr10l; + } + x = d<<(64-b); + hi = sqlite3Multiply128(x,pwr10h,&lo); + mid1 = lo>>32; + sticky = 1; + if( (hi & (U64_BIT(s)-1))==0 ) { + u32 mid2 = sqlite3Multiply128(x,((u64)pwr10l)<<32,&lo)>>32; + sticky = (mid1-mid2 > 1); + hi -= mid1 < mid2; + } + u = (hi>>s) | sticky; + adj = (u >= U64_BIT(55)-2); + if( adj ){ + u = (u>>adj) | (u&1); + e -= adj; + } + m = (u + 1 + ((u>>2)&1)) >> 2; + if( e<=(-972) ) return (double)INFINITY; + if((m & U64_BIT(52)) != 0){ + m = (m & ~U64_BIT(52)) | ((u64)(1075-e)<<52); + } + memcpy(&r,&m,8); + return r; +} - /* copy max significant digits to significand */ - while( z=((LARGEST_UINT64-9)/10) ){ - /* skip non-significant significand digits - ** (increase exponent by d to shift decimal left) */ - while( z Set if any prefix of the input is valid. Clear if +** there is no prefix of the input that can be seen as +** a valid floating point number. +** bit 1 => Set if the input contains a decimal point or eNNN +** clause. Zero if the input is an integer. +** bit 2 => The input is exactly 0.0, not an underflow from +** some value near zero. +** bit 3 => Set if there are more than about 19 significant +** digits in the input. +** +** If the input contains a syntax error but begins with text that might +** be a valid number of some kind, then the result is negative. The +** result is only zero if no prefix of the input could be interpreted as +** a number. +** +** Leading and trailing whitespace is ignored. Valid numbers are in +** one of the formats below: +** +** [+-]digits[E[+-]digits] +** [+-]digits.[digits][E[+-]digits] +** [+-].digits[E[+-]digits] +** +** Algorithm sketch: Compute an unsigned 64-bit integer s and a base-10 +** exponent d such that the value encoding by the input is s*pow(10,d). +** Then invoke sqlite3Fp10Convert2() to calculated the closest possible +** IEEE754 double. The sign is added back afterwards, if the input string +** starts with a "-". The use of an unsigned 64-bit s mantissa means that +** only about the first 19 significant digits of the input can contribute +** to the result. This can result in suboptimal rounding decisions when +** correct rounding requires more than 19 input digits. For example, +** this routine renders "3500000000000000.2500001" as +** 3500000000000000.0 instead of 3500000000000000.5 because the decision +** to round up instead of using banker's rounding to round down is determined +** by the 23rd significant digit, which this routine ignores. It is not +** possible to do better without some kind of BigNum. +*/ +SQLITE_PRIVATE int sqlite3AtoF(const char *zIn, double *pResult){ +#ifndef SQLITE_OMIT_FLOATING_POINT + const unsigned char *z = (const unsigned char*)zIn; + int neg = 0; /* True for a negative value */ + u64 s = 0; /* mantissa */ + int d = 0; /* Value is s * pow(10,d) */ + int mState = 0; /* 1: digit seen 2: fp 4: hard-zero */ + unsigned v; /* Value of a single digit */ + + start_of_text: + if( (v = (unsigned)z[0] - '0')<10 ){ + parse_integer_part: + mState = 1; + s = v; + z++; + while( (v = (unsigned)z[0] - '0')<10 ){ + s = s*10 + v; + z++; + if( s>=(LARGEST_UINT64-9)/10 ){ + mState = 9; + while( sqlite3Isdigit(z[0]) ){ z++; d++; } + break; + } } + }else if( z[0]=='-' ){ + neg = 1; + z++; + if( (v = (unsigned)z[0] - '0')<10 ) goto parse_integer_part; + }else if( z[0]=='+' ){ + z++; + if( (v = (unsigned)z[0] - '0')<10 ) goto parse_integer_part; + }else if( sqlite3Isspace(z[0]) ){ + do{ z++; }while( sqlite3Isspace(z[0]) ); + goto start_of_text; + }else{ + s = 0; } - if( z>=zEnd ) goto do_atof_calc; /* if decimal point is present */ if( *z=='.' ){ - z+=incr; - eType++; - /* copy digits from after decimal to significand - ** (decrease exponent by d to shift decimal right) */ - while( z=zEnd ) goto do_atof_calc; /* if exponent is present */ if( *z=='e' || *z=='E' ){ - z+=incr; - eValid = 0; - eType++; - - /* This branch is needed to avoid a (harmless) buffer overread. The - ** special comment alerts the mutation tester that the correct answer - ** is obtained even if the branch is omitted */ - if( z>=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/ + int esign; + z++; /* get sign of exponent */ if( *z=='-' ){ esign = -1; - z+=incr; - }else if( *z=='+' ){ - z+=incr; + z++; + }else{ + esign = +1; + if( *z=='+' ){ + z++; + } } /* copy digits to exponent */ - while( z0 && s<((LARGEST_UINT64-0x7ff)/10) ){ - s *= 10; - e--; - } - while( e<0 && (s%10)==0 ){ - s /= 10; - e++; - } - - rr[0] = (double)s; - assert( sizeof(s2)==sizeof(rr[0]) ); -#ifdef SQLITE_DEBUG - rr[1] = 18446744073709549568.0; - memcpy(&s2, &rr[1], sizeof(s2)); - assert( s2==0x43efffffffffffffLL ); -#endif - /* Largest double that can be safely converted to u64 - ** vvvvvvvvvvvvvvvvvvvvvv */ - if( rr[0]<=18446744073709549568.0 ){ - s2 = (u64)rr[0]; - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + *pResult = 0.0; + mState |= 4; }else{ - rr[1] = 0.0; + *pResult = sqlite3Fp10Convert2(s,d); } - assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */ - - if( e>0 ){ - while( e>=100 ){ - e -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( e>=10 ){ - e -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( e>=1 ){ - e -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } - }else{ - while( e<=-100 ){ - e += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( e<=-10 ){ - e += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( e<=-1 ){ - e += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } - } - *pResult = rr[0]+rr[1]; - if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; - if( sign<0 ) *pResult = -*pResult; + if( neg ) *pResult = -*pResult; assert( !sqlite3IsNaN(*pResult) ); -atof_return: /* return true if number and no extra non-whitespace characters after */ - if( z==zEnd && nDigit>0 && eValid && eType>0 ){ - return eType; - }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){ - return -1; - }else{ - return 0; + if( z[0]==0 ){ + return mState; } + if( sqlite3Isspace(z[0]) ){ + do{ z++; }while( sqlite3Isspace(*z) ); + if( z[0]==0 ){ + return mState; + } + } + return 0xfffffff0 | mState; #else - return !sqlite3Atoi64(z, pResult, length, enc); + return sqlite3Atoi64(zIn, pResult, strlen(zIn), SQLITE_UTF8)==0; #endif /* SQLITE_OMIT_FLOATING_POINT */ } -#if defined(_MSC_VER) -#pragma warning(default : 4756) + +/* +** Digit pairs used to convert a U64 or I64 into text, two digits +** at a time. +*/ +static const union { + char a[201]; + short int forceAlignment; +} sqlite3DigitPairs = { + "00010203040506070809" + "10111213141516171819" + "20212223242526272829" + "30313233343536373839" + "40414243444546474849" + "50515253545556575859" + "60616263646566676869" + "70717273747576777879" + "80818283848586878889" + "90919293949596979899" +}; + +/* +** ARMv6, ARMv7, PPC32 are known to not support hardware u64 division. +*/ +#if (defined(__arm__) && !defined(__aarch64__)) || \ + (defined(__ppc__) && !defined(__ppc64__)) +# define SQLITE_AVOID_U64_DIVIDE 1 #endif +#ifdef SQLITE_AVOID_U64_DIVIDE +/* +** Render an unsigned 64-bit integer as text onto the end of a 2-byte +** aligned buffer that is SQLITE_U64_DIGIT+1 bytes long. The last byte +** of the buffer will be filled with a \000 byte. +** +** Return the index into the buffer of the first byte. +** +** This routine is used on platforms where u64-division is slow because +** it is not available in hardware and has to be emulated in software. +** It seeks to minimize the number of u64 divisions and use u32 divisions +** instead. It is slower on platforms that have hardware u64 division, +** but much faster on platforms that do not. +*/ +static int sqlite3UInt64ToText(u64 v, char *zOut){ + u32 x32, kk; + int i; + zOut[SQLITE_U64_DIGITS] = 0; + i = SQLITE_U64_DIGITS; + assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[0]) ); + assert( TWO_BYTE_ALIGNMENT(zOut) ); + while( (v>>32)!=0 ){ + u32 y, x0, x1, y0, y1; + x32 = v % 100000000; + v = v / 100000000; + y = x32 % 10000; + x32 /= 10000; + x1 = x32 / 100; + x0 = x32 % 100; + y1 = y / 100; + y0 = y % 100; + assert( i>=8 ); + i -= 8; + *(u16*)(&zOut[i]) = *(u16*)&sqlite3DigitPairs.a[x1*2]; + *(u16*)(&zOut[i+2]) = *(u16*)&sqlite3DigitPairs.a[x0*2]; + *(u16*)(&zOut[i+4]) = *(u16*)&sqlite3DigitPairs.a[y1*2]; + *(u16*)(&zOut[i+6]) = *(u16*)&sqlite3DigitPairs.a[y0*2]; + } + x32 = v; + while( x32>=10 ){ + kk = x32 % 100; + x32 = x32 / 100; + assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk*2]) ); + assert( i>=2 ); + i -= 2; + assert( TWO_BYTE_ALIGNMENT(&zOut[i]) ); + *(u16*)(&zOut[i]) = *(u16*)&sqlite3DigitPairs.a[kk*2]; + } + if( x32 ){ + assert( i>0 ); + zOut[--i] = x32 + '0'; + } + return i; +} +#endif /* defined(SQLITE_AVOID_U64_DIVIDE) */ + /* ** Render an signed 64-bit integer as text. Store the result in zOut[] and ** return the length of the string that was stored, in bytes. The value @@ -36598,23 +37925,39 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en SQLITE_PRIVATE int sqlite3Int64ToText(i64 v, char *zOut){ int i; u64 x; - char zTemp[22]; - if( v<0 ){ - x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v; - }else{ + union { + char a[SQLITE_U64_DIGITS+1]; + u16 forceAlignment; + } u; + if( v>0 ){ x = v; + }else if( v==0 ){ + zOut[0] = '0'; + zOut[1] = 0; + return 1; + }else{ + x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v; } - i = sizeof(zTemp)-2; - zTemp[sizeof(zTemp)-1] = 0; - while( 1 /*exit-by-break*/ ){ - zTemp[i] = (x%10) + '0'; - x = x/10; - if( x==0 ) break; - i--; - }; - if( v<0 ) zTemp[--i] = '-'; - memcpy(zOut, &zTemp[i], sizeof(zTemp)-i); - return sizeof(zTemp)-1-i; +#ifdef SQLITE_AVOID_U64_DIVIDE + i = sqlite3UInt64ToText(x, u.a); +#else + i = sizeof(u.a)-1; + u.a[i] = 0; + while( x>=10 ){ + int kk = (x%100)*2; + assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk]) ); + assert( TWO_BYTE_ALIGNMENT(&u.a[i-2]) ); + *(u16*)(&u.a[i-2]) = *(u16*)&sqlite3DigitPairs.a[kk]; + i -= 2; + x /= 100; + } + if( x ){ + u.a[--i] = x + '0'; + } +#endif /* SQLITE_AVOID_U64_DIVIDE */ + if( v<0 ) u.a[--i] = '-'; + memcpy(zOut, &u.a[i], sizeof(u.a)-i); + return sizeof(u.a)-1-i; } /* @@ -36668,8 +38011,8 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc int incr; u64 u = 0; int neg = 0; /* assume positive */ - int i; - int c = 0; + int i, j; + unsigned int c = 0; int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ int rc; /* Baseline return code */ const char *zStart; @@ -36697,8 +38040,8 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc } zStart = zNum; while( zNum='0' && c<='9'; i+=incr){ - u = u*10 + c - '0'; + for(i=0; &zNum[i]19*incr ? 1 : compare2pow63(zNum, incr); - if( c<0 ){ + j = i>19*incr ? 1 : compare2pow63(zNum, incr); + if( j<0 ){ /* zNum is less than 9223372036854775808 so it fits */ assert( u<=LARGEST_INT64 ); return rc; }else{ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; - if( c>0 ){ + if( j>0 ){ /* zNum is greater than 9223372036854775808 so it overflows */ return 2; }else{ @@ -36871,7 +38214,7 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ ** representation. ** ** If iRound<=0 then round to -iRound significant digits to the -** the left of the decimal point, or to a maximum of mxRound total +** the right of the decimal point, or to a maximum of mxRound total ** significant digits. ** ** If iRound>0 round to min(iRound,mxRound) significant digits total. @@ -36884,13 +38227,14 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ ** The p->z[] array is *not* zero-terminated. */ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){ - int i; - u64 v; - int e, exp = 0; - double rr[2]; + int i; /* Index into zBuf[] where to put next character */ + int n; /* Number of digits */ + u64 v; /* mantissa */ + int e, exp = 0; /* Base-2 and base-10 exponent */ + char *zBuf; /* Local alias for p->zBuf */ + char *z; /* Local alias for p->z */ p->isSpecial = 0; - p->z = p->zBuf; assert( mxRound>0 ); /* Convert negative numbers to positive. Deal with Infinity, 0.0, and @@ -36908,78 +38252,100 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou p->sign = '+'; } memcpy(&v,&r,8); - e = v>>52; - if( (e&0x7ff)==0x7ff ){ + e = (v>>52)&0x7ff; + if( e==0x7ff ){ p->isSpecial = 1 + (v!=0x7ff0000000000000LL); p->n = 0; p->iDP = 0; + p->z = p->zBuf; return; } - - /* Multiply r by powers of ten until it lands somewhere in between - ** 1.0e+19 and 1.0e+17. - ** - ** Use Dekker-style double-double computation to increase the - ** precision. - ** - ** The error terms on constants like 1.0e+100 computed using the - ** decimal extension, for example as follows: - ** - ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); - */ - rr[0] = r; - rr[1] = 0.0; - if( rr[0]>9.223372036854774784e+18 ){ - while( rr[0]>9.223372036854774784e+118 ){ - exp += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( rr[0]>9.223372036854774784e+28 ){ - exp += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( rr[0]>9.223372036854774784e+18 ){ - exp += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } + v &= 0x000fffffffffffffULL; + if( e==0 ){ + int nn = countLeadingZeros(v); + v <<= nn; + e = -1074 - nn; }else{ - while( rr[0]<9.223372036854774784e-83 ){ - exp -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( rr[0]<9.223372036854774784e+07 ){ - exp -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( rr[0]<9.22337203685477478e+17 ){ - exp -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } + v = (v<<11) | U64_BIT(63); + e -= 1086; } - v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; + sqlite3Fp2Convert10(v, e, (iRound<=0||iRound>=18)?18:iRound+1, &v, &exp); - /* Extract significant digits. */ - i = sizeof(p->zBuf)-1; + /* Extract significant digits, start at the right-most slot in p->zBuf + ** and working back to the right. "i" keeps track of the next slot in + ** which to store a digit. */ + assert( sizeof(p->zBuf)==SQLITE_U64_DIGITS+1 ); assert( v>0 ); - while( v ){ p->zBuf[i--] = (v%10) + '0'; v /= 10; } - assert( i>=0 && izBuf)-1 ); - p->n = sizeof(p->zBuf) - 1 - i; - assert( p->n>0 ); - assert( p->nzBuf) ); - p->iDP = p->n + exp; + zBuf = p->zBuf; +#ifdef SQLITE_AVOID_U64_DIVIDE + i = sqlite3UInt64ToText(v, zBuf); +#else + i = SQLITE_U64_DIGITS; + while( v>=10 ){ + int kk = (v%100)*2; + assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk]) ); + assert( TWO_BYTE_ALIGNMENT(&zBuf[i]) ); + assert( i-2>=0 ); + *(u16*)(&zBuf[i-2]) = *(u16*)&sqlite3DigitPairs.a[kk]; + i -= 2; + v /= 100; + } + if( v ){ + assert( v<10 ); + assert( i>0 ); + zBuf[--i] = v + '0'; + } +#endif /* SQLITE_AVOID_U64_DIVIDE */ + assert( i>=0 && i0 ); + assert( n<=SQLITE_U64_DIGITS ); + p->iDP = n + exp; if( iRound<=0 ){ iRound = p->iDP - iRound; - if( iRound==0 && p->zBuf[i+1]>='5' ){ + if( iRound==0 && zBuf[i]>='5' ){ iRound = 1; - p->zBuf[i--] = '0'; - p->n++; + zBuf[--i] = '0'; + n++; p->iDP++; } } - if( iRound>0 && (iRoundn || p->n>mxRound) ){ - char *z = &p->zBuf[i+1]; + z = &zBuf[i]; /* z points to the first digit */ + if( iRound>0 && (iRoundmxRound) ){ if( iRound>mxRound ) iRound = mxRound; - p->n = iRound; + if( iRound==17 ){ + /* If the precision is exactly 17, which only happens with the "!" + ** flag (ex: "%!.17g") then try to reduce the precision if that + ** yields text that will round-trip to the original floating-point. + ** value. Thus, for exaple, 49.47 will render as 49.47, rather than + ** as 49.469999999999999. */ + if( z[15]=='9' && z[14]=='9' ){ + int jj, kk; + u64 v2; + for(jj=14; jj>0 && z[jj-1]=='9'; jj--){} + if( jj==0 ){ + v2 = 1; + }else{ + v2 = z[0] - '0'; + for(kk=1; kkiDP>=n || (z[15]=='0' && z[14]=='0' && z[13]=='0') ){ + int jj, kk; + u64 v2; + assert( z[0]!='0' ); + for(jj=13; z[jj-1]=='0'; jj--){} + v2 = z[0] - '0'; + for(kk=1; kk='5' ){ int j = iRound-1; while( 1 /*exit-by-break*/ ){ @@ -36987,8 +38353,9 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou if( z[j]<='9' ) break; z[j] = '0'; if( j==0 ){ - p->z[i--] = '1'; - p->n++; + z--; + z[0] = '1'; + n++; p->iDP++; break; }else{ @@ -36997,13 +38364,13 @@ 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) ); - assert( p->n>0 ); - while( p->z[p->n-1]=='0' ){ - p->n--; - assert( p->n>0 ); + assert( n>0 ); + while( z[n-1]=='0' ){ + n--; + assert( n>0 ); } + p->n = n; + p->z = z; } /* @@ -37017,7 +38384,7 @@ SQLITE_PRIVATE int sqlite3GetUInt32(const char *z, u32 *pI){ int i; for(i=0; sqlite3Isdigit(z[i]); i++){ v = v*10 + z[i] - '0'; - if( v>4294967296LL ){ *pI = 0; return 0; } + if( v>4294967295LL ){ *pI = 0; return 0; } } if( i==0 || z[i]!=0 ){ *pI = 0; return 0; } *pI = (u32)v; @@ -37090,171 +38457,83 @@ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ return putVarint64(p,v); } -/* -** Bitmasks used by sqlite3GetVarint(). These precomputed constants -** are defined here rather than simply putting the constant expressions -** inline in order to work around bugs in the RVT compiler. -** -** SLOT_2_0 A mask for (0x7f<<14) | 0x7f -** -** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 -*/ -#define SLOT_2_0 0x001fc07f -#define SLOT_4_2_0 0xf01fc07f - - /* ** Read a 64-bit variable-length integer from memory starting at p[0]. ** Return the number of bytes read. The value is stored in *v. */ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ - u32 a,b,s; - - if( ((signed char*)p)[0]>=0 ){ - *v = *p; - return 1; - } - if( ((signed char*)p)[1]>=0 ){ - *v = ((u32)(p[0]&0x7f)<<7) | p[1]; - return 2; - } - - /* Verify that constants are precomputed correctly */ - assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); - assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); - - a = ((u32)p[0])<<14; - b = p[1]; - p += 2; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - a &= SLOT_2_0; - b &= 0x7f; - b = b<<7; - a |= b; - *v = a; - return 3; - } - - /* CSE1 from below */ - a &= SLOT_2_0; - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - b &= SLOT_2_0; - /* moved CSE1 up */ - /* a &= (0x7f<<14)|(0x7f); */ - a = a<<7; - a |= b; - *v = a; - return 4; - } - - /* a: p0<<14 | p2 (masked) */ - /* b: p1<<14 | p3 (unmasked) */ - /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - /* moved CSE1 up */ - /* a &= (0x7f<<14)|(0x7f); */ - b &= SLOT_2_0; - s = a; - /* s: p0<<14 | p2 (masked) */ - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* we can skip these cause they were (effectively) done above - ** while calculating s */ - /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - /* b &= (0x7f<<14)|(0x7f); */ - b = b<<7; - a |= b; - s = s>>18; - *v = ((u64)s)<<32 | a; - return 5; - } - - /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - s = s<<7; - s |= b; - /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ - - p++; - b = b<<14; - b |= *p; - /* b: p1<<28 | p3<<14 | p5 (unmasked) */ - if (!(b&0x80)) - { - /* we can skip this cause it was (effectively) done above in calc'ing s */ - /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ - a &= SLOT_2_0; - a = a<<7; - a |= b; - s = s>>18; - *v = ((u64)s)<<32 | a; - return 6; - } - - p++; - a = a<<14; - a |= *p; - /* a: p2<<28 | p4<<14 | p6 (unmasked) */ - if (!(a&0x80)) - { - a &= SLOT_4_2_0; - b &= SLOT_2_0; - b = b<<7; - a |= b; - s = s>>11; - *v = ((u64)s)<<32 | a; - return 7; + u64 iKey = p[0]; + const u8 *pStart = p; + if( iKey>=0x80 ){ + u8 x; + iKey = (iKey<<7) ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<8) ^ 0x8000 ^ (*++p); + } + } + } + } + } + }else{ + iKey ^= 0x204000; + } + }else{ + iKey ^= 0x4000; + } } + *v = iKey; + return (u8)(p - pStart) + 1; +} - /* CSE2 from below */ - a &= SLOT_2_0; - p++; - b = b<<14; - b |= *p; - /* b: p3<<28 | p5<<14 | p7 (unmasked) */ - if (!(b&0x80)) - { - b &= SLOT_4_2_0; - /* moved CSE2 up */ - /* a &= (0x7f<<14)|(0x7f); */ - a = a<<7; - a |= b; - s = s>>4; - *v = ((u64)s)<<32 | a; - return 8; +/* +** Return the value of a variable-length integer without computing +** its length. This is an optimization on sqlite3GetVarint() for the +** cases when the return value of sqlite3GetVarint() is not needed. +*/ +SQLITE_PRIVATE i64 sqlite3VarintValue(const unsigned char *p){ + u64 iKey = p[0]; + if( iKey>=0x80 ){ + u8 x; + iKey = (iKey<<7) ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++p); + if( x>=0x80 ){ + iKey = (iKey<<8) ^ 0x8000 ^ (*++p); + } + } + } + } + } + }else{ + iKey ^= 0x204000; + } + }else{ + iKey ^= 0x4000; + } } - - p++; - a = a<<15; - a |= *p; - /* a: p4<<29 | p6<<15 | p8 (unmasked) */ - - /* moved CSE2 up */ - /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ - b &= SLOT_2_0; - b = b<<8; - a |= b; - - s = s<<4; - b = p[-4]; - b &= 0x7f; - b = b>>3; - s |= b; - - *v = ((u64)s)<<32 | a; - - return 9; + return *(i64*)&iKey; } /* @@ -37309,7 +38588,7 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v){ /* -** Read or write a four-byte big-endian integer value. +** Read an unsigned 32-bit integer from an unaligned big-endian array of bytes. */ SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){ #if SQLITE_BYTEORDER==4321 @@ -37325,10 +38604,14 @@ SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){ memcpy(&x,p,4); return _byteswap_ulong(x); #else + /* Test this limb using -DSQLITE_BYTEORDER=0 */ testcase( p[0]&0x80 ); return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; #endif } + +/* Write an unsigned 32-bit integer into an unaligned big-endian array of bytes. +*/ SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ #if SQLITE_BYTEORDER==4321 memcpy(p,&v,4); @@ -37339,6 +38622,7 @@ SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ u32 x = _byteswap_ulong(v); memcpy(p,&x,4); #else + /* Test this limb using -DSQLITE_BYTEORDER=0 */ p[0] = (u8)(v>>24); p[1] = (u8)(v>>16); p[2] = (u8)(v>>8); @@ -37346,7 +38630,58 @@ SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ #endif } +/* +** Read an unsigned 64-bit integer from an unaligned big-endian byte array. +*/ +SQLITE_PRIVATE SQLITE_OPT_INLINE u64 sqlite3Get8byte(const u8 *p){ +#if SQLITE_BYTEORDER==4321 + u64 x; + memcpy(&x,p,8); + return x; +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + u64 x; + memcpy(&x,p,8); + return __builtin_bswap64(x); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + u64 x; + memcpy(&x,p,8); + return _byteswap_uint64(x); +#else + /* Test this limb using -DSQLITE_BYTEORDER=0 */ + testcase( p[0]&0x80 ); + return (u64)( + (((u64)p[0]) << 56) + + (((u64)p[1]) << 48) + + (((u64)p[2]) << 40) + + (((u64)p[3]) << 32) + + (((u64)p[4]) << 24) + + (((u64)p[5]) << 16) + + (((u64)p[6]) << 8) + + (((u64)p[7]) << 0) + ); +#endif +} +#if SQLITE_BYTEORDER!=4321 /* Only used for little-endian machines */ +/* +** Byte-swap a 64-bit unsigned integer. +*/ +SQLITE_PRIVATE SQLITE_OPT_INLINE u64 sqlite3BSwap64(u64 x){ +#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + return __builtin_bswap64(x); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + return _byteswap_uint64(x); +#else + /* Test this limb using -DSQLITE_BYTEORDER=0 */ + x = (x << 32) | (x >> 32); + x = ((x & UINT64_C(0x0000ffff0000ffff)) << 16) | + ((x & UINT64_C(0xffff0000ffff0000)) >> 16); + x = ((x & UINT64_C(0x00ff00ff00ff00ff)) << 8) | + ((x & UINT64_C(0xff00ff00ff00ff00)) >> 8); + return x; +#endif +} +#endif /* SQLITE_BYTEORDER!=4321 */ /* ** Translate a single byte of Hex into an integer. @@ -38046,28 +39381,28 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 22 */ "SeekLE" OpHelp("key=r[P3@P4]"), /* 23 */ "SeekGE" OpHelp("key=r[P3@P4]"), /* 24 */ "SeekGT" OpHelp("key=r[P3@P4]"), - /* 25 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), - /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), - /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), - /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), - /* 29 */ "Found" OpHelp("key=r[P3@P4]"), - /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), - /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), - /* 32 */ "Last" OpHelp(""), - /* 33 */ "IfSizeBetween" OpHelp(""), - /* 34 */ "SorterSort" OpHelp(""), - /* 35 */ "Sort" OpHelp(""), - /* 36 */ "Rewind" OpHelp(""), - /* 37 */ "IfEmpty" OpHelp("if( empty(P1) ) goto P2"), - /* 38 */ "SorterNext" OpHelp(""), - /* 39 */ "Prev" OpHelp(""), - /* 40 */ "Next" OpHelp(""), - /* 41 */ "IdxLE" OpHelp("key=r[P3@P4]"), - /* 42 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 25 */ "IfNoHope" OpHelp("key=r[P3@P4]"), + /* 26 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 27 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 28 */ "Found" OpHelp("key=r[P3@P4]"), + /* 29 */ "SeekRowid" OpHelp("intkey=r[P3]"), + /* 30 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 31 */ "Last" OpHelp(""), + /* 32 */ "IfSizeBetween" OpHelp(""), + /* 33 */ "SorterSort" OpHelp(""), + /* 34 */ "Sort" OpHelp(""), + /* 35 */ "Rewind" OpHelp(""), + /* 36 */ "IfEmpty" OpHelp("if( empty(P1) ) goto P2"), + /* 37 */ "SorterNext" OpHelp(""), + /* 38 */ "Prev" OpHelp(""), + /* 39 */ "Next" OpHelp(""), + /* 40 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 41 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 42 */ "IdxLT" OpHelp("key=r[P3@P4]"), /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), - /* 45 */ "IdxLT" OpHelp("key=r[P3@P4]"), - /* 46 */ "IdxGE" OpHelp("key=r[P3@P4]"), + /* 45 */ "IdxGE" OpHelp("key=r[P3@P4]"), + /* 46 */ "IFindKey" OpHelp(""), /* 47 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), /* 48 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 49 */ "Program" OpHelp(""), @@ -38094,7 +39429,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 70 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), /* 71 */ "Halt" OpHelp(""), /* 72 */ "Integer" OpHelp("r[P2]=P1"), - /* 73 */ "Int64" OpHelp("r[P2]=P4"), + /* 73 */ "Int64" OpHelp("r[P2]=PINT13"), /* 74 */ "String" OpHelp("r[P2]='P4' (len=P1)"), /* 75 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), /* 76 */ "Null" OpHelp("r[P2..P3]=NULL"), @@ -38145,7 +39480,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 121 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), /* 122 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), /* 123 */ "Close" OpHelp(""), - /* 124 */ "ColumnsUsed" OpHelp(""), + /* 124 */ "ColumnsUsed" OpHelp("Cursor P1 uses columns PHEX23"), /* 125 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), /* 126 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), /* 127 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), @@ -38162,7 +39497,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 138 */ "SeekEnd" OpHelp(""), /* 139 */ "IdxInsert" OpHelp("key=r[P2]"), /* 140 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 141 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 141 */ "IdxDelete" OpHelp("key=r[P2@P5]"), /* 142 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), /* 143 */ "IdxRowid" OpHelp("r[P2]=rowid"), /* 144 */ "FinishSeek" OpHelp(""), @@ -38175,7 +39510,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 151 */ "LoadAnalysis" OpHelp(""), /* 152 */ "DropTable" OpHelp(""), /* 153 */ "DropIndex" OpHelp(""), - /* 154 */ "Real" OpHelp("r[P2]=P4"), + /* 154 */ "Real" OpHelp("r[P2]=PDBL13"), /* 155 */ "DropTrigger" OpHelp(""), /* 156 */ "IntegrityCk" OpHelp(""), /* 157 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), @@ -38234,6 +39569,22 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ ** This file contains an experimental VFS layer that operates on a ** Key/Value storage engine where both keys and values must be pure ** text. +** +** DEBUG AND TEST +** +** For testing on Unix, compile using: +** +** make clean sqlite3d CFLAGS='-DSQLITE_OS_KV_OPTIONAL' +** +** Then start up a shell using something like: +** +** ./sqlite3d 'file:dbname?vfs=kvvfs' +** +** Each K/V entry is stored in a separate file in the working +** directory that has a name like "kvvfs-dbname-*". Due to limitations +** on the key size, the name of the database must be very short - just +** a few characters. If the database name is too long, the VFS will +** malfunction and you will get SQLITE_CORRUPT errors. */ /* #include */ #if SQLITE_OS_KV || (SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL)) @@ -38242,7 +39593,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ ** Debugging logic */ -/* SQLITE_KV_TRACE() is used for tracing calls to kvstorage routines. */ +/* SQLITE_KV_TRACE() is used for tracing calls to kvrecord routines. */ #if 0 #define SQLITE_KV_TRACE(X) printf X #else @@ -38256,7 +39607,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ #define SQLITE_KV_LOG(X) #endif - /* ** Forward declaration of objects used by this VFS implementation */ @@ -38264,6 +39614,11 @@ typedef struct KVVfsFile KVVfsFile; /* A single open file. There are only two files represented by this ** VFS - the database and the rollback journal. +** +** Maintenance reminder: if this struct changes in any way, the JSON +** rendering of its structure must be updated in +** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary +** compatibility concerns, so it does not need an iVersion member. */ struct KVVfsFile { sqlite3_file base; /* IO methods */ @@ -38313,7 +39668,7 @@ static int kvvfsCurrentTime(sqlite3_vfs*, double*); static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); static sqlite3_vfs sqlite3OsKvvfsObject = { - 1, /* iVersion */ + 2, /* iVersion */ sizeof(KVVfsFile), /* szOsFile */ 1024, /* mxPathname */ 0, /* pNext */ @@ -38389,23 +39744,37 @@ static sqlite3_io_methods kvvfs_jrnl_io_methods = { /* Forward declarations for the low-level storage engine */ -static int kvstorageWrite(const char*, const char *zKey, const char *zData); -static int kvstorageDelete(const char*, const char *zKey); -static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf); -#define KVSTORAGE_KEY_SZ 32 +#ifndef SQLITE_WASM +/* In WASM builds these are implemented in JS. */ +static int kvrecordWrite(const char*, const char *zKey, const char *zData); +static int kvrecordDelete(const char*, const char *zKey); +static int kvrecordRead(const char*, const char *zKey, char *zBuf, int nBuf); +#endif +#ifndef KVRECORD_KEY_SZ +#define KVRECORD_KEY_SZ 32 +#endif /* Expand the key name with an appropriate prefix and put the result ** in zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least -** KVSTORAGE_KEY_SZ bytes. +** KVRECORD_KEY_SZ bytes. */ -static void kvstorageMakeKey( +static void kvrecordMakeKey( const char *zClass, const char *zKeyIn, char *zKeyOut ){ - sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "kvvfs-%s-%s", zClass, zKeyIn); + assert( zKeyIn ); + assert( zKeyOut ); + assert( zClass ); + sqlite3_snprintf(KVRECORD_KEY_SZ, zKeyOut, "kvvfs-%s-%s", + zClass, zKeyIn); } +#ifndef SQLITE_WASM +/* In WASM builds do not define APIs which use fopen(), fwrite(), +** and the like because those APIs are a portability issue for +** WASM. +*/ /* Write content into a key. zClass is the particular namespace of the ** underlying key/value store to use - either "local" or "session". ** @@ -38413,14 +39782,14 @@ static void kvstorageMakeKey( ** ** Return the number of errors. */ -static int kvstorageWrite( +static int kvrecordWrite( const char *zClass, const char *zKey, const char *zData ){ FILE *fd; - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); + char zXKey[KVRECORD_KEY_SZ]; + kvrecordMakeKey(zClass, zKey, zXKey); fd = fopen(zXKey, "wb"); if( fd ){ SQLITE_KV_TRACE(("KVVFS-WRITE %-15s (%d) %.50s%s\n", zXKey, @@ -38438,9 +39807,9 @@ static int kvstorageWrite( ** namespace given by zClass. If the key does not previously exist, ** this routine is a no-op. */ -static int kvstorageDelete(const char *zClass, const char *zKey){ - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); +static int kvrecordDelete(const char *zClass, const char *zKey){ + char zXKey[KVRECORD_KEY_SZ]; + kvrecordMakeKey(zClass, zKey, zXKey); unlink(zXKey); SQLITE_KV_TRACE(("KVVFS-DELETE %-15s\n", zXKey)); return 0; @@ -38461,7 +39830,7 @@ static int kvstorageDelete(const char *zClass, const char *zKey){ ** zero-terminates zBuf at zBuf[0] and returns the size of the data ** without reading it. */ -static int kvstorageRead( +static int kvrecordRead( const char *zClass, const char *zKey, char *zBuf, @@ -38469,8 +39838,8 @@ static int kvstorageRead( ){ FILE *fd; struct stat buf; - char zXKey[KVSTORAGE_KEY_SZ]; - kvstorageMakeKey(zClass, zKey, zXKey); + char zXKey[KVRECORD_KEY_SZ]; + kvrecordMakeKey(zClass, zKey, zXKey); if( access(zXKey, R_OK)!=0 || stat(zXKey, &buf)!=0 || !S_ISREG(buf.st_mode) @@ -38502,6 +39871,8 @@ static int kvstorageRead( return (int)n; } } +#endif /* #ifndef SQLITE_WASM */ + /* ** An internal level of indirection which enables us to replace the @@ -38509,17 +39880,27 @@ static int kvstorageRead( ** Maintenance reminder: if this struct changes in any way, the JSON ** rendering of its structure must be updated in ** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary -** compatibility concerns, so it does not need an iVersion -** member. +** compatibility concerns, so it does not need an iVersion member. */ typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods; struct sqlite3_kvvfs_methods { - int (*xRead)(const char *zClass, const char *zKey, char *zBuf, int nBuf); - int (*xWrite)(const char *zClass, const char *zKey, const char *zData); - int (*xDelete)(const char *zClass, const char *zKey); + int (*xRcrdRead)(const char*, const char *zKey, char *zBuf, int nBuf); + int (*xRcrdWrite)(const char*, const char *zKey, const char *zData); + int (*xRcrdDelete)(const char*, const char *zKey); const int nKeySize; + const int nBufferSize; +#ifndef SQLITE_WASM +# define MAYBE_CONST const +#else +# define MAYBE_CONST +#endif + MAYBE_CONST sqlite3_vfs * pVfs; + MAYBE_CONST sqlite3_io_methods *pIoDb; + MAYBE_CONST sqlite3_io_methods *pIoJrnl; +#undef MAYBE_CONST }; + /* ** This object holds the kvvfs I/O methods which may be swapped out ** for JavaScript-side implementations in WASM builds. In such builds @@ -38534,10 +39915,20 @@ struct sqlite3_kvvfs_methods { const #endif SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = { -kvstorageRead, -kvstorageWrite, -kvstorageDelete, -KVSTORAGE_KEY_SZ +#ifndef SQLITE_WASM + .xRcrdRead = kvrecordRead, + .xRcrdWrite = kvrecordWrite, + .xRcrdDelete = kvrecordDelete, +#else + .xRcrdRead = 0, + .xRcrdWrite = 0, + .xRcrdDelete = 0, +#endif + .nKeySize = KVRECORD_KEY_SZ, + .nBufferSize = SQLITE_KVOS_SZ, + .pVfs = &sqlite3OsKvvfsObject, + .pIoDb = &kvvfs_db_io_methods, + .pIoJrnl = &kvvfs_jrnl_io_methods }; /****** Utility subroutines ************************************************/ @@ -38564,7 +39955,10 @@ KVSTORAGE_KEY_SZ ** of hexadecimal and base-26 numbers, it is always clear where ** one stops and the next begins. */ -static int kvvfsEncode(const char *aData, int nData, char *aOut){ +#ifndef SQLITE_WASM +static +#endif +int kvvfsEncode(const char *aData, int nData, char *aOut){ int i, j; const unsigned char *a = (const unsigned char*)aData; for(i=j=0; i='a' && c<='z' ){ n += (c - 'a')*mult; + if( n>nOut ) return -1 /* oversized/malformed input */; mult *= 26; c = aIn[++i]; } - if( j+n>nOut ) return -1; + if( j+n>nOut ) return -1 /* oversized/malformed input */; memset(&aOut[j], 0, n); j += n; if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */ - }else{ + }else if( j='a' && c<='z' ){ - n += (zTxt[i] - 'a')*mult; + sqlite3_free(pFile->aJrnl); + pFile->aJrnl = 0; + pFile->nJrnl = 0; + while( (c = zTxt[i])>='a' && c<='z' ){ + n += (c - 'a')*mult; mult *= 26; + ++i; + } + if( ' '!=zTxt[i++] ){ + /* Malformed input */ + return; } - sqlite3_free(pFile->aJrnl); pFile->aJrnl = sqlite3_malloc64( n ); if( pFile->aJrnl==0 ){ - pFile->nJrnl = 0; return; } pFile->nJrnl = n; @@ -38695,13 +40102,14 @@ static void kvvfsDecodeJournal( static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){ char zData[50]; zData[0] = 0; - sqlite3KvvfsMethods.xRead(pFile->zClass, "sz", zData, sizeof(zData)-1); + sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, "sz", zData, + sizeof(zData)-1); return strtoll(zData, 0, 0); } static int kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){ char zData[50]; sqlite3_snprintf(sizeof(zData), zData, "%lld", sz); - return sqlite3KvvfsMethods.xWrite(pFile->zClass, "sz", zData); + return sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, "sz", zData); } /****** sqlite3_io_methods methods ******************************************/ @@ -38716,6 +40124,7 @@ static int kvvfsClose(sqlite3_file *pProtoFile){ pFile->isJournal ? "journal" : "db")); sqlite3_free(pFile->aJrnl); sqlite3_free(pFile->aData); + memset(pFile, 0, sizeof(*pFile)); return SQLITE_OK; } @@ -38732,16 +40141,23 @@ static int kvvfsReadJrnl( assert( pFile->isJournal ); SQLITE_KV_LOG(("xRead('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); if( pFile->aJrnl==0 ){ - int szTxt = kvstorageRead(pFile->zClass, "jrnl", 0, 0); + int rc; + int szTxt = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, "jrnl", + 0, 0); char *aTxt; if( szTxt<=4 ){ return SQLITE_IOERR; } aTxt = sqlite3_malloc64( szTxt+1 ); if( aTxt==0 ) return SQLITE_NOMEM; - kvstorageRead(pFile->zClass, "jrnl", aTxt, szTxt+1); - kvvfsDecodeJournal(pFile, aTxt, szTxt); + rc = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, "jrnl", + aTxt, szTxt+1); + if( rc>=0 ){ + kvvfsDecodeJournal(pFile, aTxt, szTxt); + rc = 0; + } sqlite3_free(aTxt); + if( rc ) return rc; if( pFile->aJrnl==0 ) return SQLITE_IOERR; } if( iOfst+iAmt>pFile->nJrnl ){ @@ -38781,8 +40197,8 @@ static int kvvfsReadDb( pgno = 1; } sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); - got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, - aData, SQLITE_KVOS_SZ-1); + got = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, zKey, + aData, SQLITE_KVOS_SZ-1); if( got<0 ){ n = 0; }else{ @@ -38850,6 +40266,7 @@ static int kvvfsWriteDb( unsigned int pgno; char zKey[30]; char *aData = pFile->aData; + int rc; SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); assert( iAmt>=512 && iAmt<=65536 ); assert( (iAmt & (iAmt-1))==0 ); @@ -38858,13 +40275,13 @@ static int kvvfsWriteDb( pgno = 1 + iOfst/iAmt; sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); kvvfsEncode(zBuf, iAmt, aData); - if( sqlite3KvvfsMethods.xWrite(pFile->zClass, zKey, aData) ){ - return SQLITE_IOERR; - } - if( iOfst+iAmt > pFile->szDb ){ - pFile->szDb = iOfst + iAmt; + rc = sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, zKey, aData); + if( 0==rc ){ + if( iOfst+iAmt > pFile->szDb ){ + pFile->szDb = iOfst + iAmt; + } } - return SQLITE_OK; + return rc; } /* @@ -38874,7 +40291,7 @@ static int kvvfsTruncateJrnl(sqlite3_file *pProtoFile, sqlite_int64 size){ KVVfsFile *pFile = (KVVfsFile *)pProtoFile; SQLITE_KV_LOG(("xTruncate('%s-journal',%lld)\n", pFile->zClass, size)); assert( size==0 ); - sqlite3KvvfsMethods.xDelete(pFile->zClass, "jrnl"); + sqlite3KvvfsMethods.xRcrdDelete(pFile->zClass, "jrnl"); sqlite3_free(pFile->aJrnl); pFile->aJrnl = 0; pFile->nJrnl = 0; @@ -38893,7 +40310,7 @@ static int kvvfsTruncateDb(sqlite3_file *pProtoFile, sqlite_int64 size){ pgnoMax = 2 + pFile->szDb/pFile->szPage; while( pgno<=pgnoMax ){ sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); - sqlite3KvvfsMethods.xDelete(pFile->zClass, zKey); + sqlite3KvvfsMethods.xRcrdDelete(pFile->zClass, zKey); pgno++; } pFile->szDb = size; @@ -38925,7 +40342,7 @@ static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){ }while( n>0 ); zOut[i++] = ' '; kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]); - i = sqlite3KvvfsMethods.xWrite(pFile->zClass, "jrnl", zOut); + i = sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, "jrnl", zOut); sqlite3_free(zOut); return i ? SQLITE_IOERR : SQLITE_OK; } @@ -39039,33 +40456,44 @@ static int kvvfsOpen( KVVfsFile *pFile = (KVVfsFile*)pProtoFile; if( zName==0 ) zName = ""; SQLITE_KV_LOG(("xOpen(\"%s\")\n", zName)); - if( strcmp(zName, "local")==0 - || strcmp(zName, "session")==0 - ){ - pFile->isJournal = 0; - pFile->base.pMethods = &kvvfs_db_io_methods; - }else - if( strcmp(zName, "local-journal")==0 - || strcmp(zName, "session-journal")==0 - ){ + assert(!pFile->zClass); + assert(!pFile->aData); + assert(!pFile->aJrnl); + assert(!pFile->nJrnl); + assert(!pFile->base.pMethods); + pFile->szPage = -1; + pFile->szDb = -1; + if( 0==sqlite3_strglob("*-journal", zName) ){ pFile->isJournal = 1; pFile->base.pMethods = &kvvfs_jrnl_io_methods; + if( 0==strcmp("session-journal",zName) ){ + pFile->zClass = "session"; + }else if( 0==strcmp("local-journal",zName) ){ + pFile->zClass = "local"; + } }else{ - return SQLITE_CANTOPEN; + pFile->isJournal = 0; + pFile->base.pMethods = &kvvfs_db_io_methods; } - if( zName[0]=='s' ){ - pFile->zClass = "session"; - }else{ - pFile->zClass = "local"; + if( !pFile->zClass ){ +#ifdef SQLITE_WASM + if( strlen(zName) >= (KVRECORD_KEY_SZ + - 6 /* "kvvfs-" */ + - 11 /* "-NNNNNNNNNNN" */) ){ + return SQLITE_CANTOPEN; + } +#else + if( 0!=strcmp(zName, "local") && 0!=strcmp(zName, "session") ){ + /* Historical naming restriction which journaling depends on. */ + return SQLITE_CANTOPEN; + } +#endif + pFile->zClass = zName; } pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ); if( pFile->aData==0 ){ return SQLITE_NOMEM; } - pFile->aJrnl = 0; - pFile->nJrnl = 0; - pFile->szPage = -1; - pFile->szDb = -1; return SQLITE_OK; } @@ -39075,13 +40503,17 @@ static int kvvfsOpen( ** returning. */ static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + int rc /* The JS impl can fail with OOM in argument conversion */; if( strcmp(zPath, "local-journal")==0 ){ - sqlite3KvvfsMethods.xDelete("local", "jrnl"); + rc = sqlite3KvvfsMethods.xRcrdDelete("local", "jrnl"); }else if( strcmp(zPath, "session-journal")==0 ){ - sqlite3KvvfsMethods.xDelete("session", "jrnl"); + rc = sqlite3KvvfsMethods.xRcrdDelete("session", "jrnl"); } - return SQLITE_OK; + else{ + rc = 0; + } + return rc; } /* @@ -39095,21 +40527,42 @@ static int kvvfsAccess( int *pResOut ){ SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath)); +#if 0 && defined(SQLITE_WASM) + /* + ** This is not having the desired effect in the JS bindings. + ** It's ostensibly the same logic as the #else block, but + ** it's not behaving that way. + ** + ** In JS we map all zPaths to Storage objects, and -journal files + ** are mapped to the storage for the main db (which is is exactly + ** what the mapping of "local-journal" -> "local" is doing). + */ + const char *zKey = (0==sqlite3_strglob("*-journal", zPath)) + ? "jrnl" : "sz"; + *pResOut = + sqlite3KvvfsMethods.xRcrdRead(zPath, zKey, 0, 0)>0; +#else if( strcmp(zPath, "local-journal")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("local", "jrnl", 0, 0)>0; + *pResOut = + sqlite3KvvfsMethods.xRcrdRead("local", "jrnl", 0, 0)>0; }else if( strcmp(zPath, "session-journal")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("session", "jrnl", 0, 0)>0; + *pResOut = + sqlite3KvvfsMethods.xRcrdRead("session", "jrnl", 0, 0)>0; }else if( strcmp(zPath, "local")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("local", "sz", 0, 0)>0; + *pResOut = + sqlite3KvvfsMethods.xRcrdRead("local", "sz", 0, 0)>0; }else if( strcmp(zPath, "session")==0 ){ - *pResOut = sqlite3KvvfsMethods.xRead("session", "sz", 0, 0)>0; + *pResOut = + sqlite3KvvfsMethods.xRcrdRead("session", "sz", 0, 0)>0; }else { *pResOut = 0; } + /*all current JS tests avoid triggering: assert( *pResOut == 0 ); */ +#endif SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut)); return SQLITE_OK; } @@ -44343,9 +45796,9 @@ static int unixShmMap( nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; if( pShmNode->nRegionszRegion = szRegion; @@ -44376,7 +45829,7 @@ static int unixShmMap( */ else{ static const int pgsz = 4096; - int iPg; + i64 iPg; /* Write to the last byte of each newly allocated or extended page */ assert( (nByte % pgsz)==0 ); @@ -44393,7 +45846,7 @@ static int unixShmMap( } /* Map the requested memory region into this processes address space. */ - apNew = (char **)sqlite3_realloc( + apNew = (char **)sqlite3_realloc64( pShmNode->apRegion, nReqRegion*sizeof(char *) ); if( !apNew ){ @@ -44402,8 +45855,8 @@ static int unixShmMap( } pShmNode->apRegion = apNew; while( pShmNode->nRegionhShm>=0 ){ pMem = osMmap(0, nMap, @@ -44792,7 +46245,6 @@ static void unixRemapfile( const char *zErr = "mmap"; int h = pFd->h; /* File descriptor open on db file */ u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */ - i64 nOrig = pFd->mmapSizeActual; /* Size of pOrig region in bytes */ u8 *pNew = 0; /* Location of new mapping */ int flags = PROT_READ; /* Flags to pass to mmap() */ @@ -44808,37 +46260,35 @@ static void unixRemapfile( #endif if( pOrig ){ -#if HAVE_MREMAP - i64 nReuse = pFd->mmapSize; -#else - const int szSyspage = osGetpagesize(); - i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); -#endif - u8 *pReq = &pOrig[nReuse]; + i64 nReuse = pFd->mmapSize & ~((int)osGetpagesize()-1); - /* Unmap any pages of the existing mapping that cannot be reused. */ - if( nReuse!=nOrig ){ - osMunmap(pReq, nOrig-nReuse); + /* Unmap any part of the current mapping that will not be reused */ + if( nReusemmapSizeActual ){ + osMunmap(&pOrig[nReuse], pFd->mmapSizeActual - nReuse); } + /* If nReuse is now zero, then the entire mapping was unmapped by the + ** call above. In this case do not attempt to extend pOrig. */ + if( nReuse>0 ){ #if HAVE_MREMAP - pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE); - zErr = "mremap"; + pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE); + zErr = "mremap"; #else - pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse); - if( pNew!=MAP_FAILED ){ - if( pNew!=pReq ){ - osMunmap(pNew, nNew - nReuse); - pNew = 0; - }else{ - pNew = pOrig; + pNew = osMmap(&pOrig[nReuse], nNew-nReuse, flags, MAP_SHARED, h, nReuse); + if( pNew!=MAP_FAILED ){ + if( pNew!=&pOrig[nReuse] ){ + osMunmap(pNew, nNew - nReuse); + pNew = 0; + }else{ + pNew = pOrig; + } } - } #endif - /* The attempt to extend the existing mapping failed. Free it. */ - if( pNew==MAP_FAILED || pNew==0 ){ - osMunmap(pOrig, nReuse); + /* The attempt to extend the existing mapping failed. Free it. */ + if( pNew==MAP_FAILED || pNew==0 ){ + osMunmap(pOrig, nReuse); + } } } @@ -45459,36 +46909,29 @@ static int fillInUnixFile( return rc; } -/* -** Directories to consider for temp files. -*/ -static const char *azTempDirs[] = { - 0, - 0, - "/var/tmp", - "/usr/tmp", - "/tmp", - "." -}; - -/* -** Initialize first two members of azTempDirs[] array. -*/ -static void unixTempFileInit(void){ - azTempDirs[0] = getenv("SQLITE_TMPDIR"); - azTempDirs[1] = getenv("TMPDIR"); -} - /* ** Return the name of a directory in which to put temporary files. ** If no suitable temporary file directory can be found, return NULL. +** +** The return value might be a string obtained from getenv() and so +** the return value should not be used after any call to setenv() or +** putenv() as that value might have been freed. */ static const char *unixTempFileDir(void){ - unsigned int i = 0; + unsigned int i; struct stat buf; - const char *zDir = sqlite3_temp_directory; + const char *zDir; - while(1){ + for(i=0; i<7; i++){ + switch( i ){ + case 0: zDir = sqlite3_temp_directory; break; + case 1: zDir = getenv("SQLITE_TMPDIR"); break; + case 2: zDir = getenv("TMPDIR"); break; + case 3: zDir = "/var/tmp"; break; + case 4: zDir = "/usr/tmp"; break; + case 5: zDir = "/tmp"; break; + default: zDir = "."; break; + } if( zDir!=0 #if OS_VXWORKS && zDir[0]=='/' @@ -45499,8 +46942,6 @@ static const char *unixTempFileDir(void){ ){ return zDir; } - if( i>=sizeof(azTempDirs)/sizeof(azTempDirs[0]) ) break; - zDir = azTempDirs[i++]; } return 0; } @@ -45849,7 +47290,22 @@ static int unixOpen( }else if( !zName ){ /* If zName is NULL, the upper layer is requesting a temp file. */ - assert(isDelete && !isNewJrnl); + assert( isDelete ); + assert( !isNewJrnl ); + assert( isExclusive ); + assert( isReadWrite ); +#if defined(__linux__) && defined(O_TMPFILE) + /* On systems that support O_TMPFILE, use that flag to create a more + ** secure temporary file that cannot be accessed by other processes + */ + zName = unixTempFileDir(); + if( zName + && (fd = robust_open(zName, O_RDWR|O_EXCL|O_TMPFILE, 0600))>=0 + ){ + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags|UNIXFILE_NOLOCK); + goto open_finished; + } +#endif rc = unixGetTempname(pVfs->mxPathname, zTmpname); if( rc!=SQLITE_OK ){ return rc; @@ -47768,9 +49224,6 @@ SQLITE_API int sqlite3_os_init(void){ assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */ #endif - /* Initialize temp file dir array. */ - unixTempFileInit(); - return SQLITE_OK; } @@ -47820,86 +49273,6 @@ SQLITE_API int sqlite3_os_end(void){ */ /* #include "os_win.h" */ -/* -** Compiling and using WAL mode requires several APIs that are only -** available in Windows platforms based on the NT kernel. -*/ -#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) -# error "WAL mode requires support from the Windows NT kernel, compile\ - with SQLITE_OMIT_WAL." -#endif - -#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0 -# error "Memory mapped files require support from the Windows NT kernel,\ - compile with SQLITE_MAX_MMAP_SIZE=0." -#endif - -/* -** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions -** based on the sub-platform)? -*/ -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) -# define SQLITE_WIN32_HAS_ANSI -#endif - -/* -** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions -** based on the sub-platform)? -*/ -#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \ - !defined(SQLITE_WIN32_NO_WIDE) -# define SQLITE_WIN32_HAS_WIDE -#endif - -/* -** Make sure at least one set of Win32 APIs is available. -*/ -#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) -# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ - must be defined." -#endif - -/* -** Define the required Windows SDK version constants if they are not -** already available. -*/ -#ifndef NTDDI_WIN8 -# define NTDDI_WIN8 0x06020000 -#endif - -#ifndef NTDDI_WINBLUE -# define NTDDI_WINBLUE 0x06030000 -#endif - -#ifndef NTDDI_WINTHRESHOLD -# define NTDDI_WINTHRESHOLD 0x06040000 -#endif - -/* -** Check to see if the GetVersionEx[AW] functions are deprecated on the -** target system. GetVersionEx was first deprecated in Win8.1. -*/ -#ifndef SQLITE_WIN32_GETVERSIONEX -# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE -# define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */ -# else -# define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */ -# endif -#endif - -/* -** Check to see if the CreateFileMappingA function is supported on the -** target system. It is unavailable when using "mincore.lib" on Win10. -** When compiling for Windows 10, always assume "mincore.lib" is in use. -*/ -#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA -# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD -# define SQLITE_WIN32_CREATEFILEMAPPINGA 0 -# else -# define SQLITE_WIN32_CREATEFILEMAPPINGA 1 -# endif -#endif - /* ** This constant should already be defined (in the "WinDef.h" SDK file). */ @@ -47979,45 +49352,7 @@ SQLITE_API int sqlite3_os_end(void){ #endif /* -** Do we need to manually define the Win32 file mapping APIs for use with WAL -** mode or memory mapped files (e.g. these APIs are available in the Windows -** CE SDK; however, they are not present in the header file)? -*/ -#if SQLITE_WIN32_FILEMAPPING_API && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) -/* -** Two of the file mapping APIs are different under WinRT. Figure out which -** set we need. -*/ -#if SQLITE_OS_WINRT -WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \ - LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR); - -WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T); -#else -#if defined(SQLITE_WIN32_HAS_ANSI) -WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \ - DWORD, DWORD, DWORD, LPCSTR); -#endif /* defined(SQLITE_WIN32_HAS_ANSI) */ - -#if defined(SQLITE_WIN32_HAS_WIDE) -WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \ - DWORD, DWORD, DWORD, LPCWSTR); -#endif /* defined(SQLITE_WIN32_HAS_WIDE) */ - -WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); -#endif /* SQLITE_OS_WINRT */ - -/* -** These file mapping APIs are common to both Win32 and WinRT. -*/ - -WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T); -WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID); -#endif /* SQLITE_WIN32_FILEMAPPING_API */ - -/* -** Some Microsoft compilers lack this definition. +** Some older Microsoft compilers lack the following definition. */ #ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) @@ -48037,19 +49372,6 @@ typedef struct winShm winShm; /* A connection to shared-memory */ typedef struct winShmNode winShmNode; /* A region of shared-memory */ #endif -/* -** WinCE lacks native support for file locking so we have to fake it -** with some code of our own. -*/ -#if SQLITE_OS_WINCE -typedef struct winceLock { - int nReaders; /* Number of reader locks obtained */ - BOOL bPending; /* Indicates a pending lock has been obtained */ - BOOL bReserved; /* Indicates a reserved lock has been obtained */ - BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ -} winceLock; -#endif - /* ** The winFile structure is a subclass of sqlite3_file* specific to the win32 ** portability layer. @@ -48068,13 +49390,6 @@ struct winFile { #endif const char *zPath; /* Full pathname of this file */ int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ -#if SQLITE_OS_WINCE - LPWSTR zDeleteOnClose; /* Name of file to delete when closing */ - HANDLE hMutex; /* Mutex used to control access to shared lock */ - HANDLE hShared; /* Shared memory segment used for locking */ - winceLock local; /* Locks obtained by this instance of winFile */ - winceLock *shared; /* Global shared lock memory for the file */ -#endif #if SQLITE_MAX_MMAP_SIZE>0 int nFetchOut; /* Number of outstanding xFetch references */ HANDLE hMap; /* Handle for accessing memory mapping */ @@ -48271,36 +49586,10 @@ static void winMemShutdown(void *pAppData); SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void); #endif /* SQLITE_WIN32_MALLOC */ -/* -** The following variable is (normally) set once and never changes -** thereafter. It records whether the operating system is Win9x -** or WinNT. -** -** 0: Operating system unknown. -** 1: Operating system is Win9x. -** 2: Operating system is WinNT. -** -** In order to facilitate testing on a WinNT system, the test fixture -** can manually set this value to 1 to emulate Win98 behavior. -*/ -#ifdef SQLITE_TEST -SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; -#else -static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; -#endif - #ifndef SYSCALL # define SYSCALL sqlite3_syscall_ptr #endif -/* -** This function is not available on Windows CE or WinRT. - */ - -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT -# define osAreFileApisANSI() 1 -#endif - /* ** Many system calls are accessed through pointer-to-functions so that ** they may be overridden at runtime to facilitate fault injection during @@ -48312,619 +49601,246 @@ static struct win_syscall { sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ sqlite3_syscall_ptr pDefault; /* Default value */ } aSyscall[] = { -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, -#else - { "AreFileApisANSI", (SYSCALL)0, 0 }, -#endif - -#ifndef osAreFileApisANSI #define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) -#endif - -#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) - { "CharLowerW", (SYSCALL)CharLowerW, 0 }, -#else - { "CharLowerW", (SYSCALL)0, 0 }, -#endif - -#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent) - -#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) - { "CharUpperW", (SYSCALL)CharUpperW, 0 }, -#else - { "CharUpperW", (SYSCALL)0, 0 }, -#endif - -#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent) { "CloseHandle", (SYSCALL)CloseHandle, 0 }, +#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[1].pCurrent) -#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "CreateFileA", (SYSCALL)CreateFileA, 0 }, -#else - { "CreateFileA", (SYSCALL)0, 0 }, -#endif - -#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ - LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "CreateFileW", (SYSCALL)CreateFileW, 0 }, -#else - { "CreateFileW", (SYSCALL)0, 0 }, -#endif - #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ - LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[2].pCurrent) -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \ - SQLITE_WIN32_CREATEFILEMAPPINGA - { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, +#if defined(SQLITE_UWP) + { "CreateFileMappingFromApp",(SYSCALL)CreateFileMappingFromApp,0 }, #else - { "CreateFileMappingA", (SYSCALL)0, 0 }, + { "CreateFileMappingFromApp",(SYSCALL)0, 0 }, #endif +#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE,\ + PSECURITY_ATTRIBUTES, \ + ULONG,ULONG64,PCWSTR))aSyscall[3].pCurrent) -#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ - DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent) - -#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) +#if !defined(SQLITE_UWP) { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, #else { "CreateFileMappingW", (SYSCALL)0, 0 }, #endif - #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ - DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[4].pCurrent) -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, -#else - { "CreateMutexW", (SYSCALL)0, 0 }, -#endif - -#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ - LPCWSTR))aSyscall[8].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, -#else - { "DeleteFileA", (SYSCALL)0, 0 }, -#endif - -#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, -#else - { "DeleteFileW", (SYSCALL)0, 0 }, -#endif - -#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) - -#if SQLITE_OS_WINCE - { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, -#else - { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, -#endif - -#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(const FILETIME*, \ - LPFILETIME))aSyscall[11].pCurrent) - -#if SQLITE_OS_WINCE - { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, -#else - { "FileTimeToSystemTime", (SYSCALL)0, 0 }, -#endif - -#define osFileTimeToSystemTime ((BOOL(WINAPI*)(const FILETIME*, \ - LPSYSTEMTIME))aSyscall[12].pCurrent) +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[5].pCurrent) { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[6].pCurrent) -#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, -#else - { "FormatMessageA", (SYSCALL)0, 0 }, -#endif - -#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ - DWORD,va_list*))aSyscall[14].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, -#else - { "FormatMessageW", (SYSCALL)0, 0 }, -#endif - #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ - DWORD,va_list*))aSyscall[15].pCurrent) + DWORD,va_list*))aSyscall[7].pCurrent) -#if !defined(SQLITE_OMIT_LOAD_EXTENSION) +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_UWP) { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, #else { "FreeLibrary", (SYSCALL)0, 0 }, #endif -#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[8].pCurrent) { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[9].pCurrent) -#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) - -#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) - { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, -#else - { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, -#endif - -#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ - LPDWORD))aSyscall[18].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, -#else - { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, -#endif - -#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ - LPDWORD))aSyscall[19].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) - { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, -#else - { "GetFileAttributesA", (SYSCALL)0, 0 }, -#endif - -#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, -#else - { "GetFileAttributesW", (SYSCALL)0, 0 }, -#endif +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) -#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, -#else - { "GetFileAttributesExW", (SYSCALL)0, 0 }, -#endif - #define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ - LPVOID))aSyscall[22].pCurrent) - -#if !SQLITE_OS_WINRT - { "GetFileSize", (SYSCALL)GetFileSize, 0 }, -#else - { "GetFileSize", (SYSCALL)0, 0 }, -#endif + LPVOID))aSyscall[11].pCurrent) -#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) + { "GetFileSizeEx", (SYSCALL)GetFileSizeEx, 0 }, +#define osGetFileSizeEx ((BOOL(WINAPI*)(HANDLE, \ + PLARGE_INTEGER))aSyscall[12].pCurrent) -#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) - { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, -#else - { "GetFullPathNameA", (SYSCALL)0, 0 }, -#endif - -#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ - LPSTR*))aSyscall[24].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, -#else - { "GetFullPathNameW", (SYSCALL)0, 0 }, -#endif - #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ - LPWSTR*))aSyscall[25].pCurrent) + LPWSTR*))aSyscall[13].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[14].pCurrent) -#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) - -#if !defined(SQLITE_OMIT_LOAD_EXTENSION) -#if SQLITE_OS_WINCE - /* The GetProcAddressA() routine is only available on Windows CE. */ - { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, -#else - /* All other Windows platforms expect GetProcAddress() to take - ** an ANSI string regardless of the _UNICODE setting */ +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_UWP) { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, -#endif #else { "GetProcAddressA", (SYSCALL)0, 0 }, #endif - #define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ - LPCSTR))aSyscall[27].pCurrent) + LPCSTR))aSyscall[15].pCurrent) -#if !SQLITE_OS_WINRT { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, -#else - { "GetSystemInfo", (SYSCALL)0, 0 }, -#endif +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[16].pCurrent) -#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) - - { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, - -#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) - -#if !SQLITE_OS_WINCE { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, -#else - { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, -#endif - #define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ - LPFILETIME))aSyscall[30].pCurrent) + LPFILETIME))aSyscall[17].pCurrent) -#if defined(SQLITE_WIN32_HAS_ANSI) - { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, -#else - { "GetTempPathA", (SYSCALL)0, 0 }, -#endif - -#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) - -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) - { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, -#else +#ifdef SQLITE_UWP { "GetTempPathW", (SYSCALL)0, 0 }, -#endif - -#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) - -#if !SQLITE_OS_WINRT - { "GetTickCount", (SYSCALL)GetTickCount, 0 }, -#else - { "GetTickCount", (SYSCALL)0, 0 }, -#endif - -#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX - { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, #else - { "GetVersionExA", (SYSCALL)0, 0 }, + { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, #endif +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[18].pCurrent) -#define osGetVersionExA ((BOOL(WINAPI*)( \ - LPOSVERSIONINFOA))aSyscall[34].pCurrent) + { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, +#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[19].pCurrent) -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ - SQLITE_WIN32_GETVERSIONEX - { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, +#ifdef SQLITE_UWP + { "HeapAlloc", (SYSCALL)0, 0 }, #else - { "GetVersionExW", (SYSCALL)0, 0 }, -#endif - -#define osGetVersionExW ((BOOL(WINAPI*)( \ - LPOSVERSIONINFOW))aSyscall[35].pCurrent) - { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, - +#endif #define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ - SIZE_T))aSyscall[36].pCurrent) + SIZE_T))aSyscall[20].pCurrent) -#if !SQLITE_OS_WINRT - { "HeapCreate", (SYSCALL)HeapCreate, 0 }, -#else +#ifdef SQLITE_UWP { "HeapCreate", (SYSCALL)0, 0 }, +#else + { "HeapCreate", (SYSCALL)HeapCreate, 0 }, #endif - #define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ - SIZE_T))aSyscall[37].pCurrent) + SIZE_T))aSyscall[21].pCurrent) -#if !SQLITE_OS_WINRT - { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, -#else +#ifdef SQLITE_UWP { "HeapDestroy", (SYSCALL)0, 0 }, +#else + { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, #endif +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[22].pCurrent) -#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent) - +#ifdef SQLITE_UWP + { "HeapFree", (SYSCALL)0, 0 }, +#else { "HeapFree", (SYSCALL)HeapFree, 0 }, +#endif +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[23].pCurrent) -#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent) - +#ifdef SQLITE_UWP + { "HeapReAlloc", (SYSCALL)0, 0 }, +#else { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, - +#endif #define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ - SIZE_T))aSyscall[40].pCurrent) + SIZE_T))aSyscall[24].pCurrent) +#ifdef SQLITE_UWP + { "HeapSize", (SYSCALL)0, 0 }, +#else { "HeapSize", (SYSCALL)HeapSize, 0 }, - +#endif #define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ - LPCVOID))aSyscall[41].pCurrent) + LPCVOID))aSyscall[25].pCurrent) -#if !SQLITE_OS_WINRT - { "HeapValidate", (SYSCALL)HeapValidate, 0 }, -#else +#ifdef SQLITE_UWP { "HeapValidate", (SYSCALL)0, 0 }, +#else + { "HeapValidate", (SYSCALL)HeapValidate, 0 }, #endif - #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ - LPCVOID))aSyscall[42].pCurrent) + LPCVOID))aSyscall[26].pCurrent) -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT - { "HeapCompact", (SYSCALL)HeapCompact, 0 }, -#else +#ifdef SQLITE_UWP { "HeapCompact", (SYSCALL)0, 0 }, -#endif - -#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION) - { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, #else - { "LoadLibraryA", (SYSCALL)0, 0 }, + { "HeapCompact", (SYSCALL)HeapCompact, 0 }, #endif +#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[27].pCurrent) -#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent) -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ - !defined(SQLITE_OMIT_LOAD_EXTENSION) +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_UWP) { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, #else { "LoadLibraryW", (SYSCALL)0, 0 }, #endif +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[28].pCurrent) -#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent) - -#if !SQLITE_OS_WINRT { "LocalFree", (SYSCALL)LocalFree, 0 }, -#else - { "LocalFree", (SYSCALL)0, 0 }, -#endif +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[29].pCurrent) -#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT - { "LockFile", (SYSCALL)LockFile, 0 }, -#else - { "LockFile", (SYSCALL)0, 0 }, -#endif - -#if !defined(osLockFile) && defined(SQLITE_WIN32_HAS_ANSI) -#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - DWORD))aSyscall[47].pCurrent) -#endif - -#if !SQLITE_OS_WINCE { "LockFileEx", (SYSCALL)LockFileEx, 0 }, -#else - { "LockFileEx", (SYSCALL)0, 0 }, -#endif - -#ifndef osLockFileEx #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ - LPOVERLAPPED))aSyscall[48].pCurrent) -#endif + LPOVERLAPPED))aSyscall[30].pCurrent) -#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ + && !defined(SQLITE_UWP) { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, #else { "MapViewOfFile", (SYSCALL)0, 0 }, #endif - #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - SIZE_T))aSyscall[49].pCurrent) + SIZE_T))aSyscall[31].pCurrent) - { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ + && defined(SQLITE_UWP) + { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, +#else + { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, +#endif +#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ + SIZE_T))aSyscall[32].pCurrent) + { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ - int))aSyscall[50].pCurrent) + int))aSyscall[33].pCurrent) { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, - #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ - LARGE_INTEGER*))aSyscall[51].pCurrent) + LARGE_INTEGER*))aSyscall[34].pCurrent) { "ReadFile", (SYSCALL)ReadFile, 0 }, - #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ - LPOVERLAPPED))aSyscall[52].pCurrent) + LPOVERLAPPED))aSyscall[35].pCurrent) { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent) -#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent) - -#if !SQLITE_OS_WINRT - { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, -#else - { "SetFilePointer", (SYSCALL)0, 0 }, -#endif - -#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ - DWORD))aSyscall[54].pCurrent) + { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, +#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER,\ + PLARGE_INTEGER,DWORD))aSyscall[37].pCurrent) -#if !SQLITE_OS_WINRT { "Sleep", (SYSCALL)Sleep, 0 }, -#else - { "Sleep", (SYSCALL)0, 0 }, -#endif - -#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent) - - { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[38].pCurrent) -#define osSystemTimeToFileTime ((BOOL(WINAPI*)(const SYSTEMTIME*, \ - LPFILETIME))aSyscall[56].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT - { "UnlockFile", (SYSCALL)UnlockFile, 0 }, -#else - { "UnlockFile", (SYSCALL)0, 0 }, -#endif - -#if !defined(osUnlockFile) && defined(SQLITE_WIN32_HAS_ANSI) -#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - DWORD))aSyscall[57].pCurrent) -#endif - -#if !SQLITE_OS_WINCE { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, -#else - { "UnlockFileEx", (SYSCALL)0, 0 }, -#endif - #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ - LPOVERLAPPED))aSyscall[58].pCurrent) + LPOVERLAPPED))aSyscall[39].pCurrent) -#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, #else { "UnmapViewOfFile", (SYSCALL)0, 0 }, #endif - -#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent) +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[40].pCurrent) { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, - #define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ - LPCSTR,LPBOOL))aSyscall[60].pCurrent) + LPCSTR,LPBOOL))aSyscall[41].pCurrent) { "WriteFile", (SYSCALL)WriteFile, 0 }, - #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ - LPOVERLAPPED))aSyscall[61].pCurrent) + LPOVERLAPPED))aSyscall[42].pCurrent) -#if SQLITE_OS_WINRT - { "CreateEventExW", (SYSCALL)CreateEventExW, 0 }, -#else - { "CreateEventExW", (SYSCALL)0, 0 }, -#endif - -#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ - DWORD,DWORD))aSyscall[62].pCurrent) - -/* -** 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 }, - #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ - DWORD))aSyscall[63].pCurrent) + DWORD))aSyscall[43].pCurrent) -#if !SQLITE_OS_WINCE { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, -#else - { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, -#endif - #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ - BOOL))aSyscall[64].pCurrent) + BOOL))aSyscall[44].pCurrent) -#if SQLITE_OS_WINRT - { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, -#else - { "SetFilePointerEx", (SYSCALL)0, 0 }, -#endif - -#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \ - PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent) - -#if SQLITE_OS_WINRT - { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 }, -#else - { "GetFileInformationByHandleEx", (SYSCALL)0, 0 }, -#endif - -#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ - FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent) - -#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) - { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, -#else - { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, -#endif - -#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ - SIZE_T))aSyscall[67].pCurrent) - -#if SQLITE_OS_WINRT - { "CreateFile2", (SYSCALL)CreateFile2, 0 }, -#else - { "CreateFile2", (SYSCALL)0, 0 }, -#endif - -#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \ - LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent) - -#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION) - { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 }, -#else - { "LoadPackagedLibrary", (SYSCALL)0, 0 }, -#endif - -#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \ - DWORD))aSyscall[69].pCurrent) - -#if SQLITE_OS_WINRT - { "GetTickCount64", (SYSCALL)GetTickCount64, 0 }, -#else - { "GetTickCount64", (SYSCALL)0, 0 }, -#endif - -#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent) - -#if SQLITE_OS_WINRT - { "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 }, -#else - { "GetNativeSystemInfo", (SYSCALL)0, 0 }, -#endif - -#define osGetNativeSystemInfo ((VOID(WINAPI*)( \ - LPSYSTEM_INFO))aSyscall[71].pCurrent) - -#if defined(SQLITE_WIN32_HAS_ANSI) { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, -#else - { "OutputDebugStringA", (SYSCALL)0, 0 }, -#endif - -#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent) - -#if defined(SQLITE_WIN32_HAS_WIDE) - { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, -#else - { "OutputDebugStringW", (SYSCALL)0, 0 }, -#endif - -#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent) +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[45].pCurrent) { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, - -#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent) - -#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) - { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, -#else - { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, -#endif - -#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ - LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent) +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[46].pCurrent) /* ** NOTE: On some sub-platforms, the InterlockedCompareExchange "function" @@ -48933,131 +49849,96 @@ static struct win_syscall { */ #if defined(InterlockedCompareExchange) { "InterlockedCompareExchange", (SYSCALL)0, 0 }, - #define osInterlockedCompareExchange InterlockedCompareExchange #else { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, - -#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \ - SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent) +#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*,\ + LONG,LONG))aSyscall[47].pCurrent) #endif /* defined(InterlockedCompareExchange) */ -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID +#if SQLITE_WIN32_USE_UUID { "UuidCreate", (SYSCALL)UuidCreate, 0 }, #else { "UuidCreate", (SYSCALL)0, 0 }, #endif +#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[48].pCurrent) -#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent) - -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID +#if SQLITE_WIN32_USE_UUID { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 }, #else { "UuidCreateSequential", (SYSCALL)0, 0 }, #endif - #define osUuidCreateSequential \ - ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent) + ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[49].pCurrent) #if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0 { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, #else { "FlushViewOfFile", (SYSCALL)0, 0 }, #endif - #define osFlushViewOfFile \ - ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) + ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[50].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[51].pCurrent) -#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) +#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[52].pCurrent) #ifndef _WIN32 { "getenv", (SYSCALL)getenv, 0 }, #else { "getenv", (SYSCALL)0, 0 }, #endif - -#define osGetenv ((const char *(*)(const char *))aSyscall[83].pCurrent) +#define osGetenv ((const char *(*)(const char *))aSyscall[53].pCurrent) #ifndef _WIN32 { "getcwd", (SYSCALL)getcwd, 0 }, #else { "getcwd", (SYSCALL)0, 0 }, #endif - -#define osGetcwd ((char*(*)(char*,size_t))aSyscall[84].pCurrent) +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[54].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) +#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[55].pCurrent) #ifndef _WIN32 { "lstat", (SYSCALL)lstat, 0 }, #else { "lstat", (SYSCALL)0, 0 }, #endif - -#define osLstat ((int(*)(const char*,struct stat*))aSyscall[86].pCurrent) +#define osLstat ((int(*)(const char*,struct stat*))aSyscall[56].pCurrent) #ifndef _WIN32 { "__errno", (SYSCALL)__errno, 0 }, #else { "__errno", (SYSCALL)0, 0 }, #endif - -#define osErrno (*((int*(*)(void))aSyscall[87].pCurrent)()) +#define osErrno (*((int*(*)(void))aSyscall[57].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) + const void *, void *, size_t))aSyscall[58].pCurrent) + + { "GetDriveTypeW", (SYSCALL)GetDriveTypeW, 0 }, +#define osGetDriveTypeW ((UINT(WINAPI*)(LPCWSTR))aSyscall[59].pCurrent) }; /* End of the overrideable system calls */ @@ -49145,6 +50026,9 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){ } #ifdef SQLITE_WIN32_MALLOC +#ifdef SQLITE_UWP +# error SQLITE_WIN32_MALLOC is incompatible with SQLITE_UWP +#endif /* ** If a Win32 native heap has been configured, this function will attempt to ** compact it. Upon success, SQLITE_OK will be returned. Upon failure, one @@ -49161,10 +50045,9 @@ SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){ hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){ DWORD lastErrno = osGetLastError(); if( lastErrno==NO_ERROR ){ @@ -49177,11 +50060,6 @@ SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){ rc = SQLITE_ERROR; } } -#else - sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p", - (void*)hHeap); - rc = SQLITE_NOTFOUND; -#endif if( pnLargest ) *pnLargest = nLargest; return rc; } @@ -49235,9 +50113,8 @@ SQLITE_API int sqlite3_win32_reset_heap(){ #ifdef _WIN32 /* ** This function outputs the specified (ANSI) string to the Win32 debugger -** (if available). +** (if available). Undocumented. Might go away at any moment. */ - SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE]; int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */ @@ -49249,7 +50126,6 @@ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ return; } #endif -#if defined(SQLITE_WIN32_HAS_ANSI) if( nMin>0 ){ memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); memcpy(zDbgBuf, zBuf, nMin); @@ -49257,49 +50133,13 @@ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ }else{ osOutputDebugStringA(zBuf); } -#elif defined(SQLITE_WIN32_HAS_WIDE) - memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); - if ( osMultiByteToWideChar( - osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf, - nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){ - return; - } - osOutputDebugStringW((LPCWSTR)zDbgBuf); -#else - if( nMin>0 ){ - memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); - memcpy(zDbgBuf, zBuf, nMin); - fprintf(stderr, "%s", zDbgBuf); - }else{ - fprintf(stderr, "%s", zBuf); - } -#endif } -#endif /* _WIN32 */ - -/* -** The following routine suspends the current thread for at least ms -** milliseconds. This is equivalent to the Win32 Sleep() interface. -*/ -#if SQLITE_OS_WINRT -static HANDLE sleepObj = NULL; -#endif SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){ -#if SQLITE_OS_WINRT - if ( sleepObj==NULL ){ - sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, - SYNCHRONIZE); - } - assert( sleepObj!=NULL ); - osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE); -#else osSleep(milliseconds); -#endif } -#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ - SQLITE_THREADSAFE>0 +#if SQLITE_MAX_WORKER_THREADS>0 && SQLITE_THREADSAFE>0 SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ DWORD rc; while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, @@ -49307,69 +50147,7 @@ SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ return rc; } #endif - -/* -** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, -** or WinCE. Return false (zero) for Win95, Win98, or WinME. -** -** Here is an interesting observation: Win95, Win98, and WinME lack -** the LockFileEx() API. But we can still statically link against that -** API as long as we don't call it when running Win95/98/ME. A call to -** this routine is used to determine if the host is Win95/98/ME or -** WinNT/2K/XP so that we will know whether or not we can safely call -** the LockFileEx() API. -*/ - -#if !SQLITE_WIN32_GETVERSIONEX -# define osIsNT() (1) -#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) -# define osIsNT() (1) -#elif !defined(SQLITE_WIN32_HAS_WIDE) -# define osIsNT() (0) -#else -# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) -#endif - -/* -** This function determines if the machine is running a version of Windows -** based on the NT kernel. -*/ -SQLITE_API int sqlite3_win32_is_nt(void){ -#if SQLITE_OS_WINRT - /* - ** NOTE: The WinRT sub-platform is always assumed to be based on the NT - ** kernel. - */ - return 1; -#elif SQLITE_WIN32_GETVERSIONEX - if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ -#if defined(SQLITE_WIN32_HAS_ANSI) - OSVERSIONINFOA sInfo; - sInfo.dwOSVersionInfoSize = sizeof(sInfo); - osGetVersionExA(&sInfo); - osInterlockedCompareExchange(&sqlite3_os_type, - (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); -#elif defined(SQLITE_WIN32_HAS_WIDE) - OSVERSIONINFOW sInfo; - sInfo.dwOSVersionInfoSize = sizeof(sInfo); - osGetVersionExW(&sInfo); - osInterlockedCompareExchange(&sqlite3_os_type, - (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); -#endif - } - return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; -#elif SQLITE_TEST - 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 - ** deprecated are always assumed to be based on the NT kernel. - */ - return 1; -#endif -} +#endif /* _WIN32 */ #ifdef SQLITE_WIN32_MALLOC /* @@ -49383,7 +50161,7 @@ static void *winMemMalloc(int nBytes){ hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif assert( nBytes>=0 ); @@ -49405,7 +50183,7 @@ static void winMemFree(void *pPrior){ hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); #endif if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ @@ -49426,7 +50204,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){ hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); #endif assert( nBytes>=0 ); @@ -49454,7 +50232,7 @@ static int winMemSize(void *p){ hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) ); #endif if( !p ) return 0; @@ -49484,7 +50262,7 @@ static int winMemInit(void *pAppData){ assert( pWinMemData->magic1==WINMEM_MAGIC1 ); assert( pWinMemData->magic2==WINMEM_MAGIC2 ); -#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE +#if SQLITE_WIN32_HEAP_CREATE if( !pWinMemData->hHeap ){ DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; @@ -49517,7 +50295,7 @@ static int winMemInit(void *pAppData){ #endif assert( pWinMemData->hHeap!=0 ); assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif return SQLITE_OK; @@ -49535,7 +50313,7 @@ static void winMemShutdown(void *pAppData){ if( pWinMemData->hHeap ){ assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE) +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); #endif if( pWinMemData->bOwned ){ @@ -49630,6 +50408,7 @@ static char *winUnicodeToUtf8(LPCWSTR zWideText){ return zText; } +#ifdef _WIN32 /* ** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM ** code page. @@ -49659,7 +50438,6 @@ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ return zMbcsText; } -#ifdef _WIN32 /* ** Convert a Microsoft Unicode string to a multi-byte character string, ** using the ANSI or OEM code page. @@ -49687,7 +50465,6 @@ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ } return zText; } -#endif /* _WIN32 */ /* ** Convert a multi-byte character string to UTF-8. @@ -49707,7 +50484,6 @@ static char *winMbcsToUtf8(const char *zText, int useAnsi){ return zTextUtf8; } -#ifdef _WIN32 /* ** Convert a UTF-8 string to a multi-byte character string. ** @@ -49757,7 +50533,6 @@ 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. @@ -49775,7 +50550,6 @@ 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. */ @@ -49914,63 +50688,24 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ */ DWORD dwLen = 0; char *zOut = 0; - - if( osIsNT() ){ -#if SQLITE_OS_WINRT - WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; - dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErrno, - 0, - zTempWide, - SQLITE_WIN32_MAX_ERRMSG_CHARS, - 0); -#else - LPWSTR zTempWide = NULL; - dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErrno, - 0, - (LPWSTR) &zTempWide, - 0, - 0); -#endif - if( dwLen > 0 ){ - /* allocate a buffer and convert to UTF8 */ - sqlite3BeginBenignMalloc(); - zOut = winUnicodeToUtf8(zTempWide); - sqlite3EndBenignMalloc(); -#if !SQLITE_OS_WINRT - /* free the system buffer allocated by FormatMessage */ - osLocalFree(zTempWide); -#endif - } - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - char *zTemp = NULL; - dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErrno, - 0, - (LPSTR) &zTemp, - 0, - 0); - if( dwLen > 0 ){ - /* allocate a buffer and convert to UTF8 */ - sqlite3BeginBenignMalloc(); - zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); - sqlite3EndBenignMalloc(); - /* free the system buffer allocated by FormatMessage */ - osLocalFree(zTemp); - } + LPWSTR zTempWide = NULL; + dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPWSTR) &zTempWide, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = winUnicodeToUtf8(zTempWide); + sqlite3EndBenignMalloc(); + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTempWide); } -#endif if( 0 == dwLen ){ sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); }else{ @@ -50077,13 +50812,13 @@ static int winRetryIoerr(int *pnRetry, DWORD *pError){ return 0; } if( winIoerrCanRetry1(e) ){ - sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + osSleep(winIoerrRetryDelay*(1+*pnRetry)); ++*pnRetry; return 1; } #if defined(winIoerrCanRetry2) else if( winIoerrCanRetry2(e) ){ - sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + osSleep(winIoerrRetryDelay*(1+*pnRetry)); ++*pnRetry; return 1; } @@ -50106,323 +50841,6 @@ static void winLogIoerr(int nRetry, int lineno){ } } -/* -** This #if does not rely on the SQLITE_OS_WINCE define because the -** corresponding section in "date.c" cannot use it. -*/ -#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ - (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) -/* -** The MSVC CRT on Windows CE may not have a localtime() function. -** So define a substitute. -*/ -/* # include */ -struct tm *__cdecl localtime(const time_t *t) -{ - static struct tm y; - FILETIME uTm, lTm; - SYSTEMTIME pTm; - sqlite3_int64 t64; - t64 = *t; - t64 = (t64 + 11644473600)*10000000; - uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); - uTm.dwHighDateTime= (DWORD)(t64 >> 32); - osFileTimeToLocalFileTime(&uTm,&lTm); - osFileTimeToSystemTime(&lTm,&pTm); - y.tm_year = pTm.wYear - 1900; - y.tm_mon = pTm.wMonth - 1; - y.tm_wday = pTm.wDayOfWeek; - y.tm_mday = pTm.wDay; - y.tm_hour = pTm.wHour; - y.tm_min = pTm.wMinute; - y.tm_sec = pTm.wSecond; - return &y; -} -#endif - -#if SQLITE_OS_WINCE -/************************************************************************* -** This section contains code for WinCE only. -*/ -#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] - -/* -** Acquire a lock on the handle h -*/ -static void winceMutexAcquire(HANDLE h){ - DWORD dwErr; - do { - dwErr = osWaitForSingleObject(h, INFINITE); - } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); -} -/* -** Release a lock acquired by winceMutexAcquire() -*/ -#define winceMutexRelease(h) ReleaseMutex(h) - -/* -** Create the mutex and shared memory used for locking in the file -** descriptor pFile -*/ -static int winceCreateLock(const char *zFilename, winFile *pFile){ - LPWSTR zTok; - LPWSTR zName; - DWORD lastErrno; - BOOL bLogged = FALSE; - BOOL bInit = TRUE; - - zName = winUtf8ToUnicode(zFilename); - if( zName==0 ){ - /* out of memory */ - return SQLITE_IOERR_NOMEM_BKPT; - } - - /* Initialize the local lockdata */ - memset(&pFile->local, 0, sizeof(pFile->local)); - - /* Replace the backslashes from the filename and lowercase it - ** to derive a mutex name. */ - zTok = osCharLowerW(zName); - for (;*zTok;zTok++){ - if (*zTok == '\\') *zTok = '_'; - } - - /* Create/open the named mutex */ - pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); - if (!pFile->hMutex){ - pFile->lastErrno = osGetLastError(); - sqlite3_free(zName); - return winLogError(SQLITE_IOERR, pFile->lastErrno, - "winceCreateLock1", zFilename); - } - - /* Acquire the mutex before continuing */ - winceMutexAcquire(pFile->hMutex); - - /* Since the names of named mutexes, semaphores, file mappings etc are - ** case-sensitive, take advantage of that by uppercasing the mutex name - ** and using that as the shared filemapping name. - */ - osCharUpperW(zName); - pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL, - PAGE_READWRITE, 0, sizeof(winceLock), - zName); - - /* Set a flag that indicates we're the first to create the memory so it - ** must be zero-initialized */ - lastErrno = osGetLastError(); - if (lastErrno == ERROR_ALREADY_EXISTS){ - bInit = FALSE; - } - - sqlite3_free(zName); - - /* If we succeeded in making the shared memory handle, map it. */ - if( pFile->hShared ){ - pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, - FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); - /* If mapping failed, close the shared memory handle and erase it */ - if( !pFile->shared ){ - pFile->lastErrno = osGetLastError(); - winLogError(SQLITE_IOERR, pFile->lastErrno, - "winceCreateLock2", zFilename); - bLogged = TRUE; - osCloseHandle(pFile->hShared); - pFile->hShared = NULL; - } - } - - /* If shared memory could not be created, then close the mutex and fail */ - if( pFile->hShared==NULL ){ - if( !bLogged ){ - pFile->lastErrno = lastErrno; - winLogError(SQLITE_IOERR, pFile->lastErrno, - "winceCreateLock3", zFilename); - bLogged = TRUE; - } - winceMutexRelease(pFile->hMutex); - osCloseHandle(pFile->hMutex); - pFile->hMutex = NULL; - return SQLITE_IOERR; - } - - /* Initialize the shared memory if we're supposed to */ - if( bInit ){ - memset(pFile->shared, 0, sizeof(winceLock)); - } - - winceMutexRelease(pFile->hMutex); - return SQLITE_OK; -} - -/* -** Destroy the part of winFile that deals with wince locks -*/ -static void winceDestroyLock(winFile *pFile){ - if (pFile->hMutex){ - /* Acquire the mutex */ - winceMutexAcquire(pFile->hMutex); - - /* The following blocks should probably assert in debug mode, but they - are to cleanup in case any locks remained open */ - if (pFile->local.nReaders){ - pFile->shared->nReaders --; - } - if (pFile->local.bReserved){ - pFile->shared->bReserved = FALSE; - } - if (pFile->local.bPending){ - pFile->shared->bPending = FALSE; - } - if (pFile->local.bExclusive){ - pFile->shared->bExclusive = FALSE; - } - - /* De-reference and close our copy of the shared memory handle */ - osUnmapViewOfFile(pFile->shared); - osCloseHandle(pFile->hShared); - - /* Done with the mutex */ - winceMutexRelease(pFile->hMutex); - osCloseHandle(pFile->hMutex); - pFile->hMutex = NULL; - } -} - -/* -** An implementation of the LockFile() API of Windows for CE -*/ -static BOOL winceLockFile( - LPHANDLE phFile, - DWORD dwFileOffsetLow, - DWORD dwFileOffsetHigh, - DWORD nNumberOfBytesToLockLow, - DWORD nNumberOfBytesToLockHigh -){ - winFile *pFile = HANDLE_TO_WINFILE(phFile); - BOOL bReturn = FALSE; - - UNUSED_PARAMETER(dwFileOffsetHigh); - UNUSED_PARAMETER(nNumberOfBytesToLockHigh); - - if (!pFile->hMutex) return TRUE; - winceMutexAcquire(pFile->hMutex); - - /* Wanting an exclusive lock? */ - if (dwFileOffsetLow == (DWORD)SHARED_FIRST - && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ - if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ - pFile->shared->bExclusive = TRUE; - pFile->local.bExclusive = TRUE; - bReturn = TRUE; - } - } - - /* Want a read-only lock? */ - else if (dwFileOffsetLow == (DWORD)SHARED_FIRST && - nNumberOfBytesToLockLow == 1){ - if (pFile->shared->bExclusive == 0){ - pFile->local.nReaders ++; - if (pFile->local.nReaders == 1){ - pFile->shared->nReaders ++; - } - bReturn = TRUE; - } - } - - /* Want a pending lock? */ - else if (dwFileOffsetLow == (DWORD)PENDING_BYTE - && nNumberOfBytesToLockLow == 1){ - /* If no pending lock has been acquired, then acquire it */ - if (pFile->shared->bPending == 0) { - pFile->shared->bPending = TRUE; - pFile->local.bPending = TRUE; - bReturn = TRUE; - } - } - - /* Want a reserved lock? */ - else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE - && nNumberOfBytesToLockLow == 1){ - if (pFile->shared->bReserved == 0) { - pFile->shared->bReserved = TRUE; - pFile->local.bReserved = TRUE; - bReturn = TRUE; - } - } - - winceMutexRelease(pFile->hMutex); - return bReturn; -} - -/* -** An implementation of the UnlockFile API of Windows for CE -*/ -static BOOL winceUnlockFile( - LPHANDLE phFile, - DWORD dwFileOffsetLow, - DWORD dwFileOffsetHigh, - DWORD nNumberOfBytesToUnlockLow, - DWORD nNumberOfBytesToUnlockHigh -){ - winFile *pFile = HANDLE_TO_WINFILE(phFile); - BOOL bReturn = FALSE; - - UNUSED_PARAMETER(dwFileOffsetHigh); - UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh); - - if (!pFile->hMutex) return TRUE; - winceMutexAcquire(pFile->hMutex); - - /* Releasing a reader lock or an exclusive lock */ - if (dwFileOffsetLow == (DWORD)SHARED_FIRST){ - /* Did we have an exclusive lock? */ - if (pFile->local.bExclusive){ - assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE); - pFile->local.bExclusive = FALSE; - pFile->shared->bExclusive = FALSE; - bReturn = TRUE; - } - - /* Did we just have a reader lock? */ - else if (pFile->local.nReaders){ - assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE - || nNumberOfBytesToUnlockLow == 1); - pFile->local.nReaders --; - if (pFile->local.nReaders == 0) - { - pFile->shared->nReaders --; - } - bReturn = TRUE; - } - } - - /* Releasing a pending lock */ - else if (dwFileOffsetLow == (DWORD)PENDING_BYTE - && nNumberOfBytesToUnlockLow == 1){ - if (pFile->local.bPending){ - pFile->local.bPending = FALSE; - pFile->shared->bPending = FALSE; - bReturn = TRUE; - } - } - /* Releasing a reserved lock */ - else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE - && nNumberOfBytesToUnlockLow == 1){ - if (pFile->local.bReserved) { - pFile->local.bReserved = FALSE; - pFile->shared->bReserved = FALSE; - bReturn = TRUE; - } - } - - winceMutexRelease(pFile->hMutex); - return bReturn; -} -/* -** End of the special code for wince -*****************************************************************************/ -#endif /* SQLITE_OS_WINCE */ /* ** Lock a file region. @@ -50435,27 +50853,11 @@ static BOOL winLockFile( DWORD numBytesLow, DWORD numBytesHigh ){ -#if SQLITE_OS_WINCE - /* - ** NOTE: Windows CE is handled differently here due its lack of the Win32 - ** API LockFile. - */ - return winceLockFile(phFile, offsetLow, offsetHigh, - numBytesLow, numBytesHigh); -#else - if( osIsNT() ){ - OVERLAPPED ovlp; - memset(&ovlp, 0, sizeof(OVERLAPPED)); - 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 + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); } #ifndef SQLITE_OMIT_WAL @@ -50479,63 +50881,56 @@ static int winHandleLockTimeout( DWORD flags = LOCKFILE_FAIL_IMMEDIATELY | (bExcl?LOCKFILE_EXCLUSIVE_LOCK:0); int rc = SQLITE_OK; BOOL ret; + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offset; - 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; - } +#if defined(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 ){ + ret = osLockFileEx(hFile, flags, 0, nByte, 0, &ovlp); +#if defined(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; + rc = SQLITE_BUSY_TIMEOUT; #else - rc = SQLITE_BUSY; + 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); + }else{ + /* Some other error has occurred */ + rc = SQLITE_IOERR_LOCK; } - osCloseHandle(ovlp.hEvent); -#endif + /* If it is still pending, cancel the LockFileEx() call. */ + osCancelIo(hFile); } + osCloseHandle(ovlp.hEvent); +#endif /* defined(SQLITE_ENABLE_SETLK_TIMEOUT) */ + if( rc==SQLITE_OK && !ret ){ rc = SQLITE_BUSY; } @@ -50553,27 +50948,11 @@ static BOOL winUnlockFile( DWORD numBytesLow, DWORD numBytesHigh ){ -#if SQLITE_OS_WINCE - /* - ** NOTE: Windows CE is handled differently here due its lack of the Win32 - ** API UnlockFile. - */ - return winceUnlockFile(phFile, offsetLow, offsetHigh, - numBytesLow, numBytesHigh); -#else - if( osIsNT() ){ - OVERLAPPED ovlp; - memset(&ovlp, 0, sizeof(OVERLAPPED)); - 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 + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); } #ifndef SQLITE_OMIT_WAL @@ -50606,43 +50985,13 @@ static int winHandleUnlock(HANDLE h, int iOff, int nByte){ */ 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() */ - - 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(). */ - if( dwRet==INVALID_SET_FILE_POINTER ){ - DWORD lastErrno = osGetLastError(); - if( lastErrno!=NO_ERROR ){ - rc = SQLITE_IOERR_SEEK; - } - } -#else - /* This implementation works for WinRT. */ - LARGE_INTEGER x; /* The new offset */ - BOOL bRet; /* Value returned by SetFilePointerEx() */ + LARGE_INTEGER x; /* The offset */ x.QuadPart = iOffset; - bRet = osSetFilePointerEx(h, x, 0, FILE_BEGIN); - - if(!bRet){ + if( osSetFilePointerEx(h, x, 0, FILE_BEGIN)==0 ){ rc = SQLITE_IOERR_SEEK; } -#endif - - OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset, sqlite3ErrName(rc))); + OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset,sqlite3ErrName(rc))); return rc; } @@ -50699,27 +51048,7 @@ static int winClose(sqlite3_file *id){ do{ rc = osCloseHandle(pFile->h); /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ - }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); -#if SQLITE_OS_WINCE -#define WINCE_DELETION_ATTEMPTS 3 - { - winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData; - if( pAppData==NULL || !pAppData->bNoLock ){ - winceDestroyLock(pFile); - } - } - if( pFile->zDeleteOnClose ){ - int cnt = 0; - while( - osDeleteFileW(pFile->zDeleteOnClose)==0 - && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff - && cnt++ < WINCE_DELETION_ATTEMPTS - ){ - sqlite3_win32_sleep(100); /* Wait a little before trying again */ - } - sqlite3_free(pFile->zDeleteOnClose); - } -#endif + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (osSleep(100), 1) ); if( rc ){ pFile->h = NULL; } @@ -50742,7 +51071,7 @@ static int winRead( int amt, /* Number of bytes to read */ sqlite3_int64 offset /* Begin reading at this offset */ ){ -#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) +#if !defined(SQLITE_WIN32_NO_OVERLAPPED) OVERLAPPED overlapped; /* The offset for ReadFile. */ #endif winFile *pFile = (winFile*)id; /* file handle */ @@ -50776,7 +51105,7 @@ static int winRead( } #endif -#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) +#if defined(SQLITE_WIN32_NO_OVERLAPPED) if( winSeekFile(pFile, offset) ){ OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", osGetCurrentProcessId(), pFile, pFile->h)); @@ -50854,13 +51183,13 @@ static int winWrite( } #endif -#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) +#if defined(SQLITE_WIN32_NO_OVERLAPPED) rc = winSeekFile(pFile, offset); if( rc==0 ){ #else { #endif -#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) +#if !defined(SQLITE_WIN32_NO_OVERLAPPED) OVERLAPPED overlapped; /* The offset for WriteFile. */ #endif u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ @@ -50868,14 +51197,14 @@ static int winWrite( DWORD nWrite; /* Bytes written by each WriteFile() call */ DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ -#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) +#if !defined(SQLITE_WIN32_NO_OVERLAPPED) memset(&overlapped, 0, sizeof(OVERLAPPED)); overlapped.Offset = (LONG)(offset & 0xffffffff); overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); #endif while( nRem>0 ){ -#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) +#if defined(SQLITE_WIN32_NO_OVERLAPPED) if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ #else if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ @@ -50888,7 +51217,7 @@ static int winWrite( lastErrno = osGetLastError(); break; } -#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) +#if !defined(SQLITE_WIN32_NO_OVERLAPPED) offset += nWrite; overlapped.Offset = (LONG)(offset & 0xffffffff); overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); @@ -50943,28 +51272,14 @@ static int winHandleTruncate(HANDLE h, sqlite3_int64 nByte){ */ 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; - + LARGE_INTEGER x; assert( pnByte ); - lowerBits = osGetFileSize(h, &upperBits); - *pnByte = (((sqlite3_int64)upperBits)<<32) + lowerBits; - if( lowerBits==INVALID_FILE_SIZE && osGetLastError()!=NO_ERROR ){ + if( osGetFileSizeEx(h, &x)==0 ){ rc = SQLITE_IOERR_FSTAT; + *pnByte = 0; + }else{ + *pnByte = x.QuadPart; } -#endif - return rc; } @@ -51163,35 +51478,17 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ assert( pSize!=0 ); SimulateIOError(return SQLITE_IOERR_FSTAT); OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); - -#if SQLITE_OS_WINRT { - FILE_STANDARD_INFO info; - if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, - &info, sizeof(info)) ){ - *pSize = info.EndOfFile.QuadPart; - }else{ + LARGE_INTEGER x; + if( osGetFileSizeEx(pFile->h, &x)==0 ){ + *pSize = 0; pFile->lastErrno = osGetLastError(); rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, "winFileSize", pFile->zPath); + }else{ + *pSize = x.QuadPart; } } -#else - { - DWORD upperBits; - DWORD lowerBits; - DWORD lastErrno; - - lowerBits = osGetFileSize(pFile->h, &upperBits); - *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; - if( (lowerBits == INVALID_FILE_SIZE) - && ((lastErrno = osGetLastError())!=NO_ERROR) ){ - pFile->lastErrno = lastErrno; - rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, - "winFileSize", pFile->zPath); - } - } -#endif OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", pFile->h, pSize, *pSize, sqlite3ErrName(rc))); return rc; @@ -51237,27 +51534,8 @@ 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 - /* - ** NOTE: Windows CE is handled differently here due its lack of the Win32 - ** API LockFileEx. - */ - res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); -#else - res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS&mask, SHARED_FIRST, 0, - SHARED_SIZE, 0); -#endif - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - int lk; - sqlite3_randomness(sizeof(lk), &lk); - pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); - res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS&mask, - SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); - } -#endif + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS&mask, SHARED_FIRST, 0, + SHARED_SIZE, 0); if( res == 0 ){ pFile->lastErrno = osGetLastError(); /* No need to log a failure to lock */ @@ -51273,14 +51551,7 @@ static int winUnlockReadLock(winFile *pFile){ int res; DWORD lastErrno; OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); - if( osIsNT() ){ - res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); - } -#endif + res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ pFile->lastErrno = lastErrno; winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, @@ -51391,7 +51662,7 @@ static int winLock(sqlite3_file *id, int locktype){ } cnt--; - if( cnt>0 ) sqlite3_win32_sleep(1); + if( cnt>0 ) osSleep(1); } gotPendingLock = res; } @@ -51600,7 +51871,7 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ /* Forward references to VFS helper methods used for temporary files */ static int winGetTempname(sqlite3_vfs *, char **); -static int winIsDir(const void *); +static int winIsDir(LPCWSTR); static BOOL winIsLongPathPrefix(const char *); static BOOL winIsDriveLetterAndColon(const char *); @@ -51832,80 +52103,70 @@ static SYSTEM_INFO winSysInfo; ** happen when the file path >32k, in which case winUtf8ToUnicode() ** will fail too. */ -static void *winConvertFromUtf8Filename(const char *zFilename){ - void *zConverted = 0; - if( osIsNT() ){ +static LPWSTR winConvertFromUtf8Filename(const char *zFilename){ + LPWSTR zConverted = 0; #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; + int nChar; + + 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; + } + /* Filenames should be prefixed, except when converted + * full path already starts with "\\?\". */ + if( osCygwin_conv_path(convertflag, zFilename, + zConverted+4, nByte)==0 ){ + if( (convertflag&CCP_RELATIVE) ){ + memmove(zConverted, zConverted+4, nByte); + }else if( memcmp(zConverted+4, L"\\\\", 4) ){ + memcpy(zConverted, L"\\\\?\\", 8); + }else if( zConverted[6]!='?' ){ + memmove(zConverted+6, zConverted+4, nByte); + memcpy(zConverted, L"\\\\?\\UNC", 14); + }else{ + memmove(zConverted, zConverted+4, nByte); } - sqlite3_free(zConverted); + 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()); + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + if( nChar==0 ){ + return 0; } -#endif + zConverted = sqlite3MallocZero( ((u64)nChar+6)*sizeof(WCHAR) ); + if( zConverted==0 ){ + return 0; + } + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, + zConverted, nChar); + if( nChar==0 ){ + sqlite3_free(zConverted); + zConverted = 0; + }else if( nChar>MAX_PATH + && winIsDriveLetterAndColon(zFilename) + && winIsDirSep(zFilename[2]) ){ + memmove(zConverted+4, zConverted, nChar*sizeof(WCHAR)); + zConverted[2] = '\\'; + memcpy(zConverted, L"\\\\?\\", 8); + }else if( nChar>MAX_PATH + && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) + && zFilename[2] != '?' ){ + memmove(zConverted+6, zConverted, nChar*sizeof(WCHAR)); + memcpy(zConverted, L"\\\\?\\UNC", 14); + } +#else /* if !defined(__CYGWIN__) */ + zConverted = winUtf8ToUnicode(zFilename); +#endif /* __CYGWIN__ */ /* caller will handle out of memory */ return zConverted; } @@ -52073,6 +52334,28 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ } } +/* +** Handle h is open on the *-shm file. This function zeroes the first +** 8 bytes of the file. If SQLITE_ENABLE_SETLK_TIMEOUT is defined, h may +** have been opened with FILE_FLAG_OVERLAPPED. +*/ +static int winZeroSharedMemory(HANDLE h){ + u8 aZero[8] = {0,0,0,0,0,0,0,0}; + DWORD nWrite = 0; + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + if( !osWriteFile(h, aZero, sizeof(aZero), &nWrite, &ovlp) ){ + /* If the file was opened with FILE_FLAG_OVERLAPPED, the write may still + ** be pending. Wait for it with GetOverlappedResult(). */ + if( osGetLastError()!=ERROR_IO_PENDING + || !GetOverlappedResult(h, &ovlp, &nWrite, TRUE) + ){ + nWrite = 0; + } + } + return (nWrite==sizeof(aZero) ? SQLITE_OK : SQLITE_IOERR_WRITE); +} + /* ** The DMS lock has not yet been taken on the shm file associated with ** pShmNode. Take the lock. Truncate the *-shm file if required. @@ -52091,7 +52374,12 @@ static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){ if( pShmNode->isReadonly ){ rc = SQLITE_READONLY_CANTINIT; }else{ - rc = winHandleTruncate(h, 0); + if( SQLITE_OK!=winHandleTruncate(h, 0) ){ + /* Sometimes the truncate operation may fail because some other + ** process is still holding an open mapping. So try to write + ** zeroes into the start of the file instead. */ + rc = winZeroSharedMemory(h); + } } /* Release the EXCLUSIVE lock acquired above. */ @@ -52124,7 +52412,7 @@ static int winHandleOpen( HANDLE *ph /* OUT: New HANDLE for file */ ){ int rc = SQLITE_OK; - void *zConverted = 0; + LPWSTR zConverted = 0; int bReadonly = *pbReadonly; HANDLE h = INVALID_HANDLE_VALUE; @@ -52152,44 +52440,14 @@ static int winHandleOpen( /* 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 - } + h = osCreateFileW(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 + ); if( h==INVALID_HANDLE_VALUE ){ if( bReadonly==0 ){ @@ -52253,15 +52511,50 @@ SQLITE_API int sqlite3_win_test_unc_locking = 0; /* ** Return true if the string passed as the only argument is likely -** to be a UNC path. In other words, if it starts with "\\". +** to be a UNC path. Return false if not. +** +** Return true if: +** +** (1) The name begins with "\\" +** (2) But does not begin with "\\?\C:\" where C can be any alphabetic +** character. +** +** For testing, also return true in all cases if the global variable +** sqlite3_win_test_unc_locking is true. */ static int winIsUNCPath(const char *zFile){ if( zFile[0]=='\\' && zFile[1]=='\\' ){ - return 1; + if( zFile[2]=='?' + && zFile[3]=='\\' + && sqlite3Isalpha(zFile[4]) + && zFile[5]==':' + && winIsDirSep(zFile[6]) + ){ + return sqlite3_win_test_unc_locking; + }else{ + return 1; + } } return sqlite3_win_test_unc_locking; } +/* +** Return true if the string passed in is the name of a file on a +** remote (network-mounted) volume. +*/ +static int winIsRemoteVolume(const char *zFile){ + WCHAR zRoot[4]; + if( strncmp(zFile, "\\\\?\\",4)==0 ) zFile += 4; + if( !sqlite3Isalpha(zFile[0]) ) return 0; + if( zFile[1]!=':' ) return 0; + if( !winIsDirSep(zFile[2]) ) return 0; + zRoot[0] = (WCHAR)zFile[0]; + zRoot[1] = ':'; + zRoot[2] = '\\'; + zRoot[3] = 0; + return osGetDriveTypeW(zRoot)==DRIVE_REMOTE; +} + /* ** Open the shared-memory area associated with database file pDbFd. */ @@ -52287,7 +52580,11 @@ static int winOpenSharedMemory(winFile *pDbFd){ pNew->zFilename = (char*)&pNew[1]; pNew->hSharedShm = INVALID_HANDLE_VALUE; pNew->isUnlocked = 1; - pNew->bUseSharedLockHandle = winIsUNCPath(pDbFd->zPath); + if( winIsUNCPath(pDbFd->zPath) || winIsRemoteVolume(pDbFd->zPath) ){ + pNew->bUseSharedLockHandle = 1; + }else{ + pNew->bUseSharedLockHandle = 0; + } sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); @@ -52595,7 +52892,7 @@ static int winShmMap( if( pShmNode->nRegion<=iRegion ){ HANDLE hShared = pShmNode->hSharedShm; struct ShmRegion *apNew; /* New aRegion[] array */ - int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + i64 nByte = ((i64)iRegion+1)*(i64)szRegion; /* Minimum file size */ sqlite3_int64 sz; /* Current size of wal-index file */ pShmNode->szRegion = szRegion; @@ -52626,7 +52923,7 @@ static int winShmMap( /* Map the requested memory region into this processes address space. */ apNew = (struct ShmRegion*)sqlite3_realloc64( - pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) + pShmNode->aRegion, ((i64)iRegion+1)*sizeof(apNew[0]) ); if( !apNew ){ rc = SQLITE_IOERR_NOMEM_BKPT; @@ -52643,27 +52940,24 @@ static int winShmMap( HANDLE hMap = NULL; /* file-mapping handle */ void *pMap = 0; /* Mapped memory region */ -#if SQLITE_OS_WINRT +#ifdef SQLITE_UWP hMap = osCreateFileMappingFromApp(hShared, NULL, protect, nByte, NULL); -#elif defined(SQLITE_WIN32_HAS_WIDE) +#else hMap = osCreateFileMappingW(hShared, NULL, protect, 0, nByte, NULL); -#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA - hMap = osCreateFileMappingA(hShared, NULL, protect, 0, nByte, NULL); #endif - - OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", + OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%lld, rc=%s\n", osGetCurrentProcessId(), pShmNode->nRegion, nByte, hMap ? "ok" : "failed")); if( hMap ){ - int iOffset = pShmNode->nRegion*szRegion; + i64 iOffset = pShmNode->nRegion*szRegion; int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; -#if SQLITE_OS_WINRT +#ifdef SQLITE_UWP pMap = osMapViewOfFileFromApp(hMap, flags, - iOffset - iOffsetShift, szRegion + iOffsetShift + iOffset - iOffsetShift, (i64)szRegion + iOffsetShift ); #else pMap = osMapViewOfFile(hMap, flags, - 0, iOffset - iOffsetShift, szRegion + iOffsetShift + 0, iOffset - iOffsetShift, (i64)szRegion + iOffsetShift ); #endif OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", @@ -52686,7 +52980,7 @@ static int winShmMap( shmpage_out: if( pShmNode->nRegion>iRegion ){ - int iOffset = iRegion*szRegion; + i64 iOffset = (i64)iRegion*(i64)szRegion; int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; char *p = (char *)pShmNode->aRegion[iRegion].pMap; *pp = (void *)&p[iOffsetShift]; @@ -52798,16 +53092,12 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ flags |= FILE_MAP_WRITE; } #endif -#if SQLITE_OS_WINRT +#ifdef SQLITE_UWP pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL); -#elif defined(SQLITE_WIN32_HAS_WIDE) +#else pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, (DWORD)((nMap>>32) & 0xffffffff), (DWORD)(nMap & 0xffffffff), NULL); -#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA - pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, - (DWORD)((nMap>>32) & 0xffffffff), - (DWORD)(nMap & 0xffffffff), NULL); #endif if( pFd->hMap==NULL ){ pFd->lastErrno = osGetLastError(); @@ -52820,7 +53110,7 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ } assert( (nMap % winSysInfo.dwPageSize)==0 ); assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); -#if SQLITE_OS_WINRT +#ifdef SQLITE_UWP pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); #else pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); @@ -53134,7 +53424,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ if( !azDirs[3] ) azDirs[3] = osGetenv("TEMP"); if( !azDirs[4] ) azDirs[4] = osGetenv("USERPROFILE"); for(i=0; ih = INVALID_HANDLE_VALUE; -#if SQLITE_OS_WINRT - if( !zUtf8Name && !sqlite3_temp_directory ){ - sqlite3_log(SQLITE_ERROR, - "sqlite3_temp_directory variable should be set for WinRT"); - } -#endif - /* If the second argument to this function is NULL, generate a ** temporary file name to use */ @@ -53459,87 +53703,28 @@ static int winOpen( } if( isDelete ){ -#if SQLITE_OS_WINCE - dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; - isTemp = 1; -#else dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN | FILE_FLAG_DELETE_ON_CLOSE; -#endif }else{ dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; } - /* Reports from the internet are that performance is always - ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ -#if SQLITE_OS_WINCE - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; -#endif - - if( osIsNT() ){ -#if SQLITE_OS_WINRT - CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; - extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); - extendedParameters.dwFileAttributes = - dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; - extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK; - extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; - extendedParameters.lpSecurityAttributes = NULL; - extendedParameters.hTemplateFile = NULL; - do{ - h = osCreateFile2((LPCWSTR)zConverted, - dwDesiredAccess, - dwShareMode, - dwCreationDisposition, - &extendedParameters); - if( h!=INVALID_HANDLE_VALUE ) break; - if( isReadWrite ){ - int rc2; - sqlite3BeginBenignMalloc(); - rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); - sqlite3EndBenignMalloc(); - if( rc2==SQLITE_OK && isRO ) break; - } - }while( winRetryIoerr(&cnt, &lastErrno) ); -#else - do{ - h = osCreateFileW((LPCWSTR)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL); - if( h!=INVALID_HANDLE_VALUE ) break; - if( isReadWrite ){ - int rc2; - sqlite3BeginBenignMalloc(); - rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); - sqlite3EndBenignMalloc(); - if( rc2==SQLITE_OK && isRO ) break; - } - }while( winRetryIoerr(&cnt, &lastErrno) ); -#endif - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - do{ - h = osCreateFileA((LPCSTR)zConverted, - dwDesiredAccess, - dwShareMode, NULL, - dwCreationDisposition, - dwFlagsAndAttributes, - NULL); - if( h!=INVALID_HANDLE_VALUE ) break; - if( isReadWrite ){ - int rc2; - sqlite3BeginBenignMalloc(); - rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); - sqlite3EndBenignMalloc(); - if( rc2==SQLITE_OK && isRO ) break; - } - }while( winRetryIoerr(&cnt, &lastErrno) ); - } -#endif + do{ + h = osCreateFileW(zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); winLogIoerr(cnt, __LINE__); OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, @@ -53574,27 +53759,7 @@ static int winOpen( pAppData = (winVfsAppData*)pVfs->pAppData; -#if SQLITE_OS_WINCE - { - if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB - && ((pAppData==NULL) || !pAppData->bNoLock) - && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK - ){ - osCloseHandle(h); - sqlite3_free(zConverted); - sqlite3_free(zTmpname); - OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); - return rc; - } - } - if( isTemp ){ - pFile->zDeleteOnClose = zConverted; - }else -#endif - { - sqlite3_free(zConverted); - } - + sqlite3_free(zConverted); sqlite3_free(zTmpname); id->pMethods = pAppData ? pAppData->pMethod : &winIoMethod; pFile->pVfs = pVfs; @@ -53641,7 +53806,7 @@ static int winDelete( int rc; DWORD attr; DWORD lastErrno = 0; - void *zConverted; + LPWSTR zConverted; UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(syncDir); @@ -53653,80 +53818,31 @@ static int winDelete( OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); return SQLITE_IOERR_NOMEM_BKPT; } - if( osIsNT() ){ - do { -#if SQLITE_OS_WINRT - WIN32_FILE_ATTRIBUTE_DATA sAttrData; - memset(&sAttrData, 0, sizeof(sAttrData)); - if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, - &sAttrData) ){ - attr = sAttrData.dwFileAttributes; + do { + attr = osGetFileAttributesW(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ }else{ - lastErrno = osGetLastError(); - if( lastErrno==ERROR_FILE_NOT_FOUND - || lastErrno==ERROR_PATH_NOT_FOUND ){ - rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ - }else{ - rc = SQLITE_ERROR; - } - break; - } -#else - attr = osGetFileAttributesW(zConverted); -#endif - if ( attr==INVALID_FILE_ATTRIBUTES ){ - lastErrno = osGetLastError(); - if( lastErrno==ERROR_FILE_NOT_FOUND - || lastErrno==ERROR_PATH_NOT_FOUND ){ - rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ - }else{ - rc = SQLITE_ERROR; - } - break; - } - if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ - rc = SQLITE_ERROR; /* Files only. */ - break; - } - if ( osDeleteFileW(zConverted) ){ - rc = SQLITE_OK; /* Deleted OK. */ - break; - } - if ( !winRetryIoerr(&cnt, &lastErrno) ){ - rc = SQLITE_ERROR; /* No more retries. */ - break; - } - } while(1); - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - do { - attr = osGetFileAttributesA(zConverted); - if ( attr==INVALID_FILE_ATTRIBUTES ){ - lastErrno = osGetLastError(); - if( lastErrno==ERROR_FILE_NOT_FOUND - || lastErrno==ERROR_PATH_NOT_FOUND ){ - rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ - }else{ - rc = SQLITE_ERROR; - } - break; - } - if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ - rc = SQLITE_ERROR; /* Files only. */ - break; - } - if ( osDeleteFileA(zConverted) ){ - rc = SQLITE_OK; /* Deleted OK. */ - break; - } - if ( !winRetryIoerr(&cnt, &lastErrno) ){ - rc = SQLITE_ERROR; /* No more retries. */ - break; + rc = SQLITE_ERROR; } - } while(1); - } -#endif + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileW(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !winRetryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); }else{ @@ -53748,9 +53864,11 @@ static int winAccess( ){ DWORD attr; int rc = 0; + int cnt = 0; DWORD lastErrno = 0; - void *zConverted; + LPWSTR zConverted; int noRetry = 0; /* Do not use winRetryIoerr() */ + WIN32_FILE_ATTRIBUTE_DATA sAttrData; UNUSED_PARAMETER(pVfs); if( (flags & NORETRY)!=0 ){ @@ -53774,43 +53892,35 @@ static int winAccess( OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); return SQLITE_IOERR_NOMEM_BKPT; } - if( osIsNT() ){ - int cnt = 0; - WIN32_FILE_ATTRIBUTE_DATA sAttrData; - memset(&sAttrData, 0, sizeof(sAttrData)); - while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, - GetFileExInfoStandard, - &sAttrData)) - && !noRetry - && winRetryIoerr(&cnt, &lastErrno) - ){ /* Loop until true */} - if( rc ){ - /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file - ** as if it does not exist. - */ - if( flags==SQLITE_ACCESS_EXISTS - && sAttrData.nFileSizeHigh==0 - && sAttrData.nFileSizeLow==0 ){ - attr = INVALID_FILE_ATTRIBUTES; - }else{ - attr = sAttrData.dwFileAttributes; - } + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW(zConverted, + GetFileExInfoStandard, + &sAttrData)) + && !noRetry + && winRetryIoerr(&cnt, &lastErrno) + ){ /* Loop until true */} + if( rc ){ + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file + ** as if it does not exist. + */ + if( flags==SQLITE_ACCESS_EXISTS + && sAttrData.nFileSizeHigh==0 + && sAttrData.nFileSizeLow==0 ){ + attr = INVALID_FILE_ATTRIBUTES; }else{ - winLogIoerr(cnt, __LINE__); - if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ - sqlite3_free(zConverted); - return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", - zFilename); - }else{ - attr = INVALID_FILE_ATTRIBUTES; - } + attr = sAttrData.dwFileAttributes; + } + }else{ + if( noRetry ) lastErrno = osGetLastError(); + winLogIoerr(cnt, __LINE__); + if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", + zFilename); + }else{ + attr = INVALID_FILE_ATTRIBUTES; } } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - attr = osGetFileAttributesA((char*)zConverted); - } -#endif sqlite3_free(zConverted); switch( flags ){ case SQLITE_ACCESS_READ: @@ -53964,11 +54074,9 @@ static int winFullPathnameNoMutex( int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT int nByte; - void *zConverted; + LPWSTR zConverted; char *zOut; -#endif /* If this path name begins with "/X:" or "\\?\", where "X" is any ** alphabetic character, discard the initial "/" from the pathname. @@ -53985,22 +54093,23 @@ static int winFullPathnameNoMutex( 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 */ + 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. */ + /* 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); + rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)myErrno, + "lstat", zIn); } }else{ bLink = ((buf.st_mode & 0170000) == 0120000); @@ -54017,7 +54126,8 @@ static int winFullPathnameNoMutex( if( rc==SQLITE_OK ){ nByte = osReadlink(zIn, zDel, nFull-1); if( nByte ==(DWORD)-1 ){ - rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "readlink", zIn); + rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, + "readlink", zIn); }else{ if( zDel[0]!='/' ){ int n; @@ -54053,26 +54163,6 @@ static int winFullPathnameNoMutex( } #endif /* __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. */ - 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 backslash. - */ - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", - sqlite3_data_directory, winGetDirSep(), zRelative); - }else{ - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); - } - return SQLITE_OK; -#endif - -#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 @@ -54096,21 +54186,21 @@ static int winFullPathnameNoMutex( if( zConverted==0 ){ return SQLITE_IOERR_NOMEM_BKPT; } - if( osIsNT() ){ + { LPWSTR zTemp; - nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); + nByte = osGetFullPathNameW(zConverted, 0, 0, 0); if( nByte==0 ){ sqlite3_free(zConverted); return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), "winFullPathname1", zRelative); } nByte += 3; - zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); + zTemp = sqlite3MallocZero( (u64)nByte*sizeof(WCHAR) ); if( zTemp==0 ){ sqlite3_free(zConverted); return SQLITE_IOERR_NOMEM_BKPT; } - nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); + nByte = osGetFullPathNameW(zConverted, nByte, zTemp, 0); if( nByte==0 ){ sqlite3_free(zConverted); sqlite3_free(zTemp); @@ -54121,32 +54211,6 @@ static int winFullPathnameNoMutex( zOut = winUnicodeToUtf8(zTemp); sqlite3_free(zTemp); } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - char *zTemp; - nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); - if( nByte==0 ){ - sqlite3_free(zConverted); - return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), - "winFullPathname3", zRelative); - } - 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+3, zTemp, 0); - if( nByte==0 ){ - sqlite3_free(zConverted); - sqlite3_free(zTemp); - return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), - "winFullPathname4", zRelative); - } - sqlite3_free(zConverted); - zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); - sqlite3_free(zTemp); - } -#endif if( zOut ){ #ifdef __CYGWIN__ if( memcmp(zOut, "\\\\?\\", 4) ){ @@ -54173,7 +54237,6 @@ static int winFullPathnameNoMutex( }else{ return SQLITE_IOERR_NOMEM_BKPT; } -#endif } static int winFullPathname( sqlite3_vfs *pVfs, /* Pointer to vfs object */ @@ -54196,25 +54259,14 @@ static int winFullPathname( ** within the shared library, and closing the shared library. */ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ - HANDLE h; - void *zConverted = winConvertFromUtf8Filename(zFilename); + HANDLE h = 0; + LPWSTR zConverted = winConvertFromUtf8Filename(zFilename); UNUSED_PARAMETER(pVfs); if( zConverted==0 ){ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); return 0; } - if( osIsNT() ){ -#if SQLITE_OS_WINRT - h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); -#else - h = osLoadLibraryW((LPCWSTR)zConverted); -#endif - } -#ifdef SQLITE_WIN32_HAS_ANSI - else{ - h = osLoadLibraryA((char*)zConverted); - } -#endif + h = osLoadLibraryW ? osLoadLibraryW(zConverted) : 0; OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); sqlite3_free(zConverted); return (void*)h; @@ -54224,16 +54276,16 @@ static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); } static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ - FARPROC proc; + FARPROC proc = 0; UNUSED_PARAMETER(pVfs); - proc = osGetProcAddressA((HANDLE)pH, zSym); + proc = osGetProcAddressA ? osGetProcAddressA((HANDLE)pH, zSym) : 0; OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", (void*)pH, zSym, (void*)proc)); return (void(*)(void))proc; } static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ UNUSED_PARAMETER(pVfs); - osFreeLibrary((HANDLE)pHandle); + if( osFreeLibrary!=0 ) osFreeLibrary((HANDLE)pHandle); OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); } #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ @@ -54282,41 +54334,37 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ e.nXor = 0; e.i = 0; { - SYSTEMTIME x; - osGetSystemTime(&x); - xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); + FILETIME x; + osGetSystemTimeAsFileTime(&x); + xorMemory(&e, (unsigned char*)&x, sizeof(x)); } { DWORD pid = osGetCurrentProcessId(); - xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); + xorMemory(&e, (unsigned char*)&pid, sizeof(pid)); } -#if SQLITE_OS_WINRT { ULONGLONG cnt = osGetTickCount64(); - xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG)); - } -#else - { - DWORD cnt = osGetTickCount(); - xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); + xorMemory(&e, (unsigned char*)&cnt, sizeof(cnt)); } -#endif /* SQLITE_OS_WINRT */ { LARGE_INTEGER i; osQueryPerformanceCounter(&i); - xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); + xorMemory(&e, (unsigned char*)&i, sizeof(i)); } -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID +#if SQLITE_WIN32_USE_UUID +#ifdef SQLITE_UWP +# error SQLITE_WIN32_USE_UUID is incompatible with SQLITE_UWP +#endif { UUID id; - memset(&id, 0, sizeof(UUID)); + memset(&id, 0, sizeof(id)); osUuidCreate(&id); - xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); + xorMemory(&e, (unsigned char*)&id, sizeof(id)); memset(&id, 0, sizeof(UUID)); osUuidCreateSequential(&id); - xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); + xorMemory(&e, (unsigned char*)&id, sizeof(id)); } -#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */ +#endif /* SQLITE_WIN32_USE_UUID */ return e.nXor>nBuf ? nBuf : e.nXor; #endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ } @@ -54326,7 +54374,7 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ ** Sleep for a little while. Return the amount of time slept. */ static int winSleep(sqlite3_vfs *pVfs, int microsec){ - sqlite3_win32_sleep((microsec+999)/1000); + osSleep((microsec+999)/1000); UNUSED_PARAMETER(pVfs); return ((microsec+999)/1000)*1000; } @@ -54364,17 +54412,7 @@ static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296; -#if SQLITE_OS_WINCE - SYSTEMTIME time; - osGetSystemTime(&time); - /* if SystemTimeToFileTime() fails, it returns zero. */ - if (!osSystemTimeToFileTime(&time,&ft)){ - return SQLITE_ERROR; - } -#else osGetSystemTimeAsFileTime( &ft ); -#endif - *piNow = winFiletimeEpoch + ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; @@ -54468,7 +54506,6 @@ SQLITE_API int sqlite3_os_init(void){ winGetSystemCall, /* xGetSystemCall */ winNextSystemCall, /* xNextSystemCall */ }; -#if defined(SQLITE_WIN32_HAS_WIDE) static sqlite3_vfs winLongPathVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ @@ -54493,7 +54530,6 @@ SQLITE_API int sqlite3_os_init(void){ winGetSystemCall, /* xGetSystemCall */ winNextSystemCall, /* xNextSystemCall */ }; -#endif static sqlite3_vfs winNolockVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ @@ -54518,7 +54554,6 @@ SQLITE_API int sqlite3_os_init(void){ winGetSystemCall, /* xGetSystemCall */ winNextSystemCall, /* xNextSystemCall */ }; -#if defined(SQLITE_WIN32_HAS_WIDE) static sqlite3_vfs winLongPathNolockVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ @@ -54543,34 +54578,29 @@ SQLITE_API int sqlite3_os_init(void){ winGetSystemCall, /* xGetSystemCall */ winNextSystemCall, /* xNextSystemCall */ }; -#endif /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==89 ); + assert( ArraySize(aSyscall)==60 ); + assert( strcmp(aSyscall[0].zName,"AreFileApisANSI")==0 ); + assert( strcmp(aSyscall[8].zName,"FreeLibrary")==0 ); + assert( strcmp(aSyscall[16].zName,"GetSystemInfo")==0 ); + assert( strcmp(aSyscall[24].zName,"HeapReAlloc")==0 ); + assert( strcmp(aSyscall[32].zName,"MapViewOfFileFromApp")==0 ); + assert( strcmp(aSyscall[40].zName,"UnmapViewOfFile")==0 ); + assert( strcmp(aSyscall[48].zName,"UuidCreate")==0 ); + assert( strcmp(aSyscall[56].zName,"lstat")==0 ); /* get memory map allocation granularity */ memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); -#if SQLITE_OS_WINRT - osGetNativeSystemInfo(&winSysInfo); -#else osGetSystemInfo(&winSysInfo); -#endif assert( winSysInfo.dwAllocationGranularity>0 ); assert( winSysInfo.dwPageSize>0 ); sqlite3_vfs_register(&winVfs, 1); - -#if defined(SQLITE_WIN32_HAS_WIDE) sqlite3_vfs_register(&winLongPathVfs, 0); -#endif - sqlite3_vfs_register(&winNolockVfs, 0); - -#if defined(SQLITE_WIN32_HAS_WIDE) sqlite3_vfs_register(&winLongPathNolockVfs, 0); -#endif - #ifndef SQLITE_OMIT_WAL winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); #endif @@ -54579,17 +54609,9 @@ SQLITE_API int sqlite3_os_init(void){ } SQLITE_API int sqlite3_os_end(void){ -#if SQLITE_OS_WINRT - if( sleepObj!=NULL ){ - osCloseHandle(sleepObj); - sleepObj = NULL; - } -#endif - #ifndef SQLITE_OMIT_WAL winBigLock = 0; #endif - return SQLITE_OK; } @@ -55358,7 +55380,7 @@ SQLITE_API unsigned char *sqlite3_serialize( sqlite3_int64 sz; int szPage = 0; sqlite3_stmt *pStmt = 0; - unsigned char *pOut; + unsigned char *pOut = 0; char *zSql; int rc; @@ -55368,12 +55390,13 @@ SQLITE_API unsigned char *sqlite3_serialize( return 0; } #endif + sqlite3_mutex_enter(db->mutex); if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; p = memdbFromDbSchema(db, zSchema); iDb = sqlite3FindDbName(db, zSchema); if( piSize ) *piSize = -1; - if( iDb<0 ) return 0; + if( iDb<0 ) goto serialize_out; if( p ){ MemStore *pStore = p->pStore; assert( pStore->pMutex==0 ); @@ -55384,19 +55407,17 @@ SQLITE_API unsigned char *sqlite3_serialize( pOut = sqlite3_malloc64( pStore->sz ); if( pOut ) memcpy(pOut, pStore->aData, pStore->sz); } - return pOut; + goto serialize_out; } pBt = db->aDb[iDb].pBt; - if( pBt==0 ) return 0; + if( pBt==0 ) goto serialize_out; szPage = sqlite3BtreeGetPageSize(pBt); zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema); rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM; sqlite3_free(zSql); - if( rc ) return 0; + if( rc ) goto serialize_out; rc = sqlite3_step(pStmt); - if( rc!=SQLITE_ROW ){ - pOut = 0; - }else{ + if( rc==SQLITE_ROW ){ sz = sqlite3_column_int64(pStmt, 0)*szPage; if( sz==0 ){ sqlite3_reset(pStmt); @@ -55430,6 +55451,9 @@ SQLITE_API unsigned char *sqlite3_serialize( } } sqlite3_finalize(pStmt); + + serialize_out: + sqlite3_mutex_leave(db->mutex); return pOut; } @@ -55475,10 +55499,10 @@ SQLITE_API int sqlite3_deserialize( if( rc ) goto end_deserialize; db->init.iDb = (u8)iDb; db->init.reopenMemdb = 1; - rc = sqlite3_step(pStmt); + sqlite3_step(pStmt); db->init.reopenMemdb = 0; - if( rc!=SQLITE_DONE ){ - rc = SQLITE_ERROR; + rc = sqlite3_finalize(pStmt); + if( rc!=SQLITE_OK ){ goto end_deserialize; } p = memdbFromDbSchema(db, zSchema); @@ -55499,7 +55523,6 @@ SQLITE_API int sqlite3_deserialize( } end_deserialize: - sqlite3_finalize(pStmt); if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){ sqlite3_free(pData); } @@ -57284,22 +57307,24 @@ static int pcache1InitBulk(PCache1 *pCache){ if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){ szBulk = pCache->szAlloc*(i64)pCache->nMax; } - zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); - sqlite3EndBenignMalloc(); - if( zBulk ){ - int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; - do{ - PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; - pX->page.pBuf = zBulk; - pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); - assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); - pX->isBulkLocal = 1; - pX->isAnchor = 0; - pX->pNext = pCache->pFree; - pX->pLruPrev = 0; /* Initializing this saves a valgrind error */ - pCache->pFree = pX; - zBulk += pCache->szAlloc; - }while( --nBulk ); + if( szBulk>=pCache->szAlloc ){ + zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); + sqlite3EndBenignMalloc(); + if( zBulk ){ + int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; + do{ + PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; + pX->page.pBuf = zBulk; + pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); + assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); + pX->isBulkLocal = 1; + pX->isAnchor = 0; + pX->pNext = pCache->pFree; + pX->pLruPrev = 0; /* Initializing this saves a valgrind error */ + pCache->pFree = pX; + zBulk += pCache->szAlloc; + }while( --nBulk ); + } } return pCache->pFree!=0; } @@ -57518,6 +57543,7 @@ static void pcache1ResizeHash(PCache1 *p){ if( nNew<256 ){ nNew = 256; } + assert( (nNew & (nNew-1))==0 ); /* nNew is always a power of two */ pcache1LeaveMutex(p->pGroup); if( p->nHash ){ sqlite3BeginBenignMalloc(); } @@ -57529,7 +57555,7 @@ static void pcache1ResizeHash(PCache1 *p){ PgHdr1 *pPage; PgHdr1 *pNext = p->apHash[i]; while( (pPage = pNext)!=0 ){ - unsigned int h = pPage->iKey % nNew; + unsigned int h = (unsigned int)(pPage->iKey & (nNew-1)); pNext = pPage->pNext; pPage->pNext = apNew[h]; apNew[h] = pPage; @@ -57579,7 +57605,8 @@ static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){ PgHdr1 **pp; assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); - h = pPage->iKey % pCache->nHash; + assert( pCache->nHash>0 && (pCache->nHash & (pCache->nHash-1))==0 ); + h = pPage->iKey & (pCache->nHash-1); for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); *pp = (*pp)->pNext; @@ -57624,14 +57651,14 @@ static void pcache1TruncateUnsafe( unsigned int h, iStop; assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); assert( pCache->iMaxKey >= iLimit ); - assert( pCache->nHash > 0 ); + assert( pCache->nHash>0 && (pCache->nHash & (pCache->nHash-1))==0 ); if( pCache->iMaxKey - iLimit < pCache->nHash ){ /* If we are just shaving the last few pages off the end of the ** cache, then there is no point in scanning the entire hash table. ** Only scan those hash slots that might contain pages that need to ** be removed. */ - h = iLimit % pCache->nHash; - iStop = pCache->iMaxKey % pCache->nHash; + h = iLimit & (pCache->nHash-1); + iStop = pCache->iMaxKey & (pCache->nHash-1); TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */ }else{ /* This is the general case where many pages are being removed. @@ -57656,7 +57683,7 @@ static void pcache1TruncateUnsafe( } } if( h==iStop ) break; - h = (h+1) % pCache->nHash; + h = (h+1) & (pCache->nHash-1); } assert( nPage<0 || pCache->nPage==(unsigned)nPage ); } @@ -57868,6 +57895,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache); assert( pCache->nHash>0 && pCache->apHash ); + assert( (pCache->nHash & (pCache->nHash-1))==0 ); /* Step 4. Try to recycle a page. */ if( pCache->bPurgeable @@ -57896,7 +57924,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( } if( pPage ){ - unsigned int h = iKey % pCache->nHash; + unsigned int h = iKey & (pCache->nHash-1); pCache->nPage++; pPage->iKey = iKey; pPage->pNext = pCache->apHash[h]; @@ -57980,8 +58008,11 @@ static PgHdr1 *pcache1FetchNoMutex( PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = 0; - /* Step 1: Search the hash table for an existing entry. */ - pPage = pCache->apHash[iKey % pCache->nHash]; + /* Step 1: Search the hash table for an existing entry. nHash is always + ** a power of two when the cache is in use (see pcache1ResizeHash()), so + ** the modulo reduces to a mask, avoiding a hardware divide. */ + assert( pCache->nHash>0 && (pCache->nHash & (pCache->nHash-1))==0 ); + pPage = pCache->apHash[iKey & (pCache->nHash-1u)]; while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; } /* Step 2: If the page was found in the hash table, then return it. @@ -58100,7 +58131,8 @@ static void pcache1Rekey( pcache1EnterMutex(pCache->pGroup); assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */ - hOld = iOld%pCache->nHash; + assert( pCache->nHash>0 && (pCache->nHash & (pCache->nHash-1))==0 ); + hOld = iOld & (pCache->nHash-1); pp = &pCache->apHash[hOld]; while( (*pp)!=pPage ){ pp = &(*pp)->pNext; @@ -58108,7 +58140,7 @@ static void pcache1Rekey( *pp = pPage->pNext; assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */ - hNew = iNew%pCache->nHash; + hNew = iNew & (pCache->nHash-1); pPage->iKey = iNew; pPage->pNext = pCache->apHash[hNew]; pCache->apHash[hNew] = pPage; @@ -58941,6 +58973,10 @@ SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db); SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal*); #endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) +SQLITE_PRIVATE void sqlite3WalStat(Wal*,sqlite3_str*); +#endif + #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ @@ -59738,6 +59774,8 @@ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); if( iRead ) return 0; /* Case (4) */ } +#else + UNUSED_PARAMETER(pgno); #endif assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) @@ -60158,17 +60196,17 @@ static int jrnlBufferSize(Pager *pPager){ */ #ifdef SQLITE_CHECK_PAGES /* -** Return a 32-bit hash of the page data for pPage. +** Return a 64-bit hash of the page data for pPage. */ -static u32 pager_datahash(int nByte, unsigned char *pData){ - u32 hash = 0; +static u64 pager_datahash(int nByte, unsigned char *pData){ + u64 hash = 0; int i; for(i=0; ipPager->pageSize, (unsigned char *)pPage->pData); } static void pager_set_pagehash(PgHdr *pPage){ @@ -60195,39 +60233,78 @@ static void checkPage(PgHdr *pPg){ #endif /* SQLITE_CHECK_PAGES */ /* -** When this is called the journal file for pager pPager must be open. -** This function attempts to read a super-journal file name from the -** end of the file and, if successful, copies it into memory supplied -** by the caller. See comments above writeSuperJournal() for the format -** used to store a super-journal file name at the end of a journal file. +** Free a buffer allocated by the readSuperJournal() function. +*/ +static void freeSuperJournal(char *zSuper){ + if( zSuper ){ + sqlite3_free(&zSuper[-4]); + } +} + +/* +** Check if zSuper is a valid super-journal name. There are two valid +** formats: ** -** zSuper must point to a buffer of at least nSuper bytes allocated by -** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is -** enough space to write the super-journal name). If the super-journal -** name in the journal is longer than nSuper bytes (including a -** nul-terminator), then this is handled as if no super-journal name -** were present in the journal. +** + The 3rd and 4th last bytes of the filename are ".9", and the +** following 2 bytes are hex digits. This is a file created in 8.3 +** filenames mode. ** -** If a super-journal file name is present at the end of the journal -** file, then it is copied into the buffer pointed to by zSuper. A -** nul-terminator byte is appended to the buffer following the -** super-journal file name. +** + The 3rd last byte of the filename is "9" and the filename +** contains the string "-mj" starting at the 12th last byte. +** All bytes following the "-mj" are hex digits. ** -** If it is determined that no super-journal file name is present -** zSuper[0] is set to 0 and SQLITE_OK returned. +** If the filename matches either of these patterns, return non-zero. +** Otherwise, return zero. +*/ +static int pagerIsSuperJrnlName(const char *zSuper){ + const int nSuper = sqlite3Strlen30(zSuper); + int ii; + +#ifdef SQLITE_ENABLE_8_3_NAMES + if( nSuper<4 ) return 0; + if( zSuper[nSuper-3]!='9' ) return 0; + if( sqlite3Isxdigit(zSuper[nSuper-2])==0 ) return 0; + if( sqlite3Isxdigit(zSuper[nSuper-1])==0 ) return 0; + if( zSuper[nSuper-4]=='.' ) return 1; +#endif + if( nSuper<12 ) return 0; + if( memcmp(&zSuper[nSuper-12], "-mj", 3) ) return 0; + if( zSuper[nSuper-3]!='9' ) return 0; + for(ii=nSuper-9; iisetSuper==0 ); assert( !pagerUseWal(pPager) ); + assert( zSuper==0 || pagerIsSuperJrnlName(zSuper) ); if( !zSuper || pPager->journalMode==PAGER_JOURNALMODE_MEMORY @@ -60916,7 +61003,7 @@ static int pagerFlushOnCommit(Pager *pPager, int bCommit){ ** database transaction. ** ** This routine is never called in PAGER_ERROR state. If it is called -** in PAGER_NONE or PAGER_SHARED state and the lock held is less +** in PAGER_OPEN or PAGER_READER state and the lock held is less ** exclusive than a RESERVED lock, it is a no-op. ** ** Otherwise, any active savepoints are released. @@ -61462,9 +61549,20 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ char *zSuperJournal = 0; /* Contents of super-journal file */ i64 nSuperJournal; /* Size of super-journal file */ char *zJournal; /* Pointer to one journal within MJ file */ - char *zSuperPtr; /* Space to hold super-journal filename */ char *zFree = 0; /* Free this buffer */ - i64 nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ + int bSeen = 0; /* If super-journal contains pPager->zJournal */ + + /* Check if this looks like a real super-journal name. If it does not, + ** return SQLITE_OK without attempting to delete it. This is to limit + ** the degree to which a crafted journal file can be used to cause + ** SQLite to delete arbitrary files. + ** + ** This test never fails, becaue the super journal name is checked + ** by readSuperJournal(). + */ + if( NEVER(pagerIsSuperJrnlName(zSuper)==0) ){ + return SQLITE_OK; + } /* Allocate space for both the pJournal and pSuper file descriptors. ** If successful, open the super-journal file for reading. @@ -61487,9 +61585,8 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ */ rc = sqlite3OsFileSize(pSuper, &nSuperJournal); if( rc!=SQLITE_OK ) goto delsuper_out; - nSuperPtr = 1 + (i64)pVfs->mxPathname; - assert( nSuperJournal>=0 && nSuperPtr>0 ); - zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2); + assert( nSuperJournal>=0 ); + zFree = sqlite3Malloc(4 + nSuperJournal + 2); if( !zFree ){ rc = SQLITE_NOMEM_BKPT; goto delsuper_out; @@ -61498,7 +61595,6 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ } zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0; zSuperJournal = &zFree[4]; - zSuperPtr = &zSuperJournal[nSuperJournal+2]; rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0); if( rc!=SQLITE_OK ) goto delsuper_out; zSuperJournal[nSuperJournal] = 0; @@ -61506,43 +61602,56 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ zJournal = zSuperJournal; while( (zJournal-zSuperJournal)zJournal)==0 ){ + bSeen = 1; + }else{ + int exists; + rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); if( rc!=SQLITE_OK ){ goto delsuper_out; } + if( exists ){ + char *zSuperPtr = 0; - rc = readSuperJournal(pJournal, zSuperPtr, nSuperPtr); - sqlite3OsClose(pJournal); - if( rc!=SQLITE_OK ){ - goto delsuper_out; - } + /* One of the journals pointed to by the super-journal exists. + ** Open it and check if it points at the super-journal. If + ** so, return without deleting the super-journal file. + ** NB: zJournal is really a MAIN_JOURNAL. But call it a + ** SUPER_JOURNAL here so that the VFS will not send the zJournal + ** name into sqlite3_database_file_object(). + */ + int c; + int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); + rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); + if( rc!=SQLITE_OK ){ + goto delsuper_out; + } - c = zSuperPtr[0]!=0 && strcmp(zSuperPtr, zSuper)==0; - if( c ){ - /* We have a match. Do not delete the super-journal file. */ - goto delsuper_out; + rc = readSuperJournal(pJournal, 1+(u64)pVfs->mxPathname, &zSuperPtr); + sqlite3OsClose(pJournal); + if( rc!=SQLITE_OK ){ + assert( zSuperPtr==0 ); + goto delsuper_out; + } + + c = zSuperPtr!=0 && strcmp(zSuperPtr, zSuper)==0; + freeSuperJournal(zSuperPtr); + if( c ){ + /* We have a match. Do not delete the super-journal file. */ + goto delsuper_out; + } } } zJournal += (sqlite3Strlen30(zJournal)+1); } sqlite3OsClose(pSuper); - rc = sqlite3OsDelete(pVfs, zSuper, 0); + if( bSeen ){ + /* Only delete the super-journal if bSeen is true - indicating that + ** the super-journal contained a pointer to this database's journal + ** file. */ + rc = sqlite3OsDelete(pVfs, zSuper, 0); + } delsuper_out: sqlite3_free(zFree); @@ -61747,19 +61856,11 @@ static int pager_playback(Pager *pPager, int isHot){ ** If a super-journal file name is specified, but the file is not ** present on disk, then the journal is not hot and does not need to be ** played back. - ** - ** TODO: Technically the following is an error because it assumes that - ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that - ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c, - ** mxPathname is 512, which is the same as the minimum allowable value - ** for pageSize. */ - zSuper = pPager->pTmpSpace; - rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname); - if( rc==SQLITE_OK && zSuper[0] ){ + rc = readSuperJournal(pPager->jfd, 1+(i64)pPager->pVfs->mxPathname, &zSuper); + if( rc==SQLITE_OK && zSuper ){ rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); } - zSuper = 0; if( rc!=SQLITE_OK || !res ){ goto end_playback; } @@ -61888,30 +61989,20 @@ static int pager_playback(Pager *pPager, int isHot){ */ pPager->changeCountDone = pPager->tempFile; - if( rc==SQLITE_OK ){ - /* Leave 4 bytes of space before the super-journal filename in memory. - ** This is because it may end up being passed to sqlite3OsOpen(), in - ** which case it requires 4 0x00 bytes in memory immediately before - ** the filename. */ - zSuper = &pPager->pTmpSpace[4]; - rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname); - testcase( rc!=SQLITE_OK ); - } if( rc==SQLITE_OK && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) ){ rc = sqlite3PagerSync(pPager, 0); } if( rc==SQLITE_OK ){ - rc = pager_end_transaction(pPager, zSuper[0]!='\0', 0); + rc = pager_end_transaction(pPager, zSuper!=0, 0); testcase( rc!=SQLITE_OK ); } - if( rc==SQLITE_OK && zSuper[0] && res ){ + if( rc==SQLITE_OK && zSuper && res ){ /* If there was a super-journal and this routine will return success, ** see if it is possible to delete the super-journal. */ - assert( zSuper==&pPager->pTmpSpace[4] ); - memset(pPager->pTmpSpace, 0, 4); + assert( memcmp(&zSuper[-4], "\0\0\0\0", 4)==0 ); rc = pager_delsuper(pPager, zSuper); testcase( rc!=SQLITE_OK ); } @@ -61924,6 +62015,7 @@ static int pager_playback(Pager *pPager, int isHot){ ** back a journal created by a process with a different sector size ** value. Reset it to the correct value for this process. */ + freeSuperJournal(zSuper); setSectorSize(pPager); return rc; } @@ -62677,7 +62769,7 @@ SQLITE_PRIVATE void sqlite3PagerSetBusyHandler( ** ** then the pager object page size is set to *pPageSize. ** -** If the page size is changed, then this function uses sqlite3PagerMalloc() +** If the page size is changed, then this function uses sqlite3PageMalloc() ** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt ** fails, SQLITE_NOMEM is returned and the page size remains unchanged. ** In all other cases, SQLITE_OK is returned. @@ -63117,6 +63209,8 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); pPager->pWal = 0; } +#else + UNUSED_PARAMETER(db); #endif pager_reset(pPager); if( MEMDB ){ @@ -63866,7 +63960,15 @@ SQLITE_PRIVATE int sqlite3PagerOpen( */ if( zFilename && zFilename[0] ){ int fout = 0; /* VFS flags returned by xOpen() */ + int bImmutable = sqlite3_uri_boolean(pPager->zFilename, "immutable", 0); + if( bImmutable ){ + vfsFlags |= SQLITE_OPEN_READONLY; + vfsFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); + } rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); + if( bImmutable ){ + goto act_like_temp_file; + } assert( !memDb ); pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; readOnly = (fout&SQLITE_OPEN_READONLY)!=0; @@ -63906,10 +64008,9 @@ SQLITE_PRIVATE int sqlite3PagerOpen( #endif } pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); - if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 - || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ - vfsFlags |= SQLITE_OPEN_READONLY; - goto act_like_temp_file; + if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 ){ + vfsFlags |= SQLITE_OPEN_READONLY; + goto act_like_temp_file; } } }else{ @@ -63929,6 +64030,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ pPager->noLock = 1; /* Do no locking */ readOnly = (vfsFlags&SQLITE_OPEN_READONLY); + assert( readOnly==0 || readOnly==1 ); } /* The following call to PagerSetPagesize() serves to set the value of @@ -64022,8 +64124,8 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ /* -** This function is called after transitioning from PAGER_UNLOCK to -** PAGER_SHARED state. It tests if there is a hot journal present in +** This function is called while transitioning from PAGER_OPEN to a +** higher state. It tests if there is a hot journal present in ** the file-system for the given pager. A hot journal is one that ** needs to be played back. According to this function, a hot-journal ** file exists if the following criteria are met: @@ -65749,6 +65851,20 @@ SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ } #endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) +/* +** Append JSON structure elements describing the current state of +** the write-ahead log to pStr. +*/ +SQLITE_PRIVATE void sqlite3PagerWalStat(Pager *pPager, sqlite3_str *pStr){ +#ifndef SQLITE_OMIT_WAL + if( pPager->pWal ){ + sqlite3WalStat(pPager->pWal, pStr); + } +#endif +} +#endif + /* ** Return the approximate number of bytes of memory currently ** used by the pager and its associated cache. @@ -67345,10 +67461,41 @@ typedef u16 ht_slot; ** walIteratorFree() - Free an iterator. ** ** This functionality is used by the checkpoint code (see walCheckpoint()). +** +** There are two possible algorithms: +** +** WALITER-1 Load all pages mentioned in the WAL file and sort them, +** then hand them back out in sorted order as requested by +** walIteratorNext(). nPagemap==0 for this algorithm. +** +** WALITER-2 Create a map of all database file pages and record the +** last WAL file frame that updates that page. Then walk +** through the map in acsending order and return all +** non-zero entries. nPagemap is positive for this algorithm. +** +** Either algorithm should work for any database and WAL file, however +** algorithm WALITER-1 is faster and uses less memory when the database is +** larger than the WAL file and algorithm WALITER-2 is faster and uses +** less memory when the WAL file is larger than the database, modulo a +** constant of proportionality. The walIteratorInit() routine selects +** the best algorithm for each situation. WALITER-2 was added for +** SQLite 3.54.0. Prior to that, WALITER-1 was used always. +** +** For algorithm WALITER-2, nPagemap stores the number of pages in the +** database file, nSegment==1, and aSegment[0].aPgno[] is the page map array +** that is nPagemap+1 entries in length. The value of aSegment[0].aPgno[PGNO] +** is the frame number of the last (newest) entry for page PGNO in the WAL +** file, or 0 if PGNO is not in the WAL file. (Aside: There is no page +** number 0 in a well-formed database, so the memory allocation is arranged +** such that aSegment[0].aPgno[0] and aSegment[0].iZero are aliases for the +** same four bits of memory. This saves us from having to use -1 and +1 +** offsets to translate between 1-based SQLite page numbers and 0-based +** C-language index numbers. tag-20260903-1) */ struct WalIterator { u32 iPrior; /* Last result returned from the iterator */ int nSegment; /* Number of entries in aSegment[] */ + u32 nPagemap; /* Non-zero in "page-map" mode */ struct WalSegment { int iNext; /* Next slot in aIndex[] not yet returned */ ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ @@ -67362,6 +67509,7 @@ struct WalIterator { #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 @@ -67781,6 +67929,12 @@ static int walDecodeFrame( return 0; } + /* Need a valid page size + */ + if( !pWal->szPage ){ + return 0; + } + /* A frame is only valid if a checksum of the WAL header, ** all prior frames, the first 16 bytes of this frame-header, ** and the frame-data matches the checksum in the last 8 @@ -67884,7 +68038,7 @@ static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ /* ** Compute a hash on a page number. The resulting hash value must land -** between 0 and (HASHTABLE_NSLOT-1). The walHashNext() function advances +** between 0 and (HASHTABLE_NSLOT-1). The walNextHash() function advances ** the hash to the next value in the event of a collision. */ static int walHash(u32 iPage){ @@ -68092,7 +68246,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; } - sLoc.aPgno[idx-1] = iPage; + sLoc.aPgno[(idx-1)&(HASHTABLE_NPAGE-1)] = iPage; AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx); #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT @@ -68518,24 +68672,38 @@ static int walIteratorNext( u32 *piPage, /* OUT: The page number of the next page */ u32 *piFrame /* OUT: Wal frame index of next page */ ){ - u32 iMin; /* Result pgno must be greater than iMin */ u32 iRet = 0xFFFFFFFF; /* 0xffffffff is never a valid page number */ - int i; /* For looping through segments */ - - iMin = p->iPrior; - assert( iMin<0xffffffff ); - for(i=p->nSegment-1; i>=0; i--){ - struct WalSegment *pSegment = &p->aSegment[i]; - while( pSegment->iNextnEntry ){ - u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; - if( iPg>iMin ){ - if( iPgiZero + pSegment->aIndex[pSegment->iNext]; - } + + if( p->nPagemap ){ + /* Algorithm WALITER-2 */ + while( p->iPriornPagemap ){ + p->iPrior++; + if( p->aSegment[0].aPgno[p->iPrior] ){ + iRet = p->iPrior; + *piFrame = p->aSegment[0].aPgno[p->iPrior]; break; } - pSegment->iNext++; + } + }else{ + /* Algorithm WALITER-1 */ + u32 iMin; /* Result pgno must be greater than iMin */ + int i; /* For looping through segments */ + + iMin = p->iPrior; + assert( iMin<0xffffffff ); + for(i=p->nSegment-1; i>=0; i--){ + struct WalSegment *pSegment = &p->aSegment[i]; + while( pSegment->iNextnEntry ){ + u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; + if( iPg>iMin ){ + if( iPgiZero + pSegment->aIndex[pSegment->iNext]; + } + break; + } + pSegment->iNext++; + } } } @@ -68704,35 +68872,59 @@ static void walIteratorFree(WalIterator *p){ ** WalIterator object when it has finished with it. */ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ + int iFirstPage; /* First 32KB *-shm page to visit */ + int iLastPage; /* Last 32KB *-shm page to visit */ + u32 iZero; /* Frame before first frame to visit */ WalIterator *p; /* Return value */ int nSegment; /* Number of segments to merge */ u32 iLast; /* Last frame in log */ sqlite3_int64 nByte; /* Number of bytes to allocate */ + sqlite3_int64 nExtra; /* Number of bytes to allocate */ int i; /* Iterator variable */ - ht_slot *aTmp; /* Temp space used by merge-sort */ + ht_slot *aTmp = 0; /* Temp space used by merge-sort */ int rc = SQLITE_OK; /* Return Code */ + int eAlg; /* Which algorithm to use. 1 or 2 */ /* This routine only runs while holding the checkpoint lock. And - ** it only runs if there is actually content in the log (mxFrame>0). - */ + ** it only runs if there is actually content in the log (mxFrame>0). */ assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); + iLast = pWal->hdr.mxFrame; + iFirstPage = walFramePage(nBackfill+1); + iLastPage = walFramePage(iLast); + iZero = iFirstPage ? (HASHTABLE_NPAGE_ONE+(iFirstPage-1)*HASHTABLE_NPAGE) : 0; + + if( (iLast-iZero)*sizeof(ht_slot)>pWal->hdr.nPage*sizeof(u32) ){ + /* Algorithm WALITER-2 */ + nSegment = 1; + eAlg = 2; + nByte = SZ_WALITERATOR(nSegment) + pWal->hdr.nPage * sizeof(u32); + nExtra = 0; + }else{ + /* Algorithm WALITER-1 */ + nSegment = iLastPage - iFirstPage + 1; + eAlg = 1; + nByte = SZ_WALITERATOR(nSegment) + (iLast-iZero)*sizeof(ht_slot); + nExtra = sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast); + } /* Allocate space for the WalIterator object. */ - nSegment = walFramePage(iLast) + 1; - nByte = SZ_WALITERATOR(nSegment) - + iLast*sizeof(ht_slot); - p = (WalIterator *)sqlite3_malloc64(nByte - + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) - ); + p = (WalIterator *)sqlite3_malloc64(nByte + nExtra); if( !p ){ return SQLITE_NOMEM_BKPT; } memset(p, 0, nByte); p->nSegment = nSegment; - aTmp = (ht_slot*)&(((u8*)p)[nByte]); + if( eAlg==2 ){ + p->nPagemap = pWal->hdr.nPage; + p->aSegment[0].aPgno = ((u32*)&p->aSegment[1]) - 1; + assert( (u8*)&(p->aSegment[0].aPgno[0]) == (u8*)&(p->aSegment[0].iZero) ); + /* ^-- verifies tag-20260903-1 */ + }else{ + aTmp = (ht_slot*)&(((u8*)p)[nByte]); + } SEH_FREE_ON_ERROR(0, p); - for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && iaSegment[p->nSegment])[sLoc.iZero]; - sLoc.iZero++; - for(j=0; jaSegment[0].aPgno; + for(j=0; jnPagemap ){ + aPagemap[pgno] = sLoc.iZero + j + 1; + } + } + }else{ + assert( i!=iFirstPage || iZero==sLoc.iZero ); + aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero - iZero]; + sLoc.iZero++; + + for(j=0; jaSegment[i-iFirstPage].iZero = sLoc.iZero; + p->aSegment[i-iFirstPage].nEntry = nEntry; + p->aSegment[i-iFirstPage].aIndex = aIndex; + p->aSegment[i-iFirstPage].aPgno = (u32 *)sLoc.aPgno; } - walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry); - p->aSegment[i].iZero = sLoc.iZero; - p->aSegment[i].nEntry = nEntry; - p->aSegment[i].aIndex = aIndex; - p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; } } if( rc!=SQLITE_OK ){ @@ -69012,68 +69216,82 @@ static int walCheckpoint( && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK ){ u32 nBackfill = pInfo->nBackfill; - pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; - - /* Sync the WAL to disk */ - rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); - - /* If the database may grow as a result of this checkpoint, hint - ** about the eventual size of the db file to the VFS layer. - */ - if( rc==SQLITE_OK ){ - i64 nReq = ((i64)mxPage * szPage); - i64 nSize; /* Current size of database file */ - sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0); - rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); - if( rc==SQLITE_OK && nSizehdr.mxFrame*szPage)pDbFd, SQLITE_FCNTL_SIZE_HINT,&nReq); + WalIndexHdr *pLive = (WalIndexHdr*)walIndexHdr(pWal); + + /* Now that read-lock slot 0 is locked, check that the wal has not been + ** wrapped since the header was read for this checkpoint. If it was, then + ** there was no work to do anyway. In this case the + ** (pInfo->nBackfillhdr.mxFrame) test above only passed because + ** pInfo->nBackfill had already been set to 0 by the writer that wrapped + ** the wal file. It would also be dangerous to proceed, as there may be + ** fewer than pWal->hdr.mxFrame valid frames in the wal file. */ + int bChg = memcmp(pLive->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)); + if( 0==bChg ){ + pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; + + /* Sync the WAL to disk */ + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); + + /* If the database may grow as a result of this checkpoint, hint + ** about the eventual size of the db file to the VFS layer. + */ + if( rc==SQLITE_OK ){ + i64 nReq = ((i64)mxPage * szPage); + i64 nSize; /* Current size of database file */ + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0); + rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); + if( rc==SQLITE_OK && nSizehdr.mxFrame*szPage)pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); + } } - } - - } - /* Iterate through the contents of the WAL, copying data to the db file */ - while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ - i64 iOffset; - assert( walFramePgno(pWal, iFrame)==iDbpage ); - SEH_INJECT_FAULT; - if( AtomicLoad(&db->u1.isInterrupted) ){ - rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; - break; - } - if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ - continue; } - iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; - /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ - rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); - if( rc!=SQLITE_OK ) break; - iOffset = (iDbpage-1)*(i64)szPage; - testcase( IS_BIG_INT(iOffset) ); - rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); - if( rc!=SQLITE_OK ) break; - } - sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); - /* If work was actually accomplished... */ - if( rc==SQLITE_OK ){ - if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ - i64 szDb = pWal->hdr.nPage*(i64)szPage; - testcase( IS_BIG_INT(szDb) ); - rc = sqlite3OsTruncate(pWal->pDbFd, szDb); - if( rc==SQLITE_OK ){ - rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); + /* Iterate through the contents of the WAL, copying data to the + ** db file */ + while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ + i64 iOffset; + assert( walFramePgno(pWal, iFrame)==iDbpage ); + SEH_INJECT_FAULT; + if( AtomicLoad(&db->u1.isInterrupted) ){ + rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; + break; + } + if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ + continue; } + iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ + rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + iOffset = (iDbpage-1)*(i64)szPage; + testcase( IS_BIG_INT(iOffset) ); + rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; } + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); + + /* If work was actually accomplished... */ if( rc==SQLITE_OK ){ - AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; + if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ + i64 szDb = pWal->hdr.nPage*(i64)szPage; + testcase( IS_BIG_INT(szDb) ); + rc = sqlite3OsTruncate(pWal->pDbFd, szDb); + if( rc==SQLITE_OK ){ + rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); + } + } + if( rc==SQLITE_OK ){ + AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; + } } } @@ -69621,7 +69839,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ /* Allocate a buffer to read frames into */ assert( (pWal->szPage & (pWal->szPage-1))==0 ); - assert( pWal->szPage>=512 && pWal->szPage<=65536 ); + assert( (pWal->szPage>=512 && pWal->szPage<=65536) || pWal->szPage==0 ); szFrame = pWal->szPage + WAL_FRAME_HDRSIZE; aFrame = (u8 *)sqlite3_malloc64(szFrame); if( aFrame==0 ){ @@ -70326,7 +70544,10 @@ static int walFindFrame( SEH_INJECT_FAULT; while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){ u32 iFrame = iH + sLoc.iZero; - if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){ + if( iFrame<=iLast + && iFrame>=pWal->minFrame + && sLoc.aPgno[(iH-1)&(HASHTABLE_NPAGE-1)]==pgno + ){ assert( iFrame>iRead || CORRUPT_DB ); iRead = iFrame; } @@ -70400,11 +70621,15 @@ SQLITE_PRIVATE int sqlite3WalReadFrame( i64 iOffset; sz = pWal->hdr.szPage; sz = (sz&0xfe00) + ((sz&0x0001)<<16); + if( nOut>sz ){ + memset(pOut+sz, 0, nOut-sz); + nOut = sz; + } testcase( sz<=32768 ); testcase( sz>=65536 ); iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); + return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset); } /* @@ -71123,6 +71348,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( /* Copy data from the log to the database file. */ if( rc==SQLITE_OK ){ + sqlite3FaultSim(660); if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ rc = SQLITE_CORRUPT_BKPT; }else if( eMode2!=SQLITE_CHECKPOINT_NOOP ){ @@ -71376,6 +71602,64 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ return pWal->pWalFd; } +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) +/* +** Helper function to sqlite3WalStat(). +** +** Append JSON-5 structure elements onto describing the current state +** of pWal onto the end of pStr. This function is for debugging and +** analysis only and is not included in production builds. +*/ +static void walIndexHdrStat(volatile WalIndexHdr *pHdr, sqlite3_str *pStr){ + sqlite3_str_appendf(pStr, "iVersion:%u",pHdr->iVersion); + sqlite3_str_appendf(pStr, ",iChange:%u",pHdr->iChange); + sqlite3_str_appendf(pStr, ",isInit:%u",pHdr->isInit); + sqlite3_str_appendf(pStr, ",bigEndCksum:%u",pHdr->bigEndCksum); + sqlite3_str_appendf(pStr, ",szPage:%u",pHdr->szPage); + sqlite3_str_appendf(pStr, ",mxFrame:%u",pHdr->mxFrame); + sqlite3_str_appendf(pStr, ",nPage:%u",pHdr->nPage); +#if 0 /* Not often needed. Declutter. */ + sqlite3_str_appendf(pStr, ",aFrameCksum:[0x%08x,0x%08x]", + pHdr->aFrameCksum[0], pHdr->aFrameCksum[1]); + sqlite3_str_appendf(pStr, ",aSalt:[0x%08x,0x%08x]", + pHdr->aSalt[0], pHdr->aSalt[1]); + sqlite3_str_appendf(pStr, ",aCksum:[0x%08x,0x%08x]", + pHdr->aCksum[0], pHdr->aCksum[1]); +#endif +} +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_WALSTAT */ + + +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) +/* +** Append JSON-5 structure elements onto describing the current state +** of pWal onto the end of pStr. This function is for debugging and +** analysis only and is not included in production builds. +*/ +SQLITE_PRIVATE void sqlite3WalStat(Wal *pWal, sqlite3_str *pStr){ + SEH_TRY { + int i; + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + volatile WalIndexHdr *pHdr = walIndexHdr(pWal); + sqlite3_str_appendf(pStr, "hdr0:{"); + walIndexHdrStat(pHdr,pStr); + sqlite3_str_appendf(pStr, "},ckpt:{"); + sqlite3_str_appendf(pStr, "nBackfill:%u",pInfo->nBackfill); + sqlite3_str_appendf(pStr, ",aReadMark:[%u", pInfo->aReadMark[0]); + for(i=1; iaReadMark[i]); + } + sqlite3_str_appendf(pStr, "],nBackfillAttempted:%u}", + pInfo->nBackfillAttempted); + + sqlite3_str_appendf(pStr, ",nWiData:%d", pWal->nWiData); + sqlite3_str_appendf(pStr, ",readLock:%d", pWal->readLock); + sqlite3_str_appendf(pStr, ",minFrame:%u", pWal->minFrame); + } + SEH_EXCEPT( ; ) +} +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_WALSTAT */ + #endif /* #ifndef SQLITE_OMIT_WAL */ /************** End of wal.c *************************************************/ @@ -71939,6 +72223,9 @@ struct BtCursor { Btree *pBtree; /* The Btree to which this cursor belongs */ Pgno *aOverflow; /* Cache of overflow page locations */ void *pKey; /* Saved key that was cursor last known position */ +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) + BtCursor *pCursorHintTableCursor; +#endif /* All fields above are zeroed when the cursor is allocated. See ** sqlite3BtreeCursorZero(). Fields that follow must be manually ** initialized. */ @@ -72107,6 +72394,7 @@ struct IntegrityCk { int nErr; /* Number of messages written to zErrMsg so far */ int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ u32 nStep; /* Number of steps into the integrity_check process */ + u8 nAbove; /* Current btree recursion depth */ const char *zPfx; /* Error message prefix */ Pgno v0; /* Value for first %u substitution in zPfx (root page) */ Pgno v1; /* Value for second %u substitution in zPfx (current pg) */ @@ -72115,6 +72403,9 @@ struct IntegrityCk { u32 *heap; /* Min-heap used for analyzing cell coverage */ sqlite3 *db; /* Database connection running the check */ i64 nRow; /* Number of rows visited in current tree */ +#ifdef SQLITE_DEBUG + u32 mxHeap; /* Maximum number of entries in the Min-heap */ +#endif }; /* @@ -72453,6 +72744,16 @@ SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ */ /* #include "btreeInt.h" */ +/* +** Suppress false-positive compiler warnings from GCC. Warnings are +** re-enabled at the bottom of this source file. +*/ +#if defined(__GNUC__) && __GNUC__>=11 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wstringop-overread" +# pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + /* ** The header string that appears at the beginning of every ** SQLite database. @@ -73433,24 +73734,41 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow) SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ /* Used only by system that substitute their own storage engine */ #ifdef SQLITE_DEBUG - if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){ - va_list ap; + va_list ap; + va_start(ap, eHintType); + if( eHintType==BTREE_HINT_RANGE ){ Expr *pExpr; Walker w; memset(&w, 0, sizeof(w)); w.xExprCallback = sqlite3CursorRangeHintExprCheck; - va_start(ap, eHintType); pExpr = va_arg(ap, Expr*); w.u.aMem = va_arg(ap, Mem*); - va_end(ap); assert( pExpr!=0 ); assert( w.u.aMem!=0 ); sqlite3WalkExpr(&w, pExpr); + }else if( ALWAYS(eHintType==BTREE_HINT_TABLECURSOR) ){ + BtCursor *pCsr = va_arg(ap, BtCursor*); + assert( pCur->pCursorHintTableCursor==0 + || pCur->pCursorHintTableCursor==pCsr + ); + assert( pCsr->pKeyInfo==0 || CORRUPT_DB ); + pCur->pCursorHintTableCursor = pCsr; } + va_end(ap); #endif /* SQLITE_DEBUG */ } #endif /* SQLITE_ENABLE_CURSOR_HINTS */ +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) +/* +** Return the pointer configured via the BTREE_HINT_TABLECURSOR hint on +** cursor pCsr. This is used from OP_DeferredSeek to assert() that the +** index cursor has been correctly configured with the table cursor. +*/ +SQLITE_PRIVATE BtCursor *sqlite3BtreeCursorHintTblCsr(BtCursor *pCsr){ + return pCsr->pCursorHintTableCursor; +} +#endif /* ** Provide flag hints to the cursor. @@ -73688,7 +74006,7 @@ static void btreeParseCellPtrNoPayload( #ifndef SQLITE_DEBUG UNUSED_PARAMETER(pPage); #endif - pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey); + pInfo->nSize = 4 + sqlite3GetVarint(&pCell[4], (u64*)&pInfo->nKey); pInfo->nPayload = 0; pInfo->nLocal = 0; pInfo->pPayload = 0; @@ -73700,7 +74018,7 @@ static void btreeParseCellPtr( CellInfo *pInfo /* Fill in this structure */ ){ u8 *pIter; /* For scanning through pCell */ - u32 nPayload; /* Number of bytes of cell payload */ + u64 nPayload; /* Number of bytes of cell payload */ u64 iKey; /* Extracted Key value */ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); @@ -73722,12 +74040,13 @@ static void btreeParseCellPtr( do{ nPayload = (nPayload<<7) | (*++pIter & 0x7f); }while( (*pIter)>=0x80 && pIternKey); + ** pIter += sqlite3GetVarint(pIter, (u64*)&pInfo->nKey); ** ** The code is inlined and the loop is unrolled for performance. ** This routine is a high-runner. @@ -73765,11 +74084,10 @@ static void btreeParseCellPtr( pIter++; pInfo->nKey = *(i64*)&iKey; - pInfo->nPayload = nPayload; + pInfo->nPayload = (u32)nPayload; 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 @@ -74576,8 +74894,15 @@ static int btreeComputeFreeSpace(MemPage *pPage){ } next = get2byte(&data[pc]); size = get2byte(&data[pc+2]); + if( size<4 && sqlite3FaultSim(422)==SQLITE_OK ){ + /* Minimum freeblock size is 4. Enable fault-sim 422 to disable this + ** check to reach interesting error states. However, disabling this + ** check can cause assertion faults due to min-heap overflow. All + ** fault-sims are for testing use only, but this one especially so. */ + return SQLITE_CORRUPT_PAGE(pPage); + } nFree = nFree + size; - if( next<=pc+size+3 ) break; + if( next0 ){ @@ -76111,6 +76436,30 @@ static SQLITE_NOINLINE int btreeBeginTrans( } #endif +#ifdef SQLITE_EXPERIMENTAL_PRAGMA_20251114 + /* If both a read and write transaction will be opened by this call, + ** then issue a file-control as if the following pragma command had + ** been evaluated: + ** + ** PRAGMA experimental_pragma_20251114 = 1|2 + ** + ** where the RHS is "1" if wrflag is 1 (RESERVED lock), or "2" if wrflag + ** is 2 (EXCLUSIVE lock). Ignore any result or error returned by the VFS. + ** + ** WARNING: This code will likely remain part of SQLite only temporarily - + ** it exists to allow users to experiment with certain types of blocking + ** locks in custom VFS implementations. It MAY BE REMOVED AT ANY TIME. */ + if( pBt->pPage1==0 && wrflag ){ + sqlite3_file *fd = sqlite3PagerFile(pPager); + char *aFcntl[3] = {0,0,0}; + aFcntl[1] = "experimental_pragma_20251114"; + assert( wrflag==1 || wrflag==2 ); + aFcntl[2] = (wrflag==1 ? "1" : "2"); + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); + sqlite3_free(aFcntl[0]); + } +#endif + /* Call lockBtree() until either pBt->pPage1 is populated or ** lockBtree() returns something other than SQLITE_OK. lockBtree() ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after @@ -77558,7 +77907,7 @@ static int accessPayload( getCellInfo(pCur); aPayload = pCur->info.pPayload; - assert( offset+amt <= pCur->info.nPayload ); + assert( (u64)offset+(u64)amt <= (u64)pCur->info.nPayload ); assert( aPayload > pPage->aData ); if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ @@ -77599,7 +77948,9 @@ static int accessPayload( ** means "not yet known" (the cache is lazily populated). */ if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){ - int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; + i64 nOvfl = pCur->info.nPayload; + testcase( nOvfl - pCur->info.nLocal + ovflSize - 1 > 0xffffffffU ); + nOvfl = (nOvfl - pCur->info.nLocal + ovflSize-1)/ovflSize; if( pCur->aOverflow==0 || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) ){ @@ -77704,6 +78055,14 @@ static int accessPayload( (eOp==0 ? PAGER_GET_READONLY : 0) ); if( rc==SQLITE_OK ){ + if( eOp!=0 + && (sqlite3PagerPageRefcount(pDbPage)!=1 + || NEVER(((MemPage*)sqlite3PagerGetExtra(pDbPage))->isInit)) + && sqlite3FaultSim(411)==SQLITE_OK + ){ + sqlite3PagerUnref(pDbPage); + return SQLITE_CORRUPT_PAGE(pPage); + } aPayload = sqlite3PagerGetData(pDbPage); nextPage = get4byte(aPayload); rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); @@ -78115,7 +78474,7 @@ SQLITE_PRIVATE int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes){ assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); - if( pCur->eState==CURSOR_VALID ){ + if( NEVER(pCur->eState==CURSOR_VALID) ){ *pRes = 0; return SQLITE_OK; } @@ -78298,7 +78657,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto( } } } - getVarint(pCell, (u64*)&nCellKey); + nCellKey = sqlite3VarintValue(pCell); if( nCellKeyupr ){ c = -1; break; } @@ -78353,12 +78712,12 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto( ** zero if the cell is less than or equal pIdxKey. Return positive ** if unknown. ** -** Return value negative: Cell at pCur[idx] less than pIdxKey +** Return value negative: Cell at pPage[idx] less than pIdxKey ** -** Return value is zero: Cell at pCur[idx] equals pIdxKey +** Return value is zero: Cell at pPage[idx] equals pIdxKey ** ** Return value positive: Nothing is known about the relationship -** of the cell at pCur[idx] and pIdxKey. +** of the cell at pPage[idx] and pIdxKey. ** ** This routine is part of an optimization. It is always safe to return ** a positive value as that will cause the optimization to be skipped. @@ -78378,14 +78737,14 @@ static int indexCellCompare( /* This branch runs if the record-size field of the cell is a ** single byte varint and the record fits entirely on the main ** b-tree page. */ - testcase( pCell+nCell+1==pPage->aDataEnd ); + if( pCell + nCell >= pPage->aDataEnd ) return 99; c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal ){ /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ - testcase( pCell+nCell+2==pPage->aDataEnd ); + if( pCell + nCell >= pPage->aDataEnd ) return 99; c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); }else{ /* If the record extends into overflow pages, do not attempt @@ -78547,14 +78906,17 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( /* This branch runs if the record-size field of the cell is a ** single byte varint and the record fits entirely on the main ** b-tree page. */ - testcase( pCell+nCell+1==pPage->aDataEnd ); + if( pCell + nCell >= pPage->aDataEnd ){ + rc = SQLITE_CORRUPT_PAGE(pPage); + goto moveto_index_finish; + } c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + && pCell + nCell < pPage->aDataEnd ){ /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ - testcase( pCell+nCell+2==pPage->aDataEnd ); c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); }else{ /* The record flows over onto one or more overflow pages. In @@ -79502,7 +79864,7 @@ static int fillInCell( nSrc = pX->nData; assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */ nHeader += putVarint32(&pCell[nHeader], nPayload); - nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); + nHeader += sqlite3PutVarint(&pCell[nHeader], *(u64*)&pX->nKey); }else{ assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); nSrc = nPayload = (int)pX->nKey; @@ -81251,7 +81613,7 @@ static int balance_nonroot( j--; pNew->xParseCell(pNew, b.apCell[j], &info); pCell = pTemp; - sz = 4 + putVarint(&pCell[4], info.nKey); + sz = 4 + sqlite3PutVarint(&pCell[4], info.nKey); pTemp = 0; }else{ pCell -= 4; @@ -82136,7 +82498,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 }else{ aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); } - if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); + if( pDest->pKeyInfo==0 ) aOut += sqlite3PutVarint(aOut, iKey); nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; if( aIn+nIn>pSrc->pPage->aDataEnd ){ @@ -82196,7 +82558,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 }while( rc==SQLITE_OK && nOut>0 ); if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ - Pgno pgnoNew; + Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */ MemPage *pNew = 0; rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); put4byte(pPgnoOut, pgnoNew); @@ -82375,7 +82737,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( pTmp!=0 ); rc = sqlite3PagerWrite(pLeaf->pDbPage); if( rc==SQLITE_OK ){ - rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n); + rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4-(pCell[0]==2), pTmp, n); } dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); if( rc ) return rc; @@ -82606,11 +82968,20 @@ SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, Pgno *piTable, int flags){ /* ** Erase the given database page and all its children. Return ** the page to the freelist. +** +** The freePageFlag parameter serves a double role: +** +** * Bit 0 (freePageFlag&1) means that the page should be freed +** after it is cleared. +** +** * Bits 1-31 (freePageFlag>>1) is the depth of recursion. Use this +** to prevent a corrupt database file from recursing too deeply and +** overflowing the CPU stack. */ static int clearDatabasePage( BtShared *pBt, /* The BTree that contains the table */ Pgno pgno, /* Page number to clear */ - int freePageFlag, /* Deallocate page if true */ + int freePageFlag, /* bit 0: Deallocate page. Bits 1-31: depth */ i64 *pnChange /* Add number of Cells freed to this counter */ ){ MemPage *pPage; @@ -82624,6 +82995,9 @@ static int clearDatabasePage( if( pgno>btreePagecount(pBt) ){ return SQLITE_CORRUPT_PGNO(pgno); } + if( (freePageFlag>>1) > BTCURSOR_MAX_DEPTH ){ + return SQLITE_CORRUPT_PGNO(pgno); + } rc = getAndInitPage(pBt, pgno, &pPage, 0); if( rc ) return rc; if( (pBt->openFlags & BTREE_SINGLE)==0 @@ -82636,14 +83010,16 @@ static int clearDatabasePage( for(i=0; inCell; i++){ pCell = findCell(pPage, i); if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); + rc = clearDatabasePage(pBt, get4byte(pCell), + (freePageFlag+2)|1, pnChange); if( rc ) goto cleardatabasepage_out; } BTREE_CLEAR_CELL(rc, pPage, pCell, info); if( rc ) goto cleardatabasepage_out; } if( !pPage->leaf ){ - rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); + rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), + (freePageFlag+2)|1, pnChange); if( rc ) goto cleardatabasepage_out; if( pPage->intKey ) pnChange = 0; } @@ -82651,7 +83027,7 @@ static int clearDatabasePage( testcase( !pPage->intKey ); *pnChange += pPage->nCell; } - if( freePageFlag ){ + if( (freePageFlag&1)!=0 ){ freePage(pPage, &rc); }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF); @@ -82781,6 +83157,9 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ } pMove = 0; rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pMove->pDbPage); + } freePage(pMove, &rc); releasePage(pMove); if( rc!=SQLITE_OK ){ @@ -83286,19 +83665,24 @@ static int checkTreePage( /* Check that the page exists */ checkProgress(pCheck); - if( pCheck->mxErr==0 ) goto end_of_check; + if( pCheck->mxErr==0 ) return 0; pBt = pCheck->pBt; usableSize = pBt->usableSize; if( iPage==0 ) return 0; if( checkRef(pCheck, iPage) ) return 0; pCheck->zPfx = "Tree %u page %u: "; pCheck->v1 = iPage; + pCheck->nAbove++; if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ checkAppendMsg(pCheck, "unable to get the page. error code=%d", rc); if( rc==SQLITE_IOERR_NOMEM ) pCheck->rc = SQLITE_NOMEM; goto end_of_check; } + if( pCheck->nAbove > BTCURSOR_MAX_DEPTH ){ + checkAppendMsg(pCheck,"btree depth exceeds %d",BTCURSOR_MAX_DEPTH); + goto end_of_check; + } /* Clear MemPage.isInit to make sure the corruption detection code in ** btreeInitPage() is executed. */ @@ -83378,6 +83762,11 @@ static int checkTreePage( doCoverageCheck = 0; continue; } + if( info.nPayload && info.pPayload[0]<2 ){ + checkAppendMsg(pCheck, "Bad cell header size"); + doCoverageCheck = 0; + continue; + } /* Check for integer primary key out of range */ if( pPage->intKey ){ @@ -83419,6 +83808,7 @@ static int checkTreePage( } }else{ /* Populate the coverage-checking heap for leaf pages */ + assert( heap!=0 && heap[0] < pCheck->mxHeap ); btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1)); } } @@ -83438,6 +83828,7 @@ static int checkTreePage( u32 size; pc = get2byteAligned(&data[cellStart+i*2]); size = pPage->xCellSize(pPage, &data[pc]); + assert( heap!=0 && heap[0] < pCheck->mxHeap ); btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); } } @@ -83454,6 +83845,7 @@ static int checkTreePage( assert( (u32)i<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */ size = get2byte(&data[i+2]); assert( (u32)(i+size)<=usableSize ); /* due to btreeComputeFreeSpace() */ + assert( heap!=0 && heap[0] < pCheck->mxHeap ); btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1)); /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a ** big-endian integer which is the offset in the b-tree page of the next @@ -83510,6 +83902,7 @@ static int checkTreePage( pCheck->zPfx = saved_zPfx; pCheck->v1 = saved_v1; pCheck->v2 = saved_v2; + pCheck->nAbove--; return depth+1; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -83587,7 +83980,10 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( checkOom(&sCheck); goto integrity_ck_cleanup; } - sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); + sCheck.heap = (u32*)sqlite3Malloc( pBt->pageSize*2 ); +#ifdef SQLITE_DEBUG + sCheck.mxHeap = pBt->pageSize/2 - 1; +#endif if( sCheck.heap==0 ){ checkOom(&sCheck); goto integrity_ck_cleanup; @@ -83639,7 +84035,9 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( } #endif sCheck.v0 = aRoot[i]; + assert( sCheck.nAbove==0 ); checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); + assert( sCheck.nAbove==0 ); } sqlite3MemSetArrayInt64(aCnt, i, sCheck.nRow); } @@ -83672,7 +84070,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( /* Clean up and report errors. */ integrity_ck_cleanup: - sqlite3PageFree(sCheck.heap); + sqlite3_free(sCheck.heap); sqlite3_free(sCheck.aPgRef); *pnErr = sCheck.nErr; if( sCheck.nErr==0 ){ @@ -83981,6 +84379,13 @@ SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ } #endif +/* Re-enable GCC compiler warnings that were suppressed at the top +** of this source file to prevent annoying false-positives. +*/ +#if defined(__GNUC__) && __GNUC__>=11 +# pragma GCC diagnostic pop +#endif + /************** End of btree.c ***********************************************/ /************** Begin file backup.c ******************************************/ /* @@ -84005,6 +84410,7 @@ SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ */ struct sqlite3_backup { sqlite3* pDestDb; /* Destination database handle */ + char *zDestDb; Btree *pDest; /* Destination b-tree file */ u32 iDestSchema; /* Original schema cookie in destination */ int bDestLocked; /* True once a write-transaction is open on pDest */ @@ -84065,8 +84471,10 @@ struct sqlite3_backup { ** error message to pErrorDb. */ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ - int i = sqlite3FindDbName(pDb, zDb); + int i; + assert( pDb!=0 ); + i = sqlite3FindDbName(pDb, zDb); if( i==1 ){ Parse sParse; int rc = 0; @@ -84094,10 +84502,8 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ ** Attempt to set the page size of the destination to match the page size ** of the source. */ -static int setDestPgsz(sqlite3_backup *p){ - int rc; - rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0); - return rc; +static int setDestPgsz(Btree *pDest, Btree *pSrc){ + return sqlite3BtreeSetPageSize(pDest, sqlite3BtreeGetPageSize(pSrc), 0, 0); } /* @@ -84154,27 +84560,37 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init( ); p = 0; }else { + int nDest = sqlite3Strlen30(zDestDb); + /* Allocate space for a new sqlite3_backup object... ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a ** call to sqlite3_backup_init() and is destroyed by a call to ** sqlite3_backup_finish(). */ - p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); + p = (sqlite3_backup*)sqlite3MallocZero(sizeof(sqlite3_backup)+nDest+1); if( !p ){ sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); + }else{ + p->zDestDb = (char*)&p[1]; + memcpy(p->zDestDb, zDestDb, nDest); } } /* If the allocation succeeded, populate the new object. */ if( p ){ + /* Do not store the pointer to the destination b-tree at this point. + ** This is because there is nothing preventing it from being detached + ** or otherwise freed before the first call to sqlite3_backup_step() + ** on this object. The source b-tree does not have this problem, as + ** incrementing Btree.nBackup (see below) effectively locks the object. */ + Btree *pDest = findBtree(pDestDb, pDestDb, zDestDb); p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); - p->pDest = findBtree(pDestDb, pDestDb, zDestDb); p->pDestDb = pDestDb; p->pSrcDb = pSrcDb; p->iNext = 1; p->isAttached = 0; - if( 0==p->pSrc || 0==p->pDest - || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK + if( 0==p->pSrc || 0==pDest + || checkReadTransaction(pDestDb, pDest)!=SQLITE_OK ){ /* One (or both) of the named databases did not exist or an OOM ** error was hit. Or there is a transaction open on the destination @@ -84298,7 +84714,7 @@ static void attachBackupObject(sqlite3_backup *p){ */ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ int rc; - int destMode; /* Destination journal mode */ + int destMode = 0; /* Destination journal mode */ int pgszSrc = 0; /* Source page size */ int pgszDest = 0; /* Destination page size */ @@ -84314,7 +84730,8 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ rc = p->rc; if( !isFatalError(rc) ){ Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ - Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */ + Btree * pDest = 0; /* Dest btree */ + Pager * pDestPager = 0; /* Dest pager */ int ii; /* Iterator variable */ int nSrcPage = -1; /* Size of source db in pages */ int bCloseTrans = 0; /* True if src db requires unlocking */ @@ -84328,6 +84745,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ rc = SQLITE_OK; } + /* If there is no open read-transaction on the source database, open ** one now. If a transaction is opened here, then it will be closed ** before this function exits. @@ -84337,34 +84755,48 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ bCloseTrans = 1; } + /* Locate the destination btree and pager. */ + if( (pDest = p->pDest)==0 ){ + pDest = findBtree(p->pDestDb, p->pDestDb, p->zDestDb); + } + if( pDest==0 ){ + rc = SQLITE_ERROR; + }else{ + pDestPager = sqlite3BtreePager(pDest); + } + /* If the destination database has not yet been locked (i.e. if this ** is the first call to backup_step() for the current backup operation), ** try to set its page size to the same as the source database. This ** is especially important on ZipVFS systems, as in that case it is ** not possible to create a database file that uses one page size by ** writing to it with another. */ - if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){ + if( p->bDestLocked==0 && rc==SQLITE_OK + && setDestPgsz(pDest, p->pSrc)==SQLITE_NOMEM + ){ rc = SQLITE_NOMEM; } /* Lock the destination database, if it is not locked already. */ if( SQLITE_OK==rc && p->bDestLocked==0 - && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2, + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(pDest, 2, (int*)&p->iDestSchema)) ){ p->bDestLocked = 1; + p->pDest = pDest; } /* Do not allow backup if the destination database is in WAL mode ** and the page sizes are different between source and destination */ - pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); - pgszDest = sqlite3BtreeGetPageSize(p->pDest); - destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); - if( SQLITE_OK==rc - && (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager)) - && pgszSrc!=pgszDest - ){ - rc = SQLITE_READONLY; + if( rc==SQLITE_OK ){ + pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); + pgszDest = sqlite3BtreeGetPageSize(p->pDest); + destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); + if( (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager)) + && pgszSrc!=pgszDest + ){ + rc = SQLITE_READONLY; + } } /* Now that there is a read-lock on the source database, query the @@ -84582,7 +85014,9 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ } /* If a transaction is still open on the Btree, roll it back. */ - sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); + if( p->pDest ){ + sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); + } /* Set the error code of the destination database handle. */ rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; @@ -84862,21 +85296,27 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ StrAccum acc; assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) ); assert( sz>22 ); - if( p->flags & MEM_Int ){ -#if GCC_VERSION>=7000000 - /* Work-around for GCC bug - ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96270 */ + if( p->flags & (MEM_Int|MEM_IntReal) ){ +#if GCC_VERSION>=7000000 && GCC_VERSION<15000000 && defined(__i386__) + /* Work-around for GCC bug or bugs: + ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96270 + ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114659 + ** The problem appears to be fixed in GCC 15 */ i64 x; - assert( (p->flags&MEM_Int)*2==sizeof(x) ); - memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2); + assert( (sqlite3Config.bSmallMalloc!=0xee)*8==sizeof(x) ); + memcpy(&x, (char*)&p->u.i, (sqlite3Config.bSmallMalloc!=0xee)*8); p->n = sqlite3Int64ToText(x, zBuf); #else p->n = sqlite3Int64ToText(p->u.i, zBuf); #endif + if( p->flags & MEM_IntReal ){ + memcpy(zBuf+p->n,".0", 3); + p->n += 2; + } }else{ sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); - sqlite3_str_appendf(&acc, "%!.15g", - (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r); + sqlite3_str_appendf(&acc, "%!.*g", + (p->db ? p->db->nFpDigit : 17), p->u.r); assert( acc.zText==zBuf && acc.mxAlloc<=0 ); zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ p->n = acc.nChar; @@ -84925,6 +85365,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 ); } if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; + if( p->db==0 ){ + return 1; /* db->nFpDigit required to validate p->z[] */ + } memcpy(&tmp, p, sizeof(tmp)); vdbeMemRenderNum(sizeof(zBuf), zBuf, &tmp); z = p->z; @@ -85075,13 +85518,16 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ ** ** This is an optimization. Correct operation continues even if ** this routine is a no-op. +** +** Return true if the strig is zero-terminated after this routine is +** called and false if it is not. */ -SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ +SQLITE_PRIVATE int sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){ /* pMem must be a string, and it cannot be an ephemeral or static string */ - return; + return 0; } - if( pMem->enc!=SQLITE_UTF8 ) return; + if( pMem->enc!=SQLITE_UTF8 ) return 0; assert( pMem->z!=0 ); if( pMem->flags & MEM_Dyn ){ if( pMem->xDel==sqlite3_free @@ -85089,18 +85535,19 @@ SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ ){ pMem->z[pMem->n] = 0; pMem->flags |= MEM_Term; - return; + return 1; } if( pMem->xDel==sqlite3RCStrUnref ){ /* Blindly assume that all RCStr objects are zero-terminated */ pMem->flags |= MEM_Term; - return; + return 1; } }else if( pMem->szMalloc >= pMem->n+1 ){ pMem->z[pMem->n] = 0; pMem->flags |= MEM_Term; - return; + return 1; } + return 0; } /* @@ -85398,18 +85845,117 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){ } } +/* +** This routine implements the uncommon and slower path for +** sqlite3MemRealValueRC() that has to deal with input strings +** that are not UTF8 or that are not zero-terminated. It is +** broken out into a separate no-inline routine so that the +** main sqlite3MemRealValueRC() routine can avoid unnecessary +** stack pushes. +** +** A text->float translation of pMem->z is written into *pValue. +** +** Result code invariants: +** +** rc==0 => ERROR: Input string not well-formed, or OOM +** rc<0 => Some prefix of the input is well-formed +** rc>0 => All of the input is well-formed +** (rc&2)==0 => The number is expressed as an integer, with no +** decimal point or eNNN suffix. +*/ +static SQLITE_NOINLINE int sqlite3MemRealValueRCSlowPath( + Mem *pMem, + double *pValue +){ + int rc = SQLITE_OK; + *pValue = 0.0; + if( pMem->enc==SQLITE_UTF8 ){ + char *zCopy = sqlite3DbStrNDup(pMem->db, pMem->z, pMem->n); + if( zCopy ){ + rc = sqlite3AtoF(zCopy, pValue); + sqlite3DbFree(pMem->db, zCopy); + } + return rc; + }else{ + int n, i, j; + char *zCopy; + const char *z; + + n = pMem->n & ~1; + zCopy = sqlite3DbMallocRaw(pMem->db, n/2 + 2); + if( zCopy ){ + z = pMem->z; + if( pMem->enc==SQLITE_UTF16LE ){ + for(i=j=0; idb, zCopy); + } + return rc; + } +} + +/* +** Invoke sqlite3AtoF() on the text value of pMem. Write the +** translation of the text input into *pValue. +** +** The caller must ensure that pMem->db!=0 and that pMem is in +** mode MEM_Str or MEM_Blob. +** +** Result code invariants: +** +** rc==0 => ERROR: Input string not well-formed, or OOM +** rc<0 => Some prefix of the input is well-formed +** rc>0 => All of the input is well-formed +** (rc&2)==0 => The number is expressed as an integer, with no +** decimal point or eNNN suffix. +*/ +SQLITE_PRIVATE int sqlite3MemRealValueRC(Mem *pMem, double *pValue){ + testcase( pMem->db==0 ); + assert( pMem->flags & (MEM_Str|MEM_Blob) ); + if( pMem->z==0 ){ + *pValue = 0.0; + return 0; + }else if( pMem->enc==SQLITE_UTF8 + && ((pMem->flags & MEM_Term)!=0 || sqlite3VdbeMemZeroTerminateIfAble(pMem)) + ){ + return sqlite3AtoF(pMem->z, pValue); + }else if( pMem->n==0 ){ + *pValue = 0.0; + return 0; + }else{ + return sqlite3MemRealValueRCSlowPath(pMem, pValue); + } +} + +/* +** This routine acts as a bridge from sqlite3VdbeRealValue() to +** sqlite3VdbeRealValueRC, allowing sqlite3VdbeRealValue() to avoid +** stuffing values onto the stack. +*/ +static SQLITE_NOINLINE double sqlite3MemRealValueNoRC(Mem *pMem){ + double r; + (void)sqlite3MemRealValueRC(pMem, &r); + return r; +} + /* ** Return the best representation of pMem that we can get into a ** double. If pMem is already a double or an integer, return its ** value. If it is a string or blob, try to convert it to a double. ** If it is a NULL, return 0.0. */ -static SQLITE_NOINLINE double memRealValue(Mem *pMem){ - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - double val = (double)0; - sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); - return val; -} SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -85420,7 +85966,7 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ testcase( pMem->flags & MEM_IntReal ); return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ - return memRealValue(pMem); + return sqlite3MemRealValueNoRC(pMem); }else{ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ return (double)0; @@ -85544,8 +86090,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ sqlite3_int64 ix; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); - if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1) + rc = sqlite3MemRealValueRC(pMem, &pMem->u.r); + if( ((rc&2)==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<2) || sqlite3RealSameAsInt(pMem->u.r, (ix = sqlite3RealToI64(pMem->u.r))) ){ pMem->u.i = ix; @@ -86009,6 +86555,84 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( return SQLITE_OK; } +/* Like sqlite3VdbeMemSetStr() except: +** +** enc is always SQLITE_UTF8 +** pMem->db is always non-NULL +*/ +SQLITE_PRIVATE int sqlite3VdbeMemSetText( + Mem *pMem, /* Memory cell to set to string value */ + const char *z, /* String pointer */ + i64 n, /* Bytes in string, or negative */ + void (*xDel)(void*) /* Destructor function */ +){ + i64 nByte = n; /* New value for pMem->n */ + u16 flags; + + assert( pMem!=0 ); + assert( pMem->db!=0 ); + assert( sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + + /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ + if( !z ){ + sqlite3VdbeMemSetNull(pMem); + return SQLITE_OK; + } + + if( nByte<0 ){ + nByte = strlen(z); + flags = MEM_Str|MEM_Term; + }else{ + flags = MEM_Str; + } + if( nByte>(i64)pMem->db->aLimit[SQLITE_LIMIT_LENGTH] ){ + if( xDel && xDel!=SQLITE_TRANSIENT ){ + if( xDel==SQLITE_DYNAMIC ){ + sqlite3DbFree(pMem->db, (void*)z); + }else{ + xDel((void*)z); + } + } + sqlite3VdbeMemSetNull(pMem); + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); + } + + /* The following block sets the new values of Mem.z and Mem.xDel. It + ** also sets a flag in local variable "flags" to indicate the memory + ** management (one of MEM_Dyn or MEM_Static). + */ + if( xDel==SQLITE_TRANSIENT ){ + i64 nAlloc = nByte + 1; + testcase( nAlloc==31 ); + testcase( nAlloc==32 ); + if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){ + return SQLITE_NOMEM_BKPT; + } + assert( pMem->z!=0 ); + memcpy(pMem->z, z, nByte); + pMem->z[nByte] = 0; + }else{ + sqlite3VdbeMemRelease(pMem); + pMem->z = (char *)z; + if( xDel==SQLITE_DYNAMIC ){ + pMem->zMalloc = pMem->z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + pMem->xDel = 0; + }else if( xDel==SQLITE_STATIC ){ + pMem->xDel = xDel; + flags |= MEM_Static; + }else{ + pMem->xDel = xDel; + flags |= MEM_Dyn; + } + } + pMem->flags = flags; + pMem->n = (int)(nByte & 0x7fffffff); + pMem->enc = SQLITE_UTF8; + return SQLITE_OK; +} + /* ** Move data out of a btree key or data field and into a Mem structure. ** The data is payload from the entry that pCur is currently pointing @@ -86032,7 +86656,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( ){ int rc; pMem->flags = MEM_Null; - if( sqlite3BtreeMaxRecordSize(pCur)=SQLITE_MAX_ALLOCATION_SIZE ){ + return SQLITE_NOMEM_BKPT; + } + if( (u64)amt + (u64)offset > (u64)sqlite3BtreeMaxRecordSize(pCur) ){ return SQLITE_CORRUPT_BKPT; } if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){ @@ -86432,7 +87061,7 @@ static int valueFromExpr( if( affinity==SQLITE_AFF_BLOB ){ if( op==TK_FLOAT ){ assert( pVal && pVal->z && pVal->flags==(MEM_Str|MEM_Term) ); - sqlite3AtoF(pVal->z, &pVal->u.r, pVal->n, SQLITE_UTF8); + sqlite3AtoF(pVal->z, &pVal->u.r); pVal->flags = MEM_Real; }else if( op==TK_INTEGER ){ /* This case is required by -9223372036854775808 and other strings @@ -86542,7 +87171,30 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr( u8 affinity, /* Affinity to use */ sqlite3_value **ppVal /* Write the new value here */ ){ - return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; + int rc = SQLITE_OK; + sqlite3_value *pVal = 0; + if( pExpr ){ + rc = valueFromExpr(db, pExpr, enc, affinity, &pVal, 0); + if( rc==SQLITE_OK && pVal + && affinity==SQLITE_AFF_REAL + && (pVal->flags & MEM_Int) + && (pVal->u.i<-140737488355328LL || pVal->u.i>140737488355327LL) + ){ + /* If the integer value is too large to fit in a 6-byte integer and + ** the affinity is REAL, convert it to a real value now. In most + ** cases an OP_RealAffinity opcode will be used to convert the + ** value to an actual real, but this opcode is omitted if the values + ** are being read directly from a table in order to create an index + ** key. It is important to get a "real" real value for the larger + ** magnitude integer values so that comparisons work correctly - + ** SQLite by default will convert real values to integers before + ** doing the comparison, which is different from converting to real + ** first. */ + sqlite3VdbeMemRealify(pVal); + } + } + *ppVal = pVal; + return rc; } #ifdef SQLITE_ENABLE_STAT4 @@ -86587,7 +87239,7 @@ static int stat4ValueFromExpr( }else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){ Vdbe *v; int iBindVar = pExpr->iColumn; - sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); + sqlite3VdbeReprepareOnBind(pParse->pVdbe, iBindVar, 0); if( (v = pParse->pReprepare)!=0 ){ pVal = valueNew(db, pAlloc); if( pVal ){ @@ -86700,6 +87352,11 @@ SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr( ** ** If *ppVal is initially NULL then the caller is responsible for ** ensuring that the value written into *ppVal is eventually freed. +** +** If the buffer does not contain a well-formed record, this routine may +** read several bytes past the end of the buffer. Callers must therefore +** ensure that any buffer which may contain a corrupt record is padded +** with at least 8 bytes of addressable memory. */ SQLITE_PRIVATE int sqlite3Stat4Column( sqlite3 *db, /* Database handle */ @@ -86887,6 +87544,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlag p->prepFlags = prepFlags; if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ p->expmask = 0; + p->smimask = 0; } assert( p->zSql==0 ); p->zSql = sqlite3DbStrNDup(p->db, z, n); @@ -86960,7 +87618,8 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ pA->zNormSql = pB->zNormSql; pB->zNormSql = zTmp; #endif - pB->expmask = pA->expmask; + pB->expmask |= pA->expmask; + pB->smimask |= pA->smimask; pB->prepFlags = pA->prepFlags; memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter)); pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++; @@ -87179,6 +87838,20 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( return i; } +/* Generate an opcode that loads a 64-bit integer into register iDest +*/ +SQLITE_PRIVATE int sqlite3VdbeAddInt64(Vdbe *p, int iDest, i64 iVal){ + return sqlite3VdbeAddOp3(p, OP_Int64, LOWER32(iVal), iDest, UPPER32(iVal)); +} + +/* Generate an opcode that loads a 64-floating point value into register iDest. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddDouble(Vdbe *p, int iDest, double rVal){ + i64 iVal; + memcpy(&iVal,&rVal,8); + return sqlite3VdbeAddOp3(p, OP_Real, LOWER32(iVal), iDest, UPPER32(iVal)); +} + /* Generate code for an unconditional jump to instruction iDest */ SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){ @@ -87282,24 +87955,6 @@ SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall( return addr; } -/* -** Add an opcode that includes the p4 value with a P4_INT64 or -** P4_REAL type. -*/ -SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8( - Vdbe *p, /* Add the opcode to this VM */ - int op, /* The new opcode */ - int p1, /* The P1 operand */ - int p2, /* The P2 operand */ - int p3, /* The P3 operand */ - const u8 *zP4, /* The P4 operand */ - int p4type /* P4 operand type */ -){ - char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8); - if( p4copy ) memcpy(p4copy, zP4, 8); - return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); -} - #ifndef SQLITE_OMIT_EXPLAIN /* ** Return the address of the current EXPLAIN QUERY PLAN baseline. @@ -87371,11 +88026,21 @@ SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){ ** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees ** as having been used. ** -** The zWhere string must have been obtained from sqlite3_malloc(). +** zWhere is a WHERE clause that defines which entries of the schema +** to reparse. If zWhere==0, that means all entries. p5 is a mask +** of INITFLAG_* values for the parse. +** +** In the current usage, the following are always true: +** +** ALTER TABLE: zWhere==0, p5!=0 +** Otherwise: zWhere!=0, p5==0 +** +** The zWhere string must have been obtained from sqlite3DbMalloc(). ** This routine will take ownership of the allocated memory. */ SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){ int j; + assert( p5==0 || zWhere==0 ); sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); sqlite3VdbeChangeP5(p, p5); for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); @@ -87432,7 +88097,7 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse *pParse){ ** a prior call to sqlite3VdbeMakeLabel(). */ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ - int nNewSize = 10 - p->nLabel; + int nNewSize = 25 - p->nLabel; p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, nNewSize*sizeof(p->aLabel[0])); if( p->aLabel==0 ){ @@ -87603,6 +88268,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ || opcode==OP_Function || opcode==OP_PureFunc || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) + || (opcode==OP_MustBeInt && pOp->p2==0) ){ hasAbort = 1; break; @@ -88196,8 +88862,6 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ freeP4FuncCtx(db, (sqlite3_context*)p4); break; } - case P4_REAL: - case P4_INT64: case P4_DYNAMIC: case P4_INTARRAY: { if( p4 ) sqlite3DbNNFreeNN(db, p4); @@ -88551,6 +89215,9 @@ static int translateP(char c, const Op *pOp){ ** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1 ** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0 ** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x +** "PINT13" -> int(P1|P3<<32) +** "PDBL13" -> real(P1|P3<<32) +** "PHEX23" -> hex(P2|P3<<32) */ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment( sqlite3 *db, /* Optional - Oom error reporting only */ @@ -88586,6 +89253,20 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment( seenCom = 1; break; } + }else if( strncmp(&zSynopsis[ii],"INT13",5)==0 ){ + sqlite3_str_appendf(&x,"%lld",INT32_TO_64(pOp->p1,pOp->p3)); + ii += 4; +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + }else if( strncmp(&zSynopsis[ii],"HEX23",5)==0 ){ + sqlite3_str_appendf(&x,"0x%llx",INT32_TO_64(pOp->p2,pOp->p3)); + ii += 4; +#endif + }else if( strncmp(&zSynopsis[ii],"DBL13",5)==0 ){ + i64 iVal = INT32_TO_64(pOp->p1,pOp->p3); + double r; + memcpy(&r, &iVal, 8); + sqlite3_str_appendf(&x,"%.17g",r); + ii += 4; }else{ int v1 = translateP(c, pOp); int v2; @@ -88715,7 +89396,6 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){ #if VDBE_DISPLAY_P4 /* ** Compute a string that describes the P4 parameter for an opcode. -** Use zTemp for any required temporary buffer space. */ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ char *zP4 = 0; @@ -88764,18 +89444,10 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } - case P4_INT64: { - sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); - break; - } case P4_INT32: { sqlite3_str_appendf(&x, "%d", pOp->p4.i); break; } - case P4_REAL: { - sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); - break; - } case P4_MEM: { Mem *pMem = pOp->p4.pMem; if( pMem->flags & MEM_Str ){ @@ -88818,6 +89490,10 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ zP4 = pOp->p4.pTab->zName; break; } + case P4_INDEX: { + zP4 = pOp->p4.pIdx->zName; + break; + } case P4_SUBRTNSIG: { SubrtnSig *pSig = pOp->p4.pSubrtnSig; sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); @@ -89497,7 +90173,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( n = ROUND8P(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); - x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ + x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes unused memory */ assert( x.nFree>=0 ); assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); @@ -89716,7 +90392,7 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName( } assert( p->aColName!=0 ); pColName = &(p->aColName[idx+var*p->nResAlloc]); - rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); + rc = sqlite3VdbeMemSetText(pColName, zName, -1, xDel); assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); return rc; } @@ -90860,67 +91536,16 @@ SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in){ } #endif /* SQLITE_MIXED_ENDIAN_64BIT_FLOAT */ - -/* Input "x" is a sequence of unsigned characters that represent a -** big-endian integer. Return the equivalent native integer -*/ -#define ONE_BYTE_INT(x) ((i8)(x)[0]) -#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1]) -#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2]) -#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) -#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) - /* -** Deserialize the data blob pointed to by buf as serial type serial_type -** and store the result in pMem. -** -** This function is implemented as two separate routines for performance. -** The few cases that require local variables are broken out into a separate -** routine so that in most cases the overhead of moving the stack pointer -** is avoided. +** Deserialize the REAL number pointed to by buf and store it in pMem. */ -static void serialGet( +static int sqlite3VdbeSerialGet7( const unsigned char *buf, /* Buffer to deserialize from */ - u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ ){ - u64 x = FOUR_BYTE_UINT(buf); - u32 y = FOUR_BYTE_UINT(buf+4); - x = (x<<32) + y; - if( serial_type==6 ){ - /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit - ** twos-complement integer. */ - pMem->u.i = *(i64*)&x; - pMem->flags = MEM_Int; - testcase( pMem->u.i<0 ); - }else{ - /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit - ** floating point number. */ -#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) - /* Verify that integers and floating point values use the same - ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is - ** defined that 64-bit floating point values really are mixed - ** endian. - */ - static const u64 t1 = ((u64)0x3ff00000)<<32; - static const double r1 = 1.0; - u64 t2 = t1; - swapMixedEndianFloat(t2); - assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); -#endif - assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); - swapMixedEndianFloat(x); - memcpy(&pMem->u.r, &x, sizeof(x)); - pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; - } -} -static int serialGet7( - const unsigned char *buf, /* Buffer to deserialize from */ - Mem *pMem /* Memory cell to write value into */ -){ - u64 x = FOUR_BYTE_UINT(buf); - u32 y = FOUR_BYTE_UINT(buf+4); - x = (x<<32) + y; + /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit + ** floating point number. */ + u64 x = sqlite3Get8byte(buf); assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); swapMixedEndianFloat(x); memcpy(&pMem->u.r, &x, sizeof(x)); @@ -90931,6 +91556,13 @@ static int serialGet7( pMem->flags = MEM_Real; return 0; } + +/* +** Deserialize the data blob pointed to by buf as serial type serial_type +** and store the result in pMem. +** +** Similar code is found in the implementation of the OP_Column opcode. +*/ SQLITE_PRIVATE void sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ @@ -90989,16 +91621,21 @@ SQLITE_PRIVATE void sqlite3VdbeSerialGet( case 5: { /* 6-byte signed integer */ /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit ** twos-complement integer. */ - pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); + pMem->u.i = SIX_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 6: { /* 8-byte signed integer */ + /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit + ** twos-complement integer. */ + pMem->u.i = (i64)sqlite3Get8byte(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); return; } - case 6: /* 8-byte signed integer */ case 7: { /* IEEE floating point */ - /* These use local variables, so do them in a separate routine - ** to avoid having to move the frame pointer in the common case */ - serialGet(buf,serial_type,pMem); + sqlite3VdbeSerialGet7(buf, pMem); return; } case 8: /* Integer 0 */ @@ -91604,7 +92241,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( }else if( serial_type==0 ){ rc = -1; }else if( serial_type==7 ){ - serialGet7(&aKey1[d1], &mem1); + sqlite3VdbeSerialGet7(&aKey1[d1], &mem1); rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); }else{ i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); @@ -91630,7 +92267,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( rc = -1; }else{ if( serial_type==7 ){ - if( serialGet7(&aKey1[d1], &mem1) ){ + if( sqlite3VdbeSerialGet7(&aKey1[d1], &mem1) ){ rc = -1; /* mem1 is a NaN */ }else if( mem1.u.ru.r ){ rc = -1; @@ -91712,7 +92349,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( serial_type = aKey1[idx1]; if( serial_type==0 || serial_type==10 - || (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0) + || (serial_type==7 && sqlite3VdbeSerialGet7(&aKey1[d1], &mem1)!=0) ){ assert( rc==0 ); }else{ @@ -91786,65 +92423,42 @@ static int vdbeRecordCompareInt( const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; int serial_type = ((const u8*)pKey1)[1]; int res; - u32 y; - u64 x; i64 v; i64 lhs; vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB ); - switch( serial_type ){ - case 1: { /* 1-byte signed integer */ - lhs = ONE_BYTE_INT(aKey); - testcase( lhs<0 ); - break; - } - case 2: { /* 2-byte signed integer */ - lhs = TWO_BYTE_INT(aKey); - testcase( lhs<0 ); - break; - } - case 3: { /* 3-byte signed integer */ - lhs = THREE_BYTE_INT(aKey); - testcase( lhs<0 ); - break; - } - case 4: { /* 4-byte signed integer */ - y = FOUR_BYTE_UINT(aKey); - lhs = (i64)*(int*)&y; - testcase( lhs<0 ); - break; - } - case 5: { /* 6-byte signed integer */ - lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); - testcase( lhs<0 ); - break; - } - case 6: { /* 8-byte signed integer */ - x = FOUR_BYTE_UINT(aKey); - x = (x<<32) | FOUR_BYTE_UINT(aKey+4); - lhs = *(i64*)&x; - testcase( lhs<0 ); - break; - } - case 8: - lhs = 0; - break; - case 9: - lhs = 1; - break; - - /* This case could be removed without changing the results of running - ** this code. Including it causes gcc to generate a faster switch - ** statement (since the range of switch targets now starts at zero and - ** is contiguous) but does not cause any duplicate code to be generated - ** (as gcc is clever enough to combine the two like cases). Other - ** compilers might be similar. */ - case 0: case 7: - return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); - default: - return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + /* Serial types 1 through 6 are big-endian integers of 1, 2, 3, 4, + ** 6, or 8 bytes. Rather than handle each width in its own switch + ** case, read 8 bytes and use an arithmetic right shift to drop the + ** unwanted low-order bytes and sign-extend the value. This helps + ** because the switch tends to mispredict when a key column contains + ** integers of varying sizes. The first entry of aShift[] is a + ** placeholder so that the table can be indexed by serial_type + ** directly. Reading 8 bytes is always safe, because a buffer passed + ** to this routine has at least 74 bytes of padding after it, as + ** explained in sqlite3VdbeFindCompare() below. + */ + if( (u32)(serial_type-1)<=5 ){ + static const u8 aShift[] = { 0, 56, 48, 40, 32, 16, 0 }; + lhs = ((i64)sqlite3Get8byte(aKey)) >> aShift[serial_type]; + /* ^^--- This shift operator + ** needs to be an arithmetic right-shift, which means that + ** if the left-hand operand (LHS) is negative, it will be sign-extended + ** so that the final results is also negative. All modern C + ** compilers work this way as long as the LHS is a signed integer + ** (which is why the unsigned result from sqlite3Get8byte() is cast + ** into i64), but it is not defined by the C standards, or so Claude + ** tells me. That the correct result is obtained is verified by the + ** following assert() and testcase() macros: + */ + assert( 0<=(i64)sqlite3Get8byte(aKey) || lhs<0 ); + testcase( lhs<0 ); + }else if( serial_type==8 || serial_type==9 ){ + lhs = serial_type - 8; + }else{ + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); } assert( pPKey2->u.i == pPKey2->aMem[0].u.i ); @@ -91979,7 +92593,7 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ testcase( flags & MEM_Null ); testcase( flags & MEM_Blob ); if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 - && p->pKeyInfo->aColl[0]==0 + && sqlite3IsBinary(p->pKeyInfo->aColl[0]) ){ assert( flags & MEM_Str ); p->u.z = p->aMem[0].z; @@ -92195,17 +92809,247 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff /* ** Configure SQL variable iVar so that binding a new value to it signals ** to sqlite3_reoptimize() that re-preparing the statement may result -** in a better query plan. +** in a better query plan. If parameter bSmallint is true, then the +** statement is only re-prepared if the new value is integer value 0 or 1. +** +** The v->expmask bit is always set. expmask means that a reprepare is +** possible. The v->smimask bit is only set if we want to restrict +** reprepare when the value changes from (0,1) to something else, or from +** something else to (0,1). */ -SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ +SQLITE_PRIVATE void sqlite3VdbeReprepareOnBind(Vdbe *v, int iVar, int bSmallint){ + u32 m; assert( iVar>0 ); assert( (v->db->flags & SQLITE_EnableQPSG)==0 || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); - if( iVar>=32 ){ - v->expmask |= 0x80000000; + + m = (iVar>=32) ? 0x80000000 : ((u32)1 << (iVar-1)); + if( bSmallint ){ + if( (v->expmask & m)==0 ) v->smimask |= m; }else{ - v->expmask |= ((u32)1 << (iVar-1)); + v->smimask &= ~m; } + v->expmask |= m; + + /* smimask is always a subset of expmask */ + assert( (v->smimask & v->expmask) == v->smimask ); +} + +/* +** Helper function for vdbeIsMatchingIndexKey(). Return true if column +** iCol should be ignored when comparing a record with a record from +** an index on disk. The field should be ignored if: +** +** * the corresponding bit in mask is set, and +** * either: +** - bIntegrity is false, or +** - the two Mem values are both real values that differ by +** BTREE_ULPDISTORTION or fewer ULPs. +*/ +static int vdbeSkipField( + Bitmask mask, /* Mask of indexed expression fields */ + int iCol, /* Column of index being considered */ + Mem *pMem1, /* Expected index value */ + Mem *pMem2, /* Actual indexed value */ + int bIntegrity /* True if running PRAGMA integrity_check */ +){ +#define BTREE_ULPDISTORTION 2 + if( iCol>=BMS || (mask & MASKBIT(iCol))==0 ) return 0; + if( bIntegrity==0 ) return 1; + if( (pMem1->flags & MEM_Real) && (pMem2->flags & MEM_Real) ){ + u64 m1, m2; + memcpy(&m1,&pMem1->u.r,8); + memcpy(&m2,&pMem2->u.r,8); + if( (m1pKeyInfo->enc; + m.db = p->pKeyInfo->db; + nRec = sqlite3BtreePayloadSize(pCur); + if( nRec>0x7fffffff ){ + return SQLITE_CORRUPT_BKPT; + } + + /* Allocate 5 extra bytes at the end of the buffer. This allows the + ** getVarint32() call below to read slightly past the end of the buffer + ** if the record is corrupt. */ + aRec = sqlite3MallocZero(nRec+5); + if( aRec==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3BtreePayload(pCur, 0, nRec, aRec); + } + + if( rc==SQLITE_OK ){ + u32 szHdr = 0; /* Size of record header in bytes */ + u32 idxHdr = 0; /* Current index in header */ + + idxHdr = getVarint32(aRec, szHdr); + if( szHdr>98307 ){ + rc = SQLITE_CORRUPT; + }else{ + int res = 0; /* Result of this function call */ + u32 idxRec = szHdr; /* Index of next field in record body */ + int ii = 0; /* Iterator variable */ + + int nCol = p->pKeyInfo->nAllField; + for(ii=0; ii=szHdr ){ + rc = SQLITE_CORRUPT_BKPT; + break; + } + idxHdr += getVarint32(&aRec[idxHdr], iSerial); + nSerial = sqlite3VdbeSerialTypeLen(iSerial); + if( (idxRec+nSerial)>nRec ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + sqlite3VdbeSerialGet(&aRec[idxRec], iSerial, &m); + if( vdbeSkipField(mask, ii, &p->aMem[ii], &m, bInt)==0 ){ + res = sqlite3MemCompare(&m, &p->aMem[ii], p->pKeyInfo->aColl[ii]); + if( res!=0 ) break; + } + } + idxRec += sqlite3VdbeSerialTypeLen(iSerial); + } + + *piRes = res; + } + } + + sqlite3_free(aRec); + return rc; +} + +/* +** This is called when the record in (*p) should be found in the index +** opened by cursor pCur, but was not. This may happen as part of a DELETE +** operation or an integrity check. +** +** One reason that an exact match was not found may be the EIIB bug - that +** a text-to-float conversion may have caused a real value in record (*p) +** to be slightly different from its counterpart on disk. This function +** attempts to find the right index record. If it does find the right +** record, it leaves *pCur pointing to it and sets (*pRes) to 0 before +** returning. Otherwise, (*pRes) is set to non-zero and an SQLite error +** code returned. +** +** The algorithm used to find the correct record is: +** +** * Scan up to BTREE_FDK_RANGE entries either side of the current entry. +** If parameter bIntegrity is false, then all fields that are indexed +** expressions or virtual table columns are omitted from the comparison. +** If bIntegrity is true, then small differences in real values in +** such fields are overlooked, but they are not omitted from the comparison +** altogether. +** +** * If the above fails to find an entry and bIntegrity is false, search +** the entire index. +*/ +SQLITE_PRIVATE int sqlite3VdbeFindIndexKey( + BtCursor *pCur, + Index *pIdx, + UnpackedRecord *p, + int *pRes, + int bIntegrity +){ +#define BTREE_FDK_RANGE 10 + int nStep = 0; + int res = 1; + int rc = SQLITE_OK; + int ii = 0; + + /* Calculate a mask based on the first 64 columns of the index. The mask + ** bit is set if the corresponding index field is either an expression + ** or a virtual column of the table. */ + Bitmask mask = 0; + for(ii=0; iinColumn, BMS); ii++){ + int iCol = pIdx->aiColumn[ii]; + if( (iCol==XN_EXPR) + || (iCol>=0 && (pIdx->pTable->aCol[iCol].colFlags & COLFLAG_VIRTUAL)) + ){ + mask |= MASKBIT(ii); + } + } + + /* If the mask is 0 at this point, then the index contains no expressions + ** or virtual columns. So do not search for a match - return so that the + ** caller may declare the db corrupt immediately. Or, if mask is non-zero, + ** proceed. */ + if( mask!=0 ){ + + /* Move the cursor back BTREE_FDK_RANGE entries. If this hits an EOF, + ** position the cursor at the first entry in the index and set nStep + ** to -1 so that the first loop below scans the entire index. Otherwise, + ** set nStep to BTREE_FDK_RANGE*2 so that the first loop below scans + ** just that many entries. */ + for(ii=0; sqlite3BtreeEof(pCur)==0 && ii=0), or the entire index if (nStep<0). */ + while( sqlite3BtreeCursorIsValidNN(pCur) ){ + for(ii=0; rc==SQLITE_OK && (iiexpired; + int iRet = 1; + if( pStmt ){ + Vdbe *p = (Vdbe*)pStmt; + sqlite3_mutex_enter(p->db->mutex); + iRet = p->expired; + sqlite3_mutex_leave(p->db->mutex); + } + return iRet; } #endif @@ -92776,15 +93626,18 @@ SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){ /**************************** sqlite3_result_ ******************************* -** The following routines are used by user-defined functions to specify -** the function result. +** The following routines are used by application-defined SQL functions to +** specify the function return value. There are many variations on +** sqlite3_result_xxxx() for different types of return values. ** -** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the -** result as a string or blob. Appropriate errors are set if the string/blob -** is too big or if an OOM occurs. +** The setStrOrError() function is a helper function that invokes +** sqlite3VdbeMemSetStr() to store the result as a string or blob. +** Appropriate errors are set if the string/blob is too big or if +** an OOM occurs. ** -** The invokeValueDestructor(P,X) routine invokes destructor function X() -** on value P if P is not going to be used and need to be destroyed. +** The invokeValueDestructor(P,X) helper function invokes the destructor +** function X() on value P if P is not going to be used and need to +** be destroyed. */ static void setResultStrOrError( sqlite3_context *pCtx, /* Function context */ @@ -92794,7 +93647,23 @@ static void setResultStrOrError( void (*xDel)(void*) /* Destructor function */ ){ Mem *pOut = pCtx->pOut; - int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); + int rc; + if( enc==SQLITE_UTF8 ){ + rc = sqlite3VdbeMemSetText(pOut, z, n, xDel); + }else if( enc==SQLITE_UTF8_ZT ){ + /* It is usually considered improper to assert() on an input. However, + ** the following assert() is checking for inputs that are documented + ** to result in undefined behavior. */ + assert( z==0 + || n<0 + || n>pOut->db->aLimit[SQLITE_LIMIT_LENGTH] + || z[n]==0 + ); + rc = sqlite3VdbeMemSetText(pOut, z, n, xDel); + pOut->flags |= MEM_Term; + }else{ + rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); + } if( rc ){ if( rc==SQLITE_TOOBIG ){ sqlite3_result_error_toobig(pCtx); @@ -92987,7 +93856,7 @@ SQLITE_API void sqlite3_result_text64( #endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); - if( enc!=SQLITE_UTF8 ){ + if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF8_ZT ){ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; n &= ~(u64)1; } @@ -93081,7 +93950,7 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ } } -/* Force an SQLITE_TOOBIG error. */ +/* Cause the SQL function to raise an SQLITE_TOOBIG error. */ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ #ifdef SQLITE_ENABLE_API_ARMOR if( pCtx==0 ) return; @@ -93092,7 +93961,7 @@ SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ SQLITE_UTF8, SQLITE_STATIC); } -/* An SQLITE_NOMEM error. */ +/* Cause the SQL function to raise an SQLITE_NOMEM error. */ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ #ifdef SQLITE_ENABLE_API_ARMOR if( pCtx==0 ) return; @@ -93103,6 +93972,64 @@ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ sqlite3OomFault(pCtx->pOut->db); } +/* Make the return value of the SQL function or virtual table pCtx +** be the content of the sqlite3_str object pStr. The eOwn flag +** determines ownership of the sqlite3_str object and its content. +** +** eOwn Ownership transfer +** ------------- ------------------------------------------------ +** +** SQLITE_COPY The SQL function returns a copy the sqlite3_str +** content and leaves the sqlite3_str object itself +** unchanged. +** +** SQLITE_XFER The content of the sqlite3_str is transferred to +** the SQL function and the SQL function takes +** responsibility for freeing that content when it is +** no longer needed. The sqlite3_str object is reset +** to an empty string. +** +** SQLITE_FINISH Like SQLITE_XFER except that the pStr is also +** freed using sqlite3_str_free(). +*/ +SQLITE_API void sqlite3_result_str(sqlite3_context *pCtx, sqlite3_str *pStr, int eOwn){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; + if( pStr==0 ) return; +#endif + testcase( pStr==(sqlite3_str*)&sqlite3OomStr ); + if( pStr->accError==0 ){ + if( pStr->nChar==0 ){ + setResultStrOrError(pCtx, "", 0, SQLITE_UTF8_ZT, SQLITE_STATIC); + sqlite3_str_reset(pStr); + }else{ + const char *zText = sqlite3_str_value(pStr); + /* Only internal code has the ability to capture a pointer to + ** an sqlite3_str object that uses static buffer. And none of + ** those internal use cases every invoke the sqlite3_result_str() + ** interface on a static-buffer sqlite3_str. Should this change + ** in the future, the following assert() will let us know. */ + assert( isMalloced(pStr) ); + if( eOwn==SQLITE_COPY ){ + setResultStrOrError(pCtx, zText, pStr->nChar, + SQLITE_UTF8, SQLITE_TRANSIENT); + }else{ + setResultStrOrError(pCtx, zText, pStr->nChar, + SQLITE_UTF8_ZT, SQLITE_DYNAMIC); + sqlite3StrAccumInit(pStr, pStr->db, 0, 0, pStr->mxAlloc); + } + } + }else if( pStr->accError==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(pCtx); + }else{ + assert( pStr->accError==SQLITE_TOOBIG ); + sqlite3_result_error_toobig(pCtx); + } + if( eOwn==SQLITE_FINISH ){ + sqlite3_str_free(pStr); + } +} + #ifndef SQLITE_UNTESTABLE /* Force the INT64 value currently stored as the result to be ** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL @@ -93138,6 +94065,8 @@ static int doWalCallbacks(sqlite3 *db){ } } } +#else + UNUSED_PARAMETER(db); #endif return rc; } @@ -93445,7 +94374,7 @@ static int valueFromValueList( Mem sMem; /* Raw content of current row */ memset(&sMem, 0, sizeof(sMem)); sz = sqlite3BtreePayloadSize(pRhs->pCsr); - rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,sz,&sMem); if( rc==SQLITE_OK ){ u8 *zBuf = (u8*)sMem.z; u32 iSerial; @@ -94053,10 +94982,8 @@ static int vdbeUnbind(Vdbe *p, unsigned int i){ sqlite3_mutex_leave(p->db->mutex); return SQLITE_RANGE; } + pVar = &p->aVar[i]; - sqlite3VdbeMemRelease(pVar); - pVar->flags = MEM_Null; - p->db->errCode = SQLITE_OK; /* If the bit corresponding to this variable in Vdbe.expmask is set, then ** binding a new value to this variable invalidates the current query plan. @@ -94068,9 +94995,22 @@ static int vdbeUnbind(Vdbe *p, unsigned int i){ ** following any change to the bindings of that parameter. */ assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 ); + assert( (p->expmask & p->smimask)==p->smimask ); if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<expired = 1; + /* If the p->smimask bit is also set, then only expire the statement if + ** the value being clobbered was integer value 0 or 1. */ + if( (p->smimask==0) + || (p->smimask & (i>=31 ? 0x80000000 : (u32)1<flags & MEM_Int)!=0 && pVar->u.i>=0 && pVar->u.i<=1) + ){ + p->expired = 1; + } } + + sqlite3VdbeMemRelease(pVar); + pVar->flags = MEM_Null; + p->db->errCode = SQLITE_OK; + return SQLITE_OK; } @@ -94094,13 +95034,25 @@ static int bindText( assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ if( zData!=0 ){ pVar = &p->aVar[i-1]; - rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); - if( rc==SQLITE_OK ){ - if( encoding==0 ){ - pVar->enc = ENC(p->db); - }else{ - rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); - } + if( encoding==SQLITE_UTF8 ){ + rc = sqlite3VdbeMemSetText(pVar, zData, nData, xDel); + }else if( encoding==SQLITE_UTF8_ZT ){ + /* It is usually consider improper to assert() on an input. + ** However, the following assert() is checking for inputs + ** that are documented to result in undefined behavior. */ + assert( zData==0 + || nData<0 + || nData>pVar->db->aLimit[SQLITE_LIMIT_LENGTH] + || ((u8*)zData)[nData]==0 + ); + rc = sqlite3VdbeMemSetText(pVar, zData, nData, xDel); + pVar->flags |= MEM_Term; + }else{ + rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); + if( encoding==0 ) pVar->enc = ENC(p->db); + } + if( rc==SQLITE_OK && encoding!=0 ){ + rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); } if( rc ){ sqlite3Error(p->db, rc); @@ -94155,15 +95107,46 @@ SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ return sqlite3_bind_int64(p, i, (i64)iValue); } SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ - int rc; - Vdbe *p = (Vdbe *)pStmt; - rc = vdbeUnbind(p, (u32)(i-1)); - if( rc==SQLITE_OK ){ - assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ - sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); + Mem *pVar; + Vdbe *p = (Vdbe*)pStmt; + if( vdbeSafetyNotNull(p) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(p->db->mutex); + if( p->eVdbeState!=VDBE_READY_STATE ){ + sqlite3Error(p->db, SQLITE_MISUSE_BKPT); + sqlite3_mutex_leave(p->db->mutex); + sqlite3_log(SQLITE_MISUSE, + "bind on a busy prepared statement: [%s]", p->zSql); + return SQLITE_MISUSE_BKPT; + } + if( i<=0 || (--i)>=p->nVar ){ + sqlite3Error(p->db, SQLITE_RANGE); sqlite3_mutex_leave(p->db->mutex); + return SQLITE_RANGE; } - return rc; + pVar = &p->aVar[i]; + if( p->expmask!=0 ){ + u32 expireMask = i>=32 ? 0x80000000 : (u32)1 << i; + assert( (p->expmask & p->smimask)==p->smimask ); + if( (p->expmask & expireMask)!=0 ){ + if( (p->smimask & expireMask)!=0 ){ + /* If the smimask bit is set, only expire the prepared statement + ** if the value is changing to or from (0,1) and something else */ + int sm1 = (pVar->flags & MEM_Int)!=0 && pVar->u.i>=0 && pVar->u.i<=1; + int sm2 = iValue>=0 && iValue<=1; + if( sm1!=sm2 ){ + p->expired = 1; + } + }else if( (pVar->flags & MEM_Int)==0 || iValue!=pVar->u.i ){ + /* Always expire if the smimask bit is clear */ + p->expired = 1; + } + } + } + sqlite3VdbeMemSetInt64(pVar, iValue); + sqlite3_mutex_leave(p->db->mutex); + return SQLITE_OK; } SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ int rc; @@ -94212,7 +95195,7 @@ SQLITE_API int sqlite3_bind_text64( unsigned char enc ){ assert( xDel!=SQLITE_DYNAMIC ); - if( enc!=SQLITE_UTF8 ){ + if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF8_ZT ){ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; nData &= ~(u64)1; } @@ -94787,6 +95770,11 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppVa sqlite3VdbeMemSetInt64(pMem, p->iKey2); }else if( iStore>=pUnpack->nField ){ pMem = (sqlite3_value *)columnNullValue(); + }else if( (p->pTab->aCol) + && (p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL) + && (pMem->flags & (MEM_Int|MEM_IntReal)) + ){ + sqlite3VdbeMemRealify(pMem); } }else{ /* For an UPDATE, memory cell (p->iNewReg+1+iStore) contains the required @@ -95249,17 +96237,19 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( #ifndef SQLITE_HWTIME_H #define SQLITE_HWTIME_H -/* -** The following routine only works on Pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if !defined(__STRICT_ANSI__) && \ - (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) +#if defined(_MSC_VER) && defined(_WIN32) + +/* #include "windows.h" */ + #include - #if defined(__GNUC__) + __inline sqlite3_uint64 sqlite3Hwtime(void){ + LARGE_INTEGER tm; + QueryPerformanceCounter(&tm); + return (sqlite3_uint64)tm.QuadPart; + } + +#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \ + (defined(i586) || defined(__i586__) || defined(_M_IX86)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned int lo, hi; @@ -95267,17 +96257,6 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( return (sqlite_uint64)hi << 32 | lo; } - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ @@ -95286,6 +96265,14 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( return (sqlite_uint64)hi << 32 | lo; } +#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + sqlite3_uint64 cnt; + __asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt)); + return cnt; + } + #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) __inline__ sqlite_uint64 sqlite3Hwtime(void){ @@ -95644,12 +96631,11 @@ static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ */ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ double rValue; - u8 enc = pRec->enc; int rc; assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str ); - rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc); + rc = sqlite3MemRealValueRC(pRec, &rValue); if( rc<=0 ) return; - if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ + if( (rc&2)==0 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ pRec->flags |= MEM_Int; }else{ pRec->u.r = rValue; @@ -95729,7 +96715,12 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ int eType = sqlite3_value_type(pVal); if( eType==SQLITE_TEXT ){ Mem *pMem = (Mem*)pVal; +#if SQLITE_THREADSAFE>0 + sqlite3_mutex *pMutex = pMem->db ? pMem->db->mutex : 0; +#endif + sqlite3_mutex_enter(pMutex); applyNumericAffinity(pMem, 0); + sqlite3_mutex_leave(pMutex); eType = sqlite3_value_type(pVal); } return eType; @@ -95762,15 +96753,15 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ pMem->u.i = 0; return MEM_Int; } - rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); + rc = sqlite3MemRealValueRC(pMem, &pMem->u.r); if( rc<=0 ){ - if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ + if( (rc&2)==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ pMem->u.i = ix; return MEM_Int; }else{ return MEM_Real; } - }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ + }else if( (rc&2)==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ pMem->u.i = ix; return MEM_Int; } @@ -95975,6 +96966,10 @@ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ /* ** Compute a bloom filter hash using pOp->p4.i registers from aMem[] beginning ** with pOp->p3. Return the hash. +** +** IMPORTANT RESTRICTION (tag-202607231411): This hash is only valid if the +** collating sequence for TEXT is BINARY. Hence, Bloom filters that use this +** hash will not work for look-ups that use any other collating sequence. */ static u64 filterHash(const Mem *aMem, const Op *pOp){ int i, mx; @@ -95987,17 +96982,33 @@ static u64 filterHash(const Mem *aMem, const Op *pOp){ h += p->u.i; }else if( p->flags & MEM_Real ){ h += sqlite3VdbeIntValue(p); - }else if( p->flags & (MEM_Str|MEM_Blob) ){ - /* All strings have the same hash and all blobs have the same hash, - ** though, at least, those hashes are different from each other and - ** from NULL. */ - h += 4093 + (p->flags & (MEM_Str|MEM_Blob)); + }else if( p->flags & MEM_Str ){ + u64 x; + h += p->n; + if( p->n >= (int)sizeof(x) ){ + memcpy(&x, p->z, sizeof(x)); + h += x; + memcpy(&x, p->z + p->n - sizeof(x), sizeof(x)); + h += x; + }else{ + x = 0; + memcpy(&x, p->z, p->n); + h += x; + } + }else if( p->flags & MEM_Blob ){ + int n = p->n; + u64 x = 0; + if( n ){ + memcpy(&x, p->z, MIN(n, (int)sizeof(x))); + h += x; + } + h += n; + if( p->flags & MEM_Zero ) h += p->u.nZero; } } return h; } - /* ** For OP_Column, factor out the case where content is loaded from ** overflow pages, so that the code to implement this case is separate @@ -96069,6 +97080,7 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow( }else{ rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, sqlite3RCStrUnref); + pDest->enc = encoding; } }else{ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest); @@ -96083,6 +97095,40 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow( return rc; } +/* +** Memory cell pMem may contain a blob or a NULL value. Cursor pCsr is +** open on an index. If the current index entry matches the blob value in +** pMem byte-for-byte, set pMem to NULL and return 1. Otherwise, return 0. +** +** If an error occurs, set (*pRc) to an SQLite error code. Return 1 in this +** case as well. +*/ +static SQLITE_NOINLINE int vdbeIndexKeyCompare( + BtCursor *pCsr, /* Cursor to compare key to */ + Mem *pMem, + int *pRc +){ + int ret = 0; + u32 nKey = 0; + + assert( pMem->flags & (MEM_Blob|MEM_Null) ); + nKey = sqlite3BtreePayloadSize(pCsr); + if( nKey==(u32)pMem->n && ALWAYS((pMem->flags & MEM_Blob)!=0) ){ + /* This code could just use sqlite3BtreePayloadFetch(). But calling that + ** function here apparently prevents compilers from inlining it in other, + ** more performance critical, places. So this code uses + ** MemFromBtreeZeroOffset(), which is just as fast in most cases, but also + ** handles the case where the index record uses overflow pages. */ + Mem m; + memset(&m, 0, sizeof(m)); + *pRc = sqlite3VdbeMemFromBtreeZeroOffset(pCsr, nKey, &m); + ret = (*pRc!=SQLITE_OK || 0==memcmp(pMem->z, m.z, nKey)); + sqlite3VdbeMemReleaseMalloc(&m); + } + + return ret; +} + /* ** Send a "statement aborts" message to the error log. */ @@ -96663,31 +97709,35 @@ case OP_Integer: { /* out2 */ break; } -/* Opcode: Int64 * P2 * P4 * -** Synopsis: r[P2]=P4 +/* Opcode: Int64 P1 P2 P3 * * +** Synopsis: r[P2]=PINT13 ** -** P4 is a pointer to a 64-bit integer value. -** Write that value into register P2. +** Combine P1 and P3 into a signed 64-bit integer. P1 is the least +** significant 32 bits and P3 is the most significant. Store the +** result in register P2. */ case OP_Int64: { /* out2 */ pOut = out2Prerelease(p, pOp); - assert( pOp->p4.pI64!=0 ); - pOut->u.i = *pOp->p4.pI64; + pOut->u.i = INT32_TO_64(pOp->p1,pOp->p3); break; } #ifndef SQLITE_OMIT_FLOATING_POINT -/* Opcode: Real * P2 * P4 * -** Synopsis: r[P2]=P4 +/* Opcode: Real P1 P2 P3 * * +** Synopsis: r[P2]=PDBL13 ** -** P4 is a pointer to a 64-bit floating point value. -** Write that value into register P2. +** P1 and P3 are combined to 64 bits with P1 being the lower the P3 +** the upper. The result is interpreted as a 64-bit floating-point +** and stored in register P2. */ case OP_Real: { /* same as TK_FLOAT, out2 */ + u64 ii; pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Real; - assert( !sqlite3IsNaN(*pOp->p4.pReal) ); - pOut->u.r = *pOp->p4.pReal; + ii = (u64)INT32_TO_64(pOp->p1,pOp->p3); + swapMixedEndianFloat(ii); + memcpy(&pOut->u.r, &ii, 8); + assert( !sqlite3IsNaN(pOut->u.r) ); break; } #endif @@ -97394,7 +98444,18 @@ case OP_AddImm: { /* in1 */ case OP_MustBeInt: { /* jump0, in1 */ pIn1 = &aMem[pOp->p1]; if( (pIn1->flags & MEM_Int)==0 ){ - applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); + if( (pIn1->flags & MEM_Real)!=0 ){ + sqlite3_int64 ix; + if( pIn1->u.r>=-9223372036854775808.0 + && pIn1->u.r<+9223372036854775808.0 + && (double)(ix = sqlite3RealToI64(pIn1->u.r))==pIn1->u.r + ){ + pIn1->u.i = ix; + MemSetTypeFlag(pIn1, MEM_Int); + } + }else{ + applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); + } if( (pIn1->flags & MEM_Int)==0 ){ VdbeBranchTaken(1, 2); if( pOp->p2==0 ){ @@ -98480,30 +99541,91 @@ case OP_Column: { /* ncycle */ assert( t==pC->aType[p2] ); if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the desired content fits on the original - ** page - where the content is not on an overflow page */ + ** page - where the content is not on an overflow page. + ** + ** The big switch() is an in-line variant of sqlite3VdbeSerialGet() that + ** has been optimized for the OP_Column opcode. + */ zData = pC->aRow + aOffset[p2]; - if( t<12 ){ - sqlite3VdbeSerialGet(zData, t, pDest); - }else{ - /* If the column value is a string, we need a persistent value, not - ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent - ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize(). - */ - static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; - pDest->n = len = (t-12)/2; - pDest->enc = encoding; - if( pDest->szMalloc < len+2 ){ - if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; + switch( t ){ + case 0: + case 11: pDest->flags = MEM_Null; - if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; - }else{ - pDest->z = pDest->zMalloc; + break; + case 1: + pDest->u.i = ONE_BYTE_INT(zData); + pDest->flags = MEM_Int; + testcase( pDest->u.i<0 ); + break; + case 2: + pDest->u.i = TWO_BYTE_INT(zData); + pDest->flags = MEM_Int; + testcase( pDest->u.i<0 ); + break; + case 3: + pDest->u.i = THREE_BYTE_INT(zData); + pDest->flags = MEM_Int; + testcase( pDest->u.i<0 ); + break; + case 4: + pDest->u.i = FOUR_BYTE_INT(zData); + pDest->flags = MEM_Int; + testcase( pDest->u.i<0 ); + break; + case 5: + pDest->u.i = SIX_BYTE_INT(zData); + pDest->flags = MEM_Int; + testcase( pDest->u.i<0 ); + break; + case 6: { + pDest->u.i = (i64)sqlite3Get8byte(zData); + pDest->flags = MEM_Int; + testcase( pDest->u.i<0 ); + break; } - memcpy(pDest->z, zData, len); - pDest->z[len] = 0; - pDest->z[len+1] = 0; - pDest->flags = aFlag[t&1]; - } + case 7: { + u64 x = sqlite3Get8byte(zData); + swapMixedEndianFloat(x); + pDest->flags = IsNaN(x) ? MEM_Null : MEM_Real; + memcpy(&pDest->u.r, &x, sizeof(x)); + testcase( pDest->u.r<0 ); + break; + } + case 8: + case 9: { + pDest->u.i = t-8; + pDest->flags = MEM_Int; + break; + } + case 10: + /* Internal use only: NULL with virtual table + ** UPDATE no-change flag set */ + pDest->flags = MEM_Null|MEM_Zero; + pDest->u.nZero = 0; + pDest->n = 0; + break; + default: { + /* If the column value is a string or blob, we need a persistent + ** value, not a MEM_Ephem value. This case is a fast short-cut + ** that is equivalent to calling sqlite3VdbeSerialGet() and + ** sqlite3VdbeDeephemeralize(). + */ + static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; + pDest->n = len = (t-12)/2; + pDest->enc = encoding; + if( pDest->szMalloc < len+2 ){ + if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; + pDest->flags = MEM_Null; + if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; + }else{ + pDest->z = pDest->zMalloc; + } + memcpy(pDest->z, zData, len); + pDest->z[len] = 0; + pDest->z[len+1] = 0; + pDest->flags = aFlag[t&1]; + } + } /* End of switch */ }else{ u8 p5; pDest->enc = encoding; @@ -98703,22 +99825,9 @@ case OP_Affinity: { assert( zAffinity[0]==SQLITE_AFF_NONE || memIsValid(pIn1) ); applyAffinity(pIn1, zAffinity[0], encoding); if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){ - /* When applying REAL affinity, if the result is still an MEM_Int - ** that will fit in 6 bytes, then change the type to MEM_IntReal - ** so that we keep the high-resolution integer value but know that - ** the type really wants to be REAL. */ - testcase( pIn1->u.i==140737488355328LL ); - testcase( pIn1->u.i==140737488355327LL ); - testcase( pIn1->u.i==-140737488355328LL ); - testcase( pIn1->u.i==-140737488355329LL ); - if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL ){ - pIn1->flags |= MEM_IntReal; - pIn1->flags &= ~MEM_Int; - }else{ - pIn1->u.r = (double)pIn1->u.i; - pIn1->flags |= MEM_Real; - pIn1->flags &= ~(MEM_Int|MEM_Str); - } + pIn1->u.r = (double)pIn1->u.i; + pIn1->flags |= MEM_Real; + pIn1->flags &= ~(MEM_Int|MEM_Str); } REGISTER_TRACE((int)(pIn1-aMem), pIn1); zAffinity++; @@ -98971,12 +100080,24 @@ case OP_MakeRecord: { } nByte = nHdr+nData; + /* If we are able to put an over-run area of 7 bytes on the end of the + ** memory allocation into which the record is being constructed, then + ** the encoding of integer values can go faster. This is only possible + ** if SQLITE_MAX_LENGTH is no with 7 of INT32_MAX and if the host CPU + ** byte-order is known at compile-time. + */ +#if SQLITE_MAX_LENGTH<=2147483640 && SQLITE_BYTEORDER>0 +# define OVERRUN 7 /* We are able to allocate an overrun of 7 bytes */ +#else +# define OVERRUN 0 /* No overrun will be available */ +#endif + /* Make sure the output register has a buffer large enough to store ** the new record. The output register (pOp->p3) is not allowed to ** be one of the input registers (because the following call to ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). */ - if( nByte+nZero<=pOut->szMalloc ){ + if( nByte+nZero<=pOut->szMalloc-OVERRUN ){ /* The output register is already large enough to hold the record. ** No error checks or buffer enlargement is required */ pOut->z = pOut->zMalloc; @@ -98986,7 +100107,7 @@ case OP_MakeRecord: { if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ + if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte+OVERRUN) ){ goto no_mem; } } @@ -99029,6 +100150,27 @@ case OP_MakeRecord: { } len = sqlite3SmallTypeSizes[serial_type]; assert( len>=1 && len<=8 && len!=5 && len!=7 ); +#if SQLITE_BYTEORDER==1234 + v = sqlite3BSwap64(v); + if( OVERRUN ){ + static const u8 aShift[] = { 0, 56, 48, 40, 32, 16, 0, 0 }; + v >>= aShift[serial_type]; + memcpy(zPayload, &v, 8); + }else{ + /* Test this limb by compiling with -DSQLITE_MAX_LENGTH=2147483647 */ + memcpy(zPayload, (u8*)&v + 8 - len, len); + } +#elif SQLITE_BYTEORDER==4321 + if( OVERRUN ){ + static const u8 aShift[] = { 0, 56, 48, 40, 32, 16, 0, 0 }; + v <<= aShift[serial_type]; + memcpy(zPayload, &v, 8); + }else{ + /* Test this limb by compiling with -DSQLITE_MAX_LENGTH=2147483647 */ + memcpy(zPayload, (u8*)&v + 8 - len, len); + } +#else + /* Test this limb by compiling with -DSQLITE_BYTEORDER=0 */ switch( len ){ default: zPayload[7] = (u8)(v&0xff); v >>= 8; zPayload[6] = (u8)(v&0xff); v >>= 8; @@ -99044,6 +100186,8 @@ case OP_MakeRecord: { /* no break */ deliberate_fall_through case 1: zPayload[0] = (u8)(v&0xff); } +#endif +#undef OVERRUN /* We are done with the OVERRUN macro now */ zPayload += len; } }else if( serial_type<0x80 ){ @@ -100001,21 +101145,21 @@ case OP_Close: { /* ncycle */ } #ifdef SQLITE_ENABLE_COLUMN_USED_MASK -/* Opcode: ColumnsUsed P1 * * P4 * +/* Opcode: ColumnsUsed P1 P2 P3 * * +** Synopsis: Cursor P1 uses columns PHEX23 ** ** This opcode (which only exists if SQLite was compiled with ** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the -** table or index for cursor P1 are used. P4 is a 64-bit integer -** (P4_INT64) in which the first 63 bits are one for each of the -** first 63 columns of the table or index that are actually used -** by the cursor. The high-order bit is set if any column after -** the 64th is used. +** table or index for cursor P1 are used. P2 and P3 combine to give +** a 64-bit unsigned integer mask. P2 stores the lower 32 bits and +** P3 stores the upper 32 bits. If the high-order bit of P3 is set +** that means that and 64-th or some later column is used. */ case OP_ColumnsUsed: { VdbeCursor *pC; pC = p->apCsr[pOp->p1]; assert( pC->eCurType==CURTYPE_BTREE ); - pC->maskUsed = *(u64*)pOp->p4.pI64; + pC->maskUsed = INT32_TO_64(pOp->p2,pOp->p3); break; } #endif @@ -100526,24 +101670,6 @@ case OP_SeekHit: { /* ncycle */ break; } -/* Opcode: IfNotOpen P1 P2 * * * -** Synopsis: if( !csr[P1] ) goto P2 -** -** If cursor P1 is not open or if P1 is set to a NULL row using the -** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through. -*/ -case OP_IfNotOpen: { /* jump */ - VdbeCursor *pCur; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pCur = p->apCsr[pOp->p1]; - VdbeBranchTaken(pCur==0 || pCur->nullRow, 2); - if( pCur==0 || pCur->nullRow ){ - goto jump_to_p2_and_check_for_interrupt; - } - break; -} - /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** @@ -100785,7 +101911,7 @@ case OP_SeekRowid: { /* jump0, in3, ncycle */ VdbeCursor *pC; BtCursor *pCrsr; int res; - u64 iKey; + i64 iKey; pIn3 = &aMem[pOp->p3]; testcase( pIn3->flags & MEM_Int ); @@ -100799,9 +101925,21 @@ case OP_SeekRowid: { /* jump0, in3, ncycle */ ** changing the datatype of pIn3, however, as it is used by other ** parts of the prepared statement. */ Mem x = pIn3[0]; - applyAffinity(&x, SQLITE_AFF_NUMERIC, encoding); - if( (x.flags & MEM_Int)==0 ) goto jump_to_p2; - iKey = x.u.i; + if( x.flags & MEM_Str ){ + applyNumericAffinity(&x, 1); + } + if( x.flags & MEM_Int ){ + iKey = x.u.i; + }else + if( (x.flags & MEM_Real)==0 + || x.u.r < -9223372036854775808.0 + || x.u.r > 9223372036854774784.0 + /* ^^^^^^^^^^^^^^^^^^^^^-- same value as every other double + ** between 9223372036854774263.0 and 923372036854775295.0 */ + || (double)(iKey = sqlite3RealToI64(x.u.r))!=x.u.r + ){ + goto jump_to_p2; + } goto notExistsWithKey; } /* Fall through into OP_NotExists */ @@ -101481,14 +102619,17 @@ case OP_Rowid: { /* out2, ncycle */ break; } -/* Opcode: NullRow P1 * * * * +/* Opcode: NullRow P1 P2 * * * ** -** Move the cursor P1 to a null row. Any OP_Column operations +** Move the cursor P1 to a null row if P2 is 0. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. ** ** If cursor P1 is not previously opened, open it now to a special ** pseudo-cursor that always returns NULL for every column. +** +** If P2 is not 0, then the nullRow flag on the pseudo-cursor is +** turned off. */ case OP_NullRow: { VdbeCursor *pC; @@ -101505,7 +102646,7 @@ case OP_NullRow: { pC->noReuse = 1; pC->uc.pCursor = sqlite3BtreeFakeValidCursor(); } - pC->nullRow = 1; + pC->nullRow = (pOp->p2==0); pC->cacheStatus = CACHE_STALE; if( pC->eCurType==CURTYPE_BTREE ){ assert( pC->uc.pCursor!=0 ); @@ -101911,20 +103052,22 @@ case OP_SorterInsert: { /* in2 */ break; } -/* Opcode: IdxDelete P1 P2 P3 * P5 -** Synopsis: key=r[P2@P3] +/* Opcode: IdxDelete P1 P2 P3 P4 P5 +** Synopsis: key=r[P2@P5] ** -** The content of P3 registers starting at register P2 form +** The content of P5 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. ** -** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error -** if no matching index entry is found. This happens when running -** an UPDATE or DELETE statement and the index entry to be updated -** or deleted is not found. For some uses of IdxDelete -** (example: the EXCEPT operator) it does not matter that no matching -** entry is found. For those cases, P5 is zero. Also, do not raise -** this (self-correcting and non-critical) error if in writable_schema mode. +** P4 is a pointer to an Index structure. +** +** If P3 is non-zero, it is the register number of a register holding +** a record that will be inserted into this index. If that record is +** identical to the one that would be deleted by this instruction, +** skip the delete and set register P3 to NULL. +** +** Raise an SQLITE_CORRUPT_INDEX error if no matching index entry is found +** and not in writable_schema mode. */ case OP_IdxDelete: { VdbeCursor *pC; @@ -101932,8 +103075,8 @@ case OP_IdxDelete: { int res; UnpackedRecord r; - assert( pOp->p3>0 ); - assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 ); + assert( pOp->p5>0 ); + assert( pOp->p2>0 && pOp->p2+pOp->p5<=(p->nMem+1 - p->nCursor)+1 ); assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); @@ -101942,18 +103085,34 @@ case OP_IdxDelete: { pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); r.pKeyInfo = pC->pKeyInfo; - r.nField = (u16)pOp->p3; + r.nField = pOp->p5; r.default_rc = 0; r.aMem = &aMem[pOp->p2]; rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res); if( rc ) goto abort_due_to_error; - if( res==0 ){ - rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); + if( res!=0 ){ + rc = sqlite3VdbeFindIndexKey(pCrsr, pOp->p4.pIdx, &r, &res, 0); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + if( res!=0 ){ + if( !sqlite3WritableSchema(db) ){ + rc = sqlite3ReportError( + SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); + goto abort_due_to_error; + } + pC->cacheStatus = CACHE_STALE; + pC->seekResult = 0; + break; + } + } + + if( pOp->p3 && vdbeIndexKeyCompare(pCrsr, &aMem[pOp->p3], &rc) ){ if( rc ) goto abort_due_to_error; - }else if( pOp->p5 && !sqlite3WritableSchema(db) ){ - rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); - goto abort_due_to_error; + sqlite3VdbeMemSetNull(&aMem[pOp->p3]); + break; } + + rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); + if( rc ) goto abort_due_to_error; assert( pC->deferredMoveto==0 ); pC->cacheStatus = CACHE_STALE; pC->seekResult = 0; @@ -102025,6 +103184,11 @@ case OP_IdxRowid: { /* out2, ncycle */ assert( pTabCur->eCurType==CURTYPE_BTREE ); assert( pTabCur->uc.pCursor!=0 ); assert( pTabCur->isTable ); +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) + assert( + sqlite3BtreeCursorHintTblCsr(pC->uc.pCursor)==pTabCur->uc.pCursor + ); +#endif pTabCur->nullRow = 0; pTabCur->movetoTarget = rowid; pTabCur->deferredMoveto = 1; @@ -102385,12 +103549,19 @@ case OP_SqlExec: { break; } -/* Opcode: ParseSchema P1 * * P4 * +/* Opcode: ParseSchema P1 * * P4 P5 ** ** Read and parse all entries from the schema table of database P1 ** that match the WHERE clause P4. If P4 is a NULL pointer, then the ** entire schema for P1 is reparsed. ** +** When P4 is NULL, the P5 value is used as the mFlags argument +** to sqlite3InitOne(). In other words, P5 should be a mask composed +** of INITFLAG_* values. +** +** The P4==0 case is only used by ALTER TABLE and P5!=0 for all such +** cases. For uses other than ALTER TABLE, P4<>0 and P5==0. +** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a re-entrant opcode. */ @@ -102418,6 +103589,7 @@ case OP_ParseSchema: { #ifndef SQLITE_OMIT_ALTERTABLE if( pOp->p4.z==0 ){ + assert( pOp->p5!=0 ); sqlite3SchemaClear(db->aDb[iDb].pSchema); db->mDbFlags &= ~DBFLAG_SchemaKnownOk; rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5); @@ -102426,6 +103598,7 @@ case OP_ParseSchema: { }else #endif { + assert( pOp->p5==0 ); zSchema = LEGACY_SCHEMA_TABLE; initData.db = db; initData.iDb = iDb; @@ -102580,6 +103753,58 @@ case OP_IntegrityCk: { sqlite3VdbeChangeEncoding(pIn1, encoding); goto check_for_interrupt; } + +/* Opcode: IFindKey P1 P2 P3 P4 * +** +** This instruction always follows an OP_Found with the same P1, P2 and P3 +** values as this instruction and a non-zero P4 value. The P4 value to +** this opcode is of type P4_INDEX and contains a pointer to the Index +** object of for the index being searched. +** +** This opcode uses sqlite3VdbeFindIndexKey() to search around the current +** cursor location for an index key that exactly matches all fields that +** are not indexed expressions or references to VIRTUAL generated columns, +** and either exactly match or are real numbers that are within 2 ULPs of +** each other if the don't match. +** +** To put it another way, this opcode looks for nearby index entries that +** are very close to the search key, but which might have small differences +** in floating-point values that come via an expression. +** +** If no nearby alternative entry is found in cursor P1, then jump to P2. +** But if a close match is found, fall through. +** +** This opcode is used by PRAGMA integrity_check to help distinguish +** between truely corrupt indexes and expression indexes that are holding +** floating-point values that are off by one or two ULPs. +*/ +case OP_IFindKey: { /* jump, in3 */ + VdbeCursor *pC; + int res; + UnpackedRecord r; + + assert( pOp[-1].opcode==OP_Found ); + assert( pOp[-1].p1==pOp->p1 ); + assert( pOp[-1].p3==pOp->p3 ); + pC = p->apCsr[pOp->p1]; + assert( pOp->p4type==P4_INDEX ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + assert( pC->isTable==0 ); + + memset(&r, 0, sizeof(r)); + r.aMem = &aMem[pOp->p3]; + r.nField = pOp->p4.pIdx->nColumn; + r.pKeyInfo = pC->pKeyInfo; + + rc = sqlite3VdbeFindIndexKey(pC->uc.pCursor, pOp->p4.pIdx, &r, &res, 1); + if( rc || res!=0 ){ + rc = SQLITE_OK; + goto jump_to_p2; + } + pC->nullRow = 0; + break; +}; #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: RowSetAdd P1 P2 * * * @@ -102735,7 +103960,7 @@ case OP_Program: { /* jump0 */ if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ rc = SQLITE_ERROR; - sqlite3VdbeError(p, "too many levels of trigger recursion"); + sqlite3VdbeError(p, "triggers nested too deep"); goto abort_due_to_error; } @@ -104346,23 +105571,37 @@ case OP_Init: { /* jump0 */ } #ifdef SQLITE_ENABLE_CURSOR_HINTS -/* Opcode: CursorHint P1 * * P4 * +/* Opcode: CursorHint P1 * P3 P4 * ** -** Provide a hint to cursor P1 that it only needs to return rows that -** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer -** to values currently held in registers. TK_COLUMN terms in the P4 +** Provide a hint to cursor P1. +** +** If P4 is of type P4_EXPR, then the hint is that the cursor need only return +** rows that satisfy the Expr in P4. TK_REGISTER terms in the P4 expression +** refer to values currently held in registers. TK_COLUMN terms in the P4 ** expression refer to columns in the b-tree to which cursor P1 is pointing. +** P3 is ignore in this case. +** +** Or, if P4 is P4_NOTUSED, then the hint is that cursor P1 is an index cursor +** used to drive table cursor P3. In other words, that this VM may execute +** OP_DeferredSeek instructions to lazily position P3 based on current +** position of P1. */ case OP_CursorHint: { VdbeCursor *pC; + pC = p->apCsr[pOp->p1]; assert( pOp->p1>=0 && pOp->p1nCursor ); - assert( pOp->p4type==P4_EXPR ); - pC = p->apCsr[pOp->p1]; + if( pC ){ assert( pC->eCurType==CURTYPE_BTREE ); - sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, - pOp->p4.pExpr, aMem); + if( pOp->p4type==P4_EXPR ){ + sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, + pOp->p4.pExpr, aMem); + }else if( p->apCsr[pOp->p3] ){ + sqlite3BtreeCursorHint( + pC->uc.pCursor, BTREE_HINT_TABLECURSOR, p->apCsr[pOp->p3]->uc.pCursor + ); + } } break; } @@ -105494,6 +106733,7 @@ struct VdbeSorter { #define SORTER_TYPE_INTEGER 0x01 #define SORTER_TYPE_TEXT 0x02 +#define SORTER_TYPE_REAL 0x04 /* ** An instance of the following object is used to read records out of a @@ -106067,6 +107307,150 @@ static int vdbeSorterCompareInt( return res; } +/* Helper function for vdbeSorterCompareReal(). +** +** The first elements of both pKey1 and pKey2 have been decoded into double +** values r1 and r2. Do the comparison between those keys and return the +** result. If r1==r2, break the tie with a comparison of subsequent elements +** from each key. +*/ +static int vdbeSorterFinishRealCompare( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2, /* Right side of comparison */ + double r1, /* REAL value of first element of pKey1 */ + double r2 /* REAL value of first element of pKey2 */ +){ + int res; + if( r1r2 ){ + res = +1; + }else{ + res = 0; + } + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ + assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); + res = res * -1; + } + return res; +} + +/* Helper function for vdbeSorterCompareReal(). +** +** Buffer p[] is a record where the first term is guaranteed to be either +** a floating-point value, or an integer stand-in for a floating point +** value (a MEM_IntReal). Whatever its format, extract the value and +** return it. +*/ +static double vdbeSorterGetReal(const u8 *p){ + double r; /* the return value */ + + assert( p[0]<0x80 ); /* 1-byte headers: nAllField<13 */ + assert( p[1]>0 && p[1]<10 ); /* first fields proven numeric */ + + if( p[1]==7 ){ + u64 x = sqlite3Get8byte(p + p[0]); + swapMixedEndianFloat(x); + assert( !IsNaN(x) ); + memcpy(&r, &x, sizeof(r)); + }else{ + Mem m; + m.u.i = 0; + sqlite3VdbeSerialGet(p + p[0], p[1], &m); + assert( m.flags==MEM_Int ); + r = (double)m.u.i; + } + return r; +} + +/* Helper function for vdbeSorterCompareReal() +** +** This routine handles the case of comparing two floating-point values +** where one or both of the floating-point are represented by integers. +** In other words, where one both is an MEM_RealInt. +** +** This subroutine is factored out from vdbeSorterCompareReal() for +** efficiency. If inlined into vdbeSorterCompareReal(), this routine +** will use extra stack space and consume CPU cycles setting up and +** breaking down that stack space, even if in the common case where +** this path is not used. +*/ +static SQLITE_NOINLINE int vdbeSorterCompareRealInt( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + if( p1[1]==6 || p2[1]==6 ){ + /* 64-bit integer values cannot be represented exactly by a double so + ** must be handled by the generalized comparison function. */ + return vdbeSorterCompare(pTask, + pbKey2Cached, pKey1,nKey1, pKey2,nKey2); + }else{ + double r1 = vdbeSorterGetReal(p1); + double r2 = vdbeSorterGetReal(p2); + return vdbeSorterFinishRealCompare(pTask,pbKey2Cached, + pKey1,nKey1,pKey2,nKey2,r1,r2); + } +} + +/* +** Comparison function optimized for the case where the first term +** of both keys are either MEM_Real or MEM_RealInt. +** +** See also vdbeSorterCompareInt() for MEM_Int values and +** vdbeSorterCompareText() for MEM_Str values. The general +** case is vdbeSorterCompare() which handles anything, but is slower. +*/ +static int vdbeSorterCompareReal( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8*const p1 = (const u8*const)pKey1; /* Left key record */ + const u8*const p2 = (const u8*const)pKey2; /* Right key record */ + u64 x; /* A real value stored as an integer */ + double r1; /* First element of pKey1 */ + double r2; /* First element of pKey2 */ + + assert( p1[0]<0x80 && p2[0]<0x80 ); /* 1-byte headers: nAllField<13 */ + assert( p1[1]>0 && p1[1]<10 ); /* first field guaranteed numeric */ + assert( p2[1]>0 && p2[1]<10 ); /* first field guaranteed numeric */ + + if( p1[1]!=7 || p2[1]!=7 ){ + /* One or both floating point values are stored as INTEGER. This might + ** be because of the MEM_RealInt encoding. Try to optimize that case. */ + return vdbeSorterCompareRealInt(pTask, + pbKey2Cached, pKey1,nKey1, pKey2,nKey2 + ); + } + assert( p1[0]<=nKey1-8 && p2[0]<=nKey2-8 ); + + x = sqlite3Get8byte(p1 + *p1); + swapMixedEndianFloat(x); + assert( !IsNaN(x) ); + memcpy(&r1, &x, sizeof(r1)); + x = sqlite3Get8byte(p2 + *p2); + swapMixedEndianFloat(x); + assert( !IsNaN(x) ); + memcpy(&r2, &x, sizeof(r2)); + return vdbeSorterFinishRealCompare(pTask, + pbKey2Cached, pKey1,nKey1, pKey2,nKey2, r1, r2 + ); +} + /* ** Initialize the temporary index cursor just opened as a sorter cursor. ** @@ -106189,7 +107573,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0 ){ - pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; + pSorter->typeMask = SORTER_TYPE_INTEGER|SORTER_TYPE_TEXT|SORTER_TYPE_REAL; } } @@ -106561,10 +107945,12 @@ static SorterRecord *vdbeSorterMerge( ** sorter object passed as the only argument. */ static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){ - if( p->typeMask==SORTER_TYPE_INTEGER ){ + if( p->typeMask & SORTER_TYPE_INTEGER ){ return vdbeSorterCompareInt; - }else if( p->typeMask==SORTER_TYPE_TEXT ){ + }else if( p->typeMask & SORTER_TYPE_TEXT ){ return vdbeSorterCompareText; + }else if( p->typeMask & SORTER_TYPE_REAL ){ + return vdbeSorterCompareReal; } return vdbeSorterCompare; } @@ -106962,8 +108348,12 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite( assert( pCsr->eCurType==CURTYPE_SORTER ); pSorter = pCsr->uc.pSorter; getVarint32NR((const u8*)&pVal->z[1], t); - if( t>0 && t<10 && t!=7 ){ - pSorter->typeMask &= SORTER_TYPE_INTEGER; + if( t>0 && t<10 ){ + if( t==7 ){ + pSorter->typeMask &= SORTER_TYPE_REAL; + }else{ + pSorter->typeMask &= (SORTER_TYPE_INTEGER|SORTER_TYPE_REAL); + } }else if( t>10 && (t & 0x01) ){ pSorter->typeMask &= SORTER_TYPE_TEXT; }else{ @@ -109862,7 +111252,7 @@ static int lookupName( ** cnt>1 means there were two or more matches. ** ** cnt==0 is always an error. cnt>1 is often an error, but might - ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING. + ** be multiple matches for a NATURAL OUTER JOIN or a OUTER JOIN USING. */ assert( pFJMatch==0 || cnt>0 ); assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); @@ -109882,6 +111272,7 @@ static int lookupName( pExpr->op = TK_FUNCTION; pExpr->u.zToken = "coalesce"; pExpr->x.pList = pFJMatch; + pExpr->affExpr = SQLITE_AFF_DEFER; cnt = 1; goto lookupname_end; }else{ @@ -109944,10 +111335,19 @@ static int lookupName( if( cnt==1 ){ assert( pNC!=0 ); #ifndef SQLITE_OMIT_AUTHORIZATION - if( pParse->db->xAuth - && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) - ){ - sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); + if( db->xAuth ){ + if( pFJMatch ){ + assert( pExpr->op==TK_FUNCTION ); + assert( sqlite3_stricmp(pExpr->u.zToken,"coalesce")==0 ); + assert( pExpr->x.pList==pFJMatch ); + assert( pFJMatch->nExpr>0 ); + for(i=0; inExpr; i++){ + assert( pFJMatch->a[i].pExpr->op==TK_COLUMN ); + sqlite3AuthRead(pParse,pFJMatch->a[i].pExpr,pSchema,pNC->pSrcList); + } + }else if( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ){ + sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); + } } #endif /* Increment the nRef value on all name contexts from TopNC up to @@ -110044,12 +111444,41 @@ static int exprProbability(Expr *p){ double r = -1.0; if( p->op!=TK_FLOAT ) return -1; assert( !ExprHasProperty(p, EP_IntValue) ); - sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); + sqlite3AtoF(p->u.zToken, &r); assert( r>=0.0 ); if( r>1.0 ) return -1; return (int)(r*134217728.0); } +/* +** Set the EP_SubtArg property on every expression inside of +** pList. If any subexpression is actually a subquery, then +** also set the EP_SubtArg property on the first result-set +** column of that subquery. +*/ +static SQLITE_NOINLINE void resolveSetExprSubtypeArg(ExprList *pList){ + int nn, ii; + nn = pList ? pList->nExpr : 0; + for(ii=0; iia[ii].pExpr; + while( 1 /*exit-by-break*/ ){ + ExprSetProperty(pExpr, EP_SubtArg); + if( pExpr->op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList); + break; + } + if( pExpr->op==TK_UPLUS ){ + pExpr = pExpr->pLeft; + assert( pExpr!=0 ); + }else{ + break; + } + } + } +} + /* ** This routine is callback for sqlite3WalkExpr(). ** @@ -110294,10 +111723,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( (pDef->funcFlags & SQLITE_SUBTYPE) || ExprHasProperty(pExpr, EP_SubtArg) ){ - int ii; - for(ii=0; iia[ii].pExpr, EP_SubtArg); - } + resolveSetExprSubtypeArg(pList); } if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ @@ -110327,8 +111753,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* Internal-use-only functions are disallowed unless the ** SQL is being compiled using sqlite3NestedParse() or ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be - ** used to activate internal functions for testing purposes */ - no_such_func = 1; + ** used to activate internal functions for testing purposes. + ** + ** The 2 value for no_such_func means that the function is + ** an internal-use-only function which should be treated as a + ** non-existant function for name resolution purposes. + */ + no_such_func = 2; pDef = 0; }else if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 @@ -110372,9 +111803,16 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ is_agg = 0; } #endif - else if( no_such_func && pParse->db->init.busy==0 + else if( no_such_func + && (pParse->db->init.busy==0 || + (no_such_func==2 && pParse->db->init.busy==2)) + /* Suppress "no such function" errors when reading + ** the sqlite_schema table. Except, do raise the error + ** if init.busy is 2, meaning the schema parse is due + ** to an ALTER TABLE ADD COLUMN statement, and the function + ** is an internal-use-only function (no_such_func==2). */ #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - && pParse->explain==0 + && pParse->explain==0 #endif ){ sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr); @@ -110631,7 +112069,7 @@ static int resolveOrderByTermToExprList( int rc; /* Return code from subprocedures */ u8 savedSuppErr; /* Saved value of db->suppressErr */ - assert( sqlite3ExprIsInteger(pE, &i, 0)==0 ); + assert( sqlite3ExprIsInteger(pE, &i, 0, 0)==0 ); pEList = pSelect->pEList; /* Resolve all names in the ORDER BY term expression @@ -110730,7 +112168,7 @@ static int resolveCompoundOrderBy( if( pItem->fg.done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( NEVER(pE==0) ) continue; - if( sqlite3ExprIsInteger(pE, &iCol, 0) ){ + if( sqlite3ExprIsInteger(pE, &iCol, 0, 0) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); return 1; @@ -110764,10 +112202,8 @@ static int resolveCompoundOrderBy( /* Convert the ORDER BY term into an integer column number iCol, ** taking care to preserve the COLLATE clause if it exists. */ if( !IN_RENAME_OBJECT ){ - Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); + Expr *pNew = sqlite3ExprInt32(db, iCol); if( pNew==0 ) return 1; - pNew->flags |= EP_IntValue; - pNew->u.iValue = iCol; if( pItem->pExpr==pE ){ pItem->pExpr = pNew; }else{ @@ -110915,7 +112351,7 @@ static int resolveOrderGroupBy( continue; } } - if( sqlite3ExprIsInteger(pE2, &iCol, 0) ){ + if( sqlite3ExprIsInteger(pE2, &iCol, 0, 0) ){ /* The ORDER BY term is an integer constant. Again, set the column ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ @@ -111121,10 +112557,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } #endif - /* The ORDER BY and GROUP BY clauses may not refer to terms in - ** outer queries - */ - sNC.pNext = 0; sNC.ncFlags |= NC_AllowAgg|NC_AllowWin; /* If this is a converted compound query, move the ORDER BY clause from @@ -111187,6 +112619,14 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ return WRC_Abort; } + /* If the SELECT statement contains ON clauses that were moved into + ** the WHERE clause, go through and verify that none of the terms + ** in the ON clauses reference tables to the right of the ON clause. */ + if( (p->selFlags & SF_OnToWhere) ){ + sqlite3SelectCheckOnClauses(pParse, p); + if( pParse->nErr ) return WRC_Abort; + } + /* Advance to the next term of the compound */ p = p->pPrior; @@ -111601,23 +113041,29 @@ SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr){ ** and the pExpr parameter is returned unchanged. */ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( - const Parse *pParse, /* Parsing context */ + Parse *pParse, /* Parsing context */ Expr *pExpr, /* Add the "COLLATE" clause to this expression */ const Token *pCollName, /* Name of collating sequence */ int dequote /* True to dequote pCollName */ ){ - if( pCollName->n>0 ){ + if( pCollName->n>0 && pParse->nErr==0 ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); + assert( pExpr!=0 ); if( pNew ){ pNew->pLeft = pExpr; pNew->flags |= EP_Collate|EP_Skip; +#if SQLITE_MAX_EXPR_DEPTH>0 + pNew->nHeight = pExpr->nHeight+1; + sqlite3ExprCheckHeight(pParse, pNew->nHeight); + testcase( pParse->nErr>0 ); +#endif pExpr = pNew; } } return pExpr; } SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString( - const Parse *pParse, /* Parsing context */ + Parse *pParse, /* Parsing context */ Expr *pExpr, /* Add the "COLLATE" clause to this expression */ const char *zC /* The collating sequence name */ ){ @@ -111759,7 +113205,9 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){ SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){ CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1); CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2); - return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0; + assert( (pColl1==pColl2) == + (sqlite3_stricmp(pColl1->zName,pColl2->zName)==0) ); + return pColl1==pColl2; } /* @@ -112089,6 +113537,7 @@ static int exprVectorRegister( Expr *pVector, /* Vector to extract element from */ int iField, /* Field to extract from pVector */ int regSelect, /* First in array of registers */ + Expr *pTmp, /* Temporary space */ Expr **ppExpr, /* OUT: Expression element */ int *pRegFree /* OUT: Temp register to free */ ){ @@ -112100,8 +113549,17 @@ static int exprVectorRegister( } if( op==TK_SELECT ){ assert( ExprUseXSelect(pVector) ); - *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; - return regSelect+iField; + /* Use the temporary expression node to wrap expression iField of the + ** sub-select in a TK_SELECT_COLUMN node. This causes the caller to + ** use the affinity of the expression in any comparison, but not the + ** collation sequence. */ + memset(pTmp, 0, sizeof(Expr)); + pTmp->op = TK_SELECT_COLUMN; + pTmp->pLeft = pVector; + pTmp->iColumn = iField; + pTmp->iTable = pVector->x.pSelect->pEList->nExpr; + *ppExpr = pTmp; + return regSelect+iField; } if( op==TK_VECTOR ){ assert( ExprUseXList(pVector) ); @@ -112168,11 +113626,12 @@ static void codeVectorCompare( for(i=0; 1 /*Loop exits by "break"*/; i++){ int regFree1 = 0, regFree2 = 0; Expr *pL = 0, *pR = 0; + Expr tmp1, tmp2; int r1, r2; assert( i>=0 && in+1 : 0; assert( db!=0 ); - if( pToken ){ - if( op!=TK_INTEGER || pToken->z==0 - || sqlite3GetInt32(pToken->z, &iValue)==0 ){ - nExtra = pToken->n+1; /* tag-20240227-a */ - assert( iValue>=0 ); - } - } pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra); if( pNew ){ memset(pNew, 0, sizeof(Expr)); pNew->op = (u8)op; pNew->iAgg = -1; - if( pToken ){ - if( nExtra==0 ){ - pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse); - pNew->u.iValue = iValue; - }else{ - pNew->u.zToken = (char*)&pNew[1]; - assert( pToken->z!=0 || pToken->n==0 ); - if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); - pNew->u.zToken[pToken->n] = 0; - if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){ - sqlite3DequoteExpr(pNew); - } + if( nExtra ){ + assert( pToken!=0 ); + pNew->u.zToken = (char*)&pNew[1]; + assert( pToken->z!=0 || pToken->n==0 ); + if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); + pNew->u.zToken[pToken->n] = 0; + if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){ + sqlite3DequoteExpr(pNew); } } #if SQLITE_MAX_EXPR_DEPTH>0 @@ -112415,6 +113862,24 @@ SQLITE_PRIVATE Expr *sqlite3Expr( return sqlite3ExprAlloc(db, op, &x, 0); } +/* +** Allocate an expression for a 32-bit signed integer literal. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprInt32(sqlite3 *db, int iVal){ + Expr *pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)); + if( pNew ){ + memset(pNew, 0, sizeof(Expr)); + pNew->op = TK_INTEGER; + pNew->iAgg = -1; + pNew->flags = EP_IntValue|EP_Leaf|(iVal?EP_IsTrue:EP_IsFalse); + pNew->u.iValue = iVal; +#if SQLITE_MAX_EXPR_DEPTH>0 + pNew->nHeight = 1; +#endif + } + return pNew; +} + /* ** Attach subtrees pLeft and pRight to the Expr node pRoot. ** @@ -112577,7 +114042,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ ){ sqlite3ExprDeferredDelete(pParse, pLeft); sqlite3ExprDeferredDelete(pParse, pRight); - return sqlite3Expr(db, TK_INTEGER, "0"); + return sqlite3ExprInt32(db, 0); }else{ return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); } @@ -112702,7 +114167,9 @@ SQLITE_PRIVATE void sqlite3ExprFunctionUsable( ){ assert( !IN_RENAME_OBJECT ); assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 ); - if( ExprHasProperty(pExpr, EP_FromDDL) ){ + if( ExprHasProperty(pExpr, EP_FromDDL) + || pParse->prepFlags & SQLITE_PREPARE_FROM_DDL + ){ if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 || (pParse->db->flags & SQLITE_TrustedSchema)==0 ){ @@ -112776,6 +114243,8 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n if( x>pParse->nVar ){ pParse->nVar = (int)x; doAdd = 1; + }else if( xaVnbmc[x>>6] & MASKBIT64(x&63))==0; }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){ doAdd = 1; } @@ -112792,6 +114261,9 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n } if( doAdd ){ pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); + if( pParse->pVList!=0 && xaVnbmc[x>>6] |= MASKBIT64(x&63); + } } } pExpr->iColumn = x; @@ -113398,9 +114870,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 & ~(u32)SF_UsesEphemeral; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; + pNew->selFlags = p->selFlags; pNew->nSelectRow = p->nSelectRow; pNew->pWith = sqlite3WithDup(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -113925,7 +115395,7 @@ static SQLITE_NOINLINE int exprNodeIsConstantFunction( if( pDef==0 || pDef->xFinalize!=0 || (pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 - || ExprHasProperty(pExpr, EP_WinFunc) + || NEVER(ExprHasProperty(pExpr, EP_WinFunc)) ){ pWalker->eCode = 0; return WRC_Abort; @@ -113946,6 +115416,7 @@ static SQLITE_NOINLINE int exprNodeIsConstantFunction( ** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2 ** sqlite3ExprIsTableConstant() pWalker->eCode==3 ** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5 +** sqlite3ExprListIsConstant() pWalker->eCode==1 or 6 ** ** In all cases, the callbacks set Walker.eCode=0 and abort if the expression ** is found to not be a constant. @@ -113972,19 +115443,25 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ } switch( pExpr->op ){ - /* Consider functions to be constant if all their arguments are constant - ** and either pWalker->eCode==4 or 5 or the function has the - ** SQLITE_FUNC_CONST flag. */ case TK_FUNCTION: - if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc)) - && !ExprHasProperty(pExpr, EP_WinFunc) - ){ + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + pWalker->eCode = 0; /* Window functions are never constant */ + return WRC_Abort; + }else if( pWalker->eCode>=4 && pWalker->eCode<=5 ){ + /* Functions used within a CREATE TABLE statement are constant as + ** long as all of their arguments are constant */ if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); return WRC_Continue; + }else if( ExprHasProperty(pExpr,EP_ConstFunc) ){ + /* Functions marked with EP_ConstFunc are constant as long as + ** all their arugments are constant and they are not window functions */ + return WRC_Continue; }else if( pWalker->pParse ){ + /* Functions are constant if they have SQLITE_FUNC_CONSTANT or + ** SQLITE_FUNC_SLOCHNG and if all arguments are constant */ return exprNodeIsConstantFunction(pWalker, pExpr); }else{ - pWalker->eCode = 0; + pWalker->eCode = 0; /* Function call is not constant */ return WRC_Abort; } case TK_ID: @@ -114018,6 +115495,13 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_RAISE ); pWalker->eCode = 0; return WRC_Abort; + case TK_IS: + case TK_ISNOT: + if( pWalker->eCode==6 ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Continue; case TK_VARIABLE: if( pWalker->eCode==5 ){ /* Silently convert bound parameters that appear inside of CREATE @@ -114052,7 +115536,7 @@ static int exprIsConst(Parse *pParse, Expr *p, int initFlag){ /* ** Walk an expression tree. Return non-zero if the expression is constant -** and 0 if it involves variables or function calls. +** or return zero if the expression involves variables or function calls. ** ** For the purposes of this function, a double-quoted string (ex: "abc") ** is considered a variable but a single-quoted string (ex: 'abc') is @@ -114068,11 +115552,27 @@ SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse *pParse, Expr *p){ return exprIsConst(pParse, p, 1); } +/* +** Return true if all expressions in pList are constant. If parameter bNoIs +** is true, do not consider expressions that contain "IS" operators to be +** constant. IS operators are not always considered constant as expressions +** like "x IS TRUE" need to be transformed to TK_TRUTH expression nodes, +** which happens at the same time as column name resolution. +*/ +SQLITE_PRIVATE int sqlite3ExprListIsConstant(Parse *pParse, ExprList *pList, int bNoIs){ + const int iInit = bNoIs ? 6 : 1; + int ii; + for(ii=0; iinExpr; ii++){ + if( 0==exprIsConst(pParse, pList->a[ii].pExpr, iInit) ) return 0; + } + return 1; +} + /* ** Walk an expression tree. Return non-zero if ** ** (1) the expression is constant, and -** (2) the expression does originate in the ON or USING clause +** (2) the expression does not originate in the ON or USING clause ** of a LEFT JOIN, and ** (3) the expression does not contain any EP_FixedCol TK_COLUMN ** operands created by the constant propagation optimization. @@ -114309,65 +115809,68 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ #endif /* -** If the expression p codes a constant integer that is small enough -** to fit in a 32-bit integer, return 1 and put the value of the integer -** in *pValue. If the expression is not an integer or if it is too big -** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. +** If the expression p codes a constant integer between 0 and 0x7fffffff, +** then return 1 and put the value of the integer in *pValue. If the +** expression is not an integer or if it is an integer that is out side +** the range of 0...0x7fffffff, then return 0 and leave *pValue unchanged. ** ** If the pParse pointer is provided, then allow the expression p to be -** a parameter (TK_VARIABLE) that is bound to an integer. -** But if pParse is NULL, then p must be a pure integer literal. -*/ -SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse){ - int rc = 0; - if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ - - /* If an expression is an integer literal that fits in a signed 32-bit - ** integer, then the EP_IntValue flag will have already been set */ - assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 - || sqlite3GetInt32(p->u.zToken, &rc)==0 ); - - if( p->flags & EP_IntValue ){ - *pValue = p->u.iValue; - return 1; - } - switch( p->op ){ - case TK_UPLUS: { - rc = sqlite3ExprIsInteger(p->pLeft, pValue, 0); - break; +** a parameter (TK_VARIABLE) that is bound to an integer between 0 and +** 0x7fffffff. Variables that hold anything other than integers, or that +** hold integers outside the range of 0..0x7fffffff are not seen. +** But if pParse is NULL, then p must be a pure integer literal between +** 0 and 0x7fffffff. +** +** If pParse is not NULL and expression p is a variable, then the variable +** is marked so as to cause the statement to be reprepared each time a new +** value is bound to it. Except, if parameter bRSI is true, then the statement +** will only be reprepared if the rebind changes the value to or from a +** "small integer" (either 0 or 1). +*/ +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse, int bRSI){ + int iSign = 1; /* Either +1 or -1. */ + while( 1/*exit-by-break*/ ){ + if( NEVER(p==0) ) return 0; + if( ExprUseUValue(p) ){ + *pValue = p->u.iValue*iSign; + return 1; } - case TK_UMINUS: { - int v = 0; - if( sqlite3ExprIsInteger(p->pLeft, &v, 0) ){ - assert( ((unsigned int)v)!=0x80000000 ); - *pValue = -v; - rc = 1; - } - break; + if( p->op==TK_UPLUS ){ + p = p->pLeft; + pParse = 0; + continue; } - case TK_VARIABLE: { - sqlite3_value *pVal; - if( pParse==0 ) break; + if( p->op==TK_UMINUS ){ + iSign = -iSign; + p = p->pLeft; + pParse = 0; + continue; + } + if( p->op==TK_VARIABLE && pParse!=0 ){ + sqlite3_value *pVal; /* The variable */ + int rc = 0; /* 1 if successful, 0 if failed */ + assert( iSign==1 ); if( NEVER(pParse->pVdbe==0) ) break; if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) break; - sqlite3VdbeSetVarmask(pParse->pVdbe, p->iColumn); pVal = sqlite3VdbeGetBoundValue(pParse->pReprepare, p->iColumn, SQLITE_AFF_BLOB); if( pVal ){ - if( sqlite3_value_type(pVal)==SQLITE_INTEGER ){ - sqlite3_int64 vv = sqlite3_value_int64(pVal); - if( vv == (vv & 0x7fffffff) ){ /* non-negative numbers only */ - *pValue = (int)vv; - rc = 1; - } + i64 vv; + if( sqlite3_value_type(pVal)==SQLITE_INTEGER + && (vv = sqlite3_value_int64(pVal))>=0 + && vv<=0x7fffffff + ){ + *pValue = (int)vv; + rc = 1; } sqlite3ValueFree(pVal); } - break; + sqlite3VdbeReprepareOnBind(pParse->pVdbe, p->iColumn, bRSI); + return rc; } - default: break; + break; } - return rc; + return 0; } /* @@ -114501,10 +116004,8 @@ static Select *isCandidateForInOpt(const Expr *pX){ if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */ p = pX->x.pSelect; if( p->pPrior ) return 0; /* Not a compound SELECT */ - if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ - testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); - testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); - return 0; /* No DISTINCT keyword and no aggregate functions */ + if( p->selFlags & SF_Aggregate ){ + return 0; /* No GROUP BY keyword or aggregate functions */ } assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ if( p->pLimit ) return 0; /* Has no LIMIT clause */ @@ -114536,13 +116037,24 @@ static Select *isCandidateForInOpt(const Expr *pX){ ** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull ** to be set to NULL if iCur contains one or more NULL values. */ -static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ +static void sqlite3SetHasNullFlag( + Vdbe *v, /* Write new code into this statement under construction */ + int iCur, /* Cursor for the index */ + int regHasNull, /* Register in which to store hasNull flag */ + int eSortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ +){ int addr1; + int op; sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); - addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + if( eSortOrder==SQLITE_SO_ASC ){ + op = OP_Rewind; + }else{ + op = OP_Last; + } + addr1 = sqlite3VdbeAddOp1(v, op, iCur); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); - VdbeComment((v, "first_entry_in(%d)", iCur)); + VdbeComment((v, op==OP_Last?"last_entry_in(%d)":"first_entry_in(%d)", iCur)); sqlite3VdbeJumpHere(v, addr1); } #endif @@ -114803,13 +116315,14 @@ SQLITE_PRIVATE int sqlite3FindInIndex( if( prRhsHasNull ){ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK - i64 mask = (1<nMem; if( nExpr==1 ){ - sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); + sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull, + pIdx->aSortOrder[0]); } } sqlite3VdbeJumpHere(v, iAddr); @@ -114842,6 +116355,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( */ u32 savedNQueryLoop = pParse->nQueryLoop; int rMayHaveNull = 0; + int bloomOk = (inFlags & IN_INDEX_MEMBERSHIP)!=0; eType = IN_INDEX_EPH; if( inFlags & IN_INDEX_LOOP ){ pParse->nQueryLoop = 0; @@ -114849,9 +116363,15 @@ SQLITE_PRIVATE int sqlite3FindInIndex( *prRhsHasNull = rMayHaveNull = ++pParse->nMem; } assert( pX->op==TK_IN ); - sqlite3CodeRhsOfIN(pParse, pX, iTab); + if( !bloomOk + && ExprUseXSelect(pX) + && (pX->x.pSelect->selFlags & SF_ClonedRhsIn)!=0 + ){ + bloomOk = 1; + } + sqlite3CodeRhsOfIN(pParse, pX, iTab, bloomOk); if( rMayHaveNull ){ - sqlite3SetHasNullFlag(v, iTab, rMayHaveNull); + sqlite3SetHasNullFlag(v, iTab, rMayHaveNull, SQLITE_SO_ASC); } pParse->nQueryLoop = savedNQueryLoop; } @@ -115007,7 +116527,8 @@ static int findCompatibleInRhsSubrtn( SQLITE_PRIVATE void sqlite3CodeRhsOfIN( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The IN operator */ - int iTab /* Use this cursor number */ + int iTab, /* Use this cursor number */ + int allowBloom /* True to allow the use of a Bloom filter */ ){ int addrOnce = 0; /* Address of the OP_Once instruction at top */ int addr; /* Address of OP_OpenEphemeral instruction */ @@ -115105,6 +116626,8 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( } #endif pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1); + assert( pKeyInfo!=0 || pParse->nErr ); + if( pKeyInfo==0 ) return; if( ExprUseXSelect(pExpr) ){ /* Case 1: expr IN (SELECT ...) @@ -115129,14 +116652,31 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; - if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ + assert( pEList!=0 ); + assert( pEList->nExpr>0 ); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + for(i=0; iaColl[i] = pColl = sqlite3BinaryCompareCollSeq( + pParse, p, pEList->a[i].pExpr + ); + if( !sqlite3IsBinary(pColl) ){ + allowBloom = 0; /* tag-202607231411 */ + } + } + if( addrOnce + && allowBloom + && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) + ){ int regBloom = ++pParse->nMem; addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); VdbeComment((v, "Bloom filter")); dest.iSDParm2 = regBloom; + sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); + pKeyInfo = 0; } testcase( pSelect->selFlags & SF_Distinct ); - testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); @@ -115154,16 +116694,6 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( sqlite3KeyInfoUnref(pKeyInfo); return; } - assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ - assert( pEList!=0 ); - assert( pEList->nExpr>0 ); - assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); - for(i=0; iaColl[i] = sqlite3BinaryCompareCollSeq( - pParse, p, pEList->a[i].pExpr - ); - } } }else if( ALWAYS(pExpr->x.pList!=0) ){ /* Case 2: expr IN (exprlist) @@ -115184,10 +116714,9 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( }else if( affinity==SQLITE_AFF_REAL ){ affinity = SQLITE_AFF_NUMERIC; } - if( pKeyInfo ){ - assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); - pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); - } + assert( pKeyInfo!=0 ); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); /* Loop through each expression in . */ r1 = sqlite3GetTempReg(pParse); @@ -115350,7 +116879,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ || (pLeft->u.iValue!=1 && pLeft->u.iValue!=0) ){ sqlite3 *db = pParse->db; - pLimit = sqlite3Expr(db, TK_INTEGER, "0"); + pLimit = sqlite3ExprInt32(db, 0); if( pLimit ){ pLimit->affExpr = SQLITE_AFF_NUMERIC; pLimit = sqlite3PExpr(pParse, TK_NE, @@ -115361,7 +116890,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } }else{ /* If there is no pre-existing limit add a limit of 1 */ - pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1"); + pLimit = sqlite3ExprInt32(pParse->db, 1); pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); } pSel->iLimit = 0; @@ -115377,6 +116906,12 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); + if( dest.eDest==SRT_Mem + && sqlite3ExprCanReturnSubtype(pParse, pSel->pEList->a[0].pExpr) + ){ + sqlite3VdbeAddOp1(v, OP_ClrSubtype, rReg); + } + /* Subroutine return */ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn @@ -115572,16 +117107,30 @@ static void sqlite3ExprCodeIN( ** we need to reorder the LHS values to be in index order. Run Affinity ** before reordering the columns, so that the affinity is correct. */ - sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); + if( nVector==1 ){ + char aff = zAff[0]; + if( aff>=SQLITE_AFF_TEXT && aff!=sqlite3ExprAffinity(pLeft) ){ + /* The OP_Affinity below may change the value. In this case, create a + ** copy of rLhs to run OP_Affinity on, in case the original register + ** is used again (e.g. if it is TK_AGG_COLUMN). */ + int rTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Copy, rLhs, rTmp, 0); + rLhs = rTmp; + sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, 1, 0, zAff, 1); + } + }else{ + sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); + } + for(i=0; ipLeft, i); if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error; if( sqlite3ExprCanBeNull(p) ){ - sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); + testcase( aiMap[i]!=i ); + sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+aiMap[i], destStep2); VdbeCoverage(v); } } @@ -115622,8 +117172,9 @@ 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 ){ /* tag-202407032019 */ - assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); + if( pOp->p3>0 ){ /* tag-202407032019 */ + assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) + || pParse->nErr ); sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, rLhs, nVector); VdbeCoverage(v); } @@ -115658,7 +117209,13 @@ static void sqlite3ExprCodeIN( ** of the RHS. */ if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6); - addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse); + if( eType==IN_INDEX_INDEX_DESC ){ + addrTop = sqlite3VdbeAddOp2(v, OP_Last, iTab, destIfFalse); + }else{ + testcase( eType==IN_INDEX_EPH ); + testcase( eType==IN_INDEX_ROWID ); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse); + } VdbeCoverage(v); if( nVector>1 ){ destNotNull = sqlite3VdbeMakeLabel(pParse); @@ -115672,9 +117229,19 @@ static void sqlite3ExprCodeIN( CollSeq *pColl; int r3 = sqlite3GetTempReg(pParse); p = sqlite3VectorFieldSubexpr(pLeft, i); - pColl = sqlite3ExprCollSeq(pParse, p); - sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3); - sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3, + if( ExprUseXSelect(pExpr) ){ + Expr *pRhs = pExpr->x.pSelect->pEList->a[i].pExpr; + pColl = sqlite3BinaryCompareCollSeq(pParse, p, pRhs); + }else{ + /* If the RHS of the IN(...) expression are scalar expressions, do + ** not consider their collation sequences. The documentation says + ** "The collating sequence used for expressions of the form "x IN (y, z, + ** ...)" is the collating sequence of x.". */ + pColl = sqlite3ExprCollSeq(pParse, p); + } + testcase( aiMap[i]!=i ); + sqlite3VdbeAddOp3(v, OP_Column, iTab, aiMap[i], r3); + sqlite3VdbeAddOp4(v, OP_Ne, rLhs+aiMap[i], destNotNull, r3, (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); sqlite3ReleaseTempReg(pParse, r3); @@ -115713,10 +117280,10 @@ static void sqlite3ExprCodeIN( static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ if( ALWAYS(z!=0) ){ double value; - sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + sqlite3AtoF(z, &value); assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ if( negateFlag ) value = -value; - sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); + sqlite3VdbeAddDouble(v, iMem, value); } } #endif @@ -115757,7 +117324,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ #endif }else{ if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; } - sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); + sqlite3VdbeAddInt64(v, iMem, value); } } } @@ -115838,12 +117405,12 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( if( iCol<0 || iCol==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); VdbeComment((v, "%s.rowid", pTab->zName)); - }else{ - int op; + }else{ int x; if( IsVirtual(pTab) ){ - op = OP_VColumn; x = iCol; + sqlite3VdbeAddOp3(v, OP_VColumn, iTabCur, x, regOut); + return; #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){ Parse *pParse = sqlite3VdbeParser(v); @@ -115863,13 +117430,11 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( }else if( !HasRowid(pTab) ){ testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) ); x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol); - op = OP_Column; }else{ x = sqlite3TableColumnToStorage(pTab,iCol); testcase( x!=iCol ); - op = OP_Column; } - sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); + sqlite3VdbeAddOp3(v, OP_Column, iTabCur, x, regOut); sqlite3ColumnDefault(v, pTab, iCol, regOut); } } @@ -116095,36 +117660,52 @@ static int exprCodeInlineFunction( } /* -** Expression Node callback for sqlite3ExprCanReturnSubtype(). +** Expression Node callback for sqlite3ExprCanReturnSubtype(). If +** pExpr is able to return a subtype, set pWalker->eCode and abort +** the search. If pExpr can never return a subtype, prune search. ** -** Only a function call is able to return a subtype. So if the node -** is not a function call, return WRC_Prune immediately. +** The only expressions that can return a subtype are: ** -** A function call is able to return a subtype if it has the -** SQLITE_RESULT_SUBTYPE property. +** 1. A function, including an aggregate function +** 2. The no-op "+" operator +** 3. A CASE...END expression +** 4. A CAST() expression +** 5. A "expr COLLATE colseq" expression. ** -** Assume that every function is able to pass-through a subtype from -** one of its argument (using sqlite3_result_value()). Most functions -** are not this way, but we don't have a mechanism to distinguish those -** that are from those that are not, so assume they all work this way. -** That means that if one of its arguments is another function and that -** other function is able to return a subtype, then this function is -** able to return a subtype. +** For any other kind of expression, prune the search. +** +** For case 1, the expression can yield a subtype if the function has +** the SQLITE_RESULT_SUBTYPE property. Functions can also return +** a subtype (via sqlite3_result_value()) if any of the arguments can +** return a subtype. +** +** In all cases 1 through 5, the expression might also return a subtype +** if any operand can return a subtype. */ static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ int n; FuncDef *pDef; sqlite3 *db; - if( pExpr->op!=TK_FUNCTION ){ + if( pExpr->op==TK_CASE || pExpr->op==TK_UPLUS + || pExpr->op==TK_COLLATE || pExpr->op==TK_CAST + ){ + return WRC_Continue; + } + if( pExpr->op!=TK_FUNCTION && pExpr->op!=TK_AGG_FUNCTION ){ return WRC_Prune; } assert( ExprUseXList(pExpr) ); db = pWalker->pParse->db; - n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0; + n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); - if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 ) return WRC_Continue; +#else + assert( pDef!=0 ); +#endif + if( (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ pWalker->eCode = 1; - return WRC_Prune; + return WRC_Abort; } return WRC_Continue; } @@ -116137,7 +117718,7 @@ static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ ** are acceptable as they only disable an optimization. False negatives, ** on the other hand, can lead to incorrect answers. */ -static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ +SQLITE_PRIVATE int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ Walker w; memset(&w, 0, sizeof(w)); w.pParse = pParse; @@ -116192,10 +117773,16 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( v = pParse->pVdbe; assert( v!=0 ); - if( p->bMaybeNullRow ){ - /* If the index is on a NULL row due to an outer join, then we - ** cannot extract the value from the index. The value must be - ** computed using the original expression. */ + if( p->bMaybeNullRow || sqlite3ExprIsConstant(pParse, pExpr) ){ + /* The value of pExpr should be computed from the original expression, + ** not from the index, if either: + ** + ** 1. The index might be on a NULL row due to an outer join. + ** + ** 2. The expression is a constant. This prevents an attempt to + ** use an index value outside of the loop that positions the + ** index. (Bug 2026-10-11T19:26:40Z). + */ int addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_IfNullRow, p->iIdxCur, addr+3, target); VdbeCoverage(v); @@ -116241,6 +117828,11 @@ static int exprPartidxExprLookup(Parse *pParse, Expr *pExpr, int iTarget){ ret = sqlite3ExprCodeTarget(pParse, p->pExpr, iTarget); sqlite3VdbeAddOp4(pParse->pVdbe, OP_Affinity, ret, 1, 0, (const char*)&p->aff, 1); + if( sqlite3ExprCanReturnSubtype(pParse, p->pExpr) ){ + /* If the expression value may have a sub-type, clear it. Values + ** read from columns do not have subtypes. */ + sqlite3VdbeAddOp1(pParse->pVdbe, OP_ClrSubtype, ret); + } if( addr ){ sqlite3VdbeJumpHere(v, addr); sqlite3VdbeChangeP3(v, addr, ret); @@ -116572,7 +118164,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) case TK_ISNOT: op = (op==TK_IS) ? TK_EQ : TK_NE; p5 = SQLITE_NULLEQ; - /* fall-through */ + /* no break */ deliberate_fall_through case TK_LT: case TK_LE: case TK_GT: @@ -116769,7 +118361,12 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0); } #endif - if( pDef==0 || pDef->xFinalize!=0 ){ + if( pDef==0 + || pDef->xFinalize!=0 + || ((pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 && + !pParse->nested && + (db->mDbFlags & DBFLAG_InternalFunc)==0) + ){ sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); break; } @@ -117910,7 +119507,7 @@ static SQLITE_NOINLINE int exprCompareVariable( sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); if( pR ){ iVar = pVar->iColumn; - sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); + sqlite3VdbeReprepareOnBind(pParse->pVdbe, iVar, 0); pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB); if( pL ){ if( sqlite3_value_type(pL)==SQLITE_TEXT ){ @@ -118166,7 +119763,7 @@ static int sqlite3ExprIsNotTrue(Expr *pExpr){ if( pExpr->op==TK_NULL ) return 1; if( pExpr->op==TK_TRUEFALSE && sqlite3ExprTruthValue(pExpr)==0 ) return 1; v = 1; - if( sqlite3ExprIsInteger(pExpr, &v, 0) && v==0 ) return 1; + if( sqlite3ExprIsInteger(pExpr, &v, 0, 0) && v==0 ) return 1; return 0; } @@ -118814,7 +120411,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ if( pIEpr==0 ) break; if( NEVER(!ExprUseYTab(pExpr)) ) break; for(i=0; inSrc; i++){ - if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break; + if( pSrcList->a[i].iCursor==pIEpr->iDataCur ){ + testcase( i>0 ); + break; + } } if( i>=pSrcList->nSrc ) break; if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ @@ -118909,7 +120509,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ if( pOBList->nExpr==1 && nArg==1 && sqlite3ExprCompare(0,pOBList->a[0].pExpr, - pExpr->x.pList->a[0].pExpr,0)==0 + pExpr->x.pList->a[0].pExpr,-1)==0 ){ pItem->bOBPayload = 0; pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct); @@ -118997,6 +120597,13 @@ SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){ */ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ if( iReg ){ +#ifdef SQLITE_DEBUG + /* Verify that iReg is not already on the unused register list */ + int kk; + for(kk=0; kknTempReg; kk++){ + assert( pParse->aTempReg[kk]!=iReg ); + } +#endif sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0); if( pParse->nTempRegaTempReg) ){ pParse->aTempReg[pParse->nTempReg++] = iReg; @@ -119414,6 +121021,30 @@ static void sqlite3ErrorIfNotEmpty( ); } +/* +** zCol is a column name used in an ALTER TABLE DROP, ADD or RENAME COLUMN +** operation. zOp identifies the specific operation - "drop", "add", "rename +** to" or "rename from". pTab is the table being altered. +** +** If pTab has a rowid and zCol is a rowid alias, then SQLITE_ERROR is +** returned and an error message left in pParse. Or, if zCol is not an alias +** for "rowid" or pTab is not an intkey table, then SQLITE_OK is returned. +*/ +static int isRowidAlias( + Parse *pParse, + Table *pTab, + const char *zCol, + const char *zOp +){ + if( HasRowid(pTab) && sqlite3IsRowid(zCol) ){ + sqlite3ErrorMsg(pParse, "cannot %s rowid alias: %s", zOp, zCol); + return SQLITE_ERROR; + } + return SQLITE_OK; +} + + + /* ** This function is called after an "ALTER TABLE ... ADD" statement ** has been parsed. Argument pColDef contains the text of the new @@ -119459,9 +121090,9 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ #endif - /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. - ** If there is a NOT NULL constraint, then the default value for the - ** column must not be NULL. + /* Check that the new column is not specified as PRIMARY KEY or UNIQUE, + ** or a rowid alias. If there is a NOT NULL constraint, then the default + ** value for the column must not be NULL. */ if( pCol->colFlags & COLFLAG_PRIMKEY ){ sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); @@ -119472,6 +121103,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ "Cannot add a UNIQUE column"); return; } + if( isRowidAlias(pParse, pTab, pCol->zCnName, "add") ) return; if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){ /* If the default value for the new column was specified with a ** literal NULL, then set pDflt to 0. This simplifies checking @@ -119560,6 +121192,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) || (pTab->tabFlags & TF_Strict)!=0 ){ + pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT CASE WHEN quick_check GLOB 'CHECK*'" " THEN raise(ABORT,'CHECK constraint failed')" @@ -119603,7 +121236,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ /* Look up the table being altered. */ assert( pParse->pNewTable==0 ); assert( sqlite3BtreeHoldsAllMutexes(db) ); - if( db->mallocFailed ) goto exit_begin_add_column; + if( NEVER(db->mallocFailed) ) goto exit_begin_add_column; pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_begin_add_column; @@ -119675,7 +121308,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ ** Or, if pTab is not a view or virtual table, zero is returned. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ +static int isRealTable(Parse *pParse, Table *pTab, int iOp){ const char *zType = 0; #ifndef SQLITE_OMIT_VIEW if( IsView(pTab) ){ @@ -119688,9 +121321,12 @@ static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ } #endif if( zType ){ + const char *azMsg[] = { + "rename columns of", "drop column from", "edit constraints of" + }; + assert( iOp>=0 && iOpzName + azMsg[iOp], zType, pTab->zName ); return 1; } @@ -119761,6 +121397,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( sqlite3MayAbort(pParse); zNew = sqlite3NameFromToken(db, pNew); if( !zNew ) goto exit_rename_column; + if( isRowidAlias(pParse, pTab, zOld, "rename from") ) goto exit_rename_column; + if( isRowidAlias(pParse, pTab, zNew, "rename to") ) goto exit_rename_column; assert( pNew->n>0 ); bQuote = sqlite3Isquote(pNew->z[0]); sqlite3NestedParse(pParse, @@ -120161,6 +121799,25 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ return pBest; } +/* +** Set the error message of the context passed as the first argument to +** the result of formatting zFmt using printf() style formatting. +*/ +static void errorMPrintf(sqlite3_context *pCtx, const char *zFmt, ...){ + sqlite3 *db = sqlite3_context_db_handle(pCtx); + char *zErr = 0; + va_list ap; + va_start(ap, zFmt); + zErr = sqlite3VMPrintf(db, zFmt, ap); + va_end(ap); + if( zErr ){ + sqlite3_result_error(pCtx, zErr, -1); + sqlite3DbFree(db, zErr); + }else{ + sqlite3_result_error_nomem(pCtx); + } +} + /* ** An error occurred while parsing or otherwise processing a database ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an @@ -120458,8 +122115,8 @@ static int renameResolveTrigger(Parse *pParse){ sqlite3SelectPrep(pParse, pStep->pSelect, &sNC); if( pParse->nErr ) rc = pParse->rc; } - if( rc==SQLITE_OK && pStep->zTarget ){ - SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep); + if( rc==SQLITE_OK && pStep->pSrc ){ + SrcList *pSrc = sqlite3SrcListDup(db, pStep->pSrc, 0); if( pSrc ){ Select *pSel = sqlite3SelectNew( pParse, pStep->pExprList, pSrc, 0, 0, 0, 0, 0, 0 @@ -120487,10 +122144,10 @@ static int renameResolveTrigger(Parse *pParse){ pSel->pSrc = 0; sqlite3SelectDelete(db, pSel); } - if( pStep->pFrom ){ + if( ALWAYS(pStep->pSrc) ){ int i; - for(i=0; ipFrom->nSrc && rc==SQLITE_OK; i++){ - SrcItem *p = &pStep->pFrom->a[i]; + for(i=0; ipSrc->nSrc && rc==SQLITE_OK; i++){ + SrcItem *p = &pStep->pSrc->a[i]; if( p->fg.isSubquery ){ assert( p->u4.pSubq!=0 ); sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0); @@ -120559,13 +122216,13 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); } - if( pStep->pFrom ){ + if( pStep->pSrc ){ int i; - SrcList *pFrom = pStep->pFrom; - for(i=0; inSrc; i++){ - if( pFrom->a[i].fg.isSubquery ){ - assert( pFrom->a[i].u4.pSubq!=0 ); - sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect); + SrcList *pSrc = pStep->pSrc; + for(i=0; inSrc; i++){ + if( pSrc->a[i].fg.isSubquery ){ + assert( pSrc->a[i].u4.pSubq!=0 ); + sqlite3WalkSelect(pWalker, pSrc->a[i].u4.pSubq->pSelect); } } } @@ -120736,8 +122393,8 @@ static void renameColumnFunc( if( rc!=SQLITE_OK ) goto renameColumnFunc_done; for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){ - if( pStep->zTarget ){ - Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb); + if( pStep->pSrc ){ + Table *pTarget = sqlite3LocateTableItem(&sParse, 0, &pStep->pSrc->a[0]); if( pTarget==pTab ){ if( pStep->pUpsert ){ ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet; @@ -120749,7 +122406,6 @@ static void renameColumnFunc( } } - /* Find tokens to edit in UPDATE OF clause */ if( sParse.pTriggerTab==pTab ){ renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); @@ -120951,13 +122607,10 @@ static void renameTableFunc( if( rc==SQLITE_OK ){ renameWalkTrigger(&sWalker, pTrigger); for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ - if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){ - renameTokenFind(&sParse, &sCtx, pStep->zTarget); - } - if( pStep->pFrom ){ + if( pStep->pSrc ){ int i; - for(i=0; ipFrom->nSrc; i++){ - SrcItem *pItem = &pStep->pFrom->a[i]; + for(i=0; ipSrc->nSrc; i++){ + SrcItem *pItem = &pStep->pSrc->a[i]; if( 0==sqlite3_stricmp(pItem->zName, zOld) ){ renameTokenFind(&sParse, &sCtx, pItem->zName); } @@ -121204,6 +122857,57 @@ static void renameTableTest( #endif } + +/* +** Return the number of bytes until the end of the next non-whitespace and +** non-comment token. For the purpose of this function, a "(" token includes +** all of the bytes through and including the matching ")", or until the +** first illegal token, whichever comes first. +** +** Write the token type into *piToken. +** +** The value returned is the number of bytes in the token itself plus +** the number of bytes of leading whitespace and comments skipped plus +** all bytes through the next matching ")" if the token is TK_LP. +** +** Example: (Note: '.' used in place of '*' in the example z[] text) +** +** ,--------- *piToken := TK_RP +** v +** z[] = " /.comment./ --comment\n (two three four) five" +** | | +** |<-------------------------------------->| +** | +** `--- return value +*/ +static int getConstraintToken(const u8 *z, int *piToken){ + int iOff = 0; + int t = 0; + do { + iOff += sqlite3GetToken(&z[iOff], &t); + }while( t==TK_SPACE || t==TK_COMMENT ); + + *piToken = t; + + if( t==TK_LP ){ + int nNest = 1; + while( nNest>0 ){ + iOff += sqlite3GetToken(&z[iOff], &t); + if( t==TK_LP ){ + nNest++; + }else if( t==TK_RP ){ + t = TK_LP; + nNest--; + }else if( t==TK_ILLEGAL ){ + break; + } + } + } + + *piToken = t; + return iOff; +} + /* ** The implementation of internal UDF sqlite_drop_column(). ** @@ -121248,15 +122952,24 @@ static void dropColumnFunc( goto drop_column_done; } - pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); if( iColnCol-1 ){ RenameToken *pEnd; + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName); zEnd = (const char*)pEnd->t.z; }else{ + int eTok; assert( IsOrdinaryTable(pTab) ); + assert( iCol!=0 ); + /* Point pCol->t.z at the "," immediately preceding the definition of + ** the column being dropped. To do this, start at the name of the + ** previous column, and tokenize until the next ",". */ + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol-1].zCnName); + do { + pCol->t.z += getConstraintToken((const u8*)pCol->t.z, &eTok); + }while( eTok!=TK_COMMA ); + pCol->t.z--; zEnd = (const char*)&zSql[pTab->u.tab.addColOffset]; - while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--; } zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd); @@ -121312,6 +123025,7 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName); goto exit_drop_column; } + if( isRowidAlias(pParse, pTab, zCol, "drop") ) goto exit_drop_column; /* Do not allow the user to drop a PRIMARY KEY column or a column ** constrained by a UNIQUE constraint. */ @@ -121425,6 +123139,684 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const T sqlite3SrcListDelete(db, pSrc); } +/* +** Return the number of bytes of leading whitespace/comments in string z[]. +*/ +static int getWhitespace(const u8 *z){ + int nRet = 0; + while( 1 ){ + int t = 0; + int n = sqlite3GetToken(&z[nRet], &t); + if( t!=TK_SPACE && t!=TK_COMMENT ) break; + nRet += n; + } + return nRet; +} + + +/* +** Argument z points into the body of a constraint - specifically the +** second token of the constraint definition. For a named constraint, +** z points to the second token of the constraint definition. For an +** unnamed NOT NULL constraint, z points to the first byte past the NOT +** keyword. +** +** Argument eTok may be the token value of the first token of the constraint +** (e.g. TK_CHECK or TK_REFERENCES) or zero. If it is either TK_REFERENCES +** or TK_FOREIGN, special parsing is enabled to find the end of the foreign-key +** constraint definition. +** +** Return the number of bytes until the end of the constraint. +*/ +static int getConstraint(const u8 *z, int eTok){ + int iOff = 0; + int t = 0; + +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( eTok==TK_FOREIGN ){ + /* For a FOREIGN KEY constraint, use getConstraint() to parse everything + ** up to the REFERENCES keyword. Then getConstraintToken() to consume + ** the TK_REFERENCES token itself. Then fall through to the special + ** handling for TK_REFERENCES below. */ + iOff = getConstraint(z, 0); + iOff += getConstraintToken(&z[iOff], &eTok); + } + + if( eTok==TK_REFERENCES ){ + /* REFERENCES is followed by a table name. Gobble this up here in + ** case the table name is a fallback token like TK_GENERATED. */ + iOff += getConstraintToken(&z[iOff], &t); + } +#endif + + /* Now, the current constraint proceeds until the next occurence of one + ** of the following tokens: + ** + ** CONSTRAINT, PRIMARY, NOT, UNIQUE, CHECK, DEFAULT, + ** COLLATE, REFERENCES, FOREIGN, GENERATED, AS, RP, or COMMA + ** + ** Also exit the loop if ILLEGAL turns up. + */ + while( 1 ){ + int n = getConstraintToken(&z[iOff], &t); + if( t==TK_CONSTRAINT || t==TK_PRIMARY || t==TK_NOT || t==TK_UNIQUE + || t==TK_CHECK || t==TK_DEFAULT || t==TK_COLLATE || t==TK_REFERENCES + || t==TK_FOREIGN || t==TK_RP || t==TK_COMMA || t==TK_ILLEGAL + || t==TK_AS || t==TK_GENERATED + ){ + break; + } + iOff += n; + } + + return iOff; +} + +/* +** Compare two constraint names. +** +** Summary: *pRes := zQuote != zCmp +** +** Details: +** Compare the (possibly quoted) constraint name zQuote[0..nQuote-1] +** against zCmp[]. Write zero into *pRes if they are the same and +** non-zero if they differ. Normally return SQLITE_OK, except if there +** is an OOM, set the OOM error condition on ctx and return SQLITE_NOMEM. +*/ +static int quotedCompare( + sqlite3_context *ctx, /* Function context on which to report errors */ + int t, /* Token type */ + const u8 *zQuote, /* Possibly quoted text. Not zero-terminated. */ + int nQuote, /* Length of zQuote in bytes */ + const u8 *zCmp, /* Zero-terminated, unquoted name to compare against */ + int *pRes /* OUT: Set to 0 if equal, non-zero if unequal */ +){ + char *zCopy = 0; /* De-quoted, zero-terminated copy of zQuote[] */ + + if( t==TK_ILLEGAL ){ + *pRes = 1; + return SQLITE_OK; + } + zCopy = sqlite3MallocZero(nQuote+1); + if( zCopy==0 ){ + sqlite3_result_error_nomem(ctx); + return SQLITE_NOMEM_BKPT; + } + memcpy(zCopy, zQuote, nQuote); + sqlite3Dequote(zCopy); + *pRes = sqlite3_stricmp((const char*)zCopy, (const char*)zCmp); + sqlite3_free(zCopy); + return SQLITE_OK; +} + +/* +** zSql[] is a CREATE TABLE statement, supposedly. Find the offset +** into zSql[] of the first character past the first "(" and write +** that offset into *piOff and return SQLITE_OK. Or, if not found, +** set the SQLITE_CORRUPT error code and return SQLITE_ERROR. +*/ +static int skipCreateTable(sqlite3_context *ctx, const u8 *zSql, int *piOff){ + int iOff = 0; + + if( zSql==0 ) return SQLITE_ERROR; + + /* Jump past the "CREATE TABLE" bit. */ + while( 1 ){ + int t = 0; + iOff += sqlite3GetToken(&zSql[iOff], &t); + if( t==TK_LP ) break; + if( t==TK_ILLEGAL ){ + sqlite3_result_error_code(ctx, SQLITE_CORRUPT_BKPT); + return SQLITE_ERROR; + } + } + + *piOff = iOff; + return SQLITE_OK; +} + +/* +** Internal SQL function sqlite3_drop_constraint(): Given an input +** CREATE TABLE statement, return a revised CREATE TABLE statement +** with a constraint removed. Two forms, depending on the datatype +** of argv[2]: +** +** sqlite_drop_constraint(SQL, INT) -- Omit NOT NULL from the INT-th column +** sqlite_drop_constraint(SQL, TEXT) -- OMIT constraint with name TEXT +** +** In the first case, the left-most column is 0. +*/ +static void dropConstraintFunc( + sqlite3_context *ctx, + int NotUsed, + sqlite3_value **argv +){ + const u8 *zSql = sqlite3_value_text(argv[0]); + const u8 *zCons = 0; + int iNotNull = -1; + int ii; + int iOff = 0; + int iStart = 0; + int iEnd = 0; + char *zNew = 0; + int t = 0; + sqlite3 *db; + UNUSED_PARAMETER(NotUsed); + + if( zSql==0 ) return; + + /* Jump past the "CREATE TABLE" bit. */ + if( skipCreateTable(ctx, zSql, &iOff) ) return; + + if( sqlite3_value_type(argv[1])==SQLITE_INTEGER ){ + iNotNull = sqlite3_value_int(argv[1]); + }else{ + zCons = sqlite3_value_text(argv[1]); + } + + /* Search for the named constraint within column definitions. */ + for(ii=0; iEnd==0; ii++){ + + /* Now parse the column or table constraint definition. Search + ** for the token CONSTRAINT if this is a DROP CONSTRAINT command, or + ** NOT in the right column if this is a DROP NOT NULL. */ + while( 1 ){ + iStart = iOff; + iOff += getConstraintToken(&zSql[iOff], &t); + if( t==TK_CONSTRAINT && (zCons || iNotNull==ii) ){ + /* Check if this is the constraint we are searching for. */ + int nTok = 0; + int cmp = 1; + + /* Skip past any whitespace. */ + iOff += getWhitespace(&zSql[iOff]); + + /* Compare the next token - which may be quoted - with the name of + ** the constraint being dropped. */ + nTok = getConstraintToken(&zSql[iOff], &t); + if( zCons ){ + if( quotedCompare(ctx, t, &zSql[iOff], nTok, zCons, &cmp) ) return; + } + iOff += nTok; + + /* The next token is usually the first token of the constraint + ** definition. This is enough to tell the type of the constraint - + ** TK_NOT means it is a NOT NULL, TK_CHECK a CHECK constraint etc. + ** + ** There is also the chance that the next token is TK_CONSTRAINT + ** (or TK_DEFAULT or TK_COLLATE), for example if a table has been + ** created as follows: + ** + ** CREATE TABLE t1(cols, CONSTRAINT one CONSTRAINT two NOT NULL); + ** + ** In this case, allow the "CONSTRAINT one" bit to be dropped by + ** this command if that is what is requested, or to advance to + ** the next iteration of the loop with &zSql[iOff] still pointing + ** to the CONSTRAINT keyword. */ + nTok = getConstraintToken(&zSql[iOff], &t); + if( t==TK_CONSTRAINT || t==TK_DEFAULT || t==TK_COLLATE + || t==TK_COMMA || t==TK_RP || t==TK_GENERATED || t==TK_AS + ){ + t = TK_CHECK; + }else{ + iOff += nTok; + iOff += getConstraint(&zSql[iOff], t); + } + + if( cmp==0 || (iNotNull>=0 && t==TK_NOT) ){ + if( t!=TK_NOT && t!=TK_CHECK && t!=TK_REFERENCES && t!=TK_FOREIGN ){ + errorMPrintf(ctx, "constraint may not be dropped: %s", zCons); + return; + } + iEnd = iOff; + break; + } + + }else if( t==TK_NOT && iNotNull==ii ){ + iEnd = iOff + getConstraint(&zSql[iOff], 0); + break; + }else if( t==TK_RP || t==TK_ILLEGAL ){ + iEnd = -1; + break; + }else if( t==TK_COMMA ){ + break; + } + } + } + + /* If the constraint has not been found it is an error. */ + if( iEnd<=0 ){ + if( zCons ){ + errorMPrintf(ctx, "no such constraint: %s", zCons); + }else{ + /* SQLite follows postgres in that a DROP NOT NULL on a column that is + ** not NOT NULL is not an error. So just return the original SQL here. */ + sqlite3_result_text(ctx, (const char*)zSql, -1, SQLITE_TRANSIENT); + } + }else{ + + /* Figure out if an extra space should be inserted after the constraint + ** is removed. And if an additional comma preceding the constraint + ** should be removed. */ + const char *zSpace = " "; + iEnd += getWhitespace(&zSql[iEnd]); + sqlite3GetToken(&zSql[iEnd], &t); + if( t==TK_RP || t==TK_COMMA ){ + zSpace = ""; + if( zSql[iStart-1]==',' ) iStart--; + } + + db = sqlite3_context_db_handle(ctx); + zNew = sqlite3MPrintf(db, "%.*s%s%s", iStart, zSql, zSpace, &zSql[iEnd]); + sqlite3_result_text(ctx, zNew, -1, SQLITE_DYNAMIC); + } +} + +/* +** Internal SQL function: +** +** sqlite_add_constraint(SQL, CONSTRAINT-TEXT, ICOL) +** +** SQL is a CREATE TABLE statement. Return a modified version of +** SQL that adds CONSTRAINT-TEXT at the end of the ICOL-th column +** definition. (The left-most column defintion is 0.) +*/ +static void addConstraintFunc( + sqlite3_context *ctx, + int NotUsed, + sqlite3_value **argv +){ + const u8 *zSql = sqlite3_value_text(argv[0]); + const char *zCons = (const char*)sqlite3_value_text(argv[1]); + int iCol = sqlite3_value_int(argv[2]); + int iOff = 0; + int ii; + sqlite3_str *pNew; + int t = 0; + UNUSED_PARAMETER(NotUsed); + + if( skipCreateTable(ctx, zSql, &iOff) ) return; + + for(ii=0; ii<=iCol || (iCol<0 && t!=TK_RP); ii++){ + iOff += getConstraintToken(&zSql[iOff], &t); + while( 1 ){ + int nTok = getConstraintToken(&zSql[iOff], &t); + if( t==TK_COMMA || t==TK_RP ) break; + if( t==TK_ILLEGAL ){ + sqlite3_result_error_code(ctx, SQLITE_CORRUPT_BKPT); + return; + } + iOff += nTok; + } + } + + iOff += getWhitespace(&zSql[iOff]); + + pNew = sqlite3_str_new(sqlite3_context_db_handle(ctx)); + sqlite3_str_append(pNew, (const char*)zSql, iOff); + if( iCol<0 ) sqlite3_str_append(pNew, ",", 1); + sqlite3_str_appendf(pNew, " %s%s", zCons, &zSql[iOff]); + sqlite3_result_str(ctx, pNew, SQLITE_FINISH); +} + +/* +** Find a column named pCol in table pTab. If successful, set output +** parameter *piCol to the index of the column in the table and return +** SQLITE_OK. Otherwise, set *piCol to -1 and return an SQLite error +** code. +*/ +static int alterFindCol(Parse *pParse, Table *pTab, Token *pCol, int *piCol){ + sqlite3 *db = pParse->db; + char *zName = sqlite3NameFromToken(db, pCol); + int rc = SQLITE_NOMEM; + int iCol = -1; + + if( zName ){ + iCol = sqlite3ColumnIndex(pTab, zName); + if( iCol<0 ){ + sqlite3ErrorMsg(pParse, "no such column: %s", zName); + rc = SQLITE_ERROR; + }else{ + rc = SQLITE_OK; + } + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( rc==SQLITE_OK ){ + const char *zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; + const char *zCol = pTab->aCol[iCol].zCnName; + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){ + pTab = 0; + } + } +#endif + + sqlite3DbFree(db, zName); + *piCol = iCol; + return rc; +} + + +/* +** Find the table named by the first entry in source list pSrc. If successful, +** return a pointer to the Table structure and set output variable (*pzDb) +** to point to the name of the database containin the table (i.e. "main", +** "temp" or the name of an attached database). +** +** If the table cannot be located, return NULL. The value of the two output +** parameters is undefined in this case. +*/ +static Table *alterFindTable( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Name of the table to look for */ + int *piDb, /* OUT: write the iDb here */ + const char **pzDb, /* OUT: write name of schema here */ + int bAuth /* Do ALTER TABLE authorization checks if true */ +){ + sqlite3 *db = pParse->db; + Table *pTab = 0; + assert( sqlite3BtreeHoldsAllMutexes(db) ); + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( pTab ){ + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + *pzDb = db->aDb[iDb].zDbSName; + *piDb = iDb; + + if( SQLITE_OK!=isRealTable(pParse, pTab, 2) + || SQLITE_OK!=isAlterableTable(pParse, pTab) + ){ + pTab = 0; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pTab && bAuth ){ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, *pzDb, pTab->zName, 0) ){ + pTab = 0; + } + } +#endif + sqlite3SrcListDelete(db, pSrc); + return pTab; +} + +/* +** Generate bytecode for one of: +** +** (1) ALTER TABLE pSrc DROP CONSTRAINT pCons +** (2) ALTER TABLE pSrc ALTER pCol DROP NOT NULL +** +** One of pCons and pCol must be NULL and the other non-null. +*/ +SQLITE_PRIVATE void sqlite3AlterDropConstraint( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* The table being altered */ + Token *pCons, /* Name of the constraint to drop */ + Token *pCol /* Name of the column from which to remove the NOT NULL */ +){ + sqlite3 *db = pParse->db; + Table *pTab = 0; + int iDb = 0; + const char *zDb = 0; + char *zArg = 0; + + assert( (pCol==0)!=(pCons==0) ); + assert( pSrc->nSrc==1 ); + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, pCons!=0); + if( !pTab ) return; + + if( pCons ){ + char *z = sqlite3NameFromToken(db, pCons); + zArg = sqlite3MPrintf(db, "%Q", z); + sqlite3DbFree(db, z); + }else{ + int iCol; + if( alterFindCol(pParse, pTab, pCol, &iCol) ) return; + zArg = sqlite3MPrintf(db, "%d", iCol); + } + + /* Edit the SQL for the named table. */ + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_drop_constraint(sql, %s) " + "WHERE type='table' AND tbl_name=%Q COLLATE nocase" + , zDb, zArg, pTab->zName + ); + sqlite3DbFree(db, zArg); + + /* Finally, reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); +} + +/* +** The implementation of SQL function sqlite_fail(MSG). This takes a single +** argument, and returns it as an error message with the error code set to +** SQLITE_CONSTRAINT. +*/ +static void failConstraintFunc( + sqlite3_context *ctx, + int NotUsed, + sqlite3_value **argv +){ + const char *zText = (const char*)sqlite3_value_text(argv[0]); + int err = sqlite3_value_int(argv[1]); + (void)NotUsed; + sqlite3_result_error(ctx, zText, -1); + sqlite3_result_error_code(ctx, err); +} + +/* +** Buffer pCons, which is nCons bytes in size, contains the text of a +** NOT NULL or CHECK constraint that will be inserted into a CREATE TABLE +** statement. If successful, this function returns the size of the buffer in +** bytes not including any trailing whitespace or "--" style comments. Or, +** if an OOM occurs, it returns 0 and sets db->mallocFailed to true. +** +** C-style comments at the end are preserved. "--" style comments are +** removed because the comment terminator might be \000, and we are about +** to insert the pCons[] text into the middle of a larger string, and that +** will have the effect of removing the comment terminator and messing up +** the syntax. +*/ +static int alterRtrimConstraint( + sqlite3 *db, /* used to record OOM error */ + const char *pCons, /* Buffer containing constraint */ + int nCons /* Size of pCons in bytes */ +){ + u8 *zTmp = (u8*)sqlite3MPrintf(db, "%.*s", nCons, pCons); + int iOff = 0; + int iEnd = 0; + + if( zTmp==0 ) return 0; + + while( 1 ){ + int t = 0; + int nToken = sqlite3GetToken(&zTmp[iOff], &t); + if( t==TK_ILLEGAL ) break; + if( t!=TK_SPACE && (t!=TK_COMMENT || zTmp[iOff]!='-') ){ + iEnd = iOff+nToken; + } + iOff += nToken; + } + + sqlite3DbFree(db, zTmp); + return iEnd; +} + +/* +** Prepare a statement of the form: +** +** ALTER TABLE pSrc ALTER pCol SET NOT NULL +*/ +SQLITE_PRIVATE void sqlite3AlterSetNotNull( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Name of the table being altered */ + Token *pCol, /* Name of the column to add a NOT NULL constraint to */ + Token *pFirst /* The NOT token of the NOT NULL constraint text */ +){ + Table *pTab = 0; + int iCol = 0; + int iDb = 0; + const char *zDb = 0; + const char *pCons = 0; + int nCons = 0; + + /* Look up the table being altered. */ + assert( pSrc->nSrc==1 ); + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 0); + if( !pTab ) return; + + /* Find the column being altered. */ + if( alterFindCol(pParse, pTab, pCol, &iCol) ){ + return; + } + + /* Find the length in bytes of the constraint definition */ + pCons = pFirst->z; + nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons); + + /* Search for a constraint violation. Throw an exception if one is found. */ + sqlite3NestedParse(pParse, + "SELECT sqlite_fail('constraint failed', %d) " + "FROM %Q.%Q AS x WHERE x.%.*s IS NULL", + SQLITE_CONSTRAINT, zDb, pTab->zName, (int)pCol->n, pCol->z + ); + + /* Edit the SQL for the named table. */ + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_add_constraint(sqlite_drop_constraint(sql, %d), %.*Q, %d) " + "WHERE type='table' AND tbl_name=%Q COLLATE nocase" + , zDb, iCol, nCons, pCons, iCol, pTab->zName + ); + + /* Finally, reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); +} + +/* +** Implementation of internal SQL function: +** +** sqlite_find_constraint(SQL, CONSTRAINT-NAME) +** +** This function returns true if the SQL passed as the first argument is a +** CREATE TABLE that contains a constraint with the name CONSTRAINT-NAME, +** or false otherwise. +*/ +static void findConstraintFunc( + sqlite3_context *ctx, + int NotUsed, + sqlite3_value **argv +){ + const u8 *zSql = 0; + const u8 *zCons = 0; + int iOff = 0; + int t = 0; + + (void)NotUsed; + zSql = sqlite3_value_text(argv[0]); + zCons = sqlite3_value_text(argv[1]); + + if( zSql==0 || zCons==0 ) return; + while( t!=TK_LP && t!=TK_ILLEGAL ){ + iOff += sqlite3GetToken(&zSql[iOff], &t); + } + + while( 1 ){ + iOff += getConstraintToken(&zSql[iOff], &t); + if( t==TK_CONSTRAINT ){ + int nTok = 0; + int cmp = 0; + iOff += getWhitespace(&zSql[iOff]); + nTok = getConstraintToken(&zSql[iOff], &t); + if( quotedCompare(ctx, t, &zSql[iOff], nTok, zCons, &cmp) ) return; + if( cmp==0 ){ + sqlite3_result_int(ctx, 1); + return; + } + }else if( t==TK_ILLEGAL ){ + break; + } + } + + sqlite3_result_int(ctx, 0); +} + +/* +** Generate bytecode to implement: +** +** ALTER TABLE pSrc ADD [CONSTRAINT pName] CHECK(pExpr) +** +** Any "ON CONFLICT" text that occurs after the "CHECK(...)", up +** until pParse->sLastToken, is included as part of the new constraint. +*/ +SQLITE_PRIVATE void sqlite3AlterAddConstraint( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* Table to add constraint to */ + Token *pFirst, /* First token of new constraint */ + Token *pName, /* Name of new constraint. NULL if name omitted. */ + const char *zExpr, /* Text of CHECK expression */ + int nExpr, /* Size of pExpr in bytes */ + Expr *pExpr /* The parsed CHECK expression */ +){ + Table *pTab = 0; /* Table identified by pSrc */ + int iDb = 0; /* Which schema does pTab live in */ + const char *zDb = 0; /* Name of the schema in which pTab lives */ + const char *pCons = 0; /* Text of the constraint */ + int nCons; /* Bytes of text to use from pCons[] */ + int rc; /* Result from error checking pExpr */ + + /* Look up the table being altered. */ + assert( pSrc->nSrc==1 ); + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 1); + if( !pTab ){ + sqlite3ExprDelete(pParse->db, pExpr); + return; + } + + /* Verify that the new CHECK constraint does not contain any + ** internal-use-only function. Forum post 2026-05-10T01:11:28Z + */ + rc = sqlite3ResolveSelfReference(pParse, pTab, NC_IsCheck, pExpr, 0); + sqlite3ExprDelete(pParse->db, pExpr); + if( rc ) return; + + /* If this new constraint has a name, check that it is not a duplicate of + ** an existing constraint. It is an error if it is. */ + if( pName ){ + char *zName = sqlite3NameFromToken(pParse->db, pName); + + sqlite3NestedParse(pParse, + "SELECT sqlite_fail('constraint %q already exists', %d) " + "FROM \"%w\"." LEGACY_SCHEMA_TABLE " " + "WHERE type='table' AND tbl_name=%Q COLLATE nocase " + "AND sqlite_find_constraint(sql, %Q)", + zName, SQLITE_ERROR, zDb, pTab->zName, zName + ); + sqlite3DbFree(pParse->db, zName); + } + + /* Search for a constraint violation. Throw an exception if one is found. */ + sqlite3NestedParse(pParse, + "SELECT sqlite_fail('constraint failed', %d) " + "FROM %Q.%Q WHERE (%.*s) IS FALSE", + SQLITE_CONSTRAINT, zDb, pTab->zName, nExpr, zExpr + ); + + /* Edit the SQL for the named table. */ + pCons = pFirst->z; + nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons); + + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_add_constraint(sql, %.*Q, -1) " + "WHERE type='table' AND tbl_name=%Q COLLATE nocase" + , zDb, nCons, pCons, pTab->zName + ); + + /* Finally, reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); +} + /* ** Register built-in functions used to help implement ALTER TABLE */ @@ -121435,6 +123827,10 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(void){ INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest), INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc), INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc), + INTERNAL_FUNCTION(sqlite_drop_constraint,2, dropConstraintFunc), + INTERNAL_FUNCTION(sqlite_fail, 2, failConstraintFunc), + INTERNAL_FUNCTION(sqlite_add_constraint, 3, addConstraintFunc), + INTERNAL_FUNCTION(sqlite_find_constraint,2, findConstraintFunc), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } @@ -122320,7 +124716,7 @@ static void statGet( assert( p->current.anEq[i] || p->nRow==0 ); #endif } - sqlite3ResultStrAccum(context, &sStat); + sqlite3_result_str(context, &sStat, SQLITE_XFER); } #ifdef SQLITE_ENABLE_STAT4 else if( eCall==STAT_GET_ROWID ){ @@ -122357,7 +124753,7 @@ static void statGet( sqlite3_str_appendf(&sStat, "%llu ", (u64)aCnt[i]); } if( sStat.nChar ) sStat.nChar--; - sqlite3ResultStrAccum(context, &sStat); + sqlite3_result_str(context, &sStat, SQLITE_XFER); } #endif /* SQLITE_ENABLE_STAT4 */ #ifndef SQLITE_DEBUG @@ -123258,9 +125654,9 @@ static int loadStatTbl( } pIdx->nSampleCol = nIdxCol; pIdx->mxSample = nSample; - nByte = ROUND8(sizeof(IndexSample) * nSample); - nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; - nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ + nByte = ROUND8(sizeof64(IndexSample) * nSample); + nByte += sizeof64(tRowcnt) * nIdxCol * 3 * nSample; + nByte += nIdxCol * sizeof64(tRowcnt); /* Space for Index.aAvgEq[] */ pIdx->aSample = sqlite3DbMallocZero(db, nByte); if( pIdx->aSample==0 ){ @@ -123268,7 +125664,7 @@ static int loadStatTbl( return SQLITE_NOMEM_BKPT; } pPtr = (u8*)pIdx->aSample; - pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); + pPtr += ROUND8(nSample*sizeof64(pIdx->aSample[0])); pSpace = (tRowcnt*)pPtr; assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); pIdx->aAvgEq = pSpace; pSpace += nIdxCol; @@ -123515,6 +125911,23 @@ SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){ ); } +/* +** If any TEMP triggers reference schema pSchema, move those triggers to +** reference the TEMP schema itself. +*/ +static void detachTempTriggers(sqlite3 *db, Schema *pSchema){ + HashElem *pEntry; + assert( db->aDb[1].pSchema ); + pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash); + while( pEntry ){ + Trigger *pTrig = (Trigger*)sqliteHashData(pEntry); + if( pTrig->pTabSchema==pSchema ){ + pTrig->pTabSchema = pTrig->pSchema; + } + pEntry = sqliteHashNext(pEntry); + } +} + /* ** An SQL user-function registered to do the work of an ATTACH statement. The ** three arguments to the function come directly from an attach statement: @@ -123565,6 +125978,16 @@ static void attachFunc( ** from sqlite3_deserialize() to close database db->init.iDb and ** reopen it as a MemDB */ Btree *pNewBt = 0; + + pNew = &db->aDb[db->init.iDb]; + assert( pNew->pBt!=0 ); + if( sqlite3BtreeTxnState(pNew->pBt)!=SQLITE_TXN_NONE + || sqlite3BtreeIsInBackup(pNew->pBt) + ){ + rc = SQLITE_BUSY; + goto attach_error; + } + pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); @@ -123574,10 +125997,16 @@ static void attachFunc( /* Both the Btree and the new Schema were allocated successfully. ** Close the old db and update the aDb[] slot with the new memdb ** values. */ - pNew = &db->aDb[db->init.iDb]; - if( ALWAYS(pNew->pBt) ) sqlite3BtreeClose(pNew->pBt); + detachTempTriggers(db, pNew->pSchema); + sqlite3BtreeClose(pNew->pBt); pNew->pBt = pNewBt; pNew->pSchema = pNewSchema; + if( db->init.iDb==0 ){ + /* Clear all eponymous virtual table instances, as they are holding + ** pointers to the schema object just freed by sqlite3BtreeClose() */ + sqlite3VtabEponymousTableClearAll(db); + } + sqlite3ExpirePreparedStatements(db, 1); }else{ sqlite3BtreeClose(pNewBt); rc = SQLITE_NOMEM; @@ -123749,7 +126178,6 @@ static void detachFunc( sqlite3 *db = sqlite3_context_db_handle(context); int i; Db *pDb = 0; - HashElem *pEntry; char zErr[128]; UNUSED_PARAMETER(NotUsed); @@ -123776,18 +126204,7 @@ static void detachFunc( goto detach_error; } - /* If any TEMP triggers reference the schema being detached, move those - ** triggers to reference the TEMP schema itself. */ - assert( db->aDb[1].pSchema ); - pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash); - while( pEntry ){ - Trigger *pTrig = (Trigger*)sqliteHashData(pEntry); - if( pTrig->pTabSchema==pDb->pSchema ){ - pTrig->pTabSchema = pTrig->pSchema; - } - pEntry = sqliteHashNext(pEntry); - } - + detachTempTriggers(db, pDb->pSchema); sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; @@ -124055,7 +126472,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( if( sqlite3WalkSelect(&pFix->w, pStep->pSelect) || sqlite3WalkExpr(&pFix->w, pStep->pWhere) || sqlite3WalkExprList(&pFix->w, pStep->pExprList) - || sqlite3FixSrcList(pFix, pStep->pFrom) + || sqlite3FixSrcList(pFix, pStep->pSrc) ){ return 1; } @@ -124162,7 +126579,7 @@ SQLITE_API int sqlite3_set_authorizer( sqlite3_mutex_enter(db->mutex); db->xAuth = (sqlite3_xauth)xAuth; db->pAuthArg = pArg; - if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1); + sqlite3ExpirePreparedStatements(db, 1); sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -124273,8 +126690,14 @@ SQLITE_PRIVATE void sqlite3AuthRead( ** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY ** is returned, then the error count and error message in pParse are ** modified appropriately. +** +** Divided into two routines. realAuthCheck() does the work. The +** sqlite3AuthCheck() routine is usually a fast no-op but invokes +** realAuthCheck() (and spends time doing some stack pushes and pops +** as a result) in the uncommon case where an authorization check is +** actually needed. */ -SQLITE_PRIVATE int sqlite3AuthCheck( +static int SQLITE_NOINLINE realAuthCheck( Parse *pParse, int code, const char *zArg1, @@ -124288,7 +126711,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( ** or if the parser is being invoked from within sqlite3_declare_vtab. */ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); - if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){ + if( IN_SPECIAL_PARSE ){ return SQLITE_OK; } @@ -124313,6 +126736,19 @@ SQLITE_PRIVATE int sqlite3AuthCheck( } return rc; } +SQLITE_PRIVATE int sqlite3AuthCheck( + Parse *pParse, + int code, + const char *zArg1, + const char *zArg2, + const char *zArg3 +){ + if( pParse->db->xAuth!=0 && pParse->db->init.busy==0 ){ + return realAuthCheck(pParse,code,zArg1,zArg2,zArg3); + }else{ + return SQLITE_OK; + } +} /* ** Push an authorization context. After this routine is called, the @@ -124417,6 +126853,7 @@ static SQLITE_NOINLINE void lockTable( assert( pToplevel->nTableLock < 0x7fff0000 ); nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); + if( pToplevel->nTableLock==0 ) pToplevel->aTableLock = 0; pToplevel->aTableLock = sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); if( pToplevel->aTableLock ){ @@ -124583,7 +127020,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* Initialize any AUTOINCREMENT data structures required. */ - if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse); + if( pParse->usesAinc ) sqlite3AutoincrementBegin(pParse); /* Code constant expressions that were factored out of inner loops. */ @@ -124616,7 +127053,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ if( pParse->nErr==0 ){ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ - assert( pParse->pAinc==0 || pParse->nTab>0 ); + assert( pParse->usesAinc==0 || pParse->nTab>0 ); sqlite3VdbeMakeReady(v, pParse); pParse->rc = SQLITE_DONE; }else{ @@ -124833,6 +127270,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem( const char *zDb; if( p->fg.fixedSchema ){ int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema); + assert( iDb>=0 && iDbdb->nDb ); zDb = pParse->db->aDb[iDb].zDbSName; }else{ assert( !p->fg.isSubquery ); @@ -124984,6 +127422,7 @@ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ for(i=0; inDb; i++){ if( DbHasProperty(db, i, DB_ResetWanted) ){ sqlite3SchemaClear(db->aDb[i].pSchema); + db->mDbFlags &= ~DBFLAG_SchemaKnownOk; } } } @@ -125047,10 +127486,41 @@ SQLITE_PRIVATE void sqlite3ColumnSetExpr( } } +#ifndef SQLITE_OMIT_AUTHORIZATION +/* +** If the expression contains any TK_FUNCTION, send it to the authorizer +** and if the authorization fails then raise an error. +*/ +static int authFunctions(Walker *pWalker, Expr *p){ + if( p->op==TK_FUNCTION ){ + Parse *pParse = pWalker->pParse; + int rc = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, p->u.zToken, 0); + if( rc ){ + sqlite3ErrorMsg(pParse, "not authorized to use function: %#T", p); + return WRC_Abort; + } + } + return WRC_Continue; +} +static void sqlite3FuncAuth(Parse *pParse, Expr *pExpr){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = authFunctions; + w.pParse = pParse; + sqlite3WalkExpr(&w,pExpr); +} +#endif /* SQLITE_OMIT_AUTHORIZATION */ + /* ** Return the expression associated with a column. The expression might be ** the DEFAULT clause or the AS clause of a generated column. ** Return NULL if the column has no associated expression. +** +** There are two variants of this routine. sqlite3ColumnExpr() just +** returns the expression with no side effects. sqlite3ColumnExprAuth() +** takes the extra step of invoking the authorizer (if one is defined) +** and raising an error if the returned expression uses any unauthorized +** SQL function. */ SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ if( pCol->iDflt==0 ) return 0; @@ -125059,6 +127529,28 @@ SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ if( NEVER(pTab->u.tab.pDfltList->nExpriDflt) ) return 0; return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; } +SQLITE_PRIVATE Expr *sqlite3ColumnExprAuth(Table *pTab, Column *pCol, Parse *pParse){ + Expr *pExpr = sqlite3ColumnExpr(pTab,pCol); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pParse->db->xAuth!=0 ){ + sqlite3FuncAuth(pParse, pExpr); + } +#endif + return pExpr; +} + +/* +** Suppress false-positive warning message generated with -O3 in GCC +** on the second call to sqlite3Strlen30() in the sqlite3ColumnSetColl() +** function below. See the forum thread beginning on 2026-05-10T01:11:22Z. +** +** See also the "pop" pragma to undo this warning suppression immediately +** after the function. +*/ +#if defined(__GNUC__) && __GNUC__>=11 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wstringop-overread" +#endif /* ** Set the collating sequence name for a column. @@ -125085,6 +127577,11 @@ SQLITE_PRIVATE void sqlite3ColumnSetColl( } } +/* Undo the false-positive warning suppression above. */ +#if defined(__GNUC__) && __GNUC__>=11 +# pragma GCC diagnostic pop +#endif + /* ** Return the collating sequence name for a column */ @@ -126107,6 +128604,13 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue( pDfltExpr = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); sqlite3DbFree(db, x.u.zToken); sqlite3ColumnSetExpr(pParse, p, pCol, pDfltExpr); +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Reject unauthorized functions from DEFAULT clauses */ + if( db->init.busy==0 && db->xAuth!=0 ){ + sqlite3FuncAuth(pParse, pExpr); + } +#endif /* SQLITE_OMIT_AUTHORIZER */ + } } if( IN_RENAME_OBJECT ){ @@ -126406,8 +128910,8 @@ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ ** The estimate is conservative. It might be larger that what is ** really needed. */ -static int identLength(const char *z){ - int n; +static i64 identLength(const char *z){ + i64 n; for(n=0; *z; n++, z++){ if( *z=='"' ){ n++; } } @@ -126562,6 +129066,23 @@ static int resizeIndexObject(Parse *pParse, Index *pIdx, int N){ return SQLITE_OK; } +/* +** Return true if the index pIdx can support a Bloom filter on its +** first N columns. Specifically, return true if all of the first N +** columns have the BINARY collating sequence or no collating sequence +** at all, and return false if there are any non-BINARY collating +** seqeuences on any of the first N columns. tag-202607231411 +*/ +SQLITE_PRIVATE int sqlite3IndexBloomable(const Index *pIdx, int N){ + int i; + assert( pIdx!=0 ); + assert( N <= pIdx->nColumn ); + for(i=0; iazColl[i],"BINARY")!=0 ) return 0; + } + return 1; +} + /* ** Estimate the total row width for a table. */ @@ -126840,9 +129361,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( !hasColumn(pPk->aiColumn, j, i) && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + const char *zColl = sqlite3ColumnColl(&pTab->aCol[i]); assert( jnColumn ); pPk->aiColumn[j] = i; - pPk->azColl[j] = sqlite3StrBINARY; + pPk->azColl[j] = zColl ? zColl : sqlite3StrBINARY; j++; } } @@ -126912,18 +129434,16 @@ SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){ /* ** Return true if zName is a shadow table name in the current database ** connection. -** -** zName is temporarily modified while this routine is running, but is -** restored to its original value prior to this routine returning. */ SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ - char *zTail; /* Pointer to the last "_" in zName */ + const char *zTail; /* Pointer to the last "_" in zName */ Table *pTab; /* Table that zName is a shadow of */ + char *zCopy; /* Transient copy of zName after last "_" */ zTail = strrchr(zName, '_'); if( zTail==0 ) return 0; - *zTail = 0; - pTab = sqlite3FindTable(db, zName, 0); - *zTail = '_'; + zCopy = sqlite3DbStrNDup(db, zName, (int)(zTail-zName)); + pTab = zCopy ? sqlite3FindTable(db, zCopy, 0) : 0; + sqlite3DbFree(db, zCopy); if( pTab==0 ) return 0; if( !IsVirtual(pTab) ) return 0; return sqlite3IsShadowTableOf(db, pTab, zName); @@ -126957,7 +129477,6 @@ static void markExprListImmutable(ExprList *pList){ #define markExprListImmutable(X) /* no-op */ #endif /* SQLITE_DEBUG */ - /* ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. @@ -127076,6 +129595,7 @@ SQLITE_PRIVATE void sqlite3EndTable( convertToWithoutRowidTable(pParse, p); } iDb = sqlite3SchemaToIndex(db, p->pSchema); + assert( iDb>=0 && iDb<=db->nDb ); #ifndef SQLITE_OMIT_CHECK /* Resolve names in all CHECK constraint expressions. @@ -127371,6 +129891,7 @@ SQLITE_PRIVATE void sqlite3CreateView( sqlite3TwoPartName(pParse, pName1, pName2, &pName); iDb = sqlite3SchemaToIndex(db, p->pSchema); + assert( iDb>=0 && iDbnDb ); sqlite3FixInit(&sFix, pParse, iDb, "view", pName); if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail; @@ -128428,8 +130949,9 @@ SQLITE_PRIVATE void sqlite3CreateIndex( if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ if( !ifNotExist ){ sqlite3ErrorMsg(pParse, "index %s already exists", zName); + }else if( db->init.busy ){ + sqlite3ErrorMsg(pParse,""); /* corruptSchema() will do the error */ }else{ - assert( !db->init.busy ); sqlite3CodeVerifySchema(pParse, iDb); sqlite3ForceNotReadOnly(pParse); } @@ -128967,6 +131489,7 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists goto exit_drop_index; } iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); + assert( iDb>=0 && iDbnDb ); #ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_DROP_INDEX; @@ -129864,8 +132387,7 @@ SQLITE_PRIVATE void sqlite3RowidConstraint( } /* -** Check to see if pIndex uses the collating sequence pColl. Return -** true if it does and false if it does not. +** Return true if any column of pIndex uses the zColl collation */ #ifndef SQLITE_OMIT_REINDEX static int collationMatch(const char *zColl, Index *pIndex){ @@ -129873,8 +132395,8 @@ static int collationMatch(const char *zColl, Index *pIndex){ assert( zColl!=0 ); for(i=0; inColumn; i++){ const char *z = pIndex->azColl[i]; - assert( z!=0 || pIndex->aiColumn[i]<0 ); - if( pIndex->aiColumn[i]>=0 && 0==sqlite3StrICmp(z, zColl) ){ + assert( z!=0 ); + if( 0==sqlite3StrICmp(z, zColl) ){ return 1; } } @@ -129882,73 +132404,39 @@ static int collationMatch(const char *zColl, Index *pIndex){ } #endif -/* -** Recompute all indices of pTab that use the collating sequence pColl. -** If pColl==0 then recompute all indices of pTab. -*/ -#ifndef SQLITE_OMIT_REINDEX -static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ - if( !IsVirtual(pTab) ){ - Index *pIndex; /* An index associated with pTab */ - - for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ - if( zColl==0 || collationMatch(zColl, pIndex) ){ - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3RefillIndex(pParse, pIndex, -1); - } - } - } -} -#endif - -/* -** Recompute all indices of all tables in all databases where the -** indices use the collating sequence pColl. If pColl==0 then recompute -** all indices everywhere. -*/ -#ifndef SQLITE_OMIT_REINDEX -static void reindexDatabases(Parse *pParse, char const *zColl){ - Db *pDb; /* A single database */ - int iDb; /* The database index number */ - sqlite3 *db = pParse->db; /* The database connection */ - HashElem *k; /* For looping over tables in pDb */ - Table *pTab; /* A table in the database */ - - assert( sqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */ - for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ - assert( pDb!=0 ); - for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ - pTab = (Table*)sqliteHashData(k); - reindexTable(pParse, pTab, zColl); - } - } -} -#endif - /* ** Generate code for the REINDEX command. ** ** REINDEX -- 1 ** REINDEX -- 2 -** REINDEX ?.? -- 3 -** REINDEX ?.? -- 4 +** REINDEX ?.? -- 3 +** REINDEX ?.? -- 4 +** REINDEX EXPRESSIONS -- 5 ** -** Form 1 causes all indices in all attached databases to be rebuilt. -** Form 2 rebuilds all indices in all databases that use the named +** Form 1 causes all indexes in all attached databases to be rebuilt. +** Form 2 rebuilds all indexes in all databases that use the named ** collating function. Forms 3 and 4 rebuild the named index or all -** indices associated with the named table. +** indexes associated with the named table, respectively. Form 5 +** rebuilds all expression indexes in addition to all collations, +** indexes, or tables named "EXPRESSIONS". +** +** If the name is ambiguous such that it matches two or more of +** forms 2 through 5, then rebuild the union of all matching indexes, +** taken care to avoid rebuilding the same index more than once. */ #ifndef SQLITE_OMIT_REINDEX SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ - CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ - char *z; /* Name of a table or index */ - const char *zDb; /* Name of the database */ - Table *pTab; /* A table in the database */ - Index *pIndex; /* An index associated with pTab */ - int iDb; /* The database index number */ + char *z = 0; /* Name of a table or index or collation */ + const char *zDb = 0; /* Name of the database */ + int iReDb = -1; /* The database index number */ sqlite3 *db = pParse->db; /* The database connection */ Token *pObjName; /* Name of the table or index to be reindexed */ + int bMatch = 0; /* At least one name match */ + const char *zColl = 0; /* Rebuild indexes using this collation */ + Table *pReTab = 0; /* Rebuild all indexes of this table */ + Index *pReIndex = 0; /* Rebuild this index */ + int isExprIdx = 0; /* Rebuild all expression indexes */ + int bAll = 0; /* Rebuild all indexes */ /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ @@ -129957,41 +132445,66 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ } if( pName1==0 ){ - reindexDatabases(pParse, 0); - return; + /* rebuild all indexes */ + bMatch = 1; + bAll = 1; }else if( NEVER(pName2==0) || pName2->z==0 ){ - char *zColl; assert( pName1->z ); - zColl = sqlite3NameFromToken(pParse->db, pName1); - if( !zColl ) return; - pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); - if( pColl ){ - reindexDatabases(pParse, zColl); - sqlite3DbFree(db, zColl); - return; + z = sqlite3NameFromToken(pParse->db, pName1); + if( z==0 ) return; + }else{ + iReDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); + if( iReDb<0 ) return; + z = sqlite3NameFromToken(db, pObjName); + if( z==0 ) return; + zDb = db->aDb[iReDb].zDbSName; + } + if( !bAll ){ + if( zDb==0 && sqlite3StrICmp(z, "expressions")==0 ){ + isExprIdx = 1; + bMatch = 1; + } + if( zDb==0 && sqlite3FindCollSeq(db, ENC(db), z, 0)!=0 ){ + zColl = z; + bMatch = 1; + } + if( zColl==0 && (pReTab = sqlite3FindTable(db, z, zDb))!=0 ){ + bMatch = 1; + } + if( zColl==0 && (pReIndex = sqlite3FindIndex(db, z, zDb))!=0 ){ + bMatch = 1; } - sqlite3DbFree(db, zColl); } - iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); - if( iDb<0 ) return; - z = sqlite3NameFromToken(db, pObjName); - if( z==0 ) return; - zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; - pTab = sqlite3FindTable(db, z, zDb); - if( pTab ){ - reindexTable(pParse, pTab, 0); - sqlite3DbFree(db, z); - return; + if( bMatch ){ + int iDb; + HashElem *k; + Table *pTab; + Index *pIdx; + Db *pDb; + for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ + assert( pDb!=0 ); + if( iReDb>=0 && iReDb!=iDb ) continue; + for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + if( IsVirtual(pTab) ) continue; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( bAll + || pTab==pReTab + || pIdx==pReIndex + || (isExprIdx && pIdx->bHasExpr) + || (zColl!=0 && collationMatch(zColl,pIdx)) + ){ + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIdx, -1); + } + } /* End loop over indexes of pTab */ + } /* End loop over tables of iDb */ + } /* End loop over databases */ + }else{ + sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); } - pIndex = sqlite3FindIndex(db, z, zDb); sqlite3DbFree(db, z); - if( pIndex ){ - iDb = sqlite3SchemaToIndex(db, pIndex->pTable->pSchema); - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3RefillIndex(pParse, pIndex, -1); - return; - } - sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); + return; } #endif @@ -130801,7 +133314,7 @@ static int vtabIsReadOnly(Parse *pParse, Table *pTab){ ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS ** virtual tables if PRAGMA trusted_schema=ON. */ - if( pParse->pToplevel!=0 + if( (pParse->pToplevel!=0 || (pParse->prepFlags & SQLITE_PREPARE_FROM_DDL)) && pTab->u.vtab.p->eVtabRisk > ((pParse->db->flags & SQLITE_TrustedSchema)!=0) ){ @@ -131630,6 +134143,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( v = pParse->pVdbe; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ + int p3 = 0; assert( iIdxCur+i!=iDataCur || pPk==pIdx ); if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; if( pIdx==pPk ) continue; @@ -131637,9 +134151,12 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel, pPrior, r1); - sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, - pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); - sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */ + if( pIdx->bHasExpr && aRegIdx ){ + p3 = aRegIdx[i]; + } + sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, p3); + sqlite3VdbeChangeP4(v, -1, (const char*)pIdx, P4_INDEX); + sqlite3VdbeChangeP5(v, pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); pPrior = pIdx; } @@ -131878,13 +134395,17 @@ static void lengthFunc( case SQLITE_TEXT: { const unsigned char *z = sqlite3_value_text(argv[0]); const unsigned char *z0; - unsigned char c; if( z==0 ) return; z0 = z; - while( (c = *z)!=0 ){ - z++; - if( c>=0xc0 ){ - while( (*z & 0xc0)==0x80 ){ z++; z0++; } + while( 1 /*exit-by-break*/ ){ + /* vvvvvv---- See tag-20260418-01 */ + if( (u8)(z[0]-1)<(0x80-1) ){ + z++; + }else if( z[0]==0 ){ + break; + }else{ + z++; + while( (z[0]&0xc0)==0x80 ){ z++; z0++; } } } sqlite3_result_int(context, (int)(z-z0)); @@ -132064,7 +134585,6 @@ static void printfFunc( PrintfArguments x; StrAccum str; const char *zFormat; - int n; sqlite3 *db = sqlite3_context_db_handle(context); if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ @@ -132074,9 +134594,7 @@ static void printfFunc( sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); str.printfFlags = SQLITE_PRINTF_SQLFUNC; sqlite3_str_appendf(&str, zFormat, &x); - n = str.nChar; - sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, - SQLITE_DYNAMIC); + sqlite3_result_str(context, &str, SQLITE_XFER); } } @@ -132125,7 +134643,7 @@ static void substrFunc( 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]; + p2 = LARGEST_INT64; } if( p1==0 ){ #ifdef SQLITE_SUBSTR_COMPATIBILITY @@ -132163,12 +134681,25 @@ static void substrFunc( } assert( p1>=0 && p2>=0 ); if( p0type!=SQLITE_BLOB ){ - while( *z && p1 ){ - SQLITE_SKIP_UTF8(z); - p1--; + for( ; p1>0; p1--){ + /* vvvvvv---- See tag-20260418-01 */ + if( (u8)(z[0]-1)<(0x80-1) ){ + z++; + }else if( z[0]==0 ){ + break; + }else{ + do{ z++; }while( (z[0]&0xc0)==0x80 ); + } } - for(z2=z; *z2 && p2; p2--){ - SQLITE_SKIP_UTF8(z2); + for(z2=z; p2>0; p2--){ + /* vvvvvv---- See tag-20260418-01 */ + if( (u8)(z2[0]-1)<(0x80-1) ){ + z2++; + }else if( z2[0]==0 ){ + break; + }else{ + do{ z2++; }while( (z2[0]&0xc0)==0x80 ); + } } sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, SQLITE_UTF8); @@ -132214,7 +134745,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ sqlite3_result_error_nomem(context); return; } - sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); + sqlite3AtoF(zBuf, &r); sqlite3_free(zBuf); } sqlite3_result_double(context, r); @@ -132846,18 +135377,11 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue, int switch( sqlite3_value_type(pValue) ){ case SQLITE_FLOAT: { - double r1, r2; - const char *zVal; - r1 = sqlite3_value_double(pValue); - sqlite3_str_appendf(pStr, "%!0.15g", r1); - zVal = sqlite3_str_value(pStr); - if( zVal ){ - sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8); - if( r1!=r2 ){ - sqlite3_str_reset(pStr); - sqlite3_str_appendf(pStr, "%!0.20e", r1); - } - } + /* ,--- Show infinity as 9.0e+999 + ** | + ** | ,--- 17 precision guarantees round-trip + ** v v */ + sqlite3_str_appendf(pStr, "%!0.17g", sqlite3_value_double(pValue)); break; } case SQLITE_INTEGER: { @@ -132949,7 +135473,7 @@ static void unistrFunc( } i = j = 0; while( iaLimit[SQLITE_LIMIT_LENGTH]); 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 ){ - sqlite3_result_null(context); - sqlite3_result_error_code(context, str.accError); - } + sqlite3_result_str(context, &str, SQLITE_XFER); } /* @@ -133079,7 +135598,7 @@ static void charFunc( } \ } *zOut = 0; - sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); + sqlite3_result_text64(context, (char*)z, zOut-z,sqlite3_free,SQLITE_UTF8_ZT); } /* @@ -133108,7 +135627,7 @@ static void hexFunc( } *z = 0; sqlite3_result_text64(context, zHex, (u64)(z-zHex), - sqlite3_free, SQLITE_UTF8); + sqlite3_free, SQLITE_UTF8_ZT); } } @@ -133242,7 +135761,7 @@ static void replaceFunc( int nRep; /* Size of zRep */ i64 nOut; /* Maximum size of zOut */ int loopLimit; /* Last zStr[] that might match zPattern[] */ - int i, j; /* Loop counters */ + i64 i, j; /* Loop counters */ unsigned cntExpand; /* Number zOut expansions */ sqlite3 *db = sqlite3_context_db_handle(context); @@ -133446,7 +135965,7 @@ static void concatFuncCore( } z[j] = 0; assert( j<=n ); - sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8); + sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8_ZT); } /* @@ -133563,6 +136082,21 @@ static void soundexFunc( } #endif /* SQLITE_SOUNDEX */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_BUILTIN_OOM_FUNCTION) +/* +** This SQL function just invokes sqlite3OomFault() and then returns +** NULL. Used for testing only. +*/ +static void oomFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3OomFault(db); +} +#endif /* SQLITE_DEBUG || SQLITE_BUILTIN_OOM_FUNCTION */ + #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** A function that loads a shared-library extension then returns NULL. @@ -133721,11 +136255,16 @@ static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ assert( p->cnt>0 ); p->cnt--; if( !p->approx ){ - if( sqlite3SubInt64(&p->iSum, sqlite3_value_int64(argv[0])) ){ - p->ovrfl = 1; - p->approx = 1; + i64 x = p->iSum; + if( sqlite3SubInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ + p->iSum = x; + return; } - }else if( type==SQLITE_INTEGER ){ + p->ovrfl = 1; + p->approx = 1; + kahanBabuskaNeumaierInit(p, p->iSum); + } + if( type==SQLITE_INTEGER ){ i64 iVal = sqlite3_value_int64(argv[0]); if( iVal!=SMALLEST_INT64 ){ kahanBabuskaNeumaierStepInt64(p, -iVal); @@ -134050,7 +136589,7 @@ static void groupConcatFinalize(sqlite3_context *context){ GroupConcatCtx *pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); if( pGCC ){ - sqlite3ResultStrAccum(context, &pGCC->str); + sqlite3_result_str(context, &pGCC->str, SQLITE_XFER); #ifndef SQLITE_OMIT_WINDOWFUNC sqlite3_free(pGCC->pnSepLengths); #endif @@ -134060,18 +136599,8 @@ static void groupConcatFinalize(sqlite3_context *context){ static void groupConcatValue(sqlite3_context *context){ GroupConcatCtx *pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); - if( pGCC ){ - StrAccum *pAccum = &pGCC->str; - if( pAccum->accError==SQLITE_TOOBIG ){ - sqlite3_result_error_toobig(context); - }else if( pAccum->accError==SQLITE_NOMEM ){ - sqlite3_result_error_nomem(context); - }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){ - sqlite3_result_text(context, "", 1, SQLITE_STATIC); - }else{ - const char *zText = sqlite3_str_value(pAccum); - sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); - } + if( pGCC && pGCC->nAccum>0 ){ + sqlite3_result_str(context, &pGCC->str, SQLITE_COPY); } } #else @@ -134112,6 +136641,8 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0); + assert( pDef!=0 ); /* The sqlite3CreateFunc() call above cannot fail + ** because the "like" SQL-function already exists */ pDef->funcFlags |= flags; pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE; } @@ -134689,54 +137220,105 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ ** (1) To avoid a dependency on qsort() ** (2) To avoid the function call to the comparison routine for each ** comparison. +** +** If parameter iReq is non-negative, then the caller will only access +** elements a[iReq] and a[iReq+1] (if it exists) of the sorted array and +** so it is not necessary to position any other elements. Or if iReq is +** negative, then the final array must be fully sorted. */ -static void percentSort(double *a, unsigned int n){ - int iLt; /* Entries before a[iLt] are less than rPivot */ - int iGt; /* Entries at or after a[iGt] are greater than rPivot */ +static void percentSort( + double *a, /* Array to sort */ + unsigned int n, /* Number of elements in array a[] */ + int iReq /* Element caller cares about (or -ve) */ +){ + int iLt; /* Entries before a[iLt] are less than or equal to rPivot */ + int iGt; /* Entries a[iGt] and after are greater or equal to rPivot */ int i; /* Loop counter */ double rPivot; /* The pivot value */ assert( n>=2 ); - if( a[0]>a[n-1] ){ - SWAP_DOUBLE(a[0],a[n-1]) - } - if( n==2 ) return; - iGt = n-1; - i = n/2; - if( a[0]>a[i] ){ - SWAP_DOUBLE(a[0],a[i]) - }else if( a[i]>a[iGt] ){ - SWAP_DOUBLE(a[i],a[iGt]) - } - if( n==3 ) return; - rPivot = a[i]; - iLt = i = 1; do{ - if( a[i]iLt ) SWAP_DOUBLE(a[i],a[iLt]) - iLt++; - i++; - }else if( a[i]>rPivot ){ - do{ - iGt--; - }while( iGt>i && a[iGt]>rPivot ); + /* Put the first, middle, and last elements in sorted order. + ** After doing so, return immediately if the array contains + ** three or fewer elements as there is nothing more to do. + */ + if( a[0]>a[n-1] ){ + SWAP_DOUBLE(a[0],a[n-1]) + } + if( n==2 ) return; + iGt = n-1; + i = n/2; + if( a[0]>a[i] ){ + SWAP_DOUBLE(a[0],a[i]) + }else if( a[i]>a[iGt] ){ SWAP_DOUBLE(a[i],a[iGt]) - }else{ - i++; } - }while( i=2 ) percentSort(a, iLt); - if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); + if( n==3 ) return; -/* Uncomment for testing */ -#if 0 - for(i=0; iiLt ) SWAP_DOUBLE(a[i],a[iLt]) + iLt++; + i++; + }else if( a[i]>rPivot ){ + do{ + iGt--; + }while( iGt>i && a[iGt]>rPivot ); + SWAP_DOUBLE(a[i],a[iGt]) + }else{ + i++; + } + }while( i0 && iLtiLt+1 ); + assert( a[iLt]==rPivot ); + assert( a[iLt-1]<=rPivot ); + assert( a[iGt]>=rPivot ); + assert( a[iLt+1]>=rPivot ); + + if( iReq>=0 ){ + /* In this case, the only elements that the caller requires sorted into + ** the correct positions are elements a[iReq] and a[iReq+1]. At this + ** point we know that element a[iLt] is in the correct position and + ** all elements smaller than a[iLt] are in the left-hand partition. + ** So if (iReq=iLt), then elements iReq and iReq+1 are either in the + ** right partition or the equal partition (elements for which + ** iLt<=iElem(int)(n/2) ){ + if( n-iGt>=2 ) percentSort(a+iGt, n-iGt, -1); + n = iLt; + }else{ + if( iLt>=2 ) percentSort(a, iLt, -1); + a += iGt; + n -= iGt; + } + } + }while( n>=2 ); } - /* ** The "inverse" function for percentile(Y,P) is called to remove a ** row that was previously inserted by "step". @@ -134769,7 +137351,7 @@ static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){ } if( p->bSorted==0 ){ assert( p->nUsed>1 ); - percentSort(p->a, p->nUsed); + percentSort(p->a, p->nUsed, -1); p->bSorted = 1; } p->bKeepSorted = 1; @@ -134798,13 +137380,17 @@ static void percentCompute(sqlite3_context *pCtx, int bIsFinal){ if( p==0 ) return; if( p->a==0 ) return; if( p->nUsed ){ + ix = p->rPct*(p->nUsed-1); + i1 = (unsigned)ix; if( p->bSorted==0 ){ + /* In cases where bIsFinal is non-zero, setting Percentile.bSorted + ** after the percentSort() call here is not technically correct, as + ** the array is not fully sorted. But in this case the object will be + ** freed below anyway, so it doesn't matter. */ assert( p->nUsed>1 ); - percentSort(p->a, p->nUsed); + percentSort(p->a, p->nUsed, (bIsFinal ? (int)i1 : -1)); p->bSorted = 1; } - ix = p->rPct*(p->nUsed-1); - i1 = (unsigned)ix; if( settings & 1 ){ vx = p->a[i1]; }else{ @@ -134859,7 +137445,7 @@ static void filestatFunc( assert( pPager!=0 ); fd = sqlite3PagerFile(pPager); pStr = sqlite3_str_new(db); - if( pStr==0 ){ + if( sqlite3_str_errcode(pStr) ){ sqlite3_result_error_nomem(context); }else{ sqlite3_str_append(pStr, "{\"db\":", 6); @@ -134872,8 +137458,7 @@ static void filestatFunc( if( rc ) sqlite3_str_append(pStr, "null", 4); } sqlite3_str_append(pStr, "}", 1); - sqlite3_result_text(context, sqlite3_str_finish(pStr), -1, - sqlite3_free); + sqlite3_result_str(context, pStr, SQLITE_FINISH); } sqlite3BtreeLeave(pBtree); }else{ @@ -134882,6 +137467,48 @@ static void filestatFunc( } #endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) +/* +** Implementation of sqlite_walstat(SCHEMA). +** +** Return JSON text that describes the current state of a WAL file. +** This function is for debugging and analysis only. It is not part +** of production builds. This function is not part of the SQLite API +** and is likely to change or be removed in future versions of SQLite. +*/ +static void walstatFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zDbName; + sqlite3_str *pStr; + Btree *pBtree; + + zDbName = (const char*)sqlite3_value_text(argv[0]); + pBtree = sqlite3DbNameToBtree(db, zDbName); + if( pBtree ){ + Pager *pPager; + sqlite3BtreeEnter(pBtree); + pPager = sqlite3BtreePager(pBtree); + assert( pPager!=0 ); + pStr = sqlite3_str_new(db); + if( sqlite3_str_errcode(pStr) ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_str_append(pStr, "{", 1); + sqlite3PagerWalStat(pPager, pStr); + sqlite3_str_append(pStr, "}", 1); + sqlite3_result_str(context, pStr, SQLITE_FINISH); + } + sqlite3BtreeLeave(pBtree); + }else{ + sqlite3_result_text(context, "{}", 2, SQLITE_STATIC); + } +} +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_WALSTAT */ + #ifdef SQLITE_DEBUG /* ** Implementation of fpdecode(x,y,z) function. @@ -134962,7 +137589,7 @@ static void parseuriFunc( flgs = (unsigned int)sqlite3_value_int(argv[1]); rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr); pResult = sqlite3_str_new(0); - if( pResult ){ + if( !sqlite3_str_errcode(pResult) ){ int i; sqlite3_str_appendf(pResult, "rc=%d", rc); sqlite3_str_appendf(pResult, ", flags=0x%x", flgs); @@ -134989,8 +137616,8 @@ static void parseuriFunc( } } } - sqlite3_result_text(ctx, sqlite3_str_finish(pResult), -1, sqlite3_free); } + sqlite3_result_str(ctx, pResult, SQLITE_FINISH); sqlite3_free_filename(zFile); sqlite3_free(zErr); } @@ -135042,6 +137669,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT) FUNCTION(sqlite_filestat, 1, 0, 0, filestatFunc ), + FUNCTION(sqlite_walstat, 1, 0, 0, walstatFunc ), #endif FUNCTION(ltrim, 1, 1, 0, trimFunc ), FUNCTION(ltrim, 2, 1, 0, trimFunc ), @@ -135070,6 +137698,9 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), FUNCTION(parseuri, -1, 0, 0, parseuriFunc ), #endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_BUILTIN_OOM_FUNCTION) + FUNCTION(oom, -1, 0, 0, oomFunc ), +#endif #ifndef SQLITE_OMIT_FLOATING_POINT FUNCTION(round, 1, 0, 0, roundFunc ), FUNCTION(round, 2, 0, 0, roundFunc ), @@ -135087,7 +137718,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(nullif, 2, 0, 1, nullifFunc ), DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ), DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), - FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), + SFUNCTION(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 ), @@ -135900,6 +138531,7 @@ SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ if( p ){ TriggerStep *pStep = p->step_list; + sqlite3SrcListDelete(dbMem, pStep->pSrc); sqlite3ExprDelete(dbMem, pStep->pWhere); sqlite3ExprListDelete(dbMem, pStep->pExprList); sqlite3SelectDelete(dbMem, pStep->pSelect); @@ -136119,6 +138751,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( if( !IsOrdinaryTable(pTab) ) return; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=00 && iDbnDb ); zDb = db->aDb[iDb].zDbSName; /* Loop through all the foreign key constraints for which pTab is the @@ -136516,7 +139149,7 @@ static Trigger *fkActionTrigger( testcase( pCol->colFlags & COLFLAG_STORED ); pDflt = 0; }else{ - pDflt = sqlite3ColumnExpr(pFKey->pFrom, pCol); + pDflt = sqlite3ColumnExprAuth(pFKey->pFrom, pCol, pParse); } if( pDflt ){ pNew = sqlite3ExprDup(db, pDflt, 0); @@ -136536,7 +139169,6 @@ static Trigger *fkActionTrigger( nFrom = sqlite3Strlen30(zFrom); if( action==OE_Restrict ){ - int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); SrcList *pSrc; Expr *pRaise; @@ -136547,10 +139179,10 @@ static Trigger *fkActionTrigger( } pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ - assert( pSrc->nSrc==1 ); - pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); - assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 ); - pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + SrcItem *pItem = &pSrc->a[0]; + pItem->zName = sqlite3DbStrDup(db, zFrom); + pItem->fg.fixedSchema = 1; + pItem->u4.pSchema = pTab->pSchema; } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), @@ -136566,14 +139198,17 @@ static Trigger *fkActionTrigger( pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ - sizeof(TriggerStep) + /* Single step in trigger program */ - nFrom + 1 /* Space for pStep->zTarget */ + sizeof(TriggerStep) /* Single step in trigger program */ ); if( pTrigger ){ pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; - pStep->zTarget = (char *)&pStep[1]; - memcpy((char *)pStep->zTarget, zFrom, nFrom); - + pStep->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pStep->pSrc ){ + SrcItem *pItem = &pStep->pSrc->a[0]; + pItem->zName = sqlite3DbStrNDup(db, zFrom, nFrom); + pItem->u4.pSchema = pTab->pSchema; + pItem->fg.fixedSchema = 1; + } pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); @@ -137132,6 +139767,9 @@ static int autoIncBegin( return 0; } + if( pToplevel->usesAinc==0 ){ + pToplevel->pAinc = 0; + } pInfo = pToplevel->pAinc; while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } if( pInfo==0 ){ @@ -137141,6 +139779,7 @@ static int autoIncBegin( if( pParse->db->mallocFailed ) return 0; pInfo->pNext = pToplevel->pAinc; pToplevel->pAinc = pInfo; + pToplevel->usesAinc = 1; pInfo->pTab = pTab; pInfo->iDb = iDb; pToplevel->nMem++; /* Register to hold name of table */ @@ -137169,6 +139808,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ assert( sqlite3IsToplevel(pParse) ); assert( v ); /* We failed long ago if this is not so */ + assert( pParse->usesAinc ); for(p = pParse->pAinc; p; p = p->pNext){ static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList autoInc[] = { @@ -137236,6 +139876,7 @@ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ sqlite3 *db = pParse->db; assert( v ); + assert( pParse->usesAinc ); for(p = pParse->pAinc; p; p = p->pNext){ static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList autoIncEnd[] = { @@ -137268,7 +139909,7 @@ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ } } SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ - if( pParse->pAinc ) autoIncrementEnd(pParse); + if( pParse->usesAinc ) autoIncrementEnd(pParse); } #else /* @@ -137295,25 +139936,13 @@ SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ } } -/* -** Return true if all expressions in the expression-list passed as the -** only argument are constant. -*/ -static int exprListIsConstant(Parse *pParse, ExprList *pRow){ - int ii; - for(ii=0; iinExpr; ii++){ - if( 0==sqlite3ExprIsConstant(pParse, pRow->a[ii].pExpr) ) return 0; - } - return 1; -} - /* ** Return true if all expressions in the expression-list passed as the ** only argument are both constant and have no affinity. */ static int exprListIsNoAffinity(Parse *pParse, ExprList *pRow){ int ii; - if( exprListIsConstant(pParse,pRow)==0 ) return 0; + if( sqlite3ExprListIsConstant(pParse, pRow, 0)==0 ) return 0; for(ii=0; iinExpr; ii++){ Expr *pExpr = pRow->a[ii].pExpr; assert( pExpr->op!=TK_RAISE ); @@ -137379,7 +140008,7 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList if( pParse->bHasWith /* condition (a) above */ || pParse->db->init.busy /* condition (b) above */ - || exprListIsConstant(pParse,pRow)==0 /* condition (c) above */ + || sqlite3ExprListIsConstant(pParse, pRow, 1)==0 /* condition (c) above */ || (pLeft->pSrc->nSrc==0 && exprListIsNoAffinity(pParse,pLeft->pEList)==0) /* condition (d) above */ || IN_SPECIAL_PARSE @@ -138092,7 +140721,7 @@ SQLITE_PRIVATE void sqlite3Insert( /* Hidden columns that are not explicitly named in the INSERT ** get their default value */ sqlite3ExprCodeFactorable(pParse, - sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + sqlite3ColumnExprAuth(pTab, &pTab->aCol[i], pParse), iRegStore); continue; } @@ -138104,7 +140733,7 @@ SQLITE_PRIVATE void sqlite3Insert( /* A column not named in the insert column list gets its ** default value */ sqlite3ExprCodeFactorable(pParse, - sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + sqlite3ColumnExprAuth(pTab, &pTab->aCol[i], pParse), iRegStore); continue; } @@ -138112,7 +140741,7 @@ SQLITE_PRIVATE void sqlite3Insert( }else if( nColumn==0 ){ /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */ sqlite3ExprCodeFactorable(pParse, - sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + sqlite3ColumnExprAuth(pTab, &pTab->aCol[i], pParse), iRegStore); continue; }else{ @@ -138163,6 +140792,7 @@ SQLITE_PRIVATE void sqlite3Insert( sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); + sqlite3MayAbort(pParse); } /* Copy the new data already generated. */ @@ -138231,6 +140861,7 @@ SQLITE_PRIVATE void sqlite3Insert( sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v); } sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v); + sqlite3MayAbort(pParse); } }else if( IsVirtual(pTab) || withoutRowid ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); @@ -138710,7 +141341,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( assert( (pCol->colFlags & COLFLAG_GENERATED)==0 ); nSeenReplace++; sqlite3ExprCodeCopy(pParse, - sqlite3ColumnExpr(pTab, pCol), iReg); + sqlite3ColumnExprAuth(pTab, pCol, pParse), iReg); sqlite3VdbeJumpHere(v, addr1); break; } @@ -138923,6 +141554,22 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( pTrigger = 0; regTrigCnt = sqlite3FkRequired(pParse, pTab, 0, 0); } + if( regTrigCnt ){ + /* At this point regTrigCnt is non-zero if there are DELETE triggers + ** or FK triggers. But we only care about these things if there is + ** a chance that a row will be deleted by an ON CONFLICT REPLACE + ** constraint. So zero regTrigCnt if no such constraint can be found. */ + if( overrideError!=OE_Replace ){ + if( overrideError!=OE_Default ){ + regTrigCnt = 0; + }else if( pkChng==0 || pPk || pTab->keyConf!=OE_Replace ){ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->onError==OE_Replace ) break; + } + if( pIdx==0 ) regTrigCnt = 0; + } + } + } if( regTrigCnt ){ /* Replace triggers might exist. Allocate the counter and ** initialize it to zero. */ @@ -138974,9 +141621,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( onError==OE_Replace /* IPK rule is REPLACE */ && onError!=overrideError /* Rules for other constraints are different */ && pTab->pIndex /* There exist other constraints */ - && !upsertIpkDelay /* IPK check already deferred by UPSERT */ ){ - ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; + if( upsertIpkDelay ){ + ipkTop = upsertIpkDelay + 1; + upsertIpkDelay = 0; + }else{ + ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; + } VdbeComment((v, "defer IPK REPLACE until last")); } @@ -139070,11 +141721,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } } sqlite3VdbeResolveLabel(v, addrRowidOk); - if( pUpsert && pUpsertClause!=pUpsert ){ - upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto); - }else if( ipkTop ){ + if( ipkTop ){ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, ipkTop-1); + }else if( pUpsert && pUpsertClause!=pUpsert ){ + upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto); } } @@ -139094,6 +141745,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int iThisCur; /* Cursor for this UNIQUE index */ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ int addrConflictCk; /* First opcode in the conflict check logic */ + int nConflictCk; /* Number of opcodes in conflict check logic */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ if( pUpsert ){ @@ -139270,6 +141922,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } } + nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk; + assert( nConflictCk>0 || db->mallocFailed ); + testcase( nConflictCk<=0 ); + testcase( nConflictCk>1 ); + /* Generate code that executes if the new index entry is not unique */ assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail || onError==OE_Ignore || onError==OE_Replace || onError==OE_Update ); @@ -139295,13 +141952,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( break; } default: { - int nConflictCk; /* Number of opcodes in conflict check logic */ - assert( onError==OE_Replace ); - nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk; - assert( nConflictCk>0 || db->mallocFailed ); - testcase( nConflictCk<=0 ); - testcase( nConflictCk>1 ); if( regTrigCnt ){ sqlite3MultiWrite(pParse); nReplaceTrig++; @@ -139315,57 +141966,57 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( pTrigger && isUpdate ){ sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur); } - if( regTrigCnt ){ - int addrBypass; /* Jump destination to bypass recheck logic */ + seenReplace = 1; + break; + } + } + if( regTrigCnt ){ + int addrBypass; /* Jump destination to bypass recheck logic */ - sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ - addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); /* Bypass recheck */ - VdbeComment((v, "bypass recheck")); - - /* Here we insert code that will be invoked after all constraint - ** checks have run, if and only if one or more replace triggers - ** fired. */ - sqlite3VdbeResolveLabel(v, lblRecheckOk); - lblRecheckOk = sqlite3VdbeMakeLabel(pParse); - if( pIdx->pPartIdxWhere ){ - /* Bypass the recheck if this partial index is not defined - ** for the current row */ - sqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk); - VdbeCoverage(v); - } - /* Copy the constraint check code from above, except change - ** the constraint-ok jump destination to be the address of - ** the next retest block */ - while( nConflictCk>0 ){ - VdbeOp x; /* Conflict check opcode to copy */ - /* The sqlite3VdbeAddOp4() call might reallocate the opcode array. - ** Hence, make a complete copy of the opcode, rather than using - ** a pointer to the opcode. */ - x = *sqlite3VdbeGetOp(v, addrConflictCk); - if( x.opcode!=OP_IdxRowid ){ - int p2; /* New P2 value for copied conflict check opcode */ - const char *zP4; - if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){ - p2 = lblRecheckOk; - }else{ - p2 = x.p2; - } - zP4 = x.p4type==P4_INT32 ? SQLITE_INT_TO_PTR(x.p4.i) : x.p4.z; - sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, zP4, x.p4type); - sqlite3VdbeChangeP5(v, x.p5); - VdbeCoverageIf(v, p2!=x.p2); - } - nConflictCk--; - addrConflictCk++; - } - /* If the retest fails, issue an abort */ - sqlite3UniqueConstraint(pParse, OE_Abort, pIdx); + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); /* Bypass recheck */ + VdbeComment((v, "bypass recheck")); - sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */ + /* Here we insert code that will be invoked after all constraint + ** checks have run, if and only if one or more replace triggers + ** fired. */ + sqlite3VdbeResolveLabel(v, lblRecheckOk); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); + if( pIdx->pPartIdxWhere ){ + /* Bypass the recheck if this partial index is not defined + ** for the current row */ + sqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk); + VdbeCoverage(v); + } + /* Copy the constraint check code from above, except change + ** the constraint-ok jump destination to be the address of + ** the next retest block */ + while( nConflictCk>0 ){ + VdbeOp x; /* Conflict check opcode to copy */ + /* The sqlite3VdbeAddOp4() call might reallocate the opcode array. + ** Hence, make a complete copy of the opcode, rather than using + ** a pointer to the opcode. */ + x = *sqlite3VdbeGetOp(v, addrConflictCk); + if( x.opcode!=OP_IdxRowid || isUpdate ){ + int p2; /* New P2 value for copied conflict check opcode */ + const char *zP4; + if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){ + p2 = lblRecheckOk; + }else{ + p2 = x.p2; + } + zP4 = x.p4type==P4_INT32 ? SQLITE_INT_TO_PTR(x.p4.i) : x.p4.z; + sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, zP4, x.p4type); + sqlite3VdbeChangeP5(v, x.p5); + VdbeCoverageIf(v, p2!=x.p2); } - seenReplace = 1; - break; + nConflictCk--; + addrConflictCk++; } + /* If the retest fails, issue an abort */ + sqlite3UniqueConstraint(pParse, OE_Abort, pIdx); + + sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */ } sqlite3VdbeResolveLabel(v, addrUniqueOk); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); @@ -139404,8 +142055,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( }else{ sqlite3VdbeGoto(v, addrRecheck); } - sqlite3VdbeResolveLabel(v, lblRecheckOk); } + if( regTrigCnt ) sqlite3VdbeResolveLabel(v, lblRecheckOk); /* Generate the table record */ if( HasRowid(pTab) ){ @@ -139508,7 +142159,10 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( || pIdx->pNext==0 || pIdx->pNext->onError==OE_Replace ); if( aRegIdx[i]==0 ) continue; - if( pIdx->pPartIdxWhere ){ + if( pIdx->pPartIdxWhere || (update_flags && pIdx->bHasExpr) ){ + /* If this is a partial index, or an UPDATE of an index on an + ** expression, then the record register may be set to NULL to indicate + ** that no record should be inserted into this index. */ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); } @@ -139683,6 +142337,44 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ return 1; } +/* +** Examine an expression node and abort if it references the ROWID. +** This is a Walker callback used by xferCompatibleCheck() +*/ +static int xferCheckRowid(Walker *pWalk, Expr *pExpr){ + if( pExpr->op==TK_COLUMN && pExpr->iColumn<0 ){ + pWalk->eCode = 1; + return WRC_Abort; + }else{ + return WRC_Continue; + } +} + +/* +** Analyze CHECK constraints on the source and destination tables and +** return true if those CHECK constraints are compatible with the +** xfer-optimization. +** +** * The pDest and pSrc tables must have identical CHECK constraints. +** +** * If the destination table, pDest, does not have an +** INTEGER PRIMARY KEY column, then no CHECK constraint may +** referenced the ROWID. (See forum post 2026-05-11T13:15:57Z) +*/ +static int xferCompatibleCheck(Table *pDest, Table *pSrc){ + if( sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ + return 0; + } + if( pDest->iPKey<0 ){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = xferCheckRowid; + sqlite3WalkExprList(&w,pDest->pCheck); + if( w.eCode ) return 0; + } + return 1; +} + /* ** Attempt the transfer optimization on INSERTs of the form ** @@ -139809,8 +142501,19 @@ static int xferOptimization( if( pDest->iPKey!=pSrc->iPKey ){ return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ } - if( (pDest->tabFlags & TF_Strict)!=0 && (pSrc->tabFlags & TF_Strict)==0 ){ - return 0; /* Cannot feed from a non-strict into a strict table */ + if( (pDest->tabFlags & TF_Strict)!=0 ){ + if( (pSrc->tabFlags & TF_Strict)==0 ){ + return 0; /* Cannot feed from a non-strict into a strict table */ + } + for(i=0; inCol; i++){ + unsigned eDestType = pDest->aCol[i].eCType; + unsigned eSrcType = pSrc->aCol[i].eCType; + if( eDestType==COLTYPE_ANY ) continue; + if( eDestType==eSrcType ) continue; + if( eDestType==COLTYPE_INT && eSrcType==COLTYPE_INTEGER ) continue; + if( eDestType==COLTYPE_INTEGER && eSrcType==COLTYPE_INT ) continue; + return 0; /* Incompatible types in source and destination */ + } } for(i=0; inCol; i++){ Column *pDestCol = &pDest->aCol[i]; @@ -139904,7 +142607,7 @@ static int xferOptimization( #ifndef SQLITE_OMIT_CHECK if( pDest->pCheck && (db->mDbFlags & DBFLAG_Vacuum)==0 - && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) + && !xferCompatibleCheck(pDest,pSrc) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } @@ -139925,6 +142628,18 @@ static int xferOptimization( if( (db->flags & SQLITE_CountRows)!=0 ){ return 0; /* xfer opt does not play well with PRAGMA count_changes */ } +#ifndef SQLITE_OMIT_AUTHORIZATION + if( db->xAuth ){ + int iDb = sqlite3SchemaToIndex(db, pSrc->pSchema); + if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 0; + for(i=0; inCol; i++){ + Column *pSrcCol = &pSrc->aCol[i]; + if( sqlite3AuthReadCol(pParse, pSrc->zName, pSrcCol->zCnName, iDb) ){ + return 0; + } + } + } +#endif /* If we get this far, it means that the xfer optimization is at ** least a possibility, though it might only work if the destination @@ -140368,7 +143083,7 @@ struct sqlite3_api_routines { const char * (*libversion)(void); int (*libversion_number)(void); void *(*malloc)(int); - char * (*mprintf)(const char*,...); + char *(SQLITE_CDECL*mprintf)(const char*,...); int (*open)(const char*,sqlite3**); int (*open16)(const void*,sqlite3**); int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); @@ -140389,11 +143104,11 @@ struct sqlite3_api_routines { void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); void (*result_value)(sqlite3_context*,sqlite3_value*); - void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + void *(*rollback_hook)(sqlite3*,void(*)(void*),void*); int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, const char*,const char*),void*); void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); - char * (*xsnprintf)(int,char*,const char*,...); + char *(SQLITE_CDECL*xsnprintf)(int,char*,const char*,...); int (*step)(sqlite3_stmt*); int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, char const**,char const**,int*,int*,int*); @@ -140457,7 +143172,7 @@ struct sqlite3_api_routines { int (*xthreadsafe)(void); void (*result_zeroblob)(sqlite3_context*,int); void (*result_error_code)(sqlite3_context*,int); - int (*test_control)(int, ...); + int (SQLITE_CDECL*test_control)(int, ...); void (*randomness)(int,void*); sqlite3 *(*context_db_handle)(sqlite3_context*); int (*extended_result_codes)(sqlite3*,int); @@ -140477,11 +143192,11 @@ struct sqlite3_api_routines { void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*), void(*xDestroy)(void*)); - int (*db_config)(sqlite3*,int,...); + int (SQLITE_CDECL*db_config)(sqlite3*,int,...); sqlite3_mutex *(*db_mutex)(sqlite3*); int (*db_status)(sqlite3*,int,int*,int*,int); int (*extended_errcode)(sqlite3*); - void (*log)(int,const char*,...); + void (SQLITE_CDECL*log)(int,const char*,...); sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); const char *(*sourceid)(void); int (*stmt_status)(sqlite3_stmt*,int,int); @@ -140491,7 +143206,7 @@ struct sqlite3_api_routines { int (*wal_checkpoint)(sqlite3*,const char*); void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); - int (*vtab_config)(sqlite3*,int op,...); + int (SQLITE_CDECL*vtab_config)(sqlite3*,int op,...); int (*vtab_on_conflict)(sqlite3*); /* Version 3.7.16 and later */ int (*close_v2)(sqlite3*); @@ -140560,7 +143275,7 @@ struct sqlite3_api_routines { int (*keyword_check)(const char*,int); sqlite3_str *(*str_new)(sqlite3*); char *(*str_finish)(sqlite3_str*); - void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); + void (SQLITE_CDECL*str_appendf)(sqlite3_str*, const char *zFormat, ...); void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); void (*str_append)(sqlite3_str*, const char *zIn, int N); void (*str_appendall)(sqlite3_str*, const char *zIn); @@ -140630,7 +143345,14 @@ struct sqlite3_api_routines { /* Version 3.51.0 and later */ int (*set_errmsg)(sqlite3*,int,const char*); int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int); - + /* Version 3.52.0 and later */ + void (*str_truncate)(sqlite3_str*,int); + void (*str_free)(sqlite3_str*); + int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*)); + int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*); + /* Version 3.54.0 and later */ + sqlite3_int64 (*incomplete)(const char*); + void (*result_str)(sqlite3_context*,sqlite3_str*,int); }; /* @@ -140969,6 +143691,14 @@ typedef int (*sqlite3_loadext_entry)( /* Version 3.51.0 and later */ #define sqlite3_set_errmsg sqlite3_api->set_errmsg #define sqlite3_db_status64 sqlite3_api->db_status64 +/* Version 3.52.0 and later */ +#define sqlite3_str_truncate sqlite3_api->str_truncate +#define sqlite3_str_free sqlite3_api->str_free +#define sqlite3_carray_bind sqlite3_api->carray_bind +#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2 +/* Version 3.54.0 and later */ +#define sqlite3_incomplete sqlite3_api->incomplete +#define sqlite3_result_str sqlite3_api->result_str #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -141495,7 +144225,20 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_setlk_timeout, /* Version 3.51.0 and later */ sqlite3_set_errmsg, - sqlite3_db_status64 + sqlite3_db_status64, + /* Version 3.52.0 and later */ + sqlite3_str_truncate, + sqlite3_str_free, +#ifdef SQLITE_ENABLE_CARRAY + sqlite3_carray_bind, + sqlite3_carray_bind_v2, +#else + 0, + 0, +#endif + /* Version 3.54.0 and later */ + sqlite3_incomplete, + sqlite3_result_str }; /* True if x is the directory separator character @@ -141597,33 +144340,42 @@ static int sqlite3LoadExtension( ** entry point name "sqlite3_extension_init" was not found, then ** construct an entry point name "sqlite3_X_init" where the X is ** replaced by the lowercase value of every ASCII alphabetic - ** character in the filename after the last "/" upto the first ".", - ** and eliding the first three characters if they are "lib". + ** character in the filename after the last "/" up to the first ".", + ** and skipping the first three characters if they are "lib". ** Examples: ** ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init + ** + ** If that still finds no entry point, repeat a second time but this + ** time include both alphabetic and numeric characters up to the first + ** ".". Example: + ** + ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example5_init */ if( xInit==0 && zProc==0 ){ int iFile, iEntry, c; int ncFile = sqlite3Strlen30(zFile); + int cnt = 0; zAltEntry = sqlite3_malloc64(ncFile+30); if( zAltEntry==0 ){ sqlite3OsDlClose(pVfs, handle); return SQLITE_NOMEM_BKPT; } - memcpy(zAltEntry, "sqlite3_", 8); - for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){} - iFile++; - if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; - for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ - if( sqlite3Isalpha(c) ){ - zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; + do{ + memcpy(zAltEntry, "sqlite3_", 8); + for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){} + iFile++; + if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; + for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ + if( sqlite3Isalpha(c) || (cnt && sqlite3Isdigit(c)) ){ + zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; + } } - } - memcpy(zAltEntry+iEntry, "_init", 6); - zEntry = zAltEntry; - xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); + memcpy(zAltEntry+iEntry, "_init", 6); + zEntry = zAltEntry; + xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); + }while( xInit==0 && (++cnt)<2 ); } if( xInit==0 ){ if( pzErrMsg ){ @@ -142168,7 +144920,7 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CountRows }, #endif -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && defined(_WIN32) {/* zName: */ "data_store_directory", /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, /* ePragFlg: */ PragFlg_NoColumns1, @@ -142591,7 +145343,7 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 68 on by default, 78 total. */ +/* Number of pragmas: 67 on by default, 78 total. */ /************** End of pragma.h **********************************************/ /************** Continuing where we left off in pragma.c *********************/ @@ -142644,7 +145396,7 @@ static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ /* on no off false yes true extra full */ int i, n; if( sqlite3Isdigit(*z) ){ - return (u8)sqlite3Atoi(z); + return sqlite3Atoi(z)!=0; } n = sqlite3Strlen30(z); for(i=0; isafety_level = iLevel; pDb->bSyncSet = 1; @@ -144317,10 +147075,9 @@ SQLITE_PRIVATE void sqlite3Pragma( for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); /* Current table */ Index *pIdx; /* An index on pTab */ - int nIdx; /* Number of indexes on pTab */ if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue; if( HasRowid(pTab) ) cnt++; - for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ cnt++; } } if( cnt==0 ) continue; if( pObjTab ) cnt++; @@ -144500,8 +147257,8 @@ SQLITE_PRIVATE void sqlite3Pragma( }else{ if( pCol->iDflt ){ sqlite3_value *pDfltValue = 0; - sqlite3ValueFromExpr(db, sqlite3ColumnExpr(pTab,pCol), ENC(db), - pCol->affinity, &pDfltValue); + sqlite3ValueFromExpr(db, sqlite3ColumnExprAuth(pTab,pCol,pParse), + ENC(db), pCol->affinity, &pDfltValue); if( pDfltValue ){ p4 = sqlite3_value_type(pDfltValue); sqlite3ValueFree(pDfltValue); @@ -144633,8 +147390,20 @@ SQLITE_PRIVATE void sqlite3Pragma( pPrior = pIdx; sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */ /* Verify that an index entry exists for the current table row */ - jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, + sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, pIdx->nColumn); VdbeCoverage(v); + jmp2 = sqlite3VdbeAddOp3(v, OP_IFindKey, iIdxCur+j, ckUniq, r1); + VdbeCoverage(v); + sqlite3VdbeChangeP4(v, -1, (const char*)pIdx, P4_INDEX); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3MPrintf(db, "index %s stores an imprecise floating-point " + "value for row ", pIdx->zName), + P4_DYNAMIC); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + integrityCheckResultRow(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, ckUniq); + + sqlite3VdbeJumpHere(v, jmp2); sqlite3VdbeLoadString(v, 3, "row "); sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); sqlite3VdbeLoadString(v, 4, " missing from index "); @@ -144642,7 +147411,7 @@ SQLITE_PRIVATE void sqlite3Pragma( jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); jmp4 = integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeResolveLabel(v, ckUniq); /* The OP_IdxRowid opcode is an optimized version of OP_Column ** that extracts the rowid off the end of the index record. @@ -145203,9 +147972,10 @@ SQLITE_PRIVATE void sqlite3Pragma( ** disables the timeout. */ /*case PragTyp_BUSY_TIMEOUT*/ default: { + int n = 0; assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT ); - if( zRight ){ - sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); + if( zRight && sqlite3GetInt32(zRight,&n) ){ + sqlite3_busy_timeout(db, n); } returnSingleInt(v, db->busyTimeout); break; @@ -145695,7 +148465,8 @@ static void corruptSchema( static const char *azAlterType[] = { "rename", "drop column", - "add column" + "add column", + "drop constraint" }; *pData->pzErrMsg = sqlite3MPrintf(db, "error in %s %s after %s: %s", azObj[0], azObj[1], @@ -145771,6 +148542,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char } assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pSchema!=0 ); if( argv[3]==0 ){ corruptSchema(pData, argv, 0); }else if( argv[4] @@ -145789,6 +148561,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char int rc; u8 saved_iDb = db->init.iDb; sqlite3_stmt *pStmt; + const char *zEnd; TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ assert( db->init.busy ); @@ -145803,7 +148576,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char db->init.orphanTrigger = 0; db->init.azInit = (const char**)argv; pStmt = 0; - TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0); + TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, &zEnd); rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = saved_iDb; @@ -145819,6 +148592,8 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char corruptSchema(pData, argv, sqlite3_errmsg(db)); } } + }else if( zEnd[0] ){ + corruptSchema(pData, argv, 0); } db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */ sqlite3_finalize(pStmt); @@ -145846,6 +148621,16 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char } } } + if( pData->pzErrMsg[0]==0 ){ + Schema *pX = db->aDb[iDb].pSchema; + if( pX->tblHash.count + pX->idxHash.count + pX->trigHash.count + > (u32)db->aLimit[SQLITE_LIMIT_SCHEMA] + ){ + *pData->pzErrMsg = sqlite3MPrintf(db, "too many schema objects"); + pData->rc = SQLITE_ERROR; + return 1; + } + } return 0; } @@ -145877,7 +148662,13 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); - db->init.busy = 1; + db->init.busy = 1 + ((mFlags & INITFLAG_AlterAdd)!=0); + /* ^--- Any non-zero value for init.busy means that we are scanning + ** the sqlite_schema table to build the internal schema representation, + ** rather than running actual CREATE statements. init.busy==2 has the + ** additional meaning that the scan is happening as part of + ** ALTER TABLE ADD COLUMN, which is stricter in its enforcement of + ** function name resolution. */ /* Construct the in-memory representation schema tables (sqlite_schema or ** sqlite_temp_schema) by invoking the parser directly. The appropriate @@ -146236,7 +149027,7 @@ SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ assert( db->pParse==pParse ); assert( pParse->nested==0 ); #ifndef SQLITE_OMIT_SHARED_CACHE - if( pParse->aTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); + if( pParse->nTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); #endif while( pParse->pCleanup ){ ParseCleanup *pCleanup = pParse->pCleanup; @@ -146320,6 +149111,7 @@ SQLITE_PRIVATE void *sqlite3ParserAddCleanup( ** is generated by Lemon. */ SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){ + assert( db!=0 ); memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ); memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); assert( db->pParse!=pParse ); @@ -146719,7 +149511,7 @@ SQLITE_API int sqlite3_prepare16( const void **pzTail /* OUT: End of parsed string */ ){ int rc; - rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); + rc = sqlite3Prepare16(db,zSql,nBytes&~1,0,ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; } @@ -146731,7 +149523,7 @@ SQLITE_API int sqlite3_prepare16_v2( const void **pzTail /* OUT: End of parsed string */ ){ int rc; - rc = sqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail); + rc = sqlite3Prepare16(db,zSql,nBytes&~1,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; } @@ -146744,7 +149536,7 @@ SQLITE_API int sqlite3_prepare16_v3( const void **pzTail /* OUT: End of parsed string */ ){ int rc; - rc = sqlite3Prepare16(db,zSql,nBytes, + rc = sqlite3Prepare16(db,zSql,nBytes&~1, SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK), ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ @@ -146778,7 +149570,7 @@ SQLITE_API int sqlite3_prepare16_v3( */ typedef struct DistinctCtx DistinctCtx; struct DistinctCtx { - u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */ + u8 isTnct; /* 0: Not distinct. 1: DISTINCT 2: DISTINCT and ORDER BY */ u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ int tabTnct; /* Ephemeral table used for DISTINCT processing */ int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ @@ -146908,8 +149700,6 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( pNew->iLimit = 0; pNew->iOffset = 0; pNew->selId = ++pParse->nSelect; - pNew->addrOpenEphm[0] = -1; - pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); pNew->pSrc = pSrc; @@ -147277,6 +150067,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ int i, j; /* Loop counters */ SrcItem *pLeft; /* Left table being joined */ SrcItem *pRight; /* Right table being joined */ + int bSeenTFunc = 0; /* True if have seen table-valued function */ pSrc = p->pSrc; pLeft = &pSrc->a[0]; @@ -147418,6 +150209,21 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ pRight->fg.isOn = 1; p->selFlags |= SF_OnToWhere; } + + if( bSeenTFunc==0 ){ + bSeenTFunc = (pLeft->fg.isTabFunc && pLeft->u1.pFuncArg); + } + + /* We also need to call sqlite3SelectCheckOnClauses() to verify that + ** table-valued function arguments do not illegally refer to any tables to + ** their right. This test is required if either (a) there is a RIGHT JOIN + ** in the SrcList, or (b) there is a LEFT JOIN to the right of a + ** table-valued function. */ + if( (pRight->fg.isTabFunc && joinType==EP_OuterON && pRight->u1.pFuncArg) + || (bSeenTFunc && joinType==EP_OuterON) + ){ + p->selFlags |= SF_OnToWhere; + } } return 0; } @@ -147882,6 +150688,48 @@ static void selectExprDefer( } #endif +#ifdef SQLITE_DEBUG +/* +** This is a byte-code validation check that only runs when SQLITE_DEBUG +** is defined. This routine looks backwards through the bytecode +** for the definition of cursor with index iCur. It extracts the KeyInfo from +** that cursor (it must be an index cursor) and verifies that the cursor +** does not use any collating seqeuences other than BINARY for its first +** nCol columns. +** +** This routine is used inside of an assert(). So it should return true +** on success and false if the invariant is not satisfied. +** +** tag-202607231411 +*/ +static int sqlite3CursorBloomable(Parse *pParse, int iCur, int nCol){ + int i,k; + Vdbe *v = pParse->pVdbe; + if( pParse->nErr ) return 1; + assert( v ); + for(k=sqlite3VdbeCurrentAddr(v)-1; k>0; k--){ + const VdbeOp *pOp = sqlite3VdbeGetOp(v, k); + const KeyInfo *pKeyInfo; + if( pOp->p1!=iCur ) continue; + if( pOp->opcode!=OP_OpenRead + && pOp->opcode!=OP_OpenWrite + && pOp->opcode!=OP_OpenEphemeral + ){ + continue; + } + assert( pOp->p4type==P4_KEYINFO ); + pKeyInfo = (const KeyInfo*)pOp->p4.pKeyInfo; + assert( pKeyInfo!=0 ); + for(i=0; iaColl[i]) ); + } + return 1; + } + return 0; +} +#endif /* SQLITE_DEBUG */ + + /* ** This routine generates the code for the inside of the inner loop ** of a SELECT. @@ -148057,29 +150905,6 @@ static void selectInnerLoop( } switch( eDest ){ - /* In this mode, write each query result to the key of the temporary - ** table iParm. - */ -#ifndef SQLITE_OMIT_COMPOUND_SELECT - case SRT_Union: { - int r1; - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); - sqlite3ReleaseTempReg(pParse, r1); - break; - } - - /* Construct a record from the query result, but instead of - ** saving that record, use it as a key to delete elements from - ** the temporary table iParm. - */ - case SRT_Except: { - sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol); - break; - } -#endif /* SQLITE_OMIT_COMPOUND_SELECT */ - /* Store the result as data using a unique key. */ case SRT_Fifo: @@ -148175,6 +151000,7 @@ static void selectInnerLoop( r1, pDest->zAffSdst, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); if( pDest->iSDParm2 ){ + assert( sqlite3CursorBloomable(pParse,iParm,nResultCol) ); sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, regResult, nResultCol); ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); @@ -148504,6 +151330,9 @@ static void generateSortTail( Table *pTab = pSort->aDefer[i].pTab; int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp2(v, OP_Rewind, pSort->aDefer[i].iCsr, + sqlite3VdbeCurrentAddr(v)+1); + VdbeCoverage(v); nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey); } #endif @@ -149192,8 +152021,8 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( } } if( zType ){ - const i64 k = sqlite3Strlen30(zType); - n = sqlite3Strlen30(pCol->zCnName); + const i64 k = strlen(zType); + n = strlen(pCol->zCnName); pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2); pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); if( pCol->zCnName ){ @@ -149210,6 +152039,20 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( pTab->szTabRow = 1; /* Any non-zero value works */ } +/* +** Check the current subquery nesting depth. Return true and set an +** error if it has gone too deep. +*/ +static int checkSubqueryNestingDepth(Parse *pParse){ +#if SQLITE_MAX_EXPR_DEPTH>0 + if( pParse->nNestSel >= pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH] ){ + sqlite3ErrorMsg(pParse, "VIEWs and/or subqueries nested too deep"); + return 1; + } +#endif + return 0; +} + /* ** Given a SELECT statement, generate a Table structure that describes ** the result set of that SELECT. @@ -149219,6 +152062,8 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, c sqlite3 *db = pParse->db; u64 savedFlags; + pParse->nNestSel++; + if( checkSubqueryNestingDepth(pParse) ) return 0; savedFlags = db->flags; db->flags &= ~(u64)SQLITE_FullColNames; db->flags |= SQLITE_ShortColNames; @@ -149240,6 +152085,8 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, c sqlite3DeleteTable(db, pTab); return 0; } + pParse->nNestSel--; + assert( pParse->nNestSel>=0 ); return pTab; } @@ -149251,9 +152098,7 @@ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ if( pParse->pVdbe ){ return pParse->pVdbe; } - if( pParse->pToplevel==0 - && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) - ){ + if( pParse->pToplevel==0 ){ pParse->okConstFactor = 1; } return sqlite3VdbeCreate(pParse); @@ -149304,7 +152149,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); assert( v!=0 ); - if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse) ){ + if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse, 0) ){ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); if( n==0 ){ @@ -149317,6 +152162,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ sqlite3ExprCode(pParse, pLimit->pLeft, iLimit); sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); VdbeComment((v, "LIMIT counter")); + sqlite3MayAbort(pParse); sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); } if( pLimit->pRight ){ @@ -149324,6 +152170,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ pParse->nMem++; /* Allocate an extra register for limit+offset */ sqlite3ExprCode(pParse, pLimit->pRight, iOffset); sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); + sqlite3MayAbort(pParse); VdbeComment((v, "OFFSET counter")); sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); VdbeComment((v, "LIMIT+OFFSET")); @@ -149366,9 +152213,9 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ ** function is responsible for ensuring that this structure is eventually ** freed. */ -static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ +static KeyInfo *multiSelectByMergeKeyInfo(Parse *pParse, Select *p, int nExtra){ ExprList *pOrderBy = p->pOrderBy; - int nOrderBy = ALWAYS(pOrderBy!=0) ? pOrderBy->nExpr : 0; + int nOrderBy = (pOrderBy!=0) ? pOrderBy->nExpr : 0; sqlite3 *db = pParse->db; KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); if( pRet ){ @@ -149501,7 +152348,7 @@ static void generateWithRecursiveQuery( regCurrent = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); if( pOrderBy ){ - KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1); + KeyInfo *pKeyInfo = multiSelectByMergeKeyInfo(pParse, p, 1); sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, (char*)pKeyInfo, P4_KEYINFO); destQueue.pOrderBy = pOrderBy; @@ -149510,8 +152357,28 @@ static void generateWithRecursiveQuery( } VdbeComment((v, "Queue table")); if( iDistinct ){ - p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); - p->selFlags |= SF_UsesEphemeral; + /* Generate an ephemeral table used to enforce distinctness on the + ** output of the recursive part of the CTE. + */ + KeyInfo *pKeyInfo; /* Collating sequence for the result set */ + CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ + + assert( p->pNext==0 ); + assert( p->pEList!=0 ); + nCol = p->pEList->nExpr; + pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nCol, 1); + if( pKeyInfo ){ + for(i=0, apColl=pKeyInfo->aColl; idb->pDfltColl; + } + } + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iDistinct, nCol, 0, + (void*)pKeyInfo, P4_KEYINFO); + }else{ + assert( pParse->nErr>0 ); + } } /* Detach the ORDER BY clause from the compound SELECT */ @@ -149586,7 +152453,7 @@ static void generateWithRecursiveQuery( #endif /* SQLITE_OMIT_CTE */ /* Forward references */ -static int multiSelectOrderBy( +static int multiSelectByMerge( Parse *pParse, /* Parsing context */ Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest /* What to do with query results */ @@ -149651,11 +152518,33 @@ static int hasAnchor(Select *p){ } /* -** This routine is called to process a compound query form from +** Return TRUE if p is a UNION with a LIMIT of exactly 1 and no OFFSET +** clause. This is a precondition for a couple of related optimizations. +** +** False negatives are harmless (apart from resulting in a slower query). +** False positives can result in incorrect answers, however. To provoke +** false negatives for testing purposes, disable the SQLITE_UnionLimit +** optimization. +*/ +static int unionWithLimitOne(sqlite3 *db, Select *p){ + int v; + if( p->op!=TK_UNION ) return 0; + if( p->pLimit==0 ) return 0; + if( p->pLimit->pRight ) return 0; /* No OFFSET */ + v = 0; + assert( p->pLimit->pLeft!=0 ); + if( sqlite3ExprIsInteger(p->pLimit->pLeft, &v, 0, 0)==0 ) return 0; + if( v!=1 ) return 0; + if( OptimizationDisabled(db, SQLITE_UnionLimit) ) return 0; + return 1; +} + +/* +** This routine is called to process a compound query formed from ** two or more separate queries using UNION, UNION ALL, EXCEPT, or ** INTERSECT ** -** "p" points to the right-most of the two queries. the query on the +** "p" points to the right-most of the two queries. The query on the ** left is p->pPrior. The left query could also be a compound query ** in which case this routine will be called recursively. ** @@ -149735,12 +152624,27 @@ static int multiSelect( generateWithRecursiveQuery(pParse, p, &dest); }else #endif - - /* Compound SELECTs that have an ORDER BY clause are handled separately. - */ if( p->pOrderBy ){ - return multiSelectOrderBy(pParse, p, pDest); - }else{ + /* If the compound has an ORDER BY clause, then always use the merge + ** algorithm. */ + return multiSelectByMerge(pParse, p, pDest); + }else if( p->op!=TK_ALL && !unionWithLimitOne(db,p) ){ + /* If the compound is EXCEPT, INTERSECT, or UNION (anything other than + ** UNION ALL) then also always use the merge algorithm. However, the + ** multiSelectByMerge() routine requires that the compound have an + ** ORDER BY clause, and it doesn't right now. So invent one first. */ + Expr *pOne = sqlite3ExprInt32(db, 1); + p->pOrderBy = sqlite3ExprListAppend(pParse, 0, pOne); + if( pParse->nErr ) goto multi_select_end; + assert( p->pOrderBy!=0 ); + p->pOrderBy->a[0].u.x.iOrderByCol = 1; + return multiSelectByMerge(pParse, p, pDest); + }else{ + /* For a UNION ALL compound without ORDER BY, or for a UNION with a + ** LIMIT of exactly 1 and no OFFSET and no ORDER BY, simply run the left + ** query, then run the right query */ + int addr = 0; + int nLimit = 0; /* Initialize to suppress harmless compiler warning */ #ifndef SQLITE_OMIT_EXPLAIN if( pPrior->pPrior==0 ){ @@ -149748,300 +152652,49 @@ static int multiSelect( ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY")); } #endif - - /* Generate code for the left and right SELECT statements. - */ - switch( p->op ){ - case TK_ALL: { - int addr = 0; - int nLimit = 0; /* Initialize to suppress harmless compiler warning */ - assert( !pPrior->pLimit ); - pPrior->iLimit = p->iLimit; - pPrior->iOffset = p->iOffset; - pPrior->pLimit = p->pLimit; - TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n")); - rc = sqlite3Select(pParse, pPrior, &dest); - pPrior->pLimit = 0; - if( rc ){ - goto multi_select_end; - } - p->pPrior = 0; - p->iLimit = pPrior->iLimit; - p->iOffset = pPrior->iOffset; - if( p->iLimit ){ - addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); - VdbeComment((v, "Jump ahead if LIMIT reached")); - if( p->iOffset ){ - sqlite3VdbeAddOp3(v, OP_OffsetLimit, - p->iLimit, p->iOffset+1, p->iOffset); - } - } - ExplainQueryPlan((pParse, 1, "UNION ALL")); - TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); - rc = sqlite3Select(pParse, p, &dest); - testcase( rc!=SQLITE_OK ); - pDelete = p->pPrior; - p->pPrior = pPrior; - p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - if( p->pLimit - && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse) - && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) - ){ - p->nSelectRow = sqlite3LogEst((u64)nLimit); - } - if( addr ){ - sqlite3VdbeJumpHere(v, addr); - } - break; - } - case TK_EXCEPT: - case TK_UNION: { - int unionTab; /* Cursor number of the temp table holding result */ - u8 op = 0; /* One of the SRT_ operations to apply to self */ - int priorOp; /* The SRT_ operation to apply to prior selects */ - Expr *pLimit; /* Saved values of p->nLimit */ - int addr; - int emptyBypass = 0; /* IfEmpty opcode to bypass RHS */ - SelectDest uniondest; - - - testcase( p->op==TK_EXCEPT ); - testcase( p->op==TK_UNION ); - priorOp = SRT_Union; - if( dest.eDest==priorOp ){ - /* We can reuse a temporary table generated by a SELECT to our - ** right. - */ - assert( p->pLimit==0 ); /* Not allowed on leftward elements */ - unionTab = dest.iSDParm; - }else{ - /* We will need to create our own temporary table to hold the - ** intermediate results. - */ - unionTab = pParse->nTab++; - assert( p->pOrderBy==0 ); - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); - assert( p->addrOpenEphm[0] == -1 ); - p->addrOpenEphm[0] = addr; - findRightmost(p)->selFlags |= SF_UsesEphemeral; - assert( p->pEList ); - } - - - /* Code the SELECT statements to our left - */ - assert( !pPrior->pOrderBy ); - sqlite3SelectDestInit(&uniondest, priorOp, unionTab); - TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); - rc = sqlite3Select(pParse, pPrior, &uniondest); - if( rc ){ - goto multi_select_end; - } - - /* Code the current SELECT statement - */ - if( p->op==TK_EXCEPT ){ - op = SRT_Except; - emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, unionTab); - VdbeCoverage(v); - }else{ - assert( p->op==TK_UNION ); - op = SRT_Union; - } - p->pPrior = 0; - pLimit = p->pLimit; - p->pLimit = 0; - uniondest.eDest = op; - ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - sqlite3SelectOpName(p->op))); - TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); - rc = sqlite3Select(pParse, p, &uniondest); - testcase( rc!=SQLITE_OK ); - assert( p->pOrderBy==0 ); - pDelete = p->pPrior; - p->pPrior = pPrior; - p->pOrderBy = 0; - if( p->op==TK_UNION ){ - p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - } - if( emptyBypass ) sqlite3VdbeJumpHere(v, emptyBypass); - sqlite3ExprDelete(db, p->pLimit); - p->pLimit = pLimit; - p->iLimit = 0; - p->iOffset = 0; - - /* Convert the data in the temporary table into whatever form - ** it is that we currently need. - */ - assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); - assert( p->pEList || db->mallocFailed ); - if( dest.eDest!=priorOp && db->mallocFailed==0 ){ - int iCont, iBreak, iStart; - iBreak = sqlite3VdbeMakeLabel(pParse); - iCont = sqlite3VdbeMakeLabel(pParse); - computeLimitRegisters(pParse, p, iBreak); - sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); - iStart = sqlite3VdbeCurrentAddr(v); - selectInnerLoop(pParse, p, unionTab, - 0, 0, &dest, iCont, iBreak); - sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); - sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); - } - break; - } - default: assert( p->op==TK_INTERSECT ); { - int tab1, tab2; - int iCont, iBreak, iStart; - Expr *pLimit; - int addr, iLimit, iOffset; - SelectDest intersectdest; - int r1; - int emptyBypass; - - /* INTERSECT is different from the others since it requires - ** two temporary tables. Hence it has its own case. Begin - ** by allocating the tables we will need. - */ - tab1 = pParse->nTab++; - tab2 = pParse->nTab++; - assert( p->pOrderBy==0 ); - - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); - assert( p->addrOpenEphm[0] == -1 ); - p->addrOpenEphm[0] = addr; - findRightmost(p)->selFlags |= SF_UsesEphemeral; - assert( p->pEList ); - - /* Code the SELECTs to our left into temporary table "tab1". - */ - sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); - TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n")); - rc = sqlite3Select(pParse, pPrior, &intersectdest); - if( rc ){ - goto multi_select_end; - } - - /* Initialize LIMIT counters before checking to see if the LHS - ** is empty, in case the jump is taken */ - iBreak = sqlite3VdbeMakeLabel(pParse); - computeLimitRegisters(pParse, p, iBreak); - emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, tab1); VdbeCoverage(v); - - /* Code the current SELECT into temporary table "tab2" - */ - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); - assert( p->addrOpenEphm[1] == -1 ); - p->addrOpenEphm[1] = addr; - - /* Disable prior SELECTs and the LIMIT counters during the computation - ** of the RHS select */ - pLimit = p->pLimit; - iLimit = p->iLimit; - iOffset = p->iOffset; - p->pPrior = 0; - p->pLimit = 0; - p->iLimit = 0; - p->iOffset = 0; - - intersectdest.iSDParm = tab2; - ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - sqlite3SelectOpName(p->op))); - TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT right...\n")); - rc = sqlite3Select(pParse, p, &intersectdest); - testcase( rc!=SQLITE_OK ); - pDelete = p->pPrior; - p->pPrior = pPrior; - if( p->nSelectRow>pPrior->nSelectRow ){ - p->nSelectRow = pPrior->nSelectRow; - } - sqlite3ExprDelete(db, p->pLimit); - - /* Reinstate the LIMIT counters prior to running the final intersect */ - p->pLimit = pLimit; - p->iLimit = iLimit; - p->iOffset = iOffset; - - /* Generate code to take the intersection of the two temporary - ** tables. - */ - if( rc ) break; - assert( p->pEList ); - sqlite3VdbeAddOp1(v, OP_Rewind, tab1); - r1 = sqlite3GetTempReg(pParse); - iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); - iCont = sqlite3VdbeMakeLabel(pParse); - sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); - VdbeCoverage(v); - sqlite3ReleaseTempReg(pParse, r1); - selectInnerLoop(pParse, p, tab1, - 0, 0, &dest, iCont, iBreak); - sqlite3VdbeResolveLabel(v, iCont); - sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); - sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); - sqlite3VdbeJumpHere(v, emptyBypass); - sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); - break; - } - } - - #ifndef SQLITE_OMIT_EXPLAIN - if( p->pNext==0 ){ - ExplainQueryPlanPop(pParse); - } - #endif - } - if( pParse->nErr ) goto multi_select_end; - - /* Compute collating sequences used by - ** temporary tables needed to implement the compound select. - ** Attach the KeyInfo structure to all temporary tables. - ** - ** This section is run by the right-most SELECT statement only. - ** SELECT statements to the left always skip this part. The right-most - ** SELECT might also skip this part if it has no ORDER BY clause and - ** no temp tables are required. - */ - if( p->selFlags & SF_UsesEphemeral ){ - int i; /* Loop counter */ - KeyInfo *pKeyInfo; /* Collating sequence for the result set */ - Select *pLoop; /* For looping through SELECT statements */ - CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ - int nCol; /* Number of columns in result set */ - - assert( p->pNext==0 ); - assert( p->pEList!=0 ); - nCol = p->pEList->nExpr; - pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); - if( !pKeyInfo ){ - rc = SQLITE_NOMEM_BKPT; + assert( !pPrior->pLimit ); + pPrior->iLimit = p->iLimit; + pPrior->iOffset = p->iOffset; + pPrior->pLimit = sqlite3ExprDup(db, p->pLimit, 0); + TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n")); + rc = sqlite3Select(pParse, pPrior, &dest); + sqlite3ExprDelete(db, pPrior->pLimit); + pPrior->pLimit = 0; + if( rc ){ goto multi_select_end; } - for(i=0, apColl=pKeyInfo->aColl; ipDfltColl; - } + p->pPrior = 0; + p->iLimit = pPrior->iLimit; + p->iOffset = pPrior->iOffset; + if( p->iLimit ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); + VdbeComment((v, "Jump ahead if LIMIT reached")); + if( p->iOffset ){ + sqlite3VdbeAddOp3(v, OP_OffsetLimit, + p->iLimit, p->iOffset+1, p->iOffset); + } + } + ExplainQueryPlan((pParse, 1, "UNION ALL")); + TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); + rc = sqlite3Select(pParse, p, &dest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + if( p->pLimit + && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse, 0) + && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) + ){ + p->nSelectRow = sqlite3LogEst((u64)nLimit); } - - for(pLoop=p; pLoop; pLoop=pLoop->pPrior){ - for(i=0; i<2; i++){ - int addr = pLoop->addrOpenEphm[i]; - if( addr<0 ){ - /* If [0] is unused then [1] is also unused. So we can - ** always safely abort as soon as the first unused slot is found */ - assert( pLoop->addrOpenEphm[1]<0 ); - break; - } - sqlite3VdbeChangeP2(v, addr, nCol); - sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo), - P4_KEYINFO); - pLoop->addrOpenEphm[i] = -1; - } + if( addr ){ + sqlite3VdbeJumpHere(v, addr); } - sqlite3KeyInfoUnref(pKeyInfo); +#ifndef SQLITE_OMIT_EXPLAIN + if( p->pNext==0 ){ + ExplainQueryPlanPop(pParse); + } +#endif } multi_select_end: @@ -150073,8 +152726,8 @@ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ ** Code an output subroutine for a coroutine implementation of a ** SELECT statement. ** -** The data to be output is contained in pIn->iSdst. There are -** pIn->nSdst columns to be output. pDest is where the output should +** The data to be output is contained in an array of pIn->nSdst registers +** starting at register pIn->iSdst. pDest is where the output should ** be sent. ** ** regReturn is the number of the register holding the subroutine @@ -150103,6 +152756,8 @@ static int generateOutputSubroutine( int iContinue; int addr; + assert( pIn->eDest==SRT_Coroutine ); + addr = sqlite3VdbeCurrentAddr(v); iContinue = sqlite3VdbeMakeLabel(pParse); @@ -150124,23 +152779,60 @@ static int generateOutputSubroutine( */ codeOffset(v, p->iOffset, iContinue); - assert( pDest->eDest!=SRT_Exists ); - assert( pDest->eDest!=SRT_Table ); switch( pDest->eDest ){ /* Store the result as data using a unique key. */ + case SRT_Fifo: + case SRT_DistFifo: + case SRT_Table: case SRT_EphemTab: { int r1 = sqlite3GetTempReg(pParse); int r2 = sqlite3GetTempReg(pParse); + int iParm = pDest->iSDParm; + testcase( pDest->eDest==SRT_Table ); + testcase( pDest->eDest==SRT_EphemTab ); + testcase( pDest->eDest==SRT_Fifo ); + testcase( pDest->eDest==SRT_DistFifo ); sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); - sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); - sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); +#if !defined(SQLITE_ENABLE_NULL_TRIM) && defined(SQLITE_DEBUG) + /* A destination of SRT_Table and a non-zero iSDParm2 parameter means + ** that this is an "UPDATE ... FROM" on a virtual table or view. In this + ** case set the p5 parameter of the OP_MakeRecord to OPFLAG_NOCHNG_MAGIC. + ** This does not affect operation in any way - it just allows MakeRecord + ** to process OPFLAG_NOCHANGE values without an assert() failing. */ + if( pDest->eDest==SRT_Table && pDest->iSDParm2 ){ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); + } +#endif +#ifndef SQLITE_OMIT_CTE + if( pDest->eDest==SRT_DistFifo ){ + /* If the destination is DistFifo, then cursor (iParm+1) is open + ** on an ephemeral index that is used to enforce uniqueness on the + ** total result. At this point, we are processing the setup portion + ** of the recursive CTE using the merge algorithm, so the results are + ** guaranteed to be unique anyhow. But we still need to populate the + ** (iParm+1) cursor for use by the subsequent recursive phase. + */ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1, + pIn->iSdst, pIn->nSdst); + } +#endif + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3ReleaseTempReg(pParse, r2); sqlite3ReleaseTempReg(pParse, r1); break; } + /* If any row exist in the result set, record that fact and abort. + */ + case SRT_Exists: { + sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm); + /* The LIMIT clause will terminate the loop for us */ + break; + } + #ifndef SQLITE_OMIT_SUBQUERY /* If we are creating a set for an "expr IN (SELECT ...)". */ @@ -150153,6 +152845,7 @@ static int generateOutputSubroutine( sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); if( pDest->iSDParm2>0 ){ + assert( sqlite3CursorBloomable(pParse, pDest->iSDParm, pIn->nSdst) ); sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, pIn->iSdst, pIn->nSdst); ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); @@ -150187,9 +152880,51 @@ static int generateOutputSubroutine( break; } +#ifndef SQLITE_OMIT_CTE + /* Write the results into a priority queue that is order according to + ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an + ** index with pSO->nExpr+2 columns. Build a key using pSO for the first + ** pSO->nExpr columns, then make sure all keys are unique by adding a + ** final OP_Sequence column. The last column is the record as a blob. + */ + case SRT_DistQueue: + case SRT_Queue: { + int nKey; + int r1, r2, r3, ii; + ExprList *pSO; + int iParm = pDest->iSDParm; + pSO = pDest->pOrderBy; + assert( pSO ); + nKey = pSO->nExpr; + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempRange(pParse, nKey+2); + r3 = r2+nKey+1; + + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r3); + if( pDest->eDest==SRT_DistQueue ){ + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); + } + for(ii=0; iiiSdst + pSO->a[ii].u.x.iOrderByCol - 1, + r2+ii); + } + sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempRange(pParse, r2, nKey+2); + break; + } +#endif /* SQLITE_OMIT_CTE */ + + /* Ignore the output */ + case SRT_Discard: { + break; + } + /* If none of the above, then the result destination must be - ** SRT_Output. This routine is never called with any other - ** destination other than the ones handled above or SRT_Output. + ** SRT_Output. ** ** For SRT_Output, results are stored in a sequence of registers. ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to @@ -150217,8 +152952,9 @@ static int generateOutputSubroutine( } /* -** Alternative compound select code generator for cases when there -** is an ORDER BY clause. +** Generate code for a compound SELECT statement using a merge +** algorithm. The compound must have an ORDER BY clause for this +** to work. ** ** We assume a query of the following form: ** @@ -150235,7 +152971,7 @@ static int generateOutputSubroutine( ** ** outB: Move the output of the selectB coroutine into the output ** of the compound query. (Only generated for UNION and -** UNION ALL. EXCEPT and INSERTSECT never output a row that +** UNION ALL. EXCEPT and INTERSECT never output a row that ** appears only in B.) ** ** AltB: Called when there is data from both coroutines and Au.x.iOrderByCol==i ) break; } if( j==nOrderBy ){ - Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); + Expr *pNew = sqlite3ExprInt32(db, i); if( pNew==0 ) return SQLITE_NOMEM_BKPT; - pNew->flags |= EP_IntValue; - pNew->u.iValue = i; p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; } @@ -150385,26 +153117,29 @@ static int multiSelectOrderBy( } /* Compute the comparison permutation and keyinfo that is used with - ** the permutation used to determine if the next - ** row of results comes from selectA or selectB. Also add explicit - ** collations to the ORDER BY clause terms so that when the subqueries - ** to the right and the left are evaluated, they use the correct - ** collation. + ** the permutation to determine if the next row of results comes + ** from selectA or selectB. Also add literal collations to the + ** ORDER BY clause terms so that when selectA and selectB are + ** evaluated, they use the correct collation. */ aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1)); if( aPermute ){ struct ExprList_item *pItem; + int bKeep = 0; aPermute[0] = nOrderBy; for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){ assert( pItem!=0 ); assert( pItem->u.x.iOrderByCol>0 ); assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); aPermute[i] = pItem->u.x.iOrderByCol - 1; + if( aPermute[i]!=(u32)i-1 ) bKeep = 1; + } + if( bKeep==0 ){ + sqlite3DbFreeNN(db, aPermute); + aPermute = 0; } - pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1); - }else{ - pKeyMerge = 0; } + pKeyMerge = multiSelectByMergeKeyInfo(pParse, p, 1); /* Allocate a range of temporary registers and the KeyInfo needed ** for the logic that removes duplicate result rows when the @@ -150457,7 +153192,7 @@ static int multiSelectOrderBy( /* Compute the limit registers */ computeLimitRegisters(pParse, p, labelEnd); - if( p->iLimit && op==TK_ALL ){ + if( p->iLimit && (op==TK_ALL || unionWithLimitOne(db,p)) ){ regLimitA = ++pParse->nMem; regLimitB = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, @@ -150483,7 +153218,7 @@ static int multiSelectOrderBy( */ addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); - VdbeComment((v, "left SELECT")); + VdbeComment((v, "SUBR: next-A")); pPrior->iLimit = regLimitA; ExplainQueryPlan((pParse, 1, "LEFT")); sqlite3Select(pParse, pPrior, &destA); @@ -150495,7 +153230,7 @@ static int multiSelectOrderBy( */ addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); - VdbeComment((v, "right SELECT")); + VdbeComment((v, "SUBR: next-B")); savedLimit = p->iLimit; savedOffset = p->iOffset; p->iLimit = regLimitB; @@ -150509,7 +153244,7 @@ static int multiSelectOrderBy( /* Generate a subroutine that outputs the current row of the A ** select as the next output row of the compound select. */ - VdbeNoopComment((v, "Output routine for A")); + VdbeNoopComment((v, "SUBR: out-A")); addrOutA = generateOutputSubroutine(pParse, p, &destA, pDest, regOutA, regPrev, pKeyDup, labelEnd); @@ -150518,7 +153253,7 @@ static int multiSelectOrderBy( ** select as the next output row of the compound select. */ if( op==TK_ALL || op==TK_UNION ){ - VdbeNoopComment((v, "Output routine for B")); + VdbeNoopComment((v, "SUBR: out-B")); addrOutB = generateOutputSubroutine(pParse, p, &destB, pDest, regOutB, regPrev, pKeyDup, labelEnd); @@ -150531,10 +153266,12 @@ static int multiSelectOrderBy( if( op==TK_EXCEPT || op==TK_INTERSECT ){ addrEofA_noB = addrEofA = labelEnd; }else{ - VdbeNoopComment((v, "eof-A subroutine")); + VdbeNoopComment((v, "SUBR: eof-A")); addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + VdbeComment((v, "out-B")); addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); VdbeCoverage(v); + VdbeComment((v, "next-B")); sqlite3VdbeGoto(v, addrEofA); p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); } @@ -150546,17 +153283,20 @@ static int multiSelectOrderBy( addrEofB = addrEofA; if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; }else{ - VdbeNoopComment((v, "eof-B subroutine")); + VdbeNoopComment((v, "SUBR: eof-B")); addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); + VdbeComment((v, "out-A")); sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); + VdbeComment((v, "next-A")); sqlite3VdbeGoto(v, addrEofB); } /* Generate code to handle the case of AB */ - VdbeNoopComment((v, "A-gt-B subroutine")); addrAgtB = sqlite3VdbeCurrentAddr(v); if( op==TK_ALL || op==TK_UNION ){ sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + VdbeComment((v, "out-B")); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + VdbeComment((v, "next-B")); + sqlite3VdbeGoto(v, labelCmpr); + }else{ + addrAgtB++; /* Just do next-B. Might as well use the next-B call + ** in the next code block */ } - sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); - sqlite3VdbeGoto(v, labelCmpr); /* This code runs once to initialize everything. */ sqlite3VdbeJumpHere(v, addr1); sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); + VdbeComment((v, "next-A")); + /* v--- Also the A>B case for EXCEPT and INTERSECT */ sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + VdbeComment((v, "next-B")); /* Implement the main merge loop */ + if( aPermute!=0 ){ + sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); + } sqlite3VdbeResolveLabel(v, labelCmpr); - sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, (char*)pKeyMerge, P4_KEYINFO); - sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); - sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v); + if( aPermute!=0 ){ + sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); + } + sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); + VdbeCoverageIf(v, op==TK_ALL); + VdbeCoverageIf(v, op==TK_UNION); + VdbeCoverageIf(v, op==TK_EXCEPT); + VdbeCoverageIf(v, op==TK_INTERSECT); /* Jump to the this point in order to terminate the query. */ @@ -150921,7 +153673,9 @@ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){ renumberCursorDoMapping(pWalker, &pExpr->iTable); } - if( ExprHasProperty(pExpr, EP_OuterON) ){ + if( ExprHasProperty(pExpr, (EP_OuterON|EP_InnerON)) ){ + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + testcase( ExprHasProperty(pExpr, EP_InnerON) ); renumberCursorDoMapping(pWalker, &pExpr->w.iJoin); } return WRC_Continue; @@ -151468,7 +154222,7 @@ static int flattenSubquery( pSub = pSub1; for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ int nSubSrc; - u8 jointype = pSubitem->fg.jointype; + u8 jointype = pParent->pSrc->a[iFrom].fg.jointype; assert( pSub!=0 ); pSubSrc = pSub->pSrc; /* FROM clause of subquery */ nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ @@ -151493,7 +154247,6 @@ static int flattenSubquery( pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1); if( pSrc==0 ) break; pParent->pSrc = pSrc; - pSubitem = &pSrc->a[iFrom]; } /* Transfer the FROM clause terms from the subquery into the @@ -151511,9 +154264,9 @@ static int flattenSubquery( pItem->fg.jointype |= (jointype & JT_LTORJ); memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } - pSubitem->fg.jointype |= jointype; + pSrc->a[iFrom].fg.jointype |= jointype; - /* Now begin substituting subquery result set expressions for + /* Begin substituting subquery result set expressions for ** references to the iParent in the outer query. ** ** Example: @@ -151525,7 +154278,7 @@ static int flattenSubquery( ** We look at every expression in the outer query and every place we see ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". */ - if( pSub->pOrderBy && (pParent->selFlags & SF_NoopOrderBy)==0 ){ + if( pSub->pOrderBy ){ /* At this point, any non-zero iOrderByCol values indicate that the ** ORDER BY column expression is identical to the iOrderByCol'th ** expression returned by SELECT statement pSub. Since these values @@ -151533,9 +154286,9 @@ static int flattenSubquery( ** zero them before transferring the ORDER BY clause. ** ** Not doing this may cause an error if a subsequent call to this - ** function attempts to flatten a compound sub-query into pParent - ** (the only way this can happen is if the compound sub-query is - ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */ + ** function attempts to flatten a compound sub-query into pParent. + ** See ticket [d11a6e908f]. + */ ExprList *pOrderBy = pSub->pOrderBy; for(i=0; inExpr; i++){ pOrderBy->a[i].u.x.iOrderByCol = 0; @@ -151626,12 +154379,21 @@ struct WhereConst { }; /* -** Add a new entry to the pConst object. Except, do not add duplicate -** pColumn entries. Also, do not add if doing so would not be appropriate. +** Add a new entry to the pConst object, if appropriate. +** +** * Do not add if pValue is not constant. (This is enforced by +** the caller) +** +** * Do not add duplicate pColumn entries +** +** * Do not add if pValue has an affinity +** +** * Do not add if the comparison uses a collating sequence other +** than binary. +** +** * Do not add if pValue is a function that might return a subtype ** -** The caller guarantees the pColumn is a column and pValue is a constant. -** This routine has to do some additional checks before completing the -** insert. +** The caller guarantees the pColumn is a column. */ static void constInsert( WhereConst *pConst, /* The WhereConst into which we are inserting */ @@ -151642,12 +154404,12 @@ static void constInsert( int i; assert( pColumn->op==TK_COLUMN ); assert( sqlite3ExprIsConstant(pConst->pParse, pValue) ); - if( ExprHasProperty(pColumn, EP_FixedCol) ) return; if( sqlite3ExprAffinity(pValue)!=0 ) return; if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ return; } + if( sqlite3ExprCanReturnSubtype(pConst->pParse, pValue) ) return; /* 2018-10-25 ticket [cf5ed20f] ** Make sure the same pColumn is not inserted more than once */ @@ -151793,7 +154555,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ ** ** If the WHERE clause contains terms of the form COLUMN=CONSTANT or ** CONSTANT=COLUMN that are top-level AND-connected terms that are not -** part of a ON clause from a LEFT JOIN, then throughout the query +** part of a ON clause from an OUTER JOIN, then throughout the query ** replace all other occurrences of COLUMN with CONSTANT. ** ** For example, the query: @@ -152153,6 +154915,16 @@ static int pushDownWhereTerms( x.pEList = pSubq->pEList; x.pCList = findLeftmostExprlist(pSubq); pNew = substExpr(&x, pNew); + assert( pNew!=0 || pParse->nErr!=0 ); + if( pParse->nErr==0 && pNew->op==TK_IN && ExprUseXSelect(pNew) ){ + assert( pNew->x.pSelect!=0 ); + pNew->x.pSelect->selFlags |= SF_ClonedRhsIn; + assert( pWhere!=0 ); + assert( pWhere->op==TK_IN ); + assert( ExprUseXSelect(pWhere) ); + assert( pWhere->x.pSelect!=0 ); + pWhere->x.pSelect->selFlags |= SF_ClonedRhsIn; + } #ifndef SQLITE_OMIT_WINDOWFUNC if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ /* Restriction 6c has prevented push-down in this case */ @@ -152387,14 +155159,14 @@ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ ** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2) ** ORDER BY ... COLLATE ... ** -** This transformation is necessary because the multiSelectOrderBy() routine +** This transformation is necessary because the multiSelectByMerge() routine ** above that generates the code for a compound SELECT with an ORDER BY clause ** uses a merge algorithm that requires the same collating sequence on the ** result columns as on the ORDER BY clause. See ticket ** http://sqlite.org/src/info/6709574d2a ** ** This transformation is only needed for EXCEPT, INTERSECT, and UNION. -** The UNION ALL operator works fine with multiSelectOrderBy() even when +** The UNION ALL operator works fine with multiSelectByMerge() even when ** there are COLLATE terms in the ORDER BY. */ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ @@ -152541,14 +155313,13 @@ SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ } /* -** This function checks if argument pFrom refers to a CTE declared by +** This function checks to see if argument pFrom refers to a CTE declared by ** a WITH clause on the stack currently maintained by the parser (on the -** pParse->pWith linked list). And if currently processing a CTE -** CTE expression, through routine checks to see if the reference is -** a recursive reference to the CTE. +** pParse->pWith linked list). And if currently processing a CTE expression, +** it also checks to see if the reference is a recursive reference to the CTE. ** -** If pFrom matches a CTE according to either of these two above, pFrom->pSTab -** and other fields are populated accordingly. +** If pFrom matches a CTE, pFrom->pSTab and other fields are populated +** accordingly. ** ** Return 0 if no match is found. ** Return 1 if a match is found. @@ -152677,6 +155448,18 @@ static int resolveFromTermToCte( pRecTerm = pRecTerm->pPrior; } +#if SQLITE_MAX_EXPR_DEPTH>0 + if( pParse->nTab>=db->aLimit[SQLITE_LIMIT_EXPR_DEPTH] ){ + /* Bug 2026-10-04T05:35:14Z: Prevent nested CTEs from generating + ** an exponential number of cursors. The error message here will + ** be "Nested too deep", which isn't exactly correct, but it is + ** sufficient, and we don't want to use extra code space for more + ** detail on such an obscure error. */ + pParse->nNestSel = pParse->nTab; + } + pParse->nNestSel++; + if( checkSubqueryNestingDepth(pParse) ) return 2; +#endif pCte->zCteErr = "circular reference: %s"; pSavedWith = pParse->pWith; pParse->pWith = pWith; @@ -152701,6 +155484,10 @@ static int resolveFromTermToCte( } } pParse->pWith = pWith; +#if SQLITE_MAX_EXPR_DEPTH>0 + pParse->nNestSel--; + assert( pParse->nNestSel>=0 ); +#endif for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); pEList = pLeft->pEList; @@ -152940,7 +155727,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( ALWAYS(IsVirtual(pTab)) - && pFrom->fg.fromDDL + && (pFrom->fg.fromDDL || (pParse->prepFlags & SQLITE_PREPARE_FROM_DDL)) && ALWAYS(pTab->u.vtab.p!=0) && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) ){ @@ -153147,6 +155934,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pRight = sqlite3Expr(db, TK_ID, zName); if( (pTabList->nSrc>1 && ( (pFrom->fg.jointype & JT_LTORJ)==0 + || zTName!=0 || (selFlags & SF_NestedFrom)!=0 || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) ) @@ -153893,7 +156681,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ && pExpr->pAggInfo==0 ){ sqlite3 *db = pWalker->pParse->db; - Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1"); + Expr *pNew = sqlite3ExprInt32(db, 1); if( pNew ){ Expr *pWhere = pS->pWhere; SWAP(Expr, *pNew, *pExpr); @@ -154033,7 +156821,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ pFrom = p->pSrc->a; - if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */ + if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */ + if( (p->selFlags & SF_Correlated)!=0 ) return 0; /* Not a correlated subq */ pSub = pFrom->u4.pSubq->pSelect; if( pSub->pPrior==0 ) return 0; /* Must be a compound */ if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ @@ -154076,6 +156865,10 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ }else{ pExpr = sqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr); } + if( pParse->nErr ){ + sqlite3ExprDelete(db, pExpr); + pExpr = 0; + } pSub = pPrior; } p->pEList->a[0].pExpr = pExpr; @@ -154211,6 +157004,7 @@ static SQLITE_NOINLINE void existsToJoin( && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) && ALWAYS(p->pSrc!=0) && p->pSrc->nSrcpLimit==0 || p->pLimit->pRight==0) ){ if( pWhere->op==TK_AND ){ Expr *pRight = pWhere->pRight; @@ -154244,7 +157038,6 @@ static SQLITE_NOINLINE void existsToJoin( ExprSetProperty(pWhere, EP_IntValue); assert( p->pWhere!=0 ); pSub->pSrc->a[0].fg.fromExists = 1; - pSub->pSrc->a[0].fg.jointype |= JT_CROSS; p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc); if( pSubWhere ){ p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere); @@ -154252,6 +157045,7 @@ static SQLITE_NOINLINE void existsToJoin( } pSub->pSrc = 0; sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub); + recomputeColumnsUsed(p, &p->pSrc->a[p->pSrc->nSrc-1]); #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x100000 ){ TREETRACE(0x100000,pParse,p, @@ -154259,7 +157053,6 @@ static SQLITE_NOINLINE void existsToJoin( sqlite3TreeViewSelect(0, p, 0); } #endif - existsToJoin(pParse, p, pSubWhere); } } } @@ -154270,9 +157063,10 @@ static SQLITE_NOINLINE void existsToJoin( */ typedef struct CheckOnCtx CheckOnCtx; struct CheckOnCtx { - SrcList *pSrc; /* SrcList for this context */ - int iJoin; /* Cursor numbers must be =< than this */ - CheckOnCtx *pParent; /* Parent context */ + SrcList *pSrc; /* SrcList for this context */ + int iJoin; /* Cursors must be left of this one, if not negative */ + int bFuncArg; /* True for table-function arg */ + CheckOnCtx *pParent; /* Parent context */ }; /* @@ -154303,11 +157097,11 @@ static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){ ** set it to the cursor number of the RHS of the join to which this ** ON expression was attached and then iterate through the entire ** expression. */ - assert( pCtx->iJoin==0 || pCtx->iJoin==pExpr->w.iJoin ); - if( pCtx->iJoin==0 ){ + assert( pCtx->iJoin<0 || pCtx->iJoin==pExpr->w.iJoin ); + if( pCtx->iJoin<0 ){ pCtx->iJoin = pExpr->w.iJoin; sqlite3WalkExprNN(pWalker, pExpr); - pCtx->iJoin = 0; + pCtx->iJoin = -1; return WRC_Prune; } } @@ -154317,14 +157111,25 @@ static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){ ** Then, if CheckOnCtx.iJoin indicates that this expression is part of an ** ON clause from that SrcList (i.e. if iJoin is non-zero), check that it ** does not refer to a table to the right of CheckOnCtx.iJoin. */ + int iTab = pExpr->iTable; do { SrcList *pSrc = pCtx->pSrc; - int iTab = pExpr->iTable; - if( iTab>=pSrc->a[0].iCursor && iTab<=pSrc->a[pSrc->nSrc-1].iCursor ){ - if( pCtx->iJoin && iTab>pCtx->iJoin ){ - sqlite3ErrorMsg(pWalker->pParse, - "ON clause references tables to its right"); - return WRC_Abort; + int nSrc = pSrc->nSrc; + int ii; + for(ii=0; iia[ii].iCursor!=iTab; ii++){} + if( iiiJoin>=0 ){ + for(ii--; ii>=0 && pSrc->a[ii].iCursor!=pCtx->iJoin; ii--){} + if( ii>=0 ){ + /* Table iJoin appears to the left of table iTab in the SrcList. + ** Therefore the expression refers to a table to its right. */ + sqlite3ErrorMsg(pWalker->pParse, + "%s references tables to its right", + (pCtx->bFuncArg ? "table-function argument" : "ON clause") + ); + return WRC_Abort; + } } break; } @@ -154346,6 +157151,7 @@ static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){ memset(&sCtx, 0, sizeof(sCtx)); sCtx.pSrc = pSelect->pSrc; sCtx.pParent = pCtx; + sCtx.iJoin = -1; pWalker->u.pCheckOnCtx = &sCtx; sqlite3WalkSelect(pWalker, pSelect); pWalker->u.pCheckOnCtx = pCtx; @@ -154358,9 +157164,10 @@ static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){ ** Check all ON clauses in pSelect to verify that they do not reference ** columns to the right. */ -static void selectCheckOnClauses(Parse *pParse, Select *pSelect){ +SQLITE_PRIVATE void sqlite3SelectCheckOnClauses(Parse *pParse, Select *pSelect){ Walker w; CheckOnCtx sCtx; + int ii; assert( pSelect->selFlags & SF_OnToWhere ); assert( pSelect->pSrc!=0 && pSelect->pSrc->nSrc>=2 ); memset(&w, 0, sizeof(w)); @@ -154370,8 +157177,67 @@ static void selectCheckOnClauses(Parse *pParse, Select *pSelect){ w.u.pCheckOnCtx = &sCtx; memset(&sCtx, 0, sizeof(sCtx)); sCtx.pSrc = pSelect->pSrc; - sqlite3WalkExprNN(&w, pSelect->pWhere); + sCtx.iJoin = -1; + sqlite3WalkExpr(&w, pSelect->pWhere); pSelect->selFlags &= ~SF_OnToWhere; + + /* Check for any table-function args that are attached to virtual tables + ** on the RHS of an outer join. They are subject to similar constraints + ** as ON clauses. Specifically: + ** + ** * If the table-valued function is to the left of any RIGHT JOIN, or if + ** it is the RHS of a RIGHT JOIN, then the table-valued function arguments + ** may not refer to any tables to the right of this one. + ** + ** * If the table-valued function is to the left of a LEFT JOIN, then it + ** may not refer to any table that occurs to the right of the LEFT JOIN. + */ + sCtx.bFuncArg = 1; + for(ii=0; iipSrc->nSrc; ii++){ + SrcItem *pItem = &pSelect->pSrc->a[ii]; + if( pItem->fg.isTabFunc ){ + sCtx.iJoin = -1; + if( (pItem->fg.jointype & (JT_LTORJ|JT_RIGHT)) ){ + sCtx.iJoin = pItem->iCursor; + }else{ + int jj; + for(jj=ii+1; jjpSrc->nSrc; jj++){ + SrcItem *pItem2 = &pSelect->pSrc->a[jj]; + if( pItem2->fg.jointype & JT_OUTER ){ + sCtx.iJoin = pItem2[-1].iCursor; + break; + } + } + } + if( sCtx.iJoin>=0 ){ + sqlite3WalkExprList(&w, pItem->u1.pFuncArg); + } + } + } +} + +/* +** If p2 exists and p1 and p2 have the same number of terms, then change +** every term of p1 to have the same sort order as p2 and return true. +** +** If p2 is NULL or p1 and p2 are different lengths, then make no changes +** and return false. +** +** p1 must be non-NULL. +*/ +static int sqlite3CopySortOrder(ExprList *p1, ExprList *p2){ + assert( p1 ); + if( p2 && p1->nExpr==p2->nExpr ){ + int ii; + for(ii=0; iinExpr; ii++){ + u8 sortFlags; + sortFlags = p2->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC; + p1->a[ii].fg.sortFlags = sortFlags; + } + return 1; + }else{ + return 0; + } } /* @@ -154469,8 +157335,7 @@ SQLITE_PRIVATE int sqlite3Select( assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); if( IgnorableDistinct(pDest) ){ - assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || - pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Discard || pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); /* All of these destinations are also able to ignore the ORDER BY clause */ if( p->pOrderBy ){ @@ -154486,7 +157351,6 @@ SQLITE_PRIVATE int sqlite3Select( p->pOrderBy = 0; } p->selFlags &= ~(u32)SF_Distinct; - p->selFlags |= SF_NoopOrderBy; } sqlite3SelectPrep(pParse, p, 0); if( pParse->nErr ){ @@ -154501,18 +157365,6 @@ SQLITE_PRIVATE int sqlite3Select( } #endif - /* If the SELECT statement contains ON clauses that were moved into - ** the WHERE clause, go through and verify that none of the terms - ** in the ON clauses reference tables to the right of the ON clause. - ** Do this now, after name resolution, but before query flattening - */ - if( p->selFlags & SF_OnToWhere ){ - selectCheckOnClauses(pParse, p); - if( pParse->nErr ){ - goto select_end; - } - } - /* If the SF_UFSrcCheck flag is set, then this function is being called ** as part of populating the temp table for an UPDATE...FROM statement. ** In this case, it is an error if the target object (pSrc->a[0]) name @@ -155026,7 +157878,8 @@ SQLITE_PRIVATE int sqlite3Select( ** BY and DISTINCT, and an index or separate temp-table for the other. */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct - && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 + && sqlite3CopySortOrder(pEList, sSort.pOrderBy) + && sqlite3ExprListCompare(pEList, sSort.pOrderBy, -1)==0 && OptimizationEnabled(db, SQLITE_GroupByOrder) #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 @@ -155240,21 +158093,10 @@ SQLITE_PRIVATE int sqlite3Select( ** but not actually sorted. Either way, record the fact that the ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp ** variable. */ - if( sSort.pOrderBy && pGroupBy->nExpr==sSort.pOrderBy->nExpr ){ - int ii; - /* The GROUP BY processing doesn't care whether rows are delivered in - ** ASC or DESC order - only that each group is returned contiguously. - ** So set the ASC/DESC flags in the GROUP BY to match those in the - ** ORDER BY to maximize the chances of rows being delivered in an - ** order that makes the ORDER BY redundant. */ - for(ii=0; iinExpr; ii++){ - u8 sortFlags; - sortFlags = sSort.pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC; - pGroupBy->a[ii].fg.sortFlags = sortFlags; - } - if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ - orderByGrp = 1; - } + if( sqlite3CopySortOrder(pGroupBy, sSort.pOrderBy) + && sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 + ){ + orderByGrp = 1; } }else{ assert( 0==sqlite3LogEst(1) ); @@ -156064,7 +158906,7 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS sqlite3SelectDelete(db, pTmp->pSelect); sqlite3IdListDelete(db, pTmp->pIdList); sqlite3UpsertDelete(db, pTmp->pUpsert); - sqlite3SrcListDelete(db, pTmp->pFrom); + sqlite3SrcListDelete(db, pTmp->pSrc); sqlite3DbFree(db, pTmp->zSpan); sqlite3DbFree(db, pTmp); @@ -156244,8 +159086,9 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + }else if( db->init.busy ){ + sqlite3ErrorMsg(pParse,""); /* Err msg generated by corruptSchema() */ }else{ - assert( !db->init.busy ); sqlite3CodeVerifySchema(pParse, iDb); VVA_ONLY( pParse->ifNotExists = 1; ) } @@ -156253,11 +159096,16 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( } } + /* NB: The SQLITE_ALLOW_TRIGGERS_ON_SYSTEM_TABLES compile-time option is + ** experimental and unsupported. Do not use it unless understand the + ** implications and you cannot get by without this capability. */ +#if !defined(SQLITE_ALLOW_TRIGGERS_ON_SYSTEM_TABLES) /* Experimental */ /* Do not create a trigger on a system table */ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); goto trigger_cleanup; } +#endif /* INSTEAD of triggers are only for views and views only support INSTEAD ** of triggers. @@ -156364,16 +159212,22 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( DbFixer sFix; /* Fixer object */ int iDb; /* Database containing the trigger */ Token nameToken; /* Trigger name for error reporting */ + i64 n; /* Number of steps */ pParse->pNewTrigger = 0; if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; zName = pTrig->zName; iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); + assert( iDb>=00 && iDbnDb ); pTrig->step_list = pStepList; - while( pStepList ){ + for(n=0; pStepList; n++){ pStepList->pTrig = pTrig; pStepList = pStepList->pNext; } + if( n>pParse->db->aLimit[SQLITE_LIMIT_TRIGGER_STEPS] ){ + sqlite3ErrorMsg(pParse, "trigger \"%w\" contains too many steps", zName); + goto triggerfinish_cleanup; + } sqlite3TokenInit(&nameToken, pTrig->zName); sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) @@ -156403,12 +159257,12 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( if( sqlite3ReadOnlyShadowTables(db) ){ TriggerStep *pStep; for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){ - if( pStep->zTarget!=0 - && sqlite3ShadowTableName(db, pStep->zTarget) + if( pStep->pSrc!=0 + && sqlite3ShadowTableName(db, pStep->pSrc->a[0].zName) ){ sqlite3ErrorMsg(pParse, "trigger \"%s\" may not write to shadow table \"%s\"", - pTrig->zName, pStep->zTarget); + pTrig->zName, pStep->pSrc->a[0].zName); goto triggerfinish_cleanup; } } @@ -156499,26 +159353,39 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep( static TriggerStep *triggerStepAllocate( Parse *pParse, /* Parser context */ u8 op, /* Trigger opcode */ - Token *pName, /* The target name */ + SrcList *pTabList, /* Target table */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ + Trigger *pNew = pParse->pNewTrigger; sqlite3 *db = pParse->db; - TriggerStep *pTriggerStep; + TriggerStep *pTriggerStep = 0; - if( pParse->nErr ) return 0; - pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); - if( pTriggerStep ){ - char *z = (char*)&pTriggerStep[1]; - memcpy(z, pName->z, pName->n); - sqlite3Dequote(z); - pTriggerStep->zTarget = z; - pTriggerStep->op = op; - pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); - if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName); + if( pParse->nErr==0 ){ + if( pNew + && pNew->pSchema!=db->aDb[1].pSchema + && pTabList->a[0].u4.zDatabase + ){ + sqlite3ErrorMsg(pParse, + "qualified table names are not allowed on INSERT, UPDATE, and DELETE " + "statements within triggers"); + }else{ + pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); + if( pTriggerStep ){ + pTriggerStep->pSrc = sqlite3SrcListDup(db, pTabList, EXPRDUP_REDUCE); + pTriggerStep->op = op; + pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); + if( pTriggerStep->pSrc && IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, + pTriggerStep->pSrc->a[0].zName, + pTabList->a[0].zName + ); + } + } } } + + sqlite3SrcListDelete(db, pTabList); return pTriggerStep; } @@ -156531,7 +159398,7 @@ static TriggerStep *triggerStepAllocate( */ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( Parse *pParse, /* Parser */ - Token *pTableName, /* Name of the table into which we insert */ + SrcList *pTabList, /* Table to INSERT into */ IdList *pColumn, /* List of columns in pTableName to insert into */ Select *pSelect, /* A SELECT statement that supplies values */ u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ @@ -156544,7 +159411,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( assert(pSelect != 0 || db->mallocFailed); - pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd); + pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTabList, zStart, zEnd); if( pTriggerStep ){ if( IN_RENAME_OBJECT ){ pTriggerStep->pSelect = pSelect; @@ -156576,7 +159443,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( */ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( Parse *pParse, /* Parser */ - Token *pTableName, /* Name of the table to be updated */ + SrcList *pTabList, /* Name of the table to be updated */ SrcList *pFrom, /* FROM clause for an UPDATE-FROM, or NULL */ ExprList *pEList, /* The SET clause: list of column and new values */ Expr *pWhere, /* The WHERE clause */ @@ -156587,21 +159454,36 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; - pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd); + pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTabList, zStart, zEnd); if( pTriggerStep ){ + SrcList *pFromDup = 0; if( IN_RENAME_OBJECT ){ pTriggerStep->pExprList = pEList; pTriggerStep->pWhere = pWhere; - pTriggerStep->pFrom = pFrom; + pFromDup = pFrom; pEList = 0; pWhere = 0; pFrom = 0; }else{ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); - pTriggerStep->pFrom = sqlite3SrcListDup(db, pFrom, EXPRDUP_REDUCE); + pFromDup = sqlite3SrcListDup(db, pFrom, EXPRDUP_REDUCE); } pTriggerStep->orconf = orconf; + + if( pFromDup && !IN_RENAME_OBJECT){ + Select *pSub; + Token as = {0, 0}; + pSub = sqlite3SelectNew(pParse, 0, pFromDup, 0,0,0,0, SF_NestedFrom, 0); + pFromDup = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &as, pSub ,0); + } + if( pFromDup && pTriggerStep->pSrc ){ + pTriggerStep->pSrc = sqlite3SrcListAppendList( + pParse, pTriggerStep->pSrc, pFromDup + ); + }else{ + sqlite3SrcListDelete(db, pFromDup); + } } sqlite3ExprListDelete(db, pEList); sqlite3ExprDelete(db, pWhere); @@ -156616,7 +159498,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( */ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( Parse *pParse, /* Parser */ - Token *pTableName, /* The table from which rows are deleted */ + SrcList *pTabList, /* The table from which rows are deleted */ Expr *pWhere, /* The WHERE clause */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ @@ -156624,7 +159506,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; - pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd); + pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTabList, zStart, zEnd); if( pTriggerStep ){ if( IN_RENAME_OBJECT ){ pTriggerStep->pWhere = pWhere; @@ -156824,6 +159706,7 @@ static SQLITE_NOINLINE Trigger *triggersReallyExist( p = pList; if( (pParse->db->flags & SQLITE_EnableTrigger)==0 && pTab->pTrigger!=0 + && sqlite3SchemaToIndex(pParse->db, pTab->pTrigger->pSchema)!=1 ){ /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off. That means that ** only TEMP triggers are allowed. Truncate the pList so that it @@ -156886,52 +159769,6 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist( return triggersReallyExist(pParse,pTab,op,pChanges,pMask); } -/* -** Convert the pStep->zTarget string into a SrcList and return a pointer -** to that SrcList. -** -** This routine adds a specific database name, if needed, to the target when -** forming the SrcList. This prevents a trigger in one database from -** referring to a target in another database. An exception is when the -** trigger is in TEMP in which case it can refer to any other database it -** wants. -*/ -SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( - Parse *pParse, /* The parsing context */ - TriggerStep *pStep /* The trigger containing the target token */ -){ - sqlite3 *db = pParse->db; - SrcList *pSrc; /* SrcList to be returned */ - char *zName = sqlite3DbStrDup(db, pStep->zTarget); - pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); - assert( pSrc==0 || pSrc->nSrc==1 ); - assert( zName || pSrc==0 ); - if( pSrc ){ - Schema *pSchema = pStep->pTrig->pSchema; - pSrc->a[0].zName = zName; - if( pSchema!=db->aDb[1].pSchema ){ - assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 ); - pSrc->a[0].u4.pSchema = pSchema; - pSrc->a[0].fg.fixedSchema = 1; - } - if( pStep->pFrom ){ - SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); - if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){ - Select *pSubquery; - Token as; - pSubquery = sqlite3SelectNew(pParse,0,pDup,0,0,0,0,SF_NestedFrom,0); - as.n = 0; - as.z = 0; - pDup = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); - } - pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup); - } - }else{ - sqlite3DbFree(db, zName); - } - return pSrc; -} - /* ** Return true if the pExpr term from the RETURNING clause argument ** list is of the form "*". Raise an error if the terms if of the @@ -157197,7 +160034,7 @@ static int codeTriggerProgram( switch( pStep->op ){ case TK_UPDATE: { sqlite3Update(pParse, - sqlite3TriggerStepSrc(pParse, pStep), + sqlite3SrcListDup(db, pStep->pSrc, 0), sqlite3ExprListDup(db, pStep->pExprList, 0), sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf, 0, 0, 0 @@ -157207,7 +160044,7 @@ static int codeTriggerProgram( } case TK_INSERT: { sqlite3Insert(pParse, - sqlite3TriggerStepSrc(pParse, pStep), + sqlite3SrcListDup(db, pStep->pSrc, 0), sqlite3SelectDup(db, pStep->pSelect, 0), sqlite3IdListDup(db, pStep->pIdList), pParse->eOrconf, @@ -157218,7 +160055,7 @@ static int codeTriggerProgram( } case TK_DELETE: { sqlite3DeleteFrom(pParse, - sqlite3TriggerStepSrc(pParse, pStep), + sqlite3SrcListDup(db, pStep->pSrc, 0), sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 ); sqlite3VdbeAddOp0(v, OP_ResetCount); @@ -157283,7 +160120,7 @@ static TriggerPrg *codeRowTrigger( Table *pTab, /* The table pTrigger is attached to */ int orconf /* ON CONFLICT policy to code trigger program with */ ){ - Parse *pTop = sqlite3ParseToplevel(pParse); + Parse *pTop; /* Top level Parse object */ sqlite3 *db = pParse->db; /* Database handle */ TriggerPrg *pPrg; /* Value to return */ Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ @@ -157292,10 +160129,24 @@ static TriggerPrg *codeRowTrigger( SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ int iEndTrigger = 0; /* Label to jump to if WHEN is false */ Parse sSubParse; /* Parse context for sub-vdbe */ + int nDepth; /* Trigger depth */ + + /* Ensure that triggers are not chained too deep. This test is linear + ** in the chaining depth, but sensible code ought not be chaining + ** triggers excessively, so that shouldn't be a problem. + */ + pTop = pParse; + for(nDepth=0; pTop->pOuterParse; pTop = pTop->pOuterParse, nDepth++){} + if( nDepth>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ + sqlite3ErrorMsg(pParse, "triggers nested too deep"); + return 0; + } + pTop = sqlite3ParseToplevel(pParse); assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); assert( pTop->pVdbe ); + /* Allocate the TriggerPrg and SubProgram objects. To ensure that they ** are freed if an error occurs, link them into the Parse.pTriggerPrg ** list of the top-level Parse object sooner rather than later. */ @@ -157671,26 +160522,37 @@ static void updateVirtualTable( ** integer. In that case, add an OP_RealAffinity opcode to make sure ** it has been converted into REAL. */ -SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ +static SQLITE_NOINLINE void columnDefaultUncommonCase( + Vdbe *v, /* Byte code under construction */ + Table *pTab, /* The table */ + Column *pCol /* Which column of the table */ +){ + sqlite3_value *pValue = 0; + u8 enc = ENC(sqlite3VdbeDb(v)); + Parse *pParse = sqlite3VdbeParser(v); + assert( !IsView(pTab) ); + sqlite3ValueFromExpr(sqlite3VdbeDb(v), + sqlite3ColumnExprAuth(pTab,pCol,pParse), enc, + pCol->affinity, &pValue); + if( pValue ){ + sqlite3VdbeAppendP4(v, pValue, P4_MEM); + } +} +SQLITE_PRIVATE void sqlite3ColumnDefault( + Vdbe *v, /* Byte code under construction */ + Table *pTab, /* The table */ + int i, /* Which column of the table */ + int iReg /* Register in which results are stored */ +){ Column *pCol; assert( pTab!=0 ); assert( pTab->nCol>i ); pCol = &pTab->aCol[i]; if( pCol->iDflt ){ - sqlite3_value *pValue = 0; - u8 enc = ENC(sqlite3VdbeDb(v)); - assert( !IsView(pTab) ); - VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); - assert( inCol ); - sqlite3ValueFromExpr(sqlite3VdbeDb(v), - sqlite3ColumnExpr(pTab,pCol), enc, - pCol->affinity, &pValue); - if( pValue ){ - sqlite3VdbeAppendP4(v, pValue, P4_MEM); - } + columnDefaultUncommonCase(v,pTab,pCol); } #ifndef SQLITE_OMIT_FLOATING_POINT - if( pCol->affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ + if( pCol->affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } #endif @@ -158505,6 +161367,7 @@ SQLITE_PRIVATE void sqlite3Update( sqlite3VdbeAddOp3(v, OP_Column, iEph, iRowidExpr, regNewRowid); } sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v); + sqlite3MayAbort(pParse); } /* Compute the old pre-UPDATE content of the row being changed, if that @@ -159296,7 +162159,8 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate( /* excluded.* columns of type REAL need to be converted to a hard real */ for(i=0; inCol; i++){ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ - sqlite3VdbeAddOp1(v, OP_RealAffinity, pTop->regData+i); + int iStorage = pTop->regData + sqlite3TableColumnToStorage(pTab, i); + sqlite3VdbeAddOp1(v, OP_RealAffinity, iStorage); } } sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0), @@ -159540,9 +162404,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( pDb = &db->aDb[nDb]; assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); pTemp = pDb->pBt; + nRes = sqlite3BtreeGetRequestedReserve(pMain); if( pOut ){ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); i64 sz = 0; + const char *zFilename; if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){ rc = SQLITE_ERROR; sqlite3SetString(pzErrMsg, db, "output file already exists"); @@ -159554,8 +162420,16 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( ** they are for the database being vacuumed, except that PAGER_CACHESPILL ** is always set. */ pgflags = db->aDb[iDb].safety_level | (db->flags & PAGER_FLAGS_MASK); + + /* If the VACUUM INTO target file is a URI filename and if the + ** "reserve=N" query parameter is present, reset the reserve to the + ** amount specified, if the amount is within range */ + zFilename = sqlite3BtreeGetFilename(pTemp); + if( ALWAYS(zFilename) ){ + int nNew = (int)sqlite3_uri_int64(zFilename, "reserve", nRes); + if( nNew>=0 && nNew<=255 ) nRes = nNew; + } } - nRes = sqlite3BtreeGetRequestedReserve(pMain); sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); @@ -159874,6 +162748,7 @@ SQLITE_API int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif + sqlite3_mutex_enter(db->mutex); for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ Module *pMod = (Module*)sqliteHashData(pThis); pNext = sqliteHashNext(pThis); @@ -159884,6 +162759,7 @@ SQLITE_API int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ } createModule(db, pMod->zName, 0, 0, 0); } + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -160452,6 +163328,8 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "%s", zErr); pParse->rc = rc; + }else{ + sqlite3MarkAllShadowTablesOf(db, pTab); } sqlite3DbFree(db, zErr); } @@ -161039,6 +163917,17 @@ SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){ } } +/* +** Erase all eponymous virtual table instances associated with database +** handle db. +*/ +SQLITE_PRIVATE void sqlite3VtabEponymousTableClearAll(sqlite3 *db){ + HashElem *pElem; + for(pElem=sqliteHashFirst(&db->aModule); pElem; pElem=sqliteHashNext(pElem)){ + sqlite3VtabEponymousTableClear(db, (Module*)sqliteHashData(pElem)); + } +} + /* ** Return the ON CONFLICT resolution mode in effect for the virtual ** table update operation currently in progress. @@ -161731,10 +164620,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); - - - - +SQLITE_PRIVATE int sqlite3WhereLoopBloomable(const WhereLoop*); /* ** Bitmasks for the operators on WhereTerm objects. These are all @@ -162374,6 +165260,7 @@ static Expr *removeUnindexableInClauseTerms( ExprList *pRhs = 0; /* New RHS after modifications */ ExprList *pLhs = 0; /* New LHS after mods */ int i; /* Loop counter */ + int nRhs = 0; /* Number of RHS terms added so far */ assert( ExprUseXSelect(pNew) ); pOrigRhs = pSelect->pEList; @@ -162387,6 +165274,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( iField!=nRhs ){ + ExprClearProperty(pNew, EP_Subrtn); + } if( NEVER(pOrigRhs->a[iField].pExpr==0) ){ continue; /* Duplicate PK column */ } @@ -162398,6 +165288,7 @@ static Expr *removeUnindexableInClauseTerms( pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); pOrigLhs->a[iField].pExpr = 0; } + nRhs++; } } sqlite3ExprListDelete(db, pOrigRhs); @@ -162497,8 +165388,20 @@ static SQLITE_NOINLINE void codeINTerm( }else{ sqlite3 *db = pParse->db; Expr *pXMod = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( nEq>1 ){ + /* If this IN(SELECT ...) expression drives more than one column of + ** the index, disable the seek-scan optimization. The reasons for this + ** are that (a) it is only possible to make this happen by populating + ** the sqlite_stat1 table with inconsistent information, and (b) it + ** would require sqlite3FindInIndex() to find an index that is not + ** only unique for the columns in question, but also delivers them + ** in sorted order (requires checking asc/desc, and rejecting cases + ** where the indexed columns are not in the right order). */ + pLoop->wsFlags &= ~WHERE_IN_SEEKSCAN; + } if( !db->mallocFailed ){ - aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nEq); + int nCol = pX->x.pSelect->pEList->nExpr; + aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nCol); eType = sqlite3FindInIndex(pParse, pXMod, IN_INDEX_LOOP, 0, aiMap, &iTab); } sqlite3ExprDelete(db, pXMod); @@ -162745,12 +165648,7 @@ static int codeAllEqualityTerms( testcase( pTerm->wtFlags & TERM_VIRTUAL ); r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); if( r1!=regBase+j ){ - if( nReg==1 ){ - sqlite3ReleaseTempReg(pParse, regBase); - regBase = r1; - }else{ - sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); - } + sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); } if( pTerm->eOperator & WO_IN ){ if( pTerm->pExpr->flags & EP_xIsSelect ){ @@ -163203,6 +166101,7 @@ static SQLITE_NOINLINE void filterPullDown( regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); sqlite3VdbeAddOp2(pParse->pVdbe, OP_MustBeInt, regRowid, addrNxt); VdbeCoverage(pParse->pVdbe); + assert( sqlite3WhereLoopBloomable(pLoop) ); sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, addrNxt, regRowid, 1); VdbeCoverage(pParse->pVdbe); @@ -163216,6 +166115,7 @@ static SQLITE_NOINLINE void filterPullDown( r1 = codeAllEqualityTerms(pParse,pLevel,0,0,&zStartAff); codeApplyAffinity(pParse, r1, nEq, zStartAff); sqlite3DbFree(pParse->db, zStartAff); + assert( sqlite3WhereLoopBloomable(pLoop) ); sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, addrNxt, r1, nEq); VdbeCoverage(pParse->pVdbe); @@ -163246,6 +166146,49 @@ static int whereLoopIsOneRow(WhereLoop *pLoop){ return 0; } +/* +** This is called while coding loop pLevel, which scans FROM clause item +** pTabItem. pE is an expression for which all the prerequisites are +** available. This function tests if pE can be coded as part of the current +** loop, or whether it needs to be deferred to ensure outer joins are +** processed correctly. This function returns non-zero if the expression +** can be coded as part of the loop, or 0 if it must be deferred. +** +** The expression must be deferred if: +** +** * There are any RIGHT joins in the FROM clause and the expression +** was not part of an ON clause, or was part of an ON clause to the +** right of the join. +** +** * The table is the RHS of a LEFT JOIN and the expression was not +** part of an ON clause on an OUTER join, or was part of an ON clause +** on an OUTER join to the right of the join. +*/ +static int whereExprIsReady( + WhereInfo *pWInfo, + WhereLevel *pLevel, + SrcItem *pTabItem, + Expr *pE +){ + u8 jtype = pTabItem->fg.jointype; + if( jtype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){ + if( !ExprHasProperty(pE,EP_OuterON|EP_InnerON) ){ + /* Defer processing WHERE clause constraints until after outer + ** join processing. tag-20220513a */ + return 0; + }else if( (jtype & JT_LEFT) && !ExprHasProperty(pE,EP_OuterON) ){ + return 0; + }else{ + Bitmask m = sqlite3WhereGetMask(&pWInfo->sMaskSet, pE->w.iJoin); + if( m & pLevel->notReady ){ + /* An ON clause that is not ripe */ + return 0; + } + } + } + return 1; +} + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -163325,6 +166268,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pLevel->iLeftJoin = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); VdbeComment((v, "init LEFT JOIN match flag")); + if( pTabItem->fg.viaCoroutine ){ + sqlite3VdbeAddOp2(v, OP_NullRow, pTabItem->iCursor, 1); + } } /* Special case of a FROM clause subquery implemented as a co-routine */ @@ -163360,7 +166306,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){ int iTab = pParse->nTab++; int iCache = ++pParse->nMem; - sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab); + sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab, 0); sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache); }else{ codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); @@ -163819,6 +166765,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( VdbeComment((v, "NULL-scan pass ctr")); } if( pLevel->regFilter ){ + assert( sqlite3WhereLoopBloomable(pLoop) ); sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, regBase, nEq); VdbeCoverage(v); @@ -164084,7 +167031,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). */ - if( pWInfo->nLevel>1 ){ + if( pWInfo->nLevel>1 || pTabItem->fg.fromExists ){ int nNotReady; /* The number of notReady tables */ SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; @@ -164097,6 +167044,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( for(k=1; k<=nNotReady; k++){ memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); } + + /* Clear the fromExists flag on the OR-optimized table entry so that + ** the calls to sqlite3WhereEnd() do not code early-exits after the + ** first row is visited. The early exit applies to this table's + ** overall loop - including the multiple OR branches and any WHERE + ** conditions not passed to the sub-loops - not to the sub-loops. */ + pOrTab->a[0].fg.fromExists = 0; }else{ pOrTab = pWInfo->pTabList; } @@ -164168,6 +167122,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( } if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */ + if( whereExprIsReady(pWInfo, pLevel, pTabItem, pExpr)==0 ) continue; pExpr = sqlite3ExprDup(db, pExpr, 0); pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); } @@ -164340,7 +167295,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( assert( pLevel->op==OP_Return ); pLevel->p2 = sqlite3VdbeCurrentAddr(v); - if( pWInfo->nLevel>1 ){ sqlite3DbFreeNN(db, pOrTab); } + if( pWInfo->pTabList!=pOrTab ){ sqlite3DbFreeNN(db, pOrTab); } if( !untestedTerms ) disableTerm(pLevel, pTerm); }else #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ @@ -164408,22 +167363,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( } pE = pTerm->pExpr; assert( pE!=0 ); - if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){ - if( !ExprHasProperty(pE,EP_OuterON|EP_InnerON) ){ - /* Defer processing WHERE clause constraints until after outer - ** join processing. tag-20220513a */ - continue; - }else if( (pTabItem->fg.jointype & JT_LEFT)==JT_LEFT - && !ExprHasProperty(pE,EP_OuterON) ){ - continue; - }else{ - Bitmask m = sqlite3WhereGetMask(&pWInfo->sMaskSet, pE->w.iJoin); - if( m & pLevel->notReady ){ - /* An ON clause that is not ripe */ - continue; - } - } - } + if( whereExprIsReady(pWInfo, pLevel, pTabItem, pE)==0 ) continue; if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ iNext = 2; continue; @@ -164497,6 +167437,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( WO_EQ|WO_IN|WO_IS, 0); if( pAlt==0 ) continue; if( pAlt->wtFlags & (TERM_CODED) ) continue; + if( ExprHasProperty(pAlt->pExpr, EP_Collate) ) continue; if( (pAlt->eOperator & WO_IN) && ExprUseXSelect(pAlt->pExpr) && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) @@ -164548,8 +167489,10 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( VdbeComment((v, "match against %s", pTab->zName)); sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk); - sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk); - sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + if( pRJ->regBloom ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } sqlite3VdbeJumpHere(v, jmp1); sqlite3ReleaseTempRange(pParse, r, nPk+1); } @@ -164573,9 +167516,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** loop will run that invokes this subroutine for unmatched rows ** of pTab, with all tables to left begin set to NULL. */ - WhereRightJoin *pRJ = pLevel->pRJ; - sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn); - pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); + { + WhereRightJoin *pRJ = pLevel->pRJ; + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn); + pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); + } assert( pParse->withinRJSubrtn < 255 ); pParse->withinRJSubrtn++; @@ -164679,22 +167624,39 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); } } + if( pLevel->iIdxCur ){ + /* pSubWhere may contain expressions that read from an index on the + ** table on the RHS of the right join. All such expressions first test + ** if the index is pointing at a NULL row, and if so, read from the + ** table cursor instead. So ensure that the index cursor really is + ** pointing at a NULL row here, so that no values are read from it during + ** the scan of the RHS of the RIGHT join below. */ + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); + } pFrom = &uSrc.sSrc; pFrom->nSrc = 1; pFrom->nAlloc = 1; memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem)); pFrom->a[0].fg.jointype = 0; - assert( pParse->withinRJSubrtn < 100 ); + if( pParse->withinRJSubrtn >= 100 ){ + /* This limit --------------^^^ + ** is based on an historical assert(). It is not compile-time or + ** run-time configurable. It could perhaps be raised as high as 254, + ** but only an attack robot would ever do even 100 RIGHT JOINS within + ** a single query, so we'll just leave it as it is. */ + sqlite3ErrorMsg(pParse, "too many RIGHT JOINs"); + return; + } pParse->withinRJSubrtn++; pSubWInfo = sqlite3WhereBegin(pParse, pFrom, pSubWhere, 0, 0, 0, WHERE_RIGHT_JOIN, 0); if( pSubWInfo ){ - int iCur = pLevel->iTabCur; - int r = ++pParse->nMem; - int nPk; - int jmp; + int iCur = pLevel->iTabCur; /* Table on RHS of RIGHT JOIN &*/ + int r = ++pParse->nMem; /* Register range to hold primary key */ + int nPk; /* Number of values in the primary key */ + int r2; /* Register holding record for primary key */ int addrCont = sqlite3WhereContinueLabel(pSubWInfo); - Table *pTab = pTabItem->pSTab; + Table *pTab = pTabItem->pSTab; /* Table on RHS of RIGHT JOIN */ if( HasRowid(pTab) ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); nPk = 1; @@ -164708,11 +167670,31 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); } } - jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); - VdbeCoverage(v); + + /* Generate code that checks to see if the current row of the RHS table + ** has appeared in any prior output row. */ + if( pRJ->regBloom ){ + sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, + sqlite3VdbeCurrentAddr(v)+2, r, nPk); + VdbeCoverage(v); + } sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); VdbeCoverage(v); - sqlite3VdbeJumpHere(v, jmp); + r2 = sqlite3GetTempReg(pParse); + + /* Generate code that inserts the PK of the RHS table into the + ** pRH->iMatch index to indicate that the current row has appeared + ** in the output set. */ + sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, r2); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r2, r, nPk); + sqlite3ReleaseTempReg(pParse, r2); + if( pRJ->regBloom ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r, nPk); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + + /* Invoke the subroutine that actually puts the current RHS table row + ** into the output set, with NULLs for the LHS. */ sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); sqlite3WhereEnd(pSubWInfo); } @@ -164938,7 +167920,7 @@ static int isLikeOrGlob( if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ z = sqlite3_value_text(pVal); } - sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); + sqlite3VdbeReprepareOnBind(pParse->pVdbe, iCol, 0); assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ assert( !ExprHasProperty(pRight, EP_IntValue) ); @@ -165019,13 +168001,14 @@ static int isLikeOrGlob( ){ int isNum; double rDummy; - isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); + assert( zNew[iTo]==0 ); + isNum = sqlite3AtoF(zNew, &rDummy); if( isNum<=0 ){ if( iTo==1 && zNew[0]=='-' ){ isNum = +1; }else{ zNew[iTo-1]++; - isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); + isNum = sqlite3AtoF(zNew, &rDummy); zNew[iTo-1]--; } } @@ -165042,7 +168025,7 @@ static int isLikeOrGlob( ** reprepare the statement when that parameter is rebound */ if( op==TK_VARIABLE ){ Vdbe *v = pParse->pVdbe; - sqlite3VdbeSetVarmask(v, pRight->iColumn); + sqlite3VdbeReprepareOnBind(v, pRight->iColumn, 0); assert( !ExprHasProperty(pRight, EP_IntValue) ); if( *pisComplete && pRight->u.zToken[1] ){ /* If the rhs of the LIKE expression is a variable, and the current @@ -165068,6 +168051,34 @@ static int isLikeOrGlob( } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ +/* +** If pExpr is one of "like", "glob", "match", or "regexp", then +** return the corresponding SQLITE_INDEX_CONSTRAINT_xxxx value. +** If not, return 0. +** +** pExpr is guaranteed to be a TK_FUNCTION. +*/ +SQLITE_PRIVATE int sqlite3ExprIsLikeOperator(const Expr *pExpr){ + static const struct { + const char *zOp; + unsigned char eOp; + } aOp[] = { + { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, + { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, + { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, + { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } + }; + int i; + assert( pExpr->op==TK_FUNCTION ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + return aOp[i].eOp; + } + } + return 0; +} + #ifndef SQLITE_OMIT_VIRTUALTABLE /* @@ -165104,15 +168115,6 @@ static int isAuxiliaryVtabOperator( Expr **ppRight /* Expression to left of MATCH/op2 */ ){ if( pExpr->op==TK_FUNCTION ){ - static const struct Op2 { - const char *zOp; - unsigned char eOp2; - } aOp[] = { - { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, - { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, - { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, - { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } - }; ExprList *pList; Expr *pCol; /* Column reference */ int i; @@ -165132,16 +168134,11 @@ static int isAuxiliaryVtabOperator( */ pCol = pList->a[1].pExpr; assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); - if( ExprIsVtab(pCol) ){ - for(i=0; iu.zToken, aOp[i].zOp)==0 ){ - *peOp2 = aOp[i].eOp2; - *ppRight = pList->a[0].pExpr; - *ppLeft = pCol; - return 1; - } - } + if( ExprIsVtab(pCol) && (i = sqlite3ExprIsLikeOperator(pExpr))!=0 ){ + *peOp2 = i; + *ppRight = pList->a[0].pExpr; + *ppLeft = pCol; + return 1; } /* We can also match against the first column of overloaded @@ -165226,7 +168223,10 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ pWC->a[iChild].iParent = iParent; pWC->a[iChild].truthProb = pWC->a[iParent].truthProb; + assert( pWC->a[iParent].nChild < UMXV(pWC->a[0].nChild) ); pWC->a[iParent].nChild++; + testcase( pWC->a[iParent].nChild == UMXV(pWC->a[0].nChild) ); + } /* @@ -165275,16 +168275,22 @@ static void whereCombineDisjuncts( Expr *pNew; /* New virtual expression */ int op; /* Operator for the combined expression */ int idxNew; /* Index in pWC of the next virtual term */ + Expr *pA, *pB; /* Expressions associated with pOne and pTwo */ if( (pOne->wtFlags | pTwo->wtFlags) & TERM_VNULL ) return; if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; - assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 ); - assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 ); - if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; - if( sqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return; + pA = pOne->pExpr; + pB = pTwo->pExpr; + assert( pA->pLeft!=0 && pA->pRight!=0 ); + assert( pB->pLeft!=0 && pB->pRight!=0 ); + if( sqlite3ExprCompare(0,pA->pLeft, pB->pLeft, -1) ) return; + if( sqlite3ExprCompare(0,pA->pRight, pB->pRight,-1) ) return; + if( ExprHasProperty(pA,EP_Commuted)!=ExprHasProperty(pB,EP_Commuted) ){ + return; + } /* If we reach this point, it means the two subterms can be combined */ if( (eOp & (eOp-1))!=0 ){ if( eOp & (WO_LT|WO_LE) ){ @@ -165295,7 +168301,7 @@ static void whereCombineDisjuncts( } } db = pWC->pWInfo->pParse->db; - pNew = sqlite3ExprDup(db, pOne->pExpr, 0); + pNew = sqlite3ExprDup(db, pA, 0); if( pNew==0 ) return; for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( opop = op; @@ -165609,29 +168615,58 @@ static void exprAnalyzeOrTerm( } } - /* At this point, okToChngToIN is true if original pTerm satisfies - ** case 1. In that case, construct a new virtual term that is - ** pTerm converted into an IN operator. + /* At this point, okToChngToIN is true if original pTerm is a + ** candidate to satisfy case 1, though we are not yet certain that + ** the collating sequences are all compatible. Try to construct a + ** new virtual term that is pTerm converted from an OR operator + ** into an IN operator. + ** + ** During construction, verify that the collating sequences on all + ** subterms of the OR are compatible. Omit the construction of the + ** new IN operator if there are any collating sequence mismatches. */ if( okToChngToIN ){ Expr *pDup; /* A transient duplicate expression */ ExprList *pList = 0; /* The RHS of the IN operator */ Expr *pLeft = 0; /* The LHS of the IN operator */ + CollSeq *pCollSeq = 0; /* Collating sequence to use */ Expr *pNew; /* The complete IN operator */ for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ + Expr *pThis; if( (pOrTerm->wtFlags & TERM_OK)==0 ) continue; assert( pOrTerm->eOperator & WO_EQ ); assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); assert( pOrTerm->leftCursor==iCursor ); assert( pOrTerm->u.x.leftColumn==iColumn ); - pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); + pThis = pOrTerm->pExpr; + pDup = sqlite3ExprDup(db, pThis->pRight, 0); pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); - pLeft = pOrTerm->pExpr->pLeft; + if( pLeft==0 ){ + pLeft = pThis->pLeft; + pCollSeq = sqlite3ExprCompareCollSeq(pParse, pThis); + }else{ + assert( 0==sqlite3ExprCompare(pParse, + sqlite3ExprSkipCollate(pThis->pLeft), + sqlite3ExprSkipCollate(pLeft), -1) ); + if( pCollSeq!=sqlite3ExprCompareCollSeq(pParse, pThis) ){ + pLeft = 0; /* Collating sequence mismatch */ + break; + } + } + } + if( pLeft==0 ){ + pNew = 0; /* Collating sequence mismatch */ + }else{ + pDup = sqlite3ExprDup(db, pLeft, 0); + if( sqlite3ExprCollSeq(pParse, pDup)!=pCollSeq + && ALWAYS(pCollSeq!=0) + ){ + assert( pCollSeq->zName!=0 ); + pDup = sqlite3ExprAddCollateString(pParse, pDup, pCollSeq->zName); + } + pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0); } - assert( pLeft!=0 ); - pDup = sqlite3ExprDup(db, pLeft, 0); - pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0); if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); @@ -165659,8 +168694,8 @@ static void exprAnalyzeOrTerm( ** 3. Not originating in the ON clause of an OUTER JOIN ** 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 +** 6. Both operands use the same collating sequence, and they must not +** use explicit COLLATE clauses. ** 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 @@ -165668,10 +168703,9 @@ static void exprAnalyzeOrTerm( */ static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ char aff1, aff2; - CollSeq *pColl; 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) */ + if( ExprHasProperty(pExpr, EP_OuterON|EP_Collate) ) return 0; /* (3) */ assert( pSrc!=0 ); if( pExpr->op==TK_IS && pSrc->nSrc>=2 @@ -165686,10 +168720,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ ){ return 0; /* (5) */ } - pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); - if( !sqlite3IsBinary(pColl) - && !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) - ){ + if( !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) ){ return 0; /* (6) */ } return 1; @@ -165857,6 +168888,7 @@ static void exprAnalyze( pExpr = pTerm->pExpr; assert( pExpr!=0 ); /* Because malloc() has not failed */ assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); +exprAnalyze_restart: pMaskSet->bVarSelect = 0; prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); op = pExpr->op; @@ -166001,6 +169033,7 @@ static void exprAnalyze( pList = pExpr->x.pList; assert( pList!=0 ); assert( pList->nExpr==2 ); + assert( pWC->a[idxTerm].nChild==0 ); for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; @@ -166021,7 +169054,12 @@ static void exprAnalyze( /* Analyze a term that is composed of two or more subterms connected by ** an OR operator. */ - else if( pExpr->op==TK_OR ){ + else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){ + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + pTerm->pExpr = pExpr = sqlite3ExprSkipCollateAndLikely(pAlt); + goto exprAnalyze_restart; + } assert( pWC->op==TK_AND ); exprAnalyzeOrTerm(pSrc, pWC, idxTerm); pTerm = &pWC->a[idxTerm]; @@ -166210,9 +169248,13 @@ static void exprAnalyze( #ifndef SQLITE_OMIT_WINDOWFUNC && pExpr->x.pSelect->pWin==0 #endif + && (pExpr->x.pSelect->selFlags & SF_MinMaxAgg)==0 && pWC->op==TK_AND + && pExpr->x.pSelect->pEList->nExpr <= UMXV(pTerm->nChild) + /* ^-- See bug 2026-06-04T10:00:49Z */ ){ int i; + assert( pTerm->nChild==0 ); for(i=0; ipLeft); i++){ int idxNew; idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE); @@ -166334,14 +169376,12 @@ static void whereAddLimitExpr( Expr *pNew; int iVal = 0; - if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){ - Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); + if( sqlite3ExprIsInteger(pExpr, &iVal, pParse, 0) && iVal>=0 ){ + Expr *pVal = sqlite3ExprInt32(db, iVal); if( pVal==0 ) return; - ExprSetProperty(pVal, EP_IntValue); - pVal->u.iValue = iVal; pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); }else{ - Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0); + Expr *pVal = sqlite3ExprAlloc(db, TK_REGISTER, 0, 0); if( pVal==0 ) return; pVal->iTable = iReg; pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); @@ -166616,6 +169656,10 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( if( pItem->fg.isTabFunc==0 ) return; pTab = pItem->pSTab; assert( pTab!=0 ); + if( !IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "'%s' is not a function", pItem->zName); + return; + } pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; for(j=k=0; jnExpr; j++){ @@ -166650,6 +169694,16 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( } } +/* +** Return true if the WhereLoop pLoop can be use a Bloom filter. +** tag-202607231411 +*/ +SQLITE_PRIVATE int sqlite3WhereLoopBloomable(const WhereLoop *pLoop){ + if( pLoop->wsFlags & WHERE_IPK ) return 1; + if( NEVER((pLoop->wsFlags & WHERE_INDEXED)==0) ) return 0; + return sqlite3IndexBloomable(pLoop->u.btree.pIndex, pLoop->u.btree.nEq); +} + /************** End of whereexpr.c *******************************************/ /************** Begin file where.c *******************************************/ /* @@ -166817,7 +169871,7 @@ SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){ ** If the ONEPASS optimization is used (if this routine returns true) ** then also write the indices of open cursors used by ONEPASS ** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data -** table and iaCur[1] gets the cursor used by an auxiliary index. +** table and aiCur[1] gets the cursor used by an auxiliary index. ** Either value may be -1, indicating that cursor is not used. ** Any cursors returned will have been opened for writing. ** @@ -167661,7 +170715,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( Bitmask idxCols; /* Bitmap of columns used for indexing */ Bitmask extraCols; /* Bitmap of additional columns */ u8 sentWarning = 0; /* True if a warning has been issued */ - u8 useBloomFilter = 0; /* True to also add a Bloom filter */ + u8 useBloomFilter = 1; /* True to also add a Bloom filter */ Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ SrcList *pTabList; /* The complete FROM clause */ @@ -167788,18 +170842,13 @@ static SQLITE_NOINLINE void constructAutomaticIndex( pIdx->aiColumn[n] = pTerm->u.x.leftColumn; pColl = sqlite3ExprCompareCollSeq(pParse, pX); assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ + if( !sqlite3IsBinary(pColl) ){ + /* Disallow the use of a Bloom filter if any non-BINARY collating + ** sequence is involved. tag-202607231411 */ + useBloomFilter = 0; + } pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; n++; - if( ALWAYS(pX->pLeft!=0) - && sqlite3ExprAffinity(pX->pLeft)!=SQLITE_AFF_TEXT - ){ - /* TUNING: only use a Bloom filter on an automatic index - ** if one or more key columns has the ability to hold numeric - ** values, since strings all have the same hash in the Bloom - ** filter implementation and hence a Bloom filter on a text column - ** is not usually helpful. */ - useBloomFilter = 1; - } } } } @@ -167869,6 +170918,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0 ); if( pLevel->regFilter ){ + assert( sqlite3WhereLoopBloomable(pLoop) ); sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, regBase, pLoop->u.btree.nEq); } @@ -167909,9 +170959,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** for pLevel. ** ** If there are inner loops within pLevel that have the WHERE_BLOOMFILTER -** flag set, initialize a Bloomfilter for them as well. Except don't do -** this recursive initialization if the SQLITE_BloomPulldown optimization has -** been turned off. +** flag set, initialize a Bloomfilter for them as well. ** ** When the Bloom filter is initialized, the WHERE_BLOOMFILTER flag is cleared ** from the loop, but the regFilter value is set to a register that implements @@ -167984,6 +171032,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( }else if( sz>10000000 ){ sz = 10000000; } + assert( sqlite3WhereLoopBloomable(pLoop) ); sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter); addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); @@ -168006,6 +171055,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( int n = pLoop->u.btree.nEq; int r1 = sqlite3GetTempRange(pParse, n); int jj; + assert( pIdx!=0 ); for(jj=0; jjpTable==pItem->pSTab ); sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); @@ -168018,7 +171068,6 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrTop); pLoop->wsFlags &= ~WHERE_BLOOMFILTER; - if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break; while( ++iLevel < pWInfo->nLevel ){ const SrcItem *pTabItem; pLevel = &pWInfo->a[iLevel]; @@ -168168,11 +171217,14 @@ static sqlite3_index_info *allocateIndexInfo( break; } if( i==n ){ + int bSortByGroup = (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0; nOrderBy = n; if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) && !pSrc->fg.rowidUsed ){ - eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); + eDistinct = 2 + bSortByGroup; }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ - eDistinct = 1; + eDistinct = 1 - bSortByGroup; + }else if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ + eDistinct = 3; } } } @@ -169100,11 +172152,16 @@ SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ WhereInfo *pWInfo; if( pWC ){ + int nb; + SrcItem *pItem; + Table *pTab; + Bitmask mAll; + pWInfo = pWC->pWInfo; - int nb = 1+(pWInfo->pTabList->nSrc+3)/4; - SrcItem *pItem = pWInfo->pTabList->a + p->iTab; - Table *pTab = pItem->pSTab; - Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; + nb = 1+(pWInfo->pTabList->nSrc+3)/4; + pItem = pWInfo->pTabList->a + p->iTab; + pTab = pItem->pSTab; + mAll = (((Bitmask)1)<<(nb*4)) - 1; sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); sqlite3DebugPrintf(" %12s", @@ -169583,6 +172640,67 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ return rc; } +/* +** Callback for estLikePatternLength(). +** +** If this node is a string literal that is longer pWalker->sz, then set +** pWalker->sz to the byte length of that string literal. +** +** pWalker->eCode indicates how to count characters: +** +** eCode==0 Count as a GLOB pattern +** eCode==1 Count as a LIKE pattern +*/ +static int exprNodePatternLengthEst(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_STRING ){ + int sz = 0; /* Pattern size in bytes */ + u8 *z = (u8*)pExpr->u.zToken; /* The pattern */ + u8 c; /* Next character of the pattern */ + u8 c1, c2, c3; /* Wildcards */ + if( pWalker->eCode ){ + c1 = '%'; + c2 = '_'; + c3 = 0; + }else{ + c1 = '*'; + c2 = '?'; + c3 = '['; + } + while( (c = *(z++))!=0 ){ + if( c==c3 ){ + if( *z ) z++; + while( *z && *z!=']' ) z++; + }else if( c!=c1 && c!=c2 ){ + sz++; + } + } + if( sz>pWalker->u.sz ) pWalker->u.sz = sz; + } + return WRC_Continue; +} + +/* +** Return the length of the longest string literal in the given +** expression. +** +** eCode indicates how to count characters: +** +** eCode==0 Count as a GLOB pattern +** eCode==1 Count as a LIKE pattern +*/ +static int estLikePatternLength(Expr *p, u16 eCode){ + Walker w; + w.u.sz = 0; + w.eCode = eCode; + w.xExprCallback = exprNodePatternLengthEst; + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + sqlite3WalkExpr(&w, p); + return w.u.sz; +} + /* ** Adjust the WhereLoop.nOut value downward to account for terms of the ** WHERE clause that reference the loop but which are not used by an @@ -169611,6 +172729,13 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ ** "x" column is boolean or else -1 or 0 or 1 is a common default value ** on the "x" column and so in that case only cap the output row estimate ** at 1/2 instead of 1/4. +** +** Heuristic 3: If there is a LIKE or GLOB (or REGEXP or MATCH) operator +** with a large constant pattern, then reduce the size of the search +** space according to the length of the pattern, under the theory that +** longer patterns are less likely to match. This heuristic was added +** to give better output-row count estimates when preparing queries for +** the Join-Order Benchmarks. See forum thread 2026-01-30T09:57:54z */ static void whereLoopOutputAdjust( WhereClause *pWC, /* The WHERE clause */ @@ -169622,6 +172747,13 @@ static void whereLoopOutputAdjust( int i, j; LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ + /* Skip all this if the FROM clause of the query is a single table and + ** there is no ORDER BY. In this case it doesn't matter how accurate + ** the WhereLoop.nOut values are. */ + if( pWC->pWInfo->pTabList->nSrc<=1 && pWC->pWInfo->pOrderBy==0 ){ + return; + } + assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ assert( pTerm!=0 ); @@ -169660,14 +172792,16 @@ static void whereLoopOutputAdjust( }else{ /* In the absence of explicit truth probabilities, use heuristics to ** guess a reasonable truth probability. */ + Expr *pOpExpr = pTerm->pExpr; pLoop->nOut--; if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ ){ - Expr *pRight = pTerm->pExpr->pRight; + Expr *pRight = pOpExpr->pRight; + Parse *pParse = pWC->pWInfo->pParse; int k = 0; - testcase( pTerm->pExpr->op==TK_IS ); - if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ + testcase( pOpExpr->op==TK_IS ); + if( sqlite3ExprIsInteger(pRight, &k, pParse, 1) && k>=(-1) && k<=1 ){ k = 10; }else{ k = 20; @@ -169676,6 +172810,23 @@ static void whereLoopOutputAdjust( pTerm->wtFlags |= TERM_HEURTRUTH; iReduce = k; } + }else + if( ExprHasProperty(pOpExpr, EP_InfixFunc) + && pOpExpr->op==TK_FUNCTION + ){ + int eOp; + assert( ExprUseXList(pOpExpr) ); + assert( pOpExpr->x.pList->nExpr>=2 ); + eOp = sqlite3ExprIsLikeOperator(pOpExpr); + if( ALWAYS(eOp>0) ){ + int szPattern; + Expr *pRHS = pOpExpr->x.pList->a[0].pExpr; + eOp = eOp==SQLITE_INDEX_CONSTRAINT_LIKE; + szPattern = estLikePatternLength(pRHS, eOp); + if( szPattern>0 ){ + pLoop->nOut -= szPattern*2; + } + } } } } @@ -169747,6 +172898,7 @@ static int whereRangeVectorLen( idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); if( aff!=idxaff ) break; + if( ExprHasProperty(pTerm->pExpr, EP_Commuted) ) SWAP(Expr*, pRhs, pLhs); pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); if( pColl==0 ) break; if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; @@ -170136,6 +173288,7 @@ static int whereLoopAddBtreeIndex( pNew->rRun += nInMul + nIn; pNew->nOut += nInMul + nIn; whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize); + if( pSrc->fg.fromExists ) pNew->nOut = 0; rc = whereLoopInsert(pBuilder, pNew); if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ @@ -170731,7 +173884,14 @@ static int whereLoopAddBtree( whereLoopOutputAdjust(pWC, pNew, rSize); if( pSrc->fg.isSubquery ){ if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; - pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; + /* Do not set btree.pOrderBy for a recursive CTE. In this case + ** the ORDER BY clause does not determine the overall order that + ** rows are emitted from the CTE in. */ + if( (pSrc->u4.pSubq->pSelect->selFlags & SF_Recursive)==0 ){ + pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; + } + }else if( pSrc->fg.fromExists ){ + pNew->nOut = 0; } rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; @@ -170834,6 +173994,7 @@ static int whereLoopAddBtree( ** positioned to the correct row during the right-join no-match ** loop. */ }else{ + if( pSrc->fg.fromExists ) pNew->nOut = 0; rc = whereLoopInsert(pBuilder, pNew); } pNew->nOut = rSize; @@ -171496,7 +174657,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ sqlite3 *db = pWInfo->pParse->db; int rc = SQLITE_OK; int bFirstPastRJ = 0; - int hasRightJoin = 0; + int hasRightCrossJoin = 0; WhereLoop *pNew; @@ -171523,22 +174684,41 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ ** prevents the right operand of a RIGHT JOIN from being swapped with ** other elements even further to the right. ** - ** The JT_LTORJ case and the hasRightJoin flag work together to - ** prevent FROM-clause terms from moving from the right side of - ** a LEFT JOIN over to the left side of that join if the LEFT JOIN - ** is itself on the left side of a RIGHT JOIN. + ** The hasRightCrossJoin flag prevent FROM-clause terms from moving + ** from the right side of a LEFT JOIN or CROSS JOIN over to the + ** left side of that same join. This is a required restriction in + ** the case of LEFT JOIN - an incorrect answer may results if it is + ** not enforced. This restriction is not required for CROSS JOIN. + ** It is provided merely as a means of controlling join order, under + ** the theory that no real-world queries that care about performance + ** actually use the CROSS JOIN syntax. */ - if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1; + if( pItem->fg.jointype & (JT_LTORJ|JT_CROSS) ){ + testcase( pItem->fg.jointype & JT_LTORJ ); + testcase( pItem->fg.jointype & JT_CROSS ); + hasRightCrossJoin = 1; + } mPrereq |= mPrior; bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; - }else if( !hasRightJoin ){ + }else if( pItem->fg.fromExists ){ + /* joins that result from the EXISTS-to-JOIN optimization should not + ** be moved to the left of any of their dependencies */ + WhereClause *pWC = &pWInfo->sWC; + WhereTerm *pTerm; + int i; + for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ + if( (pNew->maskSelf & pTerm->prereqAll)!=0 ){ + mPrereq |= (pTerm->prereqAll & (pNew->maskSelf-1)); + } + } + }else if( !hasRightCrossJoin ){ mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pSTab) ){ SrcItem *p; for(p=&pItem[1]; pfg.jointype & (JT_OUTER|JT_CROSS)) ){ + if( (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); } } @@ -171607,13 +174787,13 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ ** direction because there is no way to run a co-routine backwards. */ static SQLITE_NOINLINE int wherePathMatchSubqueryOB( - WhereInfo *pWInfo, /* The WHERE clause */ WhereLoop *pLoop, /* The nested loop term that is a subquery */ int iLoop, /* Which level of the nested loop. 0==outermost */ int iCur, /* Cursor used by the this loop */ ExprList *pOrderBy, /* The ORDER BY clause on the whole query */ Bitmask *pRevMask, /* When loops need to go in reverse order */ - Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */ + Bitmask *pOBSat, /* Which terms of pOrderBy are satisfied so far */ + u16 wctrlFlags /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */ ){ int iOB; /* Index into pOrderBy->a[] */ int jSub; /* Index into pSubOB->a[] */ @@ -171631,7 +174811,7 @@ static SQLITE_NOINLINE int wherePathMatchSubqueryOB( if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break; if( pOBExpr->iTable!=iCur ) break; if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break; - if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ + if( (wctrlFlags & WHERE_GROUPBY)==0 ){ u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */ u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */ if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){ @@ -171754,9 +174934,7 @@ static i8 wherePathSatisfiesOrderBy( pLoop = pLast; } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ - if( pLoop->u.vtab.isOrdered - && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY) - ){ + if( pLoop->u.vtab.isOrdered && pWInfo->pOrderBy==pOrderBy ){ obSat = obDone; }else{ /* No further ORDER BY terms may be matched. So this call should @@ -171793,12 +174971,20 @@ static i8 wherePathSatisfiesOrderBy( if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ Parse *pParse = pWInfo->pParse; CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[i].pExpr); - CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr); + const Expr *pCExpr = pTerm->pExpr; + CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pCExpr); + char affRight; assert( pColl1 ); if( pColl2==0 || sqlite3StrICmp(pColl1->zName, pColl2->zName) ){ continue; } - testcase( pTerm->pExpr->op==TK_IS ); + affRight = sqlite3ExprAffinity(pCExpr->pRight); + /* Left operand must be a column, hence always has affinity */ + assert( sqlite3ExprAffinity(pCExpr->pLeft)!=0 ); + if( affRight!=0 && affRight!=sqlite3ExprAffinity(pCExpr->pLeft) ){ + continue; /* An affinity conversion would be required */ + } + testcase( pCExpr->op==TK_IS ); } obSat |= MASKBIT(i); } @@ -171807,8 +174993,8 @@ static i8 wherePathSatisfiesOrderBy( if( pLoop->wsFlags & WHERE_IPK ){ if( pLoop->u.btree.pOrderBy && OptimizationEnabled(db, SQLITE_OrderBySubq) - && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur, - pOrderBy,pRevMask, &obSat) + && wherePathMatchSubqueryOB(pLoop,iLoop,iCur, + pOrderBy,pRevMask, &obSat, wctrlFlags) ){ nColumn = 0; isOrderDistinct = 0; @@ -172132,12 +175318,21 @@ static LogEst whereSortingCost( ** 12 otherwise ** ** For the purposes of this heuristic, a star-query is defined as a query -** with a large central table that is joined using an INNER JOIN, -** not CROSS or OUTER JOINs, against four or more smaller tables. -** The central table is called the "fact" table. The smaller tables -** that get joined are "dimension tables". Also, any table that is -** self-joined cannot be a dimension table; we assume that dimension -** tables may only be joined against fact tables. +** with a central "fact" table that is joined against multiple +** "dimension" tables, subject to the following constraints: +** +** (aa) Only a five-way or larger join is considered for this +** optimization. If there are fewer than four terms in the FROM +** clause, this heuristic does not apply. +** +** (bb) The join between the fact table and the dimension tables must +** be an INNER join. CROSS and OUTER JOINs do not qualify. +** +** (cc) A table must have 3 or more dimension tables in order to be +** considered a fact table. (Was 4 prior to 2026-02-10.) +** +** (dd) A table that is a self-join cannot be a dimension table. +** Dimension tables are joined against fact tables. ** ** SIDE EFFECT: (and really the whole point of this subroutine) ** @@ -172190,7 +175385,7 @@ static int computeMxChoice(WhereInfo *pWInfo){ } #endif /* SQLITE_DEBUG */ - if( nLoop>=5 + if( nLoop>=4 /* Constraint (aa) */ && !pWInfo->bStarDone && OptimizationEnabled(pWInfo->pParse->db, SQLITE_StarQuery) ){ @@ -172202,7 +175397,7 @@ static int computeMxChoice(WhereInfo *pWInfo){ pWInfo->bStarDone = 1; /* Only do this computation once */ - /* Look for fact tables with four or more dimensions where the + /* Look for fact tables with three or more dimensions where the ** dimension tables are not separately from the fact tables by an outer ** or cross join. Adjust cost weights if found. */ @@ -172219,18 +175414,17 @@ static int computeMxChoice(WhereInfo *pWInfo){ if( (pFactTab->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){ /* If the candidate fact-table is the right table of an outer join ** restrict the search for dimension-tables to be tables to the right - ** of the fact-table. */ - if( iFromIdx+4 > nLoop ) break; /* Impossible to reach nDep>=4 */ + ** of the fact-table. Constraint (bb) */ + if( iFromIdx+3 > nLoop ){ + break; /* ^-- Impossible to reach nDep>=2 - Constraint (cc) */ + } while( pStart && pStart->iTab<=iFromIdx ){ pStart = pStart->pNextLoop; } } for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){ if( (aFromTabs[pWLoop->iTab].fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){ - /* Fact-tables and dimension-tables cannot be separated by an - ** outer join (at least for the definition of fact- and dimension- - ** used by this heuristic). */ - break; + break; /* Constraint (bb) */ } if( (pWLoop->prereq & m)!=0 /* pWInfo depends on iFromIdx */ && (pWLoop->maskSelf & mSeen)==0 /* pWInfo not already a dependency */ @@ -172244,7 +175438,9 @@ static int computeMxChoice(WhereInfo *pWInfo){ } } } - if( nDep<=3 ) continue; + if( nDep<=2 ){ + continue; /* Constraint (cc) */ + } /* If we reach this point, it means that pFactTab is a fact table ** with four or more dimensions connected by inner joins. Proceed @@ -172257,6 +175453,23 @@ static int computeMxChoice(WhereInfo *pWInfo){ pWLoop->rStarDelta = 0; } } +#endif +#ifdef WHERETRACE_ENABLED /* 0x80000 */ + if( sqlite3WhereTrace & 0x80000 ){ + Bitmask mShow = mSeen; + sqlite3DebugPrintf("Fact table %s(%d), dimensions:", + pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName, + iFromIdx); + for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( mShow & pWLoop->maskSelf ){ + SrcItem *pDim = aFromTabs + pWLoop->iTab; + mShow &= ~pWLoop->maskSelf; + sqlite3DebugPrintf(" %s(%d)", + pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab); + } + } + sqlite3DebugPrintf("\n"); + } #endif pWInfo->bStarUsed = 1; @@ -172280,10 +175493,8 @@ static int computeMxChoice(WhereInfo *pWInfo){ if( sqlite3WhereTrace & 0x80000 ){ SrcItem *pDim = aFromTabs + pWLoop->iTab; sqlite3DebugPrintf( - "Increase SCAN cost of dimension %s(%d) of fact %s(%d) to %d\n", - pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab, - pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName, - iFromIdx, mxRun + "Increase SCAN cost of %s to %d\n", + pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, mxRun ); } pWLoop->rStarDelta = mxRun - pWLoop->rRun; @@ -173097,6 +176308,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ pTerm->wtFlags |= TERM_CODED; + pTerm->prereqAll = 0; } } if( i!=pWInfo->nLevel-1 ){ @@ -173144,19 +176356,17 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( pTab->tabFlags |= TF_MaybeReanalyze; if( i>=1 && (pLoop->wsFlags & reqFlags)==reqFlags - /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ - && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) + && sqlite3WhereLoopBloomable(pLoop) + && nSearch > pTab->nRowLogEst ){ - if( nSearch > pTab->nRowLogEst ){ - testcase( pItem->fg.jointype & JT_LEFT ); - pLoop->wsFlags |= WHERE_BLOOMFILTER; - pLoop->wsFlags &= ~WHERE_IDX_ONLY; - WHERETRACE(0xffffffff, ( - "-> use Bloom-filter on loop %c because there are ~%.1e " - "lookups into %s which has only ~%.1e rows\n", - pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, - (double)sqlite3LogEstToInt(pTab->nRowLogEst))); - } + testcase( pItem->fg.jointype & JT_LEFT ); + pLoop->wsFlags |= WHERE_BLOOMFILTER; + pLoop->wsFlags &= ~WHERE_IDX_ONLY; + WHERETRACE(0xffffffff, ( + "-> use Bloom-filter on loop %c because there are ~%.1e " + "lookups into %s which has only ~%.1e rows\n", + pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, + (double)sqlite3LogEstToInt(pTab->nRowLogEst))); } nSearch += pLoop->nOut; } @@ -173812,8 +177022,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( sqlite3VdbeChangeP5(v, bFordelete); } #ifdef SQLITE_ENABLE_COLUMN_USED_MASK - sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, - (const u8*)&pTabItem->colUsed, P4_INT64); + sqlite3VdbeAddOp3(v, OP_ColumnsUsed, pTabItem->iCursor, + LOWER32(pTabItem->colUsed), UPPER32(pTabItem->colUsed)); #endif if( ii>=2 && (pTabItem[0].fg.jointype & (JT_LTORJ|JT_LEFT))==0 @@ -173890,10 +177100,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue; colUsed |= ((u64)1)<<(ii<63 ? ii : 63); } - sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, - (u8*)&colUsed, P4_INT64); + sqlite3VdbeAddOp3(v, OP_ColumnsUsed, iIndexCur, + LOWER32(colUsed),UPPER32(colUsed)); } #endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ +#ifdef SQLITE_ENABLE_CURSOR_HINTS + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_CursorHint, iIndexCur, 0, pTabItem->iCursor); + } +#endif } } if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); @@ -173901,15 +177116,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0 ){ WhereRightJoin *pRJ = pLevel->pRJ; + int bBloomable = 0; pRJ->iMatch = pParse->nTab++; - pRJ->regBloom = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); assert( pTab==pTabItem->pSTab ); if( HasRowid(pTab) ){ KeyInfo *pInfo; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); + bBloomable = 1; pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0); if( pInfo ){ pInfo->aColl[0] = 0; @@ -173920,6 +177135,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( Index *pPk = sqlite3PrimaryKeyIndex(pTab); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol); sqlite3VdbeSetP4KeyInfo(pParse, pPk); + bBloomable = sqlite3IndexBloomable(pPk,pPk->nKeyCol); + } + if( bBloomable ){ + pRJ->regBloom = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); + }else{ + pRJ->regBloom = 0; } pLoop->wsFlags &= ~WHERE_IDX_ONLY; /* The nature of RIGHT JOIN processing is such that it messes up @@ -174072,6 +177294,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ){ int r1 = pParse->nMem+1; int j, op; + int addrIfNull = 0; /* Init to avoid false-positive compiler warning */ + if( pLevel->iLeftJoin ){ + addrIfNull = sqlite3VdbeAddOp2(v, OP_IfNullRow, pLevel->iIdxCur, r1); + } for(j=0; jiIdxCur, j, r1+j); } @@ -174081,25 +177307,17 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeCoverageIf(v, op==OP_SeekLT); VdbeCoverageIf(v, op==OP_SeekGT); sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); + if( pLevel->iLeftJoin ){ + sqlite3VdbeJumpHere(v, addrIfNull); + } } #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ } - if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){ - /* If the EXISTS-to-JOIN optimization was applied, then the EXISTS - ** loop(s) will be the inner-most loops of the join. There might be - ** multiple EXISTS loops, but they will all be nested, and the join - ** order will not have been changed by the query planner. If the - ** inner-most EXISTS loop sees a single successful row, it should - ** break out of *all* EXISTS loops. But only the inner-most of the - ** nested EXISTS loops should do this breakout. */ - int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */ - while( nOutera[pLevel[-nOuter-1].iFrom].fg.fromExists ) break; - nOuter++; - } - testcase( nOuter>0 ); - sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk); - VdbeComment((v, "EXISTS break")); + if( pTabList->a[pLevel->iFrom].fg.fromExists ){ + /* This is an EXISTS-to-JOIN optimization loop. If this loop sees a + ** successful row, it should break out of itself. */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); + VdbeComment((v, "EXISTS break %d", i)); } sqlite3VdbeResolveLabel(v, pLevel->addrCont); if( pLevel->op!=OP_Noop ){ @@ -174109,17 +177327,17 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeCoverageIf(v, pLevel->op==OP_Next); VdbeCoverageIf(v, pLevel->op==OP_Prev); VdbeCoverageIf(v, pLevel->op==OP_VNext); - if( pLevel->regBignull ){ - sqlite3VdbeResolveLabel(v, pLevel->addrBignull); - sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); - VdbeCoverage(v); - } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ){ sqlite3VdbeJumpHere(v, addrSeek); addrSeek = 0; } #endif + if( pLevel->regBignull ){ + sqlite3VdbeResolveLabel(v, pLevel->addrBignull); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); + VdbeCoverage(v); + } } if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ struct InLoop *pIn; @@ -174135,16 +177353,14 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0; if( pLevel->iLeftJoin ){ - /* For LEFT JOIN queries, cursor pIn->iCur may not have been - ** opened yet. This occurs for WHERE clauses such as - ** "a = ? AND b IN (...)", where the index is on (a, b). If - ** the RHS of the (a=?) is NULL, then the "b IN (...)" may - ** never have been coded, but the body of the loop run to - ** return the null-row. So, if the cursor is not open yet, - ** jump over the OP_Next or OP_Prev instruction about to - ** be coded. */ - sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, - sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut); + /* For LEFT JOIN queries, cursor pIn->iCur might have been + ** disabled by OP_NullRow. This occurs for WHERE clauses such + ** as "a = ? AND b IN (...)", where the index is on (a, b). + ** When the OP_IfNullRow jump is taken, the pIn->iBase register + ** is NULLed out as a side effect. But as that register is not + ** used when the jump is taken, the side-effect is harmless. */ + sqlite3VdbeAddOp3(v, OP_IfNullRow, pIn->iCur, + sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut, pIn->iBase); VdbeCoverage(v); } if( bEarlyOut ){ @@ -174213,6 +177429,15 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ } sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); } + if( ws & WHERE_IN_ABLE ){ + int m; + for(m=0; mu.in.nIn; m++){ + struct InLoop *pIn = &pLevel->u.in.aInLoop[m]; + if( pIn->eEndLoopOp!=OP_Noop ){ + sqlite3VdbeAddOp1(v, OP_NullRow, pIn->iCur); + } + } + } if( pLevel->op==OP_Return ){ sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); }else{ @@ -174621,7 +177846,7 @@ static void nth_valueStepFunc( break; case SQLITE_FLOAT: { double fVal = sqlite3_value_double(apArg[1]); - if( ((i64)fVal)!=fVal ) goto error_out; + if( sqlite3RealToI64(fVal)!=fVal ) goto error_out; iVal = (i64)fVal; break; } @@ -174746,6 +177971,7 @@ static void percent_rankInvFunc( UNUSED_PARAMETER(nArg); assert( nArg==0 ); UNUSED_PARAMETER(apArg); p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + assert( p!=0 ); p->nStep++; } static void percent_rankValueFunc(sqlite3_context *pCtx){ @@ -174791,6 +178017,7 @@ static void cume_distInvFunc( UNUSED_PARAMETER(nArg); assert( nArg==0 ); UNUSED_PARAMETER(apArg); p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + assert( p!=0 ); p->nStep++; } static void cume_distValueFunc(sqlite3_context *pCtx){ @@ -174847,6 +178074,7 @@ static void ntileInvFunc( assert( nArg==1 ); UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(apArg); p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + assert( p!=0 ); p->iRow++; } static void ntileValueFunc(sqlite3_context *pCtx){ @@ -175116,7 +178344,7 @@ SQLITE_PRIVATE void sqlite3WindowUpdate( pWin->eEnd = aUp[i].eEnd; pWin->eExclude = 0; if( pWin->eStart==TK_FOLLOWING ){ - pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1"); + pWin->pStart = sqlite3ExprInt32(db, 1); } break; } @@ -175204,7 +178432,9 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); } if( p->pSub ){ - int f = pExpr->flags & EP_Collate; + int f = pExpr->flags & (EP_Collate|EP_OuterON|EP_InnerON); + int iJoin = pExpr->w.iJoin; + assert( ExprHasProperty(pExpr, EP_Static)==0 ); ExprSetProperty(pExpr, EP_Static); sqlite3ExprDelete(pParse->db, pExpr); @@ -175216,6 +178446,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ pExpr->iTable = p->pWin->iEphCsr; pExpr->y.pTab = p->pTab; pExpr->flags = f; + if( (f & (EP_OuterON|EP_InnerON)) ) pExpr->w.iJoin = iJoin; } if( pParse->db->mallocFailed ) return WRC_Abort; break; @@ -175308,7 +178539,7 @@ static ExprList *exprListAppendList( int iDummy; Expr *pSub; pSub = sqlite3ExprSkipCollateAndLikely(pDup); - if( sqlite3ExprIsInteger(pSub, &iDummy, 0) ){ + if( sqlite3ExprIsInteger(pSub, &iDummy, 0, 0) ){ pSub->op = TK_NULL; pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); pSub->u.zToken = 0; @@ -175461,9 +178692,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ ** keep everything legal in this case. */ if( pSublist==0 ){ - pSublist = sqlite3ExprListAppend(pParse, 0, - sqlite3Expr(db, TK_INTEGER, "0") - ); + pSublist = sqlite3ExprListAppend(pParse, 0, sqlite3ExprInt32(db, 0)); } pSub = sqlite3SelectNew( @@ -177689,8 +180918,23 @@ static void updateDeleteLimitError( ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate ** testing. */ - static void *parserStackRealloc(void *pOld, sqlite3_uint64 newSize){ - return sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); + static void *parserStackRealloc( + void *pOld, /* Prior allocation */ + sqlite3_uint64 newSize, /* Requested new alloation size */ + Parse *pParse /* Parsing context */ + ){ + void *p = sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); + if( p==0 ) sqlite3OomFault(pParse->db); + return p; + } + static void parserStackFree(void *pOld, Parse *pParse){ + (void)pParse; + sqlite3_free(pOld); + } + + /* Return an integer that is the maximum allowed stack size */ + static int parserStackSizeLimit(Parse *pParse){ + return pParse->db->aLimit[SQLITE_LIMIT_PARSER_DEPTH]; } @@ -177729,15 +180973,46 @@ static void updateDeleteLimitError( } - /* A routine to convert a binary TK_IS or TK_ISNOT expression into a - ** unary TK_ISNULL or TK_NOTNULL expression. */ - static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ - sqlite3 *db = pParse->db; - if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){ - pA->op = (u8)op; - sqlite3ExprDelete(db, pA->pRight); - pA->pRight = 0; + /* Create a TK_ISNULL or TK_NOTNULL expression, perhaps optimized to + ** to TK_TRUEFALSE, if possible */ + static Expr *sqlite3PExprIsNull( + Parse *pParse, /* Parsing context */ + int op, /* TK_ISNULL or TK_NOTNULL */ + Expr *pLeft /* Operand */ + ){ + Expr *p = pLeft; + assert( op==TK_ISNULL || op==TK_NOTNULL ); + assert( pLeft!=0 ); + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ + p = p->pLeft; + assert( p!=0 ); } + switch( p->op ){ + case TK_INTEGER: + case TK_STRING: + case TK_FLOAT: + case TK_BLOB: + sqlite3ExprDeferredDelete(pParse, pLeft); + return sqlite3ExprInt32(pParse->db, op==TK_NOTNULL); + default: + break; + } + return sqlite3PExpr(pParse, op, pLeft, 0); + } + + /* Create a TK_IS or TK_ISNOT operator, perhaps optimized to + ** TK_ISNULL or TK_NOTNULL or TK_TRUEFALSE. */ + static Expr *sqlite3PExprIs( + Parse *pParse, /* Parsing context */ + int op, /* TK_IS or TK_ISNOT */ + Expr *pLeft, /* Left operand */ + Expr *pRight /* Right operand */ + ){ + if( pRight && pRight->op==TK_NULL ){ + sqlite3ExprDeferredDelete(pParse, pRight); + return sqlite3PExprIsNull(pParse, op==TK_IS ? TK_ISNULL : TK_NOTNULL, pLeft); + } + return sqlite3PExpr(pParse, op, pLeft, pRight); } /* Add a single new term to an ExprList that is used to store a @@ -178020,63 +181295,72 @@ static void updateDeleteLimitError( #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 323 +#define YYNOCODE 322 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 102 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - u32 yy9; - struct TrigEvent yy28; - With* yy125; - IdList* yy204; - struct FrameBound yy205; - TriggerStep* yy319; - const char* yy342; - Cte* yy361; - ExprList* yy402; - Upsert* yy403; - OnOrUsing yy421; - u8 yy444; - struct {int value; int mask;} yy481; - Window* yy483; - int yy502; - SrcList* yy563; - Expr* yy590; - Select* yy637; + ExprList* yy14; + With* yy59; + Cte* yy67; + Upsert* yy122; + IdList* yy132; + int yy144; + const char* yy168; + SrcList* yy203; + Window* yy211; + OnOrUsing yy269; + struct TrigEvent yy286; + struct {int value; int mask;} yy383; + u32 yy391; + TriggerStep* yy427; + Expr* yy454; + u8 yy462; + struct FrameBound yy509; + Select* yy555; } YYMINORTYPE; #ifndef YYSTACKDEPTH -#define YYSTACKDEPTH 100 +#define YYSTACKDEPTH 50 #endif #define sqlite3ParserARG_SDECL #define sqlite3ParserARG_PDECL #define sqlite3ParserARG_PARAM #define sqlite3ParserARG_FETCH #define sqlite3ParserARG_STORE +#undef YYREALLOC #define YYREALLOC parserStackRealloc -#define YYFREE sqlite3_free +#undef YYFREE +#define YYFREE parserStackFree +#undef YYDYNSTACK #define YYDYNSTACK 1 +#undef YYSIZELIMIT +#define YYSIZELIMIT parserStackSizeLimit +#define sqlite3ParserCTX(P) ((P)->pParse) #define sqlite3ParserCTX_SDECL Parse *pParse; #define sqlite3ParserCTX_PDECL ,Parse *pParse #define sqlite3ParserCTX_PARAM ,pParse #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; +#undef YYERRORSYMBOL +#undef YYERRSYMDT +#undef YYFALLBACK #define YYFALLBACK 1 -#define YYNSTATE 587 -#define YYNRULE 409 -#define YYNRULE_WITH_ACTION 344 +#define YYNSTATE 604 +#define YYNRULE 412 +#define YYNRULE_WITH_ACTION 348 #define YYNTOKEN 187 -#define YY_MAX_SHIFT 586 -#define YY_MIN_SHIFTREDUCE 849 -#define YY_MAX_SHIFTREDUCE 1257 -#define YY_ERROR_ACTION 1258 -#define YY_ACCEPT_ACTION 1259 -#define YY_NO_ACTION 1260 -#define YY_MIN_REDUCE 1261 -#define YY_MAX_REDUCE 1669 +#define YY_MAX_SHIFT 603 +#define YY_MIN_SHIFTREDUCE 871 +#define YY_MAX_SHIFTREDUCE 1282 +#define YY_ERROR_ACTION 1283 +#define YY_ACCEPT_ACTION 1284 +#define YY_NO_ACTION 1285 +#define YY_MIN_REDUCE 1286 +#define YY_MAX_REDUCE 1697 #define YY_MIN_DSTRCTR 206 -#define YY_MAX_DSTRCTR 320 +#define YY_MAX_DSTRCTR 319 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -178159,643 +181443,682 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2207) +#define YY_ACTTAB_COUNT (2379) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 130, 127, 234, 282, 282, 1332, 580, 1311, 464, 289, - /* 10 */ 289, 580, 1626, 385, 580, 1332, 577, 580, 566, 417, - /* 20 */ 1304, 1546, 577, 485, 566, 528, 464, 463, 562, 82, - /* 30 */ 82, 987, 294, 379, 51, 51, 502, 61, 61, 988, - /* 40 */ 82, 82, 1581, 137, 138, 91, 7, 1232, 1232, 1067, - /* 50 */ 1070, 1057, 1057, 135, 135, 136, 136, 136, 136, 417, - /* 60 */ 288, 288, 182, 288, 288, 485, 540, 288, 288, 130, - /* 70 */ 127, 234, 436, 577, 529, 566, 577, 561, 566, 1294, - /* 80 */ 577, 425, 566, 137, 138, 91, 563, 1232, 1232, 1067, - /* 90 */ 1070, 1057, 1057, 135, 135, 136, 136, 136, 136, 296, - /* 100 */ 464, 402, 1253, 134, 134, 134, 134, 133, 133, 132, - /* 110 */ 132, 132, 131, 128, 455, 455, 1054, 1054, 1068, 1071, - /* 120 */ 1259, 1, 1, 586, 2, 1263, 585, 1178, 1263, 1178, - /* 130 */ 321, 417, 155, 321, 1588, 155, 383, 112, 485, 1345, - /* 140 */ 460, 299, 1345, 134, 134, 134, 134, 133, 133, 132, - /* 150 */ 132, 132, 131, 128, 455, 137, 138, 91, 502, 1232, - /* 160 */ 1232, 1067, 1070, 1057, 1057, 135, 135, 136, 136, 136, - /* 170 */ 136, 1208, 866, 1285, 288, 288, 283, 288, 288, 527, - /* 180 */ 527, 1254, 139, 582, 7, 582, 1349, 577, 1173, 566, - /* 190 */ 577, 1058, 566, 136, 136, 136, 136, 129, 577, 551, - /* 200 */ 566, 1173, 245, 1545, 1173, 245, 133, 133, 132, 132, - /* 210 */ 132, 131, 128, 455, 302, 134, 134, 134, 134, 133, - /* 220 */ 133, 132, 132, 132, 131, 128, 455, 1579, 1208, 1209, - /* 230 */ 1208, 7, 474, 554, 459, 417, 554, 459, 130, 127, - /* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132, - /* 250 */ 131, 128, 455, 136, 136, 136, 136, 542, 487, 137, - /* 260 */ 138, 91, 1023, 1232, 1232, 1067, 1070, 1057, 1057, 135, - /* 270 */ 135, 136, 136, 136, 136, 1089, 580, 1208, 132, 132, - /* 280 */ 132, 131, 128, 455, 93, 214, 134, 134, 134, 134, - /* 290 */ 133, 133, 132, 132, 132, 131, 128, 455, 405, 19, - /* 300 */ 19, 134, 134, 134, 134, 133, 133, 132, 132, 132, - /* 310 */ 131, 128, 455, 1502, 430, 267, 348, 471, 334, 134, - /* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128, - /* 330 */ 455, 1285, 580, 6, 1208, 1209, 1208, 257, 580, 417, - /* 340 */ 515, 512, 511, 1283, 94, 1023, 468, 1208, 555, 555, - /* 350 */ 510, 1228, 1575, 44, 38, 51, 51, 415, 580, 417, - /* 360 */ 45, 51, 51, 137, 138, 91, 534, 1232, 1232, 1067, - /* 370 */ 1070, 1057, 1057, 135, 135, 136, 136, 136, 136, 402, - /* 380 */ 1152, 82, 82, 137, 138, 91, 39, 1232, 1232, 1067, - /* 390 */ 1070, 1057, 1057, 135, 135, 136, 136, 136, 136, 348, - /* 400 */ 44, 288, 288, 379, 1208, 1209, 1208, 209, 1208, 1228, - /* 410 */ 320, 571, 475, 580, 577, 580, 566, 580, 316, 264, - /* 420 */ 231, 46, 160, 134, 134, 134, 134, 133, 133, 132, - /* 430 */ 132, 132, 131, 128, 455, 303, 82, 82, 82, 82, - /* 440 */ 82, 82, 446, 134, 134, 134, 134, 133, 133, 132, - /* 450 */ 132, 132, 131, 128, 455, 1586, 548, 320, 571, 1254, - /* 460 */ 878, 1586, 384, 386, 417, 1208, 1209, 1208, 364, 182, - /* 470 */ 288, 288, 1580, 561, 1343, 561, 7, 561, 1281, 476, - /* 480 */ 350, 530, 535, 577, 560, 566, 443, 1515, 137, 138, - /* 490 */ 91, 219, 1232, 1232, 1067, 1070, 1057, 1057, 135, 135, - /* 500 */ 136, 136, 136, 136, 469, 1515, 1517, 536, 417, 288, - /* 510 */ 288, 427, 516, 288, 288, 415, 288, 288, 878, 130, - /* 520 */ 127, 234, 577, 1111, 566, 1208, 577, 1111, 566, 577, - /* 530 */ 564, 566, 137, 138, 91, 1297, 1232, 1232, 1067, 1070, - /* 540 */ 1057, 1057, 135, 135, 136, 136, 136, 136, 134, 134, - /* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 455, - /* 560 */ 497, 507, 1296, 1208, 257, 288, 288, 515, 512, 511, - /* 570 */ 1208, 1632, 1173, 123, 572, 275, 4, 510, 577, 1515, - /* 580 */ 566, 331, 1208, 1209, 1208, 1173, 552, 552, 1173, 261, - /* 590 */ 575, 7, 134, 134, 134, 134, 133, 133, 132, 132, - /* 600 */ 132, 131, 128, 455, 108, 537, 130, 127, 234, 1208, - /* 610 */ 452, 451, 417, 1455, 456, 987, 890, 96, 1602, 1237, - /* 620 */ 1208, 1209, 1208, 988, 1239, 1454, 569, 1208, 1209, 1208, - /* 630 */ 229, 526, 1238, 538, 1337, 1337, 137, 138, 91, 1453, - /* 640 */ 1232, 1232, 1067, 1070, 1057, 1057, 135, 135, 136, 136, - /* 650 */ 136, 136, 377, 1599, 975, 1044, 417, 1240, 422, 1240, - /* 660 */ 883, 121, 121, 952, 377, 1599, 1208, 1209, 1208, 122, - /* 670 */ 1208, 456, 581, 456, 367, 421, 1032, 886, 377, 1599, - /* 680 */ 137, 138, 91, 466, 1232, 1232, 1067, 1070, 1057, 1057, - /* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134, - /* 700 */ 133, 133, 132, 132, 132, 131, 128, 455, 1032, 1032, - /* 710 */ 1034, 1035, 35, 574, 574, 574, 197, 427, 1044, 198, - /* 720 */ 1208, 123, 572, 1208, 4, 320, 571, 1208, 1209, 1208, - /* 730 */ 40, 392, 580, 388, 886, 1033, 427, 1192, 575, 1032, - /* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, - /* 750 */ 128, 455, 533, 1572, 1208, 19, 19, 1208, 579, 496, - /* 760 */ 417, 157, 456, 493, 1191, 1335, 1335, 5, 1208, 953, - /* 770 */ 435, 1032, 1032, 1034, 569, 22, 22, 1208, 1209, 1208, - /* 780 */ 1208, 1209, 1208, 481, 137, 138, 91, 212, 1232, 1232, - /* 790 */ 1067, 1070, 1057, 1057, 135, 135, 136, 136, 136, 136, - /* 800 */ 1192, 48, 111, 1044, 417, 1208, 213, 974, 1045, 121, - /* 810 */ 121, 1208, 1209, 1208, 1208, 1209, 1208, 122, 221, 456, - /* 820 */ 581, 456, 44, 491, 1032, 1208, 1209, 1208, 137, 138, - /* 830 */ 91, 382, 1232, 1232, 1067, 1070, 1057, 1057, 135, 135, - /* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133, - /* 850 */ 132, 132, 132, 131, 128, 455, 1032, 1032, 1034, 1035, - /* 860 */ 35, 465, 1208, 1209, 1208, 1573, 1044, 381, 214, 1153, - /* 870 */ 1661, 539, 1661, 441, 906, 320, 571, 1572, 368, 320, - /* 880 */ 571, 416, 329, 1033, 523, 1192, 3, 1032, 134, 134, - /* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 455, - /* 900 */ 1663, 403, 1173, 307, 897, 307, 519, 580, 417, 214, - /* 910 */ 502, 948, 1028, 544, 907, 1173, 947, 396, 1173, 1032, - /* 920 */ 1032, 1034, 410, 298, 1208, 50, 1153, 1662, 417, 1662, - /* 930 */ 145, 145, 137, 138, 91, 293, 1232, 1232, 1067, 1070, - /* 940 */ 1057, 1057, 135, 135, 136, 136, 136, 136, 1192, 1151, - /* 950 */ 518, 1572, 137, 138, 91, 1509, 1232, 1232, 1067, 1070, - /* 960 */ 1057, 1057, 135, 135, 136, 136, 136, 136, 438, 323, - /* 970 */ 439, 543, 111, 1510, 274, 291, 376, 521, 371, 520, - /* 980 */ 262, 1208, 1209, 1208, 1578, 485, 367, 580, 7, 1573, - /* 990 */ 1572, 381, 134, 134, 134, 134, 133, 133, 132, 132, - /* 1000 */ 132, 131, 128, 455, 1572, 580, 1151, 580, 232, 580, - /* 1010 */ 19, 19, 134, 134, 134, 134, 133, 133, 132, 132, - /* 1020 */ 132, 131, 128, 455, 1173, 437, 580, 1211, 19, 19, - /* 1030 */ 19, 19, 19, 19, 1631, 580, 915, 1173, 47, 120, - /* 1040 */ 1173, 117, 417, 306, 502, 442, 1129, 206, 340, 19, - /* 1050 */ 19, 1439, 49, 453, 453, 453, 1372, 315, 81, 81, - /* 1060 */ 580, 304, 417, 1574, 207, 381, 137, 138, 91, 115, - /* 1070 */ 1232, 1232, 1067, 1070, 1057, 1057, 135, 135, 136, 136, - /* 1080 */ 136, 136, 580, 82, 82, 1211, 137, 138, 91, 1344, - /* 1090 */ 1232, 1232, 1067, 1070, 1057, 1057, 135, 135, 136, 136, - /* 1100 */ 136, 136, 1573, 390, 381, 82, 82, 467, 1130, 1556, - /* 1110 */ 337, 467, 339, 131, 128, 455, 1573, 161, 381, 16, - /* 1120 */ 317, 391, 432, 1131, 452, 451, 134, 134, 134, 134, - /* 1130 */ 133, 133, 132, 132, 132, 131, 128, 455, 1132, 580, - /* 1140 */ 1109, 10, 449, 267, 580, 1558, 134, 134, 134, 134, - /* 1150 */ 133, 133, 132, 132, 132, 131, 128, 455, 536, 580, - /* 1160 */ 926, 580, 19, 19, 580, 1577, 580, 147, 147, 7, - /* 1170 */ 927, 1240, 502, 1240, 580, 491, 417, 556, 285, 1228, - /* 1180 */ 973, 215, 82, 82, 66, 66, 1439, 67, 67, 21, - /* 1190 */ 21, 1114, 1114, 499, 338, 297, 417, 53, 53, 297, - /* 1200 */ 137, 138, 91, 119, 1232, 1232, 1067, 1070, 1057, 1057, - /* 1210 */ 135, 135, 136, 136, 136, 136, 417, 1340, 1315, 450, - /* 1220 */ 137, 138, 91, 227, 1232, 1232, 1067, 1070, 1057, 1057, - /* 1230 */ 135, 135, 136, 136, 136, 136, 578, 1228, 940, 940, - /* 1240 */ 137, 126, 91, 141, 1232, 1232, 1067, 1070, 1057, 1057, - /* 1250 */ 135, 135, 136, 136, 136, 136, 537, 433, 476, 350, - /* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, - /* 1270 */ 128, 455, 580, 461, 233, 347, 1439, 407, 502, 1554, - /* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, - /* 1290 */ 128, 455, 580, 324, 580, 82, 82, 491, 580, 973, - /* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, - /* 1310 */ 128, 455, 288, 288, 550, 68, 68, 54, 54, 557, - /* 1320 */ 417, 69, 69, 355, 6, 577, 948, 566, 414, 413, - /* 1330 */ 1439, 947, 454, 549, 260, 259, 258, 580, 158, 580, - /* 1340 */ 417, 222, 1184, 483, 973, 138, 91, 434, 1232, 1232, - /* 1350 */ 1067, 1070, 1057, 1057, 135, 135, 136, 136, 136, 136, - /* 1360 */ 70, 70, 71, 71, 580, 1130, 91, 580, 1232, 1232, - /* 1370 */ 1067, 1070, 1057, 1057, 135, 135, 136, 136, 136, 136, - /* 1380 */ 1131, 166, 854, 855, 856, 1286, 423, 72, 72, 108, - /* 1390 */ 73, 73, 1314, 362, 1184, 1132, 580, 305, 580, 123, - /* 1400 */ 572, 498, 4, 492, 134, 134, 134, 134, 133, 133, - /* 1410 */ 132, 132, 132, 131, 128, 455, 575, 568, 538, 55, - /* 1420 */ 55, 56, 56, 580, 134, 134, 134, 134, 133, 133, - /* 1430 */ 132, 132, 132, 131, 128, 455, 580, 1108, 233, 1108, - /* 1440 */ 456, 1606, 586, 2, 1263, 580, 57, 57, 580, 321, - /* 1450 */ 580, 155, 569, 1439, 489, 357, 580, 360, 1345, 59, - /* 1460 */ 59, 580, 44, 973, 573, 423, 580, 238, 60, 60, - /* 1470 */ 261, 74, 74, 75, 75, 287, 231, 580, 1370, 76, - /* 1480 */ 76, 1044, 424, 184, 20, 20, 580, 121, 121, 77, - /* 1490 */ 77, 97, 218, 288, 288, 122, 125, 456, 581, 456, - /* 1500 */ 143, 143, 1032, 580, 524, 580, 577, 580, 566, 144, - /* 1510 */ 144, 478, 227, 1248, 482, 123, 572, 580, 4, 320, - /* 1520 */ 571, 245, 415, 580, 447, 415, 78, 78, 62, 62, - /* 1530 */ 79, 79, 575, 319, 1032, 1032, 1034, 1035, 35, 422, - /* 1540 */ 63, 63, 580, 290, 415, 9, 80, 80, 1148, 580, - /* 1550 */ 404, 580, 490, 459, 580, 1227, 456, 580, 325, 346, - /* 1560 */ 580, 111, 580, 1192, 242, 64, 64, 477, 569, 580, - /* 1570 */ 23, 580, 170, 170, 171, 171, 580, 87, 87, 328, - /* 1580 */ 65, 65, 546, 83, 83, 146, 146, 545, 123, 572, - /* 1590 */ 345, 4, 84, 84, 168, 168, 580, 1044, 580, 148, - /* 1600 */ 148, 580, 1384, 121, 121, 575, 1025, 580, 266, 580, - /* 1610 */ 428, 122, 580, 456, 581, 456, 580, 557, 1032, 142, - /* 1620 */ 142, 169, 169, 580, 162, 162, 532, 893, 375, 456, - /* 1630 */ 152, 152, 151, 151, 1383, 149, 149, 109, 374, 150, - /* 1640 */ 150, 569, 580, 484, 580, 266, 86, 86, 580, 1096, - /* 1650 */ 1032, 1032, 1034, 1035, 35, 546, 486, 580, 266, 470, - /* 1660 */ 547, 123, 572, 1620, 4, 88, 88, 85, 85, 479, - /* 1670 */ 1044, 52, 52, 222, 905, 904, 121, 121, 575, 1192, - /* 1680 */ 58, 58, 244, 1036, 122, 893, 456, 581, 456, 912, - /* 1690 */ 913, 1032, 300, 351, 508, 111, 263, 365, 165, 111, - /* 1700 */ 111, 1092, 456, 263, 978, 1157, 266, 1096, 990, 991, - /* 1710 */ 946, 943, 125, 125, 569, 1107, 876, 1107, 159, 945, - /* 1720 */ 1313, 125, 1561, 1032, 1032, 1034, 1035, 35, 546, 341, - /* 1730 */ 1534, 205, 1533, 545, 503, 1593, 494, 352, 1380, 356, - /* 1740 */ 359, 1036, 361, 1044, 363, 1328, 1312, 370, 567, 121, - /* 1750 */ 121, 380, 1192, 1393, 1438, 1366, 280, 122, 1378, 456, - /* 1760 */ 581, 456, 167, 1443, 1032, 1293, 1284, 1272, 1271, 1273, - /* 1770 */ 1613, 1363, 312, 313, 314, 401, 12, 237, 224, 1425, - /* 1780 */ 295, 333, 336, 1430, 343, 488, 344, 513, 1375, 1616, - /* 1790 */ 1376, 1429, 1248, 408, 301, 228, 1032, 1032, 1034, 1035, - /* 1800 */ 35, 1605, 1196, 458, 349, 1311, 292, 373, 1506, 1505, - /* 1810 */ 270, 400, 400, 399, 277, 397, 1374, 1373, 863, 1553, - /* 1820 */ 186, 123, 572, 235, 4, 1192, 395, 210, 211, 223, - /* 1830 */ 1551, 239, 1245, 327, 426, 96, 220, 195, 575, 140, - /* 1840 */ 557, 326, 180, 472, 1420, 332, 188, 1413, 335, 570, - /* 1850 */ 190, 191, 192, 193, 473, 506, 247, 109, 1434, 495, - /* 1860 */ 251, 199, 456, 406, 480, 1426, 13, 409, 102, 14, - /* 1870 */ 501, 1511, 241, 1432, 569, 1431, 203, 92, 95, 1500, - /* 1880 */ 175, 281, 358, 43, 504, 253, 411, 254, 522, 1331, - /* 1890 */ 104, 1274, 1522, 354, 440, 1322, 255, 1330, 1630, 1629, - /* 1900 */ 240, 897, 229, 1044, 444, 1321, 445, 448, 269, 121, - /* 1910 */ 121, 1329, 531, 268, 310, 412, 1398, 122, 1301, 456, - /* 1920 */ 581, 456, 1300, 372, 1032, 1299, 1628, 378, 311, 90, - /* 1930 */ 572, 11, 4, 1397, 1598, 418, 1487, 389, 116, 110, - /* 1940 */ 320, 571, 1584, 559, 318, 541, 575, 1583, 42, 1354, - /* 1950 */ 387, 583, 216, 1353, 1202, 276, 1032, 1032, 1034, 1035, - /* 1960 */ 35, 393, 394, 278, 462, 279, 419, 584, 1538, 1269, - /* 1970 */ 456, 1264, 172, 420, 173, 1539, 1537, 1536, 156, 308, - /* 1980 */ 225, 89, 569, 850, 226, 1192, 457, 174, 217, 236, - /* 1990 */ 322, 154, 1106, 1104, 187, 330, 176, 1227, 929, 189, - /* 2000 */ 243, 342, 246, 1120, 194, 177, 178, 429, 431, 98, - /* 2010 */ 196, 1044, 99, 185, 100, 101, 179, 121, 121, 1123, - /* 2020 */ 248, 249, 1119, 163, 250, 122, 24, 456, 581, 456, - /* 2030 */ 1196, 458, 1032, 353, 292, 266, 1112, 200, 1242, 400, - /* 2040 */ 400, 399, 277, 397, 500, 252, 863, 201, 292, 15, - /* 2050 */ 865, 558, 505, 400, 400, 399, 277, 397, 374, 239, - /* 2060 */ 863, 327, 256, 202, 1032, 1032, 1034, 1035, 35, 326, - /* 2070 */ 103, 25, 26, 239, 509, 327, 366, 514, 369, 895, - /* 2080 */ 908, 517, 105, 326, 309, 164, 525, 106, 181, 27, - /* 2090 */ 1189, 1073, 17, 1192, 107, 1159, 1158, 284, 230, 286, - /* 2100 */ 241, 204, 125, 1175, 982, 265, 1182, 976, 175, 28, - /* 2110 */ 1179, 43, 29, 1177, 241, 30, 31, 8, 1183, 32, - /* 2120 */ 1164, 41, 175, 208, 553, 43, 111, 33, 240, 1087, - /* 2130 */ 1074, 113, 114, 1072, 1076, 34, 1077, 565, 1128, 118, - /* 2140 */ 271, 36, 240, 18, 939, 1037, 877, 272, 124, 37, - /* 2150 */ 398, 1198, 1197, 576, 183, 273, 153, 1621, 1260, 1260, - /* 2160 */ 1260, 1260, 1260, 418, 1260, 1260, 1260, 1260, 320, 571, - /* 2170 */ 1260, 1260, 1260, 1260, 1260, 1260, 1260, 418, 1260, 1260, - /* 2180 */ 1260, 1260, 320, 571, 1260, 1260, 1260, 1260, 1260, 1260, - /* 2190 */ 1260, 1260, 462, 1260, 1260, 1260, 1260, 1260, 1260, 1260, - /* 2200 */ 1260, 1260, 1260, 1260, 1260, 1260, 462, + /* 0 */ 134, 131, 238, 290, 290, 1357, 597, 1336, 482, 1610, + /* 10 */ 597, 1319, 597, 7, 597, 1357, 594, 597, 583, 428, + /* 20 */ 1570, 134, 131, 238, 1322, 545, 482, 481, 579, 84, + /* 30 */ 84, 1009, 303, 84, 84, 51, 51, 63, 63, 1010, + /* 40 */ 84, 84, 502, 141, 142, 93, 446, 1258, 1258, 1089, + /* 50 */ 1092, 1079, 1079, 139, 139, 140, 140, 140, 140, 428, + /* 60 */ 296, 296, 502, 296, 296, 571, 557, 296, 296, 1310, + /* 70 */ 578, 1362, 1362, 594, 546, 583, 594, 578, 583, 552, + /* 80 */ 594, 1308, 583, 141, 142, 93, 580, 1258, 1258, 1089, + /* 90 */ 1092, 1079, 1079, 139, 139, 140, 140, 140, 140, 403, + /* 100 */ 482, 399, 6, 138, 138, 138, 138, 137, 137, 136, + /* 110 */ 136, 136, 135, 132, 467, 44, 342, 597, 305, 1131, + /* 120 */ 1284, 1, 1, 603, 2, 1288, 602, 1204, 1288, 1204, + /* 130 */ 330, 428, 158, 330, 1617, 158, 394, 116, 308, 1370, + /* 140 */ 51, 51, 1370, 138, 138, 138, 138, 137, 137, 136, + /* 150 */ 136, 136, 135, 132, 467, 141, 142, 93, 519, 1258, + /* 160 */ 1258, 1089, 1092, 1079, 1079, 139, 139, 140, 140, 140, + /* 170 */ 140, 1234, 329, 588, 296, 296, 212, 296, 296, 572, + /* 180 */ 572, 492, 143, 1076, 1076, 1090, 1093, 594, 1199, 583, + /* 190 */ 594, 340, 583, 140, 140, 140, 140, 133, 396, 568, + /* 200 */ 540, 1199, 250, 429, 1199, 250, 137, 137, 136, 136, + /* 210 */ 136, 135, 132, 467, 291, 138, 138, 138, 138, 137, + /* 220 */ 137, 136, 136, 136, 135, 132, 467, 970, 1234, 1235, + /* 230 */ 1234, 416, 969, 471, 416, 428, 471, 493, 361, 1615, + /* 240 */ 395, 138, 138, 138, 138, 137, 137, 136, 136, 136, + /* 250 */ 135, 132, 467, 467, 134, 131, 238, 559, 1080, 141, + /* 260 */ 142, 93, 597, 1258, 1258, 1089, 1092, 1079, 1079, 139, + /* 270 */ 139, 140, 140, 140, 140, 1321, 134, 131, 238, 428, + /* 280 */ 553, 1601, 1535, 333, 97, 83, 83, 140, 140, 140, + /* 290 */ 140, 138, 138, 138, 138, 137, 137, 136, 136, 136, + /* 300 */ 135, 132, 467, 141, 142, 93, 1661, 1258, 1258, 1089, + /* 310 */ 1092, 1079, 1079, 139, 139, 140, 140, 140, 140, 138, + /* 320 */ 138, 138, 138, 137, 137, 136, 136, 136, 135, 132, + /* 330 */ 467, 595, 1234, 962, 962, 138, 138, 138, 138, 137, + /* 340 */ 137, 136, 136, 136, 135, 132, 467, 44, 402, 551, + /* 350 */ 1310, 136, 136, 136, 135, 132, 467, 390, 597, 446, + /* 360 */ 599, 145, 599, 138, 138, 138, 138, 137, 137, 136, + /* 370 */ 136, 136, 135, 132, 467, 504, 1234, 112, 554, 464, + /* 380 */ 463, 51, 51, 428, 296, 296, 483, 334, 1263, 1234, + /* 390 */ 1235, 1234, 1603, 1265, 392, 312, 448, 594, 246, 583, + /* 400 */ 550, 1264, 271, 235, 329, 588, 555, 141, 142, 93, + /* 410 */ 433, 1258, 1258, 1089, 1092, 1079, 1079, 139, 139, 140, + /* 420 */ 140, 140, 140, 22, 22, 1234, 1266, 428, 1266, 216, + /* 430 */ 296, 296, 98, 1234, 1235, 1234, 264, 888, 45, 532, + /* 440 */ 529, 528, 1045, 594, 1273, 583, 425, 424, 397, 527, + /* 450 */ 44, 141, 142, 93, 502, 1258, 1258, 1089, 1092, 1079, + /* 460 */ 1079, 139, 139, 140, 140, 140, 140, 138, 138, 138, + /* 470 */ 138, 137, 137, 136, 136, 136, 135, 132, 467, 597, + /* 480 */ 1615, 565, 1234, 1235, 1234, 23, 264, 519, 200, 532, + /* 490 */ 529, 528, 127, 589, 513, 4, 359, 491, 510, 527, + /* 500 */ 597, 502, 84, 84, 134, 131, 238, 329, 588, 592, + /* 510 */ 1631, 138, 138, 138, 138, 137, 137, 136, 136, 136, + /* 520 */ 135, 132, 467, 19, 19, 439, 1234, 1464, 297, 297, + /* 530 */ 311, 428, 1569, 468, 1635, 603, 2, 1288, 441, 578, + /* 540 */ 1111, 594, 330, 583, 158, 586, 493, 361, 577, 597, + /* 550 */ 596, 1370, 413, 1278, 1234, 141, 142, 93, 1368, 1258, + /* 560 */ 1258, 1089, 1092, 1079, 1079, 139, 139, 140, 140, 140, + /* 570 */ 140, 393, 84, 84, 1066, 571, 1234, 313, 1527, 597, + /* 580 */ 125, 125, 974, 1234, 1235, 1234, 296, 296, 126, 46, + /* 590 */ 468, 598, 468, 296, 296, 1054, 1234, 218, 443, 594, + /* 600 */ 1608, 583, 84, 84, 7, 407, 594, 519, 583, 325, + /* 610 */ 421, 1234, 1235, 1234, 250, 138, 138, 138, 138, 137, + /* 620 */ 137, 136, 136, 136, 135, 132, 467, 1054, 1054, 1056, + /* 630 */ 1057, 35, 1279, 1234, 1235, 1234, 428, 1374, 997, 578, + /* 640 */ 375, 418, 274, 416, 1601, 471, 1306, 556, 455, 594, + /* 650 */ 547, 583, 1534, 1234, 1235, 1234, 1218, 201, 413, 1178, + /* 660 */ 141, 142, 93, 223, 1258, 1258, 1089, 1092, 1079, 1079, + /* 670 */ 139, 139, 140, 140, 140, 140, 296, 296, 1254, 597, + /* 680 */ 428, 296, 296, 236, 533, 296, 296, 519, 100, 594, + /* 690 */ 1604, 583, 48, 1609, 594, 1234, 583, 7, 594, 581, + /* 700 */ 583, 908, 84, 84, 141, 142, 93, 500, 1258, 1258, + /* 710 */ 1089, 1092, 1079, 1079, 139, 139, 140, 140, 140, 140, + /* 720 */ 138, 138, 138, 138, 137, 137, 136, 136, 136, 135, + /* 730 */ 132, 467, 1369, 1234, 296, 296, 1254, 115, 1279, 326, + /* 740 */ 233, 543, 1066, 40, 282, 127, 589, 594, 4, 583, + /* 750 */ 329, 588, 1234, 1235, 1234, 1602, 597, 392, 908, 1055, + /* 760 */ 1360, 1360, 592, 1054, 138, 138, 138, 138, 137, 137, + /* 770 */ 136, 136, 136, 135, 132, 467, 185, 597, 1234, 19, + /* 780 */ 19, 1234, 975, 1601, 428, 1655, 468, 129, 912, 1199, + /* 790 */ 1234, 1235, 1234, 1329, 447, 1054, 1054, 1056, 586, 1607, + /* 800 */ 149, 149, 1199, 7, 5, 1199, 1691, 414, 141, 142, + /* 810 */ 93, 1540, 1258, 1258, 1089, 1092, 1079, 1079, 139, 139, + /* 820 */ 140, 140, 140, 140, 1218, 401, 597, 1066, 428, 1540, + /* 830 */ 1542, 50, 905, 125, 125, 1234, 1235, 1234, 1234, 1235, + /* 840 */ 1234, 126, 1234, 468, 598, 468, 519, 1234, 1054, 84, + /* 850 */ 84, 3, 141, 142, 93, 928, 1258, 1258, 1089, 1092, + /* 860 */ 1079, 1079, 139, 139, 140, 140, 140, 140, 138, 138, + /* 870 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 467, + /* 880 */ 1054, 1054, 1056, 1057, 35, 446, 461, 536, 437, 1234, + /* 890 */ 1066, 1365, 544, 544, 1602, 929, 392, 7, 1133, 1234, + /* 900 */ 1235, 1234, 1133, 1540, 1234, 1235, 1234, 1055, 574, 1218, + /* 910 */ 597, 1054, 138, 138, 138, 138, 137, 137, 136, 136, + /* 920 */ 136, 135, 132, 467, 6, 185, 1199, 1234, 231, 597, + /* 930 */ 386, 996, 428, 151, 151, 514, 1217, 561, 486, 1199, + /* 940 */ 385, 160, 1199, 1054, 1054, 1056, 1234, 1235, 1234, 426, + /* 950 */ 597, 451, 84, 84, 597, 217, 141, 142, 93, 597, + /* 960 */ 1258, 1258, 1089, 1092, 1079, 1079, 139, 139, 140, 140, + /* 970 */ 140, 140, 1218, 19, 19, 597, 428, 19, 19, 446, + /* 980 */ 1067, 446, 19, 19, 1234, 1235, 1234, 519, 449, 462, + /* 990 */ 1601, 390, 315, 1179, 1689, 560, 1689, 454, 84, 84, + /* 1000 */ 141, 142, 93, 509, 1258, 1258, 1089, 1092, 1079, 1079, + /* 1010 */ 139, 139, 140, 140, 140, 140, 138, 138, 138, 138, + /* 1020 */ 137, 137, 136, 136, 136, 135, 132, 467, 446, 1151, + /* 1030 */ 458, 1601, 366, 1045, 597, 466, 1464, 1237, 47, 1397, + /* 1040 */ 324, 569, 569, 115, 1152, 453, 7, 464, 463, 307, + /* 1050 */ 379, 358, 597, 113, 597, 329, 588, 19, 19, 1153, + /* 1060 */ 138, 138, 138, 138, 137, 137, 136, 136, 136, 135, + /* 1070 */ 132, 467, 209, 1177, 567, 19, 19, 19, 19, 49, + /* 1080 */ 428, 948, 1179, 1690, 1050, 1690, 218, 359, 488, 345, + /* 1090 */ 210, 949, 573, 566, 1266, 1237, 1266, 494, 314, 427, + /* 1100 */ 428, 1602, 1210, 392, 141, 142, 93, 444, 1258, 1258, + /* 1110 */ 1089, 1092, 1079, 1079, 139, 139, 140, 140, 140, 140, + /* 1120 */ 356, 316, 535, 316, 141, 142, 93, 553, 1258, 1258, + /* 1130 */ 1089, 1092, 1079, 1079, 139, 139, 140, 140, 140, 140, + /* 1140 */ 450, 10, 1602, 274, 392, 919, 281, 299, 387, 538, + /* 1150 */ 382, 537, 269, 597, 1210, 591, 591, 591, 378, 293, + /* 1160 */ 1583, 995, 1177, 302, 138, 138, 138, 138, 137, 137, + /* 1170 */ 136, 136, 136, 135, 132, 467, 53, 53, 524, 1254, + /* 1180 */ 597, 1151, 1580, 435, 138, 138, 138, 138, 137, 137, + /* 1190 */ 136, 136, 136, 135, 132, 467, 1152, 301, 597, 1581, + /* 1200 */ 597, 1311, 435, 54, 54, 597, 268, 597, 465, 465, + /* 1210 */ 465, 1153, 351, 496, 428, 135, 132, 467, 1150, 1199, + /* 1220 */ 478, 68, 68, 69, 69, 554, 332, 287, 21, 21, + /* 1230 */ 55, 55, 1199, 585, 428, 1199, 309, 1254, 141, 142, + /* 1240 */ 93, 119, 1258, 1258, 1089, 1092, 1079, 1079, 139, 139, + /* 1250 */ 140, 140, 140, 140, 597, 237, 484, 1480, 141, 142, + /* 1260 */ 93, 597, 1258, 1258, 1089, 1092, 1079, 1079, 139, 139, + /* 1270 */ 140, 140, 140, 140, 348, 434, 350, 70, 70, 498, + /* 1280 */ 995, 1136, 1136, 516, 56, 56, 1273, 597, 268, 597, + /* 1290 */ 373, 378, 597, 485, 215, 388, 1628, 485, 138, 138, + /* 1300 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 467, + /* 1310 */ 71, 71, 72, 72, 225, 73, 73, 597, 138, 138, + /* 1320 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 467, + /* 1330 */ 590, 435, 597, 876, 877, 878, 597, 915, 597, 1606, + /* 1340 */ 74, 74, 597, 7, 1464, 242, 597, 306, 428, 1582, + /* 1350 */ 476, 306, 368, 219, 371, 75, 75, 434, 349, 57, + /* 1360 */ 57, 58, 58, 436, 187, 59, 59, 597, 428, 61, + /* 1370 */ 61, 1479, 141, 142, 93, 123, 1258, 1258, 1089, 1092, + /* 1380 */ 1079, 1079, 139, 139, 140, 140, 140, 140, 428, 574, + /* 1390 */ 62, 62, 141, 142, 93, 915, 1258, 1258, 1089, 1092, + /* 1400 */ 1079, 1079, 139, 139, 140, 140, 140, 140, 161, 388, + /* 1410 */ 1628, 1478, 141, 130, 93, 445, 1258, 1258, 1089, 1092, + /* 1420 */ 1079, 1079, 139, 139, 140, 140, 140, 140, 267, 266, + /* 1430 */ 265, 1464, 138, 138, 138, 138, 137, 137, 136, 136, + /* 1440 */ 136, 135, 132, 467, 597, 1340, 597, 1273, 1464, 388, + /* 1450 */ 1628, 231, 138, 138, 138, 138, 137, 137, 136, 136, + /* 1460 */ 136, 135, 132, 467, 597, 163, 597, 76, 76, 77, + /* 1470 */ 77, 597, 138, 138, 138, 138, 137, 137, 136, 136, + /* 1480 */ 136, 135, 132, 467, 479, 597, 487, 78, 78, 20, + /* 1490 */ 20, 1253, 428, 495, 79, 79, 499, 426, 295, 235, + /* 1500 */ 1578, 38, 515, 900, 426, 335, 240, 426, 147, 147, + /* 1510 */ 112, 597, 428, 597, 101, 222, 995, 142, 93, 459, + /* 1520 */ 1258, 1258, 1089, 1092, 1079, 1079, 139, 139, 140, 140, + /* 1530 */ 140, 140, 597, 39, 148, 148, 80, 80, 93, 555, + /* 1540 */ 1258, 1258, 1089, 1092, 1079, 1079, 139, 139, 140, 140, + /* 1550 */ 140, 140, 328, 927, 926, 64, 64, 506, 1660, 1009, + /* 1560 */ 937, 900, 124, 426, 121, 254, 597, 1010, 597, 226, + /* 1570 */ 597, 127, 589, 164, 4, 16, 138, 138, 138, 138, + /* 1580 */ 137, 137, 136, 136, 136, 135, 132, 467, 592, 81, + /* 1590 */ 81, 65, 65, 82, 82, 597, 138, 138, 138, 138, + /* 1600 */ 137, 137, 136, 136, 136, 135, 132, 467, 597, 226, + /* 1610 */ 237, 970, 468, 597, 298, 597, 969, 597, 66, 66, + /* 1620 */ 597, 1174, 597, 415, 586, 357, 473, 115, 597, 475, + /* 1630 */ 169, 173, 173, 597, 44, 995, 174, 174, 89, 89, + /* 1640 */ 67, 67, 597, 85, 85, 150, 150, 1118, 1047, 597, + /* 1650 */ 273, 86, 86, 1066, 597, 507, 171, 171, 597, 125, + /* 1660 */ 125, 501, 597, 273, 336, 152, 152, 126, 1339, 468, + /* 1670 */ 598, 468, 146, 146, 1054, 597, 549, 172, 172, 597, + /* 1680 */ 1058, 165, 165, 256, 339, 156, 156, 127, 589, 1590, + /* 1690 */ 4, 329, 588, 503, 362, 273, 115, 352, 155, 155, + /* 1700 */ 934, 935, 153, 153, 592, 1118, 1054, 1054, 1056, 1057, + /* 1710 */ 35, 1558, 525, 597, 270, 1012, 1013, 9, 597, 376, + /* 1720 */ 597, 115, 597, 168, 597, 115, 597, 1114, 468, 270, + /* 1730 */ 1000, 968, 273, 129, 1649, 1218, 154, 154, 1058, 1408, + /* 1740 */ 586, 88, 88, 90, 90, 87, 87, 52, 52, 60, + /* 1750 */ 60, 1409, 508, 541, 563, 1183, 965, 511, 129, 562, + /* 1760 */ 127, 589, 1130, 4, 1130, 1129, 898, 1129, 162, 1066, + /* 1770 */ 967, 363, 129, 1405, 367, 125, 125, 592, 370, 372, + /* 1780 */ 374, 1353, 1338, 126, 1337, 468, 598, 468, 381, 391, + /* 1790 */ 1054, 1395, 1418, 1622, 1463, 1391, 1403, 208, 584, 1468, + /* 1800 */ 1318, 468, 243, 520, 1309, 1297, 1388, 1296, 1298, 1642, + /* 1810 */ 288, 170, 228, 586, 12, 412, 321, 322, 241, 323, + /* 1820 */ 245, 1450, 1054, 1054, 1056, 1057, 35, 563, 304, 354, + /* 1830 */ 355, 505, 564, 127, 589, 344, 4, 1455, 347, 310, + /* 1840 */ 1454, 530, 1066, 1336, 419, 384, 232, 1531, 125, 125, + /* 1850 */ 592, 1218, 1400, 360, 1530, 587, 126, 1401, 468, 598, + /* 1860 */ 468, 1645, 539, 1054, 1585, 1399, 1273, 1587, 1586, 213, + /* 1870 */ 406, 277, 214, 227, 468, 1577, 239, 1575, 1270, 1398, + /* 1880 */ 438, 198, 100, 224, 96, 144, 586, 1445, 574, 183, + /* 1890 */ 343, 191, 1438, 346, 489, 1054, 1054, 1056, 1057, 35, + /* 1900 */ 563, 193, 523, 194, 1451, 562, 195, 13, 196, 113, + /* 1910 */ 14, 490, 252, 417, 497, 1066, 1536, 1459, 1457, 202, + /* 1920 */ 1456, 125, 125, 99, 1218, 420, 512, 1525, 258, 126, + /* 1930 */ 106, 468, 598, 468, 1547, 518, 1054, 289, 365, 260, + /* 1940 */ 206, 521, 369, 422, 452, 261, 1356, 1299, 1355, 262, + /* 1950 */ 1347, 1354, 108, 919, 1346, 233, 456, 548, 457, 319, + /* 1960 */ 1659, 320, 423, 1658, 1627, 275, 276, 1423, 1054, 1054, + /* 1970 */ 1056, 1057, 35, 1634, 1222, 470, 1326, 1325, 300, 1613, + /* 1980 */ 383, 1324, 1657, 411, 411, 410, 284, 408, 389, 460, + /* 1990 */ 885, 1422, 1612, 127, 589, 1512, 4, 1218, 11, 400, + /* 2000 */ 120, 1379, 398, 247, 327, 338, 1378, 220, 114, 558, + /* 2010 */ 592, 42, 405, 337, 600, 404, 1228, 283, 285, 286, + /* 2020 */ 175, 601, 1294, 1289, 431, 159, 176, 1562, 1563, 872, + /* 2030 */ 1561, 1560, 317, 91, 468, 229, 230, 469, 221, 177, + /* 2040 */ 472, 331, 1169, 474, 249, 94, 586, 477, 95, 189, + /* 2050 */ 244, 1128, 178, 1126, 341, 43, 190, 432, 179, 192, + /* 2060 */ 188, 1253, 951, 353, 1142, 180, 251, 197, 181, 440, + /* 2070 */ 182, 102, 248, 103, 442, 1066, 104, 199, 1144, 253, + /* 2080 */ 255, 125, 125, 105, 1141, 166, 24, 257, 364, 126, + /* 2090 */ 273, 468, 598, 468, 1268, 517, 1054, 259, 204, 15, + /* 2100 */ 1134, 92, 589, 522, 4, 887, 263, 430, 203, 385, + /* 2110 */ 205, 526, 329, 588, 107, 576, 25, 26, 592, 377, + /* 2120 */ 531, 917, 380, 109, 534, 930, 318, 184, 1054, 1054, + /* 2130 */ 1056, 1057, 35, 167, 27, 110, 480, 542, 111, 1215, + /* 2140 */ 1095, 1185, 468, 17, 1184, 292, 234, 294, 272, 1004, + /* 2150 */ 207, 129, 998, 28, 586, 1201, 1203, 1218, 1190, 29, + /* 2160 */ 41, 30, 1205, 31, 8, 1209, 1208, 32, 570, 34, + /* 2170 */ 211, 115, 1109, 33, 1096, 1094, 1098, 1099, 278, 582, + /* 2180 */ 122, 117, 1149, 1066, 118, 36, 18, 593, 1059, 125, + /* 2190 */ 125, 899, 128, 37, 186, 961, 157, 126, 409, 468, + /* 2200 */ 598, 468, 1222, 470, 1054, 1224, 300, 1223, 1285, 279, + /* 2210 */ 280, 411, 411, 410, 284, 408, 1650, 1285, 885, 1285, + /* 2220 */ 300, 1285, 1285, 575, 1285, 411, 411, 410, 284, 408, + /* 2230 */ 1285, 247, 885, 338, 1285, 1285, 1054, 1054, 1056, 1057, + /* 2240 */ 35, 337, 1285, 1285, 1285, 247, 1285, 338, 1285, 1285, + /* 2250 */ 1285, 1285, 1285, 1285, 1285, 337, 1285, 1285, 1285, 1285, + /* 2260 */ 1285, 1285, 1285, 1285, 1285, 1218, 1285, 1285, 1285, 1285, + /* 2270 */ 1285, 1285, 249, 1285, 1285, 1285, 1285, 1285, 1285, 1285, + /* 2280 */ 178, 1285, 1285, 43, 1285, 1285, 249, 1285, 1285, 1285, + /* 2290 */ 1285, 1285, 1285, 1285, 178, 1285, 1285, 43, 1285, 1285, + /* 2300 */ 248, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, + /* 2310 */ 1285, 1285, 1285, 1285, 248, 1285, 1285, 1285, 1285, 1285, + /* 2320 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, + /* 2330 */ 1285, 1285, 1285, 1285, 1285, 430, 1285, 1285, 1285, 1285, + /* 2340 */ 329, 588, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 430, + /* 2350 */ 1285, 1285, 1285, 1285, 329, 588, 1285, 1285, 1285, 1285, + /* 2360 */ 1285, 1285, 1285, 1285, 480, 1285, 1285, 1285, 1285, 1285, + /* 2370 */ 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 480, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 277, 278, 279, 241, 242, 225, 195, 227, 195, 241, - /* 10 */ 242, 195, 217, 221, 195, 235, 254, 195, 256, 19, - /* 20 */ 225, 298, 254, 195, 256, 206, 213, 214, 206, 218, - /* 30 */ 219, 31, 206, 195, 218, 219, 195, 218, 219, 39, - /* 40 */ 218, 219, 313, 43, 44, 45, 317, 47, 48, 49, + /* 0 */ 277, 278, 279, 241, 242, 225, 195, 227, 195, 312, + /* 10 */ 195, 218, 195, 316, 195, 235, 254, 195, 256, 19, + /* 20 */ 297, 277, 278, 279, 218, 206, 213, 214, 206, 218, + /* 30 */ 219, 31, 206, 218, 219, 218, 219, 218, 219, 39, + /* 40 */ 218, 219, 195, 43, 44, 45, 195, 47, 48, 49, /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19, - /* 60 */ 241, 242, 195, 241, 242, 195, 255, 241, 242, 277, - /* 70 */ 278, 279, 234, 254, 255, 256, 254, 255, 256, 218, - /* 80 */ 254, 240, 256, 43, 44, 45, 264, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 271, - /* 100 */ 287, 22, 23, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 112, 113, 114, 114, 47, 48, 49, 50, + /* 60 */ 241, 242, 195, 241, 242, 195, 255, 241, 242, 195, + /* 70 */ 255, 237, 238, 254, 255, 256, 254, 255, 256, 264, + /* 80 */ 254, 207, 256, 43, 44, 45, 264, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 251, + /* 100 */ 287, 253, 215, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 114, 82, 265, 195, 271, 11, /* 120 */ 187, 188, 189, 190, 191, 192, 190, 87, 192, 89, - /* 130 */ 197, 19, 199, 197, 318, 199, 320, 25, 195, 206, - /* 140 */ 299, 271, 206, 103, 104, 105, 106, 107, 108, 109, + /* 130 */ 197, 19, 199, 197, 317, 199, 319, 25, 271, 206, + /* 140 */ 218, 219, 206, 103, 104, 105, 106, 107, 108, 109, /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 195, 47, /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 170 */ 58, 60, 21, 195, 241, 242, 215, 241, 242, 312, - /* 180 */ 313, 102, 70, 205, 317, 207, 242, 254, 77, 256, - /* 190 */ 254, 122, 256, 55, 56, 57, 58, 59, 254, 88, - /* 200 */ 256, 90, 269, 240, 93, 269, 107, 108, 109, 110, - /* 210 */ 111, 112, 113, 114, 271, 103, 104, 105, 106, 107, - /* 220 */ 108, 109, 110, 111, 112, 113, 114, 313, 117, 118, - /* 230 */ 119, 317, 81, 195, 301, 19, 195, 301, 277, 278, - /* 240 */ 279, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 195, 43, - /* 260 */ 44, 45, 74, 47, 48, 49, 50, 51, 52, 53, - /* 270 */ 54, 55, 56, 57, 58, 124, 195, 60, 109, 110, - /* 280 */ 111, 112, 113, 114, 68, 195, 103, 104, 105, 106, - /* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 208, 218, - /* 300 */ 219, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 310 */ 112, 113, 114, 162, 233, 24, 128, 129, 130, 103, + /* 170 */ 58, 60, 139, 140, 241, 242, 289, 241, 242, 309, + /* 180 */ 310, 294, 70, 47, 48, 49, 50, 254, 77, 256, + /* 190 */ 254, 195, 256, 55, 56, 57, 58, 59, 221, 88, + /* 200 */ 109, 90, 269, 240, 93, 269, 107, 108, 109, 110, + /* 210 */ 111, 112, 113, 114, 215, 103, 104, 105, 106, 107, + /* 220 */ 108, 109, 110, 111, 112, 113, 114, 136, 117, 118, + /* 230 */ 119, 298, 141, 300, 298, 19, 300, 129, 130, 317, + /* 240 */ 318, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 250 */ 112, 113, 114, 114, 277, 278, 279, 146, 122, 43, + /* 260 */ 44, 45, 195, 47, 48, 49, 50, 51, 52, 53, + /* 270 */ 54, 55, 56, 57, 58, 218, 277, 278, 279, 19, + /* 280 */ 19, 195, 286, 23, 68, 218, 219, 55, 56, 57, + /* 290 */ 58, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 300 */ 112, 113, 114, 43, 44, 45, 232, 47, 48, 49, + /* 310 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 103, /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 330 */ 114, 195, 195, 215, 117, 118, 119, 120, 195, 19, - /* 340 */ 123, 124, 125, 207, 24, 74, 246, 60, 310, 311, - /* 350 */ 133, 60, 311, 82, 22, 218, 219, 257, 195, 19, - /* 360 */ 73, 218, 219, 43, 44, 45, 206, 47, 48, 49, - /* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 22, - /* 380 */ 23, 218, 219, 43, 44, 45, 54, 47, 48, 49, - /* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 128, - /* 400 */ 82, 241, 242, 195, 117, 118, 119, 289, 60, 118, - /* 410 */ 139, 140, 294, 195, 254, 195, 256, 195, 255, 259, - /* 420 */ 260, 73, 22, 103, 104, 105, 106, 107, 108, 109, - /* 430 */ 110, 111, 112, 113, 114, 206, 218, 219, 218, 219, - /* 440 */ 218, 219, 234, 103, 104, 105, 106, 107, 108, 109, - /* 450 */ 110, 111, 112, 113, 114, 318, 319, 139, 140, 102, - /* 460 */ 60, 318, 319, 221, 19, 117, 118, 119, 23, 195, - /* 470 */ 241, 242, 313, 255, 206, 255, 317, 255, 206, 129, - /* 480 */ 130, 206, 264, 254, 264, 256, 264, 195, 43, 44, - /* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54, - /* 500 */ 55, 56, 57, 58, 246, 213, 214, 19, 19, 241, - /* 510 */ 242, 195, 23, 241, 242, 257, 241, 242, 118, 277, - /* 520 */ 278, 279, 254, 29, 256, 60, 254, 33, 256, 254, - /* 530 */ 206, 256, 43, 44, 45, 218, 47, 48, 49, 50, - /* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, - /* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - /* 560 */ 66, 19, 218, 60, 120, 241, 242, 123, 124, 125, - /* 570 */ 60, 232, 77, 19, 20, 26, 22, 133, 254, 287, - /* 580 */ 256, 265, 117, 118, 119, 90, 312, 313, 93, 47, - /* 590 */ 36, 317, 103, 104, 105, 106, 107, 108, 109, 110, - /* 600 */ 111, 112, 113, 114, 116, 117, 277, 278, 279, 60, - /* 610 */ 107, 108, 19, 276, 60, 31, 23, 152, 195, 116, - /* 620 */ 117, 118, 119, 39, 121, 276, 72, 117, 118, 119, - /* 630 */ 166, 167, 129, 145, 237, 238, 43, 44, 45, 276, - /* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 650 */ 57, 58, 315, 316, 144, 101, 19, 154, 116, 156, - /* 660 */ 23, 107, 108, 109, 315, 316, 117, 118, 119, 115, - /* 670 */ 60, 117, 118, 119, 132, 200, 122, 60, 315, 316, - /* 680 */ 43, 44, 45, 272, 47, 48, 49, 50, 51, 52, - /* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, - /* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155, - /* 710 */ 156, 157, 158, 212, 213, 214, 22, 195, 101, 22, - /* 720 */ 60, 19, 20, 60, 22, 139, 140, 117, 118, 119, - /* 730 */ 22, 251, 195, 253, 117, 118, 195, 183, 36, 122, - /* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 750 */ 113, 114, 195, 195, 60, 218, 219, 60, 195, 284, - /* 760 */ 19, 25, 60, 288, 23, 237, 238, 22, 60, 109, - /* 770 */ 233, 154, 155, 156, 72, 218, 219, 117, 118, 119, - /* 780 */ 117, 118, 119, 116, 43, 44, 45, 265, 47, 48, - /* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - /* 800 */ 183, 243, 25, 101, 19, 60, 265, 144, 23, 107, - /* 810 */ 108, 117, 118, 119, 117, 118, 119, 115, 151, 117, - /* 820 */ 118, 119, 82, 195, 122, 117, 118, 119, 43, 44, - /* 830 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54, - /* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108, - /* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157, - /* 860 */ 158, 121, 117, 118, 119, 307, 101, 309, 195, 22, - /* 870 */ 23, 195, 25, 19, 35, 139, 140, 195, 24, 139, - /* 880 */ 140, 208, 195, 118, 109, 183, 22, 122, 103, 104, - /* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - /* 900 */ 304, 305, 77, 230, 127, 232, 67, 195, 19, 195, - /* 910 */ 195, 136, 23, 88, 75, 90, 141, 203, 93, 154, - /* 920 */ 155, 156, 208, 295, 60, 243, 22, 23, 19, 25, - /* 930 */ 218, 219, 43, 44, 45, 100, 47, 48, 49, 50, - /* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 183, 102, - /* 950 */ 96, 195, 43, 44, 45, 240, 47, 48, 49, 50, - /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 134, - /* 970 */ 131, 146, 25, 286, 120, 121, 122, 123, 124, 125, - /* 980 */ 126, 117, 118, 119, 313, 195, 132, 195, 317, 307, - /* 990 */ 195, 309, 103, 104, 105, 106, 107, 108, 109, 110, - /* 1000 */ 111, 112, 113, 114, 195, 195, 102, 195, 195, 195, - /* 1010 */ 218, 219, 103, 104, 105, 106, 107, 108, 109, 110, - /* 1020 */ 111, 112, 113, 114, 77, 233, 195, 60, 218, 219, - /* 1030 */ 218, 219, 218, 219, 23, 195, 25, 90, 243, 159, - /* 1040 */ 93, 161, 19, 233, 195, 233, 23, 233, 16, 218, - /* 1050 */ 219, 195, 243, 212, 213, 214, 262, 263, 218, 219, - /* 1060 */ 195, 271, 19, 307, 233, 309, 43, 44, 45, 160, - /* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1080 */ 57, 58, 195, 218, 219, 118, 43, 44, 45, 240, - /* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1100 */ 57, 58, 307, 195, 309, 218, 219, 263, 12, 195, - /* 1110 */ 78, 267, 80, 112, 113, 114, 307, 22, 309, 24, - /* 1120 */ 255, 281, 266, 27, 107, 108, 103, 104, 105, 106, - /* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 195, - /* 1140 */ 11, 22, 255, 24, 195, 195, 103, 104, 105, 106, - /* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 19, 195, - /* 1160 */ 64, 195, 218, 219, 195, 313, 195, 218, 219, 317, - /* 1170 */ 74, 154, 195, 156, 195, 195, 19, 233, 23, 60, - /* 1180 */ 25, 24, 218, 219, 218, 219, 195, 218, 219, 218, - /* 1190 */ 219, 128, 129, 130, 162, 263, 19, 218, 219, 267, - /* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52, - /* 1210 */ 53, 54, 55, 56, 57, 58, 19, 240, 228, 255, - /* 1220 */ 43, 44, 45, 25, 47, 48, 49, 50, 51, 52, - /* 1230 */ 53, 54, 55, 56, 57, 58, 135, 118, 137, 138, - /* 1240 */ 43, 44, 45, 22, 47, 48, 49, 50, 51, 52, - /* 1250 */ 53, 54, 55, 56, 57, 58, 117, 266, 129, 130, - /* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 1270 */ 113, 114, 195, 195, 119, 295, 195, 206, 195, 195, - /* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 1290 */ 113, 114, 195, 195, 195, 218, 219, 195, 195, 144, - /* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 1310 */ 113, 114, 241, 242, 67, 218, 219, 218, 219, 146, - /* 1320 */ 19, 218, 219, 240, 215, 254, 136, 256, 107, 108, - /* 1330 */ 195, 141, 255, 86, 128, 129, 130, 195, 165, 195, - /* 1340 */ 19, 143, 95, 272, 25, 44, 45, 266, 47, 48, - /* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - /* 1360 */ 218, 219, 218, 219, 195, 12, 45, 195, 47, 48, - /* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - /* 1380 */ 27, 23, 7, 8, 9, 210, 211, 218, 219, 116, - /* 1390 */ 218, 219, 228, 16, 147, 42, 195, 295, 195, 19, - /* 1400 */ 20, 266, 22, 294, 103, 104, 105, 106, 107, 108, - /* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 218, - /* 1420 */ 219, 218, 219, 195, 103, 104, 105, 106, 107, 108, - /* 1430 */ 109, 110, 111, 112, 113, 114, 195, 154, 119, 156, - /* 1440 */ 60, 189, 190, 191, 192, 195, 218, 219, 195, 197, - /* 1450 */ 195, 199, 72, 195, 19, 78, 195, 80, 206, 218, - /* 1460 */ 219, 195, 82, 144, 210, 211, 195, 15, 218, 219, - /* 1470 */ 47, 218, 219, 218, 219, 259, 260, 195, 261, 218, - /* 1480 */ 219, 101, 302, 303, 218, 219, 195, 107, 108, 218, - /* 1490 */ 219, 150, 151, 241, 242, 115, 25, 117, 118, 119, - /* 1500 */ 218, 219, 122, 195, 146, 195, 254, 195, 256, 218, - /* 1510 */ 219, 246, 25, 61, 246, 19, 20, 195, 22, 139, - /* 1520 */ 140, 269, 257, 195, 266, 257, 218, 219, 218, 219, - /* 1530 */ 218, 219, 36, 246, 154, 155, 156, 157, 158, 116, - /* 1540 */ 218, 219, 195, 22, 257, 49, 218, 219, 23, 195, - /* 1550 */ 25, 195, 117, 301, 195, 25, 60, 195, 195, 23, - /* 1560 */ 195, 25, 195, 183, 24, 218, 219, 130, 72, 195, - /* 1570 */ 22, 195, 218, 219, 218, 219, 195, 218, 219, 195, - /* 1580 */ 218, 219, 86, 218, 219, 218, 219, 91, 19, 20, - /* 1590 */ 153, 22, 218, 219, 218, 219, 195, 101, 195, 218, - /* 1600 */ 219, 195, 195, 107, 108, 36, 23, 195, 25, 195, - /* 1610 */ 62, 115, 195, 117, 118, 119, 195, 146, 122, 218, - /* 1620 */ 219, 218, 219, 195, 218, 219, 19, 60, 122, 60, - /* 1630 */ 218, 219, 218, 219, 195, 218, 219, 150, 132, 218, - /* 1640 */ 219, 72, 195, 23, 195, 25, 218, 219, 195, 60, - /* 1650 */ 154, 155, 156, 157, 158, 86, 23, 195, 25, 195, - /* 1660 */ 91, 19, 20, 142, 22, 218, 219, 218, 219, 130, - /* 1670 */ 101, 218, 219, 143, 121, 122, 107, 108, 36, 183, - /* 1680 */ 218, 219, 142, 60, 115, 118, 117, 118, 119, 7, - /* 1690 */ 8, 122, 153, 23, 23, 25, 25, 23, 23, 25, - /* 1700 */ 25, 23, 60, 25, 23, 98, 25, 118, 84, 85, - /* 1710 */ 23, 23, 25, 25, 72, 154, 23, 156, 25, 23, - /* 1720 */ 228, 25, 195, 154, 155, 156, 157, 158, 86, 195, - /* 1730 */ 195, 258, 195, 91, 291, 322, 195, 195, 195, 195, - /* 1740 */ 195, 118, 195, 101, 195, 195, 195, 195, 238, 107, - /* 1750 */ 108, 195, 183, 195, 195, 195, 290, 115, 195, 117, - /* 1760 */ 118, 119, 244, 195, 122, 195, 195, 195, 195, 195, - /* 1770 */ 195, 258, 258, 258, 258, 193, 245, 300, 216, 274, - /* 1780 */ 247, 270, 270, 274, 296, 296, 248, 222, 262, 198, - /* 1790 */ 262, 274, 61, 274, 248, 231, 154, 155, 156, 157, - /* 1800 */ 158, 0, 1, 2, 247, 227, 5, 221, 221, 221, - /* 1810 */ 142, 10, 11, 12, 13, 14, 262, 262, 17, 202, - /* 1820 */ 300, 19, 20, 300, 22, 183, 247, 251, 251, 245, - /* 1830 */ 202, 30, 38, 32, 202, 152, 151, 22, 36, 149, - /* 1840 */ 146, 40, 43, 18, 252, 251, 236, 252, 251, 283, - /* 1850 */ 239, 239, 239, 239, 202, 18, 201, 150, 236, 202, - /* 1860 */ 201, 236, 60, 248, 248, 275, 273, 248, 159, 273, - /* 1870 */ 63, 286, 71, 275, 72, 275, 22, 297, 297, 248, - /* 1880 */ 79, 202, 202, 82, 223, 201, 223, 201, 116, 220, - /* 1890 */ 22, 202, 293, 292, 65, 229, 201, 220, 226, 226, - /* 1900 */ 99, 127, 166, 101, 24, 229, 114, 83, 92, 107, - /* 1910 */ 108, 220, 308, 202, 285, 223, 268, 115, 220, 117, - /* 1920 */ 118, 119, 222, 220, 122, 220, 220, 223, 285, 19, - /* 1930 */ 20, 22, 22, 268, 316, 134, 280, 202, 159, 148, - /* 1940 */ 139, 140, 321, 141, 282, 147, 36, 321, 25, 252, - /* 1950 */ 251, 204, 250, 252, 13, 196, 154, 155, 156, 157, - /* 1960 */ 158, 249, 248, 196, 163, 6, 306, 194, 215, 194, - /* 1970 */ 60, 194, 209, 306, 209, 215, 215, 215, 224, 224, - /* 1980 */ 216, 215, 72, 4, 216, 183, 3, 209, 22, 15, - /* 1990 */ 164, 16, 23, 23, 152, 140, 131, 25, 20, 143, - /* 2000 */ 24, 16, 145, 1, 143, 131, 131, 62, 37, 54, - /* 2010 */ 152, 101, 54, 303, 54, 54, 131, 107, 108, 117, - /* 2020 */ 34, 142, 1, 5, 116, 115, 22, 117, 118, 119, - /* 2030 */ 1, 2, 122, 162, 5, 25, 69, 69, 76, 10, - /* 2040 */ 11, 12, 13, 14, 41, 142, 17, 116, 5, 24, - /* 2050 */ 20, 141, 19, 10, 11, 12, 13, 14, 132, 30, - /* 2060 */ 17, 32, 126, 22, 154, 155, 156, 157, 158, 40, - /* 2070 */ 22, 22, 22, 30, 68, 32, 23, 68, 24, 60, - /* 2080 */ 28, 97, 22, 40, 68, 23, 22, 150, 37, 34, - /* 2090 */ 23, 23, 22, 183, 25, 23, 98, 23, 142, 23, - /* 2100 */ 71, 22, 25, 89, 117, 34, 94, 144, 79, 34, - /* 2110 */ 76, 82, 34, 87, 71, 34, 34, 44, 76, 34, - /* 2120 */ 23, 22, 79, 25, 24, 82, 25, 34, 99, 23, - /* 2130 */ 23, 143, 143, 23, 23, 22, 11, 25, 23, 25, - /* 2140 */ 22, 22, 99, 22, 136, 23, 23, 142, 22, 22, - /* 2150 */ 15, 1, 1, 25, 25, 142, 23, 142, 323, 323, - /* 2160 */ 323, 323, 323, 134, 323, 323, 323, 323, 139, 140, - /* 2170 */ 323, 323, 323, 323, 323, 323, 323, 134, 323, 323, - /* 2180 */ 323, 323, 139, 140, 323, 323, 323, 323, 323, 323, - /* 2190 */ 323, 323, 163, 323, 323, 323, 323, 323, 323, 323, - /* 2200 */ 323, 323, 323, 323, 323, 323, 163, 323, 323, 323, - /* 2210 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2220 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2230 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2240 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2250 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2260 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2270 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2280 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2290 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2300 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2310 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2320 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2330 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, - /* 2340 */ 323, 323, 323, 323, 323, 187, 187, 187, 187, 187, - /* 2350 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - /* 2360 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - /* 2370 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - /* 2380 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - /* 2390 */ 187, 187, 187, 187, + /* 330 */ 114, 135, 60, 137, 138, 103, 104, 105, 106, 107, + /* 340 */ 108, 109, 110, 111, 112, 113, 114, 82, 281, 206, + /* 350 */ 195, 109, 110, 111, 112, 113, 114, 195, 195, 195, + /* 360 */ 205, 22, 207, 103, 104, 105, 106, 107, 108, 109, + /* 370 */ 110, 111, 112, 113, 114, 195, 60, 116, 117, 107, + /* 380 */ 108, 218, 219, 19, 241, 242, 121, 23, 116, 117, + /* 390 */ 118, 119, 306, 121, 308, 206, 234, 254, 15, 256, + /* 400 */ 195, 129, 259, 260, 139, 140, 145, 43, 44, 45, + /* 410 */ 200, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* 420 */ 56, 57, 58, 218, 219, 60, 154, 19, 156, 265, + /* 430 */ 241, 242, 24, 117, 118, 119, 120, 21, 73, 123, + /* 440 */ 124, 125, 74, 254, 61, 256, 107, 108, 221, 133, + /* 450 */ 82, 43, 44, 45, 195, 47, 48, 49, 50, 51, + /* 460 */ 52, 53, 54, 55, 56, 57, 58, 103, 104, 105, + /* 470 */ 106, 107, 108, 109, 110, 111, 112, 113, 114, 195, + /* 480 */ 317, 318, 117, 118, 119, 22, 120, 195, 22, 123, + /* 490 */ 124, 125, 19, 20, 284, 22, 128, 81, 288, 133, + /* 500 */ 195, 195, 218, 219, 277, 278, 279, 139, 140, 36, + /* 510 */ 195, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 520 */ 112, 113, 114, 218, 219, 62, 60, 195, 241, 242, + /* 530 */ 271, 19, 240, 60, 189, 190, 191, 192, 233, 255, + /* 540 */ 124, 254, 197, 256, 199, 72, 129, 130, 264, 195, + /* 550 */ 195, 206, 22, 23, 60, 43, 44, 45, 206, 47, + /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 570 */ 58, 195, 218, 219, 101, 195, 60, 271, 162, 195, + /* 580 */ 107, 108, 109, 117, 118, 119, 241, 242, 115, 73, + /* 590 */ 117, 118, 119, 241, 242, 122, 60, 195, 266, 254, + /* 600 */ 312, 256, 218, 219, 316, 203, 254, 195, 256, 255, + /* 610 */ 208, 117, 118, 119, 269, 103, 104, 105, 106, 107, + /* 620 */ 108, 109, 110, 111, 112, 113, 114, 154, 155, 156, + /* 630 */ 157, 158, 102, 117, 118, 119, 19, 242, 144, 255, + /* 640 */ 23, 206, 24, 298, 195, 300, 206, 195, 264, 254, + /* 650 */ 206, 256, 240, 117, 118, 119, 183, 22, 22, 23, + /* 660 */ 43, 44, 45, 151, 47, 48, 49, 50, 51, 52, + /* 670 */ 53, 54, 55, 56, 57, 58, 241, 242, 60, 195, + /* 680 */ 19, 241, 242, 195, 23, 241, 242, 195, 152, 254, + /* 690 */ 310, 256, 243, 312, 254, 60, 256, 316, 254, 206, + /* 700 */ 256, 60, 218, 219, 43, 44, 45, 272, 47, 48, + /* 710 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 720 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 730 */ 113, 114, 240, 60, 241, 242, 118, 25, 102, 255, + /* 740 */ 166, 167, 101, 22, 26, 19, 20, 254, 22, 256, + /* 750 */ 139, 140, 117, 118, 119, 306, 195, 308, 117, 118, + /* 760 */ 237, 238, 36, 122, 103, 104, 105, 106, 107, 108, + /* 770 */ 109, 110, 111, 112, 113, 114, 195, 195, 60, 218, + /* 780 */ 219, 60, 109, 195, 19, 217, 60, 25, 23, 77, + /* 790 */ 117, 118, 119, 225, 233, 154, 155, 156, 72, 312, + /* 800 */ 218, 219, 90, 316, 22, 93, 303, 304, 43, 44, + /* 810 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54, + /* 820 */ 55, 56, 57, 58, 183, 195, 195, 101, 19, 213, + /* 830 */ 214, 243, 23, 107, 108, 117, 118, 119, 117, 118, + /* 840 */ 119, 115, 60, 117, 118, 119, 195, 60, 122, 218, + /* 850 */ 219, 22, 43, 44, 45, 35, 47, 48, 49, 50, + /* 860 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, + /* 870 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 880 */ 154, 155, 156, 157, 158, 195, 255, 67, 195, 60, + /* 890 */ 101, 240, 311, 312, 306, 75, 308, 316, 29, 117, + /* 900 */ 118, 119, 33, 287, 117, 118, 119, 118, 146, 183, + /* 910 */ 195, 122, 103, 104, 105, 106, 107, 108, 109, 110, + /* 920 */ 111, 112, 113, 114, 215, 195, 77, 60, 25, 195, + /* 930 */ 122, 144, 19, 218, 219, 66, 23, 88, 246, 90, + /* 940 */ 132, 25, 93, 154, 155, 156, 117, 118, 119, 257, + /* 950 */ 195, 131, 218, 219, 195, 265, 43, 44, 45, 195, + /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 970 */ 57, 58, 183, 218, 219, 195, 19, 218, 219, 195, + /* 980 */ 23, 195, 218, 219, 117, 118, 119, 195, 233, 255, + /* 990 */ 195, 195, 233, 22, 23, 146, 25, 233, 218, 219, + /* 1000 */ 43, 44, 45, 294, 47, 48, 49, 50, 51, 52, + /* 1010 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, + /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 114, 195, 12, + /* 1030 */ 234, 195, 240, 74, 195, 255, 195, 60, 243, 262, + /* 1040 */ 263, 311, 312, 25, 27, 19, 316, 107, 108, 265, + /* 1050 */ 24, 265, 195, 150, 195, 139, 140, 218, 219, 42, + /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1070 */ 113, 114, 233, 102, 67, 218, 219, 218, 219, 243, + /* 1080 */ 19, 64, 22, 23, 23, 25, 195, 128, 129, 130, + /* 1090 */ 233, 74, 233, 86, 154, 118, 156, 130, 265, 208, + /* 1100 */ 19, 306, 95, 308, 43, 44, 45, 266, 47, 48, + /* 1110 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1120 */ 153, 230, 96, 232, 43, 44, 45, 19, 47, 48, + /* 1130 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1140 */ 114, 22, 306, 24, 308, 127, 120, 121, 122, 123, + /* 1150 */ 124, 125, 126, 195, 147, 212, 213, 214, 132, 23, + /* 1160 */ 195, 25, 102, 100, 103, 104, 105, 106, 107, 108, + /* 1170 */ 109, 110, 111, 112, 113, 114, 218, 219, 19, 60, + /* 1180 */ 195, 12, 210, 211, 103, 104, 105, 106, 107, 108, + /* 1190 */ 109, 110, 111, 112, 113, 114, 27, 134, 195, 195, + /* 1200 */ 195, 210, 211, 218, 219, 195, 47, 195, 212, 213, + /* 1210 */ 214, 42, 16, 130, 19, 112, 113, 114, 23, 77, + /* 1220 */ 195, 218, 219, 218, 219, 117, 163, 164, 218, 219, + /* 1230 */ 218, 219, 90, 64, 19, 93, 153, 118, 43, 44, + /* 1240 */ 45, 160, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1250 */ 55, 56, 57, 58, 195, 119, 272, 276, 43, 44, + /* 1260 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1270 */ 55, 56, 57, 58, 78, 116, 80, 218, 219, 116, + /* 1280 */ 144, 128, 129, 130, 218, 219, 61, 195, 47, 195, + /* 1290 */ 16, 132, 195, 263, 195, 314, 315, 267, 103, 104, + /* 1300 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 1310 */ 218, 219, 218, 219, 151, 218, 219, 195, 103, 104, + /* 1320 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 1330 */ 210, 211, 195, 7, 8, 9, 195, 60, 195, 312, + /* 1340 */ 218, 219, 195, 316, 195, 120, 195, 263, 19, 195, + /* 1350 */ 125, 267, 78, 24, 80, 218, 219, 116, 162, 218, + /* 1360 */ 219, 218, 219, 301, 302, 218, 219, 195, 19, 218, + /* 1370 */ 219, 276, 43, 44, 45, 160, 47, 48, 49, 50, + /* 1380 */ 51, 52, 53, 54, 55, 56, 57, 58, 19, 146, + /* 1390 */ 218, 219, 43, 44, 45, 118, 47, 48, 49, 50, + /* 1400 */ 51, 52, 53, 54, 55, 56, 57, 58, 165, 314, + /* 1410 */ 315, 276, 43, 44, 45, 266, 47, 48, 49, 50, + /* 1420 */ 51, 52, 53, 54, 55, 56, 57, 58, 128, 129, + /* 1430 */ 130, 195, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1440 */ 111, 112, 113, 114, 195, 228, 195, 61, 195, 314, + /* 1450 */ 315, 25, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1460 */ 111, 112, 113, 114, 195, 22, 195, 218, 219, 218, + /* 1470 */ 219, 195, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1480 */ 111, 112, 113, 114, 195, 195, 246, 218, 219, 218, + /* 1490 */ 219, 25, 19, 246, 218, 219, 246, 257, 259, 260, + /* 1500 */ 195, 22, 266, 60, 257, 195, 120, 257, 218, 219, + /* 1510 */ 116, 195, 19, 195, 150, 151, 25, 44, 45, 266, + /* 1520 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1530 */ 57, 58, 195, 54, 218, 219, 218, 219, 45, 145, + /* 1540 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1550 */ 57, 58, 246, 121, 122, 218, 219, 19, 23, 31, + /* 1560 */ 25, 118, 159, 257, 161, 24, 195, 39, 195, 143, + /* 1570 */ 195, 19, 20, 22, 22, 24, 103, 104, 105, 106, + /* 1580 */ 107, 108, 109, 110, 111, 112, 113, 114, 36, 218, + /* 1590 */ 219, 218, 219, 218, 219, 195, 103, 104, 105, 106, + /* 1600 */ 107, 108, 109, 110, 111, 112, 113, 114, 195, 143, + /* 1610 */ 119, 136, 60, 195, 22, 195, 141, 195, 218, 219, + /* 1620 */ 195, 23, 195, 25, 72, 23, 131, 25, 195, 134, + /* 1630 */ 23, 218, 219, 195, 82, 144, 218, 219, 218, 219, + /* 1640 */ 218, 219, 195, 218, 219, 218, 219, 60, 23, 195, + /* 1650 */ 25, 218, 219, 101, 195, 117, 218, 219, 195, 107, + /* 1660 */ 108, 23, 195, 25, 195, 218, 219, 115, 228, 117, + /* 1670 */ 118, 119, 218, 219, 122, 195, 19, 218, 219, 195, + /* 1680 */ 60, 218, 219, 142, 195, 218, 219, 19, 20, 195, + /* 1690 */ 22, 139, 140, 23, 23, 25, 25, 195, 218, 219, + /* 1700 */ 7, 8, 218, 219, 36, 118, 154, 155, 156, 157, + /* 1710 */ 158, 195, 23, 195, 25, 84, 85, 49, 195, 23, + /* 1720 */ 195, 25, 195, 23, 195, 25, 195, 23, 60, 25, + /* 1730 */ 23, 23, 25, 25, 142, 183, 218, 219, 118, 195, + /* 1740 */ 72, 218, 219, 218, 219, 218, 219, 218, 219, 218, + /* 1750 */ 219, 195, 195, 146, 86, 98, 23, 195, 25, 91, + /* 1760 */ 19, 20, 154, 22, 156, 154, 23, 156, 25, 101, + /* 1770 */ 23, 195, 25, 195, 195, 107, 108, 36, 195, 195, + /* 1780 */ 195, 195, 228, 115, 195, 117, 118, 119, 195, 195, + /* 1790 */ 122, 261, 195, 321, 195, 195, 195, 258, 238, 195, + /* 1800 */ 195, 60, 299, 291, 195, 195, 258, 195, 195, 195, + /* 1810 */ 290, 244, 216, 72, 245, 193, 258, 258, 299, 258, + /* 1820 */ 299, 274, 154, 155, 156, 157, 158, 86, 247, 295, + /* 1830 */ 248, 295, 91, 19, 20, 270, 22, 274, 270, 248, + /* 1840 */ 274, 222, 101, 227, 274, 221, 231, 221, 107, 108, + /* 1850 */ 36, 183, 262, 247, 221, 283, 115, 262, 117, 118, + /* 1860 */ 119, 198, 116, 122, 220, 262, 61, 220, 220, 251, + /* 1870 */ 247, 142, 251, 245, 60, 202, 299, 202, 38, 262, + /* 1880 */ 202, 22, 152, 151, 296, 149, 72, 252, 146, 43, + /* 1890 */ 251, 236, 252, 251, 18, 154, 155, 156, 157, 158, + /* 1900 */ 86, 239, 18, 239, 275, 91, 239, 273, 239, 150, + /* 1910 */ 273, 202, 201, 248, 248, 101, 286, 236, 275, 236, + /* 1920 */ 275, 107, 108, 296, 183, 248, 202, 248, 201, 115, + /* 1930 */ 159, 117, 118, 119, 293, 63, 122, 202, 292, 201, + /* 1940 */ 22, 223, 202, 223, 65, 201, 220, 202, 220, 201, + /* 1950 */ 229, 220, 22, 127, 229, 166, 24, 307, 114, 285, + /* 1960 */ 226, 285, 223, 226, 315, 202, 92, 268, 154, 155, + /* 1970 */ 156, 157, 158, 0, 1, 2, 220, 222, 5, 320, + /* 1980 */ 220, 220, 220, 10, 11, 12, 13, 14, 223, 83, + /* 1990 */ 17, 268, 320, 19, 20, 280, 22, 183, 22, 202, + /* 2000 */ 159, 252, 251, 30, 282, 32, 252, 250, 148, 147, + /* 2010 */ 36, 25, 248, 40, 204, 249, 13, 196, 196, 6, + /* 2020 */ 209, 194, 194, 194, 305, 224, 209, 215, 215, 4, + /* 2030 */ 215, 215, 224, 215, 60, 216, 216, 3, 22, 209, + /* 2040 */ 19, 122, 122, 19, 71, 22, 72, 125, 22, 16, + /* 2050 */ 15, 23, 79, 23, 140, 82, 152, 305, 131, 143, + /* 2060 */ 302, 25, 20, 16, 1, 131, 145, 143, 131, 62, + /* 2070 */ 131, 54, 99, 54, 37, 101, 54, 152, 117, 34, + /* 2080 */ 24, 107, 108, 54, 1, 5, 22, 116, 162, 115, + /* 2090 */ 25, 117, 118, 119, 76, 41, 122, 142, 116, 24, + /* 2100 */ 69, 19, 20, 19, 22, 20, 126, 134, 69, 132, + /* 2110 */ 22, 68, 139, 140, 22, 141, 22, 22, 36, 23, + /* 2120 */ 68, 60, 24, 22, 97, 28, 68, 37, 154, 155, + /* 2130 */ 156, 157, 158, 23, 34, 150, 163, 22, 25, 23, + /* 2140 */ 23, 23, 60, 22, 98, 23, 142, 23, 34, 117, + /* 2150 */ 22, 25, 144, 34, 72, 89, 87, 183, 23, 34, + /* 2160 */ 22, 34, 76, 34, 44, 76, 94, 34, 24, 22, + /* 2170 */ 25, 25, 23, 34, 23, 23, 23, 11, 22, 25, + /* 2180 */ 25, 143, 23, 101, 143, 22, 22, 25, 23, 107, + /* 2190 */ 108, 23, 22, 22, 25, 136, 23, 115, 15, 117, + /* 2200 */ 118, 119, 1, 2, 122, 1, 5, 1, 322, 142, + /* 2210 */ 142, 10, 11, 12, 13, 14, 142, 322, 17, 322, + /* 2220 */ 5, 322, 322, 141, 322, 10, 11, 12, 13, 14, + /* 2230 */ 322, 30, 17, 32, 322, 322, 154, 155, 156, 157, + /* 2240 */ 158, 40, 322, 322, 322, 30, 322, 32, 322, 322, + /* 2250 */ 322, 322, 322, 322, 322, 40, 322, 322, 322, 322, + /* 2260 */ 322, 322, 322, 322, 322, 183, 322, 322, 322, 322, + /* 2270 */ 322, 322, 71, 322, 322, 322, 322, 322, 322, 322, + /* 2280 */ 79, 322, 322, 82, 322, 322, 71, 322, 322, 322, + /* 2290 */ 322, 322, 322, 322, 79, 322, 322, 82, 322, 322, + /* 2300 */ 99, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2310 */ 322, 322, 322, 322, 99, 322, 322, 322, 322, 322, + /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2330 */ 322, 322, 322, 322, 322, 134, 322, 322, 322, 322, + /* 2340 */ 139, 140, 322, 322, 322, 322, 322, 322, 322, 134, + /* 2350 */ 322, 322, 322, 322, 139, 140, 322, 322, 322, 322, + /* 2360 */ 322, 322, 322, 322, 163, 322, 322, 322, 322, 322, + /* 2370 */ 322, 322, 322, 322, 322, 322, 322, 322, 163, 322, + /* 2380 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2390 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2400 */ 322, 322, 322, 322, 322, 322, 322, 322, 187, 187, + /* 2410 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2420 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2430 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2440 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2450 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2460 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2470 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2480 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2490 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2500 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2510 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2520 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2530 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2540 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2550 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2560 */ 187, 187, 187, 187, 187, 187, }; -#define YY_SHIFT_COUNT (586) +#define YY_SHIFT_COUNT (603) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2151) +#define YY_SHIFT_MAX (2215) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 2029, 1801, 2043, 1380, 1380, 318, 271, 1496, 1569, 1642, - /* 10 */ 702, 702, 702, 740, 318, 318, 318, 318, 318, 0, - /* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702, - /* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 503, 503, - /* 40 */ 111, 111, 217, 287, 348, 610, 610, 736, 736, 736, - /* 50 */ 736, 40, 112, 320, 340, 445, 489, 593, 637, 741, - /* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177, - /* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, - /* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554, - /* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702, - /* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - /* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - /* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - /* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - /* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198, - /* 150 */ 183, 99, 169, 549, 610, 151, 542, 610, 610, 1017, - /* 160 */ 1017, 610, 1001, 350, 464, 464, 464, 586, 1, 1, - /* 170 */ 2207, 2207, 854, 854, 854, 465, 694, 694, 694, 694, - /* 180 */ 1096, 1096, 825, 549, 847, 904, 610, 610, 610, 610, - /* 190 */ 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, - /* 200 */ 610, 610, 610, 610, 610, 488, 947, 947, 610, 1129, - /* 210 */ 495, 495, 1139, 1139, 967, 967, 1173, 2207, 2207, 2207, - /* 220 */ 2207, 2207, 2207, 2207, 617, 765, 765, 697, 444, 708, - /* 230 */ 660, 745, 510, 663, 864, 610, 610, 610, 610, 610, - /* 240 */ 610, 610, 610, 610, 610, 188, 610, 610, 610, 610, - /* 250 */ 610, 610, 610, 610, 610, 610, 610, 610, 839, 839, - /* 260 */ 839, 610, 610, 610, 1155, 610, 610, 610, 1119, 1247, - /* 270 */ 610, 1353, 610, 610, 610, 610, 610, 610, 610, 610, - /* 280 */ 1063, 494, 1101, 291, 291, 291, 291, 1319, 1101, 1101, - /* 290 */ 775, 1221, 1375, 1452, 667, 1341, 1198, 1341, 1435, 1487, - /* 300 */ 667, 667, 1487, 667, 1198, 1435, 777, 1011, 1423, 584, - /* 310 */ 584, 584, 1273, 1273, 1273, 1273, 1471, 1471, 880, 1530, - /* 320 */ 1190, 1095, 1731, 1731, 1668, 1668, 1794, 1794, 1668, 1683, - /* 330 */ 1685, 1815, 1690, 1694, 1799, 1690, 1694, 1825, 1825, 1825, - /* 340 */ 1825, 1668, 1837, 1707, 1685, 1685, 1707, 1815, 1799, 1707, - /* 350 */ 1799, 1707, 1668, 1837, 1709, 1807, 1668, 1837, 1854, 1668, - /* 360 */ 1837, 1668, 1837, 1854, 1772, 1772, 1772, 1829, 1868, 1868, - /* 370 */ 1854, 1772, 1774, 1772, 1829, 1772, 1772, 1736, 1880, 1792, - /* 380 */ 1792, 1854, 1668, 1816, 1816, 1824, 1824, 1690, 1694, 1909, - /* 390 */ 1668, 1779, 1690, 1791, 1798, 1707, 1923, 1941, 1941, 1959, - /* 400 */ 1959, 1959, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, - /* 410 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 69, 1032, 79, - /* 420 */ 357, 1377, 1206, 400, 1525, 835, 332, 1540, 1437, 1539, - /* 430 */ 1536, 1548, 1583, 1620, 1633, 1670, 1671, 1674, 1567, 1553, - /* 440 */ 1682, 1506, 1675, 1358, 1607, 1589, 1678, 1681, 1624, 1687, - /* 450 */ 1688, 1283, 1561, 1693, 1696, 1623, 1521, 1979, 1983, 1966, - /* 460 */ 1826, 1974, 1975, 1969, 1970, 1855, 1842, 1865, 1972, 1972, - /* 470 */ 1976, 1856, 1978, 1857, 1985, 2002, 1861, 1874, 1972, 1875, - /* 480 */ 1945, 1971, 1972, 1858, 1955, 1958, 1960, 1961, 1885, 1902, - /* 490 */ 1986, 1879, 2021, 2018, 2004, 1908, 1871, 1967, 2010, 1968, - /* 500 */ 1962, 2003, 1903, 1931, 2025, 2030, 2033, 1926, 1936, 2041, - /* 510 */ 2006, 2048, 2049, 2053, 2050, 2009, 2019, 2054, 1984, 2052, - /* 520 */ 2060, 2016, 2051, 2062, 2055, 1937, 2064, 2067, 2068, 2069, - /* 530 */ 2072, 2070, 1998, 1956, 2074, 2076, 1987, 2071, 2079, 1963, - /* 540 */ 2077, 2075, 2078, 2081, 2082, 2014, 2034, 2026, 2073, 2042, - /* 550 */ 2012, 2085, 2097, 2099, 2100, 2098, 2101, 2093, 1988, 1989, - /* 560 */ 2106, 2077, 2107, 2110, 2111, 2113, 2112, 2114, 2115, 2118, - /* 570 */ 2125, 2119, 2121, 2122, 2123, 2126, 2127, 2128, 2008, 2005, - /* 580 */ 2013, 2015, 2129, 2133, 2135, 2150, 2151, + /* 0 */ 2201, 1973, 2215, 1552, 1552, 33, 368, 1668, 1741, 1814, + /* 10 */ 726, 726, 726, 265, 33, 33, 33, 33, 33, 0, + /* 20 */ 0, 216, 1349, 726, 726, 726, 726, 726, 726, 726, + /* 30 */ 726, 726, 726, 726, 726, 726, 726, 726, 272, 272, + /* 40 */ 111, 111, 316, 365, 516, 867, 867, 916, 916, 916, + /* 50 */ 916, 40, 112, 260, 364, 408, 512, 617, 661, 765, + /* 60 */ 809, 913, 957, 1061, 1081, 1195, 1215, 1329, 1349, 1349, + /* 70 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, + /* 80 */ 1349, 1349, 1349, 1349, 1349, 1349, 1369, 1349, 1473, 1493, + /* 90 */ 1493, 473, 1974, 2082, 726, 726, 726, 726, 726, 726, + /* 100 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + /* 110 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + /* 120 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + /* 130 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + /* 140 */ 726, 726, 726, 726, 726, 726, 138, 232, 232, 232, + /* 150 */ 232, 232, 232, 232, 188, 99, 242, 718, 416, 1159, + /* 160 */ 867, 867, 940, 940, 867, 1103, 417, 574, 574, 574, + /* 170 */ 611, 139, 139, 2379, 2379, 1026, 1026, 1026, 536, 466, + /* 180 */ 466, 466, 466, 1017, 1017, 849, 718, 971, 1060, 867, + /* 190 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, + /* 200 */ 867, 867, 867, 867, 867, 867, 867, 867, 261, 712, + /* 210 */ 712, 867, 108, 1142, 1142, 977, 1108, 1108, 977, 977, + /* 220 */ 1243, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 641, 789, + /* 230 */ 789, 635, 366, 721, 673, 782, 494, 787, 829, 867, + /* 240 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, + /* 250 */ 959, 867, 867, 867, 867, 867, 867, 867, 867, 867, + /* 260 */ 867, 867, 867, 867, 867, 820, 820, 820, 867, 867, + /* 270 */ 867, 1136, 867, 867, 867, 1119, 1007, 867, 1169, 867, + /* 280 */ 867, 867, 867, 867, 867, 867, 867, 1225, 1153, 869, + /* 290 */ 196, 618, 618, 618, 618, 1491, 196, 196, 91, 339, + /* 300 */ 1326, 1386, 383, 1163, 1364, 1426, 1364, 1538, 903, 1163, + /* 310 */ 1163, 903, 1163, 1426, 1538, 1018, 1535, 1241, 1528, 1528, + /* 320 */ 1528, 1394, 1394, 1394, 1394, 762, 762, 1403, 1466, 1475, + /* 330 */ 1551, 1746, 1805, 1746, 1746, 1729, 1729, 1840, 1840, 1729, + /* 340 */ 1730, 1732, 1859, 1736, 1742, 1846, 1736, 1742, 1876, 1876, + /* 350 */ 1876, 1876, 1729, 1884, 1759, 1732, 1732, 1759, 1859, 1846, + /* 360 */ 1759, 1846, 1759, 1729, 1884, 1771, 1872, 1729, 1884, 1918, + /* 370 */ 1729, 1884, 1729, 1884, 1918, 1746, 1746, 1746, 1879, 1930, + /* 380 */ 1930, 1918, 1746, 1826, 1746, 1879, 1746, 1746, 1789, 1932, + /* 390 */ 1844, 1844, 1918, 1729, 1874, 1874, 1906, 1906, 1736, 1742, + /* 400 */ 1976, 1729, 1841, 1736, 1860, 1862, 1759, 1986, 2003, 2003, + /* 410 */ 2013, 2013, 2013, 2379, 2379, 2379, 2379, 2379, 2379, 2379, + /* 420 */ 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 136, 1063, + /* 430 */ 1196, 530, 636, 1274, 1300, 1443, 1598, 1495, 1479, 967, + /* 440 */ 1083, 1602, 463, 1625, 1638, 1670, 1541, 1671, 1689, 1696, + /* 450 */ 1277, 1432, 1693, 808, 1700, 1607, 1657, 1587, 1704, 1707, + /* 460 */ 1631, 1708, 1733, 1608, 1611, 1743, 1747, 1620, 1592, 2025, + /* 470 */ 2034, 2016, 1919, 2021, 1920, 2024, 2023, 2026, 1922, 2035, + /* 480 */ 2033, 2028, 2030, 1914, 1904, 1927, 2036, 2036, 1916, 2042, + /* 490 */ 1921, 2047, 2063, 1924, 1934, 2036, 1937, 2007, 2037, 2036, + /* 500 */ 1925, 2017, 2019, 2022, 2029, 1939, 1961, 2045, 2056, 2083, + /* 510 */ 2080, 2064, 1971, 1926, 2031, 2065, 2039, 2018, 2054, 1955, + /* 520 */ 1982, 2075, 2085, 2084, 1977, 1980, 2088, 2043, 2092, 2094, + /* 530 */ 2096, 2095, 2052, 2061, 2098, 2027, 2097, 2101, 2058, 2090, + /* 540 */ 2110, 2100, 1985, 2115, 2116, 2117, 2113, 2118, 2121, 2046, + /* 550 */ 2004, 2122, 2124, 2032, 2114, 2128, 2008, 2126, 2119, 2125, + /* 560 */ 2127, 2129, 2066, 2086, 2069, 2120, 2089, 2072, 2133, 2135, + /* 570 */ 2138, 2144, 2145, 2146, 2139, 2038, 2041, 2149, 2126, 2151, + /* 580 */ 2152, 2153, 2147, 2154, 2155, 2159, 2156, 2166, 2163, 2164, + /* 590 */ 2165, 2168, 2170, 2171, 2162, 2059, 2067, 2068, 2074, 2169, + /* 600 */ 2173, 2183, 2204, 2206, }; -#define YY_REDUCE_COUNT (416) -#define YY_REDUCE_MIN (-277) -#define YY_REDUCE_MAX (1778) +#define YY_REDUCE_COUNT (427) +#define YY_REDUCE_MIN (-303) +#define YY_REDUCE_MAX (1830) static const short yy_reduce_ofst[] = { - /* 0 */ -67, 1252, -64, -178, -181, 160, 1071, 143, -184, 137, - /* 10 */ 218, 220, 222, -174, 229, 268, 272, 275, 324, -208, - /* 20 */ 242, -277, -39, 81, 537, 792, 810, 812, -189, 814, - /* 30 */ 831, 163, 865, 944, 887, 840, 964, 1077, -187, 292, - /* 40 */ -133, 274, 673, 558, 682, 795, 809, -238, -232, -238, - /* 50 */ -232, 329, 329, 329, 329, 329, 329, 329, 329, 329, - /* 60 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - /* 70 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - /* 80 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 557, - /* 90 */ 712, 949, 966, 969, 971, 979, 1097, 1099, 1103, 1142, - /* 100 */ 1144, 1169, 1172, 1201, 1203, 1228, 1241, 1250, 1253, 1255, - /* 110 */ 1261, 1266, 1271, 1282, 1291, 1308, 1310, 1312, 1322, 1328, - /* 120 */ 1347, 1354, 1356, 1359, 1362, 1365, 1367, 1374, 1376, 1381, - /* 130 */ 1401, 1403, 1406, 1412, 1414, 1417, 1421, 1428, 1447, 1449, - /* 140 */ 1453, 1462, 329, 329, 329, 329, 329, 329, 329, 329, - /* 150 */ 329, 329, 329, -22, -159, 475, -220, 756, 38, 501, - /* 160 */ 841, 714, 329, 118, 337, 349, 363, -56, 329, 329, - /* 170 */ 329, 329, -205, -205, -205, 687, -172, -130, -57, 790, - /* 180 */ 397, 528, -271, 136, 596, 596, 90, 316, 522, 541, - /* 190 */ -37, 715, 849, 977, 628, 856, 980, 991, 1081, 1102, - /* 200 */ 1135, 1083, -162, 208, 1258, 794, -86, 159, 41, 1109, - /* 210 */ 671, 852, 844, 932, 1175, 1254, 480, 1180, 100, 258, - /* 220 */ 1265, 1268, 1216, 1287, -139, 317, 344, 63, 339, 423, - /* 230 */ 563, 636, 676, 813, 908, 914, 950, 1078, 1084, 1098, - /* 240 */ 1363, 1384, 1407, 1439, 1464, 411, 1527, 1534, 1535, 1537, - /* 250 */ 1541, 1542, 1543, 1544, 1545, 1547, 1549, 1550, 990, 1164, - /* 260 */ 1492, 1551, 1552, 1556, 1217, 1558, 1559, 1560, 1473, 1413, - /* 270 */ 1563, 1510, 1568, 563, 1570, 1571, 1572, 1573, 1574, 1575, - /* 280 */ 1443, 1466, 1518, 1513, 1514, 1515, 1516, 1217, 1518, 1518, - /* 290 */ 1531, 1562, 1582, 1477, 1505, 1511, 1533, 1512, 1488, 1538, - /* 300 */ 1509, 1517, 1546, 1519, 1557, 1489, 1565, 1564, 1578, 1586, - /* 310 */ 1587, 1588, 1526, 1528, 1554, 1555, 1576, 1577, 1566, 1579, - /* 320 */ 1584, 1591, 1520, 1523, 1617, 1628, 1580, 1581, 1632, 1585, - /* 330 */ 1590, 1593, 1592, 1594, 1610, 1595, 1597, 1611, 1612, 1613, - /* 340 */ 1614, 1652, 1655, 1615, 1598, 1600, 1616, 1596, 1622, 1619, - /* 350 */ 1625, 1631, 1657, 1659, 1599, 1601, 1679, 1684, 1661, 1680, - /* 360 */ 1686, 1689, 1695, 1663, 1669, 1677, 1691, 1666, 1672, 1673, - /* 370 */ 1692, 1698, 1700, 1703, 1676, 1705, 1706, 1618, 1604, 1629, - /* 380 */ 1643, 1704, 1711, 1621, 1626, 1648, 1665, 1697, 1699, 1656, - /* 390 */ 1735, 1662, 1701, 1702, 1712, 1714, 1747, 1759, 1767, 1773, - /* 400 */ 1775, 1777, 1660, 1667, 1710, 1763, 1753, 1760, 1761, 1762, - /* 410 */ 1765, 1754, 1755, 1764, 1768, 1766, 1778, + /* 0 */ -67, 345, -64, -178, -181, 143, 435, -78, -183, 163, + /* 10 */ -185, 284, 384, -174, 189, 352, 440, 444, 493, -23, + /* 20 */ 227, -277, -1, 305, 561, 755, 759, 764, -189, 839, + /* 30 */ 857, 354, 484, 859, 631, 67, 734, 780, -187, 616, + /* 40 */ 581, 730, 891, 449, 588, 795, 836, -238, 287, -238, + /* 50 */ 287, -256, -256, -256, -256, -256, -256, -256, -256, -256, + /* 60 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, + /* 70 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, + /* 80 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, + /* 90 */ -256, 205, 582, 715, 958, 985, 1003, 1005, 1010, 1012, + /* 100 */ 1059, 1066, 1092, 1094, 1097, 1122, 1137, 1141, 1143, 1147, + /* 110 */ 1151, 1172, 1249, 1251, 1269, 1271, 1276, 1290, 1316, 1318, + /* 120 */ 1337, 1371, 1373, 1375, 1400, 1413, 1418, 1420, 1422, 1425, + /* 130 */ 1427, 1433, 1438, 1447, 1454, 1459, 1463, 1467, 1480, 1484, + /* 140 */ 1518, 1523, 1525, 1527, 1529, 1531, -256, -256, -256, -256, + /* 150 */ -256, -256, -256, -256, -256, -256, -256, 155, 210, -220, + /* 160 */ 86, -130, 943, 996, 402, -256, -113, 981, 1095, 1135, + /* 170 */ 395, -256, -256, -256, -256, 568, 568, 568, -4, -153, + /* 180 */ -133, 259, 306, -166, 523, -303, -126, 503, 503, -37, + /* 190 */ -149, 164, 690, 292, 412, 492, 651, 784, 332, 786, + /* 200 */ 841, 1149, 833, 1236, 792, 162, 796, 1253, 777, 288, + /* 210 */ 381, 380, 709, 487, 1027, 972, 1030, 1084, 991, 1120, + /* 220 */ -152, 1062, 692, 1240, 1247, 1250, 1239, 1306, -207, -194, + /* 230 */ 57, 180, 74, 315, 355, 376, 452, 488, 630, 693, + /* 240 */ 965, 1004, 1025, 1099, 1154, 1289, 1305, 1310, 1469, 1489, + /* 250 */ 984, 1494, 1502, 1516, 1544, 1556, 1557, 1562, 1576, 1578, + /* 260 */ 1579, 1583, 1584, 1585, 1586, 1217, 1440, 1554, 1589, 1593, + /* 270 */ 1594, 1530, 1597, 1599, 1600, 1539, 1472, 1601, 1560, 1604, + /* 280 */ 355, 1605, 1609, 1610, 1612, 1613, 1614, 1503, 1512, 1520, + /* 290 */ 1567, 1548, 1558, 1559, 1561, 1530, 1567, 1567, 1569, 1596, + /* 300 */ 1622, 1519, 1521, 1547, 1565, 1581, 1568, 1534, 1582, 1563, + /* 310 */ 1566, 1591, 1570, 1606, 1536, 1619, 1615, 1616, 1624, 1626, + /* 320 */ 1633, 1590, 1595, 1603, 1617, 1618, 1621, 1572, 1623, 1628, + /* 330 */ 1663, 1644, 1577, 1647, 1648, 1673, 1675, 1588, 1627, 1678, + /* 340 */ 1630, 1629, 1634, 1635, 1639, 1655, 1640, 1642, 1662, 1664, + /* 350 */ 1667, 1669, 1709, 1711, 1665, 1643, 1645, 1666, 1637, 1681, + /* 360 */ 1677, 1683, 1679, 1724, 1727, 1641, 1646, 1735, 1738, 1718, + /* 370 */ 1740, 1744, 1745, 1748, 1720, 1726, 1728, 1731, 1721, 1734, + /* 380 */ 1737, 1739, 1756, 1755, 1760, 1725, 1761, 1762, 1649, 1650, + /* 390 */ 1674, 1676, 1765, 1763, 1659, 1672, 1699, 1723, 1749, 1751, + /* 400 */ 1715, 1797, 1722, 1754, 1757, 1766, 1764, 1810, 1821, 1822, + /* 410 */ 1827, 1828, 1829, 1719, 1752, 1758, 1811, 1812, 1813, 1815, + /* 420 */ 1816, 1817, 1801, 1808, 1819, 1820, 1818, 1830, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1667, 1667, 1667, 1495, 1258, 1371, 1258, 1258, 1258, 1258, - /* 10 */ 1495, 1495, 1495, 1258, 1258, 1258, 1258, 1258, 1258, 1401, - /* 20 */ 1401, 1548, 1291, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 30 */ 1258, 1258, 1258, 1258, 1258, 1494, 1258, 1258, 1258, 1258, - /* 40 */ 1582, 1582, 1258, 1258, 1258, 1258, 1258, 1567, 1566, 1258, - /* 50 */ 1258, 1258, 1410, 1258, 1417, 1258, 1258, 1258, 1258, 1258, - /* 60 */ 1496, 1497, 1258, 1258, 1258, 1258, 1547, 1549, 1512, 1424, - /* 70 */ 1423, 1422, 1421, 1530, 1389, 1415, 1408, 1412, 1491, 1492, - /* 80 */ 1490, 1645, 1497, 1496, 1258, 1411, 1459, 1475, 1458, 1258, - /* 90 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 100 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 110 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 120 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 130 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 140 */ 1258, 1258, 1467, 1474, 1473, 1472, 1481, 1471, 1468, 1461, - /* 150 */ 1460, 1462, 1463, 1282, 1258, 1279, 1333, 1258, 1258, 1258, - /* 160 */ 1258, 1258, 1464, 1291, 1452, 1451, 1450, 1258, 1478, 1465, - /* 170 */ 1477, 1476, 1555, 1619, 1618, 1513, 1258, 1258, 1258, 1258, - /* 180 */ 1258, 1258, 1582, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 190 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 200 */ 1258, 1258, 1258, 1258, 1258, 1391, 1582, 1582, 1258, 1291, - /* 210 */ 1582, 1582, 1392, 1392, 1287, 1287, 1395, 1562, 1362, 1362, - /* 220 */ 1362, 1362, 1371, 1362, 1258, 1258, 1258, 1258, 1258, 1258, - /* 230 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1552, - /* 240 */ 1550, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 250 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 260 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1367, 1258, - /* 270 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1612, - /* 280 */ 1258, 1525, 1347, 1367, 1367, 1367, 1367, 1369, 1348, 1346, - /* 290 */ 1361, 1292, 1265, 1659, 1427, 1416, 1368, 1416, 1656, 1414, - /* 300 */ 1427, 1427, 1414, 1427, 1368, 1656, 1308, 1634, 1303, 1401, - /* 310 */ 1401, 1401, 1391, 1391, 1391, 1391, 1395, 1395, 1493, 1368, - /* 320 */ 1361, 1258, 1659, 1659, 1377, 1377, 1658, 1658, 1377, 1513, - /* 330 */ 1642, 1436, 1409, 1395, 1336, 1409, 1395, 1342, 1342, 1342, - /* 340 */ 1342, 1377, 1276, 1414, 1642, 1642, 1414, 1436, 1336, 1414, - /* 350 */ 1336, 1414, 1377, 1276, 1529, 1653, 1377, 1276, 1503, 1377, - /* 360 */ 1276, 1377, 1276, 1503, 1334, 1334, 1334, 1323, 1258, 1258, - /* 370 */ 1503, 1334, 1308, 1334, 1323, 1334, 1334, 1600, 1258, 1507, - /* 380 */ 1507, 1503, 1377, 1592, 1592, 1404, 1404, 1409, 1395, 1498, - /* 390 */ 1377, 1258, 1409, 1407, 1405, 1414, 1326, 1615, 1615, 1611, - /* 400 */ 1611, 1611, 1664, 1664, 1562, 1627, 1291, 1291, 1291, 1291, - /* 410 */ 1627, 1310, 1310, 1292, 1292, 1291, 1627, 1258, 1258, 1258, - /* 420 */ 1258, 1258, 1258, 1622, 1258, 1557, 1514, 1381, 1258, 1258, - /* 430 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 440 */ 1258, 1258, 1258, 1258, 1568, 1258, 1258, 1258, 1258, 1258, - /* 450 */ 1258, 1258, 1258, 1258, 1258, 1258, 1441, 1258, 1261, 1559, - /* 460 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1418, 1419, - /* 470 */ 1382, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1433, 1258, - /* 480 */ 1258, 1258, 1428, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 490 */ 1258, 1655, 1258, 1258, 1258, 1258, 1258, 1258, 1528, 1527, - /* 500 */ 1258, 1258, 1379, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 510 */ 1258, 1258, 1258, 1258, 1258, 1258, 1306, 1258, 1258, 1258, - /* 520 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 530 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 540 */ 1406, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - /* 550 */ 1258, 1258, 1258, 1258, 1258, 1597, 1396, 1258, 1258, 1258, - /* 560 */ 1258, 1646, 1258, 1258, 1258, 1258, 1356, 1258, 1258, 1258, - /* 570 */ 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1638, 1350, 1442, - /* 580 */ 1258, 1445, 1280, 1258, 1270, 1258, 1258, + /* 0 */ 1695, 1695, 1695, 1520, 1283, 1396, 1283, 1283, 1283, 1283, + /* 10 */ 1520, 1520, 1520, 1283, 1283, 1283, 1283, 1283, 1283, 1426, + /* 20 */ 1426, 1572, 1316, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 30 */ 1283, 1283, 1283, 1283, 1283, 1519, 1283, 1283, 1283, 1283, + /* 40 */ 1611, 1611, 1283, 1283, 1283, 1283, 1283, 1596, 1595, 1283, + /* 50 */ 1283, 1283, 1435, 1283, 1283, 1283, 1442, 1283, 1283, 1283, + /* 60 */ 1283, 1283, 1521, 1522, 1283, 1283, 1283, 1283, 1571, 1573, + /* 70 */ 1537, 1449, 1448, 1447, 1446, 1555, 1414, 1440, 1433, 1437, + /* 80 */ 1516, 1517, 1515, 1674, 1522, 1521, 1283, 1436, 1484, 1500, + /* 90 */ 1483, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 100 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 110 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 120 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 130 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 140 */ 1283, 1283, 1283, 1283, 1283, 1283, 1492, 1499, 1498, 1497, + /* 150 */ 1506, 1496, 1493, 1486, 1485, 1487, 1488, 1307, 1304, 1358, + /* 160 */ 1283, 1283, 1283, 1283, 1283, 1489, 1316, 1477, 1476, 1475, + /* 170 */ 1283, 1503, 1490, 1502, 1501, 1579, 1648, 1647, 1538, 1283, + /* 180 */ 1283, 1283, 1283, 1283, 1283, 1611, 1283, 1283, 1283, 1283, + /* 190 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 200 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1416, 1611, + /* 210 */ 1611, 1283, 1316, 1611, 1611, 1312, 1417, 1417, 1312, 1312, + /* 220 */ 1420, 1591, 1387, 1387, 1387, 1387, 1396, 1387, 1283, 1283, + /* 230 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 240 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1576, 1574, 1283, + /* 250 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 260 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 270 */ 1283, 1283, 1283, 1283, 1283, 1392, 1283, 1283, 1283, 1283, + /* 280 */ 1283, 1283, 1283, 1283, 1283, 1283, 1641, 1687, 1283, 1550, + /* 290 */ 1372, 1392, 1392, 1392, 1392, 1394, 1373, 1371, 1386, 1317, + /* 300 */ 1290, 1687, 1687, 1452, 1441, 1393, 1441, 1684, 1439, 1452, + /* 310 */ 1452, 1439, 1452, 1393, 1684, 1333, 1663, 1328, 1426, 1426, + /* 320 */ 1426, 1416, 1416, 1416, 1416, 1420, 1420, 1518, 1393, 1386, + /* 330 */ 1283, 1359, 1687, 1359, 1359, 1402, 1402, 1686, 1686, 1402, + /* 340 */ 1538, 1671, 1461, 1434, 1420, 1361, 1434, 1420, 1367, 1367, + /* 350 */ 1367, 1367, 1402, 1301, 1439, 1671, 1671, 1439, 1461, 1361, + /* 360 */ 1439, 1361, 1439, 1402, 1301, 1554, 1682, 1402, 1301, 1528, + /* 370 */ 1402, 1301, 1402, 1301, 1528, 1359, 1359, 1359, 1348, 1283, + /* 380 */ 1283, 1528, 1359, 1333, 1359, 1348, 1359, 1359, 1629, 1283, + /* 390 */ 1532, 1532, 1528, 1402, 1621, 1621, 1429, 1429, 1434, 1420, + /* 400 */ 1523, 1402, 1283, 1434, 1432, 1430, 1439, 1351, 1644, 1644, + /* 410 */ 1640, 1640, 1640, 1692, 1692, 1591, 1656, 1316, 1316, 1316, + /* 420 */ 1316, 1656, 1335, 1335, 1317, 1317, 1316, 1656, 1283, 1283, + /* 430 */ 1283, 1283, 1283, 1283, 1283, 1651, 1283, 1283, 1539, 1283, + /* 440 */ 1283, 1283, 1283, 1283, 1283, 1283, 1406, 1283, 1283, 1283, + /* 450 */ 1283, 1283, 1283, 1283, 1283, 1283, 1597, 1283, 1283, 1283, + /* 460 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1466, 1283, + /* 470 */ 1286, 1588, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 480 */ 1283, 1283, 1283, 1283, 1283, 1283, 1443, 1444, 1283, 1283, + /* 490 */ 1283, 1283, 1283, 1283, 1283, 1458, 1283, 1283, 1283, 1453, + /* 500 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1407, 1283, + /* 510 */ 1283, 1283, 1283, 1283, 1283, 1553, 1552, 1283, 1283, 1404, + /* 520 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 530 */ 1283, 1283, 1283, 1331, 1283, 1283, 1283, 1283, 1283, 1283, + /* 540 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 550 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1431, 1283, 1283, + /* 560 */ 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + /* 570 */ 1283, 1283, 1626, 1421, 1283, 1283, 1283, 1283, 1675, 1283, + /* 580 */ 1283, 1283, 1283, 1381, 1283, 1283, 1283, 1283, 1283, 1283, + /* 590 */ 1283, 1283, 1283, 1283, 1667, 1375, 1467, 1283, 1470, 1305, + /* 600 */ 1283, 1295, 1283, 1283, }; /********** End of lemon-generated parsing tables *****************************/ @@ -179380,34 +182703,33 @@ static const char *const yyTokenName[] = { /* 292 */ "foreach_clause", /* 293 */ "when_clause", /* 294 */ "trigger_cmd", - /* 295 */ "trnm", - /* 296 */ "tridxby", - /* 297 */ "database_kw_opt", - /* 298 */ "key_opt", - /* 299 */ "add_column_fullname", - /* 300 */ "kwcolumn_opt", - /* 301 */ "create_vtab", - /* 302 */ "vtabarglist", - /* 303 */ "vtabarg", - /* 304 */ "vtabargtoken", - /* 305 */ "lp", - /* 306 */ "anylist", - /* 307 */ "wqitem", - /* 308 */ "wqas", - /* 309 */ "withnm", - /* 310 */ "windowdefn_list", - /* 311 */ "windowdefn", - /* 312 */ "window", - /* 313 */ "frame_opt", - /* 314 */ "part_opt", - /* 315 */ "filter_clause", - /* 316 */ "over_clause", - /* 317 */ "range_or_rows", - /* 318 */ "frame_bound", - /* 319 */ "frame_bound_s", - /* 320 */ "frame_bound_e", - /* 321 */ "frame_exclude_opt", - /* 322 */ "frame_exclude", + /* 295 */ "tridxby", + /* 296 */ "database_kw_opt", + /* 297 */ "key_opt", + /* 298 */ "alter_add", + /* 299 */ "kwcolumn_opt", + /* 300 */ "create_vtab", + /* 301 */ "vtabarglist", + /* 302 */ "vtabarg", + /* 303 */ "vtabargtoken", + /* 304 */ "lp", + /* 305 */ "anylist", + /* 306 */ "wqitem", + /* 307 */ "wqas", + /* 308 */ "withnm", + /* 309 */ "windowdefn_list", + /* 310 */ "windowdefn", + /* 311 */ "window", + /* 312 */ "frame_opt", + /* 313 */ "part_opt", + /* 314 */ "filter_clause", + /* 315 */ "over_clause", + /* 316 */ "range_or_rows", + /* 317 */ "frame_bound", + /* 318 */ "frame_bound_s", + /* 319 */ "frame_bound_e", + /* 320 */ "frame_exclude_opt", + /* 321 */ "frame_exclude", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -179537,8 +182859,8 @@ static const char *const yyRuleName[] = { /* 119 */ "fullname ::= nm DOT nm", /* 120 */ "xfullname ::= nm", /* 121 */ "xfullname ::= nm DOT nm", - /* 122 */ "xfullname ::= nm DOT nm AS nm", - /* 123 */ "xfullname ::= nm AS nm", + /* 122 */ "xfullname ::= nm AS nm", + /* 123 */ "xfullname ::= nm DOT nm AS nm", /* 124 */ "joinop ::= COMMA|JOIN", /* 125 */ "joinop ::= JOIN_KW JOIN", /* 126 */ "joinop ::= JOIN_KW nm JOIN", @@ -179687,143 +183009,146 @@ static const char *const yyRuleName[] = { /* 269 */ "when_clause ::= WHEN expr", /* 270 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", /* 271 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 272 */ "trnm ::= nm DOT nm", - /* 273 */ "tridxby ::= INDEXED BY nm", - /* 274 */ "tridxby ::= NOT INDEXED", - /* 275 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 276 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 278 */ "trigger_cmd ::= scanpt select scanpt", - /* 279 */ "expr ::= RAISE LP IGNORE RP", - /* 280 */ "expr ::= RAISE LP raisetype COMMA expr RP", - /* 281 */ "raisetype ::= ROLLBACK", - /* 282 */ "raisetype ::= ABORT", - /* 283 */ "raisetype ::= FAIL", - /* 284 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 285 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 286 */ "cmd ::= DETACH database_kw_opt expr", - /* 287 */ "key_opt ::=", - /* 288 */ "key_opt ::= KEY expr", - /* 289 */ "cmd ::= REINDEX", - /* 290 */ "cmd ::= REINDEX nm dbnm", - /* 291 */ "cmd ::= ANALYZE", - /* 292 */ "cmd ::= ANALYZE nm dbnm", - /* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 294 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 272 */ "tridxby ::= INDEXED BY nm", + /* 273 */ "tridxby ::= NOT INDEXED", + /* 274 */ "trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt", + /* 275 */ "trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt", + /* 276 */ "trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt", + /* 277 */ "trigger_cmd ::= scanpt select scanpt", + /* 278 */ "expr ::= RAISE LP IGNORE RP", + /* 279 */ "expr ::= RAISE LP raisetype COMMA expr RP", + /* 280 */ "raisetype ::= ROLLBACK", + /* 281 */ "raisetype ::= ABORT", + /* 282 */ "raisetype ::= FAIL", + /* 283 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 284 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 285 */ "cmd ::= DETACH database_kw_opt expr", + /* 286 */ "key_opt ::=", + /* 287 */ "key_opt ::= KEY expr", + /* 288 */ "cmd ::= REINDEX", + /* 289 */ "cmd ::= REINDEX nm dbnm", + /* 290 */ "cmd ::= ANALYZE", + /* 291 */ "cmd ::= ANALYZE nm dbnm", + /* 292 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 293 */ "cmd ::= alter_add carglist", + /* 294 */ "alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken", /* 295 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", - /* 296 */ "add_column_fullname ::= fullname", - /* 297 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 298 */ "cmd ::= create_vtab", - /* 299 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 300 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 301 */ "vtabarg ::=", - /* 302 */ "vtabargtoken ::= ANY", - /* 303 */ "vtabargtoken ::= lp anylist RP", - /* 304 */ "lp ::= LP", - /* 305 */ "with ::= WITH wqlist", - /* 306 */ "with ::= WITH RECURSIVE wqlist", - /* 307 */ "wqas ::= AS", - /* 308 */ "wqas ::= AS MATERIALIZED", - /* 309 */ "wqas ::= AS NOT MATERIALIZED", - /* 310 */ "wqitem ::= withnm eidlist_opt wqas LP select RP", - /* 311 */ "withnm ::= nm", - /* 312 */ "wqlist ::= wqitem", - /* 313 */ "wqlist ::= wqlist COMMA wqitem", - /* 314 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 315 */ "windowdefn ::= nm AS LP window RP", - /* 316 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 317 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 318 */ "window ::= ORDER BY sortlist frame_opt", - /* 319 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 320 */ "window ::= nm frame_opt", - /* 321 */ "frame_opt ::=", - /* 322 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 323 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 324 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 325 */ "frame_bound_s ::= frame_bound", - /* 326 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 327 */ "frame_bound_e ::= frame_bound", - /* 328 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 329 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 330 */ "frame_bound ::= CURRENT ROW", - /* 331 */ "frame_exclude_opt ::=", - /* 332 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 333 */ "frame_exclude ::= NO OTHERS", - /* 334 */ "frame_exclude ::= CURRENT ROW", - /* 335 */ "frame_exclude ::= GROUP|TIES", - /* 336 */ "window_clause ::= WINDOW windowdefn_list", - /* 337 */ "filter_over ::= filter_clause over_clause", - /* 338 */ "filter_over ::= over_clause", - /* 339 */ "filter_over ::= filter_clause", - /* 340 */ "over_clause ::= OVER LP window RP", - /* 341 */ "over_clause ::= OVER nm", - /* 342 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 343 */ "term ::= QNUMBER", - /* 344 */ "input ::= cmdlist", - /* 345 */ "cmdlist ::= cmdlist ecmd", - /* 346 */ "cmdlist ::= ecmd", - /* 347 */ "ecmd ::= SEMI", - /* 348 */ "ecmd ::= cmdx SEMI", - /* 349 */ "ecmd ::= explain cmdx SEMI", - /* 350 */ "trans_opt ::=", - /* 351 */ "trans_opt ::= TRANSACTION", - /* 352 */ "trans_opt ::= TRANSACTION nm", - /* 353 */ "savepoint_opt ::= SAVEPOINT", - /* 354 */ "savepoint_opt ::=", - /* 355 */ "cmd ::= create_table create_table_args", - /* 356 */ "table_option_set ::= table_option", - /* 357 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 358 */ "columnlist ::= columnname carglist", - /* 359 */ "nm ::= ID|INDEXED|JOIN_KW", - /* 360 */ "nm ::= STRING", - /* 361 */ "typetoken ::= typename", - /* 362 */ "typename ::= ID|STRING", - /* 363 */ "signed ::= plus_num", - /* 364 */ "signed ::= minus_num", - /* 365 */ "carglist ::= carglist ccons", - /* 366 */ "carglist ::=", - /* 367 */ "ccons ::= NULL onconf", - /* 368 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 369 */ "ccons ::= AS generated", - /* 370 */ "conslist_opt ::= COMMA conslist", - /* 371 */ "conslist ::= conslist tconscomma tcons", - /* 372 */ "conslist ::= tcons", - /* 373 */ "tconscomma ::=", - /* 374 */ "defer_subclause_opt ::= defer_subclause", - /* 375 */ "resolvetype ::= raisetype", - /* 376 */ "selectnowith ::= oneselect", - /* 377 */ "oneselect ::= values", - /* 378 */ "sclp ::= selcollist COMMA", - /* 379 */ "as ::= ID|STRING", - /* 380 */ "indexed_opt ::= indexed_by", - /* 381 */ "returning ::=", - /* 382 */ "expr ::= term", - /* 383 */ "likeop ::= LIKE_KW|MATCH", - /* 384 */ "case_operand ::= expr", - /* 385 */ "exprlist ::= nexprlist", - /* 386 */ "nmnum ::= plus_num", - /* 387 */ "nmnum ::= nm", - /* 388 */ "nmnum ::= ON", - /* 389 */ "nmnum ::= DELETE", - /* 390 */ "nmnum ::= DEFAULT", - /* 391 */ "plus_num ::= INTEGER|FLOAT", - /* 392 */ "foreach_clause ::=", - /* 393 */ "foreach_clause ::= FOR EACH ROW", - /* 394 */ "trnm ::= nm", - /* 395 */ "tridxby ::=", - /* 396 */ "database_kw_opt ::= DATABASE", - /* 397 */ "database_kw_opt ::=", - /* 398 */ "kwcolumn_opt ::=", - /* 399 */ "kwcolumn_opt ::= COLUMNKW", - /* 400 */ "vtabarglist ::= vtabarg", - /* 401 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 402 */ "vtabarg ::= vtabarg vtabargtoken", - /* 403 */ "anylist ::=", - /* 404 */ "anylist ::= anylist LP anylist RP", - /* 405 */ "anylist ::= anylist ANY", - /* 406 */ "with ::=", - /* 407 */ "windowdefn_list ::= windowdefn", - /* 408 */ "window ::= frame_opt", + /* 296 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 297 */ "cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm", + /* 298 */ "cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL", + /* 299 */ "cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf", + /* 300 */ "cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf", + /* 301 */ "cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf", + /* 302 */ "cmd ::= create_vtab", + /* 303 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 304 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 305 */ "vtabarg ::=", + /* 306 */ "vtabargtoken ::= ANY", + /* 307 */ "vtabargtoken ::= lp anylist RP", + /* 308 */ "lp ::= LP", + /* 309 */ "with ::= WITH wqlist", + /* 310 */ "with ::= WITH RECURSIVE wqlist", + /* 311 */ "wqas ::= AS", + /* 312 */ "wqas ::= AS MATERIALIZED", + /* 313 */ "wqas ::= AS NOT MATERIALIZED", + /* 314 */ "wqitem ::= withnm eidlist_opt wqas LP select RP", + /* 315 */ "withnm ::= nm", + /* 316 */ "wqlist ::= wqitem", + /* 317 */ "wqlist ::= wqlist COMMA wqitem", + /* 318 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 319 */ "windowdefn ::= nm AS LP window RP", + /* 320 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 321 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 322 */ "window ::= ORDER BY sortlist frame_opt", + /* 323 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 324 */ "window ::= nm frame_opt", + /* 325 */ "frame_opt ::=", + /* 326 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 327 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 328 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 329 */ "frame_bound_s ::= frame_bound", + /* 330 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 331 */ "frame_bound_e ::= frame_bound", + /* 332 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 333 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 334 */ "frame_bound ::= CURRENT ROW", + /* 335 */ "frame_exclude_opt ::=", + /* 336 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 337 */ "frame_exclude ::= NO OTHERS", + /* 338 */ "frame_exclude ::= CURRENT ROW", + /* 339 */ "frame_exclude ::= GROUP|TIES", + /* 340 */ "window_clause ::= WINDOW windowdefn_list", + /* 341 */ "filter_over ::= filter_clause over_clause", + /* 342 */ "filter_over ::= over_clause", + /* 343 */ "filter_over ::= filter_clause", + /* 344 */ "over_clause ::= OVER LP window RP", + /* 345 */ "over_clause ::= OVER nm", + /* 346 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 347 */ "term ::= QNUMBER", + /* 348 */ "input ::= cmdlist", + /* 349 */ "cmdlist ::= cmdlist ecmd", + /* 350 */ "cmdlist ::= ecmd", + /* 351 */ "ecmd ::= SEMI", + /* 352 */ "ecmd ::= cmdx SEMI", + /* 353 */ "ecmd ::= explain cmdx SEMI", + /* 354 */ "trans_opt ::=", + /* 355 */ "trans_opt ::= TRANSACTION", + /* 356 */ "trans_opt ::= TRANSACTION nm", + /* 357 */ "savepoint_opt ::= SAVEPOINT", + /* 358 */ "savepoint_opt ::=", + /* 359 */ "cmd ::= create_table create_table_args", + /* 360 */ "table_option_set ::= table_option", + /* 361 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 362 */ "columnlist ::= columnname carglist", + /* 363 */ "nm ::= ID|INDEXED|JOIN_KW", + /* 364 */ "nm ::= STRING", + /* 365 */ "typetoken ::= typename", + /* 366 */ "typename ::= ID|STRING", + /* 367 */ "signed ::= plus_num", + /* 368 */ "signed ::= minus_num", + /* 369 */ "carglist ::= carglist ccons", + /* 370 */ "carglist ::=", + /* 371 */ "ccons ::= NULL onconf", + /* 372 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 373 */ "ccons ::= AS generated", + /* 374 */ "conslist_opt ::= COMMA conslist", + /* 375 */ "conslist ::= conslist tconscomma tcons", + /* 376 */ "conslist ::= tcons", + /* 377 */ "tconscomma ::=", + /* 378 */ "defer_subclause_opt ::= defer_subclause", + /* 379 */ "resolvetype ::= raisetype", + /* 380 */ "selectnowith ::= oneselect", + /* 381 */ "oneselect ::= values", + /* 382 */ "sclp ::= selcollist COMMA", + /* 383 */ "as ::= ID|STRING", + /* 384 */ "indexed_opt ::= indexed_by", + /* 385 */ "returning ::=", + /* 386 */ "expr ::= term", + /* 387 */ "likeop ::= LIKE_KW|MATCH", + /* 388 */ "case_operand ::= expr", + /* 389 */ "exprlist ::= nexprlist", + /* 390 */ "nmnum ::= plus_num", + /* 391 */ "nmnum ::= nm", + /* 392 */ "nmnum ::= ON", + /* 393 */ "nmnum ::= DELETE", + /* 394 */ "nmnum ::= DEFAULT", + /* 395 */ "plus_num ::= INTEGER|FLOAT", + /* 396 */ "foreach_clause ::=", + /* 397 */ "foreach_clause ::= FOR EACH ROW", + /* 398 */ "tridxby ::=", + /* 399 */ "database_kw_opt ::= DATABASE", + /* 400 */ "database_kw_opt ::=", + /* 401 */ "kwcolumn_opt ::=", + /* 402 */ "kwcolumn_opt ::= COLUMNKW", + /* 403 */ "vtabarglist ::= vtabarg", + /* 404 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 405 */ "vtabarg ::= vtabarg vtabargtoken", + /* 406 */ "anylist ::=", + /* 407 */ "anylist ::= anylist LP anylist RP", + /* 408 */ "anylist ::= anylist ANY", + /* 409 */ "with ::=", + /* 410 */ "windowdefn_list ::= windowdefn", + /* 411 */ "window ::= frame_opt", }; #endif /* NDEBUG */ @@ -179838,15 +183163,24 @@ static int yyGrowStack(yyParser *p){ int newSize; int idx; yyStackEntry *pNew; +#ifdef YYSIZELIMIT + int nLimit = YYSIZELIMIT(sqlite3ParserCTX(p)); +#endif newSize = oldSize*2 + 100; +#ifdef YYSIZELIMIT + if( newSize>nLimit ){ + newSize = nLimit; + if( newSize<=oldSize ) return 1; + } +#endif idx = (int)(p->yytos - p->yystack); if( p->yystack==p->yystk0 ){ - pNew = YYREALLOC(0, newSize*sizeof(pNew[0])); + pNew = YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p)); if( pNew==0 ) return 1; memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0])); }else{ - pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0])); + pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p)); if( pNew==0 ) return 1; } p->yystack = pNew; @@ -179953,7 +183287,7 @@ static void yy_destructor( case 254: /* values */ case 256: /* mvalues */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy637)); +sqlite3SelectDelete(pParse->db, (yypminor->yy555)); } break; case 218: /* term */ @@ -179965,10 +183299,10 @@ sqlite3SelectDelete(pParse->db, (yypminor->yy637)); case 283: /* case_else */ case 286: /* vinto */ case 293: /* when_clause */ - case 298: /* key_opt */ - case 315: /* filter_clause */ + case 297: /* key_opt */ + case 314: /* filter_clause */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy590)); +sqlite3ExprDelete(pParse->db, (yypminor->yy454)); } break; case 223: /* eidlist_opt */ @@ -179983,9 +183317,9 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy590)); case 271: /* setlist */ case 280: /* paren_exprlist */ case 282: /* case_exprlist */ - case 314: /* part_opt */ + case 313: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy402)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); } break; case 240: /* fullname */ @@ -179994,51 +183328,51 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy402)); case 260: /* stl_prefix */ case 265: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy563)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy203)); } break; case 243: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy125)); +sqlite3WithDelete(pParse->db, (yypminor->yy59)); } break; case 253: /* window_clause */ - case 310: /* windowdefn_list */ + case 309: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy483)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy211)); } break; case 266: /* idlist */ case 273: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy204)); +sqlite3IdListDelete(pParse->db, (yypminor->yy132)); } break; case 276: /* filter_over */ - case 311: /* windowdefn */ - case 312: /* window */ - case 313: /* frame_opt */ - case 316: /* over_clause */ + case 310: /* windowdefn */ + case 311: /* window */ + case 312: /* frame_opt */ + case 315: /* over_clause */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy483)); +sqlite3WindowDelete(pParse->db, (yypminor->yy211)); } break; case 289: /* trigger_cmd_list */ case 294: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy319)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427)); } break; case 291: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy28).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy286).b); } break; - case 318: /* frame_bound */ - case 319: /* frame_bound_s */ - case 320: /* frame_bound_e */ + case 317: /* frame_bound */ + case 318: /* frame_bound_s */ + case 319: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy205).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -180091,7 +183425,9 @@ SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){ } #if YYGROWABLESTACK - if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack); + if( pParser->yystack!=pParser->yystk0 ){ + YYFREE(pParser->yystack, sqlite3ParserCTX(pParser)); + } #endif } @@ -180274,7 +183610,7 @@ static void yyStackOverflow(yyParser *yypParser){ ** stack every overflows */ /******** Begin %stack_overflow code ******************************************/ - sqlite3OomFault(pParse->db); + if( pParse->nErr==0 ) sqlite3ErrorMsg(pParse, "Recursion limit"); /******** End %stack_overflow code ********************************************/ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ sqlite3ParserCTX_STORE @@ -180462,8 +183798,8 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 240, /* (119) fullname ::= nm DOT nm */ 265, /* (120) xfullname ::= nm */ 265, /* (121) xfullname ::= nm DOT nm */ - 265, /* (122) xfullname ::= nm DOT nm AS nm */ - 265, /* (123) xfullname ::= nm AS nm */ + 265, /* (122) xfullname ::= nm AS nm */ + 265, /* (123) xfullname ::= nm DOT nm AS nm */ 261, /* (124) joinop ::= COMMA|JOIN */ 261, /* (125) joinop ::= JOIN_KW JOIN */ 261, /* (126) joinop ::= JOIN_KW nm JOIN */ @@ -180612,143 +183948,146 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 293, /* (269) when_clause ::= WHEN expr */ 289, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ 289, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ - 295, /* (272) trnm ::= nm DOT nm */ - 296, /* (273) tridxby ::= INDEXED BY nm */ - 296, /* (274) tridxby ::= NOT INDEXED */ - 294, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 294, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 294, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 294, /* (278) trigger_cmd ::= scanpt select scanpt */ - 219, /* (279) expr ::= RAISE LP IGNORE RP */ - 219, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ - 238, /* (281) raisetype ::= ROLLBACK */ - 238, /* (282) raisetype ::= ABORT */ - 238, /* (283) raisetype ::= FAIL */ - 192, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ - 192, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 192, /* (286) cmd ::= DETACH database_kw_opt expr */ - 298, /* (287) key_opt ::= */ - 298, /* (288) key_opt ::= KEY expr */ - 192, /* (289) cmd ::= REINDEX */ - 192, /* (290) cmd ::= REINDEX nm dbnm */ - 192, /* (291) cmd ::= ANALYZE */ - 192, /* (292) cmd ::= ANALYZE nm dbnm */ - 192, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 192, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 295, /* (272) tridxby ::= INDEXED BY nm */ + 295, /* (273) tridxby ::= NOT INDEXED */ + 294, /* (274) trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ + 294, /* (275) trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ + 294, /* (276) trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ + 294, /* (277) trigger_cmd ::= scanpt select scanpt */ + 219, /* (278) expr ::= RAISE LP IGNORE RP */ + 219, /* (279) expr ::= RAISE LP raisetype COMMA expr RP */ + 238, /* (280) raisetype ::= ROLLBACK */ + 238, /* (281) raisetype ::= ABORT */ + 238, /* (282) raisetype ::= FAIL */ + 192, /* (283) cmd ::= DROP TRIGGER ifexists fullname */ + 192, /* (284) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 192, /* (285) cmd ::= DETACH database_kw_opt expr */ + 297, /* (286) key_opt ::= */ + 297, /* (287) key_opt ::= KEY expr */ + 192, /* (288) cmd ::= REINDEX */ + 192, /* (289) cmd ::= REINDEX nm dbnm */ + 192, /* (290) cmd ::= ANALYZE */ + 192, /* (291) cmd ::= ANALYZE nm dbnm */ + 192, /* (292) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 192, /* (293) cmd ::= alter_add carglist */ + 298, /* (294) alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ 192, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - 299, /* (296) add_column_fullname ::= fullname */ - 192, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 192, /* (298) cmd ::= create_vtab */ - 192, /* (299) cmd ::= create_vtab LP vtabarglist RP */ - 301, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 303, /* (301) vtabarg ::= */ - 304, /* (302) vtabargtoken ::= ANY */ - 304, /* (303) vtabargtoken ::= lp anylist RP */ - 305, /* (304) lp ::= LP */ - 269, /* (305) with ::= WITH wqlist */ - 269, /* (306) with ::= WITH RECURSIVE wqlist */ - 308, /* (307) wqas ::= AS */ - 308, /* (308) wqas ::= AS MATERIALIZED */ - 308, /* (309) wqas ::= AS NOT MATERIALIZED */ - 307, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */ - 309, /* (311) withnm ::= nm */ - 243, /* (312) wqlist ::= wqitem */ - 243, /* (313) wqlist ::= wqlist COMMA wqitem */ - 310, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 311, /* (315) windowdefn ::= nm AS LP window RP */ - 312, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 312, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 312, /* (318) window ::= ORDER BY sortlist frame_opt */ - 312, /* (319) window ::= nm ORDER BY sortlist frame_opt */ - 312, /* (320) window ::= nm frame_opt */ - 313, /* (321) frame_opt ::= */ - 313, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 313, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 317, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */ - 319, /* (325) frame_bound_s ::= frame_bound */ - 319, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */ - 320, /* (327) frame_bound_e ::= frame_bound */ - 320, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 318, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */ - 318, /* (330) frame_bound ::= CURRENT ROW */ - 321, /* (331) frame_exclude_opt ::= */ - 321, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 322, /* (333) frame_exclude ::= NO OTHERS */ - 322, /* (334) frame_exclude ::= CURRENT ROW */ - 322, /* (335) frame_exclude ::= GROUP|TIES */ - 253, /* (336) window_clause ::= WINDOW windowdefn_list */ - 276, /* (337) filter_over ::= filter_clause over_clause */ - 276, /* (338) filter_over ::= over_clause */ - 276, /* (339) filter_over ::= filter_clause */ - 316, /* (340) over_clause ::= OVER LP window RP */ - 316, /* (341) over_clause ::= OVER nm */ - 315, /* (342) filter_clause ::= FILTER LP WHERE expr RP */ - 218, /* (343) term ::= QNUMBER */ - 187, /* (344) input ::= cmdlist */ - 188, /* (345) cmdlist ::= cmdlist ecmd */ - 188, /* (346) cmdlist ::= ecmd */ - 189, /* (347) ecmd ::= SEMI */ - 189, /* (348) ecmd ::= cmdx SEMI */ - 189, /* (349) ecmd ::= explain cmdx SEMI */ - 194, /* (350) trans_opt ::= */ - 194, /* (351) trans_opt ::= TRANSACTION */ - 194, /* (352) trans_opt ::= TRANSACTION nm */ - 196, /* (353) savepoint_opt ::= SAVEPOINT */ - 196, /* (354) savepoint_opt ::= */ - 192, /* (355) cmd ::= create_table create_table_args */ - 205, /* (356) table_option_set ::= table_option */ - 203, /* (357) columnlist ::= columnlist COMMA columnname carglist */ - 203, /* (358) columnlist ::= columnname carglist */ - 195, /* (359) nm ::= ID|INDEXED|JOIN_KW */ - 195, /* (360) nm ::= STRING */ - 210, /* (361) typetoken ::= typename */ - 211, /* (362) typename ::= ID|STRING */ - 212, /* (363) signed ::= plus_num */ - 212, /* (364) signed ::= minus_num */ - 209, /* (365) carglist ::= carglist ccons */ - 209, /* (366) carglist ::= */ - 217, /* (367) ccons ::= NULL onconf */ - 217, /* (368) ccons ::= GENERATED ALWAYS AS generated */ - 217, /* (369) ccons ::= AS generated */ - 204, /* (370) conslist_opt ::= COMMA conslist */ - 230, /* (371) conslist ::= conslist tconscomma tcons */ - 230, /* (372) conslist ::= tcons */ - 231, /* (373) tconscomma ::= */ - 235, /* (374) defer_subclause_opt ::= defer_subclause */ - 237, /* (375) resolvetype ::= raisetype */ - 241, /* (376) selectnowith ::= oneselect */ - 242, /* (377) oneselect ::= values */ - 257, /* (378) sclp ::= selcollist COMMA */ - 258, /* (379) as ::= ID|STRING */ - 267, /* (380) indexed_opt ::= indexed_by */ - 275, /* (381) returning ::= */ - 219, /* (382) expr ::= term */ - 277, /* (383) likeop ::= LIKE_KW|MATCH */ - 281, /* (384) case_operand ::= expr */ - 264, /* (385) exprlist ::= nexprlist */ - 287, /* (386) nmnum ::= plus_num */ - 287, /* (387) nmnum ::= nm */ - 287, /* (388) nmnum ::= ON */ - 287, /* (389) nmnum ::= DELETE */ - 287, /* (390) nmnum ::= DEFAULT */ - 213, /* (391) plus_num ::= INTEGER|FLOAT */ - 292, /* (392) foreach_clause ::= */ - 292, /* (393) foreach_clause ::= FOR EACH ROW */ - 295, /* (394) trnm ::= nm */ - 296, /* (395) tridxby ::= */ - 297, /* (396) database_kw_opt ::= DATABASE */ - 297, /* (397) database_kw_opt ::= */ - 300, /* (398) kwcolumn_opt ::= */ - 300, /* (399) kwcolumn_opt ::= COLUMNKW */ - 302, /* (400) vtabarglist ::= vtabarg */ - 302, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ - 303, /* (402) vtabarg ::= vtabarg vtabargtoken */ - 306, /* (403) anylist ::= */ - 306, /* (404) anylist ::= anylist LP anylist RP */ - 306, /* (405) anylist ::= anylist ANY */ - 269, /* (406) with ::= */ - 310, /* (407) windowdefn_list ::= windowdefn */ - 312, /* (408) window ::= frame_opt */ + 192, /* (296) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 192, /* (297) cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ + 192, /* (298) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ + 192, /* (299) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ + 192, /* (300) cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ + 192, /* (301) cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ + 192, /* (302) cmd ::= create_vtab */ + 192, /* (303) cmd ::= create_vtab LP vtabarglist RP */ + 300, /* (304) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 302, /* (305) vtabarg ::= */ + 303, /* (306) vtabargtoken ::= ANY */ + 303, /* (307) vtabargtoken ::= lp anylist RP */ + 304, /* (308) lp ::= LP */ + 269, /* (309) with ::= WITH wqlist */ + 269, /* (310) with ::= WITH RECURSIVE wqlist */ + 307, /* (311) wqas ::= AS */ + 307, /* (312) wqas ::= AS MATERIALIZED */ + 307, /* (313) wqas ::= AS NOT MATERIALIZED */ + 306, /* (314) wqitem ::= withnm eidlist_opt wqas LP select RP */ + 308, /* (315) withnm ::= nm */ + 243, /* (316) wqlist ::= wqitem */ + 243, /* (317) wqlist ::= wqlist COMMA wqitem */ + 309, /* (318) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 310, /* (319) windowdefn ::= nm AS LP window RP */ + 311, /* (320) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 311, /* (321) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 311, /* (322) window ::= ORDER BY sortlist frame_opt */ + 311, /* (323) window ::= nm ORDER BY sortlist frame_opt */ + 311, /* (324) window ::= nm frame_opt */ + 312, /* (325) frame_opt ::= */ + 312, /* (326) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 312, /* (327) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 316, /* (328) range_or_rows ::= RANGE|ROWS|GROUPS */ + 318, /* (329) frame_bound_s ::= frame_bound */ + 318, /* (330) frame_bound_s ::= UNBOUNDED PRECEDING */ + 319, /* (331) frame_bound_e ::= frame_bound */ + 319, /* (332) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 317, /* (333) frame_bound ::= expr PRECEDING|FOLLOWING */ + 317, /* (334) frame_bound ::= CURRENT ROW */ + 320, /* (335) frame_exclude_opt ::= */ + 320, /* (336) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 321, /* (337) frame_exclude ::= NO OTHERS */ + 321, /* (338) frame_exclude ::= CURRENT ROW */ + 321, /* (339) frame_exclude ::= GROUP|TIES */ + 253, /* (340) window_clause ::= WINDOW windowdefn_list */ + 276, /* (341) filter_over ::= filter_clause over_clause */ + 276, /* (342) filter_over ::= over_clause */ + 276, /* (343) filter_over ::= filter_clause */ + 315, /* (344) over_clause ::= OVER LP window RP */ + 315, /* (345) over_clause ::= OVER nm */ + 314, /* (346) filter_clause ::= FILTER LP WHERE expr RP */ + 218, /* (347) term ::= QNUMBER */ + 187, /* (348) input ::= cmdlist */ + 188, /* (349) cmdlist ::= cmdlist ecmd */ + 188, /* (350) cmdlist ::= ecmd */ + 189, /* (351) ecmd ::= SEMI */ + 189, /* (352) ecmd ::= cmdx SEMI */ + 189, /* (353) ecmd ::= explain cmdx SEMI */ + 194, /* (354) trans_opt ::= */ + 194, /* (355) trans_opt ::= TRANSACTION */ + 194, /* (356) trans_opt ::= TRANSACTION nm */ + 196, /* (357) savepoint_opt ::= SAVEPOINT */ + 196, /* (358) savepoint_opt ::= */ + 192, /* (359) cmd ::= create_table create_table_args */ + 205, /* (360) table_option_set ::= table_option */ + 203, /* (361) columnlist ::= columnlist COMMA columnname carglist */ + 203, /* (362) columnlist ::= columnname carglist */ + 195, /* (363) nm ::= ID|INDEXED|JOIN_KW */ + 195, /* (364) nm ::= STRING */ + 210, /* (365) typetoken ::= typename */ + 211, /* (366) typename ::= ID|STRING */ + 212, /* (367) signed ::= plus_num */ + 212, /* (368) signed ::= minus_num */ + 209, /* (369) carglist ::= carglist ccons */ + 209, /* (370) carglist ::= */ + 217, /* (371) ccons ::= NULL onconf */ + 217, /* (372) ccons ::= GENERATED ALWAYS AS generated */ + 217, /* (373) ccons ::= AS generated */ + 204, /* (374) conslist_opt ::= COMMA conslist */ + 230, /* (375) conslist ::= conslist tconscomma tcons */ + 230, /* (376) conslist ::= tcons */ + 231, /* (377) tconscomma ::= */ + 235, /* (378) defer_subclause_opt ::= defer_subclause */ + 237, /* (379) resolvetype ::= raisetype */ + 241, /* (380) selectnowith ::= oneselect */ + 242, /* (381) oneselect ::= values */ + 257, /* (382) sclp ::= selcollist COMMA */ + 258, /* (383) as ::= ID|STRING */ + 267, /* (384) indexed_opt ::= indexed_by */ + 275, /* (385) returning ::= */ + 219, /* (386) expr ::= term */ + 277, /* (387) likeop ::= LIKE_KW|MATCH */ + 281, /* (388) case_operand ::= expr */ + 264, /* (389) exprlist ::= nexprlist */ + 287, /* (390) nmnum ::= plus_num */ + 287, /* (391) nmnum ::= nm */ + 287, /* (392) nmnum ::= ON */ + 287, /* (393) nmnum ::= DELETE */ + 287, /* (394) nmnum ::= DEFAULT */ + 213, /* (395) plus_num ::= INTEGER|FLOAT */ + 292, /* (396) foreach_clause ::= */ + 292, /* (397) foreach_clause ::= FOR EACH ROW */ + 295, /* (398) tridxby ::= */ + 296, /* (399) database_kw_opt ::= DATABASE */ + 296, /* (400) database_kw_opt ::= */ + 299, /* (401) kwcolumn_opt ::= */ + 299, /* (402) kwcolumn_opt ::= COLUMNKW */ + 301, /* (403) vtabarglist ::= vtabarg */ + 301, /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ + 302, /* (405) vtabarg ::= vtabarg vtabargtoken */ + 305, /* (406) anylist ::= */ + 305, /* (407) anylist ::= anylist LP anylist RP */ + 305, /* (408) anylist ::= anylist ANY */ + 269, /* (409) with ::= */ + 309, /* (410) windowdefn_list ::= windowdefn */ + 311, /* (411) window ::= frame_opt */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -180876,8 +184215,8 @@ static const signed char yyRuleInfoNRhs[] = { -3, /* (119) fullname ::= nm DOT nm */ -1, /* (120) xfullname ::= nm */ -3, /* (121) xfullname ::= nm DOT nm */ - -5, /* (122) xfullname ::= nm DOT nm AS nm */ - -3, /* (123) xfullname ::= nm AS nm */ + -3, /* (122) xfullname ::= nm AS nm */ + -5, /* (123) xfullname ::= nm DOT nm AS nm */ -1, /* (124) joinop ::= COMMA|JOIN */ -2, /* (125) joinop ::= JOIN_KW JOIN */ -3, /* (126) joinop ::= JOIN_KW nm JOIN */ @@ -181026,143 +184365,146 @@ static const signed char yyRuleInfoNRhs[] = { -2, /* (269) when_clause ::= WHEN expr */ -3, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ -2, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (272) trnm ::= nm DOT nm */ - -3, /* (273) tridxby ::= INDEXED BY nm */ - -2, /* (274) tridxby ::= NOT INDEXED */ - -9, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (278) trigger_cmd ::= scanpt select scanpt */ - -4, /* (279) expr ::= RAISE LP IGNORE RP */ - -6, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ - -1, /* (281) raisetype ::= ROLLBACK */ - -1, /* (282) raisetype ::= ABORT */ - -1, /* (283) raisetype ::= FAIL */ - -4, /* (284) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (286) cmd ::= DETACH database_kw_opt expr */ - 0, /* (287) key_opt ::= */ - -2, /* (288) key_opt ::= KEY expr */ - -1, /* (289) cmd ::= REINDEX */ - -3, /* (290) cmd ::= REINDEX nm dbnm */ - -1, /* (291) cmd ::= ANALYZE */ - -3, /* (292) cmd ::= ANALYZE nm dbnm */ - -6, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -3, /* (272) tridxby ::= INDEXED BY nm */ + -2, /* (273) tridxby ::= NOT INDEXED */ + -9, /* (274) trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ + -8, /* (275) trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ + -6, /* (276) trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ + -3, /* (277) trigger_cmd ::= scanpt select scanpt */ + -4, /* (278) expr ::= RAISE LP IGNORE RP */ + -6, /* (279) expr ::= RAISE LP raisetype COMMA expr RP */ + -1, /* (280) raisetype ::= ROLLBACK */ + -1, /* (281) raisetype ::= ABORT */ + -1, /* (282) raisetype ::= FAIL */ + -4, /* (283) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (284) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (285) cmd ::= DETACH database_kw_opt expr */ + 0, /* (286) key_opt ::= */ + -2, /* (287) key_opt ::= KEY expr */ + -1, /* (288) cmd ::= REINDEX */ + -3, /* (289) cmd ::= REINDEX nm dbnm */ + -1, /* (290) cmd ::= ANALYZE */ + -3, /* (291) cmd ::= ANALYZE nm dbnm */ + -6, /* (292) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -2, /* (293) cmd ::= alter_add carglist */ + -7, /* (294) alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ -6, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - -1, /* (296) add_column_fullname ::= fullname */ - -8, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (298) cmd ::= create_vtab */ - -4, /* (299) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (301) vtabarg ::= */ - -1, /* (302) vtabargtoken ::= ANY */ - -3, /* (303) vtabargtoken ::= lp anylist RP */ - -1, /* (304) lp ::= LP */ - -2, /* (305) with ::= WITH wqlist */ - -3, /* (306) with ::= WITH RECURSIVE wqlist */ - -1, /* (307) wqas ::= AS */ - -2, /* (308) wqas ::= AS MATERIALIZED */ - -3, /* (309) wqas ::= AS NOT MATERIALIZED */ - -6, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */ - -1, /* (311) withnm ::= nm */ - -1, /* (312) wqlist ::= wqitem */ - -3, /* (313) wqlist ::= wqlist COMMA wqitem */ - -3, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (315) windowdefn ::= nm AS LP window RP */ - -5, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (318) window ::= ORDER BY sortlist frame_opt */ - -5, /* (319) window ::= nm ORDER BY sortlist frame_opt */ - -2, /* (320) window ::= nm frame_opt */ - 0, /* (321) frame_opt ::= */ - -3, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (325) frame_bound_s ::= frame_bound */ - -2, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (327) frame_bound_e ::= frame_bound */ - -2, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (330) frame_bound ::= CURRENT ROW */ - 0, /* (331) frame_exclude_opt ::= */ - -2, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (333) frame_exclude ::= NO OTHERS */ - -2, /* (334) frame_exclude ::= CURRENT ROW */ - -1, /* (335) frame_exclude ::= GROUP|TIES */ - -2, /* (336) window_clause ::= WINDOW windowdefn_list */ - -2, /* (337) filter_over ::= filter_clause over_clause */ - -1, /* (338) filter_over ::= over_clause */ - -1, /* (339) filter_over ::= filter_clause */ - -4, /* (340) over_clause ::= OVER LP window RP */ - -2, /* (341) over_clause ::= OVER nm */ - -5, /* (342) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (343) term ::= QNUMBER */ - -1, /* (344) input ::= cmdlist */ - -2, /* (345) cmdlist ::= cmdlist ecmd */ - -1, /* (346) cmdlist ::= ecmd */ - -1, /* (347) ecmd ::= SEMI */ - -2, /* (348) ecmd ::= cmdx SEMI */ - -3, /* (349) ecmd ::= explain cmdx SEMI */ - 0, /* (350) trans_opt ::= */ - -1, /* (351) trans_opt ::= TRANSACTION */ - -2, /* (352) trans_opt ::= TRANSACTION nm */ - -1, /* (353) savepoint_opt ::= SAVEPOINT */ - 0, /* (354) savepoint_opt ::= */ - -2, /* (355) cmd ::= create_table create_table_args */ - -1, /* (356) table_option_set ::= table_option */ - -4, /* (357) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (358) columnlist ::= columnname carglist */ - -1, /* (359) nm ::= ID|INDEXED|JOIN_KW */ - -1, /* (360) nm ::= STRING */ - -1, /* (361) typetoken ::= typename */ - -1, /* (362) typename ::= ID|STRING */ - -1, /* (363) signed ::= plus_num */ - -1, /* (364) signed ::= minus_num */ - -2, /* (365) carglist ::= carglist ccons */ - 0, /* (366) carglist ::= */ - -2, /* (367) ccons ::= NULL onconf */ - -4, /* (368) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (369) ccons ::= AS generated */ - -2, /* (370) conslist_opt ::= COMMA conslist */ - -3, /* (371) conslist ::= conslist tconscomma tcons */ - -1, /* (372) conslist ::= tcons */ - 0, /* (373) tconscomma ::= */ - -1, /* (374) defer_subclause_opt ::= defer_subclause */ - -1, /* (375) resolvetype ::= raisetype */ - -1, /* (376) selectnowith ::= oneselect */ - -1, /* (377) oneselect ::= values */ - -2, /* (378) sclp ::= selcollist COMMA */ - -1, /* (379) as ::= ID|STRING */ - -1, /* (380) indexed_opt ::= indexed_by */ - 0, /* (381) returning ::= */ - -1, /* (382) expr ::= term */ - -1, /* (383) likeop ::= LIKE_KW|MATCH */ - -1, /* (384) case_operand ::= expr */ - -1, /* (385) exprlist ::= nexprlist */ - -1, /* (386) nmnum ::= plus_num */ - -1, /* (387) nmnum ::= nm */ - -1, /* (388) nmnum ::= ON */ - -1, /* (389) nmnum ::= DELETE */ - -1, /* (390) nmnum ::= DEFAULT */ - -1, /* (391) plus_num ::= INTEGER|FLOAT */ - 0, /* (392) foreach_clause ::= */ - -3, /* (393) foreach_clause ::= FOR EACH ROW */ - -1, /* (394) trnm ::= nm */ - 0, /* (395) tridxby ::= */ - -1, /* (396) database_kw_opt ::= DATABASE */ - 0, /* (397) database_kw_opt ::= */ - 0, /* (398) kwcolumn_opt ::= */ - -1, /* (399) kwcolumn_opt ::= COLUMNKW */ - -1, /* (400) vtabarglist ::= vtabarg */ - -3, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (402) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (403) anylist ::= */ - -4, /* (404) anylist ::= anylist LP anylist RP */ - -2, /* (405) anylist ::= anylist ANY */ - 0, /* (406) with ::= */ - -1, /* (407) windowdefn_list ::= windowdefn */ - -1, /* (408) window ::= frame_opt */ + -8, /* (296) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -6, /* (297) cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ + -9, /* (298) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ + -10, /* (299) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ + -11, /* (300) cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ + -9, /* (301) cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ + -1, /* (302) cmd ::= create_vtab */ + -4, /* (303) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (304) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (305) vtabarg ::= */ + -1, /* (306) vtabargtoken ::= ANY */ + -3, /* (307) vtabargtoken ::= lp anylist RP */ + -1, /* (308) lp ::= LP */ + -2, /* (309) with ::= WITH wqlist */ + -3, /* (310) with ::= WITH RECURSIVE wqlist */ + -1, /* (311) wqas ::= AS */ + -2, /* (312) wqas ::= AS MATERIALIZED */ + -3, /* (313) wqas ::= AS NOT MATERIALIZED */ + -6, /* (314) wqitem ::= withnm eidlist_opt wqas LP select RP */ + -1, /* (315) withnm ::= nm */ + -1, /* (316) wqlist ::= wqitem */ + -3, /* (317) wqlist ::= wqlist COMMA wqitem */ + -3, /* (318) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (319) windowdefn ::= nm AS LP window RP */ + -5, /* (320) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (321) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (322) window ::= ORDER BY sortlist frame_opt */ + -5, /* (323) window ::= nm ORDER BY sortlist frame_opt */ + -2, /* (324) window ::= nm frame_opt */ + 0, /* (325) frame_opt ::= */ + -3, /* (326) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (327) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (328) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (329) frame_bound_s ::= frame_bound */ + -2, /* (330) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (331) frame_bound_e ::= frame_bound */ + -2, /* (332) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (333) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (334) frame_bound ::= CURRENT ROW */ + 0, /* (335) frame_exclude_opt ::= */ + -2, /* (336) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (337) frame_exclude ::= NO OTHERS */ + -2, /* (338) frame_exclude ::= CURRENT ROW */ + -1, /* (339) frame_exclude ::= GROUP|TIES */ + -2, /* (340) window_clause ::= WINDOW windowdefn_list */ + -2, /* (341) filter_over ::= filter_clause over_clause */ + -1, /* (342) filter_over ::= over_clause */ + -1, /* (343) filter_over ::= filter_clause */ + -4, /* (344) over_clause ::= OVER LP window RP */ + -2, /* (345) over_clause ::= OVER nm */ + -5, /* (346) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (347) term ::= QNUMBER */ + -1, /* (348) input ::= cmdlist */ + -2, /* (349) cmdlist ::= cmdlist ecmd */ + -1, /* (350) cmdlist ::= ecmd */ + -1, /* (351) ecmd ::= SEMI */ + -2, /* (352) ecmd ::= cmdx SEMI */ + -3, /* (353) ecmd ::= explain cmdx SEMI */ + 0, /* (354) trans_opt ::= */ + -1, /* (355) trans_opt ::= TRANSACTION */ + -2, /* (356) trans_opt ::= TRANSACTION nm */ + -1, /* (357) savepoint_opt ::= SAVEPOINT */ + 0, /* (358) savepoint_opt ::= */ + -2, /* (359) cmd ::= create_table create_table_args */ + -1, /* (360) table_option_set ::= table_option */ + -4, /* (361) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (362) columnlist ::= columnname carglist */ + -1, /* (363) nm ::= ID|INDEXED|JOIN_KW */ + -1, /* (364) nm ::= STRING */ + -1, /* (365) typetoken ::= typename */ + -1, /* (366) typename ::= ID|STRING */ + -1, /* (367) signed ::= plus_num */ + -1, /* (368) signed ::= minus_num */ + -2, /* (369) carglist ::= carglist ccons */ + 0, /* (370) carglist ::= */ + -2, /* (371) ccons ::= NULL onconf */ + -4, /* (372) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (373) ccons ::= AS generated */ + -2, /* (374) conslist_opt ::= COMMA conslist */ + -3, /* (375) conslist ::= conslist tconscomma tcons */ + -1, /* (376) conslist ::= tcons */ + 0, /* (377) tconscomma ::= */ + -1, /* (378) defer_subclause_opt ::= defer_subclause */ + -1, /* (379) resolvetype ::= raisetype */ + -1, /* (380) selectnowith ::= oneselect */ + -1, /* (381) oneselect ::= values */ + -2, /* (382) sclp ::= selcollist COMMA */ + -1, /* (383) as ::= ID|STRING */ + -1, /* (384) indexed_opt ::= indexed_by */ + 0, /* (385) returning ::= */ + -1, /* (386) expr ::= term */ + -1, /* (387) likeop ::= LIKE_KW|MATCH */ + -1, /* (388) case_operand ::= expr */ + -1, /* (389) exprlist ::= nexprlist */ + -1, /* (390) nmnum ::= plus_num */ + -1, /* (391) nmnum ::= nm */ + -1, /* (392) nmnum ::= ON */ + -1, /* (393) nmnum ::= DELETE */ + -1, /* (394) nmnum ::= DEFAULT */ + -1, /* (395) plus_num ::= INTEGER|FLOAT */ + 0, /* (396) foreach_clause ::= */ + -3, /* (397) foreach_clause ::= FOR EACH ROW */ + 0, /* (398) tridxby ::= */ + -1, /* (399) database_kw_opt ::= DATABASE */ + 0, /* (400) database_kw_opt ::= */ + 0, /* (401) kwcolumn_opt ::= */ + -1, /* (402) kwcolumn_opt ::= COLUMNKW */ + -1, /* (403) vtabarglist ::= vtabarg */ + -3, /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (405) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (406) anylist ::= */ + -4, /* (407) anylist ::= anylist LP anylist RP */ + -2, /* (408) anylist ::= anylist ANY */ + 0, /* (409) with ::= */ + -1, /* (410) windowdefn_list ::= windowdefn */ + -1, /* (411) window ::= frame_opt */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -181214,16 +184556,16 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy502);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy502 = TK_DEFERRED;} +{yymsp[1].minor.yy144 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); - case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324); -{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/} + case 328: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==328); +{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -181246,7 +184588,7 @@ static YYACTIONTYPE yy_reduce( break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy502,0,0,yymsp[-2].minor.yy502); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144); } break; case 14: /* createkw ::= CREATE */ @@ -181262,38 +184604,38 @@ static YYACTIONTYPE yy_reduce( case 81: /* ifexists ::= */ yytestcase(yyruleno==81); case 100: /* distinct ::= */ yytestcase(yyruleno==100); case 246: /* collate ::= */ yytestcase(yyruleno==246); -{yymsp[1].minor.yy502 = 0;} +{yymsp[1].minor.yy144 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy502 = 1;} +{yymsp[-2].minor.yy144 = 1;} break; case 17: /* temp ::= TEMP */ -{yymsp[0].minor.yy502 = pParse->db->init.busy==0;} +{yymsp[0].minor.yy144 = pParse->db->init.busy==0;} break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy9,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0); } break; case 20: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy637); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy637); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); } break; case 21: /* table_option_set ::= */ -{yymsp[1].minor.yy9 = 0;} +{yymsp[1].minor.yy391 = 0;} break; case 22: /* table_option_set ::= table_option_set COMMA table_option */ -{yylhsminor.yy9 = yymsp[-2].minor.yy9|yymsp[0].minor.yy9;} - yymsp[-2].minor.yy9 = yylhsminor.yy9; +{yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;} + yymsp[-2].minor.yy391 = yylhsminor.yy391; break; case 23: /* table_option ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy9 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy9 = 0; + yymsp[-1].minor.yy391 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } @@ -181301,13 +184643,13 @@ static YYACTIONTYPE yy_reduce( case 24: /* table_option ::= nm */ { if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ - yylhsminor.yy9 = TF_Strict; + yylhsminor.yy391 = TF_Strict; }else{ - yylhsminor.yy9 = 0; + yylhsminor.yy391 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } - yymsp[0].minor.yy9 = yylhsminor.yy9; + yymsp[0].minor.yy391 = yylhsminor.yy391; break; case 25: /* columnname ::= nm typetoken */ {sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} @@ -181333,7 +184675,7 @@ static YYACTIONTYPE yy_reduce( case 30: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy342 = yyLookaheadToken.z; + yymsp[1].minor.yy168 = yyLookaheadToken.z; } break; case 31: /* scantok ::= */ @@ -181347,17 +184689,17 @@ static YYACTIONTYPE yy_reduce( {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]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 34: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy590,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; case 35: /* ccons ::= DEFAULT PLUS scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 36: /* ccons ::= DEFAULT MINUS scantok term */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy590, 0); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0); sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; @@ -181372,133 +184714,133 @@ static YYACTIONTYPE yy_reduce( } break; case 38: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy502);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);} break; case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy502,yymsp[0].minor.yy502,yymsp[-2].minor.yy502);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);} break; case 40: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy502,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 41: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy590,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} break; case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy402,yymsp[0].minor.yy502);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);} break; case 43: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy502);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);} break; case 44: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 45: /* generated ::= LP expr RP */ -{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy590,0);} +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);} break; case 46: /* generated ::= LP expr RP ID */ -{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy590,&yymsp[0].minor.yy0);} +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);} break; case 48: /* autoinc ::= AUTOINCR */ -{yymsp[0].minor.yy502 = 1;} +{yymsp[0].minor.yy144 = 1;} break; case 49: /* refargs ::= */ -{ yymsp[1].minor.yy502 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 50: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy502 = (yymsp[-1].minor.yy502 & ~yymsp[0].minor.yy481.mask) | yymsp[0].minor.yy481.value; } +{ yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; } break; case 51: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy481.value = 0; yymsp[-1].minor.yy481.mask = 0x000000; } +{ yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; } break; case 52: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy481.value = 0; yymsp[-2].minor.yy481.mask = 0x000000; } +{ yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; } break; case 53: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy481.value = yymsp[0].minor.yy502; yymsp[-2].minor.yy481.mask = 0x0000ff; } +{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; } break; case 54: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy481.value = yymsp[0].minor.yy502<<8; yymsp[-2].minor.yy481.mask = 0x00ff00; } +{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; } break; case 55: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy502 = OE_SetNull; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */} break; case 56: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy502 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 57: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy502 = OE_Cascade; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */} break; case 58: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy502 = OE_Restrict; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */} break; case 59: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy502 = OE_None; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */} break; case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy502 = 0;} +{yymsp[-2].minor.yy144 = 0;} break; case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173); -{yymsp[-1].minor.yy502 = yymsp[0].minor.yy502;} +{yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;} break; case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219); case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222); case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247); -{yymsp[-1].minor.yy502 = 1;} +{yymsp[-1].minor.yy144 = 1;} break; case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy502 = 0;} +{yymsp[-1].minor.yy144 = 0;} break; case 66: /* tconscomma ::= COMMA */ {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);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);} break; case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy402,yymsp[0].minor.yy502,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 70: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy590,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} break; case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy402, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy402, yymsp[-1].minor.yy502); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy502); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144); } break; case 73: /* onconf ::= */ case 75: /* orconf ::= */ yytestcase(yyruleno==75); -{yymsp[1].minor.yy502 = OE_Default;} +{yymsp[1].minor.yy144 = OE_Default;} break; case 74: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy502 = yymsp[0].minor.yy502;} +{yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;} break; case 77: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy502 = OE_Ignore;} +{yymsp[0].minor.yy144 = OE_Ignore;} break; case 78: /* resolvetype ::= REPLACE */ case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174); -{yymsp[0].minor.yy502 = OE_Replace;} +{yymsp[0].minor.yy144 = OE_Replace;} break; case 79: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy563, 0, yymsp[-1].minor.yy502); + sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144); } break; case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy402, yymsp[0].minor.yy637, yymsp[-7].minor.yy502, yymsp[-5].minor.yy502); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144); } break; case 83: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy563, 1, yymsp[-1].minor.yy502); + sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144); } break; case 84: /* cmd ::= select */ @@ -181507,20 +184849,20 @@ static YYACTIONTYPE yy_reduce( if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0 || sqlite3ReadSchema(pParse)==SQLITE_OK ){ - sqlite3Select(pParse, yymsp[0].minor.yy637, &dest); + sqlite3Select(pParse, yymsp[0].minor.yy555, &dest); } - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy637); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); } break; case 85: /* select ::= WITH wqlist selectnowith */ -{yymsp[-2].minor.yy637 = attachWithToSelect(pParse,yymsp[0].minor.yy637,yymsp[-1].minor.yy125);} +{yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} break; case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ -{yymsp[-3].minor.yy637 = attachWithToSelect(pParse,yymsp[0].minor.yy637,yymsp[-1].minor.yy125);} +{yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} break; case 87: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy637; + Select *p = yymsp[0].minor.yy555; if( p ){ parserDoubleLinkSelect(pParse, p); } @@ -181528,8 +184870,8 @@ static YYACTIONTYPE yy_reduce( break; case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy637; - Select *pLhs = yymsp[-2].minor.yy637; + Select *pRhs = yymsp[0].minor.yy555; + Select *pLhs = yymsp[-2].minor.yy555; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -181539,60 +184881,60 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy502; + pRhs->op = (u8)yymsp[-1].minor.yy144; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~(u32)SF_MultiValue; pRhs->selFlags &= ~(u32)SF_MultiValue; - if( yymsp[-1].minor.yy502!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy144!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy637 = pRhs; + yymsp[-2].minor.yy555 = pRhs; } break; case 89: /* multiselect_op ::= UNION */ case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); -{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-OP*/} +{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/} break; case 90: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy502 = TK_ALL;} +{yymsp[-1].minor.yy144 = TK_ALL;} break; case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy402,yymsp[-5].minor.yy563,yymsp[-4].minor.yy590,yymsp[-3].minor.yy402,yymsp[-2].minor.yy590,yymsp[-1].minor.yy402,yymsp[-7].minor.yy502,yymsp[0].minor.yy590); + yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454); } break; case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ { - yymsp[-9].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy402,yymsp[-6].minor.yy563,yymsp[-5].minor.yy590,yymsp[-4].minor.yy402,yymsp[-3].minor.yy590,yymsp[-1].minor.yy402,yymsp[-8].minor.yy502,yymsp[0].minor.yy590); - if( yymsp[-9].minor.yy637 ){ - yymsp[-9].minor.yy637->pWinDefn = yymsp[-2].minor.yy483; + yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454); + if( yymsp[-9].minor.yy555 ){ + yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211; }else{ - sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy483); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211); } } break; case 94: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy402,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0); } break; case 95: /* oneselect ::= mvalues */ { - sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy637); + sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555); } break; case 96: /* mvalues ::= values COMMA LP nexprlist RP */ case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97); { - yymsp[-4].minor.yy637 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy637, yymsp[-1].minor.yy402); + yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14); } break; case 98: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy502 = SF_Distinct;} +{yymsp[0].minor.yy144 = SF_Distinct;} break; case 99: /* distinct ::= ALL */ -{yymsp[0].minor.yy502 = SF_All;} +{yymsp[0].minor.yy144 = SF_All;} break; case 101: /* sclp ::= */ case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134); @@ -181600,20 +184942,20 @@ static YYACTIONTYPE yy_reduce( case 234: /* exprlist ::= */ yytestcase(yyruleno==234); case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237); case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242); -{yymsp[1].minor.yy402 = 0;} +{yymsp[1].minor.yy14 = 0;} break; case 102: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy402, yymsp[-2].minor.yy590); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy402, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy402,yymsp[-3].minor.yy342,yymsp[-1].minor.yy342); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168); } break; case 103: /* selcollist ::= sclp scanpt STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); - yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy402, p); + yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p); } break; case 104: /* selcollist ::= sclp scanpt nm DOT STAR */ @@ -181623,7 +184965,7 @@ static YYACTIONTYPE yy_reduce( sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, pDot); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot); } break; case 105: /* as ::= AS nm */ @@ -181634,52 +184976,53 @@ static YYACTIONTYPE yy_reduce( break; case 107: /* from ::= */ case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110); -{yymsp[1].minor.yy563 = 0;} +{yymsp[1].minor.yy203 = 0;} break; case 108: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy563 = yymsp[0].minor.yy563; - sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy563); + yymsp[-1].minor.yy203 = yymsp[0].minor.yy203; + sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203); } break; case 109: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy563 && yymsp[-1].minor.yy563->nSrc>0) ) yymsp[-1].minor.yy563->a[yymsp[-1].minor.yy563->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy502; + if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144; } break; case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */ { - yymsp[-4].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy563,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421); + yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); } break; case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ { - yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy421); - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy563, &yymsp[-1].minor.yy0); + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0); } break; case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ { - yymsp[-7].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy563,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421); - sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy563, yymsp[-3].minor.yy402); + yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); + sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14); } break; case 114: /* seltablist ::= stl_prefix LP select RP as on_using */ { - yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy637,&yymsp[0].minor.yy421); + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269); } break; case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ { - if( yymsp[-5].minor.yy563==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy421.pOn==0 && yymsp[0].minor.yy421.pUsing==0 ){ - yymsp[-5].minor.yy563 = yymsp[-3].minor.yy563; - }else if( ALWAYS(yymsp[-3].minor.yy563!=0) && yymsp[-3].minor.yy563->nSrc==1 ){ - yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421); - if( yymsp[-5].minor.yy563 ){ - SrcItem *pNew = &yymsp[-5].minor.yy563->a[yymsp[-5].minor.yy563->nSrc-1]; - SrcItem *pOld = yymsp[-3].minor.yy563->a; + if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){ + yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203; + }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){ + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); + if( yymsp[-5].minor.yy203 ){ + SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; + SrcItem *pOld = yymsp[-3].minor.yy203->a; assert( pOld->fg.fixedSchema==0 ); pNew->zName = pOld->zName; + pOld->zName = 0; assert( pOld->fg.fixedSchema==0 ); if( pOld->fg.isSubquery ){ pNew->fg.isSubquery = 1; @@ -181699,15 +185042,20 @@ static YYACTIONTYPE yy_reduce( pOld->u1.pFuncArg = 0; pOld->fg.isTabFunc = 0; pNew->fg.isTabFunc = 1; + }else if( pOld->fg.isIndexedBy ){ + pNew->u1.zIndexedBy = pOld->u1.zIndexedBy; + pOld->u1.zIndexedBy = 0; + pOld->fg.isIndexedBy = 0; + pNew->fg.isIndexedBy = 1; } - pOld->zName = 0; + pNew->fg.notIndexed = pOld->fg.notIndexed; } - sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy563); + sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy563); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy563,0,0,0,0,SF_NestedFrom,0); - yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy421); + sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0); + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269); } } break; @@ -181716,57 +185064,67 @@ static YYACTIONTYPE yy_reduce( {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} break; case 118: /* fullname ::= nm */ + case 120: /* xfullname ::= nm */ yytestcase(yyruleno==120); { - yylhsminor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy563 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy563->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy563 = yylhsminor.yy563; + yymsp[0].minor.yy203 = yylhsminor.yy203; break; case 119: /* fullname ::= nm DOT nm */ + case 121: /* xfullname ::= nm DOT nm */ yytestcase(yyruleno==121); { - yylhsminor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy563 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy563->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy563 = yylhsminor.yy563; + yymsp[-2].minor.yy203 = yylhsminor.yy203; break; - case 120: /* xfullname ::= nm */ -{yymsp[0].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} - break; - case 121: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} - break; - case 122: /* xfullname ::= nm DOT nm AS nm */ + case 122: /* xfullname ::= nm AS nm */ { - yymsp[-4].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy563 ) yymsp[-4].minor.yy563->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); + if( yylhsminor.yy203 ){ + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[-2].minor.yy0); + }else{ + yylhsminor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + } + } } + yymsp[-2].minor.yy203 = yylhsminor.yy203; break; - case 123: /* xfullname ::= nm AS nm */ + case 123: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-2].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy563 ) yymsp[-2].minor.yy563->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); + if( yylhsminor.yy203 ){ + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[-2].minor.yy0); + }else{ + yylhsminor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + } + } } + yymsp[-4].minor.yy203 = yylhsminor.yy203; break; case 124: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy502 = JT_INNER; } +{ yymsp[0].minor.yy144 = JT_INNER; } break; case 125: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} +{yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; case 126: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} +{yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; case 127: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} +{yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; case 128: /* on_using ::= ON expr */ -{yymsp[-1].minor.yy421.pOn = yymsp[0].minor.yy590; yymsp[-1].minor.yy421.pUsing = 0;} +{yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;} break; case 129: /* on_using ::= USING LP idlist RP */ -{yymsp[-3].minor.yy421.pOn = 0; yymsp[-3].minor.yy421.pUsing = yymsp[-1].minor.yy204;} +{yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;} break; case 130: /* on_using ::= */ -{yymsp[1].minor.yy421.pOn = 0; yymsp[1].minor.yy421.pUsing = 0;} +{yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;} break; case 132: /* indexed_by ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} @@ -181776,35 +185134,35 @@ static YYACTIONTYPE yy_reduce( break; case 135: /* orderby_opt ::= ORDER BY sortlist */ case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145); -{yymsp[-2].minor.yy402 = yymsp[0].minor.yy402;} +{yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;} break; case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */ { - yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402,yymsp[-2].minor.yy590); - sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy402,yymsp[-1].minor.yy502,yymsp[0].minor.yy502); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); } break; case 137: /* sortlist ::= expr sortorder nulls */ { - yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy590); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy402,yymsp[-1].minor.yy502,yymsp[0].minor.yy502); + yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); } break; case 138: /* sortorder ::= ASC */ -{yymsp[0].minor.yy502 = SQLITE_SO_ASC;} +{yymsp[0].minor.yy144 = SQLITE_SO_ASC;} break; case 139: /* sortorder ::= DESC */ -{yymsp[0].minor.yy502 = SQLITE_SO_DESC;} +{yymsp[0].minor.yy144 = SQLITE_SO_DESC;} break; case 140: /* sortorder ::= */ case 143: /* nulls ::= */ yytestcase(yyruleno==143); -{yymsp[1].minor.yy502 = SQLITE_SO_UNDEFINED;} +{yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;} break; case 141: /* nulls ::= NULLS FIRST */ -{yymsp[-1].minor.yy502 = SQLITE_SO_ASC;} +{yymsp[-1].minor.yy144 = SQLITE_SO_ASC;} break; case 142: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy502 = SQLITE_SO_DESC;} +{yymsp[-1].minor.yy144 = SQLITE_SO_DESC;} break; case 146: /* having_opt ::= */ case 148: /* limit_opt ::= */ yytestcase(yyruleno==148); @@ -181813,48 +185171,48 @@ static YYACTIONTYPE yy_reduce( case 232: /* case_else ::= */ yytestcase(yyruleno==232); case 233: /* case_operand ::= */ yytestcase(yyruleno==233); case 252: /* vinto ::= */ yytestcase(yyruleno==252); -{yymsp[1].minor.yy590 = 0;} +{yymsp[1].minor.yy454 = 0;} break; case 147: /* having_opt ::= HAVING expr */ case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154); case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156); case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231); case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251); -{yymsp[-1].minor.yy590 = yymsp[0].minor.yy590;} +{yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;} break; case 149: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy590,0);} +{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);} break; case 150: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);} +{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} break; case 151: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy590,yymsp[-2].minor.yy590);} +{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);} break; case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret orderby_opt limit_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy563, &yymsp[-3].minor.yy0); + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy203, &yymsp[-3].minor.yy0); #ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT - if( yymsp[-1].minor.yy402 || yymsp[0].minor.yy590 ){ - updateDeleteLimitError(pParse,yymsp[-1].minor.yy402,yymsp[0].minor.yy590); - yymsp[-1].minor.yy402 = 0; - yymsp[0].minor.yy590 = 0; + if( yymsp[-1].minor.yy14 || yymsp[0].minor.yy454 ){ + updateDeleteLimitError(pParse,yymsp[-1].minor.yy14,yymsp[0].minor.yy454); + yymsp[-1].minor.yy14 = 0; + yymsp[0].minor.yy454 = 0; } #endif - sqlite3DeleteFrom(pParse,yymsp[-4].minor.yy563,yymsp[-2].minor.yy590,yymsp[-1].minor.yy402,yymsp[0].minor.yy590); + sqlite3DeleteFrom(pParse,yymsp[-4].minor.yy203,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[0].minor.yy454); } break; case 157: /* where_opt_ret ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy402); yymsp[-1].minor.yy590 = 0;} +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;} break; case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy402); yymsp[-3].minor.yy590 = yymsp[-2].minor.yy590;} +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;} break; case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret orderby_opt limit_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-7].minor.yy563, &yymsp[-6].minor.yy0); - if( yymsp[-3].minor.yy563 ){ - SrcList *pFromClause = yymsp[-3].minor.yy563; + sqlite3SrcListIndexedBy(pParse, yymsp[-7].minor.yy203, &yymsp[-6].minor.yy0); + if( yymsp[-3].minor.yy203 ){ + SrcList *pFromClause = yymsp[-3].minor.yy203; if( pFromClause->nSrc>1 ){ Select *pSubquery; Token as; @@ -181863,98 +185221,98 @@ static YYACTIONTYPE yy_reduce( as.z = 0; pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); } - yymsp[-7].minor.yy563 = sqlite3SrcListAppendList(pParse, yymsp[-7].minor.yy563, pFromClause); + yymsp[-7].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-7].minor.yy203, pFromClause); } - sqlite3ExprListCheckLength(pParse,yymsp[-4].minor.yy402,"set list"); + sqlite3ExprListCheckLength(pParse,yymsp[-4].minor.yy14,"set list"); #ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT - if( yymsp[-1].minor.yy402 || yymsp[0].minor.yy590 ){ - updateDeleteLimitError(pParse,yymsp[-1].minor.yy402,yymsp[0].minor.yy590); - yymsp[-1].minor.yy402 = 0; - yymsp[0].minor.yy590 = 0; + if( yymsp[-1].minor.yy14 || yymsp[0].minor.yy454 ){ + updateDeleteLimitError(pParse,yymsp[-1].minor.yy14,yymsp[0].minor.yy454); + yymsp[-1].minor.yy14 = 0; + yymsp[0].minor.yy454 = 0; } #endif - sqlite3Update(pParse,yymsp[-7].minor.yy563,yymsp[-4].minor.yy402,yymsp[-2].minor.yy590,yymsp[-8].minor.yy502,yymsp[-1].minor.yy402,yymsp[0].minor.yy590,0); + sqlite3Update(pParse,yymsp[-7].minor.yy203,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454,yymsp[-8].minor.yy144,yymsp[-1].minor.yy14,yymsp[0].minor.yy454,0); } break; case 160: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy402, yymsp[0].minor.yy590); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1); } break; case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy402 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy402, yymsp[-3].minor.yy204, yymsp[0].minor.yy590); + yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); } break; case 162: /* setlist ::= nm EQ expr */ { - yylhsminor.yy402 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy590); - sqlite3ExprListSetName(pParse, yylhsminor.yy402, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454); + sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy402 = yylhsminor.yy402; + yymsp[-2].minor.yy14 = yylhsminor.yy14; break; case 163: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy402 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy204, yymsp[0].minor.yy590); + yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); } break; case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy563, yymsp[-1].minor.yy637, yymsp[-2].minor.yy204, yymsp[-5].minor.yy502, yymsp[0].minor.yy403); + sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122); } break; case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ { - sqlite3Insert(pParse, yymsp[-4].minor.yy563, 0, yymsp[-3].minor.yy204, yymsp[-6].minor.yy502, 0); + sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0); } break; case 166: /* upsert ::= */ -{ yymsp[1].minor.yy403 = 0; } +{ yymsp[1].minor.yy122 = 0; } break; case 167: /* upsert ::= RETURNING selcollist */ -{ yymsp[-1].minor.yy403 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy402); } +{ yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); } break; case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ -{ yymsp[-11].minor.yy403 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy402,yymsp[-6].minor.yy590,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590,yymsp[0].minor.yy403);} +{ yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);} break; case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ -{ yymsp[-8].minor.yy403 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy402,yymsp[-3].minor.yy590,0,0,yymsp[0].minor.yy403); } +{ yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); } break; case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */ -{ yymsp[-4].minor.yy403 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } +{ yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } break; case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ -{ yymsp[-7].minor.yy403 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590,0);} +{ yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);} break; case 172: /* returning ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy402);} +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14);} break; case 175: /* idlist_opt ::= */ -{yymsp[1].minor.yy204 = 0;} +{yymsp[1].minor.yy132 = 0;} break; case 176: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy204 = yymsp[-1].minor.yy204;} +{yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;} break; case 177: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy204 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy204,&yymsp[0].minor.yy0);} +{yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);} break; case 178: /* idlist ::= nm */ -{yymsp[0].minor.yy204 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} +{yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; case 179: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy590 = yymsp[-1].minor.yy590;} +{yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;} break; case 180: /* expr ::= ID|INDEXED|JOIN_KW */ -{yymsp[0].minor.yy590=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 181: /* expr ::= nm DOT nm */ { Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); - yylhsminor.yy590 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy590 = yylhsminor.yy590; + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; case 182: /* expr ::= nm DOT nm DOT nm */ { @@ -181965,27 +185323,32 @@ static YYACTIONTYPE yy_reduce( if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, 0, temp1); } - yylhsminor.yy590 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy590 = yylhsminor.yy590; + yymsp[-4].minor.yy454 = yylhsminor.yy454; break; case 183: /* term ::= NULL|FLOAT|BLOB */ case 184: /* term ::= STRING */ yytestcase(yyruleno==184); -{yymsp[0].minor.yy590=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 185: /* term ::= INTEGER */ { - yylhsminor.yy590 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); - if( yylhsminor.yy590 ) yylhsminor.yy590->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); + int iValue; + if( sqlite3GetInt32(yymsp[0].minor.yy0.z, &iValue)==0 ){ + yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 0); + }else{ + yylhsminor.yy454 = sqlite3ExprInt32(pParse->db, iValue); + } + if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); } - yymsp[0].minor.yy590 = yylhsminor.yy590; + yymsp[0].minor.yy454 = yylhsminor.yy454; break; case 186: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; - yymsp[0].minor.yy590 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy590, n); + yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -181994,80 +185357,82 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ parserSyntaxError(pParse, &t); - yymsp[0].minor.yy590 = 0; + yymsp[0].minor.yy454 = 0; }else{ - yymsp[0].minor.yy590 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy590 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy590->iTable); + yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable); } } } break; case 187: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy590 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy590, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1); } break; case 188: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy590 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy590, yymsp[-3].minor.yy590, 0); + yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0); } break; case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ { - yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy502); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144); } - yymsp[-4].minor.yy590 = yylhsminor.yy590; + yymsp[-4].minor.yy454 = yylhsminor.yy454; break; case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ { - yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy402, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy502); - sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy590, yymsp[-1].minor.yy402); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14); } - yymsp[-7].minor.yy590 = yylhsminor.yy590; + yymsp[-7].minor.yy454 = yylhsminor.yy454; break; case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ { - yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy590 = yylhsminor.yy590; + yymsp[-3].minor.yy454 = yylhsminor.yy454; break; case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ { - yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy402, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy502); - sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); } - yymsp[-5].minor.yy590 = yylhsminor.yy590; + yymsp[-5].minor.yy454 = yylhsminor.yy454; break; case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ { - yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy402, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy502); - sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483); - sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy590, yymsp[-2].minor.yy402); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14); } - yymsp[-8].minor.yy590 = yylhsminor.yy590; + yymsp[-8].minor.yy454 = yylhsminor.yy454; break; case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ { - yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); } - yymsp[-4].minor.yy590 = yylhsminor.yy590; + yymsp[-4].minor.yy454 = yylhsminor.yy454; break; case 195: /* term ::= CTIME_KW */ { - yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy590 = yylhsminor.yy590; + yymsp[0].minor.yy454 = yylhsminor.yy454; break; case 196: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy402, yymsp[-1].minor.yy590); - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy590 ){ - yymsp[-4].minor.yy590->x.pList = pList; - if( ALWAYS(pList->nExpr) ){ - yymsp[-4].minor.yy590->flags |= pList->a[0].pExpr->flags & EP_Propagate; + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy454 ){ + int i; + yymsp[-4].minor.yy454->x.pList = pList; + for(i=0; inExpr; i++){ + assert( pList->a[i].pExpr!=0 ); + yymsp[-4].minor.yy454->flags |= pList->a[i].pExpr->flags & EP_Propagate; } }else{ sqlite3ExprListDelete(pParse->db, pList); @@ -182075,7 +185440,7 @@ static YYACTIONTYPE yy_reduce( } break; case 197: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy590=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);} +{yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} break; case 198: /* expr ::= expr OR expr */ case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199); @@ -182084,7 +185449,7 @@ static YYACTIONTYPE yy_reduce( case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202); case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203); case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204); -{yymsp[-2].minor.yy590=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);} +{yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} break; case 205: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} @@ -182094,11 +185459,11 @@ static YYACTIONTYPE yy_reduce( ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy590); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy590); - yymsp[-2].minor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy590, 0); - if( yymsp[-2].minor.yy590 ) yymsp[-2].minor.yy590->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454); + yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0); + if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc; } break; case 207: /* expr ::= expr likeop expr ESCAPE expr */ @@ -182106,91 +185471,88 @@ static YYACTIONTYPE yy_reduce( ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy590); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy590); - yymsp[-4].minor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); - if( yymsp[-4].minor.yy590 ) yymsp[-4].minor.yy590->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc; } break; case 208: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy590,0);} +{yymsp[-1].minor.yy454 = sqlite3PExprIsNull(pParse,yymsp[0].major,yymsp[-1].minor.yy454);} break; case 209: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy590 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy590,0);} +{yymsp[-2].minor.yy454 = sqlite3PExprIsNull(pParse,TK_NOTNULL,yymsp[-2].minor.yy454);} break; case 210: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy590 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy590,yymsp[0].minor.yy590); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-2].minor.yy590, TK_ISNULL); + yymsp[-2].minor.yy454 = sqlite3PExprIs(pParse, TK_IS, yymsp[-2].minor.yy454, yymsp[0].minor.yy454); } break; case 211: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy590,yymsp[0].minor.yy590); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-3].minor.yy590, TK_NOTNULL); + yymsp[-3].minor.yy454 = sqlite3PExprIs(pParse, TK_ISNOT, yymsp[-3].minor.yy454, yymsp[0].minor.yy454); } break; case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */ { - yymsp[-5].minor.yy590 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy590,yymsp[0].minor.yy590); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-5].minor.yy590, TK_ISNULL); + yymsp[-5].minor.yy454 = sqlite3PExprIs(pParse, TK_IS, yymsp[-5].minor.yy454, yymsp[0].minor.yy454); } break; case 213: /* expr ::= expr IS DISTINCT FROM expr */ { - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy590,yymsp[0].minor.yy590); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-4].minor.yy590, TK_NOTNULL); + yymsp[-4].minor.yy454 = sqlite3PExprIs(pParse, TK_ISNOT, yymsp[-4].minor.yy454, yymsp[0].minor.yy454); } break; case 214: /* expr ::= NOT expr */ case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215); -{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy590, 0);/*A-overwrites-B*/} +{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/} break; case 216: /* expr ::= PLUS|MINUS expr */ { - Expr *p = yymsp[0].minor.yy590; + Expr *p = yymsp[0].minor.yy454; u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS); assert( TK_UPLUS>TK_PLUS ); assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) ); if( p && p->op==TK_UPLUS ){ p->op = op; - yymsp[-1].minor.yy590 = p; + yymsp[-1].minor.yy454 = p; }else{ - yymsp[-1].minor.yy590 = sqlite3PExpr(pParse, op, p, 0); + yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0); /*A-overwrites-B*/ } } break; case 217: /* expr ::= expr PTR expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy590); - pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy590); - yylhsminor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); } - yymsp[-2].minor.yy590 = yylhsminor.yy590; + yymsp[-2].minor.yy454 = yylhsminor.yy454; break; case 218: /* between_op ::= BETWEEN */ case 221: /* in_op ::= IN */ yytestcase(yyruleno==221); -{yymsp[0].minor.yy502 = 0;} +{yymsp[0].minor.yy144 = 0;} break; case 220: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy590); - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy590, 0); - if( yymsp[-4].minor.yy590 ){ - yymsp[-4].minor.yy590->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ){ + yymsp[-4].minor.yy454->x.pList = pList; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); } break; case 223: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy402==0 ){ + if( yymsp[-1].minor.yy14==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -182203,145 +185565,149 @@ static YYACTIONTYPE yy_reduce( ** it is or not) and if it is an aggregate, that could change the meaning ** of the whole query. */ - Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false"); + Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy144 ? "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; + if( !ExprHasProperty(yymsp[-4].minor.yy454, EP_HasFunc) ){ + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy454); + yymsp[-4].minor.yy454 = pB; }else{ - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, yymsp[-3].minor.yy502 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy590); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, yymsp[-3].minor.yy144 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy454); } }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 ){ - yymsp[-1].minor.yy402->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402); + Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr; + if( yymsp[-1].minor.yy14->nExpr==1 + && sqlite3ExprIsConstant(pParse,pRHS) + && pRHS->op!=TK_COLLATE + && yymsp[-4].minor.yy454->op!=TK_VECTOR + ){ + yymsp[-1].minor.yy14->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy590, pRHS); - }else if( yymsp[-1].minor.yy402->nExpr==1 && pRHS->op==TK_SELECT ){ - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pRHS->x.pSelect); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy454, pRHS); + }else if( yymsp[-1].minor.yy14->nExpr==1 && pRHS->op==TK_SELECT ){ + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pRHS->x.pSelect); pRHS->x.pSelect = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); }else{ - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0); - if( yymsp[-4].minor.yy590==0 ){ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402); - }else if( yymsp[-4].minor.yy590->pLeft->op==TK_VECTOR ){ - int nExpr = yymsp[-4].minor.yy590->pLeft->x.pList->nExpr; - Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy402); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454==0 ){ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + }else if( yymsp[-4].minor.yy454->pLeft->op==TK_VECTOR ){ + int nExpr = yymsp[-4].minor.yy454->pLeft->x.pList->nExpr; + Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy14); if( pSelectRHS ){ parserDoubleLinkSelect(pParse, pSelectRHS); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pSelectRHS); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelectRHS); } }else{ - yymsp[-4].minor.yy590->x.pList = yymsp[-1].minor.yy402; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy590); + yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy14; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); } } - if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); } } break; case 224: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy590 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy590, yymsp[-1].minor.yy637); + yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555); } break; case 225: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, yymsp[-1].minor.yy637); - if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); } break; case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy402 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy402); - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pSelect); - if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0); + if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); } break; case 227: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy590 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy637); + p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555); } break; case 228: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy590, 0); - if( yymsp[-4].minor.yy590 ){ - yymsp[-4].minor.yy590->x.pList = yymsp[-1].minor.yy590 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590) : yymsp[-2].minor.yy402; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy590); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ){ + yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy402); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); } } break; case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[-2].minor.yy590); - yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[0].minor.yy590); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454); } break; case 230: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590); - yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy402, yymsp[0].minor.yy590); + yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454); } break; case 235: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[0].minor.yy590);} +{yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);} break; case 236: /* nexprlist ::= expr */ -{yymsp[0].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy590); /*A-overwrites-Y*/} +{yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/} break; case 238: /* paren_exprlist ::= LP exprlist RP */ case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243); -{yymsp[-2].minor.yy402 = yymsp[-1].minor.yy402;} +{yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;} break; case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy402, yymsp[-10].minor.yy502, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy590, SQLITE_SO_ASC, yymsp[-8].minor.yy502, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; case 240: /* uniqueflag ::= UNIQUE */ - case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282); -{yymsp[0].minor.yy502 = OE_Abort;} + case 281: /* raisetype ::= ABORT */ yytestcase(yyruleno==281); +{yymsp[0].minor.yy144 = OE_Abort;} break; case 241: /* uniqueflag ::= */ -{yymsp[1].minor.yy502 = OE_None;} +{yymsp[1].minor.yy144 = OE_None;} break; case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy402 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502); + yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); } break; case 245: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy402 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502); /*A-overwrites-Y*/ + yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/ } break; case 248: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy563, yymsp[-1].minor.yy502);} +{sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);} break; case 249: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy590);} +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);} break; case 250: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy590);} +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);} break; case 253: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} @@ -182363,12 +185729,12 @@ static YYACTIONTYPE yy_reduce( Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy319, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all); } break; case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.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); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144); 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 */ @@ -182377,421 +185743,437 @@ static YYACTIONTYPE yy_reduce( } break; case 262: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/ } +{ yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ } break; case 263: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy502 = TK_INSTEAD;} +{ yymsp[-1].minor.yy144 = TK_INSTEAD;} break; case 264: /* trigger_time ::= */ -{ yymsp[1].minor.yy502 = TK_BEFORE; } +{ yymsp[1].minor.yy144 = TK_BEFORE; } break; case 265: /* trigger_event ::= DELETE|INSERT */ case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266); -{yymsp[0].minor.yy28.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy28.b = 0;} +{yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;} break; case 267: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy28.a = TK_UPDATE; yymsp[-2].minor.yy28.b = yymsp[0].minor.yy204;} +{yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;} break; case 268: /* when_clause ::= */ - case 287: /* key_opt ::= */ yytestcase(yyruleno==287); -{ yymsp[1].minor.yy590 = 0; } + case 286: /* key_opt ::= */ yytestcase(yyruleno==286); +{ yymsp[1].minor.yy454 = 0; } break; case 269: /* when_clause ::= WHEN expr */ - case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288); -{ yymsp[-1].minor.yy590 = yymsp[0].minor.yy590; } + case 287: /* key_opt ::= KEY expr */ yytestcase(yyruleno==287); +{ yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; } break; case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy319!=0 ); - yymsp[-2].minor.yy319->pLast->pNext = yymsp[-1].minor.yy319; - yymsp[-2].minor.yy319->pLast = yymsp[-1].minor.yy319; + yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427; + yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427; } break; case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy319!=0 ); - yymsp[-1].minor.yy319->pLast = yymsp[-1].minor.yy319; + yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427; } break; - case 272: /* trnm ::= nm DOT nm */ -{ - yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; - sqlite3ErrorMsg(pParse, - "qualified table names are not allowed on INSERT, UPDATE, and DELETE " - "statements within triggers"); -} - break; - case 273: /* tridxby ::= INDEXED BY nm */ + case 272: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 274: /* tridxby ::= NOT INDEXED */ + case 273: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -{yylhsminor.yy319 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy563, yymsp[-3].minor.yy402, yymsp[-1].minor.yy590, yymsp[-7].minor.yy502, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy342);} - yymsp[-8].minor.yy319 = yylhsminor.yy319; + case 274: /* trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, yymsp[-6].minor.yy203, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);} + yymsp[-8].minor.yy427 = yylhsminor.yy427; break; - case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 275: /* trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ { - yylhsminor.yy319 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy204,yymsp[-2].minor.yy637,yymsp[-6].minor.yy502,yymsp[-1].minor.yy403,yymsp[-7].minor.yy342,yymsp[0].minor.yy342);/*yylhsminor.yy319-overwrites-yymsp[-6].minor.yy502*/ + yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,yymsp[-4].minor.yy203,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/ } - yymsp[-7].minor.yy319 = yylhsminor.yy319; + yymsp[-7].minor.yy427 = yylhsminor.yy427; break; - case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy319 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy590, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy342);} - yymsp[-5].minor.yy319 = yylhsminor.yy319; + case 276: /* trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ +{yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);} + yymsp[-5].minor.yy427 = yylhsminor.yy427; break; - case 278: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy319 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy637, yymsp[-2].minor.yy342, yymsp[0].minor.yy342); /*yylhsminor.yy319-overwrites-yymsp[-1].minor.yy637*/} - yymsp[-2].minor.yy319 = yylhsminor.yy319; + case 277: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/} + yymsp[-2].minor.yy427 = yylhsminor.yy427; break; - case 279: /* expr ::= RAISE LP IGNORE RP */ + case 278: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy590 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy590 ){ - yymsp[-3].minor.yy590->affExpr = OE_Ignore; + yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy454 ){ + yymsp[-3].minor.yy454->affExpr = OE_Ignore; } } break; - case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */ + case 279: /* expr ::= RAISE LP raisetype COMMA expr RP */ { - yymsp[-5].minor.yy590 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy590, 0); - if( yymsp[-5].minor.yy590 ) { - yymsp[-5].minor.yy590->affExpr = (char)yymsp[-3].minor.yy502; + yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0); + if( yymsp[-5].minor.yy454 ) { + yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; } } break; - case 281: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy502 = OE_Rollback;} + case 280: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy144 = OE_Rollback;} break; - case 283: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy502 = OE_Fail;} + case 282: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy144 = OE_Fail;} break; - case 284: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 283: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy563,yymsp[-1].minor.yy502); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144); } break; - case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 284: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy590, yymsp[-1].minor.yy590, yymsp[0].minor.yy590); + sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454); } break; - case 286: /* cmd ::= DETACH database_kw_opt expr */ + case 285: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy590); + sqlite3Detach(pParse, yymsp[0].minor.yy454); } break; - case 289: /* cmd ::= REINDEX */ + case 288: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 290: /* cmd ::= REINDEX nm dbnm */ + case 289: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 291: /* cmd ::= ANALYZE */ + case 290: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 292: /* cmd ::= ANALYZE nm dbnm */ + case 291: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 292: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy563,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0); } break; - case 294: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 293: /* cmd ::= alter_add carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); +} + break; + case 294: /* alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ +{ + disableLookaside(pParse); + sqlite3AlterBeginAddColumn(pParse, yymsp[-4].minor.yy203); + sqlite3AddColumn(pParse, yymsp[-1].minor.yy0, yymsp[0].minor.yy0); + yymsp[-6].minor.yy0 = yymsp[-1].minor.yy0; } break; case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ { - sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy563, &yymsp[0].minor.yy0); + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0); } break; - case 296: /* add_column_fullname ::= fullname */ + case 296: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy563); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 297: /* cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ +{ + sqlite3AlterDropConstraint(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0, 0); +} + break; + case 298: /* cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ +{ + sqlite3AlterDropConstraint(pParse, yymsp[-6].minor.yy203, 0, &yymsp[-3].minor.yy0); } break; - case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 299: /* cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ { - sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy563, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterSetNotNull(pParse, yymsp[-7].minor.yy203, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0); } break; - case 298: /* cmd ::= create_vtab */ + case 300: /* cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ +{ + sqlite3AlterAddConstraint(pParse, yymsp[-8].minor.yy203, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454); +} + break; + case 301: /* cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ +{ + sqlite3AlterAddConstraint(pParse, yymsp[-6].minor.yy203, &yymsp[-4].minor.yy0, 0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454); +} + break; + case 302: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 299: /* cmd ::= create_vtab LP vtabarglist RP */ + case 303: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 300: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 304: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy502); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144); } break; - case 301: /* vtabarg ::= */ + case 305: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 302: /* vtabargtoken ::= ANY */ - case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303); - case 304: /* lp ::= LP */ yytestcase(yyruleno==304); + case 306: /* vtabargtoken ::= ANY */ + case 307: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==307); + case 308: /* lp ::= LP */ yytestcase(yyruleno==308); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 305: /* with ::= WITH wqlist */ - case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy125, 1); } + case 309: /* with ::= WITH wqlist */ + case 310: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==310); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); } break; - case 307: /* wqas ::= AS */ -{yymsp[0].minor.yy444 = M10d_Any;} + case 311: /* wqas ::= AS */ +{yymsp[0].minor.yy462 = M10d_Any;} break; - case 308: /* wqas ::= AS MATERIALIZED */ -{yymsp[-1].minor.yy444 = M10d_Yes;} + case 312: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy462 = M10d_Yes;} break; - case 309: /* wqas ::= AS NOT MATERIALIZED */ -{yymsp[-2].minor.yy444 = M10d_No;} + case 313: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy462 = M10d_No;} break; - case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */ + case 314: /* wqitem ::= withnm eidlist_opt wqas LP select RP */ { - yymsp[-5].minor.yy361 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy402, yymsp[-1].minor.yy637, yymsp[-3].minor.yy444); /*A-overwrites-X*/ + yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/ } break; - case 311: /* withnm ::= nm */ + case 315: /* withnm ::= nm */ {pParse->bHasWith = 1;} break; - case 312: /* wqlist ::= wqitem */ + case 316: /* wqlist ::= wqitem */ { - yymsp[0].minor.yy125 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy361); /*A-overwrites-X*/ + yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/ } break; - case 313: /* wqlist ::= wqlist COMMA wqitem */ + case 317: /* wqlist ::= wqlist COMMA wqitem */ { - yymsp[-2].minor.yy125 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy125, yymsp[0].minor.yy361); + yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67); } break; - case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 318: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { - assert( yymsp[0].minor.yy483!=0 ); - sqlite3WindowChain(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy483); - yymsp[0].minor.yy483->pNextWin = yymsp[-2].minor.yy483; - yylhsminor.yy483 = yymsp[0].minor.yy483; + assert( yymsp[0].minor.yy211!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211); + yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211; + yylhsminor.yy211 = yymsp[0].minor.yy211; } - yymsp[-2].minor.yy483 = yylhsminor.yy483; + yymsp[-2].minor.yy211 = yylhsminor.yy211; break; - case 315: /* windowdefn ::= nm AS LP window RP */ + case 319: /* windowdefn ::= nm AS LP window RP */ { - if( ALWAYS(yymsp[-1].minor.yy483) ){ - yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + if( ALWAYS(yymsp[-1].minor.yy211) ){ + yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } - yylhsminor.yy483 = yymsp[-1].minor.yy483; + yylhsminor.yy211 = yymsp[-1].minor.yy211; } - yymsp[-4].minor.yy483 = yylhsminor.yy483; + yymsp[-4].minor.yy211 = yylhsminor.yy211; break; - case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 320: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { - yymsp[-4].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, 0); + yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0); } break; - case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 321: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { - yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, &yymsp[-5].minor.yy0); + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy483 = yylhsminor.yy483; + yymsp[-5].minor.yy211 = yylhsminor.yy211; break; - case 318: /* window ::= ORDER BY sortlist frame_opt */ + case 322: /* window ::= ORDER BY sortlist frame_opt */ { - yymsp[-3].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, 0); + yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0); } break; - case 319: /* window ::= nm ORDER BY sortlist frame_opt */ + case 323: /* window ::= nm ORDER BY sortlist frame_opt */ { - yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0); + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy483 = yylhsminor.yy483; + yymsp[-4].minor.yy211 = yylhsminor.yy211; break; - case 320: /* window ::= nm frame_opt */ + case 324: /* window ::= nm frame_opt */ { - yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy483 = yylhsminor.yy483; + yymsp[-1].minor.yy211 = yylhsminor.yy211; break; - case 321: /* frame_opt ::= */ + case 325: /* frame_opt ::= */ { - yymsp[1].minor.yy483 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; - case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 326: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { - yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy502, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy444); + yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462); } - yymsp[-2].minor.yy483 = yylhsminor.yy483; + yymsp[-2].minor.yy211 = yylhsminor.yy211; break; - case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 327: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { - yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy502, yymsp[-3].minor.yy205.eType, yymsp[-3].minor.yy205.pExpr, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, yymsp[0].minor.yy444); + yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462); } - yymsp[-5].minor.yy483 = yylhsminor.yy483; + yymsp[-5].minor.yy211 = yylhsminor.yy211; break; - case 325: /* frame_bound_s ::= frame_bound */ - case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327); -{yylhsminor.yy205 = yymsp[0].minor.yy205;} - yymsp[0].minor.yy205 = yylhsminor.yy205; + case 329: /* frame_bound_s ::= frame_bound */ + case 331: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==331); +{yylhsminor.yy509 = yymsp[0].minor.yy509;} + yymsp[0].minor.yy509 = yylhsminor.yy509; break; - case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328); - case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330); -{yylhsminor.yy205.eType = yymsp[-1].major; yylhsminor.yy205.pExpr = 0;} - yymsp[-1].minor.yy205 = yylhsminor.yy205; + case 330: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 332: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==332); + case 334: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==334); +{yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;} + yymsp[-1].minor.yy509 = yylhsminor.yy509; break; - case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */ -{yylhsminor.yy205.eType = yymsp[0].major; yylhsminor.yy205.pExpr = yymsp[-1].minor.yy590;} - yymsp[-1].minor.yy205 = yylhsminor.yy205; + case 333: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;} + yymsp[-1].minor.yy509 = yylhsminor.yy509; break; - case 331: /* frame_exclude_opt ::= */ -{yymsp[1].minor.yy444 = 0;} + case 335: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy462 = 0;} break; - case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ -{yymsp[-1].minor.yy444 = yymsp[0].minor.yy444;} + case 336: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;} break; - case 333: /* frame_exclude ::= NO OTHERS */ - case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334); -{yymsp[-1].minor.yy444 = yymsp[-1].major; /*A-overwrites-X*/} + case 337: /* frame_exclude ::= NO OTHERS */ + case 338: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==338); +{yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 335: /* frame_exclude ::= GROUP|TIES */ -{yymsp[0].minor.yy444 = yymsp[0].major; /*A-overwrites-X*/} + case 339: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/} break; - case 336: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy483 = yymsp[0].minor.yy483; } + case 340: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; } break; - case 337: /* filter_over ::= filter_clause over_clause */ + case 341: /* filter_over ::= filter_clause over_clause */ { - if( yymsp[0].minor.yy483 ){ - yymsp[0].minor.yy483->pFilter = yymsp[-1].minor.yy590; + if( yymsp[0].minor.yy211 ){ + yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454; }else{ - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); } - yylhsminor.yy483 = yymsp[0].minor.yy483; + yylhsminor.yy211 = yymsp[0].minor.yy211; } - yymsp[-1].minor.yy483 = yylhsminor.yy483; + yymsp[-1].minor.yy211 = yylhsminor.yy211; break; - case 338: /* filter_over ::= over_clause */ + case 342: /* filter_over ::= over_clause */ { - yylhsminor.yy483 = yymsp[0].minor.yy483; + yylhsminor.yy211 = yymsp[0].minor.yy211; } - yymsp[0].minor.yy483 = yylhsminor.yy483; + yymsp[0].minor.yy211 = yylhsminor.yy211; break; - case 339: /* filter_over ::= filter_clause */ + case 343: /* filter_over ::= filter_clause */ { - yylhsminor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yylhsminor.yy483 ){ - yylhsminor.yy483->eFrmType = TK_FILTER; - yylhsminor.yy483->pFilter = yymsp[0].minor.yy590; + yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy211 ){ + yylhsminor.yy211->eFrmType = TK_FILTER; + yylhsminor.yy211->pFilter = yymsp[0].minor.yy454; }else{ - sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy590); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454); } } - yymsp[0].minor.yy483 = yylhsminor.yy483; + yymsp[0].minor.yy211 = yylhsminor.yy211; break; - case 340: /* over_clause ::= OVER LP window RP */ + case 344: /* over_clause ::= OVER LP window RP */ { - yymsp[-3].minor.yy483 = yymsp[-1].minor.yy483; - assert( yymsp[-3].minor.yy483!=0 ); + yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211; + assert( yymsp[-3].minor.yy211!=0 ); } break; - case 341: /* over_clause ::= OVER nm */ + case 345: /* over_clause ::= OVER nm */ { - yymsp[-1].minor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yymsp[-1].minor.yy483 ){ - yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy211 ){ + yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); } } break; - case 342: /* filter_clause ::= FILTER LP WHERE expr RP */ -{ yymsp[-4].minor.yy590 = yymsp[-1].minor.yy590; } + case 346: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; } break; - case 343: /* term ::= QNUMBER */ + case 347: /* term ::= QNUMBER */ { - yylhsminor.yy590=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); - sqlite3DequoteNumber(pParse, yylhsminor.yy590); + yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); + sqlite3DequoteNumber(pParse, yylhsminor.yy454); } - yymsp[0].minor.yy590 = yylhsminor.yy590; + yymsp[0].minor.yy454 = yylhsminor.yy454; break; default: - /* (344) input ::= cmdlist */ yytestcase(yyruleno==344); - /* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345); - /* (346) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=346); - /* (347) ecmd ::= SEMI */ yytestcase(yyruleno==347); - /* (348) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==348); - /* (349) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=349); - /* (350) trans_opt ::= */ yytestcase(yyruleno==350); - /* (351) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==351); - /* (352) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==352); - /* (353) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==353); - /* (354) savepoint_opt ::= */ yytestcase(yyruleno==354); - /* (355) cmd ::= create_table create_table_args */ yytestcase(yyruleno==355); - /* (356) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=356); - /* (357) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==357); - /* (358) columnlist ::= columnname carglist */ yytestcase(yyruleno==358); - /* (359) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==359); - /* (360) nm ::= STRING */ yytestcase(yyruleno==360); - /* (361) typetoken ::= typename */ yytestcase(yyruleno==361); - /* (362) typename ::= ID|STRING */ yytestcase(yyruleno==362); - /* (363) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=363); - /* (364) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=364); - /* (365) carglist ::= carglist ccons */ yytestcase(yyruleno==365); - /* (366) carglist ::= */ yytestcase(yyruleno==366); - /* (367) ccons ::= NULL onconf */ yytestcase(yyruleno==367); - /* (368) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==368); - /* (369) ccons ::= AS generated */ yytestcase(yyruleno==369); - /* (370) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==370); - /* (371) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==371); - /* (372) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=372); - /* (373) tconscomma ::= */ yytestcase(yyruleno==373); - /* (374) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=374); - /* (375) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=375); - /* (376) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=376); - /* (377) oneselect ::= values */ yytestcase(yyruleno==377); - /* (378) sclp ::= selcollist COMMA */ yytestcase(yyruleno==378); - /* (379) as ::= ID|STRING */ yytestcase(yyruleno==379); - /* (380) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=380); - /* (381) returning ::= */ yytestcase(yyruleno==381); - /* (382) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=382); - /* (383) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==383); - /* (384) case_operand ::= expr */ yytestcase(yyruleno==384); - /* (385) exprlist ::= nexprlist */ yytestcase(yyruleno==385); - /* (386) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=386); - /* (387) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=387); - /* (388) nmnum ::= ON */ yytestcase(yyruleno==388); - /* (389) nmnum ::= DELETE */ yytestcase(yyruleno==389); - /* (390) nmnum ::= DEFAULT */ yytestcase(yyruleno==390); - /* (391) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==391); - /* (392) foreach_clause ::= */ yytestcase(yyruleno==392); - /* (393) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==393); - /* (394) trnm ::= nm */ yytestcase(yyruleno==394); - /* (395) tridxby ::= */ yytestcase(yyruleno==395); - /* (396) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==396); - /* (397) database_kw_opt ::= */ yytestcase(yyruleno==397); - /* (398) kwcolumn_opt ::= */ yytestcase(yyruleno==398); - /* (399) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==399); - /* (400) vtabarglist ::= vtabarg */ yytestcase(yyruleno==400); - /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==401); - /* (402) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==402); - /* (403) anylist ::= */ yytestcase(yyruleno==403); - /* (404) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==404); - /* (405) anylist ::= anylist ANY */ yytestcase(yyruleno==405); - /* (406) with ::= */ yytestcase(yyruleno==406); - /* (407) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=407); - /* (408) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=408); + /* (348) input ::= cmdlist */ yytestcase(yyruleno==348); + /* (349) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==349); + /* (350) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=350); + /* (351) ecmd ::= SEMI */ yytestcase(yyruleno==351); + /* (352) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==352); + /* (353) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=353); + /* (354) trans_opt ::= */ yytestcase(yyruleno==354); + /* (355) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==355); + /* (356) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==356); + /* (357) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==357); + /* (358) savepoint_opt ::= */ yytestcase(yyruleno==358); + /* (359) cmd ::= create_table create_table_args */ yytestcase(yyruleno==359); + /* (360) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=360); + /* (361) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==361); + /* (362) columnlist ::= columnname carglist */ yytestcase(yyruleno==362); + /* (363) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==363); + /* (364) nm ::= STRING */ yytestcase(yyruleno==364); + /* (365) typetoken ::= typename */ yytestcase(yyruleno==365); + /* (366) typename ::= ID|STRING */ yytestcase(yyruleno==366); + /* (367) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=367); + /* (368) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=368); + /* (369) carglist ::= carglist ccons */ yytestcase(yyruleno==369); + /* (370) carglist ::= */ yytestcase(yyruleno==370); + /* (371) ccons ::= NULL onconf */ yytestcase(yyruleno==371); + /* (372) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==372); + /* (373) ccons ::= AS generated */ yytestcase(yyruleno==373); + /* (374) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==374); + /* (375) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==375); + /* (376) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=376); + /* (377) tconscomma ::= */ yytestcase(yyruleno==377); + /* (378) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=379); + /* (380) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=380); + /* (381) oneselect ::= values */ yytestcase(yyruleno==381); + /* (382) sclp ::= selcollist COMMA */ yytestcase(yyruleno==382); + /* (383) as ::= ID|STRING */ yytestcase(yyruleno==383); + /* (384) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=384); + /* (385) returning ::= */ yytestcase(yyruleno==385); + /* (386) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=386); + /* (387) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==387); + /* (388) case_operand ::= expr */ yytestcase(yyruleno==388); + /* (389) exprlist ::= nexprlist */ yytestcase(yyruleno==389); + /* (390) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=390); + /* (391) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=391); + /* (392) nmnum ::= ON */ yytestcase(yyruleno==392); + /* (393) nmnum ::= DELETE */ yytestcase(yyruleno==393); + /* (394) nmnum ::= DEFAULT */ yytestcase(yyruleno==394); + /* (395) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==395); + /* (396) foreach_clause ::= */ yytestcase(yyruleno==396); + /* (397) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==397); + /* (398) tridxby ::= */ yytestcase(yyruleno==398); + /* (399) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==399); + /* (400) database_kw_opt ::= */ yytestcase(yyruleno==400); + /* (401) kwcolumn_opt ::= */ yytestcase(yyruleno==401); + /* (402) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==402); + /* (403) vtabarglist ::= vtabarg */ yytestcase(yyruleno==403); + /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==404); + /* (405) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==405); + /* (406) anylist ::= */ yytestcase(yyruleno==406); + /* (407) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==407); + /* (408) anylist ::= anylist ANY */ yytestcase(yyruleno==408); + /* (409) with ::= */ yytestcase(yyruleno==409); + /* (410) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=410); + /* (411) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=411); break; /********** End reduce actions ************************************************/ }; @@ -183570,8 +186952,8 @@ static const unsigned char aKWCode[148] = {0, /* Check to see if z[0..n-1] is a keyword. If it is, write the ** parser symbol code for that keyword into *pType. Always ** return the integer n (the length of the token). */ -static int keywordCode(const char *z, int n, int *pType){ - int i, j; +static i64 keywordCode(const char *z, i64 n, int *pType){ + i64 i, j; const char *zKW; assert( n>=2 ); i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; @@ -184125,7 +187507,7 @@ SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *z, int *tokenType){ } case CC_DOLLAR: case CC_VARALPHA: { - int n = 0; + i64 n = 0; testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' ); testcase( z[0]=='#' ); *tokenType = TK_VARIABLE; @@ -184221,7 +187603,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ int tokenType; /* type of the next token */ int lastTokenParsed = -1; /* type of the previous token */ sqlite3 *db = pParse->db; /* The database connection */ - int mxSqlLen; /* Max length of an SQL string */ + i64 mxSqlLen; /* Max length of an SQL string */ Parse *pParentParse = 0; /* Outer parse context, if any */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK yyParser sEngine; /* Space to hold the Lemon-generated Parser object */ @@ -184351,7 +187733,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ } if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){ if( pParse->zErrMsg==0 ){ - pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); + pParse->zErrMsg = sqlite3DbStrDup(db, sqlite3ErrStr(pParse->rc)); } if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){ sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); @@ -184432,7 +187814,7 @@ SQLITE_PRIVATE char *sqlite3Normalize( sqlite3_str_append(pStr, " NULL", 5); break; } - /* Fall through */ + /* no break */ deliberate_fall_through } case TK_STRING: case TK_INTEGER: @@ -184496,7 +187878,7 @@ SQLITE_PRIVATE char *sqlite3Normalize( } case TK_SELECT: { iStartIN = 0; - /* fall through */ + /* no break */ deliberate_fall_through } default: { if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr); @@ -184568,15 +187950,55 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; #endif /* -** Return TRUE if the given SQL string ends in a semicolon. +** Return zero if the given SQL string is complete - if all comments, +** string and blob literals, and quoted identifiers have been closed and +** if the entire string ends with ";" and possibly with ";END;" if the +** string is a CREATE TRIGGER statement. A non-zero return indicates +** that the string is empty or incomplete. Bits of the return value +** indicate what is missing and is needed to close out the statement. ** ** Special handling is require for CREATE TRIGGER statements. ** Whenever the CREATE TRIGGER keywords are seen, the statement ** must end with ";END;". ** +** Let the return code be a value R. R is split up into various +** subfields, at byte boundaries: +** +** R = 0xwwwwwwww00xxyyzz +** +** In other words, zz is the least significant byte, yy is the next +** most significant byte, xx is the third byte, wwwwwwww is the upper +** four bytes of the return value. +** +** zz == SQLITE_OK Input is complete +** zz == SQLITE_ERROR Input is incomplete +** zz == SQLITE_EMPTY Input contains only whitespace +** zz == SQLITE_MISUSE Input is a NULL pointer +** zz != 0 New values for zz may be added in the future +** +** yy == 0x01 Need a semicolon at the end +** yy == 0x02 Need "END" and a semicolon +** yy == 0x03 Need semicolon, "END", and semicolon +** yy != 0 New values for yy may be added in the future +** +** xx == '\'' Incomplete string or blob literal +** xx == '"' Incomplete quoted identifier +** xx == '`' Incompelte MySQL-style quoted identifier +** xx == ']' Incomplete SQLServer-style quoted identifer +** xx == '-' Incomplete SQL-style comment +** xx == '/' Incomplete C-style comment +** xx != 0 New values of xx may be added in the future +** +** wwwwwwww Interpret as a signed integer, the number +** of unmatched "(". Negative means there are +** more ")" and "(". +** +** ((R>>24)&0xff)!=0 New uses for the 4th byte may be added +** in the future +** ** This implementation uses a state machine with 8 states: ** -** (0) INVALID We have not yet seen a non-whitespace character. +** (0) NOTHING We have not yet seen a non-whitespace character. ** ** (1) START At the beginning or end of an SQL statement. This routine ** returns 1 if it ends in the START state and 0 if it ends @@ -184620,9 +188042,11 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; ** to recognize the end of a trigger can be omitted. All we have to do ** is look for a semicolon that is not part of an string or comment. */ -SQLITE_API int sqlite3_complete(const char *zSql){ +SQLITE_API sqlite3_int64 sqlite3_incomplete(const char *zSql){ u8 state = 0; /* Current state, using numbers defined in header comment */ u8 token; /* Value of the next token */ + u8 pending = 0; /* unmatched structure character */ + int nParen = 0; /* Nested parentheses */ #ifndef SQLITE_OMIT_TRIGGER /* A complex statement machine used to detect the end of a CREATE TRIGGER @@ -184631,7 +188055,7 @@ SQLITE_API int sqlite3_complete(const char *zSql){ static const u8 trans[8][8] = { /* Token: */ /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ - /* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, }, + /* 0 NOTHING: */ { 1, 0, 2, 3, 4, 2, 2, 2, }, /* 1 START: */ { 1, 1, 2, 3, 4, 2, 2, 2, }, /* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, }, /* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, }, @@ -184647,16 +188071,26 @@ SQLITE_API int sqlite3_complete(const char *zSql){ static const u8 trans[3][3] = { /* Token: */ /* State: ** SEMI WS OTHER */ - /* 0 INVALID: */ { 1, 0, 2, }, + /* 0 NOTHING: */ { 1, 0, 2, }, /* 1 START: */ { 1, 1, 2, }, /* 2 NORMAL: */ { 1, 2, 2, }, }; #endif /* SQLITE_OMIT_TRIGGER */ + /* Mapping state number to yy value for the return */ + static const u8 statemap[8] = { + /* 0 NOTHING */ 0, + /* 1 START */ 0, + /* 2 NORMAL */ 1, + /* 3 EXPLAIN */ 1, + /* 4 CREATE */ 1, + /* 5 TRIGGER */ 3, + /* 6 SEMI */ 2, + /* 7 END */ 1, + }; #ifdef SQLITE_ENABLE_API_ARMOR if( zSql==0 ){ - (void)SQLITE_MISUSE_BKPT; - return 0; + return SQLITE_MISUSE_BKPT; } #endif @@ -184681,7 +188115,10 @@ SQLITE_API int sqlite3_complete(const char *zSql){ } zSql += 2; while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } - if( zSql[0]==0 ) return 0; + if( zSql[0]==0 ){ + pending = '/'; + goto incomplete_finish; + } zSql++; token = tkWS; break; @@ -184692,14 +188129,20 @@ SQLITE_API int sqlite3_complete(const char *zSql){ break; } while( *zSql && *zSql!='\n' ){ zSql++; } - if( *zSql==0 ) return state==1; + if( *zSql==0 ){ + pending = '-'; + goto incomplete_finish; + } token = tkWS; break; } case '[': { /* Microsoft-style identifiers in [...] */ zSql++; while( *zSql && *zSql!=']' ){ zSql++; } - if( *zSql==0 ) return 0; + if( *zSql==0 ){ + pending = ']'; + goto incomplete_finish; + } token = tkOTHER; break; } @@ -184709,7 +188152,20 @@ SQLITE_API int sqlite3_complete(const char *zSql){ int c = *zSql; zSql++; while( *zSql && *zSql!=c ){ zSql++; } - if( *zSql==0 ) return 0; + if( *zSql==0 ){ + pending = c; + goto incomplete_finish; + } + token = tkOTHER; + break; + } + case '(': { + nParen++; + token = tkOTHER; + break; + } + case ')': { + nParen--; token = tkOTHER; break; } @@ -184776,7 +188232,16 @@ SQLITE_API int sqlite3_complete(const char *zSql){ state = trans[state][token]; zSql++; } - return state==1; +incomplete_finish: + if( state==0 && pending==0 ) return SQLITE_EMPTY; + if( state==1 ) nParen = 0; + return (i64)((((u64)nParen)<<32) | + ((u64)pending<<16) | + ((u64)statemap[state]<<8) | + (state>1 || pending!=0)); +} +SQLITE_API int sqlite3_complete(const char *zSql){ + return sqlite3_incomplete(zSql)==0; } #ifndef SQLITE_OMIT_UTF16 @@ -184798,7 +188263,7 @@ SQLITE_API int sqlite3_complete16(const void *zSql){ sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); if( zSql8 ){ - rc = sqlite3_complete(zSql8); + rc = sqlite3_incomplete(zSql8)==0; }else{ rc = SQLITE_NOMEM_BKPT; } @@ -185065,17 +188530,29 @@ SQLITE_API char *sqlite3_data_directory = 0; /* ** Initialize SQLite. ** -** This routine must be called to initialize the memory allocation, -** VFS, and mutex subsystems prior to doing any serious work with -** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT +** The sqlite3_initialize() routine must be called to initialize the +** memory allocation, VFS, and mutex subsystems prior to doing any +** serious work. As long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as ** sqlite3_open(). ** ** This routine is a no-op except on its very first call for the process, -** or for the first call after a call to sqlite3_shutdown. +** or for the first call after a call to sqlite3_shutdown. Most calls +** to sqlite3_initialize() are, in fact, no-ops. For that reason, the +** routine is broken into two pieces: +** +** sqlite3Initialize() Does the actual work of initialization ** -** The first thread to call this routine runs the initialization to -** completion. If subsequent threads call this routine before the first +** sqlite3_initialize() Checks to see if initialization is needed +** and invokes sqlite3Initialize() if it is. +** +** The sqlite3_initialize() interface is called frequently, but +** sqlite3Initialize() runs rarely. The function is broken up this way +** to avoid wasting CPU cycles with unnecessary stack setup for local +** variables in cases where it is not needed. +** +** The first thread to call sqlite3_initialize() runs the initialization to +** completion. If subsequent threads call sqlite3_initialize() before the first ** thread has finished the initialization process, then the subsequent ** threads must block until the first thread finishes with the initialization. ** @@ -185083,44 +188560,29 @@ SQLITE_API char *sqlite3_data_directory = 0; ** calls to this routine should not block, of course. Otherwise the ** initialization process would never complete. ** -** Let X be the first thread to enter this routine. Let Y be some other -** thread. Then while the initial invocation of this routine by X is -** incomplete, it is required that: +** Let X be the first thread to enter sqlite3_initialize(). Let Y be some +** other thread. While the initial invocation of sqlite3_initialize() by X +** is incomplete, it is required that: ** -** * Calls to this routine from Y must block until the outer-most +** * Calls to sqlite3_initialize() from Y must block until the outer-most ** call by X completes. ** -** * Recursive calls to this routine from thread X return immediately -** without blocking. +** * Recursive calls to sqlite3_initialize() from thread X return +** immediately without blocking. */ -SQLITE_API int sqlite3_initialize(void){ - MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */ - int rc; /* Result code */ +static SQLITE_NOINLINE int sqlite3Initialize(void){ + MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */ + int rc; /* Result code */ #ifdef SQLITE_EXTRA_INIT - int bRunExtraInit = 0; /* Extra initialization needed */ -#endif - -#ifdef SQLITE_OMIT_WSD - rc = sqlite3_wsd_init(4096, 24); - if( rc!=SQLITE_OK ){ - return rc; - } + int bRunExtraInit = 0; /* Extra initialization needed */ #endif /* If the following assert() fails on some obscure processor/compiler - ** combination, the work-around is to set the correct pointer - ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */ - assert( SQLITE_PTRSIZE==sizeof(char*) ); - - /* If SQLite is already completely initialized, then this call - ** to sqlite3_initialize() should be a no-op. But the initialization - ** must be complete. So isInit must not be set until the very end - ** of this routine. + ** combination to warn that SQLite has been mis-compiled. If you hit + ** this assert(), that means you need to recompile with the + ** -DSQLITE_PTRSIZE=n compile-time option to set the correct pointer size. */ - if( sqlite3GlobalConfig.isInit ){ - sqlite3MemoryBarrier(); - return SQLITE_OK; - } + assert( SQLITE_PTRSIZE==sizeof(char*) ); /* Make sure the mutex subsystem is initialized. If unable to ** initialize the mutex subsystem, return early with the error. @@ -185266,6 +188728,26 @@ SQLITE_API int sqlite3_initialize(void){ #endif return rc; } +SQLITE_API int sqlite3_initialize(void){ + /* If this build does not support writable static data (WSD) natively + ** then we have to invoke the (application-supplied) WSD initialization + ** routine before doing anything else. */ +#ifdef SQLITE_OMIT_WSD + int rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + if( sqlite3GlobalConfig.isInit ){ + /* SQLite has already been initialized. Fast early-out. */ + sqlite3MemoryBarrier(); + return SQLITE_OK; + }else{ + /* Invoke sqlite3Initialize() to do the actual work. */ + return sqlite3Initialize(); + } +} /* ** Undo the effects of sqlite3_initialize(). Must not be called while @@ -185424,7 +188906,7 @@ SQLITE_API int sqlite3_config(int op, ...){ break; } case SQLITE_CONFIG_SMALL_MALLOC: { - sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int); + sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int)!=0; break; } case SQLITE_CONFIG_PAGECACHE: { @@ -185877,6 +189359,14 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ rc = setupLookaside(db, pBuf, sz, cnt); break; } + case SQLITE_DBCONFIG_FP_DIGITS: { + int nIn = va_arg(ap, int); + int *pOut = va_arg(ap, int*); + if( nIn>3 && nIn<24 ) db->nFpDigit = (u8)nIn; + if( pOut ) *pOut = db->nFpDigit; + rc = SQLITE_OK; + break; + } default: { static const struct { int op; /* The opcode */ @@ -185939,7 +189429,7 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ ** This is the default collating function named "BINARY" which is always ** available. */ -static int binCollFunc( +SQLITE_PRIVATE int sqlite3BinaryCompare( void *NotUsed, int nKey1, const void *pKey1, int nKey2, const void *pKey2 @@ -185971,16 +189461,19 @@ static int rtrimCollFunc( const u8 *pK2 = (const u8*)pKey2; while( nKey1 && pK1[nKey1-1]==' ' ) nKey1--; while( nKey2 && pK2[nKey2-1]==' ' ) nKey2--; - return binCollFunc(pUser, nKey1, pKey1, nKey2, pKey2); + return sqlite3BinaryCompare(pUser, nKey1, pKey1, nKey2, pKey2); } /* ** Return true if CollSeq is the default built-in BINARY. */ +#if !SQLITE_USES_INLINE SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){ - assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 ); - return p==0 || p->xCmp==binCollFunc; + assert( p==0 || p->xCmp!=sqlite3BinaryCompare + || strcmp(p->zName,"BINARY")==0 ); + return p==0 || p->xCmp==sqlite3BinaryCompare; } +#endif /* ** Another built-in collating sequence: NOCASE. @@ -186009,13 +189502,17 @@ static int nocaseCollatingFunc( ** Return the ROWID of the most recent insert */ SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){ + i64 iRet; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - return db->lastRowid; + sqlite3_mutex_enter(db->mutex); + iRet = db->lastRowid; + sqlite3_mutex_leave(db->mutex); + return iRet; } /* @@ -186034,16 +189531,21 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid) } /* -** Return the number of changes in the most recent call to sqlite3_exec(). +** Return the number of changes in the most recently executed DML +** statement. */ SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3 *db){ + i64 iRet; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - return db->nChange; + sqlite3_mutex_enter(db->mutex); + iRet = db->nChange; + sqlite3_mutex_leave(db->mutex); + return iRet; } SQLITE_API int sqlite3_changes(sqlite3 *db){ return (int)sqlite3_changes64(db); @@ -186053,13 +189555,17 @@ SQLITE_API int sqlite3_changes(sqlite3 *db){ ** Return the number of changes since the database handle was opened. */ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3 *db){ + i64 iRet; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - return db->nTotalChange; + sqlite3_mutex_enter(db->mutex); + iRet = db->nTotalChange; + sqlite3_mutex_leave(db->mutex); + return iRet; } SQLITE_API int sqlite3_total_changes(sqlite3 *db){ return (int)sqlite3_total_changes64(db); @@ -186742,6 +190248,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif + sqlite3_mutex_enter(db->mutex); if( ms>0 ){ sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, (void*)db); @@ -186752,6 +190259,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ }else{ sqlite3_busy_handler(db, 0, 0); } + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -186917,7 +190425,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( if( db->nVdbeActive ){ sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify user-function due to active statements"); - assert( !db->mallocFailed ); + assert( !db->mallocFailed || db->nVdbeExec>0 ); return SQLITE_BUSY; }else{ sqlite3ExpirePreparedStatements(db, 0); @@ -187432,6 +190940,9 @@ SQLITE_API void *sqlite3_wal_hook( sqlite3_mutex_leave(db->mutex); return pRet; #else + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(xCallback); + UNUSED_PARAMETER(pArg); return 0; #endif } @@ -187447,6 +190958,11 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( int *pnCkpt /* OUT: Total number of frames checkpointed */ ){ #ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(zDb); + UNUSED_PARAMETER(eMode); + UNUSED_PARAMETER(pnLog); + UNUSED_PARAMETER(pnCkpt); return SQLITE_OK; #else int rc; /* Return code */ @@ -187460,11 +190976,12 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( if( pnLog ) *pnLog = -1; if( pnCkpt ) *pnCkpt = -1; + assert( SQLITE_CHECKPOINT_NOOP==-1 ); assert( SQLITE_CHECKPOINT_PASSIVE==0 ); assert( SQLITE_CHECKPOINT_FULL==1 ); assert( SQLITE_CHECKPOINT_RESTART==2 ); assert( SQLITE_CHECKPOINT_TRUNCATE==3 ); - if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ + if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint ** mode: */ return SQLITE_MISUSE_BKPT; @@ -187648,9 +191165,11 @@ SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){ */ SQLITE_API int sqlite3_error_offset(sqlite3 *db){ int iOffset = -1; - if( db && sqlite3SafetyCheckSickOrOk(db) && db->errCode ){ + if( db && sqlite3SafetyCheckSickOrOk(db) ){ sqlite3_mutex_enter(db->mutex); - iOffset = db->errByteOffset; + if( db->errCode ){ + iOffset = db->errByteOffset; + } sqlite3_mutex_leave(db->mutex); } return iOffset; @@ -187704,25 +191223,43 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ ** passed to this function, we assume a malloc() failed during sqlite3_open(). */ SQLITE_API int sqlite3_errcode(sqlite3 *db){ - if( db && !sqlite3SafetyCheckSickOrOk(db) ){ + int iRet; + if( !db ) return SQLITE_NOMEM_BKPT; + if( !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE_BKPT; } - if( !db || db->mallocFailed ){ - return SQLITE_NOMEM_BKPT; + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + iRet = SQLITE_NOMEM_BKPT; + }else{ + iRet = db->errCode & db->errMask; } - return db->errCode & db->errMask; + sqlite3_mutex_leave(db->mutex); + return iRet; } SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ - if( db && !sqlite3SafetyCheckSickOrOk(db) ){ + int iRet; + if( !db ) return SQLITE_NOMEM_BKPT; + if( !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE_BKPT; } - if( !db || db->mallocFailed ){ - return SQLITE_NOMEM_BKPT; + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + iRet = SQLITE_NOMEM_BKPT; + }else{ + iRet = db->errCode; } - return db->errCode; + sqlite3_mutex_leave(db->mutex); + return iRet; } SQLITE_API int sqlite3_system_errno(sqlite3 *db){ - return db ? db->iSysErrno : 0; + int iRet = 0; + if( db ){ + sqlite3_mutex_enter(db->mutex); + iRet = db->iSysErrno; + sqlite3_mutex_leave(db->mutex); + } + return iRet; } /* @@ -187828,6 +191365,9 @@ static const int aHardLimit[] = { SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ SQLITE_MAX_TRIGGER_DEPTH, SQLITE_MAX_WORKER_THREADS, + SQLITE_MAX_PARSER_DEPTH, + SQLITE_MAX_SCHEMA, + SQLITE_MAX_TRIGGER_STEPS, }; /* @@ -187842,6 +191382,9 @@ static const int aHardLimit[] = { #if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH # error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH #endif +#if SQLITE_MAX_SQL_LENGTH>2147482624 /* 1024 less than 2^31 */ +# error SQLITE_MAX_SQL_LENGTH must not be greater than 2147482624 +#endif #if SQLITE_MAX_COMPOUND_SELECT<2 # error SQLITE_MAX_COMPOUND_SELECT must be at least 2 #endif @@ -187866,6 +191409,9 @@ static const int aHardLimit[] = { #if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 # error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 #endif +#if SQLITE_MAX_TRIGGER_STEPS<0 || SQLITE_MAX_TRIGGER_STEPS>65535 +# error SQLITE_MAX_TRIGGER_STEPS must be between 0 and 65535 +#endif /* @@ -187897,6 +191443,7 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH ); assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN ); assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_PARSER_DEPTH]==SQLITE_MAX_PARSER_DEPTH ); assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT); assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP ); assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG ); @@ -187906,12 +191453,15 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS ); - assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) ); + assert( aHardLimit[SQLITE_LIMIT_SCHEMA]==SQLITE_MAX_SCHEMA ); + assert( aHardLimit[SQLITE_LIMIT_TRIGGER_STEPS]==SQLITE_MAX_TRIGGER_STEPS ); + assert( SQLITE_LIMIT_TRIGGER_STEPS==(SQLITE_N_LIMIT-1) ); if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ return -1; } + sqlite3_mutex_enter(db->mutex); oldLimit = db->aLimit[limitId]; if( newLimit>=0 ){ /* IMP: R-52476-28732 */ if( newLimit>aHardLimit[limitId] ){ @@ -187921,6 +191471,7 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ } db->aLimit[limitId] = newLimit; } + sqlite3_mutex_leave(db->mutex); return oldLimit; /* IMP: R-53341-35419 */ } @@ -187963,7 +191514,7 @@ SQLITE_PRIVATE int sqlite3ParseUri( const char *zVfs = zDefaultVfs; char *zFile; char c; - int nUri = sqlite3Strlen30(zUri); + i64 nUri = strlen(zUri); assert( *pzErrMsg==0 ); @@ -187973,8 +191524,8 @@ SQLITE_PRIVATE int sqlite3ParseUri( ){ char *zOpt; int eState; /* Parser state when parsing URI */ - int iIn; /* Input character index */ - int iOut = 0; /* Output character index */ + i64 iIn; /* Input character index */ + i64 iOut = 0; /* Output character index */ u64 nByte = nUri+8; /* Bytes of space to allocate */ /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen @@ -188008,7 +191559,7 @@ SQLITE_PRIVATE int sqlite3ParseUri( while( zUri[iIn] && zUri[iIn]!='/' ) iIn++; if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){ *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", - iIn-7, &zUri[7]); + (int)(iIn-7), &zUri[7]); rc = SQLITE_ERROR; goto parse_uri_out; } @@ -188083,11 +191634,11 @@ SQLITE_PRIVATE int sqlite3ParseUri( ** here. Options that are interpreted here include "vfs" and those that ** correspond to flags that may be passed to the sqlite3_open_v2() ** method. */ - zOpt = &zFile[sqlite3Strlen30(zFile)+1]; + zOpt = &zFile[strlen(zFile)+1]; while( zOpt[0] ){ - int nOpt = sqlite3Strlen30(zOpt); + i64 nOpt = strlen(zOpt); char *zVal = &zOpt[nOpt+1]; - int nVal = sqlite3Strlen30(zVal); + i64 nVal = strlen(zVal); if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ zVfs = zVal; @@ -188133,7 +191684,7 @@ SQLITE_PRIVATE int sqlite3ParseUri( int mode = 0; for(i=0; aMode[i].z; i++){ const char *z = aMode[i].z; - if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ + if( nVal==(i64)strlen(z) && 0==memcmp(zVal, z, nVal) ){ mode = aMode[i].mode; break; } @@ -188270,7 +191821,7 @@ static int openDatabase( db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; if( isThreadsafe -#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS +#if defined(SQLITE_THREAD_MISUSE_WARNINGS) || sqlite3GlobalConfig.bCoreMutex #endif ){ @@ -188291,6 +191842,7 @@ static int openDatabase( db->aDb = db->aDbStatic; db->lookaside.bDisable = 1; db->lookaside.sz = 0; + db->nFpDigit = 17; assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); @@ -188395,9 +191947,12 @@ static int openDatabase( ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating ** functions: */ - createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0); - createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0); - createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, + sqlite3BinaryCompare, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, + sqlite3BinaryCompare, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, + sqlite3BinaryCompare, 0); createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0); if( db->mallocFailed ){ @@ -188736,6 +192291,12 @@ SQLITE_API int sqlite3_collation_needed16( */ SQLITE_API void *sqlite3_get_clientdata(sqlite3 *db, const char *zName){ DbClientData *p; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zName || !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif sqlite3_mutex_enter(db->mutex); for(p=db->pDbData; p; p=p->pNext){ if( strcmp(p->zName, zName)==0 ){ @@ -188811,13 +192372,17 @@ SQLITE_API int sqlite3_global_recover(void){ ** by the next COMMIT or ROLLBACK. */ SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ + int iRet; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - return db->autoCommit; + sqlite3_mutex_enter(db->mutex); + iRet = db->autoCommit; + sqlite3_mutex_leave(db->mutex); + return iRet; } /* @@ -189593,6 +193158,17 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_ATOF, const char *z, double *p); + ** + ** Test access to the sqlite3AtoF() routine. + */ + case SQLITE_TESTCTRL_ATOF: { + const char *z = va_arg(ap,const char*); + double *pR = va_arg(ap,double*); + rc = sqlite3AtoF(z,pR); + break; + } + #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) ** @@ -189809,6 +193385,7 @@ SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){ } SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){ #ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(zFilename); return 0; #else zFilename = sqlite3_filename_journal(zFilename); @@ -189830,17 +193407,19 @@ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ ** of range. */ SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){ + const char *zRet = 0; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - if( N<0 || N>=db->nDb ){ - return 0; - }else{ - return db->aDb[N].zDbSName; + sqlite3_mutex_enter(db->mutex); + if( N>=0 && NnDb ){ + zRet = db->aDb[N].zDbSName; } + sqlite3_mutex_leave(db->mutex); + return zRet; } /* @@ -191182,7 +194761,16 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */ #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) -#define deliberate_fall_through +#if !defined(deliberate_fall_through) +# if defined(__has_attribute) +# if __has_attribute(fallthrough) +# define deliberate_fall_through __attribute__((fallthrough)); +# endif +# endif +#endif +#if !defined(deliberate_fall_through) +# define deliberate_fall_through +#endif /* ** Macros needed to provide flexible arrays in a portable way @@ -191580,6 +195168,15 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ ) +SQLITE_PRIVATE int sqlite3Fts3PrepareStmt( + Fts3Table *p, /* Prepare for this connection */ + const char *zSql, /* SQL to prepare */ + int bPersist, /* True to set SQLITE_PREPARE_PERSISTENT */ + int bAllowVtab, /* True to omit SQLITE_PREPARE_NO_VTAB */ + sqlite3_stmt **pp /* OUT: Prepared statement */ +); + + /* fts3.c */ SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); @@ -191673,6 +195270,12 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); SQLITE_EXTENSION_INIT1 #endif + +/* +** Assume any b-tree layer with more levels than this is corrupt. +*/ +#define FTS3_MAX_BTREE_HEIGHT 48 + typedef struct Fts3HashWrapper Fts3HashWrapper; struct Fts3HashWrapper { Fts3Hash hash; /* Hash table */ @@ -192495,7 +196098,10 @@ static int fts3ContentColumns( ** nul-terminator byte. */ nCol = sqlite3_column_count(pStmt); for(i=0; izReadExprlist); if( !zSql ) return SQLITE_NOMEM; p->bLock++; - rc = sqlite3_prepare_v3( - p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 - ); + rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt); p->bLock--; sqlite3_free(zSql); } @@ -193391,7 +196996,11 @@ static int fts3SelectLeaf( assert( piLeaf || piLeaf2 ); fts3GetVarint32(zNode, &iHeight); - rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); + if( iHeight>FTS3_MAX_BTREE_HEIGHT ){ + rc = FTS_CORRUPT_VTAB; + }else{ + rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); + } assert_fts3_nc( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); if( rc==SQLITE_OK && iHeight>1 ){ @@ -193436,8 +197045,13 @@ static void fts3PutDeltaVarint( sqlite3_int64 iVal /* Write this value to the list */ ){ assert_fts3_nc( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) ); - *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); - *piPrev = iVal; + if( iVal-(*piPrev)>=0 ){ + /* Refuse to write a negative delta integer. This only happens with a + ** corrupt db (see the assert above) and can cause buffer overwrites + ** in some cases. */ + *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); + *piPrev = iVal; + } } /* @@ -194764,9 +198378,7 @@ static int fts3FilterMethod( } if( zSql ){ p->bLock++; - rc = sqlite3_prepare_v3( - p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 - ); + rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt); p->bLock--; sqlite3_free(zSql); }else{ @@ -195079,12 +198691,13 @@ static void fts3SnippetFunc( int nVal, /* Size of apVal[] array */ sqlite3_value **apVal /* Array of arguments */ ){ + Fts3Table *pTab = 0; Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ const char *zStart = ""; const char *zEnd = ""; const char *zEllipsis = "..."; - int iCol = -1; - int nToken = 15; /* Default number of tokens in snippet */ + i64 iCol = -1; + i64 nToken = 15; /* Default number of tokens in snippet */ /* There must be at least one argument passed to this function (otherwise ** the non-overloaded version would have been called instead of this one). @@ -195097,11 +198710,12 @@ static void fts3SnippetFunc( return; } if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return; + pTab = (Fts3Table *)pCsr->base.pVtab; switch( nVal ){ - case 6: nToken = sqlite3_value_int(apVal[5]); + case 6: nToken = sqlite3_value_int64(apVal[5]); /* no break */ deliberate_fall_through - case 5: iCol = sqlite3_value_int(apVal[4]); + case 5: iCol = sqlite3_value_int64(apVal[4]); /* no break */ deliberate_fall_through case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]); /* no break */ deliberate_fall_through @@ -195111,9 +198725,12 @@ static void fts3SnippetFunc( } if( !zEllipsis || !zEnd || !zStart ){ sqlite3_result_error_nomem(pContext); - }else if( nToken==0 ){ + }else if( nToken==0 || iCol>=pTab->nColumn ){ sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ + if( iCol<0 ) iCol = -1; + if( nToken<-64 ) nToken = -64; + if( nToken>64 ) nToken = 64; sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); } } @@ -195389,6 +199006,7 @@ static int fts3IntegrityMethod( UNUSED_PARAMETER(isQuick); rc = sqlite3Fts3IntegrityCheck(p, &bOk); + assert( pVtab->zErrMsg==0 || rc!=SQLITE_OK ); assert( rc!=SQLITE_CORRUPT_VTAB ); if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" @@ -195792,6 +199410,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ char *p1; char *p2; char *aOut; + i64 nAlloc = (i64)nPoslist*2 + FTS3_BUFFER_PADDING; if( nMaxUndeferred>iPrev ){ p1 = aPoslist; @@ -195803,7 +199422,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ nDistance = iPrev - nMaxUndeferred; } - aOut = (char *)sqlite3Fts3MallocZero(((i64)nPoslist)+FTS3_BUFFER_PADDING); + aOut = (char *)sqlite3Fts3MallocZero(nAlloc); if( !aOut ){ sqlite3_free(aPoslist); return SQLITE_NOMEM; @@ -197723,6 +201342,14 @@ static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){ #define FTS4AUX_GE_CONSTRAINT 2 #define FTS4AUX_LE_CONSTRAINT 4 +/* +** Return true if constraint iCons of pInfo uses the "binary" collation +** sequence. Or false it it uses anything else. +*/ +static int fts3auxIsBinary(sqlite3_index_info *pInfo, int iCons){ + return 0==sqlite3_stricmp("binary", sqlite3_vtab_collation(pInfo, iCons)); +} + /* ** xBestIndex - Analyze a WHERE and ORDER BY clause. */ @@ -197750,7 +201377,7 @@ static int fts3auxBestIndexMethod( /* Search for equality and range constraints on the "term" column. ** And equality constraints on the hidden "languageid" column. */ for(i=0; inConstraint; i++){ - if( pInfo->aConstraint[i].usable ){ + if( pInfo->aConstraint[i].usable && fts3auxIsBinary(pInfo, i) ){ int op = pInfo->aConstraint[i].op; int iCol = pInfo->aConstraint[i].iColumn; @@ -197905,7 +201532,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ pCsr->aStat[1].nDoc++; } eState = 2; - /* fall through */ + /* no break */ deliberate_fall_through case 2: if( v==0 ){ /* 0x00. Next integer will be a docid. */ @@ -197921,7 +201548,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ /* State 3. The integer just read is a column number. */ default: assert( eState==3 ); iCol = (int)v; - if( iCol<1 ){ + if( iCol<1 || iCol>32767 ){ rc = SQLITE_CORRUPT_VTAB; break; } @@ -197996,7 +201623,7 @@ static int fts3auxFilterMethod( pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; - if( iEq>=0 || iGe>=0 ){ + if( (iEq>=0 || iGe>=0) && sqlite3_value_type(apVal[0])==SQLITE_TEXT ){ const unsigned char *zStr = sqlite3_value_text(apVal[0]); assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); if( zStr ){ @@ -198006,7 +201633,7 @@ static int fts3auxFilterMethod( } } - if( iLe>=0 ){ + if( iLe>=0 && sqlite3_value_type(apVal[0])==SQLITE_TEXT ){ pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); if( pCsr->zStop==0 ) return SQLITE_NOMEM; pCsr->nStop = (int)strlen(pCsr->zStop); @@ -198611,6 +202238,7 @@ static int getNextNode( assert( nKey==4 ); if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){ nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear); + if( nNear>=1000000000 ) nNear = 1000000000; } } @@ -198688,7 +202316,7 @@ static int getNextNode( iColLen = 0; for(ii=0; iinCol; ii++){ const char *zStr = pParse->azCol[ii]; - int nStr = (int)strlen(zStr); + int nStr = zStr ? (int)strlen(zStr) : 0; if( nInput>nStr && zInput[nStr]==':' && sqlite3_strnicmp(zStr, zInput, nStr)==0 ){ @@ -199403,7 +203031,9 @@ static void fts3ExprTestCommon( ); } - if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ + if( rc==SQLITE_OK && fts3ExprCheckDepth(pExpr, SQLITE_FTS3_MAX_EXPR_DEPTH) ){ + sqlite3_result_error(context, "Expression nested too deep", -1); + }else if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ sqlite3_result_error(context, "Error parsing expression", -1); }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){ sqlite3_result_error_nomem(context); @@ -200464,10 +204094,11 @@ static int porterNext( if( c->iOffset>iStartOffset ){ int n = c->iOffset-iStartOffset; if( n>c->nAllocated ){ + i64 nNew = n + 20; char *pNew; - c->nAllocated = n+20; - pNew = sqlite3_realloc64(c->zToken, c->nAllocated); + pNew = sqlite3_realloc64(c->zToken, nNew); if( !pNew ) return SQLITE_NOMEM; + c->nAllocated = (int)nNew; c->zToken = pNew; } porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); @@ -201826,9 +205457,9 @@ typedef struct SegmentWriter SegmentWriter; ** incrementally. See function fts3PendingListAppend() for details. */ struct PendingList { - int nData; + sqlite3_int64 nData; char *aData; - int nSpace; + sqlite3_int64 nSpace; sqlite3_int64 iLastDocid; sqlite3_int64 iLastCol; sqlite3_int64 iLastPos; @@ -202001,6 +205632,24 @@ struct SegmentNode { #define SQL_UPDATE_LEVEL_IDX 38 #define SQL_UPDATE_LEVEL 39 +/* +** Wrapper around sqlite3_prepare_v3() to ensure that SQLITE_PREPARE_FROM_DDL +** is always set. +*/ +SQLITE_PRIVATE int sqlite3Fts3PrepareStmt( + Fts3Table *p, /* Prepare for this connection */ + const char *zSql, /* SQL to prepare */ + int bPersist, /* True to set SQLITE_PREPARE_PERSISTENT */ + int bAllowVtab, /* True to omit SQLITE_PREPARE_NO_VTAB */ + sqlite3_stmt **pp /* OUT: Prepared statement */ +){ + int f = SQLITE_PREPARE_FROM_DDL + |((bAllowVtab==0) ? SQLITE_PREPARE_NO_VTAB : 0) + |(bPersist ? SQLITE_PREPARE_PERSISTENT : 0); + + return sqlite3_prepare_v3(p->db, zSql, -1, f, pp, NULL); +} + /* ** This function is used to obtain an SQLite prepared statement handle ** for the statement identified by the second argument. If successful, @@ -202126,12 +205775,12 @@ static int fts3SqlStmt( pStmt = p->aStmt[eStmt]; if( !pStmt ){ - int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB; + int bAllowVtab = 0; char *zSql; if( eStmt==SQL_CONTENT_INSERT ){ zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){ - f &= ~SQLITE_PREPARE_NO_VTAB; + bAllowVtab = 1; zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist); }else{ zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); @@ -202139,7 +205788,7 @@ static int fts3SqlStmt( if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL); + rc = sqlite3Fts3PrepareStmt(p, zSql, 1, bAllowVtab, &pStmt); sqlite3_free(zSql); assert( rc==SQLITE_OK || pStmt==0 ); p->aStmt[eStmt] = pStmt; @@ -202488,7 +206137,9 @@ static int fts3PendingTermsAddOne( pList = (PendingList *)fts3HashFind(pHash, zToken, nToken); if( pList ){ - p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem)); + assert( (i64)pList->nData+(i64)nToken+(i64)sizeof(Fts3HashElem) + <= (i64)p->nPendingData ); + p->nPendingData -= (int)(pList->nData + nToken + sizeof(Fts3HashElem)); } if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){ if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){ @@ -202501,7 +206152,9 @@ static int fts3PendingTermsAddOne( } } if( rc==SQLITE_OK ){ - p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem)); + assert( (i64)p->nPendingData + pList->nData + nToken + + sizeof(Fts3HashElem) <= 0x3fffffff ); + p->nPendingData += (int)(pList->nData + nToken + sizeof(Fts3HashElem)); } return rc; } @@ -204835,6 +208488,10 @@ static void fts3ReadEndBlockField( for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ iVal = iVal*10 + (zText[i] - '0'); } + + /* This if() clause is just to avoid an integer overflow. The record is + ** corrupt in this case. */ + if( (i64)iVal==SMALLEST_INT64 ) iMul = 1; *pnByte = ((i64)iVal * (i64)iMul); } } @@ -205302,7 +208959,7 @@ static int fts3DoRebuild(Fts3Table *p){ if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt); sqlite3_free(zSql); } @@ -206061,7 +209718,7 @@ static int fts3IncrmergeLoad( return FTS_CORRUPT_VTAB; } - pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT; + pWriter->nLeafEst = (int)(((iEnd - iStart)+1)/FTS_MAX_APPENDABLE_HEIGHT); pWriter->iStart = iStart; pWriter->iEnd = iEnd; pWriter->iAbsLevel = iAbsLevel; @@ -206969,38 +210626,42 @@ static u64 fts3ChecksumIndex( rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); } - if( rc==SQLITE_OK ){ - while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ - char *pCsr = csr.aDoclist; - char *pEnd = &pCsr[csr.nDoclist]; + while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p,&csr)) ){ + char *pCsr = csr.aDoclist; + char *pEnd = &pCsr[csr.nDoclist]; - i64 iDocid = 0; - i64 iCol = 0; - u64 iPos = 0; + i64 iDocid = 0; + int iCol = 0; + u64 iPos = 0; - pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); - while( pCsrbDescIdx ){ + iDocid = (i64)((u64)iDocid - iVal); }else{ - pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); - if( p->bDescIdx ){ - iDocid = (i64)((u64)iDocid - iVal); - }else{ - iDocid = (i64)((u64)iDocid + iVal); - } + iDocid = (i64)((u64)iDocid + iVal); } + } + }else{ + iPos += (iVal - 2); + if( iPos>0x7FFFFFFF ){ + rc = SQLITE_CORRUPT_VTAB; + break; }else{ - iPos += (iVal - 2); cksum = cksum ^ fts3ChecksumEntry( csr.zTerm, csr.nTerm, iLangid, iIndex, iDocid, - (int)iCol, (int)iPos + iCol, (int)iPos ); } } @@ -207027,6 +210688,7 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ u64 cksum1 = 0; /* Checksum based on FTS index contents */ u64 cksum2 = 0; /* Checksum based on %_content contents */ sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ + int bContentless = (p->zContentTbl && p->zContentTbl[0]=='\0'); /* This block calculates the checksum according to the FTS index. */ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); @@ -207046,7 +210708,7 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ } /* This block calculates the checksum according to the %_content table */ - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && !bContentless ){ sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; sqlite3_stmt *pStmt = 0; char *zSql; @@ -207055,7 +210717,7 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt); sqlite3_free(zSql); } @@ -207104,7 +210766,7 @@ SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ rc = SQLITE_OK; *pbOk = 0; }else{ - *pbOk = (rc==SQLITE_OK && cksum1==cksum2); + *pbOk = (rc==SQLITE_OK && (bContentless || cksum1==cksum2)); } return rc; } @@ -207185,7 +210847,7 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ v = atoi(&zVal[9]); if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v; rc = SQLITE_OK; - }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 11) ){ v = atoi(&zVal[11]); if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v; rc = SQLITE_OK; @@ -207697,10 +211359,9 @@ struct StrBuffer { /* ** Allocate a two-slot MatchinfoBuffer object. */ -static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ +static MatchinfoBuffer *fts3MIBufferNew(i64 nElem, const char *zMatchinfo){ MatchinfoBuffer *pRet; - sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) - + SZ_MATCHINFOBUFFER(1); + sqlite3_int64 nByte = sizeof(u32) * (2*(i64)nElem+1) + SZ_MATCHINFOBUFFER(1); sqlite3_int64 nStr = strlen(zMatchinfo); pRet = sqlite3Fts3MallocZero(nByte + nStr+1); @@ -208094,6 +211755,7 @@ static int fts3BestSnippet( sqlite3_int64 nByte; /* Number of bytes of space to allocate */ int iBestScore = -1; /* Best snippet score found so far */ int i; /* Loop counter */ + Fts3Expr *pExpr = pCsr->pExpr; memset(&sIter, 0, sizeof(sIter)); @@ -208122,9 +211784,12 @@ static int fts3BestSnippet( sIter.nSnippet = nSnippet; sIter.nPhrase = nList; sIter.iCurrent = -1; - rc = sqlite3Fts3ExprIterate( - pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter - ); + rc = sqlite3Fts3ExprIterate(pExpr, fts3SnippetFindPositions, (void*)&sIter); + if( rc==SQLITE_OK ){ + /* Iterate through the expression twice, in case pointers garnered during + ** the first iteration are invalidated by a call to fts5EvalRestart(). */ + rc = sqlite3Fts3ExprIterate(pExpr, fts3SnippetFindPositions, (void*)&sIter); + } if( rc==SQLITE_OK ){ /* Set the *pmSeen output variable. */ @@ -208179,8 +211844,8 @@ static int fts3StringAppend( ** to grow the buffer until so that it is big enough to accommodate the ** appended data. */ - if( pStr->n+nAppend+1>=pStr->nAlloc ){ - sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100; + if( (i64)pStr->n+(i64)nAppend+1>=(i64)pStr->nAlloc ){ + i64 nAlloc = pStr->nAlloc+(i64)nAppend+100; char *zNew = sqlite3_realloc64(pStr->z, nAlloc); if( !zNew ){ return SQLITE_NOMEM; @@ -208452,7 +212117,7 @@ static int fts3ExprLHits( if( p->flag==FTS3_MATCHINFO_LHITS ){ p->aMatchinfo[iStart + iCol] = (u32)nHit; }else if( nHit ){ - p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F)); + p->aMatchinfo[iStart + iCol/32] |= (1U << (iCol&0x1F)); } } assert( *pIter==0x00 || *pIter==0x01 ); @@ -208571,8 +212236,8 @@ static int fts3MatchinfoCheck( return SQLITE_ERROR; } -static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ - size_t nVal; /* Number of integers output by cArg */ +static i64 fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ + i64 nVal; /* Number of integers output by cArg */ switch( cArg ){ case FTS3_MATCHINFO_NDOC: @@ -208588,16 +212253,16 @@ static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ break; case FTS3_MATCHINFO_LHITS: - nVal = (size_t)pInfo->nCol * pInfo->nPhrase; + nVal = (i64)pInfo->nCol * pInfo->nPhrase; break; case FTS3_MATCHINFO_LHITS_BM: - nVal = (size_t)pInfo->nPhrase * ((pInfo->nCol + 31) / 32); + nVal = (i64)pInfo->nPhrase * ((pInfo->nCol + 31) / 32); break; default: assert( cArg==FTS3_MATCHINFO_HITS ); - nVal = (size_t)pInfo->nCol * pInfo->nPhrase * 3; + nVal = (i64)pInfo->nCol * pInfo->nPhrase * 3; break; } @@ -208879,7 +212544,7 @@ static int fts3MatchinfoValues( case FTS3_MATCHINFO_LHITS_BM: case FTS3_MATCHINFO_LHITS: { - size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32); + i64 nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32); memset(pInfo->aMatchinfo, 0, nZero); rc = fts3ExprLHitGather(pCsr->pExpr, pInfo); break; @@ -208948,7 +212613,7 @@ static void fts3GetMatchinfo( ** initialize those elements that are constant for every row. */ if( pCsr->pMIBuffer==0 ){ - size_t nMatchinfo = 0; /* Number of u32 elements in match-info */ + i64 nMatchinfo = 0; /* Number of u32 elements in match-info */ int i; /* Used to iterate through zArg */ /* Determine the number of phrases in the query */ @@ -209033,9 +212698,8 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet( return; } - /* Limit the snippet length to 64 tokens. */ - if( nToken<-64 ) nToken = -64; - if( nToken>+64 ) nToken = +64; + /* The snippet length should already have been limited to 64 tokens. */ + assert( nToken>=-64 && nToken<=64 ); for(nSnippet=1; 1; nSnippet++){ @@ -209372,13 +213036,11 @@ SQLITE_PRIVATE void sqlite3Fts3Matchinfo( /* #include "fts3_tokenizer.h" */ /* -** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied -** from the sqlite3 source file utf.c. If this file is compiled as part -** of the amalgamation, they are not required. +** The following two macros - FTS3_READ_UTF8 and FTS3_WRITE_UTF8 - have +** been copied from the sqlite3 source file utf.c. */ -#ifndef SQLITE_AMALGAMATION -static const unsigned char sqlite3Utf8Trans1[] = { +static const unsigned char fts3Utf8Trans1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, @@ -209389,10 +213051,10 @@ static const unsigned char sqlite3Utf8Trans1[] = { 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, }; -#define READ_UTF8(zIn, zTerm, c) \ +#define FTS3_READ_UTF8(zIn, zTerm, c) \ c = *(zIn++); \ if( c>=0xc0 ){ \ - c = sqlite3Utf8Trans1[c-0xc0]; \ + c = fts3Utf8Trans1[c-0xc0]; \ while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ c = (c<<6) + (0x3f & *(zIn++)); \ } \ @@ -209401,28 +213063,26 @@ static const unsigned char sqlite3Utf8Trans1[] = { || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ } -#define WRITE_UTF8(zOut, c) { \ - if( c<0x00080 ){ \ - *zOut++ = (u8)(c&0xFF); \ - } \ - else if( c<0x00800 ){ \ - *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - } \ - else if( c<0x10000 ){ \ - *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ - *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - }else{ \ - *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ - *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ - *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ - *zOut++ = 0x80 + (u8)(c & 0x3F); \ - } \ +#define FTS3_WRITE_UTF8(zOut, c) { \ + if( c<0x00080 ){ \ + *zOut++ = (u8)(c&0xFF); \ + } \ + else if( c<0x00800 ){ \ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ + else if( c<0x10000 ){ \ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + }else{ \ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ } -#endif /* ifndef SQLITE_AMALGAMATION */ - typedef struct unicode_tokenizer unicode_tokenizer; typedef struct unicode_cursor unicode_cursor; @@ -209488,7 +213148,7 @@ static int unicodeAddExceptions( assert( bAlnum==0 || bAlnum==1 ); while( zeRemoveDiacritic); if( iOut ){ - WRITE_UTF8(zOut, iOut); + FTS3_WRITE_UTF8(zOut, iOut); } /* If the cursor is not at EOF, read the next character */ if( z>=zTerm ) break; - READ_UTF8(z, zTerm, iCode); + FTS3_READ_UTF8(z, zTerm, iCode); }while( unicodeIsAlnum(p, (int)iCode) || sqlite3FtsUnicodeIsdiacritic((int)iCode) ); @@ -210445,7 +214105,8 @@ struct JsonString { /* Allowed values for JsonString.eErr */ #define JSTRING_OOM 0x01 /* Out of memory */ #define JSTRING_MALFORMED 0x02 /* Malformed JSONB */ -#define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */ +#define JSTRING_TOODEEP 0x04 /* JSON nested too deep */ +#define JSTRING_ERR 0x08 /* Error already sent to sqlite3_result */ /* The "subtype" set for text JSON values passed through using ** sqlite3_result_subtype() and sqlite3_value_subtype(). @@ -210460,7 +214121,10 @@ struct JsonString { #define JSON_SQL 0x02 /* Result is always SQL */ #define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ #define JSON_ISSET 0x04 /* json_set(), not json_insert() */ -#define JSON_BLOB 0x08 /* Use the BLOB output format */ +#define JSON_AINS 0x08 /* json_array_insert(), not json_insert() */ +#define JSON_BLOB 0x10 /* Use the BLOB output format */ + +#define JSON_INSERT_TYPE(X) (((X)&0xC)>>2) /* A parsed JSON value. Lifecycle: @@ -210506,6 +214170,7 @@ struct JsonParse { #define JEDIT_REPL 2 /* Overwrite if exists */ #define JEDIT_INS 3 /* Insert if not exists */ #define JEDIT_SET 4 /* Insert or overwrite */ +#define JEDIT_AINS 5 /* array_insert() */ /* ** Maximum nesting depth of JSON for this implementation. @@ -210525,13 +214190,14 @@ struct JsonParse { */ #define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ #define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ +#define JSON_NOCACHE 0x04 /* Do not use the JSON cache */ /************************************************************************** ** Forward references **************************************************************************/ static void jsonReturnStringAsBlob(JsonString*); static int jsonArgIsJsonb(sqlite3_value *pJson, JsonParse *p); -static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); +static u32 jsonTranslateBlobToText(JsonParse*,u32,JsonString*); static void jsonReturnParse(sqlite3_context*,JsonParse*); static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); static void jsonParseFree(JsonParse*); @@ -210689,6 +214355,15 @@ static void jsonStringOom(JsonString *p){ jsonStringReset(p); } +/* Report JSON nested too deep +*/ +static void jsonStringTooDeep(JsonString *p){ + p->eErr |= JSTRING_TOODEEP; + assert( p->pCtx!=0 ); + sqlite3_result_error(p->pCtx, "JSON nested too deep", -1); + jsonStringReset(p); +} + /* Enlarge pJson->zBuf so that it can hold at least N more bytes. ** Return zero on success. Return non-zero on an OOM error */ @@ -210928,7 +214603,7 @@ static void jsonAppendSqlValue( break; } case SQLITE_FLOAT: { - jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue)); + jsonPrintf(100, p, "%!0.17g", sqlite3_value_double(pValue)); break; } case SQLITE_INTEGER: { @@ -210978,6 +214653,7 @@ static void jsonReturnString( ){ assert( (pParse!=0)==(ctx!=0) ); assert( ctx==0 || ctx==p->pCtx ); + jsonStringTerminate(p); if( p->eErr==0 ){ int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx)); if( flags & JSON_BLOB ){ @@ -210985,7 +214661,7 @@ static void jsonReturnString( }else if( p->bStatic ){ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, SQLITE_TRANSIENT, SQLITE_UTF8); - }else if( jsonStringTerminate(p) ){ + }else{ if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){ int rc; pParse->zJson = sqlite3RCStrRef(p->zBuf); @@ -211001,11 +214677,11 @@ static void jsonReturnString( sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed, sqlite3RCStrUnref, SQLITE_UTF8); - }else{ - sqlite3_result_error_nomem(p->pCtx); } }else if( p->eErr & JSTRING_OOM ){ sqlite3_result_error_nomem(p->pCtx); + }else if( p->eErr & JSTRING_TOODEEP ){ + /* error already in p->pCtx */ }else if( p->eErr & JSTRING_MALFORMED ){ sqlite3_result_error(p->pCtx, "malformed JSON", -1); } @@ -211267,7 +214943,7 @@ static void jsonWrongNumArgs( ** ** Return the number of errors. */ -static int jsonBlobExpand(JsonParse *pParse, u32 N){ +static int jsonBlobExpand(JsonParse *pParse, u64 N){ u8 *aNew; u64 t; assert( N>pParse->nBlobAlloc ); @@ -211295,7 +214971,7 @@ static int jsonBlobExpand(JsonParse *pParse, u32 N){ */ static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){ u8 *aOld; - u32 nSize; + u64 nSize; assert( !pParse->bReadOnly ); if( pParse->oom ) return 0; if( pParse->nBlobAlloc>0 ) return 1; @@ -211316,7 +214992,7 @@ static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte( JsonParse *pParse, u8 c ){ - jsonBlobExpand(pParse, pParse->nBlob+1); + jsonBlobExpand(pParse, (u64)pParse->nBlob+1); if( pParse->oom==0 ){ assert( pParse->nBlob+1<=pParse->nBlobAlloc ); pParse->aBlob[pParse->nBlob++] = c; @@ -211336,14 +215012,14 @@ static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){ /* Slow version of jsonBlobAppendNode() that first resizes the ** pParse->aBlob structure. */ -static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*); +static void jsonBlobAppendNode(JsonParse*,u8,u64,const void*); static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( JsonParse *pParse, u8 eType, - u32 szPayload, + u64 szPayload, const void *aPayload ){ - if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; + if( jsonBlobExpand(pParse, (u64)pParse->nBlob+(u64)szPayload+9) ) return; jsonBlobAppendNode(pParse, eType, szPayload, aPayload); } @@ -211360,7 +215036,7 @@ static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( static void jsonBlobAppendNode( JsonParse *pParse, /* The JsonParse object under construction */ u8 eType, /* Node type. One of JSONB_* */ - u32 szPayload, /* Number of bytes of payload */ + u64 szPayload, /* Number of bytes of payload */ const void *aPayload /* The payload. Might be NULL */ ){ u8 *a; @@ -211433,7 +215109,7 @@ static int jsonBlobChangePayloadSize( } delta = nNeeded - nExtra; if( delta ){ - u32 newSize = pParse->nBlob + delta; + u64 newSize = (u64)pParse->nBlob + delta; if( delta>0 ){ if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){ return 0; /* OOM error. Error state recorded in pParse->oom. */ @@ -212216,12 +215892,8 @@ static int jsonConvertTextToBlob( */ static void jsonReturnStringAsBlob(JsonString *pStr){ JsonParse px; + assert( pStr->eErr==0 ); memset(&px, 0, sizeof(px)); - jsonStringTerminate(pStr); - if( pStr->eErr ){ - sqlite3_result_error_nomem(pStr->pCtx); - return; - } px.zJson = pStr->zBuf; px.nJson = pStr->nUsed; px.db = sqlite3_context_db_handle(pStr->pCtx); @@ -212236,18 +215908,132 @@ static void jsonReturnStringAsBlob(JsonString *pStr){ } } -/* The byte at index i is a node type-code. This routine +/* +** This a helper routine for jsonbPayloadSize() and +** jsonbPayloadSizeSemiInline(). This routine is called using tail +** recursion to handle the (relatively uncommon) cases where the +** the payload size is a 2, 4, or 8 byte integer. +*/ +static u32 jsonbPayloadSizeWide( + const JsonParse *pParse, /* JSON parsing context */ + u32 i, /* Index of the node type-code */ + u32 *pSz, /* Write payload size here */ + u8 x /* pParse->aBlob[i]>>4 */ +){ + u32 sz; + u32 n; + assert( inBlob ); + assert( x==(pParse->aBlob[i]>>4) ); + assert( x>=13 ); + if( x==13 ){ + if( i+2>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2]; + n = 3; + }else if( x==14 ){ + if( i+4>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) + + (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4]; + n = 5; + }else{ + if( i+8>=pParse->nBlob + || pParse->aBlob[i+1]!=0 + || pParse->aBlob[i+2]!=0 + || pParse->aBlob[i+3]!=0 + || pParse->aBlob[i+4]!=0 + ){ + *pSz = 0; + return 0; + } + sz = ((u32)pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + + (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; + n = 9; + } + testcase( (i64)i+sz+n > pParse->nBlob ); + testcase( (i64)i+sz+n > pParse->nBlob-pParse->delta + && (i64)i+sz+n > pParse->nBlob ); + testcase( pParse->delta>0 ); + testcase( pParse->delta<0 ); + /* Quirks with -Os and gcov cause the NO_TEST line below to show up as + ** false-positive coverage miss. The testcases() macros above are + ** sufficient to prove that the branch is in fact covered */ + if( (i64)i+sz+n > pParse->nBlob + && (i64)i+sz+n > pParse->nBlob-pParse->delta /*NO_TEST*/ + ){ + *pSz = 0; + return 0; + } + *pSz = sz; + return n; +} + +/* +** This is the main routine for determining the size of a node in JSONB. +** The jsonbPayloadSizeWide() above is a helper. The two routines +** jsonbPayloadSizeInline() and jsonbPayloadSizeSemiInline() below are +** optional optimizations. It is important to keep all these routines in +** sync. Agents reading this code: Help us humans to remember that! +** +** The byte at index i is a node type-code. This routine ** determines the payload size for that node and writes that ** payload size in to *pSz. It returns the offset from i to the ** beginning of the payload. Return 0 on error. */ -static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ +static u32 jsonbPayloadSize( + const JsonParse *pParse, /* JSON parsing context */ + u32 i, /* Index of the node type-code */ + u32 *pSz /* Write payload size here */ +){ + u8 x; + u32 sz; + u32 n; + if( i>=pParse->nBlob ){ + *pSz = 0; + return 0; + }else if( (x = pParse->aBlob[i]>>4)<=11 ){ + sz = x; + n = 1; + }else if( x==12 ){ + if( i+1>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = pParse->aBlob[i+1]; + n = 2; + }else{ + return jsonbPayloadSizeWide(pParse, i, pSz, x); + } + if( (i64)i+sz+n > pParse->nBlob + && (i64)i+sz+n > pParse->nBlob-pParse->delta + ){ + *pSz = 0; + return 0; + } + *pSz = sz; + return n; +} + +#if SQLITE_USES_INLINE +/* A separate inline version of jsonbPayloadSize(), used in one particulary +** performance-critical place. +*/ +static SQLITE_INLINE u32 jsonbPayloadSizeInline( + const JsonParse *pParse, /* JSON parsing context */ + u32 i, /* Index of the node type-code */ + u32 *pSz /* Write payload size here */ +){ u8 x; u32 sz; u32 n; - assert( i<=pParse->nBlob ); - x = pParse->aBlob[i]>>4; - if( x<=11 ){ + if( i>=pParse->nBlob ){ + *pSz = 0; + return 0; + }else if( (x = pParse->aBlob[i]>>4)<=11 ){ sz = x; n = 1; }else if( x==12 ){ @@ -212295,8 +216081,62 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ *pSz = sz; return n; } +#else /* if !SQLITE_USES_INLINE */ + /* On compilers that do not support in-lining, just call the original + ** jsonbPayloadSize(). It's slower, but it gets the right answer. */ +# define jsonbPayloadSizeInline(a,b,c) jsonbPayloadSize(a,b,c) +#endif +#if SQLITE_USES_INLINE +/* A separate inline version of jsonbPayloadSize() that implements the more +** common paths inline but then calls out to a subroutine for the uncommon +** paths. +** +** * It is guaranteed that the i parameter is a valid index for +** pParse->aBlob[]. There is no possibility of running of the end +** of the allocation. +** +** * Large sizes (greater than 255) are uncommon and are handled +** by a subroutine call to the jsonbPayloadSizeWide(). +*/ +static SQLITE_INLINE u32 jsonbPayloadSizeSemiInline( + const JsonParse *pParse, /* JSON parsing context */ + u32 i, /* Index of the node type-code */ + u32 *pSz /* Write payload size here */ +){ + u8 x; + u32 sz; + u32 n; + assert( inBlob ); + if( (x = pParse->aBlob[i]>>4)<=11 ){ + sz = x; + n = 1; + }else if( x==12 ){ + if( i+1>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = pParse->aBlob[i+1]; + n = 2; + }else{ + return jsonbPayloadSizeWide(pParse,i,pSz,x); + } + if( (i64)i+sz+n > pParse->nBlob + && (i64)i+sz+n > pParse->nBlob-pParse->delta + ){ + *pSz = 0; + return 0; + } + *pSz = sz; + return n; +} +#else /* if !SQLITE_USES_INLINE */ + /* On compilers that do not support in-lining, just call the original + ** jsonbPayloadSize(). It's slower, but it gets the right answer. */ +# define jsonbPayloadSizeSemiInline(a,b,c) jsonbPayloadSize(a,b,c) +#endif + /* ** Translate the binary JSONB representation of JSON beginning at ** pParse->aBlob[i] into a JSON text string. Append the JSON @@ -212311,13 +216151,13 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ ** The pOut->eErr JSTRING_OOM flag is set on a OOM. */ static u32 jsonTranslateBlobToText( - const JsonParse *pParse, /* the complete parse of the JSON */ + JsonParse *pParse, /* the complete parse of the JSON */ u32 i, /* Start rendering at this index */ JsonString *pOut /* Write JSON here */ ){ u32 sz, n, j, iEnd; - n = jsonbPayloadSize(pParse, i, &sz); + n = jsonbPayloadSizeInline(pParse, i, &sz); if( n==0 ){ pOut->eErr |= JSTRING_MALFORMED; return pParse->nBlob+1; @@ -212372,7 +216212,8 @@ static u32 jsonTranslateBlobToText( if( sz==0 ) goto malformed_jsonb; if( zIn[0]=='-' ){ jsonAppendChar(pOut, '-'); - k++; + if( sz<=1 ) goto malformed_jsonb; + k = 1; } if( zIn[k]=='.' ){ jsonAppendChar(pOut, '0'); @@ -212461,7 +216302,7 @@ static u32 jsonTranslateBlobToText( break; case 0xe2: /* '\' followed by either U+2028 or U+2029 is ignored as - ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. + ** whitespace. Note that in UTF8, U+2028 is 0xe2 0x80 0x29. ** U+2029 is the same except for the last byte */ if( sz2<4 || 0x80!=(u8)zIn[2] @@ -212493,10 +216334,14 @@ static u32 jsonTranslateBlobToText( jsonAppendChar(pOut, '['); j = i+n; iEnd = j+sz; + if( ++pParse->iDepth > JSON_MAX_DEPTH ){ + jsonStringTooDeep(pOut); + } while( jeErr==0 ){ j = jsonTranslateBlobToText(pParse, j, pOut); jsonAppendChar(pOut, ','); } + pParse->iDepth--; if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; if( sz>0 ) jsonStringTrimOneChar(pOut); jsonAppendChar(pOut, ']'); @@ -212507,10 +216352,14 @@ static u32 jsonTranslateBlobToText( jsonAppendChar(pOut, '{'); j = i+n; iEnd = j+sz; + if( ++pParse->iDepth > JSON_MAX_DEPTH ){ + jsonStringTooDeep(pOut); + } while( jeErr==0 ){ j = jsonTranslateBlobToText(pParse, j, pOut); jsonAppendChar(pOut, (x++ & 1) ? ',' : ':'); } + pParse->iDepth--; if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; if( sz>0 ) jsonStringTrimOneChar(pOut); jsonAppendChar(pOut, '}'); @@ -212567,7 +216416,7 @@ static u32 jsonTranslateBlobToPrettyText( u32 i /* Start rendering at this index */ ){ u32 sz, n, j, iEnd; - const JsonParse *pParse = pPretty->pParse; + JsonParse *pParse = pPretty->pParse; JsonString *pOut = pPretty->pOut; n = jsonbPayloadSize(pParse, i, &sz); if( n==0 ){ @@ -212582,10 +216431,16 @@ static u32 jsonTranslateBlobToPrettyText( if( jnIndent++; + if( pPretty->nIndent >= JSON_MAX_DEPTH ){ + jsonStringTooDeep(pOut); + } while( pOut->eErr==0 ){ jsonPrettyIndent(pPretty); j = jsonTranslateBlobToPrettyText(pPretty, j); - if( j>=iEnd ) break; + if( j>=iEnd ){ + if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + break; + } jsonAppendRawNZ(pOut, ",\n", 2); } jsonAppendChar(pOut, '\n'); @@ -212603,6 +216458,10 @@ static u32 jsonTranslateBlobToPrettyText( if( jnIndent++; + if( pPretty->nIndent >= JSON_MAX_DEPTH ){ + jsonStringTooDeep(pOut); + } + pParse->iDepth = pPretty->nIndent; while( pOut->eErr==0 ){ jsonPrettyIndent(pPretty); j = jsonTranslateBlobToText(pParse, j, pOut); @@ -212641,7 +216500,7 @@ static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){ n = jsonbPayloadSize(pParse, iRoot, &sz); iEnd = iRoot+n+sz; for(i=iRoot+n; n>0 && inBlob >= (u64)iDel + (u64)nDel ); if( d<0 && d>=(-8) && aIns!=0 && jsonBlobOverwrite(&pParse->aBlob[iDel], aIns, nIns, (int)-d) ){ @@ -212767,7 +216627,7 @@ static void jsonBlobEdit( } if( d!=0 ){ if( pParse->nBlob + d > pParse->nBlobAlloc ){ - jsonBlobExpand(pParse, pParse->nBlob+d); + jsonBlobExpand(pParse, (u64)pParse->nBlob+d); if( pParse->oom ) return; } memmove(&pParse->aBlob[iDel+nIns], @@ -213002,7 +216862,9 @@ static int jsonLabelCompare( */ #define JSON_LOOKUP_ERROR 0xffffffff #define JSON_LOOKUP_NOTFOUND 0xfffffffe -#define JSON_LOOKUP_PATHERROR 0xfffffffd +#define JSON_LOOKUP_NOTARRAY 0xfffffffd +#define JSON_LOOKUP_TOODEEP 0xfffffffc +#define JSON_LOOKUP_PATHERROR 0xfffffffb #define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) /* Forward declaration */ @@ -213031,7 +216893,7 @@ static u32 jsonLookupStep(JsonParse*,u32,const char*,u32); static u32 jsonCreateEditSubstructure( JsonParse *pParse, /* The original JSONB that is being edited */ JsonParse *pIns, /* Populate this with the blob data to insert */ - const char *zTail /* Tail of the path that determins substructure */ + const char *zTail /* Tail of the path that determines substructure */ ){ static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT }; int rc; @@ -213049,7 +216911,12 @@ static u32 jsonCreateEditSubstructure( pIns->eEdit = pParse->eEdit; pIns->nIns = pParse->nIns; pIns->aIns = pParse->aIns; + pIns->iDepth = pParse->iDepth+1; + if( pIns->iDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } rc = jsonLookupStep(pIns, 0, zTail, 0); + pParse->iDepth--; pParse->oom |= pIns->oom; } return rc; /* Error code only */ @@ -213066,9 +216933,9 @@ static u32 jsonCreateEditSubstructure( ** Return one of the JSON_LOOKUP error codes if problems are seen. ** ** This routine will also modify the blob. If pParse->eEdit is one of -** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be -** made to the selected value. If an edit is performed, then the return -** value does not necessarily point to the select element. If an edit +** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, JEDIT_SET, or JEDIT_AINS, then changes +** might be made to the selected value. If an edit is performed, then the +** return value does not necessarily point to the select element. If an edit ** is performed, the return value is only useful for detecting error ** conditions. */ @@ -213094,6 +216961,13 @@ static u32 jsonLookupStep( jsonBlobEdit(pParse, iRoot, sz, 0, 0); }else if( pParse->eEdit==JEDIT_INS ){ /* Already exists, so json_insert() is a no-op */ + }else if( pParse->eEdit==JEDIT_AINS ){ + /* json_array_insert() */ + if( zPath[-1]!=']' ){ + return JSON_LOOKUP_NOTARRAY; + }else{ + jsonBlobEdit(pParse, iRoot, 0, pParse->aIns, pParse->nIns); + } }else{ /* json_set() or json_replace() */ jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns); @@ -213136,7 +217010,7 @@ static u32 jsonLookupStep( const char *zLabel; x = pParse->aBlob[j] & 0x0f; if( xJSONB_TEXTRAW ) return JSON_LOOKUP_ERROR; - n = jsonbPayloadSize(pParse, j, &sz); + n = jsonbPayloadSizeSemiInline(pParse, j, &sz); if( n==0 ) return JSON_LOOKUP_ERROR; k = j+n; /* k is the index of the label text */ if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR; @@ -213148,13 +217022,17 @@ static u32 jsonLookupStep( n = jsonbPayloadSize(pParse, v, &sz); if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; assert( j>0 ); + if( ++pParse->iDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } rc = jsonLookupStep(pParse, v, &zPath[i], j); + pParse->iDepth--; if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); return rc; } j = k+sz; if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; - n = jsonbPayloadSize(pParse, j, &sz); + n = jsonbPayloadSizeSemiInline(pParse, j, &sz); if( n==0 ) return JSON_LOOKUP_ERROR; j += n+sz; } @@ -213165,6 +217043,10 @@ static u32 jsonLookupStep( JsonParse ix; /* Header of the label to be inserted */ testcase( pParse->eEdit==JEDIT_INS ); testcase( pParse->eEdit==JEDIT_SET ); + testcase( pParse->eEdit==JEDIT_AINS ); + if( pParse->eEdit==JEDIT_AINS && sqlite3_strglob("*]",&zPath[i])!=0 ){ + return JSON_LOOKUP_NOTARRAY; + } memset(&ix, 0, sizeof(ix)); ix.db = pParse->db; jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0); @@ -213192,28 +217074,32 @@ static u32 jsonLookupStep( return rc; } }else if( zPath[0]=='[' ){ + u64 kk = 0; x = pParse->aBlob[iRoot] & 0x0f; if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND; n = jsonbPayloadSize(pParse, iRoot, &sz); - k = 0; i = 1; while( sqlite3Isdigit(zPath[i]) ){ - k = k*10 + zPath[i] - '0'; + if( kk<0xffffffff ) kk = kk*10 + zPath[i] - '0'; + /* ^^^^^^^^^^--- Allow kk to be bigger than any JSON array so that + ** we get NOTFOUND instead of PATHERROR, without overflowing kk. */ i++; } if( i<2 || zPath[i]!=']' ){ if( zPath[1]=='#' ){ - k = jsonbArrayCount(pParse, iRoot); + kk = jsonbArrayCount(pParse, iRoot); i = 2; if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ - unsigned int nn = 0; + u64 nn = 0; i = 3; do{ - nn = nn*10 + zPath[i] - '0'; + if( nn<0xffffffff ) nn = nn*10 + zPath[i] - '0'; + /* ^^^^^^^^^^--- Allow nn to be bigger than any JSON array to + ** get NOTFOUND instead of PATHERROR, without overflowing nn. */ i++; }while( sqlite3Isdigit(zPath[i]) ); - if( nn>k ) return JSON_LOOKUP_NOTFOUND; - k -= nn; + if( nn>kk ) return JSON_LOOKUP_NOTFOUND; + kk -= nn; } if( zPath[i]!=']' ){ return JSON_LOOKUP_PATHERROR; @@ -213225,21 +217111,26 @@ static u32 jsonLookupStep( j = iRoot+n; iEnd = j+sz; while( jiDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } rc = jsonLookupStep(pParse, j, &zPath[i+1], 0); + pParse->iDepth--; if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); return rc; } - k--; - n = jsonbPayloadSize(pParse, j, &sz); + kk--; + n = jsonbPayloadSizeSemiInline(pParse, j, &sz); if( n==0 ) return JSON_LOOKUP_ERROR; j += n+sz; } if( j>iEnd ) return JSON_LOOKUP_ERROR; - if( k>0 ) return JSON_LOOKUP_NOTFOUND; + if( kk>0 ) return JSON_LOOKUP_NOTFOUND; if( pParse->eEdit>=JEDIT_INS ){ JsonParse v; testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_AINS ); testcase( pParse->eEdit==JEDIT_SET ); rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]); if( !JSON_LOOKUP_ISERROR(rc) @@ -213377,7 +217268,7 @@ static void jsonReturnFromBlob( to_double: z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); if( z==0 ) goto returnfromblob_oom; - rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); + rc = sqlite3AtoF(z, &r); sqlite3DbFree(db, z); if( rc<=0 ) goto returnfromblob_malformed; sqlite3_result_double(pCtx, r); @@ -213523,8 +217414,7 @@ static int jsonFunctionArgToBlob( break; } case SQLITE_FLOAT: { - double r = sqlite3_value_double(pArg); - if( NEVER(sqlite3IsNaN(r)) ){ + if( NEVER(sqlite3IsNaN(sqlite3_value_double(pArg))) ){ jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0); }else{ int n = sqlite3_value_bytes(pArg); @@ -213557,16 +217447,35 @@ static int jsonFunctionArgToBlob( } /* -** Generate a bad path error. +** Generate a path error. +** +** The specifics of the error are determined by the rc argument. +** +** rc error +** ----------------- ---------------------- +** JSON_LOOKUP_ARRAY "not an array" +** JSON_LOOKUP_TOODEEP "JSON nested too deep" +** JSON_LOOKUP_ERROR "malformed JSON" +** otherwise... "bad JSON path" ** ** If ctx is not NULL then push the error message into ctx and return NULL. ** If ctx is NULL, then return the text of the error message. */ static char *jsonBadPathError( sqlite3_context *ctx, /* The function call containing the error */ - const char *zPath /* The path with the problem */ + const char *zPath, /* The path with the problem */ + int rc /* Maybe JSON_LOOKUP_NOTARRAY */ ){ - char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); + char *zMsg; + if( rc==(int)JSON_LOOKUP_NOTARRAY ){ + zMsg = sqlite3_mprintf("not an array element: %Q", zPath); + }else if( rc==(int)JSON_LOOKUP_ERROR ){ + zMsg = sqlite3_mprintf("malformed JSON"); + }else if( rc==(int)JSON_LOOKUP_TOODEEP ){ + zMsg = sqlite3_mprintf("JSON path too deep"); + }else{ + zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); + } if( ctx==0 ) return zMsg; if( zMsg ){ sqlite3_result_error(ctx, zMsg, -1); @@ -213583,13 +217492,13 @@ static char *jsonBadPathError( ** and return the result. ** ** The specific operation is determined by eEdit, which can be one -** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET. +** of JEDIT_INS, JEDIT_REPL, JEDIT_SET, or JEDIT_AINS. */ static void jsonInsertIntoBlob( sqlite3_context *ctx, int argc, sqlite3_value **argv, - int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */ + int eEdit /* JEDIT_INS, JEDIT_REPL, JEDIT_SET, JEDIT_AINS */ ){ int i; u32 rc = 0; @@ -213626,6 +217535,7 @@ static void jsonInsertIntoBlob( p->nIns = ax.nBlob; p->aIns = ax.aBlob; p->delta = 0; + p->iDepth = 0; rc = jsonLookupStep(p, 0, zPath+1, 0); } jsonParseReset(&ax); @@ -213638,11 +217548,7 @@ static void jsonInsertIntoBlob( jsonInsertIntoBlob_patherror: jsonParseFree(p); - if( rc==JSON_LOOKUP_ERROR ){ - sqlite3_result_error(ctx, "malformed JSON", -1); - }else{ - jsonBadPathError(ctx, zPath); - } + jsonBadPathError(ctx, zPath, rc); return; } @@ -213728,7 +217634,9 @@ static JsonParse *jsonParseFuncArg( if( eType==SQLITE_NULL ){ return 0; } - pFromCache = jsonCacheSearch(ctx, pArg); + if( (flgs & JSON_NOCACHE)==0 ){ + pFromCache = jsonCacheSearch(ctx, pArg); + } if( pFromCache ){ pFromCache->nJPRef++; if( (flgs & JSON_EDITABLE)==0 ){ @@ -214082,10 +217990,8 @@ static void jsonArrayLengthFunc( if( JSON_LOOKUP_ISERROR(i) ){ if( i==JSON_LOOKUP_NOTFOUND ){ /* no-op */ - }else if( i==JSON_LOOKUP_PATHERROR ){ - jsonBadPathError(ctx, zPath); }else{ - sqlite3_result_error(ctx, "malformed JSON", -1); + jsonBadPathError(ctx, zPath, i); } eErr = 1; i = 0; @@ -214188,7 +218094,7 @@ static void jsonExtractFunc( j = jsonLookupStep(p, 0, jx.zBuf, 0); jsonStringReset(&jx); }else{ - jsonBadPathError(ctx, zPath); + jsonBadPathError(ctx, zPath, 0); goto json_extract_error; } if( jnBlob ){ @@ -214219,11 +218125,8 @@ static void jsonExtractFunc( jsonAppendSeparator(&jx); jsonAppendRawNZ(&jx, "null", 4); } - }else if( j==JSON_LOOKUP_ERROR ){ - sqlite3_result_error(ctx, "malformed JSON", -1); - goto json_extract_error; }else{ - jsonBadPathError(ctx, zPath); + jsonBadPathError(ctx, zPath, j); goto json_extract_error; } } @@ -214247,6 +218150,7 @@ static void jsonExtractFunc( #define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */ #define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */ #define JSON_MERGE_OOM 3 /* Out-of-memory condition */ +#define JSON_MERGE_TOODEEP 4 /* Nested too deep */ /* ** RFC-7396 MergePatch for two JSONB blobs. @@ -214298,7 +218202,8 @@ static int jsonMergePatch( JsonParse *pTarget, /* The JSON parser that contains the TARGET */ u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */ const JsonParse *pPatch, /* The PATCH */ - u32 iPatch /* Index of PATCH in pPatch->aBlob[] */ + u32 iPatch, /* Index of PATCH in pPatch->aBlob[] */ + u32 iDepth /* Nesting depth */ ){ u8 x; /* Type of a single node */ u32 n, sz=0; /* Return values from jsonbPayloadSize() */ @@ -214407,7 +218312,8 @@ static int jsonMergePatch( /* Algorithm line 12 */ int rc, savedDelta = pTarget->delta; pTarget->delta = 0; - rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue); + if( iDepth>=JSON_MAX_DEPTH ) return JSON_MERGE_TOODEEP; + rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue, iDepth+1); if( rc ) return rc; pTarget->delta += savedDelta; } @@ -214428,7 +218334,8 @@ static int jsonMergePatch( pTarget->aBlob[iTEnd+szNew] = 0x00; savedDelta = pTarget->delta; pTarget->delta = 0; - rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue); + if( iDepth>=JSON_MAX_DEPTH ) return JSON_MERGE_TOODEEP; + rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue,iDepth+1); if( rc ) return rc; pTarget->delta += savedDelta; } @@ -214459,11 +218366,13 @@ static void jsonPatchFunc( if( pTarget==0 ) return; pPatch = jsonParseFuncArg(ctx, argv[1], 0); if( pPatch ){ - rc = jsonMergePatch(pTarget, 0, pPatch, 0); + rc = jsonMergePatch(pTarget, 0, pPatch, 0, 0); if( rc==JSON_MERGE_OK ){ jsonReturnParse(ctx, pTarget); }else if( rc==JSON_MERGE_OOM ){ sqlite3_result_error_nomem(ctx); + }else if( rc==JSON_MERGE_TOODEEP ){ + sqlite3_result_error(ctx, "JSON nested too deep", -1); }else{ sqlite3_result_error(ctx, "malformed JSON", -1); } @@ -214551,10 +218460,8 @@ static void jsonRemoveFunc( if( JSON_LOOKUP_ISERROR(rc) ){ if( rc==JSON_LOOKUP_NOTFOUND ){ continue; /* No-op */ - }else if( rc==JSON_LOOKUP_PATHERROR ){ - jsonBadPathError(ctx, zPath); }else{ - sqlite3_result_error(ctx, "malformed JSON", -1); + jsonBadPathError(ctx, zPath, rc); } goto json_remove_done; } @@ -214564,7 +218471,7 @@ static void jsonRemoveFunc( return; json_remove_patherror: - jsonBadPathError(ctx, zPath); + jsonBadPathError(ctx, zPath, 0); json_remove_done: jsonParseFree(p); @@ -214608,16 +218515,18 @@ static void jsonSetFunc( int argc, sqlite3_value **argv ){ - int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); - int bIsSet = (flags&JSON_ISSET)!=0; + int eInsType = JSON_INSERT_TYPE(flags); + static const char *azInsType[] = { "insert", "set", "array_insert" }; + static const u8 aEditType[] = { JEDIT_INS, JEDIT_SET, JEDIT_AINS }; if( argc<1 ) return; + assert( eInsType>=0 && eInsType<=2 ); if( (argc&1)==0 ) { - jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); + jsonWrongNumArgs(ctx, azInsType[eInsType]); return; } - jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS); + jsonInsertIntoBlob(ctx, argc, argv, aEditType[eInsType]); } /* @@ -214642,17 +218551,15 @@ static void jsonTypeFunc( zPath = (const char*)sqlite3_value_text(argv[1]); if( zPath==0 ) goto json_type_done; if( zPath[0]!='$' ){ - jsonBadPathError(ctx, zPath); + jsonBadPathError(ctx, zPath, 0); goto json_type_done; } i = jsonLookupStep(p, 0, zPath+1, 0); if( JSON_LOOKUP_ISERROR(i) ){ if( i==JSON_LOOKUP_NOTFOUND ){ /* no-op */ - }else if( i==JSON_LOOKUP_PATHERROR ){ - jsonBadPathError(ctx, zPath); }else{ - sqlite3_result_error(ctx, "malformed JSON", -1); + jsonBadPathError(ctx, zPath, i); } goto json_type_done; } @@ -214804,7 +218711,7 @@ static void jsonValidFunc( if( (flags & 0x3)==0 ) break; memset(&px, 0, sizeof(px)); - p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR); + p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR|JSON_NOCACHE); if( p ){ if( p->oom ){ sqlite3_result_error_nomem(ctx); @@ -214906,12 +218813,12 @@ static void jsonArrayStep( } static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ - int flags; pStr->pCtx = ctx; - jsonAppendChar(pStr, ']'); - flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + jsonAppendRawNZ(pStr, "]", 2); + jsonStringTrimOneChar(pStr); if( pStr->eErr ){ jsonReturnString(pStr, 0, 0); return; @@ -214932,6 +218839,9 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); jsonStringTrimOneChar(pStr); } + }else if( flags & JSON_BLOB ){ + static const u8 emptyArray = 0x0b; + sqlite3_result_blob(ctx, &emptyArray, 1, SQLITE_STATIC); }else{ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); } @@ -214965,11 +218875,9 @@ static void jsonGroupInverse( UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); -#ifdef NEVER /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will ** always have been called to initialize it */ if( NEVER(!pStr) ) return; -#endif z = pStr->zBuf; for(i=1; inUsed && ((c = z[i])!=',' || inStr || nNest); i++){ if( c=='"' ){ @@ -214998,6 +218906,13 @@ static void jsonGroupInverse( ** json_group_obj(NAME,VALUE) ** ** Return a JSON object composed of all names and values in the aggregate. +** +** Rows for which NAME is NULL do not result in a new entry. However, we +** do initially insert a "@" entry into the growing string for each null entry +** and change the first character of the string to "@" to signal that the +** string contains null entries. The "@" markers are needed in order to +** correctly process xInverse() requests. The initial "@" is converted +** back into "{" and the "@" null values are removed by jsonObjectCompute(). */ static void jsonObjectStep( sqlite3_context *ctx, @@ -215015,7 +218930,7 @@ static void jsonObjectStep( if( pStr->zBuf==0 ){ jsonStringInit(pStr, ctx); jsonAppendChar(pStr, '{'); - }else if( pStr->nUsed>1 && z!=0 ){ + }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); } pStr->pCtx = ctx; @@ -215023,28 +218938,75 @@ static void jsonObjectStep( jsonAppendString(pStr, z, n); jsonAppendChar(pStr, ':'); jsonAppendSqlValue(pStr, argv[1]); + }else{ + pStr->zBuf[0] = '@'; + jsonAppendRawNZ(pStr, "@", 1); } } } static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ - int flags; - jsonAppendChar(pStr, '}'); + JsonString *pOgStr = pStr; + JsonString tmpStr; + jsonAppendRawNZ(pOgStr, "}", 2); /* Ensure it is zero-terminated */ + jsonStringTrimOneChar(pOgStr); /* Remove the zero terminator */ pStr->pCtx = ctx; - flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); if( pStr->eErr ){ jsonReturnString(pStr, 0, 0); return; - }else if( flags & JSON_BLOB ){ + } + if( pStr->zBuf[0]!='{' ){ + /* The string contains null entries that need to be removed */ + u64 i, j; + int inStr = 0; + if( !isFinal ){ + /* Work with a temporary copy of the string if this is not the + ** final result */ + jsonStringInit(&tmpStr, ctx); + jsonAppendRawNZ(&tmpStr, pStr->zBuf, pStr->nUsed+1); + pStr = &tmpStr; + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + } + jsonStringTrimOneChar(pStr); /* Remove zero terminator */ + } + /* Fix up the string by changing the initial "@" flag back to + ** to "{" and removing all subsequence "@" entries, with their + ** associated comma delimeters. */ + pStr->zBuf[0] = '{'; + for(i=j=1; inUsed; i++){ + char c = pStr->zBuf[i]; + if( c=='"' ){ + inStr = !inStr; + pStr->zBuf[j++] = '"'; + }else if( c=='\\' ){ + pStr->zBuf[j++] = '\\'; + pStr->zBuf[j++] = pStr->zBuf[++i]; + }else if( c=='@' && !inStr ){ + assert( i+1nUsed ); + if( pStr->zBuf[i+1]==',' ){ + i++; + }else if( pStr->zBuf[j-1]==',' ){ + j--; + } + }else{ + pStr->zBuf[j++] = c; + } + } + pStr->zBuf[j] = 0; /* Restore zero terminator */ + pStr->nUsed = j; /* Truncate the string */ + } + if( flags & JSON_BLOB ){ jsonReturnStringAsBlob(pStr); if( isFinal ){ if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); }else{ - jsonStringTrimOneChar(pStr); + jsonStringTrimOneChar(pOgStr); } - return; }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : @@ -215052,8 +219014,12 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); - jsonStringTrimOneChar(pStr); + jsonStringTrimOneChar(pOgStr); } + if( pStr!=pOgStr ) jsonStringReset(pStr); + }else if( flags & JSON_BLOB ){ + static const unsigned char emptyObject = 0x0c; + sqlite3_result_blob(ctx, &emptyObject, 1, SQLITE_STATIC); }else{ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); } @@ -215215,7 +219181,9 @@ static int jsonSkipLabel(JsonEachCursor *p){ if( p->eType==JSONB_OBJECT ){ u32 sz = 0; u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz); - return p->i + n + sz; + sz += p->i + n; + if( sz >= p->sParse.nBlob ) sz = p->i; + return sz; }else{ return p->i; } @@ -215254,6 +219222,15 @@ static void jsonAppendPathName(JsonEachCursor *p){ } } +/* Report a "malformed JSON" or OOM error against the cursor. +*/ +static int jsonEachMalformedInput(sqlite3_vtab_cursor *cur){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); + jsonEachCursorReset((JsonEachCursor*)cur); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; +} + /* Advance the cursor to the next element for json_tree() */ static int jsonEachNext(sqlite3_vtab_cursor *cur){ JsonEachCursor *p = (JsonEachCursor*)cur; @@ -215265,6 +219242,7 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){ u32 i = jsonSkipLabel(p); x = p->sParse.aBlob[i] & 0x0f; n = jsonbPayloadSize(&p->sParse, i, &sz); + if( n==0 )return jsonEachMalformedInput(cur); if( x==JSONB_OBJECT || x==JSONB_ARRAY ){ JsonParent *pParent; if( p->nParent>=p->nParentAlloc ){ @@ -215310,6 +219288,7 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){ u32 n, sz = 0; u32 i = jsonSkipLabel(p); n = jsonbPayloadSize(&p->sParse, i, &sz); + if( n==0 )return jsonEachMalformedInput(cur); p->i = i + n + sz; } if( p->eType==JSONB_ARRAY && p->nParent ){ @@ -215423,7 +219402,7 @@ static int jsonEachColumn( break; } default: { - sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC); + sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_TRANSIENT); break; } case JEACH_JSON: { @@ -215546,7 +219525,7 @@ static int jsonEachFilter( if( p->sParse.oom ){ return SQLITE_NOMEM; } - goto json_each_malformed_input; + return jsonEachMalformedInput(cur); } } if( idxNum==3 ){ @@ -215554,7 +219533,7 @@ static int jsonEachFilter( if( zRoot==0 ) return SQLITE_OK; if( zRoot[0]!='$' ){ sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot, 0); jsonEachCursorReset(p); return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; } @@ -215572,7 +219551,7 @@ static int jsonEachFilter( return SQLITE_OK; } sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot, 0); jsonEachCursorReset(p); return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; } @@ -215607,12 +219586,6 @@ static int jsonEachFilter( p->aParent[0].iValue = i; } return SQLITE_OK; - -json_each_malformed_input: - sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); - jsonEachCursorReset(p); - return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; } /* The methods of the json_each virtual table */ @@ -215662,6 +219635,8 @@ SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc), JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc), JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc), + JFUNCTION(json_array_insert, -1,1,1, 1,0,JSON_AINS, jsonSetFunc), + JFUNCTION(jsonb_array_insert,-1,1,0, 1,1,JSON_AINS, jsonSetFunc), JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc), JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc), JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc), @@ -215900,7 +219875,7 @@ struct Rtree { u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ u8 nBytesPerCell; /* Bytes consumed per cell */ u8 inWrTrans; /* True if inside write transaction */ - u8 nAux; /* # of auxiliary columns in %_rowid */ + u16 nAux; /* # of auxiliary columns in %_rowid */ #ifdef SQLITE_ENABLE_GEOPOLY u8 nAuxNotNull; /* Number of initial not-null aux columns */ #endif @@ -216040,7 +220015,7 @@ struct RtreeCursor { sqlite3_stmt *pReadAux; /* Statement to read aux-data */ RtreeSearchPoint sPoint; /* Cached next search point */ RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ - u32 anQueue[RTREE_MAX_DEPTH+1]; /* Number of queued entries by iLevel */ + u32 anQueue[RTREE_MAX_DEPTH+2]; /* Number of queued entries by iLevel */ }; /* Return the Rtree of a RtreeCursor */ @@ -216220,7 +220195,7 @@ struct RtreeMatchArg { ** ** For best performance, an attempt is made to guess at the byte-order ** using C-preprocessor macros. If that is unsuccessful, or if -** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined +** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined ** at run-time. */ #ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ @@ -216276,8 +220251,11 @@ static void readCoord(u8 *p, RtreeCoord *pCoord){ ); #endif } + static i64 readInt64(u8 *p){ -#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 +#if defined(SQLITE_AMALGAMATION) + return (i64)sqlite3Get8byte(p); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 u64 x; memcpy(&x, p, 8); return (i64)_byteswap_uint64(x); @@ -216357,6 +220335,18 @@ static int writeInt64(u8 *p, i64 i){ return 8; } +/* +** Translate pVal into a 32-bit integer. If pVal is an integer +** that is larger than 32 bits, the cap it at the largest or +** smallest 32-bit integer. +*/ +static int rtreeValueInt32(sqlite3_value *pVal){ + i64 v64 = sqlite3_value_int64(pVal); + if( v64>2147483647 ) return 2147483647; + if( v64<-2147483648LL ) return (int)-2147483648LL; + return (int)v64; +} + /* ** Increment the reference count of node p. */ @@ -216495,6 +220485,9 @@ static int nodeAcquire( rc = SQLITE_CORRUPT_VTAB; RTREE_IS_CORRUPT(pRtree); } + }else if( iNode<=0 ){ + RTREE_IS_CORRUPT(pRtree); + rc = SQLITE_CORRUPT_VTAB; }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize); if( !pNode ){ @@ -216520,7 +220513,7 @@ static int nodeAcquire( */ if( rc==SQLITE_OK && pNode && iNode==1 ){ pRtree->iDepth = readInt16(pNode->zData); - if( pRtree->iDepth>RTREE_MAX_DEPTH ){ + if( pRtree->iDepth>=RTREE_MAX_DEPTH ){ rc = SQLITE_CORRUPT_VTAB; RTREE_IS_CORRUPT(pRtree); } @@ -216634,7 +220627,17 @@ static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ sqlite3_bind_null(p, 2); if( pNode->iNode==0 && rc==SQLITE_OK ){ pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); - nodeHashInsert(pRtree, pNode); + if( pNode->iNode==0 ){ + /* If the SQL statement has succeeded but sqlite3_last_insert_rowid() + ** returns 0, then the shadow table schema has been corrupted somehow + ** (e.g. the %_node table has been replaced by a WITHOUT ROWID table). + ** It would be dangerous to continue in this case as the hash table + ** implementation assumes iNode==0 means that the node is not part + ** of the hash table. */ + rc = SQLITE_CORRUPT_VTAB; + }else{ + nodeHashInsert(pRtree, pNode); + } } } return rc; @@ -216771,7 +220774,17 @@ static void rtreeRelease(Rtree *pRtree){ pRtree->inWrTrans = 0; assert( pRtree->nCursor==0 ); nodeBlobReset(pRtree); - assert( pRtree->nNodeRef==0 || pRtree->bCorrupt ); + if( pRtree->nNodeRef ){ + int i; + assert( pRtree->bCorrupt ); + for(i=0; iaHash[i] ){ + RtreeNode *pNext = pRtree->aHash[i]->pNext; + sqlite3_free(pRtree->aHash[i]); + pRtree->aHash[i] = pNext; + } + } + } sqlite3_finalize(pRtree->pWriteNode); sqlite3_finalize(pRtree->pDeleteNode); sqlite3_finalize(pRtree->pReadRowid); @@ -217126,7 +221139,7 @@ static int nodeRowidIndex( ){ int ii; int nCell = NCELL(pNode); - assert( nCell<200 ); + assert( nCell<65536 && nCell>=0 ); for(ii=0; iiRTREE_MAXCELLS ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); while( p->iCell100) ){ + if( cnt>100 ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } @@ -218421,15 +222437,6 @@ static int SplitNode( rc = updateMapping(pRtree, pCell->iRowid, pLeft, iHeight); } - if( rc==SQLITE_OK ){ - rc = nodeRelease(pRtree, pRight); - pRight = 0; - } - if( rc==SQLITE_OK ){ - rc = nodeRelease(pRtree, pLeft); - pLeft = 0; - } - splitnode_out: nodeRelease(pRtree, pRight); nodeRelease(pRtree, pLeft); @@ -218614,7 +222621,7 @@ static int rtreeInsertCell( rc = SplitNode(pRtree, pNode, pCell, iHeight); }else{ rc = AdjustTree(pRtree, pNode, pCell); - if( ALWAYS(rc==SQLITE_OK) ){ + if( rc==SQLITE_OK ){ if( iHeight==0 ){ rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); }else{ @@ -218753,12 +222760,6 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ return rc; } -/* -** Rounding constants for float->double conversion. -*/ -#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */ -#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */ - #if !defined(SQLITE_RTREE_INT_ONLY) /* ** Convert an sqlite3_value into an RtreeValue (presumably a float) @@ -218768,7 +222769,10 @@ static RtreeValue rtreeValueDown(sqlite3_value *v){ double d = sqlite3_value_double(v); float f = (float)d; if( f>d ){ - f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS)); + unsigned int x; + memcpy(&x, &f, 4); + x = (x & 0x80000000)!=0 ? x+1 : x-1; + memcpy(&f, &x, 4); } return f; } @@ -218776,12 +222780,40 @@ static RtreeValue rtreeValueUp(sqlite3_value *v){ double d = sqlite3_value_double(v); float f = (float)d; if( fcell.aCoord[ii+1].i ){ rc = rtreeConstraintError(pRtree, ii+1); goto constraint; @@ -219374,7 +223406,7 @@ static int rtreeInit( "Auxiliary rtree columns must be last" /* 4 */ }; - assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */ + assert( RTREE_MAX_AUX_COLUMN<256 ); if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){ *pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]); return SQLITE_ERROR; @@ -219497,12 +223529,14 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ int nData; int errCode; sqlite3_str *pOut; + i64 nDim64; UNUSED_PARAMETER(nArg); memset(&node, 0, sizeof(RtreeNode)); memset(&tree, 0, sizeof(Rtree)); - tree.nDim = (u8)sqlite3_value_int(apArg[0]); - if( tree.nDim<1 || tree.nDim>5 ) return; + nDim64 = sqlite3_value_int64(apArg[0]); + if( nDim64<1 || nDim64>5 ) return; + tree.nDim = (u8)nDim64; tree.nDim2 = tree.nDim*2; tree.nBytesPerCell = 8 + 8 * tree.nDim; node.zData = (u8 *)sqlite3_value_blob(apArg[1]); @@ -220242,7 +224276,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ /* The sqlite3AtoF() routine is much much faster than atof(), if it ** is available */ double r; - (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8); + (void)sqlite3AtoF((const char*)p->z, &r); *pVal = r; #else *pVal = (GeoCoord)atof((const char*)p->z); @@ -220300,7 +224334,7 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ break; } if( geopolySkipSpace(&s)==']' - && s.nVertex>=4 + && s.nVertex>=4 && s.nVertex<16777216 && s.a[0]==s.a[s.nVertex*2-2] && s.a[1]==s.a[s.nVertex*2-1] && (s.z++, geopolySkipSpace(&s)==0) @@ -220626,6 +224660,8 @@ static double geopolySine(double r){ ** ** Construct a simple, convex, regular polygon centered at X, Y ** with circumradius R and with N sides. +** +** Maximum N is 1000. Maximum R is 1.0e+300. */ static void geopolyRegularFunc( sqlite3_context *context, @@ -220635,12 +224671,12 @@ static void geopolyRegularFunc( double x = sqlite3_value_double(argv[0]); double y = sqlite3_value_double(argv[1]); double r = sqlite3_value_double(argv[2]); - int n = sqlite3_value_int(argv[3]); + i64 n = sqlite3_value_int64(argv[3]); int i; GeoPoly *p; (void)argc; - if( n<3 || r<=0.0 ) return; + if( n<3 || r<=0.0 || r>=1e300 ) return; if( n>1000 ) n = 1000; p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); if( p==0 ){ @@ -221293,6 +225329,11 @@ static int geopolyInit( int ii; (void)pAux; + if( argc>=RTREE_MAX_AUX_COLUMN+4 ){ + *pzErr = sqlite3_mprintf("Too many columns for a geopoly table"); + return SQLITE_ERROR; + } + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); @@ -221900,6 +225941,12 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){ if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0); } +#if defined(SQLITE_DEBUG) && !defined(SQLITE_RTREE_INT_ONLY) + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "rtree_round", 2, utf8, 0, + rtreeRoundFunc, 0, 0); + } +#endif /* SQLITE_DEBUG && !SQLITE_RTREE_INT_ONLY */ if( rc==SQLITE_OK ){ #ifdef SQLITE_RTREE_INT_ONLY void *c = (void *)RTREE_COORD_INT32; @@ -222170,6 +226217,9 @@ static const unsigned char icuUtf8Trans1[] = { while( (*zIn & 0xc0)==0x80 ){ \ c = (c<<6) + (0x3f & *(zIn++)); \ } \ + if( c<0x80 \ + || (c&0xFFFFF800)==0xD800 \ + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ } #define SQLITE_ICU_SKIP_UTF8(zIn) \ @@ -222427,7 +226477,7 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ const UChar *zInput; /* Pointer to input string */ UChar *zOutput = 0; /* Pointer to output buffer */ int nInput; /* Size of utf-16 input string in bytes */ - int nOut; /* Size of output buffer in bytes */ + sqlite3_int64 nOut; /* Size of output buffer in bytes */ int cnt; int bToUpper; /* True for toupper(), false for tolower() */ UErrorCode status; @@ -222450,7 +226500,7 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ } for(cnt=0; cnt<2; cnt++){ - UChar *zNew = sqlite3_realloc(zOutput, nOut); + UChar *zNew = sqlite3_realloc64(zOutput, nOut); if( zNew==0 ){ sqlite3_free(zOutput); sqlite3_result_error_nomem(p); @@ -222459,9 +226509,9 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ zOutput = zNew; status = U_ZERO_ERROR; if( bToUpper ){ - nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + nOut = 2LL*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); }else{ - nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + nOut = 2LL*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); } if( U_SUCCESS(status) ){ @@ -222581,6 +226631,7 @@ static void icuLoadCollation( } sqlite3_result_error(p, sqlite3_str_value(pStr), -1); sqlite3_free(sqlite3_str_finish(pStr)); + ucol_close(pUCollator); return; } } @@ -224074,16 +228125,26 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36, -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; unsigned int v = 0; int c; unsigned char *z = (unsigned char*)*pz; - unsigned char *zStart = z; - while( (c = zValue[0x7f&*(z++)])>=0 ){ - v = (v<<6) + c; + unsigned char *zEnd = z + (*pLen); + while( z=0 ){ + v = (v<<6) + c; + z++; } - z--; - *pLen -= (int)(z - zStart); + + *pLen -= (int)(z - (unsigned char*)*pz); *pz = (char*)z; return v; } @@ -224152,21 +228213,22 @@ static int rbuDeltaApply( int lenDelta, /* Length of the delta */ char *zOut /* Write the output into this preallocated buffer */ ){ - unsigned int limit; - unsigned int total = 0; + sqlite3_uint64 limit; + sqlite3_uint64 total = 0; #if RBU_ENABLE_DELTA_CKSUM char *zOrigOut = zOut; #endif limit = rbuDeltaGetInt(&zDelta, &lenDelta); - if( *zDelta!='\n' ){ + if( lenDelta<=0 || *zDelta!='\n' ){ /* ERROR: size integer not terminated by "\n" */ return -1; } - zDelta++; lenDelta--; - while( *zDelta && lenDelta>0 ){ + zDelta++; lenDelta--; /* Skip the \n */ + while( lenDelta>0 && zDelta[0] ){ unsigned int cnt, ofst; cnt = rbuDeltaGetInt(&zDelta, &lenDelta); + if( lenDelta<=0 ) return -1; switch( zDelta[0] ){ case '@': { zDelta++; lenDelta--; @@ -224181,7 +228243,7 @@ static int rbuDeltaApply( /* ERROR: copy exceeds output file size */ return -1; } - if( (int)(ofst+cnt) > lenSrc ){ + if( (u64)ofst+(u64)cnt > (u64)lenSrc ){ /* ERROR: copy extends past end of input */ return -1; } @@ -224196,7 +228258,7 @@ static int rbuDeltaApply( /* ERROR: insert command gives an output larger than predicted */ return -1; } - if( (int)cnt>lenDelta ){ + if( cnt>lenDelta ){ /* ERROR: insert count exceeds size of delta */ return -1; } @@ -224234,7 +228296,7 @@ static int rbuDeltaApply( static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){ int size; size = rbuDeltaGetInt(&zDelta, &lenDelta); - if( *zDelta!='\n' ){ + if( lenDelta<=0 || *zDelta!='\n' ){ /* ERROR: size integer not terminated by "\n" */ return -1; } @@ -224282,7 +228344,7 @@ static void rbuFossilDeltaFunc( return; } - aOut = sqlite3_malloc(nOut+1); + aOut = sqlite3_malloc64((i64)nOut+1); if( aOut==0 ){ sqlite3_result_error_nomem(context); }else{ @@ -224965,15 +229027,27 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ /* Check that all non-HIDDEN columns in the destination table are also ** present in the input table. Populate the abTblPk[], azTblType[] and - ** aiTblOrder[] arrays at the same time. */ + ** aiTblOrder[] arrays at the same time. + ** + ** RBU does not support tables with GENERATED columns. If the target + ** table has any, return an error. */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, - sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl) + sqlite3_mprintf("PRAGMA table_xinfo(%Q)", pIter->zTbl) ); } while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zName = (const char*)sqlite3_column_text(pStmt, 1); - if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */ + int eHidden = sqlite3_column_int(pStmt, 6); + if( zName==0 ) break; /* An OOM. Bail out */ + if( eHidden==1 ) continue; /* Hidden column. Ignore */ + if( eHidden!=0 ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf( + "generated columns not supported: %s.%s", pIter->zTbl, zName + ); + break; + } for(i=iOrder; inTblCol; i++){ if( 0==strcmp(zName, pIter->azTblCol[i]) ) break; } @@ -225826,9 +229900,9 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ char c = zSql[i]; /* If necessary, grow the pIter->aIdxCol[] array */ - if( iIdxCol==nIdxAlloc ){ - RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc( - pIter->aIdxCol, (nIdxAlloc+16)*sizeof(RbuSpan) + if( iIdxCol>=(nIdxAlloc-1) ){ + RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc64( + pIter->aIdxCol, nIdxAlloc*sizeof(RbuSpan) + 16*sizeof(RbuSpan) ); if( aIdxCol==0 ){ rc = SQLITE_NOMEM; @@ -226209,13 +230283,13 @@ static int rbuGetUpdateStmt( char *zUpdate = 0; pUp->zMask = (char*)&pUp[1]; - memcpy(pUp->zMask, zMask, pIter->nTblCol); pUp->pNext = pIter->pRbuUpdate; pIter->pRbuUpdate = pUp; if( zSet ){ const char *zPrefix = ""; - + assert( p->rc==SQLITE_OK ); + memcpy(pUp->zMask, zMask, pIter->nTblCol); if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_"; zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", zPrefix, pIter->zTbl, zSet, zWhere @@ -226305,6 +230379,9 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ case RBU_STATE_ROW: pRet->nRow = sqlite3_column_int(pStmt, 1); + if( pRet->nRow<0 ){ + rc = SQLITE_CORRUPT; + } break; case RBU_STATE_PROGRESS: @@ -227213,7 +231290,12 @@ static void rbuCreateTargetSchema(sqlite3rbu *p){ while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ const char *zSql = (const char*)sqlite3_column_text(pSql, 0); - p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg); + sqlite3_stmt *pStmt = 0; + p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, zSql); + if( p->rc==SQLITE_OK ){ + sqlite3_step(pStmt); + rbuFinalize(p, pStmt); + } } rbuFinalize(p, pSql); if( p->rc!=SQLITE_OK ) return; @@ -229620,12 +233702,14 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ while( p->iCellnCell ){ StatCell *pCell = &p->aCell[p->iCell]; while( pCell->iOvflnOvfl ){ - int nUsable, iOvfl; + int nUsable; + int iOvfl = pCell->iOvfl; sqlite3BtreeEnter(pBt); nUsable = sqlite3BtreeGetPageSize(pBt) - sqlite3BtreeGetReserveNoMutex(pBt); sqlite3BtreeLeave(pBt); pCsr->nPage++; + pCsr->iPageno = pCell->aOvfl[iOvfl]; statSizeAndOffset(pCsr); if( pCell->iOvflnOvfl-1 ){ pCsr->nPayload += nUsable - 4; @@ -229633,11 +233717,9 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ pCsr->nPayload += pCell->nLastOvfl; pCsr->nUnused += nUsable - 4 - pCell->nLastOvfl; } - iOvfl = pCell->iOvfl; pCell->iOvfl++; if( !pCsr->isAgg ){ pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); - pCsr->iPageno = pCell->aOvfl[iOvfl]; pCsr->zPagetype = "overflow"; pCsr->zPath = z = sqlite3_mprintf( "%s%.3x+%.6x", p->zPath, p->iCell, iOvfl @@ -230176,12 +234258,13 @@ static int dbpageFilter( pCsr->szPage = sqlite3BtreeGetPageSize(pBt); pCsr->mxPgno = sqlite3BtreeLastPage(pBt); if( idxNum & 1 ){ + i64 iPg = sqlite3_value_int64(argv[idxNum>>1]); assert( argc>(idxNum>>1) ); - pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]); - if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){ + if( iPg<1 || iPg>pCsr->mxPgno ){ pCsr->pgno = 1; pCsr->mxPgno = 0; }else{ + pCsr->pgno = (Pgno)iPg; pCsr->mxPgno = pCsr->pgno; } }else{ @@ -230261,6 +234344,7 @@ static int dbpageUpdate( ){ DbpageTable *pTab = (DbpageTable *)pVtab; Pgno pgno; + sqlite3_int64 pgno64; DbPage *pDbPage = 0; int rc = SQLITE_OK; char *zErr = 0; @@ -230280,11 +234364,11 @@ static int dbpageUpdate( goto update_fail; } if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ - pgno = (Pgno)sqlite3_value_int64(argv[2]); + pgno64 = sqlite3_value_int64(argv[2]); isInsert = 1; }else{ - pgno = (Pgno)sqlite3_value_int64(argv[0]); - if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ + pgno64 = (Pgno)sqlite3_value_int64(argv[0]); + if( sqlite3_value_int64(argv[1])!=pgno64 ){ zErr = "cannot insert"; goto update_fail; } @@ -230301,10 +234385,11 @@ static int dbpageUpdate( } } pBt = pTab->db->aDb[iDb].pBt; - if( pgno<1 || NEVER(pBt==0) ){ + if( pgno64<1 || pgno64>4294967294U || NEVER(pBt==0) ){ zErr = "bad page number"; goto update_fail; } + pgno = (Pgno)pgno64; szPage = sqlite3BtreeGetPageSize(pBt); if( sqlite3_value_type(argv[3])!=SQLITE_BLOB || sqlite3_value_bytes(argv[3])!=szPage @@ -230501,6 +234586,7 @@ struct carray_bind { int nData; /* Number of elements */ int mFlags; /* Control flags */ void (*xDel)(void*); /* Destructor for aData */ + void *pDel; /* Alternative argument to xDel() */ }; @@ -230637,8 +234723,14 @@ static int carrayColumn( default: { const struct iovec *p = (struct iovec*)pCur->pPtr; assert( pCur->eType==CARRAY_BLOB ); - sqlite3_result_blob(ctx, p[pCur->iRowid-1].iov_base, - (int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT); + p += pCur->iRowid-1; + if( p->iov_len>0x7fffffff ){ + sqlite3_result_error_toobig(ctx); + return SQLITE_TOOBIG; + }else{ + sqlite3_result_blob(ctx, p->iov_base, (int)p->iov_len, + SQLITE_TRANSIENT); + } return SQLITE_OK; } } @@ -230833,7 +234925,7 @@ static sqlite3_module carrayModule = { static void carrayBindDel(void *pPtr){ carray_bind *p = (carray_bind*)pPtr; if( p->xDel!=SQLITE_STATIC ){ - p->xDel(p->aData); + p->xDel(p->pDel); } sqlite3_free(p); } @@ -230841,14 +234933,26 @@ static void carrayBindDel(void *pPtr){ /* ** Invoke this interface in order to bind to the single-argument ** version of CARRAY(). +** +** pStmt The prepared statement to which to bind +** idx The index of the parameter of pStmt to which to bind +** aData The data to be bound +** nData The number of elements in aData +** mFlags One of SQLITE_CARRAY_xxxx indicating datatype of aData +** xDestroy Destructor for pDestroy or aData if pDestroy==NULL. +** pDestroy Invoke xDestroy on this pointer if not NULL +** +** The destructor is called pDestroy if pDestroy!=NULL, or against +** aData if pDestroy==NULL. */ -SQLITE_API int sqlite3_carray_bind( +SQLITE_API int sqlite3_carray_bind_v2( sqlite3_stmt *pStmt, int idx, void *aData, int nData, int mFlags, - void (*xDestroy)(void*) + void (*xDestroy)(void*), + void *pDestroy ){ carray_bind *pNew = 0; int i; @@ -230925,20 +235029,38 @@ SQLITE_API int sqlite3_carray_bind( memcpy(pNew->aData, aData, sz); } pNew->xDel = sqlite3_free; + pNew->pDel = pNew->aData; }else{ pNew->aData = aData; pNew->xDel = xDestroy; + pNew->pDel = pDestroy; } return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel); carray_bind_error: if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){ - xDestroy(aData); + xDestroy(pDestroy); } sqlite3_free(pNew); return rc; } +/* +** Invoke this interface in order to bind to the single-argument +** version of CARRAY(). Same as sqlite3_carray_bind_v2() with the +** pDestroy parameter set to NULL. +*/ +SQLITE_API int sqlite3_carray_bind( + sqlite3_stmt *pStmt, + int idx, + void *aData, + int nData, + int mFlags, + void (*xDestroy)(void*) +){ + return sqlite3_carray_bind_v2(pStmt,idx,aData,nData,mFlags,xDestroy,aData); +} + /* ** Invoke this routine to register the carray() function. */ @@ -231298,7 +235420,24 @@ static int sessionVarintLen(int iVal){ ** bytes read. */ static int sessionVarintGet(const u8 *aBuf, int *piVal){ - return getVarint32(aBuf, *piVal); + int ret = getVarint32(aBuf, *piVal); + *piVal = (*piVal & 0x7FFFFFFF); + return ret; +} + +/* +** Read a varint value from buffer aBuf[], size nBuf bytes, into *piVal. +** Return the number of bytes read. +*/ +static int sessionVarintGetSafe(const u8 *aBuf, int nBuf, int *piVal){ + u8 aCopy[9]; + const u8 *aRead = aBuf; + memset(aCopy, 0, sizeof(aCopy)); + if( nBuf> 0) & 0xFF; } +/* +** Write a double value to the buffer aBuf[]. +*/ +static void sessionPutDouble(u8 *aBuf, double r){ + /* TODO: SQLite does something special to deal with mixed-endian + ** floating point values (e.g. ARM7). This code probably should + ** too. */ + u64 i; + assert( sizeof(double)==8 && sizeof(u64)==8 ); + memcpy(&i, &r, 8); + sessionPutI64(aBuf, i); +} + /* ** This function is used to serialize the contents of value pValue (see ** comment titled "RECORD FORMAT" above). @@ -231366,16 +235518,13 @@ static int sessionSerializeValue( /* TODO: SQLite does something special to deal with mixed-endian ** floating point values (e.g. ARM7). This code probably should ** too. */ - u64 i; if( eType==SQLITE_INTEGER ){ - i = (u64)sqlite3_value_int64(pValue); + u64 i = (u64)sqlite3_value_int64(pValue); + sessionPutI64(&aBuf[1], i); }else{ - double r; - assert( sizeof(double)==8 && sizeof(u64)==8 ); - r = sqlite3_value_double(pValue); - memcpy(&i, &r, 8); + double r = sqlite3_value_double(pValue); + sessionPutDouble(&aBuf[1], r); } - sessionPutI64(&aBuf[1], i); } nByte = 9; break; @@ -231565,10 +235714,11 @@ static int sessionSerialLen(const u8 *a){ int n; assert( a!=0 ); e = *a; - if( e==0 || e==0xFF ) return 1; - if( e==SQLITE_NULL ) return 1; if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; - return sessionVarintGet(&a[1], &n) + 1 + n; + if( e==SQLITE_TEXT || e==SQLITE_BLOB ){ + return sessionVarintGet(&a[1], &n) + 1 + n; + } + return 1; } /* @@ -231591,31 +235741,31 @@ static unsigned int sessionChangeHash( u8 *a = aRecord; /* Used to iterate through change record */ for(i=0; inCol; i++){ - int eType = *a; int isPK = pTab->abPK[i]; if( bPkOnly && isPK==0 ) continue; - /* It is not possible for eType to be SQLITE_NULL here. The session - ** module does not record changes for rows with NULL values stored in - ** primary key columns. */ - assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT - || eType==SQLITE_TEXT || eType==SQLITE_BLOB - || eType==SQLITE_NULL || eType==0 - ); - assert( !isPK || (eType!=0 && eType!=SQLITE_NULL) ); - if( isPK ){ - a++; + int eType = *a++; + + assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT + || eType==SQLITE_TEXT || eType==SQLITE_BLOB + || eType==SQLITE_NULL || eType==0 + ); + h = sessionHashAppendType(h, eType); if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ h = sessionHashAppendI64(h, sessionGetI64(a)); a += 8; - }else{ + }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ int n; a += sessionVarintGet(a, &n); h = sessionHashAppendBlob(h, n, a); a += n; } + /* It should not be possible for eType to be SQLITE_NULL or 0x00 here, + ** as the session module does not record changes for rows with NULL + ** values stored in primary key columns. But a corrupt changesets + ** may contain such a value. */ }else{ a += sessionSerialLen(a); } @@ -232307,9 +236457,7 @@ static void sessionUpdateOneChange( case SQLITE_FLOAT: { double rVal = sqlite3_column_double(pDflt, iField); - i64 iVal = 0; - memcpy(&iVal, &rVal, sizeof(rVal)); - sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); + sessionPutDouble(&pNew->aRecord[pNew->nRecord], rVal); pNew->nRecord += 8; break; } @@ -232405,7 +236553,7 @@ static void sessionAppendStr( int *pRc ){ int nStr = sqlite3Strlen30(zStr); - if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ + if( 0==sessionBufferGrow(p, (i64)nStr+1, pRc) ){ memcpy(&p->aBuf[p->nBuf], zStr, nStr); p->nBuf += nStr; p->aBuf[p->nBuf] = 0x00; @@ -232473,6 +236621,16 @@ static int sessionPrepareDfltStmt( return rc; } +/* +** Finalize statement pStmt. If (*pRc) is SQLITE_OK when this function is +** called, set it to the results of the sqlite3_finalize() call. Or, if +** it is already set to an error code, leave it as is. +*/ +static void sessionFinalizeStmt(sqlite3_stmt *pStmt, int *pRc){ + int rc = sqlite3_finalize(pStmt); + if( *pRc==SQLITE_OK ) *pRc = rc; +} + /* ** Table pTab has one or more existing change-records with old.* records ** with fewer than pTab->nCol columns. This function updates all such @@ -232495,9 +236653,8 @@ static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){ } } + sessionFinalizeStmt(pStmt, &rc); pSession->rc = rc; - rc = sqlite3_finalize(pStmt); - if( pSession->rc==SQLITE_OK ) pSession->rc = rc; return pSession->rc; } @@ -233065,7 +237222,7 @@ static int sessionDiffFindNew( rc = SQLITE_NOMEM; }else{ sqlite3_stmt *pStmt; - rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(pSession->db, zStmt, -1, &pStmt, 0); if( rc==SQLITE_OK ){ SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; pDiffCtx->pStmt = pStmt; @@ -233128,7 +237285,7 @@ static int sessionDiffFindModified( rc = SQLITE_NOMEM; }else{ sqlite3_stmt *pStmt; - rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(pSession->db, zStmt, -1, &pStmt, 0); if( rc==SQLITE_OK ){ SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; @@ -233566,15 +237723,14 @@ static void sessionAppendCol( int eType = sqlite3_column_type(pStmt, iCol); sessionAppendByte(p, (u8)eType, pRc); if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - sqlite3_int64 i; u8 aBuf[8]; if( eType==SQLITE_INTEGER ){ - i = sqlite3_column_int64(pStmt, iCol); + sqlite3_int64 i = sqlite3_column_int64(pStmt, iCol); + sessionPutI64(aBuf, i); }else{ double r = sqlite3_column_double(pStmt, iCol); - memcpy(&i, &r, 8); + sessionPutDouble(aBuf, r); } - sessionPutI64(aBuf, i); sessionAppendBlob(p, aBuf, 8, pRc); } if( eType==SQLITE_BLOB || eType==SQLITE_TEXT ){ @@ -233780,6 +237936,33 @@ static int sessionPrepare( return rc; } +/* +** Prepare the statement specified by printf format zFmt and its trailing +** arguments. +*/ +static void sessionPrepareMprintf( + int *pRc, + sqlite3 *db, + sqlite3_stmt **pp, + char **pzErrmsg, + const char *zFmt, + ... +){ + if( *pRc==SQLITE_OK ){ + char *zSql; + va_list ap; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( zSql==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + *pRc = sessionPrepare(db, pp, pzErrmsg, zSql); + sqlite3_free(zSql); + } + va_end(ap); + } +} + /* ** Formulate and prepare a SELECT statement to retrieve a row from table ** zTab in database zDb based on its primary key. i.e. @@ -233824,11 +238007,11 @@ static int sessionSelectStmt( ); sessionAppendStr(&cols, "tbl, ?2, stat", &rc); }else{ - #if 0 +#if 0 if( bRowid ){ sessionAppendStr(&cols, SESSIONS_ROWID, &rc); } - #endif +#endif for(i=0; irc ) return pSession->rc; - rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); - if( rc!=SQLITE_OK ) return rc; sqlite3_mutex_enter(sqlite3_db_mutex(db)); + rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); + if( rc!=SQLITE_OK ){ + sqlite3_mutex_leave(sqlite3_db_mutex(db)); + return rc; + } for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ @@ -234510,7 +238696,8 @@ static int sessionReadRecord( u8 *aVal = &pIn->aData[pIn->iNext]; if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ int nByte; - pIn->iNext += sessionVarintGet(aVal, &nByte); + int nRem = pIn->nData - pIn->iNext; + pIn->iNext += sessionVarintGetSafe(aVal, nRem, &nByte); rc = sessionInputBuffer(pIn, nByte); if( rc==SQLITE_OK ){ if( nByte<0 || nByte>pIn->nData-pIn->iNext ){ @@ -234563,7 +238750,8 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ rc = sessionInputBuffer(pIn, 9); if( rc==SQLITE_OK ){ - nRead += sessionVarintGet(&pIn->aData[pIn->iNext + nRead], &nCol); + int nBuf = pIn->nData - pIn->iNext; + nRead += sessionVarintGetSafe(&pIn->aData[pIn->iNext], nBuf, &nCol); /* The hard upper limit for the number of columns in an SQLite ** database table is, according to sqliteLimit.h, 32676. So ** consider any table-header that purports to have more than 65536 @@ -234583,8 +238771,15 @@ static int sessionChangesetBufferTblhdr(SessionInput *pIn, int *pnByte){ while( (pIn->iNext + nRead)nData && pIn->aData[pIn->iNext + nRead] ){ nRead++; } + + /* Break out of the loop if if the nul-terminator byte has been found. + ** Otherwise, read some more input data and keep seeking. If there is + ** no more input data, consider the changeset corrupt. */ if( (pIn->iNext + nRead)nData ) break; rc = sessionInputBuffer(pIn, nRead + 100); + if( rc==SQLITE_OK && (pIn->iNext + nRead)>=pIn->nData ){ + rc = SQLITE_CORRUPT_BKPT; + } } *pnByte = nRead+1; return rc; @@ -234605,22 +238800,32 @@ static int sessionChangesetBufferRecord( int *pnByte /* OUT: Size of record in bytes */ ){ int rc = SQLITE_OK; - int nByte = 0; + i64 nByte = 0; int i; for(i=0; rc==SQLITE_OK && iaData[pIn->iNext + nByte++]; - if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ - int n; - nByte += sessionVarintGet(&pIn->aData[pIn->iNext+nByte], &n); - nByte += n; - rc = sessionInputBuffer(pIn, nByte); - }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - nByte += 8; + if( pIn->iNext+nByte>=pIn->nData ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + eType = pIn->aData[pIn->iNext + nByte++]; + if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + int n; + int nRem = pIn->nData - (pIn->iNext + nByte); + nByte += sessionVarintGetSafe(&pIn->aData[pIn->iNext+nByte], nRem,&n); + nByte += n; + rc = sessionInputBuffer(pIn, nByte); + }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + nByte += 8; + }else if( eType!=0 && eType!=SQLITE_NULL ){ + rc = SQLITE_CORRUPT_BKPT; + } } } + if( rc==SQLITE_OK && (pIn->iNext+nByte)>pIn->nData ){ + rc = SQLITE_CORRUPT_BKPT; + } } *pnByte = nByte; return rc; @@ -234716,10 +238921,10 @@ static int sessionChangesetNextOne( memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); } - /* Make sure the buffer contains at least 10 bytes of input data, or all - ** remaining data if there are less than 10 bytes available. This is - ** sufficient either for the 'T' or 'P' byte and the varint that follows - ** it, or for the two single byte values otherwise. */ + /* Make sure the buffer contains at least 2 bytes of input data, or all + ** remaining data if there are less than 2 bytes available. This is + ** sufficient either for the 'T' or 'P' byte that begins a new table, + ** or for the "op" and "bIndirect" single bytes otherwise. */ p->rc = sessionInputBuffer(&p->in, 2); if( p->rc!=SQLITE_OK ) return p->rc; @@ -234749,11 +238954,13 @@ static int sessionChangesetNextOne( return (p->rc = SQLITE_CORRUPT_BKPT); } - p->op = op; - p->bIndirect = p->in.aData[p->in.iNext++]; - if( p->op!=SQLITE_UPDATE && p->op!=SQLITE_DELETE && p->op!=SQLITE_INSERT ){ + if( (op!=SQLITE_UPDATE && op!=SQLITE_DELETE && op!=SQLITE_INSERT) + || (p->in.iNext>=p->in.nData) + ){ return (p->rc = SQLITE_CORRUPT_BKPT); } + p->op = op; + p->bIndirect = p->in.aData[p->in.iNext++]; if( paRec ){ int nVal; /* Number of values to buffer */ @@ -235062,7 +239269,13 @@ static int sessionChangesetInvert( /* Test for EOF. */ if( (rc = sessionInputBuffer(pInput, 2)) ) goto finished_invert; - if( pInput->iNext>=pInput->nData ) break; + if( pInput->iNext+1>=pInput->nData ){ + if( pInput->iNext!=pInput->nData ){ + rc = SQLITE_CORRUPT_BKPT; + goto finished_invert; + } + break; + } eType = pInput->aData[pInput->iNext]; switch( eType ){ @@ -235258,6 +239471,7 @@ struct SessionApplyCtx { u8 bRebaseStarted; /* If table header is already in rebase */ u8 bRebase; /* True to collect rebase information */ u8 bIgnoreNoop; /* True to ignore no-op conflicts */ + u8 bNoUpdateLoop; /* No update-loop processing */ int bRowid; char *zErr; /* Error message, if any */ }; @@ -235831,7 +240045,7 @@ static int sessionConflictHandler( u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent]; int nBlob = pIter->in.iNext - pIter->in.iCurrent; sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc); - return SQLITE_OK; + return rc; }else if( p->bIgnoreNoop==0 || op!=SQLITE_DELETE || eType==SQLITE_CHANGESET_CONFLICT ){ @@ -235953,7 +240167,7 @@ static int sessionApplyOneOp( for(i=0; rc==SQLITE_OK && iabPK[i] || (bPatchset==0 && pOld) ){ + if( pOld && (p->abPK[i] || bPatchset==0) ){ rc = sessionBindValue(pUp, i*2+2, pOld); } if( rc==SQLITE_OK && pNew ){ @@ -236079,7 +240293,321 @@ static int sessionApplyOneWithRetry( } /* -** Retry the changes accumulated in the pApply->constraints buffer. +** Create an iterator to iterate through the retry buffer pRetry. +*/ +static int sessionRetryIterInit( + SessionBuffer *pRetry, /* Buffer to iterate through */ + int bPatchset, /* True for patchset, false for changeset */ + const char *zTab, /* Table name */ + SessionApplyCtx *pApply, /* Session apply context */ + sqlite3_changeset_iter **ppIter /* OUT: New iterator */ +){ + sqlite3_changeset_iter *pRet = 0; + int rc = SQLITE_OK; + + rc = sessionChangesetStart( + &pRet, 0, 0, pRetry->nBuf, pRetry->aBuf, pApply->bInvertConstraints, 1 + ); + if( rc==SQLITE_OK ){ + size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); + pRet->bPatchset = bPatchset; + pRet->zTab = (char*)zTab; + pRet->nCol = pApply->nCol; + pRet->abPK = pApply->abPK; + sessionBufferGrow(&pRet->tblhdr, nByte, &rc); + pRet->apValue = (sqlite3_value**)pRet->tblhdr.aBuf; + if( rc==SQLITE_OK ){ + memset(pRet->apValue, 0, nByte); + }else{ + sqlite3changeset_finalize(pRet); + pRet = 0; + } + } + + *ppIter = pRet; + return rc; +} + +/* +** Attempt to apply all the changes in retry buffer pRetry to the database. +** Except, if parameter iSkip is greater than or equal to 0, skip change +** iSkip. +*/ +static int sessionApplyRetryBuffer( + SessionBuffer *pRetry, /* Buffer to apply changes from */ + int iSkip, /* If >=0, index of change to omit */ + sqlite3 *db, /* Database handle */ + int bPatchset, /* True for patchset, false for changeset */ + const char *zTab, /* Name of table to write to */ + SessionApplyCtx *pApply, /* Apply context */ + int(*xConflict)(void*, int, sqlite3_changeset_iter*), + void *pCtx /* First argument passed to xConflict */ +){ + int rc = SQLITE_OK; + int rc2 = SQLITE_OK; + int ii = 0; + sqlite3_changeset_iter *pIter = 0; + + assert( pApply->constraints.nBuf==0 ); + + rc = sessionRetryIterInit(pRetry, bPatchset, zTab, pApply, &pIter); + + for(ii=0; rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter); ii++){ + if( ii!=iSkip ){ + rc = sessionApplyOneWithRetry(db, pIter, pApply, xConflict, pCtx); + } + } + + rc2 = sqlite3changeset_finalize(pIter); + if( rc==SQLITE_OK ) rc = rc2; + assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 ); + + return rc; +} + +/* +** Buffer aUnique[] is pApply->nCol entries in size. This function sets +** aUnique[i] to true if column i of table zTab in the "main" database +** of db is part of at least one UNIQUE constraint, or to false otherwise. +** +** If the table has a unique index on an expression, or a partial unique +** index, all entries of aUnique[] are set to true. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int sessionUniqueColumns( + sqlite3 *db, /* Database handle */ + const char *zTab, /* Table name */ + SessionApplyCtx *pApply, /* Apply context */ + u8 *aUnique /* OUT: Array of pApply->nCol flags */ +){ + sqlite3_stmt *pList = 0; /* PRAGMA index_list */ + int rc = SQLITE_OK; + + /* Ordinary PRAGMA statements are used here instead of the equivalent + ** table-valued functions (pragma_index_list() etc.) so that this works + ** in builds with SQLITE_OMIT_VIRTUALTABLE defined. */ + memset(aUnique, 0, pApply->nCol); + sessionPrepareMprintf(&rc, db, &pList, &pApply->zErr, + "PRAGMA main.index_list(%Q)", zTab + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ + /* Columns of PRAGMA index_list are (seq, name, unique, origin, partial) */ + const char *zIdx = (const char*)sqlite3_column_text(pList, 1); + int bUnique = sqlite3_column_int(pList, 2); + int bPartial = sqlite3_column_int(pList, 4); + sqlite3_stmt *pInfo = 0; /* PRAGMA index_xinfo */ + + if( bUnique==0 ) continue; + sessionPrepareMprintf(&rc, db, &pInfo, &pApply->zErr, + "PRAGMA main.index_xinfo(%Q)", zIdx + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pInfo) ){ + /* Columns of PRAGMA index_xinfo are (seqno, cid, name, desc, coll, key)*/ + int iCid = sqlite3_column_int(pInfo, 1); + const char *zCol = (const char*)sqlite3_column_text(pInfo, 2); + int bKey = sqlite3_column_int(pInfo, 5); + int ii; + if( bKey==0 ) continue; + for(ii=0; iinCol; ii++){ + if( bPartial + || iCid==-2 + || (zCol && 0==sqlite3_stricmp(zCol, pApply->azCol[ii])) + ){ + aUnique[ii] = 1; + } + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3_finalize(pInfo); + }else{ + sqlite3_finalize(pInfo); + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3_finalize(pList); + }else{ + sqlite3_finalize(pList); + } + + return rc; +} + +/* +** Iterator pUp points to an UPDATE change. This function updates the +** affected row to set each column modified by the UPDATE change that +** is also part of at least one UNIQUE constraint to a "random" value, +** and creates another UPDATE statement that may be used to later set +** all columns modified by pUp to the actual values required by pUp. +** +** Each random value has the same type as the final value required by +** pUp for the same column: +** +** NULL -> NULL +** INTEGER -> random() +** REAL -> random() +** TEXT -> CAST(random() AS TEXT) +** BLOB -> unhex(hex(random())) +** +** If none of the columns modified by pUp are part of a UNIQUE constraint, +** then SQLITE_CONSTRAINT is returned. +** +** If successful, SQLITE_OK is returned and output variable (*ppUpdate) +** is left pointing to a prepared UPDATE statement. It is the responsibility +** of the caller to eventually free this statement using sqlite3_finalize(). +** Or, if an error occurs, an SQLite error code is returned and (*ppUpdate) +** set to NULL. pApply->zErr may be set to an error message in this case. +** Except - it is guaranteed that pApply->zErr is not set if SQLITE_CONSTRAINT +** is returned. +*/ +static int sessionUpdateToUpdate( + sqlite3 *db, /* Database to write to */ + const char *zTab, /* Table name */ + SessionApplyCtx *pApply, /* Apply context */ + sqlite3_changeset_iter *pUp, /* Iterator pointing to UPDATE change */ + sqlite3_stmt **ppUpdate /* OUT: UPDATE statement */ +){ + sqlite3_stmt *pRet = 0; /* UPDATE to set the final values */ + sqlite3_stmt *pRand = 0; /* UPDATE to set random values */ + int rc = SQLITE_OK; + u8 *aUnique = 0; /* aUnique[i] true if col i is UNIQUE */ + SessionBuffer randset = {0, 0, 0}; + SessionBuffer upset = {0, 0, 0}; + SessionBuffer where = {0, 0, 0}; + int ii; + + aUnique = (u8*)sqlite3_malloc64(pApply->nCol); + if( aUnique==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sessionUniqueColumns(db, zTab, pApply, aUnique); + } + + /* Assuming a table structure like this: + ** + ** CREATE TABLE x(a, b UNIQUE, c, d UNIQUE, e, PRIMARY KEY(a, c)); + ** + ** and an UPDATE change that sets column b to an integer, column d to + ** a text value and column e to any value, the two statements prepared + ** are: + ** + ** UPDATE main.x SET b = random(), d = CAST(random() AS TEXT) + ** WHERE a IS ?1 AND c IS ?3 + ** UPDATE main.x SET b = ?2, d = ?4, e = ?5 WHERE a IS ?1 AND c IS ?3 + */ + for(ii=0; rc==SQLITE_OK && iinCol; ii++){ + sqlite3_value *pNew = 0; + if( pApply->abPK[ii] ){ + if( where.nBuf>0 ) sessionAppendStr(&where, " AND ", &rc); + sessionAppendIdent(&where, pApply->azCol[ii], &rc); + sessionAppendPrintf(&where, &rc, " IS ?%d", ii+1); + }else if( (pNew = sessionChangesetNew(pUp, ii))!=0 ){ + if( aUnique[ii] ){ + const char *zRand = 0; + switch( sqlite3_value_type(pNew) ){ + case SQLITE_NULL: zRand = "NULL"; break; + case SQLITE_TEXT: zRand = "CAST(random() AS TEXT)"; break; + case SQLITE_BLOB: zRand = "unhex(hex(random()))"; break; + default: zRand = "random()"; break; + } + if( randset.nBuf>0 ) sessionAppendStr(&randset, ", ", &rc); + sessionAppendIdent(&randset, pApply->azCol[ii], &rc); + sessionAppendStr(&randset, " = ", &rc); + sessionAppendStr(&randset, zRand, &rc); + } + if( upset.nBuf>0 ) sessionAppendStr(&upset, ", ", &rc); + sessionAppendIdent(&upset, pApply->azCol[ii], &rc); + sessionAppendPrintf(&upset, &rc, " = ?%d", ii+1); + } + } + + if( rc==SQLITE_OK && randset.nBuf==0 ){ + /* None of the columns modified by this change are part of a UNIQUE + ** constraint. So setting them to random values cannot help resolve + ** a constraint conflict. Report this as a constraint failure. */ + rc = SQLITE_CONSTRAINT; + } + + sessionPrepareMprintf(&rc, db, &pRand, &pApply->zErr, + "UPDATE main.\"%w\" SET %s WHERE %s", + zTab, (char*)randset.aBuf, (char*)where.aBuf + ); + sessionPrepareMprintf(&rc, db, &pRet, &pApply->zErr, + "UPDATE main.\"%w\" SET %s WHERE %s", + zTab, (char*)upset.aBuf, (char*)where.aBuf + ); + + /* Bind the PK values to both statements, and the new.* values to pRet. */ + if( rc==SQLITE_OK ){ + rc = sessionBindRow( + pUp, sqlite3changeset_old, pApply->nCol, pApply->abPK, pRand + ); + } + if( rc==SQLITE_OK ){ + rc = sessionBindRow( + pUp, sqlite3changeset_old, pApply->nCol, pApply->abPK, pRet + ); + } + for(ii=0; rc==SQLITE_OK && iinCol; ii++){ + sqlite3_value *pNew = sessionChangesetNew(pUp, ii); + if( pApply->abPK[ii]==0 && pNew ){ + rc = sessionBindValue(pRet, ii+1, pNew); + } + } + + /* Evaluate the statement to set each modified column of the row to a random + ** value. If this fails with a constraint error, SQLITE_CONSTRAINT is + ** returned to the caller, but pApply->zErr is not set. */ + if( rc==SQLITE_OK ){ + sqlite3_step(pRand); + rc = sqlite3_reset(pRand); + } + sqlite3_finalize(pRand); + + if( rc!=SQLITE_OK ){ + sqlite3_finalize(pRet); + pRet = 0; + } + *ppUpdate = pRet; + + sqlite3_free(aUnique); + sqlite3_free(randset.aBuf); + sqlite3_free(upset.aBuf); + sqlite3_free(where.aBuf); + + return rc; +} + +/* +** Retry the changes accumulated in the pApply->constraints buffer. The +** pApply->constraints buffer contains all changes to table zTab that +** could not be applied due to SQLITE_CONSTRAINT errors. This function +** attempts to apply them as follows: +** +** 1) It runs through the buffer and attempts to retry each change, +** removing any that are successfully applied from the buffer. This +** is repeated until no further progress can be made. +** +** 2) For each UPDATE change in the buffer, try the following in a +** savepoint transaction: +** +** a) UPDATE the affected row, setting each column modified by the +** UPDATE change to a random value, +** b) Attempt step (1) with remaining changes, +** c) Attempt to UPDATE the affected row again, this time setting +** each modified column to the value required by the UPDATE change. +** +** If both (a) and (c) succeed, the savepoint is committed and all +** successfully applied changes are removed from the buffer. Step (2) +** is then repeated. Otherwise, if either (a) or (c) fails with +** SQLITE_CONSTRAINT, the savepoint is rolled back and the next UPDATE +** in the buffer is tried. +** +** 3) Once step (2) has been attempted for each UPDATE in the change, +** a final attempt is made to apply each remaining change. This time, +** if an SQLITE_CONSTRAINT error is encountered, the conflict handler +** is invoked and the user has to decide whether to omit the change +** or rollback the entire _apply() operation. */ static int sessionRetryConstraints( sqlite3 *db, @@ -236090,41 +240618,115 @@ static int sessionRetryConstraints( void *pCtx /* First argument passed to xConflict */ ){ int rc = SQLITE_OK; + int iUpdate = 0; + /* Step (1) */ while( pApply->constraints.nBuf ){ - sqlite3_changeset_iter *pIter2 = 0; SessionBuffer cons = pApply->constraints; memset(&pApply->constraints, 0, sizeof(SessionBuffer)); - rc = sessionChangesetStart( - &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1 + rc = sessionApplyRetryBuffer( + &cons, -1, db, bPatchset, zTab, pApply, xConflict, pCtx + ); + + sqlite3_free(cons.aBuf); + if( rc!=SQLITE_OK ) break; + + /* If no progress has been made this round, break out of the loop. */ + if( pApply->constraints.nBuf>=cons.nBuf ) break; + } + + /* Step (2) */ + while( rc==SQLITE_OK && pApply->constraints.nBuf && !pApply->bNoUpdateLoop ){ + SessionBuffer cons = {0, 0, 0}; + sqlite3_changeset_iter *pUp = 0; + sqlite3_stmt *pUpdate = 0; + int iSkip = 0; + int bConstraint = 0; /* True if an SQLITE_CONSTRAINT occurs */ + + rc = sessionRetryIterInit( + &pApply->constraints, bPatchset, zTab, pApply, &pUp ); if( rc==SQLITE_OK ){ - size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); - int rc2; - pIter2->bPatchset = bPatchset; - pIter2->zTab = (char*)zTab; - pIter2->nCol = pApply->nCol; - pIter2->abPK = pApply->abPK; - sessionBufferGrow(&pIter2->tblhdr, nByte, &rc); - pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf; - if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte); + int iThis = -1; + while( SQLITE_ROW==sqlite3changeset_next(pUp) ){ + if( pUp->op==SQLITE_UPDATE ) iThis++; + if( iThis==iUpdate ) break; + iSkip++; + } + if( iThis==iUpdate ){ + rc = sqlite3_exec(db, "SAVEPOINT update_op", 0, 0, 0); + if( rc==SQLITE_OK ){ + rc = sessionUpdateToUpdate(db, zTab, pApply, pUp, &pUpdate); + if( (rc&0xff)==SQLITE_CONSTRAINT ){ + bConstraint = 1; + rc = SQLITE_OK; + } + } + } + sqlite3changeset_finalize(pUp); + if( iThis!=iUpdate ) break; + } - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){ - rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx); + if( rc==SQLITE_OK ){ + cons = pApply->constraints; + if( bConstraint ){ + memset(&pApply->constraints, 0, sizeof(SessionBuffer)); } - rc2 = sqlite3changeset_finalize(pIter2); - if( rc==SQLITE_OK ) rc = rc2; + while( rc==SQLITE_OK && pApply->constraints.nBuf>0 ){ + SessionBuffer app = pApply->constraints; + memset(&pApply->constraints, 0, sizeof(SessionBuffer)); + rc = sessionApplyRetryBuffer( + &app, iSkip, db, bPatchset, zTab, pApply, xConflict, pCtx + ); + if( app.aBuf!=cons.aBuf ){ + sqlite3_free(app.aBuf); + } + if( pApply->constraints.nBuf>=app.nBuf ){ + break; + } + iSkip = -1; + } } - assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 ); - sqlite3_free(cons.aBuf); - if( rc!=SQLITE_OK ) break; - if( pApply->constraints.nBuf>=cons.nBuf ){ - /* No progress was made on the last round. */ - pApply->bDeferConstraints = 0; + iUpdate++; + if( rc==SQLITE_OK ){ + if( bConstraint==0 ){ + sqlite3_step(pUpdate); + rc = sqlite3_finalize(pUpdate); + pUpdate = 0; + if( (rc&0xff)==SQLITE_CONSTRAINT ){ + bConstraint = 1; + rc = SQLITE_OK; + } + } + if( bConstraint ){ + rc = sqlite3_exec(db, "ROLLBACK TO update_op", 0, 0, 0); + sqlite3_free(pApply->constraints.aBuf); + pApply->constraints = cons; + memset(&cons, 0, sizeof(cons)); + }else if( rc==SQLITE_OK ){ + iUpdate = 0; + } + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(db, "RELEASE update_op", 0, 0, 0); + } } + sqlite3_finalize(pUpdate); + + sqlite3_free(cons.aBuf); + } + + /* Step (3) */ + if( rc==SQLITE_OK && pApply->constraints.nBuf ){ + SessionBuffer cons = pApply->constraints; + memset(&pApply->constraints, 0, sizeof(SessionBuffer)); + pApply->bDeferConstraints = 0; + rc = sessionApplyRetryBuffer( + &cons, -1, db, bPatchset, zTab, pApply, xConflict, pCtx + ); + sqlite3_free(cons.aBuf); } return rc; @@ -236160,10 +240762,10 @@ static int sessionChangesetApply( int schemaMismatch = 0; int rc = SQLITE_OK; /* Return code */ const char *zTab = 0; /* Name of current table */ - int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ int bPatchset; u64 savedFlag = db->flags & SQLITE_FkNoAction; + int bNew = 0; /* True for first entry of new table */ assert( xConflict!=0 ); @@ -236178,21 +240780,23 @@ static int sessionChangesetApply( sApply.bRebase = (ppRebase && pnRebase); sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); + sApply.bNoUpdateLoop = !!(flags & SQLITE_CHANGESETAPPLY_NOUPDATELOOP); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); } - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ + while( rc==SQLITE_OK && SQLITE_ROW==sessionChangesetNext(pIter, 0, 0,&bNew) ){ int nCol; int op; const char *zNew; sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0); - if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){ + if( bNew ){ u8 *abPK; + bNew = 0; rc = sessionRetryConstraints( db, pIter->bPatchset, zTab, &sApply, xConflict, pCtx @@ -236227,7 +240831,6 @@ static int sessionChangesetApply( rc = SQLITE_NOMEM; break; } - nTab = (int)strlen(zTab); sApply.azCol = (const char **)zTab; }else{ int nMinCol = 0; @@ -236280,7 +240883,6 @@ static int sessionChangesetApply( sApply.bStat1 = 0; } } - nTab = sqlite3Strlen30(zTab); } } @@ -236601,6 +241203,21 @@ SQLITE_API int sqlite3changeset_apply_strm( ); } +/* +** The parts of the sqlite3_changegroup structure used by the +** sqlite3changegroup_change_xxx() APIs. +*/ +typedef struct ChangeData ChangeData; +struct ChangeData { + SessionTable *pTab; + int bIndirect; + int eOp; + + int nBufAlloc; + SessionBuffer *aBuf; + SessionBuffer record; +}; + /* ** sqlite3_changegroup handle. */ @@ -236612,12 +241229,17 @@ struct sqlite3_changegroup { sqlite3 *db; /* Configured by changegroup_schema() */ char *zDb; /* Configured by changegroup_schema() */ + ChangeData cd; /* Used by changegroup_change_xxx() APIs. */ }; /* ** This function is called to merge two changes to the same row together as ** part of an sqlite3changeset_concat() operation. A new change object is ** allocated and a pointer to it stored in *ppNew. +** +** Because they have been vetted by sqlite3changegroup_add() or similar, +** both the aRec[] change and the pExist change are safe to use without +** checking for buffer overflows. */ static int sessionChangeMerge( SessionTable *pTab, /* Table structure */ @@ -236758,7 +241380,7 @@ static int sessionChangeMerge( memcpy(aCsr, aRec, nRec); aCsr += nRec; }else{ - if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){ + if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist,0,aRec,0) ){ sqlite3_free(pNew); pNew = 0; } @@ -236851,15 +241473,14 @@ static int sessionChangesetExtendRecord( switch( eType ){ case SQLITE_FLOAT: case SQLITE_INTEGER: { - i64 iVal; - if( eType==SQLITE_INTEGER ){ - iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); - }else{ - double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii); - memcpy(&iVal, &rVal, sizeof(i64)); - } if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ - sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); + if( eType==SQLITE_INTEGER ){ + sqlite3_int64 iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); + sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); + }else{ + double rVal = sqlite3_column_double(pTab->pDfltStmt, ii); + sessionPutDouble(&pOut->aBuf[pOut->nBuf], rVal); + } pOut->nBuf += 8; } break; @@ -236930,13 +241551,19 @@ static int sessionChangesetFindTable( int nCol = 0; *ppTab = 0; - sqlite3changeset_pk(pIter, &abPK, &nCol); /* Search the list for an existing table */ for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ if( 0==sqlite3_strnicmp(pTab->zName, zTab, nTab+1) ) break; } + + if( pIter ){ + sqlite3changeset_pk(pIter, &abPK, &nCol); + }else if( !pTab && !pGrp->db ){ + return SQLITE_ERROR; + } + /* If one was not found above, create a new table now */ if( !pTab ){ SessionTable **ppNew; @@ -236948,17 +241575,19 @@ static int sessionChangesetFindTable( memset(pTab, 0, sizeof(SessionTable)); pTab->nCol = nCol; pTab->abPK = (u8*)&pTab[1]; - memcpy(pTab->abPK, abPK, nCol); + if( nCol>0 ){ + memcpy(pTab->abPK, abPK, nCol); + } pTab->zName = (char*)&pTab->abPK[nCol]; memcpy(pTab->zName, zTab, nTab+1); if( pGrp->db ){ pTab->nCol = 0; rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); - if( rc ){ - assert( pTab->azCol==0 ); + if( rc || pTab->nCol==0 ){ + sqlite3_free(pTab->azCol); sqlite3_free(pTab); - return rc; + return rc ? rc : SQLITE_ERROR; } } @@ -236971,7 +241600,7 @@ static int sessionChangesetFindTable( } /* Check that the table is compatible. */ - if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ + if( pIter && !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ rc = SQLITE_SCHEMA; } @@ -236980,44 +241609,27 @@ static int sessionChangesetFindTable( } /* -** Add the change currently indicated by iterator pIter to the hash table -** belonging to changegroup pGrp. +** Add a single change to the changegroup pGrp. */ static int sessionOneChangeToHash( - sqlite3_changegroup *pGrp, - sqlite3_changeset_iter *pIter, - int bRebase + sqlite3_changegroup *pGrp, /* Changegroup to update */ + SessionTable *pTab, /* Table change pertains to */ + int op, /* One of SQLITE_INSERT, UPDATE, DELETE */ + int bIndirect, /* True to flag change as "indirect" */ + int nCol, /* Number of columns in record(s) */ + u8 *aRec, /* Serialized change record(s) */ + int nRec, /* Size of aRec[] in bytes */ + int bRebase /* True if this is a rebase blob */ ){ int rc = SQLITE_OK; - int nCol = 0; - int op = 0; int iHash = 0; - int bIndirect = 0; SessionChange *pChange = 0; SessionChange *pExist = 0; SessionChange **pp = 0; - SessionTable *pTab = 0; - u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; - int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; assert( nRec>0 ); - /* Ensure that only changesets, or only patchsets, but not a mixture - ** of both, are being combined. It is an error to try to combine a - ** changeset and a patchset. */ - if( pGrp->pList==0 ){ - pGrp->bPatch = pIter->bPatchset; - }else if( pIter->bPatchset!=pGrp->bPatch ){ - rc = SQLITE_ERROR; - } - - if( rc==SQLITE_OK ){ - const char *zTab = 0; - sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); - rc = sessionChangesetFindTable(pGrp, zTab, pIter, &pTab); - } - - if( rc==SQLITE_OK && nColnCol ){ + if( nColnCol ){ SessionBuffer *pBuf = &pGrp->rec; rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, pBuf); aRec = pBuf->aBuf; @@ -237025,7 +241637,7 @@ static int sessionOneChangeToHash( assert( pGrp->db ); } - if( rc==SQLITE_OK && sessionGrowHash(0, pIter->bPatchset, pTab) ){ + if( rc==SQLITE_OK && sessionGrowHash(0, pGrp->bPatch, pTab) ){ rc = SQLITE_NOMEM; } @@ -237033,12 +241645,12 @@ static int sessionOneChangeToHash( /* Search for existing entry. If found, remove it from the hash table. ** Code below may link it back in. */ iHash = sessionChangeHash( - pTab, (pIter->bPatchset && op==SQLITE_DELETE), aRec, pTab->nChange + pTab, (pGrp->bPatch && op==SQLITE_DELETE), aRec, pTab->nChange ); for(pp=&pTab->apChange[iHash]; *pp; pp=&(*pp)->pNext){ int bPkOnly1 = 0; int bPkOnly2 = 0; - if( pIter->bPatchset ){ + if( pGrp->bPatch ){ bPkOnly1 = (*pp)->op==SQLITE_DELETE; bPkOnly2 = op==SQLITE_DELETE; } @@ -237053,7 +241665,7 @@ static int sessionOneChangeToHash( if( rc==SQLITE_OK ){ rc = sessionChangeMerge(pTab, bRebase, - pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange + pGrp->bPatch, pExist, op, bIndirect, aRec, nRec, &pChange ); } if( rc==SQLITE_OK && pChange ){ @@ -237062,6 +241674,47 @@ static int sessionOneChangeToHash( pTab->nEntry++; } + return rc; +} + +/* +** Add the change currently indicated by iterator pIter to the hash table +** belonging to changegroup pGrp. +*/ +static int sessionOneChangeIterToHash( + sqlite3_changegroup *pGrp, + sqlite3_changeset_iter *pIter, + int bRebase +){ + u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; + int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; + const char *zTab = 0; + int nCol = 0; + int op = 0; + int bIndirect = 0; + int rc = SQLITE_OK; + SessionTable *pTab = 0; + + /* Ensure that only changesets, or only patchsets, but not a mixture + ** of both, are being combined. It is an error to try to combine a + ** changeset and a patchset. */ + if( pGrp->pList==0 ){ + pGrp->bPatch = pIter->bPatchset; + }else if( pIter->bPatchset!=pGrp->bPatch ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_OK ){ + sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect); + rc = sessionChangesetFindTable(pGrp, zTab, pIter, &pTab); + } + + if( rc==SQLITE_OK ){ + rc = sessionOneChangeToHash( + pGrp, pTab, op, bIndirect, nCol, aRec, nRec, bRebase + ); + } + if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } @@ -237081,7 +241734,12 @@ static int sessionChangesetToHash( pIter->in.bNoDiscard = 1; while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ - rc = sessionOneChangeToHash(pGrp, pIter, bRebase); + if( bRebase && pIter->bPatchset ){ + /* A patchset may not be used as a rebase */ + rc = SQLITE_ERROR; + }else{ + rc = sessionOneChangeIterToHash(pGrp, pIter, bRebase); + } if( rc!=SQLITE_OK ) break; } @@ -237171,6 +241829,33 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){ return rc; } +/* +** Configure a changegroup object. +*/ +SQLITE_API int sqlite3changegroup_config( + sqlite3_changegroup *pGrp, + int op, + void *pArg +){ + int rc = SQLITE_OK; + + switch( op ){ + case SQLITE_CHANGEGROUP_CONFIG_PATCHSET: { + int arg = *(int*)pArg; + if( pGrp->pList==0 && arg>=0 ){ + pGrp->bPatch = (arg>0); + } + *(int*)pArg = pGrp->bPatch; + break; + } + default: + rc = SQLITE_MISUSE; + break; + } + + return rc; +} + /* ** Provide a database schema to the changegroup object. */ @@ -237229,7 +241914,7 @@ SQLITE_API int sqlite3changegroup_add_change( rc = SQLITE_ERROR; }else{ pIter->in.bNoDiscard = 1; - rc = sessionOneChangeToHash(pGrp, pIter, 0); + rc = sessionOneChangeIterToHash(pGrp, pIter, 0); } return rc; } @@ -237281,6 +241966,12 @@ SQLITE_API int sqlite3changegroup_output_strm( */ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ + int ii; + for(ii=0; iicd.nBufAlloc; ii++){ + sqlite3_free(pGrp->cd.aBuf[ii].aBuf); + } + sqlite3_free(pGrp->cd.record.aBuf); + sqlite3_free(pGrp->cd.aBuf); sqlite3_free(pGrp->zDb); sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp->rec.aBuf); @@ -237366,14 +242057,17 @@ static void sessionAppendRecordMerge( u8 *a2, int n2, /* Record 2 */ int *pRc /* IN/OUT: error code */ ){ - sessionBufferGrow(pBuf, n1+n2, pRc); + u8 *a1Eof = &a1[n1]; + u8 *a2Eof = &a2[n2]; + + sessionBufferGrow(pBuf, (i64)n1+n2, pRc); if( *pRc==SQLITE_OK ){ int i; u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; for(i=0; i0 && (*a1==0 || *a1==0xFF)) ){ memcpy(pOut, a2, nn2); pOut += nn2; }else{ @@ -237415,20 +242109,21 @@ static void sessionAppendPartialUpdate( u8 *aChange, int nChange, /* Record to rebase against */ int *pRc /* IN/OUT: Return Code */ ){ - sessionBufferGrow(pBuf, 2+nRec+nChange, pRc); + sessionBufferGrow(pBuf, (i64)2+nRec+nChange, pRc); if( *pRc==SQLITE_OK ){ int bData = 0; u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; int i; u8 *a1 = aRec; u8 *a2 = aChange; + u8 *a2Eof = &a2[nChange]; *pOut++ = SQLITE_UPDATE; *pOut++ = pIter->bIndirect; for(i=0; inCol; i++){ int n1 = sessionSerialLen(a1); - int n2 = sessionSerialLen(a2); - if( pIter->abPK[i] || a2[0]==0 ){ + int n2 = (a2>=a2Eof) ? 0 : sessionSerialLen(a2); + if( n2<=0 || pIter->abPK[i] || a2[0]==0 ){ if( !pIter->abPK[i] && a1[0] ) bData = 1; memcpy(pOut, a1, n1); pOut += n1; @@ -237629,8 +242324,8 @@ SQLITE_API int sqlite3rebaser_configure( sqlite3_rebaser *p, int nRebase, const void *pRebase ){ - sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ int rc; /* Return code */ + sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase); if( rc==SQLITE_OK ){ rc = sessionChangesetToHash(pIter, &p->grp, 1); @@ -237711,6 +242406,330 @@ SQLITE_API int sqlite3session_config(int op, void *pArg){ return rc; } +/* +** Begin adding a change to a changegroup object. +*/ +SQLITE_API int sqlite3changegroup_change_begin( + sqlite3_changegroup *pGrp, + int eOp, + const char *zTab, + int bIndirect, + char **pzErr +){ + SessionTable *pTab = 0; + int rc = SQLITE_OK; + + if( pGrp->cd.pTab ){ + rc = SQLITE_MISUSE; + }else if( eOp!=SQLITE_INSERT && eOp!=SQLITE_UPDATE && eOp!=SQLITE_DELETE ){ + rc = SQLITE_ERROR; + }else{ + rc = sessionChangesetFindTable(pGrp, zTab, 0, &pTab); + if( pTab==0 && pzErr ){ + *pzErr = sqlite3_mprintf("no such table: %s", zTab); + } + } + if( rc==SQLITE_OK ){ + int nReq = pTab->nCol * (eOp==SQLITE_UPDATE ? 2 : 1); + pGrp->cd.pTab = pTab; + pGrp->cd.eOp = eOp; + pGrp->cd.bIndirect = bIndirect; + + if( pGrp->cd.nBufAlloccd.aBuf, nReq * sizeof(SessionBuffer) + ); + if( aBuf==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(&aBuf[pGrp->cd.nBufAlloc], 0, + sizeof(SessionBuffer) * (nReq - pGrp->cd.nBufAlloc) + ); + pGrp->cd.aBuf = aBuf; + pGrp->cd.nBufAlloc = nReq; + } + } + +#ifdef SQLITE_DEBUG + { + /* Assert that all column values are currently undefined */ + int ii; + for(ii=0; iicd.nBufAlloc; ii++){ + assert( pGrp->cd.aBuf[ii].nBuf==0 ); + } + } +#endif + } + + return rc; +} + +/* +** This function does processing common to the _change_int64(), _change_text() +** and other similar APIs. +*/ +static int checkChangeParams( + sqlite3_changegroup *pGrp, + int bNew, + int iCol, + sqlite3_int64 nReq, + SessionBuffer **ppBuf +){ + int rc = SQLITE_OK; + if( pGrp->cd.pTab==0 ){ + rc = SQLITE_MISUSE; + }else if( iCol<0 || iCol>=pGrp->cd.pTab->nCol ){ + rc = SQLITE_RANGE; + }else if( + (bNew && pGrp->cd.eOp==SQLITE_DELETE) + || (!bNew && pGrp->cd.eOp==SQLITE_INSERT) + ){ + rc = SQLITE_ERROR; + }else{ + SessionBuffer *pBuf = &pGrp->cd.aBuf[iCol]; + if( pGrp->cd.eOp==SQLITE_UPDATE && bNew ){ + pBuf += pGrp->cd.pTab->nCol; + } + pBuf->nBuf = 0; + sessionBufferGrow(pBuf, nReq, &rc); + pBuf->nBuf = nReq; + *ppBuf = pBuf; + } + return rc; +} + +/* +** Configure the change currently under construction with an integer value. +*/ +SQLITE_API int sqlite3changegroup_change_int64( + sqlite3_changegroup *pGrp, + int bNew, + int iCol, + sqlite3_int64 iVal +){ + int rc = SQLITE_OK; + SessionBuffer *pBuf = 0; + + if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, 9, &pBuf)) ){ + return rc; + } + + pBuf->aBuf[0] = SQLITE_INTEGER; + sessionPutI64(&pBuf->aBuf[1], iVal); + return SQLITE_OK; +} + +/* +** Configure the change currently under construction with a null value. +*/ +SQLITE_API int sqlite3changegroup_change_null( + sqlite3_changegroup *pGrp, + int bNew, + int iCol +){ + int rc = SQLITE_OK; + SessionBuffer *pBuf = 0; + + if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, 1, &pBuf)) ){ + return rc; + } + + pBuf->aBuf[0] = SQLITE_NULL; + return SQLITE_OK; +} + +/* +** Configure the change currently under construction with a real value. +*/ +SQLITE_API int sqlite3changegroup_change_double( + sqlite3_changegroup *pGrp, + int bNew, + int iCol, + double fVal +){ + int rc = SQLITE_OK; + SessionBuffer *pBuf = 0; + + if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, 9, &pBuf)) ){ + return rc; + } + + pBuf->aBuf[0] = SQLITE_FLOAT; + sessionPutDouble(&pBuf->aBuf[1], fVal); + return SQLITE_OK; +} + +/* +** Configure the change currently under construction with a text value. +*/ +SQLITE_API int sqlite3changegroup_change_text( + sqlite3_changegroup *pGrp, + int bNew, + int iCol, + const char *pVal, + int nVal +){ + sqlite3_int64 nText = nVal>=0 ? nVal : strlen(pVal); + sqlite3_int64 nByte = 1 + sessionVarintLen(nText) + nText; + int rc = SQLITE_OK; + SessionBuffer *pBuf = 0; + + if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, nByte, &pBuf)) ){ + return rc; + } + + pBuf->aBuf[0] = SQLITE_TEXT; + pBuf->nBuf = (1 + sessionVarintPut(&pBuf->aBuf[1], nText)); + memcpy(&pBuf->aBuf[pBuf->nBuf], pVal, nText); + pBuf->nBuf += nText; + + return SQLITE_OK; +} + +/* +** Configure the change currently under construction with a blob value. +*/ +SQLITE_API int sqlite3changegroup_change_blob( + sqlite3_changegroup *pGrp, + int bNew, + int iCol, + const void *pVal, + int nVal +){ + sqlite3_int64 nByte = 1 + sessionVarintLen(nVal) + (i64)nVal; + int rc = SQLITE_OK; + SessionBuffer *pBuf = 0; + + if( SQLITE_OK!=(rc = checkChangeParams(pGrp, bNew, iCol, nByte, &pBuf)) ){ + return rc; + } + + pBuf->aBuf[0] = SQLITE_BLOB; + pBuf->nBuf = (1 + sessionVarintPut(&pBuf->aBuf[1], nVal)); + memcpy(&pBuf->aBuf[pBuf->nBuf], pVal, nVal); + pBuf->nBuf += nVal; + + return SQLITE_OK; +} + +/* +** Finish any change currently being constructed by the changegroup object. +*/ +SQLITE_API int sqlite3changegroup_change_finish( + sqlite3_changegroup *pGrp, + int bDiscard, + char **pzErr +){ + int rc = SQLITE_OK; + char *zErr = 0; + if( pGrp->cd.pTab ){ + SessionBuffer *aBuf = pGrp->cd.aBuf; + int ii; + + if( bDiscard==0 ){ + int nBuf = pGrp->cd.pTab->nCol; + u8 eUndef = SQLITE_NULL; + if( pGrp->cd.eOp==SQLITE_UPDATE ){ + for(ii=0; iicd.pTab->abPK[ii] ){ + if( aBuf[ii].nBuf<=1 ){ + zErr = sqlite3_mprintf( + "invalid change: %s value in PK of old.* record", + aBuf[ii].nBuf==1 ? "null" : "undefined" + ); + rc = SQLITE_ERROR; + break; + }else if( aBuf[ii + nBuf].nBuf>0 ){ + zErr = sqlite3_mprintf( + "invalid change: defined value in PK of new.* record" + ); + rc = SQLITE_ERROR; + break; + } + }else + if( pGrp->bPatch==0 && (aBuf[ii].nBuf>0)!=(aBuf[ii+nBuf].nBuf>0) ){ + zErr = sqlite3_mprintf( + "invalid change: column %d " + "- old.* value is %sdefined but new.* is %sdefined", + ii, aBuf[ii].nBuf ? "" : "un", aBuf[ii+nBuf].nBuf ? "" : "un" + ); + rc = SQLITE_ERROR; + break; + } + } + eUndef = 0x00; + if( pGrp->bPatch==0 ) nBuf = nBuf * 2; + }else{ + for(ii=0; iicd.pTab->abPK[ii]; + if( (pGrp->cd.eOp==SQLITE_INSERT || pGrp->bPatch==0 || isPK) + && aBuf[ii].nBuf==0 + ){ + zErr = sqlite3_mprintf( + "invalid change: column %d is undefined", ii + ); + rc = SQLITE_ERROR; + break; + } + if( aBuf[ii].nBuf==1 && isPK ){ + zErr = sqlite3_mprintf( + "invalid change: null value in PK" + ); + rc = SQLITE_ERROR; + break; + } + } + } + + pGrp->cd.record.nBuf = 0; + for(ii=0; iicd.aBuf[ii]; + if( pGrp->bPatch ){ + if( pGrp->cd.pTab->abPK[ii]==0 ){ + if( pGrp->cd.eOp==SQLITE_UPDATE ){ + p += pGrp->cd.pTab->nCol; + }else if( pGrp->cd.eOp==SQLITE_DELETE ){ + continue; + } + } + } + if( 0==sessionBufferGrow(&pGrp->cd.record, p->nBuf?p->nBuf:1, &rc) ){ + if( p->nBuf ){ + memcpy(&pGrp->cd.record.aBuf[pGrp->cd.record.nBuf],p->aBuf,p->nBuf); + pGrp->cd.record.nBuf += p->nBuf; + }else{ + pGrp->cd.record.aBuf[pGrp->cd.record.nBuf++] = eUndef; + } + } + } + if( rc==SQLITE_OK ){ + rc = sessionOneChangeToHash( + pGrp, pGrp->cd.pTab, + pGrp->cd.eOp, pGrp->cd.bIndirect, pGrp->cd.pTab->nCol, + pGrp->cd.record.aBuf, pGrp->cd.record.nBuf, 0 + ); + } + } + + /* Reset all aBuf[] entries to "undefined". */ + { + int nZero = pGrp->cd.pTab->nCol; + if( pGrp->cd.eOp==SQLITE_UPDATE ) nZero += nZero; + for(ii=0; iicd.aBuf[ii].nBuf = 0; + } + } + pGrp->cd.pTab = 0; + } + + if( pzErr ){ + *pzErr = zErr; + }else{ + sqlite3_free(zErr); + } + return rc; +} + #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ /************** End of sqlite3session.c **************************************/ @@ -239504,7 +244523,7 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); ** 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 +** of this template is copied straight through into the generated parser ** source file. ** ** The following is the concatenation of all %include directives from the @@ -239641,14 +244660,22 @@ typedef union { #define sqlite3Fts5ParserARG_PARAM ,pParse #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; +#undef fts5YYREALLOC #define fts5YYREALLOC realloc +#undef fts5YYFREE #define fts5YYFREE free +#undef fts5YYDYNSTACK #define fts5YYDYNSTACK 0 +#undef fts5YYSIZELIMIT +#define sqlite3Fts5ParserCTX(P) 0 #define sqlite3Fts5ParserCTX_SDECL #define sqlite3Fts5ParserCTX_PDECL #define sqlite3Fts5ParserCTX_PARAM #define sqlite3Fts5ParserCTX_FETCH #define sqlite3Fts5ParserCTX_STORE +#undef fts5YYERRORSYMBOL +#undef fts5YYERRSYMDT +#undef fts5YYFALLBACK #define fts5YYNSTATE 35 #define fts5YYNRULE 28 #define fts5YYNRULE_WITH_ACTION 28 @@ -239973,15 +245000,24 @@ static int fts5yyGrowStack(fts5yyParser *p){ int newSize; int idx; fts5yyStackEntry *pNew; +#ifdef fts5YYSIZELIMIT + int nLimit = fts5YYSIZELIMIT(sqlite3Fts5ParserCTX(p)); +#endif newSize = oldSize*2 + 100; +#ifdef fts5YYSIZELIMIT + if( newSize>nLimit ){ + newSize = nLimit; + if( newSize<=oldSize ) return 1; + } +#endif idx = (int)(p->fts5yytos - p->fts5yystack); if( p->fts5yystack==p->fts5yystk0 ){ - pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0])); + pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p)); if( pNew==0 ) return 1; memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0])); }else{ - pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0])); + pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p)); if( pNew==0 ) return 1; } p->fts5yystack = pNew; @@ -240161,7 +245197,9 @@ static void sqlite3Fts5ParserFinalize(void *p){ } #if fts5YYGROWABLESTACK - if( pParser->fts5yystack!=pParser->fts5yystk0 ) fts5YYFREE(pParser->fts5yystack); + if( pParser->fts5yystack!=pParser->fts5yystk0 ){ + fts5YYFREE(pParser->fts5yystack, sqlite3Fts5ParserCTX(pParser)); + } #endif } @@ -241214,6 +246252,16 @@ static int fts5HighlightCb( return rc; } +/* +** Return the integer value of pVal, clamped to the range [-1, 0x7FFFFFFF]. +** This is used for the column-number arguments of auxiliary functions, +** so that 64-bit values that are too large or too small to fit in a +** 32-bit signed integer are not truncated to what might be a valid +** column number. +*/ +static int fts5ValueClampedInt(sqlite3_value *pVal){ + return (int)MIN(MAX(sqlite3_value_int64(pVal), -1), 0x7FFFFFFF); +} /* ** Implementation of highlight() function. @@ -241235,7 +246283,7 @@ static void fts5HighlightFunction( return; } - iCol = sqlite3_value_int(apVal[0]); + iCol = fts5ValueClampedInt(apVal[0]); memset(&ctx, 0, sizeof(HighlightContext)); ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); @@ -241414,7 +246462,7 @@ static void fts5SnippetFunction( int rc = SQLITE_OK; /* Return code */ int iCol; /* 1st argument to snippet() */ const char *zEllips; /* 4th argument to snippet() */ - int nToken; /* 5th argument to snippet() */ + i64 nToken; /* 5th argument to snippet() */ int nInst = 0; /* Number of instance matches this row */ int i; /* Used to iterate through instances */ int nPhrase; /* Number of phrases in query */ @@ -241434,16 +246482,16 @@ static void fts5SnippetFunction( nCol = pApi->xColumnCount(pFts); memset(&ctx, 0, sizeof(HighlightContext)); - iCol = sqlite3_value_int(apVal[0]); + iCol = fts5ValueClampedInt(apVal[0]); ctx.zOpen = fts5ValueToText(apVal[1]); ctx.zClose = fts5ValueToText(apVal[2]); ctx.iRangeEnd = -1; zEllips = fts5ValueToText(apVal[3]); - nToken = sqlite3_value_int(apVal[4]); + nToken = (int)(MIN( MAX(sqlite3_value_int64(apVal[4]), 0), 64)); iBestCol = (iCol>=0 ? iCol : 0); nPhrase = pApi->xPhraseCount(pFts); - aSeen = sqlite3_malloc(nPhrase); + aSeen = sqlite3_malloc64(nPhrase); if( aSeen==0 ){ rc = SQLITE_NOMEM; } @@ -241766,7 +246814,7 @@ static void fts5GetLocaleFunction( return; } - iCol = sqlite3_value_int(apVal[0]); + iCol = fts5ValueClampedInt(apVal[0]); if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){ sqlite3_result_error_code(pCtx, SQLITE_RANGE); return; @@ -242098,7 +247146,7 @@ static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ if( nIn<0 ){ nIn = (int)strlen(pIn); } - zRet = (char*)sqlite3_malloc(nIn+1); + zRet = (char*)sqlite3_malloc64((i64)nIn+1); if( zRet ){ memcpy(zRet, pIn, nIn); zRet[nIn] = '\0'; @@ -242798,7 +247846,7 @@ static int sqlite3Fts5ConfigParse( sqlite3_int64 nByte; int bUnindexed = 0; /* True if there are one or more UNINDEXED */ - *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); + *ppOut = pRet = (Fts5Config*)sqlite3_malloc64(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(Fts5Config)); pRet->pGlobal = pGlobal; @@ -243346,8 +248394,6 @@ static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){ va_end(ap); } - - /* ** 2014 May 31 ** @@ -243664,7 +248710,7 @@ static int sqlite3Fts5ExprNew( assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 ); if( sParse.rc==SQLITE_OK ){ - *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr)); + *ppNew = pNew = sqlite3_malloc64(sizeof(Fts5Expr)); if( pNew==0 ){ sParse.rc = SQLITE_NOMEM; sqlite3Fts5ParseNodeFree(sParse.pExpr); @@ -243816,7 +248862,7 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ p2->pRoot = 0; if( sParse.rc==SQLITE_OK ){ - Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc( + Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc64( p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*) ); if( ap==0 ){ @@ -244157,7 +249203,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ i64 iPos = a[i].reader.iPos; Fts5PoslistWriter *pWriter = &a[i].writer; if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){ - sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos); + sqlite3Fts5PoslistSafeAppend(a[i].pOut, &pWriter->iPrev, iPos); } } @@ -245108,10 +250154,10 @@ static int fts5ParseTokenize( memset(pSyn, 0, (size_t)nByte); pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); pSyn->nFullTerm = pSyn->nQueryTerm = nToken; + memcpy(pSyn->pTerm, pToken, nToken); if( pCtx->pConfig->bTokendata ){ pSyn->nQueryTerm = (int)strlen(pSyn->pTerm); } - memcpy(pSyn->pTerm, pToken, nToken); pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; } @@ -246728,7 +251774,7 @@ static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte int rc = SQLITE_OK; Fts5Hash *pNew; - *ppNew = pNew = (Fts5Hash*)sqlite3_malloc(sizeof(Fts5Hash)); + *ppNew = pNew = (Fts5Hash*)sqlite3_malloc64(sizeof(Fts5Hash)); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ @@ -246960,7 +252006,7 @@ static int sqlite3Fts5HashWrite( ** + 5 bytes for the new position offset (32-bit max). */ if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){ - sqlite3_int64 nNew = p->nAlloc * 2; + sqlite3_int64 nNew = (i64)p->nAlloc * 2; Fts5HashEntry *pNew; Fts5HashEntry **pp; pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew); @@ -247513,7 +252559,12 @@ static void sqlite3Fts5HashScanEntry( #define FTS5_DATA_ID_B 16 /* Max seg id number 65535 */ #define FTS5_DATA_DLI_B 1 /* Doclist-index flag (1 bit) */ #define FTS5_DATA_HEIGHT_B 5 /* Max dlidx tree height of 32 */ -#define FTS5_DATA_PAGE_B 31 /* Max page number of 2147483648 */ +#define FTS5_DATA_PAGE_B 31 /* 31-bit page numbers */ + +/* Maximum page number within a segment. Declare any structure read from +** the database with a page number greater than this corrupt. It is not +** actually possible to create a database this large. */ +#define FTS5_MAX_PGNO 0x7FFFFF00 #define fts5_dri(segid, dlidx, height, pgno) ( \ ((i64)(segid) << (FTS5_DATA_PAGE_B+FTS5_DATA_HEIGHT_B+FTS5_DATA_DLI_B)) + \ @@ -248111,6 +253162,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); if( pRet ){ pRet->nn = nByte; + pRet->szLeaf = 0; aOut = pRet->p = (u8*)pRet + szData; }else{ rc = SQLITE_NOMEM; @@ -248123,10 +253175,8 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ sqlite3_free(pRet); pRet = 0; }else{ - /* TODO1: Fix this */ pRet->p[nByte] = 0x00; pRet->p[nByte+1] = 0x00; - pRet->szLeaf = fts5GetU16(&pRet->p[2]); } } p->rc = rc; @@ -248147,10 +253197,18 @@ static void fts5DataRelease(Fts5Data *pData){ sqlite3_free(pData); } +/* +** Read a leaf-page record. This is similar to fts5DataRead(), except that +** it fills in the Fts5Data.szLeaf value before returning. +*/ static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){ Fts5Data *pRet = fts5DataRead(p, iRowid); if( pRet ){ - if( pRet->nn<4 || pRet->szLeaf>pRet->nn ){ + assert( pRet->szLeaf==0 ); + if( pRet->nn>=4 ){ + pRet->szLeaf = fts5GetU16(&pRet->p[2]); + } + if( pRet->szLeaf<4 || pRet->szLeaf>pRet->nn ){ FTS5_CORRUPT_ROWID(p, iRowid); fts5DataRelease(pRet); pRet = 0; @@ -248394,7 +253452,7 @@ static int fts5StructureDecode( i += fts5GetVarint32(&pData[i], nTotal); if( nTotalnMerge ) rc = FTS5_CORRUPT; pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, - nTotal * sizeof(Fts5StructureSegment) + (i64)nTotal * sizeof(Fts5StructureSegment) ); nSegment -= nTotal; } @@ -248419,7 +253477,7 @@ static int fts5StructureDecode( i += fts5GetVarint(&pData[i], &pSeg->nEntry); nOriginCntr = MAX(nOriginCntr, pSeg->iOrigin2); } - if( pSeg->pgnoLastpgnoFirst ){ + if( pSeg->pgnoLastpgnoFirst || pSeg->pgnoLast>FTS5_MAX_PGNO ){ rc = FTS5_CORRUPT; break; } @@ -248923,6 +253981,7 @@ static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){ pLvl->bEof = 1; }else{ u8 *a = pLvl->pData->p; + int nn = pLvl->pData->nn; pLvl->iOff = 0; fts5DlidxLvlNext(pLvl); @@ -248931,7 +253990,7 @@ static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){ int ii = pLvl->iOff; u64 delta = 0; - while( a[ii]==0 ){ + while( iinLvl = i+1; + if( pIter->nLvl > (1<rc = FTS5_CORRUPT; + } } } @@ -249321,7 +254383,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){ /* If necessary, grow the pIter->aRowidOffset[] array. */ if( iRowidOffset>=pIter->nRowidOffset ){ - int nNew = pIter->nRowidOffset + 8; + i64 nNew = pIter->nRowidOffset + 8; int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int)); if( aNew==0 ){ p->rc = SQLITE_NOMEM; @@ -249350,7 +254412,7 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){ while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){ Fts5Data *pNew; pIter->iLeafPgno--; - pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID( + pNew = fts5LeafRead(p, FTS5_SEGMENT_ROWID( pIter->pSeg->iSegid, pIter->iLeafPgno )); if( pNew ){ @@ -249804,6 +254866,10 @@ static void fts5LeafSeek( if( nKeepn ){ + FTS5_CORRUPT_ITER(p, pIter); + return; + } assert( nKeep>=nMatch ); if( nKeep==nMatch ){ @@ -250055,6 +255121,10 @@ static void fts5SegIterNextInit( pIter->iPgidxOff = pIter->pLeaf->szLeaf; pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff); + if( iTermOff > pIter->pLeaf->szLeaf ){ + p->rc = FTS5_CORRUPT; + return; + } pIter->iLeafOffset = iTermOff; fts5SegIterLoadTerm(p, pIter, 0); fts5SegIterLoadNPos(p, pIter); @@ -250780,8 +255850,7 @@ static void fts5PoslistFilterCallback( do { while( ieState ){ fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart); @@ -250930,7 +255999,7 @@ static void fts5IndexExtractColset( /* Advance pointer p until it points to pEnd or an 0x01 byte that is ** not part of a varint */ while( paiCol[i]==iCurrent ){ @@ -250998,6 +256067,7 @@ static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ static void fts5IterSetOutputs_ZeroColset(Fts5Iter *pIter, Fts5SegIter *pSeg){ UNUSED_PARAM(pSeg); pIter->base.nData = 0; + pIter->base.bEof = 1; } /* @@ -251027,8 +256097,11 @@ static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){ assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); assert( pIter->pColset ); + assert( pIter->poslist.nSpace>=pIter->pIndex->pConfig->nCol ); - if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){ + if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf + || pSeg->nPos>pIter->pIndex->pConfig->nCol + ){ fts5IterSetOutputs_Col(pIter, pSeg); }else{ u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset]; @@ -252379,7 +257452,7 @@ static void fts5SecureDeleteOverflow( int iNext = 0; u8 *aPg = 0; - pLeaf = fts5DataRead(p, iRowid); + pLeaf = fts5LeafRead(p, iRowid); if( pLeaf==0 ) break; aPg = pLeaf->p; @@ -252387,7 +257460,7 @@ static void fts5SecureDeleteOverflow( if( iNext!=0 ){ *pbLastInDoclist = 0; } - if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){ + if( iNext==0 && pLeaf->szLeafnn ){ fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext); } @@ -252468,7 +257541,7 @@ static void fts5DoSecureDelete( int iSegid = pSeg->pSeg->iSegid; u8 *aPg = pSeg->pLeaf->p; int nPg = pSeg->pLeaf->nn; - int iPgIdx = pSeg->pLeaf->szLeaf; + int iPgIdx = pSeg->pLeaf->szLeaf; /* Offset of page footer */ u64 iDelta = 0; int iNextOff = 0; @@ -252522,6 +257595,11 @@ static void fts5DoSecureDelete( }else{ iStart = fts5GetU16(&aPg[0]); } + if( iStart>nPg ){ + FTS5_CORRUPT_IDX(p); + sqlite3_free(aIdx); + return; + } iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); assert_nc( iSOP<=pSeg->iLeafOffset ); @@ -252547,7 +257625,7 @@ static void fts5DoSecureDelete( iSOP += fts5GetVarint32(&aPg[iSOP], nPos); } assert_nc( iSOP==pSeg->iLeafOffset ); - iNextOff = pSeg->iLeafOffset + pSeg->nPos; + iNextOff = iSOP + pSeg->nPos; } } @@ -252627,31 +257705,31 @@ static void fts5DoSecureDelete( ** is another term following it on this page. So the subsequent term ** needs to be moved to replace the term associated with the entry ** being removed. */ - int nPrefix = 0; - int nSuffix = 0; - int nPrefix2 = 0; - int nSuffix2 = 0; + u64 nPrefix = 0; + u64 nSuffix = 0; + u64 nPrefix2 = 0; + u64 nSuffix2 = 0; iDelKeyOff = iNextOff; - iNextOff += fts5GetVarint32(&aPg[iNextOff], nPrefix2); - iNextOff += fts5GetVarint32(&aPg[iNextOff], nSuffix2); + iNextOff += fts5GetVarint(&aPg[iNextOff], &nPrefix2); + iNextOff += fts5GetVarint(&aPg[iNextOff], &nSuffix2); if( iKey!=1 ){ - iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nPrefix); + iKeyOff += fts5GetVarint(&aPg[iKeyOff], &nPrefix); } - iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix); + iKeyOff += fts5GetVarint(&aPg[iKeyOff], &nSuffix); nPrefix = MIN(nPrefix, nPrefix2); nSuffix = (nPrefix2 + nSuffix2) - nPrefix; - if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){ + if( (iKeyOff+nSuffix)>(u64)iPgIdx || (iNextOff+nSuffix2)>(u64)iPgIdx ){ FTS5_CORRUPT_IDX(p); }else{ if( iKey!=1 ){ iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix); } iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix); - if( nPrefix2>pSeg->term.n ){ + if( nPrefix2>(u64)pSeg->term.n ){ FTS5_CORRUPT_IDX(p); }else if( nPrefix2>nPrefix ){ memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix); @@ -252669,7 +257747,7 @@ static void fts5DoSecureDelete( /* The entry being removed may be the only position list in ** its doclist. */ for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){ - Fts5Data *pPg = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno)); + Fts5Data *pPg = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno)); int bEmpty = (pPg && pPg->nn==4); fts5DataRelease(pPg); if( bEmpty==0 ) break; @@ -252677,12 +257755,12 @@ static void fts5DoSecureDelete( if( iPgno==pSeg->iTermLeafPgno ){ i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno); - Fts5Data *pTerm = fts5DataRead(p, iId); + Fts5Data *pTerm = fts5LeafRead(p, iId); if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){ u8 *aTermIdx = &pTerm->p[pTerm->szLeaf]; int nTermIdx = pTerm->nn - pTerm->szLeaf; int iTermIdx = 0; - int iTermOff = 0; + i64 iTermOff = 0; while( 1 ){ u32 iVal = 0; @@ -252693,12 +257771,15 @@ static void fts5DoSecureDelete( } nTermIdx = iTermIdx; - memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx); - fts5PutU16(&pTerm->p[2], iTermOff); - - fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); - if( nTermIdx==0 ){ - fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); + if( iTermOff>pTerm->szLeaf ){ + FTS5_CORRUPT_IDX(p); + }else{ + memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx); + fts5PutU16(&pTerm->p[2], iTermOff); + fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); + if( nTermIdx==0 ){ + fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); + } } } fts5DataRelease(pTerm); @@ -252717,32 +257798,38 @@ static void fts5DoSecureDelete( if( p->rc==SQLITE_OK ){ const int nMove = nPg - iNextOff; /* Number of bytes to move */ int nShift = iNextOff - iOff; /* Distance to move them */ - + int nNewPg = 0; int iPrevKeyOut = 0; - int iKeyIn = 0; + i64 iKeyIn = 0; - memmove(&aPg[iOff], &aPg[iNextOff], nMove); + if( nMove>0 ){ + memmove(&aPg[iOff], &aPg[iNextOff], nMove); + } iPgIdx -= nShift; - nPg = iPgIdx; + nNewPg = iPgIdx; fts5PutU16(&aPg[2], iPgIdx); for(iIdx=0; iIdxnPg ){ + FTS5_CORRUPT_IDX(p); + break; + } if( iKeyIn!=iDelKeyOff ){ int iKeyOut = (iKeyIn - (iKeyIn>iOff ? nShift : 0)); - nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOut - iPrevKeyOut); + nNewPg += sqlite3Fts5PutVarint(&aPg[nNewPg], iKeyOut - iPrevKeyOut); iPrevKeyOut = iKeyOut; } } - if( iPgIdx==nPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ + if( p->rc==SQLITE_OK && iPgIdx==nNewPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iLeafPgno); } - assert_nc( nPg>4 || fts5GetU16(aPg)==0 ); - fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg, nPg); + assert_nc( nNewPg>4 || fts5GetU16(aPg)==0 ); + fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg, nNewPg); } sqlite3_free(aIdx); } @@ -252890,7 +257977,6 @@ static void fts5FlushOneHash(Fts5Index *p){ iOff++; if( iOff=pIter->aEof ){ pIter->aPoslist = 0; }else{ - i64 iDelta; + u64 iDelta; - p += fts5GetVarint(p, (u64*)&iDelta); + p += fts5GetVarint(p, &iDelta); pIter->iRowid += iDelta; /* Read position list size */ @@ -253305,7 +258391,7 @@ static void fts5MergeRowidLists( (void)nBuf; memset(&out, 0, sizeof(out)); assert( nBuf==1 ); - sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n); + sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9); if( p->rc ) return; fts5NextRowid(p1, &i1, &iRowid1); @@ -253313,12 +258399,12 @@ static void fts5MergeRowidLists( while( i1>=0 || i2>=0 ){ if( i1>=0 && (i2<0 || iRowid1iOut ); - fts5BufferSafeAppendVarint(&out, iRowid1 - iOut); + fts5BufferSafeAppendVarint(&out, (u64)iRowid1 - (u64)iOut); iOut = iRowid1; fts5NextRowid(p1, &i1, &iRowid1); }else{ assert( iOut==0 || iRowid2>iOut ); - fts5BufferSafeAppendVarint(&out, iRowid2 - iOut); + fts5BufferSafeAppendVarint(&out, (u64)iRowid2 - (u64)iOut); iOut = iRowid2; if( i1>=0 && iRowid1==iRowid2 ){ fts5NextRowid(p1, &i1, &iRowid1); @@ -253641,16 +258727,16 @@ struct Fts5TokenDataMap { ** aMap[] variables. */ struct Fts5TokenDataIter { - int nMapAlloc; /* Allocated size of aMap[] in entries */ - int nMap; /* Number of valid entries in aMap[] */ + i64 nMapAlloc; /* Allocated size of aMap[] in entries */ + i64 nMap; /* Number of valid entries in aMap[] */ Fts5TokenDataMap *aMap; /* Array of (rowid+pos -> token) mappings */ /* The following are used for prefix-queries only. */ Fts5Buffer terms; /* The following are used for other full-token tokendata queries only. */ - int nIter; - int nIterAlloc; + i64 nIter; + i64 nIterAlloc; Fts5PoslistReader *aPoslistReader; int *aPoslistToIter; Fts5Iter *apIter[FLEXARRAY]; @@ -253706,11 +258792,11 @@ static void fts5TokendataIterAppendMap( ){ if( p->rc==SQLITE_OK ){ if( pT->nMap==pT->nMapAlloc ){ - int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; - int nAlloc = nNew * sizeof(Fts5TokenDataMap); + i64 nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; + i64 nAlloc = nNew * sizeof(Fts5TokenDataMap); Fts5TokenDataMap *aNew; - aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nAlloc); + aNew = (Fts5TokenDataMap*)sqlite3_realloc64(pT->aMap, nAlloc); if( aNew==0 ){ p->rc = SQLITE_NOMEM; return; @@ -253736,7 +258822,7 @@ static void fts5TokendataIterAppendMap( */ static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ Fts5TokenDataMap *aTmp = 0; - int nByte = pT->nMap * sizeof(Fts5TokenDataMap); + i64 nByte = pT->nMap * sizeof(Fts5TokenDataMap); aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); if( aTmp ){ @@ -254270,9 +259356,10 @@ static Fts5TokenDataIter *fts5AppendTokendataIter( if( p->rc==SQLITE_OK ){ if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ - int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; - int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1); - Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); + i64 nAlloc = pIn ? pIn->nIterAlloc*2 : 16; + i64 nByte = SZ_FTS5TOKENDATAITER(nAlloc+1); + Fts5TokenDataIter *pNew; + pNew = (Fts5TokenDataIter*)sqlite3_realloc64(pIn, nByte); if( pNew==0 ){ p->rc = SQLITE_NOMEM; @@ -254369,8 +259456,8 @@ static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ /* Ensure the token-mapping is large enough */ if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){ - int nNew = (pT->nMapAlloc + nByte) * 2; - Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc( + i64 nNew = (pT->nMapAlloc + nByte) * 2; + Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc64( pT->aMap, nNew*sizeof(Fts5TokenDataMap) ); if( aNew==0 ){ @@ -255201,8 +260288,8 @@ static void fts5IndexTombstoneRebuild( ){ const int MINSLOT = 32; int nSlotPerPage = MAX(MINSLOT, (p->pConfig->pgsz - 8) / szKey); - int nSlot = 0; /* Number of slots in each output page */ - int nOut = 0; + i64 nSlot = 0; /* Number of slots in each output page */ + i64 nOut = 0; /* Figure out how many output pages (nOut) and how many slots per ** page (nSlot). There are three possibilities: @@ -255227,23 +260314,26 @@ static void fts5IndexTombstoneRebuild( nSlot = MINSLOT; }else if( pSeg->nPgTombstone==1 ){ /* Case 2. */ - int nElem = (int)fts5GetU32(&pData1->p[4]); + u32 nElem = fts5GetU32(&pData1->p[4]); assert( pData1 && iPg1==0 ); - nOut = 1; - nSlot = MAX(nElem*4, MINSLOT); - if( nSlot>nSlotPerPage ) nOut = 0; + if( nElem>((u32)nSlotPerPage/4) ){ + nOut = 0; + }else{ + nOut = 1; + nSlot = MAX((i64)nElem*4, MINSLOT); + } } if( nOut==0 ){ /* Case 3. */ - nOut = (pSeg->nPgTombstone * 2 + 1); + nOut = ((i64)pSeg->nPgTombstone * 2 + 1); nSlot = nSlotPerPage; } /* Allocate the required array and output pages */ while( 1 ){ int res = 0; - int ii = 0; - int szPage = 0; + i64 ii = 0; + i64 szPage = 0; Fts5Data **apOut = 0; /* Allocate space for the new hash table */ @@ -255484,6 +260574,9 @@ static int fts5QueryCksum( } /* +** This function is purely an internal test. It does not contribute to +** FTS functionality, or even the integrity-check, in any way. +** ** Check if buffer z[], size n bytes, contains as series of valid utf-8 ** encoded codepoints. If so, return 0. Otherwise, if the buffer does not ** contain valid utf-8, return non-zero. @@ -255505,8 +260598,8 @@ static int fts5TestUtf8(const char *z, int n){ }else if( (z[i] & 0xF8)==0xF0 ){ if( i+3>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1; - if( (z[i+2] & 0xC0)!=0x80 ) return 1; - i += 3; + if( (z[i+3] & 0xC0)!=0x80 ) return 1; + i += 4; }else{ return 1; } @@ -255620,7 +260713,7 @@ static void fts5IndexIntegrityCheckEmpty( /* Now check that the iter.nEmpty leaves following the current leaf ** (a) exist and (b) contain no terms. */ for(i=iFirst; p->rc==SQLITE_OK && i<=iLast; i++){ - Fts5Data *pLeaf = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i)); + Fts5Data *pLeaf = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->iSegid, i)); if( pLeaf ){ if( !fts5LeafIsTermless(pLeaf) || (i>=iNoRowid && 0!=fts5LeafFirstRowidOff(pLeaf)) @@ -255748,9 +260841,13 @@ static void fts5IndexIntegrityCheckSegment( FTS5_CORRUPT_ROWID(p, iRow); }else{ iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm); - res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); - if( res==0 ) res = nTerm - nIdxTerm; - if( res<0 ) FTS5_CORRUPT_ROWID(p, iRow); + if( (i64)iOff+(i64)nTerm>(i64)pLeaf->szLeaf ){ + FTS5_CORRUPT_ROWID(p, iRow); + }else{ + res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); + if( res==0 ) res = nTerm - nIdxTerm; + if( res<0 ) FTS5_CORRUPT_ROWID(p, iRow); + } } fts5IntegrityCheckPgidx(p, iRow, pLeaf); @@ -255781,7 +260878,7 @@ static void fts5IndexIntegrityCheckSegment( /* Check any rowid-less pages that occur before the current leaf. */ for(iPg=iPrevLeaf+1; iPg=3008002 ) #endif { - pIdxInfo->estimatedRows = nRow; + pIdxInfo->estimatedRows = MAX(1, nRow); } #endif } @@ -257354,19 +262451,30 @@ static int fts5UsePatternMatch( ** a) If a MATCH operator is present, the cost depends on the other ** constraints also present. As follows: ** -** * No other constraints: cost=1000.0 -** * One rowid range constraint: cost=750.0 -** * Both rowid range constraints: cost=500.0 -** * An == rowid constraint: cost=100.0 +** * No other constraints: cost=50000.0 +** * One rowid range constraint: cost=37500.0 +** * Both rowid range constraints: cost=30000.0 +** * An == rowid constraint: cost=25000.0 ** ** b) Otherwise, if there is no MATCH: ** -** * No other constraints: cost=1000000.0 -** * One rowid range constraint: cost=750000.0 -** * Both rowid range constraints: cost=250000.0 -** * An == rowid constraint: cost=10.0 +** * No other constraints: cost=3000000.0 +** * One rowid range constraints: cost=2250000.0 +** * Both rowid range constraint: cost=750000.0 +** * An == rowid constraint: cost=25.0 ** ** Costs are not modified by the ORDER BY clause. +** +** The ratios used in case (a) are based on informal results obtained from +** the tool/fts5cost.tcl script. The "MATCH and ==" combination has the +** cost set quite high because the query may be a prefix query. Unless +** there is a prefix index, prefix queries with rowid constraints are much +** more expensive than non-prefix queries with rowid constraints. +** +** The estimated rows returned is set to the cost/40. For simple queries, +** experimental results show that cost/4 might be about right. But for +** more complex queries that use multiple terms the number of rows might +** be far fewer than this. So we compromise and use cost/40. */ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts5Table *pTab = (Fts5Table*)pVTab; @@ -257399,7 +262507,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ return SQLITE_ERROR; } - idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1); + idxStr = (char*)sqlite3_malloc64((i64)pInfo->nConstraint * 8 + 1); if( idxStr==0 ) return SQLITE_NOMEM; pInfo->idxStr = idxStr; pInfo->needToFreeIdxStr = 1; @@ -257492,21 +262600,35 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* Calculate the estimated cost based on the flags set in idxFlags. */ if( bSeenEq ){ - pInfo->estimatedCost = nSeenMatch ? 1000.0 : 25.0; - fts5SetUniqueFlag(pInfo); + pInfo->estimatedCost = nSeenMatch ? 25000.0 : 25.0; fts5SetEstimatedRows(pInfo, 1); + fts5SetUniqueFlag(pInfo); }else{ - if( bSeenLt && bSeenGt ){ - pInfo->estimatedCost = nSeenMatch ? 5000.0 : 750000.0; - }else if( bSeenLt || bSeenGt ){ - pInfo->estimatedCost = nSeenMatch ? 7500.0 : 2250000.0; + i64 nEstRows; + if( nSeenMatch ){ + if( bSeenLt && bSeenGt ){ + pInfo->estimatedCost = 50000.0; + }else if( bSeenLt || bSeenGt ){ + pInfo->estimatedCost = 37500.0; + }else{ + pInfo->estimatedCost = 50000.0; + } + nEstRows = (i64)(pInfo->estimatedCost / 40.0); + for(i=1; iestimatedCost *= 2.5; + nEstRows = nEstRows / 2; + } }else{ - pInfo->estimatedCost = nSeenMatch ? 10000.0 : 3000000.0; - } - for(i=1; iestimatedCost *= 0.4; + if( bSeenLt && bSeenGt ){ + pInfo->estimatedCost = 750000.0; + }else if( bSeenLt || bSeenGt ){ + pInfo->estimatedCost = 2250000.0; + }else{ + pInfo->estimatedCost = 3000000.0; + } + nEstRows = (i64)(pInfo->estimatedCost / 4.0); } - fts5SetEstimatedRows(pInfo, (i64)(pInfo->estimatedCost / 4.0)); + fts5SetEstimatedRows(pInfo, nEstRows); } pInfo->idxNum = idxFlags; @@ -258849,6 +263971,7 @@ static int fts5UpdateMethod( } update_out: + sqlite3Fts5IndexCloseReader(pTab->p.pIndex); pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -259446,19 +264569,23 @@ static int fts5ApiPhraseFirstColumn( if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ Fts5Sorter *pSorter = pCsr->pSorter; - int n; - if( pSorter ){ - int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); - n = pSorter->aIdx[iPhrase] - i1; - pIter->a = &pSorter->aPoslist[i1]; + if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ + rc = SQLITE_RANGE; }else{ - rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); - } - if( rc==SQLITE_OK ){ - assert( pIter->a || n==0 ); - pIter->b = (pIter->a ? &pIter->a[n] : 0); - *piCol = 0; - fts5ApiPhraseNextColumn(pCtx, pIter, piCol); + int n; + if( pSorter ){ + int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); + n = pSorter->aIdx[iPhrase] - i1; + pIter->a = &pSorter->aPoslist[i1]; + }else{ + rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); + } + if( rc==SQLITE_OK ){ + assert( pIter->a || n==0 ); + pIter->b = (pIter->a ? &pIter->a[n] : 0); + *piCol = 0; + fts5ApiPhraseNextColumn(pCtx, pIter, piCol); + } } }else{ int n; @@ -260366,7 +265493,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2026-10-16 14:45:20 555e07ef33f69a0957d24d8e555b702464a131d6f1607f4c3c1e4551e8e6ca76", -1, SQLITE_TRANSIENT); } /* @@ -260530,7 +265657,7 @@ static int fts5Init(sqlite3 *db){ int rc; Fts5Global *pGlobal = 0; - pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global)); + pGlobal = (Fts5Global*)sqlite3_malloc64(sizeof(Fts5Global)); if( pGlobal==0 ){ rc = SQLITE_NOMEM; }else{ @@ -261008,34 +266135,31 @@ static int sqlite3Fts5StorageOpen( if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ - int nDefn = 32 + pConfig->nCol*10; - char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); - if( zDefn==0 ){ - rc = SQLITE_NOMEM; - }else{ - int i; - int iOff; - sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); - iOff = (int)strlen(zDefn); - for(i=0; inCol; i++){ - if( pConfig->eContent==FTS5_CONTENT_NORMAL - || pConfig->abUnindexed[i] - ){ - sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); - iOff += (int)strlen(&zDefn[iOff]); - } + int i = 0; + char *zDefn = 0; + sqlite3_str *pDefn = sqlite3_str_new(pConfig->db); + + sqlite3_str_appendf(pDefn, "id INTEGER PRIMARY KEY"); + for(i=0; inCol; i++){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->abUnindexed[i] ){ + sqlite3_str_appendf(pDefn, ", c%d", i); } - if( pConfig->bLocale ){ - for(i=0; inCol; i++){ - if( pConfig->abUnindexed[i]==0 ){ - sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i); - iOff += (int)strlen(&zDefn[iOff]); - } + } + if( pConfig->bLocale ){ + for(i=0; inCol; i++){ + if( pConfig->abUnindexed[i]==0 ){ + sqlite3_str_appendf(pDefn, ", l%d", i); } } + } + zDefn = sqlite3_str_finish(pDefn); + + if( zDefn ){ rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); + sqlite3_free(zDefn); + }else{ + rc = SQLITE_NOMEM; } - sqlite3_free(zDefn); } if( rc==SQLITE_OK && pConfig->bColumnsize ){ @@ -261262,6 +266386,64 @@ static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){ pStorage->pSavedRow = 0; } +/* +** Load the contents of the "averages" record from disk into the +** p->nTotalRow and p->aTotalSize[] variables. If successful, and if +** argument bCache is true, set the p->bTotalsValid flag to indicate +** that the contents of aTotalSize[] and nTotalRow are valid until +** further notice. +** +** Return SQLITE_OK if successful, or an SQLite error code if an error +** occurs. +*/ +static int fts5StorageLoadTotals(Fts5Storage *p, int bCache){ + int rc = SQLITE_OK; + if( p->bTotalsValid==0 ){ + rc = sqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize); + p->bTotalsValid = bCache; + } + return rc; +} + +/* +** Store the current contents of the p->nTotalRow and p->aTotalSize[] +** variables in the "averages" record on disk. +** +** Return SQLITE_OK if successful, or an SQLite error code if an error +** occurs. +*/ +static int fts5StorageSaveTotals(Fts5Storage *p){ + int nCol = p->pConfig->nCol; + int i; + Fts5Buffer buf; + int rc = SQLITE_OK; + memset(&buf, 0, sizeof(buf)); + + sqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow); + for(i=0; iaTotalSize[i]); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n); + } + sqlite3_free(buf.p); + + return rc; +} + +static int fts5StorageDecodeSizeArray( + int *aCol, int nCol, /* Array to populate */ + const u8 *aBlob, int nBlob /* Record to read varints from */ +){ + int i; + int iOff = 0; + for(i=0; i=nBlob ) return 1; + iOff += fts5GetVarint32(&aBlob[iOff], aCol[i]); + } + return (iOff!=nBlob); +} + /* ** This function is called to process a DELETE on a contentless_delete=1 ** table. It adds the tombstone required to delete the entry with rowid @@ -261278,19 +266460,41 @@ static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ || p->pConfig->eContent==FTS5_CONTENT_UNINDEXED ); + rc = fts5StorageLoadTotals(p, 1); + if( rc!=SQLITE_OK ) return rc; + /* Look up the origin of the document in the %_docsize table. Store ** this in stack variable iOrigin. */ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0); if( rc==SQLITE_OK ){ + int rc2; sqlite3_bind_int64(pLookup, 1, iDel); if( SQLITE_ROW==sqlite3_step(pLookup) ){ - iOrigin = sqlite3_column_int64(pLookup, 1); + int *aCol = (int*)sqlite3_malloc64(p->pConfig->nCol * sizeof(int)); + if( aCol==0 ){ + rc = SQLITE_NOMEM; + }else{ + const u8 *aBlob = sqlite3_column_blob(pLookup, 0); + int nBlob = sqlite3_column_bytes(pLookup, 0); + int ii; + if( fts5StorageDecodeSizeArray(aCol, p->pConfig->nCol, aBlob, nBlob) ){ + rc = SQLITE_CORRUPT_VTAB; + }else{ + for(ii=0; iipConfig->nCol; ii++){ + p->aTotalSize[ii] -= aCol[ii]; + } + } + sqlite3_free(aCol); + } + iOrigin = sqlite3_column_int(pLookup, 1); } - rc = sqlite3_reset(pLookup); + rc2 = sqlite3_reset(pLookup); + if( rc==SQLITE_OK ) rc = rc2; } if( rc==SQLITE_OK && iOrigin!=0 ){ rc = sqlite3Fts5IndexContentlessDelete(p->pIndex, iOrigin, iDel); + p->nTotalRow--; } return rc; @@ -261331,51 +266535,6 @@ static int fts5StorageInsertDocsize( return rc; } -/* -** Load the contents of the "averages" record from disk into the -** p->nTotalRow and p->aTotalSize[] variables. If successful, and if -** argument bCache is true, set the p->bTotalsValid flag to indicate -** that the contents of aTotalSize[] and nTotalRow are valid until -** further notice. -** -** Return SQLITE_OK if successful, or an SQLite error code if an error -** occurs. -*/ -static int fts5StorageLoadTotals(Fts5Storage *p, int bCache){ - int rc = SQLITE_OK; - if( p->bTotalsValid==0 ){ - rc = sqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize); - p->bTotalsValid = bCache; - } - return rc; -} - -/* -** Store the current contents of the p->nTotalRow and p->aTotalSize[] -** variables in the "averages" record on disk. -** -** Return SQLITE_OK if successful, or an SQLite error code if an error -** occurs. -*/ -static int fts5StorageSaveTotals(Fts5Storage *p){ - int nCol = p->pConfig->nCol; - int i; - Fts5Buffer buf; - int rc = SQLITE_OK; - memset(&buf, 0, sizeof(buf)); - - sqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow); - for(i=0; iaTotalSize[i]); - } - if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n); - } - sqlite3_free(buf.p); - - return rc; -} - /* ** Remove a row from the FTS table. */ @@ -262037,19 +267196,6 @@ static void sqlite3Fts5StorageStmtRelease( } } -static int fts5StorageDecodeSizeArray( - int *aCol, int nCol, /* Array to populate */ - const u8 *aBlob, int nBlob /* Record to read varints from */ -){ - int i; - int iOff = 0; - for(i=0; i=nBlob ) return 1; - iOff += fts5GetVarint32(&aBlob[iOff], aCol[i]); - } - return (iOff!=nBlob); -} - /* ** Argument aCol points to an array of integers containing one entry for ** each table column. This function reads the %_docsize record for the @@ -262246,7 +267392,7 @@ static int fts5AsciiCreate( if( nArg%2 ){ rc = SQLITE_ERROR; }else{ - p = sqlite3_malloc(sizeof(AsciiTokenizer)); + p = sqlite3_malloc64(sizeof(AsciiTokenizer)); if( p==0 ){ rc = SQLITE_NOMEM; }else{ @@ -262351,13 +267497,10 @@ static int fts5AsciiTokenize( /* -** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied -** from the sqlite3 source file utf.c. If this file is compiled as part -** of the amalgamation, they are not required. +** The following two macros - FTS5_READ_UTF8 and FTS5_WRITE_UTF8 - have +** been copied from the sqlite3 source file utf.c. */ -#ifndef SQLITE_AMALGAMATION - -static const unsigned char sqlite3Utf8Trans1[] = { +static const unsigned char fts5Utf8Trans1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, @@ -262368,45 +267511,43 @@ static const unsigned char sqlite3Utf8Trans1[] = { 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, }; -#define READ_UTF8(zIn, zTerm, c) \ +#define FTS5_READ_UTF8(zIn, zTerm, c) \ c = *(zIn++); \ if( c>=0xc0 ){ \ - c = sqlite3Utf8Trans1[c-0xc0]; \ + c = fts5Utf8Trans1[c-0xc0]; \ while( zIn>6)&0x1F); \ - *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \ - } \ - else if( c<0x10000 ){ \ - *zOut++ = 0xE0 + (unsigned char)((c>>12)&0x0F); \ - *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \ - *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \ - }else{ \ - *zOut++ = 0xF0 + (unsigned char)((c>>18) & 0x07); \ - *zOut++ = 0x80 + (unsigned char)((c>>12) & 0x3F); \ - *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \ - *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \ - } \ +#define FTS5_WRITE_UTF8(zOut, c) { \ + if( c<0x00080 ){ \ + *zOut++ = (unsigned char)(c&0xFF); \ + } \ + else if( c<0x00800 ){ \ + *zOut++ = 0xC0 + (unsigned char)((c>>6)&0x1F); \ + *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \ + } \ + else if( c<0x10000 ){ \ + *zOut++ = 0xE0 + (unsigned char)((c>>12)&0x0F); \ + *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \ + }else{ \ + *zOut++ = 0xF0 + (unsigned char)((c>>18) & 0x07); \ + *zOut++ = 0x80 + (unsigned char)((c>>12) & 0x3F); \ + *zOut++ = 0x80 + (unsigned char)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (unsigned char)(c & 0x3F); \ + } \ } -#endif /* ifndef SQLITE_AMALGAMATION */ - -#define FTS5_SKIP_UTF8(zIn) { \ - if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \ - while( (((unsigned char)*zIn) & 0xc0)==0x80 ){ zIn++; } \ - } \ +#define FTS5_SKIP_UTF8(zIn) { \ + if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \ + while( (((unsigned char)*zIn) & 0xc0)==0x80 ){zIn++;} \ + } \ } typedef struct Unicode61Tokenizer Unicode61Tokenizer; @@ -262445,7 +267586,7 @@ static int fts5UnicodeAddExceptions( while( zCsraTokenChar[iCode] = (unsigned char)bTokenChars; }else{ @@ -262541,7 +267682,7 @@ static int fts5UnicodeCreate( if( nArg%2 ){ rc = SQLITE_ERROR; }else{ - p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer)); + p = (Unicode61Tokenizer*)sqlite3_malloc64(sizeof(Unicode61Tokenizer)); if( p ){ const char *zCat = "L* N* Co"; int i; @@ -262649,7 +267790,7 @@ static int fts5UnicodeTokenize( /* A character outside of the ascii range. Skip past it if it is ** a separator character. Or break out of the loop if it is not. */ is = zCsr - (unsigned char*)pText; - READ_UTF8(zCsr, zTerm, iCode); + FTS5_READ_UTF8(zCsr, zTerm, iCode); if( fts5UnicodeIsAlnum(p, iCode) ){ goto non_ascii_tokenchar; } @@ -262685,11 +267826,11 @@ static int fts5UnicodeTokenize( if( *zCsr & 0x80 ){ /* An non-ascii-range character. Fold it into the output buffer if ** it is a token character, or break out of the loop if it is not. */ - READ_UTF8(zCsr, zTerm, iCode); + FTS5_READ_UTF8(zCsr, zTerm, iCode); if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){ non_ascii_tokenchar: iCode = sqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic); - if( iCode ) WRITE_UTF8(zOut, iCode); + if( iCode ) FTS5_WRITE_UTF8(zOut, iCode); }else{ break; } @@ -262760,11 +267901,17 @@ static int fts5PorterCreate( const char *zBase = "unicode61"; fts5_tokenizer_v2 *pV2 = 0; - if( nArg>0 ){ - zBase = azArg[0]; + while( nArg>0 ){ + if( sqlite3_stricmp(azArg[0],"porter")==0 ){ + nArg--; + azArg++; + }else{ + zBase = azArg[0]; + break; + } } - pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); + pRet = (PorterTokenizer*)sqlite3_malloc64(sizeof(PorterTokenizer)); if( pRet ){ memset(pRet, 0, sizeof(PorterTokenizer)); rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2); @@ -262886,9 +268033,9 @@ static int fts5Porter_Ostar(char *zStem, int nStem){ for(i=0; i=zEof ) return SQLITE_OK; - READ_UTF8(zIn, zEof, iCode); + FTS5_READ_UTF8(zIn, zEof, iCode); if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); }while( iCode==0 ); - WRITE_UTF8(zOut, iCode); + FTS5_WRITE_UTF8(zOut, iCode); } /* At the start of each iteration of this loop: @@ -263563,7 +268710,7 @@ static int fts5TriTokenize( iCode = 0; break; } - READ_UTF8(zIn, zEof, iCode); + FTS5_READ_UTF8(zIn, zEof, iCode); if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); }while( iCode==0 ); @@ -263577,7 +268724,7 @@ static int fts5TriTokenize( FTS5_SKIP_UTF8(z1); memmove(aBuf, z1, zOut - z1); zOut -= (z1 - aBuf); - WRITE_UTF8(zOut, iCode); + FTS5_WRITE_UTF8(zOut, iCode); /* Update the aStart[] array */ aStart[0] = aStart[1]; @@ -265043,6 +270190,14 @@ static int fts5VocabCreateMethod( return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr); } +/* +** Return true if constraint iCons of pInfo uses the "binary" collation +** sequence. Or false it it uses anything else. +*/ +static int fts5VocabIsBinary(sqlite3_index_info *pInfo, int iCons){ + return 0==sqlite3_stricmp("binary", sqlite3_vtab_collation(pInfo, iCons)); +} + /* ** Implementation of the xBestIndex method. ** @@ -265073,7 +270228,7 @@ static int fts5VocabBestIndexMethod( for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; - if( p->iColumn==0 ){ /* term column */ + if( p->iColumn==0 && fts5VocabIsBinary(pInfo, i) ){ /* term column */ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i; if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i; if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i; @@ -265412,6 +270567,26 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ return rc; } +/* +** If value pVal is an SQLITE_TEXT value, return a pointer to a buffer +** containing the UTF-8 representation of the value, and set output +** parameter (*pnText) to the size of the buffer contents in bytes. Or, +** if pVal is some other type of value, return NULL and set (*pnText) +** to 0 before returning. +*/ +static const char *fts5VocabValueText(sqlite3_value *pVal, int *pnText){ + const char *zRet = 0; + int nRet = 0; + + if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ + zRet = (const char*)sqlite3_value_text(pVal); + nRet = sqlite3_value_bytes(pVal); + } + + *pnText = nRet; + return zRet; +} + /* ** This is the xFilter implementation for the virtual table. */ @@ -265439,25 +270614,31 @@ static int fts5VocabFilterMethod( UNUSED_PARAM2(zUnused, nUnused); fts5VocabResetCursor(pCsr); - if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; - if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; - if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; + if( idxNum & FTS5_VOCAB_TERM_EQ ){ + pEq = apVal[iVal++]; + if( sqlite3_value_type(pEq)!=SQLITE_TEXT ) pEq = 0; + } + if( idxNum & FTS5_VOCAB_TERM_GE ){ + pGe = apVal[iVal++]; + if( sqlite3_value_type(pGe)!=SQLITE_TEXT ) pGe = 0; + } + if( idxNum & FTS5_VOCAB_TERM_LE ){ + pLe = apVal[iVal++]; + if( sqlite3_value_type(pLe)!=SQLITE_TEXT ) pLe = 0; + } pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK); if( pEq ){ - zTerm = (const char *)sqlite3_value_text(pEq); - nTerm = sqlite3_value_bytes(pEq); + zTerm = fts5VocabValueText(pEq, &nTerm); f = FTS5INDEX_QUERY_NOTOKENDATA; }else{ if( pGe ){ - zTerm = (const char *)sqlite3_value_text(pGe); - nTerm = sqlite3_value_bytes(pGe); + zTerm = fts5VocabValueText(pGe, &nTerm); } if( pLe ){ - const char *zCopy = (const char *)sqlite3_value_text(pLe); + const char *zCopy = fts5VocabValueText(pLe, &pCsr->nLeTerm); if( zCopy==0 ) zCopy = ""; - pCsr->nLeTerm = sqlite3_value_bytes(pLe); - pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1); + pCsr->zLeTerm = sqlite3_malloc64((i64)pCsr->nLeTerm+1); if( pCsr->zLeTerm==0 ){ rc = SQLITE_NOMEM; }else{ diff --git a/src/bun.js/bindings/sqlite/sqlite3_local.h b/src/bun.js/bindings/sqlite/sqlite3_local.h index 79287579fffd..e2a078870482 100644 --- a/src/bun.js/bindings/sqlite/sqlite3_local.h +++ b/src/bun.js/bindings/sqlite/sqlite3_local.h @@ -147,12 +147,12 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.51.2" -#define SQLITE_VERSION_NUMBER 3051002 -#define SQLITE_SOURCE_ID "2026-01-09 17:27:48 b270f8339eb13b504d0b2ba154ebca966b7dde08e40c3ed7d559749818cb2075" -#define SQLITE_SCM_BRANCH "branch-3.51" -#define SQLITE_SCM_TAGS "release version-3.51.2" -#define SQLITE_SCM_DATETIME "2026-01-09T17:27:48.405Z" +#define SQLITE_VERSION "3.54.1" +#define SQLITE_VERSION_NUMBER 3054001 +#define SQLITE_SOURCE_ID "2026-10-16 14:45:20 555e07ef33f69a0957d24d8e555b702464a131d6f1607f4c3c1e4551e8e6ca76" +#define SQLITE_SCM_BRANCH "branch-3.54" +#define SQLITE_SCM_TAGS "release version-3.54.1" +#define SQLITE_SCM_DATETIME "2026-10-16T14:45:20.546Z" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -464,7 +464,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Internal use only */ +#define SQLITE_EMPTY 16 /* No content */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ @@ -579,7 +579,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) -#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ +#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal only */ /* ** CAPI3REF: Flags For File Open Operations @@ -1291,6 +1291,12 @@ struct sqlite3_io_methods { #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO +/* reserved file-control numbers: +** 101 +** 102 +** 103 +*/ + /* ** CAPI3REF: Mutex Handle @@ -1491,7 +1497,7 @@ typedef const char *sqlite3_filename; ** greater and the function pointer is not NULL) and will fall back ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. ** -** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces +** ^The xSetSystemCall(), xGetSystemCall(), and xNextSystemCall() interfaces ** are not used by the SQLite core. These optional interfaces are provided ** by some VFSes to facilitate testing of the VFS code. By overriding ** system calls with functions under its control, a test program can @@ -1712,7 +1718,8 @@ SQLITE_API int sqlite3_os_end(void); ** are called "anytime configuration options". ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before ** [sqlite3_shutdown()] with a first argument that is not an anytime -** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. +** configuration option, then the sqlite3_config() call will +** return SQLITE_MISUSE. ** Note, however, that ^sqlite3_config() can be called as part of the ** implementation of an application-defined [sqlite3_os_init()]. ** @@ -2278,9 +2285,10 @@ struct sqlite3_mem_methods { ** 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. -**
  • 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" +**

  • 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. ** @@ -2568,12 +2576,15 @@ struct sqlite3_mem_methods { ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] **

    SQLITE_DBCONFIG_STMT_SCANSTATUS
    **
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in -** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears -** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() -** statistics. For statistics to be collected, the flag must be set on -** the database handle both when the SQL statement is prepared and when it -** is stepped. The flag is set (collection of statistics is enabled) -** by default.

    This option takes two arguments: an integer and a pointer to +** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears +** a flag that enables collection of run-time performance statistics +** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle] +** columns of the [bytecode virtual table]. +** For statistics to be collected, the flag must be set on +** the database handle both when the SQL statement is +** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped]. +** The flag is set (collection of statistics is enabled) by default. +**

    This option takes two arguments: an integer and a pointer to ** an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the statement scanstatus option. If the second argument ** is not NULL, then the value of the statement scanstatus setting after @@ -2646,16 +2657,34 @@ struct sqlite3_mem_methods { ** comments are allowed in SQL text after processing the first argument. **

    ** +** [[SQLITE_DBCONFIG_FP_DIGITS]] +**
    SQLITE_DBCONFIG_FP_DIGITS
    +**
    The SQLITE_DBCONFIG_FP_DIGITS setting is a small integer that determines +** the number of significant digits that SQLite will attempt to preserve when +** converting floating point numbers (IEEE 754 "doubles") into text. The +** default value 17, as of SQLite version 3.52.0. The value was 15 in all +** prior versions.

    +** This option takes two arguments which are an integer and a pointer +** to an integer. The first argument is a small integer, between 3 and 23, or +** zero. The FP_DIGITS setting is changed to that small integer, or left +** unaltered if the first argument is zero or out of range. The second argument +** is a pointer to an integer. If the pointer is not NULL, then the value of +** the FP_DIGITS setting, after possibly being modified by the first +** arguments, is written into the integer to which the second argument points. +**

    +** ** ** ** [[DBCONFIG arguments]]

    Arguments To SQLITE_DBCONFIG Options

    ** **

    Most of the SQLITE_DBCONFIG options take two arguments, so that the ** overall call to [sqlite3_db_config()] has a total of four parameters. -** The first argument (the third parameter to sqlite3_db_config()) is an integer. -** The second argument is a pointer to an integer. If the first argument is 1, -** then the option becomes enabled. If the first integer argument is 0, then the -** option is disabled. If the first argument is -1, then the option setting +** The first argument (the third parameter to sqlite3_db_config()) is +** an integer. +** The second argument is a pointer to an integer. If the first argument is 1, +** then the option becomes enabled. If the first integer argument is 0, +** then the option is disabled. +** If the first argument is -1, then the option setting ** is unchanged. The second argument, the pointer to an integer, may be NULL. ** If the second argument is not NULL, then a value of 0 or 1 is written into ** the integer to which the second argument points, depending on whether the @@ -2663,9 +2692,10 @@ struct sqlite3_mem_methods { ** the first argument. ** **

    While most SQLITE_DBCONFIG options use the argument format -** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME] -** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the -** documentation of those exceptional options for details. +** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME], +** [SQLITE_DBCONFIG_LOOKASIDE], and [SQLITE_DBCONFIG_FP_DIGITS] options +** are different. See the documentation of those exceptional options for +** details. */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ @@ -2690,7 +2720,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_FP_DIGITS 1023 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1023 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -2930,8 +2961,9 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*); ** These routines are useful during command-line input to determine if the ** currently entered text seems to form a complete SQL statement or ** if additional input is needed before sending the text into -** SQLite for parsing. ^These routines return 1 if the input string -** appears to be a complete SQL statement. ^A statement is judged to be +** SQLite for parsing. ^The sqlite3_complete(X) and sqlite3_complete16(X) +** routines return 1 if the input string X appears to be a complete SQL +** statement. ^A statement is judged to be ** complete if it ends with a semicolon token and is not a prefix of a ** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within ** string literals or quoted identifier names or comments are not @@ -2939,11 +2971,25 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*); ** embedded) and thus do not count as a statement terminator. ^Whitespace ** and comments that follow the final semicolon are ignored. ** -** ^These routines return 0 if the statement is incomplete. ^If a -** memory allocation fails, then SQLITE_NOMEM is returned. -** -** ^These routines do not parse the SQL statements and thus -** will not detect syntactically incorrect SQL. +** ^The sqlite3_complete(X) and sqlite3_complete16(X) routines return 0 +** if the statement is incomplete. ^If a memory allocation fails, then +** SQLITE_NOMEM is returned. +** +** The [sqlite3_incomplete(X)] routine is similar to [sqlite3_complete(X)] +** except that sqlite3_incomplete(X) returns SQLITE_OK if the input X is +** complete, SQLITE_EMPTY if input X consists entirely of whitespace and/or +** comments, SQLITE_MISUSE if X is a NULL pointer, and some other non-zero +** value if X is incomplete. The non-zero return from +** sqlite3_incomplete(X) contains additional information about what is +** needed to complete the input X. See the header comment on the +** implemenation of the sqlite3_incomplete() routine for a full description +** of its non-zero return values. The sqlite3_incomplete(X) interface +** is only available for UTF-8 text. +** +** ^None of these routines do a full parse the SQL statements and thus +** will not detect syntactically incorrect SQL. They only determine if +** input text has properly terminated comments, string literals, and +** quoted identifiers, and if the statement ends with a semicolon. ** ** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior ** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked @@ -2951,14 +2997,15 @@ SQLITE_API int sqlite3_is_interrupted(sqlite3*); ** then the return value from sqlite3_complete16() will be non-zero ** regardless of whether or not the input SQL is complete.)^ ** -** The input to [sqlite3_complete()] must be a zero-terminated -** UTF-8 string. +** The X input to [sqlite3_complete(X)] and [sqlite3_incomplete(X)] +** must be a zero-terminated UTF-8 string. ** ** The input to [sqlite3_complete16()] must be a zero-terminated ** UTF-16 string in native byte order. */ SQLITE_API int sqlite3_complete(const char *sql); SQLITE_API int sqlite3_complete16(const void *sql); +SQLITE_API sqlite3_int64 sqlite3_incomplete(const char *sql); /* ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors @@ -3371,7 +3418,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** ** ^The first parameter to the authorizer callback is a copy of the third ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter -** to the callback is an integer [SQLITE_COPY | action code] that specifies +** to the callback is an integer [SQLITE_READ | action code] that specifies ** the particular action to be authorized. ^The third through sixth parameters ** to the callback are either NULL pointers or zero-terminated strings ** that contain additional details about the action to be authorized. @@ -3414,21 +3461,33 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** previous call.)^ ^Disable the authorizer by installing a NULL callback. ** The authorizer is disabled by default. ** -** The authorizer callback must not do anything that will modify +**

    Limitations And Caveats

      +** +**
    • The authorizer callback must not do anything that will modify ** the database connection that invoked the authorizer callback. ** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** -** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +**
    • ^When [sqlite3_prepare_v2()] is used to prepare a statement, the ** statement might be re-prepared during [sqlite3_step()] due to a ** schema change. Hence, the application should ensure that the ** correct authorizer callback remains in place during the [sqlite3_step()]. ** -** ^Note that the authorizer callback is invoked only during +**
    • ^The authorizer callback is invoked only during ** [sqlite3_prepare()] or its variants. Authorization is not ** performed during statement evaluation in [sqlite3_step()], unless ** as stated in the previous paragraph, sqlite3_step() invokes ** sqlite3_prepare_v2() to reprepare a statement after a schema change. +** +**
    • Authorizer callbacks for the expressions of a +** [generated column] are invoked when the schema is parsed (and specifically +** when the [CREATE TABLE] statement that contains the generated column is +** parsed) not when the generated column is used in a DML statement. +** This is deliberate, as one of the purposes of generated columns +** is to give schema designers the ability to provide gated access +** to privileged columns and/or functions. +** +**
    */ SQLITE_API int sqlite3_set_authorizer( sqlite3*, @@ -3469,6 +3528,11 @@ SQLITE_API int sqlite3_set_authorizer( ** is the name of the inner-most trigger or view that is responsible for ** the access attempt or NULL if this access attempt is directly from ** top-level SQL code. +** +** The case of strings in the 3rd through the 6th argument to the +** authorization callback is arbitrary. Authorization callbacks +** implementations should use [sqlite3_stricmp()] or similar when +** doing comparisons against those values. */ /******************************************* 3rd ************ 4th ***********/ #define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ @@ -3503,9 +3567,14 @@ SQLITE_API int sqlite3_set_authorizer( #define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ #define SQLITE_FUNCTION 31 /* NULL Function Name */ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ -#define SQLITE_COPY 0 /* No longer used */ #define SQLITE_RECURSIVE 33 /* NULL NULL */ +/* +** Note: The SQLITE_COPY macro (with value 0) used to be one of the +** action codes above. That macro has now been repurposed as a possible +** value to the 3rd argument to sqlite3_result_str(). +*/ + /* ** CAPI3REF: Deprecated Tracing And Profiling Functions ** DEPRECATED @@ -4012,8 +4081,7 @@ SQLITE_API int sqlite3_open_v2( ** ** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a ** 64-bit signed integer and returns that integer, or D if P does not -** exist. If the value of P is something other than an integer, then -** zero is returned. +** exist or if the value of P is something other than an integer. ** ** The sqlite3_uri_key(F,N) returns a pointer to the name (not ** the value) of the N-th query parameter for filename F, or a NULL @@ -4172,6 +4240,7 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); **
  • sqlite3_errmsg() **
  • sqlite3_errmsg16() **
  • sqlite3_error_offset() +**
  • sqlite3_db_handle() ** ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language @@ -4218,7 +4287,7 @@ SQLITE_API const char *sqlite3_errstr(int); SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* -** CAPI3REF: Set Error Codes And Message +** CAPI3REF: Set Error Code And Message ** METHOD: sqlite3 ** ** Set the error code of the database handle passed as the first argument @@ -4335,7 +4404,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** or in an ORDER BY or GROUP BY clause.
  • )^ ** ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
    SQLITE_LIMIT_EXPR_DEPTH
    -**
    The maximum depth of the parse tree on any expression.
    )^ +**
    The maximum depth of the parse tree on any expression and +** the maximum nesting depth for subqueries and VIEWs
    )^ +** +** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(
    SQLITE_LIMIT_PARSER_DEPTH
    +**
    The maximum depth of the LALR(1) parser stack used to analyze +** input SQL statements.
    )^ ** ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
    SQLITE_LIMIT_COMPOUND_SELECT
    **
    The maximum number of terms in a compound SELECT statement.
    )^ @@ -4362,11 +4436,20 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); **
    The maximum index number of any [parameter] in an SQL statement.)^ ** ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
    SQLITE_LIMIT_TRIGGER_DEPTH
    -**
    The maximum depth of recursion for triggers.
    )^ +**
    The maximum depth of recursion for triggers, and the maximum +** nesting depth for separate triggers.
    )^ ** ** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
    SQLITE_LIMIT_WORKER_THREADS
    **
    The maximum number of auxiliary worker threads that a single ** [prepared statement] may start.
    )^ +** +** [[SQLITE_LIMIT_SCHEMA]] ^(
    SQLITE_LIMIT_SCHEMA
    +**
    The maximum number of objects (tables, indexes, triggers, and views) +** defined by the database schema.
    )^ +** +** [[SQLITE_LIMIT_TRIGGER_STEPS]] ^(
    SQLITE_LIMIT_TRIGGER_STEPS
    +**
    The maximum number of SQL statements that can be contained within +** a single trigger.
    )^ ** */ #define SQLITE_LIMIT_LENGTH 0 @@ -4381,6 +4464,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 +#define SQLITE_LIMIT_PARSER_DEPTH 12 +#define SQLITE_LIMIT_SCHEMA 13 +#define SQLITE_LIMIT_TRIGGER_STEPS 14 /* ** CAPI3REF: Prepare Flags @@ -4425,12 +4511,29 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** fails, the sqlite3_prepare_v3() call returns the same error indications ** with or without this flag; it just omits the call to [sqlite3_log()] that ** logs the error. +** +** [[SQLITE_PREPARE_FROM_DDL]]
    SQLITE_PREPARE_FROM_DDL
    +**
    The SQLITE_PREPARE_FROM_DDL flag causes the SQL compiler to enforce +** security constraints that would otherwise only be enforced when parsing +** the database schema. In other words, the SQLITE_PREPARE_FROM_DDL flag +** causes the SQL compiler to treat the SQL statement being prepared as if +** it had come from an attacker. When SQLITE_PREPARE_FROM_DDL is used and +** [SQLITE_DBCONFIG_TRUSTED_SCHEMA] is off, SQL functions may only be called +** if they are tagged with [SQLITE_INNOCUOUS] and virtual tables may only +** be used if they are tagged with [SQLITE_VTAB_INNOCUOUS]. Best practice +** is to use the SQLITE_PREPARE_FROM_DDL option when preparing any SQL that +** is derived from parts of the database schema. In particular, virtual +** table implementations that run SQL statements that are derived from +** arguments to their CREATE VIRTUAL TABLE statement should always use +** [sqlite3_prepare_v3()] and set the SQLITE_PREPARE_FROM_DDL flag to +** prevent bypass of the [SQLITE_DBCONFIG_TRUSTED_SCHEMA] security checks. ** */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 #define SQLITE_PREPARE_NO_VTAB 0x04 #define SQLITE_PREPARE_DONT_LOG 0x10 +#define SQLITE_PREPARE_FROM_DDL 0x20 /* ** CAPI3REF: Compiling An SQL Statement @@ -4444,8 +4547,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** ** The preferred routine to use is [sqlite3_prepare_v2()]. The ** [sqlite3_prepare()] interface is legacy and should be avoided. -** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used -** for special purposes. +** [sqlite3_prepare_v3()] has an extra +** [SQLITE_PREPARE_FROM_DDL|"prepFlags" option] that is sometimes +** needed for special purpose or to pass along security restrictions. ** ** The use of the UTF-8 interfaces is preferred, as SQLite currently ** does all parsing using UTF-8. The UTF-16 interfaces are provided @@ -4474,6 +4578,8 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** the nul-terminator. ** Note that nByte measures the length of the input in bytes, not ** characters, even for the UTF-16 interfaces. +** For the sqlite3_prepare16() and sqlite3_prepare16_v2() interfaces, +** the nByte value must be even or undefined behavior can result. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only @@ -4850,8 +4956,8 @@ typedef struct sqlite3_context sqlite3_context; ** it should be a pointer to well-formed UTF16 text. ** ^If the third parameter to sqlite3_bind_text64() is not NULL, then ** it should be a pointer to a well-formed unicode string that is -** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 -** otherwise. +** either UTF8 if the sixth parameter is SQLITE_UTF8 or SQLITE_UTF8_ZT, +** or UTF16 otherwise. ** ** [[byte-order determination rules]] ^The byte-order of ** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) @@ -4897,10 +5003,15 @@ typedef struct sqlite3_context sqlite3_context; ** object and pointer to it must remain valid until then. ^SQLite will then ** manage the lifetime of its private copy. ** -** ^The sixth argument to sqlite3_bind_text64() must be one of -** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] -** to specify the encoding of the text in the third parameter. If -** the sixth argument to sqlite3_bind_text64() is not one of the +** ^The sixth argument (the E argument) +** to sqlite3_bind_text64(S,K,Z,N,D,E) must be one of +** [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE] to specify the encoding of the text in the +** third parameter, Z. The special value [SQLITE_UTF8_ZT] means that the +** string argument is both UTF-8 encoded and is zero-terminated. In other +** words, SQLITE_UTF8_ZT means that the Z array is allocated to hold at +** least N+1 bytes and that the Z[N] byte is zero. If +** the E argument to sqlite3_bind_text64(S,K,Z,N,D,E) is not one of the ** allowed values shown above, or if the text encoding is different ** from the encoding specified by the sixth parameter, then the behavior ** is undefined. @@ -5215,7 +5326,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** [prepared statement]. ^In the "v2" interface, ** the more specific error code is returned directly by sqlite3_step(). ** -** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** [SQLITE_MISUSE] means that this routine was called inappropriately. ** Perhaps it was called on a [prepared statement] that has ** already been [sqlite3_finalize | finalized] or on one that had ** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could @@ -5767,6 +5878,52 @@ SQLITE_API int sqlite3_create_window_function( ** ** These constants define integer codes that represent the various ** text encodings supported by SQLite. +** +**
    +** [[SQLITE_UTF8]]
    SQLITE_UTF8
    Text is encoding as UTF-8
    +** +** [[SQLITE_UTF16LE]]
    SQLITE_UTF16LE
    Text is encoding as UTF-16 +** with each code point being expressed "little endian" - the least significant +** byte first. This is the usual encoding, for example on Windows.
    +** +** [[SQLITE_UTF16BE]]
    SQLITE_UTF16BE
    Text is encoding as UTF-16 +** with each code point being expressed "big endian" - the most significant +** byte first. This encoding is less common, but is still sometimes seen, +** specially on older systems. +** +** [[SQLITE_UTF16]]
    SQLITE_UTF16
    Text is encoding as UTF-16 +** with each code point being expressed either little endian or as big +** endian, according to the native endianness of the host computer. +** +** [[SQLITE_ANY]]
    SQLITE_ANY
    This encoding value may only be used +** to declare the preferred text for [application-defined SQL functions] +** created using [sqlite3_create_function()] and similar. If the preferred +** encoding (the 4th parameter to sqlite3_create_function() - the eTextRep +** parameter) is SQLITE_ANY, that indicates that the function does not have +** a preference regarding the text encoding of its parameters and can take +** any text encoding that the SQLite core find convenient to supply. This +** option is deprecated. Please do not use it in new applications. +** +** [[SQLITE_UTF16_ALIGNED]]
    SQLITE_UTF16_ALIGNED
    This encoding +** value may be used as the 3rd parameter (the eTextRep parameter) to +** [sqlite3_create_collation()] and similar. This encoding value means +** that the application-defined collating sequence created expects its +** input strings to be in UTF16 in native byte order, and that the start +** of the strings must be aligned to a 2-byte boundary. +** +** [[SQLITE_UTF8_ZT]]
    SQLITE_UTF8_ZT
    This option can only be +** used to specify the text encoding to strings input to +** [sqlite3_result_text64()] and [sqlite3_bind_text64()]. +** The SQLITE_UTF8_ZT encoding means that the input string (call it "z") +** is UTF-8 encoded and that it is zero-terminated. If the length parameter +** (call it "n") is non-negative, this encoding option means that the caller +** guarantees that z array contains at least n+1 bytes and that the z[n] +** byte has a value of zero. +** This option gives the same output as SQLITE_UTF8, but can be more efficient +** by avoiding the need to make a copy of the input string, in some cases. +** However, if z is allocated to hold fewer than n+1 bytes or if the +** z[n] byte is not zero, undefined behavior may result. +**
    */ #define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ #define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ @@ -5774,6 +5931,7 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_ANY 5 /* Deprecated */ #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ +#define SQLITE_UTF8_ZT 16 /* Zero-terminated UTF8 */ /* ** CAPI3REF: Function Flags @@ -6008,26 +6166,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** the SQL function that supplied the [sqlite3_value*] parameters. ** ** As long as the input parameter is correct, these routines can only -** fail if an out-of-memory error occurs during a format conversion. -** Only the following subset of interfaces are subject to out-of-memory -** errors: -** -**
      -**
    • sqlite3_value_blob() -**
    • sqlite3_value_text() -**
    • sqlite3_value_text16() -**
    • sqlite3_value_text16le() -**
    • sqlite3_value_text16be() -**
    • sqlite3_value_bytes() -**
    • sqlite3_value_bytes16() -**
    -** +** fail if an out-of-memory error occurs while trying to do a +** UTF8→UTF16 or UTF16→UTF8 conversion. ** If an out-of-memory error occurs, then the return value from these ** routines is the same as if the column had contained an SQL NULL value. -** Valid SQL NULL returns can be distinguished from out-of-memory errors -** by invoking the [sqlite3_errcode()] immediately after the suspect +** If the input sqlite3_value was not obtained from [sqlite3_value_dup()], +** then valid SQL NULL returns can also be distinguished from +** out-of-memory errors after extracting the value +** by invoking the [sqlite3_errcode()] immediately after the suspicious ** return value is obtained and before any ** other SQLite interface is called on the same [database connection]. +** If the input sqlite3_value was obtained from sqlite3_value_dup() then +** it is disconnected from the database connection and so sqlite3_errcode() +** will not work. +** In that case, the only way to distinguish an out-of-memory +** condition from a true SQL NULL is to invoke sqlite3_value_type() on the +** input to see if it is NULL prior to trying to extract the value. */ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); SQLITE_API double sqlite3_value_double(sqlite3_value*); @@ -6054,7 +6208,8 @@ SQLITE_API int sqlite3_value_frombind(sqlite3_value*); ** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) ** returns something other than SQLITE_TEXT, then the return value from ** sqlite3_value_encoding(X) is meaningless. ^Calls to -** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)], +** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], +** [sqlite3_value_text16be(X)], ** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or ** [sqlite3_value_bytes16(X)] might change the encoding of the value X and ** thus change the return from subsequent calls to sqlite3_value_encoding(X). @@ -6185,17 +6340,17 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** query execution, under some circumstances the associated auxiliary data ** might be preserved. An example of where this might be useful is in a ** regular-expression matching function. The compiled version of the regular -** expression can be stored as auxiliary data associated with the pattern string. -** Then as long as the pattern string remains the same, +** expression can be stored as auxiliary data associated with the pattern +** string. Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data -** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument -** value to the application-defined function. ^N is zero for the left-most -** function argument. ^If there is no auxiliary data -** associated with the function argument, the sqlite3_get_auxdata(C,N) interface -** returns a NULL pointer. +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary +** data associated by the sqlite3_set_auxdata(C,N,P,X) function with the +** Nth argument value to the application-defined function. ^N is zero +** for the left-most function argument. ^If there is no auxiliary data +** associated with the function argument, the sqlite3_get_auxdata(C,N) +** interface returns a NULL pointer. ** ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the ** N-th argument of the application-defined function. ^Subsequent @@ -6279,10 +6434,14 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi ** ** There is no limit (other than available memory) on the number of different ** client data pointers (with different names) that can be attached to a -** single database connection. However, the implementation is optimized -** for the case of having only one or two different client data names. -** Applications and wrapper libraries are discouraged from using more than -** one client data name each. +** single database connection. However, the current implementation stores +** the content on a linked list. Insert and retrieval performance will +** be proportional to the number of entries. The design use case, and +** the use case for which the implementation is optimized, is +** that an application will store only small number of client data names, +** typically just one or two. This interface is not intended to be a +** generalized key/value store for thousands or millions of keys. It +** will work for that, but performance might be disappointing. ** ** There is no way to enumerate the client data pointers ** associated with a database connection. The N parameter can be thought @@ -6340,7 +6499,11 @@ typedef void (*sqlite3_destructor_type)(void*); ** ** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N) ** interfaces set the result of the application-defined function to be -** a BLOB containing all zero bytes and N bytes in size. +** a BLOB containing all zero bytes and N bytes in size. The +** zeroblob64(C,N) interface returns a [result code], which is normally +** [SQLITE_OK] but might be some other value if the requested operation +** could not be complete, for example if insufficient memory is available +** or if the value of N is out of range. ** ** ^The sqlite3_result_double() interface sets the result from ** an application-defined function to be a floating point value specified @@ -6390,10 +6553,14 @@ typedef void (*sqlite3_destructor_type)(void*); ** set the return value of the application-defined function to be ** a text string which is represented as UTF-8, UTF-16 native byte order, ** UTF-16 little endian, or UTF-16 big endian, respectively. -** ^The sqlite3_result_text64() interface sets the return value of an +** ^The sqlite3_result_text64(C,Z,N,D,E) interface sets the return value of an ** application-defined function to be a text string in an encoding -** specified by the fifth (and last) parameter, which must be one -** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. +** specified the E parameter, which must be one +** of [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE]. ^The special value [SQLITE_UTF8_ZT] means that +** the result text is both UTF-8 and zero-terminated. In other words, +** SQLITE_UTF8_ZT means that the Z array holds at least N+1 bytes and that +** the Z[N] is zero. ** ^SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. ** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces @@ -6480,7 +6647,7 @@ SQLITE_API void sqlite3_result_int(sqlite3_context*, int); SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); SQLITE_API void sqlite3_result_null(sqlite3_context*); SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); -SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, +SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char *z, sqlite3_uint64 n, void(*)(void*), unsigned char encoding); SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); @@ -7419,7 +7586,7 @@ SQLITE_API int sqlite3_table_column_metadata( ** ^The sqlite3_load_extension() interface attempts to load an ** [SQLite extension] library contained in the file zFile. If ** the file cannot be loaded directly, attempts are made to load -** with various operating-system specific extensions added. +** with various operating-system specific filename extensions added. ** So for example, if "samplelib" cannot be loaded, then names like ** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might ** be tried also. @@ -7427,10 +7594,10 @@ 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 -** 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".)^ +** If that does not work, it tries names of the form "sqlite3_X_init" +** where X consists of the lower-case equivalent of all ASCII alphabetic +** characters or all ASCII alphanumeric characters in the filename from +** the last "/" to the first following "." and omitting any initial "lib".)^ ** ^The sqlite3_load_extension() interface returns ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. ** ^If an error occurs and pzErrMsg is not 0, then the @@ -7504,7 +7671,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); **
     **    int xEntryPoint(
     **      sqlite3 *db,
    -**      const char **pzErrMsg,
    +**      char **pzErrMsg,
     **      const struct sqlite3_api_routines *pThunk
     **    );
     ** 
    )^ @@ -8254,13 +8421,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix ** and Windows. ** -** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor -** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex -** implementation is included with the library. In this case the -** application must supply a custom mutex implementation using the -** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function -** before calling sqlite3_initialize() or any other public sqlite3_ -** function that calls sqlite3_initialize(). ** ** ^The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() @@ -8615,6 +8775,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 #define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ +#define SQLITE_TESTCTRL_ATOF 34 #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* @@ -8680,8 +8841,8 @@ SQLITE_API int sqlite3_keyword_check(const char*,int); **
  • ^The sqlite3_str object is created using [sqlite3_str_new()]. **
  • ^Text is appended to the sqlite3_str object using various ** methods, such as [sqlite3_str_appendf()]. -**
  • ^The sqlite3_str object is destroyed and the string it created -** is returned using the [sqlite3_str_finish()] interface. +**
  • The sqlite3_str object is destroyed and the string it created +** is returned using [sqlite3_str_finish()] or [sqlite3_result_str()]. ** */ typedef struct sqlite3_str sqlite3_str; @@ -8723,17 +8884,56 @@ SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); ** pass the returned value to [sqlite3_free()] to avoid a memory leak. ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any ** errors were encountered during construction of the string. ^The -** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the +** [sqlite3_str_finish(X)] interface might also return a NULL pointer if the ** string in [sqlite3_str] object X is zero bytes long. +** +** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object +** X and the string content it contains. Calling sqlite3_str_free(X) is +** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)). */ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); +SQLITE_API void sqlite3_str_free(sqlite3_str*); + +/* +** CAPI3REF: Return A Dynamic String From an SQL Function +** +** The [sqlite3_result_str(C,S,F)] interface causes the +** [sqlite3_str|dynamic string] S to become the return value for the +** application-defined function or virtual table that uses +** [sqlite3_context] C. The F flag can be one of [SQLITE_COPY] +** or [SQLITE_XFER] or [SQLITE_FINISH]. +** +** If the dynamic string is invalid or incomplete due to an out-of-memory +** or string-too-large error, then this routine transfers that error +** over to the SQL function. +** +** If the F argument is SQLITE_COPY, then a copy of the dynamic string +** content is made and the dynamic string object is unchanged. +** If the F argument is SQLITE_XFER, then ownership of the content +** in the dynamic is transferred to the SQL function (via a pointer copy +** rather than a string copy) and the dynamic string is reset to an +** empty string. The SQLITE_FINISH value for F works like SQLITE_RESET +** except that it also invokes the [sqlite3_str_free(S)] destructor +** on the dynamic string object. +*/ +SQLITE_API void sqlite3_result_str(sqlite3_context*, sqlite3_str*, int); + +/* +** CAPI3REF: Control Flags For sqlite3_result_str() +** +** The following integers can be used as the third "F" argument +** to [sqlite3_result_str(C,S,F)]. +*/ +#define SQLITE_COPY 0 /* Results copied. Dynamic string unchanged */ +#define SQLITE_XFER 1 /* Results transfered. Dynamic string reset */ +#define SQLITE_FINISH 2 /* Like SQLITE_XFER, plus dynamic string freed */ /* ** CAPI3REF: Add Content To A Dynamic String ** METHOD: sqlite3_str ** -** These interfaces add content to an sqlite3_str object previously obtained -** from [sqlite3_str_new()]. +** These interfaces add or remove content to an sqlite3_str object +** previously obtained from [sqlite3_str_new()]. ** ** ^The [sqlite3_str_appendf(X,F,...)] and ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] @@ -8756,6 +8956,10 @@ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); ** ^The [sqlite3_str_reset(X)] method resets the string under construction ** inside [sqlite3_str] object X back to zero bytes in length. ** +** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string +** under construction to be N bytes or less. This routine is a no-op if +** N is negative or if the string is already N bytes or smaller in size. +** ** These methods do not return a result code. ^If an error occurs, that fact ** is recorded in the [sqlite3_str] object and can be recovered by a ** subsequent call to [sqlite3_str_errcode(X)]. @@ -8766,6 +8970,7 @@ SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); SQLITE_API void sqlite3_str_reset(sqlite3_str*); +SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N); /* ** CAPI3REF: Status Of A Dynamic String @@ -10296,7 +10501,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** ** sqlite3_vtab_distinct() return value ** Rows are returned in aOrderBy order -** Rows with the same value in all aOrderBy columns are adjacent +** Rows with the same value in all aOrderBy columns are +** adjacent ** Duplicates over all colUsed columns may be omitted ** 0yesyesno ** 1noyesno @@ -10305,8 +10511,8 @@ 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 the same value for sorting purposes, two NULL values are considered -** to be the same. In other words, the comparison operator is "IS" +** 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 "==". ** ** If a virtual table implementation is unable to meet the requirements @@ -10599,9 +10805,9 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** a variable pointed to by the "pOut" parameter. ** ** The "flags" parameter must be passed a mask of flags. At present only -** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX +** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX ** is specified, then status information is available for all elements -** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If +** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API @@ -10615,7 +10821,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value ** ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. ** -** See also: [sqlite3_stmt_scanstatus_reset()] +** See also: [sqlite3_stmt_scanstatus_reset()] and the +** [nexec and ncycle] columns of the [bytecode virtual table]. */ SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ @@ -11086,8 +11293,19 @@ SQLITE_API unsigned char *sqlite3_serialize( ** used. The serialized database P is N bytes in size. M is the size ** of the buffer P, which might be larger than N. If M is larger than ** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then -** SQLite is permitted to add content to the in-memory database as -** long as the total size does not exceed M bytes. +** SQLite is permitted to add content to the in-memory database, in +** page-sized chunks, as long as the total size does not exceed M bytes. +** +** The parameter M must be greater than or equal to N. Ideally, M +** should have a value which is N+(512×K)+20 where K determines how +** must extra space is available to hold new content as the database +** grows. K can be 0 if the database is read-only. +** +** If the database content in P is malformed in a malicious way then +** it is possible that SQLite might try to read a few more than N bytes +** from P. If the veracity of the database content P is uncertain, +** then applications are advised to allocate about 20 extra bytes on +** the end of the P buffer to avoid a memory error. ** ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will ** invoke sqlite3_free() on the serialization buffer when the database @@ -11157,19 +11375,42 @@ SQLITE_API int sqlite3_deserialize( /* ** CAPI3REF: Bind array values to the CARRAY table-valued function ** -** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to -** one of the first argument of the [carray() table-valued function]. The -** S parameter is a pointer to the [prepared statement] that uses the carray() -** functions. I is the parameter index to be bound. P is a pointer to the -** array to be bound, and N is the number of eements in the array. The -** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], -** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to -** indicate the datatype of the array being bound. The X argument is not a -** NULL pointer, then SQLite will invoke the function X on the P parameter -** after it has finished using P, even if the call to -** sqlite3_carray_bind() fails. The special-case finalizer -** SQLITE_TRANSIENT has no effect here. -*/ +** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to +** parameter that is the first argument of the [carray() table-valued function]. +** The S parameter is a pointer to the [prepared statement] that uses the +** carray() functions. I is the parameter index to be bound. I must be the +** index of the parameter that is the first argument to the carray() +** table-valued function. P is a pointer to the array to be bound, and N +** is the number of elements in the array. The F argument is one of +** constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], +** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], +** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P. +** +** If the X argument is not a NULL pointer or one of the special +** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke +** the function X with argument D when it is finished using the data in P. +** The call to X(D) is a destructor for the array P. The destructor X(D) +** is invoked even if the call to sqlite3_carray_bind_v2() fails. If the X +** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes +** that the data static and the destructor is never invoked. If the X +** parameter is the special-case value [SQLITE_TRANSIENT], then +** sqlite3_carray_bind_v2() makes its own private copy of the data prior +** to returning and never invokes the destructor X. +** +** The sqlite3_carray_bind() function works the same as sqlite3_carray_bind_v2() +** with a D parameter set to P. In other words, +** sqlite3_carray_bind(S,I,P,N,F,X) is same as +** sqlite3_carray_bind_v2(S,I,P,N,F,X,P). +*/ +SQLITE_API int sqlite3_carray_bind_v2( + sqlite3_stmt *pStmt, /* Statement to be bound */ + int i, /* Parameter index */ + void *aData, /* Pointer to array data */ + int nData, /* Number of data elements */ + int mFlags, /* CARRAY flags */ + void (*xDel)(void*), /* Destructor for aData */ + void *pDel /* Optional argument to xDel() */ +); SQLITE_API int sqlite3_carray_bind( sqlite3_stmt *pStmt, /* Statement to be bound */ int i, /* Parameter index */ @@ -12713,11 +12954,23 @@ SQLITE_API int sqlite3changeset_apply_v3( ** database behave as if they were declared with "ON UPDATE NO ACTION ON ** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL ** or SET DEFAULT. +** +**
    SQLITE_CHANGESETAPPLY_NOUPDATELOOP
    +** Sometimes, a changeset contains two or more update statements such that +** although after applying all updates the database will contain no +** constraint violations, no single update can be applied before the others. +** The simplest example of this is a pair of UPDATEs that have "swapped" +** two column values with a UNIQUE constraint. +**

    +** Usually, sqlite3changeset_apply() and similar functions work hard to try +** to find a way to apply such a changeset. However, if this flag is set, +** then all such updates are considered CONSTRAINT conflicts. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 #define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 +#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -13200,6 +13453,232 @@ SQLITE_API int sqlite3session_config(int op, void *pArg); */ #define SQLITE_SESSION_CONFIG_STRMSIZE 1 +/* +** CAPI3REF: Configure a changegroup object +** +** Configure the changegroup object passed as the first argument. +** At present the only valid value for the second parameter is +** [SQLITE_CHANGEGROUP_CONFIG_PATCHSET]. +*/ +SQLITE_API int sqlite3changegroup_config(sqlite3_changegroup*, int, void *pArg); + +/* +** CAPI3REF: Options for sqlite3changegroup_config(). +** +** The following values may be passed as the 2nd parameter to +** sqlite3changegroup_config(). +** +**

    SQLITE_CHANGEGROUP_CONFIG_PATCHSET
    +** A changegroup object generates either a changeset or patchset. Usually, +** this is determined by whether the first call to sqlite3changegroup_add() +** is passed a changeset or a patchset. Or, if the first changes are added +** to the changegroup object using the sqlite3changegroup_change_xxx() +** APIs, then this option may be used to configure whether the changegroup +** object generates a changeset or patchset. +** +** When this option is invoked, parameter pArg must point to a value of +** type int. If the changegroup currently contains zero changes, and the +** value of the int variable is zero or greater than zero, then the +** changegroup is configured to generate a changeset or patchset, +** respectively. It is a no-op, not an error, if the changegroup is not +** configured because it has already started accumulating changes. +** +** Before returning, the int variable is set to 0 if the changegroup is +** configured to generate a changeset, or 1 if it is configured to generate +** a patchset. +*/ +#define SQLITE_CHANGEGROUP_CONFIG_PATCHSET 1 + + +/* +** CAPI3REF: Begin adding a change to a changegroup +** +** This API is used, in concert with other sqlite3changegroup_change_xxx() +** APIs, to add changes to a changegroup object one at a time. To add a +** single change, the caller must: +** +** 1. Invoke sqlite3changegroup_change_begin() to indicate the type of +** change (INSERT, UPDATE or DELETE), the affected table and whether +** or not the change should be marked as indirect. +** +** 2. Invoke sqlite3changegroup_change_int64() or one of the other four +** value functions - _null(), _double(), _text() or _blob() - one or +** more times to specify old.* and new.* values for the change being +** constructed. +** +** 3. Invoke sqlite3changegroup_change_finish() to either finish adding +** the change to the group, or to discard the change altogether. +** +** The first argument to this function must be a pointer to the existing +** changegroup object that the change will be added to. The second argument +** must be SQLITE_INSERT, SQLITE_UPDATE or SQLITE_DELETE. The third is the +** name of the table that the change affects, and the fourth is a boolean +** flag specifying whether the change should be marked as "indirect" (if +** bIndirect is non-zero) or not indirect (if bIndirect is zero). +** +** Following a successful call to this function, this function may not be +** called again on the same changegroup object until after +** sqlite3changegroup_change_finish() has been called. Doing so is an +** SQLITE_MISUSE error. +** +** The changegroup object passed as the first argument must be already +** configured with schema data for the specified table. It may be configured +** either by calling sqlite3changegroup_schema() with a database that contains +** the table, or sqlite3changegroup_add() with a changeset that contains the +** table. If the changegroup object has not been configured with a schema for +** the specified table when this function is called, SQLITE_ERROR is returned. +** +** If successful, SQLITE_OK is returned. Otherwise, if an error occurs, an +** SQLite error code is returned. In this case, if argument pzErr is non-NULL, +** then (*pzErr) may be set to point to a buffer containing a utf-8 formated, +** nul-terminated, English language error message. It is the responsibility +** of the caller to eventually free this buffer using sqlite3_free(). +*/ +SQLITE_API int sqlite3changegroup_change_begin( + sqlite3_changegroup*, + int eOp, + const char *zTab, + int bIndirect, + char **pzErr +); + +/* +** CAPI3REF: Add a 64-bit integer to a changegroup +** +** This function may only be called between a successful call to +** sqlite3changegroup_change_begin() and its matching +** sqlite3changegroup_change_finish() call. If it is called at any +** other time, it is an SQLITE_MISUSE error. Calling this function +** specifies a 64-bit integer value to be used in the change currently being +** added to the changegroup object passed as the first argument. +** +** The second parameter, bNew, specifies whether the value is to be part of +** the new.* (if bNew is non-zero) or old.* (if bNew is zero) record of +** the change under construction. If this does not match the type of change +** specified by the preceding call to sqlite3changegroup_change_begin() (i.e. +** an old.* value for an SQLITE_INSERT change, or a new.* value for an +** SQLITE_DELETE), then SQLITE_ERROR is returned. +** +** The third parameter specifies the column of the old.* or new.* record that +** the value will be a part of. If the specified table has an explicit primary +** key, then this is the index of the table column, numbered from 0 in the order +** specified within the CREATE TABLE statement. Or, if the table uses an +** implicit rowid key, then the column 0 is the rowid and the explicit columns +** are numbered starting from 1. If the iCol parameter is less than 0 or greater +** than the index of the last column in the table, SQLITE_RANGE is returned. +** +** The fourth parameter is the integer value to use as part of the old.* or +** new.* record. +** +** If this call is successful, SQLITE_OK is returned. Otherwise, if an +** error occurs, an SQLite error code is returned. +*/ +SQLITE_API int sqlite3changegroup_change_int64( + sqlite3_changegroup*, + int bNew, + int iCol, + sqlite3_int64 iVal +); + +/* +** CAPI3REF: Add a NULL to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). Except that +** it configures the change currently under construction with a NULL value +** instead of a 64-bit integer. +*/ +SQLITE_API int sqlite3changegroup_change_null(sqlite3_changegroup*, int, int); + +/* +** CAPI3REF: Add an double to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). Except that +** it configures the change currently being constructed with a real value +** instead of a 64-bit integer. +*/ +SQLITE_API int sqlite3changegroup_change_double(sqlite3_changegroup*, int, int, double); + +/* +** CAPI3REF: Add a text value to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). It configures +** the currently accumulated change with a text value instead of a 64-bit +** integer. Parameter pVal points to a buffer containing the text encoded using +** utf-8. Parameter nVal may either be the size of the text value in bytes, or +** else a negative value, in which case the buffer pVal points to is assumed to +** be nul-terminated. +*/ +SQLITE_API int sqlite3changegroup_change_text( + sqlite3_changegroup*, int, int, const char *pVal, int nVal +); + +/* +** CAPI3REF: Add a blob to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). It configures +** the currently accumulated change with a blob value instead of a 64-bit +** integer. Parameter pVal points to a buffer containing the blob. Parameter +** nVal is the size of the blob in bytes. +*/ +SQLITE_API int sqlite3changegroup_change_blob( + sqlite3_changegroup*, int, int, const void *pVal, int nVal +); + +/* +** CAPI3REF: Finish adding one-at-at-time changes to a changegroup +** +** This function may only be called following a successful call to +** sqlite3changegroup_change_begin(). Otherwise, it is an SQLITE_MISUSE error. +** +** If parameter bDiscard is non-zero, then the current change is simply +** discarded. In this case this function is always successful and SQLITE_OK +** returned. +** +** If parameter bDiscard is zero, then an attempt is made to add the current +** change to the changegroup. Assuming the changegroup is configured to +** produce a changeset (not a patchset), this requires that: +** +** * If the change is an INSERT or DELETE, then a value must be specified +** for all columns of the new.* or old.* record, respectively. +** +** * If the change is an UPDATE record, then values must be provided for +** the PRIMARY KEY columns of the old.* record, but must not be provided +** for PRIMARY KEY columns of the new.* record. +** +** * If the change is an UPDATE record, then for each non-PRIMARY KEY +** column in the old.* record for which a value has been provided, a +** value must also be provided for the same column in the new.* record. +** Similarly, for each non-PK column in the old.* record for which +** a value is not provided, a value must not be provided for the same +** column in the new.* record. +** +** * All values specified for PRIMARY KEY columns must be non-NULL. +** +** Otherwise, it is an error. +** +** If the changegroup already contains a change for the same row (identified +** by PRIMARY KEY columns), then the current change is combined with the +** existing change in the same way as for sqlite3changegroup_add(). +** +** For a patchset, all of the above rules apply except that it doesn't matter +** whether or not values are provided for the non-PK old.* record columns +** for an UPDATE or DELETE change. This means that code used to produce +** a changeset using the sqlite3changegroup_change_xxx() APIs may also +** be used to produce patchsets. +** +** If the call is successful, SQLITE_OK is returned. Otherwise, if an error +** occurs, an SQLite error code is returned. If an error is returned and +** parameter pzErr is not NULL, then (*pzErr) may be set to point to a buffer +** containing a nul-terminated, utf-8 encoded, English language error message. +** It is the responsibility of the caller to eventually free any such error +** message buffer using sqlite3_free(). +*/ +SQLITE_API int sqlite3changegroup_change_finish( + sqlite3_changegroup*, + int bDiscard, + char **pzErr +); + /* ** Make sure we can call this stuff from C++. */