From 9f8c98155f9131b2f4da8c05a2fd9cf936728343 Mon Sep 17 00:00:00 2001 From: Florent De'Neve Date: Thu, 3 Aug 2023 09:46:36 +0100 Subject: [PATCH] Revert "Update SQLite to 3.43.0 (JSON optimizations)" --- libstuff/sqlite3.c | 12297 +++++++++++++------------------------------ libstuff/sqlite3.h | 381 +- 2 files changed, 3610 insertions(+), 9068 deletions(-) diff --git a/libstuff/sqlite3.c b/libstuff/sqlite3.c index 1a19b45a3..4bb785113 100644 --- a/libstuff/sqlite3.c +++ b/libstuff/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version $VERSION. By combining all the individual C code files into this +** version 3.41.2. 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 @@ -16,9 +16,6 @@ ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. -** -** The content in this amalgamation comes from Fossil check-in -** d6ded3234bbfa3226ef718eec8d0ce06ae2. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -54,11 +51,11 @@ ** used on lines of code that actually ** implement parts of coverage testing. ** -** OPTIMIZATION-IF-TRUE - This branch is allowed to always be false +** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false ** and the correct answer is still obtained, ** though perhaps more slowly. ** -** OPTIMIZATION-IF-FALSE - This branch is allowed to always be true +** OPTIMIZATION-IF-FALSE - This branch is allowed to alway be true ** and the correct answer is still obtained, ** though perhaps more slowly. ** @@ -127,10 +124,6 @@ #define SQLITE_4_BYTE_ALIGNED_MALLOC #endif /* defined(_MSC_VER) && !defined(_WIN64) */ -#if !defined(HAVE_LOG2) && defined(_MSC_VER) && _MSC_VER<1800 -#define HAVE_LOG2 0 -#endif /* !defined(HAVE_LOG2) && defined(_MSC_VER) && _MSC_VER<1800 */ - #endif /* SQLITE_MSVC_H */ /************** End of msvc.h ************************************************/ @@ -460,9 +453,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.43.0" -#define SQLITE_VERSION_NUMBER 3043000 -#define SQLITE_SOURCE_ID "2023-07-28 18:52:09 1d6ded3234bbfa3226ef718eec8d0ce06ae2844628866cb6197383c9bf06267c" +#define SQLITE_VERSION "3.41.2" +#define SQLITE_VERSION_NUMBER 3041002 +#define SQLITE_SOURCE_ID "2023-03-22 13:35:58 b7a144c499446125964bbe21f3447cdfaa9de6a9743eeb970abfcbe277f14827" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -1504,7 +1497,7 @@ struct sqlite3_io_methods { ** by clients within the current process, only within other processes. ** **
  • [[SQLITE_FCNTL_CKSM_FILE]] -** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use internally by the +** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the ** [checksum VFS shim] only. ** **
  • [[SQLITE_FCNTL_RESET_CACHE]] @@ -1969,23 +1962,20 @@ SQLITE_API int sqlite3_os_end(void); ** must ensure that no other SQLite interfaces are invoked by other ** threads while sqlite3_config() is running. ** -** The first argument to sqlite3_config() is an integer -** [configuration option] that determines -** what property of SQLite is to be configured. Subsequent arguments -** vary depending on the [configuration option] -** in the first argument. -** -** For most configuration options, the sqlite3_config() interface +** The sqlite3_config() interface ** may only be invoked prior to library initialization using ** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. -** The exceptional configuration options that may be invoked at any time -** 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. +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. ** Note, however, that ^sqlite3_config() can be called as part of the ** implementation of an application-defined [sqlite3_os_init()]. ** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. @@ -2093,23 +2083,6 @@ struct sqlite3_mem_methods { ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. ** -** Most of the configuration options for sqlite3_config() -** will only work if invoked prior to [sqlite3_initialize()] or after -** [sqlite3_shutdown()]. The few exceptions to this rule are called -** "anytime configuration options". -** ^Calling [sqlite3_config()] with a first argument that is not an -** anytime configuration option in between calls to [sqlite3_initialize()] and -** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE. -** -** The set of anytime configuration options can change (by insertions -** and/or deletions) from one release of SQLite to the next. -** As of SQLite version 3.42.0, the complete set of anytime configuration -** options is: -** -** ** New configuration options may be added in future releases of SQLite. ** Existing configuration options might be discontinued. Applications ** should check the return code from [sqlite3_config()] to make sure that @@ -2456,28 +2429,28 @@ struct sqlite3_mem_methods { ** compile-time option is not set, then the default maximum is 1073741824. ** */ -#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ -#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ -#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ -#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ -#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ -#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ -#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ -#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ -#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ -/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ -#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ -#define SQLITE_CONFIG_PCACHE 14 /* no-op */ -#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ -#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ -#define SQLITE_CONFIG_URI 17 /* int */ -#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ -#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ -#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ -#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ @@ -2712,7 +2685,7 @@ struct sqlite3_mem_methods { ** ** ** [[SQLITE_DBCONFIG_DQS_DML]] -**
    SQLITE_DBCONFIG_DQS_DML
    +**
    SQLITE_DBCONFIG_DQS_DML **
    The SQLITE_DBCONFIG_DQS_DML option activates or deactivates ** the legacy [double-quoted string literal] misfeature for DML statements ** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The @@ -2721,7 +2694,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_DQS_DDL]] -**
    SQLITE_DBCONFIG_DQS_DDL
    +**
    SQLITE_DBCONFIG_DQS_DDL **
    The SQLITE_DBCONFIG_DQS option activates or deactivates ** the legacy [double-quoted string literal] misfeature for DDL statements, ** such as CREATE TABLE and CREATE INDEX. The @@ -2730,7 +2703,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] -**
    SQLITE_DBCONFIG_TRUSTED_SCHEMA
    +**
    SQLITE_DBCONFIG_TRUSTED_SCHEMA **
    The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to ** assume that database schemas are untainted by malicious content. ** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite @@ -2750,7 +2723,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] -**
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
    +**
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT **
    The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates ** the legacy file format flag. When activated, this flag causes all newly ** created database file to have a schema format version number (the 4-byte @@ -2759,7 +2732,7 @@ struct sqlite3_mem_methods { ** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, ** newly created databases are generally not understandable by SQLite versions ** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there -** is now scarcely any need to generate database files that are compatible +** is now scarcely any need to generated database files that are compatible ** all the way back to version 3.0.0, and so this setting is of little ** practical use, but is provided so that SQLite can continue to claim the ** ability to generate new database files that are compatible with version @@ -2768,40 +2741,8 @@ struct sqlite3_mem_methods { ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index. This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support -** either generated columns or descending indexes. +** either generated columns or decending indexes. **
    -** -** [[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 -** 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 -** processing the first argument is written into the integer that the second -** argument points to. -**
    -** -** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] -**
    SQLITE_DBCONFIG_REVERSE_SCANORDER
    -**
    The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order -** in which tables and indexes are scanned so that the scans start at the end -** and work toward the beginning rather than starting at the beginning and -** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the -** same as setting [PRAGMA reverse_unordered_selects]. This option takes -** two arguments which are an integer and a pointer to an integer. The first -** argument is 1, 0, or -1 to enable, disable, or leave unchanged the -** reverse scan order flag, respectively. If the second argument is not NULL, -** then 0 or 1 is written into the integer that the second argument points to -** depending on if the reverse scan order flag is set after processing the -** first argument. -**
    -** ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ @@ -2822,9 +2763,7 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ -#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ -#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -3049,7 +2988,6 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*); ** ** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether ** or not an interrupt is currently in effect for [database connection] D. -** It returns 1 if an interrupt is currently in effect, or 0 otherwise. */ SQLITE_API void sqlite3_interrupt(sqlite3*); SQLITE_API int sqlite3_is_interrupted(sqlite3*); @@ -3703,10 +3641,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** M argument should be the bitwise OR-ed combination of ** zero or more [SQLITE_TRACE] constants. ** -** ^Each call to either sqlite3_trace(D,X,P) or sqlite3_trace_v2(D,M,X,P) -** overrides (cancels) all prior calls to sqlite3_trace(D,X,P) or -** sqlite3_trace_v2(D,M,X,P) for the [database connection] D. Each -** database connection may have at most one trace callback. +** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides +** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). ** ** ^The X callback is invoked whenever any of the events identified by ** mask M occur. ^The integer return value from the callback is currently @@ -4075,7 +4011,7 @@ SQLITE_API int sqlite3_open_v2( ** as F) must be one of: ** @@ -4188,7 +4124,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** -** These interfaces are provided for use by [VFS shim] implementations and +** These interfces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of @@ -4735,41 +4671,6 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); */ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); -/* -** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement -** METHOD: sqlite3_stmt -** -** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN -** setting for prepared statement S. If E is zero, then S becomes -** a normal prepared statement. If E is 1, then S behaves as if -** its SQL text began with "EXPLAIN". If E is 2, then S behaves as if -** its SQL text began with "EXPLAIN QUERY PLAN". -** -** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared. -** SQLite tries to avoid a reprepare, but a reprepare might be necessary -** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode. -** -** Because of the potential need to reprepare, a call to -** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be -** reprepared because it was created using sqlite3_prepare() instead of -** the newer sqlite_prepare_v2() or sqlite3_prepare_v3() interfaces and -** hence has no saved SQL text with which to reprepare. -** -** Changing the explain setting for a prepared statement does not change -** the original SQL text for the statement. Hence, if the SQL text originally -** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0) -** is called to convert the statement into an ordinary statement, the EXPLAIN -** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S) -** output, even though the statement now acts like a normal SQL statement. -** -** This routine returns SQLITE_OK if the explain mode is successfully -** changed, or an error code if the explain mode could not be changed. -** The explain mode cannot be changed while a statement is active. -** Hence, it is good practice to call [sqlite3_reset(S)] -** immediately prior to calling sqlite3_stmt_explain(S,E). -*/ -SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode); - /* ** CAPI3REF: Determine If A Prepared Statement Has Been Reset ** METHOD: sqlite3_stmt @@ -4933,7 +4834,7 @@ typedef struct sqlite3_context sqlite3_context; ** with it may be passed. ^It is called to dispose of the BLOB or string even ** if the call to the bind API fails, except the destructor is not called if ** the third parameter is a NULL pointer or the fourth parameter is negative. -** ^ (2) The special constant, [SQLITE_STATIC], may be passed to indicate that +** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that ** the application remains responsible for disposing of the object. ^In this ** case, the object and the provided pointer to it must remain valid until ** either the prepared statement is finalized or the same SQL parameter is @@ -5612,26 +5513,14 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); ** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S ** back to the beginning of its program. ** -** ^The return code from [sqlite3_reset(S)] indicates whether or not -** the previous evaluation of prepared statement S completed successfully. -** ^If [sqlite3_step(S)] has never before been called on S or if -** [sqlite3_step(S)] has not been called since the previous call -** to [sqlite3_reset(S)], then [sqlite3_reset(S)] will return -** [SQLITE_OK]. +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. ** ** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S indicated an error, then ** [sqlite3_reset(S)] returns an appropriate [error code]. -** ^The [sqlite3_reset(S)] interface might also return an [error code] -** if there were no prior errors but the process of resetting -** the prepared statement caused a new error. ^For example, if an -** [INSERT] statement with a [RETURNING] clause is only stepped one time, -** that one call to [sqlite3_step(S)] might return SQLITE_ROW but -** the overall statement might still fail and the [sqlite3_reset(S)] call -** might return SQLITE_BUSY if locking constraints prevent the -** database change from committing. Therefore, it is important that -** applications check the return code from [sqlite3_reset(S)] even if -** no prior call to [sqlite3_step(S)] indicated a problem. ** ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. @@ -5848,7 +5737,7 @@ SQLITE_API int sqlite3_create_window_function( ** [application-defined SQL function] ** that has side-effects or that could potentially leak sensitive information. ** This will prevent attacks in which an application is tricked -** into using a database file that has had its schema surreptitiously +** into using a database file that has had its schema surreptiously ** modified to invoke the application-defined function in ways that are ** harmful. **

    @@ -6619,13 +6508,6 @@ SQLITE_API void sqlite3_activate_cerod( ** of the default VFS is not implemented correctly, or not implemented at ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. -** -** If a negative argument is passed to sqlite3_sleep() the results vary by -** VFS and operating system. Some system treat a negative argument as an -** instruction to sleep forever. Others understand it to mean do not sleep -** at all. ^In SQLite version 3.42.0 and later, a negative -** argument passed into sqlite3_sleep() is changed to zero before it is relayed -** down into the xSleep method of the VFS. */ SQLITE_API int sqlite3_sleep(int); @@ -8253,9 +8135,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** is undefined if the mutex is not currently entered by the ** calling thread or is not currently allocated. ** -** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), -** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer, -** then any of the four routines behaves as a no-op. +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ @@ -8525,8 +8407,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 -#define SQLITE_TESTCTRL_USELONGDOUBLE 34 -#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -9558,8 +9439,8 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is cancelled. ^The blocked connections -** unlock-notify callback may also be cancelled by closing the blocked +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** ** The unlock-notify callback is not reentrant. If an application invokes @@ -9982,7 +9863,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** [[SQLITE_VTAB_DIRECTONLY]]

    SQLITE_VTAB_DIRECTONLY
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation ** prohibits that virtual table from being used from within triggers and ** views. **
    @@ -9990,28 +9871,18 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** [[SQLITE_VTAB_INNOCUOUS]]
    SQLITE_VTAB_INNOCUOUS
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. **
    -** -** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]
    SQLITE_VTAB_USES_ALL_SCHEMAS
    -**
    Calls of the form -** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation -** instruct the query planner to begin at least a read transaction on -** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the -** virtual table is used. -**
    ** */ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 #define SQLITE_VTAB_INNOCUOUS 2 #define SQLITE_VTAB_DIRECTONLY 3 -#define SQLITE_VTAB_USES_ALL_SCHEMAS 4 /* ** CAPI3REF: Determine The Virtual Table Conflict Policy @@ -10172,7 +10043,7 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); ** communicated to the xBestIndex method as a ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use ** this constraint, it must set the corresponding -** aConstraintUsage[].argvIndex to a positive integer. ^(Then, under +** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under ** the usual mode of handling IN operators, SQLite generates [bytecode] ** that invokes the [xFilter|xFilter() method] once for each value ** on the right-hand side of the IN operator.)^ Thus the virtual table @@ -10601,7 +10472,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** When the [sqlite3_blob_write()] API is used to update a blob column, ** the pre-update hook is invoked with SQLITE_DELETE. This is because the ** in this case the new values are not available. In this case, when a -** callback made with op==SQLITE_DELETE is actually a write using the +** callback made with op==SQLITE_DELETE is actuall a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the ** pre-update hook is being invoked for some other reason, including a @@ -10984,98 +10855,6 @@ SQLITE_API int sqlite3_deserialize( #define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ -/* -** Access details of recent COMMIT commands. This function allows various -** details related to the most recent COMMIT command to be accessed. -** The requested value is always returned via output parameter (*piVal). -** The specific value requested is identified by parameter op (see -** below). -** -** SQLITE_OK is returned if successful, or SQLITE_ERROR if the "op" or -** "zDb" paramters are unrecognized. -*/ -SQLITE_API int sqlite3_commit_status( - sqlite3 *db, /* Database handle */ - const char *zDb, /* Name of database - "main" etc. */ - int op, /* SQLITE_COMMIT_XXX constant */ - unsigned int *piVal /* OUT: Write requested value here */ -); - -/* -** The following describes the five requests supported by -** sqlite3_commit_status(), each identified by an SQLITE_COMMIT_XXX -** constant: -** -** SQLITE_COMMIT_FIRSTFRAME: -** In this case argument zDb must be "main", or "temp", or else the name of -** an attached database. If zDb does not correspond to any attached database, -** SQLITE_ERROR is returned. -** -** The final value of (*piVal) for this request is only defined if (a) the -** most recent attempt to write to the database connection was successful, -** (b) the most recent attempt to write to the database did write to database -** zDb, and (c) zDb is a wal mode database. -** -** If the above conditions are true, then output parameter (*piVal) is -** set to the frame number of the first frame written by the recent -** transaction. In wal mode, or in wal2 mode when a transaction is -** written into the *-wal file, the frame number indicates the frame's -** position in the wal file - frames are numbered starting from 1. In -** wal2 mode, when a transaction is written to the *-wal2 file, the frame -** number is the frame's position in the *-wal2 file, plus (1 << 31). -** -** Note: Although the a database may have up to (1<<32) pages, each wal -** file may contain at most (1<<31) frames. -** -** SQLITE_COMMIT_NFRAME: -** zDb is interpreted in the same way as, and the final value of (*piVal) -** is undefined, for SQLITE_COMMIT_FIRSTFRAME. -** -** Otherwise, (*piVal) is set to the number of frames written by the -** recent transaction. -** -** SQLITE_COMMIT_CONFLICT_DB: -** Parameter zDb is ignored for this request. The results of this -** request are only defined if the most recent attempt to write to -** the database handle was a BEGIN CONCURRENT transaction that -** failed with an SQLITE_BUSY_SNAPSHOT error. -** -** In other cases, (*piVal) is set to the index of the database -** on which the SQLITE_BUSY_SNAPSHOT error occurred (0 for main, -** a value of 2 or greater for an attached database). This value -** may be used with the sqlite3_db_name() API to find the name -** of the conflicting database. -** -** SQLITE_COMMIT_CONFLICT_FRAME: -** Parameter zDb is ignored for this request. The results of this -** request are only defined if the most recent attempt to write to -** the database handle was a BEGIN CONCURRENT transaction that -** failed with an SQLITE_BUSY_SNAPSHOT error. -** -** (*piVal) is set to the frame number of the conflicting frame for -** the recent SQLITE_BUSY_SNAPSHOT error. The conflicting transaction may -** be found by comparing this value with the FIRSTFRAME and -** NFRAME values for recent succesfully committed transactions on -** the same db. If the CONFLICT_FRAME value is F, then the conflicting -** transaction is the most recent successful commit for which -** (FIRSTFRAME <= F <= FIRSTFRAME+NFRAME) is true. -** -** SQLITE_COMMIT_CONFLICT_PGNO: -** Parameter zDb is ignored for this request. The results of this -** request are only defined if the previous attempt to write to -** the database using database handle db failed with -** SQLITE_BUSY_SNAPSHOT. -** -** Return the page number of the conflicting page for the most -** recent SQLITE_BUSY_SNAPSHOT error. -*/ -#define SQLITE_COMMIT_FIRSTFRAME 0 -#define SQLITE_COMMIT_NFRAME 1 -#define SQLITE_COMMIT_CONFLICT_DB 2 -#define SQLITE_COMMIT_CONFLICT_FRAME 3 -#define SQLITE_COMMIT_CONFLICT_PGNO 4 - - /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. @@ -11303,20 +11082,16 @@ SQLITE_API int sqlite3session_create( SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); /* -** CAPI3REF: Configure a Session Object +** CAPIREF: Conigure a Session Object ** METHOD: sqlite3_session ** ** This method is used to configure a session object after it has been -** created. At present the only valid values for the second parameter are -** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID]. +** created. At present the only valid value for the second parameter is +** [SQLITE_SESSION_OBJCONFIG_SIZE]. ** -*/ -SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); - -/* -** CAPI3REF: Options for sqlite3session_object_config +** Arguments for sqlite3session_object_config() ** -** The following values may passed as the the 2nd parameter to +** The following values may passed as the the 4th parameter to ** sqlite3session_object_config(). ** **
    SQLITE_SESSION_OBJCONFIG_SIZE
    @@ -11332,21 +11107,12 @@ SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg ** ** It is an error (SQLITE_MISUSE) to attempt to modify this setting after ** the first table has been attached to the session object. -** -**
    SQLITE_SESSION_OBJCONFIG_ROWID
    -** This option is used to set, clear or query the flag that enables -** collection of data for tables with no explicit PRIMARY KEY. -** -** Normally, tables with no explicit PRIMARY KEY are simply ignored -** by the sessions module. However, if this flag is set, it behaves -** as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted -** as their leftmost columns. -** -** It is an error (SQLITE_MISUSE) to attempt to modify this setting after -** the first table has been attached to the session object. */ -#define SQLITE_SESSION_OBJCONFIG_SIZE 1 -#define SQLITE_SESSION_OBJCONFIG_ROWID 2 +SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); + +/* +*/ +#define SQLITE_SESSION_OBJCONFIG_SIZE 1 /* ** CAPI3REF: Enable Or Disable A Session Object @@ -12509,23 +12275,9 @@ SQLITE_API int sqlite3changeset_apply_v2( ** Invert the changeset before applying it. This is equivalent to inverting ** a changeset using sqlite3changeset_invert() before applying it. It is ** an error to specify this flag with a patchset. -** -**
    SQLITE_CHANGESETAPPLY_IGNORENOOP
    -** Do not invoke the conflict handler callback for any changes that -** would not actually modify the database even if they were applied. -** Specifically, this means that the conflict handler is not invoked -** for: -**
      -**
    • a delete change if the row being deleted cannot be found, -**
    • an update change if the modified fields are already set to -** their new values in the conflicting row, or -**
    • an insert change if all fields of the conflicting row match -** the row being inserted. -**
    */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 -#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -13672,7 +13424,7 @@ struct fts5_api { ** level of recursion for each term. A stack overflow can result ** if the number of terms is too large. In practice, most SQL ** never has more than 3 or 4 terms. Use a value of 0 to disable -** any limit on the number of terms in a compound SELECT. +** any limit on the number of terms in a compount SELECT. */ #ifndef SQLITE_MAX_COMPOUND_SELECT # define SQLITE_MAX_COMPOUND_SELECT 500 @@ -13822,8 +13574,8 @@ struct fts5_api { #endif /* -** A few places in the code require atomic load/store of aligned -** integer values. +** WAL mode depends on atomic aligned 32-bit loads and stores in a few +** places. The following macros try to make this explicit. */ #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ @@ -13879,22 +13631,15 @@ struct fts5_api { #endif /* -** Macros to hint to the compiler that a function should or should not be +** A macro to hint to the compiler that a function should not be ** inlined. */ #if defined(__GNUC__) # define SQLITE_NOINLINE __attribute__((noinline)) -# define SQLITE_INLINE __attribute__((always_inline)) inline #elif defined(_MSC_VER) && _MSC_VER>=1310 # define SQLITE_NOINLINE __declspec(noinline) -# define SQLITE_INLINE __forceinline #else # define SQLITE_NOINLINE -# define SQLITE_INLINE -#endif -#if defined(SQLITE_COVERAGE_TEST) || defined(__STRICT_ANSI__) -# undef SQLITE_INLINE -# define SQLITE_INLINE #endif /* @@ -14776,31 +14521,8 @@ typedef INT16_TYPE LogEst; ** the end of buffer S. This macro returns true if P points to something ** contained within the buffer S. */ -#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) +#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) -/* -** P is one byte past the end of a large buffer. Return true if a span of bytes -** between S..E crosses the end of that buffer. In other words, return true -** if the sub-buffer S..E-1 overflows the buffer show last byte is P-1. -** -** S is the start of the span. E is one byte past the end of end of span. -** -** P -** |-----------------| FALSE -** |-------| -** S E -** -** P -** |-----------------| -** |-------| TRUE -** S E -** -** P -** |-----------------| -** |-------| FALSE -** S E -*/ -#define SQLITE_OVERFLOW(P,S,E) (((uptr)(S)<(uptr)(P))&&((uptr)(E)>(uptr)(P))) /* ** Macros to determine whether the machine is big or little endian, @@ -15034,7 +14756,7 @@ struct BusyHandler { /* ** Name of table that holds the database schema. ** -** The PREFERRED names are used wherever possible. But LEGACY is also +** The PREFERRED names are used whereever possible. But LEGACY is also ** used for backwards compatibility. ** ** 1. Queries can use either the PREFERRED or the LEGACY names @@ -15144,13 +14866,11 @@ typedef struct Cte Cte; typedef struct CteUse CteUse; typedef struct Db Db; typedef struct DbFixer DbFixer; -typedef struct DblDbl DblDbl; typedef struct Schema Schema; typedef struct Expr Expr; typedef struct ExprList ExprList; typedef struct FastPrng FastPrng; typedef struct FKey FKey; -typedef struct FpDecode FpDecode; typedef struct FuncDestructor FuncDestructor; typedef struct FuncDef FuncDef; typedef struct FuncDefHash FuncDefHash; @@ -15169,7 +14889,6 @@ typedef struct Parse Parse; typedef struct ParseCleanup ParseCleanup; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; -typedef struct RCStr RCStr; typedef struct RenameToken RenameToken; typedef struct Returning Returning; typedef struct RowSet RowSet; @@ -15747,7 +15466,7 @@ SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*); SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int); SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zSuper, int); -SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*, DbPage *pPage1, u32*); +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*, DbPage *pPage1, Pgno*); SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zSuper); SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); @@ -16170,7 +15889,9 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags); SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*); +#endif SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); @@ -16646,7 +16367,7 @@ typedef struct VdbeOpList VdbeOpList; /* 8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\ /* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x49, 0x49, 0x49,\ /* 24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\ -/* 32 */ 0x41, 0x01, 0x41, 0x41, 0x41, 0x01, 0x41, 0x41,\ +/* 32 */ 0x41, 0x01, 0x01, 0x01, 0x41, 0x01, 0x41, 0x41,\ /* 40 */ 0x41, 0x41, 0x41, 0x41, 0x26, 0x26, 0x23, 0x0b,\ /* 48 */ 0x01, 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ /* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x41,\ @@ -16658,7 +16379,7 @@ typedef struct VdbeOpList VdbeOpList; /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ /* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\ /* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ -/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ +/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,\ /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ @@ -16840,7 +16561,7 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); ** The VdbeCoverage macros are used to set a coverage testing point ** for VDBE branch instructions. The coverage testing points are line ** numbers in the sqlite3.c source file. VDBE branch coverage testing -** only works with an amalgamation build. That's ok since a VDBE branch +** only works with an amalagmation build. That's ok since a VDBE branch ** coverage build designed for testing the test suite only. No application ** should ever ship with VDBE branch coverage measuring turned on. ** @@ -16858,7 +16579,7 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); ** // NULL option is not possible ** ** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested -** // in distinguishing equal and not-equal. +** // in distingishing equal and not-equal. ** ** Every VDBE branch operation must be tagged with one of the macros above. ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and @@ -16868,7 +16589,7 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); ** During testing, the test application will invoke ** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback ** routine that is invoked as each bytecode branch is taken. The callback -** contains the sqlite3.c source line number of the VdbeCoverage macro and +** contains the sqlite3.c source line number ov the VdbeCoverage macro and ** flags to indicate whether or not the branch was taken. The test application ** is responsible for keeping track of this and reporting byte-code branches ** that are never taken. @@ -16916,10 +16637,6 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters(Vdbe*, int, int, int); SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); #endif -#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) -SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr); -#endif - #endif /* SQLITE_VDBE_H */ /************** End of vdbe.h ************************************************/ @@ -17207,7 +16924,7 @@ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); /* ** Default synchronous levels. ** -** Note that (for historical reasons) the PAGER_SYNCHRONOUS_* macros differ +** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ ** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1. ** ** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS @@ -17254,7 +16971,7 @@ struct Db { ** An instance of the following structure stores a database schema. ** ** Most Schema objects are associated with a Btree. The exception is -** the Schema for the TEMP database (sqlite3.aDb[1]) which is free-standing. +** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing. ** In shared cache mode, a single Schema object can be shared by multiple ** Btrees that refer to the same underlying BtShared object. ** @@ -17365,7 +17082,7 @@ struct Lookaside { LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE - LookasideSlot *pSmallInit; /* List of small buffers not previously used */ + LookasideSlot *pSmallInit; /* List of small buffers not prediously used */ LookasideSlot *pSmallFree; /* List of available small buffers */ void *pMiddle; /* First byte past end of full-size buffers and ** the first byte of LOOKASIDE_SMALL buffers */ @@ -17382,7 +17099,7 @@ struct LookasideSlot { #define EnableLookaside db->lookaside.bDisable--;\ db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue -/* Size of the smaller allocations in two-size lookaside */ +/* Size of the smaller allocations in two-size lookside */ #ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE # define LOOKASIDE_SMALL 0 #else @@ -17604,12 +17321,6 @@ struct sqlite3 { #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif -#ifndef SQLITE_OMIT_CONCURRENT - /* Return values for sqlite3_commit_status() requests: - ** SQLITE_COMMIT_CONFLICT_DB, CONFLICT_FRAME and CONFLICT_PGNO. - */ - u32 aCommit[5]; -#endif }; /* @@ -17652,7 +17363,7 @@ struct sqlite3 { #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ /* result set is empty */ #define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ -#define SQLITE_StmtScanStatus 0x00000400 /* Enable stmt_scanstats() counters */ +#define SQLITE_ReadUncommit 0x00000400 /* READ UNCOMMITTED in shared-cache */ #define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */ #define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */ #define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */ @@ -17678,7 +17389,6 @@ struct sqlite3 { /* DELETE, or UPDATE and return */ /* the count using a callback. */ #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ -#define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */ #define SQLITE_NoopUpdate 0x01000000 /* UPDATE operations are no-ops */ /* Flags used only if debugging */ @@ -17736,7 +17446,6 @@ struct sqlite3 { /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #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 */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -17819,7 +17528,6 @@ struct FuncDestructor { ** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG -** SQLITE_FUNC_BYTELEN == OPFLAG_BYTELENARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API ** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS -- opposite meanings!!! @@ -17827,7 +17535,7 @@ struct FuncDestructor { ** ** Note that even though SQLITE_FUNC_UNSAFE and SQLITE_INNOCUOUS have the ** same bit value, their meanings are inverted. SQLITE_FUNC_UNSAFE is -** used internally and if set means that the function has side effects. +** used internally and if set means tha the function has side effects. ** SQLITE_INNOCUOUS is used by application code and means "not unsafe". ** See multiple instances of tag-20230109-1. */ @@ -17838,7 +17546,6 @@ struct FuncDestructor { #define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ #define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ #define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ -#define SQLITE_FUNC_BYTELEN 0x00c0 /* Built-in octet_length() function */ #define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ /* 0x0200 -- available for reuse */ #define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */ @@ -18210,7 +17917,6 @@ struct VTable { sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ - u8 bAllSchemas; /* True if might use any attached schema */ u8 eVtabRisk; /* Riskiness of allowing hacker access */ int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ @@ -18418,7 +18124,7 @@ struct FKey { ** foreign key. ** ** The OE_Default value is a place holder that means to use whatever -** conflict resolution algorithm is required from context. +** conflict resolution algorthm is required from context. ** ** The following symbolic values are used to record which type ** of conflict resolution action to take. @@ -18591,7 +18297,6 @@ struct Index { ** expression, or a reference to a VIRTUAL column */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ - int mxSample; /* Number of slots allocated to aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ @@ -18832,7 +18537,7 @@ struct Expr { ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old ** EP_Unlikely: 134217728 times likelihood - ** TK_IN: ephemeral table holding RHS + ** TK_IN: ephemerial table holding RHS ** TK_SELECT_COLUMN: Number of columns on the LHS ** TK_SELECT: 1st register of result vector */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. @@ -18914,8 +18619,6 @@ struct Expr { */ #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) #define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0) -#define ExprUseWOfst(E) (((E)->flags&(EP_InnerON|EP_OuterON))==0) -#define ExprUseWJoin(E) (((E)->flags&(EP_InnerON|EP_OuterON))!=0) #define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0) #define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0) #define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0) @@ -19104,7 +18807,7 @@ struct SrcItem { unsigned notCte :1; /* This item may not match a CTE */ unsigned isUsing :1; /* u3.pUsing is valid */ unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ - unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ + unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */ unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ @@ -19782,7 +19485,6 @@ struct AuthContext { #define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ -#define OPFLAG_BYTELENARG 0xc0 /* OP_Column only for octet_length() */ #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ @@ -19925,25 +19627,6 @@ struct sqlite3_str { #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) -/* -** The following object is the header for an "RCStr" or "reference-counted -** string". An RCStr is passed around and used like any other char* -** that has been dynamically allocated. The important interface -** differences: -** -** 1. RCStr strings are reference counted. They are deallocated -** when the reference count reaches zero. -** -** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than -** sqlite3_free() -** -** 3. Make a (read-only) copy of a read-only RCStr string using -** sqlite3RCStrRef(). -*/ -struct RCStr { - u64 nRCRef; /* Number of references */ - /* Total structure size should be a multiple of 8 bytes for alignment */ -}; /* ** A pointer to this structure is used to communicate information @@ -19970,7 +19653,7 @@ typedef struct { /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning ** parameters are for temporary use during development, to help find -** optimal values for parameters in the query planner. The should not +** optimial values for parameters in the query planner. The should not ** be used on trunk check-ins. They are a temporary mechanism available ** for transient development builds only. ** @@ -19996,7 +19679,6 @@ struct Sqlite3Config { u8 bUseCis; /* Use covering indices for full-scans */ u8 bSmallMalloc; /* Avoid large memory allocations if true */ u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ - u8 bUseLongDouble; /* Make use of long double */ int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ @@ -20083,7 +19765,6 @@ struct Walker { void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ int walkerDepth; /* Number of subqueries */ u16 eCode; /* A small processing code */ - u16 mWFlags; /* Use-dependent flags */ union { /* Extra data for callback */ NameContext *pNC; /* Naming context */ int n; /* A counter */ @@ -20102,7 +19783,6 @@ struct Walker { struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ SrcItem *pSrcItem; /* A single FROM clause item */ DbFixer *pFix; /* See sqlite3FixSelect() */ - Mem *aMem; /* See sqlite3BtreeCursorHint() */ } u; }; @@ -20123,7 +19803,6 @@ struct DbFixer { /* Forward declarations */ SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); -SQLITE_PRIVATE int sqlite3WalkExprNN(Walker*, Expr*); SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*); @@ -20373,8 +20052,6 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); # define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) # define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) # define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80) -# define sqlite3JsonId1(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x42) -# define sqlite3JsonId2(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x46) #else # define sqlite3Toupper(x) toupper((unsigned char)(x)) # define sqlite3Isspace(x) isspace((unsigned char)(x)) @@ -20384,8 +20061,6 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); # define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) # define sqlite3Tolower(x) tolower((unsigned char)(x)) # define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') -# define sqlite3JsonId1(x) (sqlite3IsIdChar(x)&&(x)<'0') -# define sqlite3JsonId2(x) sqlite3IsIdChar(x) #endif SQLITE_PRIVATE int sqlite3IsIdChar(u8); @@ -20505,20 +20180,6 @@ struct PrintfArguments { sqlite3_value **apArg; /* The argument values */ }; -/* -** 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 */ -}; - -SQLITE_PRIVATE void sqlite3FpDecode(FpDecode*,double,int,int); SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) @@ -20593,10 +20254,6 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*); -SQLITE_PRIVATE void sqlite3TouchRegister(Parse*,int); -#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) -SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse*,int); -#endif #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); #endif @@ -20747,7 +20404,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList Expr*,ExprList*,u32,Expr*); SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); -SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); @@ -20809,7 +20466,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(const Parse*,const Expr*,const Expr*, int) SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*,Expr*,int); SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList*,const ExprList*, int); SQLITE_PRIVATE int sqlite3ExprImpliesExpr(const Parse*,const Expr*,const Expr*, int); -SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int,int); +SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int); SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); @@ -20838,7 +20495,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); -SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int); +SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif @@ -20960,7 +20617,6 @@ SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); - SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); SQLITE_PRIVATE i64 sqlite3RealToI64(double); SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*); @@ -21065,7 +20721,6 @@ SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); -SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*)); SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); @@ -21173,11 +20828,6 @@ SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); -SQLITE_PRIVATE char *sqlite3RCStrRef(char*); -SQLITE_PRIVATE void sqlite3RCStrUnref(char*); -SQLITE_PRIVATE char *sqlite3RCStrNew(u64); -SQLITE_PRIVATE char *sqlite3RCStrResize(char*,u64); - SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64); SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); @@ -21293,7 +20943,10 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); -SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse*); +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) +SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info*); +#endif SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); @@ -21429,7 +21082,6 @@ SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); #define sqlite3SelectExprHeight(x) 0 #define sqlite3ExprCheckHeight(x,y) #endif -SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr*,int); SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*); SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32); @@ -21541,12 +21193,6 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void); SQLITE_PRIVATE sqlite3_uint64 sqlite3Hwtime(void); #endif -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS -# define IS_STMT_SCANSTATUS(db) (db->flags & SQLITE_StmtScanStatus) -#else -# define IS_STMT_SCANSTATUS(db) 0 -#endif - #endif /* SQLITEINT_H */ /************** End of sqliteInt.h *******************************************/ @@ -22543,7 +22189,7 @@ SQLITE_PRIVATE const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP ** isalnum() 0x06 ** isxdigit() 0x08 ** toupper() 0x20 -** SQLite identifier character 0x40 $, _, or non-ascii +** SQLite identifier character 0x40 ** Quote character 0x80 ** ** Bit 0x20 is set if the mapped character requires translation to upper @@ -22689,7 +22335,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0, /* bSmallMalloc */ 1, /* bExtraSchemaChecks */ - sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ @@ -22738,7 +22383,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ #ifdef SQLITE_DEBUG - {0,0,0,0,0,0}, /* aTune */ + {0,0,0,0,0,0} /* aTune */ #endif }; @@ -22919,9 +22564,6 @@ typedef struct VdbeSorter VdbeSorter; /* Elements of the linked list at Vdbe.pAuxData */ typedef struct AuxData AuxData; -/* A cache of large TEXT or BLOB values in a VdbeCursor */ -typedef struct VdbeTxtBlbCache VdbeTxtBlbCache; - /* Types of VDBE cursors */ #define CURTYPE_BTREE 0 #define CURTYPE_SORTER 1 @@ -22953,7 +22595,6 @@ struct VdbeCursor { Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */ - Bool colCache:1; /* pCache pointer is initialized and non-NULL */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ union { /* pBtx for isEphermeral. pAltMap otherwise */ Btree *pBtx; /* Separate file holding temporary table */ @@ -22994,7 +22635,6 @@ struct VdbeCursor { #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif - VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ /* 2*nField extra array elements allocated for aType[], beyond the one ** static element declared in the structure. nField total array slots for @@ -23007,23 +22647,12 @@ struct VdbeCursor { #define IsNullCursor(P) \ ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) + /* ** A value for VdbeCursor.cacheStatus that means the cache is always invalid. */ #define CACHE_STALE 0 -/* -** Large TEXT or BLOB values can be slow to load, so we want to avoid -** loading them more than once. For that reason, large TEXT and BLOB values -** can be stored in a cache defined by this object, and attached to the -** VdbeCursor using the pCache field. -*/ -struct VdbeTxtBlbCache { - char *pCValue; /* A RCStr buffer to hold the value */ - i64 iOffset; /* File offset of the row being cached */ - int iCol; /* Column for which the cache is valid */ -}; - /* ** When a sub-program is executed (OP_Program), a structure of this type ** is allocated to store the current value of the program counter, as @@ -23344,18 +22973,16 @@ struct Vdbe { u32 nWrite; /* Number of write operations that have occurred */ #endif u16 nResColumn; /* Number of columns in one row of the result set */ - u16 nResAlloc; /* Column slots allocated to aColName[] */ u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 eVdbeState; /* On of the VDBE_*_STATE values */ bft expired:2; /* 1: recompile VM immediately 2: when convenient */ - bft explain:2; /* 0: normal, 1: EXPLAIN, 2: EXPLAIN QUERY PLAN */ + bft explain:2; /* True if EXPLAIN present on SQL command */ bft changeCntOn:1; /* True to update the change-counter */ bft usesStmtJournal:1; /* True if uses a statement journal */ bft readOnly:1; /* True for statements that do not write */ bft bIsReader:1; /* True for statements that read */ - bft haveEqpOps:1; /* Bytecode supports EXPLAIN QUERY PLAN */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */ @@ -23402,7 +23029,7 @@ struct PreUpdate { i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem *aNew; /* Array of new.* values */ - Table *pTab; /* Schema object being updated */ + Table *pTab; /* Schema object being upated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ }; @@ -23492,7 +23119,6 @@ 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 sqlite3VdbeMemMakeWriteable(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); @@ -24056,7 +23682,6 @@ struct DateTime { char validTZ; /* True (1) if tz is valid */ char tzSet; /* Timezone was set explicitly */ char isError; /* An overflow has occurred */ - char useSubsec; /* Display subsecond precision */ }; @@ -24089,8 +23714,8 @@ struct DateTime { */ static int getDigits(const char *zDate, const char *zFormat, ...){ /* The aMx[] array translates the 3rd character of each format - ** spec into a max size: a b c d e f */ - static const u16 aMx[] = { 12, 14, 24, 31, 59, 14712 }; + ** spec into a max size: a b c d e f */ + static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 }; va_list ap; int cnt = 0; char nextC; @@ -24371,11 +23996,6 @@ static int parseDateOrTime( }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ setRawDateNumber(p, r); return 0; - }else if( (sqlite3StrICmp(zDate,"subsec")==0 - || sqlite3StrICmp(zDate,"subsecond")==0) - && sqlite3NotPureFunc(context) ){ - p->useSubsec = 1; - return setDateTimeToCurrent(context, p); } return 1; } @@ -24431,14 +24051,17 @@ static void computeYMD(DateTime *p){ ** Compute the Hour, Minute, and Seconds from the julian day number. */ static void computeHMS(DateTime *p){ - int day_ms, day_min; /* milliseconds, minutes into the day */ + int s; if( p->validHMS ) return; computeJD(p); - day_ms = (int)((p->iJD + 43200000) % 86400000); - p->s = (day_ms % 60000)/1000.0; - day_min = day_ms/60000; - p->m = day_min % 60; - p->h = day_min / 60; + s = (int)((p->iJD + 43200000) % 86400000); + p->s = s/1000.0; + s = (int)p->s; + p->s -= s; + p->h = s/3600; + s -= p->h*3600; + p->m = s/60; + p->s += s - p->m*60; p->rawS = 0; p->validHMS = 1; } @@ -24617,25 +24240,6 @@ static const struct { { 4, "year", 14713.0, 31536000.0 }, }; -/* -** If the DateTime p is raw number, try to figure out if it is -** a julian day number of a unix timestamp. Set the p value -** appropriately. -*/ -static void autoAdjustDate(DateTime *p){ - if( !p->rawS || p->validJD ){ - p->rawS = 0; - }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ - && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ - ){ - double r = p->s*1000.0 + 210866760000000.0; - clearYMD_HMS_TZ(p); - p->iJD = (sqlite3_int64)(r + 0.5); - p->validJD = 1; - p->rawS = 0; - } -} - /* ** Process a modifier to a date-time stamp. The modifiers are ** as follows: @@ -24679,8 +24283,19 @@ static int parseModifier( */ if( sqlite3_stricmp(z, "auto")==0 ){ if( idx>1 ) return 1; /* IMP: R-33611-57934 */ - autoAdjustDate(p); - rc = 0; + if( !p->rawS || p->validJD ){ + rc = 0; + p->rawS = 0; + }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ + && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ + ){ + r = p->s*1000.0 + 210866760000000.0; + clearYMD_HMS_TZ(p); + p->iJD = (sqlite3_int64)(r + 0.5); + p->validJD = 1; + p->rawS = 0; + rc = 0; + } } break; } @@ -24795,22 +24410,8 @@ static int parseModifier( ** ** Move the date backwards to the beginning of the current day, ** or month or year. - ** - ** subsecond - ** subsec - ** - ** Show subsecond precision in the output of datetime() and - ** unixepoch() and strftime('%s'). */ - if( sqlite3_strnicmp(z, "start of ", 9)!=0 ){ - if( sqlite3_stricmp(z, "subsec")==0 - || sqlite3_stricmp(z, "subsecond")==0 - ){ - p->useSubsec = 1; - rc = 0; - } - break; - } + if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break; if( !p->validJD && !p->validYMD && !p->validHMS ) break; z += 9; computeYMD(p); @@ -24846,73 +24447,18 @@ static int parseModifier( case '9': { double rRounder; int i; - int Y,M,D,h,m,x; - const char *z2 = z; - char z0 = z[0]; - for(n=1; z[n]; n++){ - if( z[n]==':' ) break; - if( sqlite3Isspace(z[n]) ) break; - if( z[n]=='-' ){ - if( n==5 && getDigits(&z[1], "40f", &Y)==1 ) break; - if( n==6 && getDigits(&z[1], "50f", &Y)==1 ) break; - } - } + for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ - assert( rc==1 ); + rc = 1; break; } - if( z[n]=='-' ){ - /* A modifier of the form (+|-)YYYY-MM-DD adds or subtracts the - ** specified number of years, months, and days. MM is limited to - ** the range 0-11 and DD is limited to 0-30. - */ - if( z0!='+' && z0!='-' ) break; /* Must start with +/- */ - if( n==5 ){ - if( getDigits(&z[1], "40f-20a-20d", &Y, &M, &D)!=3 ) break; - }else{ - assert( n==6 ); - if( getDigits(&z[1], "50f-20a-20d", &Y, &M, &D)!=3 ) break; - z++; - } - if( M>=12 ) break; /* M range 0..11 */ - if( D>=31 ) break; /* D range 0..30 */ - computeYMD_HMS(p); - p->validJD = 0; - if( z0=='-' ){ - p->Y -= Y; - p->M -= M; - D = -D; - }else{ - p->Y += Y; - p->M += M; - } - x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; - p->Y += x; - p->M -= x*12; - computeJD(p); - p->validHMS = 0; - p->validYMD = 0; - p->iJD += (i64)D*86400000; - if( z[11]==0 ){ - rc = 0; - break; - } - if( sqlite3Isspace(z[11]) - && getDigits(&z[12], "20c:20e", &h, &m)==2 - ){ - z2 = &z[12]; - n = 2; - }else{ - break; - } - } - if( z2[n]==':' ){ + if( z[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be ** omitted. */ - + const char *z2 = z; DateTime tx; sqlite3_int64 day; if( !sqlite3Isdigit(*z2) ) z2++; @@ -24922,7 +24468,7 @@ static int parseModifier( tx.iJD -= 43200000; day = tx.iJD/86400000; tx.iJD -= day*86400000; - if( z0=='-' ) tx.iJD = -tx.iJD; + if( z[0]=='-' ) tx.iJD = -tx.iJD; computeJD(p); clearYMD_HMS_TZ(p); p->iJD += tx.iJD; @@ -24938,7 +24484,7 @@ static int parseModifier( if( n>10 || n<3 ) break; if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; computeJD(p); - assert( rc==1 ); + rc = 1; rRounder = r<0 ? -0.5 : +0.5; for(i=0; iM += (int)r; @@ -25062,11 +24609,7 @@ static void unixepochFunc( DateTime x; if( isDate(context, argc, argv, &x)==0 ){ computeJD(&x); - if( x.useSubsec ){ - sqlite3_result_double(context, (x.iJD - 21086676*(i64)10000000)/1000.0); - }else{ - sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); - } + sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); } } @@ -25082,8 +24625,8 @@ static void datetimeFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - int Y, s, n; - char zBuf[32]; + int Y, s; + char zBuf[24]; computeYMD_HMS(&x); Y = x.Y; if( Y<0 ) Y = -Y; @@ -25104,28 +24647,15 @@ static void datetimeFunc( zBuf[15] = '0' + (x.m/10)%10; zBuf[16] = '0' + (x.m)%10; zBuf[17] = ':'; - if( x.useSubsec ){ - s = (int)(1000.0*x.s + 0.5); - zBuf[18] = '0' + (s/10000)%10; - zBuf[19] = '0' + (s/1000)%10; - zBuf[20] = '.'; - zBuf[21] = '0' + (s/100)%10; - zBuf[22] = '0' + (s/10)%10; - zBuf[23] = '0' + (s)%10; - zBuf[24] = 0; - n = 24; - }else{ - s = (int)x.s; - zBuf[18] = '0' + (s/10)%10; - zBuf[19] = '0' + (s)%10; - zBuf[20] = 0; - n = 20; - } + s = (int)x.s; + zBuf[18] = '0' + (s/10)%10; + zBuf[19] = '0' + (s)%10; + zBuf[20] = 0; if( x.Y<0 ){ zBuf[0] = '-'; - sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); + sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT); }else{ - sqlite3_result_text(context, &zBuf[1], n-1, SQLITE_TRANSIENT); + sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT); } } } @@ -25142,7 +24672,7 @@ static void timeFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - int s, n; + int s; char zBuf[16]; computeHMS(&x); zBuf[0] = '0' + (x.h/10)%10; @@ -25151,24 +24681,11 @@ static void timeFunc( zBuf[3] = '0' + (x.m/10)%10; zBuf[4] = '0' + (x.m)%10; zBuf[5] = ':'; - if( x.useSubsec ){ - s = (int)(1000.0*x.s + 0.5); - zBuf[6] = '0' + (s/10000)%10; - zBuf[7] = '0' + (s/1000)%10; - zBuf[8] = '.'; - zBuf[9] = '0' + (s/100)%10; - zBuf[10] = '0' + (s/10)%10; - zBuf[11] = '0' + (s)%10; - zBuf[12] = 0; - n = 12; - }else{ - s = (int)x.s; - zBuf[6] = '0' + (s/10)%10; - zBuf[7] = '0' + (s)%10; - zBuf[8] = 0; - n = 8; - } - sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); + s = (int)x.s; + zBuf[6] = '0' + (s/10)%10; + zBuf[7] = '0' + (s)%10; + zBuf[8] = 0; + sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT); } } @@ -25223,7 +24740,7 @@ static void dateFunc( ** %M minute 00-59 ** %s seconds since 1970-01-01 ** %S seconds 00-59 -** %w day of week 0-6 Sunday==0 +** %w day of week 0-6 sunday==0 ** %W week of year 00-53 ** %Y year 0000-9999 ** %% % @@ -25299,13 +24816,8 @@ static void strftimeFunc( break; } case 's': { - if( x.useSubsec ){ - sqlite3_str_appendf(&sRes,"%.3f", - (x.iJD - 21086676*(i64)10000000)/1000.0); - }else{ - i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); - sqlite3_str_appendf(&sRes,"%lld",iS); - } + i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); + sqlite3_str_appendf(&sRes,"%lld",iS); break; } case 'S': { @@ -25363,117 +24875,6 @@ static void cdateFunc( dateFunc(context, 0, 0); } -/* -** timediff(DATE1, DATE2) -** -** Return the amount of time that must be added to DATE2 in order to -** convert it into DATE2. The time difference format is: -** -** +YYYY-MM-DD HH:MM:SS.SSS -** -** The initial "+" becomes "-" if DATE1 occurs before DATE2. For -** date/time values A and B, the following invariant should hold: -** -** datetime(A) == (datetime(B, timediff(A,B)) -** -** Both DATE arguments must be either a julian day number, or an -** ISO-8601 string. The unix timestamps are not supported by this -** routine. -*/ -static void timediffFunc( - sqlite3_context *context, - int NotUsed1, - sqlite3_value **argv -){ - char sign; - int Y, M; - DateTime d1, d2; - sqlite3_str sRes; - UNUSED_PARAMETER(NotUsed1); - if( isDate(context, 1, &argv[0], &d1) ) return; - if( isDate(context, 1, &argv[1], &d2) ) return; - computeYMD_HMS(&d1); - computeYMD_HMS(&d2); - if( d1.iJD>=d2.iJD ){ - sign = '+'; - Y = d1.Y - d2.Y; - if( Y ){ - d2.Y = d1.Y; - d2.validJD = 0; - computeJD(&d2); - } - M = d1.M - d2.M; - if( M<0 ){ - Y--; - M += 12; - } - if( M!=0 ){ - d2.M = d1.M; - d2.validJD = 0; - computeJD(&d2); - } - while( d1.iJDd2.iJD ){ - M--; - if( M<0 ){ - M = 11; - Y--; - } - d2.M++; - if( d2.M>12 ){ - d2.M = 1; - d2.Y++; - } - d2.validJD = 0; - computeJD(&d2); - } - d1.iJD = d2.iJD - d1.iJD; - d1.iJD += (u64)1486995408 * (u64)100000; - } - d1.validYMD = 0; - d1.validHMS = 0; - d1.validTZ = 0; - computeYMD_HMS(&d1); - sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); - sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", - sign, Y, M, d1.D-1, d1.h, d1.m, d1.s); - sqlite3ResultStrAccum(context, &sRes); -} - - /* ** current_timestamp() ** @@ -25548,7 +24949,6 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ PURE_DATE(time, -1, 0, 0, timeFunc ), PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), - PURE_DATE(timediff, 2, 0, 0, timediffFunc ), DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), DFUNCTION(current_date, 0, 0, 0, cdateFunc ), @@ -25702,7 +25102,7 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding ** transaction has been committed. Injecting a fault at this point - ** confuses the test scripts - the COMMIT command returns SQLITE_NOMEM + ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM ** but the transaction is committed anyway. ** ** The core must call OsFileControl() though, not OsFileControlHint(), @@ -26323,7 +25723,7 @@ static void *sqlite3MemMalloc(int nByte){ ** or sqlite3MemRealloc(). ** ** For this low-level routine, we already know that pPrior!=0 since -** cases where pPrior==0 will have been intercepted and dealt with +** cases where pPrior==0 will have been intecepted and dealt with ** by higher-level routines. */ static void sqlite3MemFree(void *pPrior){ @@ -26411,7 +25811,7 @@ static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; } len = sizeof(cpuCount); - /* One usually wants to use hw.activecpu for MT decisions, but not here */ + /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); if( cpuCount>1 ){ /* defer MT decisions to system malloc */ @@ -28878,7 +28278,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ /* ** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields -** are necessary under two conditions: (1) Debug builds and (2) using +** are necessary under two condidtions: (1) Debug builds and (2) using ** home-grown mutexes. Encapsulate these conditions into a single #define. */ #if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) @@ -29379,7 +28779,7 @@ struct sqlite3_mutex { CRITICAL_SECTION mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ #ifdef SQLITE_DEBUG - volatile int nRef; /* Number of entrances */ + volatile int nRef; /* Number of enterances */ volatile DWORD owner; /* Thread holding this mutex */ volatile LONG trace; /* True to trace changes */ #endif @@ -30751,6 +30151,43 @@ static const et_info fmtinfo[] = { ** %!S Like %S but prefer the zName over the zAlias */ +/* Floating point constants used for rounding */ +static const double arRound[] = { + 5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05, + 5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10, +}; + +/* +** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point +** conversions will work. +*/ +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** "*val" is a double such that 0.1 <= *val < 10.0 +** Return the ascii code for the leading digit of *val, then +** multiply "*val" by 10.0 to renormalize. +** +** Example: +** input: *val = 3.14159 +** output: *val = 1.4159 function return = '3' +** +** The counter *cnt is incremented each time. After counter exceeds +** 16 (the number of significant digits in a 64-bit float) '0' is +** always returned. +*/ +static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ + int digit; + LONGDOUBLE_TYPE d; + if( (*cnt)<=0 ) return '0'; + (*cnt)--; + digit = (int)*val; + d = digit; + digit += '0'; + *val = (*val - d)*10.0; + return (char)digit; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + /* ** Set the StrAccum object to an error mode. */ @@ -30842,15 +30279,18 @@ SQLITE_API void sqlite3_str_vappendf( u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ sqlite_uint64 longvalue; /* Value for integer types */ - double realvalue; /* Value for real types */ + LONGDOUBLE_TYPE realvalue; /* Value for real types */ const et_info *infop; /* Pointer to the appropriate info structure */ char *zOut; /* Rendering buffer */ int nOut; /* Size of the rendering buffer */ char *zExtra = 0; /* Malloced memory used by some conversion */ - int exp, e2; /* exponent of real numbers */ +#ifndef SQLITE_OMIT_FLOATING_POINT + int exp, e2; /* exponent of real numbers */ + int nsd; /* Number of significant digits returned */ + double rounder; /* Used for rounding floating point values */ etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ - +#endif PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ char buf[etBUFSIZE]; /* Conversion buffer */ @@ -31125,66 +30565,73 @@ SQLITE_API void sqlite3_str_vappendf( break; case etFLOAT: case etEXP: - case etGENERIC: { - FpDecode s; - int iRound; - int j; - + case etGENERIC: if( bArgList ){ realvalue = getDoubleArg(pArgList); }else{ realvalue = va_arg(ap,double); } +#ifdef SQLITE_OMIT_FLOATING_POINT + length = 0; +#else 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 ){ - iRound = precision; + if( realvalue<0.0 ){ + realvalue = -realvalue; + prefix = '-'; }else{ - iRound = precision+1; + prefix = flag_prefix; } - sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16); - if( s.isSpecial ){ - if( s.isSpecial==2 ){ - bufpt = flag_zeropad ? "null" : "NaN"; - length = sqlite3Strlen30(bufpt); - break; - }else if( flag_zeropad ){ - s.z[0] = '9'; - s.iDP = 1000; - s.n = 1; - }else{ - memcpy(buf, "-Inf", 5); + if( xtype==etGENERIC && precision>0 ) precision--; + testcase( precision>0xfff ); + idx = precision & 0xfff; + rounder = arRound[idx%10]; + while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; } + if( xtype==etFLOAT ){ + double rx = (double)realvalue; + sqlite3_uint64 u; + int ex; + memcpy(&u, &rx, sizeof(u)); + ex = -1023 + (int)((u>>52)&0x7ff); + if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16; + realvalue += rounder; + } + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ + exp = 0; + if( sqlite3IsNaN((double)realvalue) ){ + bufpt = "NaN"; + length = 3; + break; + } + if( realvalue>0.0 ){ + LONGDOUBLE_TYPE scale = 1.0; + while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;} + while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; } + while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } + realvalue /= scale; + while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } + while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } + if( exp>350 ){ bufpt = buf; - if( s.sign=='-' ){ - /* no-op */ - }else if( flag_prefix ){ - buf[0] = flag_prefix; - }else{ - bufpt++; - } - length = sqlite3Strlen30(bufpt); + buf[0] = prefix; + memcpy(buf+(prefix!=0),"Inf",4); + length = 3+(prefix!=0); break; } } - if( s.sign=='-' ){ - prefix = '-'; - }else{ - prefix = flag_prefix; - } - - exp = s.iDP-1; - if( xtype==etGENERIC && precision>0 ) precision--; - + bufpt = buf; /* ** If the field type is etGENERIC, then convert to either etEXP ** or etFLOAT, as appropriate. */ + if( xtype!=etFLOAT ){ + realvalue += rounder; + if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } + } if( xtype==etGENERIC ){ flag_rtz = !flag_alternateform; if( exp<-4 || exp>precision ){ @@ -31199,32 +30646,29 @@ SQLITE_API void sqlite3_str_vappendf( if( xtype==etEXP ){ e2 = 0; }else{ - e2 = s.iDP - 1; + e2 = exp; } - 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; } } zOut = bufpt; + nsd = 16 + flag_altform2*10; flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; /* The sign in front of the number */ if( prefix ){ *(bufpt++) = prefix; } /* Digits prior to the decimal point */ - j = 0; if( e2<0 ){ *(bufpt++) = '0'; }else{ for(; e2>=0; e2--){ - *(bufpt++) = j1 ) *(bufpt++) = ','; + *(bufpt++) = et_getdigit(&realvalue,&nsd); } } /* The decimal point */ @@ -31233,12 +30677,13 @@ 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++){ + for(e2++; e2<0; precision--, e2++){ + assert( precision>0 ); *(bufpt++) = '0'; } /* Significant digits after the decimal point */ while( (precision--)>0 ){ - *(bufpt++) = jcharset]; if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; @@ -31288,8 +30732,8 @@ SQLITE_API void sqlite3_str_vappendf( while( nPad-- ) bufpt[i++] = '0'; length = width; } +#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */ break; - } case etSIZE: if( !bArgList ){ *(va_arg(ap,int*)) = pAccum->nChar; @@ -31920,22 +31364,12 @@ SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_li return zBuf; } SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ - StrAccum acc; + char *z; va_list ap; - if( n<=0 ) return zBuf; -#ifdef SQLITE_ENABLE_API_ARMOR - if( zBuf==0 || zFormat==0 ) { - (void)SQLITE_MISUSE_BKPT; - if( zBuf ) zBuf[0] = 0; - return zBuf; - } -#endif - sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); va_start(ap,zFormat); - sqlite3_str_vappendf(&acc, zFormat, ap); + z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); va_end(ap); - zBuf[acc.nChar] = 0; - return zBuf; + return z; } /* @@ -32013,75 +31447,6 @@ SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ va_end(ap); } - -/***************************************************************************** -** Reference counted string storage -*****************************************************************************/ - -/* -** Increase the reference count of the string by one. -** -** The input parameter is returned. -*/ -SQLITE_PRIVATE char *sqlite3RCStrRef(char *z){ - RCStr *p = (RCStr*)z; - assert( p!=0 ); - p--; - p->nRCRef++; - return z; -} - -/* -** Decrease the reference count by one. Free the string when the -** reference count reaches zero. -*/ -SQLITE_PRIVATE void sqlite3RCStrUnref(char *z){ - RCStr *p = (RCStr*)z; - assert( p!=0 ); - p--; - assert( p->nRCRef>0 ); - if( p->nRCRef>=2 ){ - p->nRCRef--; - }else{ - sqlite3_free(p); - } -} - -/* -** Create a new string that is capable of holding N bytes of text, not counting -** the zero byte at the end. The string is uninitialized. -** -** The reference count is initially 1. Call sqlite3RCStrUnref() to free the -** newly allocated string. -** -** This routine returns 0 on an OOM. -*/ -SQLITE_PRIVATE char *sqlite3RCStrNew(u64 N){ - RCStr *p = sqlite3_malloc64( N + sizeof(*p) + 1 ); - if( p==0 ) return 0; - p->nRCRef = 1; - return (char*)&p[1]; -} - -/* -** Change the size of the string so that it is able to hold N bytes. -** The string might be reallocated, so return the new allocation. -*/ -SQLITE_PRIVATE char *sqlite3RCStrResize(char *z, u64 N){ - RCStr *p = (RCStr*)z; - RCStr *pNew; - assert( p!=0 ); - p--; - assert( p->nRCRef==1 ); - pNew = sqlite3_realloc64(p, N+sizeof(RCStr)+1); - if( pNew==0 ){ - sqlite3_free(p); - return 0; - }else{ - return (char*)&pNew[1]; - } -} - /************** End of printf.c **********************************************/ /************** Begin file treeview.c ****************************************/ /* @@ -32729,8 +32094,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m }; assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); assert( pExpr->pRight ); - assert( sqlite3ExprSkipCollateAndLikely(pExpr->pRight)->op - == TK_TRUEFALSE ); + assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE ); x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); zUniOp = azOp[x]; break; @@ -34411,7 +33775,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ /* ** Calls to sqlite3FaultSim() are used to simulate a failure during testing, ** or to bypass normal error detection during testing in order to let -** execute proceed further downstream. +** execute proceed futher downstream. ** ** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0). The ** sqlite3FaultSim() function only returns non-zero during testing. @@ -34773,40 +34137,43 @@ SQLITE_PRIVATE u8 sqlite3StrIHash(const char *z){ return h; } -/* Double-Double multiplication. (x[0],x[1]) *= (y,yy) +/* +** Compute 10 to the E-th power. Examples: E==1 results in 10. +** E==2 results in 100. E==50 results in 1.0e50. ** -** Reference: -** T. J. Dekker, "A Floating-Point Technique for Extending the -** Available Precision". 1971-07-26. +** This routine only works for values of E between 1 and 341. */ -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 LONGDOUBLE_TYPE sqlite3Pow10(int E){ +#if defined(_MSC_VER) + static const LONGDOUBLE_TYPE x[] = { + 1.0e+001L, + 1.0e+002L, + 1.0e+004L, + 1.0e+008L, + 1.0e+016L, + 1.0e+032L, + 1.0e+064L, + 1.0e+128L, + 1.0e+256L + }; + LONGDOUBLE_TYPE r = 1.0; + int i; + assert( E>=0 && E<=307 ); + for(i=0; E!=0; i++, E >>=1){ + if( E & 1 ) r *= x[i]; + } + return r; +#else + LONGDOUBLE_TYPE x = 10.0; + LONGDOUBLE_TYPE r = 1.0; + while(1){ + if( E & 1 ) r *= x; + E >>= 1; + if( E==0 ) break; + x *= x; + } + return r; +#endif } /* @@ -34847,11 +34214,12 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en const char *zEnd; /* sign * significand * (10 ^ (esign * exponent)) */ int sign = 1; /* sign of significand */ - u64 s = 0; /* significand */ + i64 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 */ + double result; int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ @@ -34891,7 +34259,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en while( z=((LARGEST_UINT64-9)/10) ){ + if( s>=((LARGEST_INT64-9)/10) ){ /* skip non-significant significand digits ** (increase exponent by d to shift decimal left) */ while( z0 && s<(LARGEST_UINT64/10) ){ - s *= 10; - e--; - } - while( e<0 && (s%10)==0 ){ - s /= 10; - e++; + if( e<0 ) { + esign = -1; + e *= -1; + } else { + esign = 1; } - if( e==0 ){ - *pResult = s; - }else if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; - if( e>0 ){ - while( e>=100 ){ e-=100; r *= 1.0e+100L; } - while( e>=10 ){ e-=10; r *= 1.0e+10L; } - while( e>=1 ){ e-=1; r *= 1.0e+01L; } - }else{ - while( e<=-100 ){ e+=100; r *= 1.0e-100L; } - while( e<=-10 ){ e+=10; r *= 1.0e-10L; } - while( e<=-1 ){ e+=1; r *= 1.0e-01L; } - } - *pResult = r; - }else{ - double rr[2]; - u64 s2; - rr[0] = (double)s; - s2 = (u64)rr[0]; - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); - 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); + if( s==0 ) { + /* In the IEEE 754 standard, zero is signed. */ + result = sign<0 ? -(double)0 : (double)0; + } else { + /* Attempt to reduce exponent. + ** + ** Branches that are not required for the correct answer but which only + ** help to obtain the correct answer faster are marked with special + ** comments, as a hint to the mutation tester. + */ + while( e>0 ){ /*OPTIMIZATION-IF-TRUE*/ + if( esign>0 ){ + if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/ + s *= 10; + }else{ + if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/ + s /= 10; } + e--; + } + + /* adjust the sign of significand */ + s = sign<0 ? -s : s; + + if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ + result = (double)s; }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); + /* attempt to handle extremely small/large numbers better */ + if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/ + if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ + LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308); + if( esign<0 ){ + result = s / scale; + result /= 1.0e+308; + }else{ + result = s * scale; + result *= 1.0e+308; + } + }else{ assert( e>=342 ); + if( esign<0 ){ + result = 0.0*s; + }else{ +#ifdef INFINITY + result = INFINITY*s; +#else + result = 1e308*1e308*s; /* Infinity */ +#endif + } + } + }else{ + LONGDOUBLE_TYPE scale = sqlite3Pow10(e); + if( esign<0 ){ + result = s / scale; + }else{ + result = s * scale; + } } } - *pResult = rr[0]+rr[1]; - if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; } - if( sign<0 ) *pResult = -*pResult; - assert( !sqlite3IsNaN(*pResult) ); -atof_return: - /* return true if number and no extra non-whitespace characters after */ + /* store the result */ + *pResult = result; + + /* return true if number and no extra non-whitespace chracters after */ if( z==zEnd && nDigit>0 && eValid && eType>0 ){ return eType; }else if( eType>=2 && (eType==3 || eValid) && nDigit>0 ){ @@ -35054,15 +34421,13 @@ SQLITE_PRIVATE int sqlite3Int64ToText(i64 v, char *zOut){ } i = sizeof(zTemp)-2; zTemp[sizeof(zTemp)-1] = 0; - while( 1 /*exit-by-break*/ ){ - zTemp[i] = (x%10) + '0'; + do{ + 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; + }while( x ); + if( v<0 ) zTemp[i--] = '-'; + memcpy(zOut, &zTemp[i+1], sizeof(zTemp)-1-i); + return sizeof(zTemp)-2-i; } /* @@ -35155,7 +34520,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc /* This test and assignment is needed only to suppress UB warnings ** from clang and -fsanitize=undefined. This test and assignment make ** the code a little larger and slower, and no harm comes from omitting - ** them, but we must appease the undefined-behavior pharisees. */ + ** them, but we must appaise the undefined-behavior pharisees. */ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; }else if( neg ){ *pNum = -(i64)u; @@ -35227,15 +34592,11 @@ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ u = u*16 + sqlite3HexToInt(z[k]); } memcpy(pOut, &u, 8); - if( k-i>16 ) return 2; - if( z[k]!=0 ) return 1; - return 0; + return (z[k]==0 && k-i<=16) ? 0 : 2; }else #endif /* SQLITE_OMIT_HEX_INTEGER */ { - int n = (int)(0x3fffffff&strspn(z,"+- \n\t0123456789")); - if( z[n] ) n++; - return sqlite3Atoi64(z, pOut, n, SQLITE_UTF8); + return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); } } @@ -35267,7 +34628,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){ u32 u = 0; zNum += 2; while( zNum[0]=='0' ) zNum++; - for(i=0; i<8 && sqlite3Isxdigit(zNum[i]); i++){ + for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){ u = u*16 + sqlite3HexToInt(zNum[i]); } if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ @@ -35314,153 +34675,6 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ return x; } -/* -** Decode a floating-point value into an approximate decimal -** representation. -** -** Round the decimal representation to n significant digits if -** n is positive. Or round to -n signficant digits after the -** decimal point if n is negative. No rounding is performed if -** n is zero. -** -** The significant digits of the decimal representation are -** stored in p->z[] which is a often (but not always) a pointer -** into the middle of p->zBuf[]. There are p->n significant digits. -** 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; - p->isSpecial = 0; - p->z = p->zBuf; - - /* Convert negative numbers to positive. Deal with Infinity, 0.0, and - ** NaN. */ - if( r<0.0 ){ - p->sign = '-'; - r = -r; - }else if( r==0.0 ){ - p->sign = '+'; - p->n = 1; - p->iDP = 1; - p->z = "0"; - return; - }else{ - p->sign = '+'; - } - memcpy(&v,&r,8); - e = v>>52; - if( (e&0x7ff)==0x7ff ){ - p->isSpecial = 1 + (v!=0x7ff0000000000000LL); - p->n = 0; - p->iDP = 0; - return; - } - - /* Multiply r by powers of ten until it lands somewhere in between - ** 1.0e+19 and 1.0e+17. - */ - if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE rr = r; - if( rr>=1.0e+19 ){ - while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } - while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; } - while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; } - }else{ - while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; } - while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; } - while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; } - } - v = (u64)rr; - }else{ - /* If high-precision floating point is not available using "long double", - ** then 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_sci(decimal_sub('1.0e+100',decimal(1.0e+100))); - */ - double rr[2]; - rr[0] = r; - rr[1] = 0.0; - if( rr[0]>1.84e+19 ){ - while( rr[0]>1.84e+119 ){ - exp += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( rr[0]>1.84e+29 ){ - exp += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( rr[0]>1.84e+19 ){ - exp += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } - }else{ - while( rr[0]<1.84e-82 ){ - exp -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( rr[0]<1.84e+08 ){ - exp -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( rr[0]<1.84e+18 ){ - exp -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } - } - v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; - } - - - /* Extract significant digits. */ - i = sizeof(p->zBuf)-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; - if( iRound<0 ){ - iRound = p->iDP - iRound; - if( iRound==0 && p->zBuf[i+1]>='5' ){ - iRound = 1; - p->zBuf[i--] = '0'; - p->n++; - p->iDP++; - } - } - if( iRound>0 && (iRoundn || p->n>mxRound) ){ - char *z = &p->zBuf[i+1]; - if( iRound>mxRound ) iRound = mxRound; - p->n = iRound; - if( z[iRound]>='5' ){ - int j = iRound-1; - while( 1 /*exit-by-break*/ ){ - z[j]++; - if( z[j]<='9' ) break; - z[j] = '0'; - if( j==0 ){ - p->z[i--] = '1'; - p->n++; - p->iDP++; - break; - }else{ - j--; - } - } - } - } - p->z = &p->zBuf[i+1]; - assert( i+p->n < sizeof(p->zBuf) ); - while( ALWAYS(p->n>0) && p->z[p->n-1]=='0' ){ p->n--; } -} - /* ** Try to convert z into an unsigned 32-bit integer. Return true on ** success and false if there is an error. @@ -35989,7 +35203,7 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ } /* -** Attempt to add, subtract, or multiply the 64-bit signed value iB against +** Attempt to add, substract, or multiply the 64-bit signed value iB against ** the other 64-bit signed integer at *pA and store the result in *pA. ** Return 0 on success. Or if the operation would have resulted in an ** overflow, leave *pA unchanged and return 1. @@ -36302,7 +35516,7 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam #define SQLITE_HWTIME_H /* -** The following routine only works on Pentium-class (or newer) processors. +** 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. @@ -36474,7 +35688,7 @@ static void insertElement( } -/* Resize the hash table so that it contains "new_size" buckets. +/* Resize the hash table so that it cantains "new_size" buckets. ** ** The hash table might fail to resize if sqlite3_malloc() fails or ** if the new size is the same as the prior size. @@ -37860,7 +37074,7 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void){ ** This source file is organized into divisions where the logic for various ** subfunctions is contained within the appropriate division. PLEASE ** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed -** in the correct division and should be clearly labelled. +** in the correct division and should be clearly labeled. ** ** The layout of divisions is as follows: ** @@ -37920,7 +37134,7 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void){ #endif /* Use pread() and pwrite() if they are available */ -#if defined(__APPLE__) || defined(__linux__) +#if defined(__APPLE__) # define HAVE_PREAD 1 # define HAVE_PWRITE 1 #endif @@ -38457,7 +37671,7 @@ static int robustFchown(int fd, uid_t uid, gid_t gid){ /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the -** "unix" VFSes. Return SQLITE_OK upon successfully updating the +** "unix" VFSes. Return SQLITE_OK opon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable ** system call named zName. */ @@ -38979,7 +38193,7 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ ** If you close a file descriptor that points to a file that has locks, ** all locks on that file that are owned by the current process are ** released. To work around this problem, each unixInodeInfo object -** maintains a count of the number of pending locks on the inode. +** maintains a count of the number of pending locks on tha inode. ** When an attempt is made to close an unixFile, if there are ** other unixFile open on the same inode that are holding locks, the call ** to close() the file descriptor is deferred until all of the locks clear. @@ -38993,7 +38207,7 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ ** not posix compliant. Under LinuxThreads, a lock created by thread ** A cannot be modified or overridden by a different thread B. ** Only thread A can modify the lock. Locking behavior is correct -** if the application uses the newer Native Posix Thread Library (NPTL) +** if the appliation uses the newer Native Posix Thread Library (NPTL) ** on linux - with NPTL a lock created by thread A can override locks ** in thread B. But there is no way to know at compile-time which ** threading library is being used. So there is no way to know at @@ -39199,7 +38413,7 @@ static void storeLastErrno(unixFile *pFile, int error){ } /* -** Close all file descriptors accumulated in the unixInodeInfo->pUnused list. +** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. */ static void closePendingFds(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; @@ -39569,7 +38783,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ** slightly in order to be compatible with Windows95 systems simultaneously ** accessing the same database file, in case that is ever required. ** - ** Symbols defined in os.h identify the 'pending byte' and the 'reserved + ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved ** byte', each single bytes at well known offsets, and the 'shared byte ** range', a range of 510 bytes at a well known offset. ** @@ -39577,7 +38791,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ** byte'. If this is successful, 'shared byte range' is read-locked ** and the lock on the 'pending byte' released. (Legacy note: When ** SQLite was first developed, Windows95 systems were still very common, - ** and Windows95 lacks a shared-lock capability. So on Windows95, a + ** and Widnows95 lacks a shared-lock capability. So on Windows95, a ** single randomly selected by from the 'shared byte range' is locked. ** Windows95 is now pretty much extinct, but this work-around for the ** lack of shared-locks on Windows95 lives on, for backwards @@ -39598,7 +38812,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ ** obtaining a write-lock on the 'pending byte'. This ensures that no new ** SHARED locks can be obtained, but existing SHARED locks are allowed to ** persist. If the call to this function fails to obtain the EXCLUSIVE - ** lock in this case, it holds the PENDING lock instead. The client may + ** lock in this case, it holds the PENDING lock intead. The client may ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED ** locks have cleared. */ @@ -39626,7 +38840,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ /* Make sure the locking sequence is correct. ** (1) We never move from unlocked to anything higher than shared lock. - ** (2) SQLite never explicitly requests a pending lock. + ** (2) SQLite never explicitly requests a pendig lock. ** (3) A shared lock is always held when a reserve lock is requested. */ assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); @@ -40852,7 +40066,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ /* Make sure the locking sequence is correct ** (1) We never move from unlocked to anything higher than shared lock. - ** (2) SQLite never explicitly requests a pending lock. + ** (2) SQLite never explicitly requests a pendig lock. ** (3) A shared lock is always held when a reserve lock is requested. */ assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); @@ -40968,7 +40182,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + pInode->sharedByte, 1, 0)) ){ int failed2 = SQLITE_OK; - /* now attempt to get the exclusive lock range */ + /* now attemmpt to get the exclusive lock range */ failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 1); if( failed && (failed2 = afpSetLock(context->dbPath, pFile, @@ -41189,6 +40403,12 @@ static int nfsUnlock(sqlite3_file *id, int eFileLock){ ** Seek to the offset passed as the second argument, then read cnt ** bytes into pBuf. Return the number of bytes actually read. ** +** NB: If you define USE_PREAD or USE_PREAD64, then it might also +** be necessary to define _XOPEN_SOURCE to be 500. This varies from +** one system to another. Since SQLite does not define USE_PREAD +** in any form by default, we will not attempt to define _XOPEN_SOURCE. +** See tickets #2741 and #2681. +** ** To avoid stomping the errno value on a failed read the lastErrno value ** is set before returning. */ @@ -41263,7 +40483,7 @@ static int unixRead( #endif #if SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this read request as possible by transferring + /* Deal with as much of this read request as possible by transfering ** data from the memory mapping using memcpy(). */ if( offsetmmapSize ){ if( offset+amt <= pFile->mmapSize ){ @@ -41415,7 +40635,7 @@ static int unixWrite( #endif #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this write request as possible by transferring + /* Deal with as much of this write request as possible by transfering ** data from the memory mapping using memcpy(). */ if( offsetmmapSize ){ if( offset+amt <= pFile->mmapSize ){ @@ -41537,7 +40757,7 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a ** no-op. But go ahead and call fstat() to validate the file ** descriptor as we need a method to provoke a failure during - ** coverage testing. + ** coverate testing. */ #ifdef SQLITE_NO_SYNC { @@ -47334,7 +46554,7 @@ static struct win_syscall { /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the -** "win32" VFSes. Return SQLITE_OK upon successfully updating the +** "win32" VFSes. Return SQLITE_OK opon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable ** system call named zName. */ @@ -48914,7 +48134,7 @@ static int winRead( pFile->h, pBuf, amt, offset, pFile->locktype)); #if SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this read request as possible by transferring + /* Deal with as much of this read request as possible by transfering ** data from the memory mapping using memcpy(). */ if( offsetmmapSize ){ if( offset+amt <= pFile->mmapSize ){ @@ -48992,7 +48212,7 @@ static int winWrite( pFile->h, pBuf, amt, offset, pFile->locktype)); #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this write request as possible by transferring + /* Deal with as much of this write request as possible by transfering ** data from the memory mapping using memcpy(). */ if( offsetmmapSize ){ if( offset+amt <= pFile->mmapSize ){ @@ -49102,7 +48322,7 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ ** all references to memory-mapped content are closed. That is doable, ** but involves adding a few branches in the common write code path which ** could slow down normal operations slightly. Hence, we have decided for - ** now to simply make transactions a no-op if there are pending reads. We + ** now to simply make trancations a no-op if there are pending reads. We ** can maybe revisit this decision in the future. */ return SQLITE_OK; @@ -49161,7 +48381,7 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ #ifdef SQLITE_TEST /* ** Count the number of fullsyncs and normal syncs. This is used to test -** that syncs and fullsyncs are occurring at the right times. +** that syncs and fullsyncs are occuring at the right times. */ SQLITE_API int sqlite3_sync_count = 0; SQLITE_API int sqlite3_fullsync_count = 0; @@ -49518,7 +48738,7 @@ static int winLock(sqlite3_file *id, int locktype){ */ if( locktype==EXCLUSIVE_LOCK && res ){ assert( pFile->locktype>=SHARED_LOCK ); - (void)winUnlockReadLock(pFile); + res = winUnlockReadLock(pFile); res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ @@ -51372,7 +50592,7 @@ static int winOpen( if( isReadWrite ){ int rc2, isRO = 0; sqlite3BeginBenignMalloc(); - rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); + rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } @@ -51389,7 +50609,7 @@ static int winOpen( if( isReadWrite ){ int rc2, isRO = 0; sqlite3BeginBenignMalloc(); - rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); + rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } @@ -51409,7 +50629,7 @@ static int winOpen( if( isReadWrite ){ int rc2, isRO = 0; sqlite3BeginBenignMalloc(); - rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO); + rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } @@ -51632,13 +50852,6 @@ static int winAccess( OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", zFilename, flags, pResOut)); - if( zFilename==0 ){ - *pResOut = 0; - OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", - zFilename, pResOut, *pResOut)); - return SQLITE_OK; - } - zConverted = winConvertFromUtf8Filename(zFilename); if( zConverted==0 ){ OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); @@ -53505,7 +52718,7 @@ SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ h = BITVEC_HASH(i++); /* if there wasn't a hash collision, and this doesn't */ /* completely fill the hash, then just add it without */ - /* worrying about sub-dividing and re-hashing. */ + /* worring about sub-dividing and re-hashing. */ if( !p->u.aHash[h] ){ if (p->nSet<(BITVEC_NINT-1)) { goto bitvec_set_end; @@ -53801,15 +53014,11 @@ struct PCache { PgHdr *pPg; unsigned char *a; int j; - if( pLower==0 ){ - printf("%3d: NULL\n", i); - }else{ - pPg = (PgHdr*)pLower->pExtra; - printf("%3d: nRef %2lld flgs %02x data ", i, pPg->nRef, pPg->flags); - a = (unsigned char *)pLower->pBuf; - for(j=0; j<12; j++) printf("%02x", a[j]); - printf(" ptr %p\n", pPg); - } + pPg = (PgHdr*)pLower->pExtra; + printf("%3lld: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); + a = (unsigned char *)pLower->pBuf; + for(j=0; j<12; j++) printf("%02x", a[j]); + printf(" ptr %p\n", pPg); } static void pcacheDump(PCache *pCache){ int N; @@ -53822,8 +53031,9 @@ struct PCache { if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; for(i=1; i<=N; i++){ pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); + if( pLower==0 ) continue; pcachePageTrace(i, pLower); - if( pLower && ((PgHdr*)pLower)->pPage==0 ){ + if( ((PgHdr*)pLower)->pPage==0 ){ sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); } } @@ -54002,7 +53212,7 @@ static int numberOfCachePages(PCache *p){ return p->szCache; }else{ i64 n; - /* IMPLEMENTATION-OF: R-59858-46238 If the argument N is negative, then the + /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the ** number of cache pages is adjusted to be a number of pages that would ** use approximately abs(N*1024) bytes of memory based on the current ** page size. */ @@ -54490,7 +53700,7 @@ static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ } /* -** Sort the list of pages in ascending order by pgno. Pages are +** Sort the list of pages in accending order by pgno. Pages are ** connected by pDirty pointers. The pDirtyPrev pointers are ** corrupted by this sort. ** @@ -54730,7 +53940,7 @@ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHd ** If N is positive, then N pages worth of memory are allocated using a single ** sqlite3Malloc() call and that memory is used for the first N pages allocated. ** Or if N is negative, then -1024*N bytes of memory are allocated and used -** for as many pages as can be accommodated. +** for as many pages as can be accomodated. ** ** Only one of (2) or (3) can be used. Once the memory available to (2) or ** (3) is exhausted, subsequent allocations fail over to the general-purpose @@ -54764,7 +53974,7 @@ typedef struct PGroup PGroup; ** in memory directly after the associated page data, if the database is ** corrupt, code at the b-tree layer may overread the page buffer and ** read part of this structure before the corruption is detected. This -** can cause a valgrind error if the uninitialized gap is accessed. Using u16 +** can cause a valgrind error if the unitialized gap is accessed. Using u16 ** ensures there is no such gap, and therefore no bytes of uninitialized ** memory in the structure. ** @@ -56007,7 +55217,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats( ** The TEST primitive includes a "batch" number. The TEST primitive ** will only see elements that were inserted before the last change ** in the batch number. In other words, if an INSERT occurs between -** two TESTs where the TESTs have the same batch number, then the +** two TESTs where the TESTs have the same batch nubmer, then the ** value added by the INSERT will not be visible to the second TEST. ** The initial batch number is zero, so if the very first TEST contains ** a non-zero batch number, it will see all prior INSERTs. @@ -56633,7 +55843,7 @@ SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal); #ifndef SQLITE_OMIT_CONCURRENT /* Tell the wal layer that we want to commit a concurrent transaction */ -SQLITE_PRIVATE int sqlite3WalLockForCommit(Wal *pWal, PgHdr *pPg, Bitvec *pRead, u32*); +SQLITE_PRIVATE int sqlite3WalLockForCommit(Wal *pWal, PgHdr *pPg, Bitvec *pRead, Pgno*); /* Upgrade the state of the client to take into account changes written ** by other connections */ @@ -56949,7 +56159,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ ** outstanding transactions have been abandoned, the pager is able to ** transition back to OPEN state, discarding the contents of the ** page-cache and any other in-memory state at the same time. Everything -** is reloaded from disk (and, if necessary, hot-journal rollback performed) +** is reloaded from disk (and, if necessary, hot-journal rollback peformed) ** when a read-transaction is next opened on the pager (transitioning ** the pager into READER state). At that point the system has recovered ** from the error. @@ -58316,7 +57526,7 @@ static int readJournalHdr( ** + 4 bytes: super-journal name checksum. ** + 8 bytes: aJournalMagic[]. ** -** The super-journal page checksum is the sum of the bytes in the super-journal +** The super-journal page checksum is the sum of the bytes in thesuper-journal ** name, where each byte is interpreted as a signed 8-bit integer. ** ** If zSuper is a NULL pointer (occurs for a single database transaction), @@ -58369,7 +57579,7 @@ static int writeSuperJournal(Pager *pPager, const char *zSuper){ } pPager->journalOff += (nSuper+20); - /* If the pager is in persistent-journal mode, then the physical + /* If the pager is in peristent-journal mode, then the physical ** journal-file may extend past the end of the super-journal name ** and 8 bytes of magic data just written to the file. This is ** dangerous because the code to rollback a hot-journal file @@ -58585,7 +57795,7 @@ static void pager_unlock(Pager *pPager){ /* ** This function is called whenever an IOERR or FULL error that requires -** the pager to transition into the ERROR state may have occurred. +** the pager to transition into the ERROR state may ahve occurred. ** The first argument is a pointer to the pager structure, the second ** the error-code about to be returned by a pager API function. The ** value returned is a copy of the second argument to this function. @@ -58860,7 +58070,7 @@ static void pagerUnlockAndRollback(Pager *pPager){ /* ** Parameter aData must point to a buffer of pPager->pageSize bytes -** of data. Compute and return a checksum based on the contents of the +** of data. Compute and return a checksum based ont the contents of the ** page of data and the current value of pPager->cksumInit. ** ** This is not a real checksum. It is really just the sum of the @@ -59293,8 +58503,6 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ int rc = SQLITE_OK; assert( pPager->eState!=PAGER_ERROR ); assert( pPager->eState!=PAGER_READER ); - PAGERTRACE(("Truncate %d npage %u\n", PAGERID(pPager), nPage)); - if( isOpen(pPager->fd) && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) @@ -59842,7 +59050,7 @@ static int pagerWalFrames( assert( pPager->pWal ); assert( pList ); #ifdef SQLITE_DEBUG - /* Verify that the page list is in ascending order */ + /* Verify that the page list is in accending order */ for(p=pList; p && p->pDirty; p=p->pDirty){ assert( p->pgno < p->pDirty->pgno ); } @@ -59979,7 +59187,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){ #ifndef SQLITE_OMIT_WAL /* ** Check if the *-wal file that corresponds to the database opened by pPager -** exists if the database is not empty, or verify that the *-wal file does +** exists if the database is not empy, or verify that the *-wal file does ** not exist (by deleting it) if the database file is empty. ** ** If the database is not empty and the *-wal file exists, open the pager @@ -61395,7 +60603,11 @@ SQLITE_PRIVATE int sqlite3PagerOpen( int rc = SQLITE_OK; /* Return code */ int tempFile = 0; /* True for temp files (incl. in-memory files) */ int memDb = 0; /* True if this is an in-memory file */ +#ifndef SQLITE_OMIT_DESERIALIZE int memJM = 0; /* Memory journal mode */ +#else +# define memJM 0 +#endif int readOnly = 0; /* True if this is a read-only file */ int journalFileSize; /* Bytes to allocate for each journal fd */ char *zPathname = 0; /* Full path to database file */ @@ -61514,13 +60726,12 @@ SQLITE_PRIVATE int sqlite3PagerOpen( ** specific formatting and order of the various filenames, so if the format ** changes here, be sure to change it there as well. */ - assert( SQLITE_PTRSIZE==sizeof(Pager*) ); pPtr = (u8 *)sqlite3MallocZero( ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(pcacheSize) + /* PCache object */ ROUND8(pVfs->szOsFile) + /* The main db file */ journalFileSize * 2 + /* The two journal files */ - SQLITE_PTRSIZE + /* Space to hold a pointer */ + sizeof(pPager) + /* Space to hold a pointer */ 4 + /* Database prefix */ nPathname + 1 + /* database filename */ nUriByte + /* query parameters */ @@ -61542,7 +60753,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); - memcpy(pPtr, &pPager, SQLITE_PTRSIZE); pPtr += SQLITE_PTRSIZE; + memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ pPtr += 4; /* Skip zero prefix */ @@ -61598,7 +60809,9 @@ SQLITE_PRIVATE int sqlite3PagerOpen( int fout = 0; /* VFS flags returned by xOpen() */ rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); assert( !memDb ); +#ifndef SQLITE_OMIT_DESERIALIZE pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; +#endif readOnly = (fout&SQLITE_OPEN_READONLY)!=0; /* If the file was successfully opened for read/write access, @@ -61735,7 +60948,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( /* ** Return the sqlite3_file for the main database given the name -** of the corresponding WAL or Journal name as passed into +** of the corresonding WAL or Journal name as passed into ** xOpen. */ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ @@ -62250,10 +61463,6 @@ static int getPageNormal( if( !isOpen(pPager->fd) || pPager->dbSizepPager->mxPgno ){ rc = SQLITE_FULL; - if( pgno<=pPager->dbSize ){ - sqlite3PcacheRelease(pPg); - pPg = 0; - } goto pager_acquire_err; } if( noContent ){ @@ -62418,12 +61627,10 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ /* ** Release a page reference. ** -** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be used -** if we know that the page being released is not the last reference to page1. +** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be +** used if we know that the page being released is not the last page. ** The btree layer always holds page1 open until the end, so these first -** two routines can be used to release any page other than BtShared.pPage1. -** The assert() at tag-20230419-2 proves that this constraint is always -** honored. +** to routines can be used to release any page other than BtShared.pPage1. ** ** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine ** checks the total number of outstanding pages and if the number of @@ -62439,7 +61646,7 @@ SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ sqlite3PcacheRelease(pPg); } /* Do not use this routine to release the last reference to page1 */ - assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); /* tag-20230419-2 */ + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); } SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ if( pPg ) sqlite3PagerUnrefNotNull(pPg); @@ -63080,7 +62287,7 @@ SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zSuper){ ** is returned. Otherwise, if some other error occurs (IO error, OOM etc.), ** and SQLite error code is returned. */ -SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager, PgHdr *pPage1, u32 *aConflict){ +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager, PgHdr *pPage1, Pgno *piConflict){ int rc = pPager->errCode; assert( assert_pager_state(pPager) ); if( rc==SQLITE_OK ){ @@ -63101,7 +62308,7 @@ SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager, PgHdr *pPage1, u32 * ** non-zero. */ do { rc = sqlite3WalLockForCommit( - pPager->pWal, pPage1, pPager->pAllRead, aConflict + pPager->pWal, pPage1, pPager->pAllRead, piConflict ); }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) @@ -64108,7 +63315,7 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ assert( pPager->eState!=PAGER_ERROR ); pPager->journalMode = (u8)eMode; - /* When transitioning from TRUNCATE or PERSIST to any other journal + /* When transistioning from TRUNCATE or PERSIST to any other journal ** mode except WAL, unless the pager is in locking_mode=exclusive mode, ** delete the journal file. */ @@ -64278,15 +63485,13 @@ SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ */ static int pagerExclusiveLock(Pager *pPager){ int rc; /* Return code */ - u8 eOrigLock; /* Original lock */ - assert( pPager->eLock>=SHARED_LOCK ); - eOrigLock = pPager->eLock; + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ /* If the attempt to grab the exclusive lock failed, release the ** pending lock that may have been obtained instead. */ - pagerUnlockDb(pPager, eOrigLock); + pagerUnlockDb(pPager, SHARED_LOCK); } return rc; @@ -65014,7 +64219,6 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0; #define WAL_VERSION1 3007000 /* For "journal_mode=wal" */ #define WAL_VERSION2 3021000 /* For "journal_mode=wal2" */ - /* ** Index numbers for various locking bytes. WAL_NREADER is the number ** of available reader locks and should be at least 3. The default @@ -65022,7 +64226,7 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0; ** ** Technically, the various VFSes are free to implement these locks however ** they see fit. However, compatibility is encouraged so that VFSes can -** interoperate. The standard implementation used on both unix and windows +** interoperate. The standard implemention used on both unix and windows ** is for the index number to indicate a byte offset into the ** WalCkptInfo.aLock[] array in the wal-index header. In other words, all ** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which @@ -65174,7 +64378,7 @@ static void walidxSetMxFrame(WalIndexHdr *pHdr, int iWal, u32 mxFrame){ ** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) ** for any aReadMark[] means that entry is unused. aReadMark[0] is ** a special case; its value is never used and it exists as a place-holder -** to avoid having to offset aReadMark[] indexes by one. Readers holding +** to avoid having to offset aReadMark[] indexs by one. Readers holding ** WAL_READ_LOCK(0) always ignore the entire WAL and read all content ** directly from the database. ** @@ -65565,40 +64769,19 @@ static void walChecksumBytes( assert( nByte>=8 ); assert( (nByte&0x00000007)==0 ); assert( nByte<=65536 ); - assert( nByte%4==0 ); - if( !nativeCksum ){ - do { - s1 += BYTESWAP32(aData[0]) + s2; - s2 += BYTESWAP32(aData[1]) + s1; - aData += 2; - }while( aDatahdr.mxFrame. - */ + ** frame numbers greater than pWal->hdr.mxFrame. */ nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]); assert( nByte>=0 ); memset((void *)&sLoc.aPgno[iLimit], 0, nByte); @@ -66638,7 +65820,7 @@ SQLITE_PRIVATE int sqlite3WalOpen( } /* -** Change the size to which the WAL file is truncated on each reset. +** Change the size to which the WAL file is trucated on each reset. */ SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ if( pWal ) pWal->mxWalSize = iLimit; @@ -66880,15 +66062,23 @@ static int walIteratorInit( nByte = sizeof(WalIterator) + (nSegment-1)*sizeof(struct WalSegment) + iLast*sizeof(ht_slot); - p = (WalIterator *)sqlite3_malloc64(nByte - + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) - ); + p = (WalIterator *)sqlite3_malloc64(nByte); if( !p ){ return SQLITE_NOMEM_BKPT; } memset(p, 0, nByte); p->nSegment = nSegment; - aTmp = (ht_slot*)&(((u8*)p)[nByte]); + + /* Allocate temporary space used by the merge-sort routine. This block + ** of memory will be freed before this function returns. + */ + aTmp = (ht_slot *)sqlite3_malloc64( + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) + ); + if( !aTmp ){ + rc = SQLITE_NOMEM_BKPT; + } + i = iMode==2 ? iWal : walFramePage(nBackfill+1); for(; rc==SQLITE_OK && i<=iLastSeg; i+=iMode){ WalHashLoc sLoc; @@ -66926,6 +66116,8 @@ static int walIteratorInit( p->aSegment[i/iMode].aPgno = (u32*)sLoc.aPgno; } } + sqlite3_free(aTmp); + if( rc!=SQLITE_OK ){ walIteratorFree(p); p = 0; @@ -67472,7 +66664,6 @@ SQLITE_PRIVATE int sqlite3WalClose( pWal->writeLock = 1; walIndexWriteHdr(pWal); pWal->writeLock = 0; - } } @@ -68145,7 +67336,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ assert( mxReadMark<=pWal->hdr.mxFrame ); pWal->readLock = (i16)mxI; } - } return rc; } @@ -68230,15 +67420,6 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ } #endif /* SQLITE_ENABLE_SNAPSHOT */ -/* -** Return the current last frame in the wal-index - mxFrame for *-wal, -** or mxFrame2 for *-wal2. If the last frame is current in wal2, return -** mxFrame2 without clearing the 0x80000000 bit. -*/ -static u32 walGetPriorFrame(WalIndexHdr *pHdr){ - return (walidxGetFile(pHdr) ? pHdr->mxFrame2 : pHdr->mxFrame); -} - /* ** Begin a read transaction on the database. ** @@ -68301,7 +67482,7 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ rc = walOpenWal2(pWal); } - pWal->nPriorFrame = walGetPriorFrame(&pWal->hdr); + pWal->nPriorFrame = pWal->hdr.mxFrame; #ifdef SQLITE_ENABLE_SNAPSHOT if( rc==SQLITE_OK ){ if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){ @@ -68705,24 +67886,6 @@ static int walUpgradeReadlock(Wal *pWal){ #ifndef SQLITE_OMIT_CONCURRENT - -/* -** A concurrent transaction has conflicted with external frame iExternal. -** Transform this value to the one required by SQLITE_COMMIT_CONFLICT_FRAME - -** the frame offset within its wal file, with the 0x80000000 bit set for -** wal2, clear for the default wal file. -*/ -static u32 walConflictFrame(Wal *pWal, u32 iExternal){ - u32 iRet = iExternal; - if( isWalMode2(pWal) ){ - int bFile = walExternalDecode(iExternal, &iRet); - iRet = (iRet | (bFile ? 0x80000000 : 0)); - } - return iRet; -} - - - /* ** This function is only ever called when committing a "BEGIN CONCURRENT" ** transaction. It may be assumed that no frames have been written to @@ -68755,7 +67918,7 @@ SQLITE_PRIVATE int sqlite3WalLockForCommit( Wal *pWal, PgHdr *pPg1, Bitvec *pAllRead, - u32 *aConflict + Pgno *piConflict ){ int rc = walWriteLock(pWal); @@ -68787,10 +67950,7 @@ SQLITE_PRIVATE int sqlite3WalLockForCommit( if( pPg1==0 ){ /* If pPg1==0, then the current transaction modified the database ** schema. This means it conflicts with all other transactions. */ - u32 bFile = walidxGetFile(&pWal->hdr); - u32 iFrame = walidxGetMxFrame(&head, bFile) | (bFile << 31); - aConflict[SQLITE_COMMIT_CONFLICT_PGNO] = 1; - aConflict[SQLITE_COMMIT_CONFLICT_FRAME] = iFrame; + *piConflict = 1; rc = SQLITE_BUSY_SNAPSHOT; } @@ -68853,20 +68013,15 @@ SQLITE_PRIVATE int sqlite3WalLockForCommit( if( bWal2 ){ iWal = walExternalDecode(iFrame, &iFrame); } - sz = head.szPage; + sz = pWal->hdr.szPage; sz = (sz&0xfe00) + ((sz&0x0001)<<16); iOff = walFrameOffset(iFrame, sz) + WAL_FRAME_HDRSIZE + 40; rc = sqlite3OsRead(pWal->apWalFd[iWal],aNew,sizeof(aNew),iOff); if( rc==SQLITE_OK && memcmp(aOld, aNew, sizeof(aNew)) ){ - u32 iFrame = walConflictFrame(pWal, sLoc.iZero+i); - aConflict[SQLITE_COMMIT_CONFLICT_PGNO] = 1; - aConflict[SQLITE_COMMIT_CONFLICT_FRAME] = iFrame; rc = SQLITE_BUSY_SNAPSHOT; } }else if( sqlite3BitvecTestNotNull(pAllRead, sLoc.aPgno[i-1]) ){ - u32 iFrame = walConflictFrame(pWal, sLoc.iZero+i); - aConflict[SQLITE_COMMIT_CONFLICT_PGNO] = sLoc.aPgno[i-1]; - aConflict[SQLITE_COMMIT_CONFLICT_FRAME] = iFrame; + *piConflict = sLoc.aPgno[i-1]; rc = SQLITE_BUSY_SNAPSHOT; }else if( (pPg = sqlite3PagerLookup(pPg1->pPager, sLoc.aPgno[i-1])) ){ @@ -68900,7 +68055,7 @@ SQLITE_PRIVATE int sqlite3WalLockForCommit( } } - pWal->nPriorFrame = walGetPriorFrame(&pWal->hdr); + pWal->nPriorFrame = pWal->hdr.mxFrame; return rc; } @@ -69173,7 +68328,6 @@ static int walRestartLog(Wal *pWal){ rc = walUpgradeReadlock(pWal); } - pWal->nPriorFrame = walGetPriorFrame(&pWal->hdr); return rc; } @@ -69417,9 +68571,7 @@ SQLITE_PRIVATE int sqlite3WalFrames( if( rc ) return rc; } } - if( (int)pWal->szPage!=szPage ){ - return SQLITE_CORRUPT_BKPT; /* TH3 test case: cov1/corrupt155.test */ - } + assert( (int)pWal->szPage==szPage ); /* Setup information needed to write frames into the WAL */ w.pWal = pWal; @@ -69929,7 +69081,7 @@ SQLITE_PRIVATE int sqlite3WalInfo(Wal *pWal, u32 *pnPrior, u32 *pnFrame){ int rc = SQLITE_OK; if( pWal ){ *pnPrior = pWal->nPriorFrame; - *pnFrame = walGetPriorFrame(&pWal->hdr); + *pnFrame = walidxGetMxFrame(&pWal->hdr, walidxGetFile(&pWal->hdr)); } return rc; } @@ -70139,7 +69291,7 @@ SQLITE_PRIVATE int sqlite3WalJournalMode(Wal *pWal){ ** byte are used. The integer consists of all bytes that have bit 8 set and ** the first byte with bit 8 clear. The most significant byte of the integer ** appears first. A variable-length integer may not be more than 9 bytes long. -** As a special case, all 8 bits of the 9th byte are used as data. This +** As a special case, all 8 bytes of the 9th byte are used as data. This ** allows a 64-bit integer to be encoded in 9 bytes. ** ** 0x00 becomes 0x00000000 @@ -70231,7 +69383,7 @@ typedef struct BtreePtrmap BtreePtrmap; ** page that has been loaded into memory. The information in this object ** is derived from the raw on-disk page content. ** -** As each database page is loaded into memory, the pager allocates an +** As each database page is loaded into memory, the pager allocats an ** instance of this object and zeros the first 8 bytes. (This is the ** "extra" information associated with each page of the pager.) ** @@ -70331,12 +69483,6 @@ struct Btree { #ifndef SQLITE_OMIT_SHARED_CACHE BtLock lock; /* Object used to lock page 1 */ #endif -#ifndef SQLITE_OMIT_CONCURRENT - /* Return values for sqlite3_commit_status() requests: - ** SQLITE_COMMIT_FIRSTFRAME, COMMIT_NFRAME. - */ - u32 aCommit[2]; -#endif }; /* @@ -70536,7 +69682,7 @@ struct BtCursor { #define BTCF_WriteFlag 0x01 /* True if a write cursor */ #define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ #define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ -#define BTCF_AtLast 0x08 /* Cursor is pointing to the last entry */ +#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ #define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ #define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ #define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */ @@ -70688,9 +69834,8 @@ struct IntegrityCk { int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ u32 nStep; /* Number of steps into the integrity_check process */ 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) */ - int v2; /* Value for third %d substitution in zPfx */ + Pgno v1; /* Value for first %u substitution in zPfx */ + int v2; /* Value for second %d substitution in zPfx */ StrAccum errMsg; /* Accumulate the error message text here */ u32 *heap; /* Min-heap used for analyzing cell coverage */ sqlite3 *db; /* Database connection running the check */ @@ -70706,7 +69851,7 @@ struct IntegrityCk { /* ** get2byteAligned(), unlike get2byte(), requires that its argument point to a -** two-byte aligned address. get2byteAligned() is only used for accessing the +** two-byte aligned address. get2bytea() is only used for accessing the ** cell addresses in a btree header. */ #if SQLITE_BYTEORDER==4321 @@ -70883,7 +70028,7 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ ** ** There is a corresponding leave-all procedures. ** -** Enter the mutexes in ascending order by BtShared pointer address +** Enter the mutexes in accending order by BtShared pointer address ** to avoid the possibility of deadlock when two threads with ** two or more btrees in common both try to lock all their btrees ** at the same instant. @@ -71015,7 +70160,6 @@ SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ /************** End of btmutex.c *********************************************/ /************** Begin file btree.c *******************************************/ - /* ** 2004 April 6 ** @@ -71154,8 +70298,8 @@ SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){ int corruptPageError(int lineno, MemPage *p){ char *zMsg; sqlite3BeginBenignMalloc(); - zMsg = sqlite3_mprintf("database corruption page %u of %s", - p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) + zMsg = sqlite3_mprintf("database corruption page %d of %s", + (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) ); sqlite3EndBenignMalloc(); if( zMsg ){ @@ -72197,25 +71341,8 @@ 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; - 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); - } -#endif /* SQLITE_DEBUG */ } -#endif /* SQLITE_ENABLE_CURSOR_HINTS */ - +#endif /* ** Provide flag hints to the cursor. @@ -72307,7 +71434,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ - TRACE(("PTRMAP_UPDATE: %u->(%u,%u)\n", key, eType, parent)); + TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); *pRC= rc = sqlite3PagerWrite(pDbPage); if( rc==SQLITE_OK ){ pPtrmap[offset] = eType; @@ -72506,31 +71633,27 @@ static void btreeParseCellPtr( iKey = *pIter; if( iKey>=0x80 ){ u8 x; - iKey = (iKey<<7) ^ (x = *++pIter); + iKey = ((iKey&0x7f)<<7) | ((x = *++pIter) & 0x7f); if( x>=0x80 ){ - iKey = (iKey<<7) ^ (x = *++pIter); + iKey = (iKey<<7) | ((x =*++pIter) & 0x7f); if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++pIter); + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); if( x>=0x80 ){ - iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); if( x>=0x80 ){ - iKey = (iKey<<8) ^ 0x8000 ^ (*++pIter); + iKey = (iKey<<8) | (*++pIter); } } } } } - }else{ - iKey ^= 0x204000; } - }else{ - iKey ^= 0x4000; } } pIter++; @@ -72607,11 +71730,10 @@ static void btreeParseCell( ** ** cellSizePtrNoPayload() => table internal nodes ** cellSizePtrTableLeaf() => table leaf nodes -** cellSizePtr() => index internal nodes -** cellSizeIdxLeaf() => index leaf nodes +** cellSizePtr() => all index nodes & table leaf nodes */ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ - u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ + u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */ u8 *pEnd; /* End mark for a varint */ u32 nSize; /* Size value to return */ @@ -72624,49 +71746,6 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ pPage->xParseCell(pPage, pCell, &debuginfo); #endif - assert( pPage->childPtrSize==4 ); - nSize = *pIter; - if( nSize>=0x80 ){ - pEnd = &pIter[8]; - nSize &= 0x7f; - do{ - nSize = (nSize<<7) | (*++pIter & 0x7f); - }while( *(pIter)>=0x80 && pItermaxLocal ); - testcase( nSize==(u32)pPage->maxLocal+1 ); - if( nSize<=pPage->maxLocal ){ - nSize += (u32)(pIter - pCell); - assert( nSize>4 ); - }else{ - int minLocal = pPage->minLocal; - nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); - testcase( nSize==pPage->maxLocal ); - testcase( nSize==(u32)pPage->maxLocal+1 ); - if( nSize>pPage->maxLocal ){ - nSize = minLocal; - } - nSize += 4 + (u16)(pIter - pCell); - } - assert( nSize==debuginfo.nSize || CORRUPT_DB ); - return (u16)nSize; -} -static u16 cellSizePtrIdxLeaf(MemPage *pPage, u8 *pCell){ - u8 *pIter = pCell; /* For looping over bytes of pCell */ - u8 *pEnd; /* End mark for a varint */ - u32 nSize; /* Size value to return */ - -#ifdef SQLITE_DEBUG - /* The value returned by this function should always be the same as - ** the (CellInfo.nSize) value found by doing a full parse of the - ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of - ** this function verifies that this invariant is not violated. */ - CellInfo debuginfo; - pPage->xParseCell(pPage, pCell, &debuginfo); -#endif - - assert( pPage->childPtrSize==0 ); nSize = *pIter; if( nSize>=0x80 ){ pEnd = &pIter[8]; @@ -72791,7 +71870,7 @@ static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){ pPage->xParseCell(pPage, pCell, &info); if( info.nLocalaDataEnd, pCell, pCell+info.nLocal) ){ + if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){ testcase( pSrc!=pPage ); *pRC = SQLITE_CORRUPT_BKPT; return; @@ -72892,7 +71971,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ iCellStart = get2byte(&data[hdr+5]); if( nCell>0 ){ temp = sqlite3PagerTempSpace(pPage->pBt->pPager); - memcpy(temp, data, usableSize); + memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); src = temp; for(i=0; iiCellLast ){ + if( pciCellLast ){ return SQLITE_CORRUPT_PAGE(pPage); } - assert( pc>=0 && pc<=iCellLast ); + assert( pc>=iCellStart && pc<=iCellLast ); size = pPage->xCellSize(pPage, &src[pc]); cbrk -= size; if( cbrkusableSize ){ @@ -73021,7 +72100,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ ** allocation is being made in order to insert a new cell, so we will ** also end up needing a new cell pointer. */ -static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ +static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ u8 * const data = pPage->aData; /* Local cache of pPage->aData */ int top; /* First byte of cell content area */ @@ -73047,14 +72126,13 @@ static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ ** integer, so a value of 0 is used in its place. */ pTmp = &data[hdr+5]; top = get2byte(pTmp); + assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */ if( gap>top ){ if( top==0 && pPage->pBt->usableSize==65536 ){ top = 65536; }else{ return SQLITE_CORRUPT_PAGE(pPage); } - }else if( top>(int)pPage->pBt->usableSize ){ - return SQLITE_CORRUPT_PAGE(pPage); } /* If there is enough space between gap and top for one more cell pointer, @@ -73116,7 +72194,7 @@ static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ ** ** Even though the freeblock list was checked by btreeComputeFreeSpace(), ** that routine will not detect overlap between cells or freeblocks. Nor -** does it detect cells or freeblocks that encroach into the reserved bytes +** does it detect cells or freeblocks that encrouch into the reserved bytes ** at the end of the page. So do additional corruption checks inside this ** routine and return SQLITE_CORRUPT if any problems are found. */ @@ -73137,7 +72215,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( iSize>=4 ); /* Minimum cell size is 4 */ - assert( CORRUPT_DB || iStart<=pPage->pBt->usableSize-4 ); + assert( iStart<=pPage->pBt->usableSize-4 ); /* The list of freeblocks must be in ascending order. Find the ** spot on the list where iStart should be inserted. @@ -73194,11 +72272,6 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ } pTmp = &data[hdr+5]; x = get2byte(pTmp); - if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ - /* Overwrite deleted information with zeros when the secure_delete - ** option is enabled */ - memset(&data[iStart], 0, iSize); - } if( iStart<=x ){ /* The new freeblock is at the beginning of the cell content area, ** so just extend the cell content area rather than create another @@ -73210,9 +72283,14 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ }else{ /* Insert the new freeblock into the freelist */ put2byte(&data[iPtr], iStart); - put2byte(&data[iStart], iFreeBlk); - put2byte(&data[iStart+2], iSize); } + if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ + /* Overwrite deleted information with zeros when the secure_delete + ** option is enabled */ + memset(&data[iStart], 0, iSize); + } + put2byte(&data[iStart], iFreeBlk); + put2byte(&data[iStart+2], iSize); pPage->nFree += iOrigSize; return SQLITE_OK; } @@ -73249,14 +72327,14 @@ static int decodeFlags(MemPage *pPage, int flagByte){ }else if( flagByte==(PTF_ZERODATA | PTF_LEAF) ){ pPage->intKey = 0; pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtrIdxLeaf; + pPage->xCellSize = cellSizePtr; pPage->xParseCell = btreeParseCellPtrIndex; pPage->maxLocal = pBt->maxLocal; pPage->minLocal = pBt->minLocal; }else{ pPage->intKey = 0; pPage->intKeyLeaf = 0; - pPage->xCellSize = cellSizePtrIdxLeaf; + pPage->xCellSize = cellSizePtr; pPage->xParseCell = btreeParseCellPtrIndex; return SQLITE_CORRUPT_PAGE(pPage); } @@ -73575,41 +72653,68 @@ SQLITE_PRIVATE Pgno sqlite3BtreeLastPage(Btree *p){ /* ** Get a page from the pager and initialize it. +** +** If pCur!=0 then the page is being fetched as part of a moveToChild() +** call. Do additional sanity checking on the page in this case. +** And if the fetch fails, this routine must decrement pCur->iPage. +** +** The page is fetched as read-write unless pCur is not NULL and is +** a read-only cursor. +** +** If an error occurs, then *ppPage is undefined. It +** may remain unchanged, or it may be set to an invalid value. */ static int getAndInitPage( BtShared *pBt, /* The database file */ Pgno pgno, /* Number of the page to get */ MemPage **ppPage, /* Write the page pointer here */ + BtCursor *pCur, /* Cursor to receive the page, or NULL */ int bReadOnly /* True for a read-only page */ ){ int rc; DbPage *pDbPage; - MemPage *pPage; assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pCur==0 || ppPage==&pCur->pPage ); + assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); + assert( pCur==0 || pCur->iPage>0 ); if( pgno>btreePagecount(pBt) ){ - *ppPage = 0; - return SQLITE_CORRUPT_BKPT; + rc = SQLITE_CORRUPT_BKPT; + goto getAndInitPage_error1; } rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); if( rc ){ - *ppPage = 0; - return rc; + goto getAndInitPage_error1; } - pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); - if( pPage->isInit==0 ){ + *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + if( (*ppPage)->isInit==0 ){ btreePageFromDbPage(pDbPage, pgno, pBt); - rc = btreeInitPage(pPage); + rc = btreeInitPage(*ppPage); if( rc!=SQLITE_OK ){ - releasePage(pPage); - *ppPage = 0; - return rc; + goto getAndInitPage_error2; } } - assert( pPage->pgno==pgno || CORRUPT_DB ); - assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); - *ppPage = pPage; + assert( (*ppPage)->pgno==pgno || CORRUPT_DB ); + assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); + + /* If obtaining a child page for a cursor, we must verify that the page is + ** compatible with the root page. */ + if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){ + rc = SQLITE_CORRUPT_PGNO(pgno); + goto getAndInitPage_error2; + } return SQLITE_OK; + +getAndInitPage_error2: + releasePage(*ppPage); +getAndInitPage_error1: + if( pCur ){ + pCur->iPage--; + pCur->pPage = pCur->apPage[pCur->iPage]; + } + testcase( pgno==0 ); + assert( pgno!=0 || rc!=SQLITE_OK ); + return rc; } #ifndef SQLITE_OMIT_CONCURRENT @@ -73703,7 +72808,7 @@ static void pageReinit(DbPage *pData){ ** call to btreeInitPage() will likely return SQLITE_CORRUPT. ** But no harm is done by this. And it is very important that ** btreeInitPage() be called on every btree page so we make - ** the call for every page that comes in for re-initializing. */ + ** the call for every page that comes in for re-initing. */ btreeInitPage(pPage); } } @@ -73882,9 +72987,6 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( assert( sizeof(u16)==2 ); assert( sizeof(Pgno)==4 ); - /* Suppress false-positive compiler warning from PVS-Studio */ - memset(&zDbHeader[16], 0, 8); - pBt = sqlite3MallocZero( sizeof(*pBt) ); if( pBt==0 ){ rc = SQLITE_NOMEM_BKPT; @@ -74101,7 +73203,7 @@ static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){ ** can mean that fillInCell() only initializes the first 2 or 3 ** bytes of pTmpSpace, but that the first 4 bytes are copied from ** it into a database page. This is not actually a problem, but it - ** does cause a valgrind error when the 1 or 2 bytes of uninitialized + ** does cause a valgrind error when the 1 or 2 bytes of unitialized ** data is passed to system call write(). So to avoid this error, ** zero the first 4 bytes of temp space here. ** @@ -74336,7 +73438,7 @@ SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){ /* ** Return the number of bytes of space at the end of every page that -** are intentionally left unused. This is the "reserved" space that is +** are intentually left unused. This is the "reserved" space that is ** sometimes used by extensions. ** ** The value returned is the larger of the current reserve size and @@ -74583,6 +73685,7 @@ static int lockBtree(BtShared *pBt){ ){ goto page1_init_failed; } + pBt->btsFlags |= BTS_PAGESIZE_FIXED; assert( (pageSize & 7)==0 ); /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte ** integer at offset 20 is the number of bytes of space at the end of @@ -74602,7 +73705,6 @@ static int lockBtree(BtShared *pBt){ releasePageOne(pPage1); pBt->usableSize = usableSize; pBt->pageSize = pageSize; - pBt->btsFlags |= BTS_PAGESIZE_FIXED; freeTempSpace(pBt); rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, pageSize-usableSize); @@ -74622,7 +73724,6 @@ static int lockBtree(BtShared *pBt){ if( usableSize<480 ){ goto page1_init_failed; } - pBt->btsFlags |= BTS_PAGESIZE_FIXED; pBt->pageSize = pageSize; pBt->usableSize = usableSize; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -74801,11 +73902,7 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ ** when A already has a read lock, we encourage A to give up and let B ** proceed. */ -static SQLITE_NOINLINE int btreeBeginTrans( - Btree *p, /* The btree in which to start the transaction */ - int wrflag, /* True to start a write transaction */ - int *pSchemaVersion /* Put schema version number here, if not NULL */ -){ +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ BtShared *pBt = p->pBt; Pager *pPager = pBt->pPager; int rc = SQLITE_OK; @@ -74992,28 +74089,6 @@ static SQLITE_NOINLINE int btreeBeginTrans( sqlite3BtreeLeave(p); return rc; } -SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ - BtShared *pBt; - if( p->sharable - || p->inTrans==TRANS_NONE - || (p->inTrans==TRANS_READ && wrflag!=0) - ){ - return btreeBeginTrans(p,wrflag,pSchemaVersion); - } - pBt = p->pBt; - if( pSchemaVersion ){ - *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); - } - if( wrflag ){ - /* This call makes sure that the pager has the correct number of - ** open savepoints. If the second parameter is greater than 0 and - ** the sub-journal is not already open, then it will be opened here. - */ - return sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); - }else{ - return SQLITE_OK; - } -} #ifndef SQLITE_OMIT_AUTOVACUUM @@ -75151,7 +74226,7 @@ static int relocatePage( if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; /* Move page iDbPage from its current location to page number iFreePage */ - TRACE(("AUTOVACUUM: Moving %u to free page %u (ptr page %u type %u)\n", + TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", iDbPage, iFreePage, iPtrPage, eType)); rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); if( rc!=SQLITE_OK ){ @@ -75675,9 +74750,6 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){ BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); -#ifndef SQLITE_OMIT_CONCURRENT - memset(p->aCommit, 0, sizeof(p->aCommit)); -#endif #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ assert( ISCONCURRENT==0 ); @@ -75697,19 +74769,6 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){ if( rc==SQLITE_OK ){ rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zSuperJrnl, 0); } -#ifndef SQLITE_OMIT_CONCURRENT - if( rc==SQLITE_OK ){ - u32 iPrev = 0; - u32 iCurrent = 0; - sqlite3PagerWalInfo(pBt->pPager, &iPrev, &iCurrent); - if( (iPrev&0x80000000)!=(iCurrent&0x80000000) ){ - iPrev = (iPrev & 0x7FFFFFFF) | (iCurrent & 0x80000000); - } - - p->aCommit[SQLITE_COMMIT_FIRSTFRAME] = iPrev+1; - p->aCommit[SQLITE_COMMIT_NFRAME] = iCurrent-iPrev; - } -#endif sqlite3BtreeLeave(p); } return rc; @@ -76310,6 +75369,7 @@ SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){ pCur->curFlags &= ~BTCF_Pinned; } +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC /* ** Return the offset into the database file for the start of the ** payload to which the cursor is pointing. @@ -76321,6 +75381,7 @@ SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){ return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) + (i64)(pCur->info.pPayload - pCur->pPage->aData); } +#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ /* ** Return the number of bytes of payload for the entry that pCur is @@ -76346,7 +75407,7 @@ SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){ ** routine always returns 2147483647 (which is the largest record ** that SQLite can handle) or more. But returning a smaller value might ** prevent large memory allocations when trying to interpret a -** corrupt database. +** corrupt datrabase. ** ** The current implementation merely returns the size of the underlying ** database file. @@ -76810,6 +75871,7 @@ SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ static int moveToChild(BtCursor *pCur, u32 newPgno){ BtShared *pBt = pCur->pBt; int rc; + assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPageapPage[pCur->iPage] = pCur->pPage; pCur->ix = 0; pCur->iPage++; - rc = getAndInitPage(pBt, newPgno, &pCur->pPage, pCur->curPagerFlags); + rc = getAndInitPage(pBt, newPgno, &pCur->pPage, + pCur, pCur->curPagerFlags); if( rc==SQLITE_OK ){ - assert( pCur->pPage!=0 ); setMempageRoot(pCur->pPage, pCur->pgnoRoot); - if( pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey ){ - releasePage(pCur->pPage); - rc = SQLITE_CORRUPT_PGNO(newPgno); - } - } - if( rc ){ - pCur->pPage = pCur->apPage[--pCur->iPage]; } return rc; } @@ -76942,7 +75997,7 @@ static int moveToRoot(BtCursor *pCur){ sqlite3BtreeClearCursor(pCur); } rc = getAndInitPage(pCur->pBt, pCur->pgnoRoot, &pCur->pPage, - pCur->curPagerFlags); + 0, pCur->curPagerFlags); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; return rc; @@ -77055,7 +76110,7 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ *pRes = 0; rc = moveToLeftmost(pCur); }else if( rc==SQLITE_EMPTY ){ - assert( pCur->pgnoRoot==0 || (pCur->pPage!=0 && pCur->pPage->nCell==0) ); + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); *pRes = 1; rc = SQLITE_OK; } @@ -77160,7 +76215,7 @@ SQLITE_PRIVATE int sqlite3BtreeTableMoveto( /* If the requested key is one more than the previous key, then ** try to get there using sqlite3BtreeNext() rather than a full ** binary search. This is an optimization only. The correct answer - ** is still obtained without this case, only a little more slowly. */ + ** is still obtained without this case, only a little more slowely */ if( pCur->info.nKey+1==intKey ){ *pRes = 0; rc = sqlite3BtreeNext(pCur, 0); @@ -77556,36 +76611,10 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( }else{ chldPg = get4byte(findCell(pPage, lwr)); } - - /* This block is similar to an in-lined version of: - ** - ** pCur->ix = (u16)lwr; - ** rc = moveToChild(pCur, chldPg); - ** if( rc ) break; - */ - pCur->info.nSize = 0; - pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ - return SQLITE_CORRUPT_BKPT; - } - pCur->aiIdx[pCur->iPage] = (u16)lwr; - pCur->apPage[pCur->iPage] = pCur->pPage; - pCur->ix = 0; - pCur->iPage++; - rc = getAndInitPage(pCur->pBt, chldPg, &pCur->pPage, pCur->curPagerFlags); - if( rc==SQLITE_OK - && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) - ){ - releasePage(pCur->pPage); - rc = SQLITE_CORRUPT_PGNO(chldPg); - } - if( rc ){ - pCur->pPage = pCur->apPage[--pCur->iPage]; - break; - } - /* - ***** End of in-lined moveToChild() call */ - } + pCur->ix = (u16)lwr; + rc = moveToChild(pCur, chldPg); + if( rc ) break; + } moveto_index_finish: pCur->info.nSize = 0; assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); @@ -77676,8 +76705,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ pPage = pCur->pPage; idx = ++pCur->ix; - if( sqlite3FaultSim(412) ) pPage->isInit = 0; - if( !pPage->isInit ){ + if( !pPage->isInit || sqlite3FaultSim(412) ){ return SQLITE_CORRUPT_BKPT; } @@ -77950,7 +76978,7 @@ static int allocateBtreePage( memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); *ppPage = pTrunk; pTrunk = 0; - TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); }else if( k>(u32)(pBt->usableSize/4 - 2) ){ /* Value of k is out of range. Database corruption */ rc = SQLITE_CORRUPT_PGNO(iTrunk); @@ -78016,7 +77044,7 @@ static int allocateBtreePage( } } pTrunk = 0; - TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); #endif }else if( k>0 ){ /* Extract a leaf from the trunk */ @@ -78061,8 +77089,8 @@ static int allocateBtreePage( ){ int noContent; *pPgno = iPage; - TRACE(("ALLOCATE: %u was leaf %u of %u on trunk %u" - ": %u more free pages\n", + TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" + ": %d more free pages\n", *pPgno, closest+1, k, pTrunk->pgno, n-1)); rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ) goto end_allocate_page; @@ -78118,7 +77146,7 @@ static int allocateBtreePage( ** becomes a new pointer-map page, the second is used by the caller. */ MemPage *pPg = 0; - TRACE(("ALLOCATE: %u from end of file (pointer-map page)\n", pBt->nPage)); + TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); if( rc==SQLITE_OK ){ @@ -78141,7 +77169,7 @@ static int allocateBtreePage( releasePage(*ppPage); *ppPage = 0; } - TRACE(("ALLOCATE: %u from end of file\n", *pPgno)); + TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); } assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) ); @@ -78269,7 +77297,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ } rc = btreeSetHasContent(pBt, iPage); } - TRACE(("FREE-PAGE: %u leaf on trunk page %u\n",pPage->pgno,pTrunk->pgno)); + TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno)); goto freepage_out; } } @@ -78290,7 +77318,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ put4byte(pPage->aData, iTrunk); put4byte(&pPage->aData[4], 0); put4byte(&pPage1->aData[32], iPage); - TRACE(("FREE-PAGE: %u new trunk page replacing %u\n", pPage->pgno, iTrunk)); + TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk)); freepage_out: if( pPage ){ @@ -78379,7 +77407,7 @@ static SQLITE_NOINLINE int clearCellOverflow( /* Call xParseCell to compute the size of a cell. If the cell contains ** overflow, then invoke cellClearOverflow to clear out that overflow. -** Store the result code (SQLITE_OK or some error code) in rc. +** STore the result code (SQLITE_OK or some error code) in rc. ** ** Implemented as macro to force inlining for performance. */ @@ -78648,14 +77676,6 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ ** in pTemp or the original pCell) and also record its index. ** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. -** -** The insertCellFast() routine below works exactly the same as -** insertCell() except that it lacks the pTemp and iChild parameters -** which are assumed zero. Other than that, the two routines are the -** same. -** -** Fixes or enhancements to this routine should be reflected in -** insertCellFast()! */ static int insertCell( MemPage *pPage, /* Page into which we are copying */ @@ -78678,104 +77698,14 @@ static int insertCell( assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); assert( pPage->nFree>=0 ); - assert( iChild>0 ); if( pPage->nOverflow || sz+2>pPage->nFree ){ if( pTemp ){ memcpy(pTemp, pCell, sz); pCell = pTemp; } - put4byte(pCell, iChild); - j = pPage->nOverflow++; - /* Comparison against ArraySize-1 since we hold back one extra slot - ** as a contingency. In other words, never need more than 3 overflow - ** slots but 4 are allocated, just to be safe. */ - assert( j < ArraySize(pPage->apOvfl)-1 ); - pPage->apOvfl[j] = pCell; - pPage->aiOvfl[j] = (u16)i; - - /* When multiple overflows occur, they are always sequential and in - ** sorted order. This invariants arise because multiple overflows can - ** only occur when inserting divider cells into the parent page during - ** balancing, and the dividers are adjacent and sorted. - */ - assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ - assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ - }else{ - BtShared *pBt = pPage->pBt; - int rc = sqlite3PagerWrite(pPage->pDbPage); - if( NEVER(rc!=SQLITE_OK) ){ - return rc; + if( iChild ){ + put4byte(pCell, iChild); } - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - data = pPage->aData; - assert( &data[pPage->cellOffset]==pPage->aCellIdx ); - rc = allocateSpace(pPage, sz, &idx); - if( rc ){ return rc; } - /* The allocateSpace() routine guarantees the following properties - ** if it returns successfully */ - assert( idx >= 0 ); - assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); - assert( idx+sz <= (int)pPage->pBt->usableSize ); - pPage->nFree -= (u16)(2 + sz); - /* In a corrupt database where an entry in the cell index section of - ** a btree page has a value of 3 or less, the pCell value might point - ** as many as 4 bytes in front of the start of the aData buffer for - ** the source page. Make sure this does not cause problems by not - ** reading the first 4 bytes */ - memcpy(&data[idx+4], pCell+4, sz-4); - put4byte(&data[idx], iChild); - pIns = pPage->aCellIdx + i*2; - memmove(pIns+2, pIns, 2*(pPage->nCell - i)); - put2byte(pIns, idx); - pPage->nCell++; - /* increment the cell count */ - if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; - assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); -#ifndef SQLITE_OMIT_AUTOVACUUM - if( REQUIRE_PTRMAP ){ - int rc2 = SQLITE_OK; - /* The cell may contain a pointer to an overflow page. If so, write - ** the entry for the overflow page into the pointer map. - */ - ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); - if( rc2 ) return rc2; - } -#endif - } - return SQLITE_OK; -} - -/* -** This variant of insertCell() assumes that the pTemp and iChild -** parameters are both zero. Use this variant in sqlite3BtreeInsert() -** for performance improvement, and also so that this variant is only -** called from that one place, and is thus inlined, and thus runs must -** faster. -** -** Fixes or enhancements to this routine should be reflected into -** the insertCell() routine. -*/ -static int insertCellFast( - MemPage *pPage, /* Page into which we are copying */ - int i, /* New cell becomes the i-th cell of the page */ - u8 *pCell, /* Content of the new cell */ - int sz /* Bytes of content in pCell */ -){ - int idx = 0; /* Where to write new cell content in data[] */ - int j; /* Loop counter */ - u8 *data; /* The content of the whole page */ - u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ - - assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); - assert( MX_CELL(pPage->pBt)<=10921 ); - assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); - assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); - assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); - assert( pPage->nFree>=0 ); - assert( pPage->nOverflow==0 ); - if( sz+2>pPage->nFree ){ j = pPage->nOverflow++; /* Comparison against ArraySize-1 since we hold back one extra slot ** as a contingency. In other words, never need more than 3 overflow @@ -78808,7 +77738,17 @@ static int insertCellFast( assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); assert( idx+sz <= (int)pBt->usableSize ); pPage->nFree -= (u16)(2 + sz); - memcpy(&data[idx], pCell, sz); + if( iChild ){ + /* In a corrupt database where an entry in the cell index section of + ** a btree page has a value of 3 or less, the pCell value might point + ** as many as 4 bytes in front of the start of the aData buffer for + ** the source page. Make sure this does not cause problems by not + ** reading the first 4 bytes */ + memcpy(&data[idx+4], pCell+4, sz-4); + put4byte(&data[idx], iChild); + }else{ + memcpy(&data[idx], pCell, sz); + } pIns = pPage->aCellIdx + i*2; memmove(pIns+2, pIns, 2*(pPage->nCell - i)); put2byte(pIns, idx); @@ -78991,10 +77931,10 @@ static int rebuildPage( assert( i(u32)usableSize) ){ j = 0; } + if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); - for(k=0; ALWAYS(kixNx[k]<=i; k++){} + for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kapEnd[k]; pData = pEnd; @@ -79057,7 +77997,7 @@ static int rebuildPage( ** Finally, argument pBegin points to the byte immediately following the ** end of the space required by this page for the cell-pointer area (for ** all cells - not just those inserted by the current call). If the content -** area must be extended to before this point in order to accommodate all +** area must be extended to before this point in order to accomodate all ** cells in apCell[], then the cells do not fit and non-zero is returned. */ static int pageInsertArray( @@ -79077,7 +78017,7 @@ static int pageInsertArray( u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; - for(k=0; ALWAYS(kixNx[k]<=i ; k++){} + for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kapEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; @@ -79135,50 +78075,42 @@ static int pageFreeArray( u8 * const pEnd = &aData[pPg->pBt->usableSize]; u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; int nRet = 0; - int i, j; + int i; int iEnd = iFirst + nCell; - int nFree = 0; - int aOfst[10]; - int aAfter[10]; + u8 *pFree = 0; /* \__ Parameters for pending call to */ + int szFree = 0; /* / freeSpace() */ for(i=iFirst; iapCell[i]; if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ int sz; - int iAfter; - int iOfst; /* No need to use cachedCellSize() here. The sizes of all cells that ** are to be freed have already been computing while deciding which ** cells need freeing */ sz = pCArray->szCell[i]; assert( sz>0 ); - iOfst = (u16)(pCell - aData); - iAfter = iOfst+sz; - for(j=0; j=nFree ){ - if( nFree>=(int)(sizeof(aOfst)/sizeof(aOfst[0])) ){ - for(j=0; jaData && (pFree - aData)<65536 ); + freeSpace(pPg, (u16)(pFree - aData), szFree); + } + pFree = pCell; + szFree = sz; + if( pFree+sz>pEnd ){ + return 0; } - aOfst[nFree] = iOfst; - aAfter[nFree] = iAfter; - if( &aData[iAfter]>pEnd ) return 0; - nFree++; + }else{ + /* The current cell is adjacent to and before the pFree cell. + ** Combine the two regions into one to reduce the number of calls + ** to freeSpace(). */ + pFree = pCell; + szFree += sz; } nRet++; } } - for(j=0; jaData && (pFree - aData)<65536 ); + freeSpace(pPg, (u16)(pFree - aData), szFree); } return nRet; } @@ -79231,9 +78163,9 @@ static int editPage( nCell -= nTail; } - pData = &aData[get2byte(&aData[hdr+5])]; + pData = &aData[get2byteNotZero(&aData[hdr+5])]; if( pDatapPg->aDataEnd) ) goto editpage_fail; + if( pData>pPg->aDataEnd ) goto editpage_fail; /* Add cells to the start of the page */ if( iNew0), or ** (2) pPage is a virtual root page. A virtual root page is when @@ -79972,7 +78904,7 @@ static int balance_nonroot( ** that page. */ assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB); - TRACE(("BALANCE: old: %u(nc=%u) %u(nc=%u) %u(nc=%u)\n", + TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n", apOld[0]->pgno, apOld[0]->nCell, nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0, nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0 @@ -80056,8 +78988,8 @@ static int balance_nonroot( } } - TRACE(("BALANCE: new: %u(%u nc=%u) %u(%u nc=%u) %u(%u nc=%u) " - "%u(%u nc=%u) %u(%u nc=%u)\n", + TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) " + "%d(%d nc=%d) %d(%d nc=%d)\n", apNew[0]->pgno, szNew[0], cntNew[0], nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0, @@ -80189,9 +79121,9 @@ static int balance_nonroot( iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; ALWAYS(k=0 && iPg=1 || i>=0 ); - assert( iPg=0 /* On the upwards pass, or... */ || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ @@ -80304,7 +79234,7 @@ static int balance_nonroot( } assert( pParent->isInit ); - TRACE(("BALANCE: finished: old=%u new=%u cells=%u\n", + TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", nOld, nNew, b.nCell)); /* Free any old pages that were not reused as new pages. @@ -80389,7 +79319,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); assert( pChild->nCell==pRoot->nCell || CORRUPT_DB ); - TRACE(("BALANCE: copy root %u into %u\n", pRoot->pgno, pChild->pgno)); + TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); /* Copy the overflow cells from pRoot to pChild */ memcpy(pChild->aiOvfl, pRoot->aiOvfl, @@ -80583,7 +79513,7 @@ static int btreeOverwriteContent( ){ int nData = pX->nData - iOffset; if( nData<=0 ){ - /* Overwriting with zeros */ + /* Overwritting with zeros */ int i; for(i=0; ipData to write */ @@ -80872,7 +79802,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( } } assert( pCur->eState==CURSOR_VALID - || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); + || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); @@ -80887,7 +79817,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( if( rc ) return rc; } - TRACE(("INSERT: table=%u nkey=%lld ndata=%u page=%u %s\n", + TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); assert( pPage->isInit || CORRUPT_DB ); @@ -80964,7 +79894,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( }else{ assert( pPage->leaf ); } - rc = insertCellFast(pPage, idx, newCell, szNew); + rc = insertCell(pPage, idx, newCell, szNew, 0, 0); assert( pPage->nOverflow==0 || rc==SQLITE_OK ); assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); @@ -81188,9 +80118,6 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ return SQLITE_CORRUPT_BKPT; } - if( pCell<&pPage->aCellIdx[pPage->nCell] ){ - return SQLITE_CORRUPT_BKPT; - } /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must ** be preserved following this delete operation. If the current delete @@ -81367,7 +80294,7 @@ static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ MemPage *pRoot; Pgno pgnoRoot; int rc; - int ptfFlags; /* Page-type flags for the root page of new table */ + int ptfFlags; /* Page-type flage for the root page of new table */ assert( sqlite3BtreeHoldsMutex(p) ); assert( pBt->inTransaction==TRANS_WRITE ); @@ -81537,7 +80464,7 @@ static int clearDatabasePage( if( pgno>btreePagecount(pBt) ){ return SQLITE_CORRUPT_BKPT; } - rc = getAndInitPage(pBt, pgno, &pPage, 0); + rc = getAndInitPage(pBt, pgno, &pPage, 0, 0); if( rc ) return rc; setMempageRoot(pPage, pgnoRoot); if( (pBt->openFlags & BTREE_SINGLE)==0 @@ -81943,8 +80870,7 @@ static void checkAppendMsg( sqlite3_str_append(&pCheck->errMsg, "\n", 1); } if( pCheck->zPfx ){ - sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, - pCheck->v0, pCheck->v1, pCheck->v2); + sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); } sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); va_end(ap); @@ -81984,11 +80910,11 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ */ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ if( iPage>pCheck->nPage || iPage==0 ){ - checkAppendMsg(pCheck, "invalid page number %u", iPage); + checkAppendMsg(pCheck, "invalid page number %d", iPage); return 1; } if( getPageReferenced(pCheck, iPage) ){ - checkAppendMsg(pCheck, "2nd reference to page %u", iPage); + checkAppendMsg(pCheck, "2nd reference to page %d", iPage); return 1; } setPageReferenced(pCheck, iPage); @@ -82014,13 +80940,13 @@ static void checkPtrmap( rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) checkOom(pCheck); - checkAppendMsg(pCheck, "Failed to read ptrmap key=%u", iChild); + checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild); return; } if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ checkAppendMsg(pCheck, - "Bad ptr map entry key=%u expected=(%u,%u) got=(%u,%u)", + "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", iChild, eType, iParent, ePtrmapType, iPtrmapParent); } } @@ -82045,7 +80971,7 @@ static void checkList( if( checkRef(pCheck, iPage) ) break; N--; if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ - checkAppendMsg(pCheck, "failed to get page %u", iPage); + checkAppendMsg(pCheck, "failed to get page %d", iPage); break; } pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); @@ -82058,7 +80984,7 @@ static void checkList( #endif if( n>pCheck->pBt->usableSize/4-2 ){ checkAppendMsg(pCheck, - "freelist leaf count too big on page %u", iPage); + "freelist leaf count too big on page %d", iPage); N--; }else{ for(i=0; i<(int)n; i++){ @@ -82090,7 +81016,7 @@ static void checkList( } if( N && nErrAtStart==pCheck->nErr ){ checkAppendMsg(pCheck, - "%s is %u but should be %u", + "%s is %d but should be %d", isFreeList ? "size" : "overflow list length", expected-N, expected); } @@ -82205,7 +81131,7 @@ static int checkTreePage( usableSize = pBt->usableSize; if( iPage==0 ) return 0; if( checkRef(pCheck, iPage) ) return 0; - pCheck->zPfx = "Tree %u page %u: "; + pCheck->zPfx = "Page %u: "; pCheck->v1 = iPage; if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ checkAppendMsg(pCheck, @@ -82232,7 +81158,7 @@ static int checkTreePage( hdr = pPage->hdrOffset; /* Set up for cell analysis */ - pCheck->zPfx = "Tree %u page %u cell %u: "; + pCheck->zPfx = "On tree page %u cell %d: "; contentOffset = get2byteNotZero(&data[hdr+5]); assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ @@ -82252,7 +81178,7 @@ static int checkTreePage( pgno = get4byte(&data[hdr+8]); #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ - pCheck->zPfx = "Tree %u page %u right child: "; + pCheck->zPfx = "On page %u at right child: "; checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); } #endif @@ -82276,7 +81202,7 @@ static int checkTreePage( pc = get2byteAligned(pCellIdx); pCellIdx -= 2; if( pcusableSize-4 ){ - checkAppendMsg(pCheck, "Offset %u out of range %u..%u", + checkAppendMsg(pCheck, "Offset %d out of range %d..%d", pc, contentOffset, usableSize-4); doCoverageCheck = 0; continue; @@ -82408,7 +81334,7 @@ static int checkTreePage( */ if( heap[0]==0 && nFrag!=data[hdr+7] ){ checkAppendMsg(pCheck, - "Fragmentation of %u bytes reported as %u on page %u", + "Fragmentation of %d bytes reported as %d on page %u", nFrag, data[hdr+7], iPage); } } @@ -82505,7 +81431,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( /* Check the integrity of the freelist */ if( bCkFreelist ){ - sCheck.zPfx = "Freelist: "; + sCheck.zPfx = "Main freelist: "; checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), get4byte(&pBt->pPage1->aData[36])); sCheck.zPfx = 0; @@ -82522,7 +81448,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( mxInHdr = get4byte(&pBt->pPage1->aData[52]); if( mx!=mxInHdr ){ checkAppendMsg(&sCheck, - "max rootpage (%u) disagrees with header (%u)", + "max rootpage (%d) disagrees with header (%d)", mx, mxInHdr ); } @@ -82543,7 +81469,6 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); } #endif - sCheck.v0 = aRoot[i]; checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); } pBt->db->flags = savedDbFlags; @@ -82556,7 +81481,7 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( for(i=1; ISCONCURRENT==0 && i<=sCheck.nPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM if( getPageReferenced(&sCheck, i)==0 ){ - checkAppendMsg(&sCheck, "Page %u: never used", i); + checkAppendMsg(&sCheck, "Page %d is never used", i); } #else /* If the database supports auto-vacuum, make sure no tables contain @@ -82564,11 +81489,11 @@ SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( */ if( getPageReferenced(&sCheck, i)==0 && (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, "Page %u: never used", i); + checkAppendMsg(&sCheck, "Page %d is never used", i); } if( getPageReferenced(&sCheck, i)!=0 && (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ - checkAppendMsg(&sCheck, "Page %u: pointer map referenced", i); + checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i); } #endif } @@ -82872,29 +81797,22 @@ SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); ** is returned. */ SQLITE_PRIVATE int sqlite3BtreeExclusiveLock(Btree *p){ - sqlite3 *db = p->db; int rc; Pgno pgno = 0; BtShared *pBt = p->pBt; assert( p->inTrans==TRANS_WRITE && pBt->pPage1 ); - memset(db->aCommit, 0, sizeof(db->aCommit)); sqlite3BtreeEnter(p); rc = sqlite3PagerExclusiveLock(pBt->pPager, - (db->eConcurrent==CONCURRENT_SCHEMA) ? 0 : pBt->pPage1->pDbPage, - db->aCommit + (p->db->eConcurrent==CONCURRENT_SCHEMA) ? 0 : pBt->pPage1->pDbPage, + &pgno ); #ifdef SQLITE_OMIT_CONCURRENT - assert( db->aCommit[SQLITE_COMMIT_CONFLICT_PGNO]==0 ); + assert( pgno==0 ); #else - if( (rc==SQLITE_BUSY_SNAPSHOT) - && (pgno = db->aCommit[SQLITE_COMMIT_CONFLICT_PGNO]) - ){ - int iDb; + if( rc==SQLITE_BUSY_SNAPSHOT && pgno ){ PgHdr *pPg = 0; - for(iDb=0; db->aDb[iDb].pBt!=p; iDb++); - db->aCommit[SQLITE_COMMIT_CONFLICT_DB] = (u32)iDb; - (void)sqlite3PagerGet(pBt->pPager, pgno, &pPg, 0); - if( pPg ){ + int rc2 = sqlite3PagerGet(pBt->pPager, pgno, &pPg, 0); + if( rc2==SQLITE_OK ){ int bWrite = -1; const char *zObj = 0; const char *zTab = 0; @@ -82987,40 +81905,6 @@ SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ } #endif -/* -** Access details of recent COMMIT commands. This function allows various -** details related to the most recent COMMIT command to be accessed. -** The requested value is always returned via output parameter (*piVal). -** The specific value requested is identified by parameter op (see -** below). -** -** SQLITE_OK is returned if successful, or SQLITE_ERROR if the "op" or -** "zDb" paramters are unrecognized. -*/ -SQLITE_API int sqlite3_commit_status( - sqlite3 *db, /* Database handle */ - const char *zDb, /* Name of database - "main" etc. */ - int op, /* SQLITE_COMMIT_XXX constant */ - unsigned int *piVal /* OUT: Write requested value here */ -){ - int rc = SQLITE_OK; -#ifndef SQLITE_OMIT_CONCURRENT - if( op<0 || op>SQLITE_COMMIT_CONFLICT_PGNO ){ - rc = SQLITE_ERROR; - }else if( op==SQLITE_COMMIT_FIRSTFRAME || op==SQLITE_COMMIT_NFRAME ){ - int iDb = sqlite3FindDbName(db, zDb); - if( iDb<0 ){ - rc = SQLITE_ERROR; - }else{ - *piVal = db->aDb[iDb].pBt->aCommit[op]; - } - }else{ - *piVal = db->aCommit[op]; - } -#endif - return rc; -} - /************** End of btree.c ***********************************************/ /************** Begin file backup.c ******************************************/ /* @@ -83267,7 +82151,13 @@ static int backupOnePage( assert( !isFatalError(p->rc) ); assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); assert( zSrcData ); - assert( nSrcPgsz==nDestPgsz || sqlite3PagerIsMemdb(pDestPager)==0 ); + + /* Catch the case where the destination is an in-memory database and the + ** page sizes of the source and destination differ. + */ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ + rc = SQLITE_READONLY; + } /* This loop runs once for each destination page spanned by the source ** page. For each iteration, variable iOff is set to the byte offset @@ -83400,10 +82290,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ 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 - ){ + if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){ rc = SQLITE_READONLY; } @@ -83952,7 +82839,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ char *z; int i, j, incr; if( (p->flags & MEM_Str)==0 ) return 1; - if( p->db && p->db->mallocFailed ) return 1; if( p->flags & MEM_Term ){ /* Insure that the string is properly zero-terminated. Pay particular ** attention to the case where p->n is odd */ @@ -84109,37 +82995,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ return SQLITE_OK; } -/* -** If pMem is already a string, detect if it is a zero-terminated -** string, or make it into one if possible, and mark it as such. -** -** This is an optimization. Correct operation continues even if -** this routine is a no-op. -*/ -SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ - if( (pMem->flags & (MEM_Str|MEM_Term))!=MEM_Str ) return; - if( pMem->enc!=SQLITE_UTF8 ) return; - if( NEVER(pMem->z==0) ) return; - if( pMem->flags & MEM_Dyn ){ - if( pMem->xDel==sqlite3_free - && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1) - ){ - pMem->z[pMem->n] = 0; - pMem->flags |= MEM_Term; - return; - } - if( pMem->xDel==(void(*)(void*))sqlite3RCStrUnref ){ - /* Blindly assume that all RCStr objects are zero-terminated */ - pMem->flags |= MEM_Term; - return; - } - }else if( pMem->szMalloc>0 && pMem->szMalloc >= pMem->n+1 ){ - pMem->z[pMem->n] = 0; - pMem->flags |= MEM_Term; - return; - } -} - /* ** It is already known that pMem contains an unterminated string. ** Add the zero terminator. @@ -84266,7 +83121,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ vdbeMemRenderNum(nByte, pMem->z, pMem); assert( pMem->z!=0 ); - assert( pMem->n==(int)sqlite3Strlen30NN(pMem->z) ); + assert( pMem->n==sqlite3Strlen30NN(pMem->z) ); pMem->enc = SQLITE_UTF8; pMem->flags |= MEM_Str|MEM_Term; if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); @@ -84401,6 +83256,36 @@ SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){ if( p->szMalloc ) vdbeMemClear(p); } +/* +** Convert a 64-bit IEEE double into a 64-bit signed integer. +** If the double is out of range of a 64-bit signed integer then +** return the closest available 64-bit signed integer. +*/ +static SQLITE_NOINLINE i64 doubleToInt64(double r){ +#ifdef SQLITE_OMIT_FLOATING_POINT + /* When floating-point is omitted, double and int64 are the same thing */ + return r; +#else + /* + ** Many compilers we encounter do not define constants for the + ** minimum and maximum 64-bit integers, or they define them + ** inconsistently. And many do not understand the "LL" notation. + ** So we define our own static constants here using nothing + ** larger than a 32-bit integer constant. + */ + static const i64 maxInt = LARGEST_INT64; + static const i64 minInt = SMALLEST_INT64; + + if( r<=(double)minInt ){ + return minInt; + }else if( r>=(double)maxInt ){ + return maxInt; + }else{ + return (i64)r; + } +#endif +} + /* ** Return some kind of integer value which is the best we can do ** at representing the value that *pMem describes as an integer. @@ -84427,7 +83312,7 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){ testcase( flags & MEM_IntReal ); return pMem->u.i; }else if( flags & MEM_Real ){ - return sqlite3RealToI64(pMem->u.r); + return doubleToInt64(pMem->u.r); }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ return memIntValue(pMem); }else{ @@ -84489,7 +83374,7 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ if( pMem->flags & MEM_IntReal ){ MemSetTypeFlag(pMem, MEM_Int); }else{ - i64 ix = sqlite3RealToI64(pMem->u.r); + i64 ix = doubleToInt64(pMem->u.r); /* Only mark the value as an integer if ** @@ -84557,8 +83442,8 @@ SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ ** from UBSAN. */ SQLITE_PRIVATE i64 sqlite3RealToI64(double r){ - if( r<-9223372036854774784.0 ) return SMALLEST_INT64; - if( r>+9223372036854774784.0 ) return LARGEST_INT64; + if( r<=(double)SMALLEST_INT64 ) return SMALLEST_INT64; + if( r>=(double)LARGEST_INT64) return LARGEST_INT64; return (i64)r; } @@ -84629,7 +83514,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ break; } default: { - int rc; assert( aff==SQLITE_AFF_TEXT ); assert( MEM_Str==(MEM_Blob>>3) ); pMem->flags |= (pMem->flags&MEM_Blob)>>3; @@ -84637,9 +83521,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1; - rc = sqlite3VdbeChangeEncoding(pMem, encoding); - if( rc ) return rc; - sqlite3VdbeMemZeroTerminateIfAble(pMem); + return sqlite3VdbeChangeEncoding(pMem, encoding); } } return SQLITE_OK; @@ -85163,24 +84045,6 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ return valueToText(pVal, enc); } -/* Return true if sqlit3_value object pVal is a string or blob value -** that uses the destructor specified in the second argument. -** -** TODO: Maybe someday promote this interface into a published API so -** that third-party extensions can get access to it? -*/ -SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value *pVal, void(*xFree)(void*)){ - if( ALWAYS(pVal!=0) - && ALWAYS((pVal->flags & (MEM_Str|MEM_Blob))!=0) - && (pVal->flags & MEM_Dyn)!=0 - && pVal->xDel==xFree - ){ - return 1; - }else{ - return 0; - } -} - /* ** Create a new sqlite3_value object. */ @@ -85248,7 +84112,6 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ } pRec->nField = p->iVal+1; - sqlite3VdbeMemSetNull(&pRec->aMem[p->iVal]); return &pRec->aMem[p->iVal]; } #else @@ -85302,9 +84165,6 @@ static int valueFromFunction( if( pList ) nVal = pList->nExpr; assert( !ExprHasProperty(p, EP_IntValue) ); pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); -#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - if( pFunc==0 ) return SQLITE_OK; -#endif assert( pFunc ); if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) @@ -85341,11 +84201,16 @@ static int valueFromFunction( }else{ sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); assert( rc==SQLITE_OK ); + assert( enc==pVal->enc + || (pVal->flags & MEM_Str)==0 + || db->mallocFailed ); +#if 0 /* Not reachable except after a prior failure */ rc = sqlite3VdbeChangeEncoding(pVal, enc); - if( NEVER(rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal)) ){ + if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ rc = SQLITE_TOOBIG; pCtx->pParse->nErr++; } +#endif } value_from_function_out: @@ -85409,13 +84274,6 @@ static int valueFromExpr( rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); testcase( rc!=SQLITE_OK ); if( *ppVal ){ -#ifdef SQLITE_ENABLE_STAT4 - rc = ExpandBlob(*ppVal); -#else - /* zero-blobs only come from functions, not literal values. And - ** functions are only processed under STAT4 */ - assert( (ppVal[0][0].flags & MEM_Zero)==0 ); -#endif sqlite3VdbeMemCast(*ppVal, aff, enc); sqlite3ValueApplyAffinity(*ppVal, affinity, enc); } @@ -86037,35 +84895,6 @@ static void test_addop_breakpoint(int pc, Op *pOp){ } #endif -/* -** Slow paths for sqlite3VdbeAddOp3() and sqlite3VdbeAddOp4Int() for the -** unusual case when we need to increase the size of the Vdbe.aOp[] array -** before adding the new opcode. -*/ -static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ - assert( p->nOpAlloc<=p->nOp ); - if( growOpArray(p, 1) ) return 1; - assert( p->nOpAlloc>p->nOp ); - return sqlite3VdbeAddOp3(p, op, p1, p2, p3); -} -static SQLITE_NOINLINE int addOp4IntSlow( - 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 */ - int p4 /* The P4 operand as an integer */ -){ - int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); - if( p->db->mallocFailed==0 ){ - VdbeOp *pOp = &p->aOp[addr]; - pOp->p4type = P4_INT32; - pOp->p4.i = p4; - } - return addr; -} - - /* ** Add a new instruction to the list of instructions current in the ** VDBE. Return the address of the new instruction. @@ -86076,16 +84905,17 @@ static SQLITE_NOINLINE int addOp4IntSlow( ** ** op The opcode for this instruction ** -** p1, p2, p3, p4 Operands +** p1, p2, p3 Operands +** +** Use the sqlite3VdbeResolveLabel() function to fix an address and +** the sqlite3VdbeChangeP4() function to change the value of the P4 +** operand. */ -SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ - return sqlite3VdbeAddOp3(p, op, 0, 0, 0); -} -SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ - return sqlite3VdbeAddOp3(p, op, p1, 0, 0); -} -SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ - return sqlite3VdbeAddOp3(p, op, p1, p2, 0); +static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ + assert( p->nOpAlloc<=p->nOp ); + if( growOpArray(p, 1) ) return 1; + assert( p->nOpAlloc>p->nOp ); + return sqlite3VdbeAddOp3(p, op, p1, p2, p3); } SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ int i; @@ -86108,9 +84938,6 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ pOp->p3 = p3; pOp->p4.p = 0; pOp->p4type = P4_NOTUSED; - - /* Replicate this logic in sqlite3VdbeAddOp4Int() - ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS pOp->zComment = 0; #endif @@ -86127,59 +84954,16 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ #ifdef SQLITE_VDBE_COVERAGE pOp->iSrcLine = 0; #endif - /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ** Replicate in sqlite3VdbeAddOp4Int() */ - return i; } -SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( - 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 */ - int p4 /* The P4 operand as an integer */ -){ - int i; - VdbeOp *pOp; - - i = p->nOp; - if( p->nOpAlloc<=i ){ - return addOp4IntSlow(p, op, p1, p2, p3, p4); - } - p->nOp++; - pOp = &p->aOp[i]; - assert( pOp!=0 ); - pOp->opcode = (u8)op; - pOp->p5 = 0; - pOp->p1 = p1; - pOp->p2 = p2; - pOp->p3 = p3; - pOp->p4.i = p4; - pOp->p4type = P4_INT32; - - /* Replicate this logic in sqlite3VdbeAddOp3() - ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ -#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - pOp->zComment = 0; -#endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) - pOp->nExec = 0; - pOp->nCycle = 0; -#endif -#ifdef SQLITE_DEBUG - if( p->db->flags & SQLITE_VdbeAddopTrace ){ - sqlite3VdbePrintOp(0, i, &p->aOp[i]); - test_addop_breakpoint(i, &p->aOp[i]); - } -#endif -#ifdef SQLITE_VDBE_COVERAGE - pOp->iSrcLine = 0; -#endif - /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ** Replicate in sqlite3VdbeAddOp3() */ - - return i; +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ + return sqlite3VdbeAddOp3(p, op, 0, 0, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ + return sqlite3VdbeAddOp3(p, op, p1, 0, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ + return sqlite3VdbeAddOp3(p, op, p1, p2, 0); } /* Generate code for an unconditional jump to instruction iDest @@ -86336,10 +85120,10 @@ SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){ */ SQLITE_PRIVATE int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ int addr = 0; -#if !defined(SQLITE_DEBUG) +#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. ** But omit them (for performance) during production builds */ - if( pParse->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) + if( pParse->explain==2 ) #endif { char *zMsg; @@ -86357,7 +85141,7 @@ SQLITE_PRIVATE int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, if( bPush){ pParse->addrExplain = iThis; } - sqlite3VdbeScanStatus(v, iThis, -1, -1, 0, 0); + sqlite3VdbeScanStatus(v, iThis, 0, 0, 0, 0); } return addr; } @@ -86387,6 +85171,26 @@ SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, sqlite3MayAbort(p->pParse); } +/* +** Add an opcode that includes the p4 value as an integer. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( + 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 */ + int p4 /* The P4 operand as an integer */ +){ + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + if( p->db->mallocFailed==0 ){ + VdbeOp *pOp = &p->aOp[addr]; + pOp->p4type = P4_INT32; + pOp->p4.i = p4; + } + return addr; +} + /* Insert the end of a co-routine */ SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ @@ -86693,13 +85497,11 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ Op *pOp; Parse *pParse = p->pParse; int *aLabel = pParse->aLabel; - - assert( pParse->db->mallocFailed==0 ); /* tag-20230419-1 */ p->readOnly = 1; p->bIsReader = 0; pOp = &p->aOp[p->nOp-1]; assert( p->aOp[0].opcode==OP_Init ); - while( 1 /* Loop terminates when it reaches the OP_Init opcode */ ){ + while( 1 /* Loop termates when it reaches the OP_Init opcode */ ){ /* Only JUMP opcodes and the short list of special opcodes in the switch ** below need to be considered. The mkopcodeh.tcl generator script groups ** all these opcodes together near the front of the opcode list. Skip @@ -86754,7 +85556,6 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** have non-negative values for P2. */ assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); assert( ADDR(pOp->p2)<-pParse->nLabel ); - assert( aLabel!=0 ); /* True because of tag-20230419-1 */ pOp->p2 = aLabel[ADDR(pOp->p2)]; } break; @@ -86998,20 +85799,18 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus( LogEst nEst, /* Estimated number of output rows */ const char *zName /* Name of table or index being scanned */ ){ - if( IS_STMT_SCANSTATUS(p->db) ){ - sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); - ScanStatus *aNew; - aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); - if( aNew ){ - ScanStatus *pNew = &aNew[p->nScan++]; - memset(pNew, 0, sizeof(ScanStatus)); - pNew->addrExplain = addrExplain; - pNew->addrLoop = addrLoop; - pNew->addrVisit = addrVisit; - pNew->nEst = nEst; - pNew->zName = sqlite3DbStrDup(p->db, zName); - p->aScan = aNew; - } + sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); + ScanStatus *aNew; + aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); + if( aNew ){ + ScanStatus *pNew = &aNew[p->nScan++]; + memset(pNew, 0, sizeof(ScanStatus)); + pNew->addrExplain = addrExplain; + pNew->addrLoop = addrLoop; + pNew->addrVisit = addrVisit; + pNew->nEst = nEst; + pNew->zName = sqlite3DbStrDup(p->db, zName); + p->aScan = aNew; } } @@ -87028,22 +85827,20 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatusRange( int addrStart, int addrEnd ){ - if( IS_STMT_SCANSTATUS(p->db) ){ - ScanStatus *pScan = 0; - int ii; - for(ii=p->nScan-1; ii>=0; ii--){ - pScan = &p->aScan[ii]; - if( pScan->addrExplain==addrExplain ) break; - pScan = 0; - } - if( pScan ){ - if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1; - for(ii=0; iiaAddrRange); ii+=2){ - if( pScan->aAddrRange[ii]==0 ){ - pScan->aAddrRange[ii] = addrStart; - pScan->aAddrRange[ii+1] = addrEnd; - break; - } + ScanStatus *pScan = 0; + int ii; + for(ii=p->nScan-1; ii>=0; ii--){ + pScan = &p->aScan[ii]; + if( pScan->addrExplain==addrExplain ) break; + pScan = 0; + } + if( pScan ){ + if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1; + for(ii=0; iiaAddrRange); ii+=2){ + if( pScan->aAddrRange[ii]==0 ){ + pScan->aAddrRange[ii] = addrStart; + pScan->aAddrRange[ii+1] = addrEnd; + break; } } } @@ -87060,21 +85857,19 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters( int addrLoop, int addrVisit ){ - if( IS_STMT_SCANSTATUS(p->db) ){ - ScanStatus *pScan = 0; - int ii; - for(ii=p->nScan-1; ii>=0; ii--){ - pScan = &p->aScan[ii]; - if( pScan->addrExplain==addrExplain ) break; - pScan = 0; - } - if( pScan ){ - if( addrLoop>0 ) pScan->addrLoop = addrLoop; - if( addrVisit>0 ) pScan->addrVisit = addrVisit; - } + ScanStatus *pScan = 0; + int ii; + for(ii=p->nScan-1; ii>=0; ii--){ + pScan = &p->aScan[ii]; + if( pScan->addrExplain==addrExplain ) break; + pScan = 0; + } + if( pScan ){ + pScan->addrLoop = addrLoop; + pScan->addrVisit = addrVisit; } } -#endif /* defined(SQLITE_ENABLE_STMT_SCANSTATUS) */ +#endif /* @@ -87153,7 +85948,7 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){ /* ** If the input FuncDef structure is ephemeral, then free it. If -** the FuncDef is not ephemeral, then do nothing. +** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ assert( db!=0 ); @@ -87317,6 +86112,7 @@ SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters( } #endif /* SQLITE_DEBUG */ + /* ** Change the value of the P4 operand for a specific instruction. ** This routine is useful when a large program is loaded from a @@ -87497,7 +86293,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* Return the most recently added opcode */ -SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe *p){ +VdbeOp * sqlite3VdbeGetLastOp(Vdbe *p){ return sqlite3VdbeGetOp(p, p->nOp - 1); } @@ -88237,7 +87033,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( sqlite3VdbeMemSetInt64(pMem+1, pOp->p2); sqlite3VdbeMemSetInt64(pMem+2, pOp->p3); sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free); - assert( p->nResColumn==4 ); + p->nResColumn = 4; }else{ sqlite3VdbeMemSetInt64(pMem+0, i); sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode), @@ -88256,7 +87052,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( sqlite3VdbeMemSetNull(pMem+7); #endif sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); - assert( p->nResColumn==8 ); + p->nResColumn = 8; } p->pResultRow = pMem; if( db->mallocFailed ){ @@ -88470,9 +87266,26 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( resolveP2Values(p, &nArg); p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); if( pParse->explain ){ + static const char * const azColName[] = { + "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", + "id", "parent", "notused", "detail" + }; + int iFirst, mx, i; if( nMem<10 ) nMem = 10; p->explain = pParse->explain; - p->nResColumn = 12 - 4*p->explain; + if( pParse->explain==2 ){ + sqlite3VdbeSetNumCols(p, 4); + iFirst = 8; + mx = 12; + }else{ + sqlite3VdbeSetNumCols(p, 8); + iFirst = 0; + mx = 8; + } + for(i=iFirst; iexpired = 0; @@ -88524,23 +87337,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx); } -static SQLITE_NOINLINE void freeCursorWithCache(Vdbe *p, VdbeCursor *pCx){ - VdbeTxtBlbCache *pCache = pCx->pCache; - assert( pCx->colCache ); - pCx->colCache = 0; - pCx->pCache = 0; - if( pCache->pCValue ){ - sqlite3RCStrUnref(pCache->pCValue); - pCache->pCValue = 0; - } - sqlite3DbFree(p->db, pCache); - sqlite3VdbeFreeCursorNN(p, pCx); -} SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){ - if( pCx->colCache ){ - freeCursorWithCache(p, pCx); - return; - } switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); @@ -88641,12 +87438,12 @@ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ int n; sqlite3 *db = p->db; - if( p->nResAlloc ){ - releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); + if( p->nResColumn ){ + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3DbFree(db, p->aColName); } n = nResColumn*COLNAME_N; - p->nResColumn = p->nResAlloc = (u16)nResColumn; + p->nResColumn = (u16)nResColumn; p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); if( p->aColName==0 ) return; initMemArray(p->aColName, n, db, MEM_Null); @@ -88671,14 +87468,14 @@ SQLITE_PRIVATE int sqlite3VdbeSetColName( ){ int rc; Mem *pColName; - assert( idxnResAlloc ); + assert( idxnResColumn ); assert( vardb->mallocFailed ){ assert( !zName || xDel!=SQLITE_DYNAMIC ); return SQLITE_NOMEM_BKPT; } assert( p->aColName!=0 ); - pColName = &(p->aColName[idx+var*p->nResAlloc]); + pColName = &(p->aColName[idx+var*p->nResColumn]); rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); return rc; @@ -89218,8 +88015,6 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ db->flags &= ~(u64)SQLITE_DeferFKs; sqlite3CommitInternalChanges(db); } - }else if( p->rc==SQLITE_SCHEMA && db->nVdbeActive>1 ){ - p->nChange = 0; }else{ sqlite3RollbackAll(db, SQLITE_OK); p->nChange = 0; @@ -89522,7 +88317,7 @@ static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ assert( db!=0 ); assert( p->db==0 || p->db==db ); if( p->aColName ){ - releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3DbNNFreeNN(db, p->aColName); } for(pSub=p->pProgram; pSub; pSub=pNext){ @@ -89540,9 +88335,9 @@ static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ #ifdef SQLITE_ENABLE_NORMALIZE sqlite3DbFree(db, p->zNormSql); { - DblquoteStr *pThis, *pNxt; - for(pThis=p->pDblStr; pThis; pThis=pNxt){ - pNxt = pThis->pNextStr; + DblquoteStr *pThis, *pNext; + for(pThis=p->pDblStr; pThis; pThis=pNext){ + pNext = pThis->pNextStr; sqlite3DbFree(db, pThis); } } @@ -90122,15 +88917,6 @@ static int vdbeRecordCompareDebug( if( d1+(u64)serial_type1+2>(u64)nKey1 && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 ){ - if( serial_type1>=1 - && serial_type1<=7 - && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)<=(u64)nKey1+8 - && CORRUPT_DB - ){ - return 1; /* corrupt record not detected by - ** sqlite3VdbeRecordCompareWithSkip(). Return true - ** to avoid firing the assert() */ - } break; } @@ -90574,7 +89360,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( /* Serial types 12 or greater are strings and blobs (greater than ** numbers). Types 10 and 11 are currently "reserved for future ** use", so it doesn't really matter what the results of comparing - ** them to numeric values are. */ + ** them to numberic values are. */ rc = serial_type==10 ? -1 : +1; }else if( serial_type==0 ){ rc = -1; @@ -91178,20 +89964,6 @@ SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){ return 1; } -#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) -/* -** This Walker callback is used to help verify that calls to -** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have -** byte-code register values correctly initialized. -*/ -SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_REGISTER ){ - assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 ); - } - return WRC_Continue; -} -#endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */ - #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored @@ -91254,16 +90026,6 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( PreUpdate preupdate; const char *zTbl = pTab->zName; static const u8 fakeSortOrder = 0; -#ifdef SQLITE_DEBUG - int nRealCol; - if( pTab->tabFlags & TF_WithoutRowid ){ - nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; - }else if( pTab->tabFlags & TF_HasVirtual ){ - nRealCol = pTab->nNVCol; - }else{ - nRealCol = pTab->nCol; - } -#endif assert( db->pPreUpdate==0 ); memset(&preupdate, 0, sizeof(PreUpdate)); @@ -91280,8 +90042,8 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( assert( pCsr!=0 ); assert( pCsr->eCurType==CURTYPE_BTREE ); - assert( pCsr->nField==nRealCol - || (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1) + assert( pCsr->nField==pTab->nCol + || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1) ); preupdate.v = v; @@ -91588,7 +90350,7 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ SQLITE_NULL, /* 0x1f (not possible) */ SQLITE_FLOAT, /* 0x20 INTREAL */ SQLITE_NULL, /* 0x21 (not possible) */ - SQLITE_FLOAT, /* 0x22 INTREAL + TEXT */ + SQLITE_TEXT, /* 0x22 INTREAL + TEXT */ SQLITE_NULL, /* 0x23 (not possible) */ SQLITE_FLOAT, /* 0x24 (not possible) */ SQLITE_NULL, /* 0x25 (not possible) */ @@ -91831,7 +90593,6 @@ SQLITE_API void sqlite3_result_text64( (void)invokeValueDestructor(z, xDel, pCtx); }else{ setResultStrOrError(pCtx, z, (int)n, enc, xDel); - sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut); } } #ifndef SQLITE_OMIT_UTF16 @@ -92204,7 +90965,7 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ ** The destructor function for a ValueList object. This needs to be ** a separate function, unknowable to the application, to ensure that ** calls to sqlite3_vtab_in_first()/sqlite3_vtab_in_next() that are not -** preceded by activation of IN processing via sqlite3_vtab_int() do not +** preceeded by activation of IN processing via sqlite3_vtab_int() do not ** try to access a fake ValueList object inserted by a hostile extension. */ SQLITE_PRIVATE void sqlite3VdbeValueListFree(void *pToDelete){ @@ -92444,8 +91205,7 @@ SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){ */ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; - if( pVm==0 ) return 0; - return pVm->nResColumn; + return pVm ? pVm->nResColumn : 0; } /* @@ -92534,7 +91294,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ ** sqlite3_column_real() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() -** sqlite3_column_blob() +** sqiite3_column_blob() */ static void columnMallocFailure(sqlite3_stmt *pStmt) { @@ -92618,32 +91378,6 @@ SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ return iType; } -/* -** Column names appropriate for EXPLAIN or EXPLAIN QUERY PLAN. -*/ -static const char * const azExplainColNames8[] = { - "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", /* EXPLAIN */ - "id", "parent", "notused", "detail" /* EQP */ -}; -static const u16 azExplainColNames16data[] = { - /* 0 */ 'a', 'd', 'd', 'r', 0, - /* 5 */ 'o', 'p', 'c', 'o', 'd', 'e', 0, - /* 12 */ 'p', '1', 0, - /* 15 */ 'p', '2', 0, - /* 18 */ 'p', '3', 0, - /* 21 */ 'p', '4', 0, - /* 24 */ 'p', '5', 0, - /* 27 */ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0, - /* 35 */ 'i', 'd', 0, - /* 38 */ 'p', 'a', 'r', 'e', 'n', 't', 0, - /* 45 */ 'n', 'o', 't', 'u', 's', 'e', 'd', 0, - /* 53 */ 'd', 'e', 't', 'a', 'i', 'l', 0 -}; -static const u8 iExplainColNames16[] = { - 0, 5, 12, 15, 18, 21, 24, 27, - 35, 38, 45, 53 -}; - /* ** Convert the N-th element of pStmt->pColName[] into a string using ** xFunc() then return that string. If N is out of range, return 0. @@ -92676,29 +91410,15 @@ static const void *columnName( return 0; } #endif - if( N<0 ) return 0; ret = 0; p = (Vdbe *)pStmt; db = p->db; assert( db!=0 ); - sqlite3_mutex_enter(db->mutex); - - if( p->explain ){ - if( useType>0 ) goto columnName_end; - n = p->explain==1 ? 8 : 4; - if( N>=n ) goto columnName_end; - if( useUtf16 ){ - int i = iExplainColNames16[N + 8*p->explain - 8]; - ret = (void*)&azExplainColNames16data[i]; - }else{ - ret = (void*)azExplainColNames8[N + 8*p->explain - 8]; - } - goto columnName_end; - } - n = p->nResColumn; - if( NmallocFailed; + n = sqlite3_column_count(pStmt); + if( N=0 ){ N += useType*n; + sqlite3_mutex_enter(db->mutex); + assert( db->mallocFailed==0 ); #ifndef SQLITE_OMIT_UTF16 if( useUtf16 ){ ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]); @@ -92710,14 +91430,12 @@ static const void *columnName( /* A malloc may have failed inside of the _text() call. If this ** is the case, clear the mallocFailed flag and return NULL. */ - assert( db->mallocFailed==0 || db->mallocFailed==1 ); - if( db->mallocFailed > prior_mallocFailed ){ + if( db->mallocFailed ){ sqlite3OomClear(db); ret = 0; } + sqlite3_mutex_leave(db->mutex); } -columnName_end: - sqlite3_mutex_leave(db->mutex); return ret; } @@ -92810,7 +91528,7 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ /* ** Unbind the value bound to variable i in virtual machine p. This is the ** the same as binding a NULL value to the column. If the "i" parameter is -** out of range, then SQLITE_RANGE is returned. Otherwise SQLITE_OK. +** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. ** ** A successful evaluation of this routine acquires the mutex on p. ** the mutex is released if any kind of error occurs. @@ -93174,35 +91892,6 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->explain : 0; } -/* -** Set the explain mode for a statement. -*/ -SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ - Vdbe *v = (Vdbe*)pStmt; - int rc; - if( v->eVdbeState!=VDBE_READY_STATE ) return SQLITE_BUSY; - if( v->explain==eMode ) return SQLITE_OK; - if( v->zSql==0 || eMode<0 || eMode>2 ) return SQLITE_ERROR; - sqlite3_mutex_enter(v->db->mutex); - if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){ - /* No reprepare necessary */ - v->explain = eMode; - rc = SQLITE_OK; - }else{ - int haveEqpOps = v->explain==2 || v->haveEqpOps; - v->explain = eMode; - rc = sqlite3Reprepare(v); - v->haveEqpOps = haveEqpOps!=0; - } - if( v->explain ){ - v->nResColumn = 12 - 4*v->explain; - }else{ - v->nResColumn = v->nResAlloc; - } - sqlite3_mutex_leave(v->db->mutex); - return rc; -} - /* ** Return true if the prepared statement is in need of being reset. */ @@ -93528,24 +92217,15 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( void *pOut /* OUT: Write the answer here */ ){ Vdbe *p = (Vdbe*)pStmt; - VdbeOp *aOp = p->aOp; - int nOp = p->nOp; - ScanStatus *pScan = 0; + ScanStatus *pScan; int idx; - if( p->pFrame ){ - VdbeFrame *pFrame; - for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); - aOp = pFrame->aOp; - nOp = pFrame->nOp; - } - if( iScan<0 ){ int ii; if( iScanStatusOp==SQLITE_SCANSTAT_NCYCLE ){ i64 res = 0; - for(ii=0; iinOp; ii++){ + res += p->aOp[ii].nCycle; } *(i64*)pOut = res; return 0; @@ -93571,7 +92251,7 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( switch( iScanStatusOp ){ case SQLITE_SCANSTAT_NLOOP: { if( pScan->addrLoop>0 ){ - *(sqlite3_int64*)pOut = aOp[pScan->addrLoop].nExec; + *(sqlite3_int64*)pOut = p->aOp[pScan->addrLoop].nExec; }else{ *(sqlite3_int64*)pOut = -1; } @@ -93579,7 +92259,7 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( } case SQLITE_SCANSTAT_NVISIT: { if( pScan->addrVisit>0 ){ - *(sqlite3_int64*)pOut = aOp[pScan->addrVisit].nExec; + *(sqlite3_int64*)pOut = p->aOp[pScan->addrVisit].nExec; }else{ *(sqlite3_int64*)pOut = -1; } @@ -93601,7 +92281,7 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( } case SQLITE_SCANSTAT_EXPLAIN: { if( pScan->addrExplain ){ - *(const char**)pOut = aOp[ pScan->addrExplain ].p4.z; + *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z; }else{ *(const char**)pOut = 0; } @@ -93609,7 +92289,7 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( } case SQLITE_SCANSTAT_SELECTID: { if( pScan->addrExplain ){ - *(int*)pOut = aOp[ pScan->addrExplain ].p1; + *(int*)pOut = p->aOp[ pScan->addrExplain ].p1; }else{ *(int*)pOut = -1; } @@ -93617,7 +92297,7 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( } case SQLITE_SCANSTAT_PARENTID: { if( pScan->addrExplain ){ - *(int*)pOut = aOp[ pScan->addrExplain ].p2; + *(int*)pOut = p->aOp[ pScan->addrExplain ].p2; }else{ *(int*)pOut = -1; } @@ -93635,18 +92315,18 @@ SQLITE_API int sqlite3_stmt_scanstatus_v2( if( iIns==0 ) break; if( iIns>0 ){ while( iIns<=iEnd ){ - res += aOp[iIns].nCycle; + res += p->aOp[iIns].nCycle; iIns++; } }else{ int iOp; - for(iOp=0; iOpnOp; iOp++){ + Op *pOp = &p->aOp[iOp]; if( pOp->p1!=iEnd ) continue; if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_NCYCLE)==0 ){ continue; } - res += aOp[iOp].nCycle; + res += p->aOp[iOp].nCycle; } } } @@ -94442,9 +93122,6 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); } sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); - if( f & MEM_Term ){ - sqlite3_str_appendf(pStr, "(0-term)"); - } } } #endif @@ -94572,92 +93249,12 @@ static u64 filterHash(const Mem *aMem, const Op *pOp){ }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)); + /* no-op */ } } 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 -** the common case where all content fits on the page. Factoring out -** the code reduces register pressure and helps the common case -** to run faster. -*/ -static SQLITE_NOINLINE int vdbeColumnFromOverflow( - VdbeCursor *pC, /* The BTree cursor from which we are reading */ - int iCol, /* The column to read */ - int t, /* The serial-type code for the column value */ - i64 iOffset, /* Offset to the start of the content value */ - Mem *pDest /* Store the value into this register. */ -){ - int rc; - sqlite3 *db = pDest->db; - int encoding = pDest->enc; - int len = sqlite3VdbeSerialTypeLen(t); - assert( pC->eCurType==CURTYPE_BTREE ); - if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) return SQLITE_TOOBIG; - if( len > 4000 ){ - /* Cache large column values that are on overflow pages using - ** an RCStr (reference counted string) so that if they are reloaded, - ** that do not have to be copied a second time. The overhead of - ** creating and managing the cache is such that this is only - ** profitable for larger TEXT and BLOB values. - */ - VdbeTxtBlbCache *pCache; - char *pBuf; - if( pC->colCache==0 ){ - pC->pCache = sqlite3DbMallocZero(db, sizeof(VdbeTxtBlbCache) ); - if( pC->pCache==0 ) return SQLITE_NOMEM; - pC->colCache = 1; - } - pCache = pC->pCache; - if( pCache->pCValue==0 - || pCache->iCol!=iCol - || pCache->iOffset!=sqlite3BtreeOffset(pC->uc.pCursor) - ){ - if( pCache->pCValue ) sqlite3RCStrUnref(pCache->pCValue); - pBuf = pCache->pCValue = sqlite3RCStrNew( len+3 ); - if( pBuf==0 ) return SQLITE_NOMEM; - rc = sqlite3BtreePayload(pC->uc.pCursor, iOffset, len, pBuf); - if( rc ) return rc; - pBuf[len] = 0; - pBuf[len+1] = 0; - pBuf[len+2] = 0; - pCache->iCol = iCol; - pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor); - }else{ - pBuf = pCache->pCValue; - } - assert( t>=12 ); - sqlite3RCStrRef(pBuf); - if( t&1 ){ - rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding, - (void(*)(void*))sqlite3RCStrUnref); - pDest->flags |= MEM_Term; - }else{ - rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, - (void(*)(void*))sqlite3RCStrUnref); - } - }else{ - rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest); - if( rc ) return rc; - sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); - if( (t&1)!=0 && encoding==SQLITE_UTF8 ){ - pDest->z[len] = 0; - pDest->flags |= MEM_Term; - } - } - pDest->flags &= ~MEM_Ephem; - return rc; -} - - /* ** Return the symbolic name for the data type of a pMem */ @@ -94702,7 +93299,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Mem *pOut = 0; /* Output operand */ #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) u64 *pnCycle = 0; - int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0; #endif /*** INSERT STACK UNION HERE ***/ @@ -94767,17 +93363,13 @@ SQLITE_PRIVATE int sqlite3VdbeExec( assert( pOp>=aOp && pOp<&aOp[p->nOp]); nVmStep++; - -#if defined(VDBE_PROFILE) +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) pOp->nExec++; pnCycle = &pOp->nCycle; - if( sqlite3NProfileCnt==0 ) *pnCycle -= sqlite3Hwtime(); -#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( bStmtScanStatus ){ - pOp->nExec++; - pnCycle = &pOp->nCycle; +# ifdef VDBE_PROFILE + if( sqlite3NProfileCnt==0 ) +# endif *pnCycle -= sqlite3Hwtime(); - } #endif /* Only allow tracing if SQLITE_DEBUG is defined. @@ -94895,8 +93487,8 @@ SQLITE_PRIVATE int sqlite3VdbeExec( case OP_Goto: { /* jump */ #ifdef SQLITE_DEBUG - /* In debugging mode, when the p5 flags is set on an OP_Goto, that - ** means we should really jump back to the preceding OP_ReleaseReg + /* In debuggging mode, when the p5 flags is set on an OP_Goto, that + ** means we should really jump back to the preceeding OP_ReleaseReg ** instruction. */ if( pOp->p5 ){ assert( pOp->p2 < (int)(pOp - aOp) ); @@ -95104,7 +93696,7 @@ case OP_HaltIfNull: { /* in3 */ ** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. ** ** 0: (no change) -** 1: NOT NULL constraint failed: P4 +** 1: NOT NULL contraint failed: P4 ** 2: UNIQUE constraint failed: P4 ** 3: CHECK constraint failed: P4 ** 4: FOREIGN KEY constraint failed: P4 @@ -96365,7 +94957,7 @@ case OP_Compare: { /* Opcode: Jump P1 P2 P3 * * ** ** Jump to the instruction at address P1, P2, or P3 depending on whether -** in the most recent OP_Compare instruction the P1 vector was less than, +** in the most recent OP_Compare instruction the P1 vector was less than ** equal to, or greater than the P2 vector, respectively. ** ** This opcode must immediately follow an OP_Compare opcode. @@ -96592,12 +95184,6 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ ** (0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04. ** SQLITE_BLOB is 0x08. SQLITE_NULL is 0x10. ** -** WARNING: This opcode does not reliably distinguish between NULL and REAL -** when P1>=0. If the database contains a NaN value, this opcode will think -** that the datatype is REAL when it should be NULL. When P1<0 and the value -** is already stored in register P3, then this opcode does reliably -** distinguish between NULL and REAL. The problem only arises then P1>=0. -** ** Take the jump to address P2 if and only if the datatype of the ** value determined by P1 and P3 corresponds to one of the bits in the ** P5 bitmask. @@ -96711,7 +95297,7 @@ case OP_IfNullRow: { /* jump */ VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; - if( pC && pC->nullRow ){ + if( ALWAYS(pC) && pC->nullRow ){ sqlite3VdbeMemSetNull(aMem + pOp->p3); goto jump_to_p2; } @@ -97022,15 +95608,10 @@ case OP_Column: { /* ncycle */ pDest->flags = aFlag[t&1]; } }else{ - u8 p5; pDest->enc = encoding; - assert( pDest->db==db ); /* This branch happens only when content is on overflow pages */ - if( ((p5 = (pOp->p5 & OPFLAG_BYTELENARG))!=0 - && (p5==OPFLAG_TYPEOFARG - || (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG)) - ) - ) + if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 + && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) || (len = sqlite3VdbeSerialTypeLen(t))==0 ){ /* Content is irrelevant for @@ -97048,12 +95629,11 @@ case OP_Column: { /* ncycle */ */ sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ - rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2], pDest); - if( rc ){ - if( rc==SQLITE_NOMEM ) goto no_mem; - if( rc==SQLITE_TOOBIG ) goto too_big; - goto abort_due_to_error; - } + if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); + pDest->flags &= ~MEM_Ephem; } } @@ -97212,7 +95792,7 @@ case OP_Affinity: { }else{ pIn1->u.r = (double)pIn1->u.i; pIn1->flags |= MEM_Real; - pIn1->flags &= ~(MEM_Int|MEM_Str); + pIn1->flags &= ~MEM_Int; } } REGISTER_TRACE((int)(pIn1-aMem), pIn1); @@ -98373,7 +96953,7 @@ case OP_OpenEphemeral: { /* ncycle */ } pCx = p->apCsr[pOp->p1]; if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){ - /* If the ephemeral table is already open and has no duplicates from + /* If the ephermeral table is already open and has no duplicates from ** OP_OpenDup, then erase all existing content so that the table is ** empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); @@ -98864,7 +97444,7 @@ case OP_SeekGT: { /* jump, in3, group, ncycle */ ** row. If This.P5 is false (0) then a jump is made to SeekGE.P2. If ** This.P5 is true (non-zero) then a jump is made to This.P2. The P5==0 ** case occurs when there are no inequality constraints to the right of -** the IN constraint. The jump to SeekGE.P2 ends the loop. The P5!=0 case +** the IN constraing. The jump to SeekGE.P2 ends the loop. The P5!=0 case ** occurs when there are inequality constraints to the right of the IN ** operator. In that case, the This.P2 will point either directly to or ** to setup code prior to the OP_IdxGT or OP_IdxGE opcode that checks for @@ -98872,7 +97452,7 @@ case OP_SeekGT: { /* jump, in3, group, ncycle */ ** ** Possible outcomes from this opcode:
      ** -**
    1. If the cursor is initially not pointed to any valid row, then +**
    2. If the cursor is initally not pointed to any valid row, then ** fall through into the subsequent OP_SeekGE opcode. ** **
    3. If the cursor is left pointing to a row that is before the target @@ -98987,7 +97567,6 @@ case OP_SeekScan: { /* ncycle */ break; } nStep--; - pC->cacheStatus = CACHE_STALE; rc = sqlite3BtreeNext(pC->uc.pCursor, 0); if( rc ){ if( rc==SQLITE_DONE ){ @@ -99855,7 +98434,7 @@ case OP_SorterCompare: { ** parameter P3. Clearing the P3 column cache as part of this opcode saves ** us from having to issue a separate NullRow instruction to clear that cache. */ -case OP_SorterData: { /* ncycle */ +case OP_SorterData: { VdbeCursor *pC; pOut = &aMem[pOp->p2]; @@ -100130,8 +98709,8 @@ case OP_IfSmaller: { /* jump */ ** regression tests can determine whether or not the optimizer is ** correctly optimizing out sorts. */ -case OP_SorterSort: /* jump ncycle */ -case OP_Sort: { /* jump ncycle */ +case OP_SorterSort: /* jump */ +case OP_Sort: { /* jump */ #ifdef SQLITE_TEST sqlite3_sort_count++; sqlite3_search_count--; @@ -101545,7 +100124,7 @@ case OP_AggStep1: { /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it - ** reinitializes the relevant parts of the sqlite3_context object */ + ** reinitializes the relavant parts of the sqlite3_context object */ if( pCtx->pMem != pMem ){ pCtx->pMem = pMem; for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; @@ -101640,7 +100219,6 @@ case OP_AggFinal: { } sqlite3VdbeChangeEncoding(pMem, encoding); UPDATE_MAX_BLOBSIZE(pMem); - REGISTER_TRACE((int)(pMem-aMem), pMem); break; } @@ -101783,7 +100361,6 @@ case OP_JournalMode: { /* out2 */ rc = sqlite3BtreeSetVersion(pBt, 1 + isWalMode(eNew) + (eNew==PAGER_JOURNALMODE_WAL2) ); - } } #endif /* ifndef SQLITE_OMIT_WAL */ @@ -102441,7 +101018,7 @@ case OP_MaxPgcnt: { /* out2 */ ** This opcode works exactly like OP_Function. The only difference is in ** its name. This opcode is used in places where the function must be ** purely non-deterministic. Some built-in date/time functions can be -** either deterministic of non-deterministic, depending on their arguments. +** either determinitic of non-deterministic, depending on their arguments. ** When those function are used in a non-deterministic way, they will check ** to see if they were called using OP_PureFunc instead of OP_Function, and ** if they were, they throw an error. @@ -102459,7 +101036,7 @@ case OP_Function: { /* group */ /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it - ** reinitializes the relevant parts of the sqlite3_context object */ + ** reinitializes the relavant parts of the sqlite3_context object */ pOut = &aMem[pOp->p3]; if( pCtx->pOut != pOut ){ pCtx->pVdbe = p; @@ -102535,7 +101112,7 @@ case OP_FilterAdd: { printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); } #endif - h %= (pIn1->n*8); + h %= pIn1->n; pIn1->z[h/8] |= 1<<(h&7); break; } @@ -102571,7 +101148,7 @@ case OP_Filter: { /* jump */ printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); } #endif - h %= (pIn1->n*8); + h %= pIn1->n; if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ VdbeBranchTaken(1, 2); p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; @@ -102797,10 +101374,8 @@ default: { /* This is really OP_Noop, OP_Explain */ *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); pnCycle = 0; #elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( pnCycle ){ - *pnCycle += sqlite3Hwtime(); - pnCycle = 0; - } + *pnCycle += sqlite3Hwtime(); + pnCycle = 0; #endif /* The following code adds nothing to the actual functionality @@ -102823,7 +101398,7 @@ default: { /* This is really OP_Noop, OP_Explain */ } if( opProperty==0xff ){ /* Never happens. This code exists to avoid a harmless linkage - ** warning about sqlite3VdbeRegisterDump() being defined but not + ** warning aboud sqlite3VdbeRegisterDump() being defined but not ** used. */ sqlite3VdbeRegisterDump(p); } @@ -103279,7 +101854,7 @@ SQLITE_API int sqlite3_blob_open( if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); sqlite3DbFree(db, pBlob); } - sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); sqlite3ParseObjectReset(&sParse); rc = sqlite3ApiExit(db, rc); @@ -103438,7 +102013,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ ((Vdbe*)p->pStmt)->rc = SQLITE_OK; rc = blobSeekToRow(p, iRow, &zErr); if( rc!=SQLITE_OK ){ - sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); } assert( rc!=SQLITE_SCHEMA ); @@ -103541,7 +102116,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ ** The threshold for the amount of main memory to use before flushing ** records to a PMA is roughly the same as the limit configured for the ** page-cache of the main database. Specifically, the threshold is set to -** the value returned by "PRAGMA main.page_size" multiplied by +** the value returned by "PRAGMA main.page_size" multipled by ** that returned by "PRAGMA main.cache_size", in bytes. ** ** If the sorter is running in single-threaded mode, then all PMAs generated @@ -103564,7 +102139,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ ** ** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the ** sorter is running in single-threaded mode, then these PMAs are merged -** incrementally as keys are retrieved from the sorter by the VDBE. The +** incrementally as keys are retreived from the sorter by the VDBE. The ** MergeEngine object, described in further detail below, performs this ** merge. ** @@ -103727,7 +102302,7 @@ struct MergeEngine { ** ** Essentially, this structure contains all those fields of the VdbeSorter ** structure for which each thread requires a separate instance. For example, -** each thread requeries its own UnpackedRecord object to unpack records in +** each thread requries its own UnpackedRecord object to unpack records in ** as part of comparison operations. ** ** Before a background thread is launched, variable bDone is set to 0. Then, @@ -103799,7 +102374,7 @@ struct VdbeSorter { ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. ** aKey might point into aMap or into aBuffer. If neither of those locations ** contain a contiguous representation of the key, then aAlloc is allocated -** and the key is copied into aAlloc and aKey is made to point to aAlloc. +** and the key is copied into aAlloc and aKey is made to poitn to aAlloc. ** ** pFd==0 at EOF. */ @@ -105170,7 +103745,7 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ ** the background thread from a sub-tasks previous turn is still running, ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, ** fall back to using the final sub-task. The first (pSorter->nTask-1) - ** sub-tasks are preferred as they use background threads - the final + ** sub-tasks are prefered as they use background threads - the final ** sub-task uses the main thread. */ for(i=0; iiPrev + i + 1) % nWorker; @@ -105654,7 +104229,7 @@ static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); - /* Set up the required files for pIncr. A multi-threaded IncrMerge object + /* Set up the required files for pIncr. A multi-theaded IncrMerge object ** requires two temp files to itself, whereas a single-threaded object ** only requires a region of pTask->file2. */ if( rc==SQLITE_OK ){ @@ -106294,8 +104869,6 @@ static int bytecodevtabConnect( "p5 INT," "comment TEXT," "subprog TEXT," - "nexec INT," - "ncycle INT," "stmt HIDDEN" ");", @@ -106458,7 +105031,7 @@ static int bytecodevtabColumn( } } } - i += 20; + i += 10; } } switch( i ){ @@ -106508,31 +105081,16 @@ static int bytecodevtabColumn( } break; } - -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - case 9: /* nexec */ - sqlite3_result_int(ctx, pOp->nExec); - break; - case 10: /* ncycle */ - sqlite3_result_int(ctx, pOp->nCycle); - break; -#else - case 9: /* nexec */ - case 10: /* ncycle */ - sqlite3_result_int(ctx, 0); - break; -#endif - - case 20: /* tables_used.type */ + case 10: /* tables_used.type */ sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC); break; - case 21: /* tables_used.schema */ + case 11: /* tables_used.schema */ sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC); break; - case 22: /* tables_used.name */ + case 12: /* tables_used.name */ sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC); break; - case 23: /* tables_used.wr */ + case 13: /* tables_used.wr */ sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite); break; } @@ -106606,7 +105164,7 @@ static int bytecodevtabBestIndex( int rc = SQLITE_CONSTRAINT; struct sqlite3_index_constraint *p; bytecodevtab *pVTab = (bytecodevtab*)tab; - int iBaseCol = pVTab->bTablesUsed ? 4 : 10; + int iBaseCol = pVTab->bTablesUsed ? 4 : 8; pIdxInfo->estimatedCost = (double)100; pIdxInfo->estimatedRows = 100; pIdxInfo->idxNum = 0; @@ -107177,7 +105735,7 @@ static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){ ** The return value from this routine is WRC_Abort to abandon the tree walk ** and WRC_Continue to continue. */ -SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3WalkExprNN(Walker *pWalker, Expr *pExpr){ +static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ int rc; testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); testcase( ExprHasProperty(pExpr, EP_Reduced) ); @@ -107186,9 +105744,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3WalkExprNN(Walker *pWalker, Expr *pExp if( rc ) return rc & WRC_Abort; if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ assert( pExpr->x.pList==0 || pExpr->pRight==0 ); - if( pExpr->pLeft && sqlite3WalkExprNN(pWalker, pExpr->pLeft) ){ - return WRC_Abort; - } + if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; if( pExpr->pRight ){ assert( !ExprHasProperty(pExpr, EP_WinFunc) ); pExpr = pExpr->pRight; @@ -107212,7 +105768,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3WalkExprNN(Walker *pWalker, Expr *pExp return WRC_Continue; } SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ - return pExpr ? sqlite3WalkExprNN(pWalker,pExpr) : WRC_Continue; + return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue; } /* @@ -107338,7 +105894,7 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ } /* Increase the walkerDepth when entering a subquery, and -** decrease when leaving the subquery. +** descrease when leaving the subquery. */ SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){ UNUSED_PARAMETER(pSelect); @@ -107845,8 +106401,7 @@ static int lookupName( assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); if( pParse->bReturning ){ if( (pNC->ncFlags & NC_UBaseReg)!=0 - && ALWAYS(zTab==0 - || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) + && (zTab==0 || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) ){ pExpr->iTable = op!=TK_DELETE; pTab = pParse->pTriggerTab; @@ -109072,7 +107627,7 @@ static int resolveOrderGroupBy( } for(j=0; jpEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ - /* Since this expression is being changed into a reference + /* Since this expresion is being changed into a reference ** to an identical expression in the result set, remove all Window ** objects belonging to the expression from the Select.pWin list. */ windowRemoveExprFromSelect(pSelect, pE); @@ -109395,8 +107950,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames( return SQLITE_ERROR; } #endif - assert( pExpr!=0 ); - sqlite3WalkExprNN(&w, pExpr); + sqlite3WalkExpr(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight -= pExpr->nHeight; #endif @@ -109438,7 +107992,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( return WRC_Abort; } #endif - sqlite3WalkExprNN(&w, pExpr); + sqlite3WalkExpr(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight -= pExpr->nHeight; #endif @@ -109460,7 +108014,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( /* ** Resolve all names in all expressions of a SELECT and in all -** descendants of the SELECT, including compounds off of p->pPrior, +** decendents of the SELECT, including compounds off of p->pPrior, ** subqueries in expressions, and subqueries used as FROM clause ** terms. ** @@ -109610,7 +108164,6 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ if( op==TK_SELECT_COLUMN ){ assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); assert( pExpr->iColumn < pExpr->iTable ); - assert( pExpr->iColumn >= 0 ); assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); return sqlite3ExprAffinity( pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr @@ -109822,10 +108375,11 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ }else{ Expr *pNext = p->pRight; /* The Expr.x union is never used at the same time as Expr.pRight */ - assert( !ExprUseXList(p) || p->x.pList==0 || p->pRight==0 ); - if( ExprUseXList(p) && p->x.pList!=0 && !db->mallocFailed ){ + assert( ExprUseXList(p) ); + assert( p->x.pList==0 || p->pRight==0 ); + if( p->x.pList!=0 && !db->mallocFailed ){ int i; - for(i=0; ix.pList->nExpr; i++){ + for(i=0; ALWAYS(ix.pList->nExpr); i++){ if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ pNext = p->x.pList->a[i].pExpr; break; @@ -109847,7 +108401,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ /* ** Return the collation sequence for the expression pExpr. If ** there is no defined collating sequence, return a pointer to the -** default collation sequence. +** defautl collation sequence. ** ** See also: sqlite3ExprCollSeq() ** @@ -109977,7 +108531,7 @@ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq( return pColl; } -/* Expression p is a comparison operator. Return a collation sequence +/* Expresssion p is a comparison operator. Return a collation sequence ** appropriate for the comparison operator. ** ** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). @@ -110433,15 +108987,6 @@ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ #define exprSetHeight(y) #endif /* SQLITE_MAX_EXPR_DEPTH>0 */ -/* -** Set the error offset for an Expr node, if possible. -*/ -SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ - if( pExpr==0 ) return; - if( NEVER(ExprUseWJoin(pExpr)) ) return; - pExpr->w.iOfst = iOfst; -} - /* ** This routine is the core allocator for Expr nodes. ** @@ -110666,9 +109211,9 @@ SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprLis ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. ** -** If one side or the other of the AND is known to be false, and neither side -** is part of an ON clause, then instead of returning an AND expression, -** just return a constant expression with a value of false. +** If one side or the other of the AND is known to be false, then instead +** of returning an AND expression, just return a constant expression with +** a value of false. */ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ sqlite3 *db = pParse->db; @@ -110676,17 +109221,14 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ return pRight; }else if( pRight==0 ){ return pLeft; + }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight)) + && !IN_RENAME_OBJECT + ){ + sqlite3ExprDeferredDelete(pParse, pLeft); + sqlite3ExprDeferredDelete(pParse, pRight); + return sqlite3Expr(db, TK_INTEGER, "0"); }else{ - u32 f = pLeft->flags | pRight->flags; - if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse - && !IN_RENAME_OBJECT - ){ - sqlite3ExprDeferredDelete(pParse, pLeft); - sqlite3ExprDeferredDelete(pParse, pRight); - return sqlite3Expr(db, TK_INTEGER, "0"); - }else{ - return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); - } + return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); } } @@ -110902,7 +109444,7 @@ SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ /* ** Arrange to cause pExpr to be deleted when the pParse is deleted. ** This is similar to sqlite3ExprDelete() except that the delete is -** deferred until the pParse is deleted. +** deferred untilthe pParse is deleted. ** ** The pExpr might be deleted immediately on an OOM error. ** @@ -111744,7 +110286,7 @@ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ ** and 0 if it is FALSE. */ SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){ - pExpr = sqlite3ExprSkipCollateAndLikely((Expr*)pExpr); + pExpr = sqlite3ExprSkipCollate((Expr*)pExpr); assert( pExpr->op==TK_TRUEFALSE ); assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 @@ -111931,17 +110473,12 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ } /* -** Check pExpr to see if it is an constraint on the single data source -** pSrc = &pSrcList->a[iSrc]. In other words, check to see if pExpr -** constrains pSrc but does not depend on any other tables or data -** sources anywhere else in the query. Return true (non-zero) if pExpr -** is a constraint on pSrc only. -** +** Check pExpr to see if it is an invariant constraint on data source pSrc. ** This is an optimization. False negatives will perhaps cause slower ** queries, but false positives will yield incorrect answers. So when in ** doubt, return 0. ** -** To be an single-source constraint, the following must be true: +** To be an invariant constraint, the following must be true: ** ** (1) pExpr cannot refer to any table other than pSrc->iCursor. ** @@ -111952,31 +110489,13 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ ** ** (4) If pSrc is the right operand of a LEFT JOIN, then... ** (4a) pExpr must come from an ON clause.. -** (4b) and specifically the ON clause associated with the LEFT JOIN. + (4b) and specifically the ON clause associated with the LEFT JOIN. ** ** (5) If pSrc is not the right operand of a LEFT JOIN or the left ** operand of a RIGHT JOIN, then pExpr must be from the WHERE ** clause, not an ON clause. -** -** (6) Either: -** -** (6a) pExpr does not originate in an ON or USING clause, or -** -** (6b) The ON or USING clause from which pExpr is derived is -** not to the left of a RIGHT JOIN (or FULL JOIN). -** -** Without this restriction, accepting pExpr as a single-table -** constraint might move the the ON/USING filter expression -** from the left side of a RIGHT JOIN over to the right side, -** which leads to incorrect answers. See also restriction (9) -** on push-down. */ -SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( - Expr *pExpr, /* The constraint */ - const SrcList *pSrcList, /* Complete FROM clause */ - int iSrc /* Which element of pSrcList to use */ -){ - const SrcItem *pSrc = &pSrcList->a[iSrc]; +SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ if( pSrc->fg.jointype & JT_LTORJ ){ return 0; /* rule (3) */ } @@ -111986,19 +110505,6 @@ SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( }else{ if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */ } - if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) /* (6a) */ - && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (6b) */ - ){ - int jj; - for(jj=0; jjw.iJoin==pSrcList->a[jj].iCursor ){ - if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){ - return 0; /* restriction (6) */ - } - break; - } - } - } return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ } @@ -112241,7 +110747,7 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ ** pX is the RHS of an IN operator. If pX is a SELECT statement ** that can be simplified to a direct table access, then return ** a pointer to the SELECT statement. If pX is not a SELECT statement, -** or if the SELECT statement needs to be materialized into a transient +** or if the SELECT statement needs to be manifested into a transient ** table, then return NULL. */ #ifndef SQLITE_OMIT_SUBQUERY @@ -112337,7 +110843,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. ** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. ** IN_INDEX_EPH - The cursor was opened on a specially created and -** populated ephemeral table. +** populated epheremal table. ** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be ** implemented as a sequence of comparisons. ** @@ -112350,7 +110856,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** an ephemeral table might need to be generated from the RHS and then ** pX->iTable made to point to the ephemeral table instead of an ** existing table. In this case, the creation and initialization of the -** ephemeral table might be put inside of a subroutine, the EP_Subrtn flag +** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag ** will be set on pX and the pX->y.sub fields will be set to show where ** the subroutine is coded. ** @@ -112362,12 +110868,12 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate ** through the set members) then the b-tree must not contain duplicates. -** An ephemeral table will be created unless the selected columns are guaranteed +** An epheremal table will be created unless the selected columns are guaranteed ** to be unique - either because it is an INTEGER PRIMARY KEY or due to ** a UNIQUE constraint or index. ** ** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used -** for fast set membership tests) then an ephemeral table must +** for fast set membership tests) then an epheremal table must ** be used unless is a single INTEGER PRIMARY KEY column or an ** index can be found with the specified as its left-most. ** @@ -112527,6 +111033,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; + assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr ); for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; assert( pIdx->azColl[j] ); @@ -112700,7 +111207,7 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ ** x IN (SELECT a FROM b) -- IN operator with subquery on the right ** ** The pExpr parameter is the IN operator. The cursor number for the -** constructed ephemeral table is returned. The first time the ephemeral +** constructed ephermeral table is returned. The first time the ephemeral ** table is computed, the cursor number is also stored in pExpr->iTable, ** however the cursor number returned might not be the same, as it might ** have been duplicated using OP_OpenDup. @@ -113547,7 +112054,7 @@ static void exprToRegister(Expr *pExpr, int iReg){ /* ** Evaluate an expression (either a vector or a scalar expression) and store -** the result in contiguous temporary registers. Return the index of +** the result in continguous temporary registers. Return the index of ** the first register used to store the result. ** ** If the returned result register is a temporary scalar, then also write @@ -113587,7 +112094,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ */ static void setDoNotMergeFlagOnCopy(Vdbe *v){ if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){ - sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergeable */ + sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */ } } @@ -113677,13 +112184,13 @@ static int exprCodeInlineFunction( } case INLINEFUNC_implies_nonnull_row: { - /* Result of sqlite3ExprImpliesNonNullRow() */ + /* REsult of sqlite3ExprImpliesNonNullRow() */ Expr *pA1; assert( nFarg==2 ); pA1 = pFarg->a[1].pExpr; if( pA1->op==TK_COLUMN ){ sqlite3VdbeAddOp2(v, OP_Integer, - sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable,1), + sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable), target); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); @@ -113812,19 +112319,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) AggInfo *pAggInfo = pExpr->pAggInfo; struct AggInfo_col *pCol; assert( pAggInfo!=0 ); - assert( pExpr->iAgg>=0 ); - if( pExpr->iAgg>=pAggInfo->nColumn ){ - /* Happens when the left table of a RIGHT JOIN is null and - ** is using an expression index */ - sqlite3VdbeAddOp2(v, OP_Null, 0, target); -#ifdef SQLITE_VDBE_COVERAGE - /* Verify that the OP_Null above is exercised by tests - ** tag-20230325-2 */ - sqlite3VdbeAddOp2(v, OP_NotNull, target, 1); - VdbeCoverageNeverTaken(v); -#endif - break; - } + assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); pCol = &pAggInfo->aCol[pExpr->iAgg]; if( !pAggInfo->directMode ){ return AggInfoColumnReg(pAggInfo, pExpr->iAgg); @@ -113859,7 +112354,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) if( ExprHasProperty(pExpr, EP_FixedCol) ){ /* This COLUMN expression is really a constant due to WHERE clause ** constraints, and that constant is coded by the pExpr->pLeft - ** expression. However, make sure the constant has the correct + ** expresssion. However, make sure the constant has the correct ** datatype by applying the Affinity of the table column to the ** constant. */ @@ -113999,8 +112494,11 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ - sqlite3ExprCode(pParse, pExpr->pLeft, target); - assert( inReg==target ); + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + if( inReg!=target ){ + sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); + inReg = target; + } assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3VdbeAddOp2(v, OP_Cast, target, sqlite3AffinityType(pExpr->u.zToken, 0)); @@ -114185,7 +112683,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); break; } - if( (pDef->funcFlags & SQLITE_FUNC_INLINE)!=0 && ALWAYS(pFarg!=0) ){ + if( pDef->funcFlags & SQLITE_FUNC_INLINE ){ assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); return exprCodeInlineFunction(pParse, pFarg, @@ -114211,10 +112709,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) r1 = sqlite3GetTempRange(pParse, nFarg); } - /* For length() and typeof() and octet_length() functions, + /* For length() and typeof() functions with a column argument, ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG - ** or OPFLAG_TYPEOFARG or OPFLAG_BYTELENARG respectively, to avoid - ** unnecessary data loading. + ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data + ** loading. */ if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ u8 exprOp; @@ -114224,16 +112722,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); - assert( SQLITE_FUNC_BYTELEN==OPFLAG_BYTELENARG ); - assert( (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG)==OPFLAG_BYTELENARG ); - testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_LENGTHARG ); - testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_TYPEOFARG ); - testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_BYTELENARG); - pFarg->a[0].pExpr->op2 = pDef->funcFlags & OPFLAG_BYTELENARG; + testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); + pFarg->a[0].pExpr->op2 = + pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); } } - sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR); + sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, + SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); }else{ r1 = 0; } @@ -114341,9 +112837,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** Clear subtypes as subtypes may not cross a subquery boundary. */ assert( pExpr->pLeft ); - sqlite3ExprCode(pParse, pExpr->pLeft, target); - sqlite3VdbeAddOp1(v, OP_ClrSubtype, target); - return target; + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + if( inReg!=target ){ + sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); + inReg = target; + } + sqlite3VdbeAddOp1(v, OP_ClrSubtype, inReg); + return inReg; }else{ pExpr = pExpr->pLeft; goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */ @@ -114453,9 +112953,12 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** "target" and not someplace else. */ pParse->okConstFactor = 0; /* note (1) above */ - sqlite3ExprCode(pParse, pExpr->pLeft, target); - assert( target==inReg ); + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); pParse->okConstFactor = okConstFactor; + if( inReg!=target ){ /* note (2) above */ + sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); + inReg = target; + } sqlite3VdbeJumpHere(v, addrINR); break; } @@ -114590,7 +113093,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** ** If regDest>=0 then the result is always stored in that register and the ** result is not reusable. If regDest<0 then this routine is free to -** store the value wherever it wants. The register where the expression +** store the value whereever it wants. The register where the expression ** is stored is returned. When regDest<0, two identical expressions might ** code to the same register, if they do not contain function calls and hence ** are factored out into the initialization section at the end of the @@ -114693,9 +113196,7 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); if( inReg!=target ){ u8 op; - if( ALWAYS(pExpr) - && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER) - ){ + if( ALWAYS(pExpr) && ExprHasProperty(pExpr,EP_Subquery) ){ op = OP_Copy; }else{ op = OP_SCopy; @@ -115508,7 +114009,7 @@ static int exprImpliesNotNull( ** pE1: x!=123 pE2: x IS NOT NULL Result: true ** pE1: x!=?1 pE2: x IS NOT NULL Result: true ** pE1: x IS NULL pE2: x IS NOT NULL Result: false -** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false ** ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has ** Expr.iTable<0 then assume a table number given by iTab. @@ -115545,29 +114046,11 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr( return 0; } -/* This is a helper function to impliesNotNullRow(). In this routine, -** set pWalker->eCode to one only if *both* of the input expressions -** separately have the implies-not-null-row property. -*/ -static void bothImplyNotNullRow(Walker *pWalker, Expr *pE1, Expr *pE2){ - if( pWalker->eCode==0 ){ - sqlite3WalkExpr(pWalker, pE1); - if( pWalker->eCode ){ - pWalker->eCode = 0; - sqlite3WalkExpr(pWalker, pE2); - } - } -} - /* ** This is the Expr node callback for sqlite3ExprImpliesNonNullRow(). ** If the expression node requires that the table at pWalker->iCur ** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. ** -** pWalker->mWFlags is non-zero if this inquiry is being undertaking on -** behalf of a RIGHT JOIN (or FULL JOIN). That makes a difference when -** evaluating terms in the ON clause of an inner join. -** ** This routine controls an optimization. False positives (setting ** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives ** (never setting pWalker->eCode) is a harmless missed optimization. @@ -115576,33 +114059,28 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_AGG_COLUMN ); testcase( pExpr->op==TK_AGG_FUNCTION ); if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune; - if( ExprHasProperty(pExpr, EP_InnerON) && pWalker->mWFlags ){ - /* If iCur is used in an inner-join ON clause to the left of a - ** RIGHT JOIN, that does *not* mean that the table must be non-null. - ** But it is difficult to check for that condition precisely. - ** To keep things simple, any use of iCur from any inner-join is - ** ignored while attempting to simplify a RIGHT JOIN. */ - return WRC_Prune; - } switch( pExpr->op ){ case TK_ISNOT: case TK_ISNULL: case TK_NOTNULL: case TK_IS: + case TK_OR: case TK_VECTOR: + case TK_CASE: + case TK_IN: case TK_FUNCTION: case TK_TRUTH: - case TK_CASE: testcase( pExpr->op==TK_ISNOT ); testcase( pExpr->op==TK_ISNULL ); testcase( pExpr->op==TK_NOTNULL ); testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_OR ); testcase( pExpr->op==TK_VECTOR ); + testcase( pExpr->op==TK_CASE ); + testcase( pExpr->op==TK_IN ); testcase( pExpr->op==TK_FUNCTION ); testcase( pExpr->op==TK_TRUTH ); - testcase( pExpr->op==TK_CASE ); return WRC_Prune; - case TK_COLUMN: if( pWalker->u.iCur==pExpr->iTable ){ pWalker->eCode = 1; @@ -115610,38 +114088,21 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ } return WRC_Prune; - case TK_OR: case TK_AND: - /* Both sides of an AND or OR must separately imply non-null-row. - ** Consider these cases: - ** 1. NOT (x AND y) - ** 2. x OR y - ** If only one of x or y is non-null-row, then the overall expression - ** can be true if the other arm is false (case 1) or true (case 2). - */ - testcase( pExpr->op==TK_OR ); - testcase( pExpr->op==TK_AND ); - bothImplyNotNullRow(pWalker, pExpr->pLeft, pExpr->pRight); - return WRC_Prune; - - case TK_IN: - /* Beware of "x NOT IN ()" and "x NOT IN (SELECT 1 WHERE false)", - ** both of which can be true. But apart from these cases, if - ** the left-hand side of the IN is NULL then the IN itself will be - ** NULL. */ - if( ExprUseXList(pExpr) && ALWAYS(pExpr->x.pList->nExpr>0) ){ + if( pWalker->eCode==0 ){ sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( pWalker->eCode ){ + pWalker->eCode = 0; + sqlite3WalkExpr(pWalker, pExpr->pRight); + } } return WRC_Prune; case TK_BETWEEN: - /* In "x NOT BETWEEN y AND z" either x must be non-null-row or else - ** both y and z must be non-null row */ - assert( ExprUseXList(pExpr) ); - assert( pExpr->x.pList->nExpr==2 ); - sqlite3WalkExpr(pWalker, pExpr->pLeft); - bothImplyNotNullRow(pWalker, pExpr->x.pList->a[0].pExpr, - pExpr->x.pList->a[1].pExpr); + if( sqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){ + assert( pWalker->eCode ); + return WRC_Abort; + } return WRC_Prune; /* Virtual tables are allowed to use constraints like x=NULL. So @@ -115703,7 +114164,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ ** be non-NULL, then the LEFT JOIN can be safely converted into an ** ordinary join. */ -SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){ +SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ Walker w; p = sqlite3ExprSkipCollateAndLikely(p); if( p==0 ) return 0; @@ -115711,7 +114172,7 @@ SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){ p = p->pLeft; }else{ while( p->op==TK_AND ){ - if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab, isRJ) ) return 1; + if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1; p = p->pRight; } } @@ -115719,7 +114180,6 @@ SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){ w.xSelectCallback = 0; w.xSelectCallback2 = 0; w.eCode = 0; - w.mWFlags = isRJ!=0; w.u.iCur = iTab; sqlite3WalkExpr(&w, p); return w.eCode; @@ -115780,7 +114240,7 @@ SQLITE_PRIVATE int sqlite3ExprCoveredByIndex( } -/* Structure used to pass information throughout the Walker in order to +/* Structure used to pass information throught the Walker in order to ** implement sqlite3ReferencesSrcList(). */ struct RefSrcList { @@ -115921,11 +114381,9 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ int iAgg = pExpr->iAgg; Parse *pParse = pWalker->pParse; sqlite3 *db = pParse->db; - assert( iAgg>=0 ); if( pExpr->op!=TK_AGG_FUNCTION ){ - if( iAggnColumn - && pAggInfo->aCol[iAgg].pCExpr==pExpr - ){ + assert( iAgg>=0 && iAggnColumn ); + if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aCol[iAgg].pCExpr = pExpr; @@ -115934,9 +114392,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ } }else{ assert( pExpr->op==TK_AGG_FUNCTION ); - if( ALWAYS(iAggnFunc) - && pAggInfo->aFunc[iAgg].pFExpr==pExpr - ){ + assert( iAgg>=0 && iAggnFunc ); + if( pAggInfo->aFunc[iAgg].pFExpr==pExpr ){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aFunc[iAgg].pFExpr = pExpr; @@ -115996,7 +114453,7 @@ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ ** Return the index in aCol[] of the entry that describes that column. ** ** If no prior entry is found, create a new one and return -1. The -** new column will have an index of pAggInfo->nColumn-1. +** new column will have an idex of pAggInfo->nColumn-1. */ static void findOrCreateAggInfoColumn( Parse *pParse, /* Parsing context */ @@ -116009,7 +114466,6 @@ static void findOrCreateAggInfoColumn( assert( pAggInfo->iFirstReg==0 ); pCol = pAggInfo->aCol; for(k=0; knColumn; k++, pCol++){ - if( pCol->pCExpr==pExpr ) return; if( pCol->iTable==pExpr->iTable && pCol->iColumn==pExpr->iColumn && pExpr->op!=TK_IF_NULL_ROW @@ -116087,12 +114543,7 @@ 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( i>=pSrcList->nSrc ) break; - if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ - if( pParse->nErr ){ return WRC_Abort; } + if( pExpr->pAggInfo!=0 ) break; /* Already resolved by outer context */ /* If we reach this point, it means that expression pExpr can be ** translated into a reference to an index column as described by @@ -116103,9 +114554,6 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ tmp.iTable = pIEpr->iIdxCur; tmp.iColumn = pIEpr->iIdxCol; findOrCreateAggInfoColumn(pParse, pAggInfo, &tmp); - if( pParse->nErr ){ return WRC_Abort; } - assert( pAggInfo->aCol!=0 ); - assert( tmp.iAggnColumn ); pAggInfo->aCol[tmp.iAgg].pCExpr = pExpr; pExpr->pAggInfo = pAggInfo; pExpr->iAgg = tmp.iAgg; @@ -116129,7 +114577,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ } /* endif pExpr->iTable==pItem->iCursor */ } /* end loop over pSrcList */ } - return WRC_Continue; + return WRC_Prune; } case TK_AGG_FUNCTION: { if( (pNC->ncFlags & NC_InAggFunc)==0 @@ -116282,37 +114730,6 @@ SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ pParse->nRangeReg = 0; } -/* -** Make sure sufficient registers have been allocated so that -** iReg is a valid register number. -*/ -SQLITE_PRIVATE void sqlite3TouchRegister(Parse *pParse, int iReg){ - if( pParse->nMemnMem = iReg; -} - -#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) -/* -** Return the latest reusable register in the set of all registers. -** The value returned is no less than iMin. If any register iMin or -** greater is in permanent use, then return one more than that last -** permanent register. -*/ -SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse *pParse, int iMin){ - const ExprList *pList = pParse->pConstExpr; - if( pList ){ - int i; - for(i=0; inExpr; i++){ - if( pList->a[i].u.iConstExprReg>=iMin ){ - iMin = pList->a[i].u.iConstExprReg + 1; - } - } - } - pParse->nTempReg = 0; - pParse->nRangeReg = 0; - return iMin; -} -#endif /* SQLITE_ENABLE_STAT4 || SQLITE_DEBUG */ - /* ** Validate that no temporary register falls within the range of ** iFirst..iLast, inclusive. This routine is only call from within assert() @@ -116332,14 +114749,6 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ return 0; } } - if( pParse->pConstExpr ){ - ExprList *pList = pParse->pConstExpr; - for(i=0; inExpr; i++){ - int iReg = pList->a[i].u.iConstExprReg; - if( iReg==0 ) continue; - if( iReg>=iFirst && iReg<=iLast ) return 0; - } - } return 1; } #endif /* SQLITE_DEBUG */ @@ -116890,7 +115299,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); pNew->pSchema = db->aDb[iDb].pSchema; pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; - assert( pNew->nTabRef==1 ); + pNew->nTabRef = 1; exit_begin_add_column: sqlite3SrcListDelete(db, pSrc); @@ -117395,7 +115804,7 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ } /* -** An error occurred while parsing or otherwise processing a database +** An error occured while parsing or otherwise processing a database ** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an ** ALTER TABLE RENAME COLUMN program. The error message emitted by the ** sub-routine is currently stored in pParse->zErrMsg. This function @@ -117627,19 +116036,6 @@ static int renameEditSql( return rc; } -/* -** Set all pEList->a[].fg.eEName fields in the expression-list to val. -*/ -static void renameSetENames(ExprList *pEList, int val){ - if( pEList ){ - int i; - for(i=0; inExpr; i++){ - assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); - pEList->a[i].fg.eEName = val; - } - } -} - /* ** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming ** it was read from the schema of database zDb. Return SQLITE_OK if @@ -117687,17 +116083,7 @@ static int renameResolveTrigger(Parse *pParse){ pSrc = 0; rc = SQLITE_NOMEM; }else{ - /* pStep->pExprList contains an expression-list used for an UPDATE - ** statement. So the a[].zEName values are the RHS of the - ** " = " clauses of the UPDATE statement. So, before - ** running SelectPrep(), change all the eEName values in - ** pStep->pExprList to ENAME_SPAN (from their current value of - ** ENAME_NAME). This is to prevent any ids in ON() clauses that are - ** part of pSrc from being incorrectly resolved against the - ** a[].zEName values as if they were column aliases. */ - renameSetENames(pStep->pExprList, ENAME_SPAN); sqlite3SelectPrep(pParse, pSel, 0); - renameSetENames(pStep->pExprList, ENAME_NAME); rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK; assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList ); assert( pSrc==pSel->pSrc ); @@ -119646,15 +118032,11 @@ static void analyzeOneTable( int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ int regPrev = iMem; /* MUST BE LAST (see below) */ -#ifdef SQLITE_ENABLE_STAT4 - int doOnce = 1; /* Flag for a one-time computation */ -#endif #ifdef SQLITE_ENABLE_PREUPDATE_HOOK Table *pStat1 = 0; #endif - sqlite3TouchRegister(pParse, iMem); - assert( sqlite3NoTempsInRange(pParse, regNewRowid, iMem) ); + pParse->nMem = MAX(pParse->nMem, iMem); v = sqlite3GetVdbe(pParse); if( v==0 || NEVER(pTab==0) ){ return; @@ -119760,7 +118142,7 @@ static void analyzeOneTable( ** the regPrev array and a trailing rowid (the rowid slot is required ** when building a record to insert into the sample column of ** the sqlite_stat4 table. */ - sqlite3TouchRegister(pParse, regPrev+nColTest); + pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); /* Open a read-only cursor on the index being analyzed. */ assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); @@ -119932,35 +118314,7 @@ static void analyzeOneTable( int addrIsNull; u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; - if( doOnce ){ - int mxCol = nCol; - Index *pX; - - /* Compute the maximum number of columns in any index */ - for(pX=pTab->pIndex; pX; pX=pX->pNext){ - int nColX; /* Number of columns in pX */ - if( !HasRowid(pTab) && IsPrimaryKeyIndex(pX) ){ - nColX = pX->nKeyCol; - }else{ - nColX = pX->nColumn; - } - if( nColX>mxCol ) mxCol = nColX; - } - - /* Allocate space to compute results for the largest index */ - sqlite3TouchRegister(pParse, regCol+mxCol); - doOnce = 0; -#ifdef SQLITE_DEBUG - /* Verify that the call to sqlite3ClearTempRegCache() below - ** really is needed. - ** https://sqlite.org/forum/forumpost/83cb4a95a0 (2023-03-25) - */ - testcase( !sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); -#endif - sqlite3ClearTempRegCache(pParse); /* tag-20230325-1 */ - assert( sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); - } - assert( sqlite3NoTempsInRange(pParse, regEq, regCol+nCol) ); + pParse->nMem = MAX(pParse->nMem, regCol+nCol); addrNext = sqlite3VdbeCurrentAddr(v); callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid); @@ -120041,11 +118395,6 @@ static void analyzeDatabase(Parse *pParse, int iDb){ for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ Table *pTab = (Table*)sqliteHashData(k); analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); -#ifdef SQLITE_ENABLE_STAT4 - iMem = sqlite3FirstAvailableRegister(pParse, iMem); -#else - assert( iMem==sqlite3FirstAvailableRegister(pParse,iMem) ); -#endif } loadAnalysis(pParse, iDb); } @@ -120433,10 +118782,6 @@ static int loadStatTbl( pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); assert( pIdx==0 || pIdx->nSample==0 ); if( pIdx==0 ) continue; - if( pIdx->aSample!=0 ){ - /* The same index appears in sqlite_stat4 under multiple names */ - continue; - } assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ nIdxCol = pIdx->nKeyCol; @@ -120444,7 +118789,6 @@ static int loadStatTbl( nIdxCol = pIdx->nColumn; } pIdx->nSampleCol = nIdxCol; - pIdx->mxSample = nSample; nByte = sizeof(IndexSample) * nSample; nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ @@ -120484,11 +118828,6 @@ static int loadStatTbl( if( zIndex==0 ) continue; pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); if( pIdx==0 ) continue; - if( pIdx->nSample>=pIdx->mxSample ){ - /* Too many slots used because the same index appears in - ** sqlite_stat4 using multiple names */ - continue; - } /* This next condition is true if data has already been loaded from ** the sqlite_stat4 table. */ nCol = pIdx->nSampleCol; @@ -120501,15 +118840,14 @@ static int loadStatTbl( decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); - /* Take a copy of the sample. Add 8 extra 0x00 bytes the end of the buffer. + /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. ** This is in case the sample record is corrupted. In that case, the ** sqlite3VdbeRecordCompare() may read up to two varints past the ** end of the allocated buffer before it realizes it is dealing with - ** a corrupt record. Or it might try to read a large integer from the - ** buffer. In any case, eight 0x00 bytes prevents this from causing + ** a corrupt record. Adding the two 0x00 bytes prevents this from causing ** a buffer overread. */ pSample->n = sqlite3_column_bytes(pStmt, 4); - pSample->p = sqlite3DbMallocZero(db, pSample->n + 8); + pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); if( pSample->p==0 ){ sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; @@ -120533,12 +118871,11 @@ static int loadStat4(sqlite3 *db, const char *zDb){ const Table *pStat4; assert( db->lookaside.bDisable ); - if( OptimizationEnabled(db, SQLITE_Stat4) - && (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0 + if( (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0 && IsOrdinaryTable(pStat4) ){ rc = loadStatTbl(db, - "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx COLLATE nocase", + "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", zDb ); @@ -121467,7 +119804,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( sqlite3 *db = pParse->db; int rc; - /* Don't do any authorization checks if the database is initializing + /* Don't do any authorization checks if the database is initialising ** or if the parser is being invoked from within sqlite3_declare_vtab. */ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); @@ -121768,17 +120105,15 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ pParse->nVtabLock = 0; #endif -#ifndef SQLITE_OMIT_SHARED_CACHE /* Once all the cookies have been verified and transactions opened, ** obtain the required table-locks. This is a no-op unless the ** shared-cache feature is enabled. */ - if( pParse->nTableLock ) codeTableLocks(pParse); -#endif + codeTableLocks(pParse); /* Initialize any AUTOINCREMENT data structures required. */ - if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse); + sqlite3AutoincrementBegin(pParse); /* Code constant expressions that where factored out of inner loops. ** @@ -122291,7 +120626,7 @@ SQLITE_PRIVATE void sqlite3ColumnSetColl( } /* -** Return the collating sequence name for a column +** Return the collating squence name for a column */ SQLITE_PRIVATE const char *sqlite3ColumnColl(Column *pCol){ const char *z; @@ -122384,7 +120719,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ if( IsOrdinaryTable(pTable) ){ sqlite3FkDelete(db, pTable); } -#ifndef SQLITE_OMIT_VIRTUALTABLE +#ifndef SQLITE_OMIT_VIRTUAL_TABLE else if( IsVirtual(pTable) ){ sqlite3VtabClear(db, pTable); } @@ -123049,7 +121384,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ } if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); - /* Because keywords GENERATE ALWAYS can be converted into identifiers + /* Because keywords GENERATE ALWAYS can be converted into indentifiers ** by the parser, we can sometimes end up with a typename that ends ** with "generated always". Check for this case and omit the surplus ** text. */ @@ -123270,7 +121605,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The parsed expression of the default value */ const char *zStart, /* Start of the default value text */ - const char *zEnd /* First character past end of default value text */ + const char *zEnd /* First character past end of defaut value text */ ){ Table *p; Column *pCol; @@ -123618,7 +121953,7 @@ static int identLength(const char *z){ ** to the specified offset in the buffer and updates *pIdx to refer ** to the first byte after the last byte written before returning. ** -** If the string zSignedIdent consists entirely of alphanumeric +** If the string zSignedIdent consists entirely of alpha-numeric ** characters, does not begin with a digit and is not an SQL keyword, ** then it is copied to the output buffer exactly as it is. Otherwise, ** it is quoted using double-quotes. @@ -123770,7 +122105,7 @@ static void estimateIndexWidth(Index *pIdx){ for(i=0; inColumn; i++){ i16 x = pIdx->aiColumn[i]; assert( xpTable->nCol ); - wIndex += x<0 ? 1 : aCol[x].szEst; + wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst; } pIdx->szIdxRow = sqlite3LogEst(wIndex*4); } @@ -125508,7 +123843,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( #ifndef SQLITE_OMIT_TEMPDB /* If the index name was unqualified, check if the table ** is a temp table. If so, set the database to 1. Do not do this - ** if initializing a database schema. + ** if initialising a database schema. */ if( !db->init.busy ){ pTab = sqlite3SrcListLookup(pParse, pTblName); @@ -127165,7 +125500,7 @@ SQLITE_PRIVATE void sqlite3CteDelete(sqlite3 *db, Cte *pCte){ /* ** This routine is invoked once per CTE by the parser while parsing a -** WITH clause. The CTE described by the third argument is added to +** WITH clause. The CTE described by teh third argument is added to ** the WITH clause of the second argument. If the second argument is ** NULL, then a new WITH argument is created. */ @@ -127416,7 +125751,6 @@ SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){ ** strings is BINARY. */ db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0); - sqlite3ExpirePreparedStatements(db, 1); } /* @@ -127807,9 +126141,8 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); - if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab); + sqlite3DeleteTable(pParse->db, pItem->pTab); pItem->pTab = pTab; - pItem->fg.notCte = 1; if( pTab ){ pTab->nTabRef++; if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ @@ -127889,15 +126222,13 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){ ** If pTab is writable but other errors have occurred -> return 1. ** If pTab is writable and no prior errors -> return 0; */ -SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, Trigger *pTrigger){ +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ if( tabIsReadOnly(pParse, pTab) ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; } #ifndef SQLITE_OMIT_VIEW - if( IsView(pTab) - && (pTrigger==0 || (pTrigger->bReturning && pTrigger->pNext==0)) - ){ + if( !viewOk && IsView(pTab) ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); return 1; } @@ -127962,7 +126293,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( sqlite3 *db = pParse->db; Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ - ExprList *pEList = NULL; /* Expression list containing only pSelectRowid*/ + ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ Select *pSelect = NULL; /* Complete SELECT tree */ Table *pTab; @@ -128000,20 +126331,14 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( ); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); - assert( pPk!=0 ); - assert( pPk->nKeyCol>=1 ); if( pPk->nKeyCol==1 ){ - const char *zName; - assert( pPk->aiColumn[0]>=0 && pPk->aiColumn[0]nCol ); - zName = pTab->aCol[pPk->aiColumn[0]].zCnName; + const char *zName = pTab->aCol[pPk->aiColumn[0]].zCnName; pLhs = sqlite3Expr(db, TK_ID, zName); pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); }else{ int i; for(i=0; inKeyCol; i++){ - Expr *p; - assert( pPk->aiColumn[i]>=0 && pPk->aiColumn[i]nCol ); - p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); + Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); pEList = sqlite3ExprListAppend(pParse, pEList, p); } pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); @@ -128042,7 +126367,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( pOrderBy,0,pLimit ); - /* now generate the new WHERE rowid IN clause for the DELETE/UPDATE */ + /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); sqlite3PExprAddSelect(pParse, pInClause, pSelect); return pInClause; @@ -128157,7 +126482,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( goto delete_from_cleanup; } - if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ goto delete_from_cleanup; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -128271,7 +126596,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( if( HasRowid(pTab) ){ /* For a rowid table, initialize the RowSet to an empty set */ pPk = 0; - assert( nPk==1 ); + nPk = 1; iRowSet = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); }else{ @@ -128636,11 +126961,9 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete( sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); /* Invoke AFTER DELETE trigger programs. */ - if( pTrigger ){ - sqlite3CodeRowTrigger(pParse, pTrigger, - TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel - ); - } + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel + ); /* Jump here if the row had already been deleted before any BEFORE ** trigger programs were invoked. Or if a trigger program throws a @@ -128953,42 +127276,6 @@ static void lengthFunc( } } -/* -** Implementation of the octet_length() function -*/ -static void bytelengthFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - assert( argc==1 ); - UNUSED_PARAMETER(argc); - switch( sqlite3_value_type(argv[0]) ){ - case SQLITE_BLOB: { - sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); - break; - } - case SQLITE_INTEGER: - case SQLITE_FLOAT: { - i64 m = sqlite3_context_db_handle(context)->enc<=SQLITE_UTF8 ? 1 : 2; - sqlite3_result_int64(context, sqlite3_value_bytes(argv[0])*m); - break; - } - case SQLITE_TEXT: { - if( sqlite3_value_encoding(argv[0])<=SQLITE_UTF8 ){ - sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); - }else{ - sqlite3_result_int(context, sqlite3_value_bytes16(argv[0])); - } - break; - } - default: { - sqlite3_result_null(context); - break; - } - } -} - /* ** Implementation of the abs() function. ** @@ -129265,7 +127552,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ - zBuf = sqlite3_mprintf("%!.*f",n,r); + zBuf = sqlite3_mprintf("%.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; @@ -129467,7 +127754,7 @@ struct compareInfo { /* ** For LIKE and GLOB matching on EBCDIC machines, assume that every -** character is exactly one byte in size. Also, provide the Utf8Read() +** character is exactly one byte in size. Also, provde the Utf8Read() ** macro for fast reading of the next character in the common case where ** the next character is ASCII. */ @@ -129700,7 +127987,7 @@ SQLITE_API int sqlite3_like_count = 0; /* ** Implementation of the like() SQL function. This function implements -** the built-in LIKE operator. The first argument to the function is the +** the build-in LIKE operator. The first argument to the function is the ** pattern and the second argument is the string. So, the SQL statements: ** ** A LIKE B @@ -130033,7 +128320,6 @@ static void charFunc( *zOut++ = 0x80 + (u8)(c & 0x3F); } \ } - *zOut = 0; sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); } @@ -130087,7 +128373,7 @@ static int strContainsChar(const u8 *zStr, int nStr, u32 ch){ ** decoded and returned as a blob. ** ** If there is only a single argument, then it must consist only of an -** even number of hexadecimal digits. Otherwise, return NULL. +** even number of hexadeximal digits. Otherwise, return NULL. ** ** Or, if there is a second argument, then any character that appears in ** the second argument is also allowed to appear between pairs of hexadecimal @@ -130361,7 +128647,7 @@ static void trimFunc( /* ** The "unknown" function is automatically substituted in place of ** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN -** when the SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION compile-time option is used. +** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used. ** When the "sqlite3" command-line shell is built using this functionality, ** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries ** involving application-defined functions to be examined in a generic @@ -130477,68 +128763,13 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ */ typedef struct SumCtx SumCtx; struct SumCtx { - double rSum; /* Running sum as as a double */ - double rErr; /* Error term for Kahan-Babushka-Neumaier summation */ - i64 iSum; /* Running sum as a signed integer */ + double rSum; /* Floating point sum */ + i64 iSum; /* Integer sum */ i64 cnt; /* Number of elements summed */ - u8 approx; /* True if any non-integer value was input to the sum */ - u8 ovrfl; /* Integer overflow seen */ + u8 overflow; /* True if integer overflow seen */ + u8 approx; /* True if non-integer value was input to the sum */ }; -/* -** Do one step of the Kahan-Babushka-Neumaier summation. -** -** https://en.wikipedia.org/wiki/Kahan_summation_algorithm -** -** Variables are marked "volatile" to defeat c89 x86 floating point -** optimizations can mess up this algorithm. -*/ -static void kahanBabuskaNeumaierStep( - volatile SumCtx *pSum, - volatile double r -){ - volatile double s = pSum->rSum; - volatile double t = s + r; - if( fabs(s) > fabs(r) ){ - pSum->rErr += (s - t) + r; - }else{ - pSum->rErr += (r - t) + s; - } - pSum->rSum = t; -} - -/* -** Add a (possibly large) integer to the running sum. -*/ -static void kahanBabuskaNeumaierStepInt64(volatile SumCtx *pSum, i64 iVal){ - if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ - i64 iBig, iSm; - iSm = iVal % 16384; - iBig = iVal - iSm; - kahanBabuskaNeumaierStep(pSum, iBig); - kahanBabuskaNeumaierStep(pSum, iSm); - }else{ - kahanBabuskaNeumaierStep(pSum, (double)iVal); - } -} - -/* -** Initialize the Kahan-Babaska-Neumaier sum from a 64-bit integer -*/ -static void kahanBabuskaNeumaierInit( - volatile SumCtx *p, - i64 iVal -){ - if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ - i64 iSm = iVal % 16384; - p->rSum = (double)(iVal - iSm); - p->rErr = (double)iSm; - }else{ - p->rSum = (double)iVal; - p->rErr = 0.0; - } -} - /* ** Routines used to compute the sum, average, and total. ** @@ -130558,29 +128789,15 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ type = sqlite3_value_numeric_type(argv[0]); if( p && type!=SQLITE_NULL ){ p->cnt++; - if( p->approx==0 ){ - if( type!=SQLITE_INTEGER ){ - kahanBabuskaNeumaierInit(p, p->iSum); - p->approx = 1; - kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); - }else{ - i64 x = p->iSum; - if( sqlite3AddInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ - p->iSum = x; - }else{ - p->ovrfl = 1; - kahanBabuskaNeumaierInit(p, p->iSum); - p->approx = 1; - kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); - } + if( type==SQLITE_INTEGER ){ + i64 v = sqlite3_value_int64(argv[0]); + p->rSum += v; + if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ + p->approx = p->overflow = 1; } }else{ - if( type==SQLITE_INTEGER ){ - kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); - }else{ - p->ovrfl = 0; - kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); - } + p->rSum += sqlite3_value_double(argv[0]); + p->approx = 1; } } } @@ -130597,18 +128814,13 @@ static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ if( ALWAYS(p) && type!=SQLITE_NULL ){ assert( p->cnt>0 ); p->cnt--; - if( !p->approx ){ - p->iSum -= sqlite3_value_int64(argv[0]); - }else if( type==SQLITE_INTEGER ){ - i64 iVal = sqlite3_value_int64(argv[0]); - if( iVal!=SMALLEST_INT64 ){ - kahanBabuskaNeumaierStepInt64(p, -iVal); - }else{ - kahanBabuskaNeumaierStepInt64(p, LARGEST_INT64); - kahanBabuskaNeumaierStepInt64(p, 1); - } + assert( type==SQLITE_INTEGER || p->approx ); + if( type==SQLITE_INTEGER && p->approx==0 ){ + i64 v = sqlite3_value_int64(argv[0]); + p->rSum -= v; + p->iSum -= v; }else{ - kahanBabuskaNeumaierStep(p, -sqlite3_value_double(argv[0])); + p->rSum -= sqlite3_value_double(argv[0]); } } } @@ -130619,12 +128831,10 @@ static void sumFinalize(sqlite3_context *context){ SumCtx *p; p = sqlite3_aggregate_context(context, 0); if( p && p->cnt>0 ){ - if( p->approx ){ - if( p->ovrfl ){ - sqlite3_result_error(context,"integer overflow",-1); - }else{ - sqlite3_result_double(context, p->rSum+p->rErr); - } + if( p->overflow ){ + sqlite3_result_error(context,"integer overflow",-1); + }else if( p->approx ){ + sqlite3_result_double(context, p->rSum); }else{ sqlite3_result_int64(context, p->iSum); } @@ -130634,27 +128844,14 @@ static void avgFinalize(sqlite3_context *context){ SumCtx *p; p = sqlite3_aggregate_context(context, 0); if( p && p->cnt>0 ){ - double r; - if( p->approx ){ - r = p->rSum+p->rErr; - }else{ - r = (double)(p->iSum); - } - sqlite3_result_double(context, r/(double)p->cnt); + sqlite3_result_double(context, p->rSum/(double)p->cnt); } } static void totalFinalize(sqlite3_context *context){ SumCtx *p; - double r = 0.0; p = sqlite3_aggregate_context(context, 0); - if( p ){ - if( p->approx ){ - r = p->rSum+p->rErr; - }else{ - r = (double)(p->iSum); - } - } - sqlite3_result_double(context, r); + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + sqlite3_result_double(context, p ? p->rSum : (double)0); } /* @@ -130876,7 +129073,7 @@ static void groupConcatInverse( if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); /* pGCC is always non-NULL since groupConcatStep() will have always - ** run first to initialize it */ + ** run frist to initialize it */ if( ALWAYS(pGCC) ){ int nVS; /* Must call sqlite3_value_text() to convert the argument into text prior @@ -131244,37 +129441,6 @@ static void signFunc( sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); } -#ifdef SQLITE_DEBUG -/* -** Implementation of fpdecode(x,y,z) function. -** -** x is a real number that is to be decoded. y is the precision. -** z is the maximum real precision. -*/ -static void fpdecodeFunc( - sqlite3_context *context, - int argc, - sqlite3_value **argv -){ - FpDecode s; - double x; - int y, z; - char zBuf[100]; - UNUSED_PARAMETER(argc); - assert( argc==3 ); - x = sqlite3_value_double(argv[0]); - y = sqlite3_value_int(argv[1]); - z = sqlite3_value_int(argv[2]); - sqlite3FpDecode(&s, x, y, z); - if( s.isSpecial==2 ){ - sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); - }else{ - sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP); - } - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); -} -#endif /* SQLITE_DEBUG */ - /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as @@ -131339,16 +129505,12 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), - FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN), FUNCTION(instr, 2, 0, 0, instrFunc ), FUNCTION(printf, -1, 0, 0, printfFunc ), FUNCTION(format, -1, 0, 0, printfFunc ), FUNCTION(unicode, 1, 0, 0, unicodeFunc ), FUNCTION(char, -1, 0, 0, charFunc ), FUNCTION(abs, 1, 0, 0, absFunc ), -#ifdef SQLITE_DEBUG - FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), -#endif #ifndef SQLITE_OMIT_FLOATING_POINT FUNCTION(round, 1, 0, 0, roundFunc ), FUNCTION(round, 2, 0, 0, roundFunc ), @@ -132788,22 +130950,22 @@ static Trigger *fkActionTrigger( if( action==OE_Restrict ){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - SrcList *pSrc; + Token tFrom; + Token tDb; Expr *pRaise; + tFrom.z = zFrom; + tFrom.n = nFrom; + tDb.z = db->aDb[iDb].zDbSName; + tDb.n = sqlite3Strlen30(tDb.z); + pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); if( pRaise ){ pRaise->affExpr = OE_Abort; } - pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); - if( pSrc ){ - assert( pSrc->nSrc==1 ); - pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); - pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); - } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), - pSrc, + sqlite3SrcListAppend(pParse, 0, &tDb, &tFrom), pWhere, 0, 0, 0, 0, 0 ); @@ -132919,8 +131081,9 @@ SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ if( pFKey->pPrevTo ){ pFKey->pPrevTo->pNextTo = pFKey->pNextTo; }else{ - const char *z = (pFKey->pNextTo ? pFKey->pNextTo->zTo : pFKey->zTo); - sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, pFKey->pNextTo); + void *p = (void *)pFKey->pNextTo; + const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); } if( pFKey->pNextTo ){ pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; @@ -132983,10 +131146,8 @@ SQLITE_PRIVATE void sqlite3OpenTable( assert( pParse->pVdbe!=0 ); v = pParse->pVdbe; assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); - if( !pParse->db->noSharedCache ){ - sqlite3TableLock(pParse, iDb, pTab->tnum, - (opcode==OP_OpenWrite)?1:0, pTab->zName); - } + sqlite3TableLock(pParse, iDb, pTab->tnum, + (opcode==OP_OpenWrite)?1:0, pTab->zName); if( HasRowid(pTab) ){ sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); VdbeComment((v, "%s", pTab->zName)); @@ -133020,48 +131181,46 @@ SQLITE_PRIVATE void sqlite3OpenTable( ** is managed along with the rest of the Index structure. It will be ** released when sqlite3DeleteIndex() is called. */ -static SQLITE_NOINLINE const char *computeIndexAffStr(sqlite3 *db, Index *pIdx){ - /* The first time a column affinity string for a particular index is - ** required, it is allocated and populated here. It is then stored as - ** a member of the Index structure for subsequent use. - ** - ** The column affinity string will eventually be deleted by - ** sqliteDeleteIndex() when the Index structure itself is cleaned - ** up. - */ - int n; - Table *pTab = pIdx->pTable; - pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ if( !pIdx->zColAff ){ - sqlite3OomFault(db); - return 0; - } - for(n=0; nnColumn; n++){ - i16 x = pIdx->aiColumn[n]; - char aff; - if( x>=0 ){ - aff = pTab->aCol[x].affinity; - }else if( x==XN_ROWID ){ - aff = SQLITE_AFF_INTEGER; - }else{ - assert( x==XN_EXPR ); - assert( pIdx->bHasExpr ); - assert( pIdx->aColExpr!=0 ); - aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); + /* The first time a column affinity string for a particular index is + ** required, it is allocated and populated here. It is then stored as + ** a member of the Index structure for subsequent use. + ** + ** The column affinity string will eventually be deleted by + ** sqliteDeleteIndex() when the Index structure itself is cleaned + ** up. + */ + int n; + Table *pTab = pIdx->pTable; + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); + if( !pIdx->zColAff ){ + sqlite3OomFault(db); + return 0; } - if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; - pIdx->zColAff[n] = aff; + for(n=0; nnColumn; n++){ + i16 x = pIdx->aiColumn[n]; + char aff; + if( x>=0 ){ + aff = pTab->aCol[x].affinity; + }else if( x==XN_ROWID ){ + aff = SQLITE_AFF_INTEGER; + }else{ + assert( x==XN_EXPR ); + assert( pIdx->bHasExpr ); + assert( pIdx->aColExpr!=0 ); + aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); + } + if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; + pIdx->zColAff[n] = aff; + } + pIdx->zColAff[n] = 0; } - pIdx->zColAff[n] = 0; - return pIdx->zColAff; -} -SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ - if( !pIdx->zColAff ) return computeIndexAffStr(db, pIdx); + return pIdx->zColAff; } - /* ** Compute an affinity string for a table. Space is obtained ** from sqlite3DbMalloc(). The caller is responsible for freeing @@ -133115,7 +131274,7 @@ SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3 *db, const Table *pTab){ ** For STRICT tables: ** ------------------ ** -** Generate an appropriate OP_TypeCheck opcode that will verify the +** Generate an appropropriate OP_TypeCheck opcode that will verify the ** datatypes against the column definitions in pTab. If iReg==0, that ** means an OP_MakeRecord opcode has already been generated and should be ** the last opcode generated. The new OP_TypeCheck needs to be inserted @@ -133746,7 +131905,7 @@ SQLITE_PRIVATE void sqlite3Insert( /* Cannot insert into a read-only table. */ - if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ goto insert_cleanup; } @@ -134193,7 +132352,7 @@ SQLITE_PRIVATE void sqlite3Insert( } /* Copy the new data already generated. */ - assert( pTab->nNVCol>0 || pParse->nErr>0 ); + assert( pTab->nNVCol>0 ); sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); #ifndef SQLITE_OMIT_GENERATED_COLUMNS @@ -134407,7 +132566,7 @@ SQLITE_PRIVATE void sqlite3Insert( /* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). * Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this ** expression node references any of the -** columns that are being modified by an UPDATE statement. +** columns that are being modifed by an UPDATE statement. */ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN ){ @@ -134630,7 +132789,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int *aiChng, /* column i is unchanged if aiChng[i]<0 */ Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ ){ - Vdbe *v; /* VDBE under construction */ + Vdbe *v; /* VDBE under constrution */ Index *pIdx; /* Pointer to one of the indices */ Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ sqlite3 *db; /* Database connection */ @@ -135113,7 +133272,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( pIdx; pIdx = indexIteratorNext(&sIdxIter, &ix) ){ - int regIdx; /* Range of registers holding content for pIdx */ + int regIdx; /* Range of registers hold conent for pIdx */ int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ @@ -135608,8 +133767,6 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices( assert( op==OP_OpenRead || op==OP_OpenWrite ); assert( op==OP_OpenWrite || p5==0 ); - assert( piDataCur!=0 ); - assert( piIdxCur!=0 ); if( IsVirtual(pTab) ){ /* This routine is a no-op for virtual tables. Leave the output ** variables *piDataCur and *piIdxCur set to illegal cursor numbers @@ -135622,18 +133779,18 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices( assert( v!=0 ); if( iBase<0 ) iBase = pParse->nTab; iDataCur = iBase++; - *piDataCur = iDataCur; + if( piDataCur ) *piDataCur = iDataCur; if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); - }else if( pParse->db->noSharedCache==0 ){ + }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); } - *piIdxCur = iBase; + if( piIdxCur ) *piIdxCur = iBase; for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - *piDataCur = iIdxCur; + if( piDataCur ) *piDataCur = iIdxCur; p5 = 0; } if( aToOpen==0 || aToOpen[i+1] ){ @@ -135931,7 +134088,7 @@ static int xferOptimization( } #endif #ifndef SQLITE_OMIT_FOREIGN_KEY - /* Disallow the transfer optimization if the destination table contains + /* Disallow the transfer optimization if the destination table constains ** any foreign key constraints. This is more restrictive than necessary. ** But the main beneficiary of the transfer optimization is the VACUUM ** command, and the VACUUM command disables foreign key constraints. So @@ -137558,25 +135715,15 @@ static int sqlite3LoadExtension( /* tag-20210611-1. Some dlopen() implementations will segfault if given ** an oversize filename. Most filesystems have a pathname limit of 4K, ** so limit the extension filename length to about twice that. - ** https://sqlite.org/forum/forumpost/08a0d6d9bf - ** - ** Later (2023-03-25): Save an extra 6 bytes for the filename suffix. - ** See https://sqlite.org/forum/forumpost/24083b579d. - */ + ** https://sqlite.org/forum/forumpost/08a0d6d9bf */ if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found; - /* Do not allow sqlite3_load_extension() to link to a copy of the - ** running application, by passing in an empty filename. */ - if( nMsg==0 ) goto extension_not_found; - handle = sqlite3OsDlOpen(pVfs, zFile); #if SQLITE_OS_UNIX || SQLITE_OS_WIN for(ii=0; iiaDb[iDb].zDbSName; sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - sqlite3TouchRegister(pParse, pTab->nCol+regRow); + if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); sqlite3VdbeLoadString(v, regResult, pTab->zName); assert( IsOrdinaryTable(pTab) ); @@ -140122,7 +138269,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** regRow..regRow+n. If any of the child key values are NULL, this ** row cannot cause an FK violation. Jump directly to addrOk in ** this case. */ - sqlite3TouchRegister(pParse, regRow + pFK->nCol); + if( regRow+pFK->nCol>pParse->nMem ) pParse->nMem = regRow+pFK->nCol; for(j=0; jnCol; j++){ int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); @@ -140189,9 +138336,9 @@ SQLITE_PRIVATE void sqlite3Pragma( ** The "quick_check" is reduced version of ** integrity_check designed to detect most database corruption ** without the overhead of cross-checking indexes. Quick_check - ** is linear time whereas integrity_check is O(NlogN). + ** is linear time wherease integrity_check is O(NlogN). ** - ** The maximum number of errors is 100 by default. A different default + ** The maximum nubmer of errors is 100 by default. A different default ** can be specified using a numeric parameter N. ** ** Or, the parameter N can be the name of a table. In that case, only @@ -140251,7 +138398,6 @@ SQLITE_PRIVATE void sqlite3Pragma( if( iDb>=0 && i!=iDb ) continue; sqlite3CodeVerifySchema(pParse, i); - pParse->okConstFactor = 0; /* tag-20230327-1 */ /* Do an integrity check of the B-Tree ** @@ -140287,7 +138433,7 @@ SQLITE_PRIVATE void sqlite3Pragma( aRoot[0] = cnt; /* Make sure sufficient number of registers have been allocated */ - sqlite3TouchRegister(pParse, 8+mxIdx); + pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ @@ -140437,29 +138583,15 @@ SQLITE_PRIVATE void sqlite3Pragma( labelOk = sqlite3VdbeMakeLabel(pParse); if( pCol->notNull ){ /* (1) NOT NULL columns may not contain a NULL */ - int jmp3; int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + sqlite3VdbeChangeP5(v, 0x0f); VdbeCoverage(v); - if( p1<0 ){ - sqlite3VdbeChangeP5(v, 0x0f); /* INT, REAL, TEXT, or BLOB */ - jmp3 = jmp2; - }else{ - sqlite3VdbeChangeP5(v, 0x0d); /* INT, TEXT, or BLOB */ - /* OP_IsType does not detect NaN values in the database file - ** which should be treated as a NULL. So if the header type - ** is REAL, we have to load the actual data using OP_Column - ** to reliably determine if the value is a NULL. */ - sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); - jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); - VdbeCoverage(v); - } zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pCol->zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); if( doTypeCheck ){ sqlite3VdbeGoto(v, labelError); sqlite3VdbeJumpHere(v, jmp2); - sqlite3VdbeJumpHere(v, jmp3); }else{ /* VDBE byte code will fall thru */ } @@ -140567,7 +138699,7 @@ SQLITE_PRIVATE void sqlite3Pragma( int jmp7; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur+j, 3); jmp7 = sqlite3VdbeAddOp3(v, OP_Eq, 3, 0, r1+pIdx->nColumn-1); - VdbeCoverageNeverNull(v); + VdbeCoverage(v); sqlite3VdbeLoadString(v, 3, "rowid not at end-of-record for row "); sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); @@ -140949,7 +139081,7 @@ SQLITE_PRIVATE void sqlite3Pragma( Schema *pSchema; /* The current schema */ Table *pTab; /* A table in the schema */ Index *pIdx; /* An index of the table */ - LogEst szThreshold; /* Size threshold above which reanalysis needed */ + LogEst szThreshold; /* Size threshold above which reanalysis is needd */ char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ u32 opMask; /* Mask of operations to perform */ @@ -141773,9 +139905,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl #else encoding = SQLITE_UTF8; #endif - if( db->nVdbeActive>0 && encoding!=ENC(db) - && (db->mDbFlags & DBFLAG_Vacuum)==0 - ){ + if( db->nVdbeActive>0 && encoding!=ENC(db) ){ rc = SQLITE_LOCKED; goto initone_error_out; }else{ @@ -142075,7 +140205,7 @@ SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ ** immediately. ** ** Use this mechanism for uncommon cleanups. There is a higher setup -** cost for this mechanism (an extra malloc), so it should not be used +** cost for this mechansim (an extra malloc), so it should not be used ** for common cleanups that happen on most calls. But for less ** common cleanups, we save a single NULL-pointer comparison in ** sqlite3ParseObjectReset(), which reduces the total CPU cycle count. @@ -142167,18 +140297,9 @@ static int sqlite3Prepare( sParse.pOuterParse = db->pParse; db->pParse = &sParse; sParse.db = db; - if( pReprepare ){ - sParse.pReprepare = pReprepare; - sParse.explain = sqlite3_stmt_isexplain((sqlite3_stmt*)pReprepare); - }else{ - assert( sParse.pReprepare==0 ); - } + sParse.pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); - if( db->mallocFailed ){ - sqlite3ErrorMsg(&sParse, "out of memory"); - db->errCode = rc = SQLITE_NOMEM; - goto end_prepare; - } + if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory"); assert( sqlite3_mutex_held(db->mutex) ); /* For a long-term use prepared statement avoid the use of @@ -142782,7 +140903,7 @@ static Select *findRightmost(Select *p){ ** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT ** ** To preserve historical compatibly, SQLite also accepts a variety -** of other non-standard and in many cases nonsensical join types. +** of other non-standard and in many cases non-sensical join types. ** This routine makes as much sense at it can from the nonsense join ** type and returns a result. Examples of accepted nonsense join types ** include but are not limited to: @@ -143053,7 +141174,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; - /* If this is a NATURAL join, synthesize an appropriate USING clause + /* If this is a NATURAL join, synthesize an approprate USING clause ** to specify which columns should be joined. */ if( pRight->fg.jointype & JT_NATURAL ){ @@ -143267,9 +141388,9 @@ static void pushOntoSorter( ** (2) All output columns are included in the sort record. In that ** case regData==regOrigData. ** (3) Some output columns are omitted from the sort record due to - ** the SQLITE_ENABLE_SORTER_REFERENCES optimization, or due to the + ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the ** SQLITE_ECEL_OMITREF optimization, or due to the - ** SortCtx.pDeferredRowLoad optimization. In any of these cases + ** SortCtx.pDeferredRowLoad optimiation. In any of these cases ** regOrigData is 0 to prevent this routine from trying to copy ** values that might not yet exist. */ @@ -143325,7 +141446,7 @@ static void pushOntoSorter( testcase( pKI->nAllField > pKI->nKeyField+2 ); pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, pKI->nAllField-pKI->nKeyField-1); - pOp = 0; /* Ensure pOp not used after sqlite3VdbeAddOp3() */ + pOp = 0; /* Ensure pOp not used after sqltie3VdbeAddOp3() */ addrJmp = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); @@ -143419,7 +141540,7 @@ static void codeOffset( ** The returned value in this case is a copy of parameter iTab. ** ** WHERE_DISTINCT_ORDERED: -** In this case rows are being delivered sorted order. The ephemeral +** In this case rows are being delivered sorted order. The ephermal ** table is not required. Instead, the current set of values ** is compared against previous row. If they match, the new row ** is not distinct and control jumps to VM address addrRepeat. Otherwise, @@ -144651,6 +142772,13 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames( int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */ int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */ +#ifndef SQLITE_OMIT_EXPLAIN + /* If this is an EXPLAIN, skip this step */ + if( pParse->explain ){ + return; + } +#endif + if( pParse->colNamesSet ) return; /* Column names are determined by the left-most term of a compound select */ while( pSelect->pPrior ) pSelect = pSelect->pPrior; @@ -144837,7 +142965,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( ** kind (maybe a parenthesized subquery in the FROM clause of a larger ** query, or a VIEW, or a CTE). This routine computes type information ** for that Table object based on the Select object that implements the -** subquery. For the purposes of this routine, "type information" means: +** subquery. For the purposes of this routine, "type infomation" means: ** ** * The datatype name, as it might appear in a CREATE TABLE statement ** * Which collating sequence to use for the column @@ -144861,7 +142989,7 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( assert( (pSelect->selFlags & SF_Resolved)!=0 ); assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); - if( db->mallocFailed || IN_RENAME_OBJECT ) return; + if( db->mallocFailed ) return; while( pSelect->pPrior ) pSelect = pSelect->pPrior; a = pSelect->pEList->a; memset(&sNC, 0, sizeof(sNC)); @@ -144906,16 +143034,18 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( break; } } - } - } - if( zType ){ - i64 m = sqlite3Strlen30(zType); - n = sqlite3Strlen30(pCol->zCnName); - pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); - pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); - if( pCol->zCnName ){ - memcpy(&pCol->zCnName[n+1], zType, m+1); - pCol->colFlags |= COLFLAG_HASTYPE; + } + } + if( zType ){ + i64 m = sqlite3Strlen30(zType); + n = sqlite3Strlen30(pCol->zCnName); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); + if( pCol->zCnName ){ + memcpy(&pCol->zCnName[n+1], zType, m+1); + pCol->colFlags |= COLFLAG_HASTYPE; + }else{ + testcase( pCol->colFlags & COLFLAG_HASTYPE ); + pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); } } pColl = sqlite3ExprCollSeq(pParse, p); @@ -145166,7 +143296,7 @@ static void generateWithRecursiveQuery( int iQueue; /* The Queue table */ int iDistinct = 0; /* To ensure unique results if UNION */ int eDest = SRT_Fifo; /* How to write to Queue */ - SelectDest destQueue; /* SelectDest targeting the Queue table */ + SelectDest destQueue; /* SelectDest targetting the Queue table */ int i; /* Loop counter */ int rc; /* Result code */ ExprList *pOrderBy; /* The ORDER BY clause */ @@ -145766,7 +143896,7 @@ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ /* ** Code an output subroutine for a coroutine implementation of a -** SELECT statement. +** SELECT statment. ** ** The data to be output is contained in pIn->iSdst. There are ** pIn->nSdst columns to be output. pDest is where the output should @@ -145988,7 +144118,7 @@ static int generateOutputSubroutine( ** ** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not ** actually called using Gosub and they do not Return. EofA and EofB loop -** until all data is exhausted then jump to the "end" label. AltB, AeqB, +** until all data is exhausted then jump to the "end" labe. AltB, AeqB, ** and AgtB jump to either L2 or to one of EofA or EofB. */ #ifndef SQLITE_OMIT_COMPOUND_SELECT @@ -146025,7 +144155,7 @@ static int multiSelectOrderBy( int savedOffset; /* Saved value of p->iOffset */ int labelCmpr; /* Label for the start of the merge algorithm */ int labelEnd; /* Label for the end of the overall SELECT stmt */ - int addr1; /* Jump instructions that get retargeted */ + int addr1; /* Jump instructions that get retargetted */ int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ KeyInfo *pKeyMerge; /* Comparison information for merging rows */ @@ -146394,14 +144524,11 @@ static Expr *substExpr( #endif { Expr *pNew; - int iColumn; - Expr *pCopy; + int iColumn = pExpr->iColumn; + Expr *pCopy = pSubst->pEList->a[iColumn].pExpr; Expr ifNullRow; - iColumn = pExpr->iColumn; - assert( iColumn>=0 ); assert( pSubst->pEList!=0 && iColumnpEList->nExpr ); assert( pExpr->pRight==0 ); - pCopy = pSubst->pEList->a[iColumn].pExpr; if( sqlite3ExprIsVector(pCopy) ){ sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ @@ -146750,7 +144877,7 @@ static int compoundHasDifferentAffinities(Select *p){ ** (9) If the subquery uses LIMIT then the outer query may not be aggregate. ** ** (**) Restriction (10) was removed from the code on 2005-02-05 but we -** accidentally carried the comment forward until 2014-09-15. Original +** accidently carried the comment forward until 2014-09-15. Original ** constraint: "If the subquery is aggregate then the outer query ** may not use LIMIT." ** @@ -146785,7 +144912,8 @@ static int compoundHasDifferentAffinities(Select *p){ ** query or there are no RIGHT or FULL JOINs in any arm ** of the subquery. (This is a duplicate of condition (27b).) ** (17h) The corresponding result set expressions in all arms of the -** compound must have the same affinity. +** compound must have the same affinity. (See restriction (9) +** on the push-down optimization.) ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, @@ -147024,7 +145152,7 @@ static int flattenSubquery( testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; - /* Delete the transient structures associated with the subquery */ + /* Delete the transient structures associated with thesubquery */ pSub1 = pSubitem->pSelect; sqlite3DbFree(db, pSubitem->zDatabase); sqlite3DbFree(db, pSubitem->zName); @@ -147206,7 +145334,7 @@ static int flattenSubquery( ** ORDER BY column expression is identical to the iOrderByCol'th ** expression returned by SELECT statement pSub. Since these values ** do not necessarily correspond to columns in SELECT statement pParent, - ** zero them before transferring the ORDER BY clause. + ** zero them before transfering 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 @@ -147266,7 +145394,8 @@ static int flattenSubquery( } } - /* Finally, delete what is left of the subquery and return success. + /* Finially, delete what is left of the subquery and return + ** success. */ sqlite3AggInfoPersistWalkerInit(&w, pParse); sqlite3WalkSelect(&w,pSub1); @@ -147301,7 +145430,7 @@ 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. +** pColumn entires. Also, do not add if doing so would not be appropriate. ** ** The caller guarantees the pColumn is a column and pValue is a constant. ** This routine has to do some additional checks before completing the @@ -147487,7 +145616,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ ** SELECT * FROM t1 WHERE a=123 AND b=123; ** ** The two SELECT statements above should return different answers. b=a -** is always true because the comparison uses numeric affinity, but b=123 +** is alway true because the comparison uses numeric affinity, but b=123 ** is false because it uses text affinity and '0123' is not the same as '123'. ** To work around this, the expression tree is not actually changed from ** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol @@ -147571,7 +145700,7 @@ static int propagateConstants( ** At the time this function is called it is guaranteed that ** ** * the sub-query uses only one distinct window frame, and -** * that the window frame has a PARTITION BY clause. +** * that the window frame has a PARTITION BY clase. */ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ assert( pSubq->pWin->pPartition ); @@ -147652,24 +145781,10 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** or EXCEPT, then all of the result set columns for all arms of ** the compound must use the BINARY collating sequence. ** -** (9) All three of the following are true: +** (9) If the subquery is a compound, then all arms of the compound must +** have the same affinity. (This is the same as restriction (17h) +** for query flattening.) ** -** (9a) The WHERE clause expression originates in the ON or USING clause -** of a join (either an INNER or an OUTER join), and -** -** (9b) The subquery is to the right of the ON/USING clause -** -** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING -** clause and the subquery. -** -** Without this restriction, the push-down optimization might move -** the ON/USING filter expression from the left side of a RIGHT JOIN -** over to the right side, which leads to incorrect answers. See -** also restriction (6) in sqlite3ExprIsSingleTableConstraint(). -** -** (10) The inner query is not the right-hand table of a RIGHT JOIN. -** -** (11) The subquery is not a VALUES clause ** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. @@ -147678,20 +145793,13 @@ static int pushDownWhereTerms( Parse *pParse, /* Parse context (for malloc() and error reporting) */ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ Expr *pWhere, /* The WHERE clause of the outer query */ - SrcList *pSrcList, /* The complete from clause of the outer query */ - int iSrc /* Which FROM clause term to try to push into */ + SrcItem *pSrc /* The subquery term of the outer FROM clause */ ){ Expr *pNew; - SrcItem *pSrc; /* The subquery FROM term into which WHERE is pushed */ int nChng = 0; - pSrc = &pSrcList->a[iSrc]; if( pWhere==0 ) return 0; - if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ){ - return 0; /* restrictions (2) and (11) */ - } - if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ){ - return 0; /* restrictions (10) */ - } + if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; + if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0; if( pSubq->pPrior ){ Select *pSel; @@ -147707,6 +145815,9 @@ static int pushDownWhereTerms( if( pSel->pWin ) return 0; /* restriction (6b) */ #endif } + if( compoundHasDifferentAffinities(pSubq) ){ + return 0; /* restriction (9) */ + } if( notUnionAll ){ /* If any of the compound arms are connected using UNION, INTERSECT, ** or EXCEPT, then we must ensure that none of the columns use a @@ -147746,28 +145857,11 @@ static int pushDownWhereTerms( return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrcList, iSrc); + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc); pWhere = pWhere->pLeft; } -#if 0 /* These checks now done by sqlite3ExprIsSingleTableConstraint() */ - if( ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) /* (9a) */ - && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (9c) */ - ){ - int jj; - for(jj=0; jjw.iJoin==pSrcList->a[jj].iCursor ){ - /* If we reach this point, both (9a) and (9b) are satisfied. - ** The following loop checks (9c): - */ - for(jj++; jja[jj].fg.jointype & JT_RIGHT)!=0 ){ - return 0; /* restriction (9) */ - } - } - } - } - } +#if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */ if( isLeftJoin && (ExprHasProperty(pWhere,EP_OuterON)==0 || pWhere->w.iJoin!=iCursor) @@ -147781,7 +145875,7 @@ static int pushDownWhereTerms( } #endif - if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){ + if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ @@ -147815,78 +145909,6 @@ static int pushDownWhereTerms( } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ -/* -** Check to see if a subquery contains result-set columns that are -** never used. If it does, change the value of those result-set columns -** to NULL so that they do not cause unnecessary work to compute. -** -** Return the number of column that were changed to NULL. -*/ -static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ - int nCol; - Select *pSub; /* The subquery to be simplified */ - Select *pX; /* For looping over compound elements of pSub */ - Table *pTab; /* The table that describes the subquery */ - int j; /* Column number */ - int nChng = 0; /* Number of columns converted to NULL */ - Bitmask colUsed; /* Columns that may not be NULLed out */ - - assert( pItem!=0 ); - if( pItem->fg.isCorrelated || pItem->fg.isCte ){ - return 0; - } - assert( pItem->pTab!=0 ); - pTab = pItem->pTab; - assert( pItem->pSelect!=0 ); - pSub = pItem->pSelect; - assert( pSub->pEList->nExpr==pTab->nCol ); - if( (pSub->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ - testcase( pSub->selFlags & SF_Distinct ); - testcase( pSub->selFlags & SF_Aggregate ); - return 0; - } - for(pX=pSub; pX; pX=pX->pPrior){ - if( pX->pPrior && pX->op!=TK_ALL ){ - /* This optimization does not work for compound subqueries that - ** use UNION, INTERSECT, or EXCEPT. Only UNION ALL is allowed. */ - return 0; - } -#ifndef SQLITE_OMIT_WINDOWFUNC - if( pX->pWin ){ - /* This optimization does not work for subqueries that use window - ** functions. */ - return 0; - } -#endif - } - colUsed = pItem->colUsed; - if( pSub->pOrderBy ){ - ExprList *pList = pSub->pOrderBy; - for(j=0; jnExpr; j++){ - u16 iCol = pList->a[j].u.x.iOrderByCol; - if( iCol>0 ){ - iCol--; - colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); - } - } - } - nCol = pTab->nCol; - for(j=0; jpPrior) { - Expr *pY = pX->pEList->a[j].pExpr; - if( pY->op==TK_NULL ) continue; - pY->op = TK_NULL; - ExprClearProperty(pY, EP_Skip|EP_Unlikely); - pX->selFlags |= SF_PushDown; - nChng++; - } - } - return nChng; -} - - /* ** The pFunc is the only aggregate function in the query. Check to see ** if the query is a candidate for the min/max optimization. @@ -148651,16 +146673,10 @@ static int selectExpander(Walker *pWalker, Select *p){ ** expanded. */ int tableSeen = 0; /* Set to 1 when TABLE matches */ char *zTName = 0; /* text of name of TABLE */ - int iErrOfst; if( pE->op==TK_DOT ){ assert( pE->pLeft!=0 ); assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); zTName = pE->pLeft->u.zToken; - assert( ExprUseWOfst(pE->pLeft) ); - iErrOfst = pE->pRight->w.iOfst; - }else{ - assert( ExprUseWOfst(pE) ); - iErrOfst = pE->w.iOfst; } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab = pFrom->pTab; /* Table for this data source */ @@ -148697,7 +146713,6 @@ static int selectExpander(Walker *pWalker, Select *p){ for(ii=0; iinId; ii++){ const char *zUName = pUsing->a[ii].zName; pRight = sqlite3Expr(db, TK_ID, zUName); - sqlite3ExprSetErrorOffset(pRight, iErrOfst); pNew = sqlite3ExprListAppend(pParse, pNew, pRight); if( pNew ){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; @@ -148770,7 +146785,6 @@ static int selectExpander(Walker *pWalker, Select *p){ }else{ pExpr = pRight; } - sqlite3ExprSetErrorOffset(pExpr, iErrOfst); pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); if( pNew==0 ){ break; /* OOM */ @@ -149041,13 +147055,12 @@ static void optimizeAggregateUseOfIndexedExpr( assert( pSelect->pGroupBy!=0 ); pAggInfo->nColumn = pAggInfo->nAccumulator; if( ALWAYS(pAggInfo->nSortingColumn>0) ){ - int mx = pSelect->pGroupBy->nExpr - 1; - int j, k; - for(j=0; jnColumn; j++){ - k = pAggInfo->aCol[j].iSorterColumn; - if( k>mx ) mx = k; + if( pAggInfo->nColumn==0 ){ + pAggInfo->nSortingColumn = pSelect->pGroupBy->nExpr; + }else{ + pAggInfo->nSortingColumn = + pAggInfo->aCol[pAggInfo->nColumn-1].iSorterColumn+1; } - pAggInfo->nSortingColumn = mx+1; } analyzeAggFuncArgs(pAggInfo, pNC); #if TREETRACE_ENABLED @@ -149081,13 +147094,11 @@ static int aggregateIdxEprRefToColCallback(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue; if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue; pAggInfo = pExpr->pAggInfo; - if( NEVER(pExpr->iAgg>=pAggInfo->nColumn) ) return WRC_Continue; - assert( pExpr->iAgg>=0 ); + assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); pCol = &pAggInfo->aCol[pExpr->iAgg]; pExpr->op = TK_AGG_COLUMN; pExpr->iTable = pCol->iTable; pExpr->iColumn = pCol->iColumn; - ExprClearProperty(pExpr, EP_Skip|EP_Collate|EP_Unlikely); return WRC_Prune; } @@ -149118,7 +147129,7 @@ static void aggregateConvertIndexedExprRefToColumn(AggInfo *pAggInfo){ ** * The aCol[] and aFunc[] arrays may be modified ** * The AggInfoColumnReg() and AggInfoFuncReg() macros may not be used ** -** After calling this routine: +** After clling this routine: ** ** * The aCol[] and aFunc[] arrays are fixed ** * The AggInfoColumnReg() and AggInfoFuncReg() macros may be used @@ -149441,6 +147452,7 @@ static void agginfoFree(sqlite3 *db, AggInfo *p){ sqlite3DbFreeNN(db, p); } +#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION /* ** Attempt to transform a query of the form ** @@ -149468,7 +147480,6 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ if( p->pWhere ) return 0; - if( p->pHaving ) return 0; if( p->pGroupBy ) return 0; if( p->pOrderBy ) return 0; pExpr = p->pEList->a[0].pExpr; @@ -149488,8 +147499,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( pSub->pWhere ) return 0; /* No WHERE clause */ if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ - assert( pSub->pHaving==0 ); /* Due to the previous */ - pSub = pSub->pPrior; /* Repeat over compound */ + pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); /* If we reach this point then it is OK to perform the transformation */ @@ -149532,6 +147542,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ #endif return 1; } +#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */ /* ** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same @@ -149772,59 +147783,22 @@ SQLITE_PRIVATE int sqlite3Select( ** to a real table */ assert( pTab!=0 ); - /* Try to simplify joins: - ** - ** LEFT JOIN -> JOIN - ** RIGHT JOIN -> JOIN - ** FULL JOIN -> RIGHT JOIN - ** - ** If terms of the i-th table are used in the WHERE clause in such a - ** way that the i-th table cannot be the NULL row of a join, then - ** perform the appropriate simplification. This is called - ** "OUTER JOIN strength reduction" in the SQLite documentation. + /* Convert LEFT JOIN into JOIN if there are terms of the right table + ** of the LEFT JOIN used in the WHERE clause. */ - if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 - && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, - pItem->fg.jointype & JT_LTORJ) + if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT + && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) && OptimizationEnabled(db, SQLITE_SimplifyJoin) ){ - if( pItem->fg.jointype & JT_LEFT ){ - if( pItem->fg.jointype & JT_RIGHT ){ - TREETRACE(0x1000,pParse,p, - ("FULL-JOIN simplifies to RIGHT-JOIN on term %d\n",i)); - pItem->fg.jointype &= ~JT_LEFT; - }else{ - TREETRACE(0x1000,pParse,p, - ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); - pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); - } - } - if( pItem->fg.jointype & JT_LTORJ ){ - for(j=i+1; jnSrc; j++){ - SrcItem *pI2 = &pTabList->a[j]; - if( pI2->fg.jointype & JT_RIGHT ){ - if( pI2->fg.jointype & JT_LEFT ){ - TREETRACE(0x1000,pParse,p, - ("FULL-JOIN simplifies to LEFT-JOIN on term %d\n",j)); - pI2->fg.jointype &= ~JT_RIGHT; - }else{ - TREETRACE(0x1000,pParse,p, - ("RIGHT-JOIN simplifies to JOIN on term %d\n",j)); - pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER); - } - } - } - for(j=pTabList->nSrc-1; j>=i; j--){ - pTabList->a[j].fg.jointype &= ~JT_LTORJ; - if( pTabList->a[j].fg.jointype & JT_RIGHT ) break; - } - } + TREETRACE(0x1000,pParse,p, + ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); + pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); assert( pItem->iCursor>=0 ); unsetJoinExpr(p->pWhere, pItem->iCursor, pTabList->a[0].fg.jointype & JT_LTORJ); } - /* No further action if this term of the FROM clause is not a subquery */ + /* No futher action if this term of the FROM clause is no a subquery */ if( pSub==0 ) continue; /* Catch mismatch in the declared columns of a view and the number of @@ -149957,12 +147931,14 @@ SQLITE_PRIVATE int sqlite3Select( TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); } +#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) && countOfViewOptimization(pParse, p) ){ if( db->mallocFailed ) goto select_end; pTabList = p->pSrc; } +#endif /* For each term in the FROM clause, do two things: ** (1) Authorized unreferenced tables @@ -150021,7 +147997,7 @@ SQLITE_PRIVATE int sqlite3Select( if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) - && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x4000 ){ @@ -150035,22 +148011,6 @@ SQLITE_PRIVATE int sqlite3Select( TREETRACE(0x4000,pParse,p,("Push-down not possible\n")); } - /* Convert unused result columns of the subquery into simple NULL - ** expressions, to avoid unneeded searching and computation. - */ - if( OptimizationEnabled(db, SQLITE_NullUnusedCols) - && disableUnusedSubqueryResultColumns(pItem) - ){ -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x4000 ){ - TREETRACE(0x4000,pParse,p, - ("Change unused result columns to NULL for subquery %d:\n", - pSub->selId)); - sqlite3TreeViewSelect(0, p, 0); - } -#endif - } - zSavedAuthContext = pParse->zAuthContext; pParse->zAuthContext = pItem->zName; @@ -150078,7 +148038,7 @@ SQLITE_PRIVATE int sqlite3Select( }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ /* This is a CTE for which materialization code has already been ** generated. Invoke the subroutine to compute the materialization, - ** the make the pItem->iCursor be a copy of the ephemeral table that + ** the make the pItem->iCursor be a copy of the ephemerial table that ** holds the result of the materialization. */ CteUse *pCteUse = pItem->u2.pCteUse; sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); @@ -150461,7 +148421,7 @@ SQLITE_PRIVATE int sqlite3Select( */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ - int addr1; /* A-vs-B comparison jump */ + int addr1; /* A-vs-B comparision jump */ int addrOutputRow; /* Start of subroutine that outputs a result row */ int regOutputRow; /* Return address register for output subroutine */ int addrSetAbort; /* Set the abort flag and return */ @@ -150552,13 +148512,9 @@ SQLITE_PRIVATE int sqlite3Select( int nCol; int nGroupBy; -#ifdef SQLITE_ENABLE_STMT_SCANSTATUS - int addrExp; /* Address of OP_Explain instruction */ -#endif - ExplainQueryPlan2(addrExp, (pParse, 0, "USE TEMP B-TREE FOR %s", + explainTempTable(pParse, (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? - "DISTINCT" : "GROUP BY" - )); + "DISTINCT" : "GROUP BY"); groupBySort = 1; nGroupBy = pGroupBy->nExpr; @@ -150583,23 +148539,18 @@ SQLITE_PRIVATE int sqlite3Select( } pAggInfo->directMode = 0; regRecord = sqlite3GetTempReg(pParse); - sqlite3VdbeScanStatusCounters(v, addrExp, 0, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); - sqlite3VdbeScanStatusRange(v, addrExp, sqlite3VdbeCurrentAddr(v)-2, -1); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); TREETRACE(0x2,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); - sqlite3VdbeScanStatusCounters(v, addrExp, sqlite3VdbeCurrentAddr(v), 0); sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); pAggInfo->useSortingIdx = 1; - sqlite3VdbeScanStatusRange(v, addrExp, -1, sortPTab); - sqlite3VdbeScanStatusRange(v, addrExp, -1, pAggInfo->sortingIdx); } /* If there are entries in pAgggInfo->aFunc[] that contain subexpressions @@ -152597,9 +150548,6 @@ SQLITE_PRIVATE u32 sqlite3TriggerColmask( Trigger *p; assert( isNew==1 || isNew==0 ); - if( IsView(pTab) ){ - return 0xffffffff; - } for(p=pTrigger; p; p=p->pNext){ if( p->op==op && (tr_tm&p->tr_tm) @@ -152850,7 +150798,7 @@ static void updateFromSelect( assert( pTabList->nSrc>1 ); if( pSrc ){ - assert( pSrc->a[0].fg.notCte ); + pSrc->a[0].fg.notCte = 1; pSrc->a[0].iCursor = -1; pSrc->a[0].pTab->nTabRef--; pSrc->a[0].pTab = 0; @@ -153034,7 +150982,7 @@ SQLITE_PRIVATE void sqlite3Update( if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto update_cleanup; } - if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ goto update_cleanup; } @@ -153450,8 +151398,6 @@ SQLITE_PRIVATE void sqlite3Update( if( !isView ){ int addrOnce = 0; - int iNotUsed1 = 0; - int iNotUsed2 = 0; /* Open every index that needs updating. */ if( eOnePass!=ONEPASS_OFF ){ @@ -153463,7 +151409,7 @@ SQLITE_PRIVATE void sqlite3Update( addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, - aToOpen, &iNotUsed1, &iNotUsed2); + aToOpen, 0, 0); if( addrOnce ){ sqlite3VdbeJumpHereOrPopInst(v, addrOnce); } @@ -153754,10 +151700,8 @@ SQLITE_PRIVATE void sqlite3Update( sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } - if( pTrigger ){ - sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, - TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); - } + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); /* Repeat the above with the next record to be updated, until ** all record selected by the WHERE clause have been updated. @@ -153852,7 +151796,7 @@ static void updateVirtualTable( int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */ int regArg; /* First register in VUpdate arg array */ int regRec; /* Register in which to assemble record */ - int regRowid; /* Register for ephemeral table rowid */ + int regRowid; /* Register for ephem table rowid */ int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ int eOnePass; /* True to use onepass strategy */ @@ -153973,7 +151917,7 @@ static void updateVirtualTable( sqlite3WhereEnd(pWInfo); } - /* Begin scanning through the ephemeral table. */ + /* Begin scannning through the ephemeral table. */ addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); /* Extract arguments from the current row of the ephemeral table and @@ -154530,7 +152474,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** - ** An optimization would be to use a non-journaled pager. + ** An optimisation would be to use a non-journaled pager. ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but ** that actually made the VACUUM run slower. Very little journalling ** actually occurs when doing a vacuum since the vacuum_db is initially @@ -155220,7 +153164,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ ** the information we've collected. ** ** The VM register number pParse->regRowid holds the rowid of an - ** entry in the sqlite_schema table that was created for this vtab + ** entry in the sqlite_schema table tht was created for this vtab ** by sqlite3StartTable(). */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -155841,10 +153785,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ break; } if( xMethod && pVTab->iSavepoint>iSavepoint ){ - u64 savedFlags = (db->flags & SQLITE_Defensive); - db->flags &= ~(u64)SQLITE_Defensive; rc = xMethod(pVTab->pVtab, iSavepoint); - db->flags |= savedFlags; } sqlite3VtabUnlock(pVTab); } @@ -155964,7 +153905,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ ** ** An eponymous virtual table instance is one that is named after its ** module, and more importantly, does not require a CREATE VIRTUAL TABLE -** statement in order to come into existence. Eponymous virtual table +** statement in order to come into existance. Eponymous virtual table ** instances always exist. They cannot be DROP-ed. ** ** Any virtual table module for which xConnect and xCreate are the same @@ -156073,10 +154014,6 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ p->pVTable->eVtabRisk = SQLITE_VTABRISK_High; break; } - case SQLITE_VTAB_USES_ALL_SCHEMAS: { - p->pVTable->bAllSchemas = 1; - break; - } default: { rc = SQLITE_MISUSE_BKPT; break; @@ -156155,7 +154092,7 @@ typedef struct WhereRightJoin WhereRightJoin; /* ** This object is a header on a block of allocated memory that will be -** automatically freed when its WInfo object is destructed. +** automatically freed when its WInfo oject is destructed. */ struct WhereMemBlock { WhereMemBlock *pNext; /* Next block in the chain */ @@ -156216,7 +154153,7 @@ struct WhereLevel { int iCur; /* The VDBE cursor used by this IN operator */ int addrInTop; /* Top of the IN loop */ int iBase; /* Base register of multi-key index record */ - int nPrefix; /* Number of prior entries in the key */ + int nPrefix; /* Number of prior entires in the key */ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ @@ -156466,7 +154403,7 @@ struct WhereClause { int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ int nBase; /* Number of terms through the last non-Virtual */ - WhereTerm *a; /* Each a[] describes a term of the WHERE clause */ + WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ #if defined(SQLITE_SMALL_STACK) WhereTerm aStatic[1]; /* Initial static space for a[] */ #else @@ -156850,9 +154787,9 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ /* ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN -** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG -** was defined at compile-time. If it is not a no-op, a single OP_Explain -** opcode is added to the output to describe the table scan strategy in pLevel. +** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was +** defined at compile-time. If it is not a no-op, a single OP_Explain opcode +** is added to the output to describe the table scan strategy in pLevel. ** ** If an OP_Explain opcode is added to the VM, its address is returned. ** Otherwise, if no OP_Explain is coded, zero is returned. @@ -156864,8 +154801,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ int ret = 0; -#if !defined(SQLITE_DEBUG) - if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( sqlite3ParseToplevel(pParse)->explain==2 ) #endif { SrcItem *pItem = &pTabList->a[pLevel->iFrom]; @@ -157031,35 +154968,27 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( WhereLevel *pLvl, /* Level to add scanstatus() entry for */ int addrExplain /* Address of OP_Explain (or 0) */ ){ - if( IS_STMT_SCANSTATUS( sqlite3VdbeDb(v) ) ){ - const char *zObj = 0; - WhereLoop *pLoop = pLvl->pWLoop; - int wsFlags = pLoop->wsFlags; - int viaCoroutine = 0; + const char *zObj = 0; + WhereLoop *pLoop = pLvl->pWLoop; + int wsFlags = pLoop->wsFlags; + int viaCoroutine = 0; - if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ - zObj = pLoop->u.btree.pIndex->zName; - }else{ - zObj = pSrclist->a[pLvl->iFrom].zName; - viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine; - } - sqlite3VdbeScanStatus( - v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj - ); + if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ + zObj = pLoop->u.btree.pIndex->zName; + }else{ + zObj = pSrclist->a[pLvl->iFrom].zName; + viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine; + } + sqlite3VdbeScanStatus( + v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj + ); - if( viaCoroutine==0 ){ - if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ - sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); - } - if( wsFlags & WHERE_INDEXED ){ - sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); - } - }else{ - int addr = pSrclist->a[pLvl->iFrom].addrFillSub; - VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); - assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); - assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); - sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); + if( viaCoroutine==0 ){ + if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ + sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); + } + if( wsFlags & WHERE_INDEXED ){ + sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); } } } @@ -157557,7 +155486,7 @@ static int codeAllEqualityTerms( /* Figure out how many memory cells we will need then allocate them. */ regBase = pParse->nMem + 1; - nReg = nEq + nExtraReg; + nReg = pLoop->u.btree.nEq + nExtraReg; pParse->nMem += nReg; zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); @@ -157604,6 +155533,9 @@ static int codeAllEqualityTerms( sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); } } + } + for(j=nSkip; jaLTerm[j]; if( pTerm->eOperator & WO_IN ){ if( pTerm->pExpr->flags & EP_xIsSelect ){ /* No affinity ever needs to be (or should be) applied to a value @@ -157746,19 +155678,18 @@ static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ ** 2) transform the expression node to a TK_REGISTER node that reads ** from the newly populated register. ** -** Also, if the node is a TK_COLUMN that does access the table identified +** Also, if the node is a TK_COLUMN that does access the table idenified ** by pCCurHint.iTabCur, and an index is being used (which we will ** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into ** an access of the index rather than the original table. */ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ int rc = WRC_Continue; - int reg; struct CCurHint *pHint = pWalker->u.pCCurHint; if( pExpr->op==TK_COLUMN ){ if( pExpr->iTable!=pHint->iTabCur ){ - reg = ++pWalker->pParse->nMem; /* Register for column value */ - reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); + int reg = ++pWalker->pParse->nMem; /* Register for column value */ + sqlite3ExprCode(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ @@ -157766,15 +155697,15 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); assert( pExpr->iColumn>=0 ); } - }else if( pExpr->pAggInfo ){ + }else if( pExpr->op==TK_AGG_FUNCTION ){ + /* An aggregate function in the WHERE clause of a query means this must + ** be a correlated sub-query, and expression pExpr is an aggregate from + ** the parent context. Do not walk the function arguments in this case. + ** + ** todo: It should be possible to replace this node with a TK_REGISTER + ** expression, as the result of the expression must be stored in a + ** register at this point. The same holds for TK_AGG_COLUMN nodes. */ rc = WRC_Prune; - reg = ++pWalker->pParse->nMem; /* Register for column value */ - reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); - pExpr->op = TK_REGISTER; - pExpr->iTable = reg; - }else if( pExpr->op==TK_TRUEFALSE ){ - /* Do not walk disabled expressions. tag-20230504-1 */ - return WRC_Prune; } return rc; } @@ -157876,7 +155807,7 @@ static void codeCursorHint( } if( pExpr!=0 ){ sWalker.xExprCallback = codeCursorHintFixExpr; - if( pParse->nErr==0 ) sqlite3WalkExpr(&sWalker, pExpr); + sqlite3WalkExpr(&sWalker, pExpr); sqlite3VdbeAddOp4(v, OP_CursorHint, (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, (const char*)pExpr, P4_EXPR); @@ -158364,7 +156295,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( }; assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ - assert( TK_GE==TK_GT+3 ); /* ... is correct. */ + assert( TK_GE==TK_GT+3 ); /* ... is correcct. */ assert( (pStart->wtFlags & TERM_VNULL)==0 ); testcase( pStart->wtFlags & TERM_VIRTUAL ); @@ -158670,7 +156601,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** guess. */ addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, (pIdx->aiRowLogEst[0]+9)/10); - if( pRangeStart || pRangeEnd ){ + if( pRangeStart ){ sqlite3VdbeChangeP5(v, 1); sqlite3VdbeChangeP2(v, addrSeekScan, sqlite3VdbeCurrentAddr(v)+1); addrSeekScan = 0; @@ -158711,7 +156642,16 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( assert( pLevel->p2==0 ); if( pRangeEnd ){ Expr *pRight = pRangeEnd->pExpr->pRight; - assert( addrSeekScan==0 ); + if( addrSeekScan ){ + /* For a seek-scan that has a range on the lowest term of the index, + ** we have to make the top of the loop be code that sets the end + ** condition of the range. Otherwise, the OP_SeekScan might jump + ** over that initialization, leaving the range-end value set to the + ** range-start value, resulting in a wrong answer. + ** See ticket 5981a8c041a3c2f3 (2021-11-02). + */ + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + } codeExprOrVector(pParse, pRight, regBase+nEq, nTop); whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 @@ -158745,7 +156685,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( zEndAff ) sqlite3DbNNFreeNN(db, zEndAff); /* Top of the loop body */ - pLevel->p2 = sqlite3VdbeCurrentAddr(v); + if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ @@ -159544,7 +157484,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( ** the WHERE clause of SQL statements. ** ** This file was originally part of where.c but was split out to improve -** readability and editability. This file contains utility routines for +** readability and editabiliity. This file contains utility routines for ** analyzing Expr objects in the WHERE clause. */ /* #include "sqliteInt.h" */ @@ -159760,7 +157700,7 @@ static int isLikeOrGlob( ** range search. The third is because the caller assumes that the pattern ** consists of at least one character after all escapes have been ** removed. */ - if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ + if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ @@ -160333,7 +158273,7 @@ static void exprAnalyzeOrTerm( pOrTerm->leftCursor))==0 ){ /* This term must be of the form t1.a==t2.b where t2 is in the ** chngToIN set but t1 is not. This term will be either preceded - ** or followed by an inverted copy (t2.b==t1.a). Skip this term + ** or follwed by an inverted copy (t2.b==t1.a). Skip this term ** and use its inversion. */ testcase( pOrTerm->wtFlags & TERM_COPIED ); testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); @@ -160595,8 +158535,8 @@ static void exprAnalyze( WhereTerm *pTerm; /* The term to be analyzed */ WhereMaskSet *pMaskSet; /* Set of table index masks */ Expr *pExpr; /* The expression to be analyzed */ - Bitmask prereqLeft; /* Prerequisites of the pExpr->pLeft */ - Bitmask prereqAll; /* Prerequisites of pExpr */ + Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */ + Bitmask prereqAll; /* Prerequesites of pExpr */ Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ @@ -160742,7 +158682,7 @@ static void exprAnalyze( && 0==sqlite3ExprCanBeNull(pLeft) ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); - pExpr->op = TK_TRUEFALSE; /* See tag-20230504-1 */ + pExpr->op = TK_TRUEFALSE; pExpr->u.zToken = "false"; ExprSetProperty(pExpr, EP_IsFalse); pTerm->prereqAll = 0; @@ -161387,12 +159327,9 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( pRhs = sqlite3PExpr(pParse, TK_UPLUS, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); - if( pItem->fg.jointype & (JT_LEFT|JT_RIGHT) ){ - testcase( pItem->fg.jointype & JT_LEFT ); /* testtag-20230227a */ - testcase( pItem->fg.jointype & JT_RIGHT ); /* testtag-20230227b */ + if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){ joinType = EP_OuterON; }else{ - testcase( pItem->fg.jointype & JT_LTORJ ); /* testtag-20230227c */ joinType = EP_InnerON; } sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType); @@ -162235,7 +160172,7 @@ static void explainAutomaticIndex( int bPartial, /* True if pIdx is a partial index */ int *pAddrExplain /* OUT: Address of OP_Explain */ ){ - if( IS_STMT_SCANSTATUS(pParse->db) && pParse->explain!=2 ){ + if( pParse->explain!=2 ){ Table *pTab = pIdx->pTable; const char *zSep = ""; char *zText = 0; @@ -162274,7 +160211,8 @@ static void explainAutomaticIndex( */ static SQLITE_NOINLINE void constructAutomaticIndex( Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ + const WhereClause *pWC, /* The WHERE clause */ + const SrcItem *pSrc, /* The FROM clause term to get the next index */ const Bitmask notReady, /* Mask of cursors that are not available */ WhereLevel *pLevel /* Write new index here */ ){ @@ -162295,12 +160233,10 @@ static SQLITE_NOINLINE void constructAutomaticIndex( char *zNotUsed; /* Extra space on the end of pIdx */ 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 sentWarning = 0; /* True if a warnning has been issued */ Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ - SrcList *pTabList; /* The complete FROM clause */ - SrcItem *pSrc; /* The FROM clause term to get the next index */ + SrcItem *pTabItem; /* FROM clause term being indexed */ int addrCounter = 0; /* Address where integer counter is initialized */ int regBase; /* Array of registers where record is assembled */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -162316,8 +160252,6 @@ static SQLITE_NOINLINE void constructAutomaticIndex( /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ nKeyCol = 0; - pTabList = pWC->pWInfo->pTabList; - pSrc = &pTabList->a[pLevel->iFrom]; pTable = pSrc->pTab; pWCEnd = &pWC->a[pWC->nTerm]; pLoop = pLevel->pWLoop; @@ -162328,7 +160262,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** WHERE clause (or the ON clause of a LEFT join) that constrain which ** rows of the target table (pSrc) that can be used. */ if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom) + && sqlite3ExprIsTableConstraint(pExpr, pSrc) ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); @@ -162369,11 +160303,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** original table changes and the index and table cannot both be used ** if they go out of sync. */ - if( IsView(pTable) ){ - extraCols = ALLBITS; - }else{ - extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); - } + extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); mxBitCol = MIN(BMS-1,pTable->nCol); testcase( pTable->nCol==BMS-1 ); testcase( pTable->nCol==BMS-2 ); @@ -162409,16 +160339,6 @@ static SQLITE_NOINLINE void constructAutomaticIndex( assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ 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; - } } } } @@ -162451,21 +160371,20 @@ static SQLITE_NOINLINE void constructAutomaticIndex( sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "for %s", pTable->zName)); - if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) && useBloomFilter ){ - sqlite3WhereExplainBloomFilter(pParse, pWC->pWInfo, pLevel); + if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ pLevel->regFilter = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); } /* Fill the automatic index with content */ - assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); - if( pSrc->fg.viaCoroutine ){ - int regYield = pSrc->regReturn; + pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; + if( pTabItem->fg.viaCoroutine ){ + int regYield = pTabItem->regReturn; addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); VdbeCoverage(v); - VdbeComment((v, "next row of %s", pSrc->pTab->zName)); + VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); }else{ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } @@ -162486,14 +160405,14 @@ static SQLITE_NOINLINE void constructAutomaticIndex( sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); - if( pSrc->fg.viaCoroutine ){ + if( pTabItem->fg.viaCoroutine ){ sqlite3VdbeChangeP2(v, addrCounter, regBase+n); testcase( pParse->db->mallocFailed ); assert( pLevel->iIdxCur>0 ); translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, - pSrc->regResult, pLevel->iIdxCur); + pTabItem->regResult, pLevel->iIdxCur); sqlite3VdbeGoto(v, addrTop); - pSrc->fg.viaCoroutine = 0; + pTabItem->fg.viaCoroutine = 0; }else{ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); @@ -162556,11 +160475,9 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); do{ - const SrcList *pTabList; const SrcItem *pItem; const Table *pTab; u64 sz; - int iSrc; sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel); addrCont = sqlite3VdbeMakeLabel(pParse); iCur = pLevel->iTabCur; @@ -162574,9 +160491,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( ** testing complicated. By basing the blob size on the value in the ** sqlite_stat1 table, testing is much easier. */ - pTabList = pWInfo->pTabList; - iSrc = pLevel->iFrom; - pItem = &pTabList->a[iSrc]; + pItem = &pWInfo->pTabList->a[pLevel->iFrom]; assert( pItem!=0 ); pTab = pItem->pTab; assert( pTab!=0 ); @@ -162593,7 +160508,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( for(pTerm=pWInfo->sWC.a; pTermpExpr; if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc) + && sqlite3ExprIsTableConstraint(pExpr, pItem) ){ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); } @@ -162897,9 +160812,6 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); } } - if( pTab->u.vtab.p->bAllSchemas ){ - sqlite3VtabUsesAllSchemas(pParse); - } sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = 0; return rc; @@ -163157,7 +161069,7 @@ SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCo ** Value pLoop->nOut is currently set to the estimated number of rows ** visited for scanning (a=? AND b=?). This function reduces that estimate ** by some factor to account for the (c BETWEEN ? AND ?) expression based -** on the stat4 data for the index. this scan will be performed multiple +** on the stat4 data for the index. this scan will be peformed multiple ** times (once for each (a,b) combination that matches a=?) is dealt with ** by the caller. ** @@ -163430,7 +161342,7 @@ static int whereRangeScanEst( UNUSED_PARAMETER(pBuilder); assert( pLower || pUpper ); #endif - assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 || pParse->nErr>0 ); + assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 ); nNew = whereRangeAdjust(pLower, nOut); nNew = whereRangeAdjust(pUpper, nNew); @@ -163912,7 +161824,7 @@ static WhereLoop **whereLoopFindLesser( ** rSetup. Call this SETUP-INVARIANT */ assert( p->rSetup>=pTemplate->rSetup ); - /* Any loop using an application-defined index (or PRIMARY KEY or + /* Any loop using an appliation-defined index (or PRIMARY KEY or ** UNIQUE constraint) with one or more == constraints is better ** than an automatic index. Unless it is a skip-scan. */ if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 @@ -164057,7 +161969,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ }else{ /* We will be overwriting WhereLoop p[]. But before we do, first ** go through the rest of the list and delete any other entries besides - ** p[] that are also supplanted by pTemplate */ + ** p[] that are also supplated by pTemplate */ WhereLoop **ppTail = &p->pNextLoop; WhereLoop *pToDel; while( *ppTail ){ @@ -164257,7 +162169,7 @@ static int whereRangeVectorLen( } /* -** Adjust the cost C by the costMult factor T. This only occurs if +** Adjust the cost C by the costMult facter T. This only occurs if ** compiled with -DSQLITE_ENABLE_COSTMULT */ #ifdef SQLITE_ENABLE_COSTMULT @@ -164284,7 +162196,7 @@ static int whereLoopAddBtreeIndex( Index *pProbe, /* An index on pSrc */ LogEst nInMul /* log(Number of iterations due to IN) */ ){ - WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyze context */ + WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */ Parse *pParse = pWInfo->pParse; /* Parsing context */ sqlite3 *db = pParse->db; /* Database connection malloc context */ WhereLoop *pNew; /* Template WhereLoop under construction */ @@ -164594,7 +162506,7 @@ static int whereLoopAddBtreeIndex( assert( pSrc->pTab->szTabRow>0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* The pProbe->szIdxRow is low for an IPK table since the interior - ** pages are small. Thus szIdxRow gives a good estimate of seek cost. + ** pages are small. Thuse szIdxRow gives a good estimate of seek cost. ** But the leaf pages are full-size, so pProbe->szIdxRow would badly ** under-estimate the scanning cost. */ rCostIdx = pNew->nOut + 16; @@ -164939,7 +162851,7 @@ static SQLITE_NOINLINE u32 whereIsCoveringIndex( */ static int whereLoopAddBtree( WhereLoopBuilder *pBuilder, /* WHERE clause information */ - Bitmask mPrereq /* Extra prerequisites for using this table */ + Bitmask mPrereq /* Extra prerequesites for using this table */ ){ WhereInfo *pWInfo; /* WHERE analysis context */ Index *pProbe; /* An index we are evaluating */ @@ -165446,7 +163358,7 @@ static int whereLoopAddVirtualOne( ** ** Return a pointer to the collation name: ** -** 1. If there is an explicit COLLATE operator on the constraint, return it. +** 1. If there is an explicit COLLATE operator on the constaint, return it. ** ** 2. Else, if the column has an alternative collation, return that. ** @@ -165531,6 +163443,8 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ return pHidden->eDistinct; } +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** Cause the prepared statement that is associated with a call to ** xBestIndex to potentially use all schemas. If the statement being @@ -165540,7 +163454,9 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ ** ** This is used by the (built-in) sqlite_dbpage virtual table. */ -SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse *pParse){ +SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + Parse *pParse = pHidden->pParse; int nDb = pParse->db->nDb; int i; for(i=0; iwsFlags & WHERE_VIEWSCAN)!=0 && nLoop>1 ){ + if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 ){ rCost += -10; nOut += -30; - WHERETRACE(0x80,("VIEWSCAN cost reduction for %c\n",pWLoop->cId)); } /* Check to see if pWLoop should be added to the set of @@ -166933,13 +164849,6 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ ** at most a single row. ** 4) The table must not be referenced by any part of the query apart ** from its own USING or ON clause. -** 5) The table must not have an inner-join ON or USING clause if there is -** a RIGHT JOIN anywhere in the query. Otherwise the ON/USING clause -** might move from the right side to the left side of the RIGHT JOIN. -** Note: Due to (2), this condition can only arise if the table is -** the right-most table of a subquery that was flattened into the -** main query and that subquery was the right-hand operand of an -** inner join that held an ON or USING clause. ** ** For example, given: ** @@ -166965,7 +164874,6 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( ){ int i; Bitmask tabUsed; - int hasRightJoin; /* Preconditions checked by the caller */ assert( pWInfo->nLevel>=2 ); @@ -166980,7 +164888,6 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( if( pWInfo->pOrderBy ){ tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); } - hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0; for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; SrcItem *pItem; @@ -167003,12 +164910,6 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( break; } } - if( hasRightJoin - && ExprHasProperty(pTerm->pExpr, EP_InnerON) - && pTerm->pExpr->w.iJoin==pItem->iCursor - ){ - break; /* restriction (5) */ - } } if( pTerm drop loop %c not used\n", pLoop->cId)); @@ -167219,7 +165120,7 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( ** ** OUTER JOINS ** -** An outer join of tables t1 and t2 is conceptually coded as follows: +** An outer join of tables t1 and t2 is conceptally coded as follows: ** ** foreach row1 in t1 do ** flag = 0 @@ -167374,7 +165275,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** ** The N-th term of the FROM clause is assigned a bitmask of 1<nErr ) goto whereBeginError; - /* The False-WHERE-Term-Bypass optimization: + /* Special case: WHERE terms that do not refer to any tables in the join + ** (constant expressions). Evaluate each such term, and jump over all the + ** generated code if the result is not true. ** - ** If there are WHERE terms that are false, then no rows will be output, - ** so skip over all of the code generated here. + ** Do not do this if the expression contains non-deterministic functions + ** that are not within a sub-select. This is not strictly required, but + ** preserves SQLite's legacy behaviour in the following two cases: ** - ** Conditions: - ** - ** (1) The WHERE term must not refer to any tables in the join. - ** (2) The term must not come from an ON clause on the - ** right-hand side of a LEFT or FULL JOIN. - ** (3) The term must not come from an ON clause, or there must be - ** no RIGHT or FULL OUTER joins in pTabList. - ** (4) If the expression contains non-deterministic functions - ** that are not within a sub-select. This is not required - ** for correctness but rather to preserves SQLite's legacy - ** behaviour in the following two cases: - ** - ** WHERE random()>0; -- eval random() once per row - ** WHERE (SELECT random())>0; -- eval random() just once overall - ** - ** Note that the Where term need not be a constant in order for this - ** optimization to apply, though it does need to be constant relative to - ** the current subquery (condition 1). The term might include variables - ** from outer queries so that the value of the term changes from one - ** invocation of the current subquery to the next. + ** FROM ... WHERE random()>0; -- eval random() once per row + ** FROM ... WHERE (SELECT random())>0; -- eval random() once overall */ for(ii=0; iinBase; ii++){ - WhereTerm *pT = &sWLB.pWC->a[ii]; /* A term of the WHERE clause */ - Expr *pX; /* The expression of pT */ + WhereTerm *pT = &sWLB.pWC->a[ii]; if( pT->wtFlags & TERM_VIRTUAL ) continue; - pX = pT->pExpr; - assert( pX!=0 ); - assert( pT->prereqAll!=0 || !ExprHasProperty(pX, EP_OuterON) ); - if( pT->prereqAll==0 /* Conditions (1) and (2) */ - && (nTabList==0 || exprIsDeterministic(pX)) /* Condition (4) */ - && !(ExprHasProperty(pX, EP_InnerON) /* Condition (3) */ - && (pTabList->a[0].fg.jointype & JT_LTORJ)!=0 ) - ){ - sqlite3ExprIfFalse(pParse, pX, pWInfo->iBreak, SQLITE_JUMPIFNULL); + if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){ + sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL); pT->wtFlags |= TERM_CODED; } } @@ -167689,7 +165567,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( assert( n<=pTab->nCol ); } #ifdef SQLITE_ENABLE_CURSOR_HINTS - if( pLoop->u.btree.pIndex!=0 && (pTab->tabFlags & TF_WithoutRowid)==0 ){ + if( pLoop->u.btree.pIndex!=0 ){ sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); }else #endif @@ -167826,11 +165704,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( sqlite3VdbeJumpHere(v, iOnce); } } - assert( pTabList == pWInfo->pTabList ); if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ #ifndef SQLITE_OMIT_AUTOMATIC_INDEX - constructAutomaticIndex(pParse, &pWInfo->sWC, notReady, pLevel); + constructAutomaticIndex(pParse, &pWInfo->sWC, + &pTabList->a[pLevel->iFrom], notReady, pLevel); #endif }else{ sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady); @@ -168147,8 +166025,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ k = pLevel->addrBody + 1; #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeAddopTrace ){ - printf("TRANSLATE cursor %d->%d in opcode range %d..%d\n", - pLevel->iTabCur, pLevel->iIdxCur, k, last-1); + printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); } /* Proof that the "+1" on the k value above is safe */ pOp = sqlite3VdbeGetOp(v, k - 1); @@ -168355,7 +166232,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ** ** These are the same built-in window functions supported by Postgres. ** Although the behaviour of aggregate window functions (functions that -** can be used as either aggregates or window functions) allows them to +** can be used as either aggregates or window funtions) allows them to ** be implemented using an API, built-in window functions are much more ** esoteric. Additionally, some window functions (e.g. nth_value()) ** may only be implemented by caching the entire partition in memory. @@ -168885,7 +166762,7 @@ static Window *windowFind(Parse *pParse, Window *pList, const char *zName){ ** is the Window object representing the associated OVER clause. This ** function updates the contents of pWin as follows: ** -** * If the OVER clause referred to a named window (as in "max(x) OVER win"), +** * If the OVER clause refered to a named window (as in "max(x) OVER win"), ** search list pList for a matching WINDOW definition, and update pWin ** accordingly. If no such WINDOW clause can be found, leave an error ** in pParse. @@ -169023,7 +166900,6 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ } /* no break */ deliberate_fall_through - case TK_IF_NULL_ROW: case TK_AGG_FUNCTION: case TK_COLUMN: { int iCol = -1; @@ -169506,7 +167382,7 @@ SQLITE_PRIVATE Window *sqlite3WindowAssemble( } /* -** Window *pWin has just been created from a WINDOW clause. Token pBase +** Window *pWin has just been created from a WINDOW clause. Tokne pBase ** is the base window. Earlier windows from the same WINDOW clause are ** stored in the linked list starting at pWin->pNextWin. This function ** either updates *pWin according to the base specification, or else @@ -169812,7 +167688,7 @@ struct WindowCsrAndReg { ** ** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING) ** -** The windows functions implementation caches the input rows in a temp +** The windows functions implmentation caches the input rows in a temp ** table, sorted by "a, b" (it actually populates the cache lazily, and ** aggressively removes rows once they are no longer required, but that's ** a mere detail). It keeps three cursors open on the temp table. One @@ -170821,7 +168697,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** For the most part, the patterns above are adapted to support UNBOUNDED by ** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and -** CURRENT ROW by assuming that it is equivalent to "0 PRECEDING/FOLLOWING". +** CURRENT ROW by assuming that it is equivilent to "0 PRECEDING/FOLLOWING". ** This is optimized of course - branches that will never be taken and ** conditions that are always true are omitted from the VM code. The only ** exceptional case is: @@ -171100,7 +168976,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( } /* Allocate registers for the array of values from the sub-query, the - ** same values in record form, and the rowid used to insert said record + ** samve values in record form, and the rowid used to insert said record ** into the ephemeral table. */ regNew = pParse->nMem+1; pParse->nMem += nInput; @@ -171341,10 +169217,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( /************** End of window.c **********************************************/ /************** Begin file parse.c *******************************************/ /* This file is automatically generated by Lemon from input grammar -** source file "parse.y" with these options: -** -** -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -*/ +** source file "parse.y". */ /* ** 2001-09-15 ** @@ -171361,7 +169234,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( ** The canonical source code to this file ("parse.y") is a Lemon grammar ** file that specifies the input grammar and actions to take while parsing. ** That input file is processed by Lemon to generate a C-language -** implementation of a parser for the given grammar. You might be reading +** implementation of a parser for the given grammer. You might be reading ** this comment as part of the translated C-code. Edits should be made ** to the original parse.y sources. */ @@ -171863,18 +169736,18 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 579 -#define YYNRULE 403 -#define YYNRULE_WITH_ACTION 338 +#define YYNSTATE 580 +#define YYNRULE 405 +#define YYNRULE_WITH_ACTION 342 #define YYNTOKEN 186 -#define YY_MAX_SHIFT 578 -#define YY_MIN_SHIFTREDUCE 837 -#define YY_MAX_SHIFTREDUCE 1239 -#define YY_ERROR_ACTION 1240 -#define YY_ACCEPT_ACTION 1241 -#define YY_NO_ACTION 1242 -#define YY_MIN_REDUCE 1243 -#define YY_MAX_REDUCE 1645 +#define YY_MAX_SHIFT 579 +#define YY_MIN_SHIFTREDUCE 839 +#define YY_MAX_SHIFTREDUCE 1243 +#define YY_ERROR_ACTION 1244 +#define YY_ACCEPT_ACTION 1245 +#define YY_NO_ACTION 1246 +#define YY_MIN_REDUCE 1247 +#define YY_MAX_REDUCE 1651 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -171941,217 +169814,217 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2086) +#define YY_ACTTAB_COUNT (2087) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 572, 1314, 572, 1293, 208, 208, 572, 1276, 478, 572, - /* 10 */ 1190, 1314, 392, 572, 118, 115, 229, 406, 412, 413, - /* 20 */ 381, 278, 278, 41, 41, 41, 41, 271, 1210, 71, - /* 30 */ 71, 973, 41, 41, 569, 1524, 71, 71, 279, 974, - /* 40 */ 303, 9, 303, 262, 125, 126, 80, 1214, 1214, 1051, - /* 50 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 413, - /* 60 */ 1241, 1, 1, 578, 2, 1245, 554, 547, 1331, 1190, - /* 70 */ 317, 495, 146, 554, 528, 118, 115, 229, 529, 1327, - /* 80 */ 569, 553, 382, 292, 125, 126, 80, 1214, 1214, 1051, - /* 90 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 118, + /* 0 */ 572, 1318, 572, 1297, 208, 208, 572, 1280, 478, 572, + /* 10 */ 1196, 1318, 392, 572, 118, 115, 229, 406, 412, 413, + /* 20 */ 381, 278, 278, 41, 41, 41, 41, 271, 1217, 71, + /* 30 */ 71, 975, 41, 41, 569, 1530, 71, 71, 279, 976, + /* 40 */ 303, 9, 303, 262, 125, 126, 80, 1221, 1221, 1054, + /* 50 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 413, + /* 60 */ 1245, 1, 1, 579, 2, 1249, 554, 547, 1335, 1196, + /* 70 */ 317, 495, 146, 554, 528, 118, 115, 229, 529, 1331, + /* 80 */ 569, 553, 382, 292, 125, 126, 80, 1221, 1221, 1054, + /* 90 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 118, /* 100 */ 115, 229, 122, 122, 122, 122, 121, 121, 120, 120, - /* 110 */ 120, 119, 116, 448, 284, 284, 421, 1190, 1191, 1190, - /* 120 */ 460, 1563, 380, 1565, 460, 379, 1161, 569, 1161, 413, - /* 130 */ 1563, 541, 145, 1190, 336, 101, 1210, 118, 115, 229, + /* 110 */ 120, 119, 116, 448, 284, 284, 421, 1196, 1197, 1198, + /* 120 */ 460, 1571, 380, 1573, 460, 379, 1167, 569, 1167, 413, + /* 130 */ 1571, 541, 145, 1196, 336, 101, 1217, 118, 115, 229, /* 140 */ 448, 240, 122, 122, 122, 122, 121, 121, 120, 120, - /* 150 */ 120, 119, 116, 448, 125, 126, 80, 1214, 1214, 1051, - /* 160 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 1038, - /* 170 */ 1038, 1052, 1055, 452, 453, 530, 1190, 1191, 1190, 127, - /* 180 */ 548, 548, 122, 122, 122, 122, 121, 121, 120, 120, - /* 190 */ 120, 119, 116, 448, 1558, 333, 148, 335, 6, 413, - /* 200 */ 1279, 124, 124, 124, 124, 117, 120, 120, 120, 119, + /* 150 */ 120, 119, 116, 448, 125, 126, 80, 1221, 1221, 1054, + /* 160 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 1041, + /* 170 */ 1041, 1055, 1058, 452, 453, 530, 1196, 1197, 1198, 127, + /* 180 */ 548, 1558, 122, 122, 122, 122, 121, 121, 120, 120, + /* 190 */ 120, 119, 116, 448, 1566, 333, 148, 335, 6, 413, + /* 200 */ 1283, 124, 124, 124, 124, 117, 120, 120, 120, 119, /* 210 */ 116, 448, 122, 122, 122, 122, 121, 121, 120, 120, - /* 220 */ 120, 119, 116, 448, 125, 126, 80, 1214, 1214, 1051, - /* 230 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 413, - /* 240 */ 1190, 1191, 1190, 1042, 83, 469, 346, 82, 122, 122, + /* 220 */ 120, 119, 116, 448, 125, 126, 80, 1221, 1221, 1054, + /* 230 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 413, + /* 240 */ 1196, 1197, 1198, 1045, 83, 469, 346, 82, 122, 122, /* 250 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 448, - /* 260 */ 197, 1433, 1190, 1278, 125, 126, 80, 1214, 1214, 1051, - /* 270 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 334, - /* 280 */ 377, 1190, 122, 122, 122, 122, 121, 121, 120, 120, - /* 290 */ 120, 119, 116, 448, 1602, 572, 118, 115, 229, 373, - /* 300 */ 1576, 1190, 1286, 124, 124, 124, 124, 285, 285, 413, + /* 260 */ 197, 1438, 1196, 1282, 125, 126, 80, 1221, 1221, 1054, + /* 270 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 334, + /* 280 */ 377, 1196, 122, 122, 122, 122, 121, 121, 120, 120, + /* 290 */ 120, 119, 116, 448, 1611, 572, 118, 115, 229, 373, + /* 300 */ 1584, 1196, 1290, 124, 124, 124, 124, 285, 285, 413, /* 310 */ 121, 121, 120, 120, 120, 119, 116, 448, 70, 70, /* 320 */ 569, 495, 122, 122, 122, 122, 121, 121, 120, 120, - /* 330 */ 120, 119, 116, 448, 125, 126, 80, 1214, 1214, 1051, - /* 340 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 208, + /* 330 */ 120, 119, 116, 448, 125, 126, 80, 1221, 1221, 1054, + /* 340 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 208, /* 350 */ 122, 122, 122, 122, 121, 121, 120, 120, 120, 119, - /* 360 */ 116, 448, 401, 526, 445, 444, 1523, 1190, 1156, 1190, - /* 370 */ 1191, 1190, 252, 316, 563, 508, 505, 504, 325, 544, - /* 380 */ 387, 1156, 224, 518, 1156, 503, 16, 16, 1190, 1191, - /* 390 */ 1190, 1551, 122, 122, 122, 122, 121, 121, 120, 120, - /* 400 */ 120, 119, 116, 448, 1582, 578, 2, 1245, 1190, 1191, - /* 410 */ 1190, 1222, 317, 1222, 146, 577, 413, 1245, 480, 1156, - /* 420 */ 360, 1327, 317, 85, 146, 1190, 1009, 1319, 1319, 1190, - /* 430 */ 537, 1327, 1156, 1190, 142, 1156, 572, 535, 190, 572, - /* 440 */ 214, 125, 126, 80, 1214, 1214, 1051, 1054, 1041, 1041, + /* 360 */ 116, 448, 401, 526, 445, 444, 1529, 1196, 1162, 1196, + /* 370 */ 1197, 1198, 252, 316, 563, 508, 505, 504, 325, 544, + /* 380 */ 387, 1162, 224, 518, 1162, 503, 16, 16, 1196, 1197, + /* 390 */ 1198, 1557, 122, 122, 122, 122, 121, 121, 120, 120, + /* 400 */ 120, 119, 116, 448, 1590, 579, 2, 1249, 1196, 1197, + /* 410 */ 1198, 1228, 317, 1228, 146, 578, 413, 1249, 480, 1162, + /* 420 */ 360, 1331, 317, 85, 146, 1196, 1011, 1323, 1323, 1196, + /* 430 */ 537, 1331, 1162, 1196, 142, 1162, 572, 535, 190, 572, + /* 440 */ 214, 125, 126, 80, 1221, 1221, 1054, 1057, 1044, 1044, /* 450 */ 123, 123, 124, 124, 124, 124, 284, 284, 222, 71, - /* 460 */ 71, 572, 13, 13, 445, 444, 284, 284, 1488, 569, - /* 470 */ 1608, 572, 377, 1219, 1190, 1191, 1190, 426, 1221, 569, - /* 480 */ 344, 1579, 521, 240, 71, 71, 1220, 478, 536, 1639, - /* 490 */ 399, 316, 563, 240, 51, 51, 533, 1317, 1317, 122, + /* 460 */ 71, 572, 13, 13, 445, 444, 284, 284, 1494, 569, + /* 470 */ 1617, 572, 377, 1225, 1196, 1197, 1198, 426, 1227, 569, + /* 480 */ 344, 1587, 521, 240, 71, 71, 1226, 478, 536, 1647, + /* 490 */ 399, 316, 563, 240, 51, 51, 533, 1321, 1321, 122, /* 500 */ 122, 122, 122, 121, 121, 120, 120, 120, 119, 116, - /* 510 */ 448, 1222, 423, 1222, 1267, 452, 550, 284, 284, 413, - /* 520 */ 154, 554, 142, 509, 574, 452, 574, 874, 939, 520, - /* 530 */ 569, 522, 1190, 1191, 1190, 149, 1190, 1191, 1190, 413, - /* 540 */ 1190, 1191, 1190, 878, 125, 126, 80, 1214, 1214, 1051, - /* 550 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 413, - /* 560 */ 1009, 458, 295, 871, 125, 126, 80, 1214, 1214, 1051, - /* 570 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 316, - /* 580 */ 563, 327, 98, 1550, 125, 126, 80, 1214, 1214, 1051, - /* 590 */ 1054, 1041, 1041, 123, 123, 124, 124, 124, 124, 566, + /* 510 */ 448, 1228, 423, 1228, 1271, 452, 550, 284, 284, 413, + /* 520 */ 154, 554, 142, 509, 575, 452, 575, 876, 941, 520, + /* 530 */ 569, 522, 1196, 1197, 1198, 149, 1196, 1197, 1198, 413, + /* 540 */ 1196, 1197, 1198, 880, 125, 126, 80, 1221, 1221, 1054, + /* 550 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 413, + /* 560 */ 1011, 458, 295, 873, 125, 126, 80, 1221, 1221, 1054, + /* 570 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 316, + /* 580 */ 563, 327, 98, 1556, 125, 126, 80, 1221, 1221, 1054, + /* 590 */ 1057, 1044, 1044, 123, 123, 124, 124, 124, 124, 566, /* 600 */ 566, 566, 122, 122, 122, 122, 121, 121, 120, 120, - /* 610 */ 120, 119, 116, 448, 344, 464, 330, 1556, 1028, 142, + /* 610 */ 120, 119, 116, 448, 344, 464, 330, 1563, 1031, 142, /* 620 */ 403, 6, 122, 122, 122, 122, 121, 121, 120, 120, - /* 630 */ 120, 119, 116, 448, 874, 1019, 934, 572, 516, 1018, - /* 640 */ 572, 933, 122, 122, 122, 122, 121, 121, 120, 120, + /* 630 */ 120, 119, 116, 448, 876, 1022, 936, 572, 516, 1021, + /* 640 */ 572, 935, 122, 122, 122, 122, 121, 121, 120, 120, /* 650 */ 120, 119, 116, 448, 252, 284, 284, 508, 505, 504, - /* 660 */ 13, 13, 413, 13, 13, 934, 1174, 503, 569, 1193, - /* 670 */ 933, 1018, 1018, 1020, 417, 431, 316, 563, 433, 446, - /* 680 */ 446, 446, 413, 484, 529, 476, 1029, 125, 126, 80, - /* 690 */ 1214, 1214, 1051, 1054, 1041, 1041, 123, 123, 124, 124, - /* 700 */ 124, 124, 413, 175, 482, 1028, 1014, 125, 126, 80, - /* 710 */ 1214, 1214, 1051, 1054, 1041, 1041, 123, 123, 124, 124, - /* 720 */ 124, 124, 1019, 1352, 311, 457, 1018, 125, 126, 80, - /* 730 */ 1214, 1214, 1051, 1054, 1041, 1041, 123, 123, 124, 124, + /* 660 */ 13, 13, 413, 13, 13, 936, 1180, 503, 569, 1200, + /* 670 */ 935, 1021, 1021, 1023, 417, 431, 316, 563, 433, 446, + /* 680 */ 446, 446, 413, 484, 529, 476, 1032, 125, 126, 80, + /* 690 */ 1221, 1221, 1054, 1057, 1044, 1044, 123, 123, 124, 124, + /* 700 */ 124, 124, 413, 175, 482, 1031, 1016, 125, 126, 80, + /* 710 */ 1221, 1221, 1054, 1057, 1044, 1044, 123, 123, 124, 124, + /* 720 */ 124, 124, 1022, 1356, 311, 457, 1021, 125, 126, 80, + /* 730 */ 1221, 1221, 1054, 1057, 1044, 1044, 123, 123, 124, 124, /* 740 */ 124, 124, 423, 457, 456, 122, 122, 122, 122, 121, - /* 750 */ 121, 120, 120, 120, 119, 116, 448, 489, 1018, 1018, - /* 760 */ 1020, 486, 527, 854, 290, 122, 122, 122, 122, 121, - /* 770 */ 121, 120, 120, 120, 119, 116, 448, 1193, 571, 572, + /* 750 */ 121, 120, 120, 120, 119, 116, 448, 489, 1021, 1021, + /* 760 */ 1023, 486, 527, 856, 290, 122, 122, 122, 122, 121, + /* 770 */ 121, 120, 120, 120, 119, 116, 448, 1200, 571, 572, /* 780 */ 97, 530, 294, 572, 100, 122, 122, 122, 122, 121, /* 790 */ 121, 120, 120, 120, 119, 116, 448, 284, 284, 284, - /* 800 */ 284, 483, 13, 13, 572, 413, 13, 13, 1432, 531, - /* 810 */ 569, 206, 569, 1156, 259, 226, 457, 302, 519, 519, - /* 820 */ 1557, 200, 467, 6, 6, 413, 1156, 133, 133, 1156, - /* 830 */ 125, 126, 80, 1214, 1214, 1051, 1054, 1041, 1041, 123, - /* 840 */ 123, 124, 124, 124, 124, 413, 373, 1576, 1190, 478, - /* 850 */ 125, 126, 80, 1214, 1214, 1051, 1054, 1041, 1041, 123, - /* 860 */ 123, 124, 124, 124, 124, 1073, 570, 1190, 928, 928, - /* 870 */ 125, 126, 80, 1214, 1214, 1051, 1054, 1041, 1041, 123, - /* 880 */ 123, 124, 124, 124, 124, 885, 1493, 1190, 122, 122, + /* 800 */ 284, 483, 13, 13, 572, 413, 13, 13, 1437, 531, + /* 810 */ 569, 206, 569, 1162, 259, 226, 457, 302, 519, 1565, + /* 820 */ 1564, 200, 467, 6, 6, 413, 1162, 133, 133, 1162, + /* 830 */ 125, 126, 80, 1221, 1221, 1054, 1057, 1044, 1044, 123, + /* 840 */ 123, 124, 124, 124, 124, 413, 373, 1584, 1196, 478, + /* 850 */ 125, 126, 80, 1221, 1221, 1054, 1057, 1044, 1044, 123, + /* 860 */ 123, 124, 124, 124, 124, 1077, 570, 1196, 930, 930, + /* 870 */ 125, 126, 80, 1221, 1221, 1054, 1057, 1044, 1044, 123, + /* 880 */ 123, 124, 124, 124, 124, 887, 1499, 1196, 122, 122, /* 890 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 448, - /* 900 */ 191, 423, 572, 1480, 1493, 1495, 378, 495, 122, 122, + /* 900 */ 191, 423, 572, 1486, 1499, 1501, 378, 495, 122, 122, /* 910 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 448, - /* 920 */ 1098, 1098, 492, 572, 298, 71, 71, 1114, 122, 122, + /* 920 */ 1102, 1102, 492, 572, 298, 71, 71, 1118, 122, 122, /* 930 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 448, - /* 940 */ 572, 1190, 1115, 572, 495, 104, 13, 13, 495, 572, - /* 950 */ 532, 555, 1487, 1297, 32, 1190, 1191, 1190, 1116, 1419, + /* 940 */ 572, 1196, 1119, 572, 495, 104, 13, 13, 495, 572, + /* 950 */ 532, 555, 1493, 1301, 32, 1196, 1197, 1198, 1120, 1423, /* 960 */ 572, 201, 312, 71, 71, 107, 71, 71, 572, 500, - /* 970 */ 207, 478, 71, 71, 1190, 1191, 1190, 1493, 914, 119, - /* 980 */ 116, 448, 961, 13, 13, 413, 284, 284, 915, 1326, - /* 990 */ 209, 71, 71, 1322, 1190, 1191, 1190, 256, 549, 569, - /* 1000 */ 554, 960, 495, 313, 1607, 413, 903, 1093, 556, 443, - /* 1010 */ 125, 126, 80, 1214, 1214, 1051, 1054, 1041, 1041, 123, + /* 970 */ 207, 478, 71, 71, 1196, 1197, 1198, 1499, 916, 119, + /* 980 */ 116, 448, 963, 13, 13, 413, 284, 284, 917, 1330, + /* 990 */ 209, 71, 71, 1326, 1196, 1197, 1198, 256, 549, 569, + /* 1000 */ 554, 962, 495, 313, 1616, 413, 905, 1097, 556, 443, + /* 1010 */ 125, 126, 80, 1221, 1221, 1054, 1057, 1044, 1044, 123, /* 1020 */ 123, 124, 124, 124, 124, 413, 175, 12, 447, 428, - /* 1030 */ 125, 114, 80, 1214, 1214, 1051, 1054, 1041, 1041, 123, - /* 1040 */ 123, 124, 124, 124, 124, 129, 300, 351, 1190, 1191, - /* 1050 */ 1190, 126, 80, 1214, 1214, 1051, 1054, 1041, 1041, 123, - /* 1060 */ 123, 124, 124, 124, 124, 418, 227, 1190, 122, 122, + /* 1030 */ 125, 114, 80, 1221, 1221, 1054, 1057, 1044, 1044, 123, + /* 1040 */ 123, 124, 124, 124, 124, 129, 300, 351, 1196, 1197, + /* 1050 */ 1198, 126, 80, 1221, 1221, 1054, 1057, 1044, 1044, 123, + /* 1060 */ 123, 124, 124, 124, 124, 418, 227, 1196, 122, 122, /* 1070 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 448, - /* 1080 */ 5, 363, 281, 572, 959, 299, 100, 1325, 122, 122, + /* 1080 */ 5, 363, 281, 572, 961, 299, 100, 1329, 122, 122, /* 1090 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 448, - /* 1100 */ 203, 398, 1235, 572, 1263, 468, 135, 135, 122, 122, + /* 1100 */ 203, 398, 1241, 572, 1267, 468, 135, 135, 122, 122, /* 1110 */ 122, 122, 121, 121, 120, 120, 120, 119, 116, 448, /* 1120 */ 284, 284, 284, 284, 469, 346, 55, 55, 413, 410, - /* 1130 */ 409, 437, 12, 569, 523, 569, 364, 1156, 1190, 284, - /* 1140 */ 284, 545, 545, 386, 1137, 1637, 6, 1637, 557, 572, - /* 1150 */ 1156, 3, 569, 1156, 1419, 80, 1214, 1214, 1051, 1054, - /* 1160 */ 1041, 1041, 123, 123, 124, 124, 124, 124, 449, 284, - /* 1170 */ 284, 543, 56, 56, 1190, 1191, 1190, 228, 111, 564, - /* 1180 */ 1236, 4, 569, 284, 284, 1137, 1638, 1534, 1638, 1267, - /* 1190 */ 542, 398, 1136, 1210, 1555, 567, 569, 1419, 6, 1167, - /* 1200 */ 459, 1265, 959, 842, 843, 844, 377, 511, 262, 377, + /* 1130 */ 409, 437, 12, 569, 523, 569, 364, 1162, 1196, 284, + /* 1140 */ 284, 545, 1565, 386, 1141, 1645, 6, 1645, 557, 572, + /* 1150 */ 1162, 3, 569, 1162, 1423, 80, 1221, 1221, 1054, 1057, + /* 1160 */ 1044, 1044, 123, 123, 124, 124, 124, 124, 449, 284, + /* 1170 */ 284, 543, 56, 56, 1196, 1197, 1198, 228, 111, 564, + /* 1180 */ 1242, 4, 569, 284, 284, 1141, 1646, 1540, 1646, 1271, + /* 1190 */ 542, 398, 1140, 1217, 1562, 567, 569, 1423, 6, 1173, + /* 1200 */ 459, 1269, 961, 844, 845, 846, 377, 511, 262, 377, /* 1210 */ 485, 122, 122, 122, 122, 121, 121, 120, 120, 120, - /* 1220 */ 119, 116, 448, 1135, 429, 434, 572, 1114, 449, 572, + /* 1220 */ 119, 116, 448, 1139, 429, 434, 572, 1118, 449, 572, /* 1230 */ 561, 270, 287, 372, 514, 367, 513, 257, 111, 564, - /* 1240 */ 142, 4, 1115, 363, 1536, 1190, 1191, 1190, 894, 15, - /* 1250 */ 15, 1167, 43, 43, 157, 567, 454, 153, 1116, 1028, - /* 1260 */ 572, 1532, 572, 375, 1135, 109, 109, 441, 8, 572, - /* 1270 */ 1236, 572, 484, 110, 377, 449, 573, 449, 560, 512, - /* 1280 */ 1018, 320, 572, 57, 57, 44, 44, 895, 316, 563, - /* 1290 */ 561, 1419, 58, 58, 59, 59, 484, 316, 563, 1268, - /* 1300 */ 419, 1210, 432, 358, 539, 60, 60, 572, 375, 538, - /* 1310 */ 321, 866, 1018, 1018, 1020, 1021, 27, 1550, 572, 1028, - /* 1320 */ 1550, 572, 155, 1095, 151, 109, 109, 1095, 572, 113, - /* 1330 */ 61, 61, 572, 110, 572, 449, 573, 449, 324, 572, - /* 1340 */ 1018, 62, 62, 435, 45, 45, 572, 440, 255, 254, - /* 1350 */ 253, 46, 46, 233, 1419, 47, 47, 49, 49, 490, - /* 1360 */ 572, 430, 50, 50, 353, 1364, 356, 565, 419, 63, - /* 1370 */ 63, 343, 1018, 1018, 1020, 1021, 27, 1581, 1178, 451, - /* 1380 */ 572, 547, 288, 64, 64, 1550, 97, 396, 396, 395, - /* 1390 */ 273, 393, 1554, 973, 851, 301, 6, 572, 1230, 959, - /* 1400 */ 449, 974, 572, 65, 65, 256, 572, 234, 572, 323, - /* 1410 */ 111, 564, 30, 4, 572, 531, 572, 322, 572, 866, + /* 1240 */ 142, 4, 1119, 363, 1542, 1196, 1197, 1198, 896, 15, + /* 1250 */ 15, 1173, 43, 43, 157, 567, 454, 153, 1120, 1031, + /* 1260 */ 572, 1538, 572, 375, 1139, 109, 109, 441, 8, 572, + /* 1270 */ 1242, 572, 484, 110, 377, 449, 574, 573, 560, 512, + /* 1280 */ 1021, 320, 572, 57, 57, 44, 44, 897, 316, 563, + /* 1290 */ 561, 1423, 58, 58, 59, 59, 484, 316, 563, 1272, + /* 1300 */ 419, 1217, 432, 358, 539, 60, 60, 572, 375, 538, + /* 1310 */ 321, 868, 1021, 1021, 1023, 1024, 27, 1556, 572, 1031, + /* 1320 */ 1556, 572, 155, 1099, 151, 109, 109, 1099, 572, 113, + /* 1330 */ 61, 61, 572, 110, 572, 449, 574, 573, 324, 572, + /* 1340 */ 1021, 62, 62, 435, 45, 45, 572, 440, 255, 254, + /* 1350 */ 253, 46, 46, 233, 1423, 47, 47, 49, 49, 490, + /* 1360 */ 572, 430, 50, 50, 353, 1368, 356, 565, 419, 63, + /* 1370 */ 63, 343, 1021, 1021, 1023, 1024, 27, 1589, 1184, 451, + /* 1380 */ 572, 547, 288, 64, 64, 1556, 97, 396, 396, 395, + /* 1390 */ 273, 393, 1561, 975, 853, 301, 6, 572, 1236, 961, + /* 1400 */ 449, 976, 572, 65, 65, 256, 572, 234, 572, 323, + /* 1410 */ 111, 564, 30, 4, 572, 531, 572, 322, 572, 868, /* 1420 */ 14, 14, 572, 449, 491, 66, 66, 567, 572, 131, /* 1430 */ 131, 132, 132, 111, 564, 222, 4, 67, 67, 52, /* 1440 */ 52, 68, 68, 572, 31, 69, 69, 236, 572, 550, - /* 1450 */ 567, 53, 53, 293, 572, 168, 1209, 293, 141, 572, - /* 1460 */ 893, 892, 561, 572, 420, 177, 163, 163, 283, 226, + /* 1450 */ 567, 53, 53, 293, 572, 168, 1216, 293, 141, 572, + /* 1460 */ 895, 894, 561, 572, 420, 177, 163, 163, 283, 226, /* 1470 */ 572, 164, 164, 418, 461, 235, 539, 76, 76, 572, - /* 1480 */ 1363, 540, 54, 54, 411, 561, 72, 72, 388, 463, - /* 1490 */ 384, 1028, 228, 134, 134, 1552, 462, 109, 109, 539, - /* 1500 */ 572, 471, 73, 73, 538, 110, 411, 449, 573, 449, - /* 1510 */ 414, 411, 1018, 572, 1028, 316, 563, 959, 470, 475, + /* 1480 */ 1367, 540, 54, 54, 411, 561, 72, 72, 388, 463, + /* 1490 */ 384, 1031, 228, 134, 134, 1559, 462, 109, 109, 539, + /* 1500 */ 572, 471, 73, 73, 538, 110, 411, 449, 574, 573, + /* 1510 */ 414, 411, 1021, 572, 1031, 316, 563, 961, 470, 475, /* 1520 */ 109, 109, 474, 161, 161, 86, 213, 237, 110, 411, - /* 1530 */ 449, 573, 449, 315, 1296, 1018, 136, 136, 289, 455, - /* 1540 */ 572, 341, 1539, 411, 1018, 1018, 1020, 1021, 27, 1178, - /* 1550 */ 451, 572, 217, 288, 108, 881, 106, 216, 396, 396, - /* 1560 */ 395, 273, 393, 130, 130, 851, 337, 1018, 1018, 1020, - /* 1570 */ 1021, 27, 319, 217, 162, 162, 17, 572, 234, 572, - /* 1580 */ 323, 152, 572, 38, 288, 1132, 1080, 400, 322, 396, - /* 1590 */ 396, 395, 273, 393, 472, 286, 851, 572, 1022, 572, - /* 1600 */ 156, 156, 140, 140, 1350, 139, 139, 525, 342, 234, - /* 1610 */ 100, 323, 572, 1512, 1011, 424, 261, 296, 236, 322, + /* 1530 */ 449, 574, 573, 315, 1300, 1021, 136, 136, 289, 455, + /* 1540 */ 572, 341, 1545, 411, 1021, 1021, 1023, 1024, 27, 1184, + /* 1550 */ 451, 572, 217, 288, 108, 883, 106, 216, 396, 396, + /* 1560 */ 395, 273, 393, 130, 130, 853, 337, 1021, 1021, 1023, + /* 1570 */ 1024, 27, 319, 217, 162, 162, 17, 572, 234, 572, + /* 1580 */ 323, 152, 572, 38, 288, 1136, 1084, 400, 322, 396, + /* 1590 */ 396, 395, 273, 393, 472, 286, 853, 572, 1025, 572, + /* 1600 */ 156, 156, 140, 140, 1354, 139, 139, 525, 342, 234, + /* 1610 */ 100, 323, 572, 1518, 1013, 424, 261, 296, 236, 322, /* 1620 */ 137, 137, 138, 138, 572, 477, 168, 261, 449, 141, - /* 1630 */ 479, 1511, 261, 900, 901, 75, 75, 487, 111, 564, + /* 1630 */ 479, 1517, 261, 902, 903, 75, 75, 487, 111, 564, /* 1640 */ 348, 4, 572, 371, 239, 572, 235, 77, 77, 236, - /* 1650 */ 572, 449, 347, 370, 100, 567, 501, 168, 258, 1295, - /* 1660 */ 141, 111, 564, 881, 4, 74, 74, 1360, 42, 42, - /* 1670 */ 361, 352, 100, 48, 48, 976, 977, 235, 567, 355, - /* 1680 */ 1076, 414, 258, 357, 359, 1141, 316, 563, 1310, 964, - /* 1690 */ 561, 261, 1294, 931, 1080, 113, 366, 1092, 1091, 1092, - /* 1700 */ 1091, 864, 932, 150, 113, 376, 1022, 1373, 1418, 1346, - /* 1710 */ 455, 199, 414, 561, 1596, 1358, 1570, 316, 563, 1028, - /* 1720 */ 558, 559, 1423, 1275, 1266, 109, 109, 938, 1254, 1253, - /* 1730 */ 1255, 1589, 276, 110, 496, 449, 573, 449, 211, 1343, - /* 1740 */ 1018, 455, 1028, 308, 309, 11, 219, 310, 109, 109, - /* 1750 */ 397, 232, 1405, 291, 329, 339, 110, 340, 449, 573, - /* 1760 */ 449, 332, 345, 1018, 1410, 297, 481, 369, 1409, 404, - /* 1770 */ 506, 223, 1018, 1018, 1020, 1021, 27, 1293, 391, 1355, - /* 1780 */ 1484, 1483, 552, 1356, 1354, 1353, 562, 218, 204, 205, - /* 1790 */ 1592, 1230, 449, 265, 1227, 1018, 1018, 1020, 1021, 27, - /* 1800 */ 1531, 1529, 79, 564, 179, 4, 230, 81, 215, 422, - /* 1810 */ 85, 1489, 449, 1406, 188, 84, 128, 1400, 550, 567, - /* 1820 */ 328, 35, 111, 564, 173, 4, 1393, 465, 331, 181, - /* 1830 */ 499, 466, 242, 183, 184, 185, 186, 98, 1412, 567, - /* 1840 */ 1411, 1414, 36, 246, 192, 488, 1500, 91, 402, 494, - /* 1850 */ 473, 405, 1478, 350, 561, 277, 248, 196, 497, 407, - /* 1860 */ 515, 354, 249, 436, 1256, 250, 1304, 1313, 1312, 1311, - /* 1870 */ 93, 1606, 885, 1303, 561, 408, 1605, 224, 438, 439, - /* 1880 */ 1283, 1575, 524, 1028, 263, 1282, 368, 264, 1281, 109, - /* 1890 */ 109, 1604, 1561, 306, 307, 442, 374, 110, 1560, 449, - /* 1900 */ 573, 449, 10, 1028, 1018, 1378, 1377, 385, 105, 109, - /* 1910 */ 109, 314, 1465, 34, 99, 534, 575, 110, 1184, 449, - /* 1920 */ 573, 449, 1336, 551, 1018, 383, 210, 1335, 389, 390, - /* 1930 */ 272, 274, 275, 576, 1251, 1246, 1018, 1018, 1020, 1021, - /* 1940 */ 27, 165, 1516, 1517, 1515, 415, 1514, 166, 147, 304, - /* 1950 */ 838, 167, 220, 221, 450, 212, 1018, 1018, 1020, 1021, - /* 1960 */ 27, 78, 231, 318, 144, 1090, 1088, 326, 180, 169, - /* 1970 */ 1209, 182, 917, 238, 241, 338, 1104, 170, 187, 171, + /* 1650 */ 572, 449, 347, 370, 100, 567, 501, 168, 258, 1299, + /* 1660 */ 141, 111, 564, 883, 4, 74, 74, 1364, 42, 42, + /* 1670 */ 361, 352, 100, 48, 48, 978, 979, 235, 567, 355, + /* 1680 */ 1080, 414, 258, 357, 359, 1145, 316, 563, 1314, 966, + /* 1690 */ 561, 261, 1298, 933, 1084, 113, 366, 1096, 1095, 1096, + /* 1700 */ 1095, 866, 934, 150, 113, 376, 1025, 1377, 1422, 1350, + /* 1710 */ 455, 199, 414, 561, 1604, 1362, 1578, 316, 563, 1031, + /* 1720 */ 558, 559, 1428, 1279, 1270, 109, 109, 940, 1258, 1257, + /* 1730 */ 1259, 1597, 276, 110, 496, 449, 574, 573, 211, 1347, + /* 1740 */ 1021, 455, 1031, 308, 309, 11, 219, 310, 109, 109, + /* 1750 */ 397, 232, 1409, 291, 329, 339, 110, 340, 449, 574, + /* 1760 */ 573, 332, 345, 1021, 1414, 297, 481, 369, 1413, 404, + /* 1770 */ 506, 223, 1021, 1021, 1023, 1024, 27, 1297, 391, 1359, + /* 1780 */ 1490, 1489, 552, 1360, 1358, 1357, 562, 218, 204, 205, + /* 1790 */ 1600, 1236, 449, 265, 1233, 1021, 1021, 1023, 1024, 27, + /* 1800 */ 1537, 1535, 79, 564, 179, 4, 230, 81, 215, 422, + /* 1810 */ 85, 1495, 449, 1410, 188, 84, 128, 1404, 550, 567, + /* 1820 */ 328, 35, 111, 564, 173, 4, 1397, 465, 331, 181, + /* 1830 */ 499, 466, 242, 183, 184, 185, 186, 98, 1416, 567, + /* 1840 */ 1415, 1418, 36, 246, 192, 488, 1506, 91, 402, 494, + /* 1850 */ 473, 405, 1484, 350, 561, 277, 248, 196, 497, 407, + /* 1860 */ 515, 354, 249, 436, 1260, 250, 1308, 1317, 1316, 1315, + /* 1870 */ 93, 1615, 887, 1307, 561, 408, 1614, 224, 438, 439, + /* 1880 */ 1287, 1583, 524, 1031, 263, 1286, 368, 264, 1285, 109, + /* 1890 */ 109, 1613, 1569, 306, 307, 442, 374, 110, 1568, 449, + /* 1900 */ 574, 573, 10, 1031, 1021, 1382, 1381, 385, 105, 109, + /* 1910 */ 109, 314, 1470, 34, 99, 534, 576, 110, 1190, 449, + /* 1920 */ 574, 573, 1340, 551, 1021, 383, 210, 1339, 389, 390, + /* 1930 */ 272, 274, 275, 577, 1255, 1250, 1021, 1021, 1023, 1024, + /* 1940 */ 27, 165, 1522, 1523, 1521, 415, 1520, 166, 147, 304, + /* 1950 */ 840, 167, 220, 221, 450, 212, 1021, 1021, 1023, 1024, + /* 1960 */ 27, 78, 231, 318, 144, 1094, 1092, 326, 180, 169, + /* 1970 */ 1216, 182, 919, 238, 241, 338, 1108, 170, 187, 171, /* 1980 */ 425, 427, 189, 87, 88, 416, 178, 172, 89, 90, - /* 1990 */ 1107, 243, 244, 1103, 158, 18, 245, 261, 349, 1096, - /* 2000 */ 193, 493, 1224, 247, 194, 37, 853, 498, 370, 251, - /* 2010 */ 362, 883, 195, 92, 510, 19, 20, 502, 95, 365, - /* 2020 */ 507, 94, 305, 159, 896, 517, 96, 1172, 160, 1057, - /* 2030 */ 1143, 39, 225, 1142, 174, 280, 282, 968, 198, 962, - /* 2040 */ 113, 1162, 260, 7, 21, 22, 1158, 1160, 23, 1166, - /* 2050 */ 1147, 24, 25, 33, 546, 1165, 26, 202, 100, 102, - /* 2060 */ 1071, 1058, 103, 1056, 1060, 1113, 1061, 1112, 266, 267, - /* 2070 */ 28, 40, 927, 1023, 865, 112, 29, 568, 394, 268, - /* 2080 */ 269, 1597, 176, 143, 1180, 1179, + /* 1990 */ 1111, 243, 244, 1107, 158, 18, 245, 261, 349, 1100, + /* 2000 */ 193, 493, 1230, 247, 194, 37, 855, 498, 370, 251, + /* 2010 */ 362, 885, 195, 92, 510, 19, 20, 502, 95, 365, + /* 2020 */ 507, 94, 305, 159, 898, 517, 96, 1178, 160, 1060, + /* 2030 */ 1147, 39, 225, 1146, 174, 280, 282, 970, 198, 964, + /* 2040 */ 113, 1168, 260, 7, 21, 22, 1164, 1166, 23, 1172, + /* 2050 */ 1152, 24, 25, 33, 546, 1171, 26, 202, 100, 102, + /* 2060 */ 1075, 1061, 103, 1059, 1063, 1117, 1064, 1116, 266, 267, + /* 2070 */ 28, 40, 929, 1026, 867, 112, 29, 568, 394, 268, + /* 2080 */ 269, 1606, 1605, 176, 143, 1186, 1185, }; static const YYCODETYPE yy_lookahead[] = { /* 0 */ 194, 224, 194, 226, 194, 194, 194, 217, 194, 194, @@ -172362,7 +170235,7 @@ static const YYCODETYPE yy_lookahead[] = { /* 2050 */ 23, 34, 34, 22, 24, 93, 34, 25, 25, 142, /* 2060 */ 23, 23, 142, 23, 23, 23, 11, 23, 25, 22, /* 2070 */ 22, 22, 135, 23, 23, 22, 22, 25, 15, 141, - /* 2080 */ 141, 141, 25, 23, 1, 1, 320, 320, 320, 320, + /* 2080 */ 141, 141, 141, 25, 23, 1, 1, 320, 320, 320, /* 2090 */ 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, /* 2100 */ 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, /* 2110 */ 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, @@ -172381,11 +170254,11 @@ static const YYCODETYPE yy_lookahead[] = { /* 2240 */ 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, /* 2250 */ 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, /* 2260 */ 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, - /* 2270 */ 320, 320, + /* 2270 */ 320, 320, 320, }; -#define YY_SHIFT_COUNT (578) +#define YY_SHIFT_COUNT (579) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2084) +#define YY_SHIFT_MAX (2085) static const unsigned short int yy_shift_ofst[] = { /* 0 */ 1548, 1377, 1579, 1159, 1159, 538, 1219, 1391, 1414, 1803, /* 10 */ 1803, 1803, 353, 0, 0, 180, 826, 1803, 1803, 1803, @@ -172403,12 +170276,12 @@ static const unsigned short int yy_shift_ofst[] = { /* 130 */ 146, 248, 248, 248, 248, 248, 248, 248, 80, 204, /* 140 */ 98, 60, 124, 1, 424, 424, 742, 950, 424, 424, /* 150 */ 258, 258, 424, 235, 235, 235, 868, 235, 117, 217, - /* 160 */ 217, 27, 27, 2086, 2086, 1112, 1112, 1112, 272, 416, + /* 160 */ 217, 27, 27, 2087, 2087, 1112, 1112, 1112, 272, 416, /* 170 */ 416, 416, 416, 915, 915, 343, 1, 1122, 1163, 424, /* 180 */ 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, /* 190 */ 424, 424, 424, 424, 424, 424, 424, 424, 424, 665, /* 200 */ 1061, 1061, 424, 996, 737, 737, 59, 59, 660, 660, - /* 210 */ 371, 1150, 2086, 2086, 2086, 2086, 2086, 2086, 2086, 518, + /* 210 */ 371, 1150, 2087, 2087, 2087, 2087, 2087, 2087, 2087, 518, /* 220 */ 605, 605, 878, 535, 932, 420, 1058, 839, 858, 1129, /* 230 */ 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, /* 240 */ 487, 424, 424, 424, 424, 424, 424, 424, 424, 424, @@ -172426,9 +170299,9 @@ static const unsigned short int yy_shift_ofst[] = { /* 360 */ 1745, 1745, 1745, 1799, 1848, 1848, 1835, 1745, 1746, 1745, /* 370 */ 1799, 1745, 1745, 1712, 1854, 1766, 1766, 1835, 1652, 1796, /* 380 */ 1796, 1813, 1813, 1668, 1673, 1880, 1652, 1750, 1668, 1767, - /* 390 */ 1769, 1688, 1888, 1905, 1905, 1926, 1926, 1926, 2086, 2086, - /* 400 */ 2086, 2086, 2086, 2086, 2086, 2086, 2086, 2086, 2086, 2086, - /* 410 */ 2086, 2086, 2086, 122, 118, 1079, 1169, 1287, 1221, 1302, + /* 390 */ 1769, 1688, 1888, 1905, 1905, 1926, 1926, 1926, 2087, 2087, + /* 400 */ 2087, 2087, 2087, 2087, 2087, 2087, 2087, 2087, 2087, 2087, + /* 410 */ 2087, 2087, 2087, 122, 118, 1079, 1169, 1287, 1221, 1302, /* 420 */ 1562, 1439, 1390, 1503, 1389, 1465, 1585, 1554, 1591, 1602, /* 430 */ 1607, 1629, 1633, 1647, 1546, 1340, 1626, 1522, 1588, 1577, /* 440 */ 1657, 1666, 1592, 1670, 1544, 1545, 1678, 1679, 1589, 1573, @@ -172444,7 +170317,7 @@ static const unsigned short int yy_shift_ofst[] = { /* 540 */ 1961, 1998, 1974, 1962, 2018, 2027, 2031, 2030, 2032, 2033, /* 550 */ 2022, 1917, 1920, 2037, 2015, 2038, 2040, 2041, 2042, 2043, /* 560 */ 2044, 2047, 2055, 2048, 2049, 2050, 2051, 2053, 2054, 2052, - /* 570 */ 1937, 1938, 1939, 1940, 2057, 2060, 2063, 2083, 2084, + /* 570 */ 1937, 1938, 1939, 1940, 1941, 2058, 2061, 2063, 2084, 2085, }; #define YY_REDUCE_COUNT (412) #define YY_REDUCE_MIN (-261) @@ -172494,64 +170367,64 @@ static const short yy_reduce_ofst[] = { /* 410 */ 1738, 1747, 1743, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1643, 1643, 1643, 1473, 1240, 1351, 1240, 1240, 1240, 1473, - /* 10 */ 1473, 1473, 1240, 1381, 1381, 1526, 1273, 1240, 1240, 1240, - /* 20 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1472, 1240, 1240, - /* 30 */ 1240, 1240, 1559, 1559, 1240, 1240, 1240, 1240, 1240, 1240, - /* 40 */ 1240, 1240, 1390, 1240, 1397, 1240, 1240, 1240, 1240, 1240, - /* 50 */ 1474, 1475, 1240, 1240, 1240, 1525, 1527, 1490, 1404, 1403, - /* 60 */ 1402, 1401, 1508, 1369, 1395, 1388, 1392, 1469, 1470, 1468, - /* 70 */ 1621, 1475, 1474, 1240, 1391, 1437, 1453, 1436, 1240, 1240, - /* 80 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 90 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 100 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 110 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 120 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 130 */ 1445, 1452, 1451, 1450, 1459, 1449, 1446, 1439, 1438, 1440, - /* 140 */ 1441, 1240, 1240, 1264, 1240, 1240, 1261, 1315, 1240, 1240, - /* 150 */ 1240, 1240, 1240, 1545, 1544, 1240, 1442, 1240, 1273, 1431, - /* 160 */ 1430, 1456, 1443, 1455, 1454, 1533, 1595, 1594, 1491, 1240, - /* 170 */ 1240, 1240, 1240, 1240, 1240, 1559, 1240, 1240, 1240, 1240, - /* 180 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 190 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1371, - /* 200 */ 1559, 1559, 1240, 1273, 1559, 1559, 1372, 1372, 1269, 1269, - /* 210 */ 1375, 1240, 1540, 1342, 1342, 1342, 1342, 1351, 1342, 1240, - /* 220 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 230 */ 1240, 1240, 1240, 1240, 1530, 1528, 1240, 1240, 1240, 1240, - /* 240 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 250 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 260 */ 1240, 1240, 1240, 1347, 1240, 1240, 1240, 1240, 1240, 1240, - /* 270 */ 1240, 1240, 1240, 1240, 1240, 1588, 1240, 1503, 1329, 1347, - /* 280 */ 1347, 1347, 1347, 1349, 1330, 1328, 1341, 1274, 1247, 1635, - /* 290 */ 1407, 1396, 1348, 1396, 1632, 1394, 1407, 1407, 1394, 1407, - /* 300 */ 1348, 1632, 1290, 1610, 1285, 1381, 1381, 1381, 1371, 1371, - /* 310 */ 1371, 1371, 1375, 1375, 1471, 1348, 1341, 1240, 1635, 1635, - /* 320 */ 1357, 1357, 1634, 1634, 1357, 1491, 1618, 1416, 1389, 1375, - /* 330 */ 1318, 1389, 1375, 1324, 1324, 1324, 1324, 1357, 1258, 1394, - /* 340 */ 1618, 1618, 1394, 1416, 1318, 1394, 1318, 1394, 1357, 1258, - /* 350 */ 1507, 1629, 1357, 1258, 1481, 1357, 1258, 1357, 1258, 1481, - /* 360 */ 1316, 1316, 1316, 1305, 1240, 1240, 1481, 1316, 1290, 1316, - /* 370 */ 1305, 1316, 1316, 1577, 1240, 1485, 1485, 1481, 1357, 1569, - /* 380 */ 1569, 1384, 1384, 1389, 1375, 1476, 1357, 1240, 1389, 1387, - /* 390 */ 1385, 1394, 1308, 1591, 1591, 1587, 1587, 1587, 1640, 1640, - /* 400 */ 1540, 1603, 1273, 1273, 1273, 1273, 1603, 1292, 1292, 1274, - /* 410 */ 1274, 1273, 1603, 1240, 1240, 1240, 1240, 1240, 1240, 1598, - /* 420 */ 1240, 1535, 1492, 1361, 1240, 1240, 1240, 1240, 1240, 1240, - /* 430 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1546, 1240, - /* 440 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1421, - /* 450 */ 1240, 1243, 1537, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 460 */ 1240, 1398, 1399, 1362, 1240, 1240, 1240, 1240, 1240, 1240, - /* 470 */ 1240, 1413, 1240, 1240, 1240, 1408, 1240, 1240, 1240, 1240, - /* 480 */ 1240, 1240, 1240, 1240, 1631, 1240, 1240, 1240, 1240, 1240, - /* 490 */ 1240, 1506, 1505, 1240, 1240, 1359, 1240, 1240, 1240, 1240, - /* 500 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1288, - /* 510 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 520 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, - /* 530 */ 1240, 1240, 1240, 1386, 1240, 1240, 1240, 1240, 1240, 1240, - /* 540 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1574, 1376, - /* 550 */ 1240, 1240, 1240, 1240, 1622, 1240, 1240, 1240, 1240, 1240, - /* 560 */ 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1614, - /* 570 */ 1332, 1422, 1240, 1425, 1262, 1240, 1252, 1240, 1240, + /* 0 */ 1651, 1651, 1651, 1479, 1244, 1355, 1244, 1244, 1244, 1479, + /* 10 */ 1479, 1479, 1244, 1385, 1385, 1532, 1277, 1244, 1244, 1244, + /* 20 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1478, 1244, 1244, + /* 30 */ 1244, 1244, 1567, 1567, 1244, 1244, 1244, 1244, 1244, 1244, + /* 40 */ 1244, 1244, 1394, 1244, 1401, 1244, 1244, 1244, 1244, 1244, + /* 50 */ 1480, 1481, 1244, 1244, 1244, 1531, 1533, 1496, 1408, 1407, + /* 60 */ 1406, 1405, 1514, 1373, 1399, 1392, 1396, 1474, 1475, 1473, + /* 70 */ 1477, 1481, 1480, 1244, 1395, 1442, 1458, 1441, 1244, 1244, + /* 80 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 90 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 100 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 110 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 120 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 130 */ 1450, 1457, 1456, 1455, 1464, 1454, 1451, 1444, 1443, 1445, + /* 140 */ 1446, 1244, 1244, 1268, 1244, 1244, 1265, 1319, 1244, 1244, + /* 150 */ 1244, 1244, 1244, 1551, 1550, 1244, 1447, 1244, 1277, 1436, + /* 160 */ 1435, 1461, 1448, 1460, 1459, 1539, 1603, 1602, 1497, 1244, + /* 170 */ 1244, 1244, 1244, 1244, 1244, 1567, 1244, 1244, 1244, 1244, + /* 180 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 190 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1375, + /* 200 */ 1567, 1567, 1244, 1277, 1567, 1567, 1376, 1376, 1273, 1273, + /* 210 */ 1379, 1244, 1546, 1346, 1346, 1346, 1346, 1355, 1346, 1244, + /* 220 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 230 */ 1244, 1244, 1244, 1244, 1536, 1534, 1244, 1244, 1244, 1244, + /* 240 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 250 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 260 */ 1244, 1244, 1244, 1351, 1244, 1244, 1244, 1244, 1244, 1244, + /* 270 */ 1244, 1244, 1244, 1244, 1244, 1596, 1244, 1509, 1333, 1351, + /* 280 */ 1351, 1351, 1351, 1353, 1334, 1332, 1345, 1278, 1251, 1643, + /* 290 */ 1411, 1400, 1352, 1400, 1640, 1398, 1411, 1411, 1398, 1411, + /* 300 */ 1352, 1640, 1294, 1619, 1289, 1385, 1385, 1385, 1375, 1375, + /* 310 */ 1375, 1375, 1379, 1379, 1476, 1352, 1345, 1244, 1643, 1643, + /* 320 */ 1361, 1361, 1642, 1642, 1361, 1497, 1627, 1420, 1393, 1379, + /* 330 */ 1322, 1393, 1379, 1328, 1328, 1328, 1328, 1361, 1262, 1398, + /* 340 */ 1627, 1627, 1398, 1420, 1322, 1398, 1322, 1398, 1361, 1262, + /* 350 */ 1513, 1637, 1361, 1262, 1487, 1361, 1262, 1361, 1262, 1487, + /* 360 */ 1320, 1320, 1320, 1309, 1244, 1244, 1487, 1320, 1294, 1320, + /* 370 */ 1309, 1320, 1320, 1585, 1244, 1491, 1491, 1487, 1361, 1577, + /* 380 */ 1577, 1388, 1388, 1393, 1379, 1482, 1361, 1244, 1393, 1391, + /* 390 */ 1389, 1398, 1312, 1599, 1599, 1595, 1595, 1595, 1648, 1648, + /* 400 */ 1546, 1612, 1277, 1277, 1277, 1277, 1612, 1296, 1296, 1278, + /* 410 */ 1278, 1277, 1612, 1244, 1244, 1244, 1244, 1244, 1244, 1607, + /* 420 */ 1244, 1541, 1498, 1365, 1244, 1244, 1244, 1244, 1244, 1244, + /* 430 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1552, 1244, + /* 440 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1425, + /* 450 */ 1244, 1247, 1543, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 460 */ 1244, 1402, 1403, 1366, 1244, 1244, 1244, 1244, 1244, 1244, + /* 470 */ 1244, 1417, 1244, 1244, 1244, 1412, 1244, 1244, 1244, 1244, + /* 480 */ 1244, 1244, 1244, 1244, 1639, 1244, 1244, 1244, 1244, 1244, + /* 490 */ 1244, 1512, 1511, 1244, 1244, 1363, 1244, 1244, 1244, 1244, + /* 500 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1292, + /* 510 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 520 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, + /* 530 */ 1244, 1244, 1244, 1390, 1244, 1244, 1244, 1244, 1244, 1244, + /* 540 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1582, 1380, + /* 550 */ 1244, 1244, 1244, 1244, 1630, 1244, 1244, 1244, 1244, 1244, + /* 560 */ 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1623, + /* 570 */ 1336, 1427, 1244, 1426, 1430, 1266, 1244, 1256, 1244, 1244, }; /********** End of lemon-generated parsing tables *****************************/ @@ -173350,231 +171223,233 @@ static const char *const yyRuleName[] = { /* 175 */ "idlist ::= idlist COMMA nm", /* 176 */ "idlist ::= nm", /* 177 */ "expr ::= LP expr RP", - /* 178 */ "expr ::= ID|INDEXED|JOIN_KW", - /* 179 */ "expr ::= nm DOT nm", - /* 180 */ "expr ::= nm DOT nm DOT nm", - /* 181 */ "term ::= NULL|FLOAT|BLOB", - /* 182 */ "term ::= STRING", - /* 183 */ "term ::= INTEGER", - /* 184 */ "expr ::= VARIABLE", - /* 185 */ "expr ::= expr COLLATE ID|STRING", - /* 186 */ "expr ::= CAST LP expr AS typetoken RP", - /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", - /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", - /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", - /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", - /* 191 */ "term ::= CTIME_KW", - /* 192 */ "expr ::= LP nexprlist COMMA expr RP", - /* 193 */ "expr ::= expr AND expr", - /* 194 */ "expr ::= expr OR expr", - /* 195 */ "expr ::= expr LT|GT|GE|LE expr", - /* 196 */ "expr ::= expr EQ|NE expr", - /* 197 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 198 */ "expr ::= expr PLUS|MINUS expr", - /* 199 */ "expr ::= expr STAR|SLASH|REM expr", - /* 200 */ "expr ::= expr CONCAT expr", - /* 201 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 202 */ "expr ::= expr likeop expr", - /* 203 */ "expr ::= expr likeop expr ESCAPE expr", - /* 204 */ "expr ::= expr ISNULL|NOTNULL", - /* 205 */ "expr ::= expr NOT NULL", - /* 206 */ "expr ::= expr IS expr", - /* 207 */ "expr ::= expr IS NOT expr", - /* 208 */ "expr ::= expr IS NOT DISTINCT FROM expr", - /* 209 */ "expr ::= expr IS DISTINCT FROM expr", - /* 210 */ "expr ::= NOT expr", - /* 211 */ "expr ::= BITNOT expr", - /* 212 */ "expr ::= PLUS|MINUS expr", - /* 213 */ "expr ::= expr PTR expr", - /* 214 */ "between_op ::= BETWEEN", - /* 215 */ "between_op ::= NOT BETWEEN", - /* 216 */ "expr ::= expr between_op expr AND expr", - /* 217 */ "in_op ::= IN", - /* 218 */ "in_op ::= NOT IN", - /* 219 */ "expr ::= expr in_op LP exprlist RP", - /* 220 */ "expr ::= LP select RP", - /* 221 */ "expr ::= expr in_op LP select RP", - /* 222 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 223 */ "expr ::= EXISTS LP select RP", - /* 224 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 225 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 226 */ "case_exprlist ::= WHEN expr THEN expr", - /* 227 */ "case_else ::= ELSE expr", - /* 228 */ "case_else ::=", - /* 229 */ "case_operand ::=", - /* 230 */ "exprlist ::=", - /* 231 */ "nexprlist ::= nexprlist COMMA expr", - /* 232 */ "nexprlist ::= expr", - /* 233 */ "paren_exprlist ::=", - /* 234 */ "paren_exprlist ::= LP exprlist RP", - /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 236 */ "uniqueflag ::= UNIQUE", - /* 237 */ "uniqueflag ::=", - /* 238 */ "eidlist_opt ::=", - /* 239 */ "eidlist_opt ::= LP eidlist RP", - /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 241 */ "eidlist ::= nm collate sortorder", - /* 242 */ "collate ::=", - /* 243 */ "collate ::= COLLATE ID|STRING", - /* 244 */ "cmd ::= DROP INDEX ifexists fullname", - /* 245 */ "cmd ::= VACUUM vinto", - /* 246 */ "cmd ::= VACUUM nm vinto", - /* 247 */ "vinto ::= INTO expr", - /* 248 */ "vinto ::=", - /* 249 */ "cmd ::= PRAGMA nm dbnm", - /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 258 */ "trigger_time ::= BEFORE|AFTER", - /* 259 */ "trigger_time ::= INSTEAD OF", - /* 260 */ "trigger_time ::=", - /* 261 */ "trigger_event ::= DELETE|INSERT", - /* 262 */ "trigger_event ::= UPDATE", - /* 263 */ "trigger_event ::= UPDATE OF idlist", - /* 264 */ "when_clause ::=", - /* 265 */ "when_clause ::= WHEN expr", - /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 268 */ "trnm ::= nm DOT nm", - /* 269 */ "tridxby ::= INDEXED BY nm", - /* 270 */ "tridxby ::= NOT INDEXED", - /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 274 */ "trigger_cmd ::= scanpt select scanpt", - /* 275 */ "expr ::= RAISE LP IGNORE RP", - /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 277 */ "raisetype ::= ROLLBACK", - /* 278 */ "raisetype ::= ABORT", - /* 279 */ "raisetype ::= FAIL", - /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 282 */ "cmd ::= DETACH database_kw_opt expr", - /* 283 */ "key_opt ::=", - /* 284 */ "key_opt ::= KEY expr", - /* 285 */ "cmd ::= REINDEX", - /* 286 */ "cmd ::= REINDEX nm dbnm", - /* 287 */ "cmd ::= ANALYZE", - /* 288 */ "cmd ::= ANALYZE nm dbnm", - /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", - /* 292 */ "add_column_fullname ::= fullname", - /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 294 */ "cmd ::= create_vtab", - /* 295 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 297 */ "vtabarg ::=", - /* 298 */ "vtabargtoken ::= ANY", - /* 299 */ "vtabargtoken ::= lp anylist RP", - /* 300 */ "lp ::= LP", - /* 301 */ "with ::= WITH wqlist", - /* 302 */ "with ::= WITH RECURSIVE wqlist", - /* 303 */ "wqas ::= AS", - /* 304 */ "wqas ::= AS MATERIALIZED", - /* 305 */ "wqas ::= AS NOT MATERIALIZED", - /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP", - /* 307 */ "wqlist ::= wqitem", - /* 308 */ "wqlist ::= wqlist COMMA wqitem", - /* 309 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 310 */ "windowdefn ::= nm AS LP window RP", - /* 311 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 312 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 313 */ "window ::= ORDER BY sortlist frame_opt", - /* 314 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 315 */ "window ::= nm frame_opt", - /* 316 */ "frame_opt ::=", - /* 317 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 318 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 319 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 320 */ "frame_bound_s ::= frame_bound", - /* 321 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 322 */ "frame_bound_e ::= frame_bound", - /* 323 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 324 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 325 */ "frame_bound ::= CURRENT ROW", - /* 326 */ "frame_exclude_opt ::=", - /* 327 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 328 */ "frame_exclude ::= NO OTHERS", - /* 329 */ "frame_exclude ::= CURRENT ROW", - /* 330 */ "frame_exclude ::= GROUP|TIES", - /* 331 */ "window_clause ::= WINDOW windowdefn_list", - /* 332 */ "filter_over ::= filter_clause over_clause", - /* 333 */ "filter_over ::= over_clause", - /* 334 */ "filter_over ::= filter_clause", - /* 335 */ "over_clause ::= OVER LP window RP", - /* 336 */ "over_clause ::= OVER nm", - /* 337 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 338 */ "input ::= cmdlist", - /* 339 */ "cmdlist ::= cmdlist ecmd", - /* 340 */ "cmdlist ::= ecmd", - /* 341 */ "ecmd ::= SEMI", - /* 342 */ "ecmd ::= cmdx SEMI", - /* 343 */ "ecmd ::= explain cmdx SEMI", - /* 344 */ "trans_opt ::=", - /* 345 */ "trans_opt ::= TRANSACTION", - /* 346 */ "trans_opt ::= TRANSACTION nm", - /* 347 */ "savepoint_opt ::= SAVEPOINT", - /* 348 */ "savepoint_opt ::=", - /* 349 */ "cmd ::= create_table create_table_args", - /* 350 */ "table_option_set ::= table_option", - /* 351 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 352 */ "columnlist ::= columnname carglist", - /* 353 */ "nm ::= ID|INDEXED|JOIN_KW", - /* 354 */ "nm ::= STRING", - /* 355 */ "typetoken ::= typename", - /* 356 */ "typename ::= ID|STRING", - /* 357 */ "signed ::= plus_num", - /* 358 */ "signed ::= minus_num", - /* 359 */ "carglist ::= carglist ccons", - /* 360 */ "carglist ::=", - /* 361 */ "ccons ::= NULL onconf", - /* 362 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 363 */ "ccons ::= AS generated", - /* 364 */ "conslist_opt ::= COMMA conslist", - /* 365 */ "conslist ::= conslist tconscomma tcons", - /* 366 */ "conslist ::= tcons", - /* 367 */ "tconscomma ::=", - /* 368 */ "defer_subclause_opt ::= defer_subclause", - /* 369 */ "resolvetype ::= raisetype", - /* 370 */ "selectnowith ::= oneselect", - /* 371 */ "oneselect ::= values", - /* 372 */ "sclp ::= selcollist COMMA", - /* 373 */ "as ::= ID|STRING", - /* 374 */ "indexed_opt ::= indexed_by", - /* 375 */ "returning ::=", - /* 376 */ "expr ::= term", - /* 377 */ "likeop ::= LIKE_KW|MATCH", - /* 378 */ "case_operand ::= expr", - /* 379 */ "exprlist ::= nexprlist", - /* 380 */ "nmnum ::= plus_num", - /* 381 */ "nmnum ::= nm", - /* 382 */ "nmnum ::= ON", - /* 383 */ "nmnum ::= DELETE", - /* 384 */ "nmnum ::= DEFAULT", - /* 385 */ "plus_num ::= INTEGER|FLOAT", - /* 386 */ "foreach_clause ::=", - /* 387 */ "foreach_clause ::= FOR EACH ROW", - /* 388 */ "trnm ::= nm", - /* 389 */ "tridxby ::=", - /* 390 */ "database_kw_opt ::= DATABASE", - /* 391 */ "database_kw_opt ::=", - /* 392 */ "kwcolumn_opt ::=", - /* 393 */ "kwcolumn_opt ::= COLUMNKW", - /* 394 */ "vtabarglist ::= vtabarg", - /* 395 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 396 */ "vtabarg ::= vtabarg vtabargtoken", - /* 397 */ "anylist ::=", - /* 398 */ "anylist ::= anylist LP anylist RP", - /* 399 */ "anylist ::= anylist ANY", - /* 400 */ "with ::=", - /* 401 */ "windowdefn_list ::= windowdefn", - /* 402 */ "window ::= frame_opt", + /* 178 */ "expr ::= ID|INDEXED", + /* 179 */ "expr ::= JOIN_KW", + /* 180 */ "expr ::= nm DOT nm", + /* 181 */ "expr ::= nm DOT nm DOT nm", + /* 182 */ "term ::= NULL|FLOAT|BLOB", + /* 183 */ "term ::= STRING", + /* 184 */ "term ::= INTEGER", + /* 185 */ "expr ::= VARIABLE", + /* 186 */ "expr ::= expr COLLATE ID|STRING", + /* 187 */ "expr ::= CAST LP expr AS typetoken RP", + /* 188 */ "expr ::= ID|INDEXED LP distinct exprlist RP", + /* 189 */ "expr ::= ID|INDEXED LP STAR RP", + /* 190 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", + /* 191 */ "expr ::= ID|INDEXED LP STAR RP filter_over", + /* 192 */ "term ::= CTIME_KW", + /* 193 */ "expr ::= LP nexprlist COMMA expr RP", + /* 194 */ "expr ::= expr AND expr", + /* 195 */ "expr ::= expr OR expr", + /* 196 */ "expr ::= expr LT|GT|GE|LE expr", + /* 197 */ "expr ::= expr EQ|NE expr", + /* 198 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 199 */ "expr ::= expr PLUS|MINUS expr", + /* 200 */ "expr ::= expr STAR|SLASH|REM expr", + /* 201 */ "expr ::= expr CONCAT expr", + /* 202 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 203 */ "expr ::= expr likeop expr", + /* 204 */ "expr ::= expr likeop expr ESCAPE expr", + /* 205 */ "expr ::= expr ISNULL|NOTNULL", + /* 206 */ "expr ::= expr NOT NULL", + /* 207 */ "expr ::= expr IS expr", + /* 208 */ "expr ::= expr IS NOT expr", + /* 209 */ "expr ::= expr IS NOT DISTINCT FROM expr", + /* 210 */ "expr ::= expr IS DISTINCT FROM expr", + /* 211 */ "expr ::= NOT expr", + /* 212 */ "expr ::= BITNOT expr", + /* 213 */ "expr ::= PLUS|MINUS expr", + /* 214 */ "expr ::= expr PTR expr", + /* 215 */ "between_op ::= BETWEEN", + /* 216 */ "between_op ::= NOT BETWEEN", + /* 217 */ "expr ::= expr between_op expr AND expr", + /* 218 */ "in_op ::= IN", + /* 219 */ "in_op ::= NOT IN", + /* 220 */ "expr ::= expr in_op LP exprlist RP", + /* 221 */ "expr ::= LP select RP", + /* 222 */ "expr ::= expr in_op LP select RP", + /* 223 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 224 */ "expr ::= EXISTS LP select RP", + /* 225 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 226 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 227 */ "case_exprlist ::= WHEN expr THEN expr", + /* 228 */ "case_else ::= ELSE expr", + /* 229 */ "case_else ::=", + /* 230 */ "case_operand ::= expr", + /* 231 */ "case_operand ::=", + /* 232 */ "exprlist ::=", + /* 233 */ "nexprlist ::= nexprlist COMMA expr", + /* 234 */ "nexprlist ::= expr", + /* 235 */ "paren_exprlist ::=", + /* 236 */ "paren_exprlist ::= LP exprlist RP", + /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 238 */ "uniqueflag ::= UNIQUE", + /* 239 */ "uniqueflag ::=", + /* 240 */ "eidlist_opt ::=", + /* 241 */ "eidlist_opt ::= LP eidlist RP", + /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 243 */ "eidlist ::= nm collate sortorder", + /* 244 */ "collate ::=", + /* 245 */ "collate ::= COLLATE ID|STRING", + /* 246 */ "cmd ::= DROP INDEX ifexists fullname", + /* 247 */ "cmd ::= VACUUM vinto", + /* 248 */ "cmd ::= VACUUM nm vinto", + /* 249 */ "vinto ::= INTO expr", + /* 250 */ "vinto ::=", + /* 251 */ "cmd ::= PRAGMA nm dbnm", + /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 260 */ "trigger_time ::= BEFORE|AFTER", + /* 261 */ "trigger_time ::= INSTEAD OF", + /* 262 */ "trigger_time ::=", + /* 263 */ "trigger_event ::= DELETE|INSERT", + /* 264 */ "trigger_event ::= UPDATE", + /* 265 */ "trigger_event ::= UPDATE OF idlist", + /* 266 */ "when_clause ::=", + /* 267 */ "when_clause ::= WHEN expr", + /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 270 */ "trnm ::= nm DOT nm", + /* 271 */ "tridxby ::= INDEXED BY nm", + /* 272 */ "tridxby ::= NOT INDEXED", + /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 276 */ "trigger_cmd ::= scanpt select scanpt", + /* 277 */ "expr ::= RAISE LP IGNORE RP", + /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 279 */ "raisetype ::= ROLLBACK", + /* 280 */ "raisetype ::= ABORT", + /* 281 */ "raisetype ::= FAIL", + /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 284 */ "cmd ::= DETACH database_kw_opt expr", + /* 285 */ "key_opt ::=", + /* 286 */ "key_opt ::= KEY expr", + /* 287 */ "cmd ::= REINDEX", + /* 288 */ "cmd ::= REINDEX nm dbnm", + /* 289 */ "cmd ::= ANALYZE", + /* 290 */ "cmd ::= ANALYZE nm dbnm", + /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 294 */ "add_column_fullname ::= fullname", + /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 296 */ "cmd ::= create_vtab", + /* 297 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 299 */ "vtabarg ::=", + /* 300 */ "vtabargtoken ::= ANY", + /* 301 */ "vtabargtoken ::= lp anylist RP", + /* 302 */ "lp ::= LP", + /* 303 */ "with ::= WITH wqlist", + /* 304 */ "with ::= WITH RECURSIVE wqlist", + /* 305 */ "wqas ::= AS", + /* 306 */ "wqas ::= AS MATERIALIZED", + /* 307 */ "wqas ::= AS NOT MATERIALIZED", + /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 309 */ "wqlist ::= wqitem", + /* 310 */ "wqlist ::= wqlist COMMA wqitem", + /* 311 */ "windowdefn_list ::= windowdefn", + /* 312 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 313 */ "windowdefn ::= nm AS LP window RP", + /* 314 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 315 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 316 */ "window ::= ORDER BY sortlist frame_opt", + /* 317 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 318 */ "window ::= frame_opt", + /* 319 */ "window ::= nm frame_opt", + /* 320 */ "frame_opt ::=", + /* 321 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 322 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 323 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 324 */ "frame_bound_s ::= frame_bound", + /* 325 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 326 */ "frame_bound_e ::= frame_bound", + /* 327 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 328 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 329 */ "frame_bound ::= CURRENT ROW", + /* 330 */ "frame_exclude_opt ::=", + /* 331 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 332 */ "frame_exclude ::= NO OTHERS", + /* 333 */ "frame_exclude ::= CURRENT ROW", + /* 334 */ "frame_exclude ::= GROUP|TIES", + /* 335 */ "window_clause ::= WINDOW windowdefn_list", + /* 336 */ "filter_over ::= filter_clause over_clause", + /* 337 */ "filter_over ::= over_clause", + /* 338 */ "filter_over ::= filter_clause", + /* 339 */ "over_clause ::= OVER LP window RP", + /* 340 */ "over_clause ::= OVER nm", + /* 341 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 342 */ "input ::= cmdlist", + /* 343 */ "cmdlist ::= cmdlist ecmd", + /* 344 */ "cmdlist ::= ecmd", + /* 345 */ "ecmd ::= SEMI", + /* 346 */ "ecmd ::= cmdx SEMI", + /* 347 */ "ecmd ::= explain cmdx SEMI", + /* 348 */ "trans_opt ::=", + /* 349 */ "trans_opt ::= TRANSACTION", + /* 350 */ "trans_opt ::= TRANSACTION nm", + /* 351 */ "savepoint_opt ::= SAVEPOINT", + /* 352 */ "savepoint_opt ::=", + /* 353 */ "cmd ::= create_table create_table_args", + /* 354 */ "table_option_set ::= table_option", + /* 355 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 356 */ "columnlist ::= columnname carglist", + /* 357 */ "nm ::= ID|INDEXED", + /* 358 */ "nm ::= STRING", + /* 359 */ "nm ::= JOIN_KW", + /* 360 */ "typetoken ::= typename", + /* 361 */ "typename ::= ID|STRING", + /* 362 */ "signed ::= plus_num", + /* 363 */ "signed ::= minus_num", + /* 364 */ "carglist ::= carglist ccons", + /* 365 */ "carglist ::=", + /* 366 */ "ccons ::= NULL onconf", + /* 367 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 368 */ "ccons ::= AS generated", + /* 369 */ "conslist_opt ::= COMMA conslist", + /* 370 */ "conslist ::= conslist tconscomma tcons", + /* 371 */ "conslist ::= tcons", + /* 372 */ "tconscomma ::=", + /* 373 */ "defer_subclause_opt ::= defer_subclause", + /* 374 */ "resolvetype ::= raisetype", + /* 375 */ "selectnowith ::= oneselect", + /* 376 */ "oneselect ::= values", + /* 377 */ "sclp ::= selcollist COMMA", + /* 378 */ "as ::= ID|STRING", + /* 379 */ "indexed_opt ::= indexed_by", + /* 380 */ "returning ::=", + /* 381 */ "expr ::= term", + /* 382 */ "likeop ::= LIKE_KW|MATCH", + /* 383 */ "exprlist ::= nexprlist", + /* 384 */ "nmnum ::= plus_num", + /* 385 */ "nmnum ::= nm", + /* 386 */ "nmnum ::= ON", + /* 387 */ "nmnum ::= DELETE", + /* 388 */ "nmnum ::= DEFAULT", + /* 389 */ "plus_num ::= INTEGER|FLOAT", + /* 390 */ "foreach_clause ::=", + /* 391 */ "foreach_clause ::= FOR EACH ROW", + /* 392 */ "trnm ::= nm", + /* 393 */ "tridxby ::=", + /* 394 */ "database_kw_opt ::= DATABASE", + /* 395 */ "database_kw_opt ::=", + /* 396 */ "kwcolumn_opt ::=", + /* 397 */ "kwcolumn_opt ::= COLUMNKW", + /* 398 */ "vtabarglist ::= vtabarg", + /* 399 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 400 */ "vtabarg ::= vtabarg vtabargtoken", + /* 401 */ "anylist ::=", + /* 402 */ "anylist ::= anylist LP anylist RP", + /* 403 */ "anylist ::= anylist ANY", + /* 404 */ "with ::=", }; #endif /* NDEBUG */ @@ -174259,231 +172134,233 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 264, /* (175) idlist ::= idlist COMMA nm */ 264, /* (176) idlist ::= nm */ 218, /* (177) expr ::= LP expr RP */ - 218, /* (178) expr ::= ID|INDEXED|JOIN_KW */ - 218, /* (179) expr ::= nm DOT nm */ - 218, /* (180) expr ::= nm DOT nm DOT nm */ - 217, /* (181) term ::= NULL|FLOAT|BLOB */ - 217, /* (182) term ::= STRING */ - 217, /* (183) term ::= INTEGER */ - 218, /* (184) expr ::= VARIABLE */ - 218, /* (185) expr ::= expr COLLATE ID|STRING */ - 218, /* (186) expr ::= CAST LP expr AS typetoken RP */ - 218, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - 218, /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - 218, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - 218, /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - 217, /* (191) term ::= CTIME_KW */ - 218, /* (192) expr ::= LP nexprlist COMMA expr RP */ - 218, /* (193) expr ::= expr AND expr */ - 218, /* (194) expr ::= expr OR expr */ - 218, /* (195) expr ::= expr LT|GT|GE|LE expr */ - 218, /* (196) expr ::= expr EQ|NE expr */ - 218, /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 218, /* (198) expr ::= expr PLUS|MINUS expr */ - 218, /* (199) expr ::= expr STAR|SLASH|REM expr */ - 218, /* (200) expr ::= expr CONCAT expr */ - 275, /* (201) likeop ::= NOT LIKE_KW|MATCH */ - 218, /* (202) expr ::= expr likeop expr */ - 218, /* (203) expr ::= expr likeop expr ESCAPE expr */ - 218, /* (204) expr ::= expr ISNULL|NOTNULL */ - 218, /* (205) expr ::= expr NOT NULL */ - 218, /* (206) expr ::= expr IS expr */ - 218, /* (207) expr ::= expr IS NOT expr */ - 218, /* (208) expr ::= expr IS NOT DISTINCT FROM expr */ - 218, /* (209) expr ::= expr IS DISTINCT FROM expr */ - 218, /* (210) expr ::= NOT expr */ - 218, /* (211) expr ::= BITNOT expr */ - 218, /* (212) expr ::= PLUS|MINUS expr */ - 218, /* (213) expr ::= expr PTR expr */ - 276, /* (214) between_op ::= BETWEEN */ - 276, /* (215) between_op ::= NOT BETWEEN */ - 218, /* (216) expr ::= expr between_op expr AND expr */ - 277, /* (217) in_op ::= IN */ - 277, /* (218) in_op ::= NOT IN */ - 218, /* (219) expr ::= expr in_op LP exprlist RP */ - 218, /* (220) expr ::= LP select RP */ - 218, /* (221) expr ::= expr in_op LP select RP */ - 218, /* (222) expr ::= expr in_op nm dbnm paren_exprlist */ - 218, /* (223) expr ::= EXISTS LP select RP */ - 218, /* (224) expr ::= CASE case_operand case_exprlist case_else END */ - 280, /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 280, /* (226) case_exprlist ::= WHEN expr THEN expr */ - 281, /* (227) case_else ::= ELSE expr */ - 281, /* (228) case_else ::= */ - 279, /* (229) case_operand ::= */ - 262, /* (230) exprlist ::= */ - 254, /* (231) nexprlist ::= nexprlist COMMA expr */ - 254, /* (232) nexprlist ::= expr */ - 278, /* (233) paren_exprlist ::= */ - 278, /* (234) paren_exprlist ::= LP exprlist RP */ - 191, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 282, /* (236) uniqueflag ::= UNIQUE */ - 282, /* (237) uniqueflag ::= */ - 222, /* (238) eidlist_opt ::= */ - 222, /* (239) eidlist_opt ::= LP eidlist RP */ - 233, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ - 233, /* (241) eidlist ::= nm collate sortorder */ - 283, /* (242) collate ::= */ - 283, /* (243) collate ::= COLLATE ID|STRING */ - 191, /* (244) cmd ::= DROP INDEX ifexists fullname */ - 191, /* (245) cmd ::= VACUUM vinto */ - 191, /* (246) cmd ::= VACUUM nm vinto */ - 284, /* (247) vinto ::= INTO expr */ - 284, /* (248) vinto ::= */ - 191, /* (249) cmd ::= PRAGMA nm dbnm */ - 191, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 191, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 191, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 191, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 212, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ - 213, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ - 191, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 286, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 288, /* (258) trigger_time ::= BEFORE|AFTER */ - 288, /* (259) trigger_time ::= INSTEAD OF */ - 288, /* (260) trigger_time ::= */ - 289, /* (261) trigger_event ::= DELETE|INSERT */ - 289, /* (262) trigger_event ::= UPDATE */ - 289, /* (263) trigger_event ::= UPDATE OF idlist */ - 291, /* (264) when_clause ::= */ - 291, /* (265) when_clause ::= WHEN expr */ - 287, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 287, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ - 293, /* (268) trnm ::= nm DOT nm */ - 294, /* (269) tridxby ::= INDEXED BY nm */ - 294, /* (270) tridxby ::= NOT INDEXED */ - 292, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 292, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 292, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 292, /* (274) trigger_cmd ::= scanpt select scanpt */ - 218, /* (275) expr ::= RAISE LP IGNORE RP */ - 218, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ - 237, /* (277) raisetype ::= ROLLBACK */ - 237, /* (278) raisetype ::= ABORT */ - 237, /* (279) raisetype ::= FAIL */ - 191, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ - 191, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 191, /* (282) cmd ::= DETACH database_kw_opt expr */ - 296, /* (283) key_opt ::= */ - 296, /* (284) key_opt ::= KEY expr */ - 191, /* (285) cmd ::= REINDEX */ - 191, /* (286) cmd ::= REINDEX nm dbnm */ - 191, /* (287) cmd ::= ANALYZE */ - 191, /* (288) cmd ::= ANALYZE nm dbnm */ - 191, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 191, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 191, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - 297, /* (292) add_column_fullname ::= fullname */ - 191, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 191, /* (294) cmd ::= create_vtab */ - 191, /* (295) cmd ::= create_vtab LP vtabarglist RP */ - 299, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 301, /* (297) vtabarg ::= */ - 302, /* (298) vtabargtoken ::= ANY */ - 302, /* (299) vtabargtoken ::= lp anylist RP */ - 303, /* (300) lp ::= LP */ - 267, /* (301) with ::= WITH wqlist */ - 267, /* (302) with ::= WITH RECURSIVE wqlist */ - 306, /* (303) wqas ::= AS */ - 306, /* (304) wqas ::= AS MATERIALIZED */ - 306, /* (305) wqas ::= AS NOT MATERIALIZED */ - 305, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ - 242, /* (307) wqlist ::= wqitem */ - 242, /* (308) wqlist ::= wqlist COMMA wqitem */ - 307, /* (309) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 308, /* (310) windowdefn ::= nm AS LP window RP */ - 309, /* (311) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 309, /* (312) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 309, /* (313) window ::= ORDER BY sortlist frame_opt */ - 309, /* (314) window ::= nm ORDER BY sortlist frame_opt */ - 309, /* (315) window ::= nm frame_opt */ - 310, /* (316) frame_opt ::= */ - 310, /* (317) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 310, /* (318) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 314, /* (319) range_or_rows ::= RANGE|ROWS|GROUPS */ - 316, /* (320) frame_bound_s ::= frame_bound */ - 316, /* (321) frame_bound_s ::= UNBOUNDED PRECEDING */ - 317, /* (322) frame_bound_e ::= frame_bound */ - 317, /* (323) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 315, /* (324) frame_bound ::= expr PRECEDING|FOLLOWING */ - 315, /* (325) frame_bound ::= CURRENT ROW */ - 318, /* (326) frame_exclude_opt ::= */ - 318, /* (327) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 319, /* (328) frame_exclude ::= NO OTHERS */ - 319, /* (329) frame_exclude ::= CURRENT ROW */ - 319, /* (330) frame_exclude ::= GROUP|TIES */ - 252, /* (331) window_clause ::= WINDOW windowdefn_list */ - 274, /* (332) filter_over ::= filter_clause over_clause */ - 274, /* (333) filter_over ::= over_clause */ - 274, /* (334) filter_over ::= filter_clause */ - 313, /* (335) over_clause ::= OVER LP window RP */ - 313, /* (336) over_clause ::= OVER nm */ - 312, /* (337) filter_clause ::= FILTER LP WHERE expr RP */ - 186, /* (338) input ::= cmdlist */ - 187, /* (339) cmdlist ::= cmdlist ecmd */ - 187, /* (340) cmdlist ::= ecmd */ - 188, /* (341) ecmd ::= SEMI */ - 188, /* (342) ecmd ::= cmdx SEMI */ - 188, /* (343) ecmd ::= explain cmdx SEMI */ - 193, /* (344) trans_opt ::= */ - 193, /* (345) trans_opt ::= TRANSACTION */ - 193, /* (346) trans_opt ::= TRANSACTION nm */ - 195, /* (347) savepoint_opt ::= SAVEPOINT */ - 195, /* (348) savepoint_opt ::= */ - 191, /* (349) cmd ::= create_table create_table_args */ - 204, /* (350) table_option_set ::= table_option */ - 202, /* (351) columnlist ::= columnlist COMMA columnname carglist */ - 202, /* (352) columnlist ::= columnname carglist */ - 194, /* (353) nm ::= ID|INDEXED|JOIN_KW */ - 194, /* (354) nm ::= STRING */ - 209, /* (355) typetoken ::= typename */ - 210, /* (356) typename ::= ID|STRING */ - 211, /* (357) signed ::= plus_num */ - 211, /* (358) signed ::= minus_num */ - 208, /* (359) carglist ::= carglist ccons */ - 208, /* (360) carglist ::= */ - 216, /* (361) ccons ::= NULL onconf */ - 216, /* (362) ccons ::= GENERATED ALWAYS AS generated */ - 216, /* (363) ccons ::= AS generated */ - 203, /* (364) conslist_opt ::= COMMA conslist */ - 229, /* (365) conslist ::= conslist tconscomma tcons */ - 229, /* (366) conslist ::= tcons */ - 230, /* (367) tconscomma ::= */ - 234, /* (368) defer_subclause_opt ::= defer_subclause */ - 236, /* (369) resolvetype ::= raisetype */ - 240, /* (370) selectnowith ::= oneselect */ - 241, /* (371) oneselect ::= values */ - 255, /* (372) sclp ::= selcollist COMMA */ - 256, /* (373) as ::= ID|STRING */ - 265, /* (374) indexed_opt ::= indexed_by */ - 273, /* (375) returning ::= */ - 218, /* (376) expr ::= term */ - 275, /* (377) likeop ::= LIKE_KW|MATCH */ - 279, /* (378) case_operand ::= expr */ - 262, /* (379) exprlist ::= nexprlist */ - 285, /* (380) nmnum ::= plus_num */ - 285, /* (381) nmnum ::= nm */ - 285, /* (382) nmnum ::= ON */ - 285, /* (383) nmnum ::= DELETE */ - 285, /* (384) nmnum ::= DEFAULT */ - 212, /* (385) plus_num ::= INTEGER|FLOAT */ - 290, /* (386) foreach_clause ::= */ - 290, /* (387) foreach_clause ::= FOR EACH ROW */ - 293, /* (388) trnm ::= nm */ - 294, /* (389) tridxby ::= */ - 295, /* (390) database_kw_opt ::= DATABASE */ - 295, /* (391) database_kw_opt ::= */ - 298, /* (392) kwcolumn_opt ::= */ - 298, /* (393) kwcolumn_opt ::= COLUMNKW */ - 300, /* (394) vtabarglist ::= vtabarg */ - 300, /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ - 301, /* (396) vtabarg ::= vtabarg vtabargtoken */ - 304, /* (397) anylist ::= */ - 304, /* (398) anylist ::= anylist LP anylist RP */ - 304, /* (399) anylist ::= anylist ANY */ - 267, /* (400) with ::= */ - 307, /* (401) windowdefn_list ::= windowdefn */ - 309, /* (402) window ::= frame_opt */ + 218, /* (178) expr ::= ID|INDEXED */ + 218, /* (179) expr ::= JOIN_KW */ + 218, /* (180) expr ::= nm DOT nm */ + 218, /* (181) expr ::= nm DOT nm DOT nm */ + 217, /* (182) term ::= NULL|FLOAT|BLOB */ + 217, /* (183) term ::= STRING */ + 217, /* (184) term ::= INTEGER */ + 218, /* (185) expr ::= VARIABLE */ + 218, /* (186) expr ::= expr COLLATE ID|STRING */ + 218, /* (187) expr ::= CAST LP expr AS typetoken RP */ + 218, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ + 218, /* (189) expr ::= ID|INDEXED LP STAR RP */ + 218, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + 218, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ + 217, /* (192) term ::= CTIME_KW */ + 218, /* (193) expr ::= LP nexprlist COMMA expr RP */ + 218, /* (194) expr ::= expr AND expr */ + 218, /* (195) expr ::= expr OR expr */ + 218, /* (196) expr ::= expr LT|GT|GE|LE expr */ + 218, /* (197) expr ::= expr EQ|NE expr */ + 218, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 218, /* (199) expr ::= expr PLUS|MINUS expr */ + 218, /* (200) expr ::= expr STAR|SLASH|REM expr */ + 218, /* (201) expr ::= expr CONCAT expr */ + 275, /* (202) likeop ::= NOT LIKE_KW|MATCH */ + 218, /* (203) expr ::= expr likeop expr */ + 218, /* (204) expr ::= expr likeop expr ESCAPE expr */ + 218, /* (205) expr ::= expr ISNULL|NOTNULL */ + 218, /* (206) expr ::= expr NOT NULL */ + 218, /* (207) expr ::= expr IS expr */ + 218, /* (208) expr ::= expr IS NOT expr */ + 218, /* (209) expr ::= expr IS NOT DISTINCT FROM expr */ + 218, /* (210) expr ::= expr IS DISTINCT FROM expr */ + 218, /* (211) expr ::= NOT expr */ + 218, /* (212) expr ::= BITNOT expr */ + 218, /* (213) expr ::= PLUS|MINUS expr */ + 218, /* (214) expr ::= expr PTR expr */ + 276, /* (215) between_op ::= BETWEEN */ + 276, /* (216) between_op ::= NOT BETWEEN */ + 218, /* (217) expr ::= expr between_op expr AND expr */ + 277, /* (218) in_op ::= IN */ + 277, /* (219) in_op ::= NOT IN */ + 218, /* (220) expr ::= expr in_op LP exprlist RP */ + 218, /* (221) expr ::= LP select RP */ + 218, /* (222) expr ::= expr in_op LP select RP */ + 218, /* (223) expr ::= expr in_op nm dbnm paren_exprlist */ + 218, /* (224) expr ::= EXISTS LP select RP */ + 218, /* (225) expr ::= CASE case_operand case_exprlist case_else END */ + 280, /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 280, /* (227) case_exprlist ::= WHEN expr THEN expr */ + 281, /* (228) case_else ::= ELSE expr */ + 281, /* (229) case_else ::= */ + 279, /* (230) case_operand ::= expr */ + 279, /* (231) case_operand ::= */ + 262, /* (232) exprlist ::= */ + 254, /* (233) nexprlist ::= nexprlist COMMA expr */ + 254, /* (234) nexprlist ::= expr */ + 278, /* (235) paren_exprlist ::= */ + 278, /* (236) paren_exprlist ::= LP exprlist RP */ + 191, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 282, /* (238) uniqueflag ::= UNIQUE */ + 282, /* (239) uniqueflag ::= */ + 222, /* (240) eidlist_opt ::= */ + 222, /* (241) eidlist_opt ::= LP eidlist RP */ + 233, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ + 233, /* (243) eidlist ::= nm collate sortorder */ + 283, /* (244) collate ::= */ + 283, /* (245) collate ::= COLLATE ID|STRING */ + 191, /* (246) cmd ::= DROP INDEX ifexists fullname */ + 191, /* (247) cmd ::= VACUUM vinto */ + 191, /* (248) cmd ::= VACUUM nm vinto */ + 284, /* (249) vinto ::= INTO expr */ + 284, /* (250) vinto ::= */ + 191, /* (251) cmd ::= PRAGMA nm dbnm */ + 191, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 191, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 191, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 191, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 212, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ + 213, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ + 191, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 286, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 288, /* (260) trigger_time ::= BEFORE|AFTER */ + 288, /* (261) trigger_time ::= INSTEAD OF */ + 288, /* (262) trigger_time ::= */ + 289, /* (263) trigger_event ::= DELETE|INSERT */ + 289, /* (264) trigger_event ::= UPDATE */ + 289, /* (265) trigger_event ::= UPDATE OF idlist */ + 291, /* (266) when_clause ::= */ + 291, /* (267) when_clause ::= WHEN expr */ + 287, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 287, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ + 293, /* (270) trnm ::= nm DOT nm */ + 294, /* (271) tridxby ::= INDEXED BY nm */ + 294, /* (272) tridxby ::= NOT INDEXED */ + 292, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 292, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 292, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 292, /* (276) trigger_cmd ::= scanpt select scanpt */ + 218, /* (277) expr ::= RAISE LP IGNORE RP */ + 218, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ + 237, /* (279) raisetype ::= ROLLBACK */ + 237, /* (280) raisetype ::= ABORT */ + 237, /* (281) raisetype ::= FAIL */ + 191, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ + 191, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 191, /* (284) cmd ::= DETACH database_kw_opt expr */ + 296, /* (285) key_opt ::= */ + 296, /* (286) key_opt ::= KEY expr */ + 191, /* (287) cmd ::= REINDEX */ + 191, /* (288) cmd ::= REINDEX nm dbnm */ + 191, /* (289) cmd ::= ANALYZE */ + 191, /* (290) cmd ::= ANALYZE nm dbnm */ + 191, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 191, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 191, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 297, /* (294) add_column_fullname ::= fullname */ + 191, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 191, /* (296) cmd ::= create_vtab */ + 191, /* (297) cmd ::= create_vtab LP vtabarglist RP */ + 299, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 301, /* (299) vtabarg ::= */ + 302, /* (300) vtabargtoken ::= ANY */ + 302, /* (301) vtabargtoken ::= lp anylist RP */ + 303, /* (302) lp ::= LP */ + 267, /* (303) with ::= WITH wqlist */ + 267, /* (304) with ::= WITH RECURSIVE wqlist */ + 306, /* (305) wqas ::= AS */ + 306, /* (306) wqas ::= AS MATERIALIZED */ + 306, /* (307) wqas ::= AS NOT MATERIALIZED */ + 305, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ + 242, /* (309) wqlist ::= wqitem */ + 242, /* (310) wqlist ::= wqlist COMMA wqitem */ + 307, /* (311) windowdefn_list ::= windowdefn */ + 307, /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 308, /* (313) windowdefn ::= nm AS LP window RP */ + 309, /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 309, /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 309, /* (316) window ::= ORDER BY sortlist frame_opt */ + 309, /* (317) window ::= nm ORDER BY sortlist frame_opt */ + 309, /* (318) window ::= frame_opt */ + 309, /* (319) window ::= nm frame_opt */ + 310, /* (320) frame_opt ::= */ + 310, /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 310, /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 314, /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */ + 316, /* (324) frame_bound_s ::= frame_bound */ + 316, /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */ + 317, /* (326) frame_bound_e ::= frame_bound */ + 317, /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 315, /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */ + 315, /* (329) frame_bound ::= CURRENT ROW */ + 318, /* (330) frame_exclude_opt ::= */ + 318, /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 319, /* (332) frame_exclude ::= NO OTHERS */ + 319, /* (333) frame_exclude ::= CURRENT ROW */ + 319, /* (334) frame_exclude ::= GROUP|TIES */ + 252, /* (335) window_clause ::= WINDOW windowdefn_list */ + 274, /* (336) filter_over ::= filter_clause over_clause */ + 274, /* (337) filter_over ::= over_clause */ + 274, /* (338) filter_over ::= filter_clause */ + 313, /* (339) over_clause ::= OVER LP window RP */ + 313, /* (340) over_clause ::= OVER nm */ + 312, /* (341) filter_clause ::= FILTER LP WHERE expr RP */ + 186, /* (342) input ::= cmdlist */ + 187, /* (343) cmdlist ::= cmdlist ecmd */ + 187, /* (344) cmdlist ::= ecmd */ + 188, /* (345) ecmd ::= SEMI */ + 188, /* (346) ecmd ::= cmdx SEMI */ + 188, /* (347) ecmd ::= explain cmdx SEMI */ + 193, /* (348) trans_opt ::= */ + 193, /* (349) trans_opt ::= TRANSACTION */ + 193, /* (350) trans_opt ::= TRANSACTION nm */ + 195, /* (351) savepoint_opt ::= SAVEPOINT */ + 195, /* (352) savepoint_opt ::= */ + 191, /* (353) cmd ::= create_table create_table_args */ + 204, /* (354) table_option_set ::= table_option */ + 202, /* (355) columnlist ::= columnlist COMMA columnname carglist */ + 202, /* (356) columnlist ::= columnname carglist */ + 194, /* (357) nm ::= ID|INDEXED */ + 194, /* (358) nm ::= STRING */ + 194, /* (359) nm ::= JOIN_KW */ + 209, /* (360) typetoken ::= typename */ + 210, /* (361) typename ::= ID|STRING */ + 211, /* (362) signed ::= plus_num */ + 211, /* (363) signed ::= minus_num */ + 208, /* (364) carglist ::= carglist ccons */ + 208, /* (365) carglist ::= */ + 216, /* (366) ccons ::= NULL onconf */ + 216, /* (367) ccons ::= GENERATED ALWAYS AS generated */ + 216, /* (368) ccons ::= AS generated */ + 203, /* (369) conslist_opt ::= COMMA conslist */ + 229, /* (370) conslist ::= conslist tconscomma tcons */ + 229, /* (371) conslist ::= tcons */ + 230, /* (372) tconscomma ::= */ + 234, /* (373) defer_subclause_opt ::= defer_subclause */ + 236, /* (374) resolvetype ::= raisetype */ + 240, /* (375) selectnowith ::= oneselect */ + 241, /* (376) oneselect ::= values */ + 255, /* (377) sclp ::= selcollist COMMA */ + 256, /* (378) as ::= ID|STRING */ + 265, /* (379) indexed_opt ::= indexed_by */ + 273, /* (380) returning ::= */ + 218, /* (381) expr ::= term */ + 275, /* (382) likeop ::= LIKE_KW|MATCH */ + 262, /* (383) exprlist ::= nexprlist */ + 285, /* (384) nmnum ::= plus_num */ + 285, /* (385) nmnum ::= nm */ + 285, /* (386) nmnum ::= ON */ + 285, /* (387) nmnum ::= DELETE */ + 285, /* (388) nmnum ::= DEFAULT */ + 212, /* (389) plus_num ::= INTEGER|FLOAT */ + 290, /* (390) foreach_clause ::= */ + 290, /* (391) foreach_clause ::= FOR EACH ROW */ + 293, /* (392) trnm ::= nm */ + 294, /* (393) tridxby ::= */ + 295, /* (394) database_kw_opt ::= DATABASE */ + 295, /* (395) database_kw_opt ::= */ + 298, /* (396) kwcolumn_opt ::= */ + 298, /* (397) kwcolumn_opt ::= COLUMNKW */ + 300, /* (398) vtabarglist ::= vtabarg */ + 300, /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ + 301, /* (400) vtabarg ::= vtabarg vtabargtoken */ + 304, /* (401) anylist ::= */ + 304, /* (402) anylist ::= anylist LP anylist RP */ + 304, /* (403) anylist ::= anylist ANY */ + 267, /* (404) with ::= */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -174667,231 +172544,233 @@ static const signed char yyRuleInfoNRhs[] = { -3, /* (175) idlist ::= idlist COMMA nm */ -1, /* (176) idlist ::= nm */ -3, /* (177) expr ::= LP expr RP */ - -1, /* (178) expr ::= ID|INDEXED|JOIN_KW */ - -3, /* (179) expr ::= nm DOT nm */ - -5, /* (180) expr ::= nm DOT nm DOT nm */ - -1, /* (181) term ::= NULL|FLOAT|BLOB */ - -1, /* (182) term ::= STRING */ - -1, /* (183) term ::= INTEGER */ - -1, /* (184) expr ::= VARIABLE */ - -3, /* (185) expr ::= expr COLLATE ID|STRING */ - -6, /* (186) expr ::= CAST LP expr AS typetoken RP */ - -5, /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ - -4, /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ - -6, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ - -5, /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ - -1, /* (191) term ::= CTIME_KW */ - -5, /* (192) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (193) expr ::= expr AND expr */ - -3, /* (194) expr ::= expr OR expr */ - -3, /* (195) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (196) expr ::= expr EQ|NE expr */ - -3, /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (198) expr ::= expr PLUS|MINUS expr */ - -3, /* (199) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (200) expr ::= expr CONCAT expr */ - -2, /* (201) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (202) expr ::= expr likeop expr */ - -5, /* (203) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (204) expr ::= expr ISNULL|NOTNULL */ - -3, /* (205) expr ::= expr NOT NULL */ - -3, /* (206) expr ::= expr IS expr */ - -4, /* (207) expr ::= expr IS NOT expr */ - -6, /* (208) expr ::= expr IS NOT DISTINCT FROM expr */ - -5, /* (209) expr ::= expr IS DISTINCT FROM expr */ - -2, /* (210) expr ::= NOT expr */ - -2, /* (211) expr ::= BITNOT expr */ - -2, /* (212) expr ::= PLUS|MINUS expr */ - -3, /* (213) expr ::= expr PTR expr */ - -1, /* (214) between_op ::= BETWEEN */ - -2, /* (215) between_op ::= NOT BETWEEN */ - -5, /* (216) expr ::= expr between_op expr AND expr */ - -1, /* (217) in_op ::= IN */ - -2, /* (218) in_op ::= NOT IN */ - -5, /* (219) expr ::= expr in_op LP exprlist RP */ - -3, /* (220) expr ::= LP select RP */ - -5, /* (221) expr ::= expr in_op LP select RP */ - -5, /* (222) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (223) expr ::= EXISTS LP select RP */ - -5, /* (224) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (226) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (227) case_else ::= ELSE expr */ - 0, /* (228) case_else ::= */ - 0, /* (229) case_operand ::= */ - 0, /* (230) exprlist ::= */ - -3, /* (231) nexprlist ::= nexprlist COMMA expr */ - -1, /* (232) nexprlist ::= expr */ - 0, /* (233) paren_exprlist ::= */ - -3, /* (234) paren_exprlist ::= LP exprlist RP */ - -12, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (236) uniqueflag ::= UNIQUE */ - 0, /* (237) uniqueflag ::= */ - 0, /* (238) eidlist_opt ::= */ - -3, /* (239) eidlist_opt ::= LP eidlist RP */ - -5, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (241) eidlist ::= nm collate sortorder */ - 0, /* (242) collate ::= */ - -2, /* (243) collate ::= COLLATE ID|STRING */ - -4, /* (244) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (245) cmd ::= VACUUM vinto */ - -3, /* (246) cmd ::= VACUUM nm vinto */ - -2, /* (247) vinto ::= INTO expr */ - 0, /* (248) vinto ::= */ - -3, /* (249) cmd ::= PRAGMA nm dbnm */ - -5, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (258) trigger_time ::= BEFORE|AFTER */ - -2, /* (259) trigger_time ::= INSTEAD OF */ - 0, /* (260) trigger_time ::= */ - -1, /* (261) trigger_event ::= DELETE|INSERT */ - -1, /* (262) trigger_event ::= UPDATE */ - -3, /* (263) trigger_event ::= UPDATE OF idlist */ - 0, /* (264) when_clause ::= */ - -2, /* (265) when_clause ::= WHEN expr */ - -3, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (268) trnm ::= nm DOT nm */ - -3, /* (269) tridxby ::= INDEXED BY nm */ - -2, /* (270) tridxby ::= NOT INDEXED */ - -9, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (274) trigger_cmd ::= scanpt select scanpt */ - -4, /* (275) expr ::= RAISE LP IGNORE RP */ - -6, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (277) raisetype ::= ROLLBACK */ - -1, /* (278) raisetype ::= ABORT */ - -1, /* (279) raisetype ::= FAIL */ - -4, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (282) cmd ::= DETACH database_kw_opt expr */ - 0, /* (283) key_opt ::= */ - -2, /* (284) key_opt ::= KEY expr */ - -1, /* (285) cmd ::= REINDEX */ - -3, /* (286) cmd ::= REINDEX nm dbnm */ - -1, /* (287) cmd ::= ANALYZE */ - -3, /* (288) cmd ::= ANALYZE nm dbnm */ - -6, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -6, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - -1, /* (292) add_column_fullname ::= fullname */ - -8, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (294) cmd ::= create_vtab */ - -4, /* (295) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (297) vtabarg ::= */ - -1, /* (298) vtabargtoken ::= ANY */ - -3, /* (299) vtabargtoken ::= lp anylist RP */ - -1, /* (300) lp ::= LP */ - -2, /* (301) with ::= WITH wqlist */ - -3, /* (302) with ::= WITH RECURSIVE wqlist */ - -1, /* (303) wqas ::= AS */ - -2, /* (304) wqas ::= AS MATERIALIZED */ - -3, /* (305) wqas ::= AS NOT MATERIALIZED */ - -6, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ - -1, /* (307) wqlist ::= wqitem */ - -3, /* (308) wqlist ::= wqlist COMMA wqitem */ - -3, /* (309) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (310) windowdefn ::= nm AS LP window RP */ - -5, /* (311) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (312) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (313) window ::= ORDER BY sortlist frame_opt */ - -5, /* (314) window ::= nm ORDER BY sortlist frame_opt */ - -2, /* (315) window ::= nm frame_opt */ - 0, /* (316) frame_opt ::= */ - -3, /* (317) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (318) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (319) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (320) frame_bound_s ::= frame_bound */ - -2, /* (321) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (322) frame_bound_e ::= frame_bound */ - -2, /* (323) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (324) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (325) frame_bound ::= CURRENT ROW */ - 0, /* (326) frame_exclude_opt ::= */ - -2, /* (327) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (328) frame_exclude ::= NO OTHERS */ - -2, /* (329) frame_exclude ::= CURRENT ROW */ - -1, /* (330) frame_exclude ::= GROUP|TIES */ - -2, /* (331) window_clause ::= WINDOW windowdefn_list */ - -2, /* (332) filter_over ::= filter_clause over_clause */ - -1, /* (333) filter_over ::= over_clause */ - -1, /* (334) filter_over ::= filter_clause */ - -4, /* (335) over_clause ::= OVER LP window RP */ - -2, /* (336) over_clause ::= OVER nm */ - -5, /* (337) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (338) input ::= cmdlist */ - -2, /* (339) cmdlist ::= cmdlist ecmd */ - -1, /* (340) cmdlist ::= ecmd */ - -1, /* (341) ecmd ::= SEMI */ - -2, /* (342) ecmd ::= cmdx SEMI */ - -3, /* (343) ecmd ::= explain cmdx SEMI */ - 0, /* (344) trans_opt ::= */ - -1, /* (345) trans_opt ::= TRANSACTION */ - -2, /* (346) trans_opt ::= TRANSACTION nm */ - -1, /* (347) savepoint_opt ::= SAVEPOINT */ - 0, /* (348) savepoint_opt ::= */ - -2, /* (349) cmd ::= create_table create_table_args */ - -1, /* (350) table_option_set ::= table_option */ - -4, /* (351) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (352) columnlist ::= columnname carglist */ - -1, /* (353) nm ::= ID|INDEXED|JOIN_KW */ - -1, /* (354) nm ::= STRING */ - -1, /* (355) typetoken ::= typename */ - -1, /* (356) typename ::= ID|STRING */ - -1, /* (357) signed ::= plus_num */ - -1, /* (358) signed ::= minus_num */ - -2, /* (359) carglist ::= carglist ccons */ - 0, /* (360) carglist ::= */ - -2, /* (361) ccons ::= NULL onconf */ - -4, /* (362) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (363) ccons ::= AS generated */ - -2, /* (364) conslist_opt ::= COMMA conslist */ - -3, /* (365) conslist ::= conslist tconscomma tcons */ - -1, /* (366) conslist ::= tcons */ - 0, /* (367) tconscomma ::= */ - -1, /* (368) defer_subclause_opt ::= defer_subclause */ - -1, /* (369) resolvetype ::= raisetype */ - -1, /* (370) selectnowith ::= oneselect */ - -1, /* (371) oneselect ::= values */ - -2, /* (372) sclp ::= selcollist COMMA */ - -1, /* (373) as ::= ID|STRING */ - -1, /* (374) indexed_opt ::= indexed_by */ - 0, /* (375) returning ::= */ - -1, /* (376) expr ::= term */ - -1, /* (377) likeop ::= LIKE_KW|MATCH */ - -1, /* (378) case_operand ::= expr */ - -1, /* (379) exprlist ::= nexprlist */ - -1, /* (380) nmnum ::= plus_num */ - -1, /* (381) nmnum ::= nm */ - -1, /* (382) nmnum ::= ON */ - -1, /* (383) nmnum ::= DELETE */ - -1, /* (384) nmnum ::= DEFAULT */ - -1, /* (385) plus_num ::= INTEGER|FLOAT */ - 0, /* (386) foreach_clause ::= */ - -3, /* (387) foreach_clause ::= FOR EACH ROW */ - -1, /* (388) trnm ::= nm */ - 0, /* (389) tridxby ::= */ - -1, /* (390) database_kw_opt ::= DATABASE */ - 0, /* (391) database_kw_opt ::= */ - 0, /* (392) kwcolumn_opt ::= */ - -1, /* (393) kwcolumn_opt ::= COLUMNKW */ - -1, /* (394) vtabarglist ::= vtabarg */ - -3, /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (396) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (397) anylist ::= */ - -4, /* (398) anylist ::= anylist LP anylist RP */ - -2, /* (399) anylist ::= anylist ANY */ - 0, /* (400) with ::= */ - -1, /* (401) windowdefn_list ::= windowdefn */ - -1, /* (402) window ::= frame_opt */ + -1, /* (178) expr ::= ID|INDEXED */ + -1, /* (179) expr ::= JOIN_KW */ + -3, /* (180) expr ::= nm DOT nm */ + -5, /* (181) expr ::= nm DOT nm DOT nm */ + -1, /* (182) term ::= NULL|FLOAT|BLOB */ + -1, /* (183) term ::= STRING */ + -1, /* (184) term ::= INTEGER */ + -1, /* (185) expr ::= VARIABLE */ + -3, /* (186) expr ::= expr COLLATE ID|STRING */ + -6, /* (187) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ + -4, /* (189) expr ::= ID|INDEXED LP STAR RP */ + -6, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + -5, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ + -1, /* (192) term ::= CTIME_KW */ + -5, /* (193) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (194) expr ::= expr AND expr */ + -3, /* (195) expr ::= expr OR expr */ + -3, /* (196) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (197) expr ::= expr EQ|NE expr */ + -3, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (199) expr ::= expr PLUS|MINUS expr */ + -3, /* (200) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (201) expr ::= expr CONCAT expr */ + -2, /* (202) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (203) expr ::= expr likeop expr */ + -5, /* (204) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (205) expr ::= expr ISNULL|NOTNULL */ + -3, /* (206) expr ::= expr NOT NULL */ + -3, /* (207) expr ::= expr IS expr */ + -4, /* (208) expr ::= expr IS NOT expr */ + -6, /* (209) expr ::= expr IS NOT DISTINCT FROM expr */ + -5, /* (210) expr ::= expr IS DISTINCT FROM expr */ + -2, /* (211) expr ::= NOT expr */ + -2, /* (212) expr ::= BITNOT expr */ + -2, /* (213) expr ::= PLUS|MINUS expr */ + -3, /* (214) expr ::= expr PTR expr */ + -1, /* (215) between_op ::= BETWEEN */ + -2, /* (216) between_op ::= NOT BETWEEN */ + -5, /* (217) expr ::= expr between_op expr AND expr */ + -1, /* (218) in_op ::= IN */ + -2, /* (219) in_op ::= NOT IN */ + -5, /* (220) expr ::= expr in_op LP exprlist RP */ + -3, /* (221) expr ::= LP select RP */ + -5, /* (222) expr ::= expr in_op LP select RP */ + -5, /* (223) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (224) expr ::= EXISTS LP select RP */ + -5, /* (225) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (227) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (228) case_else ::= ELSE expr */ + 0, /* (229) case_else ::= */ + -1, /* (230) case_operand ::= expr */ + 0, /* (231) case_operand ::= */ + 0, /* (232) exprlist ::= */ + -3, /* (233) nexprlist ::= nexprlist COMMA expr */ + -1, /* (234) nexprlist ::= expr */ + 0, /* (235) paren_exprlist ::= */ + -3, /* (236) paren_exprlist ::= LP exprlist RP */ + -12, /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (238) uniqueflag ::= UNIQUE */ + 0, /* (239) uniqueflag ::= */ + 0, /* (240) eidlist_opt ::= */ + -3, /* (241) eidlist_opt ::= LP eidlist RP */ + -5, /* (242) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (243) eidlist ::= nm collate sortorder */ + 0, /* (244) collate ::= */ + -2, /* (245) collate ::= COLLATE ID|STRING */ + -4, /* (246) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (247) cmd ::= VACUUM vinto */ + -3, /* (248) cmd ::= VACUUM nm vinto */ + -2, /* (249) vinto ::= INTO expr */ + 0, /* (250) vinto ::= */ + -3, /* (251) cmd ::= PRAGMA nm dbnm */ + -5, /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (256) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (257) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (260) trigger_time ::= BEFORE|AFTER */ + -2, /* (261) trigger_time ::= INSTEAD OF */ + 0, /* (262) trigger_time ::= */ + -1, /* (263) trigger_event ::= DELETE|INSERT */ + -1, /* (264) trigger_event ::= UPDATE */ + -3, /* (265) trigger_event ::= UPDATE OF idlist */ + 0, /* (266) when_clause ::= */ + -2, /* (267) when_clause ::= WHEN expr */ + -3, /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (269) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (270) trnm ::= nm DOT nm */ + -3, /* (271) tridxby ::= INDEXED BY nm */ + -2, /* (272) tridxby ::= NOT INDEXED */ + -9, /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (276) trigger_cmd ::= scanpt select scanpt */ + -4, /* (277) expr ::= RAISE LP IGNORE RP */ + -6, /* (278) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (279) raisetype ::= ROLLBACK */ + -1, /* (280) raisetype ::= ABORT */ + -1, /* (281) raisetype ::= FAIL */ + -4, /* (282) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (284) cmd ::= DETACH database_kw_opt expr */ + 0, /* (285) key_opt ::= */ + -2, /* (286) key_opt ::= KEY expr */ + -1, /* (287) cmd ::= REINDEX */ + -3, /* (288) cmd ::= REINDEX nm dbnm */ + -1, /* (289) cmd ::= ANALYZE */ + -3, /* (290) cmd ::= ANALYZE nm dbnm */ + -6, /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (294) add_column_fullname ::= fullname */ + -8, /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (296) cmd ::= create_vtab */ + -4, /* (297) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (299) vtabarg ::= */ + -1, /* (300) vtabargtoken ::= ANY */ + -3, /* (301) vtabargtoken ::= lp anylist RP */ + -1, /* (302) lp ::= LP */ + -2, /* (303) with ::= WITH wqlist */ + -3, /* (304) with ::= WITH RECURSIVE wqlist */ + -1, /* (305) wqas ::= AS */ + -2, /* (306) wqas ::= AS MATERIALIZED */ + -3, /* (307) wqas ::= AS NOT MATERIALIZED */ + -6, /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (309) wqlist ::= wqitem */ + -3, /* (310) wqlist ::= wqlist COMMA wqitem */ + -1, /* (311) windowdefn_list ::= windowdefn */ + -3, /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (313) windowdefn ::= nm AS LP window RP */ + -5, /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (316) window ::= ORDER BY sortlist frame_opt */ + -5, /* (317) window ::= nm ORDER BY sortlist frame_opt */ + -1, /* (318) window ::= frame_opt */ + -2, /* (319) window ::= nm frame_opt */ + 0, /* (320) frame_opt ::= */ + -3, /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (324) frame_bound_s ::= frame_bound */ + -2, /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (326) frame_bound_e ::= frame_bound */ + -2, /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (329) frame_bound ::= CURRENT ROW */ + 0, /* (330) frame_exclude_opt ::= */ + -2, /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (332) frame_exclude ::= NO OTHERS */ + -2, /* (333) frame_exclude ::= CURRENT ROW */ + -1, /* (334) frame_exclude ::= GROUP|TIES */ + -2, /* (335) window_clause ::= WINDOW windowdefn_list */ + -2, /* (336) filter_over ::= filter_clause over_clause */ + -1, /* (337) filter_over ::= over_clause */ + -1, /* (338) filter_over ::= filter_clause */ + -4, /* (339) over_clause ::= OVER LP window RP */ + -2, /* (340) over_clause ::= OVER nm */ + -5, /* (341) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (342) input ::= cmdlist */ + -2, /* (343) cmdlist ::= cmdlist ecmd */ + -1, /* (344) cmdlist ::= ecmd */ + -1, /* (345) ecmd ::= SEMI */ + -2, /* (346) ecmd ::= cmdx SEMI */ + -3, /* (347) ecmd ::= explain cmdx SEMI */ + 0, /* (348) trans_opt ::= */ + -1, /* (349) trans_opt ::= TRANSACTION */ + -2, /* (350) trans_opt ::= TRANSACTION nm */ + -1, /* (351) savepoint_opt ::= SAVEPOINT */ + 0, /* (352) savepoint_opt ::= */ + -2, /* (353) cmd ::= create_table create_table_args */ + -1, /* (354) table_option_set ::= table_option */ + -4, /* (355) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (356) columnlist ::= columnname carglist */ + -1, /* (357) nm ::= ID|INDEXED */ + -1, /* (358) nm ::= STRING */ + -1, /* (359) nm ::= JOIN_KW */ + -1, /* (360) typetoken ::= typename */ + -1, /* (361) typename ::= ID|STRING */ + -1, /* (362) signed ::= plus_num */ + -1, /* (363) signed ::= minus_num */ + -2, /* (364) carglist ::= carglist ccons */ + 0, /* (365) carglist ::= */ + -2, /* (366) ccons ::= NULL onconf */ + -4, /* (367) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (368) ccons ::= AS generated */ + -2, /* (369) conslist_opt ::= COMMA conslist */ + -3, /* (370) conslist ::= conslist tconscomma tcons */ + -1, /* (371) conslist ::= tcons */ + 0, /* (372) tconscomma ::= */ + -1, /* (373) defer_subclause_opt ::= defer_subclause */ + -1, /* (374) resolvetype ::= raisetype */ + -1, /* (375) selectnowith ::= oneselect */ + -1, /* (376) oneselect ::= values */ + -2, /* (377) sclp ::= selcollist COMMA */ + -1, /* (378) as ::= ID|STRING */ + -1, /* (379) indexed_opt ::= indexed_by */ + 0, /* (380) returning ::= */ + -1, /* (381) expr ::= term */ + -1, /* (382) likeop ::= LIKE_KW|MATCH */ + -1, /* (383) exprlist ::= nexprlist */ + -1, /* (384) nmnum ::= plus_num */ + -1, /* (385) nmnum ::= nm */ + -1, /* (386) nmnum ::= ON */ + -1, /* (387) nmnum ::= DELETE */ + -1, /* (388) nmnum ::= DEFAULT */ + -1, /* (389) plus_num ::= INTEGER|FLOAT */ + 0, /* (390) foreach_clause ::= */ + -3, /* (391) foreach_clause ::= FOR EACH ROW */ + -1, /* (392) trnm ::= nm */ + 0, /* (393) tridxby ::= */ + -1, /* (394) database_kw_opt ::= DATABASE */ + 0, /* (395) database_kw_opt ::= */ + 0, /* (396) kwcolumn_opt ::= */ + -1, /* (397) kwcolumn_opt ::= COLUMNKW */ + -1, /* (398) vtabarglist ::= vtabarg */ + -3, /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (400) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (401) anylist ::= */ + -4, /* (402) anylist ::= anylist LP anylist RP */ + -2, /* (403) anylist ::= anylist ANY */ + 0, /* (404) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -174934,10 +172813,10 @@ static YYACTIONTYPE yy_reduce( /********** Begin reduce actions **********************************************/ YYMINORTYPE yylhsminor; case 0: /* explain ::= EXPLAIN */ -{ if( pParse->pReprepare==0 ) pParse->explain = 1; } +{ pParse->explain = 1; } break; case 1: /* explain ::= EXPLAIN QUERY PLAN */ -{ if( pParse->pReprepare==0 ) pParse->explain = 2; } +{ pParse->explain = 2; } break; case 2: /* cmdx ::= cmd */ { sqlite3FinishCoding(pParse); } @@ -174950,7 +172829,7 @@ static YYACTIONTYPE yy_reduce( break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); - case 319: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==319); + case 323: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==323); {yymsp[0].minor.yy92 = yymsp[0].major; /*A-overwrites-X*/} break; case 7: /* transtype ::= ID */ @@ -174999,7 +172878,7 @@ static YYACTIONTYPE yy_reduce( case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); case 81: /* ifexists ::= */ yytestcase(yyruleno==81); case 98: /* distinct ::= */ yytestcase(yyruleno==98); - case 242: /* collate ::= */ yytestcase(yyruleno==242); + case 244: /* collate ::= */ yytestcase(yyruleno==244); {yymsp[1].minor.yy92 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ @@ -175183,9 +173062,9 @@ static YYACTIONTYPE yy_reduce( break; case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); - case 215: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==215); - case 218: /* in_op ::= NOT IN */ yytestcase(yyruleno==218); - case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243); + case 216: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==216); + case 219: /* in_op ::= NOT IN */ yytestcase(yyruleno==219); + case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245); {yymsp[-1].minor.yy92 = 1;} break; case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ @@ -175258,6 +173137,7 @@ static YYACTIONTYPE yy_reduce( if( p ){ parserDoubleLinkSelect(pParse, p); } + yymsp[0].minor.yy299 = p; /*A-overwrites-X*/ } break; case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ @@ -175334,9 +173214,9 @@ static YYACTIONTYPE yy_reduce( case 99: /* sclp ::= */ case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); - case 230: /* exprlist ::= */ yytestcase(yyruleno==230); - case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233); - case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238); + case 232: /* exprlist ::= */ yytestcase(yyruleno==232); + case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235); + case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240); {yymsp[1].minor.yy402 = 0;} break; case 100: /* selcollist ::= sclp scanpt expr scanpt as */ @@ -175349,24 +173229,21 @@ static YYACTIONTYPE yy_reduce( case 101: /* 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); } break; case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ { - Expr *pRight, *pLeft, *pDot; - pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); - 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); + Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); + Expr *pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); + Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, pDot); } break; case 103: /* as ::= AS nm */ case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115); - case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254); - case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255); + case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256); + case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 105: /* from ::= */ @@ -175410,7 +173287,7 @@ static YYACTIONTYPE yy_reduce( { if( yymsp[-5].minor.yy387==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy305.pOn==0 && yymsp[0].minor.yy305.pUsing==0 ){ yymsp[-5].minor.yy387 = yymsp[-3].minor.yy387; - }else if( ALWAYS(yymsp[-3].minor.yy387!=0) && yymsp[-3].minor.yy387->nSrc==1 ){ + }else if( yymsp[-3].minor.yy387->nSrc==1 ){ yymsp[-5].minor.yy387 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy387,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy305); if( yymsp[-5].minor.yy387 ){ SrcItem *pNew = &yymsp[-5].minor.yy387->a[yymsp[-5].minor.yy387->nSrc-1]; @@ -175538,16 +173415,16 @@ static YYACTIONTYPE yy_reduce( case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); case 151: /* where_opt ::= */ yytestcase(yyruleno==151); case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); - case 228: /* case_else ::= */ yytestcase(yyruleno==228); - case 229: /* case_operand ::= */ yytestcase(yyruleno==229); - case 248: /* vinto ::= */ yytestcase(yyruleno==248); + case 229: /* case_else ::= */ yytestcase(yyruleno==229); + case 231: /* case_operand ::= */ yytestcase(yyruleno==231); + case 250: /* vinto ::= */ yytestcase(yyruleno==250); {yymsp[1].minor.yy2 = 0;} break; case 145: /* having_opt ::= HAVING expr */ case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); - case 227: /* case_else ::= ELSE expr */ yytestcase(yyruleno==227); - case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247); + case 228: /* case_else ::= ELSE expr */ yytestcase(yyruleno==228); + case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249); {yymsp[-1].minor.yy2 = yymsp[0].minor.yy2;} break; case 147: /* limit_opt ::= LIMIT expr */ @@ -175673,10 +173550,11 @@ static YYACTIONTYPE yy_reduce( case 177: /* expr ::= LP expr RP */ {yymsp[-2].minor.yy2 = yymsp[-1].minor.yy2;} break; - case 178: /* expr ::= ID|INDEXED|JOIN_KW */ + case 178: /* expr ::= ID|INDEXED */ + case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179); {yymsp[0].minor.yy2=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 179: /* expr ::= nm DOT nm */ + case 180: /* expr ::= nm DOT nm */ { Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); @@ -175684,7 +173562,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy2 = yylhsminor.yy2; break; - case 180: /* expr ::= nm DOT nm DOT nm */ + case 181: /* expr ::= nm DOT nm DOT nm */ { Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); @@ -175697,18 +173575,18 @@ static YYACTIONTYPE yy_reduce( } yymsp[-4].minor.yy2 = yylhsminor.yy2; break; - case 181: /* term ::= NULL|FLOAT|BLOB */ - case 182: /* term ::= STRING */ yytestcase(yyruleno==182); + case 182: /* term ::= NULL|FLOAT|BLOB */ + case 183: /* term ::= STRING */ yytestcase(yyruleno==183); {yymsp[0].minor.yy2=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 183: /* term ::= INTEGER */ + case 184: /* term ::= INTEGER */ { yylhsminor.yy2 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); if( yylhsminor.yy2 ) yylhsminor.yy2->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); } yymsp[0].minor.yy2 = yylhsminor.yy2; break; - case 184: /* expr ::= VARIABLE */ + case 185: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; @@ -175730,50 +173608,50 @@ static YYACTIONTYPE yy_reduce( } } break; - case 185: /* expr ::= expr COLLATE ID|STRING */ + case 186: /* expr ::= expr COLLATE ID|STRING */ { yymsp[-2].minor.yy2 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy2, &yymsp[0].minor.yy0, 1); } break; - case 186: /* expr ::= CAST LP expr AS typetoken RP */ + case 187: /* expr ::= CAST LP expr AS typetoken RP */ { yymsp[-5].minor.yy2 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy2, yymsp[-3].minor.yy2, 0); } break; - case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { yylhsminor.yy2 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy92); } yymsp[-4].minor.yy2 = yylhsminor.yy2; break; - case 188: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + case 189: /* expr ::= ID|INDEXED LP STAR RP */ { yylhsminor.yy2 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } yymsp[-3].minor.yy2 = yylhsminor.yy2; break; - case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + case 190: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ { yylhsminor.yy2 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy402, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy92); sqlite3WindowAttach(pParse, yylhsminor.yy2, yymsp[0].minor.yy3); } yymsp[-5].minor.yy2 = yylhsminor.yy2; break; - case 190: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + case 191: /* expr ::= ID|INDEXED LP STAR RP filter_over */ { yylhsminor.yy2 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); sqlite3WindowAttach(pParse, yylhsminor.yy2, yymsp[0].minor.yy3); } yymsp[-4].minor.yy2 = yylhsminor.yy2; break; - case 191: /* term ::= CTIME_KW */ + case 192: /* term ::= CTIME_KW */ { yylhsminor.yy2 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } yymsp[0].minor.yy2 = yylhsminor.yy2; break; - case 192: /* expr ::= LP nexprlist COMMA expr RP */ + case 193: /* expr ::= LP nexprlist COMMA expr RP */ { ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy402, yymsp[-1].minor.yy2); yymsp[-4].minor.yy2 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); @@ -175787,22 +173665,22 @@ static YYACTIONTYPE yy_reduce( } } break; - case 193: /* expr ::= expr AND expr */ + case 194: /* expr ::= expr AND expr */ {yymsp[-2].minor.yy2=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy2,yymsp[0].minor.yy2);} break; - case 194: /* expr ::= expr OR expr */ - case 195: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==195); - case 196: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==196); - case 197: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==197); - case 198: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==198); - case 199: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==199); - case 200: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==200); + case 195: /* expr ::= expr OR expr */ + case 196: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==196); + case 197: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==197); + case 198: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==198); + case 199: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==201); {yymsp[-2].minor.yy2=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy2,yymsp[0].minor.yy2);} break; - case 201: /* likeop ::= NOT LIKE_KW|MATCH */ + case 202: /* 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*/} break; - case 202: /* expr ::= expr likeop expr */ + case 203: /* expr ::= expr likeop expr */ { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; @@ -175814,7 +173692,7 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-2].minor.yy2 ) yymsp[-2].minor.yy2->flags |= EP_InfixFunc; } break; - case 203: /* expr ::= expr likeop expr ESCAPE expr */ + case 204: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; @@ -175827,47 +173705,47 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-4].minor.yy2 ) yymsp[-4].minor.yy2->flags |= EP_InfixFunc; } break; - case 204: /* expr ::= expr ISNULL|NOTNULL */ + case 205: /* expr ::= expr ISNULL|NOTNULL */ {yymsp[-1].minor.yy2 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy2,0);} break; - case 205: /* expr ::= expr NOT NULL */ + case 206: /* expr ::= expr NOT NULL */ {yymsp[-2].minor.yy2 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy2,0);} break; - case 206: /* expr ::= expr IS expr */ + case 207: /* expr ::= expr IS expr */ { yymsp[-2].minor.yy2 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy2,yymsp[0].minor.yy2); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy2, yymsp[-2].minor.yy2, TK_ISNULL); } break; - case 207: /* expr ::= expr IS NOT expr */ + case 208: /* expr ::= expr IS NOT expr */ { yymsp[-3].minor.yy2 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy2,yymsp[0].minor.yy2); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy2, yymsp[-3].minor.yy2, TK_NOTNULL); } break; - case 208: /* expr ::= expr IS NOT DISTINCT FROM expr */ + case 209: /* expr ::= expr IS NOT DISTINCT FROM expr */ { yymsp[-5].minor.yy2 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy2,yymsp[0].minor.yy2); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy2, yymsp[-5].minor.yy2, TK_ISNULL); } break; - case 209: /* expr ::= expr IS DISTINCT FROM expr */ + case 210: /* expr ::= expr IS DISTINCT FROM expr */ { yymsp[-4].minor.yy2 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy2,yymsp[0].minor.yy2); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy2, yymsp[-4].minor.yy2, TK_NOTNULL); } break; - case 210: /* expr ::= NOT expr */ - case 211: /* expr ::= BITNOT expr */ yytestcase(yyruleno==211); + case 211: /* expr ::= NOT expr */ + case 212: /* expr ::= BITNOT expr */ yytestcase(yyruleno==212); {yymsp[-1].minor.yy2 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy2, 0);/*A-overwrites-B*/} break; - case 212: /* expr ::= PLUS|MINUS expr */ + case 213: /* expr ::= PLUS|MINUS expr */ { yymsp[-1].minor.yy2 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy2, 0); /*A-overwrites-B*/ } break; - case 213: /* expr ::= expr PTR expr */ + case 214: /* expr ::= expr PTR expr */ { ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy2); pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy2); @@ -175875,11 +173753,11 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy2 = yylhsminor.yy2; break; - case 214: /* between_op ::= BETWEEN */ - case 217: /* in_op ::= IN */ yytestcase(yyruleno==217); + case 215: /* between_op ::= BETWEEN */ + case 218: /* in_op ::= IN */ yytestcase(yyruleno==218); {yymsp[0].minor.yy92 = 0;} break; - case 216: /* expr ::= expr between_op expr AND expr */ + case 217: /* expr ::= expr between_op expr AND expr */ { ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy2); pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy2); @@ -175892,7 +173770,7 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-3].minor.yy92 ) yymsp[-4].minor.yy2 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy2, 0); } break; - case 219: /* expr ::= expr in_op LP exprlist RP */ + case 220: /* expr ::= expr in_op LP exprlist RP */ { if( yymsp[-1].minor.yy402==0 ){ /* Expressions of the form @@ -175938,20 +173816,20 @@ static YYACTIONTYPE yy_reduce( } } break; - case 220: /* expr ::= LP select RP */ + case 221: /* expr ::= LP select RP */ { yymsp[-2].minor.yy2 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy2, yymsp[-1].minor.yy299); } break; - case 221: /* expr ::= expr in_op LP select RP */ + case 222: /* expr ::= expr in_op LP select RP */ { yymsp[-4].minor.yy2 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy2, 0); sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy2, yymsp[-1].minor.yy299); if( yymsp[-3].minor.yy92 ) yymsp[-4].minor.yy2 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy2, 0); } break; - case 222: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 223: /* 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); @@ -175961,14 +173839,14 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-3].minor.yy92 ) yymsp[-4].minor.yy2 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy2, 0); } break; - case 223: /* expr ::= EXISTS LP select RP */ + case 224: /* expr ::= EXISTS LP select RP */ { Expr *p; p = yymsp[-3].minor.yy2 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy299); } break; - case 224: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 225: /* expr ::= CASE case_operand case_exprlist case_else END */ { yymsp[-4].minor.yy2 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy2, 0); if( yymsp[-4].minor.yy2 ){ @@ -175980,29 +173858,32 @@ static YYACTIONTYPE yy_reduce( } } break; - case 225: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 226: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[-2].minor.yy2); yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[0].minor.yy2); } break; - case 226: /* case_exprlist ::= WHEN expr THEN expr */ + case 227: /* case_exprlist ::= WHEN expr THEN expr */ { yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy2); yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy402, yymsp[0].minor.yy2); } break; - case 231: /* nexprlist ::= nexprlist COMMA expr */ + case 230: /* case_operand ::= expr */ +{yymsp[0].minor.yy2 = yymsp[0].minor.yy2; /*A-overwrites-X*/} + break; + case 233: /* nexprlist ::= nexprlist COMMA expr */ {yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[0].minor.yy2);} break; - case 232: /* nexprlist ::= expr */ + case 234: /* nexprlist ::= expr */ {yymsp[0].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy2); /*A-overwrites-Y*/} break; - case 234: /* paren_exprlist ::= LP exprlist RP */ - case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239); + case 236: /* paren_exprlist ::= LP exprlist RP */ + case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241); {yymsp[-2].minor.yy402 = yymsp[-1].minor.yy402;} break; - case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 237: /* 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.yy92, @@ -176012,48 +173893,48 @@ static YYACTIONTYPE yy_reduce( } } break; - case 236: /* uniqueflag ::= UNIQUE */ - case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278); + case 238: /* uniqueflag ::= UNIQUE */ + case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280); {yymsp[0].minor.yy92 = OE_Abort;} break; - case 237: /* uniqueflag ::= */ + case 239: /* uniqueflag ::= */ {yymsp[1].minor.yy92 = OE_None;} break; - case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */ { yymsp[-4].minor.yy402 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy92, yymsp[0].minor.yy92); } break; - case 241: /* eidlist ::= nm collate sortorder */ + case 243: /* eidlist ::= nm collate sortorder */ { yymsp[-2].minor.yy402 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy92, yymsp[0].minor.yy92); /*A-overwrites-Y*/ } break; - case 244: /* cmd ::= DROP INDEX ifexists fullname */ + case 246: /* cmd ::= DROP INDEX ifexists fullname */ {sqlite3DropIndex(pParse, yymsp[0].minor.yy387, yymsp[-1].minor.yy92);} break; - case 245: /* cmd ::= VACUUM vinto */ + case 247: /* cmd ::= VACUUM vinto */ {sqlite3Vacuum(pParse,0,yymsp[0].minor.yy2);} break; - case 246: /* cmd ::= VACUUM nm vinto */ + case 248: /* cmd ::= VACUUM nm vinto */ {sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy2);} break; - case 249: /* cmd ::= PRAGMA nm dbnm */ + case 251: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; @@ -176061,50 +173942,50 @@ static YYACTIONTYPE yy_reduce( sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy347, &all); } break; - case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 259: /* 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.yy92, yymsp[-4].minor.yy210.a, yymsp[-4].minor.yy210.b, yymsp[-2].minor.yy387, yymsp[0].minor.yy2, yymsp[-10].minor.yy92, yymsp[-8].minor.yy92); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 258: /* trigger_time ::= BEFORE|AFTER */ + case 260: /* trigger_time ::= BEFORE|AFTER */ { yymsp[0].minor.yy92 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 259: /* trigger_time ::= INSTEAD OF */ + case 261: /* trigger_time ::= INSTEAD OF */ { yymsp[-1].minor.yy92 = TK_INSTEAD;} break; - case 260: /* trigger_time ::= */ + case 262: /* trigger_time ::= */ { yymsp[1].minor.yy92 = TK_BEFORE; } break; - case 261: /* trigger_event ::= DELETE|INSERT */ - case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262); + case 263: /* trigger_event ::= DELETE|INSERT */ + case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264); {yymsp[0].minor.yy210.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy210.b = 0;} break; - case 263: /* trigger_event ::= UPDATE OF idlist */ + case 265: /* trigger_event ::= UPDATE OF idlist */ {yymsp[-2].minor.yy210.a = TK_UPDATE; yymsp[-2].minor.yy210.b = yymsp[0].minor.yy400;} break; - case 264: /* when_clause ::= */ - case 283: /* key_opt ::= */ yytestcase(yyruleno==283); + case 266: /* when_clause ::= */ + case 285: /* key_opt ::= */ yytestcase(yyruleno==285); { yymsp[1].minor.yy2 = 0; } break; - case 265: /* when_clause ::= WHEN expr */ - case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284); + case 267: /* when_clause ::= WHEN expr */ + case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286); { yymsp[-1].minor.yy2 = yymsp[0].minor.yy2; } break; - case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { assert( yymsp[-2].minor.yy347!=0 ); yymsp[-2].minor.yy347->pLast->pNext = yymsp[-1].minor.yy347; yymsp[-2].minor.yy347->pLast = yymsp[-1].minor.yy347; } break; - case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */ { assert( yymsp[-1].minor.yy347!=0 ); yymsp[-1].minor.yy347->pLast = yymsp[-1].minor.yy347; } break; - case 268: /* trnm ::= nm DOT nm */ + case 270: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -176112,39 +173993,39 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 269: /* tridxby ::= INDEXED BY nm */ + case 271: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 270: /* tridxby ::= NOT INDEXED */ + case 272: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ {yylhsminor.yy347 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy387, yymsp[-3].minor.yy402, yymsp[-1].minor.yy2, yymsp[-7].minor.yy92, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy616);} yymsp[-8].minor.yy347 = yylhsminor.yy347; break; - case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { yylhsminor.yy347 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy400,yymsp[-2].minor.yy299,yymsp[-6].minor.yy92,yymsp[-1].minor.yy258,yymsp[-7].minor.yy616,yymsp[0].minor.yy616);/*yylhsminor.yy347-overwrites-yymsp[-6].minor.yy92*/ } yymsp[-7].minor.yy347 = yylhsminor.yy347; break; - case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ {yylhsminor.yy347 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy2, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy616);} yymsp[-5].minor.yy347 = yylhsminor.yy347; break; - case 274: /* trigger_cmd ::= scanpt select scanpt */ + case 276: /* trigger_cmd ::= scanpt select scanpt */ {yylhsminor.yy347 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy299, yymsp[-2].minor.yy616, yymsp[0].minor.yy616); /*yylhsminor.yy347-overwrites-yymsp[-1].minor.yy299*/} yymsp[-2].minor.yy347 = yylhsminor.yy347; break; - case 275: /* expr ::= RAISE LP IGNORE RP */ + case 277: /* expr ::= RAISE LP IGNORE RP */ { yymsp[-3].minor.yy2 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( yymsp[-3].minor.yy2 ){ @@ -176152,7 +174033,7 @@ static YYACTIONTYPE yy_reduce( } } break; - case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */ { yymsp[-5].minor.yy2 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); if( yymsp[-5].minor.yy2 ) { @@ -176160,114 +174041,118 @@ static YYACTIONTYPE yy_reduce( } } break; - case 277: /* raisetype ::= ROLLBACK */ + case 279: /* raisetype ::= ROLLBACK */ {yymsp[0].minor.yy92 = OE_Rollback;} break; - case 279: /* raisetype ::= FAIL */ + case 281: /* raisetype ::= FAIL */ {yymsp[0].minor.yy92 = OE_Fail;} break; - case 280: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 282: /* cmd ::= DROP TRIGGER ifexists fullname */ { sqlite3DropTrigger(pParse,yymsp[0].minor.yy387,yymsp[-1].minor.yy92); } break; - case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { sqlite3Attach(pParse, yymsp[-3].minor.yy2, yymsp[-1].minor.yy2, yymsp[0].minor.yy2); } break; - case 282: /* cmd ::= DETACH database_kw_opt expr */ + case 284: /* cmd ::= DETACH database_kw_opt expr */ { sqlite3Detach(pParse, yymsp[0].minor.yy2); } break; - case 285: /* cmd ::= REINDEX */ + case 287: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 286: /* cmd ::= REINDEX nm dbnm */ + case 288: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 287: /* cmd ::= ANALYZE */ + case 289: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 288: /* cmd ::= ANALYZE nm dbnm */ + case 290: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy387,&yymsp[0].minor.yy0); } break; - case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname 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 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ { sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy387, &yymsp[0].minor.yy0); } break; - case 292: /* add_column_fullname ::= fullname */ + case 294: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy387); } break; - case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy387, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 294: /* cmd ::= create_vtab */ + case 296: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 295: /* cmd ::= create_vtab LP vtabarglist RP */ + case 297: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 298: /* 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.yy92); } break; - case 297: /* vtabarg ::= */ + case 299: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 298: /* vtabargtoken ::= ANY */ - case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299); - case 300: /* lp ::= LP */ yytestcase(yyruleno==300); + case 300: /* vtabargtoken ::= ANY */ + case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301); + case 302: /* lp ::= LP */ yytestcase(yyruleno==302); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 301: /* with ::= WITH wqlist */ - case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302); + case 303: /* with ::= WITH wqlist */ + case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304); { sqlite3WithPush(pParse, yymsp[0].minor.yy131, 1); } break; - case 303: /* wqas ::= AS */ + case 305: /* wqas ::= AS */ {yymsp[0].minor.yy498 = M10d_Any;} break; - case 304: /* wqas ::= AS MATERIALIZED */ + case 306: /* wqas ::= AS MATERIALIZED */ {yymsp[-1].minor.yy498 = M10d_Yes;} break; - case 305: /* wqas ::= AS NOT MATERIALIZED */ + case 307: /* wqas ::= AS NOT MATERIALIZED */ {yymsp[-2].minor.yy498 = M10d_No;} break; - case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */ + case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */ { yymsp[-5].minor.yy79 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy402, yymsp[-1].minor.yy299, yymsp[-3].minor.yy498); /*A-overwrites-X*/ } break; - case 307: /* wqlist ::= wqitem */ + case 309: /* wqlist ::= wqitem */ { yymsp[0].minor.yy131 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy79); /*A-overwrites-X*/ } break; - case 308: /* wqlist ::= wqlist COMMA wqitem */ + case 310: /* wqlist ::= wqlist COMMA wqitem */ { yymsp[-2].minor.yy131 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy131, yymsp[0].minor.yy79); } break; - case 309: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 311: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy3 = yymsp[0].minor.yy3; } + yymsp[0].minor.yy3 = yylhsminor.yy3; + break; + case 312: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { assert( yymsp[0].minor.yy3!=0 ); sqlite3WindowChain(pParse, yymsp[0].minor.yy3, yymsp[-2].minor.yy3); @@ -176276,7 +174161,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-2].minor.yy3 = yylhsminor.yy3; break; - case 310: /* windowdefn ::= nm AS LP window RP */ + case 313: /* windowdefn ::= nm AS LP window RP */ { if( ALWAYS(yymsp[-1].minor.yy3) ){ yymsp[-1].minor.yy3->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); @@ -176285,83 +174170,90 @@ static YYACTIONTYPE yy_reduce( } yymsp[-4].minor.yy3 = yylhsminor.yy3; break; - case 311: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 314: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { yymsp[-4].minor.yy3 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy3, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, 0); } break; - case 312: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 315: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { yylhsminor.yy3 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy3, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, &yymsp[-5].minor.yy0); } yymsp[-5].minor.yy3 = yylhsminor.yy3; break; - case 313: /* window ::= ORDER BY sortlist frame_opt */ + case 316: /* window ::= ORDER BY sortlist frame_opt */ { yymsp[-3].minor.yy3 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy3, 0, yymsp[-1].minor.yy402, 0); } break; - case 314: /* window ::= nm ORDER BY sortlist frame_opt */ + case 317: /* window ::= nm ORDER BY sortlist frame_opt */ { yylhsminor.yy3 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy3, 0, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0); } yymsp[-4].minor.yy3 = yylhsminor.yy3; break; - case 315: /* window ::= nm frame_opt */ + case 318: /* window ::= frame_opt */ + case 337: /* filter_over ::= over_clause */ yytestcase(yyruleno==337); +{ + yylhsminor.yy3 = yymsp[0].minor.yy3; +} + yymsp[0].minor.yy3 = yylhsminor.yy3; + break; + case 319: /* window ::= nm frame_opt */ { yylhsminor.yy3 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy3, 0, 0, &yymsp[-1].minor.yy0); } yymsp[-1].minor.yy3 = yylhsminor.yy3; break; - case 316: /* frame_opt ::= */ + case 320: /* frame_opt ::= */ { yymsp[1].minor.yy3 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; - case 317: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 321: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { yylhsminor.yy3 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy92, yymsp[-1].minor.yy337.eType, yymsp[-1].minor.yy337.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy498); } yymsp[-2].minor.yy3 = yylhsminor.yy3; break; - case 318: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 322: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { yylhsminor.yy3 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy92, yymsp[-3].minor.yy337.eType, yymsp[-3].minor.yy337.pExpr, yymsp[-1].minor.yy337.eType, yymsp[-1].minor.yy337.pExpr, yymsp[0].minor.yy498); } yymsp[-5].minor.yy3 = yylhsminor.yy3; break; - case 320: /* frame_bound_s ::= frame_bound */ - case 322: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==322); + case 324: /* frame_bound_s ::= frame_bound */ + case 326: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==326); {yylhsminor.yy337 = yymsp[0].minor.yy337;} yymsp[0].minor.yy337 = yylhsminor.yy337; break; - case 321: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 323: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==323); - case 325: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==325); + case 325: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 327: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==327); + case 329: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==329); {yylhsminor.yy337.eType = yymsp[-1].major; yylhsminor.yy337.pExpr = 0;} yymsp[-1].minor.yy337 = yylhsminor.yy337; break; - case 324: /* frame_bound ::= expr PRECEDING|FOLLOWING */ + case 328: /* frame_bound ::= expr PRECEDING|FOLLOWING */ {yylhsminor.yy337.eType = yymsp[0].major; yylhsminor.yy337.pExpr = yymsp[-1].minor.yy2;} yymsp[-1].minor.yy337 = yylhsminor.yy337; break; - case 326: /* frame_exclude_opt ::= */ + case 330: /* frame_exclude_opt ::= */ {yymsp[1].minor.yy498 = 0;} break; - case 327: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ + case 331: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ {yymsp[-1].minor.yy498 = yymsp[0].minor.yy498;} break; - case 328: /* frame_exclude ::= NO OTHERS */ - case 329: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==329); + case 332: /* frame_exclude ::= NO OTHERS */ + case 333: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==333); {yymsp[-1].minor.yy498 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 330: /* frame_exclude ::= GROUP|TIES */ + case 334: /* frame_exclude ::= GROUP|TIES */ {yymsp[0].minor.yy498 = yymsp[0].major; /*A-overwrites-X*/} break; - case 331: /* window_clause ::= WINDOW windowdefn_list */ + case 335: /* window_clause ::= WINDOW windowdefn_list */ { yymsp[-1].minor.yy3 = yymsp[0].minor.yy3; } break; - case 332: /* filter_over ::= filter_clause over_clause */ + case 336: /* filter_over ::= filter_clause over_clause */ { if( yymsp[0].minor.yy3 ){ yymsp[0].minor.yy3->pFilter = yymsp[-1].minor.yy2; @@ -176372,13 +174264,7 @@ static YYACTIONTYPE yy_reduce( } yymsp[-1].minor.yy3 = yylhsminor.yy3; break; - case 333: /* filter_over ::= over_clause */ -{ - yylhsminor.yy3 = yymsp[0].minor.yy3; -} - yymsp[0].minor.yy3 = yylhsminor.yy3; - break; - case 334: /* filter_over ::= filter_clause */ + case 338: /* filter_over ::= filter_clause */ { yylhsminor.yy3 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( yylhsminor.yy3 ){ @@ -176390,13 +174276,13 @@ static YYACTIONTYPE yy_reduce( } yymsp[0].minor.yy3 = yylhsminor.yy3; break; - case 335: /* over_clause ::= OVER LP window RP */ + case 339: /* over_clause ::= OVER LP window RP */ { yymsp[-3].minor.yy3 = yymsp[-1].minor.yy3; assert( yymsp[-3].minor.yy3!=0 ); } break; - case 336: /* over_clause ::= OVER nm */ + case 340: /* over_clause ::= OVER nm */ { yymsp[-1].minor.yy3 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( yymsp[-1].minor.yy3 ){ @@ -176404,75 +174290,73 @@ static YYACTIONTYPE yy_reduce( } } break; - case 337: /* filter_clause ::= FILTER LP WHERE expr RP */ + case 341: /* filter_clause ::= FILTER LP WHERE expr RP */ { yymsp[-4].minor.yy2 = yymsp[-1].minor.yy2; } break; default: - /* (338) input ::= cmdlist */ yytestcase(yyruleno==338); - /* (339) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==339); - /* (340) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=340); - /* (341) ecmd ::= SEMI */ yytestcase(yyruleno==341); - /* (342) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==342); - /* (343) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=343); - /* (344) trans_opt ::= */ yytestcase(yyruleno==344); - /* (345) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==345); - /* (346) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==346); - /* (347) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==347); - /* (348) savepoint_opt ::= */ yytestcase(yyruleno==348); - /* (349) cmd ::= create_table create_table_args */ yytestcase(yyruleno==349); - /* (350) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=350); - /* (351) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==351); - /* (352) columnlist ::= columnname carglist */ yytestcase(yyruleno==352); - /* (353) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==353); - /* (354) nm ::= STRING */ yytestcase(yyruleno==354); - /* (355) typetoken ::= typename */ yytestcase(yyruleno==355); - /* (356) typename ::= ID|STRING */ yytestcase(yyruleno==356); - /* (357) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=357); - /* (358) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=358); - /* (359) carglist ::= carglist ccons */ yytestcase(yyruleno==359); - /* (360) carglist ::= */ yytestcase(yyruleno==360); - /* (361) ccons ::= NULL onconf */ yytestcase(yyruleno==361); - /* (362) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==362); - /* (363) ccons ::= AS generated */ yytestcase(yyruleno==363); - /* (364) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==364); - /* (365) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==365); - /* (366) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=366); - /* (367) tconscomma ::= */ yytestcase(yyruleno==367); - /* (368) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=368); - /* (369) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=369); - /* (370) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=370); - /* (371) oneselect ::= values */ yytestcase(yyruleno==371); - /* (372) sclp ::= selcollist COMMA */ yytestcase(yyruleno==372); - /* (373) as ::= ID|STRING */ yytestcase(yyruleno==373); - /* (374) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=374); - /* (375) returning ::= */ yytestcase(yyruleno==375); - /* (376) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=376); - /* (377) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==377); - /* (378) case_operand ::= expr */ yytestcase(yyruleno==378); - /* (379) exprlist ::= nexprlist */ yytestcase(yyruleno==379); - /* (380) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=380); - /* (381) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=381); - /* (382) nmnum ::= ON */ yytestcase(yyruleno==382); - /* (383) nmnum ::= DELETE */ yytestcase(yyruleno==383); - /* (384) nmnum ::= DEFAULT */ yytestcase(yyruleno==384); - /* (385) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==385); - /* (386) foreach_clause ::= */ yytestcase(yyruleno==386); - /* (387) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==387); - /* (388) trnm ::= nm */ yytestcase(yyruleno==388); - /* (389) tridxby ::= */ yytestcase(yyruleno==389); - /* (390) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==390); - /* (391) database_kw_opt ::= */ yytestcase(yyruleno==391); - /* (392) kwcolumn_opt ::= */ yytestcase(yyruleno==392); - /* (393) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==393); - /* (394) vtabarglist ::= vtabarg */ yytestcase(yyruleno==394); - /* (395) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==395); - /* (396) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==396); - /* (397) anylist ::= */ yytestcase(yyruleno==397); - /* (398) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==398); - /* (399) anylist ::= anylist ANY */ yytestcase(yyruleno==399); - /* (400) with ::= */ yytestcase(yyruleno==400); - /* (401) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=401); - /* (402) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=402); + /* (342) input ::= cmdlist */ yytestcase(yyruleno==342); + /* (343) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==343); + /* (344) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=344); + /* (345) ecmd ::= SEMI */ yytestcase(yyruleno==345); + /* (346) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==346); + /* (347) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=347); + /* (348) trans_opt ::= */ yytestcase(yyruleno==348); + /* (349) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==349); + /* (350) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==350); + /* (351) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==351); + /* (352) savepoint_opt ::= */ yytestcase(yyruleno==352); + /* (353) cmd ::= create_table create_table_args */ yytestcase(yyruleno==353); + /* (354) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=354); + /* (355) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==355); + /* (356) columnlist ::= columnname carglist */ yytestcase(yyruleno==356); + /* (357) nm ::= ID|INDEXED */ yytestcase(yyruleno==357); + /* (358) nm ::= STRING */ yytestcase(yyruleno==358); + /* (359) nm ::= JOIN_KW */ yytestcase(yyruleno==359); + /* (360) typetoken ::= typename */ yytestcase(yyruleno==360); + /* (361) typename ::= ID|STRING */ yytestcase(yyruleno==361); + /* (362) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=362); + /* (363) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=363); + /* (364) carglist ::= carglist ccons */ yytestcase(yyruleno==364); + /* (365) carglist ::= */ yytestcase(yyruleno==365); + /* (366) ccons ::= NULL onconf */ yytestcase(yyruleno==366); + /* (367) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==367); + /* (368) ccons ::= AS generated */ yytestcase(yyruleno==368); + /* (369) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==369); + /* (370) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==370); + /* (371) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=371); + /* (372) tconscomma ::= */ yytestcase(yyruleno==372); + /* (373) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=373); + /* (374) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=374); + /* (375) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=375); + /* (376) oneselect ::= values */ yytestcase(yyruleno==376); + /* (377) sclp ::= selcollist COMMA */ yytestcase(yyruleno==377); + /* (378) as ::= ID|STRING */ yytestcase(yyruleno==378); + /* (379) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=379); + /* (380) returning ::= */ yytestcase(yyruleno==380); + /* (381) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=381); + /* (382) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==382); + /* (383) exprlist ::= nexprlist */ yytestcase(yyruleno==383); + /* (384) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=384); + /* (385) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=385); + /* (386) nmnum ::= ON */ yytestcase(yyruleno==386); + /* (387) nmnum ::= DELETE */ yytestcase(yyruleno==387); + /* (388) nmnum ::= DEFAULT */ yytestcase(yyruleno==388); + /* (389) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==389); + /* (390) foreach_clause ::= */ yytestcase(yyruleno==390); + /* (391) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==391); + /* (392) trnm ::= nm */ yytestcase(yyruleno==392); + /* (393) tridxby ::= */ yytestcase(yyruleno==393); + /* (394) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==394); + /* (395) database_kw_opt ::= */ yytestcase(yyruleno==395); + /* (396) kwcolumn_opt ::= */ yytestcase(yyruleno==396); + /* (397) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==397); + /* (398) vtabarglist ::= vtabarg */ yytestcase(yyruleno==398); + /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==399); + /* (400) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==400); + /* (401) anylist ::= */ yytestcase(yyruleno==401); + /* (402) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==402); + /* (403) anylist ::= anylist ANY */ yytestcase(yyruleno==403); + /* (404) with ::= */ yytestcase(yyruleno==404); break; /********** End reduce actions ************************************************/ }; @@ -177048,7 +174932,7 @@ static const unsigned char aKWHash[127] = { /* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 ** then the i-th keyword has no more hash collisions. Otherwise, ** the next keyword with the same hash is aKWHash[i]-1. */ -static const unsigned char aKWNext[148] = {0, +static const unsigned char aKWNext[147] = { 0, 0, 0, 0, 4, 0, 43, 0, 0, 106, 114, 0, 0, 0, 2, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 0, 141, 0, 0, 119, 52, 0, 0, 137, 12, 0, 0, 62, 0, @@ -177063,7 +174947,7 @@ static const unsigned char aKWNext[148] = {0, 102, 0, 0, 87, }; /* aKWLen[i] is the length (in bytes) of the i-th keyword */ -static const unsigned char aKWLen[148] = {0, +static const unsigned char aKWLen[147] = { 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7, 6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4, @@ -177079,7 +174963,7 @@ static const unsigned char aKWLen[148] = {0, }; /* aKWOffset[i] is the index into zKWText[] of the start of ** the text for the i-th keyword. */ -static const unsigned short int aKWOffset[148] = {0, +static const unsigned short int aKWOffset[147] = { 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, 86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126, @@ -177094,7 +174978,7 @@ static const unsigned short int aKWOffset[148] = {0, 648, 650, 655, 659, }; /* aKWCode[i] is the parser symbol code for the i-th keyword */ -static const unsigned char aKWCode[148] = {0, +static const unsigned char aKWCode[147] = { TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, @@ -177261,185 +175145,185 @@ static const unsigned char aKWCode[148] = {0, static int keywordCode(const char *z, int n, int *pType){ int i, j; const char *zKW; - assert( n>=2 ); - i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; - for(i=(int)aKWHash[i]; i>0; i=aKWNext[i]){ - if( aKWLen[i]!=n ) continue; - zKW = &zKWText[aKWOffset[i]]; + if( n>=2 ){ + i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; + for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){ + if( aKWLen[i]!=n ) continue; + zKW = &zKWText[aKWOffset[i]]; #ifdef SQLITE_ASCII - if( (z[0]&~0x20)!=zKW[0] ) continue; - if( (z[1]&~0x20)!=zKW[1] ) continue; - j = 2; - while( j=2 ) keywordCode((char*)z, n, &id); + keywordCode((char*)z, n, &id); return id; } #define SQLITE_N_KEYWORD 147 SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; - i++; *pzName = zKWText + aKWOffset[i]; *pnName = aKWLen[i]; return SQLITE_OK; @@ -177810,8 +175694,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ return i; } case CC_KYWD0: { - if( aiClass[z[1]]>CC_KYWD ){ i = 1; break; } - for(i=2; aiClass[z[i]]<=CC_KYWD; i++){} + for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} if( IdChar(z[i]) ){ /* This token started out using characters that can appear in keywords, ** but z[i] is a character not allowed within keywords, so this must @@ -178590,6 +176473,12 @@ static int sqlite3TestExtInit(sqlite3 *db){ ** Forward declarations of external module initializer functions ** for modules that need them. */ +#ifdef SQLITE_ENABLE_FTS1 +SQLITE_PRIVATE int sqlite3Fts1Init(sqlite3*); +#endif +#ifdef SQLITE_ENABLE_FTS2 +SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*); +#endif #ifdef SQLITE_ENABLE_FTS5 SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); #endif @@ -178602,6 +176491,12 @@ SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); ** built-in extensions. */ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { +#ifdef SQLITE_ENABLE_FTS1 + sqlite3Fts1Init, +#endif +#ifdef SQLITE_ENABLE_FTS2 + sqlite3Fts2Init, +#endif #ifdef SQLITE_ENABLE_FTS3 sqlite3Fts3Init, #endif @@ -178967,21 +176862,9 @@ SQLITE_API int sqlite3_config(int op, ...){ va_list ap; int rc = SQLITE_OK; - /* sqlite3_config() normally returns SQLITE_MISUSE if it is invoked while - ** the SQLite library is in use. Except, a few selected opcodes - ** are allowed. - */ - if( sqlite3GlobalConfig.isInit ){ - static const u64 mAnytimeConfigOption = 0 - | MASKBIT64( SQLITE_CONFIG_LOG ) - | MASKBIT64( SQLITE_CONFIG_PCACHE_HDRSZ ) - ; - if( op<0 || op>63 || (MASKBIT64(op) & mAnytimeConfigOption)==0 ){ - return SQLITE_MISUSE_BKPT; - } - testcase( op==SQLITE_CONFIG_LOG ); - testcase( op==SQLITE_CONFIG_PCACHE_HDRSZ ); - } + /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while + ** the SQLite library is in use. */ + if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; va_start(ap, op); switch( op ){ @@ -179050,7 +176933,6 @@ SQLITE_API int sqlite3_config(int op, ...){ break; } case SQLITE_CONFIG_MEMSTATUS: { - assert( !sqlite3GlobalConfig.isInit ); /* Cannot change at runtime */ /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes ** single argument of type int, interpreted as a boolean, which enables ** or disables the collection of memory allocation statistics. */ @@ -179174,10 +177056,8 @@ SQLITE_API int sqlite3_config(int op, ...){ ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); */ typedef void(*LOGFUNC_t)(void*,int,const char*); - LOGFUNC_t xLog = va_arg(ap, LOGFUNC_t); - void *pLogArg = va_arg(ap, void*); - AtomicStore(&sqlite3GlobalConfig.xLog, xLog); - AtomicStore(&sqlite3GlobalConfig.pLogArg, pLogArg); + sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); + sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); break; } @@ -179191,8 +177071,7 @@ SQLITE_API int sqlite3_config(int op, ...){ ** argument of type int. If non-zero, then URI handling is globally ** enabled. If the parameter is zero, then URI handling is globally ** disabled. */ - int bOpenUri = va_arg(ap, int); - AtomicStore(&sqlite3GlobalConfig.bOpenUri, bOpenUri); + sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); break; } @@ -179507,8 +177386,6 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema }, - { SQLITE_DBCONFIG_STMT_SCANSTATUS, SQLITE_StmtScanStatus }, - { SQLITE_DBCONFIG_REVERSE_SCANORDER, SQLITE_ReverseOrder }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ @@ -181494,9 +179371,9 @@ SQLITE_PRIVATE int sqlite3ParseUri( assert( *pzErrMsg==0 ); - if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ - || AtomicLoad(&sqlite3GlobalConfig.bOpenUri)) /* IMP: R-51689-46548 */ - && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ + if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ + || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */ + && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ ){ char *zOpt; int eState; /* Parser state when parsing URI */ @@ -181854,7 +179731,7 @@ static int openDatabase( ** 0 off off ** ** Legacy behavior is 3 (double-quoted string literals are allowed anywhere) -** and so that is the default. But developers are encouraged to use +** and so that is the default. But developers are encouranged to use ** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible. */ #if !defined(SQLITE_DQS) @@ -181902,9 +179779,6 @@ static int openDatabase( #endif #if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE) | SQLITE_LegacyAlter -#endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) - | SQLITE_StmtScanStatus #endif ; sqlite3HashInit(&db->aCollSeq); @@ -182389,7 +180263,7 @@ SQLITE_API int sqlite3_table_column_metadata( /* Find the column for which info is requested */ if( zColumnName==0 ){ - /* Query for existence of table only */ + /* Query for existance of table only */ }else{ for(iCol=0; iColnCol; iCol++){ pCol = &pTab->aCol[iCol]; @@ -182470,7 +180344,7 @@ SQLITE_API int sqlite3_sleep(int ms){ /* This function works in milliseconds, but the underlying OsSleep() ** API uses microseconds. Hence the 1000's. */ - rc = (sqlite3OsSleep(pVfs, ms<0 ? 0 : 1000*ms)/1000); + rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000); return rc; } @@ -182829,7 +180703,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** formed and never corrupt. This flag is clear by default, indicating that ** database files might have arbitrary corruption. Setting the flag during ** testing causes certain assert() statements in the code to be activated - ** that demonstrate invariants on well-formed database files. + ** that demonstrat invariants on well-formed database files. */ case SQLITE_TESTCTRL_NEVER_CORRUPT: { sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); @@ -182983,7 +180857,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** ** op==0 Store the current sqlite3TreeTrace in *ptr ** op==1 Set sqlite3TreeTrace to the value *ptr - ** op==2 Store the current sqlite3WhereTrace in *ptr + ** op==3 Store the current sqlite3WhereTrace in *ptr ** op==3 Set sqlite3WhereTrace to the value *ptr */ case SQLITE_TESTCTRL_TRACEFLAGS: { @@ -183019,21 +180893,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } - /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); - ** - ** X<0 Make no changes to the bUseLongDouble. Just report value. - ** X==0 Disable bUseLongDouble - ** X==1 Enable bUseLongDouble - ** X==2 Set bUseLongDouble to its default value for this platform - */ - case SQLITE_TESTCTRL_USELONGDOUBLE: { - int b = va_arg(ap, int); - if( b==2 ) b = sizeof(LONGDOUBLE_TYPE)>8; - if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; - rc = sqlite3Config.bUseLongDouble!=0; - break; - } - #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) @@ -183334,7 +181193,7 @@ SQLITE_API int sqlite3_snapshot_get( } /* -** Open a read-transaction on the snapshot identified by pSnapshot. +** Open a read-transaction on the snapshot idendified by pSnapshot. */ SQLITE_API int sqlite3_snapshot_open( sqlite3 *db, @@ -199398,7 +197257,6 @@ static int fts3IncrmergeLoad( for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ NodeReader reader; - memset(&reader, 0, sizeof(reader)); pNode = &pWriter->aNodeWriter[i]; if( pNode->block.a){ @@ -203474,7 +201332,6 @@ static const char jsonIsSpace[] = { typedef struct JsonString JsonString; typedef struct JsonNode JsonNode; typedef struct JsonParse JsonParse; -typedef struct JsonCleanup JsonCleanup; /* An instance of this object represents a JSON string ** under construction. Really, this is a generic string accumulator @@ -203490,26 +201347,16 @@ struct JsonString { char zSpace[100]; /* Initial static space */ }; -/* A deferred cleanup task. A list of JsonCleanup objects might be -** run when the JsonParse object is destroyed. -*/ -struct JsonCleanup { - JsonCleanup *pJCNext; /* Next in a list */ - void (*xOp)(void*); /* Routine to run */ - void *pArg; /* Argument to xOp() */ -}; - /* JSON type values */ -#define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */ -#define JSON_NULL 1 -#define JSON_TRUE 2 -#define JSON_FALSE 3 -#define JSON_INT 4 -#define JSON_REAL 5 -#define JSON_STRING 6 -#define JSON_ARRAY 7 -#define JSON_OBJECT 8 +#define JSON_NULL 0 +#define JSON_TRUE 1 +#define JSON_FALSE 2 +#define JSON_INT 3 +#define JSON_REAL 4 +#define JSON_STRING 5 +#define JSON_ARRAY 6 +#define JSON_OBJECT 7 /* The "subtype" set for JSON values */ #define JSON_SUBTYPE 74 /* Ascii for "J" */ @@ -203518,97 +201365,59 @@ struct JsonCleanup { ** Names of the various JSON types: */ static const char * const jsonType[] = { - "subst", "null", "true", "false", "integer", "real", "text", "array", "object" }; /* Bit values for the JsonNode.jnFlag field */ -#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ -#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ -#define JNODE_REMOVE 0x04 /* Do not output */ -#define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */ -#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */ -#define JNODE_LABEL 0x20 /* Is a label of an object */ -#define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */ +#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ +#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ +#define JNODE_REMOVE 0x04 /* Do not output */ +#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ +#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ +#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ +#define JNODE_LABEL 0x40 /* Is a label of an object */ -/* A single node of parsed JSON. An array of these nodes describes -** a parse of JSON + edits. -** -** Use the json_parse() SQL function (available when compiled with -** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including -** a complete listing and decoding of the array of JsonNodes. +/* A single node of parsed JSON */ struct JsonNode { u8 eType; /* One of the JSON_ type values */ u8 jnFlags; /* JNODE flags */ u8 eU; /* Which union element to use */ - u32 n; /* Bytes of content for INT, REAL or STRING - ** Number of sub-nodes for ARRAY and OBJECT - ** Node that SUBST applies to */ + u32 n; /* Bytes of content, or number of sub-nodes */ union { const char *zJContent; /* 1: Content for INT, REAL, and STRING */ u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ - u32 iPrev; /* 4: Previous SUBST node, or 0 */ + u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */ + JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */ } u; }; - -/* A parsed and possibly edited JSON string. Lifecycle: -** -** 1. JSON comes in and is parsed into an array aNode[]. The original -** JSON text is stored in zJson. -** -** 2. Zero or more changes are made (via json_remove() or json_replace() -** or similar) to the aNode[] array. -** -** 3. A new, edited and mimified JSON string is generated from aNode -** and stored in zAlt. The JsonParse object always owns zAlt. -** -** Step 1 always happens. Step 2 and 3 may or may not happen, depending -** on the operation. -** -** aNode[].u.zJContent entries typically point into zJson. Hence zJson -** must remain valid for the lifespan of the parse. For edits, -** aNode[].u.zJContent might point to malloced space other than zJson. -** Entries in pClup are responsible for freeing that extra malloced space. -** -** When walking the parse tree in aNode[], edits are ignored if useMod is -** false. +/* A completely parsed JSON string */ struct JsonParse { u32 nNode; /* Number of slots of aNode[] used */ u32 nAlloc; /* Number of slots of aNode[] allocated */ JsonNode *aNode; /* Array of nodes containing the parse */ - char *zJson; /* Original JSON string (before edits) */ - char *zAlt; /* Revised and/or mimified JSON */ + const char *zJson; /* Original JSON string */ u32 *aUp; /* Index of parent of each node */ - JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */ - u16 iDepth; /* Nesting depth */ - u8 nErr; /* Number of errors seen */ u8 oom; /* Set to true if out of memory */ - u8 bJsonIsRCStr; /* True if zJson is an RCStr */ - u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ - u8 useMod; /* Actually use the edits contain inside aNode */ - u8 hasMod; /* aNode contains edits from the original zJson */ - u32 nJPRef; /* Number of references to this object */ + u8 nErr; /* Number of errors seen */ + u16 iDepth; /* Nesting depth */ int nJson; /* Length of the zJson string in bytes */ - int nAlt; /* Length of alternative JSON string zAlt, in bytes */ - u32 iErr; /* Error location in zJson[] */ - u32 iSubst; /* Last JSON_SUBST entry in aNode[] */ - u32 iHold; /* Age of this entry in the cache for LRU replacement */ + u32 iHold; /* Replace cache line with the lowest iHold value */ }; /* ** Maximum nesting depth of JSON for this implementation. ** ** This limit is needed to avoid a stack overflow in the recursive -** descent parser. A depth of 1000 is far deeper than any sane JSON -** should go. Historical note: This limit was 2000 prior to version 3.42.0 +** descent parser. A depth of 2000 is far deeper than any sane JSON +** should go. */ -#define JSON_MAX_DEPTH 1000 +#define JSON_MAX_DEPTH 2000 /************************************************************************** ** Utility routines for dealing with JsonString objects @@ -203631,14 +201440,16 @@ static void jsonInit(JsonString *p, sqlite3_context *pCtx){ jsonZero(p); } + /* Free all allocated memory and reset the JsonString object back to its ** initial state. */ static void jsonReset(JsonString *p){ - if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); + if( !p->bStatic ) sqlite3_free(p->zBuf); jsonZero(p); } + /* Report an out-of-memory (OOM) condition */ static void jsonOom(JsonString *p){ @@ -203655,7 +201466,7 @@ static int jsonGrow(JsonString *p, u32 N){ char *zNew; if( p->bStatic ){ if( p->bErr ) return 1; - zNew = sqlite3RCStrNew(nTotal); + zNew = sqlite3_malloc64(nTotal); if( zNew==0 ){ jsonOom(p); return SQLITE_NOMEM; @@ -203664,12 +201475,12 @@ static int jsonGrow(JsonString *p, u32 N){ p->zBuf = zNew; p->bStatic = 0; }else{ - p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); - if( p->zBuf==0 ){ - p->bErr = 1; - jsonZero(p); + zNew = sqlite3_realloc64(p->zBuf, nTotal); + if( zNew==0 ){ + jsonOom(p); return SQLITE_NOMEM; } + p->zBuf = zNew; } p->nAlloc = nTotal; return SQLITE_OK; @@ -203677,36 +201488,13 @@ static int jsonGrow(JsonString *p, u32 N){ /* Append N bytes from zIn onto the end of the JsonString string. */ -static SQLITE_NOINLINE void jsonAppendExpand( - JsonString *p, - const char *zIn, - u32 N -){ - assert( N>0 ); - if( jsonGrow(p,N) ) return; - memcpy(p->zBuf+p->nUsed, zIn, N); - p->nUsed += N; -} static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ if( N==0 ) return; - if( N+p->nUsed >= p->nAlloc ){ - jsonAppendExpand(p,zIn,N); - }else{ - memcpy(p->zBuf+p->nUsed, zIn, N); - p->nUsed += N; - } -} -static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ - assert( N>0 ); - if( N+p->nUsed >= p->nAlloc ){ - jsonAppendExpand(p,zIn,N); - }else{ - memcpy(p->zBuf+p->nUsed, zIn, N); - p->nUsed += N; - } + if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; } - /* Append formatted text (not to exceed N bytes) to the JsonString. */ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ @@ -203720,36 +201508,11 @@ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ /* Append a single character */ -static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ - if( jsonGrow(p,1) ) return; - p->zBuf[p->nUsed++] = c; -} static void jsonAppendChar(JsonString *p, char c){ - if( p->nUsed>=p->nAlloc ){ - jsonAppendCharExpand(p,c); - }else{ - p->zBuf[p->nUsed++] = c; - } -} - -/* Try to force the string to be a zero-terminated RCStr string. -** -** Return true on success. Return false if an OOM prevents this -** from happening. -*/ -static int jsonForceRCStr(JsonString *p){ - jsonAppendChar(p, 0); - if( p->bErr ) return 0; - p->nUsed--; - if( p->bStatic==0 ) return 1; - p->nAlloc = 0; - p->nUsed++; - jsonGrow(p, p->nUsed); - p->nUsed--; - return p->bStatic==0; + if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; + p->zBuf[p->nUsed++] = c; } - /* Append a comma separator to the output buffer, if the previous ** character is not '[' or '{'. */ @@ -203757,8 +201520,7 @@ static void jsonAppendSeparator(JsonString *p){ char c; if( p->nUsed==0 ) return; c = p->zBuf[p->nUsed-1]; - if( c=='[' || c=='{' ) return; - jsonAppendChar(p, ','); + if( c!='[' && c!='{' ) jsonAppendChar(p, ','); } /* Append the N-byte string in zIn to the end of the JsonString string @@ -203805,130 +201567,6 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ assert( p->nUsednAlloc ); } -/* -** The zIn[0..N] string is a JSON5 string literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ - u32 i; - jsonAppendChar(p, '"'); - zIn++; - N -= 2; - while( N>0 ){ - for(i=0; i0 ){ - jsonAppendRawNZ(p, zIn, i); - zIn += i; - N -= i; - if( N==0 ) break; - } - assert( zIn[0]=='\\' ); - switch( (u8)zIn[1] ){ - case '\'': - jsonAppendChar(p, '\''); - break; - case 'v': - jsonAppendRawNZ(p, "\\u0009", 6); - break; - case 'x': - jsonAppendRawNZ(p, "\\u00", 4); - jsonAppendRawNZ(p, &zIn[2], 2); - zIn += 2; - N -= 2; - break; - case '0': - jsonAppendRawNZ(p, "\\u0000", 6); - break; - case '\r': - if( zIn[2]=='\n' ){ - zIn++; - N--; - } - break; - case '\n': - break; - case 0xe2: - assert( N>=4 ); - assert( 0x80==(u8)zIn[2] ); - assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] ); - zIn += 2; - N -= 2; - break; - default: - jsonAppendRawNZ(p, zIn, 2); - break; - } - zIn += 2; - N -= 2; - } - jsonAppendChar(p, '"'); -} - -/* -** The zIn[0..N] string is a JSON5 integer literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){ - if( zIn[0]=='+' ){ - zIn++; - N--; - }else if( zIn[0]=='-' ){ - jsonAppendChar(p, '-'); - zIn++; - N--; - } - if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){ - sqlite3_int64 i = 0; - int rc = sqlite3DecOrHexToI64(zIn, &i); - if( rc<=1 ){ - jsonPrintf(100,p,"%lld",i); - }else{ - assert( rc==2 ); - jsonAppendRawNZ(p, "9.0e999", 7); - } - return; - } - assert( N>0 ); - jsonAppendRawNZ(p, zIn, N); -} - -/* -** The zIn[0..N] string is a JSON5 real literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){ - u32 i; - if( zIn[0]=='+' ){ - zIn++; - N--; - }else if( zIn[0]=='-' ){ - jsonAppendChar(p, '-'); - zIn++; - N--; - } - if( zIn[0]=='.' ){ - jsonAppendChar(p, '0'); - } - for(i=0; i0 ){ - jsonAppendRawNZ(p, zIn, N); - } -} - - - /* ** Append a function parameter value to the JSON string under ** construction. @@ -203939,14 +201577,11 @@ static void jsonAppendValue( ){ switch( sqlite3_value_type(pValue) ){ case SQLITE_NULL: { - jsonAppendRawNZ(p, "null", 4); + jsonAppendRaw(p, "null", 4); break; } + case SQLITE_INTEGER: case SQLITE_FLOAT: { - jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue)); - break; - } - case SQLITE_INTEGER: { const char *z = (const char*)sqlite3_value_text(pValue); u32 n = (u32)sqlite3_value_bytes(pValue); jsonAppendRaw(p, z, n); @@ -203975,25 +201610,15 @@ static void jsonAppendValue( /* Make the JSON in p the result of the SQL function. -** -** The JSON string is reset. */ static void jsonResult(JsonString *p){ if( p->bErr==0 ){ - if( p->bStatic ){ - sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, - SQLITE_TRANSIENT, SQLITE_UTF8); - }else if( jsonForceRCStr(p) ){ - sqlite3RCStrRef(p->zBuf); - sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, - (void(*)(void*))sqlite3RCStrUnref, - SQLITE_UTF8); - } - } - if( p->bErr==1 ){ - sqlite3_result_error_nomem(p->pCtx); + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, + SQLITE_UTF8); + jsonZero(p); } - jsonReset(p); + assert( p->bStatic ); } /************************************************************************** @@ -204018,73 +201643,20 @@ static u32 jsonNodeSize(JsonNode *pNode){ ** delete the JsonParse object itself. */ static void jsonParseReset(JsonParse *pParse){ - while( pParse->pClup ){ - JsonCleanup *pTask = pParse->pClup; - pParse->pClup = pTask->pJCNext; - pTask->xOp(pTask->pArg); - sqlite3_free(pTask); - } - assert( pParse->nJPRef<=1 ); - if( pParse->aNode ){ - sqlite3_free(pParse->aNode); - pParse->aNode = 0; - } + sqlite3_free(pParse->aNode); + pParse->aNode = 0; pParse->nNode = 0; pParse->nAlloc = 0; - if( pParse->aUp ){ - sqlite3_free(pParse->aUp); - pParse->aUp = 0; - } - if( pParse->bJsonIsRCStr ){ - sqlite3RCStrUnref(pParse->zJson); - pParse->zJson = 0; - pParse->bJsonIsRCStr = 0; - } - if( pParse->zAlt ){ - sqlite3RCStrUnref(pParse->zAlt); - pParse->zAlt = 0; - } + sqlite3_free(pParse->aUp); + pParse->aUp = 0; } /* ** Free a JsonParse object that was obtained from sqlite3_malloc(). -** -** Note that destroying JsonParse might call sqlite3RCStrUnref() to -** destroy the zJson value. The RCStr object might recursively invoke -** JsonParse to destroy this pParse object again. Take care to ensure -** that this recursive destructor sequence terminates harmlessly. */ static void jsonParseFree(JsonParse *pParse){ - if( pParse->nJPRef>1 ){ - pParse->nJPRef--; - }else{ - jsonParseReset(pParse); - sqlite3_free(pParse); - } -} - -/* -** Add a cleanup task to the JsonParse object. -** -** If an OOM occurs, the cleanup operation happens immediately -** and this function returns SQLITE_NOMEM. -*/ -static int jsonParseAddCleanup( - JsonParse *pParse, /* Add the cleanup task to this parser */ - void(*xOp)(void*), /* The cleanup task */ - void *pArg /* Argument to the cleanup */ -){ - JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) ); - if( pTask==0 ){ - pParse->oom = 1; - xOp(pArg); - return SQLITE_ERROR; - } - pTask->pJCNext = pParse->pClup; - pParse->pClup = pTask; - pTask->xOp = xOp; - pTask->pArg = pArg; - return SQLITE_OK; + jsonParseReset(pParse); + sqlite3_free(pParse); } /* @@ -204093,76 +201665,46 @@ static int jsonParseAddCleanup( ** the number of JsonNode objects that are encoded. */ static void jsonRenderNode( - JsonParse *pParse, /* the complete parse of the JSON */ JsonNode *pNode, /* The node to render */ - JsonString *pOut /* Write JSON here */ + JsonString *pOut, /* Write JSON here */ + sqlite3_value **aReplace /* Replacement values */ ){ assert( pNode!=0 ); - while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){ - u32 idx = (u32)(pNode - pParse->aNode); - u32 i = pParse->iSubst; - while( 1 /*exit-by-break*/ ){ - assert( inNode ); - assert( pParse->aNode[i].eType==JSON_SUBST ); - assert( pParse->aNode[i].eU==4 ); - assert( pParse->aNode[i].u.iPrevaNode[i].n==idx ){ - pNode = &pParse->aNode[i+1]; - break; - } - i = pParse->aNode[i].u.iPrev; + if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ + if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){ + assert( pNode->eU==4 ); + jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); + return; } + assert( pNode->eU==5 ); + pNode = pNode->u.pPatch; } switch( pNode->eType ){ default: { assert( pNode->eType==JSON_NULL ); - jsonAppendRawNZ(pOut, "null", 4); + jsonAppendRaw(pOut, "null", 4); break; } case JSON_TRUE: { - jsonAppendRawNZ(pOut, "true", 4); + jsonAppendRaw(pOut, "true", 4); break; } case JSON_FALSE: { - jsonAppendRawNZ(pOut, "false", 5); + jsonAppendRaw(pOut, "false", 5); break; } case JSON_STRING: { - assert( pNode->eU==1 ); if( pNode->jnFlags & JNODE_RAW ){ - if( pNode->jnFlags & JNODE_LABEL ){ - jsonAppendChar(pOut, '"'); - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); - jsonAppendChar(pOut, '"'); - }else{ - jsonAppendString(pOut, pNode->u.zJContent, pNode->n); - } - }else if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_REAL: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); + assert( pNode->eU==1 ); + jsonAppendString(pOut, pNode->u.zJContent, pNode->n); + break; } - break; + /* no break */ deliberate_fall_through } + case JSON_REAL: case JSON_INT: { assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } + jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); break; } case JSON_ARRAY: { @@ -204170,16 +201712,15 @@ static void jsonRenderNode( jsonAppendChar(pOut, '['); for(;;){ while( j<=pNode->n ){ - if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ + if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ jsonAppendSeparator(pOut); - jsonRenderNode(pParse, &pNode[j], pOut); + jsonRenderNode(&pNode[j], pOut, aReplace); } j += jsonNodeSize(&pNode[j]); } if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; assert( pNode->eU==2 ); - pNode = &pParse->aNode[pNode->u.iAppend]; + pNode = &pNode[pNode->u.iAppend]; j = 1; } jsonAppendChar(pOut, ']'); @@ -204190,18 +201731,17 @@ static void jsonRenderNode( jsonAppendChar(pOut, '{'); for(;;){ while( j<=pNode->n ){ - if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ + if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ jsonAppendSeparator(pOut); - jsonRenderNode(pParse, &pNode[j], pOut); + jsonRenderNode(&pNode[j], pOut, aReplace); jsonAppendChar(pOut, ':'); - jsonRenderNode(pParse, &pNode[j+1], pOut); + jsonRenderNode(&pNode[j+1], pOut, aReplace); } j += 1 + jsonNodeSize(&pNode[j+1]); } if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; assert( pNode->eU==2 ); - pNode = &pParse->aNode[pNode->u.iAppend]; + pNode = &pNode[pNode->u.iAppend]; j = 1; } jsonAppendChar(pOut, '}'); @@ -204211,29 +201751,18 @@ static void jsonRenderNode( } /* -** Return a JsonNode and all its descendants as a JSON string. +** Return a JsonNode and all its descendents as a JSON string. */ static void jsonReturnJson( - JsonParse *pParse, /* The complete JSON */ JsonNode *pNode, /* Node to return */ sqlite3_context *pCtx, /* Return value for this function */ - int bGenerateAlt /* Also store the rendered text in zAlt */ + sqlite3_value **aReplace /* Array of replacement values */ ){ JsonString s; - if( pParse->oom ){ - sqlite3_result_error_nomem(pCtx); - return; - } - if( pParse->nErr==0 ){ - jsonInit(&s, pCtx); - jsonRenderNode(pParse, pNode, &s); - if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){ - pParse->zAlt = sqlite3RCStrRef(s.zBuf); - pParse->nAlt = s.nUsed; - } - jsonResult(&s); - sqlite3_result_subtype(pCtx, JSON_SUBTYPE); - } + jsonInit(&s, pCtx); + jsonRenderNode(pNode, &s, aReplace); + jsonResult(&s); + sqlite3_result_subtype(pCtx, JSON_SUBTYPE); } /* @@ -204271,9 +201800,9 @@ static u32 jsonHexToInt4(const char *z){ ** Make the JsonNode the return value of the function. */ static void jsonReturn( - JsonParse *pParse, /* Complete JSON parse tree */ JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx /* Return value for this function */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ ){ switch( pNode->eType ){ default: { @@ -204291,40 +201820,59 @@ static void jsonReturn( } case JSON_INT: { sqlite3_int64 i = 0; - int rc; - int bNeg = 0; const char *z; - assert( pNode->eU==1 ); z = pNode->u.zJContent; - if( z[0]=='-' ){ z++; bNeg = 1; } - else if( z[0]=='+' ){ z++; } - rc = sqlite3DecOrHexToI64(z, &i); - if( rc<=1 ){ - sqlite3_result_int64(pCtx, bNeg ? -i : i); - }else if( rc==3 && bNeg ){ - sqlite3_result_int64(pCtx, SMALLEST_INT64); - }else{ - goto to_double; + if( z[0]=='-' ){ z++; } + while( z[0]>='0' && z[0]<='9' ){ + unsigned v = *(z++) - '0'; + if( i>=LARGEST_INT64/10 ){ + if( i>LARGEST_INT64/10 ) goto int_as_real; + if( z[0]>='0' && z[0]<='9' ) goto int_as_real; + if( v==9 ) goto int_as_real; + if( v==8 ){ + if( pNode->u.zJContent[0]=='-' ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + goto int_done; + }else{ + goto int_as_real; + } + } + } + i = i*10 + v; } + if( pNode->u.zJContent[0]=='-' ){ i = -i; } + sqlite3_result_int64(pCtx, i); + int_done: break; + int_as_real: ; /* no break */ deliberate_fall_through } case JSON_REAL: { double r; +#ifdef SQLITE_AMALGAMATION const char *z; assert( pNode->eU==1 ); - to_double: z = pNode->u.zJContent; sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); +#else + assert( pNode->eU==1 ); + r = strtod(pNode->u.zJContent, 0); +#endif sqlite3_result_double(pCtx, r); break; } case JSON_STRING: { +#if 0 /* Never happens because JNODE_RAW is only set by json_set(), + ** json_insert() and json_replace() and those routines do not + ** call jsonReturn() */ if( pNode->jnFlags & JNODE_RAW ){ assert( pNode->eU==1 ); sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, SQLITE_TRANSIENT); - }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ + }else +#endif + assert( (pNode->jnFlags & JNODE_RAW)==0 ); + if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ /* JSON formatted without any backslash-escapes */ assert( pNode->eU==1 ); sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, @@ -204336,17 +201884,18 @@ static void jsonReturn( const char *z; char *zOut; u32 j; - u32 nOut = n; assert( pNode->eU==1 ); z = pNode->u.zJContent; - zOut = sqlite3_malloc( nOut+1 ); + zOut = sqlite3_malloc( n+1 ); if( zOut==0 ){ sqlite3_result_error_nomem(pCtx); break; } for(i=1, j=0; iaNode after first expanding the -** size of the aNode array. Return the index of the new node. -** -** If an OOM error occurs, set pParse->oom and return -1. -*/ static JSON_NOINLINE int jsonParseAddNodeExpand( JsonParse *pParse, /* Append the node to this object */ u32 eType, /* Node type */ @@ -204463,7 +201988,7 @@ static JSON_NOINLINE int jsonParseAddNodeExpand( pParse->oom = 1; return -1; } - pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode); + pParse->nAlloc = nNew; pParse->aNode = pNew; assert( pParse->nNodenAlloc ); return jsonParseAddNode(pParse, eType, n, zContent); @@ -204481,235 +202006,34 @@ static int jsonParseAddNode( const char *zContent /* Content */ ){ JsonNode *p; - assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc ); - if( pParse->nNode>=pParse->nAlloc ){ + if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){ return jsonParseAddNodeExpand(pParse, eType, n, zContent); } p = &pParse->aNode[pParse->nNode]; - p->eType = (u8)(eType & 0xff); - p->jnFlags = (u8)(eType >> 8); + p->eType = (u8)eType; + p->jnFlags = 0; VVA( p->eU = zContent ? 1 : 0 ); p->n = n; p->u.zJContent = zContent; return pParse->nNode++; } -/* -** Add an array of new nodes to the current pParse->aNode array. -** Return the index of the first node added. -** -** If an OOM error occurs, set pParse->oom. -*/ -static void jsonParseAddNodeArray( - JsonParse *pParse, /* Append the node to this object */ - JsonNode *aNode, /* Array of nodes to add */ - u32 nNode /* Number of elements in aNew */ -){ - if( pParse->nNode + nNode > pParse->nAlloc ){ - u32 nNew = pParse->nNode + nNode; - JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode)); - if( aNew==0 ){ - pParse->oom = 1; - return; - } - pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode); - pParse->aNode = aNew; - } - memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode)); - pParse->nNode += nNode; -} - -/* -** Add a new JSON_SUBST node. The node immediately following -** this new node will be the substitute content for iNode. -*/ -static int jsonParseAddSubstNode( - JsonParse *pParse, /* Add the JSON_SUBST here */ - u32 iNode /* References this node */ -){ - int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0); - if( pParse->oom ) return -1; - pParse->aNode[iNode].jnFlags |= JNODE_REPLACE; - pParse->aNode[idx].eU = 4; - pParse->aNode[idx].u.iPrev = pParse->iSubst; - pParse->iSubst = idx; - pParse->hasMod = 1; - pParse->useMod = 1; - return idx; -} - -/* -** Return true if z[] begins with 2 (or more) hexadecimal digits -*/ -static int jsonIs2Hex(const char *z){ - return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]); -} - /* ** Return true if z[] begins with 4 (or more) hexadecimal digits */ static int jsonIs4Hex(const char *z){ - return jsonIs2Hex(z) && jsonIs2Hex(&z[2]); -} - -/* -** Return the number of bytes of JSON5 whitespace at the beginning of -** the input string z[]. -** -** JSON5 whitespace consists of any of the following characters: -** -** Unicode UTF-8 Name -** U+0009 09 horizontal tab -** U+000a 0a line feed -** U+000b 0b vertical tab -** U+000c 0c form feed -** U+000d 0d carriage return -** U+0020 20 space -** U+00a0 c2 a0 non-breaking space -** U+1680 e1 9a 80 ogham space mark -** U+2000 e2 80 80 en quad -** U+2001 e2 80 81 em quad -** U+2002 e2 80 82 en space -** U+2003 e2 80 83 em space -** U+2004 e2 80 84 three-per-em space -** U+2005 e2 80 85 four-per-em space -** U+2006 e2 80 86 six-per-em space -** U+2007 e2 80 87 figure space -** U+2008 e2 80 88 punctuation space -** U+2009 e2 80 89 thin space -** U+200a e2 80 8a hair space -** U+2028 e2 80 a8 line separator -** U+2029 e2 80 a9 paragraph separator -** U+202f e2 80 af narrow no-break space (NNBSP) -** U+205f e2 81 9f medium mathematical space (MMSP) -** U+3000 e3 80 80 ideographical space -** U+FEFF ef bb bf byte order mark -** -** In addition, comments between '/', '*' and '*', '/' and -** from '/', '/' to end-of-line are also considered to be whitespace. -*/ -static int json5Whitespace(const char *zIn){ - int n = 0; - const u8 *z = (u8*)zIn; - while( 1 /*exit by "goto whitespace_done"*/ ){ - switch( z[n] ){ - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x20: { - n++; - break; - } - case '/': { - if( z[n+1]=='*' && z[n+2]!=0 ){ - int j; - for(j=n+3; z[j]!='/' || z[j-1]!='*'; j++){ - if( z[j]==0 ) goto whitespace_done; - } - n = j+1; - break; - }else if( z[n+1]=='/' ){ - int j; - char c; - for(j=n+2; (c = z[j])!=0; j++){ - if( c=='\n' || c=='\r' ) break; - if( 0xe2==(u8)c && 0x80==(u8)z[j+1] - && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]) - ){ - j += 2; - break; - } - } - n = j; - if( z[n] ) n++; - break; - } - goto whitespace_done; - } - case 0xc2: { - if( z[n+1]==0xa0 ){ - n += 2; - break; - } - goto whitespace_done; - } - case 0xe1: { - if( z[n+1]==0x9a && z[n+2]==0x80 ){ - n += 3; - break; - } - goto whitespace_done; - } - case 0xe2: { - if( z[n+1]==0x80 ){ - u8 c = z[n+2]; - if( c<0x80 ) goto whitespace_done; - if( c<=0x8a || c==0xa8 || c==0xa9 || c==0xaf ){ - n += 3; - break; - } - }else if( z[n+1]==0x81 && z[n+2]==0x9f ){ - n += 3; - break; - } - goto whitespace_done; - } - case 0xe3: { - if( z[n+1]==0x80 && z[n+2]==0x80 ){ - n += 3; - break; - } - goto whitespace_done; - } - case 0xef: { - if( z[n+1]==0xbb && z[n+2]==0xbf ){ - n += 3; - break; - } - goto whitespace_done; - } - default: { - goto whitespace_done; - } - } - } - whitespace_done: - return n; + int i; + for(i=0; i<4; i++) if( !sqlite3Isxdigit(z[i]) ) return 0; + return 1; } -/* -** Extra floating-point literals to allow in JSON. -*/ -static const struct NanInfName { - char c1; - char c2; - char n; - char eType; - char nRepl; - char *zMatch; - char *zRepl; -} aNanInfName[] = { - { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" }, - { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" }, - { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" }, - { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" }, - { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" }, -}; - /* ** Parse a single JSON value which begins at pParse->zJson[i]. Return the ** index of the first character past the end of the value parsed. ** -** Special return values: -** -** 0 End of input -** -1 Syntax error -** -2 '}' seen -** -3 ']' seen -** -4 ',' seen -** -5 ':' seen +** Return negative for a syntax error. Special cases: return -2 if the +** first non-whitespace character is '}' and return -3 if the first +** non-whitespace character is ']'. */ static int jsonParseValue(JsonParse *pParse, u32 i){ char c; @@ -204718,476 +202042,175 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ int x; JsonNode *pNode; const char *z = pParse->zJson; -json_parse_restart: - switch( (u8)z[i] ){ - case '{': { + while( fast_isspace(z[i]) ){ i++; } + if( (c = z[i])=='{' ){ /* Parse object */ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); if( iThis<0 ) return -1; - if( ++pParse->iDepth > JSON_MAX_DEPTH ){ - pParse->iErr = i; - return -1; - } for(j=i+1;;j++){ - u32 nNode = pParse->nNode; + while( fast_isspace(z[j]) ){ j++; } + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); - if( x<=0 ){ - if( x==(-2) ){ - j = pParse->iErr; - if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; - break; - } - j += json5Whitespace(&z[j]); - if( sqlite3JsonId1(z[j]) - || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2])) - ){ - int k = j+1; - while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) - || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2])) - ){ - k++; - } - jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]); - pParse->hasNonstd = 1; - x = k; - }else{ - if( x!=-1 ) pParse->iErr = j; - return -1; - } - } - if( pParse->oom ) return -1; - pNode = &pParse->aNode[nNode]; - if( pNode->eType!=JSON_STRING ){ - pParse->iErr = j; + if( x<0 ){ + pParse->iDepth--; + if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; return -1; } + if( pParse->oom ) return -1; + pNode = &pParse->aNode[pParse->nNode-1]; + if( pNode->eType!=JSON_STRING ) return -1; pNode->jnFlags |= JNODE_LABEL; j = x; - if( z[j]==':' ){ - j++; - }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); - if( z[j]==':' ){ - j++; - goto parse_object_value; - } - } - x = jsonParseValue(pParse, j); - if( x!=(-5) ){ - if( x!=(-1) ) pParse->iErr = j; - return -1; - } - j = pParse->iErr+1; - } - parse_object_value: + while( fast_isspace(z[j]) ){ j++; } + if( z[j]!=':' ) return -1; + j++; x = jsonParseValue(pParse, j); - if( x<=0 ){ - if( x!=(-1) ) pParse->iErr = j; - return -1; - } + pParse->iDepth--; + if( x<0 ) return -1; j = x; - if( z[j]==',' ){ - continue; - }else if( z[j]=='}' ){ - break; - }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); - if( z[j]==',' ){ - continue; - }else if( z[j]=='}' ){ - break; - } - } - x = jsonParseValue(pParse, j); - if( x==(-4) ){ - j = pParse->iErr; - continue; - } - if( x==(-2) ){ - j = pParse->iErr; - break; - } - } - pParse->iErr = j; - return -1; + while( fast_isspace(z[j]) ){ j++; } + c = z[j]; + if( c==',' ) continue; + if( c!='}' ) return -1; + break; } pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; - pParse->iDepth--; return j+1; - } - case '[': { + }else if( c=='[' ){ /* Parse array */ iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); if( iThis<0 ) return -1; - if( ++pParse->iDepth > JSON_MAX_DEPTH ){ - pParse->iErr = i; - return -1; - } memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); for(j=i+1;;j++){ + while( fast_isspace(z[j]) ){ j++; } + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); - if( x<=0 ){ - if( x==(-3) ){ - j = pParse->iErr; - if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; - break; - } - if( x!=(-1) ) pParse->iErr = j; + pParse->iDepth--; + if( x<0 ){ + if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; return -1; } j = x; - if( z[j]==',' ){ - continue; - }else if( z[j]==']' ){ - break; - }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); - if( z[j]==',' ){ - continue; - }else if( z[j]==']' ){ - break; - } - } - x = jsonParseValue(pParse, j); - if( x==(-4) ){ - j = pParse->iErr; - continue; - } - if( x==(-3) ){ - j = pParse->iErr; - break; - } - } - pParse->iErr = j; - return -1; + while( fast_isspace(z[j]) ){ j++; } + c = z[j]; + if( c==',' ) continue; + if( c!=']' ) return -1; + break; } pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; - pParse->iDepth--; return j+1; - } - case '\'': { - u8 jnFlags; - char cDelim; - pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; - goto parse_string; - case '"': + }else if( c=='"' ){ /* Parse string */ - jnFlags = 0; - parse_string: - cDelim = z[i]; - for(j=i+1; 1; j++){ - static const char aOk[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }; - if( aOk[(unsigned char)z[j]] ) continue; + u8 jnFlags = 0; + j = i+1; + for(;;){ c = z[j]; - if( c==cDelim ){ - break; - }else if( c=='\\' ){ + if( (c & ~0x1f)==0 ){ + /* Control characters are not allowed in strings */ + return -1; + } + if( c=='\\' ){ c = z[++j]; if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' - || (c=='u' && jsonIs4Hex(&z[j+1])) ){ - jnFlags |= JNODE_ESCAPE; - }else if( c=='\'' || c=='0' || c=='v' || c=='\n' - || (0xe2==(u8)c && 0x80==(u8)z[j+1] - && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) - || (c=='x' && jsonIs2Hex(&z[j+1])) ){ - jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); - pParse->hasNonstd = 1; - }else if( c=='\r' ){ - if( z[j+1]=='\n' ) j++; - jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); - pParse->hasNonstd = 1; + || (c=='u' && jsonIs4Hex(z+j+1)) ){ + jnFlags = JNODE_ESCAPE; }else{ - pParse->iErr = j; return -1; } - }else if( c<=0x1f ){ - /* Control characters are not allowed in strings */ - pParse->iErr = j; - return -1; + }else if( c=='"' ){ + break; } + j++; } - jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]); + jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); + if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; return j+1; - } - case 't': { - if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_TRUE, 0, 0); - return i+4; - } - pParse->iErr = i; - return -1; - } - case 'f': { - if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ - jsonParseAddNode(pParse, JSON_FALSE, 0, 0); - return i+5; - } - pParse->iErr = i; - return -1; - } - case '+': { - u8 seenDP, seenE, jnFlags; - pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; - goto parse_number; - case '.': - if( sqlite3Isdigit(z[i+1]) ){ - pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; - seenE = 0; - seenDP = JSON_REAL; - goto parse_number_2; - } - pParse->iErr = i; - return -1; - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': + }else if( c=='n' + && strncmp(z+i,"null",4)==0 + && !sqlite3Isalnum(z[i+4]) ){ + jsonParseAddNode(pParse, JSON_NULL, 0, 0); + return i+4; + }else if( c=='t' + && strncmp(z+i,"true",4)==0 + && !sqlite3Isalnum(z[i+4]) ){ + jsonParseAddNode(pParse, JSON_TRUE, 0, 0); + return i+4; + }else if( c=='f' + && strncmp(z+i,"false",5)==0 + && !sqlite3Isalnum(z[i+5]) ){ + jsonParseAddNode(pParse, JSON_FALSE, 0, 0); + return i+5; + }else if( c=='-' || (c>='0' && c<='9') ){ /* Parse number */ - jnFlags = 0; - parse_number: - seenDP = JSON_INT; - seenE = 0; + u8 seenDP = 0; + u8 seenE = 0; assert( '-' < '0' ); - assert( '+' < '0' ); - assert( '.' < '0' ); - c = z[i]; - if( c<='0' ){ - if( c=='0' ){ - if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ - assert( seenDP==JSON_INT ); - pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; - for(j=i+3; sqlite3Isxdigit(z[j]); j++){} - goto parse_number_finish; - }else if( sqlite3Isdigit(z[i+1]) ){ - pParse->iErr = i+1; - return -1; - } - }else{ - if( !sqlite3Isdigit(z[i+1]) ){ - /* JSON5 allows for "+Infinity" and "-Infinity" using exactly - ** that case. SQLite also allows these in any case and it allows - ** "+inf" and "-inf". */ - if( (z[i+1]=='I' || z[i+1]=='i') - && sqlite3StrNICmp(&z[i+1], "inf",3)==0 - ){ - pParse->hasNonstd = 1; - if( z[i]=='-' ){ - jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999"); - }else{ - jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999"); - } - return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); - } - if( z[i+1]=='.' ){ - pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; - goto parse_number_2; - } - pParse->iErr = i; - return -1; - } - if( z[i+1]=='0' ){ - if( sqlite3Isdigit(z[i+2]) ){ - pParse->iErr = i+1; - return -1; - }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ - pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; - for(j=i+4; sqlite3Isxdigit(z[j]); j++){} - goto parse_number_finish; - } - } - } + j = c=='-' ? i+1 : i; + if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; } - parse_number_2: - for(j=i+1;; j++){ + j = i+1; + for(;; j++){ c = z[j]; - if( sqlite3Isdigit(c) ) continue; + if( c>='0' && c<='9' ) continue; if( c=='.' ){ - if( seenDP==JSON_REAL ){ - pParse->iErr = j; - return -1; - } - seenDP = JSON_REAL; + if( z[j-1]=='-' ) return -1; + if( seenDP ) return -1; + seenDP = 1; continue; } if( c=='e' || c=='E' ){ - if( z[j-1]<'0' ){ - if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ - pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; - }else{ - pParse->iErr = j; - return -1; - } - } - if( seenE ){ - pParse->iErr = j; - return -1; - } - seenDP = JSON_REAL; - seenE = 1; + if( z[j-1]<'0' ) return -1; + if( seenE ) return -1; + seenDP = seenE = 1; c = z[j+1]; if( c=='+' || c=='-' ){ j++; c = z[j+1]; } - if( c<'0' || c>'9' ){ - pParse->iErr = j; - return -1; - } + if( c<'0' || c>'9' ) return -1; continue; } break; } - if( z[j-1]<'0' ){ - if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ - pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; - }else{ - pParse->iErr = j; - return -1; - } - } - parse_number_finish: - jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]); + if( z[j-1]<'0' ) return -1; + jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, + j - i, &z[i]); return j; - } - case '}': { - pParse->iErr = i; + }else if( c=='}' ){ return -2; /* End of {...} */ - } - case ']': { - pParse->iErr = i; + }else if( c==']' ){ return -3; /* End of [...] */ - } - case ',': { - pParse->iErr = i; - return -4; /* List separator */ - } - case ':': { - pParse->iErr = i; - return -5; /* Object label/value separator */ - } - case 0: { + }else if( c==0 ){ return 0; /* End of file */ - } - case 0x09: - case 0x0a: - case 0x0d: - case 0x20: { - do{ - i++; - }while( fast_isspace(z[i]) ); - goto json_parse_restart; - } - case 0x0b: - case 0x0c: - case '/': - case 0xc2: - case 0xe1: - case 0xe2: - case 0xe3: - case 0xef: { - j = json5Whitespace(&z[i]); - if( j>0 ){ - i += j; - pParse->hasNonstd = 1; - goto json_parse_restart; - } - pParse->iErr = i; - return -1; - } - case 'n': { - if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); - return i+4; - } - /* fall-through into the default case that checks for NaN */ - } - default: { - u32 k; - int nn; - c = z[i]; - for(k=0; khasNonstd = 1; - return i + nn; - } - pParse->iErr = i; + }else{ return -1; /* Syntax error */ } - } /* End switch(z[i]) */ } /* ** Parse a complete JSON string. Return 0 on success or non-zero if there -** are any errors. If an error occurs, free all memory held by pParse, -** but not pParse itself. +** are any errors. If an error occurs, free all memory associated with +** pParse. ** -** pParse must be initialized to an empty parse object prior to calling -** this routine. +** pParse is uninitialized when this routine is called. */ static int jsonParse( JsonParse *pParse, /* Initialize and fill this JsonParse object */ - sqlite3_context *pCtx /* Report errors here */ + sqlite3_context *pCtx, /* Report errors here */ + const char *zJson /* Input JSON text to be parsed */ ){ int i; - const char *zJson = pParse->zJson; + memset(pParse, 0, sizeof(*pParse)); + if( zJson==0 ) return 1; + pParse->zJson = zJson; i = jsonParseValue(pParse, 0); if( pParse->oom ) i = -1; if( i>0 ){ assert( pParse->iDepth==0 ); while( fast_isspace(zJson[i]) ) i++; - if( zJson[i] ){ - i += json5Whitespace(&zJson[i]); - if( zJson[i] ){ - jsonParseReset(pParse); - return 1; - } - pParse->hasNonstd = 1; - } + if( zJson[i] ) i = -1; } if( i<=0 ){ if( pCtx!=0 ){ @@ -205203,7 +202226,6 @@ static int jsonParse( return 0; } - /* Mark node i of pParse as being a child of iParent. Call recursively ** to fill in all the descendants of node i. */ @@ -205253,49 +202275,26 @@ static int jsonParseFindParents(JsonParse *pParse){ #define JSON_CACHE_SZ 4 /* Max number of cache entries */ /* -** Obtain a complete parse of the JSON found in the pJson argument -** -** Use the sqlite3_get_auxdata() cache to find a preexisting parse -** if it is available. If the cache is not available or if it -** is no longer valid, parse the JSON again and return the new parse. -** Also register the new parse so that it will be available for +** Obtain a complete parse of the JSON found in the first argument +** of the argv array. Use the sqlite3_get_auxdata() cache for this +** parse if it is available. If the cache is not available or if it +** is no longer valid, parse the JSON again and return the new parse, +** and also register the new parse so that it will be available for ** future sqlite3_get_auxdata() calls. -** -** If an error occurs and pErrCtx!=0 then report the error on pErrCtx -** and return NULL. -** -** The returned pointer (if it is not NULL) is owned by the cache in -** most cases, not the caller. The caller does NOT need to invoke -** jsonParseFree(), in most cases. -** -** Except, if an error occurs and pErrCtx==0 then return the JsonParse -** object with JsonParse.nErr non-zero and the caller will own the JsonParse -** object. In that case, it will be the responsibility of the caller to -** invoke jsonParseFree(). To summarize: -** -** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the -** cache. Call does not need to -** free it. -** -** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller -** and so the caller must free it. */ static JsonParse *jsonParseCached( - sqlite3_context *pCtx, /* Context to use for cache search */ - sqlite3_value *pJson, /* Function param containing JSON text */ - sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */ - int bUnedited /* No prior edits allowed */ + sqlite3_context *pCtx, + sqlite3_value **argv, + sqlite3_context *pErrCtx ){ - char *zJson = (char*)sqlite3_value_text(pJson); - int nJson = sqlite3_value_bytes(pJson); + const char *zJson = (const char*)sqlite3_value_text(argv[0]); + int nJson = sqlite3_value_bytes(argv[0]); JsonParse *p; JsonParse *pMatch = 0; int iKey; int iMinKey = 0; u32 iMinHold = 0xffffffff; u32 iMaxHold = 0; - int bJsonRCStr; - if( zJson==0 ) return 0; for(iKey=0; iKeynJson==nJson - && (p->hasMod==0 || bUnedited==0) - && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0) + && memcmp(p->zJson,zJson,nJson)==0 ){ p->nErr = 0; - p->useMod = 0; - pMatch = p; - }else - if( pMatch==0 - && p->zAlt!=0 - && bUnedited==0 - && p->nAlt==nJson - && memcmp(p->zAlt, zJson, nJson)==0 - ){ - p->nErr = 0; - p->useMod = 1; pMatch = p; }else if( p->iHoldiHold; @@ -205330,44 +202317,24 @@ static JsonParse *jsonParseCached( } } if( pMatch ){ - /* The input JSON text was found in the cache. Use the preexisting - ** parse of this JSON */ pMatch->nErr = 0; pMatch->iHold = iMaxHold+1; - assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */ return pMatch; } - - /* The input JSON was not found anywhere in the cache. We will need - ** to parse it ourselves and generate a new JsonParse object. - */ - bJsonRCStr = sqlite3ValueIsOfClass(pJson,(void(*)(void*))sqlite3RCStrUnref); - p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); + p = sqlite3_malloc64( sizeof(*p) + nJson + 1 ); if( p==0 ){ sqlite3_result_error_nomem(pCtx); return 0; } memset(p, 0, sizeof(*p)); - if( bJsonRCStr ){ - p->zJson = sqlite3RCStrRef(zJson); - p->bJsonIsRCStr = 1; - }else{ - p->zJson = (char*)&p[1]; - memcpy(p->zJson, zJson, nJson+1); - } - p->nJPRef = 1; - if( jsonParse(p, pErrCtx) ){ - if( pErrCtx==0 ){ - p->nErr = 1; - assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */ - return p; - } - jsonParseFree(p); + p->zJson = (char*)&p[1]; + memcpy((char*)p->zJson, zJson, nJson+1); + if( jsonParse(p, pErrCtx, p->zJson) ){ + sqlite3_free(p); return 0; } p->nJson = nJson; p->iHold = iMaxHold+1; - /* Transfer ownership of the new JsonParse to the cache */ sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, (void(*)(void*))jsonParseFree); return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); @@ -205377,7 +202344,7 @@ static JsonParse *jsonParseCached( ** Compare the OBJECT label at pNode against zKey,nKey. Return true on ** a match. */ -static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){ +static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ assert( pNode->eU==1 ); if( pNode->jnFlags & JNODE_RAW ){ if( pNode->n!=nKey ) return 0; @@ -205387,15 +202354,6 @@ static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){ return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; } } -static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){ - if( p1->jnFlags & JNODE_RAW ){ - return jsonLabelCompare(p2, p1->u.zJContent, p1->n); - }else if( p2->jnFlags & JNODE_RAW ){ - return jsonLabelCompare(p1, p2->u.zJContent, p2->n); - }else{ - return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0; - } -} /* forward declaration */ static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); @@ -205418,26 +202376,9 @@ static JsonNode *jsonLookupStep( ){ u32 i, j, nKey; const char *zKey; - JsonNode *pRoot; - if( pParse->oom ) return 0; - pRoot = &pParse->aNode[iRoot]; - while( (pRoot->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){ - u32 idx = (u32)(pRoot - pParse->aNode); - i = pParse->iSubst; - while( 1 /*exit-by-break*/ ){ - assert( inNode ); - assert( pParse->aNode[i].eType==JSON_SUBST ); - assert( pParse->aNode[i].eU==4 ); - assert( pParse->aNode[i].u.iPrevaNode[i].n==idx ){ - pRoot = &pParse->aNode[i+1]; - iRoot = i+1; - break; - } - i = pParse->aNode[i].u.iPrev; - } - } + JsonNode *pRoot = &pParse->aNode[iRoot]; if( zPath[0]==0 ) return pRoot; + if( pRoot->jnFlags & JNODE_REPLACE ) return 0; if( zPath[0]=='.' ){ if( pRoot->eType!=JSON_OBJECT ) return 0; zPath++; @@ -205471,16 +202412,14 @@ static JsonNode *jsonLookupStep( j += jsonNodeSize(&pRoot[j]); } if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; assert( pRoot->eU==2 ); - iRoot = pRoot->u.iAppend; + iRoot += pRoot->u.iAppend; pRoot = &pParse->aNode[iRoot]; j = 1; } if( pApnd ){ u32 iStart, iLabel; JsonNode *pNode; - assert( pParse->useMod ); iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); zPath += i; @@ -205489,7 +202428,7 @@ static JsonNode *jsonLookupStep( if( pNode ){ pRoot = &pParse->aNode[iRoot]; assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart; + pRoot->u.iAppend = iStart - iRoot; pRoot->jnFlags |= JNODE_APPEND; VVA( pRoot->eU = 2 ); pParse->aNode[iLabel].jnFlags |= JNODE_RAW; @@ -205510,13 +202449,12 @@ static JsonNode *jsonLookupStep( if( pRoot->eType!=JSON_ARRAY ) return 0; for(;;){ while( j<=pBase->n ){ - if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++; + if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++; j += jsonNodeSize(&pBase[j]); } if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; assert( pBase->eU==2 ); - iBase = pBase->u.iAppend; + iBase += pBase->u.iAppend; pBase = &pParse->aNode[iBase]; j = 1; } @@ -205544,16 +202482,13 @@ static JsonNode *jsonLookupStep( zPath += j + 1; j = 1; for(;;){ - while( j<=pRoot->n - && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod)) - ){ - if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; + while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ + if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; j += jsonNodeSize(&pRoot[j]); } if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; assert( pRoot->eU==2 ); - iRoot = pRoot->u.iAppend; + iRoot += pRoot->u.iAppend; pRoot = &pParse->aNode[iRoot]; j = 1; } @@ -205563,14 +202498,13 @@ static JsonNode *jsonLookupStep( if( i==0 && pApnd ){ u32 iStart; JsonNode *pNode; - assert( pParse->useMod ); iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); if( pParse->oom ) return 0; if( pNode ){ pRoot = &pParse->aNode[iRoot]; assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart; + pRoot->u.iAppend = iStart - iRoot; pRoot->jnFlags |= JNODE_APPEND; VVA( pRoot->eU = 2 ); } @@ -205697,90 +202631,47 @@ static void jsonRemoveAllNulls(JsonNode *pNode){ ** SQL functions used for testing and debugging ****************************************************************************/ -#if SQLITE_DEBUG -/* -** Print N node entries. -*/ -static void jsonDebugPrintNodeEntries( - JsonNode *aNode, /* First node entry to print */ - int N /* Number of node entries to print */ -){ - int i; - for(i=0; iaNode, p->nNode); -} -static void jsonDebugPrintNode(JsonNode *pNode){ - jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode)); -} -#else - /* The usual case */ -# define jsonDebugPrintNode(X) -# define jsonDebugPrintParse(X) -#endif - #ifdef SQLITE_DEBUG /* -** SQL function: json_parse(JSON) -** -** Parse JSON using jsonParseCached(). Then print a dump of that -** parse on standard output. Return the mimified JSON result, just -** like the json() function. +** The json_parse(JSON) function returns a string which describes +** a parse of the JSON provided. Or it returns NULL if JSON is not +** well-formed. */ static void jsonParseFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonParse *p; /* The parse */ + JsonString s; /* Output string - not real JSON */ + JsonParse x; /* The parse */ + u32 i; assert( argc==1 ); - p = jsonParseCached(ctx, argv[0], ctx, 0); - if( p==0 ) return; - printf("nNode = %u\n", p->nNode); - printf("nAlloc = %u\n", p->nAlloc); - printf("nJson = %d\n", p->nJson); - printf("nAlt = %d\n", p->nAlt); - printf("nErr = %u\n", p->nErr); - printf("oom = %u\n", p->oom); - printf("hasNonstd = %u\n", p->hasNonstd); - printf("useMod = %u\n", p->useMod); - printf("hasMod = %u\n", p->hasMod); - printf("nJPRef = %u\n", p->nJPRef); - printf("iSubst = %u\n", p->iSubst); - printf("iHold = %u\n", p->iHold); - jsonDebugPrintNodeEntries(p->aNode, p->nNode); - jsonReturnJson(p, p->aNode, ctx, 1); + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + jsonParseFindParents(&x); + jsonInit(&s, ctx); + for(i=0; inNode ); if( argc==2 ){ @@ -205877,14 +202768,9 @@ static void jsonArrayLengthFunc( return; } if( pNode->eType==JSON_ARRAY ){ - while( 1 /*exit-by-break*/ ){ - for(i=1; i<=pNode->n; n++){ - i += jsonNodeSize(&pNode[i]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( p->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &p->aNode[pNode->u.iAppend]; + assert( (pNode->jnFlags & JNODE_APPEND)==0 ); + for(i=1; i<=pNode->n; n++){ + i += jsonNodeSize(&pNode[i]); } } sqlite3_result_int64(ctx, n); @@ -205931,14 +202817,14 @@ static void jsonExtractFunc( JsonString jx; if( argc<2 ) return; - p = jsonParseCached(ctx, argv[0], ctx, 0); + p = jsonParseCached(ctx, argv, ctx); if( p==0 ) return; if( argc==2 ){ /* With a single PATH argument */ zPath = (const char*)sqlite3_value_text(argv[1]); if( zPath==0 ) return; if( flags & JSON_ABPATH ){ - if( zPath[0]!='$' || (zPath[1]!='.' && zPath[1]!='[' && zPath[1]!=0) ){ + if( zPath[0]!='$' ){ /* The -> and ->> operators accept abbreviated PATH arguments. This ** is mostly for compatibility with PostgreSQL, but also for ** convenience. @@ -205949,11 +202835,11 @@ static void jsonExtractFunc( */ jsonInit(&jx, ctx); if( sqlite3Isdigit(zPath[0]) ){ - jsonAppendRawNZ(&jx, "$[", 2); + jsonAppendRaw(&jx, "$[", 2); jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); - jsonAppendRawNZ(&jx, "]", 2); + jsonAppendRaw(&jx, "]", 2); }else{ - jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='[')); + jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='[')); jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); jsonAppendChar(&jx, 0); } @@ -205964,15 +202850,15 @@ static void jsonExtractFunc( } if( pNode ){ if( flags & JSON_JSON ){ - jsonReturnJson(p, pNode, ctx, 0); + jsonReturnJson(pNode, ctx, 0); }else{ - jsonReturn(p, pNode, ctx); + jsonReturn(pNode, ctx, 0); sqlite3_result_subtype(ctx, 0); } } }else{ pNode = jsonLookup(p, zPath, 0, ctx); - if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx); + if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0); } }else{ /* Two or more PATH arguments results in a JSON array with each @@ -205986,9 +202872,9 @@ static void jsonExtractFunc( if( p->nErr ) break; jsonAppendSeparator(&jx); if( pNode ){ - jsonRenderNode(p, pNode, &jx); + jsonRenderNode(pNode, &jx, 0); }else{ - jsonAppendRawNZ(&jx, "null", 4); + jsonAppendRaw(&jx, "null", 4); } } if( i==argc ){ @@ -206029,42 +202915,51 @@ static JsonNode *jsonMergePatch( assert( pPatch[i].eU==1 ); nKey = pPatch[i].n; zKey = pPatch[i].u.zJContent; + assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); for(j=1; jn; j += jsonNodeSize(&pTarget[j+1])+1 ){ assert( pTarget[j].eType==JSON_STRING ); assert( pTarget[j].jnFlags & JNODE_LABEL ); - if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){ - if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break; + assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); + if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ + if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; if( pPatch[i+1].eType==JSON_NULL ){ pTarget[j+1].jnFlags |= JNODE_REMOVE; }else{ JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); if( pNew==0 ) return 0; - if( pNew!=&pParse->aNode[iTarget+j+1] ){ - jsonParseAddSubstNode(pParse, iTarget+j+1); - jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew)); - } pTarget = &pParse->aNode[iTarget]; + if( pNew!=&pTarget[j+1] ){ + assert( pTarget[j+1].eU==0 + || pTarget[j+1].eU==1 + || pTarget[j+1].eU==2 ); + testcase( pTarget[j+1].eU==1 ); + testcase( pTarget[j+1].eU==2 ); + VVA( pTarget[j+1].eU = 5 ); + pTarget[j+1].u.pPatch = pNew; + pTarget[j+1].jnFlags |= JNODE_PATCH; + } } break; } } if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ - int iStart; - JsonNode *pApnd; - u32 nApnd; - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); + int iStart, iPatch; + iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - pApnd = &pPatch[i+1]; - if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd); - nApnd = jsonNodeSize(pApnd); - jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd)); + iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); if( pParse->oom ) return 0; - pParse->aNode[iStart].n = 1+nApnd; + jsonRemoveAllNulls(pPatch); + pTarget = &pParse->aNode[iTarget]; + assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 ); + testcase( pParse->aNode[iRoot].eU==2 ); pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; - pParse->aNode[iRoot].u.iAppend = iStart; VVA( pParse->aNode[iRoot].eU = 2 ); + pParse->aNode[iRoot].u.iAppend = iStart - iRoot; iRoot = iStart; - pTarget = &pParse->aNode[iTarget]; + assert( pParse->aNode[iPatch].eU==0 ); + VVA( pParse->aNode[iPatch].eU = 5 ); + pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; + pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; } } return pTarget; @@ -206080,27 +202975,25 @@ static void jsonPatchFunc( int argc, sqlite3_value **argv ){ - JsonParse *pX; /* The JSON that is being patched */ - JsonParse *pY; /* The patch */ + JsonParse x; /* The JSON that is being patched */ + JsonParse y; /* The patch */ JsonNode *pResult; /* The result of the merge */ UNUSED_PARAMETER(argc); - pX = jsonParseCached(ctx, argv[0], ctx, 1); - if( pX==0 ) return; - pY = jsonParseCached(ctx, argv[1], ctx, 1); - if( pY==0 ) return; - pX->useMod = 1; - pX->hasMod = 1; - pY->useMod = 1; - pResult = jsonMergePatch(pX, 0, pY->aNode); - assert( pResult!=0 || pX->oom ); - if( pResult && pX->oom==0 ){ - jsonDebugPrintParse(pX); - jsonDebugPrintNode(pResult); - jsonReturnJson(pX, pResult, ctx, 0); + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ + jsonParseReset(&x); + return; + } + pResult = jsonMergePatch(&x, 0, y.aNode); + assert( pResult!=0 || x.oom ); + if( pResult ){ + jsonReturnJson(pResult, ctx, 0); }else{ sqlite3_result_error_nomem(ctx); } + jsonParseReset(&x); + jsonParseReset(&y); } @@ -206156,118 +203049,26 @@ static void jsonRemoveFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ + JsonParse x; /* The parse */ JsonNode *pNode; const char *zPath; u32 i; if( argc<1 ) return; - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); for(i=1; i<(u32)argc; i++){ zPath = (const char*)sqlite3_value_text(argv[i]); if( zPath==0 ) goto remove_done; - pNode = jsonLookup(pParse, zPath, 0, ctx); - if( pParse->nErr ) goto remove_done; - if( pNode ){ - pNode->jnFlags |= JNODE_REMOVE; - pParse->hasMod = 1; - pParse->useMod = 1; - } + pNode = jsonLookup(&x, zPath, 0, ctx); + if( x.nErr ) goto remove_done; + if( pNode ) pNode->jnFlags |= JNODE_REMOVE; } - if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){ - jsonReturnJson(pParse, pParse->aNode, ctx, 1); + if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ + jsonReturnJson(x.aNode, ctx, 0); } remove_done: - jsonDebugPrintParse(p); -} - -/* -** Substitute the value at iNode with the pValue parameter. -*/ -static void jsonReplaceNode( - sqlite3_context *pCtx, - JsonParse *p, - int iNode, - sqlite3_value *pValue -){ - int idx = jsonParseAddSubstNode(p, iNode); - if( idx<=0 ){ - assert( p->oom ); - return; - } - switch( sqlite3_value_type(pValue) ){ - case SQLITE_NULL: { - jsonParseAddNode(p, JSON_NULL, 0, 0); - break; - } - case SQLITE_FLOAT: { - char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue)); - int n; - if( z==0 ){ - p->oom = 1; - break; - } - n = sqlite3Strlen30(z); - jsonParseAddNode(p, JSON_REAL, n, z); - jsonParseAddCleanup(p, sqlite3_free, z); - break; - } - case SQLITE_INTEGER: { - char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue)); - int n; - if( z==0 ){ - p->oom = 1; - break; - } - n = sqlite3Strlen30(z); - jsonParseAddNode(p, JSON_INT, n, z); - jsonParseAddCleanup(p, sqlite3_free, z); - - break; - } - case SQLITE_TEXT: { - const char *z = (const char*)sqlite3_value_text(pValue); - u32 n = (u32)sqlite3_value_bytes(pValue); - if( z==0 ){ - p->oom = 1; - break; - } - if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ - char *zCopy = sqlite3DbStrDup(0, z); - int k; - if( zCopy ){ - jsonParseAddCleanup(p, sqlite3_free, zCopy); - }else{ - p->oom = 1; - sqlite3_result_error_nomem(pCtx); - } - k = jsonParseAddNode(p, JSON_STRING, n, zCopy); - assert( k>0 || p->oom ); - if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW; - }else{ - JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1); - if( pPatch==0 ){ - p->oom = 1; - break; - } - jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode); - /* The nodes copied out of pPatch and into p likely contain - ** u.zJContent pointers into pPatch->zJson. So preserve the - ** content of pPatch until p is destroyed. */ - assert( pPatch->nJPRef>=1 ); - pPatch->nJPRef++; - jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch); - } - break; - } - default: { - jsonParseAddNode(p, JSON_NULL, 0, 0); - sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1); - p->nErr++; - break; - } - } + jsonParseReset(&x); } /* @@ -206281,7 +203082,7 @@ static void jsonReplaceFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ + JsonParse x; /* The parse */ JsonNode *pNode; const char *zPath; u32 i; @@ -206291,20 +203092,28 @@ static void jsonReplaceFunc( jsonWrongNumArgs(ctx, "replace"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); - pParse->useMod = 1; - pNode = jsonLookup(pParse, zPath, 0, ctx); - if( pParse->nErr ) goto replace_err; + pNode = jsonLookup(&x, zPath, 0, ctx); + if( x.nErr ) goto replace_err; if( pNode ){ - jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); + assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 ); + testcase( pNode->eU!=0 && pNode->eU!=1 ); + pNode->jnFlags |= (u8)JNODE_REPLACE; + VVA( pNode->eU = 4 ); + pNode->u.iReplace = i + 1; } } - jsonReturnJson(pParse, pParse->aNode, ctx, 1); + if( x.aNode[0].jnFlags & JNODE_REPLACE ){ + assert( x.aNode[0].eU==4 ); + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); + }else{ + jsonReturnJson(x.aNode, ctx, argv); + } replace_err: - jsonDebugPrintParse(pParse); + jsonParseReset(&x); } @@ -206325,7 +203134,7 @@ static void jsonSetFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ + JsonParse x; /* The parse */ JsonNode *pNode; const char *zPath; u32 i; @@ -206337,27 +203146,33 @@ static void jsonSetFunc( jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); bApnd = 0; - pParse->useMod = 1; - pNode = jsonLookup(pParse, zPath, &bApnd, ctx); - if( pParse->oom ){ + pNode = jsonLookup(&x, zPath, &bApnd, ctx); + if( x.oom ){ sqlite3_result_error_nomem(ctx); goto jsonSetDone; - }else if( pParse->nErr ){ + }else if( x.nErr ){ goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ - jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); + testcase( pNode->eU!=0 && pNode->eU!=1 ); + assert( pNode->eU!=3 && pNode->eU!=5 ); + VVA( pNode->eU = 4 ); + pNode->jnFlags |= (u8)JNODE_REPLACE; + pNode->u.iReplace = i + 1; } } - jsonDebugPrintParse(pParse); - jsonReturnJson(pParse, pParse->aNode, ctx, 1); - + if( x.aNode[0].jnFlags & JNODE_REPLACE ){ + assert( x.aNode[0].eU==4 ); + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); + }else{ + jsonReturnJson(x.aNode, ctx, argv); + } jsonSetDone: - /* no cleanup required */; + jsonParseReset(&x); } /* @@ -206376,7 +203191,7 @@ static void jsonTypeFunc( const char *zPath; JsonNode *pNode; - p = jsonParseCached(ctx, argv[0], ctx, 0); + p = jsonParseCached(ctx, argv, ctx); if( p==0 ) return; if( argc==2 ){ zPath = (const char*)sqlite3_value_text(argv[1]); @@ -206392,8 +203207,8 @@ static void jsonTypeFunc( /* ** json_valid(JSON) ** -** Return 1 if JSON is a well-formed canonical JSON string according -** to RFC-7159. Return 0 otherwise. +** Return 1 if JSON is a well-formed JSON string according to RFC-7159. +** Return 0 otherwise. */ static void jsonValidFunc( sqlite3_context *ctx, @@ -206402,69 +203217,8 @@ static void jsonValidFunc( ){ JsonParse *p; /* The parse */ UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - p = jsonParseCached(ctx, argv[0], 0, 0); - if( p==0 || p->oom ){ - sqlite3_result_error_nomem(ctx); - sqlite3_free(p); - }else{ - sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod)); - if( p->nErr ) jsonParseFree(p); - } -} - -/* -** json_error_position(JSON) -** -** If the argument is not an interpretable JSON string, then return the 1-based -** character position at which the parser first recognized that the input -** was in error. The left-most character is 1. If the string is valid -** JSON, then return 0. -** -** Note that json_valid() is only true for strictly conforming canonical JSON. -** But this routine returns zero if the input contains extension. Thus: -** -** (1) If the input X is strictly conforming canonical JSON: -** -** json_valid(X) returns true -** json_error_position(X) returns 0 -** -** (2) If the input X is JSON but it includes extension (such as JSON5) that -** are not part of RFC-8259: -** -** json_valid(X) returns false -** json_error_position(X) return 0 -** -** (3) If the input X cannot be interpreted as JSON even taking extensions -** into account: -** -** json_valid(X) return false -** json_error_position(X) returns 1 or more -*/ -static void jsonErrorFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonParse *p; /* The parse */ - UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - p = jsonParseCached(ctx, argv[0], 0, 0); - if( p==0 || p->oom ){ - sqlite3_result_error_nomem(ctx); - sqlite3_free(p); - }else if( p->nErr==0 ){ - sqlite3_result_int(ctx, 0); - }else{ - int n = 1; - u32 i; - const char *z = (const char*)sqlite3_value_text(argv[0]); - for(i=0; iiErr && ALWAYS(z[i]); i++){ - if( (z[i]&0xc0)!=0x80 ) n++; - } - sqlite3_result_int(ctx, n); - jsonParseFree(p); - } + p = jsonParseCached(ctx, argv, 0); + sqlite3_result_int(ctx, p!=0); } @@ -206506,8 +203260,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ assert( pStr->bStatic ); }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, - pStr->bStatic ? SQLITE_TRANSIENT : - (void(*)(void*))sqlite3RCStrUnref); + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -206548,7 +203301,7 @@ static void jsonGroupInverse( 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 */ + ** always have been called to initalize it */ if( NEVER(!pStr) ) return; #endif z = pStr->zBuf; @@ -206615,8 +203368,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ assert( pStr->bStatic ); }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, - pStr->bStatic ? SQLITE_TRANSIENT : - (void(*)(void*))sqlite3RCStrUnref); + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -206727,6 +203479,7 @@ static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ /* Reset a JsonEachCursor back to its original state. Free any memory ** held. */ static void jsonEachCursorReset(JsonEachCursor *p){ + sqlite3_free(p->zJson); sqlite3_free(p->zRoot); jsonParseReset(&p->sParse); p->iRowid = 0; @@ -206809,16 +203562,14 @@ static void jsonAppendObjectPathElement( assert( pNode->eU==1 ); z = pNode->u.zJContent; nn = pNode->n; - if( (pNode->jnFlags & JNODE_RAW)==0 ){ - assert( nn>=2 ); - assert( z[0]=='"' || z[0]=='\'' ); - assert( z[nn-1]=='"' || z[0]=='\'' ); - if( nn>2 && sqlite3Isalpha(z[1]) ){ - for(jj=2; jj=2 ); + assert( z[0]=='"' ); + assert( z[nn-1]=='"' ); + if( nn>2 && sqlite3Isalpha(z[1]) ){ + for(jj=2; jji==0 ) break; if( p->eType==JSON_OBJECT ){ - jsonReturn(&p->sParse, pThis, ctx); + jsonReturn(pThis, ctx, 0); }else if( p->eType==JSON_ARRAY ){ u32 iKey; if( p->bRecursive ){ @@ -206880,7 +203631,7 @@ static int jsonEachColumn( } case JEACH_VALUE: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(&p->sParse, pThis, ctx); + jsonReturn(pThis, ctx, 0); break; } case JEACH_TYPE: { @@ -206891,7 +203642,7 @@ static int jsonEachColumn( case JEACH_ATOM: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(&p->sParse, pThis, ctx); + jsonReturn(pThis, ctx, 0); break; } case JEACH_ID: { @@ -207046,19 +203797,11 @@ static int jsonEachFilter( if( idxNum==0 ) return SQLITE_OK; z = (const char*)sqlite3_value_text(argv[0]); if( z==0 ) return SQLITE_OK; - memset(&p->sParse, 0, sizeof(p->sParse)); - p->sParse.nJPRef = 1; - if( sqlite3ValueIsOfClass(argv[0], (void(*)(void*))sqlite3RCStrUnref) ){ - p->sParse.zJson = sqlite3RCStrRef((char*)z); - }else{ - n = sqlite3_value_bytes(argv[0]); - p->sParse.zJson = sqlite3RCStrNew( n+1 ); - if( p->sParse.zJson==0 ) return SQLITE_NOMEM; - memcpy(p->sParse.zJson, z, (size_t)n+1); - } - p->sParse.bJsonIsRCStr = 1; - p->zJson = p->sParse.zJson; - if( jsonParse(&p->sParse, 0) ){ + n = sqlite3_value_bytes(argv[0]); + p->zJson = sqlite3_malloc64( n+1 ); + if( p->zJson==0 ) return SQLITE_NOMEM; + memcpy(p->zJson, z, (size_t)n+1); + if( jsonParse(&p->sParse, 0, p->zJson) ){ int rc = SQLITE_NOMEM; if( p->sParse.oom==0 ){ sqlite3_free(cur->pVtab->zErrMsg); @@ -207186,7 +203929,6 @@ SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ JFUNCTION(json_array, -1, 0, jsonArrayFunc), JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc), JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc), - JFUNCTION(json_error_position,1, 0, jsonErrorFunc), JFUNCTION(json_extract, -1, 0, jsonExtractFunc), JFUNCTION(->, 2, JSON_JSON, jsonExtractFunc), JFUNCTION(->>, 2, JSON_SQL, jsonExtractFunc), @@ -207336,11 +204078,6 @@ typedef unsigned int u32; #endif #endif /* !defined(SQLITE_AMALGAMATION) */ -/* Macro to check for 4-byte alignment. Only used inside of assert() */ -#ifdef SQLITE_DEBUG -# define FOUR_BYTE_ALIGNED(X) ((((char*)(X) - (char*)0) & 3)==0) -#endif - /* #include */ /* #include */ /* #include */ @@ -207716,17 +204453,16 @@ struct RtreeMatchArg { ** at run-time. */ #ifndef SQLITE_BYTEORDER -# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ - defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ - defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) -# define SQLITE_BYTEORDER 1234 -# elif defined(sparc) || defined(__ppc__) || \ - defined(__ARMEB__) || defined(__AARCH64EB__) -# define SQLITE_BYTEORDER 4321 -# else -# define SQLITE_BYTEORDER 0 -# endif +#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__) +# define SQLITE_BYTEORDER 1234 +#elif defined(sparc) || defined(__ppc__) +# define SQLITE_BYTEORDER 4321 +#else +# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */ +#endif #endif @@ -207747,7 +204483,7 @@ static int readInt16(u8 *p){ return (p[0]<<8) + p[1]; } static void readCoord(u8 *p, RtreeCoord *pCoord){ - assert( FOUR_BYTE_ALIGNED(p) ); + assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 pCoord->u = _byteswap_ulong(*(u32*)p); #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 @@ -207801,7 +204537,7 @@ static void writeInt16(u8 *p, int i){ } static int writeCoord(u8 *p, RtreeCoord *pCoord){ u32 i; - assert( FOUR_BYTE_ALIGNED(p) ); + assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ assert( sizeof(RtreeCoord)==4 ); assert( sizeof(u32)==4 ); #if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 @@ -208529,7 +205265,7 @@ static void rtreeNonleafConstraint( assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE || p->op==RTREE_FALSE ); - assert( FOUR_BYTE_ALIGNED(pCellData) ); + assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ @@ -208582,7 +205318,7 @@ static void rtreeLeafConstraint( || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE || p->op==RTREE_FALSE ); pCellData += 8 + p->iCoord*4; - assert( FOUR_BYTE_ALIGNED(pCellData) ); + assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ RTREE_DECODE_COORD(eInt, pCellData, xN); switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ @@ -209152,20 +205888,7 @@ static int rtreeFilter( p->pInfo->nCoord = pRtree->nDim2; p->pInfo->anQueue = pCsr->anQueue; p->pInfo->mxLevel = pRtree->iDepth + 1; - }else if( eType==SQLITE_INTEGER ){ - sqlite3_int64 iVal = sqlite3_value_int64(argv[ii]); -#ifdef SQLITE_RTREE_INT_ONLY - p->u.rValue = iVal; -#else - p->u.rValue = (double)iVal; - if( iVal>=((sqlite3_int64)1)<<48 - || -iVal>=((sqlite3_int64)1)<<48 - ){ - if( p->op==RTREE_LT ) p->op = RTREE_LE; - if( p->op==RTREE_GT ) p->op = RTREE_GE; - } -#endif - }else if( eType==SQLITE_FLOAT ){ + }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ #ifdef SQLITE_RTREE_INT_ONLY p->u.rValue = sqlite3_value_int64(argv[ii]); #else @@ -209296,12 +206019,11 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ u8 op; - u8 doOmit = 1; switch( p->op ){ - case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; doOmit = 0; break; - case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; + case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; - case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break; default: op = 0; break; @@ -209310,7 +206032,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ zIdxStr[iIdx++] = op; zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); - pIdxInfo->aConstraintUsage[ii].omit = doOmit; + pIdxInfo->aConstraintUsage[ii].omit = 1; } } } @@ -218285,11 +215007,6 @@ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){ p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff); } -/* -** This value is copied from the definition of ZIPVFS_CTRL_FILE_POINTER -** in zipvfs.h. -*/ -#define RBU_ZIPVFS_CTRL_FILE_POINTER 230439 /* ** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if @@ -218298,20 +215015,9 @@ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){ static int rbuLockDatabase(sqlite3 *db){ int rc = SQLITE_OK; sqlite3_file *fd = 0; + sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); - sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd); - if( fd ){ - sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); - rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); - if( rc==SQLITE_OK ){ - rc = fd->pMethods->xUnlock(fd, SQLITE_LOCK_NONE); - } - sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd); - }else{ - sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); - } - - if( rc==SQLITE_OK && fd->pMethods ){ + if( fd->pMethods ){ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); if( rc==SQLITE_OK ){ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE); @@ -221548,7 +218254,6 @@ static int dbpageConnect( (void)pzErr; sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); - sqlite3_vtab_config(db, SQLITE_VTAB_USES_ALL_SCHEMAS); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); if( rc==SQLITE_OK ){ @@ -221632,6 +218337,7 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ){ pIdxInfo->orderByConsumed = 1; } + sqlite3VtabUsesAllSchemas(pIdxInfo); return SQLITE_OK; } @@ -221932,8 +218638,6 @@ typedef struct SessionInput SessionInput; # endif #endif -#define SESSIONS_ROWID "_rowid_" - /* ** The three different types of changesets generated. */ @@ -221962,7 +218666,6 @@ struct sqlite3_session { int bEnable; /* True if currently recording */ int bIndirect; /* True if all changes are indirect */ int bAutoAttach; /* True to auto-attach tables */ - int bImplicitPK; /* True to handle tables with implicit PK */ int rc; /* Non-zero if an error has occurred */ void *pFilterCtx; /* First argument to pass to xTableFilter */ int (*xTableFilter)(void *pCtx, const char *zTab); @@ -222040,7 +218743,6 @@ struct SessionTable { char *zName; /* Local name of table */ int nCol; /* Number of columns in table zName */ int bStat1; /* True if this is sqlite_stat1 */ - int bRowid; /* True if this table uses rowid for PK */ const char **azCol; /* Column names */ u8 *abPK; /* Array of primary key flags */ int nEntry; /* Total number of entries in hash table */ @@ -222433,7 +219135,6 @@ static unsigned int sessionHashAppendType(unsigned int h, int eType){ */ static int sessionPreupdateHash( sqlite3_session *pSession, /* Session object that owns pTab */ - i64 iRowid, SessionTable *pTab, /* Session table handle */ int bNew, /* True to hash the new.* PK */ int *piHash, /* OUT: Hash value */ @@ -222442,53 +219143,48 @@ static int sessionPreupdateHash( unsigned int h = 0; /* Hash value to return */ int i; /* Used to iterate through columns */ - if( pTab->bRowid ){ - assert( pTab->nCol-1==pSession->hook.xCount(pSession->hook.pCtx) ); - h = sessionHashAppendI64(h, iRowid); - }else{ - assert( *pbNullPK==0 ); - assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) ); - for(i=0; inCol; i++){ - if( pTab->abPK[i] ){ - int rc; - int eType; - sqlite3_value *pVal; + assert( *pbNullPK==0 ); + assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) ); + for(i=0; inCol; i++){ + if( pTab->abPK[i] ){ + int rc; + int eType; + sqlite3_value *pVal; - if( bNew ){ - rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal); + if( bNew ){ + rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal); + }else{ + rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal); + } + if( rc!=SQLITE_OK ) return rc; + + eType = sqlite3_value_type(pVal); + h = sessionHashAppendType(h, eType); + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + i64 iVal; + if( eType==SQLITE_INTEGER ){ + iVal = sqlite3_value_int64(pVal); }else{ - rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal); + double rVal = sqlite3_value_double(pVal); + assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); + memcpy(&iVal, &rVal, 8); } - if( rc!=SQLITE_OK ) return rc; - - eType = sqlite3_value_type(pVal); - h = sessionHashAppendType(h, eType); - if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - i64 iVal; - if( eType==SQLITE_INTEGER ){ - iVal = sqlite3_value_int64(pVal); - }else{ - double rVal = sqlite3_value_double(pVal); - assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); - memcpy(&iVal, &rVal, 8); - } - h = sessionHashAppendI64(h, iVal); - }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ - const u8 *z; - int n; - if( eType==SQLITE_TEXT ){ - z = (const u8 *)sqlite3_value_text(pVal); - }else{ - z = (const u8 *)sqlite3_value_blob(pVal); - } - n = sqlite3_value_bytes(pVal); - if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; - h = sessionHashAppendBlob(h, n, z); + h = sessionHashAppendI64(h, iVal); + }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + const u8 *z; + int n; + if( eType==SQLITE_TEXT ){ + z = (const u8 *)sqlite3_value_text(pVal); }else{ - assert( eType==SQLITE_NULL ); - assert( pTab->bStat1==0 || i!=1 ); - *pbNullPK = 1; + z = (const u8 *)sqlite3_value_blob(pVal); } + n = sqlite3_value_bytes(pVal); + if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; + h = sessionHashAppendBlob(h, n, z); + }else{ + assert( eType==SQLITE_NULL ); + assert( pTab->bStat1==0 || i!=1 ); + *pbNullPK = 1; } } } @@ -222771,7 +219467,6 @@ static int sessionMergeUpdate( */ static int sessionPreupdateEqual( sqlite3_session *pSession, /* Session object that owns SessionTable */ - i64 iRowid, /* Rowid value if pTab->bRowid */ SessionTable *pTab, /* Table associated with change */ SessionChange *pChange, /* Change to compare to */ int op /* Current pre-update operation */ @@ -222779,11 +219474,6 @@ static int sessionPreupdateEqual( int iCol; /* Used to iterate through columns */ u8 *a = pChange->aRecord; /* Cursor used to scan change record */ - if( pTab->bRowid ){ - if( a[0]!=SQLITE_INTEGER ) return 0; - return sessionGetI64(&a[1])==iRowid; - } - assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); for(iCol=0; iColnCol; iCol++){ if( !pTab->abPK[iCol] ){ @@ -222806,7 +219496,6 @@ static int sessionPreupdateEqual( rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal); } assert( rc==SQLITE_OK ); - (void)rc; /* Suppress warning about unused variable */ if( sqlite3_value_type(pVal)!=eType ) return 0; /* A SessionChange object never has a NULL value in a PK column */ @@ -222929,8 +219618,7 @@ static int sessionTableInfo( int *pnCol, /* OUT: number of columns */ const char **pzTab, /* OUT: Copy of zThis */ const char ***pazCol, /* OUT: Array of column names for table */ - u8 **pabPK, /* OUT: Array of booleans - true for PK col */ - int *pbRowid /* OUT: True if only PK is a rowid */ + u8 **pabPK /* OUT: Array of booleans - true for PK col */ ){ char *zPragma; sqlite3_stmt *pStmt; @@ -222942,7 +219630,6 @@ static int sessionTableInfo( u8 *pAlloc = 0; char **azCol = 0; u8 *abPK = 0; - int bRowid = 0; /* Set to true to use rowid as PK */ assert( pazCol && pabPK ); @@ -222987,15 +219674,10 @@ static int sessionTableInfo( } nByte = nThis + 1; - bRowid = (pbRowid!=0); while( SQLITE_ROW==sqlite3_step(pStmt) ){ nByte += sqlite3_column_bytes(pStmt, 1); nDbCol++; - if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; } - if( nDbCol==0 ) bRowid = 0; - nDbCol += bRowid; - nByte += strlen(SESSIONS_ROWID); rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ){ @@ -223017,14 +219699,6 @@ static int sessionTableInfo( } i = 0; - if( bRowid ){ - size_t nName = strlen(SESSIONS_ROWID); - memcpy(pAlloc, SESSIONS_ROWID, nName+1); - azCol[i] = (char*)pAlloc; - pAlloc += nName+1; - abPK[i] = 1; - i++; - } while( SQLITE_ROW==sqlite3_step(pStmt) ){ int nName = sqlite3_column_bytes(pStmt, 1); const unsigned char *zName = sqlite3_column_text(pStmt, 1); @@ -223036,6 +219710,7 @@ static int sessionTableInfo( i++; } rc = sqlite3_reset(pStmt); + } /* If successful, populate the output variables. Otherwise, zero them and @@ -223052,7 +219727,6 @@ static int sessionTableInfo( if( pzTab ) *pzTab = 0; sessionFree(pSession, azCol); } - if( pbRowid ) *pbRowid = bRowid; sqlite3_finalize(pStmt); return rc; } @@ -223074,8 +219748,7 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, - pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK, - (pSession->bImplicitPK ? &pTab->bRowid : 0) + pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK ); if( pSession->rc==SQLITE_OK ){ int i; @@ -223147,7 +219820,6 @@ static int sessionUpdateMaxSize( ){ i64 nNew = 2; if( pC->op==SQLITE_INSERT ){ - if( pTab->bRowid ) nNew += 9; if( op!=SQLITE_DELETE ){ int ii; for(ii=0; iinCol; ii++){ @@ -223164,16 +219836,12 @@ static int sessionUpdateMaxSize( }else{ int ii; u8 *pCsr = pC->aRecord; - if( pTab->bRowid ){ - nNew += 9 + 1; - pCsr += 9; - } - for(ii=pTab->bRowid; iinCol; ii++){ + for(ii=0; iinCol; ii++){ int bChanged = 1; int nOld = 0; int eType; sqlite3_value *p = 0; - pSession->hook.xNew(pSession->hook.pCtx, ii-pTab->bRowid, &p); + pSession->hook.xNew(pSession->hook.pCtx, ii, &p); if( p==0 ){ return SQLITE_NOMEM; } @@ -223252,7 +219920,6 @@ static int sessionUpdateMaxSize( */ static void sessionPreupdateOneChange( int op, /* One of SQLITE_UPDATE, INSERT, DELETE */ - i64 iRowid, sqlite3_session *pSession, /* Session object pTab is attached to */ SessionTable *pTab /* Table that change applies to */ ){ @@ -223268,7 +219935,7 @@ static void sessionPreupdateOneChange( /* Check the number of columns in this xPreUpdate call matches the ** number of columns in the table. */ - if( (pTab->nCol-pTab->bRowid)!=pSession->hook.xCount(pSession->hook.pCtx) ){ + if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){ pSession->rc = SQLITE_SCHEMA; return; } @@ -223301,16 +219968,14 @@ static void sessionPreupdateOneChange( /* Calculate the hash-key for this change. If the primary key of the row ** includes a NULL value, exit early. Such changes are ignored by the ** session module. */ - rc = sessionPreupdateHash( - pSession, iRowid, pTab, op==SQLITE_INSERT, &iHash, &bNull - ); + rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull); if( rc!=SQLITE_OK ) goto error_out; if( bNull==0 ){ /* Search the hash table for an existing record for this row. */ SessionChange *pC; for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){ - if( sessionPreupdateEqual(pSession, iRowid, pTab, pC, op) ) break; + if( sessionPreupdateEqual(pSession, pTab, pC, op) ) break; } if( pC==0 ){ @@ -223325,7 +219990,7 @@ static void sessionPreupdateOneChange( /* Figure out how large an allocation is required */ nByte = sizeof(SessionChange); - for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ + for(i=0; inCol; i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); @@ -223340,9 +220005,6 @@ static void sessionPreupdateOneChange( rc = sessionSerializeValue(0, p, &nByte); if( rc!=SQLITE_OK ) goto error_out; } - if( pTab->bRowid ){ - nByte += 9; /* Size of rowid field - an integer */ - } /* Allocate the change object */ pC = (SessionChange *)sessionMalloc64(pSession, nByte); @@ -223359,12 +220021,7 @@ static void sessionPreupdateOneChange( ** required values and encodings have already been cached in memory. ** It is not possible for an OOM to occur in this block. */ nByte = 0; - if( pTab->bRowid ){ - pC->aRecord[0] = SQLITE_INTEGER; - sessionPutI64(&pC->aRecord[1], iRowid); - nByte = 9; - } - for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ + for(i=0; inCol; i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ pSession->hook.xOld(pSession->hook.pCtx, i, &p); @@ -223479,10 +220136,9 @@ static void xPreUpdate( pSession->rc = sessionFindTable(pSession, zName, &pTab); if( pTab ){ assert( pSession->rc==SQLITE_OK ); - assert( op==SQLITE_UPDATE || iKey1==iKey2 ); - sessionPreupdateOneChange(op, iKey1, pSession, pTab); + sessionPreupdateOneChange(op, pSession, pTab); if( op==SQLITE_UPDATE ){ - sessionPreupdateOneChange(SQLITE_INSERT, iKey2, pSession, pTab); + sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab); } } } @@ -223521,7 +220177,6 @@ static void sessionPreupdateHooks( typedef struct SessionDiffCtx SessionDiffCtx; struct SessionDiffCtx { sqlite3_stmt *pStmt; - int bRowid; int nOldOff; }; @@ -223530,17 +220185,17 @@ struct SessionDiffCtx { */ static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){ SessionDiffCtx *p = (SessionDiffCtx*)pCtx; - *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff+p->bRowid); + *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff); return SQLITE_OK; } static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){ SessionDiffCtx *p = (SessionDiffCtx*)pCtx; - *ppVal = sqlite3_column_value(p->pStmt, iVal+p->bRowid); + *ppVal = sqlite3_column_value(p->pStmt, iVal); return SQLITE_OK; } static int sessionDiffCount(void *pCtx){ SessionDiffCtx *p = (SessionDiffCtx*)pCtx; - return (p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt)) - p->bRowid; + return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt); } static int sessionDiffDepth(void *pCtx){ (void)pCtx; @@ -223619,16 +220274,14 @@ static char *sessionExprCompareOther( static char *sessionSelectFindNew( const char *zDb1, /* Pick rows in this db only */ const char *zDb2, /* But not in this one */ - int bRowid, const char *zTbl, /* Table name */ const char *zExpr ){ - const char *zSel = (bRowid ? SESSIONS_ROWID ", *" : "*"); char *zRet = sqlite3_mprintf( - "SELECT %s FROM \"%w\".\"%w\" WHERE NOT EXISTS (" + "SELECT * FROM \"%w\".\"%w\" WHERE NOT EXISTS (" " SELECT 1 FROM \"%w\".\"%w\" WHERE %s" ")", - zSel, zDb1, zTbl, zDb2, zTbl, zExpr + zDb1, zTbl, zDb2, zTbl, zExpr ); return zRet; } @@ -223642,9 +220295,7 @@ static int sessionDiffFindNew( char *zExpr ){ int rc = SQLITE_OK; - char *zStmt = sessionSelectFindNew( - zDb1, zDb2, pTab->bRowid, pTab->zName, zExpr - ); + char *zStmt = sessionSelectFindNew(zDb1, zDb2, pTab->zName,zExpr); if( zStmt==0 ){ rc = SQLITE_NOMEM; @@ -223655,10 +220306,8 @@ static int sessionDiffFindNew( SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; pDiffCtx->pStmt = pStmt; pDiffCtx->nOldOff = 0; - pDiffCtx->bRowid = pTab->bRowid; while( SQLITE_ROW==sqlite3_step(pStmt) ){ - i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0); - sessionPreupdateOneChange(op, iRowid, pSession, pTab); + sessionPreupdateOneChange(op, pSession, pTab); } rc = sqlite3_finalize(pStmt); } @@ -223668,27 +220317,6 @@ static int sessionDiffFindNew( return rc; } -/* -** Return a comma-separated list of the fully-qualified (with both database -** and table name) column names from table pTab. e.g. -** -** "main"."t1"."a", "main"."t1"."b", "main"."t1"."c" -*/ -static char *sessionAllCols( - const char *zDb, - SessionTable *pTab -){ - int ii; - char *zRet = 0; - for(ii=0; iinCol; ii++){ - zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"", - zRet, (zRet ? ", " : ""), zDb, pTab->zName, pTab->azCol[ii] - ); - if( !zRet ) break; - } - return zRet; -} - static int sessionDiffFindModified( sqlite3_session *pSession, SessionTable *pTab, @@ -223703,13 +220331,11 @@ static int sessionDiffFindModified( if( zExpr2==0 ){ rc = SQLITE_NOMEM; }else{ - char *z1 = sessionAllCols(pSession->zDb, pTab); - char *z2 = sessionAllCols(zFrom, pTab); char *zStmt = sqlite3_mprintf( - "SELECT %s,%s FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)", - z1, z2, pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2 + "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)", + pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2 ); - if( zStmt==0 || z1==0 || z2==0 ){ + if( zStmt==0 ){ rc = SQLITE_NOMEM; }else{ sqlite3_stmt *pStmt; @@ -223720,15 +220346,12 @@ static int sessionDiffFindModified( pDiffCtx->pStmt = pStmt; pDiffCtx->nOldOff = pTab->nCol; while( SQLITE_ROW==sqlite3_step(pStmt) ){ - i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0); - sessionPreupdateOneChange(SQLITE_UPDATE, iRowid, pSession, pTab); + sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab); } rc = sqlite3_finalize(pStmt); } + sqlite3_free(zStmt); } - sqlite3_free(zStmt); - sqlite3_free(z1); - sqlite3_free(z2); } return rc; @@ -223767,12 +220390,9 @@ SQLITE_API int sqlite3session_diff( int bHasPk = 0; int bMismatch = 0; int nCol; /* Columns in zFrom.zTbl */ - int bRowid = 0; u8 *abPK; const char **azCol = 0; - rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK, - pSession->bImplicitPK ? &bRowid : 0 - ); + rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); if( rc==SQLITE_OK ){ if( pTo->nCol!=nCol ){ bMismatch = 1; @@ -224114,10 +220734,9 @@ static void sessionAppendStr( int *pRc ){ int nStr = sqlite3Strlen30(zStr); - if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ + if( 0==sessionBufferGrow(p, nStr, pRc) ){ memcpy(&p->aBuf[p->nBuf], zStr, nStr); p->nBuf += nStr; - p->aBuf[p->nBuf] = 0x00; } } @@ -224139,27 +220758,6 @@ static void sessionAppendInteger( sessionAppendStr(p, aBuf, pRc); } -static void sessionAppendPrintf( - SessionBuffer *p, /* Buffer to append to */ - int *pRc, - const char *zFmt, - ... -){ - if( *pRc==SQLITE_OK ){ - char *zApp = 0; - va_list ap; - va_start(ap, zFmt); - zApp = sqlite3_vmprintf(zFmt, ap); - if( zApp==0 ){ - *pRc = SQLITE_NOMEM; - }else{ - sessionAppendStr(p, zApp, pRc); - } - va_end(ap); - sqlite3_free(zApp); - } -} - /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string zStr enclosed in quotes (") and @@ -224174,7 +220772,7 @@ static void sessionAppendIdent( const char *zStr, /* String to quote, escape and append */ int *pRc /* IN/OUT: Error code */ ){ - int nStr = sqlite3Strlen30(zStr)*2 + 2 + 2; + int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1; if( 0==sessionBufferGrow(p, nStr, pRc) ){ char *zOut = (char *)&p->aBuf[p->nBuf]; const char *zIn = zStr; @@ -224185,7 +220783,6 @@ static void sessionAppendIdent( } *zOut++ = '"'; p->nBuf = (int)((u8 *)zOut - p->aBuf); - p->aBuf[p->nBuf] = 0x00; } } @@ -224321,7 +220918,7 @@ static int sessionAppendUpdate( /* If at least one field has been modified, this is not a no-op. */ if( bChanged ) bNoop = 0; - /* Add a field to the old.* record. This is omitted if this module is + /* Add a field to the old.* record. This is omitted if this modules is ** currently generating a patchset. */ if( ePatchset!=SESSIONS_PATCHSET ){ if( ePatchset==SESSIONS_FULLCHANGESET || bChanged || abPK[i] ){ @@ -224410,20 +221007,12 @@ static int sessionAppendDelete( ** Formulate and prepare a SELECT statement to retrieve a row from table ** zTab in database zDb based on its primary key. i.e. ** -** SELECT *, FROM zDb.zTab WHERE (pk1, pk2,...) IS (?1, ?2,...) -** -** where is: -** -** 1 AND (?A OR ?1 IS ) AND ... -** -** for each non-pk . +** SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ... */ static int sessionSelectStmt( sqlite3 *db, /* Database handle */ - int bIgnoreNoop, const char *zDb, /* Database name */ const char *zTab, /* Table name */ - int bRowid, int nCol, /* Number of columns in table */ const char **azCol, /* Names of table columns */ u8 *abPK, /* PRIMARY KEY array */ @@ -224431,50 +221020,8 @@ static int sessionSelectStmt( ){ int rc = SQLITE_OK; char *zSql = 0; - const char *zSep = ""; - const char *zCols = bRowid ? SESSIONS_ROWID ", *" : "*"; int nSql = -1; - int i; - - SessionBuffer nooptest = {0, 0, 0}; - SessionBuffer pkfield = {0, 0, 0}; - SessionBuffer pkvar = {0, 0, 0}; - - sessionAppendStr(&nooptest, ", 1", &rc); - - if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){ - sessionAppendStr(&nooptest, " AND (?6 OR ?3 IS stat)", &rc); - sessionAppendStr(&pkfield, "tbl, idx", &rc); - sessionAppendStr(&pkvar, - "?1, (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", &rc - ); - zCols = "tbl, ?2, stat"; - }else{ - for(i=0; izDb, zName, &nCol, 0, &azCol, &abPK, - (pSession->bImplicitPK ? &bRowid : 0) - ); - if( rc==SQLITE_OK && ( - pTab->nCol!=nCol - || pTab->bRowid!=bRowid - || memcmp(abPK, pTab->abPK, nCol) - )){ + rc = sessionTableInfo(0, db, pSession->zDb, zName, &nCol, 0,&azCol,&abPK); + if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){ rc = SQLITE_SCHEMA; } @@ -224678,8 +221214,7 @@ static int sessionGenerateChangeset( /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ rc = sessionSelectStmt( - db, 0, pSession->zDb, zName, bRowid, nCol, azCol, abPK, &pSel - ); + db, pSession->zDb, zName, nCol, azCol, abPK, &pSel); } nNoop = buf.nBuf; @@ -224894,19 +221429,6 @@ SQLITE_API int sqlite3session_object_config(sqlite3_session *pSession, int op, v break; } - case SQLITE_SESSION_OBJCONFIG_ROWID: { - int iArg = *(int*)pArg; - if( iArg>=0 ){ - if( pSession->pTable ){ - rc = SQLITE_MISUSE; - }else{ - pSession->bImplicitPK = (iArg!=0); - } - } - *(int*)pArg = pSession->bImplicitPK; - break; - } - default: rc = SQLITE_MISUSE; } @@ -225904,8 +222426,6 @@ struct SessionApplyCtx { SessionBuffer rebase; /* Rebase information (if any) here */ u8 bRebaseStarted; /* If table header is already in rebase */ u8 bRebase; /* True to collect rebase information */ - u8 bIgnoreNoop; /* True to ignore no-op conflicts */ - int bRowid; }; /* Number of prepared UPDATE statements to cache. */ @@ -226156,10 +222676,8 @@ static int sessionSelectRow( const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ - /* TODO */ - return sessionSelectStmt(db, p->bIgnoreNoop, - "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect - ); + return sessionSelectStmt( + db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect); } /* @@ -226318,33 +222836,20 @@ static int sessionBindRow( */ static int sessionSeekToRow( sqlite3_changeset_iter *pIter, /* Changeset iterator */ - SessionApplyCtx *p + u8 *abPK, /* Primary key flags array */ + sqlite3_stmt *pSelect /* SELECT statement from sessionSelectRow() */ ){ - sqlite3_stmt *pSelect = p->pSelect; int rc; /* Return code */ int nCol; /* Number of columns in table */ int op; /* Changset operation (SQLITE_UPDATE etc.) */ const char *zDummy; /* Unused */ - sqlite3_clear_bindings(pSelect); sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); rc = sessionBindRow(pIter, op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old, - nCol, p->abPK, pSelect + nCol, abPK, pSelect ); - if( op!=SQLITE_DELETE && p->bIgnoreNoop ){ - int ii; - for(ii=0; rc==SQLITE_OK && iiabPK[ii]==0 ){ - sqlite3_value *pVal = 0; - sqlite3changeset_new(pIter, ii, &pVal); - sqlite3_bind_int(pSelect, ii+1+nCol, (pVal==0)); - if( pVal ) rc = sessionBindValue(pSelect, ii+1, pVal); - } - } - } - if( rc==SQLITE_OK ){ rc = sqlite3_step(pSelect); if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect); @@ -226459,22 +222964,16 @@ static int sessionConflictHandler( /* Bind the new.* PRIMARY KEY values to the SELECT statement. */ if( pbReplace ){ - rc = sessionSeekToRow(pIter, p); + rc = sessionSeekToRow(pIter, p->abPK, p->pSelect); }else{ rc = SQLITE_OK; } if( rc==SQLITE_ROW ){ /* There exists another row with the new.* primary key. */ - if( p->bIgnoreNoop - && sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1) - ){ - res = SQLITE_CHANGESET_OMIT; - }else{ - pIter->pConflict = p->pSelect; - res = xConflict(pCtx, eType, pIter); - pIter->pConflict = 0; - } + pIter->pConflict = p->pSelect; + res = xConflict(pCtx, eType, pIter); + pIter->pConflict = 0; rc = sqlite3_reset(p->pSelect); }else if( rc==SQLITE_OK ){ if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){ @@ -226582,7 +223081,7 @@ static int sessionApplyOneOp( sqlite3_step(p->pDelete); rc = sqlite3_reset(p->pDelete); - if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 && p->bIgnoreNoop==0 ){ + if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ rc = sessionConflictHandler( SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry ); @@ -226639,7 +223138,7 @@ static int sessionApplyOneOp( /* Check if there is a conflicting row. For sqlite_stat1, this needs ** to be done using a SELECT, as there is no PRIMARY KEY in the ** database schema to throw an exception if a duplicate is inserted. */ - rc = sessionSeekToRow(pIter, p); + rc = sessionSeekToRow(pIter, p->abPK, p->pSelect); if( rc==SQLITE_ROW ){ rc = SQLITE_CONSTRAINT; sqlite3_reset(p->pSelect); @@ -226816,7 +223315,6 @@ static int sessionChangesetApply( memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); @@ -226854,7 +223352,6 @@ static int sessionChangesetApply( sApply.bStat1 = 0; sApply.bDeferConstraints = 1; sApply.bRebaseStarted = 0; - sApply.bRowid = 0; memset(&sApply.constraints, 0, sizeof(SessionBuffer)); /* If an xFilter() callback was specified, invoke it now. If the @@ -226874,8 +223371,8 @@ static int sessionChangesetApply( int i; sqlite3changeset_pk(pIter, &abPK, 0); - rc = sessionTableInfo(0, db, "main", zNew, - &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK, &sApply.bRowid + rc = sessionTableInfo(0, + db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK ); if( rc!=SQLITE_OK ) break; for(i=0; iiPos++; - if( p->iRangeEnd>=0 ){ + if( p->iRangeEnd>0 ){ if( iPosiRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK; if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff; } @@ -231109,7 +227584,7 @@ static int fts5HighlightCb( } if( iPos==p->iter.iEnd ){ - if( p->iRangeEnd>=0 && p->iter.iStartiRangeStart ){ + if( p->iRangeEnd && p->iter.iStartiRangeStart ){ fts5HighlightAppend(&rc, p, p->zOpen, -1); } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); @@ -231120,7 +227595,7 @@ static int fts5HighlightCb( } } - if( p->iRangeEnd>=0 && iPos==p->iRangeEnd ){ + if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; if( iPos>=p->iter.iStart && iPositer.iEnd ){ @@ -231155,7 +227630,6 @@ static void fts5HighlightFunction( memset(&ctx, 0, sizeof(HighlightContext)); ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); - ctx.iRangeEnd = -1; rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); if( ctx.zIn ){ @@ -231341,7 +227815,6 @@ static void fts5SnippetFunction( iCol = sqlite3_value_int(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]); @@ -232082,8 +228555,6 @@ static void sqlite3Fts5TermsetFree(Fts5Termset *p){ #define FTS5_DEFAULT_CRISISMERGE 16 #define FTS5_DEFAULT_HASHSIZE (1024*1024) -#define FTS5_DEFAULT_DELETE_AUTOMERGE 10 /* default 10% */ - /* Maximum allowed page size */ #define FTS5_MAX_PAGE_SIZE (64*1024) @@ -232414,16 +228885,6 @@ static int fts5ConfigParseSpecial( return rc; } - if( sqlite3_strnicmp("contentless_delete", zCmd, nCmd)==0 ){ - if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ - *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive"); - rc = SQLITE_ERROR; - }else{ - pConfig->bContentlessDelete = (zArg[0]=='1'); - } - return rc; - } - if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ if( pConfig->zContentRowid ){ *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); @@ -232622,7 +229083,6 @@ static int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; } - assert( (pRet->abUnindexed && pRet->azCol) || rc!=SQLITE_OK ); for(i=3; rc==SQLITE_OK && ibContentlessDelete - && pRet->eContent!=FTS5_CONTENT_NONE - ){ - *pzErr = sqlite3_mprintf( - "contentless_delete=1 requires a contentless table" - ); - rc = SQLITE_ERROR; - } - - /* We only allow contentless_delete=1 if columnsize=0 is not present. - ** - ** This restriction may be removed at some point. - */ - if( rc==SQLITE_OK && pRet->bContentlessDelete && pRet->bColumnsize==0 ){ - *pzErr = sqlite3_mprintf( - "contentless_delete=1 is incompatible with columnsize=0" - ); - rc = SQLITE_ERROR; - } - /* If a tokenizer= option was successfully parsed, the tokenizer has ** already been allocated. Otherwise, allocate an instance of the default ** tokenizer (unicode61) now. */ @@ -232984,18 +229422,6 @@ static int sqlite3Fts5ConfigSetValue( } } - else if( 0==sqlite3_stricmp(zKey, "deletemerge") ){ - int nVal = -1; - if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ - nVal = sqlite3_value_int(pVal); - }else{ - *pbBadkey = 1; - } - if( nVal<0 ) nVal = FTS5_DEFAULT_DELETE_AUTOMERGE; - if( nVal>100 ) nVal = 0; - pConfig->nDeleteMerge = nVal; - } - else if( 0==sqlite3_stricmp(zKey, "rank") ){ const char *zIn = (const char*)sqlite3_value_text(pVal); char *zRank; @@ -233010,18 +229436,6 @@ static int sqlite3Fts5ConfigSetValue( rc = SQLITE_OK; *pbBadkey = 1; } - } - - else if( 0==sqlite3_stricmp(zKey, "secure-delete") ){ - int bVal = -1; - if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ - bVal = sqlite3_value_int(pVal); - } - if( bVal<0 ){ - *pbBadkey = 1; - }else{ - pConfig->bSecureDelete = (bVal ? 1 : 0); - } }else{ *pbBadkey = 1; } @@ -233044,7 +229458,6 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE; pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE; pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE; - pConfig->nDeleteMerge = FTS5_DEFAULT_DELETE_AUTOMERGE; zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName); if( zSql ){ @@ -233067,20 +229480,15 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ rc = sqlite3_finalize(p); } - if( rc==SQLITE_OK - && iVersion!=FTS5_CURRENT_VERSION - && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE - ){ + if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){ rc = SQLITE_ERROR; if( pConfig->pzErrmsg ){ assert( 0==*pConfig->pzErrmsg ); - *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format " - "(found %d, expected %d or %d) - run 'rebuild'", - iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE + *pConfig->pzErrmsg = sqlite3_mprintf( + "invalid fts5 file format (found %d, expected %d) - run 'rebuild'", + iVersion, FTS5_CURRENT_VERSION ); } - }else{ - pConfig->iVersion = iVersion; } if( rc==SQLITE_OK ){ @@ -233108,10 +229516,6 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ /* #include "fts5Int.h" */ /* #include "fts5parse.h" */ -#ifndef SQLITE_FTS5_MAX_EXPR_DEPTH -# define SQLITE_FTS5_MAX_EXPR_DEPTH 256 -#endif - /* ** All token types in the generated fts5parse.h file are greater than 0. */ @@ -233152,17 +229556,11 @@ struct Fts5Expr { ** FTS5_NOT (nChild, apChild valid) ** FTS5_STRING (pNear valid) ** FTS5_TERM (pNear valid) -** -** iHeight: -** Distance from this node to furthest leaf. This is always 0 for nodes -** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one -** greater than the largest child value. */ struct Fts5ExprNode { int eType; /* Node type */ int bEof; /* True at EOF */ int bNomatch; /* True if entry is not a match */ - int iHeight; /* Distance to tree leaf nodes */ /* Next method for this node. */ int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64); @@ -233232,31 +229630,6 @@ struct Fts5Parse { int bPhraseToAnd; /* Convert "a+b" to "a AND b" */ }; -/* -** Check that the Fts5ExprNode.iHeight variables are set correctly in -** the expression tree passed as the only argument. -*/ -#ifndef NDEBUG -static void assert_expr_depth_ok(int rc, Fts5ExprNode *p){ - if( rc==SQLITE_OK ){ - if( p->eType==FTS5_TERM || p->eType==FTS5_STRING || p->eType==0 ){ - assert( p->iHeight==0 ); - }else{ - int ii; - int iMaxChild = 0; - for(ii=0; iinChild; ii++){ - Fts5ExprNode *pChild = p->apChild[ii]; - iMaxChild = MAX(iMaxChild, pChild->iHeight); - assert_expr_depth_ok(SQLITE_OK, pChild); - } - assert( p->iHeight==iMaxChild+1 ); - } - } -} -#else -# define assert_expr_depth_ok(rc, p) -#endif - static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){ va_list ap; va_start(ap, zFmt); @@ -233371,8 +229744,6 @@ static int sqlite3Fts5ExprNew( }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); sqlite3Fts5ParserFree(pEngine, fts5ParseFree); - assert_expr_depth_ok(sParse.rc, sParse.pExpr); - /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ if( iColnCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ @@ -233535,7 +229906,7 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ Fts5Parse sParse; memset(&sParse, 0, sizeof(sParse)); - if( *pp1 && p2 ){ + if( *pp1 ){ Fts5Expr *p1 = *pp1; int nPhrase = p1->nPhrase + p2->nPhrase; @@ -233560,7 +229931,7 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ } sqlite3_free(p2->apExprPhrase); sqlite3_free(p2); - }else if( p2 ){ + }else{ *pp1 = p2; } @@ -235334,7 +231705,6 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ } static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ - int ii = p->nChild; if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); @@ -235343,9 +231713,6 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ }else{ p->apChild[p->nChild++] = pSub; } - for( ; iinChild; ii++){ - p->iHeight = MAX(p->iHeight, p->apChild[ii]->iHeight + 1); - } } /* @@ -235376,7 +231743,6 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( if( pRet ){ pRet->eType = FTS5_AND; pRet->nChild = nTerm; - pRet->iHeight = 1; fts5ExprAssignXNext(pRet); pParse->nPhrase--; for(ii=0; iiiHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ - sqlite3Fts5ParseError(pParse, - "fts5 expression tree is too large (maximum depth %d)", - SQLITE_FTS5_MAX_EXPR_DEPTH - ); - sqlite3_free(pRet); - pRet = 0; - } } } } @@ -235568,7 +231926,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( return pRet; } -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ sqlite3_int64 nByte = 0; Fts5ExprTerm *p; @@ -235935,14 +232293,14 @@ static void fts5ExprFold( sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics)); } } -#endif /* if SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* ifdef SQLITE_TEST */ /* ** This is called during initialization to register the fts5_expr() scalar ** UDF with the SQLite handle passed as the only argument. */ static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST struct Fts5ExprFunc { const char *z; void (*x)(sqlite3_context*,int,sqlite3_value**); @@ -236702,6 +233060,7 @@ static int fts5HashEntrySort( pList = fts5HashEntryMerge(pList, ap[i]); } + pHash->nEntry = 0; sqlite3_free(ap); *ppSorted = pList; return SQLITE_OK; @@ -236755,28 +233114,6 @@ static int sqlite3Fts5HashScanInit( return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan); } -#ifdef SQLITE_DEBUG -static int fts5HashCount(Fts5Hash *pHash){ - int nEntry = 0; - int ii; - for(ii=0; iinSlot; ii++){ - Fts5HashEntry *p = 0; - for(p=pHash->aSlot[ii]; p; p=p->pHashNext){ - nEntry++; - } - } - return nEntry; -} -#endif - -/* -** Return true if the hash table is empty, false otherwise. -*/ -static int sqlite3Fts5HashIsEmpty(Fts5Hash *pHash){ - assert( pHash->nEntry==fts5HashCount(pHash) ); - return pHash->nEntry==0; -} - static void sqlite3Fts5HashScanNext(Fts5Hash *p){ assert( !sqlite3Fts5HashScanEof(p) ); p->pScan = p->pScan->pScanNext; @@ -236865,24 +233202,6 @@ static void sqlite3Fts5HashScanEntry( #define FTS5_MAX_LEVEL 64 -/* -** There are two versions of the format used for the structure record: -** -** 1. the legacy format, that may be read by all fts5 versions, and -** -** 2. the V2 format, which is used by contentless_delete=1 databases. -** -** Both begin with a 4-byte "configuration cookie" value. Then, a legacy -** format structure record contains a varint - the number of levels in -** the structure. Whereas a V2 structure record contains the constant -** 4 bytes [0xff 0x00 0x00 0x01]. This is unambiguous as the value of a -** varint has to be at least 16256 to begin with "0xFF". And the default -** maximum number of levels is 64. -** -** See below for more on structure record formats. -*/ -#define FTS5_STRUCTURE_V2 "\xFF\x00\x00\x01" - /* ** Details: ** @@ -236890,7 +233209,7 @@ static void sqlite3Fts5HashScanEntry( ** ** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB); ** -** , contains the following 6 types of records. See the comments surrounding +** , contains the following 5 types of records. See the comments surrounding ** the FTS5_*_ROWID macros below for a description of how %_data rowids are ** assigned to each fo them. ** @@ -236899,12 +233218,12 @@ static void sqlite3Fts5HashScanEntry( ** The set of segments that make up an index - the index structure - are ** recorded in a single record within the %_data table. The record consists ** of a single 32-bit configuration cookie value followed by a list of -** SQLite varints. -** -** If the structure record is a V2 record, the configuration cookie is -** followed by the following 4 bytes: [0xFF 0x00 0x00 0x01]. +** SQLite varints. If the FTS table features more than one index (because +** there are one or more prefix indexes), it is guaranteed that all share +** the same cookie value. ** -** Next, the record continues with three varints: +** Immediately following the configuration cookie, the record begins with +** three varints: ** ** + number of levels, ** + total number of segments on all levels, @@ -236919,12 +233238,6 @@ static void sqlite3Fts5HashScanEntry( ** + first leaf page number (often 1, always greater than 0) ** + final leaf page number ** -** Then, for V2 structures only: -** -** + lower origin counter value, -** + upper origin counter value, -** + the number of tombstone hash pages. -** ** 2. The Averages Record: ** ** A single record within the %_data table. The data is a list of varints. @@ -237040,38 +233353,6 @@ static void sqlite3Fts5HashScanEntry( ** * A list of delta-encoded varints - the first rowid on each subsequent ** child page. ** -** 6. Tombstone Hash Page -** -** These records are only ever present in contentless_delete=1 tables. -** There are zero or more of these associated with each segment. They -** are used to store the tombstone rowids for rows contained in the -** associated segments. -** -** The set of nHashPg tombstone hash pages associated with a single -** segment together form a single hash table containing tombstone rowids. -** To find the page of the hash on which a key might be stored: -** -** iPg = (rowid % nHashPg) -** -** Then, within page iPg, which has nSlot slots: -** -** iSlot = (rowid / nHashPg) % nSlot -** -** Each tombstone hash page begins with an 8 byte header: -** -** 1-byte: Key-size (the size in bytes of each slot). Either 4 or 8. -** 1-byte: rowid-0-tombstone flag. This flag is only valid on the -** first tombstone hash page for each segment (iPg=0). If set, -** the hash table contains rowid 0. If clear, it does not. -** Rowid 0 is handled specially. -** 2-bytes: unused. -** 4-bytes: Big-endian integer containing number of entries on page. -** -** Following this are nSlot 4 or 8 byte slots (depending on the key-size -** in the first byte of the page header). The number of slots may be -** determined based on the size of the page record and the key-size: -** -** nSlot = (nByte - 8) / key-size */ /* @@ -237105,7 +233386,6 @@ static void sqlite3Fts5HashScanEntry( #define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno) #define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno) -#define FTS5_TOMBSTONE_ROWID(segid,ipg) fts5_dri(segid+(1<<16), 0, 0, ipg) #ifdef SQLITE_DEBUG static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; } @@ -237141,12 +233421,6 @@ struct Fts5Data { /* ** One object per %_data table. -** -** nContentlessDelete: -** The number of contentless delete operations since the most recent -** call to fts5IndexFlush() or fts5IndexDiscardData(). This is tracked -** so that extra auto-merge work can be done by fts5IndexFlush() to -** account for the delete operations. */ struct Fts5Index { Fts5Config *pConfig; /* Virtual table configuration */ @@ -237161,8 +233435,6 @@ struct Fts5Index { int nPendingData; /* Current bytes of pending data */ i64 iWriteRowid; /* Rowid for current doc being written */ int bDelete; /* Current write is a delete */ - int nContentlessDelete; /* Number of contentless delete ops */ - int nPendingRow; /* Number of INSERT in hash table */ /* Error state. */ int rc; /* Current error code */ @@ -237176,8 +233448,6 @@ struct Fts5Index { sqlite3_stmt *pIdxSelect; int nRead; /* Total number of blocks read */ - sqlite3_stmt *pDeleteFromIdx; - sqlite3_stmt *pDataVersion; i64 iStructVersion; /* data_version when pStruct read */ Fts5Structure *pStruct; /* Current db structure (or NULL) */ @@ -237197,23 +233467,11 @@ struct Fts5DoclistIter { ** The contents of the "structure" record for each index are represented ** using an Fts5Structure record in memory. Which uses instances of the ** other Fts5StructureXXX types as components. -** -** nOriginCntr: -** This value is set to non-zero for structure records created for -** contentlessdelete=1 tables only. In that case it represents the -** origin value to apply to the next top-level segment created. */ struct Fts5StructureSegment { int iSegid; /* Segment id */ int pgnoFirst; /* First leaf page number in segment */ int pgnoLast; /* Last leaf page number in segment */ - - /* contentlessdelete=1 tables only: */ - u64 iOrigin1; - u64 iOrigin2; - int nPgTombstone; /* Number of tombstone hash table pages */ - u64 nEntryTombstone; /* Number of tombstone entries that "count" */ - u64 nEntry; /* Number of rows in this segment */ }; struct Fts5StructureLevel { int nMerge; /* Number of segments in incr-merge */ @@ -237223,7 +233481,6 @@ struct Fts5StructureLevel { struct Fts5Structure { int nRef; /* Object reference count */ u64 nWriteCounter; /* Total leaves written to level 0 */ - u64 nOriginCntr; /* Origin value for next top-level segment */ int nSegment; /* Total segments in this structure */ int nLevel; /* Number of levels in this index */ Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */ @@ -237283,6 +233540,9 @@ struct Fts5CResult { ** iLeafOffset: ** Byte offset within the current leaf that is the first byte of the ** position list data (one byte passed the position-list size field). +** rowid field of the current entry. Usually this is the size field of the +** position list data. The exception is if the rowid for the current entry +** is the last thing on the leaf page. ** ** pLeaf: ** Buffer containing current leaf page data. Set to NULL at EOF. @@ -237312,13 +233572,6 @@ struct Fts5CResult { ** ** iTermIdx: ** Index of current term on iTermLeafPgno. -** -** apTombstone/nTombstone: -** These are used for contentless_delete=1 tables only. When the cursor -** is first allocated, the apTombstone[] array is allocated so that it -** is large enough for all tombstones hash pages associated with the -** segment. The pages themselves are loaded lazily from the database as -** they are required. */ struct Fts5SegIter { Fts5StructureSegment *pSeg; /* Segment to iterate through */ @@ -237327,8 +233580,6 @@ struct Fts5SegIter { Fts5Data *pLeaf; /* Current leaf data */ Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ i64 iLeafOffset; /* Byte offset within current leaf */ - Fts5Data **apTombstone; /* Array of tombstone pages */ - int nTombstone; /* Next method */ void (*xNext)(Fts5Index*, Fts5SegIter*, int*); @@ -237458,60 +233709,6 @@ static u16 fts5GetU16(const u8 *aIn){ return ((u16)aIn[0] << 8) + aIn[1]; } -/* -** The only argument points to a buffer at least 8 bytes in size. This -** function interprets the first 8 bytes of the buffer as a 64-bit big-endian -** unsigned integer and returns the result. -*/ -static u64 fts5GetU64(u8 *a){ - return ((u64)a[0] << 56) - + ((u64)a[1] << 48) - + ((u64)a[2] << 40) - + ((u64)a[3] << 32) - + ((u64)a[4] << 24) - + ((u64)a[5] << 16) - + ((u64)a[6] << 8) - + ((u64)a[7] << 0); -} - -/* -** The only argument points to a buffer at least 4 bytes in size. This -** function interprets the first 4 bytes of the buffer as a 32-bit big-endian -** unsigned integer and returns the result. -*/ -static u32 fts5GetU32(const u8 *a){ - return ((u32)a[0] << 24) - + ((u32)a[1] << 16) - + ((u32)a[2] << 8) - + ((u32)a[3] << 0); -} - -/* -** Write iVal, formated as a 64-bit big-endian unsigned integer, to the -** buffer indicated by the first argument. -*/ -static void fts5PutU64(u8 *a, u64 iVal){ - a[0] = ((iVal >> 56) & 0xFF); - a[1] = ((iVal >> 48) & 0xFF); - a[2] = ((iVal >> 40) & 0xFF); - a[3] = ((iVal >> 32) & 0xFF); - a[4] = ((iVal >> 24) & 0xFF); - a[5] = ((iVal >> 16) & 0xFF); - a[6] = ((iVal >> 8) & 0xFF); - a[7] = ((iVal >> 0) & 0xFF); -} - -/* -** Write iVal, formated as a 32-bit big-endian unsigned integer, to the -** buffer indicated by the first argument. -*/ -static void fts5PutU32(u8 *a, u32 iVal){ - a[0] = ((iVal >> 24) & 0xFF); - a[1] = ((iVal >> 16) & 0xFF); - a[2] = ((iVal >> 8) & 0xFF); - a[3] = ((iVal >> 0) & 0xFF); -} - /* ** Allocate and return a buffer at least nByte bytes in size. ** @@ -237739,17 +233936,10 @@ static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){ /* ** Remove all records associated with segment iSegid. */ -static void fts5DataRemoveSegment(Fts5Index *p, Fts5StructureSegment *pSeg){ - int iSegid = pSeg->iSegid; +static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){ i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0); i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1; fts5DataDelete(p, iFirst, iLast); - - if( pSeg->nPgTombstone ){ - i64 iTomb1 = FTS5_TOMBSTONE_ROWID(iSegid, 0); - i64 iTomb2 = FTS5_TOMBSTONE_ROWID(iSegid, pSeg->nPgTombstone-1); - fts5DataDelete(p, iTomb1, iTomb2); - } if( p->pIdxDeleter==0 ){ Fts5Config *pConfig = p->pConfig; fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf( @@ -237860,19 +234050,11 @@ static int fts5StructureDecode( int nSegment = 0; sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */ Fts5Structure *pRet = 0; /* Structure object to return */ - int bStructureV2 = 0; /* True for FTS5_STRUCTURE_V2 */ - u64 nOriginCntr = 0; /* Largest origin value seen so far */ /* Grab the cookie value */ if( piCookie ) *piCookie = sqlite3Fts5Get32(pData); i = 4; - /* Check if this is a V2 structure record. Set bStructureV2 if it is. */ - if( 0==memcmp(&pData[i], FTS5_STRUCTURE_V2, 4) ){ - i += 4; - bStructureV2 = 1; - } - /* Read the total number of levels and segments from the start of the ** structure record. */ i += fts5GetVarint32(&pData[i], nLevel); @@ -237919,18 +234101,9 @@ static int fts5StructureDecode( rc = FTS5_CORRUPT; break; } - assert( pSeg!=0 ); i += fts5GetVarint32(&pData[i], pSeg->iSegid); i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst); i += fts5GetVarint32(&pData[i], pSeg->pgnoLast); - if( bStructureV2 ){ - i += fts5GetVarint(&pData[i], &pSeg->iOrigin1); - i += fts5GetVarint(&pData[i], &pSeg->iOrigin2); - i += fts5GetVarint32(&pData[i], pSeg->nPgTombstone); - i += fts5GetVarint(&pData[i], &pSeg->nEntryTombstone); - i += fts5GetVarint(&pData[i], &pSeg->nEntry); - nOriginCntr = MAX(nOriginCntr, pSeg->iOrigin2); - } if( pSeg->pgnoLastpgnoFirst ){ rc = FTS5_CORRUPT; break; @@ -237941,9 +234114,6 @@ static int fts5StructureDecode( } } if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT; - if( bStructureV2 ){ - pRet->nOriginCntr = nOriginCntr+1; - } if( rc!=SQLITE_OK ){ fts5StructureRelease(pRet); @@ -237961,7 +234131,6 @@ static int fts5StructureDecode( */ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ fts5StructureMakeWritable(pRc, ppStruct); - assert( (ppStruct!=0 && (*ppStruct)!=0) || (*pRc)!=SQLITE_OK ); if( *pRc==SQLITE_OK ){ Fts5Structure *pStruct = *ppStruct; int nLevel = pStruct->nLevel; @@ -238156,7 +234325,6 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){ Fts5Buffer buf; /* Buffer to serialize record into */ int iLvl; /* Used to iterate through levels */ int iCookie; /* Cookie value to store */ - int nHdr = (pStruct->nOriginCntr>0 ? (4+4+9+9+9) : (4+9+9)); assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); memset(&buf, 0, sizeof(Fts5Buffer)); @@ -238165,12 +234333,9 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){ iCookie = p->pConfig->iCookie; if( iCookie<0 ) iCookie = 0; - if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, nHdr) ){ + if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){ sqlite3Fts5Put32(buf.p, iCookie); buf.n = 4; - if( pStruct->nOriginCntr>0 ){ - fts5BufferSafeAppendBlob(&buf, FTS5_STRUCTURE_V2, 4); - } fts5BufferSafeAppendVarint(&buf, pStruct->nLevel); fts5BufferSafeAppendVarint(&buf, pStruct->nSegment); fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter); @@ -238184,17 +234349,9 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){ assert( pLvl->nMerge<=pLvl->nSeg ); for(iSeg=0; iSegnSeg; iSeg++){ - Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; - fts5BufferAppendVarint(&p->rc, &buf, pSeg->iSegid); - fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoFirst); - fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoLast); - if( pStruct->nOriginCntr>0 ){ - fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin1); - fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin2); - fts5BufferAppendVarint(&p->rc, &buf, pSeg->nPgTombstone); - fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntryTombstone); - fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntry); - } + fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid); + fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst); + fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast); } } @@ -238432,25 +234589,42 @@ static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){ pLvl->bEof = 1; }else{ u8 *a = pLvl->pData->p; - - pLvl->iOff = 0; - fts5DlidxLvlNext(pLvl); - while( 1 ){ - int nZero = 0; - int ii = pLvl->iOff; - u64 delta = 0; - - while( a[ii]==0 ){ - nZero++; - ii++; + i64 iVal; + int iLimit; + int ii; + int nZero = 0; + + /* Currently iOff points to the first byte of a varint. This block + ** decrements iOff until it points to the first byte of the previous + ** varint. Taking care not to read any memory locations that occur + ** before the buffer in memory. */ + iLimit = (iOff>9 ? iOff-9 : 0); + for(iOff--; iOff>iLimit; iOff--){ + if( (a[iOff-1] & 0x80)==0 ) break; + } + + fts5GetVarint(&a[iOff], (u64*)&iVal); + pLvl->iRowid -= iVal; + pLvl->iLeafPgno--; + + /* Skip backwards past any 0x00 varints. */ + for(ii=iOff-1; ii>=pLvl->iFirstOff && a[ii]==0x00; ii--){ + nZero++; + } + if( ii>=pLvl->iFirstOff && (a[ii] & 0x80) ){ + /* The byte immediately before the last 0x00 byte has the 0x80 bit + ** set. So the last 0x00 is only a varint 0 if there are 8 more 0x80 + ** bytes before a[ii]. */ + int bZero = 0; /* True if last 0x00 counts */ + if( (ii-8)>=pLvl->iFirstOff ){ + int j; + for(j=1; j<=8 && (a[ii-j] & 0x80); j++); + bZero = (j>8); } - ii += sqlite3Fts5GetVarint(&a[ii], &delta); - - if( ii>=iOff ) break; - pLvl->iLeafPgno += nZero+1; - pLvl->iRowid += delta; - pLvl->iOff = ii; + if( bZero==0 ) nZero--; } + pLvl->iLeafPgno -= nZero; + pLvl->iOff = iOff - nZero; } return pLvl->bEof; @@ -238646,7 +234820,7 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){ i64 iOff = pIter->iLeafOffset; ASSERT_SZLEAF_OK(pIter->pLeaf); - while( iOff>=pIter->pLeaf->szLeaf ){ + if( iOff>=pIter->pLeaf->szLeaf ){ fts5SegIterNextPage(p, pIter); if( pIter->pLeaf==0 ){ if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; @@ -238717,23 +234891,6 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ } } -/* -** Allocate a tombstone hash page array (pIter->apTombstone) for the -** iterator passed as the second argument. If an OOM error occurs, leave -** an error in the Fts5Index object. -*/ -static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ - const int nTomb = pIter->pSeg->nPgTombstone; - if( nTomb>0 ){ - Fts5Data **apTomb = 0; - apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb); - if( apTomb ){ - pIter->apTombstone = apTomb; - pIter->nTombstone = nTomb; - } - } -} - /* ** Initialize the iterator object pIter to iterate through the entries in ** segment pSeg. The iterator is left pointing to the first entry when @@ -238762,12 +234919,10 @@ static void fts5SegIterInit( fts5SegIterSetNext(p, pIter); pIter->pSeg = pSeg; pIter->iLeafPgno = pSeg->pgnoFirst-1; - do { - fts5SegIterNextPage(p, pIter); - }while( p->rc==SQLITE_OK && pIter->pLeaf && pIter->pLeaf->nn==4 ); + fts5SegIterNextPage(p, pIter); } - if( p->rc==SQLITE_OK && pIter->pLeaf ){ + if( p->rc==SQLITE_OK ){ pIter->iLeafOffset = 4; assert( pIter->pLeaf!=0 ); assert_nc( pIter->pLeaf->nn>4 ); @@ -238775,7 +234930,6 @@ static void fts5SegIterInit( pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; fts5SegIterLoadTerm(p, pIter, 0); fts5SegIterLoadNPos(p, pIter); - fts5SegIterAllocTombstone(p, pIter); } } @@ -238962,7 +235116,7 @@ static void fts5SegIterNext_None( iOff = pIter->iLeafOffset; /* Next entry is on the next page */ - while( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){ + if( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){ fts5SegIterNextPage(p, pIter); if( p->rc || pIter->pLeaf==0 ) return; pIter->iRowid = 0; @@ -239155,7 +235309,7 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ Fts5Data *pLast = 0; int pgnoLast = 0; - if( pDlidx && p->pConfig->iVersion==FTS5_CURRENT_VERSION ){ + if( pDlidx ){ int iSegid = pIter->pSeg->iSegid; pgnoLast = fts5DlidxIterPgno(pDlidx); pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast)); @@ -239477,7 +235631,6 @@ static void fts5SegIterSeekInit( } fts5SegIterSetNext(p, pIter); - fts5SegIterAllocTombstone(p, pIter); /* Either: ** @@ -239558,20 +235711,6 @@ static void fts5SegIterHashInit( fts5SegIterSetNext(p, pIter); } -/* -** Array ap[] contains n elements. Release each of these elements using -** fts5DataRelease(). Then free the array itself using sqlite3_free(). -*/ -static void fts5IndexFreeArray(Fts5Data **ap, int n){ - if( ap ){ - int ii; - for(ii=0; iiterm); fts5DataRelease(pIter->pLeaf); fts5DataRelease(pIter->pNextLeaf); - fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone); fts5DlidxIterFree(pIter->pDlidx); sqlite3_free(pIter->aRowidOffset); memset(pIter, 0, sizeof(Fts5SegIter)); @@ -239732,8 +235870,7 @@ static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){ /* ** Move the seg-iter so that it points to the first rowid on page iLeafPgno. -** It is an error if leaf iLeafPgno does not exist. Unless the db is -** a 'secure-delete' db, if it contains no rowids then this is also an error. +** It is an error if leaf iLeafPgno does not exist or contains no rowids. */ static void fts5SegIterGotoPage( Fts5Index *p, /* FTS5 backend object */ @@ -239748,23 +235885,21 @@ static void fts5SegIterGotoPage( fts5DataRelease(pIter->pNextLeaf); pIter->pNextLeaf = 0; pIter->iLeafPgno = iLeafPgno-1; + fts5SegIterNextPage(p, pIter); + assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno ); - while( p->rc==SQLITE_OK ){ + if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){ int iOff; - fts5SegIterNextPage(p, pIter); - if( pIter->pLeaf==0 ) break; + u8 *a = pIter->pLeaf->p; + int n = pIter->pLeaf->szLeaf; + iOff = fts5LeafFirstRowidOff(pIter->pLeaf); - if( iOff>0 ){ - u8 *a = pIter->pLeaf->p; - int n = pIter->pLeaf->szLeaf; - if( iOff<4 || iOff>=n ){ - p->rc = FTS5_CORRUPT; - }else{ - iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); - pIter->iLeafOffset = iOff; - fts5SegIterLoadNPos(p, pIter); - } - break; + if( iOff<4 || iOff>=n ){ + p->rc = FTS5_CORRUPT; + }else{ + iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); + pIter->iLeafOffset = iOff; + fts5SegIterLoadNPos(p, pIter); } } } @@ -239917,84 +236052,6 @@ static void fts5MultiIterSetEof(Fts5Iter *pIter){ pIter->iSwitchRowid = pSeg->iRowid; } -/* -** The argument to this macro must be an Fts5Data structure containing a -** tombstone hash page. This macro returns the key-size of the hash-page. -*/ -#define TOMBSTONE_KEYSIZE(pPg) (pPg->p[0]==4 ? 4 : 8) - -#define TOMBSTONE_NSLOT(pPg) \ - ((pPg->nn > 16) ? ((pPg->nn-8) / TOMBSTONE_KEYSIZE(pPg)) : 1) - -/* -** Query a single tombstone hash table for rowid iRowid. Return true if -** it is found or false otherwise. The tombstone hash table is one of -** nHashTable tables. -*/ -static int fts5IndexTombstoneQuery( - Fts5Data *pHash, /* Hash table page to query */ - int nHashTable, /* Number of pages attached to segment */ - u64 iRowid /* Rowid to query hash for */ -){ - const int szKey = TOMBSTONE_KEYSIZE(pHash); - const int nSlot = TOMBSTONE_NSLOT(pHash); - int iSlot = (iRowid / nHashTable) % nSlot; - int nCollide = nSlot; - - if( iRowid==0 ){ - return pHash->p[1]; - }else if( szKey==4 ){ - u32 *aSlot = (u32*)&pHash->p[8]; - while( aSlot[iSlot] ){ - if( fts5GetU32((u8*)&aSlot[iSlot])==iRowid ) return 1; - if( nCollide--==0 ) break; - iSlot = (iSlot+1)%nSlot; - } - }else{ - u64 *aSlot = (u64*)&pHash->p[8]; - while( aSlot[iSlot] ){ - if( fts5GetU64((u8*)&aSlot[iSlot])==iRowid ) return 1; - if( nCollide--==0 ) break; - iSlot = (iSlot+1)%nSlot; - } - } - - return 0; -} - -/* -** Return true if the iterator passed as the only argument points -** to an segment entry for which there is a tombstone. Return false -** if there is no tombstone or if the iterator is already at EOF. -*/ -static int fts5MultiIterIsDeleted(Fts5Iter *pIter){ - int iFirst = pIter->aFirst[1].iFirst; - Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; - - if( pSeg->pLeaf && pSeg->nTombstone ){ - /* Figure out which page the rowid might be present on. */ - int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone; - assert( iPg>=0 ); - - /* If tombstone hash page iPg has not yet been loaded from the - ** database, load it now. */ - if( pSeg->apTombstone[iPg]==0 ){ - pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex, - FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) - ); - if( pSeg->apTombstone[iPg]==0 ) return 0; - } - - return fts5IndexTombstoneQuery( - pSeg->apTombstone[iPg], - pSeg->nTombstone, - pSeg->iRowid - ); - } - - return 0; -} - /* ** Move the iterator to the next entry. ** @@ -240032,9 +236089,7 @@ static void fts5MultiIterNext( fts5AssertMultiIterSetup(p, pIter); assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf ); - if( (pIter->bSkipEmpty==0 || pSeg->nPos) - && 0==fts5MultiIterIsDeleted(pIter) - ){ + if( pIter->bSkipEmpty==0 || pSeg->nPos ){ pIter->xSetOutputs(pIter, pSeg); return; } @@ -240066,9 +236121,7 @@ static void fts5MultiIterNext2( } fts5AssertMultiIterSetup(p, pIter); - }while( (fts5MultiIterIsEmpty(p, pIter) || fts5MultiIterIsDeleted(pIter)) - && (p->rc==SQLITE_OK) - ); + }while( fts5MultiIterIsEmpty(p, pIter) ); } } @@ -240561,7 +236614,7 @@ static void fts5MultiIterNew( if( iLevel<0 ){ assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); nSeg = pStruct->nSegment; - nSeg += (p->pHash && 0==(flags & FTS5INDEX_QUERY_SKIPHASH)); + nSeg += (p->pHash ? 1 : 0); }else{ nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment); } @@ -240582,7 +236635,7 @@ static void fts5MultiIterNew( if( p->rc==SQLITE_OK ){ if( iLevel<0 ){ Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel]; - if( p->pHash && 0==(flags & FTS5INDEX_QUERY_SKIPHASH) ){ + if( p->pHash ){ /* Add a segment iterator for the current contents of the hash table. */ Fts5SegIter *pIter = &pNew->aSeg[iIter++]; fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter); @@ -240623,9 +236676,7 @@ static void fts5MultiIterNew( fts5MultiIterSetEof(pNew); fts5AssertMultiIterSetup(p, pNew); - if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew)) - || fts5MultiIterIsDeleted(pNew) - ){ + if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){ fts5MultiIterNext(p, pNew, 0, 0); }else if( pNew->base.bEof==0 ){ Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; @@ -240803,9 +236854,7 @@ static void fts5IndexDiscardData(Fts5Index *p){ if( p->pHash ){ sqlite3Fts5HashClear(p->pHash); p->nPendingData = 0; - p->nPendingRow = 0; } - p->nContentlessDelete = 0; } /* @@ -241341,7 +237390,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){ fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr); fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n); fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p); - fts5BufferAppendBlob(&p->rc, &buf,pData->szLeaf-iOff,&pData->p[iOff]); + fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff,&pData->p[iOff]); if( p->rc==SQLITE_OK ){ /* Set the szLeaf field */ fts5PutU16(&buf.p[2], (u16)buf.n); @@ -241442,12 +237491,6 @@ static void fts5IndexMergeLevel( /* Read input from all segments in the input level */ nInput = pLvl->nSeg; - - /* Set the range of origins that will go into the output segment. */ - if( pStruct->nOriginCntr>0 ){ - pSeg->iOrigin1 = pLvl->aSeg[0].iOrigin1; - pSeg->iOrigin2 = pLvl->aSeg[pLvl->nSeg-1].iOrigin2; - } } bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2); @@ -241507,11 +237550,8 @@ static void fts5IndexMergeLevel( int i; /* Remove the redundant segments from the %_data table */ - assert( pSeg->nEntry==0 ); for(i=0; iaSeg[i]; - pSeg->nEntry += (pOld->nEntry - pOld->nEntryTombstone); - fts5DataRemoveSegment(p, pOld); + fts5DataRemoveSegment(p, pLvl->aSeg[i].iSegid); } /* Remove the redundant segments from the input level */ @@ -241537,43 +237577,6 @@ static void fts5IndexMergeLevel( if( pnRem ) *pnRem -= writer.nLeafWritten; } -/* -** If this is not a contentless_delete=1 table, or if the 'deletemerge' -** configuration option is set to 0, then this function always returns -1. -** Otherwise, it searches the structure object passed as the second argument -** for a level suitable for merging due to having a large number of -** tombstones in the tombstone hash. If one is found, its index is returned. -** Otherwise, if there is no suitable level, -1. -*/ -static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){ - Fts5Config *pConfig = p->pConfig; - int iRet = -1; - if( pConfig->bContentlessDelete && pConfig->nDeleteMerge>0 ){ - int ii; - int nBest = 0; - - for(ii=0; iinLevel; ii++){ - Fts5StructureLevel *pLvl = &pStruct->aLevel[ii]; - i64 nEntry = 0; - i64 nTomb = 0; - int iSeg; - for(iSeg=0; iSegnSeg; iSeg++){ - nEntry += pLvl->aSeg[iSeg].nEntry; - nTomb += pLvl->aSeg[iSeg].nEntryTombstone; - } - assert( nEntry>0 || pLvl->nSeg==0 ); - if( nEntry>0 ){ - int nPercent = (nTomb * 100) / nEntry; - if( nPercent>=pConfig->nDeleteMerge && nPercent>nBest ){ - iRet = ii; - nBest = nPercent; - } - } - } - } - return iRet; -} - /* ** Do up to nPg pages of automerge work on the index. ** @@ -241593,15 +237596,14 @@ static int fts5IndexMerge( int iBestLvl = 0; /* Level offering the most input segments */ int nBest = 0; /* Number of input segments on best level */ - /* Set iBestLvl to the level to read input segments from. Or to -1 if - ** there is no level suitable to merge segments from. */ + /* Set iBestLvl to the level to read input segments from. */ assert( pStruct->nLevel>0 ); for(iLvl=0; iLvlnLevel; iLvl++){ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; if( pLvl->nMerge ){ if( pLvl->nMerge>nBest ){ iBestLvl = iLvl; - nBest = nMin; + nBest = pLvl->nMerge; } break; } @@ -241610,18 +237612,22 @@ static int fts5IndexMerge( iBestLvl = iLvl; } } - if( nBestnLevel; iLvl++){ + assert( pStruct->aLevel[iLvl].nSeg==0 ); } +#endif - if( iBestLvl<0 ) break; + if( nBestaLevel[iBestLvl].nMerge==0 ){ + break; + } bRet = 1; fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem); if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){ fts5StructurePromote(p, iBestLvl+1, pStruct); } - - if( nMin==1 ) nMin = 2; } *ppStruct = pStruct; return bRet; @@ -241662,16 +237668,16 @@ static void fts5IndexCrisismerge( ){ const int nCrisis = p->pConfig->nCrisisMerge; Fts5Structure *pStruct = *ppStruct; - if( pStruct && pStruct->nLevel>0 ){ - int iLvl = 0; - while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){ - fts5IndexMergeLevel(p, &pStruct, iLvl, 0); - assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) ); - fts5StructurePromote(p, iLvl+1, pStruct); - iLvl++; - } - *ppStruct = pStruct; + int iLvl = 0; + + assert( p->rc!=SQLITE_OK || pStruct->nLevel>0 ); + while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){ + fts5IndexMergeLevel(p, &pStruct, iLvl, 0); + assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) ); + fts5StructurePromote(p, iLvl+1, pStruct); + iLvl++; } + *ppStruct = pStruct; } static int fts5IndexReturn(Fts5Index *p){ @@ -241705,419 +237711,6 @@ static int fts5PoslistPrefix(const u8 *aBuf, int nMax){ return ret; } -/* -** Execute the SQL statement: -** -** DELETE FROM %_idx WHERE (segid, (pgno/2)) = ($iSegid, $iPgno); -** -** This is used when a secure-delete operation removes the last term -** from a segment leaf page. In that case the %_idx entry is removed -** too. This is done to ensure that if all instances of a token are -** removed from an fts5 database in secure-delete mode, no trace of -** the token itself remains in the database. -*/ -static void fts5SecureDeleteIdxEntry( - Fts5Index *p, /* FTS5 backend object */ - int iSegid, /* Id of segment to delete entry for */ - int iPgno /* Page number within segment */ -){ - if( iPgno!=1 ){ - assert( p->pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE ); - if( p->pDeleteFromIdx==0 ){ - fts5IndexPrepareStmt(p, &p->pDeleteFromIdx, sqlite3_mprintf( - "DELETE FROM '%q'.'%q_idx' WHERE (segid, (pgno/2)) = (?1, ?2)", - p->pConfig->zDb, p->pConfig->zName - )); - } - if( p->rc==SQLITE_OK ){ - sqlite3_bind_int(p->pDeleteFromIdx, 1, iSegid); - sqlite3_bind_int(p->pDeleteFromIdx, 2, iPgno); - sqlite3_step(p->pDeleteFromIdx); - p->rc = sqlite3_reset(p->pDeleteFromIdx); - } - } -} - -/* -** This is called when a secure-delete operation removes a position-list -** that overflows onto segment page iPgno of segment pSeg. This function -** rewrites node iPgno, and possibly one or more of its right-hand peers, -** to remove this portion of the position list. -** -** Output variable (*pbLastInDoclist) is set to true if the position-list -** removed is followed by a new term or the end-of-segment, or false if -** it is followed by another rowid/position list. -*/ -static void fts5SecureDeleteOverflow( - Fts5Index *p, - Fts5StructureSegment *pSeg, - int iPgno, - int *pbLastInDoclist -){ - const int bDetailNone = (p->pConfig->eDetail==FTS5_DETAIL_NONE); - int pgno; - Fts5Data *pLeaf = 0; - assert( iPgno!=1 ); - - *pbLastInDoclist = 1; - for(pgno=iPgno; p->rc==SQLITE_OK && pgno<=pSeg->pgnoLast; pgno++){ - i64 iRowid = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno); - int iNext = 0; - u8 *aPg = 0; - - pLeaf = fts5DataRead(p, iRowid); - if( pLeaf==0 ) break; - aPg = pLeaf->p; - - iNext = fts5GetU16(&aPg[0]); - if( iNext!=0 ){ - *pbLastInDoclist = 0; - } - if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){ - fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext); - } - - if( iNext==0 ){ - /* The page contains no terms or rowids. Replace it with an empty - ** page and move on to the right-hand peer. */ - const u8 aEmpty[] = {0x00, 0x00, 0x00, 0x04}; - assert_nc( bDetailNone==0 || pLeaf->nn==4 ); - if( bDetailNone==0 ) fts5DataWrite(p, iRowid, aEmpty, sizeof(aEmpty)); - fts5DataRelease(pLeaf); - pLeaf = 0; - }else if( bDetailNone ){ - break; - }else if( iNext>=pLeaf->szLeaf || pLeaf->nnszLeaf || iNext<4 ){ - p->rc = FTS5_CORRUPT; - break; - }else{ - int nShift = iNext - 4; - int nPg; - - int nIdx = 0; - u8 *aIdx = 0; - - /* Unless the current page footer is 0 bytes in size (in which case - ** the new page footer will be as well), allocate and populate a - ** buffer containing the new page footer. Set stack variables aIdx - ** and nIdx accordingly. */ - if( pLeaf->nn>pLeaf->szLeaf ){ - int iFirst = 0; - int i1 = pLeaf->szLeaf; - int i2 = 0; - - i1 += fts5GetVarint32(&aPg[i1], iFirst); - if( iFirstrc = FTS5_CORRUPT; - break; - } - aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2); - if( aIdx==0 ) break; - i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift); - if( i1nn ){ - memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1); - i2 += (pLeaf->nn-i1); - } - nIdx = i2; - } - - /* Modify the contents of buffer aPg[]. Set nPg to the new size - ** in bytes. The new page is always smaller than the old. */ - nPg = pLeaf->szLeaf - nShift; - memmove(&aPg[4], &aPg[4+nShift], nPg-4); - fts5PutU16(&aPg[2], nPg); - if( fts5GetU16(&aPg[0]) ) fts5PutU16(&aPg[0], 4); - if( nIdx>0 ){ - memcpy(&aPg[nPg], aIdx, nIdx); - nPg += nIdx; - } - sqlite3_free(aIdx); - - /* Write the new page to disk and exit the loop */ - assert( nPg>4 || fts5GetU16(aPg)==0 ); - fts5DataWrite(p, iRowid, aPg, nPg); - break; - } - } - fts5DataRelease(pLeaf); -} - -/* -** Completely remove the entry that pSeg currently points to from -** the database. -*/ -static void fts5DoSecureDelete( - Fts5Index *p, - Fts5SegIter *pSeg -){ - const int bDetailNone = (p->pConfig->eDetail==FTS5_DETAIL_NONE); - int iSegid = pSeg->pSeg->iSegid; - u8 *aPg = pSeg->pLeaf->p; - int nPg = pSeg->pLeaf->nn; - int iPgIdx = pSeg->pLeaf->szLeaf; - - u64 iDelta = 0; - u64 iNextDelta = 0; - int iNextOff = 0; - int iOff = 0; - int nIdx = 0; - u8 *aIdx = 0; - int bLastInDoclist = 0; - int iIdx = 0; - int iStart = 0; - int iKeyOff = 0; - int iPrevKeyOff = 0; - int iDelKeyOff = 0; /* Offset of deleted key, if any */ - - nIdx = nPg-iPgIdx; - aIdx = sqlite3Fts5MallocZero(&p->rc, nIdx+16); - if( p->rc ) return; - memcpy(aIdx, &aPg[iPgIdx], nIdx); - - /* At this point segment iterator pSeg points to the entry - ** this function should remove from the b-tree segment. - ** - ** In detail=full or detail=column mode, pSeg->iLeafOffset is the - ** offset of the first byte in the position-list for the entry to - ** remove. Immediately before this comes two varints that will also - ** need to be removed: - ** - ** + the rowid or delta rowid value for the entry, and - ** + the size of the position list in bytes. - ** - ** Or, in detail=none mode, there is a single varint prior to - ** pSeg->iLeafOffset - the rowid or delta rowid value. - ** - ** This block sets the following variables: - ** - ** iStart: - ** iDelta: - */ - { - int iSOP; - if( pSeg->iLeafPgno==pSeg->iTermLeafPgno ){ - iStart = pSeg->iTermLeafOffset; - }else{ - iStart = fts5GetU16(&aPg[0]); - } - - iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); - assert_nc( iSOP<=pSeg->iLeafOffset ); - - if( bDetailNone ){ - while( iSOPiLeafOffset ){ - if( aPg[iSOP]==0x00 ) iSOP++; - if( aPg[iSOP]==0x00 ) iSOP++; - iStart = iSOP; - iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); - } - - iNextOff = iSOP; - if( iNextOffiEndofDoclist && aPg[iNextOff]==0x00 ) iNextOff++; - if( iNextOffiEndofDoclist && aPg[iNextOff]==0x00 ) iNextOff++; - - }else{ - int nPos = 0; - iSOP += fts5GetVarint32(&aPg[iSOP], nPos); - while( iSOPiLeafOffset ){ - iStart = iSOP + (nPos/2); - iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta); - iSOP += fts5GetVarint32(&aPg[iSOP], nPos); - } - assert_nc( iSOP==pSeg->iLeafOffset ); - iNextOff = pSeg->iLeafOffset + pSeg->nPos; - } - } - - iOff = iStart; - if( iNextOff>=iPgIdx ){ - int pgno = pSeg->iLeafPgno+1; - fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); - iNextOff = iPgIdx; - }else{ - /* Set bLastInDoclist to true if the entry being removed is the last - ** in its doclist. */ - for(iIdx=0, iKeyOff=0; iIdxiTermLeafOffset && pSeg->iLeafPgno==pSeg->iTermLeafPgno - ){ - /* The entry being removed was the only position list in its - ** doclist. Therefore the term needs to be removed as well. */ - int iKey = 0; - for(iIdx=0, iKeyOff=0; iIdx(u32)iStart ) break; - iKeyOff += iVal; - } - - iDelKeyOff = iOff = iKeyOff; - if( iNextOff!=iPgIdx ){ - int nPrefix = 0; - int nSuffix = 0; - int nPrefix2 = 0; - int nSuffix2 = 0; - - iDelKeyOff = iNextOff; - iNextOff += fts5GetVarint32(&aPg[iNextOff], nPrefix2); - iNextOff += fts5GetVarint32(&aPg[iNextOff], nSuffix2); - - if( iKey!=1 ){ - iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nPrefix); - } - iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix); - - nPrefix = MIN(nPrefix, nPrefix2); - nSuffix = (nPrefix2 + nSuffix2) - nPrefix; - - if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){ - p->rc = FTS5_CORRUPT; - }else{ - if( iKey!=1 ){ - iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix); - } - iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix); - if( nPrefix2>pSeg->term.n ){ - p->rc = FTS5_CORRUPT; - }else if( nPrefix2>nPrefix ){ - memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix); - iOff += (nPrefix2-nPrefix); - } - memmove(&aPg[iOff], &aPg[iNextOff], nSuffix2); - iOff += nSuffix2; - iNextOff += nSuffix2; - } - } - }else if( iStart==4 ){ - int iPgno; - - assert_nc( pSeg->iLeafPgno>pSeg->iTermLeafPgno ); - /* 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)); - int bEmpty = (pPg && pPg->nn==4); - fts5DataRelease(pPg); - if( bEmpty==0 ) break; - } - - if( iPgno==pSeg->iTermLeafPgno ){ - i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno); - Fts5Data *pTerm = fts5DataRead(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; - - while( 1 ){ - u32 iVal = 0; - int nByte = fts5GetVarint32(&aTermIdx[iTermIdx], iVal); - iTermOff += iVal; - if( (iTermIdx+nByte)>=nTermIdx ) break; - iTermIdx += nByte; - } - 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); - } - } - fts5DataRelease(pTerm); - } - } - - if( p->rc==SQLITE_OK ){ - const int nMove = nPg - iNextOff; - int nShift = 0; - - memmove(&aPg[iOff], &aPg[iNextOff], nMove); - iPgIdx -= (iNextOff - iOff); - nPg = iPgIdx; - fts5PutU16(&aPg[2], iPgIdx); - - nShift = iNextOff - iOff; - for(iIdx=0, iKeyOff=0, iPrevKeyOff=0; iIdxiOff ){ - iKeyOff -= nShift; - nShift = 0; - } - nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOff - iPrevKeyOff); - iPrevKeyOff = iKeyOff; - } - } - - if( iPgIdx==nPg && 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); - } - sqlite3_free(aIdx); -} - -/* -** This is called as part of flushing a delete to disk in 'secure-delete' -** mode. It edits the segments within the database described by argument -** pStruct to remove the entries for term zTerm, rowid iRowid. -*/ -static void fts5FlushSecureDelete( - Fts5Index *p, - Fts5Structure *pStruct, - const char *zTerm, - i64 iRowid -){ - const int f = FTS5INDEX_QUERY_SKIPHASH; - int nTerm = (int)strlen(zTerm); - Fts5Iter *pIter = 0; /* Used to find term instance */ - - fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter); - if( fts5MultiIterEof(p, pIter)==0 ){ - i64 iThis = fts5MultiIterRowid(pIter); - if( iThisrc==SQLITE_OK - && fts5MultiIterEof(p, pIter)==0 - && iRowid==fts5MultiIterRowid(pIter) - ){ - Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; - fts5DoSecureDelete(p, pSeg); - } - } - - fts5MultiIterFree(pIter); -} - - /* ** Flush the contents of in-memory hash table iHash to a new level-0 ** segment on disk. Also update the corresponding structure record. @@ -242134,196 +237727,146 @@ static void fts5FlushOneHash(Fts5Index *p){ /* Obtain a reference to the index structure and allocate a new segment-id ** for the new level-0 segment. */ pStruct = fts5StructureRead(p); + iSegid = fts5AllocateSegid(p, pStruct); fts5StructureInvalidate(p); - if( sqlite3Fts5HashIsEmpty(pHash)==0 ){ - iSegid = fts5AllocateSegid(p, pStruct); - if( iSegid ){ - const int pgsz = p->pConfig->pgsz; - int eDetail = p->pConfig->eDetail; - int bSecureDelete = p->pConfig->bSecureDelete; - Fts5StructureSegment *pSeg; /* New segment within pStruct */ - Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ - Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ - - Fts5SegWriter writer; - fts5WriteInit(p, &writer, iSegid); - - pBuf = &writer.writer.buf; - pPgidx = &writer.writer.pgidx; - - /* fts5WriteInit() should have initialized the buffers to (most likely) - ** the maximum space required. */ - assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) ); - assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) ); - - /* Begin scanning through hash table entries. This loop runs once for each - ** term/doclist currently stored within the hash table. */ - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); - } - while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ - const char *zTerm; /* Buffer containing term */ - int nTerm; /* Size of zTerm in bytes */ - const u8 *pDoclist; /* Pointer to doclist for this term */ - int nDoclist; /* Size of doclist in bytes */ - - /* Get the term and doclist for this entry. */ - sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); - nTerm = (int)strlen(zTerm); - if( bSecureDelete==0 ){ - fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); - if( p->rc!=SQLITE_OK ) break; - assert( writer.bFirstRowidInPage==0 ); - } - - if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ - /* The entire doclist will fit on the current leaf. */ - fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); - }else{ - int bTermWritten = !bSecureDelete; - i64 iRowid = 0; - i64 iPrev = 0; - int iOff = 0; - - /* The entire doclist will not fit on this leaf. The following - ** loop iterates through the poslists that make up the current - ** doclist. */ - while( p->rc==SQLITE_OK && iOffrc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ - iOff++; - continue; - } - } - } + if( iSegid ){ + const int pgsz = p->pConfig->pgsz; + int eDetail = p->pConfig->eDetail; + Fts5StructureSegment *pSeg; /* New segment within pStruct */ + Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ + Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ - if( p->rc==SQLITE_OK && bTermWritten==0 ){ - fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); - bTermWritten = 1; - assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 ); - } + Fts5SegWriter writer; + fts5WriteInit(p, &writer, iSegid); - if( writer.bFirstRowidInPage ){ - fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */ - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); - writer.bFirstRowidInPage = 0; - fts5WriteDlidxAppend(p, &writer, iRowid); - }else{ - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev); - } + pBuf = &writer.writer.buf; + pPgidx = &writer.writer.pgidx; + + /* fts5WriteInit() should have initialized the buffers to (most likely) + ** the maximum space required. */ + assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) ); + assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) ); + + /* Begin scanning through hash table entries. This loop runs once for each + ** term/doclist currently stored within the hash table. */ + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); + } + while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ + const char *zTerm; /* Buffer containing term */ + const u8 *pDoclist; /* Pointer to doclist for this term */ + int nDoclist; /* Size of doclist in bytes */ + + /* Write the term for this entry to disk. */ + sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); + fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm); + if( p->rc!=SQLITE_OK ) break; + + assert( writer.bFirstRowidInPage==0 ); + if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ + /* The entire doclist will fit on the current leaf. */ + fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); + }else{ + i64 iRowid = 0; + u64 iDelta = 0; + int iOff = 0; + + /* The entire doclist will not fit on this leaf. The following + ** loop iterates through the poslists that make up the current + ** doclist. */ + while( p->rc==SQLITE_OK && iOffp[0], (u16)pBuf->n); /* first rowid on page */ + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); + writer.bFirstRowidInPage = 0; + fts5WriteDlidxAppend(p, &writer, iRowid); if( p->rc!=SQLITE_OK ) break; - assert( pBuf->n<=pBuf->nSpace ); - iPrev = iRowid; + }else{ + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta); + } + assert( pBuf->n<=pBuf->nSpace ); - if( eDetail==FTS5_DETAIL_NONE ){ + if( eDetail==FTS5_DETAIL_NONE ){ + if( iOffp[pBuf->n++] = 0; + iOff++; if( iOffp[pBuf->n++] = 0; iOff++; - if( iOffp[pBuf->n++] = 0; - iOff++; - } - } - if( (pBuf->n + pPgidx->n)>=pgsz ){ - fts5WriteFlushLeaf(p, &writer); } + } + if( (pBuf->n + pPgidx->n)>=pgsz ){ + fts5WriteFlushLeaf(p, &writer); + } + }else{ + int bDummy; + int nPos; + int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy); + nCopy += nPos; + if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){ + /* The entire poslist will fit on the current leaf. So copy + ** it in one go. */ + fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy); }else{ - int bDummy; - int nPos; - int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy); - nCopy += nPos; - if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){ - /* The entire poslist will fit on the current leaf. So copy - ** it in one go. */ - fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy); - }else{ - /* The entire poslist will not fit on this leaf. So it needs - ** to be broken into sections. The only qualification being - ** that each varint must be stored contiguously. */ - const u8 *pPoslist = &pDoclist[iOff]; - int iPos = 0; - while( p->rc==SQLITE_OK ){ - int nSpace = pgsz - pBuf->n - pPgidx->n; - int n = 0; - if( (nCopy - iPos)<=nSpace ){ - n = nCopy - iPos; - }else{ - n = fts5PoslistPrefix(&pPoslist[iPos], nSpace); - } - assert( n>0 ); - fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n); - iPos += n; - if( (pBuf->n + pPgidx->n)>=pgsz ){ - fts5WriteFlushLeaf(p, &writer); - } - if( iPos>=nCopy ) break; + /* The entire poslist will not fit on this leaf. So it needs + ** to be broken into sections. The only qualification being + ** that each varint must be stored contiguously. */ + const u8 *pPoslist = &pDoclist[iOff]; + int iPos = 0; + while( p->rc==SQLITE_OK ){ + int nSpace = pgsz - pBuf->n - pPgidx->n; + int n = 0; + if( (nCopy - iPos)<=nSpace ){ + n = nCopy - iPos; + }else{ + n = fts5PoslistPrefix(&pPoslist[iPos], nSpace); + } + assert( n>0 ); + fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n); + iPos += n; + if( (pBuf->n + pPgidx->n)>=pgsz ){ + fts5WriteFlushLeaf(p, &writer); } + if( iPos>=nCopy ) break; } - iOff += nCopy; } + iOff += nCopy; } } - - /* TODO2: Doclist terminator written here. */ - /* pBuf->p[pBuf->n++] = '\0'; */ - assert( pBuf->n<=pBuf->nSpace ); - if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); } - sqlite3Fts5HashClear(pHash); - fts5WriteFinish(p, &writer, &pgnoLast); - assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 ); - if( pgnoLast>0 ){ - /* Update the Fts5Structure. It is written back to the database by the - ** fts5StructureRelease() call below. */ - if( pStruct->nLevel==0 ){ - fts5StructureAddLevel(&p->rc, &pStruct); - } - fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0); - if( p->rc==SQLITE_OK ){ - pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ]; - pSeg->iSegid = iSegid; - pSeg->pgnoFirst = 1; - pSeg->pgnoLast = pgnoLast; - if( pStruct->nOriginCntr>0 ){ - pSeg->iOrigin1 = pStruct->nOriginCntr; - pSeg->iOrigin2 = pStruct->nOriginCntr; - pSeg->nEntry = p->nPendingRow; - pStruct->nOriginCntr++; - } - pStruct->nSegment++; - } - fts5StructurePromote(p, 0, pStruct); - } + /* TODO2: Doclist terminator written here. */ + /* pBuf->p[pBuf->n++] = '\0'; */ + assert( pBuf->n<=pBuf->nSpace ); + if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); + } + sqlite3Fts5HashClear(pHash); + fts5WriteFinish(p, &writer, &pgnoLast); + + /* Update the Fts5Structure. It is written back to the database by the + ** fts5StructureRelease() call below. */ + if( pStruct->nLevel==0 ){ + fts5StructureAddLevel(&p->rc, &pStruct); + } + fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0); + if( p->rc==SQLITE_OK ){ + pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ]; + pSeg->iSegid = iSegid; + pSeg->pgnoFirst = 1; + pSeg->pgnoLast = pgnoLast; + pStruct->nSegment++; } + fts5StructurePromote(p, 0, pStruct); } - fts5IndexAutomerge(p, &pStruct, pgnoLast + p->nContentlessDelete); + fts5IndexAutomerge(p, &pStruct, pgnoLast); fts5IndexCrisismerge(p, &pStruct); fts5StructureWrite(p, pStruct); fts5StructureRelease(pStruct); - p->nContentlessDelete = 0; } /* @@ -242331,11 +237874,10 @@ static void fts5FlushOneHash(Fts5Index *p){ */ static void fts5IndexFlush(Fts5Index *p){ /* Unless it is empty, flush the hash table to disk */ - if( p->nPendingData || p->nContentlessDelete ){ + if( p->nPendingData ){ assert( p->pHash ); - fts5FlushOneHash(p); p->nPendingData = 0; - p->nPendingRow = 0; + fts5FlushOneHash(p); } } @@ -242351,22 +237893,17 @@ static Fts5Structure *fts5IndexOptimizeStruct( /* Figure out if this structure requires optimization. A structure does ** not require optimization if either: ** - ** 1. it consists of fewer than two segments, or - ** 2. all segments are on the same level, or - ** 3. all segments except one are currently inputs to a merge operation. + ** + it consists of fewer than two segments, or + ** + all segments are on the same level, or + ** + all segments except one are currently inputs to a merge operation. ** - ** In the first case, if there are no tombstone hash pages, return NULL. In - ** the second, increment the ref-count on *pStruct and return a copy of the - ** pointer to it. + ** In the first case, return NULL. In the second, increment the ref-count + ** on *pStruct and return a copy of the pointer to it. */ - if( nSeg==0 ) return 0; + if( nSeg<2 ) return 0; for(i=0; inLevel; i++){ int nThis = pStruct->aLevel[i].nSeg; - int nMerge = pStruct->aLevel[i].nMerge; - if( nThis>0 && (nThis==nSeg || (nThis==nSeg-1 && nMerge==nThis)) ){ - if( nSeg==1 && nThis==1 && pStruct->aLevel[i].aSeg[0].nPgTombstone==0 ){ - return 0; - } + if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){ fts5StructureRef(pStruct); return pStruct; } @@ -242382,7 +237919,6 @@ static Fts5Structure *fts5IndexOptimizeStruct( pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL); pNew->nRef = 1; pNew->nWriteCounter = pStruct->nWriteCounter; - pNew->nOriginCntr = pStruct->nOriginCntr; pLvl = &pNew->aLevel[pNew->nLevel-1]; pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pLvl->aSeg ){ @@ -242413,7 +237949,6 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - assert( p->nContentlessDelete==0 ); pStruct = fts5StructureRead(p); fts5StructureInvalidate(p); @@ -242443,10 +237978,7 @@ static int sqlite3Fts5IndexOptimize(Fts5Index *p){ ** INSERT command. */ static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ - Fts5Structure *pStruct = 0; - - fts5IndexFlush(p); - pStruct = fts5StructureRead(p); + Fts5Structure *pStruct = fts5StructureRead(p); if( pStruct ){ int nMin = p->pConfig->nUsermerge; fts5StructureInvalidate(p); @@ -242454,7 +237986,7 @@ static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct); fts5StructureRelease(pStruct); pStruct = pNew; - nMin = 1; + nMin = 2; nMerge = nMerge*-1; } if( pStruct && pStruct->nLevel ){ @@ -242968,9 +238500,6 @@ static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ p->iWriteRowid = iRowid; p->bDelete = bDelete; - if( bDelete==0 ){ - p->nPendingRow++; - } return fts5IndexReturn(p); } @@ -243008,9 +238537,6 @@ static int sqlite3Fts5IndexReinit(Fts5Index *p){ fts5StructureInvalidate(p); fts5IndexDiscardData(p); memset(&s, 0, sizeof(Fts5Structure)); - if( p->pConfig->bContentlessDelete ){ - s.nOriginCntr = 1; - } fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); fts5StructureWrite(p, &s); return fts5IndexReturn(p); @@ -243075,7 +238601,6 @@ static int sqlite3Fts5IndexClose(Fts5Index *p){ sqlite3_finalize(p->pIdxDeleter); sqlite3_finalize(p->pIdxSelect); sqlite3_finalize(p->pDataVersion); - sqlite3_finalize(p->pDeleteFromIdx); sqlite3Fts5HashFree(p->pHash); sqlite3_free(p->zDataTbl); sqlite3_free(p); @@ -243402,347 +238927,6 @@ static int sqlite3Fts5IndexLoadConfig(Fts5Index *p){ return fts5IndexReturn(p); } -/* -** Retrieve the origin value that will be used for the segment currently -** being accumulated in the in-memory hash table when it is flushed to -** disk. If successful, SQLITE_OK is returned and (*piOrigin) set to -** the queried value. Or, if an error occurs, an error code is returned -** and the final value of (*piOrigin) is undefined. -*/ -static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin){ - Fts5Structure *pStruct; - pStruct = fts5StructureRead(p); - if( pStruct ){ - *piOrigin = pStruct->nOriginCntr; - fts5StructureRelease(pStruct); - } - return fts5IndexReturn(p); -} - -/* -** Buffer pPg contains a page of a tombstone hash table - one of nPg pages -** associated with the same segment. This function adds rowid iRowid to -** the hash table. The caller is required to guarantee that there is at -** least one free slot on the page. -** -** If parameter bForce is false and the hash table is deemed to be full -** (more than half of the slots are occupied), then non-zero is returned -** and iRowid not inserted. Or, if bForce is true or if the hash table page -** is not full, iRowid is inserted and zero returned. -*/ -static int fts5IndexTombstoneAddToPage( - Fts5Data *pPg, - int bForce, - int nPg, - u64 iRowid -){ - const int szKey = TOMBSTONE_KEYSIZE(pPg); - const int nSlot = TOMBSTONE_NSLOT(pPg); - const int nElem = fts5GetU32(&pPg->p[4]); - int iSlot = (iRowid / nPg) % nSlot; - int nCollide = nSlot; - - if( szKey==4 && iRowid>0xFFFFFFFF ) return 2; - if( iRowid==0 ){ - pPg->p[1] = 0x01; - return 0; - } - - if( bForce==0 && nElem>=(nSlot/2) ){ - return 1; - } - - fts5PutU32(&pPg->p[4], nElem+1); - if( szKey==4 ){ - u32 *aSlot = (u32*)&pPg->p[8]; - while( aSlot[iSlot] ){ - iSlot = (iSlot + 1) % nSlot; - if( nCollide--==0 ) return 0; - } - fts5PutU32((u8*)&aSlot[iSlot], (u32)iRowid); - }else{ - u64 *aSlot = (u64*)&pPg->p[8]; - while( aSlot[iSlot] ){ - iSlot = (iSlot + 1) % nSlot; - if( nCollide--==0 ) return 0; - } - fts5PutU64((u8*)&aSlot[iSlot], iRowid); - } - - return 0; -} - -/* -** This function attempts to build a new hash containing all the keys -** currently in the tombstone hash table for segment pSeg. The new -** hash will be stored in the nOut buffers passed in array apOut[]. -** All pages of the new hash use key-size szKey (4 or 8). -** -** Return 0 if the hash is successfully rebuilt into the nOut pages. -** Or non-zero if it is not (because one page became overfull). In this -** case the caller should retry with a larger nOut parameter. -** -** Parameter pData1 is page iPg1 of the hash table being rebuilt. -*/ -static int fts5IndexTombstoneRehash( - Fts5Index *p, - Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */ - Fts5Data *pData1, /* One page of current hash - or NULL */ - int iPg1, /* Which page of the current hash is pData1 */ - int szKey, /* 4 or 8, the keysize */ - int nOut, /* Number of output pages */ - Fts5Data **apOut /* Array of output hash pages */ -){ - int ii; - int res = 0; - - /* Initialize the headers of all the output pages */ - for(ii=0; iip[0] = szKey; - fts5PutU32(&apOut[ii]->p[4], 0); - } - - /* Loop through the current pages of the hash table. */ - for(ii=0; res==0 && iinPgTombstone; ii++){ - Fts5Data *pData = 0; /* Page ii of the current hash table */ - Fts5Data *pFree = 0; /* Free this at the end of the loop */ - - if( iPg1==ii ){ - pData = pData1; - }else{ - pFree = pData = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid, ii)); - } - - if( pData ){ - int szKeyIn = TOMBSTONE_KEYSIZE(pData); - int nSlotIn = (pData->nn - 8) / szKeyIn; - int iIn; - for(iIn=0; iInp[8]; - if( aSlot[iIn] ) iVal = fts5GetU32((u8*)&aSlot[iIn]); - }else{ - u64 *aSlot = (u64*)&pData->p[8]; - if( aSlot[iIn] ) iVal = fts5GetU64((u8*)&aSlot[iIn]); - } - - /* If iVal is not 0 at this point, insert it into the new hash table */ - if( iVal ){ - Fts5Data *pPg = apOut[(iVal % nOut)]; - res = fts5IndexTombstoneAddToPage(pPg, 0, nOut, iVal); - if( res ) break; - } - } - - /* If this is page 0 of the old hash, copy the rowid-0-flag from the - ** old hash to the new. */ - if( ii==0 ){ - apOut[0]->p[1] = pData->p[1]; - } - } - fts5DataRelease(pFree); - } - - return res; -} - -/* -** This is called to rebuild the hash table belonging to segment pSeg. -** If parameter pData1 is not NULL, then one page of the existing hash table -** has already been loaded - pData1, which is page iPg1. The key-size for -** the new hash table is szKey (4 or 8). -** -** If successful, the new hash table is not written to disk. Instead, -** output parameter (*pnOut) is set to the number of pages in the new -** hash table, and (*papOut) to point to an array of buffers containing -** the new page data. -** -** If an error occurs, an error code is left in the Fts5Index object and -** both output parameters set to 0 before returning. -*/ -static void fts5IndexTombstoneRebuild( - Fts5Index *p, - Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */ - Fts5Data *pData1, /* One page of current hash - or NULL */ - int iPg1, /* Which page of the current hash is pData1 */ - int szKey, /* 4 or 8, the keysize */ - int *pnOut, /* OUT: Number of output pages */ - Fts5Data ***papOut /* OUT: Output hash pages */ -){ - 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; - - /* Figure out how many output pages (nOut) and how many slots per - ** page (nSlot). There are three possibilities: - ** - ** 1. The hash table does not yet exist. In this case the new hash - ** table will consist of a single page with MINSLOT slots. - ** - ** 2. The hash table exists but is currently a single page. In this - ** case an attempt is made to grow the page to accommodate the new - ** entry. The page is allowed to grow up to nSlotPerPage (see above) - ** slots. - ** - ** 3. The hash table already consists of more than one page, or of - ** a single page already so large that it cannot be grown. In this - ** case the new hash consists of (nPg*2+1) pages of nSlotPerPage - ** slots each, where nPg is the current number of pages in the - ** hash table. - */ - if( pSeg->nPgTombstone==0 ){ - /* Case 1. */ - nOut = 1; - nSlot = MINSLOT; - }else if( pSeg->nPgTombstone==1 ){ - /* Case 2. */ - int nElem = (int)fts5GetU32(&pData1->p[4]); - assert( pData1 && iPg1==0 ); - nOut = 1; - nSlot = MAX(nElem*4, MINSLOT); - if( nSlot>nSlotPerPage ) nOut = 0; - } - if( nOut==0 ){ - /* Case 3. */ - nOut = (pSeg->nPgTombstone * 2 + 1); - nSlot = nSlotPerPage; - } - - /* Allocate the required array and output pages */ - while( 1 ){ - int res = 0; - int ii = 0; - int szPage = 0; - Fts5Data **apOut = 0; - - /* Allocate space for the new hash table */ - assert( nSlot>=MINSLOT ); - apOut = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data*) * nOut); - szPage = 8 + nSlot*szKey; - for(ii=0; iirc, - sizeof(Fts5Data)+szPage - ); - if( pNew ){ - pNew->nn = szPage; - pNew->p = (u8*)&pNew[1]; - apOut[ii] = pNew; - } - } - - /* Rebuild the hash table. */ - if( p->rc==SQLITE_OK ){ - res = fts5IndexTombstoneRehash(p, pSeg, pData1, iPg1, szKey, nOut, apOut); - } - if( res==0 ){ - if( p->rc ){ - fts5IndexFreeArray(apOut, nOut); - apOut = 0; - nOut = 0; - } - *pnOut = nOut; - *papOut = apOut; - break; - } - - /* If control flows to here, it was not possible to rebuild the hash - ** table. Free all buffers and then try again with more pages. */ - assert( p->rc==SQLITE_OK ); - fts5IndexFreeArray(apOut, nOut); - nSlot = nSlotPerPage; - nOut = nOut*2 + 1; - } -} - - -/* -** Add a tombstone for rowid iRowid to segment pSeg. -*/ -static void fts5IndexTombstoneAdd( - Fts5Index *p, - Fts5StructureSegment *pSeg, - u64 iRowid -){ - Fts5Data *pPg = 0; - int iPg = -1; - int szKey = 0; - int nHash = 0; - Fts5Data **apHash = 0; - - p->nContentlessDelete++; - - if( pSeg->nPgTombstone>0 ){ - iPg = iRowid % pSeg->nPgTombstone; - pPg = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg)); - if( pPg==0 ){ - assert( p->rc!=SQLITE_OK ); - return; - } - - if( 0==fts5IndexTombstoneAddToPage(pPg, 0, pSeg->nPgTombstone, iRowid) ){ - fts5DataWrite(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg), pPg->p, pPg->nn); - fts5DataRelease(pPg); - return; - } - } - - /* Have to rebuild the hash table. First figure out the key-size (4 or 8). */ - szKey = pPg ? TOMBSTONE_KEYSIZE(pPg) : 4; - if( iRowid>0xFFFFFFFF ) szKey = 8; - - /* Rebuild the hash table */ - fts5IndexTombstoneRebuild(p, pSeg, pPg, iPg, szKey, &nHash, &apHash); - assert( p->rc==SQLITE_OK || (nHash==0 && apHash==0) ); - - /* If all has succeeded, write the new rowid into one of the new hash - ** table pages, then write them all out to disk. */ - if( nHash ){ - int ii = 0; - fts5IndexTombstoneAddToPage(apHash[iRowid % nHash], 1, nHash, iRowid); - for(ii=0; iiiSegid, ii); - fts5DataWrite(p, iTombstoneRowid, apHash[ii]->p, apHash[ii]->nn); - } - pSeg->nPgTombstone = nHash; - fts5StructureWrite(p, p->pStruct); - } - - fts5DataRelease(pPg); - fts5IndexFreeArray(apHash, nHash); -} - -/* -** Add iRowid to the tombstone list of the segment or segments that contain -** rows from origin iOrigin. Return SQLITE_OK if successful, or an SQLite -** error code otherwise. -*/ -static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid){ - Fts5Structure *pStruct; - pStruct = fts5StructureRead(p); - if( pStruct ){ - int bFound = 0; /* True after pSeg->nEntryTombstone incr. */ - int iLvl; - for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){ - int iSeg; - for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){ - Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; - if( pSeg->iOrigin1<=(u64)iOrigin && pSeg->iOrigin2>=(u64)iOrigin ){ - if( bFound==0 ){ - pSeg->nEntryTombstone++; - bFound = 1; - } - fts5IndexTombstoneAdd(p, pSeg, iRowid); - } - } - } - fts5StructureRelease(pStruct); - } - return fts5IndexReturn(p); -} /************************************************************************* ************************************************************************** @@ -244047,7 +239231,6 @@ static void fts5IndexIntegrityCheckSegment( Fts5StructureSegment *pSeg /* Segment to check internal consistency */ ){ Fts5Config *pConfig = p->pConfig; - int bSecureDelete = (pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE); sqlite3_stmt *pStmt = 0; int rc2; int iIdxPrevLeaf = pSeg->pgnoFirst-1; @@ -244083,19 +239266,7 @@ static void fts5IndexIntegrityCheckSegment( ** is also a rowid pointer within the leaf page header, it points to a ** location before the term. */ if( pLeaf->nn<=pLeaf->szLeaf ){ - - if( nIdxTerm==0 - && pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE - && pLeaf->nn==pLeaf->szLeaf - && pLeaf->nn==4 - ){ - /* special case - the very first page in a segment keeps its %_idx - ** entry even if all the terms are removed from it by secure-delete - ** operations. */ - }else{ - p->rc = FTS5_CORRUPT; - } - + p->rc = FTS5_CORRUPT; }else{ int iOff; /* Offset of first term on leaf */ int iRowidOff; /* Offset of first rowid on leaf */ @@ -244159,12 +239330,9 @@ static void fts5IndexIntegrityCheckSegment( ASSERT_SZLEAF_OK(pLeaf); if( iRowidOff>=pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; - }else if( bSecureDelete==0 || iRowidOff>0 ){ - i64 iDlRowid = fts5DlidxIterRowid(pDlidx); + }else{ fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid); - if( iRowidrc = FTS5_CORRUPT; - } + if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT; } fts5DataRelease(pLeaf); } @@ -244294,14 +239462,13 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum ** function only. */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST /* ** Decode a segment-data rowid from the %_data table. This function is ** the opposite of macro FTS5_SEGMENT_ROWID(). */ static void fts5DecodeRowid( i64 iRowid, /* Rowid from %_data table */ - int *pbTombstone, /* OUT: Tombstone hash flag */ int *piSegid, /* OUT: Segment id */ int *pbDlidx, /* OUT: Dlidx flag */ int *piHeight, /* OUT: Height */ @@ -244317,16 +239484,13 @@ static void fts5DecodeRowid( iRowid >>= FTS5_DATA_DLI_B; *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1)); - iRowid >>= FTS5_DATA_ID_B; - - *pbTombstone = (int)(iRowid & 0x0001); } -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ - int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */ - fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); + int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */ + fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno); if( iSegid==0 ){ if( iKey==FTS5_AVERAGES_ROWID ){ @@ -244336,16 +239500,14 @@ static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ } } else{ - sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%s%ssegid=%d h=%d pgno=%d}", - bDlidx ? "dlidx " : "", - bTomb ? "tombstone " : "", - iSegid, iHeight, iPgno + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}", + bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno ); } } -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST static void fts5DebugStructure( int *pRc, /* IN/OUT: error code */ Fts5Buffer *pBuf, @@ -244360,22 +239522,16 @@ static void fts5DebugStructure( ); for(iSeg=0; iSegnSeg; iSeg++){ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; - sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d", + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}", pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast ); - if( pSeg->iOrigin1>0 ){ - sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " origin=%lld..%lld", - pSeg->iOrigin1, pSeg->iOrigin2 - ); - } - sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); } sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); } } -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST /* ** This is part of the fts5_decode() debugging aid. ** @@ -244400,9 +239556,9 @@ static void fts5DecodeStructure( fts5DebugStructure(pRc, pBuf, p); fts5StructureRelease(p); } -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST /* ** This is part of the fts5_decode() debugging aid. ** @@ -244425,9 +239581,9 @@ static void fts5DecodeAverages( zSpace = " "; } } -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST /* ** Buffer (a/n) is assumed to contain a list of serialized varints. Read ** each varint and append its string representation to buffer pBuf. Return @@ -244444,9 +239600,9 @@ static int fts5DecodePoslist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ } return iOff; } -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST /* ** The start of buffer (a/n) contains the start of a doclist. The doclist ** may or may not finish within the buffer. This function appends a text @@ -244479,9 +239635,9 @@ static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ return iOff; } -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST /* ** This function is part of the fts5_decode() debugging function. It is ** only ever used with detail=none tables. @@ -244522,9 +239678,9 @@ static void fts5DecodeRowidList( sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp); } } -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST /* ** The implementation of user-defined scalar function fts5_decode(). */ @@ -244535,7 +239691,6 @@ static void fts5DecodeFunction( ){ i64 iRowid; /* Rowid for record being decoded */ int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */ - int bTomb; const u8 *aBlob; int n; /* Record to decode */ u8 *a = 0; Fts5Buffer s; /* Build up text to return here */ @@ -244558,7 +239713,7 @@ static void fts5DecodeFunction( if( a==0 ) goto decode_out; if( n>0 ) memcpy(a, aBlob, n); - fts5DecodeRowid(iRowid, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); + fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno); fts5DebugRowid(&rc, &s, iRowid); if( bDlidx ){ @@ -244577,28 +239732,6 @@ static void fts5DecodeFunction( " %d(%lld)", lvl.iLeafPgno, lvl.iRowid ); } - }else if( bTomb ){ - u32 nElem = fts5GetU32(&a[4]); - int szKey = (aBlob[0]==4 || aBlob[0]==8) ? aBlob[0] : 8; - int nSlot = (n - 8) / szKey; - int ii; - sqlite3Fts5BufferAppendPrintf(&rc, &s, " nElem=%d", (int)nElem); - if( aBlob[1] ){ - sqlite3Fts5BufferAppendPrintf(&rc, &s, " 0"); - } - for(ii=0; iiestimatedCost = (double)100; - pIdxInfo->estimatedRows = 100; - pIdxInfo->idxNum = 0; - for(i=0, p=pIdxInfo->aConstraint; inConstraint; i++, p++){ - if( p->usable==0 ) continue; - if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==11 ){ - rc = SQLITE_OK; - pIdxInfo->aConstraintUsage[i].omit = 1; - pIdxInfo->aConstraintUsage[i].argvIndex = 1; - break; - } - } - return rc; -} - -/* -** This method is the destructor for bytecodevtab objects. -*/ -static int fts5structDisconnectMethod(sqlite3_vtab *pVtab){ - Fts5StructVtab *p = (Fts5StructVtab*)pVtab; - sqlite3_free(p); - return SQLITE_OK; -} - -/* -** Constructor for a new bytecodevtab_cursor object. -*/ -static int fts5structOpenMethod(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){ - int rc = SQLITE_OK; - Fts5StructVcsr *pNew = 0; - - pNew = sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); - *ppCsr = (sqlite3_vtab_cursor*)pNew; - - return SQLITE_OK; -} - -/* -** Destructor for a bytecodevtab_cursor. -*/ -static int fts5structCloseMethod(sqlite3_vtab_cursor *cur){ - Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; - fts5StructureRelease(pCsr->pStruct); - sqlite3_free(pCsr); - return SQLITE_OK; -} - - -/* -** Advance a bytecodevtab_cursor to its next row of output. -*/ -static int fts5structNextMethod(sqlite3_vtab_cursor *cur){ - Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; - - assert( pCsr->pStruct ); - pCsr->iSeg++; - pCsr->iRowid++; - while( pCsr->iSeg>=pCsr->pStruct->aLevel[pCsr->iLevel].nSeg ){ - pCsr->iLevel++; - pCsr->iSeg = 0; - } - if( pCsr->iLevel>=pCsr->pStruct->nLevel ){ - fts5StructureRelease(pCsr->pStruct); - pCsr->pStruct = 0; - } - return SQLITE_OK; -} - -/* -** Return TRUE if the cursor has been moved off of the last -** row of output. -*/ -static int fts5structEofMethod(sqlite3_vtab_cursor *cur){ - Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; - return pCsr->pStruct==0; -} - -static int fts5structRowidMethod( - sqlite3_vtab_cursor *cur, - sqlite_int64 *piRowid -){ - Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; - *piRowid = pCsr->iRowid; - return SQLITE_OK; -} - -/* -** Return values of columns for the row at which the bytecodevtab_cursor -** is currently pointing. -*/ -static int fts5structColumnMethod( - sqlite3_vtab_cursor *cur, /* The cursor */ - sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ - int i /* Which column to return */ -){ - Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; - Fts5Structure *p = pCsr->pStruct; - Fts5StructureSegment *pSeg = &p->aLevel[pCsr->iLevel].aSeg[pCsr->iSeg]; - - switch( i ){ - case 0: /* level */ - sqlite3_result_int(ctx, pCsr->iLevel); - break; - case 1: /* segment */ - sqlite3_result_int(ctx, pCsr->iSeg); - break; - case 2: /* merge */ - sqlite3_result_int(ctx, pCsr->iSeg < p->aLevel[pCsr->iLevel].nMerge); - break; - case 3: /* segid */ - sqlite3_result_int(ctx, pSeg->iSegid); - break; - case 4: /* leaf1 */ - sqlite3_result_int(ctx, pSeg->pgnoFirst); - break; - case 5: /* leaf2 */ - sqlite3_result_int(ctx, pSeg->pgnoLast); - break; - case 6: /* origin1 */ - sqlite3_result_int64(ctx, pSeg->iOrigin1); - break; - case 7: /* origin2 */ - sqlite3_result_int64(ctx, pSeg->iOrigin2); - break; - case 8: /* npgtombstone */ - sqlite3_result_int(ctx, pSeg->nPgTombstone); - break; - case 9: /* nentrytombstone */ - sqlite3_result_int64(ctx, pSeg->nEntryTombstone); - break; - case 10: /* nentry */ - sqlite3_result_int64(ctx, pSeg->nEntry); - break; - } - return SQLITE_OK; -} - -/* -** Initialize a cursor. -** -** idxNum==0 means show all subprograms -** idxNum==1 means show only the main bytecode and omit subprograms. -*/ -static int fts5structFilterMethod( - sqlite3_vtab_cursor *pVtabCursor, - int idxNum, const char *idxStr, - int argc, sqlite3_value **argv -){ - Fts5StructVcsr *pCsr = (Fts5StructVcsr *)pVtabCursor; - int rc = SQLITE_OK; - - const u8 *aBlob = 0; - int nBlob = 0; - - assert( argc==1 ); - fts5StructureRelease(pCsr->pStruct); - pCsr->pStruct = 0; - - nBlob = sqlite3_value_bytes(argv[0]); - aBlob = (const u8*)sqlite3_value_blob(argv[0]); - rc = fts5StructureDecode(aBlob, nBlob, 0, &pCsr->pStruct); - if( rc==SQLITE_OK ){ - pCsr->iLevel = 0; - pCsr->iRowid = 0; - pCsr->iSeg = -1; - rc = fts5structNextMethod(pVtabCursor); - } - - return rc; -} - -#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#endif /* SQLITE_TEST */ /* ** This is called as part of registering the FTS5 module with database @@ -245030,7 +239936,7 @@ static int fts5structFilterMethod( ** SQLite error code is returned instead. */ static int sqlite3Fts5IndexInit(sqlite3 *db){ -#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +#ifdef SQLITE_TEST int rc = sqlite3_create_function( db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0 ); @@ -245047,36 +239953,6 @@ static int sqlite3Fts5IndexInit(sqlite3 *db){ db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0 ); } - - if( rc==SQLITE_OK ){ - static const sqlite3_module fts5structure_module = { - 0, /* iVersion */ - 0, /* xCreate */ - fts5structConnectMethod, /* xConnect */ - fts5structBestIndexMethod, /* xBestIndex */ - fts5structDisconnectMethod, /* xDisconnect */ - 0, /* xDestroy */ - fts5structOpenMethod, /* xOpen */ - fts5structCloseMethod, /* xClose */ - fts5structFilterMethod, /* xFilter */ - fts5structNextMethod, /* xNext */ - fts5structEofMethod, /* xEof */ - fts5structColumnMethod, /* xColumn */ - fts5structRowidMethod, /* xRowid */ - 0, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindFunction */ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0, /* xRollbackTo */ - 0 /* xShadowName */ - }; - rc = sqlite3_create_module(db, "fts5_structure", &fts5structure_module, 0); - } return rc; #else return SQLITE_OK; @@ -246718,7 +241594,6 @@ static int fts5UpdateMethod( Fts5Config *pConfig = pTab->p.pConfig; int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ - int bUpdateOrDelete = 0; /* A transaction must be open when this is called. */ assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); @@ -246729,11 +241604,6 @@ static int fts5UpdateMethod( || sqlite3_value_type(apVal[0])==SQLITE_NULL ); assert( pTab->p.pConfig->pzErrmsg==0 ); - if( pConfig->pgsz==0 ){ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); - if( rc!=SQLITE_OK ) return rc; - } - pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; /* Put any active cursors into REQUIRE_SEEK state. */ @@ -246748,14 +241618,7 @@ static int fts5UpdateMethod( if( pConfig->eContent!=FTS5_CONTENT_NORMAL && 0==sqlite3_stricmp("delete", z) ){ - if( pConfig->bContentlessDelete ){ - fts5SetVtabError(pTab, - "'delete' may not be used with a contentless_delete=1 table" - ); - rc = SQLITE_ERROR; - }else{ - rc = fts5SpecialDelete(pTab, apVal); - } + rc = fts5SpecialDelete(pTab, apVal); }else{ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); } @@ -246772,7 +241635,7 @@ static int fts5UpdateMethod( ** Cases 3 and 4 may violate the rowid constraint. */ int eConflict = SQLITE_ABORT; - if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->bContentlessDelete ){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ eConflict = sqlite3_vtab_on_conflict(pConfig->db); } @@ -246780,12 +241643,8 @@ static int fts5UpdateMethod( assert( nArg!=1 || eType0==SQLITE_INTEGER ); /* Filter out attempts to run UPDATE or DELETE on contentless tables. - ** This is not suported. Except - DELETE is supported if the CREATE - ** VIRTUAL TABLE statement contained "contentless_delete=1". */ - if( eType0==SQLITE_INTEGER - && pConfig->eContent==FTS5_CONTENT_NONE - && (nArg>1 || pConfig->bContentlessDelete==0) - ){ + ** This is not suported. */ + if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){ pTab->p.base.zErrMsg = sqlite3_mprintf( "cannot %s contentless fts5 table: %s", (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName @@ -246797,7 +241656,6 @@ static int fts5UpdateMethod( else if( nArg==1 ){ i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); - bUpdateOrDelete = 1; } /* INSERT or UPDATE */ @@ -246813,7 +241671,6 @@ static int fts5UpdateMethod( if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); - bUpdateOrDelete = 1; } fts5StorageInsert(&rc, pTab, apVal, pRowid); } @@ -246842,24 +241699,10 @@ static int fts5UpdateMethod( rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); fts5StorageInsert(&rc, pTab, apVal, pRowid); } - bUpdateOrDelete = 1; } } } - if( rc==SQLITE_OK - && bUpdateOrDelete - && pConfig->bSecureDelete - && pConfig->iVersion==FTS5_CURRENT_VERSION - ){ - rc = sqlite3Fts5StorageConfigValue( - pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE - ); - if( rc==SQLITE_OK ){ - pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE; - } - } - sqlite3Fts5IndexCloseReader(pTab->p.pIndex); pTab->p.pConfig->pzErrmsg = 0; return rc; @@ -246873,7 +241716,8 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_SYNC, 0); pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; - rc = sqlite3Fts5FlushToDisk(&pTab->p); + fts5TripCursors(pTab); + rc = sqlite3Fts5StorageSync(pTab->pStorage); pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -247719,7 +242563,6 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); - pTab->p.pConfig->pgsz = 0; return sqlite3Fts5StorageRollback(pTab->pStorage); } @@ -247922,7 +242765,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-07-28 18:52:09 1d6ded3234bbfa3226ef718eec8d0ce06ae2844628866cb6197383c9bf06267c", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2023-03-22 13:35:58 b7a144c499446125964bbe21f3447cdfaa9de6a9743eeb970abfcbe277f14827", -1, SQLITE_TRANSIENT); } /* @@ -248135,10 +242978,10 @@ static int fts5StorageGetStmt( "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */ - "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */ + "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* REPLACE_DOCSIZE */ "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */ - "SELECT sz%s FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ + "SELECT sz FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */ "SELECT %s FROM %s AS T", /* SCAN */ @@ -248186,19 +243029,6 @@ static int fts5StorageGetStmt( break; } - case FTS5_STMT_REPLACE_DOCSIZE: - zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, - (pC->bContentlessDelete ? ",?" : "") - ); - break; - - case FTS5_STMT_LOOKUP_DOCSIZE: - zSql = sqlite3_mprintf(azStmt[eStmt], - (pC->bContentlessDelete ? ",origin" : ""), - pC->zDb, pC->zName - ); - break; - default: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName); break; @@ -248388,11 +243218,9 @@ static int sqlite3Fts5StorageOpen( } if( rc==SQLITE_OK && pConfig->bColumnsize ){ - const char *zCols = "id INTEGER PRIMARY KEY, sz BLOB"; - if( pConfig->bContentlessDelete ){ - zCols = "id INTEGER PRIMARY KEY, sz BLOB, origin INTEGER"; - } - rc = sqlite3Fts5CreateTable(pConfig, "docsize", zCols, 0, pzErr); + rc = sqlite3Fts5CreateTable( + pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr + ); } if( rc==SQLITE_OK ){ rc = sqlite3Fts5CreateTable( @@ -248469,7 +243297,7 @@ static int fts5StorageDeleteFromIndex( ){ Fts5Config *pConfig = p->pConfig; sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ - int rc = SQLITE_OK; /* Return code */ + int rc; /* Return code */ int rc2; /* sqlite3_reset() return code */ int iCol; Fts5InsertCtx ctx; @@ -248485,6 +243313,7 @@ static int fts5StorageDeleteFromIndex( ctx.pStorage = p; ctx.iCol = -1; + rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ const char *zText; @@ -248521,37 +243350,6 @@ static int fts5StorageDeleteFromIndex( return rc; } -/* -** 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 -** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs, -** an SQLite error code. -*/ -static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ - i64 iOrigin = 0; - sqlite3_stmt *pLookup = 0; - int rc = SQLITE_OK; - - assert( p->pConfig->bContentlessDelete ); - assert( p->pConfig->eContent==FTS5_CONTENT_NONE ); - - /* 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 ){ - sqlite3_bind_int64(pLookup, 1, iDel); - if( SQLITE_ROW==sqlite3_step(pLookup) ){ - iOrigin = sqlite3_column_int64(pLookup, 1); - } - rc = sqlite3_reset(pLookup); - } - - if( rc==SQLITE_OK && iOrigin!=0 ){ - rc = sqlite3Fts5IndexContentlessDelete(p->pIndex, iOrigin, iDel); - } - - return rc; -} /* ** Insert a record into the %_docsize table. Specifically, do: @@ -248572,17 +243370,10 @@ static int fts5StorageInsertDocsize( rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pReplace, 1, iRowid); - if( p->pConfig->bContentlessDelete ){ - i64 iOrigin = 0; - rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); - sqlite3_bind_int64(pReplace, 3, iOrigin); - } - if( rc==SQLITE_OK ){ - sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); - sqlite3_bind_null(pReplace, 2); - } + sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } } return rc; @@ -248646,15 +243437,7 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap /* Delete the index records */ if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); - } - - if( rc==SQLITE_OK ){ - if( p->pConfig->bContentlessDelete ){ - rc = fts5StorageContentlessDelete(p, iDel); - }else{ - rc = fts5StorageDeleteFromIndex(p, iDel, apVal); - } + rc = fts5StorageDeleteFromIndex(p, iDel, apVal); } /* Delete the %_docsize record */ diff --git a/libstuff/sqlite3.h b/libstuff/sqlite3.h index 5cecc6cc7..bfa453516 100644 --- a/libstuff/sqlite3.h +++ b/libstuff/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.43.0" -#define SQLITE_VERSION_NUMBER 3043000 -#define SQLITE_SOURCE_ID "2023-07-28 18:52:09 1d6ded3234bbfa3226ef718eec8d0ce06ae2844628866cb6197383c9bf06267c" +#define SQLITE_VERSION "3.41.2" +#define SQLITE_VERSION_NUMBER 3041002 +#define SQLITE_SOURCE_ID "2023-03-22 13:35:58 b7a144c499446125964bbe21f3447cdfaa9de6a9743eeb970abfcbe277f14827" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -1190,7 +1190,7 @@ struct sqlite3_io_methods { ** by clients within the current process, only within other processes. ** **
    4. [[SQLITE_FCNTL_CKSM_FILE]] -** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use internally by the +** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the ** [checksum VFS shim] only. ** **
    5. [[SQLITE_FCNTL_RESET_CACHE]] @@ -1655,23 +1655,20 @@ SQLITE_API int sqlite3_os_end(void); ** must ensure that no other SQLite interfaces are invoked by other ** threads while sqlite3_config() is running. ** -** The first argument to sqlite3_config() is an integer -** [configuration option] that determines -** what property of SQLite is to be configured. Subsequent arguments -** vary depending on the [configuration option] -** in the first argument. -** -** For most configuration options, the sqlite3_config() interface +** The sqlite3_config() interface ** may only be invoked prior to library initialization using ** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. -** The exceptional configuration options that may be invoked at any time -** 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. +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. ** Note, however, that ^sqlite3_config() can be called as part of the ** implementation of an application-defined [sqlite3_os_init()]. ** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. @@ -1779,23 +1776,6 @@ struct sqlite3_mem_methods { ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. ** -** Most of the configuration options for sqlite3_config() -** will only work if invoked prior to [sqlite3_initialize()] or after -** [sqlite3_shutdown()]. The few exceptions to this rule are called -** "anytime configuration options". -** ^Calling [sqlite3_config()] with a first argument that is not an -** anytime configuration option in between calls to [sqlite3_initialize()] and -** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE. -** -** The set of anytime configuration options can change (by insertions -** and/or deletions) from one release of SQLite to the next. -** As of SQLite version 3.42.0, the complete set of anytime configuration -** options is: -**
        -**
      • SQLITE_CONFIG_LOG -**
      • SQLITE_CONFIG_PCACHE_HDRSZ -**
      -** ** New configuration options may be added in future releases of SQLite. ** Existing configuration options might be discontinued. Applications ** should check the return code from [sqlite3_config()] to make sure that @@ -2142,28 +2122,28 @@ struct sqlite3_mem_methods { ** compile-time option is not set, then the default maximum is 1073741824. ** */ -#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ -#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ -#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ -#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ -#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ -#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ -#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ -#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ -#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ -/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ -#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ -#define SQLITE_CONFIG_PCACHE 14 /* no-op */ -#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ -#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ -#define SQLITE_CONFIG_URI 17 /* int */ -#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ -#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ -#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ -#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ @@ -2398,7 +2378,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_DQS_DML]] -**
    SQLITE_DBCONFIG_DQS_DML
    +**
    SQLITE_DBCONFIG_DQS_DML **
    The SQLITE_DBCONFIG_DQS_DML option activates or deactivates ** the legacy [double-quoted string literal] misfeature for DML statements ** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The @@ -2407,7 +2387,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_DQS_DDL]] -**
    SQLITE_DBCONFIG_DQS_DDL
    +**
    SQLITE_DBCONFIG_DQS_DDL **
    The SQLITE_DBCONFIG_DQS option activates or deactivates ** the legacy [double-quoted string literal] misfeature for DDL statements, ** such as CREATE TABLE and CREATE INDEX. The @@ -2416,7 +2396,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] -**
    SQLITE_DBCONFIG_TRUSTED_SCHEMA
    +**
    SQLITE_DBCONFIG_TRUSTED_SCHEMA **
    The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to ** assume that database schemas are untainted by malicious content. ** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite @@ -2436,7 +2416,7 @@ struct sqlite3_mem_methods { **
    ** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] -**
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
    +**
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT **
    The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates ** the legacy file format flag. When activated, this flag causes all newly ** created database file to have a schema format version number (the 4-byte @@ -2445,7 +2425,7 @@ struct sqlite3_mem_methods { ** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, ** newly created databases are generally not understandable by SQLite versions ** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there -** is now scarcely any need to generate database files that are compatible +** is now scarcely any need to generated database files that are compatible ** all the way back to version 3.0.0, and so this setting is of little ** practical use, but is provided so that SQLite can continue to claim the ** ability to generate new database files that are compatible with version @@ -2454,40 +2434,8 @@ struct sqlite3_mem_methods { ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index. This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support -** either generated columns or descending indexes. +** either generated columns or decending indexes. **
    -** -** [[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 -** 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 -** processing the first argument is written into the integer that the second -** argument points to. -**
    -** -** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] -**
    SQLITE_DBCONFIG_REVERSE_SCANORDER
    -**
    The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order -** in which tables and indexes are scanned so that the scans start at the end -** and work toward the beginning rather than starting at the beginning and -** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the -** same as setting [PRAGMA reverse_unordered_selects]. This option takes -** two arguments which are an integer and a pointer to an integer. The first -** argument is 1, 0, or -1 to enable, disable, or leave unchanged the -** reverse scan order flag, respectively. If the second argument is not NULL, -** then 0 or 1 is written into the integer that the second argument points to -** depending on if the reverse scan order flag is set after processing the -** first argument. -**
    -** ** */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ @@ -2508,9 +2456,7 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ -#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ -#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -2735,7 +2681,6 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*); ** ** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether ** or not an interrupt is currently in effect for [database connection] D. -** It returns 1 if an interrupt is currently in effect, or 0 otherwise. */ SQLITE_API void sqlite3_interrupt(sqlite3*); SQLITE_API int sqlite3_is_interrupted(sqlite3*); @@ -3389,10 +3334,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** M argument should be the bitwise OR-ed combination of ** zero or more [SQLITE_TRACE] constants. ** -** ^Each call to either sqlite3_trace(D,X,P) or sqlite3_trace_v2(D,M,X,P) -** overrides (cancels) all prior calls to sqlite3_trace(D,X,P) or -** sqlite3_trace_v2(D,M,X,P) for the [database connection] D. Each -** database connection may have at most one trace callback. +** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides +** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). ** ** ^The X callback is invoked whenever any of the events identified by ** mask M occur. ^The integer return value from the callback is currently @@ -3761,7 +3704,7 @@ SQLITE_API int sqlite3_open_v2( ** as F) must be one of: **
      **
    • A database filename pointer created by the SQLite core and -** passed into the xOpen() method of a VFS implementation, or +** passed into the xOpen() method of a VFS implemention, or **
    • A filename obtained from [sqlite3_db_filename()], or **
    • A new filename constructed using [sqlite3_create_filename()]. **
    @@ -3874,7 +3817,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); /* ** CAPI3REF: Create and Destroy VFS Filenames ** -** These interfaces are provided for use by [VFS shim] implementations and +** These interfces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of @@ -4421,41 +4364,6 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); */ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); -/* -** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement -** METHOD: sqlite3_stmt -** -** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN -** setting for prepared statement S. If E is zero, then S becomes -** a normal prepared statement. If E is 1, then S behaves as if -** its SQL text began with "EXPLAIN". If E is 2, then S behaves as if -** its SQL text began with "EXPLAIN QUERY PLAN". -** -** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared. -** SQLite tries to avoid a reprepare, but a reprepare might be necessary -** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode. -** -** Because of the potential need to reprepare, a call to -** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be -** reprepared because it was created using sqlite3_prepare() instead of -** the newer sqlite_prepare_v2() or sqlite3_prepare_v3() interfaces and -** hence has no saved SQL text with which to reprepare. -** -** Changing the explain setting for a prepared statement does not change -** the original SQL text for the statement. Hence, if the SQL text originally -** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0) -** is called to convert the statement into an ordinary statement, the EXPLAIN -** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S) -** output, even though the statement now acts like a normal SQL statement. -** -** This routine returns SQLITE_OK if the explain mode is successfully -** changed, or an error code if the explain mode could not be changed. -** The explain mode cannot be changed while a statement is active. -** Hence, it is good practice to call [sqlite3_reset(S)] -** immediately prior to calling sqlite3_stmt_explain(S,E). -*/ -SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode); - /* ** CAPI3REF: Determine If A Prepared Statement Has Been Reset ** METHOD: sqlite3_stmt @@ -4619,7 +4527,7 @@ typedef struct sqlite3_context sqlite3_context; ** with it may be passed. ^It is called to dispose of the BLOB or string even ** if the call to the bind API fails, except the destructor is not called if ** the third parameter is a NULL pointer or the fourth parameter is negative. -** ^ (2) The special constant, [SQLITE_STATIC], may be passed to indicate that +** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that ** the application remains responsible for disposing of the object. ^In this ** case, the object and the provided pointer to it must remain valid until ** either the prepared statement is finalized or the same SQL parameter is @@ -5298,26 +5206,14 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); ** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S ** back to the beginning of its program. ** -** ^The return code from [sqlite3_reset(S)] indicates whether or not -** the previous evaluation of prepared statement S completed successfully. -** ^If [sqlite3_step(S)] has never before been called on S or if -** [sqlite3_step(S)] has not been called since the previous call -** to [sqlite3_reset(S)], then [sqlite3_reset(S)] will return -** [SQLITE_OK]. +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. ** ** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S indicated an error, then ** [sqlite3_reset(S)] returns an appropriate [error code]. -** ^The [sqlite3_reset(S)] interface might also return an [error code] -** if there were no prior errors but the process of resetting -** the prepared statement caused a new error. ^For example, if an -** [INSERT] statement with a [RETURNING] clause is only stepped one time, -** that one call to [sqlite3_step(S)] might return SQLITE_ROW but -** the overall statement might still fail and the [sqlite3_reset(S)] call -** might return SQLITE_BUSY if locking constraints prevent the -** database change from committing. Therefore, it is important that -** applications check the return code from [sqlite3_reset(S)] even if -** no prior call to [sqlite3_step(S)] indicated a problem. ** ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. @@ -5534,7 +5430,7 @@ SQLITE_API int sqlite3_create_window_function( ** [application-defined SQL function] ** that has side-effects or that could potentially leak sensitive information. ** This will prevent attacks in which an application is tricked -** into using a database file that has had its schema surreptitiously +** into using a database file that has had its schema surreptiously ** modified to invoke the application-defined function in ways that are ** harmful. **

    @@ -6305,13 +6201,6 @@ SQLITE_API void sqlite3_activate_cerod( ** of the default VFS is not implemented correctly, or not implemented at ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. -** -** If a negative argument is passed to sqlite3_sleep() the results vary by -** VFS and operating system. Some system treat a negative argument as an -** instruction to sleep forever. Others understand it to mean do not sleep -** at all. ^In SQLite version 3.42.0 and later, a negative -** argument passed into sqlite3_sleep() is changed to zero before it is relayed -** down into the xSleep method of the VFS. */ SQLITE_API int sqlite3_sleep(int); @@ -7939,9 +7828,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** is undefined if the mutex is not currently entered by the ** calling thread or is not currently allocated. ** -** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), -** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer, -** then any of the four routines behaves as a no-op. +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines +** behave as no-ops. ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ @@ -8211,8 +8100,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 -#define SQLITE_TESTCTRL_USELONGDOUBLE 34 -#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -9244,8 +9132,8 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is cancelled. ^The blocked connections -** unlock-notify callback may also be cancelled by closing the blocked +** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** ** The unlock-notify callback is not reentrant. If an application invokes @@ -9668,7 +9556,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** [[SQLITE_VTAB_DIRECTONLY]]

    SQLITE_VTAB_DIRECTONLY
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation ** prohibits that virtual table from being used from within triggers and ** views. **
    @@ -9676,28 +9564,18 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** [[SQLITE_VTAB_INNOCUOUS]]
    SQLITE_VTAB_INNOCUOUS
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** the [xConnect] or [xCreate] methods of a [virtual table] implmentation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. **
    -** -** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]
    SQLITE_VTAB_USES_ALL_SCHEMAS
    -**
    Calls of the form -** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implementation -** instruct the query planner to begin at least a read transaction on -** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the -** virtual table is used. -**
    ** */ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 #define SQLITE_VTAB_INNOCUOUS 2 #define SQLITE_VTAB_DIRECTONLY 3 -#define SQLITE_VTAB_USES_ALL_SCHEMAS 4 /* ** CAPI3REF: Determine The Virtual Table Conflict Policy @@ -9858,7 +9736,7 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); ** communicated to the xBestIndex method as a ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use ** this constraint, it must set the corresponding -** aConstraintUsage[].argvIndex to a positive integer. ^(Then, under +** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under ** the usual mode of handling IN operators, SQLite generates [bytecode] ** that invokes the [xFilter|xFilter() method] once for each value ** on the right-hand side of the IN operator.)^ Thus the virtual table @@ -10287,7 +10165,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** When the [sqlite3_blob_write()] API is used to update a blob column, ** the pre-update hook is invoked with SQLITE_DELETE. This is because the ** in this case the new values are not available. In this case, when a -** callback made with op==SQLITE_DELETE is actually a write using the +** callback made with op==SQLITE_DELETE is actuall a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the ** pre-update hook is being invoked for some other reason, including a @@ -10670,98 +10548,6 @@ SQLITE_API int sqlite3_deserialize( #define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ -/* -** Access details of recent COMMIT commands. This function allows various -** details related to the most recent COMMIT command to be accessed. -** The requested value is always returned via output parameter (*piVal). -** The specific value requested is identified by parameter op (see -** below). -** -** SQLITE_OK is returned if successful, or SQLITE_ERROR if the "op" or -** "zDb" paramters are unrecognized. -*/ -SQLITE_API int sqlite3_commit_status( - sqlite3 *db, /* Database handle */ - const char *zDb, /* Name of database - "main" etc. */ - int op, /* SQLITE_COMMIT_XXX constant */ - unsigned int *piVal /* OUT: Write requested value here */ -); - -/* -** The following describes the five requests supported by -** sqlite3_commit_status(), each identified by an SQLITE_COMMIT_XXX -** constant: -** -** SQLITE_COMMIT_FIRSTFRAME: -** In this case argument zDb must be "main", or "temp", or else the name of -** an attached database. If zDb does not correspond to any attached database, -** SQLITE_ERROR is returned. -** -** The final value of (*piVal) for this request is only defined if (a) the -** most recent attempt to write to the database connection was successful, -** (b) the most recent attempt to write to the database did write to database -** zDb, and (c) zDb is a wal mode database. -** -** If the above conditions are true, then output parameter (*piVal) is -** set to the frame number of the first frame written by the recent -** transaction. In wal mode, or in wal2 mode when a transaction is -** written into the *-wal file, the frame number indicates the frame's -** position in the wal file - frames are numbered starting from 1. In -** wal2 mode, when a transaction is written to the *-wal2 file, the frame -** number is the frame's position in the *-wal2 file, plus (1 << 31). -** -** Note: Although the a database may have up to (1<<32) pages, each wal -** file may contain at most (1<<31) frames. -** -** SQLITE_COMMIT_NFRAME: -** zDb is interpreted in the same way as, and the final value of (*piVal) -** is undefined, for SQLITE_COMMIT_FIRSTFRAME. -** -** Otherwise, (*piVal) is set to the number of frames written by the -** recent transaction. -** -** SQLITE_COMMIT_CONFLICT_DB: -** Parameter zDb is ignored for this request. The results of this -** request are only defined if the most recent attempt to write to -** the database handle was a BEGIN CONCURRENT transaction that -** failed with an SQLITE_BUSY_SNAPSHOT error. -** -** In other cases, (*piVal) is set to the index of the database -** on which the SQLITE_BUSY_SNAPSHOT error occurred (0 for main, -** a value of 2 or greater for an attached database). This value -** may be used with the sqlite3_db_name() API to find the name -** of the conflicting database. -** -** SQLITE_COMMIT_CONFLICT_FRAME: -** Parameter zDb is ignored for this request. The results of this -** request are only defined if the most recent attempt to write to -** the database handle was a BEGIN CONCURRENT transaction that -** failed with an SQLITE_BUSY_SNAPSHOT error. -** -** (*piVal) is set to the frame number of the conflicting frame for -** the recent SQLITE_BUSY_SNAPSHOT error. The conflicting transaction may -** be found by comparing this value with the FIRSTFRAME and -** NFRAME values for recent succesfully committed transactions on -** the same db. If the CONFLICT_FRAME value is F, then the conflicting -** transaction is the most recent successful commit for which -** (FIRSTFRAME <= F <= FIRSTFRAME+NFRAME) is true. -** -** SQLITE_COMMIT_CONFLICT_PGNO: -** Parameter zDb is ignored for this request. The results of this -** request are only defined if the previous attempt to write to -** the database using database handle db failed with -** SQLITE_BUSY_SNAPSHOT. -** -** Return the page number of the conflicting page for the most -** recent SQLITE_BUSY_SNAPSHOT error. -*/ -#define SQLITE_COMMIT_FIRSTFRAME 0 -#define SQLITE_COMMIT_NFRAME 1 -#define SQLITE_COMMIT_CONFLICT_DB 2 -#define SQLITE_COMMIT_CONFLICT_FRAME 3 -#define SQLITE_COMMIT_CONFLICT_PGNO 4 - - /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. @@ -10989,20 +10775,16 @@ SQLITE_API int sqlite3session_create( SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); /* -** CAPI3REF: Configure a Session Object +** CAPIREF: Conigure a Session Object ** METHOD: sqlite3_session ** ** This method is used to configure a session object after it has been -** created. At present the only valid values for the second parameter are -** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID]. +** created. At present the only valid value for the second parameter is +** [SQLITE_SESSION_OBJCONFIG_SIZE]. ** -*/ -SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); - -/* -** CAPI3REF: Options for sqlite3session_object_config +** Arguments for sqlite3session_object_config() ** -** The following values may passed as the the 2nd parameter to +** The following values may passed as the the 4th parameter to ** sqlite3session_object_config(). ** **
    SQLITE_SESSION_OBJCONFIG_SIZE
    @@ -11018,21 +10800,12 @@ SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg ** ** It is an error (SQLITE_MISUSE) to attempt to modify this setting after ** the first table has been attached to the session object. -** -**
    SQLITE_SESSION_OBJCONFIG_ROWID
    -** This option is used to set, clear or query the flag that enables -** collection of data for tables with no explicit PRIMARY KEY. -** -** Normally, tables with no explicit PRIMARY KEY are simply ignored -** by the sessions module. However, if this flag is set, it behaves -** as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted -** as their leftmost columns. -** -** It is an error (SQLITE_MISUSE) to attempt to modify this setting after -** the first table has been attached to the session object. */ -#define SQLITE_SESSION_OBJCONFIG_SIZE 1 -#define SQLITE_SESSION_OBJCONFIG_ROWID 2 +SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); + +/* +*/ +#define SQLITE_SESSION_OBJCONFIG_SIZE 1 /* ** CAPI3REF: Enable Or Disable A Session Object @@ -12195,23 +11968,9 @@ SQLITE_API int sqlite3changeset_apply_v2( ** Invert the changeset before applying it. This is equivalent to inverting ** a changeset using sqlite3changeset_invert() before applying it. It is ** an error to specify this flag with a patchset. -** -**
    SQLITE_CHANGESETAPPLY_IGNORENOOP
    -** Do not invoke the conflict handler callback for any changes that -** would not actually modify the database even if they were applied. -** Specifically, this means that the conflict handler is not invoked -** for: -**
      -**
    • a delete change if the row being deleted cannot be found, -**
    • an update change if the modified fields are already set to -** their new values in the conflicting row, or -**
    • an insert change if all fields of the conflicting row match -** the row being inserted. -**
    */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 -#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 /* ** CAPI3REF: Constants Passed To The Conflict Handler